[DEV] correct some parsing, add separate of internal valiable and correct : at end of element

This commit is contained in:
Edouard DUPIN 2017-08-18 01:37:01 +02:00
parent 9bd3e16588
commit b3a3c82d75
12 changed files with 575 additions and 718 deletions

View File

@ -1,2 +1 @@
include README.rst
include bash-autocompletion/monk

View File

@ -1,7 +1,7 @@
Prude
=====
`prude` is a generic C++ annalysing code to check language error (english).
`prude` is a generic code annalyser to check ```language``` error. The ```language``` check is the english.
.. image:: https://badge.fury.io/py/prude.png
@ -14,45 +14,16 @@ Release (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.
This is a tool to annalyse C, C++ file and determine if it have some english word that does not exist.
Prude is under a FREE license that can be found in the COPYING file.
@ -63,11 +34,6 @@ git repository
http://github.com/HeeroYui/prude/
Documentation
-------------
http://github.io/HeeroYui/prude/
Installation
------------
@ -89,6 +55,72 @@ Install pip on MacOs:
sudo easy_install pip
developpement for prude:
git clone http://github.com/HeeroYui/prude/
cd prude
./setup.py develop --user
Documentation
-------------
Usage
******
Go to your coding directory and execute:
prude yourFileToParce.cpp
# OR (multiple files)
prude yourFileToParce.cpp other_file.py and.txt
# simply the path
prude .
You can use some options:
--color/-C to have beautifull color check
--recursive/-r Parse all under directories
Create exceptions:
******************
prude parse all upper folder to find all file ".prude_*" and add it in the list of exceptions error.
The search end when find the file ".prude".
you can have:
root_path
--> .prude
--> .prude_lua
--> .prude_tinyxml
--> module
--> submodule
--> .prude_local
--> .prude_local2
--> my_file_cpp.cpp
--> sub_second
--> file_c.c
The check of the file ```my_file_cpp.cpp``` use all the .prude* file and the file ```file_c.c``` only use the file on the root_path
A prude file is contituated like:
* ```#``` Comment the line
* ```+``` Use the end of the line to check the exact match of the string (ex: +MY_VariableStupidName)
* direct element is use to comare each word in lower case to exclude error on it (ex: destructor)
* ```!``` Command to apply at the configuration.
- ```!NO_CAPITAL_LETTER``` ==> disable the check of the word in capital letter
- ```!CAPITAL_LETTER``` ==> enable the check of the word in capital letter (default)
Some tricky things (removed because it is errored at the declaration and no more need in library using it):
* The namespace call are disable (ex namespace::prout)
* The parameter access are disable (ex: variable.hello() or variable->hello())
* The "#include ..." and the "# include ..."
Now you can play.
Note: in the http://github.com/HeeroYui/prude/common/ you have some common C library that declare stupid thing in global...
License (APACHE v2.0)
---------------------

144
bin/prude
View File

@ -1,148 +1,6 @@
#!/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;
summary = []
# 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;
if os.path.isfile(argument_value) == True:
# Single file:
tmp_count_error = module.annalyse(argument_value)
summary.append([argument_value, tmp_count_error])
number_of_error += tmp_count_error
else:
# a full path
list_files = os.listdir(argument_value)
real_list = []
for ff_file in list_files:
if os.path.isfile(os.path.join(argument_value,ff_file)) == False:
continue
if len(ff_file) > 3 \
and ( ff_file[-4:].lower() == ".cpp" \
or ff_file[-4:].lower() == ".hpp" \
or ff_file[-4:].lower() == ".c++" \
or ff_file[-2:].lower() == ".c" \
or ff_file[-4:].lower() == ".h++" \
or ff_file[-2:].lower() == ".h" \
or ff_file[-3:].lower() == ".hh" \
or ff_file[-3:].lower() == ".cc" \
or ff_file[-3:].lower() == ".py" \
or ff_file[-4:].lower() == ".lua" \
or ff_file[-3:].lower() == ".md"):
real_list.append(os.path.join(argument_value,ff_file))
# sort list to have all time the same order.
real_list.sort()
# TODO: Add filter if needed.
for ff_file in real_list:
debug.info("-----------------------------------------------")
tmp_count_error = module.annalyse(ff_file)
summary.append([ff_file, tmp_count_error])
number_of_error += tmp_count_error
actionDone = True
# if no action done : we do "all" ...
if actionDone == False:
usage()
exit(-1)
if number_of_error != 0:
debug.info("Detected " + str(number_of_error) + " ERROR(s) on " + str(len(summary)) + " files")
for elem in summary:
if elem[1] != 0:
debug.info(elem[0] + "\r\t\t\t\t\t\t [ERROR] " + str(elem[1]))
else:
debug.info(elem[0] + "\r\t\t\t\t\t\t [ OK ]")
exit(-1);
debug.info("[ OK ]")
exit(0);
import prude

152
common/.prude_lua Normal file
View File

@ -0,0 +1,152 @@
# This file is for prude parsing (must start with .prude_* or project file .prude)
# some possibiliries:
# - Check the compleate name with case sensitive [a-zA-Z0-9_] ==> to ignore it. format +ABC_def
# - not case-sensitive separate word camel-case and snake-case (set direct word)
# - with # simple comment
# - start with ! for global parameter
+LUA_NOREF
+LUA_REGISTRYINDEX
+LUA_GCCOLLECT
luaref
userdata
+lua_Alloc
+lua_atpanic
+lua_call
+lua_CFunction
+lua_checkstack
+lua_close
+lua_concat
+lua_cpcall
+lua_createtable
+lua_dump
+lua_equal
+lua_error
+lua_gc
+lua_getallocf
+lua_getfenv
+lua_getfield
+lua_getglobal
+lua_getmetatable
+lua_gettable
+lua_gettop
+lua_insert
+lua_Integer
+lua_isboolean
+lua_iscfunction
+lua_isfunction
+lua_islightuserdata
+lua_isnil
+lua_isnone
+lua_isnoneornil
+lua_isnumber
+lua_isstring
+lua_istable
+lua_isthread
+lua_isuserdata
+lua_lessthan
+lua_load
+lua_newstate
+lua_newtable
+lua_newthread
+lua_newuserdata
+lua_next
+lua_Number
+lua_objlen
+lua_pcall
+lua_pop
+lua_pushboolean
+lua_pushcclosure
+lua_pushcfunction
+lua_pushfstring
+lua_pushinteger
+lua_pushlightuserdata
+lua_pushliteral
+lua_pushlstring
+lua_pushnil
+lua_pushnumber
+lua_pushstring
+lua_pushthread
+lua_pushvalue
+lua_pushvfstring
+lua_rawequal
+lua_rawget
+lua_rawgeti
+lua_rawset
+lua_rawseti
+lua_Reader
+lua_register
+lua_remove
+lua_replace
+lua_resume
+lua_setallocf
+lua_setfenv
+lua_setfield
+lua_setglobal
+lua_setmetatable
+lua_settable
+lua_settop
+lua_State
+lua_status
+lua_toboolean
+lua_tocfunction
+lua_tointeger
+lua_tolstring
+lua_tonumber
+lua_topointer
+lua_tostring
+lua_tothread
+lua_touserdata
+lua_type
+lua_typename
+lua_Writer
+lua_xmove
+lua_yield
+luaL_addchar
+luaL_addlstring
+luaL_addsize
+luaL_addstring
+luaL_addvalue
+luaL_argcheck
+luaL_argerror
+luaL_Buffer
+luaL_buffinit
+luaL_callmeta
+luaL_checkany
+luaL_checkint
+luaL_checkinteger
+luaL_checklong
+luaL_checklstring
+luaL_checknumber
+luaL_checkoption
+luaL_checkstack
+luaL_checkstring
+luaL_checktype
+luaL_checkudata
+luaL_dofile
+luaL_dostring
+luaL_error
+luaL_getmetafield
+luaL_getmetatable
+luaL_gsub
+luaL_loadbuffer
+luaL_loadfile
+luaL_loadstring
+luaL_newmetatable
+luaL_newstate
+luaL_openlibs
+luaL_optint
+luaL_optinteger
+luaL_optlong
+luaL_optlstring
+luaL_optnumber
+luaL_optstring
+luaL_prepbuffer
+luaL_pushresult
+luaL_ref
+luaL_Reg
+luaL_register
+luaL_typename
+luaL_typerror
+luaL_unref
+luaL_where

View File

@ -3,24 +3,162 @@
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
## @copyright 2017, 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
import copy
from . import debug
from . import module
from . import arg as arguments
from . import env
is_init = False
from . import tools
from . import module
def init():
global is_init;
if is_init == True:
return
myArgs = arguments.doxyArg()
myArgs.add(arguments.ArgDefine("h", "help", desc="Display this help"))
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(arguments.ArgDefine("r", "recursive", desc="Recursive check of the paths"))
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
recursive = 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
elif argument.get_option_name() == "recursive":
if active==False:
recursive = 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)
actionDone = False;
summary = []
def recursive_get(path):
out = []
for root, directories, filenames in os.walk(path):
for filename in filenames:
#debug.info(os.path.join(root,filename))
if len(filename) > 2 \
and ( ff_file[-3:].lower() == ".d" \
or ff_file[-3:].lower() == ".o"):
pass
else:
out.append(os.path.join(root,filename))
for dir in directories:
tmp = recursive_get(os.path.join(root,dir))
for elem in tmp:
out.append(elem)
return out
# 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;
if os.path.isfile(argument_value) == True:
# Single file:
tmp_count_error = module.annalyse(argument_value)
summary.append([argument_value, tmp_count_error])
number_of_error += tmp_count_error
else:
# a full path
if recursive == True:
list_files = os.listdir(argument_value)
else:
list_files = recursive_get(argument_value)
real_list = []
for ff_file in list_files:
if os.path.isfile(os.path.join(argument_value,ff_file)) == False:
continue
if len(ff_file) > 3 \
and ( ff_file[-4:].lower() == ".cpp" \
or ff_file[-4:].lower() == ".hpp" \
or ff_file[-4:].lower() == ".c++" \
or ff_file[-2:].lower() == ".c" \
or ff_file[-4:].lower() == ".h++" \
or ff_file[-2:].lower() == ".h" \
or ff_file[-3:].lower() == ".hh" \
or ff_file[-3:].lower() == ".cc" \
or ff_file[-3:].lower() == ".py" \
or ff_file[-4:].lower() == ".lua" \
or ff_file[-3:].lower() == ".md"):
real_list.append(os.path.join(argument_value,ff_file))
# sort list to have all time the same order.
real_list.sort()
# TODO: Add filter if needed.
for ff_file in real_list:
debug.info("-----------------------------------------------")
tmp_count_error = module.annalyse(ff_file)
summary.append([ff_file, tmp_count_error])
number_of_error += tmp_count_error
actionDone = True
# if no action done : we do "all" ...
if actionDone == False:
usage()
exit(-1)
if number_of_error != 0:
debug.info("Detected " + str(number_of_error) + " ERROR(s) on " + str(len(summary)) + " files")
for elem in summary:
if elem[1] != 0:
debug.info(elem[0] + "\r\t\t\t\t\t\t [ERROR] " + str(elem[1]))
else:
debug.info(elem[0] + "\r\t\t\t\t\t\t [ OK ]")
exit(-1);
debug.info("[ OK ]")
exit(0);

View File

@ -9,7 +9,6 @@
##
import os
import threading
import re
debug_level=3
@ -23,9 +22,6 @@ color_blue = ""
color_purple = ""
color_cyan = ""
debug_lock = threading.Lock()
def set_level(id):
global debug_level
debug_level = id
@ -72,82 +68,57 @@ def disable_color():
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')
@ -157,10 +128,7 @@ def print_compilator(myString):
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

View File

@ -3,7 +3,7 @@
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
## @copyright 2017, Edouard DUPIN, all right reserved
##
## @license APACHE v2.0 (see license file)
##
@ -12,22 +12,6 @@
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):
@ -40,30 +24,6 @@ def get_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 ""
@ -72,15 +32,19 @@ def file_read_data(path):
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 []
def read_file_property(folder):
# 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())
list_files = os.listdir(folder)
for ff_file in list_files:
if ( len(ff_file) >= 7 \
and ff_file[:7] == ".prude_") \
or ff_file == ".prude":
pass
else:
continue
debug.debug("Load config file:" + os.path.join(folder,ff_file))
data = file_read_data(os.path.join(prude_root_path,ff_file))
for elem in data.split("\n"):
if elem == "":
continue
@ -100,30 +64,38 @@ def get_local_filter():
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
def get_local_filter(path_to_search):
path_to_search = os.path.join(os.getcwd(), path_to_search)
if os.path.exists(path_to_search) == False:
return []
# parse the global .prude file
filter_list = [{"check-capital":True}, [], []]
current_path = path_to_search
while current_path != "/":
list_files = os.listdir(current_path)
debug.debug("read path: " + current_path)
tmp_value = read_file_property(current_path)
for key in tmp_value[0]:
filter_list[0][key] = tmp_value[0][key]
for elem in tmp_value[1]:
if elem not in filter_list[1]:
filter_list[1].append(elem)
for elem in tmp_value[2]:
if elem not in filter_list[2]:
filter_list[2].append(elem.lower())
if os.path.exists(os.path.join(current_path, ".prude")) == True:
debug.debug("fulllist:" + str(filter_list))
return filter_list
current_path = os.path.dirname(current_path)
debug.debug("fulllist (root):" + str(filter_list))
return filter_list

View File

@ -3,7 +3,7 @@
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
## @copyright 2017, Edouard DUPIN, all right reserved
##
## @license APACHE v2.0 (see license file)
##
@ -103,24 +103,119 @@ tolerate_words = [
"ll",
"xll",
#libc funtions
"memcpy", "strncpy", "printf", "sprintf", "fopen", "malloc", "calloc", "kalloc",
"memcpy", "strncpy", "printf", "sprintf", "fopen", "malloc", "calloc", "kalloc", "realloc",
"noinline", "ramtext", "constexpr", "typename", "inline", "memset", "getchar", "putchar",
"fread", "fwrite", "gets", "puts",
"fread", "fwrite", "gets", "puts", "memmove", "iterator",
#pb with number parsing:
"ull",
]
application_filter = None
previous_sugestion = {}
def add_word(current_word, line, line_id, start_word_pos):
#remove end char: - . ->
while True:
if len(current_word) > 1 \
and current_word[-1] == ':' \
and current_word[-2] != ':':
current_word = current_word[:-1]
continue
if len(current_word) > 1 \
and current_word[-1] == '>' \
and current_word[-2] == '-':
current_word = current_word[:-2]
continue
while len(current_word) > 0 \
and current_word[-1] == '.':
current_word = current_word[:-1]
continue
while len(current_word) > 0 \
and current_word[-1] == '-':
current_word = current_word[:-1]
continue
break
tmp = re.sub(r'0(x|X)[0-9a-fA-F]+(ull|ll)?', '', current_word)
if tmp != current_word:
is_a_number = True
else:
is_a_number = False
# check if not a current Type:
if current_word in generic_cpp_type:
return {
"line":line,
"line-id":line_id,
"pos":start_word_pos,
"word":current_word,
"word-list":[[0,current_word]],
"generic-type":True,
"in-namespace":False,
"number":is_a_number
}
# 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
if len(current_word.split("->")) >= 2:
in_namespace = True
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])
return {
"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,
"number":is_a_number
}
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()
application_filter = env.get_local_filter(os.path.dirname(filename))
line_id = 0
number_of_error = 0
# Annalyse in separate files:
@ -131,7 +226,7 @@ def annalyse(filename):
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 = re.sub(r'0(x|X)[0-9a-fA-F]+(ull|ll)?', '', line)
line_id += 1
if len(line) == 0:
continue;
@ -153,9 +248,33 @@ def annalyse(filename):
and line[:2] == "#!":
# remove include handle ==> this is for later ...
continue
have_special_char = False
for elem in line:
position_in_line += 1
if elem in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:":
if elem in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_":
if current_word != "" \
and current_word[-1] == '-':
word_list.append(add_word(current_word, line, line_id, start_word_pos))
current_word = ""
start_word_pos = None
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 elem == '>':
#Special multiple word element...
if current_word != "" \
and current_word[-1] == '-':
current_word += elem
else:
continue
if position_in_line != len(line):
continue
if elem in ":.-":
#Special multiple word element...
have_special_char = True
current_word += elem
if start_word_pos == None:
start_word_pos = position_in_line
@ -163,76 +282,13 @@ def annalyse(filename):
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
})
word_list.append(add_word(current_word, line, line_id, start_word_pos))
current_word = ""
start_word_pos = None
for elem in word_list:
debug.extreme_verbose(" " + str(elem["pos"]) + ":" + elem["word"])
debug.debug(" " + str(elem["pos"]) + ":" + elem["word"])
if len(elem["word-list"]) > 1:
for elem_sub in elem["word-list"]:
debug.extreme_verbose(" " + str(elem_sub))
@ -246,6 +302,9 @@ def annalyse(filename):
if elem["in-namespace"] == True:
# nothing to parse ==> parse at the definition...
continue
if elem["number"] == 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"]);

View File

@ -1,66 +0,0 @@
#!/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)

View File

View File

@ -9,49 +9,6 @@
##
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):
@ -64,242 +21,4 @@ def file_read_data(path, binary=False):
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

26
test/the_test_cpp.cpp Normal file
View File

@ -0,0 +1,26 @@
uint32_t hello
// Stipd comment
::global_name_space();
etk::nameFunction();
prout->call()
prout.call()
prout::call()
call-0x1562
call.
call-
call->
call:
bool:
0x1524 0x5847894ull