summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@gmail.com>2019-07-17 15:54:27 +0000
committerXavier Claessens <xclaesse@gmail.com>2019-07-17 15:54:27 +0000
commit3a87f89913ddc8e33977d15388cb77c869eaf15c (patch)
tree96ce0cf6b8ec1a687c09eae767b38218898e25e4
parent53295ae10e2e3160480b6d0e52cc0602b4ca4e7a (diff)
parentc042912cac003c2077ac6353b8a84b3ddd00d1bf (diff)
downloadgtk-doc-3a87f89913ddc8e33977d15388cb77c869eaf15c.tar.gz
Merge branch 'glib-deprecated' into 'master'
Add support for GLIB_DEPRECATED_ decorators See merge request GNOME/gtk-doc!32
-rw-r--r--gtkdoc/scan.py47
-rw-r--r--tests/bugs/docs/Makefile.am2
-rw-r--r--tests/bugs/docs/meson.build2
-rw-r--r--tests/bugs/docs/tester-sections.txt6
-rw-r--r--tests/bugs/src/tester.h63
-rwxr-xr-xtests/scan.py67
6 files changed, 172 insertions, 15 deletions
diff --git a/gtkdoc/scan.py b/gtkdoc/scan.py
index 7da060f..ae4f866 100644
--- a/gtkdoc/scan.py
+++ b/gtkdoc/scan.py
@@ -81,14 +81,10 @@ CLINE_MATCHER = [
r"""^\s*enum\s+
_?(\w+) # 1: name
\s+\{""", re.VERBOSE),
- re.compile(r'^\s*typedef\s+enum\s+_?(\w+)\s+\1\s*;'),
+ None, # in ScanHeaderContent()
re.compile(r'^\s*typedef\s+enum'),
# 8-11: STRUCTS AND UNIONS
- re.compile(
- r"""^\s*typedef\s+
- (struct|union)\s+ # 1: struct/union
- _(\w+) # 2: name
- \s+\2\s*;""", re.VERBOSE),
+ None, # in ScanHeaderContent()
re.compile(r'^\s*(?:struct|union)\s+_(\w+)\s*;'),
re.compile(
r"""^\s*
@@ -132,7 +128,7 @@ CLINE_MATCHER = [
# 18-21: FUNCTIONS
None, # in ScanHeaderContent()
None, # in ScanHeaderContent()
- re.compile(r'^\s*([A-Za-z]\w*)\s*\('),
+ re.compile(r'^\s*\(?([A-Za-z]\w*)\)?\s*\('),
re.compile(r'^\s*\('),
# 22-23: STRUCTS
re.compile(r'^\s*struct\s+_?(\w+)\s*\*'),
@@ -377,8 +373,10 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
# avoid generating regex with |'' (matching no string)
ignore_decorators = ''
+ optional_decorators_regex = ''
if options.ignore_decorators:
- ignore_decorators = '|' + options.ignore_decorators
+ ignore_decorators = '|' + options.ignore_decorators.replace('()', '\(\w*\)')
+ optional_decorators_regex = '(?:\s+(?:%s))?' % ignore_decorators[1:]
# FUNCTION POINTER VARIABLES
CLINE_MATCHER[4] = re.compile(
@@ -389,6 +387,14 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
\(\*\s*
(\w+) # 4: name
\)\s*\(""" % ignore_decorators, re.VERBOSE)
+
+ CLINE_MATCHER[6] = re.compile(r'^\s*typedef\s+enum\s+_?(\w+)\s+\1%s\s*;' % optional_decorators_regex)
+ CLINE_MATCHER[8] = re.compile(
+ r"""^\s*typedef\s+
+ (struct|union)\s+ # 1: struct/union
+ _(\w+)\s+\2 # 2: name
+ %s # 3: optional decorator
+ \s*;""" % optional_decorators_regex, re.VERBOSE)
# OTHER TYPEDEFS
CLINE_MATCHER[15] = re.compile(
r"""^\s*
@@ -411,7 +417,7 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
(?:\b(?:extern|static|inline|G_INLINE_FUNC%s)\s*)*
(%s\w+) # 1: return type
([\s*]+(?:\s*(?:\*+|\bconst\b|\bG_CONST_RETURN\b))*)\s* # 2: .. cont'
- ([A-Za-z]\w*) # 3: name
+ \(?([A-Za-z]\w*)\)? # 3: name
\s*\(""" % (ignore_decorators, RET_TYPE_MODIFIER), re.VERBOSE)
PLINE_MATCHER[2] = re.compile(
@@ -882,19 +888,33 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
in_declaration = ''
if in_declaration == 'enum':
- em = re.search(r'\}\s*(\w+)?;\s*$', decl)
+ # Examples:
+ # "};"
+ # "} MyEnum;"
+ # "} MyEnum DEPRECATED_FOR(NewEnum);"
+ # "} DEPRECATED_FOR(NewEnum);"
+ em = re.search(r'\n\s*\}\s*(?:(\w+)?%s)?;\s*$' % optional_decorators_regex, decl)
if em:
if symbol == '':
symbol = em.group(1)
+ # Enums could contain deprecated values and that doesn't mean
+ # the whole enum is deprecated, so they are ignored when setting
+ # deprecated_conditional_nest above. Here we can check if the
+ # _DEPRECATED is between '}' and ';' which would mean the enum
+ # as a whole is deprecated.
+ if re.search(r'\n\s*\}.*_DEPRECATED.*;\s*$', decl):
+ deprecated = '<DEPRECATED/>\n'
if AddSymbolToList(slist, symbol):
- decl_list.append('<ENUM>\n<NAME>%s</NAME>\n%s%s</ENUM>\n' % (symbol, deprecated, decl))
+ stripped_decl = re.sub(optional_decorators_regex, '', decl)
+ decl_list.append('<ENUM>\n<NAME>%s</NAME>\n%s%s</ENUM>\n' % (symbol, deprecated, stripped_decl))
deprecated_conditional_nest = int(deprecated_conditional_nest)
in_declaration = ''
# We try to handle nested structs/unions, but unmatched brackets in
# comments will cause problems.
if in_declaration == 'struct' or in_declaration == 'union':
- sm = re.search(r'\n\}\s*(\w*);\s*$', decl)
+ # Same regex as for enum
+ sm = re.search(r'\n\}\s*(?:(\w+)?%s)?;\s*$' % optional_decorators_regex, decl)
if level <= 1 and sm:
if symbol == '':
symbol = sm.group(1)
@@ -908,8 +928,9 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
logging.info('Store struct: "%s"', symbol)
if AddSymbolToList(slist, symbol):
structsym = in_declaration.upper()
+ stripped_decl = re.sub('(%s)' % optional_decorators_regex, '', decl)
decl_list.append('<%s>\n<NAME>%s</NAME>\n%s%s</%s>\n' %
- (structsym, symbol, deprecated, decl, structsym))
+ (structsym, symbol, deprecated, stripped_decl, structsym))
if symbol in forward_decls:
del forward_decls[symbol]
deprecated_conditional_nest = int(deprecated_conditional_nest)
diff --git a/tests/bugs/docs/Makefile.am b/tests/bugs/docs/Makefile.am
index 7e3643c..2f33b00 100644
--- a/tests/bugs/docs/Makefile.am
+++ b/tests/bugs/docs/Makefile.am
@@ -19,7 +19,7 @@ SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
SCAN_OPTIONS=--deprecated-guards="GTKDOC_TESTER_DISABLE_DEPRECATED" \
- --ignore-decorators='GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR\(.+\)' \
+ --ignore-decorators='GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR()|MY_DEPRECATED_FOR()' \
--rebuild-types
# Extra options to supply to gtkdoc-mkdb.
diff --git a/tests/bugs/docs/meson.build b/tests/bugs/docs/meson.build
index 567fb4f..726cf4d 100644
--- a/tests/bugs/docs/meson.build
+++ b/tests/bugs/docs/meson.build
@@ -34,7 +34,7 @@ test(
'--source-dir=@0@'.format(bugs_test_source_dir),
'--ignore-headers=config.h',
'--deprecated-guards=GTKDOC_TESTER_DISABLE_DEPRECATED',
- '--ignore-decorators=GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR\(.+\)',
+ '--ignore-decorators=GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR()|MY_DEPRECATED_FOR()',
'--rebuild-types',
],
)
diff --git a/tests/bugs/docs/tester-sections.txt b/tests/bugs/docs/tester-sections.txt
index 9e6a5ff..e71d1bd 100644
--- a/tests/bugs/docs/tester-sections.txt
+++ b/tests/bugs/docs/tester-sections.txt
@@ -12,6 +12,10 @@ Bug512154
Bug644291
Bug000000Scope
Bug76
+MyDeprecatedEnum
+MyNotDeprecatedEnum
+MyDeprecatedStruct
+MyNotDeprecatedStruct
<SUBSECTION Functions>
bug_000000_va1
BUG_000000_VA2
@@ -59,6 +63,7 @@ bug_783420
gst_play_marshal_BUFFER__BOXED
BUG_791928
_
+inline_func_with_macro
<SUBSECTION Standard>
<SUBSECTION Private>
GTKDOC_GNUC_CONST
@@ -68,4 +73,5 @@ GLIB_DEPRECATED
BUG_711598_DEPRECATED_FOR
bug_554833_new
G_GNUC_NONNULL
+MY_DEPRECATED_FOR
</SECTION>
diff --git a/tests/bugs/src/tester.h b/tests/bugs/src/tester.h
index 0940e3e..3ed3fc0 100644
--- a/tests/bugs/src/tester.h
+++ b/tests/bugs/src/tester.h
@@ -432,4 +432,67 @@ struct _Bug76
};
typedef struct _Bug76 Bug76;
+#define MY_DEPRECATED_FOR(val)
+
+/**
+ * MyNotDeprecatedEnum:
+ * @MY_NOT_DEPRECATED_ENUM_VAL1: new value
+ *
+ * some description
+ */
+typedef enum {
+ MY_NOT_DEPRECATED_ENUM_VAL1,
+} MyNotDeprecatedEnum;
+
+/**
+ * MyDeprecatedEnum:
+ * @MY_DEPRECATED_ENUM_VAL1: deprecated, use instead %MY_DEPRECATED_ENUM_VAL2
+ * @MY_DEPRECATED_ENUM_VAL2: val2
+ *
+ * some description
+ * Deprecated: Use #MyNotDeprecatedEnum instead
+ */
+typedef enum {
+ MY_DEPRECATED_ENUM_VAL1 MY_DEPRECATED_FOR(MY_DEPRECATED_ENUM_VAL2),
+ MY_DEPRECATED_ENUM_VAL2,
+} MyDeprecatedEnum MY_DEPRECATED_FOR(MyNotDeprecatedEnum);
+
+/**
+ * MyDeprecatedStruct:
+ *
+ * some description
+ * Deprecated: Use #MyNotDeprecatedStruct instead
+ */
+typedef struct _MyDeprecatedStruct MyDeprecatedStruct MY_DEPRECATED_FOR(MyNotDeprecatedStruct);
+struct _MyDeprecatedStruct {
+ /*< private >*/
+ guint index;
+} MY_DEPRECATED_FOR(MyNotDeprecatedStruct);
+
+/**
+ * MyNotDeprecatedStruct:
+ *
+ * some description
+ */
+typedef struct {
+ /*< private >*/
+ guint index_plop;
+} MyNotDeprecatedStruct;
+
+/**
+ * inline_func_with_macro:
+ * @obj: arg
+ *
+ * GLib has a few inline functions with a macro that has the same name. It puts
+ * the inline function name into parenthesis to avoid macro expansion.
+ * See g_set_object().
+ */
+static inline gboolean
+(inline_func_with_macro) (void *obj)
+{
+ return TRUE;
+}
+
+#define inline_func_with_macro(obj)
+
#endif // GTKDOC_TESTER_H
diff --git a/tests/scan.py b/tests/scan.py
index 57b4603..98fddf7 100755
--- a/tests/scan.py
+++ b/tests/scan.py
@@ -220,6 +220,39 @@ class ScanHeaderContentEnum(ScanHeaderContentTestCase):
header.splitlines(keepends=True))
self.assertDecl('Data', header, slist)
+ def test_HandleDeprecatedMemberDecorator(self):
+ header = textwrap.dedent("""\
+ typedef enum {
+ VAL_DEFAULT,
+ OTHER_VAL MY_DEPRECATED_FOR(VAL_DEFAULT),
+ } Data;""")
+ expected = textwrap.dedent("""\
+ typedef enum {
+ VAL_DEFAULT,
+ OTHER_VAL,
+ } Data;""")
+ self.options.ignore_decorators = 'MY_DEPRECATED_FOR()'
+ slist, doc_comments = self.scanHeaderContent(
+ header.splitlines(keepends=True))
+ self.assertDecl('Data', expected, slist)
+
+ def test_HandleDeprecatedDecorator(self):
+ header = textwrap.dedent("""\
+ typedef enum {
+ VAL_DEFAULT,
+ OTHER_VAL,
+ } Data MY_DEPRECATED_FOR(OtherEnum);""")
+ expected = textwrap.dedent("""\
+ <DEPRECATED/>
+ typedef enum {
+ VAL_DEFAULT,
+ OTHER_VAL,
+ } Data;""")
+ self.options.ignore_decorators = 'MY_DEPRECATED_FOR()'
+ slist, doc_comments = self.scanHeaderContent(
+ header.splitlines(keepends=True))
+ self.assertDecl('Data', expected, slist)
+
class ScanHeaderContentFunctions(ScanHeaderContentTestCase):
"""Test parsing of function declarations."""
@@ -364,6 +397,18 @@ class ScanHeaderContentFunctions(ScanHeaderContentTestCase):
header.splitlines(keepends=True))
self.assertDecl('func', 'int', 'int a', slist)
+ @parameterized.expand(INLINE_MODIFIERS)
+ def test_FindsInlineFunctionWithParenthesisName(self, _, modifier):
+ header = textwrap.dedent("""\
+ %s void
+ (func) (void)
+ {
+ }
+ """ % modifier)
+ slist, doc_comments = self.scanHeaderContent(
+ header.splitlines(keepends=True))
+ self.assertDecl('func', 'void', 'void', slist)
+
class ScanHeaderContentMacros(ScanHeaderContentTestCase):
"""Test parsing of macro declarations."""
@@ -480,6 +525,28 @@ class ScanHeaderContentStructs(ScanHeaderContentTestCase):
header.splitlines(keepends=True))
self.assertIn('<TITLE>GtkdocObject</TITLE>', slist)
+ def test_DeprecatedDecorator(self):
+ header = textwrap.dedent("""\
+ typedef struct {
+ int x;
+ } Data MY_DEPRECATED_FOR(OtherStruct);""")
+ expected = textwrap.dedent("""\
+ <DEPRECATED/>
+ typedef struct {
+ int x;
+ } Data;""")
+ self.options.ignore_decorators = 'MY_DEPRECATED_FOR()'
+ slist, doc_comments = self.scanHeaderContent(
+ header.splitlines(keepends=True))
+ self.assertDecl('Data', expected, slist)
+
+ def test_DeprecatedOpaqueStructTypedef(self):
+ header = 'typedef struct _data data MY_DEPRECATED_FOR(OtherData);'
+ expected = '<DEPRECATED/>\n'
+ self.options.ignore_decorators = 'MY_DEPRECATED_FOR()'
+ slist, doc_comments = self.scanHeaderContent([header])
+ self.assertDecl('data', expected, slist)
+
class ScanHeaderContentUnions(ScanHeaderContentTestCase):
"""Test parsing of union declarations."""