diff --git a/.travis.yml b/.travis.yml index 35f8643..d57fc60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,15 +11,15 @@ python: matrix: fast_finish: true -# jobs: -# include: -# - stage: format-check -# python: -# - "3.6" -# install: -# - pip install black -# script: -# - black --check --diff . +jobs: + include: + - stage: format-check + python: + - "3.6" + install: + - pip install black + script: + - black --check --diff . # command to install dependencies install: diff --git a/CppHeaderParser/CppHeaderParser.py b/CppHeaderParser/CppHeaderParser.py index 93c124f..9fdae7b 100644 --- a/CppHeaderParser/CppHeaderParser.py +++ b/CppHeaderParser/CppHeaderParser.py @@ -56,79 +56,83 @@ import inspect + def lineno(): """Returns the current line number in our program.""" return inspect.currentframe().f_back.f_lineno + try: from .version import __version__ except ImportError: - __version__ = 'devel' + __version__ = "devel" version = __version__ tokens = [ - 'NUMBER', - 'FLOAT_NUMBER', - 'TEMPLATE_NAME', - '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', - 'ELLIPSIS', - 'DOT', + "NUMBER", + "FLOAT_NUMBER", + "TEMPLATE_NAME", + "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", + "ELLIPSIS", + "DOT", ] t_ignore = " \r?@\f" -t_NUMBER = r'[0-9][0-9XxA-Fa-f]*' -t_FLOAT_NUMBER = r'[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?' -t_TEMPLATE_NAME = r'CppHeaderParser_template_[0-9]+' -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' +t_NUMBER = r"[0-9][0-9XxA-Fa-f]*" +t_FLOAT_NUMBER = r"[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?" +t_TEMPLATE_NAME = r"CppHeaderParser_template_[0-9]+" +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?' + r"\/\/.*\n?" global doxygenCommentCache if t.value.startswith("///") or t.value.startswith("//!"): if doxygenCommentCache: @@ -137,37 +141,43 @@ def t_COMMENT_SINGLELINE(t): 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.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 = "'" -t_ELLIPSIS = r'\.\.\.' -t_DOT = r'\.' -#found at http://wordaligned.org/articles/string-literals-and-regular-expressions -#TODO: This does not work with the string "bla \" bla" +t_ELLIPSIS = r"\.\.\." +t_DOT = r"\." +# 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 +# Found at http://ostermiller.org/findcomment.html def t_COMMENT_MULTILINE(t): - r'/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/' + r"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/" global doxygenCommentCache if t.value.startswith("/**") or t.value.startswith("/*!"): - #not sure why, but get double new lines + # not sure why, but get double new lines v = t.value.replace("\n\n", "\n") - #strip prefixing whitespace + # 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"]) + t.lexer.lineno += len([a for a in t.value if a == "\n"]) + + def t_NEWLINE(t): - r'\n+' + r"\n+" t.lexer.lineno += len(t.value) + def t_error(v): - print(( "Lex error: ", v )) + print(("Lex error: ", v)) + lex.lex() # Controls error_print @@ -179,39 +189,43 @@ def t_error(v): # Controls trace_print debug_trace = 0 + def error_print(arg): - if print_errors: print(("[%4d] %s"%(inspect.currentframe().f_back.f_lineno, 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))) + 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))) + 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("[%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', -] +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 +# 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: @@ -220,6 +234,7 @@ def is_namespace(nameStack): return True return False + def is_enum_namestack(nameStack): """Determines if a namestack is an enum namestack""" if len(nameStack) == 0: @@ -230,11 +245,29 @@ def is_enum_namestack(nameStack): 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 + 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 @@ -251,96 +284,125 @@ def is_function_pointer_stack(stack): 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 "(" 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 + 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 + 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 + except: + pass global curLine - return 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 + if "__attribute__" not in stack: + return stack try: - debug_print("Stripping __attribute__ from %s"% stack) + 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] == '(': + 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 == '(': + if elm == "(": paren_count += 1 - elif elm == ')': + 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) + 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) + + 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 - + except: + pass + def lineno(self): return TagStr.lineno_reg.get(id(self), -1) -class CppParseError(Exception): pass - + +class CppParseError(Exception): + pass + + class CppClass(dict): """Takes a name stack and turns it into a class @@ -387,54 +449,58 @@ class CppClass(dict): def get_all_methods(self): r = [] - for typ in supportedAccessSpecifier: r += self['methods'][typ] + for typ in supportedAccessSpecifier: + r += self["methods"][typ] return r - def get_all_method_names( self ): + def get_all_method_names(self): r = [] - for typ in supportedAccessSpecifier: r += self.get_method_names(typ) # returns list + for typ in supportedAccessSpecifier: + r += self.get_method_names(typ) # returns list return r - def get_all_pure_virtual_methods( self ): + def get_all_pure_virtual_methods(self): r = {} - for typ in supportedAccessSpecifier: r.update(self.get_pure_virtual_methods(typ)) # returns dict + 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_method_names( self, type='public' ): return [ meth['name'] for meth in self['methods'][ type ] ] - - def get_pure_virtual_methods( self, type='public' ): + def get_pure_virtual_methods(self, type="public"): r = {} - for meth in self['methods'][ type ]: - if meth['pure_virtual']: r[ meth['name'] ] = meth + for meth in self["methods"][type]: + if meth["pure_virtual"]: + r[meth["name"]] = meth return r def __init__(self, nameStack, curTemplate): - self['nested_classes'] = [] - self['parent'] = None - self['abstract'] = False + self["nested_classes"] = [] + self["parent"] = None + self["abstract"] = False self._public_enums = {} self._public_structs = {} self._public_typedefs = {} self._public_forward_declares = [] - self['namespace'] = "" + self["namespace"] = "" - debug_print( "Class: %s"%nameStack ) - debug_print( "Template: %s"%curTemplate) - - if (len(nameStack) < 2): - nameStack.insert(1, "")#anonymous struct + debug_print("Class: %s" % nameStack) + debug_print("Template: %s" % curTemplate) + + 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'] + # Re-Join class paths (ex ['class', 'Bar', ':', ':', 'Foo'] -> ['class', 'Bar::Foo'] try: new_nameStack = [] for name in nameStack: - if len(new_nameStack) == 0: + if len(new_nameStack) == 0: new_nameStack.append(name) elif name == ":" and new_nameStack[-1].endswith(":"): new_nameStack[-1] += name @@ -443,10 +509,13 @@ def __init__(self, nameStack, curTemplate): del new_nameStack[-1] else: new_nameStack.append(name) - trace_print("Convert from namestack\n %s\nto\n%s"%(nameStack, new_nameStack)) + trace_print( + "Convert from namestack\n %s\nto\n%s" % (nameStack, new_nameStack) + ) nameStack = new_nameStack - except: pass - + except: + pass + # Handle final specifier self["final"] = False try: @@ -455,105 +524,119 @@ def __init__(self, nameStack, curTemplate): del nameStack[final_index] self["final"] = True trace_print("final") - except: pass - + except: + pass + self["name"] = nameStack[1] self["line_number"] = detect_lineno(nameStack[0]) - - #Handle template classes + + # 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 : + if "<" in elm: open_template_count += 1 found_first = True - elif '>' in elm: + elif ">" in elm: open_template_count -= 1 if found_first and open_template_count == 0: - self["name"] = "".join(nameStack[1:i + 1]) - break; + self["name"] = "".join(nameStack[1 : i + 1]) + break i += 1 elif ":" in nameStack: - self['name'] = nameStack[ nameStack.index(':') - 1 ] + self["name"] = nameStack[nameStack.index(":") - 1] inheritList = [] - if nameStack.count(':') == 1: - nameStack = nameStack[nameStack.index(":") + 1:] + if nameStack.count(":") == 1: + nameStack = nameStack[nameStack.index(":") + 1 :] while len(nameStack): tmpStack = [] - tmpInheritClass = {"access":"private", "virtual": False} + tmpInheritClass = {"access": "private", "virtual": False} if "," in nameStack: - tmpStack = nameStack[:nameStack.index(",")] - nameStack = nameStack[nameStack.index(",") + 1:] + 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:])) + if "<" in tmpStack[i]: + tmpStack2 = tmpStack[: i - 1] + tmpStack2.append("".join(tmpStack[i - 1 :])) tmpStack = tmpStack2 break if len(tmpStack) == 0: - break; + 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["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 + 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) - if 'class' in tmpInheritClass: inheritList.append(tmpInheritClass) + elif nameStack.count(":") == 2: + self["parent"] = self["name"] + self["name"] = nameStack[-1] - 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 :] - elif nameStack.count(':') > 2 and nameStack[0] in ("class", "struct"): - tmpStack = nameStack[nameStack.index(":") + 1:] - superTmpStack = [[]] for tok in tmpStack: - if tok == ',': + if tok == ",": superTmpStack.append([]) else: superTmpStack[-1].append(tok) - + for tmpStack in superTmpStack: - tmpInheritClass = {"access":"private"} - + 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; + 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]) + if len(tmpStack) == 1 and tmpStack[0] != ":": + inheritNSStack.append(tmpStack[0]) tmpInheritClass["class"] = "::".join(inheritNSStack) inheritList.append(tmpInheritClass) - self['inherits'] = inheritList + self["inherits"] = inheritList if curTemplate: self["template"] = curTemplate - trace_print("Setting template to '%s'"%self["template"]) + trace_print("Setting template to '%s'" % self["template"]) methodAccessSpecificList = {} propertyAccessSpecificList = {} @@ -561,7 +644,7 @@ def __init__(self, nameStack, curTemplate): structAccessSpecificList = {} typedefAccessSpecificList = {} forwardAccessSpecificList = {} - + for accessSpecifier in supportedAccessSpecifier: methodAccessSpecificList[accessSpecifier] = [] propertyAccessSpecificList[accessSpecifier] = [] @@ -570,94 +653,107 @@ def __init__(self, nameStack, curTemplate): typedefAccessSpecificList[accessSpecifier] = [] forwardAccessSpecificList[accessSpecifier] = [] - self['methods'] = methodAccessSpecificList - self['properties'] = propertyAccessSpecificList - self['enums'] = enumAccessSpecificList - self['structs'] = structAccessSpecificList - self['typedefs'] = typedefAccessSpecificList - self['forward_declares'] = forwardAccessSpecificList + 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["final"]: rtn += " final" - if self['abstract']: rtn += ' (abstract)\n' - else: rtn += '\n' + if self["namespace"]: + namespace_prefix = self["namespace"] + "::" + rtn = "%s %s" % (self["declaration_method"], namespace_prefix + self["name"]) + if self["final"]: + rtn += " final" + 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 "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"]) + 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 += " %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 += " %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 += " %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 += "\t\t" + method.show() + "\n" rtn += " }\n" print(rtn) - + def __str__(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["final"]: rtn += " final" - if self['abstract']: rtn += ' (abstract)\n' - else: rtn += '\n' + if self["namespace"]: + namespace_prefix = self["namespace"] + "::" + rtn = "%s %s" % (self["declaration_method"], namespace_prefix + self["name"]) + if self["final"]: + rtn += " final" + 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 "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"]) + 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 += "%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 += " %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 += " %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 += " %s\n" % (repr(method)) rtn += "}\n" return rtn -class CppUnion( CppClass ): +class CppUnion(CppClass): """Takes a name stack and turns it into a union Contains the following Keys: @@ -672,89 +768,115 @@ class CppUnion( CppClass ): 'members': [] } """ - + def __init__(self, nameStack): CppClass.__init__(self, nameStack, None) 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] - + 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 __str__(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 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 "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 += " %s\n" % (repr(member)) rtn += "}\n" return rtn - -class _CppMethod( dict ): - def _params_helper1( self, stack ): +class _CppMethod(dict): + def _params_helper1(self, stack): # deal with "throw" keyword - if 'throw' in stack: stack = stack[ : stack.index('throw') ] + if "throw" in stack: + stack = stack[: stack.index("throw")] ## remove GCC keyword __attribute__(...) and preserve returns ## cleaned = [] - hit = False; hitOpen = 0; hitClose = 0 + hit = False + hitOpen = 0 + hitClose = 0 for a in stack: - if a == '__attribute__': hit = True + if a == "__attribute__": + hit = True if hit: - if a == '(': hitOpen += 1 - elif a == ')': hitClose += 1 - if a==')' and hitOpen == hitClose: + if a == "(": + hitOpen += 1 + elif a == ")": + hitClose += 1 + if a == ")" and hitOpen == hitClose: hit = False else: - cleaned.append( a ) + 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 + 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 + 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 return stack - def _params_helper2( self, params ): + 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] + 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' ] + p["type"] = self["namespace"] + p["type"] + else: + p["namespace"] = self["namespace"] -class CppMethod( _CppMethod ): + +class CppMethod(_CppMethod): """Takes a name stack and turns it into a method Contains the following Keys: @@ -763,55 +885,75 @@ class CppMethod( _CppMethod ): 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 ) + 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, curTemplate): - debug_print( "Method: %s"%nameStack ) - debug_print( "Template: %s"%curTemplate ) + debug_print("Method: %s" % nameStack) + debug_print("Template: %s" % curTemplate) 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('(')]) + 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('(')]) + 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() + 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["rtnType"] = self["rtnType"].replace(" : : ", "::") + self["rtnType"] = self["rtnType"].replace(" <", "<") + self["rtnType"] = ( + self["rtnType"].replace(" >", ">").replace(">>", "> >").replace(">>", "> >") + ) + self["rtnType"] = self["rtnType"].replace(" ,", ",") + # deal with "noexcept" specifier/operator cleaned = [] - hit = False; parentCount = 0 - self['noexcept'] = '' + hit = False + parentCount = 0 + self["noexcept"] = "" for a in nameStack: - if a == 'noexcept': hit = True + if a == "noexcept": + hit = True if hit: - if a == '(': parentCount += 1 - elif a == ')': parentCount -= 1 - elif parentCount == 0 and a != 'noexcept': hit = False; cleaned.append( a ); continue # noexcept without parenthesis - if a==')' and parentCount == 0: hit = False - self['noexcept'] += a + if a == "(": + parentCount += 1 + elif a == ")": + parentCount -= 1 + elif parentCount == 0 and a != "noexcept": + hit = False + cleaned.append(a) + continue # noexcept without parenthesis + if a == ")" and parentCount == 0: + hit = False + self["noexcept"] += a else: - cleaned.append( a ) + cleaned.append(a) nameStack = cleaned - self['noexcept'] = self['noexcept'] if self['noexcept'] else None - + self["noexcept"] = self["noexcept"] if self["noexcept"] else None + for spec in ["const", "final", "override"]: self[spec] = False for i in reversed(nameStack): @@ -821,10 +963,10 @@ def __init__(self, nameStack, curClass, methinfo, curTemplate): elif i == ")": break - self.update( methinfo ) + self.update(methinfo) self["line_number"] = detect_lineno(nameStack[0]) - #Filter out initializer lists used in constructors + # Filter out initializer lists used in constructors try: paren_depth_counter = 0 for i in range(0, len(nameStack)): @@ -832,36 +974,38 @@ def __init__(self, nameStack, curClass, methinfo, curTemplate): if elm == "(": paren_depth_counter += 1 if elm == ")": - paren_depth_counter -=1 - if paren_depth_counter == 0 and nameStack[i+1] == ':': + paren_depth_counter -= 1 + if paren_depth_counter == 0 and nameStack[i + 1] == ":": debug_print("Stripping out initializer list") - nameStack = nameStack[:i+1] + nameStack = nameStack[: i + 1] break - except: pass - - paramsStack = self._params_helper1( nameStack ) - - debug_print( "curTemplate: %s"%curTemplate) + except: + pass + + paramsStack = self._params_helper1(nameStack) + + debug_print("curTemplate: %s" % curTemplate) if curTemplate: self["template"] = curTemplate - debug_print( "SET self['template'] to `%s`"%self["template"]) + debug_print("SET self['template'] to `%s`" % self["template"]) params = [] - #See if there is a doxygen comment for the variable + # 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:] + # Strip out the param + doxyLine = doxyLine[doxyLine.find("param ") + 6 :] (var, desc) = doxyLine.split(" ", 1) doxyVarDesc[var] = desc.strip() lastParamDesc = var - except: pass + except: + pass elif " @return " in doxyLine or " \return " in doxyLine: lastParamDesc = "" # not handled for now @@ -871,81 +1015,95 @@ def __init__(self, nameStack, curClass, methinfo, curTemplate): if " " not in doxyLine: lastParamDesc = "" continue - doxyLine = doxyLine[doxyLine.find(" ") + 1:] + doxyLine = doxyLine[doxyLine.find(" ") + 1 :] doxyVarDesc[lastParamDesc] += " " + doxyLine - except: pass + except: + pass # non-vararg by default self["vararg"] = False - #Create the variable now - while (len(paramsStack)): + # Create the variable now + while len(paramsStack): # Find commas that are not nexted in <>'s like template types open_template_count = 0 open_paren_count = 0 param_separator = 0 i = 0 for elm in paramsStack: - if '<' in elm : + if "<" in elm: open_template_count += 1 - elif '>' in elm: + elif ">" in elm: open_template_count -= 1 - elif '(' in elm : + elif "(" in elm: open_paren_count += 1 - elif ')' in elm: + elif ")" in elm: open_paren_count -= 1 - elif elm == ',' and open_template_count == 0 and open_paren_count==0: + elif elm == "," and open_template_count == 0 and open_paren_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:] + param = CppVariable( + paramsStack[0:param_separator], doxyVarDesc=doxyVarDesc + ) + if len(list(param.keys())): + params.append(param) + paramsStack = paramsStack[param_separator + 1 :] elif len(paramsStack) and paramsStack[0] == "...": self["vararg"] = True paramsStack = paramsStack[1:] else: - param = CppVariable(paramsStack, doxyVarDesc=doxyVarDesc) - if len(list(param.keys())): params.append(param) + param = CppVariable(paramsStack, doxyVarDesc=doxyVarDesc) + if len(list(param.keys())): + params.append(param) break - self["parameters"] = params - self._params_helper2( params ) # mods params inplace + self._params_helper2(params) # mods params inplace def __str__(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 + 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 ): + def _name_stack_helper(self, stack): stack = list(stack) - if '=' not in stack: # TODO refactor me + 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 + 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);" + # 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 ): + 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: @@ -958,94 +1116,122 @@ class CppVariable( _CppVariable ): exist if there is a default value self['extern'] - True if its an extern, false if not """ + Vars = [] - def __init__(self, nameStack, **kwargs): - debug_print("trace %s"%nameStack) + + def __init__(self, nameStack, **kwargs): + debug_print("trace %s" % nameStack) if len(nameStack) and nameStack[0] == "extern": - self['extern'] = True + self["extern"] = True del nameStack[0] else: - self['extern'] = False - + self["extern"] = False + _stack_ = nameStack - if "[" in nameStack: #strip off array informatin - arrayStack = nameStack[nameStack.index("["):] + if "[" in nameStack: # strip off array informatin + arrayStack = nameStack[nameStack.index("[") :] if nameStack.count("[") > 1: debug_print("Multi dimensional array") - debug_print("arrayStack=%s"%arrayStack) + debug_print("arrayStack=%s" % arrayStack) nums = [x for x in arrayStack if x.isdigit()] # Calculate size by multiplying all dimensions p = 1 for n in nums: p *= int(n) - #Multi dimensional array + # Multi dimensional array self["array_size"] = p self["multi_dimensional_array"] = 1 self["multi_dimensional_array_size"] = "x".join(nums) else: debug_print("Array") if len(arrayStack) == 3: - self["array_size"] = arrayStack[1] - nameStack = nameStack[:nameStack.index("[")] + self["array_size"] = arrayStack[1] + nameStack = nameStack[: nameStack.index("[")] self["array"] = 1 else: self["array"] = 0 - nameStack = self._name_stack_helper( nameStack ) + nameStack = self._name_stack_helper(nameStack) global doxygenCommentCache if len(doxygenCommentCache): self["doxygen"] = doxygenCommentCache doxygenCommentCache = "" - debug_print( "Variable: %s"%nameStack ) + 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(")")]) + 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]) + elif "=" in nameStack: + self["type"] = " ".join(nameStack[: nameStack.index("=") - 1]) self["name"] = nameStack[nameStack.index("=") - 1] - self["defaultValue"] = " ".join(nameStack[nameStack.index("=") + 1:]) # deprecate camelCase in dicts - self['default'] = " ".join(nameStack[nameStack.index("=") + 1:]) + self["defaultValue"] = " ".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 + elif is_fundamental(nameStack[-1]) or nameStack[-1] in [">", "<", ":", "."]: + # Un named parameter self["type"] = " ".join(nameStack) self["name"] = "" - else: # common case + 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 + 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 + except: + pass self.init() - CppVariable.Vars.append( self ) # save and resolve later - + CppVariable.Vars.append(self) # save and resolve later + def __str__(self): - keys_white_list = ['constant','name','reference','type','static','pointer','desc', 'line_number', 'extern'] - 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 + keys_white_list = [ + "constant", + "name", + "reference", + "type", + "static", + "pointer", + "desc", + "line_number", + "extern", + ] + 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 ): + 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: @@ -1057,42 +1243,49 @@ def resolve_enum_values( self, values ): {'name': 'RED', 'value': 1}, {'name': 'GREEN', 'value': 8}] """ - t = int; i = 0 - names = [ v['name'] for v in values ] + t = int + i = 0 + names = [v["name"] for v in values] for v in values: - if 'value' in v: - a = v['value'].strip() + 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] + a = v["value"] = a[1] if a.lower().startswith("0x"): try: - i = a = int(a , 16) - except:pass + i = a = int(a, 16) + except: + pass elif a.isdigit(): - i = a = int( a ) + i = a = int(a) elif a in names: for other in values: - if other['name'] == a: - v['value'] = other['value'] + 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 + 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 + 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 + 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 @@ -1105,6 +1298,7 @@ class CppEnum(_CppEnum): if a value for a given enum value was defined } """ + def __init__(self, nameStack): global doxygenCommentCache if len(doxygenCommentCache): @@ -1113,55 +1307,61 @@ def __init__(self, nameStack): if len(nameStack) == 3 and nameStack[0] == "enum": debug_print("Created enum as just name/value") self["name"] = nameStack[1] - self["instances"]=[nameStack[2]] + self["instances"] = [nameStack[2]] if len(nameStack) < 4 or "{" not in nameStack or "}" not in nameStack: - #Not enough stuff for an enum + # 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('}')] + # 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:] + tmpStack = valueStack[: valueStack.index(",")] + valueStack = valueStack[valueStack.index(",") + 1 :] else: tmpStack = valueStack valueStack = [] d = {} - if len(tmpStack) == 1: d["name"] = tmpStack[0] + if len(tmpStack) == 1: + d["name"] = tmpStack[0] elif len(tmpStack) >= 3 and tmpStack[1] == "=": - d["name"] = tmpStack[0]; d["value"] = " ".join(tmpStack[2:]) + 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] ) + debug_print("WARN-enum: parser missed value for %s" % tmpStack[0]) d["name"] = tmpStack[0] - if d: valueList.append( d ) + if d: + valueList.append(d) if len(valueList): - self['type'] = self.resolve_enum_values( valueList ) # returns int for standard enum + self["type"] = self.resolve_enum_values( + valueList + ) # returns int for standard enum self["values"] = valueList else: - warning_print( 'WARN-enum: empty enum %s'%nameStack ) + 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:] + # Figure out if it has a name + preBraceStack = nameStack[: nameStack.index("{")] + postBraceStack = nameStack[nameStack.index("}") + 1 :] self["typedef"] = False - if (len(preBraceStack) == 4 and ":" in nameStack and "typedef" not in nameStack): + if len(preBraceStack) == 4 and ":" in nameStack and "typedef" not in nameStack: # C++11 specify enum type with "enum : ..." syntax self["name"] = preBraceStack[1] self["type"] = preBraceStack[3] - elif (len(preBraceStack) == 2 and "typedef" not in nameStack): + elif len(preBraceStack) == 2 and "typedef" not in nameStack: # enum "enum ..." syntax - self["name"] = preBraceStack[1] + self["name"] = preBraceStack[1] elif len(postBraceStack) and "typedef" in nameStack: self["name"] = " ".join(postBraceStack) self["typedef"] = True - else: warning_print( 'WARN-enum: nameless enum %s'%nameStack ) - #See if there are instances of this + 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: @@ -1173,38 +1373,43 @@ def __init__(self, nameStack): 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 ) + 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 + "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 +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() + 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? + SubTypedefs = {} # TODO deprecate? NAMESPACES = [] CLASSES = {} STRUCTS = {} @@ -1215,685 +1420,858 @@ def initextra(self): self.classes_order = [] self.structs = Resolver.STRUCTS self.structs_order = [] - self.namespaces = Resolver.NAMESPACES # save all namespaces + 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.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 + self._template_typenames = [] # template - def current_namespace(self): return self.cur_namespace(True) + 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 + 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('*','') + 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 + 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 + 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 - ''' + 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() + 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,'') + 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 y not in self.C_FUNDAMENTAL: + alias = y + break - #if alias == 'class': + # if alias == 'class': # result['class'] = result['name'] # forward decl of class # result['forward_decl'] = True - if alias == '__extension__': result['fundamental_extension'] = True + if alias == "__extension__": + result["fundamental_extension"] = True elif alias: - if alias in result['aliases']: + if alias in result["aliases"]: # already resolved return - result['aliases'].append( alias ) + result["aliases"].append(alias) if alias in C99_NONSTANDARD: - result['type'] = C99_NONSTANDARD[ alias ] - result['typedef'] = alias - result['typedefs'] += 1 + 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 ) + 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 + klass = self.classes[alias] + result["fundamental"] = False + result["class"] = klass + result["unresolved"] = False + else: + result["unresolved"] = True else: - result['fundamental'] = True - result['unresolved'] = False - + 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 ( + 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 + 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'] ) + 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' + 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] + 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 + 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' + 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*' + 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 + 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 + 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 + 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 "::" 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'] ) + 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 + 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' + 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 ] + 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*' + 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 + if "method" in var: + var["enum"] = ( + var["method"]["path"] + + "::" + + enum["name"] + ) + else: # class property + var["unresolved"] = True except: - var['unresolved'] = True - - var['fundamental'] = True + var["unresolved"] = True + + var["fundamental"] = True - else: var['unresolved'] = True # TODO klass._public_xxx + else: + var["unresolved"] = True # TODO klass._public_xxx - elif a in self.namespaces: # a::b can also be a nested namespace + elif ( + a in self.namespaces + ): # a::b can also be a nested namespace if b in self.global_enums: - enum = self.global_enums[ b ] + 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 ) + 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' + 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' + 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 + 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 + 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 - + 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 - + if var["unresolved"] and "method" in var: + var["method"]["unresolved_parameters"] = True # create stripped raw_type # - p = '* & const static mutable'.split() # +++ new July7: "mutable" + p = "* & const static mutable".split() # +++ new July7: "mutable" for var in CppVariable.Vars: - if 'raw_type' not in var: + 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'] + 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'] + 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: + 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 - + 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:] - + 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) + 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) + trace_print("Adding #define %s" % macro) self.defines.append(re.split("[\t ]+", macro, 1)[1].strip()) elif macro.lower().startswith("#pragma"): - trace_print("Adding #pragma %s"%macro) + trace_print("Adding #pragma %s" % macro) self.pragmas.append(re.split("[\t ]+", macro, 1)[1].strip()) elif macro.lower().startswith("#include"): - trace_print("Adding #include %s"%macro) + trace_print("Adding #include %s" % macro) self.includes.append(re.split("[\t ]+", macro, 1)[1].strip()) else: - debug_print("Cant detect what to do with precomp macro '%s'"%macro) - except: pass + debug_print( + "Cant detect what to do with precomp macro '%s'" % macro + ) + except: + pass self._precomp_macro_buf = None - - def concrete_typedef( self, key ): + def concrete_typedef(self, key): if key not in self.typedefs: - #print( 'FAILED typedef', key ) + # 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 + 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 ): +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 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 + 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 + 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 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('::') + 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 + 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*' + 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 # +++ + else: + trace_print(a, b) + trace_print(meth) + meth["returns_unknown"] = True # +++ elif a in self.classes: - klass = self.classes[ a ] + 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*' + 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 + meth["returns_class"] = True elif b in klass._public_typedefs: - typedef = klass._public_typedefs[ b ] - meth['returns_fundamental'] = is_fundamental( typedef ) + 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 + 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 - + trace_print( + "WARN: UNKNOWN RETURN", meth["name"], meth["returns"] + ) + meth["returns_unknown"] = True + if meth["returns"].startswith(": : "): meth["returns"] = meth["returns"].replace(": : ", "::") - + 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 - - - - + 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 + # 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 ) + 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 + 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 ':;' and stack[1] != ':': stack = stack[1:] - info = { - 'debug': ' '.join(stack).replace(' : : ', '::' ).replace(' < ', '<' ).replace(' > ', '> ' ).replace(" >",">").replace(">>", "> >").replace(">>", "> >"), - 'class':None, - 'namespace':self.cur_namespace(add_double_colon=True), + self._structs_brace_level[struct["type"]] = self.braceDepth + + def parse_method_type(self, stack): + trace_print("meth type info", stack) + if stack[0] in ":;" and stack[1] != ":": + 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 default'.split(): info[tag]=False - header = stack[ : stack.index('(') ] - header = ' '.join( header ) - header = header.replace(' : : ', '::' ) - header = header.replace(' < ', '<' ) - header = header.replace(' > ', '> ' ) - header = header.replace('default ', 'default' ) + for ( + tag + ) in "defined pure_virtual operator constructor destructor extern template virtual static explicit inline friend returns returns_pointer returns_fundamental returns_class default".split(): + info[tag] = False + header = stack[: stack.index("(")] + header = " ".join(header) + header = header.replace(" : : ", "::") + header = header.replace(" < ", "<") + header = header.replace(" > ", "> ") + header = header.replace("default ", "default") header = header.strip() - if '{' in stack: - info['defined'] = True + 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 + 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 + 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 "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): + if " ".join(["operator", "(", ")", "("]) in " ".join(stack): op = "()" else: - trace_print( 'Error parsing operator') + trace_print("Error parsing operator") return None - - info['operator'] = op - name = 'operator' + op - a = stack[ : stack.index('operator') ] + + info["operator"] = op + name = "operator" + op + a = stack[: stack.index("operator")] elif r: name = r[-1] - a = r[ : -1 ] # strip name + a = r[:-1] # strip name - if name is None: return None - #if name.startswith('~'): name = name[1:] + if name is None: + return None + # if name.startswith('~'): name = name[1:] - while a and a[0] == '}': # strip - can have multiple } } + 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 "::" 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 + # Class function defined outside the class return None # info['name'] = name - #else: info['name'] = name + # else: info['name'] = name - if name.startswith('~'): - info['destructor'] = True - if 'default;' in stack: - info['defined'] = True - info['default'] = True + if name.startswith("~"): + info["destructor"] = True + if "default;" in stack: + info["defined"] = True + info["default"] = True name = name[1:] elif not a or (name == self.curClass and len(self.curClass)): - info['constructor'] = True - if 'default;' in stack: - info['defined'] = True - info['default'] = 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() + info["constructor"] = True + if "default;" in stack: + info["defined"] = True + info["default"] = 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_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() + 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 ) + 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'] ) + 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 ) + trace_print("WARN - struct contains methods - skipping") + trace_print(self.stack) assert 0 - - info = self.parse_method_type( self.stack ) + + 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, self.curTemplate) - 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, self.curTemplate) + if ( + info["class"] and info["class"] in self.classes + ): # case where methods are defined outside of class + newMethod = CppMethod( + self.nameStack, info["name"], info, self.curTemplate + ) + 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, self.curTemplate + ) 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 + 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.curTemplate) self.functions.append(newMethod) global parseHistory - parseHistory.append({"braceDepth": self.braceDepth, "item_type": "method", "item": newMethod}) + parseHistory.append( + { + "braceDepth": self.braceDepth, + "item_type": "method", + "item": newMethod, + } + ) else: - trace_print( 'free function?', self.nameStack ) + 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() + 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 + while stack and stack[-1].isdigit(): + stack.pop() # throw away array size for now - idx = stack.index('typedef') + idx = stack.index("typedef") if stack[-1] == "]": try: name = namespace + "".join(stack[-4:]) @@ -1903,181 +2281,215 @@ def _parse_typedef( self, stack, namespace='' ): name = namespace + stack[-1] else: 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 + 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} + 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 - + 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 ) + 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 ) - + 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] == ';' - debug_print( "trace" ) - if self.nameStack[0] == 'typedef': + assert self.stack[-1] == ";" + debug_print("trace") + 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 + 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": + # 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; + 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 + 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) + 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]: + + 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.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() + newVar["namespace"] = self.current_namespace() if self.curStruct: - self.curStruct[ 'fields' ].append( newVar ) - newVar['property_of_struct'] = 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}) + newVar["property_of_class"] = klass["name"] + parseHistory.append( + {"braceDepth": self.braceDepth, "item_type": "variable", "item": newVar} + ) else: - debug_print( "Found Global variable" ) + debug_print("Found Global variable") newVar = CppVariable(self.nameStack) self.variables.append(newVar) - self.stack = [] # CLEAR STACK + 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 ) + # 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' ) + 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' ) + error_print("ERROR: WRONG BRACE DEPTH") return - + # When dealing with typedefed structs, get rid of typedef keyword to handle later on if self.nameStack[0] == "typedef": del self.nameStack[0] if len(self.nameStack) == 1: self.anon_struct_counter += 1 # We cant handle more than 1 anonymous struct, so name them uniquely - self.nameStack.append(""%self.anon_struct_counter) - + self.nameStack.append("" % self.anon_struct_counter) + if self.nameStack[0] == "class": - self.curAccessSpecifier = 'private' - else:#struct - self.curAccessSpecifier = 'public' - debug_print("curAccessSpecifier changed/defaulted to %s"%self.curAccessSpecifier) + 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) - if newClass['name'] == 'union ': + if newClass["name"] == "union ": self.anon_union_counter = [self.braceDepth, 2] else: self.anon_union_counter = [self.braceDepth, 1] - trace_print( 'NEW UNION', newClass['name'] ) + trace_print("NEW UNION", newClass["name"]) else: newClass = CppClass(self.nameStack, self.curTemplate) - trace_print( 'NEW CLASS', newClass['name'] ) + 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 + 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 ) + 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 + 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 ) + 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 + self.curClass = key = parent + "::" + newClass["name"] + self._classes_brace_level[key] = self.braceDepth else: newClass["namespace"] = self.cur_namespace() - key = newClass['name'] + key = newClass["name"] self.curClass = newClass["name"] - self._classes_brace_level[ newClass['name'] ] = self.braceDepth + 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 ) + 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 + 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}) - + 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') + 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 ) + 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 ): + +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() - + + IGNORE_NAMES = "__extension__".split() + def show(self): - for className in list(self.classes.keys()):self.classes[className].show() + for className in list(self.classes.keys()): + self.classes[className].show() def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): """Create the parsed C++ header file parse tree @@ -2092,7 +2504,7 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): CppVariable.Vars = [] CppStruct.Structs = [] - if (argType == "file"): + if argType == "file": self.headerFileName = os.path.expandvars(headerFileName) self.mainClass = os.path.split(self.headerFileName)[1][:-2] headerFileStr = "" @@ -2103,46 +2515,53 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): 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. + # this keeps the API compatible, TODO proper namespace for everything. Resolver.CLASSES = {} self.classes = Resolver.CLASSES - #Functions that are not part of a class + # 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._precomp_macro_buf = ( + [] + ) # for internal purposes, will end up filling out pragmras and defines at the end self.enums = [] self.variables = [] self.global_enums = {} self.nameStack = [] self.nameSpaces = [] - self.curAccessSpecifier = 'private' # private is default + self.curAccessSpecifier = "private" # private is default self.curTemplate = None self.accessSpecifierStack = [] self.accessSpecifierScratch = [] - debug_print("curAccessSpecifier changed/defaulted to %s"%self.curAccessSpecifier) + debug_print( + "curAccessSpecifier changed/defaulted to %s" % self.curAccessSpecifier + ) self.initextra() # Old namestacks for a given level self.nameStackHistory = [] - self.anon_struct_counter = 0 + self.anon_struct_counter = 0 self.anon_union_counter = [-1, 0] self.templateRegistry = [] - if (len(self.headerFileName)): - fd = io.open(self.headerFileName, 'r', encoding=encoding) + if len(self.headerFileName): + fd = io.open(self.headerFileName, "r", encoding=encoding) 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() - + if " " not in supportedAccessSpecifier[i]: + continue + supportedAccessSpecifier[i] = re.sub( + "[ ]+", " ", supportedAccessSpecifier[i] + ).strip() + # Strip out template declarations templateSectionsToSliceOut = [] try: @@ -2150,65 +2569,79 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): start = m.start() # Search for the final '>' which may or may not be caught in the case of nexted <>'s for i in range(start, len(headerFileStr)): - if headerFileStr[i] == '<': + if headerFileStr[i] == "<": firstBracket = i break ltgtStackCount = 1 - #Now look for fianl '>' + # Now look for fianl '>' for i in range(firstBracket + 1, len(headerFileStr)): - if headerFileStr[i] == '<': + if headerFileStr[i] == "<": ltgtStackCount += 1 - elif headerFileStr[i] == '>': + elif headerFileStr[i] == ">": ltgtStackCount -= 1 if ltgtStackCount == 0: end = i break templateSectionsToSliceOut.append((start, end)) - + # Now strip out all instances of the template templateSectionsToSliceOut.reverse() for tslice in templateSectionsToSliceOut: # Replace the template symbol with a single symbol - template_symbol="CppHeaderParser_template_%d"%len(self.templateRegistry) - self.templateRegistry.append(headerFileStr[tslice[0]: tslice[1]+1]) - newlines = headerFileStr[tslice[0]: tslice[1]].count("\n") * "\n" #Keep line numbers the same - headerFileStr = headerFileStr[:tslice[0]] + newlines + " " + template_symbol + " " + headerFileStr[tslice[1] + 1:] + template_symbol = "CppHeaderParser_template_%d" % len( + self.templateRegistry + ) + self.templateRegistry.append(headerFileStr[tslice[0] : tslice[1] + 1]) + newlines = ( + headerFileStr[tslice[0] : tslice[1]].count("\n") * "\n" + ) # Keep line numbers the same + headerFileStr = ( + headerFileStr[: tslice[0]] + + newlines + + " " + + template_symbol + + " " + + headerFileStr[tslice[1] + 1 :] + ) except: pass # 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]') + 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"]) + # 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) + 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) + + # 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) + # 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 + + # Filter out any ignore symbols that end with "()" to account for #define magic functions for ignore in ignoreSymbols: - if not ignore.endswith("()"): continue + if not ignore.endswith("()"): + continue while True: locStart = headerFileStr.find(ignore[:-1]) if locStart == -1: - break; + break locEnd = None - #Now walk till we find the last paren and account for sub parens + # 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)): @@ -2222,18 +2655,20 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): inQuotes = True if parenCount == 0: locEnd = i + 1 - break; + break else: - if c == '"' and headerFileStr[i-1] != '\\': + if c == '"' and headerFileStr[i - 1] != "\\": inQuotes = False - + if locEnd: - #Strip it out but keep the linecount the same so line numbers are right + # 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) - + 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) @@ -2244,68 +2679,85 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): try: while True: tok = lex.token() - if not tok: break - if self.anon_union_counter[0] == self.braceDepth and self.anon_union_counter[1]: + 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 - if tok.type != 'TEMPLATE_NAME': - self.stack.append( tok.value ) + # debug_print("TOK: %s"%tok) + if tok.type == "NAME" and tok.value in self.IGNORE_NAMES: + continue + if tok.type != "TEMPLATE_NAME": + 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) + 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 == 'TEMPLATE_NAME': + if tok.type == "TEMPLATE_NAME": try: - templateId = int(tok.value.replace("CppHeaderParser_template_","")) + templateId = int( + tok.value.replace("CppHeaderParser_template_", "") + ) self.curTemplate = self.templateRegistry[templateId] - except: pass - 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" + except: + pass + 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 ) + 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': + 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") + 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 + # 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 + # 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 = [] + if self.stack and self.stack[0] == "class": + self.stack = [] self.braceDepth += 1 - - elif (tok.type == 'CLOSE_BRACE'): + + elif tok.type == "CLOSE_BRACE": if self.braceDepth == 0: continue - if (self.braceDepth == len(self.nameSpaces)): + if self.braceDepth == len(self.nameSpaces): tmp = self.nameSpaces.pop() - self.stack = [] # clear stack when namespace ends? + 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: @@ -2313,239 +2765,346 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs): 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' ) + # 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.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' ) + # 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._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'): + elif tok.type == "CLOSE_PAREN": self.nameStack.append(tok.value) - elif (tok.type == 'OPEN_SQUARE_BRACKET'): + elif tok.type == "OPEN_SQUARE_BRACKET": self.nameStack.append(tok.value) - elif (tok.type == 'CLOSE_SQUARE_BRACKET'): + elif tok.type == "CLOSE_SQUARE_BRACKET": self.nameStack.append(tok.value) - elif (tok.type == 'TAB'): pass - elif (tok.type == 'EQUALS'): + elif tok.type == "TAB": + pass + elif tok.type == "EQUALS": self.nameStack.append(tok.value) - elif (tok.type == 'COMMA'): + elif tok.type == "COMMA": self.nameStack.append(tok.value) - elif (tok.type == 'BACKSLASH'): + elif tok.type == "BACKSLASH": self.nameStack.append(tok.value) - elif (tok.type == 'DIVIDE'): + elif tok.type == "DIVIDE": self.nameStack.append(tok.value) - elif (tok.type == 'PIPE'): + elif tok.type == "PIPE": self.nameStack.append(tok.value) - elif (tok.type == 'PERCENT'): + elif tok.type == "PERCENT": self.nameStack.append(tok.value) - elif (tok.type == 'CARET'): + elif tok.type == "CARET": self.nameStack.append(tok.value) - elif (tok.type == 'EXCLAMATION'): + elif tok.type == "EXCLAMATION": self.nameStack.append(tok.value) - elif (tok.type == 'SQUOTE'): pass - elif (tok.type == 'NUMBER' or tok.type == 'FLOAT_NUMBER'): + elif tok.type == "SQUOTE": + pass + elif tok.type == "NUMBER" or tok.type == "FLOAT_NUMBER": self.nameStack.append(tok.value) - elif (tok.type == 'MINUS'): + elif tok.type == "MINUS": self.nameStack.append(tok.value) - elif (tok.type == 'PLUS'): + elif tok.type == "PLUS": self.nameStack.append(tok.value) - elif (tok.type == 'STRING_LITERAL'): + elif tok.type == "STRING_LITERAL": self.nameStack.append(tok.value) - elif (tok.type == 'ELLIPSIS'): + elif tok.type == "ELLIPSIS": self.nameStack.append(tok.value) - elif (tok.type == 'DOT'): pass # preserve behaviour and eat individual fullstops - elif (tok.type == 'NAME' or tok.type == 'AMPERSTAND' or tok.type == 'ASTERISK' or tok.type == 'CHAR_LITERAL'): + elif tok.type == "DOT": + pass # preserve behaviour and eat individual fullstops + 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'): + 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"): + 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; + 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) + 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 + 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.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]: + 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[:] + # 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 ) + 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.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))) + 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 = [] # Delete some temporary variables - for key in ["_precomp_macro_buf", "nameStack", "nameSpaces", "curAccessSpecifier", "accessSpecifierStack", - "accessSpecifierScratch", "nameStackHistory", "anon_struct_counter", "anon_union_counter", - "_classes_brace_level", "_forward_decls", "stack", "mainClass", "curStruct", "_template_typenames", - "_method_body", "braceDepth", "_structs_brace_level", "typedefs_order", "curTemplate", "templateRegistry"]: + for key in [ + "_precomp_macro_buf", + "nameStack", + "nameSpaces", + "curAccessSpecifier", + "accessSpecifierStack", + "accessSpecifierScratch", + "nameStackHistory", + "anon_struct_counter", + "anon_union_counter", + "_classes_brace_level", + "_forward_decls", + "stack", + "mainClass", + "curStruct", + "_template_typenames", + "_method_body", + "braceDepth", + "_structs_brace_level", + "typedefs_order", + "curTemplate", + "templateRegistry", + ]: del self.__dict__[key] - 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) nameStackCopy = self.nameStack[:] - - 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 () + + 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)) + + if len(self.curClass): + debug_print("%s (%s) " % (self.curClass, self.curAccessSpecifier)) else: - debug_print( " (%s) "%self.curAccessSpecifier) + debug_print(" (%s) " % self.curAccessSpecifier) - #Filter special case of array with casting in it + # 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 and - (('struct' not in self.nameStack and 'union' not in self.nameStack) or self.stack[-1] == ";") and - not is_enum_namestack(self.nameStack)): - trace_print('STACK', self.stack) + 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 + and ( + ("struct" not in self.nameStack and "union" not in self.nameStack) + or self.stack[-1] == ";" + ) + and not is_enum_namestack(self.nameStack) + ): + trace_print("STACK", self.stack) self.evaluate_typedef() return - - elif (len(self.nameStack) == 0): - debug_print( "trace" ) - debug_print( "(Empty Stack)" ) + + elif len(self.nameStack) == 0: + debug_print("trace") + debug_print("(Empty Stack)") return - elif (self.nameStack[0] == "namespace"): - #Taken care of outside of here + 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 + 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 ( + 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" ) + 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" ) + 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 + 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: + else: self.evaluate_method_stack() else: - #Free function + # Free function self.evaluate_method_stack() - elif (len(self.nameStack) == 1 and len(self.nameStackHistory) > self.braceDepth - and (self.nameStackHistory[self.braceDepth][0][0:2] == ["typedef", "struct"] or - self.nameStackHistory[self.braceDepth][0][0:2] == ["typedef", "union"])): + elif ( + len(self.nameStack) == 1 + and len(self.nameStackHistory) > self.braceDepth + and ( + self.nameStackHistory[self.braceDepth][0][0:2] == ["typedef", "struct"] + or self.nameStackHistory[self.braceDepth][0][0:2] + == ["typedef", "union"] + ) + ): # Look for the name of a typedef struct: struct typedef {...] StructName; or unions to get renamed debug_print("found the naming of a union") type_name_to_rename = self.nameStackHistory[self.braceDepth][1] new_name = self.nameStack[0] type_to_rename = self.classes[type_name_to_rename] type_to_rename["name"] = self.nameStack[0] - #Now re install it in its new location + # Now re install it in its new location self.classes[new_name] = type_to_rename if new_name != type_name_to_rename: - del self.classes[type_name_to_rename] - 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") or self.nameStack[0] == 'typedef' and self.nameStack[1] in ('struct', 'union'): - #Parsing a union can reuse much of the class parsing - debug_print( "trace" ) + del self.classes[type_name_to_rename] + 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") + or self.nameStack[0] == "typedef" + and self.nameStack[1] in ("struct", "union") + ): + # Parsing a union can reuse much of the class parsing + debug_print("trace") self.evaluate_class_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 + 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 = "" - elif (self.braceDepth < 1): - debug_print( "trace" ) - #Ignore global stuff for now - debug_print( "Global stuff: %s"%self.nameStack ) + elif self.braceDepth < 1: + debug_print("trace") + # Ignore global stuff for now + debug_print("Global stuff: %s" % self.nameStack) self.nameStack = [] doxygenCommentCache = "" - elif (self.braceDepth > len(self.nameSpaces) + 1): - debug_print( "trace" ) + elif self.braceDepth > len(self.nameSpaces) + 1: + debug_print("trace") self.nameStack = [] doxygenCommentCache = "" @@ -2553,33 +3112,36 @@ def evaluate_stack(self, token=None): self.nameStackHistory[self.braceDepth] = (nameStackCopy, self.curClass) except: self.nameStackHistory.append((nameStackCopy, self.curClass)) - self.nameStack = [] # its a little confusing to have some if/else above return and others not, and then clearning the nameStack down here + self.nameStack = ( + [] + ) # its a little confusing to have some if/else above return and others not, and then clearning the nameStack down here doxygenCommentCache = "" self.curTemplate = None - def evaluate_enum_stack(self): """Create an Enum out of the name stack""" - debug_print( "evaluating enum" ) + 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 + 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 + if "name" in newEnum and newEnum["name"]: + self.global_enums[newEnum["name"]] = newEnum - #This enum has instances, turn them into properties + # 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.nameStack = [instanceType, instance] self.evaluate_property_stack() del newEnum["instances"] @@ -2588,32 +3150,35 @@ def strip_parent_keys(self): obj_queue = [self] while len(obj_queue): obj = obj_queue.pop() - trace_print("pop %s type %s"%(obj, type(obj))) + trace_print("pop %s type %s" % (obj, type(obj))) try: if "parent" in obj.keys(): del obj["parent"] - trace_print("Stripped parent from %s"%obj.keys()) - except: pass + trace_print("Stripped parent from %s" % obj.keys()) + except: + pass try: if "method" in obj.keys(): del obj["method"] - trace_print("Stripped method from %s"%obj.keys()) - except: pass + trace_print("Stripped method from %s" % obj.keys()) + except: + pass # Figure out what sub types are one of ours try: - if not hasattr(obj, 'keys'): + if not hasattr(obj, "keys"): obj = obj.__dict__ for k in obj.keys(): - trace_print("-Try key %s"%(k)) - trace_print("-type %s"%(type(obj[k]))) - if k in ["nameStackHistory", "parent", "_public_typedefs"]: continue + trace_print("-Try key %s" % (k)) + trace_print("-type %s" % (type(obj[k]))) + if k in ["nameStackHistory", "parent", "_public_typedefs"]: + continue if type(obj[k]) == list: for i in obj[k]: - trace_print("push l %s"%i) + trace_print("push l %s" % i) obj_queue.append(i) - elif type(obj[k]) == dict: + elif type(obj[k]) == dict: if len(obj): - trace_print("push d %s"%obj[k]) + trace_print("push d %s" % obj[k]) obj_queue.append(obj[k]) elif type(obj[k]) == type(type(0)): if type(obj[k]) == int: @@ -2629,36 +3194,37 @@ def strip_parent_keys(self): def toJSON(self, indent=4): """Converts a parsed structure to JSON""" import json + self.strip_parent_keys() try: del self.__dict__["classes_order"] - except: pass + except: + pass return json.dumps(self.__dict__, indent=indent) - def __repr__(self): rtn = { - "classes": self.classes, - "functions": self.functions, - "enums": self.enums, - "variables": self.variables, + "classes": self.classes, + "functions": self.functions, + "enums": self.enums, + "variables": self.variables, } return repr(rtn) def __str__(self): rtn = "" for className in list(self.classes.keys()): - rtn += "%s\n"%self.classes[className] + rtn += "%s\n" % self.classes[className] if self.functions: rtn += "// functions\n" for f in self.functions: - rtn += "%s\n"%f + rtn += "%s\n" % f if self.variables: rtn += "// variables\n" for f in self.variables: - rtn += "%s\n"%f + rtn += "%s\n" % f if self.enums: rtn += "// enums\n" for f in self.enums: - rtn += "%s\n"%f + rtn += "%s\n" % f return rtn diff --git a/CppHeaderParser/__init__.py b/CppHeaderParser/__init__.py index 024da04..dd2fb30 100644 --- a/CppHeaderParser/__init__.py +++ b/CppHeaderParser/__init__.py @@ -3,4 +3,4 @@ from .CppHeaderParser import * -#__all__ = ['CppHeaderParser'] +# __all__ = ['CppHeaderParser'] diff --git a/CppHeaderParser/examples/readSampleClass.py b/CppHeaderParser/examples/readSampleClass.py index 0bab4f7..35d4ac4 100755 --- a/CppHeaderParser/examples/readSampleClass.py +++ b/CppHeaderParser/examples/readSampleClass.py @@ -1,21 +1,25 @@ #!/usr/bin/python import sys + sys.path = ["../"] + sys.path import CppHeaderParser + try: cppHeader = CppHeaderParser.CppHeader("SampleClass.h") except CppHeaderParser.CppParseError as e: print(e) sys.exit(1) -print("CppHeaderParser view of %s"%cppHeader) +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("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"]) @@ -52,12 +56,12 @@ print("\nFree functions are:") for func in cppHeader.functions: - print(" %s"%func["name"]) + print(" %s" % func["name"]) print("\n#includes are:") for incl in cppHeader.includes: - print(" %s"%incl) + print(" %s" % incl) print("\n#defines are:") for define in cppHeader.defines: - print(" %s"%define) + print(" %s" % define) diff --git a/CppHeaderParser/test/gen_test.py b/CppHeaderParser/test/gen_test.py deleted file mode 100644 index 4ba96a9..0000000 --- a/CppHeaderParser/test/gen_test.py +++ /dev/null @@ -1,153 +0,0 @@ -import sys -sys.path = [".."] + sys.path -import CppHeaderParser - -testScript = "" -testCaseClasses = [] - -def main(): - #init testScript with boiler plate code - global testScript - global testCaseClasses - testScript = """\ -import unittest -from test import test_support -import sys -sys.path = [".."] + sys.path -import CppHeaderParser - -""" - cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - for className, classInstance in cppHeader.classes.items(): - gen_test_cases_for_class(className, classInstance) - - testScript += """\ - - -def test_main(): - test_support.run_unittest( - %s) - -if __name__ == '__main__': - test_main() - -"""%",\n ".join(testCaseClasses) - - print testScript - -def gen_test_cases_for_class(className, classInstance): - for methAccessor in classInstance["methods"].keys(): - idx = 0 - for method in classInstance["methods"][methAccessor]: - gen_test_case_for_method(className, classInstance, methAccessor, idx, method); - idx += 1 - - for propAccessor in classInstance["properties"].keys(): - idx = 0 - for property in classInstance["properties"][propAccessor]: - gen_test_case_for_property(className, classInstance, propAccessor, idx, property); - idx += 1 - - for enumAccessor in classInstance["enums"].keys(): - idx = 0 - for enum in classInstance["enums"][enumAccessor]: - gen_test_case_for_enum(className, classInstance, enumAccessor, idx, enum); - idx += 1 - -def gen_test_case_for_method(className, classInstance, methAccessor, methIndex, method): - global testScript - global testCaseClasses - testCaseClassName = "%s_%s_TestCase"%(className, method["name"]) - testCaseClasses.append(testCaseClassName) - testScript += """\ - - -class %s(unittest.TestCase): - - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - -"""%testCaseClassName - methString = """self.cppHeader.classes["%s"]["methods"]["%s"][%d]"""%( - className, methAccessor, methIndex) - for key in ["name", "rtnType", "parameters", "doxygen"]: - if key in method.keys(): - gen_test_equals(key, methString + '["%s"]'%key, method[key]) - else: - gen_test_key_not_exist(key, methString) - - - -def gen_test_case_for_property(className, classInstance, propAccessor, propIndex, property): - global testScript - global testCaseClasses - testCaseClassName = "%s_%s_TestCase"%(className, property["name"]) - testCaseClasses.append(testCaseClassName) - testScript += """\ - - -class %s(unittest.TestCase): - - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - -"""%testCaseClassName - propString = """self.cppHeader.classes["%s"]["properties"]["%s"][%d]"""%( - className, propAccessor, propIndex) - for key in ["name", "type", "doxygen"]: - if key in property.keys(): - gen_test_equals(key, propString + '["%s"]'%key, property[key]) - else: - gen_test_key_not_exist(key, propString) - - - - -def gen_test_case_for_enum(className, classInstance, enumAccessor, enumIndex, enum): - global testScript - global testCaseClasses - testCaseClassName = "%s_%s_TestCase"%(className, enum["name"]) - testCaseClasses.append(testCaseClassName) - testScript += """\ - - -class %s(unittest.TestCase): - - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - -"""%testCaseClassName - enumString = """self.cppHeader.classes["%s"]["enums"]["%s"][%d]"""%( - className, enumAccessor, enumIndex) - for key in ["name", "namespace", "doxygen", "values"]: - if key in enum.keys(): - gen_test_equals(key, enumString + '["%s"]'%key, enum[key]) - else: - gen_test_key_not_exist(key, enumString) - - - -def gen_test_equals(name, v1, v2): - global testScript - testScript += """\ - def test_%s(self): - self.assertEqual( - %s, - %s) - -"""%(name.lower(), v1, repr(v2)) - -def gen_test_key_not_exist(key, testObj): - global testScript - testScript += """\ - def test_%s(self): - self.assertTrue( - "%s" - not in %s.keys()) - -"""%(key.lower(), key, testObj) - -if __name__ == "__main__": - main() - - diff --git a/CppHeaderParser/test/test_CppHeaderParser.py b/CppHeaderParser/test/test_CppHeaderParser.py index dc55327..c877c85 100644 --- a/CppHeaderParser/test/test_CppHeaderParser.py +++ b/CppHeaderParser/test/test_CppHeaderParser.py @@ -9,9 +9,10 @@ def filter_pameters(p): "Reduce a list of dictionaries to the desired keys for function parameter testing" rtn = [] for d in p: - rtn.append({'name': d['name'], 'desc': d['desc'], 'type': d['type']}) + rtn.append({"name": d["name"], "desc": d["desc"], "type": d["type"]}) return rtn + def filter_dict_keys(d, keys): "Filter a dictonary to a specified set of keys" rtn = {} @@ -19,1161 +20,1747 @@ def filter_dict_keys(d, keys): rtn[k] = d.get(k, None) return rtn -class SampleClass_SampleClass_TestCase(unittest.TestCase): +class SampleClass_SampleClass_TestCase(unittest.TestCase): def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][0]["name"], - 'SampleClass') + "SampleClass", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][0]["rtnType"], - 'void') + "void", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["SampleClass"]["methods"]["public"][0]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["SampleClass"]["methods"]["public"][0][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["SampleClass"]["methods"]["public"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["SampleClass"]["methods"]["public"][0].keys() + ) class SampleClass_meth1_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][1]["name"], - 'meth1') + "meth1", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][1]["rtnType"], - 'string') + "string", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["SampleClass"]["methods"]["public"][1]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["SampleClass"]["methods"]["public"][1][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][1]["doxygen"], - '/*!\n* Method 1\n*/') - + "/*!\n* Method 1\n*/", + ) class SampleClass_meth2_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][2]["name"], - 'meth2') + "meth2", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][2]["rtnType"], - 'int') + "int", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["SampleClass"]["methods"]["public"][2]["parameters"]), - [{'type': 'int', 'name': 'v1', 'desc': 'Variable 1'}]) + filter_pameters( + self.cppHeader.classes["SampleClass"]["methods"]["public"][2][ + "parameters" + ] + ), + [{"type": "int", "name": "v1", "desc": "Variable 1"}], + ) def test_doxygen(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][2]["doxygen"], - '///\n/// Method 2 description\n///\n/// @param v1 Variable 1\n///') - + "///\n/// Method 2 description\n///\n/// @param v1 Variable 1\n///", + ) class SampleClass_meth3_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][3]["name"], - 'meth3') + "meth3", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][3]["rtnType"], - 'void') + "void", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["SampleClass"]["methods"]["public"][3]["parameters"]), - [{'type': 'const string &', 'name': 'v1', 'desc': 'Variable 1 with a really long wrapping description'}, {'type': 'vector &', 'name': 'v2', 'desc': 'Variable 2'}]) + filter_pameters( + self.cppHeader.classes["SampleClass"]["methods"]["public"][3][ + "parameters" + ] + ), + [ + { + "type": "const string &", + "name": "v1", + "desc": "Variable 1 with a really long wrapping description", + }, + {"type": "vector &", "name": "v2", "desc": "Variable 2"}, + ], + ) def test_doxygen(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][3]["doxygen"], - '/**\n* Method 3 description\n*\n* \\param v1 Variable 1 with a really long\n* wrapping description\n* \\param v2 Variable 2\n*/') - + "/**\n* Method 3 description\n*\n* \\param v1 Variable 1 with a really long\n* wrapping description\n* \\param v2 Variable 2\n*/", + ) class SampleClass_meth4_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][4]["name"], - 'meth4') + "meth4", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][4]["rtnType"], - 'unsigned int') + "unsigned int", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["SampleClass"]["methods"]["public"][4]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["SampleClass"]["methods"]["public"][4][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["public"][4]["doxygen"], - '/**********************************\n* Method 4 description\n*\n* @return Return value\n*********************************/') - + "/**********************************\n* Method 4 description\n*\n* @return Return value\n*********************************/", + ) class SampleClass_meth5_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["private"][0]["name"], - 'meth5') + "meth5", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["methods"]["private"][0]["rtnType"], - 'void *') + "void *", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["SampleClass"]["methods"]["private"][0]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["SampleClass"]["methods"]["private"][0][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["SampleClass"]["methods"]["private"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["SampleClass"]["methods"]["private"][0].keys() + ) class SampleClass_prop1_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["properties"]["private"][0]["name"], - 'prop1') + "prop1", + ) def test_type(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["properties"]["private"][0]["type"], - 'string') + "string", + ) def test_doxygen(self): self.assertEqual( - self.cppHeader.classes["SampleClass"]["properties"]["private"][0]["doxygen"], - '/// prop1 description') - + self.cppHeader.classes["SampleClass"]["properties"]["private"][0][ + "doxygen" + ], + "/// prop1 description", + ) class SampleClass_prop5_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["properties"]["private"][1]["name"], - 'prop5') + "prop5", + ) def test_type(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["properties"]["private"][1]["type"], - 'int') + "int", + ) def test_doxygen(self): self.assertEqual( - self.cppHeader.classes["SampleClass"]["properties"]["private"][1]["doxygen"], - '//! prop5 description') - + self.cppHeader.classes["SampleClass"]["properties"]["private"][1][ + "doxygen" + ], + "//! prop5 description", + ) class SampleClass_Elephant_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["enums"]["public"][0]["name"], - 'Elephant') + "Elephant", + ) def test_namespace(self): self.assertEqual( - self.cppHeader.classes["SampleClass"]["enums"]["public"][0]["namespace"], - '') + self.cppHeader.classes["SampleClass"]["enums"]["public"][0]["namespace"], "" + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["SampleClass"]["enums"]["public"][0].keys()) + "doxygen" + not in self.cppHeader.classes["SampleClass"]["enums"]["public"][0].keys() + ) def test_values(self): self.assertEqual( self.cppHeader.classes["SampleClass"]["enums"]["public"][0]["values"], - [{'name': 'EL_ONE', 'value': 1}, {'name': 'EL_TWO', 'value': 2}, {'name': 'EL_NINE', 'value': 9}, {'name': 'EL_TEN', 'value': 10}]) - + [ + {"name": "EL_ONE", "value": 1}, + {"name": "EL_TWO", "value": 2}, + {"name": "EL_NINE", "value": 9}, + {"name": "EL_TEN", "value": 10}, + ], + ) class AlphaClass_AlphaClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["methods"]["public"][0]["name"], - 'AlphaClass') + "AlphaClass", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["methods"]["public"][0]["rtnType"], - 'void') + "void", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["AlphaClass"]["methods"]["public"][0]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["AlphaClass"]["methods"]["public"][0][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["AlphaClass"]["methods"]["public"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["AlphaClass"]["methods"]["public"][0].keys() + ) class AlphaClass_alphaMethod_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["methods"]["public"][1]["name"], - 'alphaMethod') + "alphaMethod", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["methods"]["public"][1]["rtnType"], - 'void') + "void", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["AlphaClass"]["methods"]["public"][1]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["AlphaClass"]["methods"]["public"][1][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["AlphaClass"]["methods"]["public"][1].keys()) - + "doxygen" + not in self.cppHeader.classes["AlphaClass"]["methods"]["public"][1].keys() + ) class AlphaClass_alphaString_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["properties"]["public"][0]["name"], - 'alphaString') + "alphaString", + ) def test_type(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["properties"]["public"][0]["type"], - 'string') + "string", + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["AlphaClass"]["properties"]["public"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["AlphaClass"]["properties"]["public"][ + 0 + ].keys() + ) class AlphaClass_Zebra_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["enums"]["protected"][0]["name"], - 'Zebra') + "Zebra", + ) def test_namespace(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["enums"]["protected"][0]["namespace"], - 'Alpha') + "Alpha", + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["AlphaClass"]["enums"]["protected"][0].keys()) + "doxygen" + not in self.cppHeader.classes["AlphaClass"]["enums"]["protected"][0].keys() + ) def test_values(self): self.assertEqual( self.cppHeader.classes["AlphaClass"]["enums"]["protected"][0]["values"], - [{'name': 'Z_A', 'value': 0}, - {'name': 'Z_B', 'raw_value': '0x2B', 'value': 43}, - {'name': 'Z_C', 'raw_value': 'j', 'value': 106}, - {'name': 'Z_D', 'value': 107}]) - + [ + {"name": "Z_A", "value": 0}, + {"name": "Z_B", "raw_value": "0x2B", "value": 43}, + {"name": "Z_C", "raw_value": "j", "value": 106}, + {"name": "Z_D", "value": 107}, + ], + ) class OmegaClass_OmegaClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["methods"]["public"][0]["name"], - 'OmegaClass') + "OmegaClass", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["methods"]["public"][0]["rtnType"], - 'void') + "void", + ) def test_parameters(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["OmegaClass"]["methods"]["public"][0]["parameters"]), - []) + filter_pameters( + self.cppHeader.classes["OmegaClass"]["methods"]["public"][0][ + "parameters" + ] + ), + [], + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["OmegaClass"]["methods"]["public"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["OmegaClass"]["methods"]["public"][0].keys() + ) class OmegaClass_omegaString_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["properties"]["public"][0]["name"], - 'omegaString') + "omegaString", + ) def test_type(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["properties"]["public"][0]["type"], - 'string') + "string", + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["OmegaClass"]["properties"]["public"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["OmegaClass"]["properties"]["public"][ + 0 + ].keys() + ) class OmegaClass_Rino_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["enums"]["protected"][0]["name"], - 'Rino') + "Rino", + ) def test_namespace(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["enums"]["protected"][0]["namespace"], - 'Alpha::Omega') + "Alpha::Omega", + ) def test_doxygen(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["enums"]["protected"][0]["doxygen"], - '///\n/// @brief Rino Numbers, not that that means anything\n///') + "///\n/// @brief Rino Numbers, not that that means anything\n///", + ) def test_values(self): self.assertEqual( self.cppHeader.classes["OmegaClass"]["enums"]["protected"][0]["values"], - [{'name': 'RI_ZERO', 'value': 0}, {'name': 'RI_ONE', 'value': 1}, {'name': 'RI_TWO', 'value': 2}]) + [ + {"name": "RI_ZERO", "value": 0}, + {"name": "RI_ONE", "value": 1}, + {"name": "RI_TWO", "value": 2}, + ], + ) class Bug3488053_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_public(self): - self.assertEqual(len(self.cppHeader.classes["Bug_3488053::Bug_3488053_Nested"]["properties"]["public"]), 1) - + self.assertEqual( + len( + self.cppHeader.classes["Bug_3488053::Bug_3488053_Nested"]["properties"][ + "public" + ] + ), + 1, + ) + def test_private(self): - self.assertEqual(len(self.cppHeader.classes["Bug_3488053::Bug_3488053_Nested"]["properties"]["private"]), 0) - + self.assertEqual( + len( + self.cppHeader.classes["Bug_3488053::Bug_3488053_Nested"]["properties"][ + "private" + ] + ), + 0, + ) + def test_protected(self): - self.assertEqual(len(self.cppHeader.classes["Bug_3488053::Bug_3488053_Nested"]["properties"]["protected"]), 0) - + self.assertEqual( + len( + self.cppHeader.classes["Bug_3488053::Bug_3488053_Nested"]["properties"][ + "protected" + ] + ), + 0, + ) + class Bug3488360_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_BloodOrange_inherits(self): self.assertEqual(self.cppHeader.classes["BloodOrange"]["inherits"], []) - + def test_Bananna_inherits(self): - self.assertEqual(self.cppHeader.classes["Bananna"]["inherits"], [{'access': 'public', 'class': 'Citrus::BloodOrange', 'virtual': False}]) - + self.assertEqual( + self.cppHeader.classes["Bananna"]["inherits"], + [{"access": "public", "class": "Citrus::BloodOrange", "virtual": False}], + ) + def test_ExcellentCake_inherits(self): - self.assertEqual(self.cppHeader.classes["ExcellentCake"]["inherits"], - [{'access': 'private', 'class': 'Citrus::BloodOrange', 'virtual': False}, - {'access': 'private', 'class': 'Convoluted::Nested::Mixin', 'virtual': False}]) - + self.assertEqual( + self.cppHeader.classes["ExcellentCake"]["inherits"], + [ + {"access": "private", "class": "Citrus::BloodOrange", "virtual": False}, + { + "access": "private", + "class": "Convoluted::Nested::Mixin", + "virtual": False, + }, + ], + ) + + class Bug3487551_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_method_rtn_type(self): - self.assertEqual(self.cppHeader.classes["Bug_3487551"]["methods"]["public"][0]["rtnType"], "int") - + self.assertEqual( + self.cppHeader.classes["Bug_3487551"]["methods"]["public"][0]["rtnType"], + "int", + ) -class SampleStruct_meth_TestCase(unittest.TestCase): +class SampleStruct_meth_TestCase(unittest.TestCase): def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleStruct"]["methods"]["public"][0]["name"], - 'meth') + "meth", + ) def test_rtntype(self): self.assertEqual( self.cppHeader.classes["SampleStruct"]["methods"]["public"][0]["rtnType"], - 'unsigned int') + "unsigned int", + ) def test_parameters(self): self.assertEqual( - self.cppHeader.classes["SampleStruct"]["methods"]["public"][0]["parameters"], - []) + self.cppHeader.classes["SampleStruct"]["methods"]["public"][0][ + "parameters" + ], + [], + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["SampleStruct"]["methods"]["public"][0].keys()) - + "doxygen" + not in self.cppHeader.classes["SampleStruct"]["methods"]["public"][0].keys() + ) class SampleStruct_prop_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_name(self): self.assertEqual( self.cppHeader.classes["SampleStruct"]["properties"]["private"][0]["name"], - 'prop') + "prop", + ) def test_type(self): self.assertEqual( self.cppHeader.classes["SampleStruct"]["properties"]["private"][0]["type"], - 'int') + "int", + ) def test_doxygen(self): self.assertTrue( - "doxygen" - not in self.cppHeader.classes["SampleStruct"]["properties"]["private"][0].keys()) + "doxygen" + not in self.cppHeader.classes["SampleStruct"]["properties"]["private"][ + 0 + ].keys() + ) class Bird_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_items_array(self): - self.assertEqual(self.cppHeader.classes["Bird"]["properties"]["private"][0]["array"], 1) - + self.assertEqual( + self.cppHeader.classes["Bird"]["properties"]["private"][0]["array"], 1 + ) + def test_otherItems_array(self): - self.assertEqual(self.cppHeader.classes["Bird"]["properties"]["private"][1]["array"], 1) - + self.assertEqual( + self.cppHeader.classes["Bird"]["properties"]["private"][1]["array"], 1 + ) + def test_oneItem_array(self): - self.assertEqual(self.cppHeader.classes["Bird"]["properties"]["private"][2]["array"], 0) - + self.assertEqual( + self.cppHeader.classes["Bird"]["properties"]["private"][2]["array"], 0 + ) + def test_items_array_size(self): - self.assertEqual(self.cppHeader.classes["Bird"]["properties"]["private"][0]["array_size"], "MAX_ITEM") - + self.assertEqual( + self.cppHeader.classes["Bird"]["properties"]["private"][0]["array_size"], + "MAX_ITEM", + ) + def test_otherItems_array_size(self): - self.assertEqual(self.cppHeader.classes["Bird"]["properties"]["private"][1]["array_size"], "7") + self.assertEqual( + self.cppHeader.classes["Bird"]["properties"]["private"][1]["array_size"], + "7", + ) class Monkey_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_methods(self): self.assertEqual(len(self.cppHeader.classes["Monkey"]["methods"]["public"]), 0) - + def test_num_private_methods(self): self.assertEqual(len(self.cppHeader.classes["Monkey"]["methods"]["private"]), 1) - - def test_num_protected_methods(self): - self.assertEqual(len(self.cppHeader.classes["Monkey"]["methods"]["protected"]), 0) + def test_num_protected_methods(self): + self.assertEqual( + len(self.cppHeader.classes["Monkey"]["methods"]["protected"]), 0 + ) class Chicken_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_methods(self): self.assertEqual(len(self.cppHeader.classes["Chicken"]["methods"]["public"]), 0) - + def test_num_private_methods(self): - self.assertEqual(len(self.cppHeader.classes["Chicken"]["methods"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["Chicken"]["methods"]["private"]), 1 + ) + def test_num_protected_methods(self): - self.assertEqual(len(self.cppHeader.classes["Chicken"]["methods"]["protected"]), 0) - - def test_template(self): - self.assertEqual(self.cppHeader.classes["Chicken"]["methods"]["private"][0]['template'], "template ") + self.assertEqual( + len(self.cppHeader.classes["Chicken"]["methods"]["protected"]), 0 + ) + def test_template(self): + self.assertEqual( + self.cppHeader.classes["Chicken"]["methods"]["private"][0]["template"], + "template ", + ) class Lizzard_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_normal_constructor(self): - cmp_values = {'inline': False, 'name': 'Lizzard', 'parameters': [], 'friend': False, - 'explicit': False, 'constructor': True, 'namespace': '', 'destructor': False, - 'pure_virtual': False, 'returns': '', 'static': False, 'virtual': False, - 'template': False, 'rtnType': 'void', 'extern': False, 'path': 'Lizzard', - 'returns_pointer': 0, 'class': None} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["Lizzard"]["methods"]["private"][0], cmp_values.keys()), - cmp_values) - - def test_explicit_constructor(self): - cmp_values = {'inline': False, 'name': 'Lizzard', 'friend': False, - 'explicit': True, 'constructor': True, 'namespace': '', 'destructor': False, - 'pure_virtual': False, 'returns': '', 'static': False, 'virtual': False, - 'template': False, 'rtnType': 'void', 'extern': False, 'path': 'Lizzard', - 'returns_pointer': 0, 'class': None} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["Lizzard"]["methods"]["private"][1], cmp_values.keys()), - cmp_values) + cmp_values = { + "inline": False, + "name": "Lizzard", + "parameters": [], + "friend": False, + "explicit": False, + "constructor": True, + "namespace": "", + "destructor": False, + "pure_virtual": False, + "returns": "", + "static": False, + "virtual": False, + "template": False, + "rtnType": "void", + "extern": False, + "path": "Lizzard", + "returns_pointer": 0, + "class": None, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["Lizzard"]["methods"]["private"][0], + cmp_values.keys(), + ), + cmp_values, + ) + def test_explicit_constructor(self): + cmp_values = { + "inline": False, + "name": "Lizzard", + "friend": False, + "explicit": True, + "constructor": True, + "namespace": "", + "destructor": False, + "pure_virtual": False, + "returns": "", + "static": False, + "virtual": False, + "template": False, + "rtnType": "void", + "extern": False, + "path": "Lizzard", + "returns_pointer": 0, + "class": None, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["Lizzard"]["methods"]["private"][1], + cmp_values.keys(), + ), + cmp_values, + ) class Owl_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_methods(self): self.assertEqual(len(self.cppHeader.classes["Owl"]["methods"]["public"]), 0) - + def test_num_private_methods(self): self.assertEqual(len(self.cppHeader.classes["Owl"]["methods"]["private"]), 1) - + def test_num_protected_methods(self): self.assertEqual(len(self.cppHeader.classes["Owl"]["methods"]["protected"]), 0) class Grape_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["GrapeClass"]["properties"]["public"]), 0) - + self.assertEqual( + len(self.cppHeader.classes["GrapeClass"]["properties"]["public"]), 0 + ) + def test_num_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["GrapeClass"]["properties"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["GrapeClass"]["properties"]["private"]), 1 + ) + def test_num_protected_properties(self): - self.assertEqual(len(self.cppHeader.classes["GrapeClass"]["properties"]["protected"]), 0) + self.assertEqual( + len(self.cppHeader.classes["GrapeClass"]["properties"]["protected"]), 0 + ) def test_num_public_methods(self): - self.assertEqual(len(self.cppHeader.classes["GrapeClass"]["methods"]["public"]), 0) - + self.assertEqual( + len(self.cppHeader.classes["GrapeClass"]["methods"]["public"]), 0 + ) + def test_num_private_methods(self): - self.assertEqual(len(self.cppHeader.classes["GrapeClass"]["methods"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["GrapeClass"]["methods"]["private"]), 1 + ) + def test_num_protected_methods(self): - self.assertEqual(len(self.cppHeader.classes["GrapeClass"]["methods"]["protected"]), 0) + self.assertEqual( + len(self.cppHeader.classes["GrapeClass"]["methods"]["protected"]), 0 + ) class AnonHolderClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_property(self): - cmp_values = {'constant': 0, 'name': 'a', 'reference': 0, 'type': '', 'static': 0, 'pointer': 0} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["AnonHolderClass"]["properties"]["public"][0], cmp_values.keys()), cmp_values) + cmp_values = { + "constant": 0, + "name": "a", + "reference": 0, + "type": "", + "static": 0, + "pointer": 0, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["AnonHolderClass"]["properties"]["public"][0], + cmp_values.keys(), + ), + cmp_values, + ) class CowClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_class_declaration_method(self): - self.assertEqual(self.cppHeader.classes["CowClass"]["declaration_method"], "class") + self.assertEqual( + self.cppHeader.classes["CowClass"]["declaration_method"], "class" + ) def test_struct_declaration_method(self): - self.assertEqual(self.cppHeader.classes["CowStruct"]["declaration_method"], "struct") + self.assertEqual( + self.cppHeader.classes["CowStruct"]["declaration_method"], "struct" + ) class Mango_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - - def test_virtual_inherits(self): - self.assertEqual(self.cppHeader.classes["MangoClass"]["inherits"][0]["virtual"], True) + def test_virtual_inherits(self): + self.assertEqual( + self.cppHeader.classes["MangoClass"]["inherits"][0]["virtual"], True + ) class Eagle_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_property(self): - cmp_values = {'constant': 0, 'name': 'a', 'reference': 0, 'array_size': 'MAX_LEN', 'type': 'int', 'static': 0, 'pointer': 0} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["EagleClass"]["properties"]["private"][0], cmp_values.keys()), cmp_values) - + cmp_values = { + "constant": 0, + "name": "a", + "reference": 0, + "array_size": "MAX_LEN", + "type": "int", + "static": 0, + "pointer": 0, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["EagleClass"]["properties"]["private"][0], + cmp_values.keys(), + ), + cmp_values, + ) -class Frog_TestCase(unittest.TestCase): +class Frog_TestCase(unittest.TestCase): def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["FrogClass"]["properties"]["private"]), 3) + self.assertEqual( + len(self.cppHeader.classes["FrogClass"]["properties"]["private"]), 3 + ) - class Cat_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["CatClass"]["properties"]["private"]), 0) + self.assertEqual( + len(self.cppHeader.classes["CatClass"]["properties"]["private"]), 0 + ) class Fish_TestCase(unittest.TestCase): - def setUp(self): - #Just make sure it doesnt crash + # Just make sure it doesnt crash self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - -class Panda_TestCase(unittest.TestCase): +class Panda_TestCase(unittest.TestCase): def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_property_CONST_A(self): - cmp_values = {'typedef': None, 'unresolved': False, 'constant': 1, 'name': 'CONST_A', - 'parent': None, 'pointer': 0, 'namespace': '', 'raw_type': 'int', 'class': 0, - 'property_of_class': 'PandaClass', 'static': 1, 'fundamental': True, - 'mutable': False, 'typedefs': 0, 'array': 0, 'type': 'static const int', - 'reference': 0, 'aliases': []} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["PandaClass"]["properties"]["private"][0], cmp_values.keys()), cmp_values) + cmp_values = { + "typedef": None, + "unresolved": False, + "constant": 1, + "name": "CONST_A", + "parent": None, + "pointer": 0, + "namespace": "", + "raw_type": "int", + "class": 0, + "property_of_class": "PandaClass", + "static": 1, + "fundamental": True, + "mutable": False, + "typedefs": 0, + "array": 0, + "type": "static const int", + "reference": 0, + "aliases": [], + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["PandaClass"]["properties"]["private"][0], + cmp_values.keys(), + ), + cmp_values, + ) def test_property_CONST_B(self): - cmp_values = {'typedef': None, 'unresolved': False, 'constant': 1, 'name': 'CONST_B', - 'parent': None, 'pointer': 0, 'namespace': '', 'raw_type': 'int', 'class': 0, - 'property_of_class': 'PandaClass', 'static': 1, 'fundamental': True, - 'mutable': False, 'typedefs': 0, 'array': 0, 'type': 'static const int', - 'reference': 0, 'aliases': []} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["PandaClass"]["properties"]["private"][1], cmp_values.keys()), cmp_values) + cmp_values = { + "typedef": None, + "unresolved": False, + "constant": 1, + "name": "CONST_B", + "parent": None, + "pointer": 0, + "namespace": "", + "raw_type": "int", + "class": 0, + "property_of_class": "PandaClass", + "static": 1, + "fundamental": True, + "mutable": False, + "typedefs": 0, + "array": 0, + "type": "static const int", + "reference": 0, + "aliases": [], + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["PandaClass"]["properties"]["private"][1], + cmp_values.keys(), + ), + cmp_values, + ) class Potato_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_private_properties_potato(self): - self.assertEqual(len(self.cppHeader.classes["PotatoClass"]["properties"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["PotatoClass"]["properties"]["private"]), 1 + ) + def test_num_public_properties_potato_fwdstruct(self): - self.assertEqual(len(self.cppHeader.classes["PotatoClass::FwdStruct"]["properties"]["public"]), 1) + self.assertEqual( + len( + self.cppHeader.classes["PotatoClass::FwdStruct"]["properties"]["public"] + ), + 1, + ) class Hog_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_private_properties_potato(self): - self.assertEqual(len(self.cppHeader.classes["HogClass"]["properties"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["HogClass"]["properties"]["private"]), 1 + ) + def test_property(self): - cmp_values = {'constant': 0, 'name': 'u', 'reference': 0, 'type': 'union HogUnion', 'static': 0, 'pointer': 0} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["HogClass"]["properties"]["private"][0], cmp_values.keys()), cmp_values) + cmp_values = { + "constant": 0, + "name": "u", + "reference": 0, + "type": "union HogUnion", + "static": 0, + "pointer": 0, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["HogClass"]["properties"]["private"][0], + cmp_values.keys(), + ), + cmp_values, + ) def test_union(self): - cmp_values = {"name": "union HogUnion", "parent": "HogClass", "declaration_method": "union"} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["HogClass::union HogUnion"], cmp_values.keys()), cmp_values) - + cmp_values = { + "name": "union HogUnion", + "parent": "HogClass", + "declaration_method": "union", + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["HogClass::union HogUnion"], cmp_values.keys() + ), + cmp_values, + ) + def test_union_member_a(self): - cmp_values = {'constant': 0, 'name': 'a', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["HogClass::union HogUnion"]["members"][0], cmp_values.keys()), cmp_values) - + cmp_values = { + "constant": 0, + "name": "a", + "reference": 0, + "type": "int", + "static": 0, + "pointer": 0, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["HogClass::union HogUnion"]["members"][0], + cmp_values.keys(), + ), + cmp_values, + ) + def test_union_member_b(self): - cmp_values = {'constant': 0, 'name': 'b', 'reference': 0, 'type': 'float', 'static': 0, 'pointer': 0} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["HogClass::union HogUnion"]["members"][1], cmp_values.keys()), cmp_values) + cmp_values = { + "constant": 0, + "name": "b", + "reference": 0, + "type": "float", + "static": 0, + "pointer": 0, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["HogClass::union HogUnion"]["members"][1], + cmp_values.keys(), + ), + cmp_values, + ) + # Bug 3497158 class CherryClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["CherryClass::NestStruct"]["properties"]["public"]), 1) - + self.assertEqual( + len( + self.cppHeader.classes["CherryClass::NestStruct"]["properties"][ + "public" + ] + ), + 1, + ) + def test_num_public_methods(self): - self.assertEqual(len(self.cppHeader.classes["CherryClass::NestStruct"]["methods"]["public"]), 1) + self.assertEqual( + len(self.cppHeader.classes["CherryClass::NestStruct"]["methods"]["public"]), + 1, + ) + # Bug 3517308 class GarlicClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["GarlicClass"]["properties"]["public"]), 0) - + self.assertEqual( + len(self.cppHeader.classes["GarlicClass"]["properties"]["public"]), 0 + ) + def test_num_public_methods(self): - self.assertEqual(len(self.cppHeader.classes["GarlicClass"]["methods"]["public"]), 3) + self.assertEqual( + len(self.cppHeader.classes["GarlicClass"]["methods"]["public"]), 3 + ) + # Bug 3514728 class CarrotClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["CarrotClass"]["properties"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["CarrotClass"]["properties"]["private"]), 1 + ) + def test_num_private_methods(self): - self.assertEqual(len(self.cppHeader.classes["CarrotClass"]["methods"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["CarrotClass"]["methods"]["private"]), 1 + ) + def test_method_params(self): self.assertEqual( - filter_pameters(self.cppHeader.classes["CarrotClass"]["methods"]["private"][0]["parameters"]), - []) - + filter_pameters( + self.cppHeader.classes["CarrotClass"]["methods"]["private"][0][ + "parameters" + ] + ), + [], + ) + def test_class_template(self): - self.assertEqual(self.cppHeader.classes["CarrotClass"]["template"], "template") + self.assertEqual( + self.cppHeader.classes["CarrotClass"]["template"], "template" + ) # Bug 3517289 class CarrotClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_private_methods(self): - self.assertEqual(len(self.cppHeader.classes["ExternClass"]["methods"]["private"]), 1) + self.assertEqual( + len(self.cppHeader.classes["ExternClass"]["methods"]["private"]), 1 + ) # Bug 3514671 class OliveStruct_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["OliveStruct"]["properties"]["public"]), 4) - + self.assertEqual( + len(self.cppHeader.classes["OliveStruct"]["properties"]["public"]), 4 + ) + def test_var_a(self): - self.assertEqual(self.cppHeader.classes["OliveStruct"]["properties"]["public"][0]["name"], "a") + self.assertEqual( + self.cppHeader.classes["OliveStruct"]["properties"]["public"][0]["name"], + "a", + ) # Bug 3515330 class Rooster_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_num_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["RoosterOuterClass"]["properties"]["public"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["RoosterOuterClass"]["properties"]["public"]), 1 + ) + def test_num_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["RoosterOuterClass"]["properties"]["private"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["RoosterOuterClass"]["properties"]["private"]), 1 + ) + def test_num_sub1_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["RoosterOuterClass::RoosterSubClass1"]["properties"]["public"]), 1) - + self.assertEqual( + len( + self.cppHeader.classes["RoosterOuterClass::RoosterSubClass1"][ + "properties" + ]["public"] + ), + 1, + ) + def test_num_sub1_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["RoosterOuterClass::RoosterSubClass1"]["properties"]["private"]), 1) - + self.assertEqual( + len( + self.cppHeader.classes["RoosterOuterClass::RoosterSubClass1"][ + "properties" + ]["private"] + ), + 1, + ) + def test_num_sub2_public_properties(self): - self.assertEqual(len(self.cppHeader.classes["RoosterOuterClass::RoosterSubClass2"]["properties"]["public"]), 1) - + self.assertEqual( + len( + self.cppHeader.classes["RoosterOuterClass::RoosterSubClass2"][ + "properties" + ]["public"] + ), + 1, + ) + def test_num_sub2_private_properties(self): - self.assertEqual(len(self.cppHeader.classes["RoosterOuterClass::RoosterSubClass2"]["properties"]["private"]), 1) + self.assertEqual( + len( + self.cppHeader.classes["RoosterOuterClass::RoosterSubClass2"][ + "properties" + ]["private"] + ), + 1, + ) # Bug 3514672 class OperatorClass_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_op_0(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][0]["name"], 'operator=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][0]["name"], + "operator=", + ) def test_op_1(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][1]["name"], 'operator-=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][1]["name"], + "operator-=", + ) def test_op_2(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][2]["name"], 'operator+=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][2]["name"], + "operator+=", + ) def test_op_3(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][3]["name"], 'operator[]') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][3]["name"], + "operator[]", + ) def test_op_4(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][4]["name"], 'operator==') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][4]["name"], + "operator==", + ) def test_op_5(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][5]["name"], 'operator+') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][5]["name"], + "operator+", + ) def test_op_6(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][6]["name"], 'operator-') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][6]["name"], + "operator-", + ) def test_op_7(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][7]["name"], 'operator*') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][7]["name"], + "operator*", + ) def test_op_8(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][8]["name"], 'operator\\') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][8]["name"], + "operator\\", + ) def test_op_9(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][9]["name"], 'operator%') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][9]["name"], + "operator%", + ) def test_op_10(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][10]["name"], 'operator^') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][10]["name"], + "operator^", + ) def test_op_11(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][11]["name"], 'operator|') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][11]["name"], + "operator|", + ) def test_op_12(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][12]["name"], 'operator&') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][12]["name"], + "operator&", + ) def test_op_13(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][13]["name"], 'operator~') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][13]["name"], + "operator~", + ) def test_op_14(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][14]["name"], 'operator<<') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][14]["name"], + "operator<<", + ) def test_op_15(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][15]["name"], 'operator>>') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][15]["name"], + "operator>>", + ) def test_op_16(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][16]["name"], 'operator!=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][16]["name"], + "operator!=", + ) def test_op_17(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][17]["name"], 'operator<') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][17]["name"], + "operator<", + ) def test_op_18(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][18]["name"], 'operator>') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][18]["name"], + "operator>", + ) def test_op_19(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][19]["name"], 'operator>=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][19]["name"], + "operator>=", + ) def test_op_20(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][20]["name"], 'operator<=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][20]["name"], + "operator<=", + ) def test_op_21(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][21]["name"], 'operator!') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][21]["name"], + "operator!", + ) def test_op_22(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][22]["name"], 'operator&&') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][22]["name"], + "operator&&", + ) def test_op_23(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][23]["name"], 'operator||') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][23]["name"], + "operator||", + ) def test_op_24(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][24]["name"], 'operator+=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][24]["name"], + "operator+=", + ) def test_op_25(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][25]["name"], 'operator-=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][25]["name"], + "operator-=", + ) def test_op_26(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][26]["name"], 'operator*=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][26]["name"], + "operator*=", + ) def test_op_27(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][27]["name"], 'operator\\=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][27]["name"], + "operator\\=", + ) def test_op_28(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][28]["name"], 'operator%=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][28]["name"], + "operator%=", + ) def test_op_29(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][29]["name"], 'operator&=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][29]["name"], + "operator&=", + ) def test_op_30(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][30]["name"], 'operator|=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][30]["name"], + "operator|=", + ) def test_op_31(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][31]["name"], 'operator^=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][31]["name"], + "operator^=", + ) def test_op_32(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][32]["name"], 'operator<<=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][32]["name"], + "operator<<=", + ) def test_op_33(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][33]["name"], 'operator>>=') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][33]["name"], + "operator>>=", + ) def test_op_34(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][34]["name"], 'operator++') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][34]["name"], + "operator++", + ) def test_op_35(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][35]["name"], 'operator--') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][35]["name"], + "operator--", + ) def test_op_36(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][36]["name"], 'operator()') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][36]["name"], + "operator()", + ) def test_op_37(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][37]["name"], 'operator->') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][37]["name"], + "operator->", + ) def test_op_38(self): - self.assertEqual(self.cppHeader.classes["OperatorClass"]["methods"]["public"][38]["name"], 'operator,') + self.assertEqual( + self.cppHeader.classes["OperatorClass"]["methods"]["public"][38]["name"], + "operator,", + ) # Feature Request 3519502 & 3523010 class CrowClass_TestCase(unittest.TestCase): - def setUp(self): self.savedSupportedAccessSpecifier = CppHeaderParser.supportedAccessSpecifier - CppHeaderParser.supportedAccessSpecifier.append("public slots ")#intentionally add expra spaces to make sure they get cleaned up + CppHeaderParser.supportedAccessSpecifier.append( + "public slots " + ) # intentionally add expra spaces to make sure they get cleaned up self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_methods(self): - self.assertEqual(len(self.cppHeader.classes["CrowClass"]["methods"]["public"]), 1) + self.assertEqual( + len(self.cppHeader.classes["CrowClass"]["methods"]["public"]), 1 + ) def test_rtntype_public_slot_method(self): - self.assertEqual(self.cppHeader.classes["CrowClass"]["methods"]["public slots"][0]["rtnType"], 'void') + self.assertEqual( + self.cppHeader.classes["CrowClass"]["methods"]["public slots"][0][ + "rtnType" + ], + "void", + ) def test_num_public_slot_methods(self): - self.assertEqual(len(self.cppHeader.classes["CrowClass"]["methods"]["public slots"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["CrowClass"]["methods"]["public slots"]), 1 + ) + def tearDown(self): CppHeaderParser.supportedAccessSpecifier = self.savedSupportedAccessSpecifier # Bug 3497170 class DriverFuncs_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_name_0(self): - self.assertEqual(self.cppHeader.classes["DriverFuncs"]["properties"]["public"][0]["name"], "init") - + self.assertEqual( + self.cppHeader.classes["DriverFuncs"]["properties"]["public"][0]["name"], + "init", + ) + def test_type_0(self): - self.assertEqual(self.cppHeader.classes["DriverFuncs"]["properties"]["public"][0]["type"], "void * ( * ) ( )") - + self.assertEqual( + self.cppHeader.classes["DriverFuncs"]["properties"]["public"][0]["type"], + "void * ( * ) ( )", + ) + def test_function_pointer_field_0(self): - self.assertEqual(self.cppHeader.classes["DriverFuncs"]["properties"]["public"][0]["function_pointer"], 1) - + self.assertEqual( + self.cppHeader.classes["DriverFuncs"]["properties"]["public"][0][ + "function_pointer" + ], + 1, + ) + def test_name_1(self): - self.assertEqual(self.cppHeader.classes["DriverFuncs"]["properties"]["public"][1]["name"], "write") - + self.assertEqual( + self.cppHeader.classes["DriverFuncs"]["properties"]["public"][1]["name"], + "write", + ) + def test_type_1(self): - self.assertEqual(self.cppHeader.classes["DriverFuncs"]["properties"]["public"][1]["type"], "void ( * ) ( void * buf, int buflen )") - + self.assertEqual( + self.cppHeader.classes["DriverFuncs"]["properties"]["public"][1]["type"], + "void ( * ) ( void * buf, int buflen )", + ) + def test_function_pointer_field_1(self): - self.assertEqual(self.cppHeader.classes["DriverFuncs"]["properties"]["public"][1]["function_pointer"], 1) - + self.assertEqual( + self.cppHeader.classes["DriverFuncs"]["properties"]["public"][1][ + "function_pointer" + ], + 1, + ) + # Bug 3519178 class Snail_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_rtn_type(self): - self.assertEqual(self.cppHeader.classes["Snail2Class"]["methods"]["public"][0]["rtnType"], "SnailNamespace::SnailClass") - + self.assertEqual( + self.cppHeader.classes["Snail2Class"]["methods"]["public"][0]["rtnType"], + "SnailNamespace::SnailClass", + ) + def test_param_name(self): - self.assertEqual(self.cppHeader.classes["Snail2Class"]["methods"]["public"][0]["parameters"][0]["name"], "") - + self.assertEqual( + self.cppHeader.classes["Snail2Class"]["methods"]["public"][0]["parameters"][ + 0 + ]["name"], + "", + ) + def test_param_name(self): - self.assertEqual(self.cppHeader.classes["Snail2Class"]["methods"]["public"][0]["parameters"][0]["type"], "tr1::shared_ptr >") + self.assertEqual( + self.cppHeader.classes["Snail2Class"]["methods"]["public"][0]["parameters"][ + 0 + ]["type"], + "tr1::shared_ptr >", + ) + # Feature Request 3523198 class Quale_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_rtn_type(self): - self.assertEqual(self.cppHeader.classes["QualeClass"]["methods"]["private"][0]["rtnType"], "void") + self.assertEqual( + self.cppHeader.classes["QualeClass"]["methods"]["private"][0]["rtnType"], + "void", + ) # Feature Request 3523235 class Rock_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_const_0(self): - self.assertEqual(self.cppHeader.classes["RockClass"]["methods"]["private"][0]["const"], True) - + self.assertEqual( + self.cppHeader.classes["RockClass"]["methods"]["private"][0]["const"], True + ) + def test_const_1(self): - self.assertEqual(self.cppHeader.classes["RockClass"]["methods"]["private"][1]["const"], False) + self.assertEqual( + self.cppHeader.classes["RockClass"]["methods"]["private"][1]["const"], False + ) # Bug 3523196 class Almond_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_rtn_type(self): - self.assertEqual(self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["rtnType"], "std::map > >") - + self.assertEqual( + self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["rtnType"], + "std::map > >", + ) + def test_param_1_name(self): - self.assertEqual(self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][0]["name"], "flag") - + self.assertEqual( + self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][ + 0 + ]["name"], + "flag", + ) + def test_param_1_type(self): - self.assertEqual(self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][0]["type"], "bool") - + self.assertEqual( + self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][ + 0 + ]["type"], + "bool", + ) + def test_param_2_name(self): - self.assertEqual(self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][1]["name"], "bigArg") - + self.assertEqual( + self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][ + 1 + ]["name"], + "bigArg", + ) + def test_param_2_type(self): - self.assertEqual(self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][1]["type"], "std::map > >") + self.assertEqual( + self.cppHeader.classes["AlmondClass"]["methods"]["public"][0]["parameters"][ + 1 + ]["type"], + "std::map > >", + ) # Bug 3524327 class Stone_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_const_0(self): - self.assertEqual(self.cppHeader.classes["StoneClass"]["methods"]["private"][0]["const"], True) - + self.assertEqual( + self.cppHeader.classes["StoneClass"]["methods"]["private"][0]["const"], True + ) + def test_const_1(self): - self.assertEqual(self.cppHeader.classes["StoneClass"]["methods"]["private"][1]["const"], False) - + self.assertEqual( + self.cppHeader.classes["StoneClass"]["methods"]["private"][1]["const"], + False, + ) + # Bug 3531219 class Kangaroo_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_kangaroo_methods(self): - self.assertEqual(len(self.cppHeader.classes["Kangaroo"]["methods"]["public"]), 1) - + self.assertEqual( + len(self.cppHeader.classes["Kangaroo"]["methods"]["public"]), 1 + ) + def test_num_joey_methods(self): - self.assertEqual(len(self.cppHeader.classes["Kangaroo::Joey"]["methods"]["public"]), 1) + self.assertEqual( + len(self.cppHeader.classes["Kangaroo::Joey"]["methods"]["public"]), 1 + ) # Bug 3535465 class Ant_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_num_constructor_1_params(self): - self.assertEqual(len(self.cppHeader.classes["Ant"]["methods"]["public"][0]["parameters"]), 3) - + self.assertEqual( + len(self.cppHeader.classes["Ant"]["methods"]["public"][0]["parameters"]), 3 + ) + def test_num_constructor_2_params(self): - self.assertEqual(len(self.cppHeader.classes["Ant"]["methods"]["public"][1]["parameters"]), 1) + self.assertEqual( + len(self.cppHeader.classes["Ant"]["methods"]["public"][1]["parameters"]), 1 + ) + # Bug 3536069 class Onion_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_properties_red(self): - self.assertEqual(len(self.cppHeader.classes["Onion"]["properties"]["public"]), 1) + self.assertEqual( + len(self.cppHeader.classes["Onion"]["properties"]["public"]), 1 + ) def test_num_public_properties_sweet(self): - self.assertEqual(len(self.cppHeader.classes["Onion"]["properties"]["public"]), 1) + self.assertEqual( + len(self.cppHeader.classes["Onion"]["properties"]["public"]), 1 + ) def test_class_template(self): - self.assertEqual(self.cppHeader.classes["Onion"]["template"], "template ") - + self.assertEqual( + self.cppHeader.classes["Onion"]["template"], + "template ", + ) + + # Bug 3536067 class BlueJay_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_num_public_methods(self): self.assertEqual(len(self.cppHeader.classes["BlueJay"]["methods"]["public"]), 1) + # Bug 3536266 class functions_TestCase(unittest.TestCase): - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader("""\ + self.cppHeader = CppHeaderParser.CppHeader( + """\ void global_funct1(int i); int global_funct2(void); - """, "string") - + """, + "string", + ) + def test_num_functions(self): self.assertEqual(len(self.cppHeader.functions), 2) - + def test_function_name_1(self): self.assertEqual(self.cppHeader.functions[0]["name"], "global_funct1") - + def test_function_name_2(self): self.assertEqual(self.cppHeader.functions[1]["name"], "global_funct2") - + # Bug 3536071 class Pea_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") @@ -1181,68 +1768,82 @@ def test_num_inherits(self): self.assertEqual(len(self.cppHeader.classes["Pea"]["inherits"]), 1) def test_name_inherits(self): - self.assertEqual(self.cppHeader.classes["Pea"]["inherits"][0]["class"], "Vegetable") + self.assertEqual( + self.cppHeader.classes["Pea"]["inherits"][0]["class"], "Vegetable" + ) + # Bug 3540172 class functions2_TestCase(unittest.TestCase): - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader("""\ + self.cppHeader = CppHeaderParser.CppHeader( + """\ void global_funct1(int i); int global_funct2(void){ // do something } - """, "string") - + """, + "string", + ) + def test_num_functions(self): self.assertEqual(len(self.cppHeader.functions), 2) - + def test_function_name_1(self): self.assertEqual(self.cppHeader.functions[0]["name"], "global_funct1") - + def test_function_name_2(self): self.assertEqual(self.cppHeader.functions[1]["name"], "global_funct2") + # Feature: line numbers class line_num_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("LineNumTest.h") - + def test_lineno_function1(self): return self.assertEqual(self.cppHeader.functions[0]["line_number"], 13) - + def test_lineno_function2(self): return self.assertEqual(self.cppHeader.functions[1]["line_number"], 17) - + def test_lineno_Worm(self): return self.assertEqual(self.cppHeader.classes["Worm"]["line_number"], 20) - + def test_lineno_Worm_Constructor(self): - return self.assertEqual(self.cppHeader.classes["Worm"]["methods"]["public"][0]["line_number"], 23) - + return self.assertEqual( + self.cppHeader.classes["Worm"]["methods"]["public"][0]["line_number"], 23 + ) + def test_lineno_Worm_getName(self): - return self.assertEqual(self.cppHeader.classes["Worm"]["methods"]["public"][1]["line_number"], 24) - + return self.assertEqual( + self.cppHeader.classes["Worm"]["methods"]["public"][1]["line_number"], 24 + ) + def test_lineno_Worm_namep(self): - return self.assertEqual(self.cppHeader.classes["Worm"]["properties"]["private"][0]["line_number"], 29) + return self.assertEqual( + self.cppHeader.classes["Worm"]["properties"]["private"][0]["line_number"], + 29, + ) + # Bug 3567172 class Pear_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_property(self): - self.assertEqual(self.cppHeader.classes["Pear"]["properties"]["private"][0]["name"], "stem_property") - + self.assertEqual( + self.cppHeader.classes["Pear"]["properties"]["private"][0]["name"], + "stem_property", + ) # Bug 3567217 and 3569663 class Macro_TestCase(unittest.TestCase): - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader(r""" + self.cppHeader = CppHeaderParser.CppHeader( + r""" #include #include "../../debug.h" @@ -1253,98 +1854,103 @@ def setUp(self): #define DEBUG_PRINT(x) \ printf("---------------\n"); \ printf("DEBUG: %d\n", x); \ - printf("---------------\n");""", "string") + printf("---------------\n");""", + "string", + ) def test_includes(self): - self.assertEqual(self.cppHeader.includes, ['', '"../../debug.h"']) - + self.assertEqual(self.cppHeader.includes, ["", '"../../debug.h"']) + def test_pragmas(self): - self.assertEqual(self.cppHeader.pragmas, ['once']) - + self.assertEqual(self.cppHeader.pragmas, ["once"]) + def test_pragmas0(self): - self.assertEqual(self.cppHeader.defines[0], 'ONE 1') - + self.assertEqual(self.cppHeader.defines[0], "ONE 1") + def test_pragmas1(self): self.assertEqual(self.cppHeader.defines[1], 'TWO_NUM_N_NAME "2 (TWO)"') - - def test_pragmas2(self): - self.assertEqual(self.cppHeader.defines[2], 'DEBUG_PRINT(x) \\\n printf("---------------\\n"); \\\n printf("DEBUG: %d\\n", x); \\\n printf("---------------\\n");') + def test_pragmas2(self): + self.assertEqual( + self.cppHeader.defines[2], + 'DEBUG_PRINT(x) \\\n printf("---------------\\n"); \\\n printf("DEBUG: %d\\n", x); \\\n printf("---------------\\n");', + ) # Bug: 3567854 and 3568241 class Beans_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_anonymous_union_name(self): - return self.assertEqual(self.cppHeader.classes["Beans"]["properties"]["public"][1]["name"], "") - + return self.assertEqual( + self.cppHeader.classes["Beans"]["properties"]["public"][1]["name"], "" + ) + def test_second_anonymous_union_name(self): - return self.assertEqual(self.cppHeader.classes["Beans"]["properties"]["public"][3]["name"], "") + return self.assertEqual( + self.cppHeader.classes["Beans"]["properties"]["public"][3]["name"], "" + ) # Bug: 3567854 and 3568241 class termite_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_termite_function(self): self.assertEqual(self.cppHeader.functions[5]["name"], "termite") - # Bug: 3569622 class Japyx_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_japyxFunc(self): self.assertEqual(self.cppHeader.functions[6]["name"], "japyxFunc") # Bug: 3570105 class Author_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_name(self): self.assertEqual(self.cppHeader.enums[0]["name"], "Author") - + def test_name(self): - self.assertEqual(self.cppHeader.enums[0]["values"], [ - {'name': 'NAME', 'value': "( 'J' << 24 | 'A' << 16 | 'S' << 8 | 'H' )"}]) + self.assertEqual( + self.cppHeader.enums[0]["values"], + [{"name": "NAME", "value": "( 'J' << 24 | 'A' << 16 | 'S' << 8 | 'H' )"}], + ) # Bug: 3577484 class Fly_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_exists(self): self.assertEqual("FruitFly" in self.cppHeader.classes, True) + # Bug BitBucket #2 class ClassAfterMagicMacro_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_class_exists(self): self.assertEqual("ClassAfterMagicMacro" in self.cppHeader.classes, True) + # Bug BitBucket #3 class FilterMagicMacro_TestCase(unittest.TestCase): - def setUp(self): savedIgnoreSymbols = CppHeaderParser.ignoreSymbols CppHeaderParser.ignoreSymbols.append("MAGIC_FUNC()") - self.cppHeader = CppHeaderParser.CppHeader(r""" + self.cppHeader = CppHeaderParser.CppHeader( + r""" class FilterMagicMacro { public: @@ -1358,332 +1964,432 @@ class FilterMagicMacro MAGIC_FUNC("1) \" var") void FilterMagicMacroMethod(int); -};""", "string") +};""", + "string", + ) CppHeaderParser.ignoreSymbols = savedIgnoreSymbols - + def test_method_exists(self): - self.assertEqual(self.cppHeader.classes["FilterMagicMacro"]["methods"]["public"][0]["name"], "FilterMagicMacroMethod") - + self.assertEqual( + self.cppHeader.classes["FilterMagicMacro"]["methods"]["public"][0]["name"], + "FilterMagicMacroMethod", + ) + def test_line_num_is_correct(self): - self.assertEqual(self.cppHeader.classes["FilterMagicMacro"]["methods"]["public"][0]["line_number"], 14); + self.assertEqual( + self.cppHeader.classes["FilterMagicMacro"]["methods"]["public"][0][ + "line_number" + ], + 14, + ) + # Bug BitBucket #4 class ClassRegularTypedefs_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_uint_exists(self): self.assertEqual("uint" in self.cppHeader.typedefs, True) - + def test_string_array_exists(self): self.assertEqual("string_array" in self.cppHeader.typedefs, True) - + def test_SmartObjPtr_exists(self): self.assertEqual("SmartObjPtr" in self.cppHeader.typedefs, True) - + def test_StrStrMap_exists(self): self.assertEqual("StrStrMap" in self.cppHeader.typedefs, True) - + def test_AfterTypedefClass_exists(self): self.assertEqual("AfterTypedefClass" in self.cppHeader.classes, True) + # Bug BitBucket #6 class LineNumAfterDivide_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_line_num(self): - self.assertEqual(self.cppHeader.classes["LineNumAfterDivide"]["methods"]["private"][1]["line_number"], 583) + self.assertEqual( + self.cppHeader.classes["LineNumAfterDivide"]["methods"]["private"][1][ + "line_number" + ], + 583, + ) + # Bug BitBucket #5 class ClassHerbCilantro_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_HerbCilantro_exists(self): self.assertEqual("Herb::Cilantro" in self.cppHeader.classes, True) + # Bug BitBucket #7 class print_statement_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_function_name_type(self): self.assertEqual(self.cppHeader.functions[7]["name"], "print_statement") - + def test_return_type(self): self.assertEqual(self.cppHeader.functions[7]["returns"], "int") + # Bug BitBucket #8 class Garlic_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_function_exists(self): - self.assertEqual(self.cppHeader.classes["Garlic"]["methods"]["public"][0]["name"], "genNum") + self.assertEqual( + self.cppHeader.classes["Garlic"]["methods"]["public"][0]["name"], "genNum" + ) + # Bug SourceForge #54 class Wheat_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_name(self): self.assertEqual(self.cppHeader.enums[1]["name"], "Wheat") - + def test_typedef(self): self.assertEqual(self.cppHeader.enums[1]["typedef"], False) + # Bug SourceForge #55 class PeachPlumb_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Peach_exists(self): self.assertEqual("Peach" in self.cppHeader.classes, True) - + def test_Plumb_exists(self): self.assertEqual("Plumb" in self.cppHeader.classes, True) - + def test_function_exists(self): - self.assertEqual(self.cppHeader.classes["Plumb"]["methods"]["private"][0]["name"], "doSomethingGreat") + self.assertEqual( + self.cppHeader.classes["Plumb"]["methods"]["private"][0]["name"], + "doSomethingGreat", + ) + # Bug BitBucket #9 class Grape_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Grape_exists(self): self.assertEqual("Grape" in self.cppHeader.classes, True) - + def test_a_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][0]["name"], "a") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][0]["name"], "a" + ) + def test_a_type(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][0]["type"], "int") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][0]["type"], "int" + ) + def test_b_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][1]["name"], "b") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][1]["name"], "b" + ) + def test_b_type(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][1]["type"], "int") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][1]["type"], "int" + ) + def test_c_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][2]["name"], "c") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][2]["name"], "c" + ) + def test_d_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][3]["name"], "d") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][3]["name"], "d" + ) + def test_e_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][4]["name"], "e") - + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][4]["name"], "e" + ) + def test_f_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][5]["name"], "f") + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][5]["name"], "f" + ) + # Bug BitBucket #14 class Avacado_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Avacado_exists(self): self.assertEqual("Avacado" in self.cppHeader.classes, True) - + def test_foo_return_type(self): - self.assertEqual(self.cppHeader.classes["Avacado"]["methods"]["public"][0]["returns"], "uint8_t") - + self.assertEqual( + self.cppHeader.classes["Avacado"]["methods"]["public"][0]["returns"], + "uint8_t", + ) + def test_bar_return_type(self): - self.assertEqual(self.cppHeader.classes["Avacado"]["methods"]["public"][1]["returns"], "::uint8_t") + self.assertEqual( + self.cppHeader.classes["Avacado"]["methods"]["public"][1]["returns"], + "::uint8_t", + ) + # Bug BitBucket #13 class Raspberry_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_anon_struct_1_exists(self): self.assertEqual("" in self.cppHeader.classes, True) - + def test_beta_exists(self): - self.assertEqual(self.cppHeader.classes[""]["properties"]["public"][0]["name"], "anon_struct_variable") - + self.assertEqual( + self.cppHeader.classes[""]["properties"]["public"][0][ + "name" + ], + "anon_struct_variable", + ) + def test_Raspberry_exists(self): self.assertEqual("Raspberry" in self.cppHeader.classes, True) - + def test_a_exists(self): - self.assertEqual(self.cppHeader.classes["Raspberry"]["properties"]["public"][0]["name"], "a") + self.assertEqual( + self.cppHeader.classes["Raspberry"]["properties"]["public"][0]["name"], "a" + ) + # Bug BitBucket #15 & 16 class Hen_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_default_a(self): - self.assertEqual(self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][0]["defaultValue"], "100") - + self.assertEqual( + self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][0][ + "defaultValue" + ], + "100", + ) + def test_default_b(self): - self.assertEqual(self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][1]["defaultValue"], "0xfd") - + self.assertEqual( + self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][1][ + "defaultValue" + ], + "0xfd", + ) + def test_default_c(self): - self.assertEqual(self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][2]["defaultValue"], "1.7e-3") - + self.assertEqual( + self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][2][ + "defaultValue" + ], + "1.7e-3", + ) + def test_default_d(self): - self.assertEqual(self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][3]["defaultValue"], "3.14") - + self.assertEqual( + self.cppHeader.classes["Hen"]["methods"]["public"][0]["parameters"][3][ + "defaultValue" + ], + "3.14", + ) + def test_default_s1(self): - self.assertEqual(self.cppHeader.classes["Hen"]["methods"]["public"][1]["parameters"][0]["defaultValue"], '""') - + self.assertEqual( + self.cppHeader.classes["Hen"]["methods"]["public"][1]["parameters"][0][ + "defaultValue" + ], + '""', + ) + def test_default_s2(self): - self.assertEqual(self.cppHeader.classes["Hen"]["methods"]["public"][1]["parameters"][1]["defaultValue"], '"nothing"') + self.assertEqual( + self.cppHeader.classes["Hen"]["methods"]["public"][1]["parameters"][1][ + "defaultValue" + ], + '"nothing"', + ) # Bug BitBucket #19 class Raddish_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Avacado_exists(self): - self.assertEqual(self.cppHeader.classes["Raddish_SetIterator"]["properties"]["protected"][0]["name"], "_beg") - + self.assertEqual( + self.cppHeader.classes["Raddish_SetIterator"]["properties"]["protected"][0][ + "name" + ], + "_beg", + ) + def test_class_template(self): - template_str = \ - "template >" - self.assertEqual(self.cppHeader.classes["Raddish_SetIterator"]["template"], template_str) + template_str = ( + "template >" + ) + self.assertEqual( + self.cppHeader.classes["Raddish_SetIterator"]["template"], template_str + ) # Bug bug 57 class Carambola_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_name(self): self.assertEqual(self.cppHeader.enums[2]["name"], "Carambola") - + def test_values(self): - self.assertEqual(self.cppHeader.enums[2]["values"], [ - {'name': 'StarFruit', 'value': '( 2 + 2 ) / 2'}]) - + self.assertEqual( + self.cppHeader.enums[2]["values"], + [{"name": "StarFruit", "value": "( 2 + 2 ) / 2"}], + ) + def test_typedef(self): self.assertEqual(self.cppHeader.enums[2]["typedef"], True) - + # globals class Globals_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_externVar_name(self): self.assertEqual(self.cppHeader.variables[2]["name"], "externVar") - + def test_externVar_extern(self): self.assertEqual(self.cppHeader.variables[2]["extern"], 1) - + def test_globalVar_name(self): self.assertEqual(self.cppHeader.variables[3]["name"], "globalVar") - + def test_globalVar_extern(self): self.assertEqual(self.cppHeader.variables[3]["extern"], 0) + # globals class TypedefArray_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_name(self): self.assertEqual("TenCharArray[10]" in self.cppHeader.typedefs, True) - + def test_value(self): self.assertEqual(self.cppHeader.typedefs["TenCharArray[10]"], "char") + # typedef structs class TypedefStruct_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_name(self): self.assertEqual("MAGIC_FILE" in self.cppHeader.typedefs, True) - + def test_value(self): - self.assertEqual(self.cppHeader.typedefs["MAGIC_FILE"], "struct SUPER_MAGIC_FILE") - - + self.assertEqual( + self.cppHeader.typedefs["MAGIC_FILE"], "struct SUPER_MAGIC_FILE" + ) + + # Bug SourceForge #10 class Picture_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_array_size(self): - self.assertEqual(self.cppHeader.classes["Picture"]["properties"]["public"][1]["array_size"], 16384) - + self.assertEqual( + self.cppHeader.classes["Picture"]["properties"]["public"][1]["array_size"], + 16384, + ) + def test_multi_dimensional_array_size(self): - self.assertEqual(self.cppHeader.classes["Picture"]["properties"]["public"][1]["multi_dimensional_array_size"], "128x128") - + self.assertEqual( + self.cppHeader.classes["Picture"]["properties"]["public"][1][ + "multi_dimensional_array_size" + ], + "128x128", + ) # SourceForge bug 58 class Apricot_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Apricot_exists(self): self.assertEqual("Apricot" in self.cppHeader.classes, True) - + def test_i_exists(self): self.assertEqual(self.cppHeader.classes["Apricot"]["members"][0]["name"], "i") - + def test_f_exists(self): self.assertEqual(self.cppHeader.classes["Apricot"]["members"][1]["name"], "f") - + def test_s_exists(self): self.assertEqual(self.cppHeader.classes["Apricot"]["members"][2]["name"], "s") # SourceForge bug 59 class LemonLime_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_lemon_not_final(self): self.assertEqual(self.cppHeader.classes["Lemon"]["final"], False) - + def test_lime_final(self): self.assertEqual(self.cppHeader.classes["Lime"]["final"], True) - + def test_lemon_foo_is_final(self): - self.assertEqual(self.cppHeader.classes["Lemon"]["methods"]["public"][0]["final"], True) - + self.assertEqual( + self.cppHeader.classes["Lemon"]["methods"]["public"][0]["final"], True + ) + def test_lemon_foo2_is_not_final(self): - self.assertEqual(self.cppHeader.classes["Lemon"]["methods"]["public"][1]["final"], False) - + self.assertEqual( + self.cppHeader.classes["Lemon"]["methods"]["public"][1]["final"], False + ) + def test_lime_abc_is_not_override(self): - self.assertEqual(self.cppHeader.classes["Lime"]["methods"]["public"][0]["override"], False) - + self.assertEqual( + self.cppHeader.classes["Lime"]["methods"]["public"][0]["override"], False + ) + def test_lime_foo2_is_not_override(self): - self.assertEqual(self.cppHeader.classes["Lime"]["methods"]["public"][1]["override"], True) + self.assertEqual( + self.cppHeader.classes["Lime"]["methods"]["public"][1]["override"], True + ) class JSON_TestCase(unittest.TestCase): - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader(r""" + self.cppHeader = CppHeaderParser.CppHeader( + r""" struct Lemon { virtual void foo() final; @@ -1694,118 +2400,158 @@ def setUp(self): { void abc(); void foo2() override; -};""", "string") +};""", + "string", + ) self.jsonString = self.cppHeader.toJSON() - + def test_hasLemon(self): hasString = ' "Lemon": {' in self.jsonString self.assertEqual(hasString, True) - + def test_can_parse_complex_file(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") j = self.cppHeader.toJSON() + # BitBucket bug 24 class Mouse_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_MouseClass_exists(self): self.assertEqual("MouseClass" in self.cppHeader.classes, True) - + def test_mouse_typedef_correct_value(self): - self.assertEqual(self.cppHeader.classes["MouseClass"]["methods"]["public"][0]["parameters"][0]['raw_type'], - "MouseNS::MouseClass::mouse_typedef") + self.assertEqual( + self.cppHeader.classes["MouseClass"]["methods"]["public"][0]["parameters"][ + 0 + ]["raw_type"], + "MouseNS::MouseClass::mouse_typedef", + ) + # BitBucket bug 26 class Fig_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Fig_exists(self): self.assertEqual("Fig" in self.cppHeader.classes, True) - + def test_a_exists(self): - self.assertEqual(self.cppHeader.classes["Grape"]["properties"]["public"][0]["name"], "a") + self.assertEqual( + self.cppHeader.classes["Grape"]["properties"]["public"][0]["name"], "a" + ) + # BitBucket bug 27 class Olive_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Olive_exists(self): self.assertEqual("union olive" in self.cppHeader.classes, True) - + def test_union_member_x(self): - cmp_values = {'constant': 0, 'name': 'x', 'reference': 0, 'type': 'int', 'static': 0, 'pointer': 0} - self.assertEqual(filter_dict_keys(self.cppHeader.classes["union olive"]["members"][0], cmp_values.keys()), cmp_values) + cmp_values = { + "constant": 0, + "name": "x", + "reference": 0, + "type": "int", + "static": 0, + "pointer": 0, + } + self.assertEqual( + filter_dict_keys( + self.cppHeader.classes["union olive"]["members"][0], cmp_values.keys() + ), + cmp_values, + ) + # BitBucket bug 61 class Beet_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_Beet_exists(self): self.assertEqual("BeetStruct" in self.cppHeader.classes, True) - + def test_BeetEnum_exists(self): - self.assertEqual(self.cppHeader.classes["BeetStruct"]["enums"]["public"][0]["name"], "BeetEnum") + self.assertEqual( + self.cppHeader.classes["BeetStruct"]["enums"]["public"][0]["name"], + "BeetEnum", + ) + # BitBucket bug 40 class set_callback_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") - + def test_set_callback(self): self.assertEqual(self.cppHeader.functions[8]["name"], "set_callback") - self.assertEqual(self.cppHeader.functions[8]["parameters"][1]["name"], "callback") - self.assertEqual(self.cppHeader.functions[8]["parameters"][1]["function_pointer"], 1) - self.assertEqual(self.cppHeader.functions[8]["parameters"][1]["type"], "long ( * ) ( struct test_st *, int, const char *, int long, long, long )") + self.assertEqual( + self.cppHeader.functions[8]["parameters"][1]["name"], "callback" + ) + self.assertEqual( + self.cppHeader.functions[8]["parameters"][1]["function_pointer"], 1 + ) + self.assertEqual( + self.cppHeader.functions[8]["parameters"][1]["type"], + "long ( * ) ( struct test_st *, int, const char *, int long, long, long )", + ) + # BitBucket bug 45 class HALControlWord_TestCase(unittest.TestCase): - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader("""\ + self.cppHeader = CppHeaderParser.CppHeader( + """\ struct HAL_ControlWord { int x : 1; int y : 1; }; typedef struct HAL_ControlWord HAL_ControlWord; int HAL_GetControlWord(HAL_ControlWord* controlWord); - """, "string") - + """, + "string", + ) + def test_functions(self): self.assertEqual(len(self.cppHeader.functions), 1) self.assertEqual(self.cppHeader.functions[0]["name"], "HAL_GetControlWord") - + def test_classes(self): self.assertEqual(len(self.cppHeader.classes), 1) - self.assertEqual(self.cppHeader.classes["HAL_ControlWord"]["name"], "HAL_ControlWord") + self.assertEqual( + self.cppHeader.classes["HAL_ControlWord"]["name"], "HAL_ControlWord" + ) def test_num_typedefs(self): self.assertEqual(len(self.cppHeader.typedefs), 1) - self.assertEqual(self.cppHeader.typedefs["HAL_ControlWord"], "struct HAL_ControlWord") + self.assertEqual( + self.cppHeader.typedefs["HAL_ControlWord"], "struct HAL_ControlWord" + ) + # Bitbucket bug 47 class CommentEOF_TestCase(unittest.TestCase): - def setUp(self): - self.cppHeader = CppHeaderParser.CppHeader(""" + self.cppHeader = CppHeaderParser.CppHeader( + """ namespace a { -} // namespace a""", "string") +} // namespace a""", + "string", + ) def test_comment(self): - self.assertTrue('a' in self.cppHeader.namespaces) + self.assertTrue("a" in self.cppHeader.namespaces) + # BitBucket bug 35 class Grackle_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") @@ -1813,79 +2559,205 @@ def test_Grackle_exists(self): self.assertEqual("Grackle" in self.cppHeader.classes, True) def test_Grackle_no_noexcept_None(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][0]["noexcept"], None) + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][0]["noexcept"], None + ) def test_Grackle_noexcept(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][1]["noexcept"], 'noexcept') + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][1]["noexcept"], + "noexcept", + ) def test_Grackle_const_noexcept(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][2]["const"], True) - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][2]["noexcept"], 'noexcept') + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][2]["const"], True + ) + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][2]["noexcept"], + "noexcept", + ) def test_Grackle_noexcept_true(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][3]["noexcept"], 'noexcept(true)') + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][3]["noexcept"], + "noexcept(true)", + ) def test_Grackle_const_noexcept_true(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][4]["const"], True) - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][4]["noexcept"], 'noexcept(true)') + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][4]["const"], True + ) + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][4]["noexcept"], + "noexcept(true)", + ) def test_Grackle_noexcept_noexcept_operator(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][5]["noexcept"], 'noexcept(noexcept(Grackle()))') + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][5]["noexcept"], + "noexcept(noexcept(Grackle()))", + ) def test_Grackle_const_noexcept_noexcept_operator(self): - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][6]["const"], True) - self.assertEqual(self.cppHeader.classes["Grackle"]["methods"]["public"][6]["noexcept"], 'noexcept(noexcept(Grackle()))') + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][6]["const"], True + ) + self.assertEqual( + self.cppHeader.classes["Grackle"]["methods"]["public"][6]["noexcept"], + "noexcept(noexcept(Grackle()))", + ) + # Test enhancement 13 (default constructor / destructor) -class DefaultConstDest_TestCase(): +class DefaultConstDest_TestCase: def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_DefaultConstDest_exists(self): self.assertEqual("DefaultConstDest" in self.cppHeader.classes, True) self.assertEqual("default_class_tricky" in self.cppHeader.classes, True) - + def test_DefaultConstDest_constructor_default(self): - self.assertEqual(self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][0]["constructor"], True) - self.assertEqual(self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][0]["default"], True) - self.assertEqual(self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][0]["defined"], True) + self.assertEqual( + self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][0][ + "constructor" + ], + True, + ) + self.assertEqual( + self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][0][ + "default" + ], + True, + ) + self.assertEqual( + self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][0][ + "defined" + ], + True, + ) def test_DefaultConstDest_destructor_default(self): - self.assertEqual(self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][1]["destructor"], True) - self.assertEqual(self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][1]["default"], True) - self.assertEqual(self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][1]["defined"], True) + self.assertEqual( + self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][1][ + "destructor" + ], + True, + ) + self.assertEqual( + self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][1][ + "default" + ], + True, + ) + self.assertEqual( + self.cppHeader.classes["DefaultConstDest"]["methods"]["public"][1][ + "defined" + ], + True, + ) def test_DefaultConstDest_default_edgeCaseNaming(self): - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][0]["constructor"], True) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][0]["default"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][0]["defined"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][1]["destructor"], True) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][1]["default"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][1]["defined"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2]["name"], "randomMethod1_default") - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2]["destructor"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2]["default"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2]["defined"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3]["name"], "defaultrandomMethod2") - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3]["destructor"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3]["default"], False) - self.assertEqual(self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3]["defined"], False) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][0][ + "constructor" + ], + True, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][0][ + "default" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][0][ + "defined" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][1][ + "destructor" + ], + True, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][1][ + "default" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][1][ + "defined" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2][ + "name" + ], + "randomMethod1_default", + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2][ + "destructor" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2][ + "default" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][2][ + "defined" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3][ + "name" + ], + "defaultrandomMethod2", + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3][ + "destructor" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3][ + "default" + ], + False, + ) + self.assertEqual( + self.cppHeader.classes["default_class_tricky"]["methods"]["public"][3][ + "defined" + ], + False, + ) class VarargFunc_TestCase(unittest.TestCase): - def setUp(self): self.cppHeader = CppHeaderParser.CppHeader("TestSampleClass.h") def test_vararg_func(self): - vf = next(x for x in self.cppHeader.functions if x['name'] == 'vararg_func') - nvf = next(x for x in self.cppHeader.functions if x['name'] == 'non_vararg_func') - self.assertTrue(vf['vararg']) - self.assertFalse(nvf['vararg']) - self.assertEqual(len(vf['parameters']), len(nvf['parameters'])) + vf = next(x for x in self.cppHeader.functions if x["name"] == "vararg_func") + nvf = next( + x for x in self.cppHeader.functions if x["name"] == "non_vararg_func" + ) + self.assertTrue(vf["vararg"]) + self.assertFalse(nvf["vararg"]) + self.assertEqual(len(vf["parameters"]), len(nvf["parameters"])) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() - - diff --git a/doc_generator.py b/doc_generator.py deleted file mode 100644 index 2cfd7d2..0000000 --- a/doc_generator.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/python -# Generate documenation -# * README.txt -# * README.html -import sys - -def gen_readme_html(): - """generate README.html""" - import cgi - f = open("templates/README.html").read() - sampleClass = open("CppHeaderParser/examples/SampleClass.h").read() - readSampleClass = open("CppHeaderParser/examples/readSampleClass.py").read() - - f = f.replace("{SAMPLE_CLASS_H}", cgi.escape(sampleClass)) - f = f.replace("{READ_SAMPLE_CLASS_PY}", cgi.escape(readSampleClass)) - f = f.replace("{READ_SAMPLE_CLASS_PY_OUTPUT}", cgi.escape(get_sample_class_output())) - open("README.html", "wa").write(f) - - -def gen_readme_txt(): - """generate README.txt""" - import cgi - f = open("templates/README.txt").read() - sampleClass = open("CppHeaderParser/examples/SampleClass.h").read() - readSampleClass = open("CppHeaderParser/examples/readSampleClass.py").read() - - f = f.replace("{SAMPLE_CLASS_H}", " " + sampleClass.replace("\n", "\n ")) - f = f.replace("{READ_SAMPLE_CLASS_PY}", " " + readSampleClass.replace("\n", "\n ")) - f = f.replace("{READ_SAMPLE_CLASS_PY_OUTPUT}", " " + get_sample_class_output().replace("\n", "\n ")) - open("README.txt", "wa").write(f) - print "wrote README.txt" - - import docutils.core - h = docutils.core.publish_string(source=open("README.txt").read(), writer_name='html') - h = h.replace("", "/*customization*/\npre.literal-block{\ncolor: #6A6A6A;\n}\n\n") - h = h.replace('
', '
')
-    open("README.html", "wa").write(h)
-    print "wrote README.html"
-
-
-def get_sample_class_output():
-    import subprocess
-    return subprocess.Popen(["python", "readSampleClass.py"],
-        stdout=subprocess.PIPE,
-        cwd="CppHeaderParser/examples"
-        ).communicate()[0]
-
-
-
-
-if __name__ == "__main__":
-    gen_readme_txt()
diff --git a/setup.py b/setup.py
index 87046f4..620986e 100644
--- a/setup.py
+++ b/setup.py
@@ -39,42 +39,43 @@
     exec(fp.read(), globals())
 
 DESCRIPTION = (
-    'Parse C++ header files and generate a data structure '
-    'representing the class'
-    )
+    "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'
-    ]
+    "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 = 'robotpy-cppheaderparser',
-    version = __version__,
-    author = 'Jashua Cloutier',
-    author_email = 'jashuac@bellsouth.net',
-    maintainer = 'RobotPy Development Team',
-    maintainer_email = 'robotpy@googlegroups.com',
-    url = 'https://github.com/robotpy/robotpy-cppheaderparser',
-    description = DESCRIPTION,
-    long_description = open('README.md').read(),
-    license = 'BSD',
-    platforms = 'Platform Independent',
-    packages = ['CppHeaderParser'],
-    keywords = 'c++ header parser ply',
-    classifiers = CLASSIFIERS,
-    requires = ['ply'],
-    install_requires=['ply'],
-    package_data = { 'CppHeaderParser': ['README', 'README.html', 'doc/*.*', 'examples/*.*'], },
-    )
+    name="robotpy-cppheaderparser",
+    version=__version__,
+    author="Jashua Cloutier",
+    author_email="jashuac@bellsouth.net",
+    maintainer="RobotPy Development Team",
+    maintainer_email="robotpy@googlegroups.com",
+    url="https://github.com/robotpy/robotpy-cppheaderparser",
+    description=DESCRIPTION,
+    long_description=open("README.md").read(),
+    license="BSD",
+    platforms="Platform Independent",
+    packages=["CppHeaderParser"],
+    keywords="c++ header parser ply",
+    classifiers=CLASSIFIERS,
+    requires=["ply"],
+    install_requires=["ply"],
+    package_data={
+        "CppHeaderParser": ["README", "README.html", "doc/*.*", "examples/*.*"]
+    },
+)