diff --git a/cppParser/Class.py b/cppParser/Class.py new file mode 100644 index 0000000..755bdfb --- /dev/null +++ b/cppParser/Class.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re +import Node +import lutinDebug as debug + +import inspect + +class Class(Node.Node): + def __init__(self): + + # List of the class name (with their namespace : [['ewol','widget','plop'], ...]) + self.parents = [] + + # CPP section: + self.namespaces = [] + self.classes = [] + # C section: + self.structs = [] + self.variables = [] + self.methodes = [] + self.unions = [] + self.types = [] + + + + def to_str(self): + return "" + + + diff --git a/cppParser/CppHeaderParser/CppHeaderParser3.py b/cppParser/CppHeaderParser/CppHeaderParser3.py deleted file mode 100644 index 54d3a25..0000000 --- a/cppParser/CppHeaderParser/CppHeaderParser3.py +++ /dev/null @@ -1,2407 +0,0 @@ -#!/usr/bin/python -# -# Author: Jashua R. Cloutier (contact via https://bitbucket.org/senex) -# Project: http://senexcanis.com/open-source/cppheaderparser/ -# -# Copyright (C) 2011, Jashua R. Cloutier -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * Neither the name of Jashua R. Cloutier nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. Stories, -# blog entries etc making reference to this project may mention the -# name Jashua R. Cloutier in terms of project originator/creator etc. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# -# The CppHeaderParser.py script is written in Python 2.4 and released to -# the open source community for continuous improvements under the BSD -# 2.0 new license, which can be found at: -# -# http://www.opensource.org/licenses/bsd-license.php -# -"""Parse C++ header files and generate a data structure -representing the class -""" - -import ply.lex as lex -import os -import sys -import re - -import inspect - -def lineno(): - """Returns the current line number in our program.""" - return inspect.currentframe().f_back.f_lineno - -version = __version__ = "2.4" - -tokens = [ - 'NUMBER', - 'NAME', - 'OPEN_PAREN', - 'CLOSE_PAREN', - 'OPEN_BRACE', - 'CLOSE_BRACE', - 'OPEN_SQUARE_BRACKET', - 'CLOSE_SQUARE_BRACKET', - 'COLON', - 'SEMI_COLON', - 'COMMA', - 'TAB', - 'BACKSLASH', - 'PIPE', - 'PERCENT', - 'EXCLAMATION', - 'CARET', - 'COMMENT_SINGLELINE', - 'COMMENT_MULTILINE', - 'PRECOMP_MACRO', - 'PRECOMP_MACRO_CONT', - 'ASTERISK', - 'AMPERSTAND', - 'EQUALS', - 'MINUS', - 'PLUS', - 'DIVIDE', - 'CHAR_LITERAL', - 'STRING_LITERAL', - 'NEW_LINE', - 'SQUOTE', -] - -t_ignore = " \r.?@\f" -t_NUMBER = r'[0-9][0-9XxA-Fa-f]*' -t_NAME = r'[<>A-Za-z_~][A-Za-z0-9_]*' -t_OPEN_PAREN = r'\(' -t_CLOSE_PAREN = r'\)' -t_OPEN_BRACE = r'{' -t_CLOSE_BRACE = r'}' -t_OPEN_SQUARE_BRACKET = r'\[' -t_CLOSE_SQUARE_BRACKET = r'\]' -t_SEMI_COLON = r';' -t_COLON = r':' -t_COMMA = r',' -t_TAB = r'\t' -t_BACKSLASH = r'\\' -t_PIPE = r'\|' -t_PERCENT = r'%' -t_CARET = r'\^' -t_EXCLAMATION = r'!' -t_PRECOMP_MACRO = r'\#.*' -t_PRECOMP_MACRO_CONT = r'.*\\\n' -def t_COMMENT_SINGLELINE(t): - r'\/\/.*\n' - global doxygenCommentCache - if t.value.startswith("///") or t.value.startswith("//!"): - if doxygenCommentCache: - doxygenCommentCache += "\n" - if t.value.endswith("\n"): - doxygenCommentCache += t.value[:-1] - else: - doxygenCommentCache += t.value - t.lexer.lineno += len([a for a in t.value if a=="\n"]) -t_ASTERISK = r'\*' -t_MINUS = r'\-' -t_PLUS = r'\+' -t_DIVIDE = r'/(?!/)' -t_AMPERSTAND = r'&' -t_EQUALS = r'=' -t_CHAR_LITERAL = "'.'" -t_SQUOTE = "'" -#found at http://wordaligned.org/articles/string-literals-and-regular-expressions -#TODO: This does not work with the string "bla \" bla" -t_STRING_LITERAL = r'"([^"\\]|\\.)*"' -#Found at http://ostermiller.org/findcomment.html -def t_COMMENT_MULTILINE(t): - r'/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/' - global doxygenCommentCache - if t.value.startswith("/**") or t.value.startswith("/*!"): - #not sure why, but get double new lines - v = t.value.replace("\n\n", "\n") - #strip prefixing whitespace - v = re.sub("\n[\s]+\*", "\n*", v) - doxygenCommentCache += v - t.lexer.lineno += len([a for a in t.value if a=="\n"]) -def t_NEWLINE(t): - r'\n+' - t.lexer.lineno += len(t.value) - -def t_error(v): - print(( "Lex error: ", v )) - -lex.lex() -# Controls error_print -print_errors = 1 -# Controls warning_print -print_warnings = 1 -# Controls debug_print -debug = 0 -# Controls trace_print -debug_trace = 0 - -def error_print(arg): - if print_errors: print(("[%4d] %s"%(inspect.currentframe().f_back.f_lineno, arg))) - -def warning_print(arg): - if print_warnings: print(("[%4d] %s"%(inspect.currentframe().f_back.f_lineno, arg))) - -def debug_print(arg): - global debug - if debug: print(("[%4d] %s"%(inspect.currentframe().f_back.f_lineno, arg))) - -def trace_print(*arg): - global debug_trace - if debug_trace: - sys.stdout.write("[%s] "%(inspect.currentframe().f_back.f_lineno)) - for a in arg: sys.stdout.write("%s "%a) - sys.stdout.write("\n") - -supportedAccessSpecifier = [ - 'public', - 'protected', - 'private' -] - -#Symbols to ignore, usually special macros -ignoreSymbols = [ - 'Q_OBJECT', -] - -doxygenCommentCache = "" - -#Track what was added in what order and at what depth -parseHistory = [] - -def is_namespace(nameStack): - """Determines if a namespace is being specified""" - if len(nameStack) == 0: - return False - if nameStack[0] == "namespace": - return True - return False - -def is_enum_namestack(nameStack): - """Determines if a namestack is an enum namestack""" - if len(nameStack) == 0: - return False - if nameStack[0] == "enum": - return True - if len(nameStack) > 1 and nameStack[0] == "typedef" and nameStack[1] == "enum": - return True - return False - -def is_fundamental(s): - for a in s.split(): - if a not in ["size_t", "struct", "union", "unsigned", "signed", "bool", "char", "short", "int", "float", "double", "long", "void", "*"]: return False - return True - -def is_function_pointer_stack(stack): - """Count how many non-nested paranthesis are in the stack. Useful for determining if a stack is a function pointer""" - paren_depth = 0 - paren_count = 0 - star_after_first_paren = False - last_e = None - for e in stack: - if e == "(": - paren_depth += 1 - elif e == ")" and paren_depth > 0: - paren_depth -= 1 - if paren_depth == 0: - paren_count += 1 - elif e == "*" and last_e == "(" and paren_count == 0 and paren_depth == 1: - star_after_first_paren = True - last_e = e - - if star_after_first_paren and paren_count == 2: - return True - else: - return False - -def is_method_namestack(stack): - r = False - if '(' not in stack: r = False - elif stack[0] == 'typedef': r = False # TODO deal with typedef function prototypes - #elif '=' in stack and stack.index('=') < stack.index('(') and stack[stack.index('=')-1] != 'operator': r = False #disabled July6th - allow all operators - elif 'operator' in stack: r = True # allow all operators - elif '{' in stack and stack.index('{') < stack.index('('): r = False # struct that looks like a method/class - elif '(' in stack and ')' in stack: - if '{' in stack and '}' in stack: r = True - elif stack[-1] == ';': - if is_function_pointer_stack(stack): - r = False - else: - r = True - elif '{' in stack: r = True # ideally we catch both braces... TODO - else: r = False - #Test for case of property set to something with parens such as "static const int CONST_A = (1 << 7) - 1;" - if r and "(" in stack and "=" in stack and 'operator' not in stack: - if stack.index("=") < stack.index("("): r = False - return r - -def is_property_namestack(nameStack): - r = False - if '(' not in nameStack and ')' not in nameStack: r = True - elif "(" in nameStack and "=" in nameStack and nameStack.index("=") < nameStack.index("("): r = True - #See if we are a function pointer - if not r and is_function_pointer_stack(nameStack): r = True - return r - -def detect_lineno(s): - """Detect the line number for a given token string""" - try: - rtn = s.lineno() - if rtn != -1: - return rtn - except: pass - global curLine - return curLine - -def filter_out_attribute_keyword(stack): - """Strips __attribute__ and its parenthetical expression from the stack""" - if "__attribute__" not in stack: return stack - try: - debug_print("Stripping __attribute__ from %s"% stack) - attr_index = stack.index("__attribute__") - attr_end = attr_index + 1 #Assuming not followed by parenthetical expression which wont happen - #Find final paren - if stack[attr_index + 1] == '(': - paren_count = 1 - for i in range(attr_index + 2, len(stack)): - elm = stack[i] - if elm == '(': - paren_count += 1 - elif elm == ')': - paren_count -= 1 - if paren_count == 0: - attr_end = i + 1 - break - new_stack = stack[0:attr_index] + stack[attr_end:] - debug_print("stripped stack is %s"% new_stack) - return new_stack - except: - return stack - - -class TagStr(str): - """Wrapper for a string that allows us to store the line number associated with it""" - lineno_reg = {} - def __new__(cls,*args,**kw): - new_obj = str.__new__(cls,*args) - if "lineno" in kw: - TagStr.lineno_reg[id(new_obj)] = kw["lineno"] - return new_obj - - def __del__(self): - try: - del TagStr.lineno_reg[id(self)] - except: pass - - def lineno(self): - return TagStr.lineno_reg.get(id(self), -1) - -class CppParseError(Exception): pass - -class CppClass(dict): - """Takes a name stack and turns it into a class - - Contains the following Keys: - self['name'] - Name of the class - self['doxygen'] - Doxygen comments associated with the class if they exist - self['inherits'] - List of Classes that this one inherits where the values - are of the form {"access": Anything in supportedAccessSpecifier - "class": Name of the class - self['methods'] - Dictionary where keys are from supportedAccessSpecifier - and values are a lists of CppMethod's - self['properties'] - Dictionary where keys are from supportedAccessSpecifier - and values are lists of CppVariable's - self['enums'] - Dictionary where keys are from supportedAccessSpecifier and - values are lists of CppEnum's - self['structs'] - Dictionary where keys are from supportedAccessSpecifier and - values are lists of nested Struct's - - An example of how this could look is as follows: - #self = - { - 'name': "" - 'inherits':[] - 'methods': - { - 'public':[], - 'protected':[], - 'private':[] - }, - 'properties': - { - 'public':[], - 'protected':[], - 'private':[] - }, - 'enums': - { - 'public':[], - 'protected':[], - 'private':[] - } - } - """ - - def get_all_methods(self): - r = [] - for typ in supportedAccessSpecifier: r += self['methods'][typ] - return r - - def get_all_method_names( self ): - r = [] - for typ in supportedAccessSpecifier: r += self.get_method_names(typ) # returns list - return r - - def get_all_pure_virtual_methods( self ): - r = {} - for typ in supportedAccessSpecifier: r.update(self.get_pure_virtual_methods(typ)) # returns dict - return r - - - def get_method_names( self, type='public' ): return [ meth['name'] for meth in self['methods'][ type ] ] - - def get_pure_virtual_methods( self, type='public' ): - r = {} - for meth in self['methods'][ type ]: - if meth['pure_virtual']: r[ meth['name'] ] = meth - return r - - def __init__(self, nameStack): - self['nested_classes'] = [] - self['parent'] = None - self['abstract'] = False - self._public_enums = {} - self._public_structs = {} - self._public_typedefs = {} - self._public_forward_declares = [] - self['namespace'] = "" - - debug_print( "Class: %s"%nameStack ) - if (len(nameStack) < 2): - nameStack.insert(1, "")#anonymous struct - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - - if "::" in "".join(nameStack): - #Re-Join class paths (ex ['class', 'Bar', ':', ':', 'Foo'] -> ['class', 'Bar::Foo'] - try: - new_nameStack = [] - for name in nameStack: - if len(new_nameStack) == 0: - new_nameStack.append(name) - elif name == ":" and new_nameStack[-1].endswith(":"): - new_nameStack[-1] += name - elif new_nameStack[-1].endswith("::"): - new_nameStack[-2] += new_nameStack[-1] + name - del new_nameStack[-1] - else: - new_nameStack.append(name) - trace_print("Convert from namestack\n %s\nto\n%s"%(nameStack, new_nameStack)) - nameStack = new_nameStack - except: pass - - self["name"] = nameStack[1] - self["line_number"] = detect_lineno(nameStack[0]) - - #Handle template classes - if len(nameStack) > 3 and nameStack[2].startswith("<"): - open_template_count = 0 - param_separator = 0 - found_first = False - i = 0 - for elm in nameStack: - if '<' in elm : - open_template_count += 1 - found_first = True - elif '>' in elm: - open_template_count -= 1 - if found_first and open_template_count == 0: - self["name"] = "".join(nameStack[1:i + 1]) - break; - i += 1 - elif ":" in nameStack: - self['name'] = nameStack[ nameStack.index(':') - 1 ] - - inheritList = [] - - if nameStack.count(':') == 1: - nameStack = nameStack[nameStack.index(":") + 1:] - while len(nameStack): - tmpStack = [] - tmpInheritClass = {"access":"private", "virtual": False} - if "," in nameStack: - tmpStack = nameStack[:nameStack.index(",")] - nameStack = nameStack[nameStack.index(",") + 1:] - else: - tmpStack = nameStack - nameStack = [] - - # Convert template classes to one name in the last index - for i in range(0, len(tmpStack)): - if '<' in tmpStack[i]: - tmpStack2 = tmpStack[:i-1] - tmpStack2.append("".join(tmpStack[i-1:])) - tmpStack = tmpStack2 - break - if len(tmpStack) == 0: - break; - elif len(tmpStack) == 1: - tmpInheritClass["class"] = tmpStack[0] - elif len(tmpStack) == 2: - tmpInheritClass["access"] = tmpStack[0] - tmpInheritClass["class"] = tmpStack[1] - elif len(tmpStack) == 3 and "virtual" in tmpStack: - tmpInheritClass["access"] = tmpStack[1] if tmpStack[1] != "virtual" else tmpStack[0] - tmpInheritClass["class"] = tmpStack[2] - tmpInheritClass["virtual"] = True - else: - warning_print( "Warning: can not parse inheriting class %s"%(" ".join(tmpStack))) - if '>' in tmpStack: pass # allow skip templates for now - else: raise NotImplemented - - if 'class' in tmpInheritClass: inheritList.append(tmpInheritClass) - - elif nameStack.count(':') == 2: self['parent'] = self['name']; self['name'] = nameStack[-1] - - elif nameStack.count(':') > 2 and nameStack[0] in ("class", "struct"): - tmpStack = nameStack[nameStack.index(":") + 1:] - - superTmpStack = [[]] - for tok in tmpStack: - if tok == ',': - superTmpStack.append([]) - else: - superTmpStack[-1].append(tok) - - for tmpStack in superTmpStack: - tmpInheritClass = {"access":"private"} - - if len(tmpStack) and tmpStack[0] in supportedAccessSpecifier: - tmpInheritClass["access"] = tmpStack[0] - tmpStack = tmpStack[1:] - - inheritNSStack = [] - while len(tmpStack) > 3: - if tmpStack[0] == ':': break; - if tmpStack[1] != ':': break; - if tmpStack[2] != ':': break; - inheritNSStack.append(tmpStack[0]) - tmpStack = tmpStack[3:] - if len(tmpStack) == 1 and tmpStack[0] != ':': - inheritNSStack.append(tmpStack[0]) - tmpInheritClass["class"] = "::".join(inheritNSStack) - inheritList.append(tmpInheritClass) - - self['inherits'] = inheritList - - methodAccessSpecificList = {} - propertyAccessSpecificList = {} - enumAccessSpecificList = {} - structAccessSpecificList = {} - typedefAccessSpecificList = {} - forwardAccessSpecificList = {} - - for accessSpecifier in supportedAccessSpecifier: - methodAccessSpecificList[accessSpecifier] = [] - propertyAccessSpecificList[accessSpecifier] = [] - enumAccessSpecificList[accessSpecifier] = [] - structAccessSpecificList[accessSpecifier] = [] - typedefAccessSpecificList[accessSpecifier] = [] - forwardAccessSpecificList[accessSpecifier] = [] - - self['methods'] = methodAccessSpecificList - self['properties'] = propertyAccessSpecificList - self['enums'] = enumAccessSpecificList - self['structs'] = structAccessSpecificList - self['typedefs'] = typedefAccessSpecificList - self['forward_declares'] = forwardAccessSpecificList - - - def show(self): - """Convert class to a string""" - namespace_prefix = "" - if self["namespace"]: namespace_prefix = self["namespace"] + "::" - rtn = "%s %s"%(self["declaration_method"], namespace_prefix + self["name"]) - if self['abstract']: rtn += ' (abstract)\n' - else: rtn += '\n' - - if 'doxygen' in list(self.keys()): rtn += self["doxygen"] + '\n' - if 'parent' in list(self.keys()) and self['parent']: rtn += 'parent class: ' + self['parent'] + '\n' - - if "inherits" in list(self.keys()): - rtn += " Inherits: " - for inheritClass in self["inherits"]: - if inheritClass["virtual"]: rtn += "virtual " - rtn += "%s %s, "%(inheritClass["access"], inheritClass["class"]) - rtn += "\n" - rtn += " {\n" - for accessSpecifier in supportedAccessSpecifier: - rtn += " %s\n"%(accessSpecifier) - #Enums - if (len(self["enums"][accessSpecifier])): - rtn += " \n" - for enum in self["enums"][accessSpecifier]: - rtn += " %s\n"%(repr(enum)) - #Properties - if (len(self["properties"][accessSpecifier])): - rtn += " \n" - for property in self["properties"][accessSpecifier]: - rtn += " %s\n"%(repr(property)) - #Methods - if (len(self["methods"][accessSpecifier])): - rtn += " \n" - for method in self["methods"][accessSpecifier]: - rtn += "\t\t" + method.show() + '\n' - rtn += " }\n" - print(rtn) - - def __repr__(self): - """Convert class to a string""" - namespace_prefix = "" - if self["namespace"]: namespace_prefix = self["namespace"] + "::" - rtn = "%s %s"%(self["declaration_method"], namespace_prefix + self["name"]) - if self['abstract']: rtn += ' (abstract)\n' - else: rtn += '\n' - - if 'doxygen' in list(self.keys()): rtn += self["doxygen"] + '\n' - if 'parent' in list(self.keys()) and self['parent']: rtn += 'parent class: ' + self['parent'] + '\n' - - if "inherits" in list(self.keys()) and len(self["inherits"]): - rtn += "Inherits: " - for inheritClass in self["inherits"]: - if inheritClass.get("virtual", False): rtn += "virtual " - rtn += "%s %s, "%(inheritClass["access"], inheritClass["class"]) - rtn += "\n" - rtn += "{\n" - for accessSpecifier in supportedAccessSpecifier: - rtn += "%s\n"%(accessSpecifier) - #Enums - if (len(self["enums"][accessSpecifier])): - rtn += " // Enums\n" - for enum in self["enums"][accessSpecifier]: - rtn += " %s\n"%(repr(enum)) - #Properties - if (len(self["properties"][accessSpecifier])): - rtn += " // Properties\n" - for property in self["properties"][accessSpecifier]: - rtn += " %s\n"%(repr(property)) - #Methods - if (len(self["methods"][accessSpecifier])): - rtn += " // Methods\n" - for method in self["methods"][accessSpecifier]: - rtn += " %s\n"%(repr(method)) - rtn += "}\n" - return rtn - - -class CppUnion( CppClass ): - """Takes a name stack and turns it into a union - - Contains the following Keys: - self['name'] - Name of the union - self['doxygen'] - Doxygen comments associated with the union if they exist - self['members'] - List of members the union has - - An example of how this could look is as follows: - #self = - { - 'name': "" - 'members': [] - } - """ - - def __init__(self, nameStack): - CppClass.__init__(self, nameStack) - self["name"] = "union " + self["name"] - self["members"] = self["properties"]["public"] - - def transform_to_union_keys(self): - print("union keys: %s"%list(self.keys())) - for key in ['inherits', 'parent', 'abstract', 'namespace', 'typedefs', 'methods']: - del self[key] - - def show(self): - """Convert class to a string""" - print(self) - - - def __repr__(self): - """Convert class to a string""" - namespace_prefix = "" - if self["namespace"]: namespace_prefix = self["namespace"] + "::" - rtn = "%s %s"%(self["declaration_method"], namespace_prefix + self["name"]) - if self['abstract']: rtn += ' (abstract)\n' - else: rtn += '\n' - - if 'doxygen' in list(self.keys()): rtn += self["doxygen"] + '\n' - if 'parent' in list(self.keys()) and self['parent']: rtn += 'parent class: ' + self['parent'] + '\n' - - rtn += "{\n" - for member in self["members"]: - rtn += " %s\n"%(repr(member)) - rtn += "}\n" - return rtn - - - -class _CppMethod( dict ): - def _params_helper1( self, stack ): - # deal with "throw" keyword - if 'throw' in stack: stack = stack[ : stack.index('throw') ] - - ## remove GCC keyword __attribute__(...) and preserve returns ## - cleaned = [] - hit = False; hitOpen = 0; hitClose = 0 - for a in stack: - if a == '__attribute__': hit = True - if hit: - if a == '(': hitOpen += 1 - elif a == ')': hitClose += 1 - if a==')' and hitOpen == hitClose: - hit = False - else: - cleaned.append( a ) - stack = cleaned - - # also deal with attribute((const)) function prefix # - # TODO this needs to be better # - if len(stack) > 5: - a = ''.join(stack) - if a.startswith('((__const__))'): stack = stack[ 5 : ] - elif a.startswith('__attribute__((__const__))'): stack = stack[ 6 : ] - - stack = stack[stack.index('(') + 1: ] - if not stack: return [] - if len(stack)>=3 and stack[0]==')' and stack[1]==':': # is this always a constructor? - self['constructor'] = True - return [] - - stack.reverse(); _end_ = stack.index(')'); stack.reverse() - stack = stack[ : len(stack)-(_end_+1) ] - if '(' not in stack: return stack # safe to return, no defaults that init a class - - # transforms ['someclass', '(', '0', '0', '0', ')'] into "someclass(0,0,0)'" - r = []; hit=False - for a in stack: - if a == '(': hit=True - elif a == ')': hit=False - if hit or a == ')': r[-1] = r[-1] + a - else: r.append( a ) - return r - - def _params_helper2( self, params ): - for p in params: - p['method'] = self # save reference in variable to parent method - if '::' in p['type']: - ns = p['type'].split('::')[0] - if ns not in Resolver.NAMESPACES and ns in Resolver.CLASSES: - p['type'] = self['namespace'] + p['type'] - else: p['namespace'] = self[ 'namespace' ] - -class CppMethod( _CppMethod ): - """Takes a name stack and turns it into a method - - Contains the following Keys: - self['rtnType'] - Return type of the method (ex. "int") - self['name'] - Name of the method (ex. "getSize") - self['doxygen'] - Doxygen comments associated with the method if they exist - self['parameters'] - List of CppVariables - """ - def show(self): - r = ['method name: %s (%s)' %(self['name'],self['debug']) ] - if self['returns']: r.append( 'returns: %s'%self['returns'] ) - if self['parameters']: r.append( 'number arguments: %s' %len(self['parameters'])) - if self['pure_virtual']: r.append( 'pure virtual: %s'%self['pure_virtual'] ) - if self['constructor']: r.append( 'constructor' ) - if self['destructor']: r.append( 'destructor' ) - return '\n\t\t '.join( r ) - - def __init__(self, nameStack, curClass, methinfo): - debug_print( "Method: %s"%nameStack ) - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - if "operator" in nameStack: - self["rtnType"] = " ".join(nameStack[:nameStack.index('operator')]) - self["name"] = "".join(nameStack[nameStack.index('operator'):nameStack.index('(')]) - else: - self["rtnType"] = " ".join(nameStack[:nameStack.index('(') - 1]) - self["name"] = " ".join(nameStack[nameStack.index('(') - 1:nameStack.index('(')]) - if self["rtnType"].startswith("virtual"): - self["rtnType"] = self["rtnType"][len("virtual"):].strip() - if len(self["rtnType"]) == 0 or self["name"] == curClass: - self["rtnType"] = "void" - - self["rtnType"] = self["rtnType"].replace(' : : ', '::' ) - self["rtnType"] = self["rtnType"].replace(" <","<") - self["rtnType"] = self["rtnType"].replace(" >",">").replace(">>", "> >").replace(">>", "> >") - self["rtnType"] = self["rtnType"].replace(" ,",",") - - self["const"] = False - for i in reversed(nameStack): - if i == "const": - self["const"] = True - break - elif i == ")": - break - - self.update( methinfo ) - self["line_number"] = detect_lineno(nameStack[0]) - - #Filter out initializer lists used in constructors - try: - paren_depth_counter = 0 - for i in range(0, len(nameStack)): - elm = nameStack[i] - if elm == "(": - paren_depth_counter += 1 - if elm == ")": - paren_depth_counter -=1 - if paren_depth_counter == 0 and nameStack[i+1] == ':': - debug_print("Stripping out initializer list") - nameStack = nameStack[:i+1] - break - except: pass - - paramsStack = self._params_helper1( nameStack ) - - - params = [] - #See if there is a doxygen comment for the variable - doxyVarDesc = {} - - if "doxygen" in self: - doxyLines = self["doxygen"].split("\n") - lastParamDesc = "" - for doxyLine in doxyLines: - if " @param " in doxyLine or " \param " in doxyLine: - try: - #Strip out the param - doxyLine = doxyLine[doxyLine.find("param ") + 6:] - (var, desc) = doxyLine.split(" ", 1) - doxyVarDesc[var] = desc.strip() - lastParamDesc = var - except: pass - elif " @return " in doxyLine or " \return " in doxyLine: - lastParamDesc = "" - # not handled for now - elif lastParamDesc: - try: - doxyLine = doxyLine.strip() - if " " not in doxyLine: - lastParamDesc = "" - continue - doxyLine = doxyLine[doxyLine.find(" ") + 1:] - doxyVarDesc[lastParamDesc] += " " + doxyLine - except: pass - - #Create the variable now - while (len(paramsStack)): - # Find commas that are not nexted in <>'s like template types - open_template_count = 0 - param_separator = 0 - i = 0 - for elm in paramsStack: - if '<' in elm : - open_template_count += 1 - elif '>' in elm: - open_template_count -= 1 - elif elm == ',' and open_template_count == 0: - param_separator = i - break - i += 1 - - if param_separator: - param = CppVariable(paramsStack[0:param_separator], doxyVarDesc=doxyVarDesc) - if len(list(param.keys())): params.append(param) - paramsStack = paramsStack[param_separator + 1:] - else: - param = CppVariable(paramsStack, doxyVarDesc=doxyVarDesc) - if len(list(param.keys())): params.append(param) - break - - - self["parameters"] = params - self._params_helper2( params ) # mods params inplace - - def __repr__(self): - filter_keys = ("parent", "defined", "operator", "returns_reference") - cpy = dict((k,v) for (k,v) in list(self.items()) if k not in filter_keys) - return "%s"%cpy - - -class _CppVariable(dict): - def _name_stack_helper( self, stack ): - stack = list(stack) - if '=' not in stack: # TODO refactor me - # check for array[n] and deal with funny array syntax: "int myvar:99" - array = [] - while stack and stack[-1].isdigit(): array.append( stack.pop() ) - if array: array.reverse(); self['array'] = int(''.join(array)) - if stack and stack[-1].endswith(':'): stack[-1] = stack[-1][:-1] - - while stack and not stack[-1]: stack.pop() # can be empty - return stack - - def init(self): - #assert self['name'] # allow unnamed variables, methods like this: "void func(void);" - a = [] - self['aliases'] = []; self['parent'] = None; self['typedef'] = None - for key in 'constant reference pointer static typedefs class fundamental unresolved'.split(): - self[ key ] = 0 - for b in self['type'].split(): - if b == '__const__': b = 'const' - a.append( b ) - self['type'] = ' '.join( a ) - - -class CppVariable( _CppVariable ): - """Takes a name stack and turns it into a method - - Contains the following Keys: - self['type'] - Type for the variable (ex. "const string &") - self['name'] - Name of the variable (ex. "numItems") - self['namespace'] - Namespace containing the enum - self['desc'] - Description of the variable if part of a method (optional) - self['doxygen'] - Doxygen comments associated with the method if they exist - self['defaltValue'] - Default value of the variable, this key will only - exist if there is a default value - """ - Vars = [] - def __init__(self, nameStack, **kwargs): - _stack_ = nameStack - if "[" in nameStack: #strip off array informatin - arrayStack = nameStack[nameStack.index("["):] - if len(arrayStack) == 3: - self["array_size"] = arrayStack[1] - nameStack = nameStack[:nameStack.index("[")] - self["array"] = 1 - else: - self["array"] = 0 - nameStack = self._name_stack_helper( nameStack ) - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - - debug_print( "Variable: %s"%nameStack ) - - self["line_number"] = detect_lineno(nameStack[0]) - self["function_pointer"] = 0 - - if (len(nameStack) < 2): # +++ - if len(nameStack) == 1: self['type'] = nameStack[0]; self['name'] = '' - else: error_print(_stack_); assert 0 - - elif is_function_pointer_stack(nameStack): #function pointer - self["type"] = " ".join(nameStack[:nameStack.index("(") + 2] + nameStack[nameStack.index(")") :]) - self["name"] = " ".join(nameStack[nameStack.index("(") + 2 : nameStack.index(")")]) - self["function_pointer"] = 1 - - elif ("=" in nameStack): - self["type"] = " ".join(nameStack[:nameStack.index("=") - 1]) - self["name"] = nameStack[nameStack.index("=") - 1] - self["defaltValue"] = " ".join(nameStack[nameStack.index("=") + 1:]) # deprecate camelCase in dicts - self['default'] = " ".join(nameStack[nameStack.index("=") + 1:]) - - elif is_fundamental(nameStack[-1]) or nameStack[-1] in ['>', '<' , ':', '.']: - #Un named parameter - self["type"] = " ".join(nameStack) - self["name"] = "" - - else: # common case - self["type"] = " ".join(nameStack[:-1]) - self["name"] = nameStack[-1] - - self["type"] = self["type"].replace(" :",":") - self["type"] = self["type"].replace(": ",":") - self["type"] = self["type"].replace(" <","<") - self["type"] = self["type"].replace(" >",">").replace(">>", "> >").replace(">>", "> >") - self["type"] = self["type"].replace(" ,",",") - #Optional doxygen description - try: - self["desc"] = kwargs["doxyVarDesc"][self["name"]] - except: pass - - self.init() - CppVariable.Vars.append( self ) # save and resolve later - - def __repr__(self): - keys_white_list = ['constant','name','reference','type','static','pointer','desc', 'line_number'] - cpy = dict((k,v) for (k,v) in list(self.items()) if k in keys_white_list) - if "array_size" in self: cpy["array_size"] = self["array_size"] - return "%s"%cpy - -class _CppEnum(dict): - def resolve_enum_values( self, values ): - """Evaluates the values list of dictionaries passed in and figures out what the enum value - for each enum is editing in place: - - Example: - From: [{'name': 'ORANGE'}, - {'name': 'RED'}, - {'name': 'GREEN', 'value': '8'}] - To: [{'name': 'ORANGE', 'value': 0}, - {'name': 'RED', 'value': 1}, - {'name': 'GREEN', 'value': 8}] - """ - t = int; i = 0 - names = [ v['name'] for v in values ] - for v in values: - if 'value' in v: - a = v['value'].strip() - # Remove single quotes from single quoted chars (unless part of some expression - if len(a) == 3 and a[0] == "'" and a[2] == "'": - a = v['value'] = a[1] - if a.lower().startswith("0x"): - try: - i = a = int(a , 16) - except:pass - elif a.isdigit(): - i = a = int( a ) - elif a in names: - for other in values: - if other['name'] == a: - v['value'] = other['value'] - break - - elif '"' in a or "'" in a: t = str # only if there are quotes it this a string enum - else: - try: - a = i = ord(a) - except: pass - #Allow access of what is in the file pre-convert if converted - if v['value'] != str(a): - v['raw_value'] = v['value'] - v['value'] = a - else: v['value'] = i - try: - v['value'] = v['value'].replace(" < < ", " << ").replace(" >> ", " >> ") - except: pass - i += 1 - return t - -class CppEnum(_CppEnum): - """Takes a name stack and turns it into an Enum - - Contains the following Keys: - self['name'] - Name of the enum (ex. "ItemState") - self['namespace'] - Namespace containing the enum - self['values'] - List of values where the values are a dictionary of the - form {"name": name of the key (ex. "PARSING_HEADER"), - "value": Specified value of the enum, this key will only exist - if a value for a given enum value was defined - } - """ - def __init__(self, nameStack): - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - if len(nameStack) == 3 and nameStack[0] == "enum": - debug_print("Created enum as just name/value") - self["name"] = nameStack[1] - self["instances"]=[nameStack[2]] - if len(nameStack) < 4 or "{" not in nameStack or "}" not in nameStack: - #Not enough stuff for an enum - debug_print("Bad enum") - return - valueList = [] - self["line_number"] = detect_lineno(nameStack[0]) - #Figure out what values it has - valueStack = nameStack[nameStack.index('{') + 1: nameStack.index('}')] - while len(valueStack): - tmpStack = [] - if "," in valueStack: - tmpStack = valueStack[:valueStack.index(",")] - valueStack = valueStack[valueStack.index(",") + 1:] - else: - tmpStack = valueStack - valueStack = [] - d = {} - if len(tmpStack) == 1: d["name"] = tmpStack[0] - elif len(tmpStack) >= 3 and tmpStack[1] == "=": - d["name"] = tmpStack[0]; d["value"] = " ".join(tmpStack[2:]) - elif len(tmpStack) == 2 and tmpStack[1] == "=": - debug_print( "WARN-enum: parser missed value for %s"%tmpStack[0] ) - d["name"] = tmpStack[0] - - if d: valueList.append( d ) - - if len(valueList): - self['type'] = self.resolve_enum_values( valueList ) # returns int for standard enum - self["values"] = valueList - else: - warning_print( 'WARN-enum: empty enum %s'%nameStack ) - return - #Figure out if it has a name - preBraceStack = nameStack[:nameStack.index("{")] - postBraceStack = nameStack[nameStack.index("}") + 1:] - if (len(preBraceStack) == 2 and "typedef" not in nameStack): - self["name"] = preBraceStack[1] - elif len(postBraceStack) and "typedef" in nameStack: - self["name"] = " ".join(postBraceStack) - else: warning_print( 'WARN-enum: nameless enum %s'%nameStack ) - #See if there are instances of this - if "typedef" not in nameStack and len(postBraceStack): - self["instances"] = [] - for var in postBraceStack: - if "," in var: - continue - self["instances"].append(var) - self["namespace"] = "" - - -class CppStruct(dict): - Structs = [] - def __init__(self, nameStack): - if len(nameStack) >= 2: self['type'] = nameStack[1] - else: self['type'] = None - self['fields'] = [] - self.Structs.append( self ) - global curLine - self["line_number"] = curLine - -C99_NONSTANDARD = { - 'int8' : 'signed char', - 'int16' : 'short int', - 'int32' : 'int', - 'int64' : 'int64_t', # this can be: long int (64bit), or long long int (32bit) - 'uint' : 'unsigned int', - 'uint8' : 'unsigned char', - 'uint16' : 'unsigned short int', - 'uint32' : 'unsigned int', - 'uint64' : 'uint64_t', # depends on host bits -} - - -def standardize_fundamental( s ): - if s in C99_NONSTANDARD: return C99_NONSTANDARD[ s ] - else: return s - - -class Resolver(object): - C_FUNDAMENTAL = 'size_t unsigned signed bool char wchar short int float double long void'.split() - C_FUNDAMENTAL += 'struct union enum'.split() - - - SubTypedefs = {} # TODO deprecate? - NAMESPACES = [] - CLASSES = {} - STRUCTS = {} - - def initextra(self): - self.typedefs = {} - self.typedefs_order = [] - self.classes_order = [] - self.structs = Resolver.STRUCTS - self.structs_order = [] - self.namespaces = Resolver.NAMESPACES # save all namespaces - self.curStruct = None - self.stack = [] # full name stack, good idea to keep both stacks? (simple stack and full stack) - self._classes_brace_level = {} # class name : level - self._structs_brace_level = {} # struct type : level - self._method_body = None - self._forward_decls = [] - self._template_typenames = [] # template - - def current_namespace(self): return self.cur_namespace(True) - - def cur_namespace(self, add_double_colon=False): - rtn = "" - i = 0 - while i < len(self.nameSpaces): - rtn += self.nameSpaces[i] - if add_double_colon or i < len(self.nameSpaces) - 1: rtn += "::" - i+=1 - return rtn - - - def guess_ctypes_type( self, string ): - pointers = string.count('*') - string = string.replace('*','') - - a = string.split() - if 'unsigned' in a: u = 'u' - else: u = '' - if 'long' in a and 'double' in a: b = 'longdouble' # there is no ctypes.c_ulongdouble (this is a 64bit float?) - elif a.count('long') == 2 and 'int' in a: b = '%sint64' %u - elif a.count('long') == 2: b = '%slonglong' %u - elif 'long' in a: b = '%slong' %u - elif 'double' in a: b = 'double' # no udouble in ctypes - elif 'short' in a: b = '%sshort' %u - elif 'char' in a: b = '%schar' %u - elif 'wchar' in a: b = 'wchar' - elif 'bool' in a: b = 'bool' - elif 'float' in a: b = 'float' - - elif 'int' in a: b = '%sint' %u - elif 'int8' in a: b = 'int8' - elif 'int16' in a: b = 'int16' - elif 'int32' in a: b = 'int32' - elif 'int64' in a: b = 'int64' - - elif 'uint' in a: b = 'uint' - elif 'uint8' in a: b = 'uint8' - elif 'uint16' in a: b = 'uint16' - elif 'uint32' in a: b = 'uint32' - elif 'uint64' in a: b = 'uint64' - - elif 'size_t' in a: b = 'size_t' - elif 'void' in a: b = 'void_p' - - elif string in 'struct union'.split(): b = 'void_p' # what should be done here? don't trust struct, it could be a class, no need to expose via ctypes - else: b = 'void_p' - - if not pointers: return 'ctypes.c_%s' %b - else: - x = '' - for i in range(pointers): x += 'ctypes.POINTER(' - x += 'ctypes.c_%s' %b - x += ')' * pointers - return x - - def resolve_type( self, string, result ): # recursive - ''' - keeps track of useful things like: how many pointers, number of typedefs, is fundamental or a class, etc... - ''' - ## be careful with templates, what is inside can be a pointer but the overall type is not a pointer - ## these come before a template - s = string.split('<')[0] - result[ 'constant' ] += s.split().count('const') - result[ 'static' ] += s.split().count('static') - result[ 'mutable' ] = 'mutable' in s.split() - - ## these come after a template - s = string.split('>')[-1] - result[ 'pointer' ] += s.count('*') - result[ 'reference' ] += s.count('&') - - - x = string; alias = False - for a in '* & const static mutable'.split(): x = x.replace(a,'') - for y in x.split(): - if y not in self.C_FUNDAMENTAL: alias = y; break - - #if alias == 'class': - # result['class'] = result['name'] # forward decl of class - # result['forward_decl'] = True - if alias == '__extension__': result['fundamental_extension'] = True - elif alias: - result['aliases'].append( alias ) - if alias in C99_NONSTANDARD: - result['type'] = C99_NONSTANDARD[ alias ] - result['typedef'] = alias - result['typedefs'] += 1 - elif alias in self.typedefs: - result['typedefs'] += 1 - result['typedef'] = alias - self.resolve_type( self.typedefs[alias], result ) - elif alias in self.classes: - klass = self.classes[alias]; result['fundamental'] = False - result['class'] = klass - result['unresolved'] = False - else: result['unresolved'] = True - else: - result['fundamental'] = True - result['unresolved'] = False - - - def finalize_vars(self): - for s in CppStruct.Structs: # vars within structs can be ignored if they do not resolve - for var in s['fields']: var['parent'] = s['type'] - #for c in self.classes.values(): - # for var in c.get_all_properties(): var['parent'] = c['name'] - - ## RESOLVE ## - for var in CppVariable.Vars: - self.resolve_type( var['type'], var ) - #if 'method' in var and var['method']['name'] == '_notifyCurrentCamera': print(var); assert 0 - - # then find concrete type and best guess ctypes type # - for var in CppVariable.Vars: - if not var['aliases']: #var['fundamental']: - var['ctypes_type'] = self.guess_ctypes_type( var['type'] ) - else: - var['unresolved'] = False # below may test to True - if var['class']: - var['ctypes_type'] = 'ctypes.c_void_p' - else: - assert var['aliases'] - tag = var['aliases'][0] - - klass = None - nestedEnum = None - nestedStruct = None - nestedTypedef = None - if 'method' in var and 'parent' in list(var['method'].keys()): - klass = var['method']['parent'] - if tag in var['method']['parent']._public_enums: - nestedEnum = var['method']['parent']._public_enums[ tag ] - elif tag in var['method']['parent']._public_structs: - nestedStruct = var['method']['parent']._public_structs[ tag ] - elif tag in var['method']['parent']._public_typedefs: - nestedTypedef = var['method']['parent']._public_typedefs[ tag ] - - - if '<' in tag: # should also contain '>' - var['template'] = tag # do not resolve templates - var['ctypes_type'] = 'ctypes.c_void_p' - var['unresolved'] = True - - elif nestedEnum: - enum = nestedEnum - if enum['type'] is int: - var['ctypes_type'] = 'ctypes.c_int' - var['raw_type'] = 'int' - - elif enum['type'] is str: - var['ctypes_type'] = 'ctypes.c_char_p' - var['raw_type'] = 'char*' - - var['enum'] = var['method']['path'] + '::' + enum['name'] - var['fundamental'] = True - - elif nestedStruct: - var['ctypes_type'] = 'ctypes.c_void_p' - var['raw_type'] = var['method']['path'] + '::' + nestedStruct['type'] - var['fundamental'] = False - - elif nestedTypedef: - var['fundamental'] = is_fundamental( nestedTypedef ) - if not var['fundamental']: - var['raw_type'] = var['method']['path'] + '::' + tag - - else: - _tag = tag - if '::' in tag and tag.split('::')[0] in self.namespaces: tag = tag.split('::')[-1] - con = self.concrete_typedef( _tag ) - if con: - var['concrete_type'] = con - var['ctypes_type'] = self.guess_ctypes_type( var['concrete_type'] ) - - elif tag in self.structs: - trace_print( 'STRUCT', var ) - var['struct'] = tag - var['ctypes_type'] = 'ctypes.c_void_p' - var['raw_type'] = self.structs[tag]['namespace'] + '::' + tag - - elif tag in self._forward_decls: - var['forward_declared'] = tag - var['ctypes_type'] = 'ctypes.c_void_p' - - elif tag in self.global_enums: - enum = self.global_enums[ tag ] - if enum['type'] is int: - var['ctypes_type'] = 'ctypes.c_int' - var['raw_type'] = 'int' - elif enum['type'] is str: - var['ctypes_type'] = 'ctypes.c_char_p' - var['raw_type'] = 'char*' - var['enum'] = enum['namespace'] + enum['name'] - var['fundamental'] = True - - - elif var['parent']: - warning_print( 'WARN unresolved %s'%_tag) - var['ctypes_type'] = 'ctypes.c_void_p' - var['unresolved'] = True - - - elif tag.count('::')==1: - trace_print( 'trying to find nested something in', tag ) - a = tag.split('::')[0] - b = tag.split('::')[-1] - if a in self.classes: # a::b is most likely something nested in a class - klass = self.classes[ a ] - if b in klass._public_enums: - trace_print( '...found nested enum', b ) - enum = klass._public_enums[ b ] - if enum['type'] is int: - var['ctypes_type'] = 'ctypes.c_int' - var['raw_type'] = 'int' - elif enum['type'] is str: - var['ctypes_type'] = 'ctypes.c_char_p' - var['raw_type'] = 'char*' - try: - if 'method' in var: var['enum'] = var['method']['path'] + '::' + enum['name'] - else: # class property - var['unresolved'] = True - except: - var['unresolved'] = True - - var['fundamental'] = True - - else: var['unresolved'] = True # TODO klass._public_xxx - - elif a in self.namespaces: # a::b can also be a nested namespace - if b in self.global_enums: - enum = self.global_enums[ b ] - trace_print(enum) - trace_print(var) - assert 0 - - elif b in self.global_enums: # falling back, this is a big ugly - enum = self.global_enums[ b ] - assert a in enum['namespace'].split('::') - if enum['type'] is int: - var['ctypes_type'] = 'ctypes.c_int' - var['raw_type'] = 'int' - elif enum['type'] is str: - var['ctypes_type'] = 'ctypes.c_char_p' - var['raw_type'] = 'char*' - var['fundamental'] = True - - else: # boost::gets::crazy - trace_print('NAMESPACES', self.namespaces) - trace_print( a, b ) - trace_print( '---- boost gets crazy ----' ) - var['ctypes_type'] = 'ctypes.c_void_p' - var['unresolved'] = True - - - elif 'namespace' in var and self.concrete_typedef(var['namespace']+tag): - #print( 'TRYING WITH NS', var['namespace'] ) - con = self.concrete_typedef( var['namespace']+tag ) - if con: - var['typedef'] = var['namespace']+tag - var['type'] = con - if 'struct' in con.split(): - var['raw_type'] = var['typedef'] - var['ctypes_type'] = 'ctypes.c_void_p' - else: - self.resolve_type( var['type'], var ) - var['ctypes_type'] = self.guess_ctypes_type( var['type'] ) - - elif '::' in var: - var['ctypes_type'] = 'ctypes.c_void_p' - var['unresolved'] = True - - elif tag in self.SubTypedefs: # TODO remove SubTypedefs - if 'property_of_class' in var or 'property_of_struct' in var: - trace_print( 'class:', self.SubTypedefs[ tag ], 'tag:', tag ) - var['typedef'] = self.SubTypedefs[ tag ] # class name - var['ctypes_type'] = 'ctypes.c_void_p' - else: - trace_print( "WARN-this should almost never happen!" ) - trace_print( var ); trace_print('-'*80) - var['unresolved'] = True - - elif tag in self._template_typenames: - var['typename'] = tag - var['ctypes_type'] = 'ctypes.c_void_p' - var['unresolved'] = True # TODO, how to deal with templates? - - elif tag.startswith('_'): # assume starting with underscore is not important for wrapping - warning_print( 'WARN unresolved %s'%_tag) - var['ctypes_type'] = 'ctypes.c_void_p' - var['unresolved'] = True - - else: - trace_print( 'WARN: unknown type', var ) - assert 'property_of_class' in var or 'property_of_struct' # only allow this case - var['unresolved'] = True - - - ## if not resolved and is a method param, not going to wrap these methods ## - if var['unresolved'] and 'method' in var: var['method']['unresolved_parameters'] = True - - - # create stripped raw_type # - p = '* & const static mutable'.split() # +++ new July7: "mutable" - for var in CppVariable.Vars: - if 'raw_type' not in var: - raw = [] - for x in var['type'].split(): - if x not in p: raw.append( x ) - var['raw_type'] = ' '.join( raw ) - - #if 'AutoConstantEntry' in var['raw_type']: print(var); assert 0 - if var['class']: - if '::' not in var['raw_type']: - if not var['class']['parent']: - var['raw_type'] = var['class']['namespace'] + '::' + var['raw_type'] - elif var['class']['parent'] in self.classes: - parent = self.classes[ var['class']['parent'] ] - var['raw_type'] = parent['namespace'] + '::' + var['class']['name'] + '::' + var['raw_type'] - else: - var['unresolved'] = True - - elif '::' in var['raw_type'] and var['raw_type'].split('::')[0] not in self.namespaces: - var['raw_type'] = var['class']['namespace'] + '::' + var['raw_type'] - else: - var['unresolved'] = True - - elif 'forward_declared' in var and 'namespace' in var: - if '::' not in var['raw_type']: - var['raw_type'] = var['namespace'] + var['raw_type'] - elif '::' in var['raw_type'] and var['raw_type'].split('::')[0] in self.namespaces: - pass - else: trace_print('-'*80); trace_print(var); raise NotImplemented - - - ## need full name space for classes in raw type ## - if var['raw_type'].startswith( '::' ): - #print(var) - #print('NAMESPACE', var['class']['namespace']) - #print( 'PARENT NS', var['class']['parent']['namespace'] ) - #assert 0 - var['unresolved'] = True - if 'method' in var: var['method']['unresolved_parameters'] = True - #var['raw_type'] = var['raw_type'][2:] - - # Take care of #defines and #pragmas etc - trace_print("Processing precomp_macro_buf: %s"%self._precomp_macro_buf) - for m in self._precomp_macro_buf: - macro = m.replace("\\n", "\n") - try: - if macro.lower().startswith("#define"): - trace_print("Adding #define %s"%macro) - self.defines.append(macro.split(" ", 1)[1].strip()) - elif macro.lower().startswith("#pragma"): - trace_print("Adding #pragma %s"%macro) - self.pragmas.append(macro.split(" ", 1)[1].strip()) - elif macro.lower().startswith("#include"): - trace_print("Adding #include %s"%macro) - self.includes.append(macro.split(" ", 1)[1].strip()) - else: - debug_print("Cant detect what to do with precomp macro '%s'"%macro) - except: pass - self._precomp_macro_buf = None - - - def concrete_typedef( self, key ): - if key not in self.typedefs: - #print( 'FAILED typedef', key ) - return None - while key in self.typedefs: - prev = key - key = self.typedefs[ key ] - if '<' in key or '>' in key: return prev # stop at template - if key.startswith('std::'): return key # stop at std lib - return key - - -class _CppHeader( Resolver ): - def finalize(self): - self.finalize_vars() - # finalize classes and method returns types - for cls in list(self.classes.values()): - for meth in cls.get_all_methods(): - if meth['pure_virtual']: cls['abstract'] = True - - if not meth['returns_fundamental'] and meth['returns'] in C99_NONSTANDARD: - meth['returns'] = C99_NONSTANDARD[meth['returns']] - meth['returns_fundamental'] = True - - elif not meth['returns_fundamental']: # describe the return type - con = None - if cls['namespace'] and '::' not in meth['returns']: - con = self.concrete_typedef( cls['namespace'] + '::' + meth['returns'] ) - else: con = self.concrete_typedef( meth['returns'] ) - - - if con: - meth['returns_concrete'] = con - meth['returns_fundamental'] = is_fundamental( con ) - - elif meth['returns'] in self.classes: - trace_print( 'meth returns class:', meth['returns'] ) - meth['returns_class'] = True - - elif meth['returns'] in self.SubTypedefs: - meth['returns_class'] = True - meth['returns_nested'] = self.SubTypedefs[ meth['returns'] ] - - elif meth['returns'] in cls._public_enums: - enum = cls._public_enums[ meth['returns'] ] - meth['returns_enum'] = enum['type'] - meth['returns_fundamental'] = True - if enum['type'] == int: meth['returns'] = 'int' - else: meth['returns'] = 'char*' - - elif meth['returns'] in self.global_enums: - enum = self.global_enums[ meth['returns'] ] - meth['returns_enum'] = enum['type'] - meth['returns_fundamental'] = True - if enum['type'] == int: meth['returns'] = 'int' - else: meth['returns'] = 'char*' - - elif meth['returns'].count('::')==1: - trace_print( meth ) - a,b = meth['returns'].split('::') - if a in self.namespaces: - if b in self.classes: - klass = self.classes[ b ] - meth['returns_class'] = a + '::' + b - elif '<' in b and '>' in b: - warning_print( 'WARN-can not return template: %s'%b ) - meth['returns_unknown'] = True - elif b in self.global_enums: - enum = self.global_enums[ b ] - meth['returns_enum'] = enum['type'] - meth['returns_fundamental'] = True - if enum['type'] == int: meth['returns'] = 'int' - else: meth['returns'] = 'char*' - - else: trace_print( a, b); trace_print( meth); meth['returns_unknown'] = True # +++ - - elif a in self.classes: - klass = self.classes[ a ] - if b in klass._public_enums: - trace_print( '...found nested enum', b ) - enum = klass._public_enums[ b ] - meth['returns_enum'] = enum['type'] - meth['returns_fundamental'] = True - if enum['type'] == int: meth['returns'] = 'int' - else: meth['returns'] = 'char*' - - elif b in klass._public_forward_declares: - meth['returns_class'] = True - - elif b in klass._public_typedefs: - typedef = klass._public_typedefs[ b ] - meth['returns_fundamental'] = is_fundamental( typedef ) - - else: - trace_print( meth ) # should be a nested class, TODO fix me. - meth['returns_unknown'] = True - - elif '::' in meth['returns']: - trace_print('TODO namespace or extra nested return:', meth) - meth['returns_unknown'] = True - else: - trace_print( 'WARN: UNKNOWN RETURN', meth['name'], meth['returns']) - meth['returns_unknown'] = True - - for cls in list(self.classes.values()): - methnames = cls.get_all_method_names() - pvm = cls.get_all_pure_virtual_methods() - - for d in cls['inherits']: - c = d['class'] - a = d['access'] # do not depend on this to be 'public' - trace_print( 'PARENT CLASS:', c ) - if c not in self.classes: trace_print('WARN: parent class not found') - if c in self.classes and self.classes[c]['abstract']: - p = self.classes[ c ] - for meth in p.get_all_methods(): #p["methods"]["public"]: - trace_print( '\t\tmeth', meth['name'], 'pure virtual', meth['pure_virtual'] ) - if meth['pure_virtual'] and meth['name'] not in methnames: cls['abstract'] = True; break - - - - - - def evaluate_struct_stack(self): - """Create a Struct out of the name stack (but not its parts)""" - #print( 'eval struct stack', self.nameStack ) - #if self.braceDepth != len(self.nameSpaces): return - struct = CppStruct(self.nameStack) - struct["namespace"] = self.cur_namespace() - self.structs[ struct['type'] ] = struct - self.structs_order.append( struct ) - if self.curClass: - struct['parent'] = self.curClass - klass = self.classes[ self.curClass ] - klass['structs'][self.curAccessSpecifier].append( struct ) - if self.curAccessSpecifier == 'public': klass._public_structs[ struct['type'] ] = struct - self.curStruct = struct - self._structs_brace_level[ struct['type'] ] = self.braceDepth - - - def parse_method_type( self, stack ): - trace_print( 'meth type info', stack ) - if stack[0] in ':;': stack = stack[1:] - info = { - 'debug': ' '.join(stack).replace(' : : ', '::' ).replace(' < ', '<' ).replace(' > ', '> ' ).replace(" >",">").replace(">>", "> >").replace(">>", "> >"), - 'class':None, - 'namespace':self.cur_namespace(add_double_colon=True), - } - - for tag in 'defined pure_virtual operator constructor destructor extern template virtual static explicit inline friend returns returns_pointer returns_fundamental returns_class'.split(): info[tag]=False - header = stack[ : stack.index('(') ] - header = ' '.join( header ) - header = header.replace(' : : ', '::' ) - header = header.replace(' < ', '<' ) - header = header.replace(' > ', '> ' ) - header = header.strip() - - if '{' in stack: - info['defined'] = True - self._method_body = self.braceDepth + 1 - trace_print( 'NEW METHOD WITH BODY', self.braceDepth ) - elif stack[-1] == ';': - info['defined'] = False - self._method_body = None # not a great idea to be clearing here - else: assert 0 - - if len(stack) > 3 and stack[-1] == ';' and stack[-2] == '0' and stack[-3] == '=': - info['pure_virtual'] = True - - r = header.split() - name = None - if 'operator' in stack: # rare case op overload defined outside of class - op = stack[ stack.index('operator')+1 : stack.index('(') ] - op = ''.join(op) - if not op: - if " ".join(['operator', '(', ')', '(']) in " ".join(stack): - op = "()" - else: - trace_print( 'Error parsing operator') - return None - - info['operator'] = op - name = 'operator' + op - a = stack[ : stack.index('operator') ] - - elif r: - name = r[-1] - a = r[ : -1 ] # strip name - - if name is None: return None - #if name.startswith('~'): name = name[1:] - - while a and a[0] == '}': # strip - can have multiple } } - a = a[1:] - - - if '::' in name: - #klass,name = name.split('::') # methods can be defined outside of class - klass = name[ : name.rindex('::') ] - name = name.split('::')[-1] - info['class'] = klass - if klass in self.classes and not self.curClass: - #Class function defined outside the class - return None - # info['name'] = name - #else: info['name'] = name - - if name.startswith('~'): - info['destructor'] = True - name = name[1:] - elif not a or (name == self.curClass and len(self.curClass)): - info['constructor'] = True - - info['name'] = name - - for tag in 'extern virtual static explicit inline friend'.split(): - if tag in a: info[ tag ] = True; a.remove( tag ) # inplace - if 'template' in a: - a.remove('template') - b = ' '.join( a ) - if '>' in b: - info['template'] = b[ : b.index('>')+1 ] - info['returns'] = b[ b.index('>')+1 : ] # find return type, could be incorrect... TODO - if '' - if typname not in self._template_typenames: self._template_typenames.append( typname ) - else: info['returns'] = ' '.join( a ) - else: info['returns'] = ' '.join( a ) - info['returns'] = info['returns'].replace(' <', '<').strip() - - ## be careful with templates, do not count pointers inside template - info['returns_pointer'] = info['returns'].split('>')[-1].count('*') - if info['returns_pointer']: info['returns'] = info['returns'].replace('*','').strip() - - info['returns_reference'] = '&' in info['returns'] - if info['returns']: info['returns'] = info['returns'].replace('&','').strip() - - a = [] - for b in info['returns'].split(): - if b == '__const__': info['returns_const'] = True - elif b == 'const': info['returns_const'] = True - else: a.append( b ) - info['returns'] = ' '.join( a ) - - info['returns_fundamental'] = is_fundamental( info['returns'] ) - return info - - def evaluate_method_stack(self): - """Create a method out of the name stack""" - - if self.curStruct: - trace_print( 'WARN - struct contains methods - skipping' ) - trace_print( self.stack ) - assert 0 - - info = self.parse_method_type( self.stack ) - if info: - if info[ 'class' ] and info['class'] in self.classes: # case where methods are defined outside of class - newMethod = CppMethod(self.nameStack, info['name'], info) - klass = self.classes[ info['class'] ] - klass[ 'methods' ][ 'public' ].append( newMethod ) - newMethod['parent'] = klass - if klass['namespace']: newMethod['path'] = klass['namespace'] + '::' + klass['name'] - else: newMethod['path'] = klass['name'] - - elif self.curClass: # normal case - newMethod = CppMethod(self.nameStack, self.curClass, info) - klass = self.classes[self.curClass] - klass['methods'][self.curAccessSpecifier].append(newMethod) - newMethod['parent'] = klass - if klass['namespace']: newMethod['path'] = klass['namespace'] + '::' + klass['name'] - else: newMethod['path'] = klass['name'] - else: #non class functions - debug_print("FREE FUNCTION") - newMethod = CppMethod(self.nameStack, None, info) - self.functions.append(newMethod) - global parseHistory - parseHistory.append({"braceDepth": self.braceDepth, "item_type": "method", "item": newMethod}) - else: - trace_print( 'free function?', self.nameStack ) - - self.stack = [] - - def _parse_typedef( self, stack, namespace='' ): - if not stack or 'typedef' not in stack: return - stack = list( stack ) # copy just to be safe - if stack[-1] == ';': stack.pop() - - while stack and stack[-1].isdigit(): stack.pop() # throw away array size for now - - idx = stack.index('typedef') - name = namespace + stack[-1] - s = '' - for a in stack[idx+1:-1]: - if a == '{': break - if not s or s[-1] in ':<>' or a in ':<>': s += a # keep compact - else: s += ' ' + a # spacing - - r = {'name':name, 'raw':s, 'type':s} - if not is_fundamental(s): - if 'struct' in s.split(): pass # TODO is this right? "struct ns::something" - elif '::' not in s: s = namespace + s # only add the current name space if no namespace given - r['type'] = s - if s: return r - - - def evaluate_typedef(self): - ns = self.cur_namespace(add_double_colon=True) - res = self._parse_typedef( self.stack, ns ) - if res: - name = res['name'] - self.typedefs[ name ] = res['type'] - if name not in self.typedefs_order: self.typedefs_order.append( name ) - - - def evaluate_property_stack(self): - """Create a Property out of the name stack""" - global parseHistory - assert self.stack[-1] == ';' - if self.nameStack[0] == 'typedef': - if self.curClass: - typedef = self._parse_typedef( self.stack ) - name = typedef['name'] - klass = self.classes[ self.curClass ] - klass[ 'typedefs' ][ self.curAccessSpecifier ].append( name ) - if self.curAccessSpecifier == 'public': klass._public_typedefs[ name ] = typedef['type'] - Resolver.SubTypedefs[ name ] = self.curClass - else: assert 0 - elif self.curStruct or self.curClass: - if len(self.nameStack) == 1: - #See if we can de anonymize the type - filteredParseHistory = [h for h in parseHistory if h["braceDepth"] == self.braceDepth] - if len(filteredParseHistory) and filteredParseHistory[-1]["item_type"] == "class": - self.nameStack.insert(0, filteredParseHistory[-1]["item"]["name"]) - debug_print("DEANONYMOIZING %s to type '%s'"%(self.nameStack[1], self.nameStack[0])) - if "," in self.nameStack: #Maybe we have a variable list - #Figure out what part is the variable separator but remember templates of function pointer - #First find left most comma outside of a > and ) - leftMostComma = 0; - for i in range(0, len(self.nameStack)): - name = self.nameStack[i] - if name in (">", ")"): leftMostComma = 0 - if leftMostComma == 0 and name == ",": leftMostComma = i - # Is it really a list of variables? - if leftMostComma != 0: - trace_print("Multiple variables for namestack in %s. Separating processing"%self.nameStack) - orig_nameStack = self.nameStack[:] - orig_stack = self.stack[:] - - type_nameStack = orig_nameStack[:leftMostComma-1] - for name in orig_nameStack[leftMostComma - 1::2]: - self.nameStack = type_nameStack + [name] - self.stack = orig_stack[:] # Not maintained for mucking, but this path it doesnt matter - self.evaluate_property_stack() - return - - newVar = CppVariable(self.nameStack) - newVar['namespace'] = self.current_namespace() - if self.curStruct: - self.curStruct[ 'fields' ].append( newVar ) - newVar['property_of_struct'] = self.curStruct - elif self.curClass: - klass = self.classes[self.curClass] - klass["properties"][self.curAccessSpecifier].append(newVar) - newVar['property_of_class'] = klass['name'] - parseHistory.append({"braceDepth": self.braceDepth, "item_type": "variable", "item": newVar}) - - self.stack = [] # CLEAR STACK - - def evaluate_class_stack(self): - """Create a Class out of the name stack (but not its parts)""" - #dont support sub classes today - #print( 'eval class stack', self.nameStack ) - parent = self.curClass - if self.braceDepth > len( self.nameSpaces) and parent: - trace_print( 'HIT NESTED SUBCLASS' ) - self.accessSpecifierStack.append(self.curAccessSpecifier) - elif self.braceDepth != len(self.nameSpaces): - error_print( 'ERROR: WRONG BRACE DEPTH' ) - return - - if self.nameStack[0] == "class": - self.curAccessSpecifier = 'private' - else:#struct - self.curAccessSpecifier = 'public' - debug_print("curAccessSpecifier changed/defaulted to %s"%self.curAccessSpecifier) - if self.nameStack[0] == "union": - newClass = CppUnion(self.nameStack) - self.anon_union_counter = [self.braceDepth, 2] - trace_print( 'NEW UNION', newClass['name'] ) - else: - newClass = CppClass(self.nameStack) - trace_print( 'NEW CLASS', newClass['name'] ) - newClass["declaration_method"] = self.nameStack[0] - self.classes_order.append( newClass ) # good idea to save ordering - self.stack = [] # fixes if class declared with ';' in closing brace - if parent: - newClass["namespace"] = self.classes[ parent ]['namespace'] + '::' + parent - newClass['parent'] = parent - self.classes[ parent ]['nested_classes'].append( newClass ) - ## supports nested classes with the same name ## - self.curClass = key = parent+'::'+newClass['name'] - self._classes_brace_level[ key ] = self.braceDepth - - elif newClass['parent']: # nested class defined outside of parent. A::B {...} - parent = newClass['parent'] - newClass["namespace"] = self.classes[ parent ]['namespace'] + '::' + parent - self.classes[ parent ]['nested_classes'].append( newClass ) - ## supports nested classes with the same name ## - self.curClass = key = parent+'::'+newClass['name'] - self._classes_brace_level[ key ] = self.braceDepth - - else: - newClass["namespace"] = self.cur_namespace() - key = newClass['name'] - self.curClass = newClass["name"] - self._classes_brace_level[ newClass['name'] ] = self.braceDepth - - if not key.endswith("::") and not key.endswith(" ") and len(key) != 0: - if key in self.classes: - trace_print( 'ERROR name collision:', key ) - self.classes[key].show() - trace_print('-'*80) - newClass.show() - assert key not in self.classes # namespace collision - self.classes[ key ] = newClass - global parseHistory - parseHistory.append({"braceDepth": self.braceDepth, "item_type": "class", "item": newClass}) - - - def evalute_forward_decl(self): - trace_print( 'FORWARD DECL', self.nameStack ) - assert self.nameStack[0] in ('class', 'struct') - name = self.nameStack[-1] - if self.curClass: - klass = self.classes[ self.curClass ] - klass['forward_declares'][self.curAccessSpecifier].append( name ) - if self.curAccessSpecifier == 'public': klass._public_forward_declares.append( name ) - else: self._forward_decls.append( name ) - -class CppHeader( _CppHeader ): - """Parsed C++ class header - - Variables produced: - self.classes - Dictionary of classes found in a given header file where the - key is the name of the class - """ - IGNORE_NAMES = '__extension__'.split() - - def show(self): - for className in list(self.classes.keys()):self.classes[className].show() - - def __init__(self, headerFileName, argType="file", **kwargs): - """Create the parsed C++ header file parse tree - - headerFileName - Name of the file to parse OR actual file contents (depends on argType) - argType - Indicates how to interpret headerFileName as a file string or file name - kwargs - Supports the following keywords - """ - ## reset global state ## - global doxygenCommentCache - doxygenCommentCache = "" - CppVariable.Vars = [] - CppStruct.Structs = [] - - if (argType == "file"): - self.headerFileName = os.path.expandvars(headerFileName) - self.mainClass = os.path.split(self.headerFileName)[1][:-2] - headerFileStr = "" - elif argType == "string": - self.headerFileName = "" - self.mainClass = "???" - headerFileStr = headerFileName - else: - raise Exception("Arg type must be either file or string") - self.curClass = "" - - # nested classes have parent::nested, but no extra namespace, - # this keeps the API compatible, TODO proper namespace for everything. - Resolver.CLASSES = {} - self.classes = Resolver.CLASSES - #Functions that are not part of a class - self.functions = [] - - self.pragmas = [] - self.defines = [] - self.includes = [] - self._precomp_macro_buf = [] #for internal purposes, will end up filling out pragmras and defines at the end - - self.enums = [] - self.global_enums = {} - self.nameStack = [] - self.nameSpaces = [] - self.curAccessSpecifier = 'private' # private is default - self.accessSpecifierStack = [] - self.accessSpecifierScratch = [] - debug_print("curAccessSpecifier changed/defaulted to %s"%self.curAccessSpecifier) - self.initextra() - - self.anon_union_counter = [-1, 0] - - if (len(self.headerFileName)): - fd = open(self.headerFileName) - headerFileStr = "".join(fd.readlines()) - fd.close() - - # Make sure supportedAccessSpecifier are sane - for i in range(0, len(supportedAccessSpecifier)): - if " " not in supportedAccessSpecifier[i]: continue - supportedAccessSpecifier[i] = re.sub("[ ]+", " ", supportedAccessSpecifier[i]).strip() - - # Strip out template declarations - headerFileStr = re.sub("template[\t ]*<[^>]*>", "", headerFileStr) - - # Change multi line #defines and expressions to single lines maintaining line nubmers - # Based from http://stackoverflow.com/questions/2424458/regular-expression-to-match-cs-multiline-preprocessor-statements - matches = re.findall(r'(?m)^(?:.*\\\r?\n)+.*$', headerFileStr) - is_define = re.compile(r'[ \t\v]*#[Dd][Ee][Ff][Ii][Nn][Ee]') - for m in matches: - #Keep the newlines so that linecount doesnt break - num_newlines = len([a for a in m if a=="\n"]) - if is_define.match(m): - new_m = m.replace("\n", "\\n") - else: - # Just expression taking up multiple lines, make it take 1 line for easier parsing - new_m = m.replace("\\\n", " ") - if (num_newlines > 0): - new_m += "\n"*(num_newlines) - headerFileStr = headerFileStr.replace(m, new_m) - - #Filter out Extern "C" statements. These are order dependent - matches = re.findall(re.compile(r'extern[\t ]+"[Cc]"[\t \n\r]*{', re.DOTALL), headerFileStr) - for m in matches: - #Keep the newlines so that linecount doesnt break - num_newlines = len([a for a in m if a=="\n"]) - headerFileStr = headerFileStr.replace(m, "\n" * num_newlines) - headerFileStr = re.sub(r'extern[ ]+"[Cc]"[ ]*', "", headerFileStr) - - #Filter out any ignore symbols that end with "()" to account for #define magic functions - for ignore in ignoreSymbols: - if not ignore.endswith("()"): continue - while True: - locStart = headerFileStr.find(ignore[:-1]) - if locStart == -1: - break; - locEnd = None - #Now walk till we find the last paren and account for sub parens - parenCount = 1 - inQuotes = False - for i in range(locStart + len(ignore) - 1, len(headerFileStr)): - c = headerFileStr[i] - if not inQuotes: - if c == "(": - parenCount += 1 - elif c == ")": - parenCount -= 1 - elif c == '"': - inQuotes = True - if parenCount == 0: - locEnd = i + 1 - break; - else: - if c == '"' and headerFileStr[i-1] != '\\': - inQuotes = False - - if locEnd: - #Strip it out but keep the linecount the same so line numbers are right - match_str = headerFileStr[locStart:locEnd] - debug_print("Striping out '%s'"%match_str) - num_newlines = len([a for a in match_str if a=="\n"]) - headerFileStr = headerFileStr.replace(headerFileStr[locStart:locEnd], "\n"*num_newlines) - - self.braceDepth = 0 - lex.lex() - lex.input(headerFileStr) - global curLine - global curChar - curLine = 0 - curChar = 0 - try: - while True: - tok = lex.token() - if not tok: break - if self.anon_union_counter[0] == self.braceDepth and self.anon_union_counter[1]: - self.anon_union_counter[1] -= 1 - tok.value = TagStr(tok.value, lineno=tok.lineno) - #debug_print("TOK: %s"%tok) - if tok.type == 'NAME' and tok.value in self.IGNORE_NAMES: continue - self.stack.append( tok.value ) - curLine = tok.lineno - curChar = tok.lexpos - if (tok.type in ('PRECOMP_MACRO', 'PRECOMP_MACRO_CONT')): - debug_print("PRECOMP: %s"%tok) - self._precomp_macro_buf.append(tok.value) - self.stack = [] - self.nameStack = [] - continue - if (tok.type == 'OPEN_BRACE'): - if len(self.nameStack) >= 2 and is_namespace(self.nameStack): # namespace {} with no name used in boost, this sets default? - if self.nameStack[1] == "__IGNORED_NAMESPACE__CppHeaderParser__":#Used in filtering extern "C" - self.nameStack[1] = "" - self.nameSpaces.append(self.nameStack[1]) - ns = self.cur_namespace(); self.stack = [] - if ns not in self.namespaces: self.namespaces.append( ns ) - # Detect special condition of macro magic before class declaration so we - # can filter it out - if 'class' in self.nameStack and self.nameStack[0] != 'class': - classLocationNS = self.nameStack.index("class") - classLocationS = self.stack.index("class") - if "(" not in self.nameStack[classLocationNS:]: - debug_print("keyword 'class' found in unexpected location in nameStack, must be following #define magic. Process that before moving on") - origNameStack = self.nameStack - origStack = self.stack - #Process first part of stack which is probably #define macro magic and may cause issues - self.nameStack = self.nameStack[:classLocationNS] - self.stack = self.stack[:classLocationS] - try: - self.evaluate_stack() - except: - debug_print("Error processing #define magic... Oh well") - #Process rest of stack - self.nameStack = origNameStack[classLocationNS:] - self.stack = origStack[classLocationS:] - - - if len(self.nameStack) and not is_enum_namestack(self.nameStack): - self.evaluate_stack() - else: - self.nameStack.append(tok.value) - if self.stack and self.stack[0] == 'class': self.stack = [] - self.braceDepth += 1 - - elif (tok.type == 'CLOSE_BRACE'): - if self.braceDepth == 0: - continue - if (self.braceDepth == len(self.nameSpaces)): - tmp = self.nameSpaces.pop() - self.stack = [] # clear stack when namespace ends? - if len(self.nameStack) and is_enum_namestack(self.nameStack): - self.nameStack.append(tok.value) - elif self.braceDepth < 10: - self.evaluate_stack() - else: - self.nameStack = [] - self.braceDepth -= 1 - #self.stack = []; print 'BRACE DEPTH', self.braceDepth, 'NS', len(self.nameSpaces) - if self.curClass: debug_print( 'CURBD %s'%self._classes_brace_level[ self.curClass ] ) - - if (self.braceDepth == 0) or (self.curClass and self._classes_brace_level[self.curClass]==self.braceDepth): - trace_print( 'END OF CLASS DEF' ) - if self.accessSpecifierStack: - self.curAccessSpecifier = self.accessSpecifierStack[-1] - self.accessSpecifierStack = self.accessSpecifierStack[:-1] - if self.curClass and self.classes[ self.curClass ]['parent']: self.curClass = self.classes[ self.curClass ]['parent'] - else: self.curClass = ""; #self.curStruct = None - self.stack = [] - - #if self.curStruct: self.curStruct = None - if self.braceDepth == 0 or (self.curStruct and self._structs_brace_level[self.curStruct['type']]==self.braceDepth): - trace_print( 'END OF STRUCT DEF' ) - self.curStruct = None - - if self._method_body and (self.braceDepth + 1) <= self._method_body: - self._method_body = None; self.stack = []; self.nameStack = []; trace_print( 'FORCE CLEAR METHBODY' ) - - if (tok.type == 'OPEN_PAREN'): - self.nameStack.append(tok.value) - elif (tok.type == 'CLOSE_PAREN'): - self.nameStack.append(tok.value) - elif (tok.type == 'OPEN_SQUARE_BRACKET'): - self.nameStack.append(tok.value) - elif (tok.type == 'CLOSE_SQUARE_BRACKET'): - self.nameStack.append(tok.value) - elif (tok.type == 'TAB'): pass - elif (tok.type == 'EQUALS'): - self.nameStack.append(tok.value) - elif (tok.type == 'COMMA'): - self.nameStack.append(tok.value) - elif (tok.type == 'BACKSLASH'): - self.nameStack.append(tok.value) - elif (tok.type == 'PIPE'): - self.nameStack.append(tok.value) - elif (tok.type == 'PERCENT'): - self.nameStack.append(tok.value) - elif (tok.type == 'CARET'): - self.nameStack.append(tok.value) - elif (tok.type == 'EXCLAMATION'): - self.nameStack.append(tok.value) - elif (tok.type == 'SQUOTE'): pass - elif (tok.type == 'NUMBER'): - self.nameStack.append(tok.value) - elif (tok.type == 'MINUS'): - self.nameStack.append(tok.value) - elif (tok.type == 'PLUS'): - self.nameStack.append(tok.value) - elif (tok.type == 'STRING_LITERAL'): - self.nameStack.append(tok.value) - elif (tok.type == 'NAME' or tok.type == 'AMPERSTAND' or tok.type == 'ASTERISK' or tok.type == 'CHAR_LITERAL'): - if tok.value in ignoreSymbols: - debug_print("Ignore symbol %s"%tok.value) - elif (tok.value == 'class'): - self.nameStack.append(tok.value) - elif tok.value in supportedAccessSpecifier: - if len(self.nameStack) and self.nameStack[0] in ("class", "struct", "union"): - self.nameStack.append(tok.value) - elif self.braceDepth == len(self.nameSpaces) + 1 or self.braceDepth == (len(self.nameSpaces) + len(self.curClass.split("::"))): - self.curAccessSpecifier = tok.value; - self.accessSpecifierScratch.append(tok.value) - debug_print("curAccessSpecifier updated to %s"%self.curAccessSpecifier) - self.stack = [] - else: - self.nameStack.append(tok.value) - if self.anon_union_counter[0] == self.braceDepth: - self.anon_union_counter = [-1, 0] - elif (tok.type == 'COLON'): - #Dont want colon to be first in stack - if len(self.nameStack) == 0: - self.accessSpecifierScratch = [] - continue - - # Handle situation where access specifiers can be multi words such as "public slots" - jns = " ".join(self.accessSpecifierScratch + self.nameStack) - if jns in supportedAccessSpecifier: - self.curAccessSpecifier = jns; - debug_print("curAccessSpecifier updated to %s"%self.curAccessSpecifier) - self.stack = [] - self.nameStack = [] - else: - self.nameStack.append(tok.value) - self.accessSpecifierScratch = [] - - elif (tok.type == 'SEMI_COLON'): - if self.anon_union_counter[0] == self.braceDepth and self.anon_union_counter[1]: - debug_print("Creating anonymous union") - #Force the processing of an anonymous union - saved_namestack = self.nameStack[:] - saved_stack = self.stack[:] - self.nameStack = [""] - self.stack = self.nameStack + [";"] - self.nameStack = self.nameStack[0:1] - debug_print("pre eval anon stack") - self.evaluate_stack( tok.type ) - debug_print("post eval anon stack") - self.nameStack = saved_namestack - self.stack = saved_stack - self.anon_union_counter = [-1, 0]; - - - if (self.braceDepth < 10): self.evaluate_stack( tok.type ) - self.stack = [] - self.nameStack = [] - - except: - if (debug): raise - raise CppParseError("Not able to parse %s on line %d evaluating \"%s\"\nError around: %s" - % (self.headerFileName, tok.lineno, tok.value, " ".join(self.nameStack))) - - self.finalize() - global parseHistory - parseHistory = [] - - def evaluate_stack(self, token=None): - """Evaluates the current name stack""" - global doxygenCommentCache - - self.nameStack = filter_out_attribute_keyword(self.nameStack) - self.stack = filter_out_attribute_keyword(self.stack) - - debug_print( "Evaluating stack %s\n BraceDepth: %s (called from %d)" %(self.nameStack,self.braceDepth, inspect.currentframe().f_back.f_lineno)) - - #Handle special case of overloading operator () - if "operator()(" in "".join(self.nameStack): - operator_index = self.nameStack.index("operator") - self.nameStack.pop(operator_index + 2) - self.nameStack.pop(operator_index + 1) - self.nameStack[operator_index] = "operator()" - - if (len(self.curClass)): - debug_print( "%s (%s) "%(self.curClass, self.curAccessSpecifier)) - - #Filter special case of array with casting in it - try: - bracePos = self.nameStack.index("[") - parenPos = self.nameStack.index("(") - if bracePos == parenPos - 1: - endParen = self.nameStack.index(")") - self.nameStack = self.nameStack[:bracePos + 1] + self.nameStack[endParen + 1:] - debug_print("Filtered namestack to=%s"%self.nameStack) - except: pass - - #if 'typedef' in self.nameStack: self.evaluate_typedef() # allows nested typedefs, probably a bad idea - if not self.curClass and 'typedef' in self.nameStack: - trace_print('STACK', self.stack) - self.evaluate_typedef() - return - - elif (len(self.nameStack) == 0): - debug_print( "trace" ) - debug_print( "(Empty Stack)" ) - return - elif (self.nameStack[0] == "namespace"): - #Taken care of outside of here - pass - elif len(self.nameStack) == 2 and self.nameStack[0] == "friend":#friend class declaration - pass - elif len(self.nameStack) >= 2 and self.nameStack[0] == 'using' and self.nameStack[1] == 'namespace': pass # TODO - - elif is_enum_namestack(self.nameStack): - debug_print( "trace" ) - self.evaluate_enum_stack() - - elif self._method_body and (self.braceDepth + 1) > self._method_body: trace_print( 'INSIDE METHOD DEF' ) - elif is_method_namestack(self.stack) and not self.curStruct and '(' in self.nameStack: - debug_print( "trace" ) - if self.braceDepth > 0: - if "{" in self.stack and self.stack[0] != '{' and self.stack[-1] == ';' and self.braceDepth == 1: - #Special case of a method defined outside a class that has a body - pass - else: - self.evaluate_method_stack() - else: - #Free function - self.evaluate_method_stack() - elif is_property_namestack(self.nameStack) and self.stack[-1] == ';': - debug_print( "trace" ) - if self.nameStack[0] in ('class', 'struct') and len(self.stack) == 3: self.evalute_forward_decl() - elif len(self.nameStack) >= 2 and (self.nameStack[0]=='friend' and self.nameStack[1]=='class'): pass - else: self.evaluate_property_stack() # catches class props and structs in a namespace - - elif self.nameStack[0] in ("class", "struct", "union"): - #Parsing a union can reuse much of the class parsing - debug_print( "trace" ) - self.evaluate_class_stack() - #elif (self.nameStack[0] == "struct"): - # debug_print( "trace" ) - ##this causes a bug when structs are nested in protected or private##self.curAccessSpecifier = "public" - # self.evaluate_struct_stack() - - - elif not self.curClass: - debug_print( "trace" ) - if is_enum_namestack(self.nameStack): self.evaluate_enum_stack() - elif self.curStruct and self.stack[-1] == ';': self.evaluate_property_stack() # this catches fields of global structs - self.nameStack = [] - doxygenCommentCache = "" - return - elif (self.braceDepth < 1): - debug_print( "trace" ) - #Ignore global stuff for now - debug_print( "Global stuff: %s"%self.nameStack ) - self.nameStack = [] - doxygenCommentCache = "" - return - elif (self.braceDepth > len(self.nameSpaces) + 1): - debug_print( "trace" ) - self.nameStack = [] - doxygenCommentCache = "" - return - - self.nameStack = [] # its a little confusing to have some if/else above return and others not, and then clearning the nameStack down here - doxygenCommentCache = "" - - - def evaluate_enum_stack(self): - """Create an Enum out of the name stack""" - debug_print( "evaluating enum" ) - newEnum = CppEnum(self.nameStack) - if len(list(newEnum.keys())): - if len(self.curClass): - newEnum["namespace"] = self.cur_namespace(False) - klass = self.classes[self.curClass] - klass["enums"][self.curAccessSpecifier].append(newEnum) - if self.curAccessSpecifier == 'public' and 'name' in newEnum: klass._public_enums[ newEnum['name'] ] = newEnum - else: - newEnum["namespace"] = self.cur_namespace(True) - self.enums.append(newEnum) - if 'name' in newEnum and newEnum['name']: self.global_enums[ newEnum['name'] ] = newEnum - - #This enum has instances, turn them into properties - if "instances" in newEnum: - instanceType = "enum" - if "name" in newEnum: - instanceType = newEnum["name"] - for instance in newEnum["instances"]: - self.nameStack = [instanceType, instance] - self.evaluate_property_stack() - del newEnum["instances"] - - - def __repr__(self): - rtn = "" - for className in list(self.classes.keys()): - rtn += "%s\n"%self.classes[className] - if self.functions: - rtn += "// functions\n" - for f in self.functions: - rtn += "%s\n"%f - if self.enums: - rtn += "// enums\n" - for f in self.enums: - rtn += "%s\n"%f - return rtn diff --git a/cppParser/CppHeaderParser/__init__.py b/cppParser/CppHeaderParser/__init__.py deleted file mode 100644 index 5af3d18..0000000 --- a/cppParser/CppHeaderParser/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# CppHeaderParser package -# Author: Jashua Cloutier (contact via sourceforge username:senexcanis) -import sys -if sys.version_info[0] == 2: - from CppHeaderParser import * -else: - from CppHeaderParser3 import * - -#__all__ = ['CppHeaderParser'] diff --git a/cppParser/CppHeaderParser/doc/CppHeaderParser.html b/cppParser/CppHeaderParser/doc/CppHeaderParser.html deleted file mode 100644 index 5432924..0000000 --- a/cppParser/CppHeaderParser/doc/CppHeaderParser.html +++ /dev/null @@ -1,1445 +0,0 @@ - - -Python: module CppHeaderParser - - - - -
 
- 
CppHeaderParser (version 2.4)
index
/home/senex/workspace/cppheaderparser/CppHeaderParser/CppHeaderParser.py
-

Parse C++ header files and generate a data structure
-representing the class

-

- - - - - -
 
-Modules
       
inspect
-ply.lex
-
os
-re
-
sys
-

- - - - - -
 
-Classes
       
-
_CppEnum(__builtin__.dict) -
-
-
CppEnum -
-
-
_CppHeader(Resolver) -
-
-
CppHeader -
-
-
_CppMethod(__builtin__.dict) -
-
-
CppMethod -
-
-
_CppVariable(__builtin__.dict) -
-
-
CppVariable -
-
-
__builtin__.dict(__builtin__.object) -
-
-
CppClass -
-
-
CppUnion -
-
-
CppStruct -
-
-
__builtin__.object -
-
-
Resolver -
-
-
__builtin__.str(__builtin__.basestring) -
-
-
TagStr -
-
-
exceptions.Exception(exceptions.BaseException) -
-
-
CppParseError -
-
-
-

- - - - - - - -
 
-class CppClass(__builtin__.dict)
   Takes a name stack and turns it into a class

-Contains the following Keys:
-self['name'] - Name of the class
-self['doxygen'] - Doxygen comments associated with the class if they exist
-self['inherits'] - List of Classes that this one inherits where the values
-    are of the form {"access": Anything in supportedAccessSpecifier
-                              "class": Name of the class
-self['methods'] - Dictionary where keys are from supportedAccessSpecifier
-    and values are a lists of CppMethod's
-self['properties'] - Dictionary where keys are from supportedAccessSpecifier
-    and values are lists of CppVariable's 
-self['enums'] - Dictionary where keys are from supportedAccessSpecifier and
-    values are lists of CppEnum's
-self['structs'] - Dictionary where keys are from supportedAccessSpecifier and
-    values are lists of nested Struct's

-An example of how this could look is as follows:
-#self =
-{
-    'name': ""
-    'inherits':[]
-    'methods':
-    {
-        'public':[],
-        'protected':[], 
-        'private':[]
-    }, 
-    'properties':
-    {
-        'public':[],
-        'protected':[], 
-        'private':[]
-    },
-    'enums':
-    {
-        'public':[],
-        'protected':[], 
-        'private':[]
-    }
-}
 
 
Method resolution order:
-
CppClass
-
__builtin__.dict
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, nameStack)
- -
__repr__(self)
Convert class to a string
- -
get_all_method_names(self)
- -
get_all_methods(self)
- -
get_all_pure_virtual_methods(self)
- -
get_method_names(self, type='public')
- -
get_pure_virtual_methods(self, type='public')
- -
show(self)
Convert class to a string
- -
-Data descriptors defined here:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Methods inherited from __builtin__.dict:
-
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
- -
__contains__(...)
D.__contains__(k) -> True if D has a key k, else False
- -
__delitem__(...)
x.__delitem__(y) <==> del x[y]
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__iter__(...)
x.__iter__() <==> iter(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__setitem__(...)
x.__setitem__(i, y) <==> x[i]=y
- -
__sizeof__(...)
D.__sizeof__() -> size of D in memory, in bytes
- -
clear(...)
D.clear() -> None.  Remove all items from D.
- -
copy(...)
D.copy() -> a shallow copy of D
- -
fromkeys(...)
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
-v defaults to None.
- -
get(...)
D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
- -
has_key(...)
D.has_key(k) -> True if D has a key k, else False
- -
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
- -
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
- -
iterkeys(...)
D.iterkeys() -> an iterator over the keys of D
- -
itervalues(...)
D.itervalues() -> an iterator over the values of D
- -
keys(...)
D.keys() -> list of D's keys
- -
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-If key is not found, d is returned if given, otherwise KeyError is raised
- -
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
-2-tuple; but raise KeyError if D is empty.
- -
setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
- -
update(...)
D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
-If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
-If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
-In either case, this is followed by: for k in F: D[k] = F[k]
- -
values(...)
D.values() -> list of D's values
- -
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
- -
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
- -
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
- -
-Data and other attributes inherited from __builtin__.dict:
-
__hash__ = None
- -
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -

- - - - - - - -
 
-class CppEnum(_CppEnum)
   Takes a name stack and turns it into an Enum

-Contains the following Keys:
-self['name'] - Name of the enum (ex. "ItemState")
-self['namespace'] - Namespace containing the enum
-self['values'] - List of values where the values are a dictionary of the
-    form {"name": name of the key (ex. "PARSING_HEADER"),
-              "value": Specified value of the enum, this key will only exist
-                if a value for a given enum value was defined
-            }
 
 
Method resolution order:
-
CppEnum
-
_CppEnum
-
__builtin__.dict
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, nameStack)
- -
-Methods inherited from _CppEnum:
-
resolve_enum_values(self, values)
Evaluates the values list of dictionaries passed in and figures out what the enum value
-for each enum is editing in place:

-Example:
-From: [{'name': 'ORANGE'},
-       {'name': 'RED'},
-       {'name': 'GREEN', 'value': '8'}]
-To:   [{'name': 'ORANGE', 'value': 0},
-       {'name': 'RED', 'value': 1},
-       {'name': 'GREEN', 'value': 8}]
- -
-Data descriptors inherited from _CppEnum:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Methods inherited from __builtin__.dict:
-
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
- -
__contains__(...)
D.__contains__(k) -> True if D has a key k, else False
- -
__delitem__(...)
x.__delitem__(y) <==> del x[y]
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__iter__(...)
x.__iter__() <==> iter(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__setitem__(...)
x.__setitem__(i, y) <==> x[i]=y
- -
__sizeof__(...)
D.__sizeof__() -> size of D in memory, in bytes
- -
clear(...)
D.clear() -> None.  Remove all items from D.
- -
copy(...)
D.copy() -> a shallow copy of D
- -
fromkeys(...)
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
-v defaults to None.
- -
get(...)
D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
- -
has_key(...)
D.has_key(k) -> True if D has a key k, else False
- -
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
- -
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
- -
iterkeys(...)
D.iterkeys() -> an iterator over the keys of D
- -
itervalues(...)
D.itervalues() -> an iterator over the values of D
- -
keys(...)
D.keys() -> list of D's keys
- -
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-If key is not found, d is returned if given, otherwise KeyError is raised
- -
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
-2-tuple; but raise KeyError if D is empty.
- -
setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
- -
update(...)
D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
-If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
-If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
-In either case, this is followed by: for k in F: D[k] = F[k]
- -
values(...)
D.values() -> list of D's values
- -
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
- -
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
- -
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
- -
-Data and other attributes inherited from __builtin__.dict:
-
__hash__ = None
- -
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -

- - - - - - - -
 
-class CppHeader(_CppHeader)
   Parsed C++ class header

-Variables produced:
-self.classes - Dictionary of classes found in a given header file where the
-    key is the name of the class
 
 
Method resolution order:
-
CppHeader
-
_CppHeader
-
Resolver
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, headerFileName, argType='file', **kwargs)
Create the parsed C++ header file parse tree

-headerFileName - Name of the file to parse OR actual file contents (depends on argType)
-argType - Indicates how to interpret headerFileName as a file string or file name
-kwargs - Supports the following keywords
- -
__repr__(self)
- -
evaluate_enum_stack(self)
Create an Enum out of the name stack
- -
evaluate_stack(self, token=None)
Evaluates the current name stack
- -
show(self)
- -
-Data and other attributes defined here:
-
IGNORE_NAMES = ['__extension__']
- -
-Methods inherited from _CppHeader:
-
evaluate_class_stack(self)
Create a Class out of the name stack (but not its parts)
- -
evaluate_method_stack(self)
Create a method out of the name stack
- -
evaluate_property_stack(self)
Create a Property out of the name stack
- -
evaluate_struct_stack(self)
Create a Struct out of the name stack (but not its parts)
- -
evaluate_typedef(self)
- -
evalute_forward_decl(self)
- -
finalize(self)
- -
parse_method_type(self, stack)
- -
-Methods inherited from Resolver:
-
concrete_typedef(self, key)
- -
cur_namespace(self, add_double_colon=False)
- -
current_namespace(self)
- -
finalize_vars(self)
- -
guess_ctypes_type(self, string)
- -
initextra(self)
- -
resolve_type(self, string, result)
keeps track of useful things like: how many pointers, number of typedefs, is fundamental or a class, etc...
- -
-Data descriptors inherited from Resolver:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Data and other attributes inherited from Resolver:
-
CLASSES = {}
- -
C_FUNDAMENTAL = ['size_t', 'unsigned', 'signed', 'bool', 'char', 'wchar', 'short', 'int', 'float', 'double', 'long', 'void', 'struct', 'union', 'enum']
- -
NAMESPACES = []
- -
STRUCTS = {}
- -
SubTypedefs = {}
- -

- - - - - - - -
 
-class CppMethod(_CppMethod)
   Takes a name stack and turns it into a method

-Contains the following Keys:
-self['rtnType'] - Return type of the method (ex. "int")
-self['name'] - Name of the method (ex. "getSize")
-self['doxygen'] - Doxygen comments associated with the method if they exist
-self['parameters'] - List of CppVariables
 
 
Method resolution order:
-
CppMethod
-
_CppMethod
-
__builtin__.dict
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, nameStack, curClass, methinfo)
- -
__repr__(self)
- -
show(self)
- -
-Data descriptors inherited from _CppMethod:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Methods inherited from __builtin__.dict:
-
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
- -
__contains__(...)
D.__contains__(k) -> True if D has a key k, else False
- -
__delitem__(...)
x.__delitem__(y) <==> del x[y]
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__iter__(...)
x.__iter__() <==> iter(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__setitem__(...)
x.__setitem__(i, y) <==> x[i]=y
- -
__sizeof__(...)
D.__sizeof__() -> size of D in memory, in bytes
- -
clear(...)
D.clear() -> None.  Remove all items from D.
- -
copy(...)
D.copy() -> a shallow copy of D
- -
fromkeys(...)
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
-v defaults to None.
- -
get(...)
D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
- -
has_key(...)
D.has_key(k) -> True if D has a key k, else False
- -
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
- -
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
- -
iterkeys(...)
D.iterkeys() -> an iterator over the keys of D
- -
itervalues(...)
D.itervalues() -> an iterator over the values of D
- -
keys(...)
D.keys() -> list of D's keys
- -
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-If key is not found, d is returned if given, otherwise KeyError is raised
- -
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
-2-tuple; but raise KeyError if D is empty.
- -
setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
- -
update(...)
D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
-If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
-If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
-In either case, this is followed by: for k in F: D[k] = F[k]
- -
values(...)
D.values() -> list of D's values
- -
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
- -
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
- -
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
- -
-Data and other attributes inherited from __builtin__.dict:
-
__hash__ = None
- -
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -

- - - - - -
 
-class CppParseError(exceptions.Exception)
    
Method resolution order:
-
CppParseError
-
exceptions.Exception
-
exceptions.BaseException
-
__builtin__.object
-
-
-Data descriptors defined here:
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Methods inherited from exceptions.Exception:
-
__init__(...)
x.__init__(...) initializes x; see help(type(x)) for signature
- -
-Data and other attributes inherited from exceptions.Exception:
-
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -
-Methods inherited from exceptions.BaseException:
-
__delattr__(...)
x.__delattr__('name') <==> del x.name
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__getslice__(...)
x.__getslice__(i, j) <==> x[i:j]

-Use of negative indices is not supported.
- -
__reduce__(...)
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
- -
__setstate__(...)
- -
__str__(...)
x.__str__() <==> str(x)
- -
__unicode__(...)
- -
-Data descriptors inherited from exceptions.BaseException:
-
__dict__
-
-
args
-
-
message
-
-

- - - - - -
 
-class CppStruct(__builtin__.dict)
    
Method resolution order:
-
CppStruct
-
__builtin__.dict
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, nameStack)
- -
-Data descriptors defined here:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Data and other attributes defined here:
-
Structs = []
- -
-Methods inherited from __builtin__.dict:
-
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
- -
__contains__(...)
D.__contains__(k) -> True if D has a key k, else False
- -
__delitem__(...)
x.__delitem__(y) <==> del x[y]
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__iter__(...)
x.__iter__() <==> iter(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__setitem__(...)
x.__setitem__(i, y) <==> x[i]=y
- -
__sizeof__(...)
D.__sizeof__() -> size of D in memory, in bytes
- -
clear(...)
D.clear() -> None.  Remove all items from D.
- -
copy(...)
D.copy() -> a shallow copy of D
- -
fromkeys(...)
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
-v defaults to None.
- -
get(...)
D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
- -
has_key(...)
D.has_key(k) -> True if D has a key k, else False
- -
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
- -
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
- -
iterkeys(...)
D.iterkeys() -> an iterator over the keys of D
- -
itervalues(...)
D.itervalues() -> an iterator over the values of D
- -
keys(...)
D.keys() -> list of D's keys
- -
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-If key is not found, d is returned if given, otherwise KeyError is raised
- -
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
-2-tuple; but raise KeyError if D is empty.
- -
setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
- -
update(...)
D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
-If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
-If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
-In either case, this is followed by: for k in F: D[k] = F[k]
- -
values(...)
D.values() -> list of D's values
- -
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
- -
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
- -
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
- -
-Data and other attributes inherited from __builtin__.dict:
-
__hash__ = None
- -
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -

- - - - - - - -
 
-class CppUnion(CppClass)
   Takes a name stack and turns it into a union

-Contains the following Keys:
-self['name'] - Name of the union
-self['doxygen'] - Doxygen comments associated with the union if they exist
-self['members'] - List of members the union has 

-An example of how this could look is as follows:
-#self =
-{
-    'name': ""
-    'members': []
-}
 
 
Method resolution order:
-
CppUnion
-
CppClass
-
__builtin__.dict
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, nameStack)
- -
__repr__(self)
Convert class to a string
- -
show(self)
Convert class to a string
- -
transform_to_union_keys(self)
- -
-Methods inherited from CppClass:
-
get_all_method_names(self)
- -
get_all_methods(self)
- -
get_all_pure_virtual_methods(self)
- -
get_method_names(self, type='public')
- -
get_pure_virtual_methods(self, type='public')
- -
-Data descriptors inherited from CppClass:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Methods inherited from __builtin__.dict:
-
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
- -
__contains__(...)
D.__contains__(k) -> True if D has a key k, else False
- -
__delitem__(...)
x.__delitem__(y) <==> del x[y]
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__iter__(...)
x.__iter__() <==> iter(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__setitem__(...)
x.__setitem__(i, y) <==> x[i]=y
- -
__sizeof__(...)
D.__sizeof__() -> size of D in memory, in bytes
- -
clear(...)
D.clear() -> None.  Remove all items from D.
- -
copy(...)
D.copy() -> a shallow copy of D
- -
fromkeys(...)
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
-v defaults to None.
- -
get(...)
D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
- -
has_key(...)
D.has_key(k) -> True if D has a key k, else False
- -
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
- -
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
- -
iterkeys(...)
D.iterkeys() -> an iterator over the keys of D
- -
itervalues(...)
D.itervalues() -> an iterator over the values of D
- -
keys(...)
D.keys() -> list of D's keys
- -
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-If key is not found, d is returned if given, otherwise KeyError is raised
- -
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
-2-tuple; but raise KeyError if D is empty.
- -
setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
- -
update(...)
D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
-If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
-If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
-In either case, this is followed by: for k in F: D[k] = F[k]
- -
values(...)
D.values() -> list of D's values
- -
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
- -
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
- -
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
- -
-Data and other attributes inherited from __builtin__.dict:
-
__hash__ = None
- -
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -

- - - - - - - -
 
-class CppVariable(_CppVariable)
   Takes a name stack and turns it into a method

-Contains the following Keys:
-self['type'] - Type for the variable (ex. "const string &")
-self['name'] - Name of the variable (ex. "numItems")
-self['namespace'] - Namespace containing the enum
-self['desc'] - Description of the variable if part of a method (optional)
-self['doxygen'] - Doxygen comments associated with the method if they exist
-self['defaltValue'] - Default value of the variable, this key will only
-    exist if there is a default value
 
 
Method resolution order:
-
CppVariable
-
_CppVariable
-
__builtin__.dict
-
__builtin__.object
-
-
-Methods defined here:
-
__init__(self, nameStack, **kwargs)
- -
__repr__(self)
- -
-Data and other attributes defined here:
-
Vars = []
- -
-Methods inherited from _CppVariable:
-
init(self)
- -
-Data descriptors inherited from _CppVariable:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Methods inherited from __builtin__.dict:
-
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
- -
__contains__(...)
D.__contains__(k) -> True if D has a key k, else False
- -
__delitem__(...)
x.__delitem__(y) <==> del x[y]
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__iter__(...)
x.__iter__() <==> iter(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__setitem__(...)
x.__setitem__(i, y) <==> x[i]=y
- -
__sizeof__(...)
D.__sizeof__() -> size of D in memory, in bytes
- -
clear(...)
D.clear() -> None.  Remove all items from D.
- -
copy(...)
D.copy() -> a shallow copy of D
- -
fromkeys(...)
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
-v defaults to None.
- -
get(...)
D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
- -
has_key(...)
D.has_key(k) -> True if D has a key k, else False
- -
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
- -
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
- -
iterkeys(...)
D.iterkeys() -> an iterator over the keys of D
- -
itervalues(...)
D.itervalues() -> an iterator over the values of D
- -
keys(...)
D.keys() -> list of D's keys
- -
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-If key is not found, d is returned if given, otherwise KeyError is raised
- -
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
-2-tuple; but raise KeyError if D is empty.
- -
setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
- -
update(...)
D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
-If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
-If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
-In either case, this is followed by: for k in F: D[k] = F[k]
- -
values(...)
D.values() -> list of D's values
- -
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
- -
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
- -
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
- -
-Data and other attributes inherited from __builtin__.dict:
-
__hash__ = None
- -
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
- -

- - - - - -
 
-class Resolver(__builtin__.object)
    Methods defined here:
-
concrete_typedef(self, key)
- -
cur_namespace(self, add_double_colon=False)
- -
current_namespace(self)
- -
finalize_vars(self)
- -
guess_ctypes_type(self, string)
- -
initextra(self)
- -
resolve_type(self, string, result)
keeps track of useful things like: how many pointers, number of typedefs, is fundamental or a class, etc...
- -
-Data descriptors defined here:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
__weakref__
-
list of weak references to the object (if defined)
-
-
-Data and other attributes defined here:
-
CLASSES = {}
- -
C_FUNDAMENTAL = ['size_t', 'unsigned', 'signed', 'bool', 'char', 'wchar', 'short', 'int', 'float', 'double', 'long', 'void', 'struct', 'union', 'enum']
- -
NAMESPACES = []
- -
STRUCTS = {}
- -
SubTypedefs = {}
- -

- - - - - - - -
 
-class TagStr(__builtin__.str)
   Wrapper for a string that allows us to store the line number associated with it
 
 
Method resolution order:
-
TagStr
-
__builtin__.str
-
__builtin__.basestring
-
__builtin__.object
-
-
-Methods defined here:
-
__del__(self)
- -
lineno(self)
- -
-Static methods defined here:
-
__new__(cls, *args, **kw)
- -
-Data descriptors defined here:
-
__dict__
-
dictionary for instance variables (if defined)
-
-
-Data and other attributes defined here:
-
lineno_reg = {}
- -
-Methods inherited from __builtin__.str:
-
__add__(...)
x.__add__(y) <==> x+y
- -
__contains__(...)
x.__contains__(y) <==> y in x
- -
__eq__(...)
x.__eq__(y) <==> x==y
- -
__format__(...)
S.__format__(format_spec) -> string

-Return a formatted version of S as described by format_spec.
- -
__ge__(...)
x.__ge__(y) <==> x>=y
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__getitem__(...)
x.__getitem__(y) <==> x[y]
- -
__getnewargs__(...)
- -
__getslice__(...)
x.__getslice__(i, j) <==> x[i:j]

-Use of negative indices is not supported.
- -
__gt__(...)
x.__gt__(y) <==> x>y
- -
__hash__(...)
x.__hash__() <==> hash(x)
- -
__le__(...)
x.__le__(y) <==> x<=y
- -
__len__(...)
x.__len__() <==> len(x)
- -
__lt__(...)
x.__lt__(y) <==> x<y
- -
__mod__(...)
x.__mod__(y) <==> x%y
- -
__mul__(...)
x.__mul__(n) <==> x*n
- -
__ne__(...)
x.__ne__(y) <==> x!=y
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__rmod__(...)
x.__rmod__(y) <==> y%x
- -
__rmul__(...)
x.__rmul__(n) <==> n*x
- -
__sizeof__(...)
S.__sizeof__() -> size of S in memory, in bytes
- -
__str__(...)
x.__str__() <==> str(x)
- -
capitalize(...)
S.capitalize() -> string

-Return a copy of the string S with only its first character
-capitalized.
- -
center(...)
S.center(width[, fillchar]) -> string

-Return S centered in a string of length width. Padding is
-done using the specified fill character (default is a space)
- -
count(...)
S.count(sub[, start[, end]]) -> int

-Return the number of non-overlapping occurrences of substring sub in
-string S[start:end].  Optional arguments start and end are interpreted
-as in slice notation.
- -
decode(...)
S.decode([encoding[,errors]]) -> object

-Decodes S using the codec registered for encoding. encoding defaults
-to the default encoding. errors may be given to set a different error
-handling scheme. Default is 'strict' meaning that encoding errors raise
-a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
-as well as any other name registered with codecs.register_error that is
-able to handle UnicodeDecodeErrors.
- -
encode(...)
S.encode([encoding[,errors]]) -> object

-Encodes S using the codec registered for encoding. encoding defaults
-to the default encoding. errors may be given to set a different error
-handling scheme. Default is 'strict' meaning that encoding errors raise
-a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and
-'xmlcharrefreplace' as well as any other name registered with
-codecs.register_error that is able to handle UnicodeEncodeErrors.
- -
endswith(...)
S.endswith(suffix[, start[, end]]) -> bool

-Return True if S ends with the specified suffix, False otherwise.
-With optional start, test S beginning at that position.
-With optional end, stop comparing S at that position.
-suffix can also be a tuple of strings to try.
- -
expandtabs(...)
S.expandtabs([tabsize]) -> string

-Return a copy of S where all tab characters are expanded using spaces.
-If tabsize is not given, a tab size of 8 characters is assumed.
- -
find(...)
S.find(sub [,start [,end]]) -> int

-Return the lowest index in S where substring sub is found,
-such that sub is contained within S[start:end].  Optional
-arguments start and end are interpreted as in slice notation.

-Return -1 on failure.
- -
format(...)
S.format(*args, **kwargs) -> string

-Return a formatted version of S, using substitutions from args and kwargs.
-The substitutions are identified by braces ('{' and '}').
- -
index(...)
S.index(sub [,start [,end]]) -> int

-Like S.find() but raise ValueError when the substring is not found.
- -
isalnum(...)
S.isalnum() -> bool

-Return True if all characters in S are alphanumeric
-and there is at least one character in S, False otherwise.
- -
isalpha(...)
S.isalpha() -> bool

-Return True if all characters in S are alphabetic
-and there is at least one character in S, False otherwise.
- -
isdigit(...)
S.isdigit() -> bool

-Return True if all characters in S are digits
-and there is at least one character in S, False otherwise.
- -
islower(...)
S.islower() -> bool

-Return True if all cased characters in S are lowercase and there is
-at least one cased character in S, False otherwise.
- -
isspace(...)
S.isspace() -> bool

-Return True if all characters in S are whitespace
-and there is at least one character in S, False otherwise.
- -
istitle(...)
S.istitle() -> bool

-Return True if S is a titlecased string and there is at least one
-character in S, i.e. uppercase characters may only follow uncased
-characters and lowercase characters only cased ones. Return False
-otherwise.
- -
isupper(...)
S.isupper() -> bool

-Return True if all cased characters in S are uppercase and there is
-at least one cased character in S, False otherwise.
- -
join(...)
S.join(iterable) -> string

-Return a string which is the concatenation of the strings in the
-iterable.  The separator between elements is S.
- -
ljust(...)
S.ljust(width[, fillchar]) -> string

-Return S left-justified in a string of length width. Padding is
-done using the specified fill character (default is a space).
- -
lower(...)
S.lower() -> string

-Return a copy of the string S converted to lowercase.
- -
lstrip(...)
S.lstrip([chars]) -> string or unicode

-Return a copy of the string S with leading whitespace removed.
-If chars is given and not None, remove characters in chars instead.
-If chars is unicode, S will be converted to unicode before stripping
- -
partition(...)
S.partition(sep) -> (head, sep, tail)

-Search for the separator sep in S, and return the part before it,
-the separator itself, and the part after it.  If the separator is not
-found, return S and two empty strings.
- -
replace(...)
S.replace(old, new[, count]) -> string

-Return a copy of string S with all occurrences of substring
-old replaced by new.  If the optional argument count is
-given, only the first count occurrences are replaced.
- -
rfind(...)
S.rfind(sub [,start [,end]]) -> int

-Return the highest index in S where substring sub is found,
-such that sub is contained within S[start:end].  Optional
-arguments start and end are interpreted as in slice notation.

-Return -1 on failure.
- -
rindex(...)
S.rindex(sub [,start [,end]]) -> int

-Like S.rfind() but raise ValueError when the substring is not found.
- -
rjust(...)
S.rjust(width[, fillchar]) -> string

-Return S right-justified in a string of length width. Padding is
-done using the specified fill character (default is a space)
- -
rpartition(...)
S.rpartition(sep) -> (head, sep, tail)

-Search for the separator sep in S, starting at the end of S, and return
-the part before it, the separator itself, and the part after it.  If the
-separator is not found, return two empty strings and S.
- -
rsplit(...)
S.rsplit([sep [,maxsplit]]) -> list of strings

-Return a list of the words in the string S, using sep as the
-delimiter string, starting at the end of the string and working
-to the front.  If maxsplit is given, at most maxsplit splits are
-done. If sep is not specified or is None, any whitespace string
-is a separator.
- -
rstrip(...)
S.rstrip([chars]) -> string or unicode

-Return a copy of the string S with trailing whitespace removed.
-If chars is given and not None, remove characters in chars instead.
-If chars is unicode, S will be converted to unicode before stripping
- -
split(...)
S.split([sep [,maxsplit]]) -> list of strings

-Return a list of the words in the string S, using sep as the
-delimiter string.  If maxsplit is given, at most maxsplit
-splits are done. If sep is not specified or is None, any
-whitespace string is a separator and empty strings are removed
-from the result.
- -
splitlines(...)
S.splitlines(keepends=False) -> list of strings

-Return a list of the lines in S, breaking at line boundaries.
-Line breaks are not included in the resulting list unless keepends
-is given and true.
- -
startswith(...)
S.startswith(prefix[, start[, end]]) -> bool

-Return True if S starts with the specified prefix, False otherwise.
-With optional start, test S beginning at that position.
-With optional end, stop comparing S at that position.
-prefix can also be a tuple of strings to try.
- -
strip(...)
S.strip([chars]) -> string or unicode

-Return a copy of the string S with leading and trailing
-whitespace removed.
-If chars is given and not None, remove characters in chars instead.
-If chars is unicode, S will be converted to unicode before stripping
- -
swapcase(...)
S.swapcase() -> string

-Return a copy of the string S with uppercase characters
-converted to lowercase and vice versa.
- -
title(...)
S.title() -> string

-Return a titlecased version of S, i.e. words start with uppercase
-characters, all remaining cased characters have lowercase.
- -
translate(...)
S.translate(table [,deletechars]) -> string

-Return a copy of the string S, where all characters occurring
-in the optional argument deletechars are removed, and the
-remaining characters have been mapped through the given
-translation table, which must be a string of length 256 or None.
-If the table argument is None, no translation is applied and
-the operation simply removes the characters in deletechars.
- -
upper(...)
S.upper() -> string

-Return a copy of the string S converted to uppercase.
- -
zfill(...)
S.zfill(width) -> string

-Pad a numeric string S with zeros on the left, to fill a field
-of the specified width.  The string S is never truncated.
- -

- - - - - -
 
-Functions
       
debug_print(arg)
-
detect_lineno(s)
Detect the line number for a given token string
-
error_print(arg)
-
filter_out_attribute_keyword(stack)
Strips __attribute__ and its parenthetical expression from the stack
-
is_enum_namestack(nameStack)
Determines if a namestack is an enum namestack
-
is_function_pointer_stack(stack)
Count how many non-nested paranthesis are in the stack.  Useful for determining if a stack is a function pointer
-
is_fundamental(s)
-
is_method_namestack(stack)
-
is_namespace(nameStack)
Determines if a namespace is being specified
-
is_property_namestack(nameStack)
-
lineno()
Returns the current line number in our program.
-
standardize_fundamental(s)
-
t_COMMENT_MULTILINE(t)
/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/
-
t_COMMENT_SINGLELINE(t)
\/\/.*\n
-
t_NEWLINE(t)
\n+
-
t_error(v)
-
trace_print(*arg)
-
warning_print(arg)
-

- - - - - -
 
-Data
       C99_NONSTANDARD = {'int16': 'short int', 'int32': 'int', 'int64': 'int64_t', 'int8': 'signed char', 'uint': 'unsigned int', 'uint16': 'unsigned short int', 'uint32': 'unsigned int', 'uint64': 'uint64_t', 'uint8': 'unsigned char'}
-__version__ = '2.4'
-debug = 0
-debug_trace = 0
-doxygenCommentCache = ''
-ignoreSymbols = ['Q_OBJECT']
-parseHistory = []
-print_errors = 1
-print_warnings = 1
-supportedAccessSpecifier = ['public', 'protected', 'private']
-t_AMPERSTAND = '&'
-t_ASTERISK = r'\*'
-t_BACKSLASH = r'\\'
-t_CARET = r'\^'
-t_CHAR_LITERAL = "'.'"
-t_CLOSE_BRACE = '}'
-t_CLOSE_PAREN = r'\)'
-t_CLOSE_SQUARE_BRACKET = r'\]'
-t_COLON = ':'
-t_COMMA = ','
-t_DIVIDE = '/(?!/)'
-t_EQUALS = '='
-t_EXCLAMATION = '!'
-t_MINUS = r'\-'
-t_NAME = '[<>A-Za-z_~][A-Za-z0-9_]*'
-t_NUMBER = '[0-9][0-9XxA-Fa-f]*'
-t_OPEN_BRACE = '{'
-t_OPEN_PAREN = r'\('
-t_OPEN_SQUARE_BRACKET = r'\['
-t_PERCENT = '%'
-t_PIPE = r'\|'
-t_PLUS = r'\+'
-t_PRECOMP_MACRO = r'\#.*'
-t_PRECOMP_MACRO_CONT = r'.*\\\n'
-t_SEMI_COLON = ';'
-t_SQUOTE = "'"
-t_STRING_LITERAL = r'"([^"\\]|\\.)*"'
-t_TAB = r'\t'
-t_ignore = ' \r.?@\x0c'
-tokens = ['NUMBER', 'NAME', 'OPEN_PAREN', 'CLOSE_PAREN', 'OPEN_BRACE', 'CLOSE_BRACE', 'OPEN_SQUARE_BRACKET', 'CLOSE_SQUARE_BRACKET', 'COLON', 'SEMI_COLON', 'COMMA', 'TAB', 'BACKSLASH', 'PIPE', 'PERCENT', 'EXCLAMATION', 'CARET', 'COMMENT_SINGLELINE', 'COMMENT_MULTILINE', 'PRECOMP_MACRO', ...]
-version = '2.4'
- \ No newline at end of file diff --git a/cppParser/CppHeaderParser/examples/SampleClass.h b/cppParser/CppHeaderParser/examples/SampleClass.h deleted file mode 100644 index 6140f11..0000000 --- a/cppParser/CppHeaderParser/examples/SampleClass.h +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -#define DEF_1 1 -#define OS_NAME "Linux" - -using namespace std; -class SampleClass -{ -public: - SampleClass(); - /*! - * Method 1 - */ - string meth1(); - - /// - /// Method 2 description - /// - /// @param v1 Variable 1 - /// - int meth2(int v1); - - /** - * Method 3 description - * - * \param v1 Variable 1 - * \param v2 Variable 2 - */ - void meth3(const string & v1, vector & v2); - - /********************************** - * Method 4 description - * - * @return Return value - *********************************/ - unsigned int meth4(); -private: - void * meth5(){return NULL}; - - /// prop1 description - string prop1; - //! prop5 description - int prop5; -}; -namespace Alpha -{ - class AlphaClass - { - public: - AlphaClass(); - - void alphaMethod(); - - string alphaString; - }; - - namespace Omega - { - class OmegaClass - { - public: - OmegaClass(); - - string omegaString; - }; - }; -} - -int sampleFreeFunction(int i) -{ - return i + 1; -} - -int anotherFreeFunction(void); -} diff --git a/cppParser/CppHeaderParser/examples/readSampleClass.py b/cppParser/CppHeaderParser/examples/readSampleClass.py deleted file mode 100755 index 7ddcb25..0000000 --- a/cppParser/CppHeaderParser/examples/readSampleClass.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/python -import sys -sys.path = ["../"] + sys.path -import CppHeaderParser -try: - cppHeader = CppHeaderParser.CppHeader("SampleClass.h") -except CppHeaderParser.CppParseError, e: - print e - sys.exit(1) - -print "CppHeaderParser view of %s"%cppHeader - -sampleClass = cppHeader.classes["SampleClass"] -print "Number of public methods %d"%(len(sampleClass["methods"]["public"])) -print "Number of private properties %d"%(len(sampleClass["properties"]["private"])) -meth3 = [m for m in sampleClass["methods"]["public"] if m["name"] == "meth3"][0] #get meth3 -meth3ParamTypes = [t["type"] for t in meth3["parameters"]] #get meth3s parameters -print "Parameter Types for public method meth3 %s"%(meth3ParamTypes) - -print "\nReturn type for meth1:" -print cppHeader.classes["SampleClass"]["methods"]["public"][1]["rtnType"] - -print "\nDoxygen for meth2:" -print cppHeader.classes["SampleClass"]["methods"]["public"][2]["doxygen"] - -print "\nParameters for meth3:" -print cppHeader.classes["SampleClass"]["methods"]["public"][3]["parameters"] - -print "\nDoxygen for meth4:" -print cppHeader.classes["SampleClass"]["methods"]["public"][4]["doxygen"] - -print "\nReturn type for meth5:" -print cppHeader.classes["SampleClass"]["methods"]["private"][0]["rtnType"] - -print "\nDoxygen type for prop1:" -print cppHeader.classes["SampleClass"]["properties"]["private"][0]["doxygen"] - -print "\nType for prop5:" -print cppHeader.classes["SampleClass"]["properties"]["private"][1]["type"] - -print "\nNamespace for AlphaClass is:" -print cppHeader.classes["AlphaClass"]["namespace"] - -print "\nReturn type for alphaMethod is:" -print cppHeader.classes["AlphaClass"]["methods"]["public"][0]["rtnType"] - -print "\nNamespace for OmegaClass is:" -print cppHeader.classes["OmegaClass"]["namespace"] - -print "\nType for omegaString is:" -print cppHeader.classes["AlphaClass"]["properties"]["public"][0]["type"] - -print "\nFree functions are:" -for func in cppHeader.functions: - print " %s"%func["name"] - -print "\n#includes are:" -for incl in cppHeader.includes: - print " %s"%incl - -print "\n#defines are:" -for define in cppHeader.defines: - print " %s"%define \ No newline at end of file diff --git a/cppParser/CppHeaderParser/oldCppHeaderParser.py b/cppParser/CppHeaderParser/oldCppHeaderParser.py deleted file mode 100644 index cc3755f..0000000 --- a/cppParser/CppHeaderParser/oldCppHeaderParser.py +++ /dev/null @@ -1,669 +0,0 @@ -#!/usr/bin/python -# -# Author: Jashua R. Cloutier (contact via sourceforge username:senexcanis) -# -# Copyright (C) 2010, Jashua R. Cloutier -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * Neither the name of Jashua R. Cloutier nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# -# The CppHeaderParser.py script is written in Python 2.4 and released to -# the open source community for continuous improvements under the BSD -# 2.0 new license, which can be found at: -# -# http://www.opensource.org/licenses/bsd-license.php -# -"""Parse C++ header files and generate a data structure -representing the class -""" - -import ply.lex as lex -import os -import sys -import re - -import inspect - -def lineno(): - """Returns the current line number in our program.""" - return inspect.currentframe().f_back.f_lineno - - -__version__ = "1.9" -version = "1.9" -tokens = [ - 'NUMBER', - 'NAME', - 'OPEN_PAREN', - 'CLOSE_PAREN', - 'OPEN_BRACE', - 'CLOSE_BRACE', - 'COLON', - 'SEMI_COLON', - 'COMMA', - 'COMMENT_SINGLELINE', - 'COMMENT_MULTILINE', - 'PRECOMP_MACRO', - 'PRECOMP_MACRO_CONT', - 'ASTERISK', - 'AMPERSTAND', - 'EQUALS', - 'MINUS', - 'PLUS', - 'DIVIDE', - 'CHAR_LITERAL', - 'STRING_LITERAL', - 'OPERATOR_DIVIDE_OVERLOAD', - 'NEW_LINE', -] - -t_ignore = " \t\r[].|!?%@" -t_NUMBER = r'[0-9][0-9XxA-Fa-f]*' -t_NAME = r'[<>A-Za-z_~][A-Za-z0-9_]*' -t_OPERATOR_DIVIDE_OVERLOAD = r'/=' -t_OPEN_PAREN = r'\(' -t_CLOSE_PAREN = r'\)' -t_OPEN_BRACE = r'{' -t_CLOSE_BRACE = r'}' -t_SEMI_COLON = r';' -t_COLON = r':' -t_COMMA = r',' -t_PRECOMP_MACRO = r'\#.*' -t_PRECOMP_MACRO_CONT = r'.*\\\n' -def t_COMMENT_SINGLELINE(t): - r'\/\/.*\n' - global doxygenCommentCache - if t.value.startswith("///") or t.value.startswith("//!"): - if doxygenCommentCache: - doxygenCommentCache += "\n" - if t.value.endswith("\n"): - doxygenCommentCache += t.value[:-1] - else: - doxygenCommentCache += t.value -t_ASTERISK = r'\*' -t_MINUS = r'\-' -t_PLUS = r'\+' -t_DIVIDE = r'/[^/]' -t_AMPERSTAND = r'&' -t_EQUALS = r'=' -t_CHAR_LITERAL = "'.'" -#found at http://wordaligned.org/articles/string-literals-and-regular-expressions -#TODO: This does not work with the string "bla \" bla" -t_STRING_LITERAL = r'"([^"\\]|\\.)*"' -#Found at http://ostermiller.org/findcomment.html -def t_COMMENT_MULTILINE(t): - r'/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/' - global doxygenCommentCache - if t.value.startswith("/**") or t.value.startswith("/*!"): - #not sure why, but get double new lines - v = t.value.replace("\n\n", "\n") - #strip prefixing whitespace - v = re.sub("\n[\s]+\*", "\n*", v) - doxygenCommentCache += v -def t_NEWLINE(t): - r'\n+' - t.lexer.lineno += len(t.value) - -def t_error(v): - print "Lex error: ", v - -lex.lex() -debug = 0 - -supportedAccessSpecifier = [ - 'public', - 'protected', - 'private' -] - -doxygenCommentCache = "" - -def is_namespace(nameStack): - """Determines if a namespace is being specified""" - if len(nameStack) == 0: - return False - if nameStack[0] == "namespace": - return True - return False - -def is_enum_namestack(nameStack): - """Determines if a namestack is an enum namestack""" - if len(nameStack) == 0: - return False - if nameStack[0] == "enum": - return True - if len(nameStack) > 1 and nameStack[0] == "typedef" and nameStack[1] == "enum": - return True - return False - -class CppParseError(Exception): pass - -class CppClass(dict): - """Takes a name stack and turns it into a class - - Contains the following Keys: - self['name'] - Name of the class - self['doxygen'] - Doxygen comments associated with the class if they exist - self['inherits'] - List of Classes that this one inherits where the values - are of the form {"access": Anything in supportedAccessSpecifier - "class": Name of the class - self['methods'] - Dictionary where keys are from supportedAccessSpecifier - and values are a lists of CppMethod's - self['properties'] - Dictionary where keys are from supportedAccessSpecifier - and values are lists of CppVariable's - self['enums'] - Dictionary where keys are from supportedAccessSpecifier and - values are lists of CppEnum's - - An example of how this could look is as follows: - #self = - { - 'name': "" - 'inherits':[] - 'methods': - { - 'public':[], - 'protected':[], - 'private':[] - }, - 'properties': - { - 'public':[], - 'protected':[], - 'private':[] - }, - 'enums': - { - 'public':[], - 'protected':[], - 'private':[] - } - } - """ - def __init__(self, nameStack): - if (debug): print "Class: ", nameStack - if (len(nameStack) < 2): - print "Error detecting class" - return - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - self["name"] = nameStack[1] - inheritList = [] - if ":" in nameStack: - nameStack = nameStack[nameStack.index(":") + 1:] - while len(nameStack): - tmpStack = [] - tmpInheritClass = {"access":"private"} - if "," in nameStack: - tmpStack = nameStack[:nameStack.index(",")] - nameStack = nameStack[nameStack.index(",") + 1:] - else: - tmpStack = nameStack - nameStack = [] - if len(tmpStack) == 0: - break; - elif len(tmpStack) == 1: - tmpInheritClass["class"] = tmpStack[0] - elif len(tmpStack) == 2: - tmpInheritClass["access"] = tmpStack[0] - tmpInheritClass["class"] = tmpStack[1] - else: - print "Warning: Cant figure out class inheriting %s\n"%(" ".join(tmpStack)) - continue - inheritList.append(tmpInheritClass) - methodAccessSpecificList = {} - propertyAccessSpecificList = {} - enumAccessSpecificList = {} - - for accessSpecifier in supportedAccessSpecifier: - methodAccessSpecificList[accessSpecifier] = [] - propertyAccessSpecificList[accessSpecifier] = [] - enumAccessSpecificList[accessSpecifier] = [] - self['inherits'] = inheritList - self['methods'] = methodAccessSpecificList - self['properties'] = propertyAccessSpecificList - self['enums'] = enumAccessSpecificList - self['namespace'] = "" - - def __repr__(self): - """Convert class to a string""" - namespace_prefix = "" - if self["namespace"]: namespace_prefix = self["namespace"] + "::" - rtn = "class %s\n"%(namespace_prefix + self["name"]) - try: - print self["doxygen"], - except: pass - if "inherits" in self.keys(): - rtn += "Inherits: " - for inheritClass in self["inherits"]: - rtn += "%s %s, "%(inheritClass["access"], inheritClass["class"]) - rtn += "\n" - rtn += "{\n" - for accessSpecifier in supportedAccessSpecifier: - rtn += "%s\n"%(accessSpecifier) - #Enums - if (len(self["enums"][accessSpecifier])): - rtn += " // Enums\n" - for enum in self["enums"][accessSpecifier]: - rtn += " %s\n"%(repr(enum)) - #Properties - if (len(self["properties"][accessSpecifier])): - rtn += " // Properties\n" - for property in self["properties"][accessSpecifier]: - rtn += " %s\n"%(repr(property)) - #Methods - if (len(self["methods"][accessSpecifier])): - rtn += " // Method\n" - for method in self["methods"][accessSpecifier]: - rtn += " %s\n"%(repr(method)) - rtn += "}\n" - return rtn - -class CppMethod(dict): - """Takes a name stack and turns it into a method - - Contains the following Keys: - self['rtnType'] - Return type of the method (ex. "int") - self['name'] - Name of the method (ex. "getSize") - self['doxygen'] - Doxygen comments associated with the method if they exist - self['parameters'] - List of CppVariables - """ - def __init__(self, nameStack, curClass): - if (debug): print "Method: ", nameStack - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - if "operator" in nameStack: - self["rtnType"] = " ".join(nameStack[:nameStack.index('operator')]) - self["name"] = "".join(nameStack[nameStack.index('operator'):nameStack.index('(')]) - else: - self["rtnType"] = " ".join(nameStack[:nameStack.index('(') - 1]) - self["name"] = " ".join(nameStack[nameStack.index('(') - 1:nameStack.index('(')]) - if len(self["rtnType"]) == 0 or self["name"] == curClass: - self["rtnType"] = "void" - paramsStack = nameStack[nameStack.index('(') + 1: ] - #Remove things from the stack till we hit the last paren, this helps handle abstract and normal methods - while (paramsStack[-1] != ")"): - paramsStack.pop() - paramsStack.pop() - params = [] - #See if there is a doxygen comment for the variable - doxyVarDesc = {} - #TODO: Put this into a class - if self.has_key("doxygen"): - doxyLines = self["doxygen"].split("\n") - lastParamDesc = "" - for doxyLine in doxyLines: - if " @param " in doxyLine or " \param " in doxyLine: - try: - #Strip out the param - doxyLine = doxyLine[doxyLine.find("param ") + 6:] - (var, desc) = doxyLine.split(" ", 1) - doxyVarDesc[var] = desc.strip() - lastParamDesc = var - except: pass - elif " @return " in doxyLine or " \return " in doxyLine: - lastParamDesc = "" - # not handled for now - elif lastParamDesc: - try: - doxyLine = doxyLine.strip() - if " " not in doxyLine: - lastParamDesc = "" - continue - doxyLine = doxyLine[doxyLine.find(" ") + 1:] - doxyVarDesc[lastParamDesc] += " " + doxyLine - except: pass - - #Create the variable now - while (len(paramsStack)): - if (',' in paramsStack): - params.append(CppVariable(paramsStack[0:paramsStack.index(',')], doxyVarDesc=doxyVarDesc)) - paramsStack = paramsStack[paramsStack.index(',') + 1:] - else: - param = CppVariable(paramsStack, doxyVarDesc=doxyVarDesc) - if len(param.keys()): - params.append(param) - break - self["parameters"] = params - - -class CppVariable(dict): - """Takes a name stack and turns it into a method - - Contains the following Keys: - self['type'] - Type for the variable (ex. "const string &") - self['name'] - Name of the variable (ex. "numItems") - self['namespace'] - Namespace containing the enum - self['desc'] - Description of the variable if part of a method (optional) - self['doxygen'] - Doxygen comments associated with the method if they exist - self['defaltValue'] - Default value of the variable, this key will only - exist if there is a default value - """ - def __init__(self, nameStack, **kwargs): - if (debug): print "Variable: ", nameStack - if (len(nameStack) < 2): - return - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - if ("=" in nameStack): - self["type"] = " ".join(nameStack[:nameStack.index("=") - 1]) - self["name"] = nameStack[nameStack.index("=") - 1] - self["defaltValue"] = " ".join(nameStack[nameStack.index("=") + 1:]) - else: - self["type"] = " ".join(nameStack[:-1]) - self["name"] = nameStack[-1] - self["type"] = self["type"].replace(" :",":") - self["type"] = self["type"].replace(": ",":") - self["type"] = self["type"].replace(" <","<") - self["type"] = self["type"].replace(" >",">") - #Optional doxygen description - try: - self["desc"] = kwargs["doxyVarDesc"][self["name"]] - except: pass - -class CppEnum(dict): - """Takes a name stack and turns it into an Enum - - Contains the following Keys: - self['name'] - Name of the enum (ex. "ItemState") - self['namespace'] - Namespace containing the enum - self['values'] - List of values where the values are a dictionary of the - form {"name": name of the key (ex. "PARSING_HEADER"), - "value": Specified value of the enum, this key will only exist - if a value for a given enum value was defined - } - """ - def __init__(self, nameStack): - if len(nameStack) < 4 or "{" not in nameStack or "}" not in nameStack: - #Not enough stuff for an enum - return - global doxygenCommentCache - if len(doxygenCommentCache): - self["doxygen"] = doxygenCommentCache - doxygenCommentCache = "" - valueList = [] - #Figure out what values it has - valueStack = nameStack[nameStack.index('{') + 1: nameStack.index('}')] - while len(valueStack): - tmpStack = [] - if "," in valueStack: - tmpStack = valueStack[:valueStack.index(",")] - valueStack = valueStack[valueStack.index(",") + 1:] - else: - tmpStack = valueStack - valueStack = [] - if len(tmpStack) == 1: - valueList.append({"name": tmpStack[0]}) - elif len(tmpStack) >= 3 and tmpStack[1] == "=": - valueList.append({"name": tmpStack[0], "value": " ".join(tmpStack[2:])}) - elif len(tmpStack) == 2 and tmpStack[1] == "=": - if (debug): print "Missed value for %s"%tmpStack[0] - valueList.append({"name": tmpStack[0]}) - if len(valueList): - self["values"] = valueList - else: - #An enum without any values is useless, dont bother existing - return - #Figure out if it has a name - preBraceStack = nameStack[:nameStack.index("{")] - postBraceStack = nameStack[nameStack.index("}") + 1:] - if (len(preBraceStack) == 2 and "typedef" not in nameStack): - self["name"] = preBraceStack[1] - elif len(postBraceStack) and "typedef" in nameStack: - self["name"] = " ".join(postBraceStack) - #See if there are instances of this - if "typedef" not in nameStack and len(postBraceStack): - self["instances"] = [] - for var in postBraceStack: - if "," in var: - continue - self["instances"].append(var) - self["namespace"] = "" - -class CppHeader: - """Parsed C++ class header - - Variables produced: - self.classes - Dictionary of classes found in a given header file where the - key is the name of the class - """ - def __init__(self, headerFileName, argType = "file"): - if (argType == "file"): - self.headerFileName = os.path.expandvars(headerFileName) - self.mainClass = os.path.split(self.headerFileName)[1][:-2] - headerFileStr = "" -# if headerFileName[-2:] != ".h": -# raise Exception("file must be a header file and end with .h") - elif argType == "string": - self.headerFileName = "" - self.mainClass = "???" - headerFileStr = headerFileName - else: - raise Exception("Arg type must be either file or string") - self.curClass = "" - self.classes = {} - self.enums = [] - self.nameStack = [] - self.nameSpaces = [] - self.curAccessSpecifier = 'private' - - if (len(self.headerFileName)): - headerFileStr = "\n".join(open(self.headerFileName).readlines()) - self.braceDepth = 0 - lex.input(headerFileStr) - curLine = 0 - curChar = 0 - try: - while True: - tok = lex.token() - # Example: LexToken(COLON,';',1,373) - # where (tok.name, tok.value, ?, ?) - if not tok: - break - curLine = tok.lineno - curChar = tok.lexpos - if (tok.type == 'OPEN_BRACE'): - if len(self.nameStack) and is_namespace(self.nameStack): - self.nameSpaces.append(self.nameStack[1]) - if len(self.nameStack) and not is_enum_namestack(self.nameStack): - self.evaluate_stack() - else: - self.nameStack.append(tok.value) - self.braceDepth += 1 - elif (tok.type == 'CLOSE_BRACE'): - if self.braceDepth == 0: - continue - if (self.braceDepth == len(self.nameSpaces)): - tmp = self.nameSpaces.pop() - if len(self.nameStack) and is_enum_namestack(self.nameStack): - self.nameStack.append(tok.value) - elif self.braceDepth < 10: - self.evaluate_stack() - else: - self.nameStack = [] - self.braceDepth -= 1 - if (self.braceDepth == 0): - self.curClass = "" - - if (tok.type == 'OPEN_PAREN'): - self.nameStack.append(tok.value) - elif (tok.type == 'CLOSE_PAREN'): - self.nameStack.append(tok.value) - elif (tok.type == 'EQUALS'): - self.nameStack.append(tok.value) - elif (tok.type == 'COMMA'): - self.nameStack.append(tok.value) - elif (tok.type == 'NUMBER'): - self.nameStack.append(tok.value) - elif (tok.type == 'MINUS'): - self.nameStack.append(tok.value) - elif (tok.type == 'PLUS'): - self.nameStack.append(tok.value) - elif (tok.type == 'STRING_LITERAL'): - self.nameStack.append(tok.value) - elif (tok.type == 'NAME' or tok.type == 'AMPERSTAND' or tok.type == 'ASTERISK'): - if (tok.value == 'class'): - self.nameStack.append(tok.value) - elif (tok.value in supportedAccessSpecifier and self.braceDepth == len(self.nameSpaces) + 1): - self.curAccessSpecifier = tok.value - else: - self.nameStack.append(tok.value) - elif (tok.type == 'COLON'): - #Dont want colon to be first in stack - if len(self.nameStack) == 0: - continue - self.nameStack.append(tok.value) - elif (tok.type == 'SEMI_COLON'): - if (self.braceDepth < 10): - self.evaluate_stack() - except: - raise CppParseError("Not able to parse %s on line %d evaluating \"%s\"\nError around: %s" - % (self.headerFileName, tok.lineno, tok.value, " ".join(self.nameStack))) - - def evaluate_stack(self): - """Evaluates the current name stack""" - global doxygenCommentCache - if (debug): print "Evaluating stack %s at..."%self.nameStack - if (len(self.curClass)): - if (debug): print "%s (%s) "%(self.curClass, self.curAccessSpecifier), - if (len(self.nameStack) == 0): - if (debug): print "line ",lineno() - if (debug): print "(Empty Stack)" - return - elif (self.nameStack[0] == "namespace"): - #Taken care of outside of here - pass - elif (self.nameStack[0] == "class"): - if (debug): print "line ",lineno() - self.evaluate_class_stack() - elif (self.nameStack[0] == "struct"): - if (debug): print "line ",lineno() - self.curAccessSpecifier = "public" - self.evaluate_class_stack() - elif (len(self.curClass) == 0): - if (debug): print "line ",lineno() - if is_enum_namestack(self.nameStack): - self.evaluate_enum_stack() - self.nameStack = [] - doxygenCommentCache = "" - return - elif (self.braceDepth < 1): - if (debug): print "line ",lineno() - #Ignore global stuff for now - if (debug): print "Global stuff: ", self.nameStack - self.nameStack = [] - doxygenCommentCache = "" - return - elif (self.braceDepth > len(self.nameSpaces) + 1): - if (debug): print "line ",lineno() - self.nameStack = [] - doxygenCommentCache = "" - return - elif is_enum_namestack(self.nameStack): - if (debug): print "line ",lineno() - #elif self.nameStack[0] == "enum": - self.evaluate_enum_stack() - elif ('(' in self.nameStack): - if (debug): print "line ",lineno() - self.evaluate_method_stack() - else: - if (debug): print "line ",lineno() - self.evaluate_property_stack() - self.nameStack = [] - doxygenCommentCache = "" - - def evaluate_class_stack(self): - """Create a Class out of the name stack (but not its parts)""" - #dont support sub classes today - if self.braceDepth != len(self.nameSpaces): - return - newClass = CppClass(self.nameStack) - if len(newClass.keys()): - self.curClass = newClass["name"] - self.classes[self.curClass] = newClass - else: - self.curClass = "" - newClass["namespace"] = self.cur_namespace() - - def evaluate_method_stack(self): - """Create a method out of the name stack""" - newMethod = CppMethod(self.nameStack, self.curClass) - if len(newMethod.keys()): - self.classes[self.curClass]["methods"][self.curAccessSpecifier].append(newMethod) - - def evaluate_property_stack(self): - """Create a Property out of the name stack""" - newVar = CppVariable(self.nameStack) - if len(newVar.keys()): - self.classes[self.curClass]["properties"][self.curAccessSpecifier].append(newVar) - - def evaluate_enum_stack(self): - """Create an Enum out of the name stack""" - newEnum = CppEnum(self.nameStack) - if len(newEnum.keys()): - if len(self.curClass): - newEnum["namespace"] = self.cur_namespace() - self.classes[self.curClass]["enums"][self.curAccessSpecifier].append(newEnum) - else: - newEnum["namespace"] = self.cur_namespace() -# print "Adding global enum" - self.enums.append(newEnum) - #This enum has instances, turn them into properties - if newEnum.has_key("instances"): - instanceType = "enum" - if newEnum.has_key("name"): - instanceType = newEnum["name"] - for instance in newEnum["instances"]: - self.nameStack = [instanceType, instance] - self.evaluate_property_stack() - del newEnum["instances"] - - def cur_namespace(self, add_double_colon = False): - rtn = "" - i = 0 - while i < len(self.nameSpaces): - rtn += self.nameSpaces[i] - if add_double_colon or i < len(self.nameSpaces) - 1: - rtn += "::" - i+=1 - return rtn - - - def __repr__(self): - rtn = "" - for className in self.classes.keys(): - rtn += repr(self.classes[className]) - return rtn diff --git a/cppParser/CppHeaderParser/repr.py b/cppParser/CppHeaderParser/repr.py deleted file mode 100755 index 8fe320e..0000000 --- a/cppParser/CppHeaderParser/repr.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python - -import CppHeaderParser - -f = CppHeaderParser.CppHeader("test/TestSampleClass.h") - -print f - -print "=" * 20 - -#print f.classes["SampleClass"]["methods"]["public"][2]["parameters"] -print f.classes["AlphaClass"]["enums"]["protected"][0]["values"] \ No newline at end of file diff --git a/cppParser/Enum.py b/cppParser/Enum.py new file mode 100644 index 0000000..21cc38f --- /dev/null +++ b/cppParser/Enum.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + +import Node + +import inspect + + +class Enum(Node): + def __init__(self): + self.name = libName + + #List is contituated of 3 element : {'name':"plop", 'value':5, 'doc'=""}, ...] + self.list = [] + + diff --git a/cppParser/Library.py b/cppParser/Library.py new file mode 100644 index 0000000..ed0c803 --- /dev/null +++ b/cppParser/Library.py @@ -0,0 +1,21 @@ +#!/usr/bin/python +import LutinDebug as debug +import os +import sys +import re + +class Libray(): + def __init__(self, libName): + self.name = libName + # CPP section: + self.namespaces = [] + self.classes = [] + # C section: + self.structs = [] + self.variables = [] + self.methodes = [] + self.unions = [] + self.types = [] + + + diff --git a/cppParser/Methode.py b/cppParser/Methode.py new file mode 100644 index 0000000..5f198da --- /dev/null +++ b/cppParser/Methode.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + + + +class Methode(): + def __init__(self): + self.name = "" + self.returnType = Type.TypeVoid() + self.virtual = False # only for C++ + self.static = False + self.inline = False + self.doc = None + self.variable = None + self.visibility = "private" # only for C++ : "public" "protected" "private" + + def to_str(self): + ret = "" + if self.virtual == True: + ret += "virtual " + if self.static == True: + ret += "static " + if self.inline == True: + ret += "inline " + ret += self.returnType.to_str() + ret += " " + ret += self.name + ret += "(" + # ... + ret += ")" + return ret + diff --git a/cppParser/Namespace.py b/cppParser/Namespace.py new file mode 100644 index 0000000..54df3c8 --- /dev/null +++ b/cppParser/Namespace.py @@ -0,0 +1,29 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + +import inspect + +class Namespace(): + def __init__(self): + self.name = "" + # CPP section: + self.namespaces = [] + self.classes = [] + # C section: + self.structs = [] + self.variables = [] + self.methodes = [] + self.unions = [] + self.types = [] + + def to_str(self) : + return "" + diff --git a/cppParser/Node.py b/cppParser/Node.py new file mode 100644 index 0000000..56ab8ab --- /dev/null +++ b/cppParser/Node.py @@ -0,0 +1,22 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + +class Node(): + def __init__(self): + self.name = "" + self.doc = None + self.fileName = "" + self.lineNumber = "" + + def to_str(): + return "" + + diff --git a/cppParser/PKG-INFO b/cppParser/PKG-INFO deleted file mode 100644 index f097dbc..0000000 --- a/cppParser/PKG-INFO +++ /dev/null @@ -1,290 +0,0 @@ -Metadata-Version: 1.1 -Name: CppHeaderParser -Version: 2.4 -Summary: Parse C++ header files and generate a data structure representing the class -Home-page: http://senexcanis.com/open-source/cppheaderparser/ -Author: Jashua Cloutier -Author-email: jashuac@bellsouth.net -License: BSD -Description: Python package "CppHeaderParser" - -------------------------------- - **Purpose:** Parse C++ header files and generate a data structure representing the class - - **Author:** Jashua Cloutier - - **Licence:** BSD - - **External modules required:** PLY - - **Quick start**:: - - #include - #include - - #define DEF_1 1 - #define OS_NAME "Linux" - - using namespace std; - class SampleClass - { - public: - SampleClass(); - /*! - * Method 1 - */ - string meth1(); - - /// - /// Method 2 description - /// - /// @param v1 Variable 1 - /// - int meth2(int v1); - - /** - * Method 3 description - * - * \param v1 Variable 1 - * \param v2 Variable 2 - */ - void meth3(const string & v1, vector & v2); - - /********************************** - * Method 4 description - * - * @return Return value - *********************************/ - unsigned int meth4(); - private: - void * meth5(){return NULL}; - - /// prop1 description - string prop1; - //! prop5 description - int prop5; - }; - namespace Alpha - { - class AlphaClass - { - public: - AlphaClass(); - - void alphaMethod(); - - string alphaString; - }; - - namespace Omega - { - class OmegaClass - { - public: - OmegaClass(); - - string omegaString; - }; - }; - } - - int sampleFreeFunction(int i) - { - return i + 1; - } - - int anotherFreeFunction(void); - } - - - **Python code**:: - - #!/usr/bin/python - import sys - sys.path = ["../"] + sys.path - import CppHeaderParser - try: - cppHeader = CppHeaderParser.CppHeader("SampleClass.h") - except CppHeaderParser.CppParseError, e: - print e - sys.exit(1) - - print "CppHeaderParser view of %s"%cppHeader - - sampleClass = cppHeader.classes["SampleClass"] - print "Number of public methods %d"%(len(sampleClass["methods"]["public"])) - print "Number of private properties %d"%(len(sampleClass["properties"]["private"])) - meth3 = [m for m in sampleClass["methods"]["public"] if m["name"] == "meth3"][0] #get meth3 - meth3ParamTypes = [t["type"] for t in meth3["parameters"]] #get meth3s parameters - print "Parameter Types for public method meth3 %s"%(meth3ParamTypes) - - print "\nReturn type for meth1:" - print cppHeader.classes["SampleClass"]["methods"]["public"][1]["rtnType"] - - print "\nDoxygen for meth2:" - print cppHeader.classes["SampleClass"]["methods"]["public"][2]["doxygen"] - - print "\nParameters for meth3:" - print cppHeader.classes["SampleClass"]["methods"]["public"][3]["parameters"] - - print "\nDoxygen for meth4:" - print cppHeader.classes["SampleClass"]["methods"]["public"][4]["doxygen"] - - print "\nReturn type for meth5:" - print cppHeader.classes["SampleClass"]["methods"]["private"][0]["rtnType"] - - print "\nDoxygen type for prop1:" - print cppHeader.classes["SampleClass"]["properties"]["private"][0]["doxygen"] - - print "\nType for prop5:" - print cppHeader.classes["SampleClass"]["properties"]["private"][1]["type"] - - print "\nNamespace for AlphaClass is:" - print cppHeader.classes["AlphaClass"]["namespace"] - - print "\nReturn type for alphaMethod is:" - print cppHeader.classes["AlphaClass"]["methods"]["public"][0]["rtnType"] - - print "\nNamespace for OmegaClass is:" - print cppHeader.classes["OmegaClass"]["namespace"] - - print "\nType for omegaString is:" - print cppHeader.classes["AlphaClass"]["properties"]["public"][0]["type"] - - print "\nFree functions are:" - for func in cppHeader.functions: - print " %s"%func["name"] - - print "\n#includes are:" - for incl in cppHeader.includes: - print " %s"%incl - - print "\n#defines are:" - for define in cppHeader.defines: - print " %s"%define - - **Output**:: - - CppHeaderParser view of class SampleClass - { - public - // Methods - {'line_number': 11, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'SampleClass', 'returns_pointer': 0, 'class': None, 'name': 'SampleClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'SampleClass ( ) ;', 'inline': False} - {'line_number': 15, 'static': False, 'rtnType': 'string', 'returns_unknown': True, 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'string', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/*!\n* Method 1\n*/', 'name': 'meth1', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': False, 'constructor': False, 'debug': 'string meth1 ( ) ;', 'returns_pointer': 0} - {'line_number': 22, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 22, 'constant': 0, 'name': 'v1', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '///\n/// Method 2 description\n///\n/// @param v1 Variable 1\n///', 'name': 'meth2', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int meth2 ( int v1 ) ;', 'returns_pointer': 0} - {'line_number': 30, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [{'line_number': 30, 'constant': 1, 'name': 'v1', 'reference': 1, 'type': 'const string &', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}, {'line_number': 30, 'constant': 0, 'name': 'v2', 'reference': 1, 'type': 'vector &', 'static': 0, 'pointer': 0, 'desc': 'Variable 2'}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'unresolved_parameters': True, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/**\n* Method 3 description\n*\n* \\param v1 Variable 1\n* \\param v2 Variable 2\n*/', 'name': 'meth3', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void meth3 ( const string & v1 , vector & v2 ) ;', 'returns_pointer': 0} - {'line_number': 37, 'static': False, 'rtnType': 'unsigned int', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'unsigned int', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/**********************************\n* Method 4 description\n*\n* @return Return value\n*********************************/', 'name': 'meth4', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'unsigned int meth4 ( ) ;', 'returns_pointer': 0} - protected - private - // Properties - {'line_number': 42, 'constant': 0, 'name': 'prop1', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0} - {'line_number': 44, 'constant': 0, 'name': 'prop5', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0} - // Methods - {'line_number': 39, 'static': False, 'rtnType': 'void *', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'SampleClass', 'returns_pointer': 1, 'class': None, 'name': 'meth5', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void * meth5 ( ) {', 'inline': False} - } - - class Alpha::AlphaClass - { - public - // Properties - {'line_number': 55, 'constant': 0, 'name': 'alphaString', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0} - // Methods - {'line_number': 51, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::AlphaClass', 'returns_pointer': 0, 'class': None, 'name': 'AlphaClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'AlphaClass ( ) ;', 'inline': False} - {'line_number': 53, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::AlphaClass', 'returns_pointer': 0, 'class': None, 'name': 'alphaMethod', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void alphaMethod ( ) ;', 'inline': False} - protected - private - } - - class Alpha::Omega::OmegaClass - { - public - // Properties - {'line_number': 65, 'constant': 0, 'name': 'omegaString', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0} - // Methods - {'line_number': 63, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::Omega::', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::Omega::OmegaClass', 'returns_pointer': 0, 'class': None, 'name': 'OmegaClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'OmegaClass ( ) ;', 'inline': False} - protected - private - } - - // functions - {'line_number': 70, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 70, 'constant': 0, 'name': 'i', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'returns_pointer': 0, 'class': None, 'name': 'sampleFreeFunction', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int sampleFreeFunction ( int i ) {', 'inline': False} - {'line_number': 75, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 75, 'constant': 0, 'name': '', 'reference': 0, 'type': 'void', 'static': 0, 'pointer': 0}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'returns_pointer': 0, 'class': None, 'name': 'anotherFreeFunction', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int anotherFreeFunction ( void ) ;', 'inline': False} - - Number of public methods 5 - Number of private properties 2 - Parameter Types for public method meth3 ['const string &', 'vector &'] - - Return type for meth1: - string - - Doxygen for meth2: - /// - /// Method 2 description - /// - /// @param v1 Variable 1 - /// - - Parameters for meth3: - [{'line_number': 30, 'constant': 1, 'name': 'v1', 'reference': 1, 'type': 'const string &', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}, {'line_number': 30, 'constant': 0, 'name': 'v2', 'reference': 1, 'type': 'vector &', 'static': 0, 'pointer': 0, 'desc': 'Variable 2'}] - - Doxygen for meth4: - /********************************** - * Method 4 description - * - * @return Return value - *********************************/ - - Return type for meth5: - void * - - Doxygen type for prop1: - /// prop1 description - - Type for prop5: - int - - Namespace for AlphaClass is: - Alpha - - Return type for alphaMethod is: - void - - Namespace for OmegaClass is: - Alpha::Omega - - Type for omegaString is: - string - - Free functions are: - sampleFreeFunction - anotherFreeFunction - - #includes are: - - - - #defines are: - DEF_1 1 - OS_NAME "Linux" - - - - Contributors - ------------ - * Chris Love - * HartsAntler - -Keywords: c++ header parser ply -Platform: Platform Independent -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: C++ -Classifier: License :: OSI Approved :: BSD License -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Topic :: Software Development -Classifier: Topic :: Software Development :: Code Generators -Classifier: Topic :: Software Development :: Compilers -Classifier: Topic :: Software Development :: Disassemblers -Requires: ply diff --git a/cppParser/Parse.py b/cppParser/Parse.py new file mode 100644 index 0000000..0fa4b1d --- /dev/null +++ b/cppParser/Parse.py @@ -0,0 +1,469 @@ +#!/usr/bin/python +import os +import sys +import re + +import ply.lex as lex + +import inspect +import lutinDebug as debug +import lutinTools +import Class + +tokens = [ + 'NUMBER', + 'NAME', + 'OPEN_PAREN', + 'CLOSE_PAREN', + 'OPEN_BRACE', + 'CLOSE_BRACE', + 'OPEN_SQUARE_BRACKET', + 'CLOSE_SQUARE_BRACKET', + 'COLON', + 'SEMI_COLON', + 'COMMA', + 'TAB', + 'BACKSLASH', + 'PIPE', + 'PERCENT', + 'EXCLAMATION', + 'CARET', + 'COMMENT_SINGLELINE', + 'COMMENT_MULTILINE', + 'PRECOMP_MACRO', + 'PRECOMP_MACRO_CONT', + 'ASTERISK', + 'AMPERSTAND', + 'EQUALS', + 'MINUS', + 'PLUS', + 'DIVIDE', + 'CHAR_LITERAL', + 'STRING_LITERAL', + 'NEW_LINE', + 'SQUOTE', +] + +t_ignore = " \r.?@\f" +t_NUMBER = r'[0-9][0-9XxA-Fa-f]*' +t_NAME = r'[<>A-Za-z_~][A-Za-z0-9_]*' +t_OPEN_PAREN = r'\(' +t_CLOSE_PAREN = r'\)' +t_OPEN_BRACE = r'{' +t_CLOSE_BRACE = r'}' +t_OPEN_SQUARE_BRACKET = r'\[' +t_CLOSE_SQUARE_BRACKET = r'\]' +t_SEMI_COLON = r';' +t_COLON = r':' +t_COMMA = r',' +t_TAB = r'\t' +t_BACKSLASH = r'\\' +t_PIPE = r'\|' +t_PERCENT = r'%' +t_CARET = r'\^' +t_EXCLAMATION = r'!' +t_PRECOMP_MACRO = r'\#.*' +t_PRECOMP_MACRO_CONT = r'.*\\\n' +def t_COMMENT_SINGLELINE(t): + r'\/\/.*\n' + global doxygenCommentCache + if t.value.startswith("///") or t.value.startswith("//!"): + if doxygenCommentCache: + doxygenCommentCache += "\n" + if t.value.endswith("\n"): + doxygenCommentCache += t.value[:-1] + else: + doxygenCommentCache += t.value + t.lexer.lineno += len(filter(lambda a: a=="\n", t.value)) +t_ASTERISK = r'\*' +t_MINUS = r'\-' +t_PLUS = r'\+' +t_DIVIDE = r'/(?!/)' +t_AMPERSTAND = r'&' +t_EQUALS = r'=' +t_CHAR_LITERAL = "'.'" +t_SQUOTE = "'" +#found at http://wordaligned.org/articles/string-literals-and-regular-expressions +#TODO: This does not work with the string "bla \" bla" +t_STRING_LITERAL = r'"([^"\\]|\\.)*"' +#Found at http://ostermiller.org/findcomment.html +def t_COMMENT_MULTILINE(t): + r'/\*([^*]|\n|(\*+([^*/]|\n)))*\*+/' + global doxygenCommentCache + if t.value.startswith("/**") or t.value.startswith("/*!"): + #not sure why, but get double new lines + v = t.value.replace("\n\n", "\n") + #strip prefixing whitespace + v = re.sub("\n[\s]+\*", "\n*", v) + doxygenCommentCache += v + t.lexer.lineno += len(filter(lambda a: a=="\n", t.value)) +def t_NEWLINE(t): + r'\n+' + t.lexer.lineno += len(t.value) + +def t_error(v): + print( "Lex error: ", v ) + +lex.lex() + + +class TagStr(str): + """Wrapper for a string that allows us to store the line number associated with it""" + lineno_reg = {} + def __new__(cls,*args,**kw): + new_obj = str.__new__(cls,*args) + if "lineno" in kw: + TagStr.lineno_reg[id(new_obj)] = kw["lineno"] + return new_obj + + def __del__(self): + try: + del TagStr.lineno_reg[id(self)] + except: pass + + def lineno(self): + return TagStr.lineno_reg.get(id(self), -1) + + +doxygenCommentCache = "" + +#Track what was added in what order and at what depth +parseHistory = [] + +def is_namespace(nameStack): + """Determines if a namespace is being specified""" + if len(nameStack) == 0: + return False + if nameStack[0] == "namespace": + return True + return False + +def is_enum_namestack(nameStack): + """Determines if a namestack is an enum namestack""" + if len(nameStack) == 0: + return False + if nameStack[0] == "enum": + return True + if len(nameStack) > 1 \ + and nameStack[0] == "typedef" \ + and nameStack[1] == "enum": + return True + return False + +def is_fundamental(s): + for a in s.split(): + if a not in ["size_t", \ + "struct", \ + "union", \ + "unsigned", \ + "signed", \ + "bool", \ + "char", \ + "short", \ + "int", \ + "float", \ + "double", \ + "long", \ + "void", \ + "*"]: + return False + return True + +def is_function_pointer_stack(stack): + """Count how many non-nested paranthesis are in the stack. Useful for determining if a stack is a function pointer""" + paren_depth = 0 + paren_count = 0 + star_after_first_paren = False + last_e = None + for e in stack: + if e == "(": + paren_depth += 1 + elif e == ")" \ + and paren_depth > 0: + paren_depth -= 1 + if paren_depth == 0: + paren_count += 1 + elif e == "*" \ + and last_e == "(" \ + and paren_count == 0 \ + and paren_depth == 1: + star_after_first_paren = True + last_e = e + if star_after_first_paren and paren_count == 2: + return True + else: + return False + +def is_method_namestack(stack): + r = False + if '(' not in stack: + r = False + elif stack[0] == 'typedef': + r = False # TODO deal with typedef function prototypes + #elif '=' in stack and stack.index('=') < stack.index('(') and stack[stack.index('=')-1] != 'operator': r = False #disabled July6th - allow all operators + elif 'operator' in stack: + r = True # allow all operators + elif '{' in stack \ + and stack.index('{') < stack.index('('): + r = False # struct that looks like a method/class + elif '(' in stack \ + and ')' in stack: + if '{' in stack \ + and '}' in stack: + r = True + elif stack[-1] == ';': + if is_function_pointer_stack(stack): + r = False + else: + r = True + elif '{' in stack: + r = True # ideally we catch both braces... TODO + else: + r = False + #Test for case of property set to something with parens such as "static const int CONST_A = (1 << 7) - 1;" + if r \ + and "(" in stack \ + and "=" in stack \ + and 'operator' not in stack: + if stack.index("=") < stack.index("("): r = False + return r + +def is_property_namestack(nameStack): + r = False + if '(' not in nameStack \ + and ')' not in nameStack: + r = True + elif "(" in nameStack \ + and "=" in nameStack \ + and nameStack.index("=") < nameStack.index("("): + r = True + #See if we are a function pointer + if not r \ + and is_function_pointer_stack(nameStack): + r = True + return r + +def detect_lineno(s): + """Detect the line number for a given token string""" + try: + rtn = s.lineno() + if rtn != -1: + return rtn + except: pass + global curLine + return curLine + +def filter_out_attribute_keyword(stack): + """Strips __attribute__ and its parenthetical expression from the stack""" + if "__attribute__" not in stack: + return stack + try: + debug.debug("Stripping __attribute__ from %s"% stack) + attr_index = stack.index("__attribute__") + attr_end = attr_index + 1 #Assuming not followed by parenthetical expression which wont happen + #Find final paren + if stack[attr_index + 1] == '(': + paren_count = 1 + for i in xrange(attr_index + 2, len(stack)): + elm = stack[i] + if elm == '(': + paren_count += 1 + elif elm == ')': + paren_count -= 1 + if paren_count == 0: + attr_end = i + 1 + break + new_stack = stack[0:attr_index] + stack[attr_end:] + debug.debug("stripped stack is %s"% new_stack) + return new_stack + except: + return stack + + + +supportedAccessSpecifier = [ + 'public', + 'protected', + 'private' +] + + +## +## @brief Join the class name element : ['class', 'Bar', ':', ':', 'Foo'] -> ['class', 'Bar::Foo'] +## @param table Input table to convert. ex: [':', '\t', 'class', 'Bar', ':', ':', 'Foo'] +## @return The new table. ex: ['class', 'Bar::Foo'] +## +def create_compleate_class_name(table): + compleateLine = "" + compleateLine = compleateLine.join(table); + if "::" not in compleateLine: + return table + # we need to convert it : + out = [] + for name in table: + if len(out) == 0: + out.append(name) + elif name == ":" \ + and out[-1].endswith(":"): + out[-1] += name + elif out[-1].endswith("::"): + out[-2] += out[-1] + name + del out[-1] + else: + out.append(name) + return out + +class parse_file(): + + def __init__(self, fileName): + self.m_classes = [] + self.m_elementParseStack = [] + debug.info("Parse File tod document : '" + fileName + "'") + + self.headerFileName = fileName + + self.anon_union_counter = [-1, 0] + # load all the file data : + headerFileStr = lutinTools.FileReadData(fileName) + + # Make sure supportedAccessSpecifier are sane + for i in range(0, len(supportedAccessSpecifier)): + if " " not in supportedAccessSpecifier[i]: continue + supportedAccessSpecifier[i] = re.sub("[ ]+", " ", supportedAccessSpecifier[i]).strip() + + # Strip out template declarations + # TODO : What is the real need ??? + headerFileStr = re.sub("template[\t ]*<[^>]*>", "", headerFileStr) + # remove all needed \r unneeded ==> this simplify next resExp ... + headerFileStr = re.sub("\r", "\r\n", headerFileStr) + headerFileStr = re.sub("\r\n\n", "\r\n", headerFileStr) + headerFileStr = re.sub("\r", "", headerFileStr) + # TODO : Can generate some error ... + headerFileStr = re.sub("\#if 0(.*?)(\#endif|\#else)", "", headerFileStr, flags=re.DOTALL) + + debug.debug(headerFileStr) + + # Change multi line #defines and expressions to single lines maintaining line nubmers + matches = re.findall(r'(?m)^(?:.*\\\n)+.*$', headerFileStr) + is_define = re.compile(r'[ \t\v]*#[Dd][Ee][Ff][Ii][Nn][Ee]') + for m in matches: + #Keep the newlines so that linecount doesnt break + num_newlines = len(filter(lambda a: a=="\n", m)) + if is_define.match(m): + new_m = m.replace("\n", "<**multiLine**>\\n") + else: + # Just expression taking up multiple lines, make it take 1 line for easier parsing + new_m = m.replace("\\\n", " ") + if (num_newlines > 0): + new_m += "\n"*(num_newlines) + headerFileStr = headerFileStr.replace(m, new_m) + + #Filter out Extern "C" statements. These are order dependent + headerFileStr = re.sub(r'extern( |\t)+"[Cc]"( |\t)*{', "{", headerFileStr) + + ###### debug.info(headerFileStr) + self.stack = [] # token stack to find the namespace and the element name ... + self.nameStack = [] # + self.braceDepth = 0 + lex.lex() + lex.input(headerFileStr) + global curLine + global curChar + curLine = 0 + curChar = 0 + while True: + tok = lex.token() + if not tok: + break + tok.value = TagStr(tok.value, lineno=tok.lineno) + debug.debug("TOK: " + str(tok)) + self.stack.append( tok.value ) + curLine = tok.lineno + curChar = tok.lexpos + if (tok.type in ('PRECOMP_MACRO', 'PRECOMP_MACRO_CONT')): + debug.debug("PRECOMP: " + str(tok)) + self.stack = [] + self.nameStack = [] + # Do nothing for macro ==> many time not needed ... + continue + if (tok.type == 'OPEN_BRACE'): + # When we open a brace, this is the time to parse the stack ... + # Clean the stack : (remove \t\r\n , and concatenate the 'xx', ':', ':', 'yy' in 'xx::yy', + self.nameStack = create_compleate_class_name(self.nameStack) + if len(self.nameStack) <= 0: + #open brace with no name ... + debug.warning("[" + str(self.braceDepth) + "] find an empty stack ...") + elif 'namespace' in self.nameStack: + debug.info("[" + str(self.braceDepth) + "] find a namespace : " + str(self.nameStack)); + elif 'class' in self.nameStack: + debug.info("[" + str(self.braceDepth) + "] find a class : " + str(self.nameStack)); + elif 'enum' in self.nameStack: + debug.info("[" + str(self.braceDepth) + "] find a enum : " + str(self.nameStack)); + elif 'struct' in self.nameStack: + debug.info("[" + str(self.braceDepth) + "] find a struct : " + str(self.nameStack)); + elif 'typedef' in self.nameStack: + debug.info("[" + str(self.braceDepth) + "] find a typedef : " + str(self.nameStack)); + elif 'union' in self.nameStack: + debug.info("[" + str(self.braceDepth) + "] find a union : " + str(self.nameStack)); + else: + debug.warning("[" + str(self.braceDepth) + "] find an unknow stack : " + str(self.nameStack)) + self.stack = [] + self.nameStack = [] + self.braceDepth += 1 + elif tok.type == 'CLOSE_BRACE': + self.braceDepth -= 1 + debug.info("[" + str(self.braceDepth) + "] close brace"); + if len(self.m_elementParseStack) != 0 \ + and self.m_elementParseStack[len(self.m_elementParseStack)-1]['level'] == self.braceDepth : + self.m_elementParseStack.pop() + if tok.type == 'OPEN_PAREN': + self.nameStack.append(tok.value) + elif tok.type == 'CLOSE_PAREN': + self.nameStack.append(tok.value) + elif tok.type == 'OPEN_SQUARE_BRACKET': + self.nameStack.append(tok.value) + elif tok.type == 'CLOSE_SQUARE_BRACKET': + self.nameStack.append(tok.value) + elif tok.type == 'TAB': + pass + elif tok.type == 'EQUALS': + self.nameStack.append(tok.value) + elif tok.type == 'COMMA': + self.nameStack.append(tok.value) + elif tok.type == 'BACKSLASH': + self.nameStack.append(tok.value) + elif tok.type == 'PIPE': + self.nameStack.append(tok.value) + elif tok.type == 'PERCENT': + self.nameStack.append(tok.value) + elif tok.type == 'CARET': + self.nameStack.append(tok.value) + elif tok.type == 'EXCLAMATION': + self.nameStack.append(tok.value) + elif tok.type == 'SQUOTE': + pass + elif tok.type == 'NUMBER': + self.nameStack.append(tok.value) + elif tok.type == 'MINUS': + self.nameStack.append(tok.value) + elif tok.type == 'PLUS': + self.nameStack.append(tok.value) + elif tok.type == 'STRING_LITERAL': + self.nameStack.append(tok.value) + elif tok.type == 'NAME' \ + or tok.type == 'AMPERSTAND' \ + or tok.type == 'ASTERISK' \ + or tok.type == 'CHAR_LITERAL': + self.nameStack.append(tok.value) + elif tok.type == 'COLON': + if self.nameStack[0] in ['private', 'protected', 'public']: + debug.info("[" + str(self.braceDepth) + "] change visibility : " + self.nameStack[0]); + self.nameStack = [] + self.stack = [] + else : + self.nameStack.append(tok.value) + elif tok.type == 'SEMI_COLON': + if len(self.nameStack) != 0: + debug.info("[" + str(self.braceDepth) + "] semicolumn : " + str(self.nameStack)); + self.stack = [] + self.nameStack = [] diff --git a/cppParser/README.html b/cppParser/README.html deleted file mode 100644 index 98f373c..0000000 --- a/cppParser/README.html +++ /dev/null @@ -1,598 +0,0 @@ - - - - - - - - - - -

- - -
-

Python package "CppHeaderParser"

-

Purpose: Parse C++ header files and generate a data structure representing the class

-

Author: Jashua Cloutier

-

Licence: BSD

-

External modules required: PLY

-

Quick start:

-
-#include <vector>
-#include <string>
-
-#define DEF_1 1
-#define OS_NAME "Linux"
-
-using namespace std;
-class SampleClass
-{
-public:
-    SampleClass();
-    /*!
-     * Method 1
-     */
-    string meth1();
-
-    ///
-    /// Method 2 description
-    ///
-    /// @param v1 Variable 1
-    ///
-    int meth2(int v1);
-
-    /**
-     * Method 3 description
-     *
-     * \param v1 Variable 1
-     * \param v2 Variable 2
-     */
-    void meth3(const string & v1, vector<string> & v2);
-
-    /**********************************
-     * Method 4 description
-     *
-     * @return Return value
-     *********************************/
-    unsigned int meth4();
-private:
-    void * meth5(){return NULL};
-
-    /// prop1 description
-    string prop1;
-    //! prop5 description
-    int prop5;
-};
-namespace Alpha
-{
-    class AlphaClass
-    {
-    public:
-        AlphaClass();
-
-        void alphaMethod();
-
-        string alphaString;
-    };
-
-    namespace Omega
-    {
-        class OmegaClass
-        {
-        public:
-            OmegaClass();
-
-            string omegaString;
-        };
-    };
-}
-
-int sampleFreeFunction(int i)
-{
-    return i + 1;
-}
-
-int anotherFreeFunction(void);
-}
-
-

Python code:

-
-#!/usr/bin/python
-import sys
-sys.path = ["../"] + sys.path
-import CppHeaderParser
-try:
-    cppHeader = CppHeaderParser.CppHeader("SampleClass.h")
-except CppHeaderParser.CppParseError,  e:
-    print e
-    sys.exit(1)
-
-print "CppHeaderParser view of %s"%cppHeader
-
-sampleClass = cppHeader.classes["SampleClass"]
-print "Number of public methods %d"%(len(sampleClass["methods"]["public"]))
-print "Number of private properties %d"%(len(sampleClass["properties"]["private"]))
-meth3 = [m for m in sampleClass["methods"]["public"] if m["name"] == "meth3"][0] #get meth3
-meth3ParamTypes = [t["type"] for t in meth3["parameters"]] #get meth3s parameters
-print "Parameter Types for public method meth3 %s"%(meth3ParamTypes)
-
-print "\nReturn type for meth1:"
-print cppHeader.classes["SampleClass"]["methods"]["public"][1]["rtnType"]
-
-print "\nDoxygen for meth2:"
-print cppHeader.classes["SampleClass"]["methods"]["public"][2]["doxygen"]
-
-print "\nParameters for meth3:"
-print cppHeader.classes["SampleClass"]["methods"]["public"][3]["parameters"]
-
-print "\nDoxygen for meth4:"
-print cppHeader.classes["SampleClass"]["methods"]["public"][4]["doxygen"]
-
-print "\nReturn type for meth5:"
-print cppHeader.classes["SampleClass"]["methods"]["private"][0]["rtnType"]
-
-print "\nDoxygen type for prop1:"
-print cppHeader.classes["SampleClass"]["properties"]["private"][0]["doxygen"]
-
-print "\nType for prop5:"
-print cppHeader.classes["SampleClass"]["properties"]["private"][1]["type"]
-
-print "\nNamespace for AlphaClass is:"
-print cppHeader.classes["AlphaClass"]["namespace"]
-
-print "\nReturn type for alphaMethod is:"
-print cppHeader.classes["AlphaClass"]["methods"]["public"][0]["rtnType"]
-
-print "\nNamespace for OmegaClass is:"
-print cppHeader.classes["OmegaClass"]["namespace"]
-
-print "\nType for omegaString is:"
-print cppHeader.classes["AlphaClass"]["properties"]["public"][0]["type"]
-
-print "\nFree functions are:"
-for func in cppHeader.functions:
-    print " %s"%func["name"]
-
-print "\n#includes are:"
-for incl in cppHeader.includes:
-    print " %s"%incl
-
-print "\n#defines are:"
-for define in cppHeader.defines:
-    print " %s"%define
-
-

Output:

-
-CppHeaderParser view of class SampleClass
-{
-public
-    // Methods
-   {'line_number': 11, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'SampleClass', 'returns_pointer': 0, 'class': None, 'name': 'SampleClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'SampleClass ( ) ;', 'inline': False}
-   {'line_number': 15, 'static': False, 'rtnType': 'string', 'returns_unknown': True, 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'string', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/*!\n* Method 1\n*/', 'name': 'meth1', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': False, 'constructor': False, 'debug': 'string meth1 ( ) ;', 'returns_pointer': 0}
-   {'line_number': 22, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 22, 'constant': 0, 'name': 'v1', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '///\n/// Method 2 description\n///\n/// @param v1 Variable 1\n///', 'name': 'meth2', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int meth2 ( int v1 ) ;', 'returns_pointer': 0}
-   {'line_number': 30, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [{'line_number': 30, 'constant': 1, 'name': 'v1', 'reference': 1, 'type': 'const string &', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}, {'line_number': 30, 'constant': 0, 'name': 'v2', 'reference': 1, 'type': 'vector<string> &', 'static': 0, 'pointer': 0, 'desc': 'Variable 2'}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'unresolved_parameters': True, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/**\n* Method 3 description\n*\n* \\param v1 Variable 1\n* \\param v2 Variable 2\n*/', 'name': 'meth3', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void meth3 ( const string & v1 , vector <string> & v2 ) ;', 'returns_pointer': 0}
-   {'line_number': 37, 'static': False, 'rtnType': 'unsigned int', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'unsigned int', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/**********************************\n* Method 4 description\n*\n* @return Return value\n*********************************/', 'name': 'meth4', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'unsigned int meth4 ( ) ;', 'returns_pointer': 0}
-protected
-private
-    // Properties
-    {'line_number': 42, 'constant': 0, 'name': 'prop1', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0}
-    {'line_number': 44, 'constant': 0, 'name': 'prop5', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0}
-    // Methods
-   {'line_number': 39, 'static': False, 'rtnType': 'void *', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'SampleClass', 'returns_pointer': 1, 'class': None, 'name': 'meth5', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void * meth5 ( ) {', 'inline': False}
-}
-
-class Alpha::AlphaClass
-{
-public
-    // Properties
-    {'line_number': 55, 'constant': 0, 'name': 'alphaString', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0}
-    // Methods
-   {'line_number': 51, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::AlphaClass', 'returns_pointer': 0, 'class': None, 'name': 'AlphaClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'AlphaClass ( ) ;', 'inline': False}
-   {'line_number': 53, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::AlphaClass', 'returns_pointer': 0, 'class': None, 'name': 'alphaMethod', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void alphaMethod ( ) ;', 'inline': False}
-protected
-private
-}
-
-class Alpha::Omega::OmegaClass
-{
-public
-    // Properties
-    {'line_number': 65, 'constant': 0, 'name': 'omegaString', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0}
-    // Methods
-   {'line_number': 63, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::Omega::', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::Omega::OmegaClass', 'returns_pointer': 0, 'class': None, 'name': 'OmegaClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'OmegaClass ( ) ;', 'inline': False}
-protected
-private
-}
-
-// functions
-{'line_number': 70, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 70, 'constant': 0, 'name': 'i', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'returns_pointer': 0, 'class': None, 'name': 'sampleFreeFunction', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int sampleFreeFunction ( int i ) {', 'inline': False}
-{'line_number': 75, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 75, 'constant': 0, 'name': '', 'reference': 0, 'type': 'void', 'static': 0, 'pointer': 0}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'returns_pointer': 0, 'class': None, 'name': 'anotherFreeFunction', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int anotherFreeFunction ( void ) ;', 'inline': False}
-
-Number of public methods 5
-Number of private properties 2
-Parameter Types for public method meth3 ['const string &', 'vector<string> &']
-
-Return type for meth1:
-string
-
-Doxygen for meth2:
-///
-/// Method 2 description
-///
-/// @param v1 Variable 1
-///
-
-Parameters for meth3:
-[{'line_number': 30, 'constant': 1, 'name': 'v1', 'reference': 1, 'type': 'const string &', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}, {'line_number': 30, 'constant': 0, 'name': 'v2', 'reference': 1, 'type': 'vector<string> &', 'static': 0, 'pointer': 0, 'desc': 'Variable 2'}]
-
-Doxygen for meth4:
-/**********************************
-* Method 4 description
-*
-* @return Return value
-*********************************/
-
-Return type for meth5:
-void *
-
-Doxygen type for prop1:
-/// prop1 description
-
-Type for prop5:
-int
-
-Namespace for AlphaClass is:
-Alpha
-
-Return type for alphaMethod is:
-void
-
-Namespace for OmegaClass is:
-Alpha::Omega
-
-Type for omegaString is:
-string
-
-Free functions are:
- sampleFreeFunction
- anotherFreeFunction
-
-#includes are:
- <vector>
- <string>
-
-#defines are:
- DEF_1 1
- OS_NAME "Linux"
-
-
-
-

Contributors

-
    -
  • Chris Love
  • -
  • HartsAntler
  • -
-
-
- - diff --git a/cppParser/README.txt b/cppParser/README.txt deleted file mode 100644 index 405f1ed..0000000 --- a/cppParser/README.txt +++ /dev/null @@ -1,266 +0,0 @@ -Python package "CppHeaderParser" --------------------------------- -**Purpose:** Parse C++ header files and generate a data structure representing the class - -**Author:** Jashua Cloutier - -**Licence:** BSD - -**External modules required:** PLY - -**Quick start**:: - - #include - #include - - #define DEF_1 1 - #define OS_NAME "Linux" - - using namespace std; - class SampleClass - { - public: - SampleClass(); - /*! - * Method 1 - */ - string meth1(); - - /// - /// Method 2 description - /// - /// @param v1 Variable 1 - /// - int meth2(int v1); - - /** - * Method 3 description - * - * \param v1 Variable 1 - * \param v2 Variable 2 - */ - void meth3(const string & v1, vector & v2); - - /********************************** - * Method 4 description - * - * @return Return value - *********************************/ - unsigned int meth4(); - private: - void * meth5(){return NULL}; - - /// prop1 description - string prop1; - //! prop5 description - int prop5; - }; - namespace Alpha - { - class AlphaClass - { - public: - AlphaClass(); - - void alphaMethod(); - - string alphaString; - }; - - namespace Omega - { - class OmegaClass - { - public: - OmegaClass(); - - string omegaString; - }; - }; - } - - int sampleFreeFunction(int i) - { - return i + 1; - } - - int anotherFreeFunction(void); - } - - -**Python code**:: - - #!/usr/bin/python - import sys - sys.path = ["../"] + sys.path - import CppHeaderParser - try: - cppHeader = CppHeaderParser.CppHeader("SampleClass.h") - except CppHeaderParser.CppParseError, e: - print e - sys.exit(1) - - print "CppHeaderParser view of %s"%cppHeader - - sampleClass = cppHeader.classes["SampleClass"] - print "Number of public methods %d"%(len(sampleClass["methods"]["public"])) - print "Number of private properties %d"%(len(sampleClass["properties"]["private"])) - meth3 = [m for m in sampleClass["methods"]["public"] if m["name"] == "meth3"][0] #get meth3 - meth3ParamTypes = [t["type"] for t in meth3["parameters"]] #get meth3s parameters - print "Parameter Types for public method meth3 %s"%(meth3ParamTypes) - - print "\nReturn type for meth1:" - print cppHeader.classes["SampleClass"]["methods"]["public"][1]["rtnType"] - - print "\nDoxygen for meth2:" - print cppHeader.classes["SampleClass"]["methods"]["public"][2]["doxygen"] - - print "\nParameters for meth3:" - print cppHeader.classes["SampleClass"]["methods"]["public"][3]["parameters"] - - print "\nDoxygen for meth4:" - print cppHeader.classes["SampleClass"]["methods"]["public"][4]["doxygen"] - - print "\nReturn type for meth5:" - print cppHeader.classes["SampleClass"]["methods"]["private"][0]["rtnType"] - - print "\nDoxygen type for prop1:" - print cppHeader.classes["SampleClass"]["properties"]["private"][0]["doxygen"] - - print "\nType for prop5:" - print cppHeader.classes["SampleClass"]["properties"]["private"][1]["type"] - - print "\nNamespace for AlphaClass is:" - print cppHeader.classes["AlphaClass"]["namespace"] - - print "\nReturn type for alphaMethod is:" - print cppHeader.classes["AlphaClass"]["methods"]["public"][0]["rtnType"] - - print "\nNamespace for OmegaClass is:" - print cppHeader.classes["OmegaClass"]["namespace"] - - print "\nType for omegaString is:" - print cppHeader.classes["AlphaClass"]["properties"]["public"][0]["type"] - - print "\nFree functions are:" - for func in cppHeader.functions: - print " %s"%func["name"] - - print "\n#includes are:" - for incl in cppHeader.includes: - print " %s"%incl - - print "\n#defines are:" - for define in cppHeader.defines: - print " %s"%define - -**Output**:: - - CppHeaderParser view of class SampleClass - { - public - // Methods - {'line_number': 11, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'SampleClass', 'returns_pointer': 0, 'class': None, 'name': 'SampleClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'SampleClass ( ) ;', 'inline': False} - {'line_number': 15, 'static': False, 'rtnType': 'string', 'returns_unknown': True, 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'string', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/*!\n* Method 1\n*/', 'name': 'meth1', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': False, 'constructor': False, 'debug': 'string meth1 ( ) ;', 'returns_pointer': 0} - {'line_number': 22, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 22, 'constant': 0, 'name': 'v1', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '///\n/// Method 2 description\n///\n/// @param v1 Variable 1\n///', 'name': 'meth2', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int meth2 ( int v1 ) ;', 'returns_pointer': 0} - {'line_number': 30, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [{'line_number': 30, 'constant': 1, 'name': 'v1', 'reference': 1, 'type': 'const string &', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}, {'line_number': 30, 'constant': 0, 'name': 'v2', 'reference': 1, 'type': 'vector &', 'static': 0, 'pointer': 0, 'desc': 'Variable 2'}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'unresolved_parameters': True, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/**\n* Method 3 description\n*\n* \\param v1 Variable 1\n* \\param v2 Variable 2\n*/', 'name': 'meth3', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void meth3 ( const string & v1 , vector & v2 ) ;', 'returns_pointer': 0} - {'line_number': 37, 'static': False, 'rtnType': 'unsigned int', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'unsigned int', 'template': False, 'friend': False, 'returns_class': False, 'inline': False, 'extern': False, 'path': 'SampleClass', 'class': None, 'doxygen': '/**********************************\n* Method 4 description\n*\n* @return Return value\n*********************************/', 'name': 'meth4', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'unsigned int meth4 ( ) ;', 'returns_pointer': 0} - protected - private - // Properties - {'line_number': 42, 'constant': 0, 'name': 'prop1', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0} - {'line_number': 44, 'constant': 0, 'name': 'prop5', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0} - // Methods - {'line_number': 39, 'static': False, 'rtnType': 'void *', 'const': False, 'parameters': [], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'SampleClass', 'returns_pointer': 1, 'class': None, 'name': 'meth5', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void * meth5 ( ) {', 'inline': False} - } - - class Alpha::AlphaClass - { - public - // Properties - {'line_number': 55, 'constant': 0, 'name': 'alphaString', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0} - // Methods - {'line_number': 51, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::AlphaClass', 'returns_pointer': 0, 'class': None, 'name': 'AlphaClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'AlphaClass ( ) ;', 'inline': False} - {'line_number': 53, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::', 'virtual': False, 'destructor': False, 'returns': 'void', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::AlphaClass', 'returns_pointer': 0, 'class': None, 'name': 'alphaMethod', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'void alphaMethod ( ) ;', 'inline': False} - protected - private - } - - class Alpha::Omega::OmegaClass - { - public - // Properties - {'line_number': 65, 'constant': 0, 'name': 'omegaString', 'reference': 0, 'type': 'string', 'static': 0, 'pointer': 0} - // Methods - {'line_number': 63, 'static': False, 'rtnType': 'void', 'const': False, 'parameters': [], 'namespace': 'Alpha::Omega::', 'virtual': False, 'destructor': False, 'returns': '', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'path': 'Alpha::Omega::OmegaClass', 'returns_pointer': 0, 'class': None, 'name': 'OmegaClass', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': True, 'debug': 'OmegaClass ( ) ;', 'inline': False} - protected - private - } - - // functions - {'line_number': 70, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 70, 'constant': 0, 'name': 'i', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'returns_pointer': 0, 'class': None, 'name': 'sampleFreeFunction', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int sampleFreeFunction ( int i ) {', 'inline': False} - {'line_number': 75, 'static': False, 'rtnType': 'int', 'const': False, 'parameters': [{'line_number': 75, 'constant': 0, 'name': '', 'reference': 0, 'type': 'void', 'static': 0, 'pointer': 0}], 'namespace': '', 'virtual': False, 'destructor': False, 'returns': 'int', 'template': False, 'friend': False, 'returns_class': False, 'extern': False, 'returns_pointer': 0, 'class': None, 'name': 'anotherFreeFunction', 'pure_virtual': False, 'explicit': False, 'returns_fundamental': True, 'constructor': False, 'debug': 'int anotherFreeFunction ( void ) ;', 'inline': False} - - Number of public methods 5 - Number of private properties 2 - Parameter Types for public method meth3 ['const string &', 'vector &'] - - Return type for meth1: - string - - Doxygen for meth2: - /// - /// Method 2 description - /// - /// @param v1 Variable 1 - /// - - Parameters for meth3: - [{'line_number': 30, 'constant': 1, 'name': 'v1', 'reference': 1, 'type': 'const string &', 'static': 0, 'pointer': 0, 'desc': 'Variable 1'}, {'line_number': 30, 'constant': 0, 'name': 'v2', 'reference': 1, 'type': 'vector &', 'static': 0, 'pointer': 0, 'desc': 'Variable 2'}] - - Doxygen for meth4: - /********************************** - * Method 4 description - * - * @return Return value - *********************************/ - - Return type for meth5: - void * - - Doxygen type for prop1: - /// prop1 description - - Type for prop5: - int - - Namespace for AlphaClass is: - Alpha - - Return type for alphaMethod is: - void - - Namespace for OmegaClass is: - Alpha::Omega - - Type for omegaString is: - string - - Free functions are: - sampleFreeFunction - anotherFreeFunction - - #includes are: - - - - #defines are: - DEF_1 1 - OS_NAME "Linux" - - - -Contributors ------------- -* Chris Love -* HartsAntler diff --git a/cppParser/Resolver.py b/cppParser/Resolver.py new file mode 100644 index 0000000..e69de29 diff --git a/cppParser/Struct.py b/cppParser/Struct.py new file mode 100644 index 0000000..7393540 --- /dev/null +++ b/cppParser/Struct.py @@ -0,0 +1,22 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + +import inspect + +class CppStruct(dict): + Structs = [] + def __init__(self, nameStack): + if len(nameStack) >= 2: self['type'] = nameStack[1] + else: self['type'] = None + self['fields'] = [] + self.Structs.append( self ) + global curLine + self["line_number"] = curLine diff --git a/cppParser/Type.py b/cppParser/Type.py new file mode 100644 index 0000000..1f7c3ef --- /dev/null +++ b/cppParser/Type.py @@ -0,0 +1,28 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + +import inspect + +class Type(): + def __init__(self): + self.name = "" + self.const = False # the const xxxxx + self.constVar = False # the char* const VarName + self.static = False + self.inline = False + self.reference = False + + +class TypeVoid(Type): + def __init__(self): + Type.__init__() + self.name = "void" + diff --git a/cppParser/Union.py b/cppParser/Union.py new file mode 100644 index 0000000..def346b --- /dev/null +++ b/cppParser/Union.py @@ -0,0 +1,10 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re diff --git a/cppParser/Variable.py b/cppParser/Variable.py new file mode 100644 index 0000000..a126e27 --- /dev/null +++ b/cppParser/Variable.py @@ -0,0 +1,23 @@ +#!/usr/bin/python +try : + # normal install module + import ply.lex as lex +except ImportError : + # local module + import lex +import os +import sys +import re + +class Variable(): + def __init__(self): + self.name = "" + self.type = Type.TypeVoid() + self.const = False # the const xxxxx + self.constVar = False # the char* const VarName + self.static = False + self.external = False + + def to_str(self) : + return "" + diff --git a/cppParser/CppHeaderParser/CppHeaderParser.py b/cppParser/parserCpp.py similarity index 100% rename from cppParser/CppHeaderParser/CppHeaderParser.py rename to cppParser/parserCpp.py diff --git a/cppParser/setup.py b/cppParser/setup.py deleted file mode 100755 index 1a22a05..0000000 --- a/cppParser/setup.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import sys, glob -from distutils.core import setup - -DESCRIPTION = ( - 'Parse C++ header files and generate a data structure ' - 'representing the class' - ) - - -CLASSIFIERS = [ - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 3', - 'Programming Language :: C++', - 'License :: OSI Approved :: BSD License', - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Topic :: Software Development', - 'Topic :: Software Development :: Code Generators', - 'Topic :: Software Development :: Compilers', - 'Topic :: Software Development :: Disassemblers' - ] - -setup( - name = 'CppHeaderParser', - version = '2.4', - author = 'Jashua Cloutier', - author_email = 'jashuac@bellsouth.net', - url = 'http://senexcanis.com/open-source/cppheaderparser/', - description = DESCRIPTION, - long_description = open('README.txt').read(), - license = 'BSD', - platforms = 'Platform Independent', - packages = ['CppHeaderParser'], - keywords = 'c++ header parser ply', - classifiers = CLASSIFIERS, - requires = ['ply'], - package_data = { 'CppHeaderParser': ['README', 'README.html', 'doc/*.*', 'examples/*.*'], }, - ) diff --git a/lutinDoc.py b/lutinDoc.py index b642dca..449c548 100644 --- a/lutinDoc.py +++ b/lutinDoc.py @@ -5,9 +5,11 @@ import lutinTools # TODO : Add try of generic input ... sys.path.append(lutinTools.GetCurrentPath(__file__) + "/ply/ply/") sys.path.append(lutinTools.GetCurrentPath(__file__) + "/cppParser/CppHeaderParser/") +sys.path.append(lutinTools.GetCurrentPath(__file__) + "/cppParser/") sys.path.append(lutinTools.GetCurrentPath(__file__) + "/codeBB/") sys.path.append(lutinTools.GetCurrentPath(__file__) + "/codeHL/") import CppHeaderParser +import Parse import lutinDocHtml import lutinDocMd import os @@ -131,6 +133,9 @@ class doc: ## def add_file(self, filename): debug.debug("adding file in documantation : '" + filename + "'"); + plop = Parse.parse_file('/home/edupin/dev/perso/Widget.h') + debug.error("parse done"); + try: metaData = CppHeaderParser.CppHeader(filename) except CppHeaderParser.CppParseError, e: