diff options
author | Stefan Sauer <ensonic@users.sf.net> | 2019-07-28 10:44:13 +0200 |
---|---|---|
committer | Stefan Sauer <ensonic@users.sf.net> | 2019-07-28 10:44:51 +0200 |
commit | 9b85fb55b6a2f0dcf5552753b5fd58ac3c368d72 (patch) | |
tree | 044086768cb844b87a6a79f86916bcc0a70bcf4f | |
parent | a6985fe9ff78f782ac2983bcded3a1701af0cf58 (diff) | |
download | gtk-doc-9b85fb55b6a2f0dcf5552753b5fd58ac3c368d72.tar.gz |
mkdb: extract helper function in sctruct output generation
Add some tests for it too.
See #95
-rw-r--r-- | gtkdoc/mkdb.py | 90 | ||||
-rwxr-xr-x | tests/mkdb.py | 47 |
2 files changed, 97 insertions, 40 deletions
diff --git a/gtkdoc/mkdb.py b/gtkdoc/mkdb.py index 5658449..009e99e 100644 --- a/gtkdoc/mkdb.py +++ b/gtkdoc/mkdb.py @@ -1209,6 +1209,55 @@ def uri_escape(text): return re.sub(r"([^A-Za-z0-9\-_.!~*'()]", do_escape, text) +def extract_struct_body(symbol, decl, has_typedef, public): + """Returns a normalized struct body. + + Normalizes whitespace and newlines and supresses non public members. + + Returns: + str: the nomalized struct declaration + """ + decl_out = '' + + m = re.search( + r'^\s*(typedef\s+)?struct\s*\w*\s*(?:\/\*.*\*\/)?\s*{(.*)}\s*\w*\s*;\s*$', decl, flags=re.DOTALL) + if m: + new_boby = '' + for line in m.group(2).splitlines(): + logging.info("Struct line: %s", line) + m2 = re.search(r'/\*\s*<\s*public\s*>\s*\*/', line) + m3 = re.search(r'/\*\s*<\s*(private|protected)\s*>\s*\*/', line) + if m2: + public = True + elif m3: + public = False + elif public: + new_boby += line + "\n" + + if new_boby: + # Strip any blank lines off the ends. + new_boby = re.sub(r'^\s*\n', '', new_boby) + new_boby = re.sub(r'\n\s*$', r'\n', new_boby) + + if has_typedef: + decl_out = "typedef struct {\n%s} %s;\n" % (new_boby, symbol) + else: + decl_out = "struct %s {\n%s};\n" % (symbol, new_boby) + else: + common.LogWarning(*GetSymbolSourceLocation(symbol), + "Couldn't parse struct:\n%s" % decl) + + if decl_out == '': + # If we couldn't parse the struct or it was all private, output an + # empty struct declaration. + if has_typedef: + decl_out = "typedef struct _%s %s;" % (symbol, symbol) + else: + decl_out = "struct %s;" % symbol + + return decl_out + + def OutputSymbolExtraLinks(symbol): """Returns extralinks for the symbol (if enabled). @@ -1404,46 +1453,7 @@ def OutputStruct(symbol, declaration): logging.info("Found opaque struct: %s", symbol) decl_out = "struct %s;" % symbol else: - m = re.search( - r'^\s*(typedef\s+)?struct\s*\w*\s*(?:\/\*.*\*\/)?\s*{(.*)}\s*\w*\s*;\s*$', declaration, flags=re.S) - if m: - struct_contents = m.group(2) - - public = default_to_public - new_declaration = '' - - for decl_line in struct_contents.splitlines(): - logging.info("Struct line: %s", decl_line) - m2 = re.search(r'/\*\s*<\s*public\s*>\s*\*/', decl_line) - m3 = re.search(r'/\*\s*<\s*(private|protected)\s*>\s*\*/', decl_line) - if m2: - public = True - elif m3: - public = False - elif public: - new_declaration += decl_line + "\n" - - if new_declaration: - # Strip any blank lines off the ends. - new_declaration = re.sub(r'^\s*\n', '', new_declaration) - new_declaration = re.sub(r'\n\s*$', r'\n', new_declaration) - - if has_typedef: - decl_out = "typedef struct {\n%s} %s;\n" % (new_declaration, symbol) - else: - decl_out = "struct %s {\n%s};\n" % (symbol, new_declaration) - - else: - common.LogWarning(*GetSymbolSourceLocation(symbol), - "Couldn't parse struct:\n%s" % declaration) - - # If we couldn't parse the struct or it was all private, output an - # empty struct declaration. - if decl_out == '': - if has_typedef: - decl_out = "typedef struct _%s %s;" % (symbol, symbol) - else: - decl_out = "struct %s;" % symbol + decl_out = extract_struct_body(symbol, declaration, has_typedef, default_to_public) decl_out = CreateValidSGML(decl_out) desc += "<programlisting language=\"C\">%s</programlisting>\n" % decl_out diff --git a/tests/mkdb.py b/tests/mkdb.py index 9d58c77..d41bd8c 100755 --- a/tests/mkdb.py +++ b/tests/mkdb.py @@ -203,5 +203,52 @@ class ScanSourceContentAnnotations(ScanSourceContentTestCase): # multiple annotations, multiline annotations, symbol-level ... +class OutputStruct(unittest.TestCase): + + def test_SimpleStructGetNormalized(self): + res = mkdb.extract_struct_body('data', textwrap.dedent("""\ + struct data + { + int i; + char *c; + }; + """), False, True) + self.assertEqual(textwrap.dedent("""\ + struct data { + int i; + char *c; + }; + """), res) + + def test_SimpleTypedefStructGetNormalized(self): + res = mkdb.extract_struct_body('data', textwrap.dedent("""\ + typedef struct _data + { + int i; + char *c; + } data; + """), True, True) + self.assertEqual(textwrap.dedent("""\ + typedef struct { + int i; + char *c; + } data; + """), res) + + def test_InternalStructNameIsNormalized(self): + res = mkdb.extract_struct_body('data', textwrap.dedent("""\ + struct _data { + int i; + char *c; + }; + """), False, True) + self.assertEqual(textwrap.dedent("""\ + struct data { + int i; + char *c; + }; + """), res) + + if __name__ == '__main__': unittest.main() |