[DEV] basic version that start to work
This commit is contained in:
parent
8b1d7c6c81
commit
b34ab69747
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Compiled python modules.
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Setuptools distribution folder.
|
||||||
|
/dist/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Python egg metadata, regenerated from source files by setuptools.
|
||||||
|
/*.egg-info
|
69
.travis.yml
Normal file
69
.travis.yml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#language: python
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- dev
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
packages:
|
||||||
|
- g++-4.9
|
||||||
|
- expect
|
||||||
|
- binutils-mingw-w64-i686 # 32bit MinGW
|
||||||
|
- gcc-mingw-w64-i686
|
||||||
|
- g++-mingw-w64-i686
|
||||||
|
- binutils-mingw-w64-x86-64 # 64bit MinGW
|
||||||
|
- gcc-mingw-w64-x86-64
|
||||||
|
- g++-mingw-w64-x86-64
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: linux
|
||||||
|
env: CONF=release BUILDER=gcc TARGET=Linux TAG=Linux
|
||||||
|
compiler: gcc
|
||||||
|
- os: linux
|
||||||
|
env: CONF=debug BUILDER=clang TARGET=Linux
|
||||||
|
compiler: clang
|
||||||
|
- os: linux
|
||||||
|
env: CONF=release BUILDER=gcc TARGET=Windows TAG=Mingw
|
||||||
|
compiler: gcc
|
||||||
|
- os: linux
|
||||||
|
env: CONF=release BUILDER=gcc TARGET=Android TAG=Android DISABLE_PACKAGE=-p
|
||||||
|
compiler: gcc
|
||||||
|
- os: osx
|
||||||
|
env: CONF=release BUILDER=clang TARGET=MacOs TAG=MacOs
|
||||||
|
compiler: clang
|
||||||
|
- os: osx
|
||||||
|
env: CONF=release BUILDER=clang TARGET=IOs TAG=IOs
|
||||||
|
compiler: clang
|
||||||
|
|
||||||
|
install:
|
||||||
|
- cd ..
|
||||||
|
# download NDK
|
||||||
|
- if [ "$TAG" == "Android" ]; then
|
||||||
|
git clone --depth 1 --branch master https://github.com/HeeroYui/android-download-tool;
|
||||||
|
./android-download-tool/dl-android.sh;
|
||||||
|
fi
|
||||||
|
- git clone --depth 1 --branch master https://github.com/atria-soft/ci.git
|
||||||
|
- cd -
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- ./setup.py build
|
||||||
|
- export PYTHONPATH=$PYTHONPATH:./lutin/build/lib.linux-x86_64-2.7/:./lutin/build/lib.linux-x86_64-2.7/lutin/:./lutin/build/lib:./lutin/build/lib/lutin/
|
||||||
|
- cd ..
|
||||||
|
- pwd
|
||||||
|
- ls -l *
|
||||||
|
- ./ci/build_send.py --tag=$TAG --status=START;
|
||||||
|
|
||||||
|
script:
|
||||||
|
- ./lutin/build/scripts-2.7/lutin -w -j4 -C -P -t$TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF $GCOV $DISABLE_PACKAGE test-c; STATUS=$?
|
||||||
|
- ./ci/build_send.py --tag=$TAG --status="$STATUS";
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
- yui.heero@gmail.com
|
2
MANIFEST.in
Normal file
2
MANIFEST.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
include README.rst
|
||||||
|
include bash-autocompletion/monk
|
109
README.rst
Normal file
109
README.rst
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
Prude
|
||||||
|
=====
|
||||||
|
|
||||||
|
`prude` is a generic C++ annalysing code to check language error (english).
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: https://badge.fury.io/py/prude.png
|
||||||
|
:target: https://pypi.python.org/pypi/prude
|
||||||
|
|
||||||
|
Release (master)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
.. image:: https://travis-ci.org/HeeroYui/prude.svg?branch=master
|
||||||
|
:target: https://travis-ci.org/HeeroYui/prude
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=master&tag=Linux
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=master&tag=MacOs
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=master&tag=Mingw
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=master&tag=Android
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=master&tag=IOs
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
|
||||||
|
|
||||||
|
Developement (dev)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. image:: https://travis-ci.org/HeeroYui/prude.svg?branch=dev
|
||||||
|
:target: https://travis-ci.org/HeeroYui/prude
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=dev&tag=Linux
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=dev&tag=MacOs
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=dev&tag=Mingw
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=dev&tag=Android
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
.. image:: http://atria-soft.com/ci/build/HeeroYui/prude.svg?branch=dev&tag=IOs
|
||||||
|
:target: http://atria-soft.com/ci/HeeroYui/prude
|
||||||
|
|
||||||
|
|
||||||
|
Instructions
|
||||||
|
------------
|
||||||
|
|
||||||
|
This is a tool to annalyse C, C++ file and determone if it have some english word that does not exist.
|
||||||
|
|
||||||
|
|
||||||
|
Prude is under a FREE license that can be found in the COPYING file.
|
||||||
|
Any contribution is more than welcome ;)
|
||||||
|
|
||||||
|
git repository
|
||||||
|
--------------
|
||||||
|
|
||||||
|
http://github.com/HeeroYui/prude/
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
http://github.io/HeeroYui/prude/
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Requirements: ``Python >= 2.7`` and ``pip``
|
||||||
|
|
||||||
|
Just run:
|
||||||
|
|
||||||
|
pip install prude
|
||||||
|
|
||||||
|
Install pip on debian/ubuntu:
|
||||||
|
|
||||||
|
sudo apt-get install pip
|
||||||
|
|
||||||
|
Install pip on ARCH-linux:
|
||||||
|
|
||||||
|
sudo pacman -S pip
|
||||||
|
|
||||||
|
Install pip on MacOs:
|
||||||
|
|
||||||
|
sudo easy_install pip
|
||||||
|
|
||||||
|
|
||||||
|
License (APACHE v2.0)
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Copyright prude Edouard DUPIN
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
105
bin/prude
Executable file
105
bin/prude
Executable file
@ -0,0 +1,105 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
# for path inspection:
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import copy
|
||||||
|
import prude
|
||||||
|
import prude.debug as debug
|
||||||
|
import prude.arg as arguments
|
||||||
|
import prude.env as env
|
||||||
|
import prude.tools as tools
|
||||||
|
import prude.module as module
|
||||||
|
|
||||||
|
myArgs = arguments.doxyArg()
|
||||||
|
myArgs.add(arguments.ArgDefine("h", "help", desc="Display this help"))
|
||||||
|
myArgs.add(arguments.ArgDefine("H", "HELP", desc="Display this help (with all compleate information)"))
|
||||||
|
myArgs.add_section("option", "Can be set one time in all case")
|
||||||
|
myArgs.add(arguments.ArgDefine("v", "verbose", list=[["0","None"],["1","error"],["2","warning"],["3","info"],["4","debug"],["5","verbose"],["6","extreme_verbose"]], desc="display makefile debug level (verbose) default =2"))
|
||||||
|
myArgs.add(arguments.ArgDefine("C", "color", desc="Display makefile output in color"))
|
||||||
|
|
||||||
|
myArgs.add_section("cible", "generate in order set")
|
||||||
|
localArgument = myArgs.parse()
|
||||||
|
|
||||||
|
"""
|
||||||
|
display the help of this makefile
|
||||||
|
"""
|
||||||
|
def usage(full=False):
|
||||||
|
color = debug.get_color_set()
|
||||||
|
# generic argument displayed :
|
||||||
|
myArgs.display()
|
||||||
|
print(" ex: " + sys.argv[0] + " myFile1.cpp")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def check_boolean(value):
|
||||||
|
if value == "" \
|
||||||
|
or value == "1" \
|
||||||
|
or value == "true" \
|
||||||
|
or value == "True" \
|
||||||
|
or value == True:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# preparse the argument to get the verbose element for debug mode
|
||||||
|
def parseGenericArg(argument, active):
|
||||||
|
debug.extreme_verbose("parse arg : " + argument.get_option_name() + " " + argument.get_arg() + " active=" + str(active))
|
||||||
|
if argument.get_option_name() == "help":
|
||||||
|
if active==False:
|
||||||
|
usage()
|
||||||
|
return True
|
||||||
|
if argument.get_option_name() == "HELP":
|
||||||
|
if active==False:
|
||||||
|
usage(True)
|
||||||
|
return True
|
||||||
|
elif argument.get_option_name() == "verbose":
|
||||||
|
if active==True:
|
||||||
|
debug.set_level(int(argument.get_arg()))
|
||||||
|
return True
|
||||||
|
elif argument.get_option_name() == "color":
|
||||||
|
if active==True:
|
||||||
|
if check_boolean(argument.get_arg()) == True:
|
||||||
|
debug.enable_color()
|
||||||
|
else:
|
||||||
|
debug.disable_color()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# parse default unique argument:
|
||||||
|
for argument in localArgument:
|
||||||
|
parseGenericArg(argument, True)
|
||||||
|
|
||||||
|
# initialize the system ...
|
||||||
|
prude.init()
|
||||||
|
|
||||||
|
actionDone = False;
|
||||||
|
|
||||||
|
# parse all argument
|
||||||
|
number_of_error = 0
|
||||||
|
for argument in localArgument:
|
||||||
|
if parseGenericArg(argument, False) == True:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
argument_value = argument.get_arg()
|
||||||
|
debug.debug("something request : '" + argument_value + "'")
|
||||||
|
if argument.get_option_name() != "":
|
||||||
|
debug.warning("Can not understand argument : '" + argument.get_option_name() + "'")
|
||||||
|
usage()
|
||||||
|
break;
|
||||||
|
number_of_error += module.annalyse(argument_value)
|
||||||
|
actionDone = True
|
||||||
|
|
||||||
|
# if no action done : we do "all" ...
|
||||||
|
if actionDone == False:
|
||||||
|
usage()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if number_of_error != 0:
|
||||||
|
exit(-1);
|
26
prude/__init__.py
Executable file
26
prude/__init__.py
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import fnmatch
|
||||||
|
# Local import
|
||||||
|
from . import target
|
||||||
|
from . import tools
|
||||||
|
from . import debug
|
||||||
|
from . import module
|
||||||
|
from . import env
|
||||||
|
is_init = False
|
||||||
|
|
||||||
|
def init():
|
||||||
|
global is_init;
|
||||||
|
if is_init == True:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
262
prude/arg.py
Normal file
262
prude/arg.py
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
import sys
|
||||||
|
# Local import
|
||||||
|
from . import debug
|
||||||
|
|
||||||
|
class ArgElement:
|
||||||
|
def __init__(self, option, value=""):
|
||||||
|
self.option = option;
|
||||||
|
self.arg = value;
|
||||||
|
|
||||||
|
def get_option_name(self):
|
||||||
|
return self.option
|
||||||
|
|
||||||
|
def get_arg(self):
|
||||||
|
return self.arg
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
if len(self.arg)==0:
|
||||||
|
debug.info("option : " + self.option)
|
||||||
|
elif len(self.option)==0:
|
||||||
|
debug.info("element : " + self.arg)
|
||||||
|
else:
|
||||||
|
debug.info("option : " + self.option + ":" + self.arg)
|
||||||
|
|
||||||
|
|
||||||
|
class ArgDefine:
|
||||||
|
def __init__(self,
|
||||||
|
smallOption="", # like v for -v
|
||||||
|
bigOption="", # like verbose for --verbose
|
||||||
|
list=[], # ["val", "description"]
|
||||||
|
desc="",
|
||||||
|
haveParam=False):
|
||||||
|
self.option_small = smallOption;
|
||||||
|
self.option_big = bigOption;
|
||||||
|
self.list = list;
|
||||||
|
if len(self.list)!=0:
|
||||||
|
self.have_param = True
|
||||||
|
else:
|
||||||
|
if True==haveParam:
|
||||||
|
self.have_param = True
|
||||||
|
else:
|
||||||
|
self.have_param = False
|
||||||
|
self.description = desc;
|
||||||
|
|
||||||
|
def get_option_small(self):
|
||||||
|
return self.option_small
|
||||||
|
|
||||||
|
def get_option_big(self):
|
||||||
|
return self.option_big
|
||||||
|
|
||||||
|
def need_parameters(self):
|
||||||
|
return self.have_param
|
||||||
|
|
||||||
|
def get_porperties(self):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def check_availlable(self, argument):
|
||||||
|
if len(self.list)==0:
|
||||||
|
return True
|
||||||
|
for element,desc in self.list:
|
||||||
|
if element == argument:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
color = debug.get_color_set()
|
||||||
|
if self.option_small != "" and self.option_big != "":
|
||||||
|
print(" " + color['red'] + "-" + self.option_small + "" + color['default'] + " / " + color['red'] + "--" + self.option_big + color['default'])
|
||||||
|
elif self.option_small != "":
|
||||||
|
print(" " + color['red'] + "-" + self.option_small + color['default'])
|
||||||
|
elif self.option_big != "":
|
||||||
|
print(" " + color['red'] + "--" + self.option_big + color['default'])
|
||||||
|
else:
|
||||||
|
print(" ???? ==> internal error ...")
|
||||||
|
if self.description != "":
|
||||||
|
print(" " + self.description)
|
||||||
|
if len(self.list)!=0:
|
||||||
|
hasDescriptiveElement=False
|
||||||
|
for val,desc in self.list:
|
||||||
|
if desc!="":
|
||||||
|
hasDescriptiveElement=True
|
||||||
|
break;
|
||||||
|
if hasDescriptiveElement==True:
|
||||||
|
for val,desc in self.list:
|
||||||
|
print(" " + val + " : " + desc)
|
||||||
|
else:
|
||||||
|
tmpElementPrint = ""
|
||||||
|
for val,desc in self.list:
|
||||||
|
if len(tmpElementPrint)!=0:
|
||||||
|
tmpElementPrint += " / "
|
||||||
|
tmpElementPrint += val
|
||||||
|
print(" { " + tmpElementPrint + " }")
|
||||||
|
|
||||||
|
def parse(self, argList, currentID):
|
||||||
|
return currentID;
|
||||||
|
|
||||||
|
|
||||||
|
class ArgSection:
|
||||||
|
def __init__(self,
|
||||||
|
sectionName="",
|
||||||
|
desc=""):
|
||||||
|
self.section = sectionName;
|
||||||
|
self.description = desc;
|
||||||
|
|
||||||
|
def get_option_small(self):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def get_option_big(self):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def get_porperties(self):
|
||||||
|
color = debug.get_color_set()
|
||||||
|
return " [" + color['blue'] + self.section + color['default'] + "]"
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
color = debug.get_color_set()
|
||||||
|
print(" [" + color['blue'] + self.section + color['default'] + "] : " + self.description)
|
||||||
|
|
||||||
|
def parse(self, argList, currentID):
|
||||||
|
return currentID;
|
||||||
|
|
||||||
|
|
||||||
|
class doxyArg:
|
||||||
|
def __init__(self):
|
||||||
|
self.listProperties = []
|
||||||
|
|
||||||
|
def add(self, argument):
|
||||||
|
self.listProperties.append(argument) #ArgDefine(smallOption, bigOption, haveParameter, parameterList, description));
|
||||||
|
|
||||||
|
def add_section(self, sectionName, sectionDesc):
|
||||||
|
self.listProperties.append(ArgSection(sectionName, sectionDesc))
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
|
listArgument = [] # composed of list element
|
||||||
|
NotparseNextElement=False
|
||||||
|
for iii in range(1, len(sys.argv)):
|
||||||
|
# special case of parameter in some elements
|
||||||
|
if NotparseNextElement==True:
|
||||||
|
NotparseNextElement = False
|
||||||
|
continue
|
||||||
|
debug.verbose("parse [" + str(iii) + "]=" + sys.argv[iii])
|
||||||
|
argument = sys.argv[iii]
|
||||||
|
optionList = argument.split("=")
|
||||||
|
debug.verbose(str(optionList))
|
||||||
|
if type(optionList) == type(str()):
|
||||||
|
option = optionList
|
||||||
|
else:
|
||||||
|
option = optionList[0]
|
||||||
|
optionParam = argument[len(option)+1:]
|
||||||
|
debug.verbose(option)
|
||||||
|
argumentFound=False;
|
||||||
|
if option[:2]=="--":
|
||||||
|
# big argument
|
||||||
|
for prop in self.listProperties:
|
||||||
|
if prop.get_option_big()=="":
|
||||||
|
continue
|
||||||
|
if prop.get_option_big() == option[2:]:
|
||||||
|
# find it
|
||||||
|
debug.verbose("find argument 2 : " + option[2:])
|
||||||
|
if prop.need_parameters()==True:
|
||||||
|
internalSub = option[2+len(prop.get_option_big()):]
|
||||||
|
if len(internalSub)!=0:
|
||||||
|
if len(optionParam)!=0:
|
||||||
|
# wrong argument ...
|
||||||
|
debug.warning("maybe wrong argument for : '" + prop.get_option_big() + "' cmdLine='" + argument + "'")
|
||||||
|
prop.display()
|
||||||
|
continue
|
||||||
|
optionParam = internalSub
|
||||||
|
if len(optionParam)==0:
|
||||||
|
#Get the next parameters
|
||||||
|
if len(sys.argv) > iii+1:
|
||||||
|
optionParam = sys.argv[iii+1]
|
||||||
|
NotparseNextElement=True
|
||||||
|
else :
|
||||||
|
# missing arguments
|
||||||
|
debug.warning("parsing argument error : '" + prop.get_option_big() + "' Missing : subParameters ... cmdLine='" + argument + "'")
|
||||||
|
prop.display()
|
||||||
|
exit(-1)
|
||||||
|
if prop.check_availlable(optionParam)==False:
|
||||||
|
debug.warning("argument error : '" + prop.get_option_big() + "' SubParameters not availlable ... cmdLine='" + argument + "' option='" + optionParam + "'")
|
||||||
|
prop.display()
|
||||||
|
exit(-1)
|
||||||
|
listArgument.append(ArgElement(prop.get_option_big(),optionParam))
|
||||||
|
argumentFound = True
|
||||||
|
else:
|
||||||
|
if len(optionParam)!=0:
|
||||||
|
debug.warning("parsing argument error : '" + prop.get_option_big() + "' need no subParameters : '" + optionParam + "' cmdLine='" + argument + "'")
|
||||||
|
prop.display()
|
||||||
|
listArgument.append(ArgElement(prop.get_option_big()))
|
||||||
|
argumentFound = True
|
||||||
|
break;
|
||||||
|
if False==argumentFound:
|
||||||
|
debug.error("UNKNOW argument : '" + argument + "'")
|
||||||
|
elif option[:1]=="-":
|
||||||
|
# small argument
|
||||||
|
for prop in self.listProperties:
|
||||||
|
if prop.get_option_small()=="":
|
||||||
|
continue
|
||||||
|
if prop.get_option_small() == option[1:1+len(prop.get_option_small())]:
|
||||||
|
# find it
|
||||||
|
debug.verbose("find argument 1 : " + option[1:1+len(prop.get_option_small())])
|
||||||
|
if prop.need_parameters()==True:
|
||||||
|
internalSub = option[1+len(prop.get_option_small()):]
|
||||||
|
if len(internalSub)!=0:
|
||||||
|
if len(optionParam)!=0:
|
||||||
|
# wrong argument ...
|
||||||
|
debug.warning("maybe wrong argument for : '" + prop.get_option_big() + "' cmdLine='" + argument + "'")
|
||||||
|
prop.display()
|
||||||
|
continue
|
||||||
|
optionParam = internalSub
|
||||||
|
if len(optionParam)==0:
|
||||||
|
#Get the next parameters
|
||||||
|
if len(sys.argv) > iii+1:
|
||||||
|
optionParam = sys.argv[iii+1]
|
||||||
|
NotparseNextElement=True
|
||||||
|
else :
|
||||||
|
# missing arguments
|
||||||
|
debug.warning("parsing argument error : '" + prop.get_option_big() + "' Missing : subParameters cmdLine='" + argument + "'")
|
||||||
|
prop.display()
|
||||||
|
exit(-1)
|
||||||
|
if prop.check_availlable(optionParam)==False:
|
||||||
|
debug.warning("argument error : '" + prop.get_option_big() + "' SubParameters not availlable ... cmdLine='" + argument + "' option='" + optionParam + "'")
|
||||||
|
prop.display()
|
||||||
|
exit(-1)
|
||||||
|
listArgument.append(ArgElement(prop.get_option_big(),optionParam))
|
||||||
|
argumentFound = True
|
||||||
|
else:
|
||||||
|
if len(optionParam)!=0:
|
||||||
|
debug.warning("parsing argument error : '" + prop.get_option_big() + "' need no subParameters : '" + optionParam + "' cmdLine='" + argument + "'")
|
||||||
|
prop.display()
|
||||||
|
listArgument.append(ArgElement(prop.get_option_big()))
|
||||||
|
argumentFound = True
|
||||||
|
break;
|
||||||
|
|
||||||
|
if argumentFound==False:
|
||||||
|
#unknow element ... ==> just add in the list ...
|
||||||
|
debug.verbose("unknow argument : " + argument)
|
||||||
|
listArgument.append(ArgElement("", argument))
|
||||||
|
|
||||||
|
#for argument in listArgument:
|
||||||
|
# argument.display()
|
||||||
|
#exit(0)
|
||||||
|
return listArgument;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
print("usage:")
|
||||||
|
listOfPropertiesArg = "";
|
||||||
|
for element in self.listProperties :
|
||||||
|
listOfPropertiesArg += element.get_porperties()
|
||||||
|
print(" " + sys.argv[0] + listOfPropertiesArg + " ...")
|
||||||
|
for element in self.listProperties :
|
||||||
|
element.display()
|
181
prude/debug.py
Normal file
181
prude/debug.py
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
import re
|
||||||
|
|
||||||
|
debug_level=3
|
||||||
|
debug_color=False
|
||||||
|
|
||||||
|
color_default= ""
|
||||||
|
color_red = ""
|
||||||
|
color_green = ""
|
||||||
|
color_yellow = ""
|
||||||
|
color_blue = ""
|
||||||
|
color_purple = ""
|
||||||
|
color_cyan = ""
|
||||||
|
|
||||||
|
|
||||||
|
debug_lock = threading.Lock()
|
||||||
|
|
||||||
|
def set_level(id):
|
||||||
|
global debug_level
|
||||||
|
debug_level = id
|
||||||
|
#print "SetDebug level at " + str(debug_level)
|
||||||
|
|
||||||
|
def get_level():
|
||||||
|
global debug_level
|
||||||
|
return debug_level
|
||||||
|
|
||||||
|
def enable_color():
|
||||||
|
global debug_color
|
||||||
|
debug_color = True
|
||||||
|
global color_default
|
||||||
|
color_default= "\033[00m"
|
||||||
|
global color_red
|
||||||
|
color_red = "\033[31m"
|
||||||
|
global color_green
|
||||||
|
color_green = "\033[32m"
|
||||||
|
global color_yellow
|
||||||
|
color_yellow = "\033[33m"
|
||||||
|
global color_blue
|
||||||
|
color_blue = "\033[01;34m"
|
||||||
|
global color_purple
|
||||||
|
color_purple = "\033[35m"
|
||||||
|
global color_cyan
|
||||||
|
color_cyan = "\033[36m"
|
||||||
|
|
||||||
|
def disable_color():
|
||||||
|
global debug_color
|
||||||
|
debug_color = True
|
||||||
|
global color_default
|
||||||
|
color_default= ""
|
||||||
|
global color_red
|
||||||
|
color_red = ""
|
||||||
|
global color_green
|
||||||
|
color_green = ""
|
||||||
|
global color_yellow
|
||||||
|
color_yellow = ""
|
||||||
|
global color_blue
|
||||||
|
color_blue = ""
|
||||||
|
global color_purple
|
||||||
|
color_purple = ""
|
||||||
|
global color_cyan
|
||||||
|
color_cyan = ""
|
||||||
|
|
||||||
|
def extreme_verbose(input, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 6 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_blue + input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def verbose(input, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 5 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_blue + input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def debug(input, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 4 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_green + input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def info(input, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 3 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def warning(input, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 2 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_purple + "[WARNING] " + input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def todo(input, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 3 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_purple + "[TODO] " + input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def error(input, force=False, crash=True):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 1 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_red + "[ERROR] " + input + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
if crash == True:
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
def print_element(type, lib, dir, name, force=False):
|
||||||
|
global debug_lock
|
||||||
|
global debug_level
|
||||||
|
if debug_level >= 3 \
|
||||||
|
or force == True:
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(color_cyan + type + color_default + " : " + color_yellow + lib + color_default + " " + dir + " " + color_blue + name + color_default)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def print_compilator(myString):
|
||||||
|
global debug_color
|
||||||
|
global debug_lock
|
||||||
|
if debug_color == True:
|
||||||
|
myString = myString.replace('\\n', '\n')
|
||||||
|
myString = myString.replace('\\t', '\t')
|
||||||
|
myString = myString.replace('error:', color_red+'error:'+color_default)
|
||||||
|
myString = myString.replace('warning:', color_purple+'warning:'+color_default)
|
||||||
|
myString = myString.replace('note:', color_green+'note:'+color_default)
|
||||||
|
myString = re.sub(r'([/\w_-]+\.\w+):', r'-COLORIN-\1-COLOROUT-:', myString)
|
||||||
|
myString = myString.replace('-COLORIN-', color_yellow)
|
||||||
|
myString = myString.replace('-COLOROUT-', color_default)
|
||||||
|
|
||||||
|
debug_lock.acquire()
|
||||||
|
print(myString)
|
||||||
|
debug_lock.release()
|
||||||
|
|
||||||
|
def get_color_set() :
|
||||||
|
global color_default
|
||||||
|
global color_red
|
||||||
|
global color_green
|
||||||
|
global color_yellow
|
||||||
|
global color_blue
|
||||||
|
global color_purple
|
||||||
|
global color_cyan
|
||||||
|
return {
|
||||||
|
"default": color_default,
|
||||||
|
"red": color_red,
|
||||||
|
"green": color_green,
|
||||||
|
"yellow": color_yellow,
|
||||||
|
"blue": color_blue,
|
||||||
|
"purple": color_purple,
|
||||||
|
"cyan": color_cyan,
|
||||||
|
}
|
178713
prude/english.py
Normal file
178713
prude/english.py
Normal file
File diff suppressed because it is too large
Load Diff
127
prude/env.py
Normal file
127
prude/env.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
# Local import
|
||||||
|
from . import debug
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
force_mode=False
|
||||||
|
|
||||||
|
def set_force_mode(val):
|
||||||
|
global force_mode
|
||||||
|
if val==1:
|
||||||
|
force_mode = 1
|
||||||
|
else:
|
||||||
|
force_mode = 0
|
||||||
|
|
||||||
|
def get_force_mode():
|
||||||
|
global force_mode
|
||||||
|
return force_mode
|
||||||
|
|
||||||
|
|
||||||
|
system_base_name = "prude"
|
||||||
|
|
||||||
|
def set_system_base_name(val):
|
||||||
|
global system_base_name
|
||||||
|
system_base_name = val
|
||||||
|
debug.debug("Set basename: '" + str(system_base_name) + "'")
|
||||||
|
|
||||||
|
def get_system_base_name():
|
||||||
|
global system_base_name
|
||||||
|
return system_base_name
|
||||||
|
|
||||||
|
|
||||||
|
prude_root_path = os.path.join(os.getcwd())
|
||||||
|
if os.path.exists(os.path.join(prude_root_path, "." + get_system_base_name())) == True:
|
||||||
|
# all is good ...
|
||||||
|
pass
|
||||||
|
elif os.path.exists(os.path.join(prude_root_path, "..", "." + get_system_base_name())) == True:
|
||||||
|
prude_root_path = os.path.join(os.getcwd(), "..")
|
||||||
|
elif os.path.exists(os.path.join(prude_root_path, "..", "..", "." + get_system_base_name())) == True:
|
||||||
|
prude_root_path = os.path.join(os.getcwd(), "..", "..")
|
||||||
|
elif os.path.exists(os.path.join(prude_root_path, "..", "..", "..", "." + get_system_base_name())) == True:
|
||||||
|
prude_root_path = os.path.join(os.getcwd(), "..", "..", "..")
|
||||||
|
elif os.path.exists(os.path.join(prude_root_path, "..", "..", "..", "..", "." + get_system_base_name())) == True:
|
||||||
|
prude_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..")
|
||||||
|
elif os.path.exists(os.path.join(prude_root_path, "..", "..", "..", "..", "..", "." + get_system_base_name())) == True:
|
||||||
|
prude_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..", "..")
|
||||||
|
elif os.path.exists(os.path.join(prude_root_path, "..", "..", "..", "..", "..", "..", "." + get_system_base_name())) == True:
|
||||||
|
prude_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..", "..", "..")
|
||||||
|
else:
|
||||||
|
#debug.error("the root path of " + get_system_base_name() + " must not be upper that 6 parent path")
|
||||||
|
pass
|
||||||
|
prude_path = os.path.join(prude_root_path, "." + get_system_base_name())
|
||||||
|
|
||||||
|
def get_local_config_file():
|
||||||
|
return prude_path
|
||||||
|
|
||||||
|
def file_read_data(path):
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
return ""
|
||||||
|
file = open(path, "r")
|
||||||
|
data_file = file.read()
|
||||||
|
file.close()
|
||||||
|
return data_file
|
||||||
|
|
||||||
|
def get_local_filter():
|
||||||
|
global capital_letter_check
|
||||||
|
capital_letter_check = True
|
||||||
|
if os.path.exists(prude_root_path) == False:
|
||||||
|
return []
|
||||||
|
# parse the global .prude file
|
||||||
|
filter_list = [{"check-capital":True}, [], []]
|
||||||
|
if os.path.exists(get_local_config_file()) == True:
|
||||||
|
data = file_read_data(get_local_config_file())
|
||||||
|
for elem in data.split("\n"):
|
||||||
|
if elem == "":
|
||||||
|
continue
|
||||||
|
if elem[0] == "#":
|
||||||
|
continue
|
||||||
|
if elem[0] == "!":
|
||||||
|
# specific control check
|
||||||
|
if elem == "!NO_CAPITAL_LETTER":
|
||||||
|
filter_list[0]["check-capital"] = False
|
||||||
|
else:
|
||||||
|
debug.error("unknows parameter: '" + elem + "'")
|
||||||
|
continue
|
||||||
|
if elem[0] == "+":
|
||||||
|
# check the full name:
|
||||||
|
filter_list[1].append(elem[1:])
|
||||||
|
else:
|
||||||
|
filter_list[2].append(elem)
|
||||||
|
|
||||||
|
list_files = os.listdir(prude_root_path)
|
||||||
|
for ff_file in list_files:
|
||||||
|
if len(ff_file) <= 7 \
|
||||||
|
or ff_file[:7] != ".prude_":
|
||||||
|
continue
|
||||||
|
debug.debug("Load config file:" + os.path.join(prude_root_path,ff_file))
|
||||||
|
data = file_read_data(os.path.join(prude_root_path,ff_file))
|
||||||
|
for elem in data.split("\n"):
|
||||||
|
if elem == "":
|
||||||
|
continue
|
||||||
|
if elem[0] == "#":
|
||||||
|
continue
|
||||||
|
if elem[0] == "!":
|
||||||
|
# specific control check
|
||||||
|
if elem == "!NO_CAPITAL_LETTER":
|
||||||
|
filter_list[0]["check-capital"] = False
|
||||||
|
else:
|
||||||
|
debug.error("unknows parameter: '" + elem + "'")
|
||||||
|
continue
|
||||||
|
if elem[0] == "+":
|
||||||
|
# check the full name:
|
||||||
|
filter_list[1].append(elem[1:])
|
||||||
|
else:
|
||||||
|
filter_list[2].append(elem)
|
||||||
|
debug.verbose("fulllist:" + str(filter_list))
|
||||||
|
return filter_list
|
281
prude/module.py
Normal file
281
prude/module.py
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import copy
|
||||||
|
import inspect
|
||||||
|
import fnmatch
|
||||||
|
import re
|
||||||
|
import difflib
|
||||||
|
# Local import
|
||||||
|
from . import tools
|
||||||
|
from . import debug
|
||||||
|
from . import env
|
||||||
|
from . import english
|
||||||
|
|
||||||
|
generic_cpp_type = [
|
||||||
|
"void",
|
||||||
|
"float",
|
||||||
|
"char",
|
||||||
|
"char32_t",
|
||||||
|
"int",
|
||||||
|
"int8_t",
|
||||||
|
"int16_t",
|
||||||
|
"int32_t",
|
||||||
|
"int64_t",
|
||||||
|
"int128_t",
|
||||||
|
"uint8_t",
|
||||||
|
"uint16_t",
|
||||||
|
"uint32_t",
|
||||||
|
"uint64_t",
|
||||||
|
"uint128_t",
|
||||||
|
"const",
|
||||||
|
"bool",
|
||||||
|
"enum",
|
||||||
|
"class",
|
||||||
|
"namespace",
|
||||||
|
"pragma",
|
||||||
|
"struct",
|
||||||
|
"NULL",
|
||||||
|
"nullptr",
|
||||||
|
"sizeof",
|
||||||
|
# generic names:
|
||||||
|
"openGL",
|
||||||
|
"boolean",
|
||||||
|
"TODO",
|
||||||
|
"todo",
|
||||||
|
"vec2",
|
||||||
|
"vec3",
|
||||||
|
"ivec2",
|
||||||
|
"ivec3",
|
||||||
|
"uvec2",
|
||||||
|
"uvec3",
|
||||||
|
"bvec2",
|
||||||
|
"bvec3",
|
||||||
|
"Edouard",
|
||||||
|
"DUPIN"
|
||||||
|
]
|
||||||
|
|
||||||
|
tolerate_words = [
|
||||||
|
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
|
||||||
|
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
||||||
|
"min", "max", "fifo", "filo", "ascii",
|
||||||
|
# generic variables:
|
||||||
|
"iii", "jjj", "kkk", "xxx", "yyy", "zzz",
|
||||||
|
"tmp", "it", "val", "pos", "nb",
|
||||||
|
|
||||||
|
# classicle programation achronimes:
|
||||||
|
"pc", "cpu", "gpio", "io", "proc", "ctrl", "rx", "tx", "msg", "async", "sync", "ack", "src", "freq",
|
||||||
|
"ui", "params", "ip", "log", "udp", "tcp", "ftp",
|
||||||
|
"unicode", "utf", "xml", "json", "bmp", "jpg", "jpeg", "tga", "gif", "http", "https",
|
||||||
|
"sys", "arg", "args", "argc", "argv", "init", "main", "fnmatch", "env", "len", "desc", "str",
|
||||||
|
"cmd", "dir", "bsy", "id",
|
||||||
|
#classical libraries
|
||||||
|
"lua",
|
||||||
|
|
||||||
|
#dxygen element
|
||||||
|
"param",
|
||||||
|
|
||||||
|
#language word:
|
||||||
|
"ifdef", "ifndef","endif", "elif",
|
||||||
|
|
||||||
|
# licences:
|
||||||
|
"mpl", "bsd", "lgpl", "gpl",
|
||||||
|
|
||||||
|
# units:
|
||||||
|
"hz", "khz", "mhz", "thz",
|
||||||
|
"ms", "us", "ns", "min", "sec",
|
||||||
|
|
||||||
|
# some hewxa values:
|
||||||
|
"xf", "xff", "xfff", "xffff", "xfffff", "xffffff",
|
||||||
|
"xffffffffull",
|
||||||
|
"ll",
|
||||||
|
"xll",
|
||||||
|
#libc funtions
|
||||||
|
"memcpy", "strncpy", "printf", "sprintf", "fopen", "malloc", "calloc", "kalloc",
|
||||||
|
"noinline", "ramtext", "constexpr", "typename", "inline", "memet",
|
||||||
|
]
|
||||||
|
|
||||||
|
application_filter = None
|
||||||
|
|
||||||
|
|
||||||
|
def annalyse(filename):
|
||||||
|
global application_filter
|
||||||
|
debug.info("Annalyse: '" + filename + "'")
|
||||||
|
data = tools.file_read_data(filename)
|
||||||
|
if application_filter == None:
|
||||||
|
application_filter = env.get_local_filter()
|
||||||
|
line_id = 0
|
||||||
|
number_of_error = 0
|
||||||
|
# Annalyse in separate files:
|
||||||
|
for line in data.split("\n"):
|
||||||
|
# replace all \t with a " "
|
||||||
|
line = re.sub(r'\t',
|
||||||
|
r' ',
|
||||||
|
line,
|
||||||
|
flags=re.DOTALL)
|
||||||
|
# remove the hexa string ==> not able to parse it for now ...
|
||||||
|
line = re.sub(r'0(x|X)[0-9a-fA-F]+(ull|ll)?', '', line)
|
||||||
|
line_id += 1
|
||||||
|
if len(line) == 0:
|
||||||
|
continue;
|
||||||
|
debug.verbose(filename + ":" + str(line_id) + " " + line)
|
||||||
|
# List of all word:
|
||||||
|
word_list = []
|
||||||
|
current_word = ""
|
||||||
|
position_in_line = 0
|
||||||
|
start_word_pos = None
|
||||||
|
if len(line) >= 8 \
|
||||||
|
and line[:8] == "#include":
|
||||||
|
# remove include handle ==> this is for later ...
|
||||||
|
continue
|
||||||
|
if len(line) >= 9 \
|
||||||
|
and line[:9] == "# include":
|
||||||
|
# remove include handle ==> this is for later ...
|
||||||
|
continue
|
||||||
|
if len(line) >= 2 \
|
||||||
|
and line[:2] == "#!":
|
||||||
|
# remove include handle ==> this is for later ...
|
||||||
|
continue
|
||||||
|
for elem in line:
|
||||||
|
position_in_line += 1
|
||||||
|
if elem in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:":
|
||||||
|
current_word += elem
|
||||||
|
if start_word_pos == None:
|
||||||
|
start_word_pos = position_in_line
|
||||||
|
# this is to get the last word of the line
|
||||||
|
if position_in_line != len(line):
|
||||||
|
continue
|
||||||
|
if current_word != "":
|
||||||
|
# check if not a current Type:
|
||||||
|
if current_word in generic_cpp_type:
|
||||||
|
word_list.append({
|
||||||
|
"line":line,
|
||||||
|
"line-id":line_id,
|
||||||
|
"pos":start_word_pos,
|
||||||
|
"word":current_word,
|
||||||
|
"word-list":[[0,current_word]],
|
||||||
|
"generic-type":True,
|
||||||
|
"in-namespace":False
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
# separate with camelCase and snake case:
|
||||||
|
under_word_list = []
|
||||||
|
current_sub_word = ""
|
||||||
|
offset_in_word_count = 0
|
||||||
|
offset_in_word = None
|
||||||
|
in_namespace = False
|
||||||
|
if len(current_word.split("::")) >= 2:
|
||||||
|
in_namespace = True
|
||||||
|
for elem_word in current_word:
|
||||||
|
offset_in_word_count += 1
|
||||||
|
if elem_word in "abcdefghijklmnopqrstuvwxyz:":
|
||||||
|
current_sub_word += elem_word
|
||||||
|
if offset_in_word == None:
|
||||||
|
offset_in_word = offset_in_word_count - 1;
|
||||||
|
elif elem_word in "0123456789":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if current_sub_word != "":
|
||||||
|
if elem_word in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||||
|
and current_sub_word[-1] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
while len(current_sub_word) > 0 \
|
||||||
|
and current_sub_word[-1] == ":":
|
||||||
|
current_sub_word = current_sub_word[:-1]
|
||||||
|
if current_sub_word != "":
|
||||||
|
under_word_list.append([offset_in_word,current_sub_word])
|
||||||
|
current_sub_word = ""
|
||||||
|
offset_in_word = None
|
||||||
|
if elem_word != "_":
|
||||||
|
if offset_in_word == None:
|
||||||
|
offset_in_word = offset_in_word_count - 1;
|
||||||
|
current_sub_word += elem_word
|
||||||
|
if current_sub_word != "":
|
||||||
|
while len(current_sub_word) > 0 \
|
||||||
|
and current_sub_word[-1] == ":":
|
||||||
|
current_sub_word = current_sub_word[:-1]
|
||||||
|
if current_sub_word != "":
|
||||||
|
under_word_list.append([offset_in_word,current_sub_word])
|
||||||
|
# add at minimal 1 word...
|
||||||
|
if len(under_word_list) == 0:
|
||||||
|
offset_in_word == 0
|
||||||
|
under_word_list.append([offset_in_word,current_sub_word])
|
||||||
|
word_list.append({
|
||||||
|
"line":line,
|
||||||
|
"line-id":line_id,
|
||||||
|
"pos":start_word_pos,
|
||||||
|
"word":current_word,
|
||||||
|
"word-list":under_word_list,
|
||||||
|
"generic-type":False,
|
||||||
|
"in-namespace":in_namespace
|
||||||
|
})
|
||||||
|
current_word = ""
|
||||||
|
start_word_pos = None
|
||||||
|
|
||||||
|
|
||||||
|
for elem in word_list:
|
||||||
|
debug.extreme_verbose(" " + str(elem["pos"]) + ":" + elem["word"])
|
||||||
|
if len(elem["word-list"]) > 1:
|
||||||
|
for elem_sub in elem["word-list"]:
|
||||||
|
debug.extreme_verbose(" " + str(elem_sub))
|
||||||
|
debug.extreme_verbose(" " + str(elem["pos"]) + "+" + str(elem_sub[0]) + ": " + elem_sub[1])
|
||||||
|
|
||||||
|
# check the files:
|
||||||
|
for elem in word_list:
|
||||||
|
if elem["generic-type"] == True:
|
||||||
|
# nothing to parse ==> language basis...
|
||||||
|
continue
|
||||||
|
if elem["in-namespace"] == True:
|
||||||
|
# nothing to parse ==> parse at the definition...
|
||||||
|
continue
|
||||||
|
if elem["word"] in application_filter[1]:
|
||||||
|
# nothing to parse ==> parse at the definition...
|
||||||
|
debug.extreme_verbose("reject global names " + elem["word"]);
|
||||||
|
continue
|
||||||
|
for elem_sub in elem["word-list"]:
|
||||||
|
if application_filter[0]["check-capital"]:
|
||||||
|
capital = True
|
||||||
|
for elemmm in elem_sub[1]:
|
||||||
|
if elemmm in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
capital = False
|
||||||
|
break
|
||||||
|
if capital == True:
|
||||||
|
continue
|
||||||
|
tmp_elem = elem_sub[1].lower()
|
||||||
|
if len(tmp_elem) == 0 \
|
||||||
|
or tmp_elem == ":" \
|
||||||
|
or tmp_elem == "::":
|
||||||
|
continue
|
||||||
|
if tmp_elem[-1] == ":":
|
||||||
|
if len(tmp_elem) >= 2 \
|
||||||
|
and tmp_elem[-2] == ":":
|
||||||
|
# this is a classicle namespace of C++ ==> just drop it, it might create an error in the namespace declaration
|
||||||
|
continue
|
||||||
|
if tmp_elem in tolerate_words:
|
||||||
|
continue
|
||||||
|
if tmp_elem in application_filter[2]:
|
||||||
|
continue
|
||||||
|
if tmp_elem not in english.list_english_word:
|
||||||
|
number_of_error += 1
|
||||||
|
debug.print_compilator(filename + ":" + str(elem["line-id"]) + ":error: unknown word: '" + tmp_elem + "'")
|
||||||
|
debug.print_compilator(" '" + str(elem["line"]) + "'")
|
||||||
|
debug.print_compilator(" " + " "*(elem["pos"]+elem_sub[0]) + "^")
|
||||||
|
list_of_words = difflib.get_close_matches(tmp_elem, english.list_english_word)
|
||||||
|
if len(list_of_words) != 0:
|
||||||
|
debug.print_compilator(" try: " + str(list_of_words))
|
||||||
|
if number_of_error != 0:
|
||||||
|
debug.warning(filename + " " + str(number_of_error) + " error(s)")
|
||||||
|
return number_of_error
|
||||||
|
|
66
prude/multiprocess.py
Normal file
66
prude/multiprocess.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import shlex
|
||||||
|
# Local import
|
||||||
|
from . import debug
|
||||||
|
from . import tools
|
||||||
|
from . import env
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(cmd_line, store_cmd_line="", store_output_file=""):
|
||||||
|
global error_occured
|
||||||
|
global exit_flag
|
||||||
|
global current_id_execution
|
||||||
|
global error_execution
|
||||||
|
# prepare command line:
|
||||||
|
args = shlex.split(cmd_line)
|
||||||
|
debug.verbose("cmd = " + str(args))
|
||||||
|
try:
|
||||||
|
# create the subprocess
|
||||||
|
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
debug.error("subprocess.CalledProcessError : TODO ...")
|
||||||
|
except:
|
||||||
|
debug.error("Exception on : " + str(args))
|
||||||
|
# launch the subprocess:
|
||||||
|
output, err = p.communicate()
|
||||||
|
if sys.version_info >= (3, 0):
|
||||||
|
output = output.decode("utf-8")
|
||||||
|
err = err.decode("utf-8")
|
||||||
|
# store error if needed:
|
||||||
|
tools.store_warning(store_output_file, output, err)
|
||||||
|
# Check error :
|
||||||
|
if p.returncode == 0:
|
||||||
|
debug.debug(env.print_pretty(cmd_line))
|
||||||
|
if output != "":
|
||||||
|
debug.print_compilator(output)
|
||||||
|
if err != "":
|
||||||
|
debug.print_compilator(err)
|
||||||
|
else:
|
||||||
|
# if No ID : Not in a multiprocess mode ==> just stop here
|
||||||
|
debug.debug(env.print_pretty(cmd_line), force=True)
|
||||||
|
debug.print_compilator(output)
|
||||||
|
debug.print_compilator(err)
|
||||||
|
if p.returncode == 2:
|
||||||
|
debug.error("can not compile file ... [keyboard interrrupt]")
|
||||||
|
else:
|
||||||
|
debug.error("can not compile file ... ret : " + str(p.returncode))
|
||||||
|
debug.verbose("done 3")
|
||||||
|
# write cmd line only after to prevent errors ...
|
||||||
|
tools.store_command(cmd_line, store_cmd_line)
|
||||||
|
|
0
prude/target.py
Normal file
0
prude/target.py
Normal file
305
prude/tools.py
Normal file
305
prude/tools.py
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import errno
|
||||||
|
import fnmatch
|
||||||
|
import stat
|
||||||
|
# Local import
|
||||||
|
from . import debug
|
||||||
|
from . import env
|
||||||
|
|
||||||
|
def get_run_path():
|
||||||
|
return os.getcwd()
|
||||||
|
|
||||||
|
def get_current_path(file):
|
||||||
|
return os.path.dirname(os.path.realpath(file))
|
||||||
|
|
||||||
|
def create_directory_of_file(file):
|
||||||
|
path = os.path.dirname(file)
|
||||||
|
try:
|
||||||
|
os.stat(path)
|
||||||
|
except:
|
||||||
|
os.makedirs(path)
|
||||||
|
|
||||||
|
def get_list_sub_path(path):
|
||||||
|
# TODO : os.listdir(path)
|
||||||
|
for dirname, dirnames, filenames in os.walk(path):
|
||||||
|
return dirnames
|
||||||
|
return []
|
||||||
|
|
||||||
|
def remove_path_and_sub_path(path):
|
||||||
|
if os.path.isdir(path):
|
||||||
|
debug.verbose("remove path : '" + path + "'")
|
||||||
|
shutil.rmtree(path)
|
||||||
|
|
||||||
|
def remove_file(path):
|
||||||
|
if os.path.isfile(path):
|
||||||
|
os.remove(path)
|
||||||
|
elif os.path.islink(path):
|
||||||
|
os.remove(path)
|
||||||
|
|
||||||
|
def file_size(path):
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
return 0
|
||||||
|
statinfo = os.stat(path)
|
||||||
|
return statinfo.st_size
|
||||||
|
|
||||||
|
def file_read_data(path, binary=False):
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
return ""
|
||||||
|
if binary == True:
|
||||||
|
file = open(path, "rb")
|
||||||
|
else:
|
||||||
|
file = open(path, "r")
|
||||||
|
data_file = file.read()
|
||||||
|
file.close()
|
||||||
|
return data_file
|
||||||
|
|
||||||
|
def version_to_string(version):
|
||||||
|
version_ID = ""
|
||||||
|
for id in version:
|
||||||
|
if len(version_ID) != 0:
|
||||||
|
if type(id) == str:
|
||||||
|
version_ID += "-"
|
||||||
|
else:
|
||||||
|
version_ID += "."
|
||||||
|
version_ID += str(id)
|
||||||
|
return version_ID
|
||||||
|
|
||||||
|
##
|
||||||
|
## @brief Write data in a specific path.
|
||||||
|
## @param[in] path Path of the data might be written.
|
||||||
|
## @param[in] data Data To write in the file.
|
||||||
|
## @param[in] only_if_new (default: False) Write data only if data is different.
|
||||||
|
## @return True Something has been copied
|
||||||
|
## @return False Nothing has been copied
|
||||||
|
##
|
||||||
|
def file_write_data(path, data, only_if_new=False):
|
||||||
|
if only_if_new == True:
|
||||||
|
old_data = file_read_data(path)
|
||||||
|
if old_data == data:
|
||||||
|
return False
|
||||||
|
#real write of data:
|
||||||
|
create_directory_of_file(path)
|
||||||
|
file = open(path, "w")
|
||||||
|
file.write(data)
|
||||||
|
file.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def list_to_str(list):
|
||||||
|
if type(list) == type(str()):
|
||||||
|
return list + " "
|
||||||
|
else:
|
||||||
|
result = ""
|
||||||
|
# mulyiple imput in the list ...
|
||||||
|
for elem in list:
|
||||||
|
result += list_to_str(elem)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def add_prefix(prefix,list):
|
||||||
|
if type(list) == type(None):
|
||||||
|
return ""
|
||||||
|
if type(list) == type(str()):
|
||||||
|
return prefix+list
|
||||||
|
else:
|
||||||
|
if len(list)==0:
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
result=[]
|
||||||
|
for elem in list:
|
||||||
|
result.append(prefix+elem)
|
||||||
|
return result
|
||||||
|
|
||||||
|
##
|
||||||
|
## @brief Clean a path from all un-needed element in a directory
|
||||||
|
## @param[in] path Path to clean
|
||||||
|
## @param[in] normal_list List of all files/path in the path
|
||||||
|
## @return True Something has been removed
|
||||||
|
## @return False Nothing has been removed
|
||||||
|
##
|
||||||
|
def clean_directory(path, normal_list):
|
||||||
|
has_file_removed = False
|
||||||
|
# get a list of all element in the path:
|
||||||
|
for root, dirnames, filenames in os.walk(path):
|
||||||
|
for file in filenames:
|
||||||
|
file_name = os.path.join(root, file)
|
||||||
|
if file_name not in normal_list:
|
||||||
|
debug.print_element("remove file ", os.path.relpath(file_name), "==>", "---")
|
||||||
|
os.remove(file_name)
|
||||||
|
has_file_removed = True
|
||||||
|
return has_file_removed
|
||||||
|
|
||||||
|
def filter_extention(list_files, extentions, invert=False):
|
||||||
|
out = []
|
||||||
|
for file in list_files:
|
||||||
|
in_list = False
|
||||||
|
for ext in extentions:
|
||||||
|
if file[-len(ext):] == ext:
|
||||||
|
in_list = True
|
||||||
|
if in_list == True \
|
||||||
|
and invert == False:
|
||||||
|
out.append(file)
|
||||||
|
elif in_list == False \
|
||||||
|
and invert == True:
|
||||||
|
out.append(file)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def move_if_needed(src, dst):
|
||||||
|
if not os.path.isfile(src):
|
||||||
|
debug.error("request move if needed, but file does not exist: '" + str(src) + "' to '" + str(dst) + "'")
|
||||||
|
return
|
||||||
|
src_data = file_read_data(src)
|
||||||
|
if os.path.isfile(dst):
|
||||||
|
# file exist ==> must check ...
|
||||||
|
dst_data = file_read_data(dst)
|
||||||
|
if src_data == dst_data:
|
||||||
|
# nothing to do ...
|
||||||
|
return
|
||||||
|
file_write_data(dst, src_data)
|
||||||
|
remove_file(src)
|
||||||
|
|
||||||
|
def store_command(cmd_line, file):
|
||||||
|
# write cmd line only after to prevent errors ...
|
||||||
|
if file == "" \
|
||||||
|
or file == None:
|
||||||
|
return;
|
||||||
|
debug.verbose("create cmd file: " + file)
|
||||||
|
# Create directory:
|
||||||
|
create_directory_of_file(file)
|
||||||
|
# Store the command Line:
|
||||||
|
file2 = open(file, "w")
|
||||||
|
file2.write(cmd_line)
|
||||||
|
file2.flush()
|
||||||
|
file2.close()
|
||||||
|
|
||||||
|
def store_warning(file, output, err):
|
||||||
|
# write warning line only after to prevent errors ...
|
||||||
|
if file == "" \
|
||||||
|
or file == None:
|
||||||
|
return;
|
||||||
|
if env.get_warning_mode() == False:
|
||||||
|
debug.verbose("remove warning file: " + file)
|
||||||
|
# remove file if exist...
|
||||||
|
remove_file(file);
|
||||||
|
return;
|
||||||
|
debug.verbose("create warning file: " + file)
|
||||||
|
# Create directory:
|
||||||
|
create_directory_of_file(file)
|
||||||
|
# Store the command Line:
|
||||||
|
file2 = open(file, "w")
|
||||||
|
file2.write("===== output =====\n")
|
||||||
|
file2.write(output)
|
||||||
|
file2.write("\n\n")
|
||||||
|
file2.write("===== error =====\n")
|
||||||
|
file2.write(err)
|
||||||
|
file2.write("\n\n")
|
||||||
|
file2.flush()
|
||||||
|
file2.close()
|
||||||
|
|
||||||
|
|
||||||
|
## List tools:
|
||||||
|
def list_append_and_check(listout, newElement, order):
|
||||||
|
for element in listout:
|
||||||
|
if element==newElement:
|
||||||
|
return
|
||||||
|
listout.append(newElement)
|
||||||
|
if order == True:
|
||||||
|
if type(newElement) is not dict:
|
||||||
|
listout.sort()
|
||||||
|
|
||||||
|
def list_append_to(out_list, in_list, order=False):
|
||||||
|
if type(in_list) == str:
|
||||||
|
list_append_and_check(out_list, in_list, order)
|
||||||
|
elif type(in_list) == list:
|
||||||
|
# mulyiple imput in the list ...
|
||||||
|
for elem in in_list:
|
||||||
|
list_append_and_check(out_list, elem, order)
|
||||||
|
elif type(in_list) == dict:
|
||||||
|
list_append_and_check(out_list, in_list, order)
|
||||||
|
else:
|
||||||
|
debug.warning("can not add in list other than {list/dict/str} : " + str(type(in_list)))
|
||||||
|
|
||||||
|
def list_append_to_2(listout, module, list, order=False):
|
||||||
|
# sepcial cse of bool
|
||||||
|
if type(list) == bool:
|
||||||
|
listout[module] = list
|
||||||
|
return
|
||||||
|
# add list in the Map
|
||||||
|
if module not in listout:
|
||||||
|
listout[module] = []
|
||||||
|
# add elements...
|
||||||
|
list_append_to(listout[module], list, order)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## @brief The vertion number can be set in an external file to permit to have a singe position to change when create a vew version
|
||||||
|
## @param[in] path_module (string) Path of the module position
|
||||||
|
## @param[in] filename_or_version (string or list) Path of the version or the real version lint parameter
|
||||||
|
## @return (list) List of version number
|
||||||
|
##
|
||||||
|
def get_version_from_file_or_direct(path_module, filename_or_version):
|
||||||
|
# check case of iser set the version directly
|
||||||
|
if type(filename_or_version) == list:
|
||||||
|
return filename_or_version
|
||||||
|
# this use a version file
|
||||||
|
file_data = file_read_data(os.path.join(path_module, filename_or_version))
|
||||||
|
if len(file_data) == 0:
|
||||||
|
debug.warning("not enought data in the file version size=0 " + path_module + " / " + filename_or_version)
|
||||||
|
return [0,0,0]
|
||||||
|
lines = file_data.split("\n")
|
||||||
|
if len(lines) != 1:
|
||||||
|
debug.warning("More thatn one line in the file version ==> bas case use mode: 'XX', XX.YYY', 'XX.Y.ZZZ' or 'XX.Y-dev' : " + path_module + " / " + filename_or_version)
|
||||||
|
return [0,0,0]
|
||||||
|
line = lines[0]
|
||||||
|
debug.debug("Parse line: '" + line + "'")
|
||||||
|
#check if we have "-dev"
|
||||||
|
dev_mode = False
|
||||||
|
if line[-4:] == "-dev":
|
||||||
|
dev_mode = True
|
||||||
|
line = line[:-4]
|
||||||
|
out = []
|
||||||
|
list_elem = line.split('.')
|
||||||
|
for elem in list_elem:
|
||||||
|
out.append(int(elem))
|
||||||
|
if dev_mode == True:
|
||||||
|
out.append("dev")
|
||||||
|
debug.debug(" ==> " + str(out))
|
||||||
|
return out
|
||||||
|
|
||||||
|
##
|
||||||
|
## @brief Get the list of the authors frim an input list or a file
|
||||||
|
## @param[in] path_module (string) Path of the module position
|
||||||
|
## @param[in] filename_or_version (string or list) Path of the author file or the real list of authors
|
||||||
|
## @return (list) List of authors
|
||||||
|
##
|
||||||
|
def get_maintainer_from_file_or_direct(path_module, filename_or_author):
|
||||||
|
# check case of iser set the version directly
|
||||||
|
if type(filename_or_author) == list:
|
||||||
|
return filename_or_author
|
||||||
|
# this use a version file
|
||||||
|
file_data = file_read_data(os.path.join(path_module, filename_or_author))
|
||||||
|
if len(file_data) == 0:
|
||||||
|
debug.warning("not enought data in the file author size=0 " + path_module + " / " + filename_or_author)
|
||||||
|
return []
|
||||||
|
# One user by line and # for comment line
|
||||||
|
out = []
|
||||||
|
for elem in file_data.split('\n'):
|
||||||
|
if len(elem) == 0:
|
||||||
|
continue
|
||||||
|
if elem[0] == "#":
|
||||||
|
# comment ...
|
||||||
|
continue
|
||||||
|
out.append(elem)
|
||||||
|
return out
|
||||||
|
|
45
setup.py
Executable file
45
setup.py
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license APACHE v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
def readme():
|
||||||
|
with open('README.rst') as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||||
|
setup(name='prude',
|
||||||
|
version='0.2.0',
|
||||||
|
description='Prude is a simple parser thacj check word error (CamelCase and snake_case)',
|
||||||
|
long_description=readme(),
|
||||||
|
url='http://github.com/HeeroYui/prude',
|
||||||
|
author='Edouard DUPIN',
|
||||||
|
author_email='yui.heero@gmail.com',
|
||||||
|
license='APACHE-2',
|
||||||
|
packages=['prude'],
|
||||||
|
classifiers=[
|
||||||
|
'Development Status :: 4 - Beta',
|
||||||
|
'License :: OSI Approved :: Apache Software License',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Topic :: Software Development :: Compilers',
|
||||||
|
],
|
||||||
|
keywords='documentation over doxygen',
|
||||||
|
scripts=['bin/prude'],
|
||||||
|
# Does not work on MacOs
|
||||||
|
#data_file=[
|
||||||
|
# ('/etc/bash_completion.d', ['bash-autocompletion/lutin']),
|
||||||
|
#],
|
||||||
|
include_package_data = True,
|
||||||
|
zip_safe=False)
|
||||||
|
|
||||||
|
#To developp: sudo ./setup.py install
|
||||||
|
# sudo ./setup.py develop
|
||||||
|
#TO register all in pip: ./setup.py register sdist upload
|
||||||
|
|
Loading…
Reference in New Issue
Block a user