summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2019-07-28 10:44:13 +0200
committerStefan Sauer <ensonic@users.sf.net>2019-07-28 10:44:51 +0200
commit9b85fb55b6a2f0dcf5552753b5fd58ac3c368d72 (patch)
tree044086768cb844b87a6a79f86916bcc0a70bcf4f
parenta6985fe9ff78f782ac2983bcded3a1701af0cf58 (diff)
downloadgtk-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.py90
-rwxr-xr-xtests/mkdb.py47
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()