Fix parsing macros with only a variadic argument Function-like macros with only a variadic argument (e.g. MACRO(...)) were not parsed correctly, so linking to them would fail. Change-Id: I1126f76473d82b717629f70d0d82245ce46dae86 Reviewed-on: https://pigweed-review.googlesource.com/c/third_party/github/sphinx-contrib/doxylink/+/386618
diff --git a/sphinxcontrib/doxylink/parsing.py b/sphinxcontrib/doxylink/parsing.py index ee6e848..4cafcc0 100644 --- a/sphinxcontrib/doxylink/parsing.py +++ b/sphinxcontrib/doxylink/parsing.py
@@ -2,7 +2,7 @@ from pyparsing import Word, Literal, nums, alphanums, OneOrMore, Opt, \ SkipTo, ParseException, Group, Combine, delimitedList, quotedString, \ - nestedExpr, ParseResults, oneOf, ungroup, Keyword, ZeroOrMore + nestedExpr, ParseResults, oneOf, ungroup, Keyword, ZeroOrMore, Empty, replaceWith # define punctuation - reuse of expressions helps packratting work better LPAR, RPAR, LBRACK, RBRACK, LCBRACK, RCBRACK, COMMA, EQ = map(Literal, "()[]{},=") @@ -56,8 +56,10 @@ default_value = Literal('=') + OneOrMore(number | quotedString | input_type | parentheses_pair | angle_bracket_pair | square_bracket_pair | curly_bracket_pair | Word('|&^')) # A combination building up the interesting bit -- the argument type, e.g. 'const QString &', 'int' or 'char*' -argument_type = Opt(qualifier, default='')("qualifier1") + \ - input_type("input_type").setParseAction(' '.join) + \ +argument_type_prefix = (qualifier("qualifier1") + input_type("input_type").setParseAction(' '.join)) | \ + (Empty().setParseAction(replaceWith(''))("qualifier1") + input_type("input_type").setParseAction(' '.join)) + +argument_type = argument_type_prefix + \ Opt(qualifier, default='')("qualifier2") + \ Group(ZeroOrMore(pointer_or_reference))("pointer_or_references") + \ Opt('...')("parameter_pack") @@ -66,7 +68,7 @@ argument = Group(argument_type('argument_type') + Opt(input_name) + Opt(default_value)) # List of arguments in parentheses with an optional 'const' on the end -arglist = LPAR + delimitedList(argument)('arg_list') + Opt(COMMA + '...')('var_args') + RPAR +arglist = LPAR + Opt(delimitedList(argument)('arg_list')) + Opt(COMMA) + Opt('...')('var_args') + RPAR def normalise(symbol: str) -> Tuple[str, str]:
diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 27fdde9..fe511af 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py
@@ -65,10 +65,20 @@ /// Simple macro. #define SIMPLE_MACRO 42 -/// A function-like macro. -#define FUNCTION_LIKE_MACRO(int x, int y); +/// Function-like macro. +#define FUNCTION_LIKE_MACRO_1(x) +/// Function-like macro. +#define FUNCTION_LIKE_MACRO_2(x, y); +/// Variadic macro. +#define VARIADIC_FUNCTION_LIKE_MACRO_1(...) + +/// Variadic macro. +#define VARIADIC_FUNCTION_LIKE_MACRO_2(x, ...) + +/// Macro with a keyword as its parameter. +#define MACRO_WITH_KEYWORD_PARAM(enum) """ _CXX_NAMES = ( @@ -87,7 +97,11 @@ ("secondary", "TestFunction"), ("secondary", "ambiguous_var"), (None, "SIMPLE_MACRO"), - (None, "FUNCTION_LIKE_MACRO"), + (None, "FUNCTION_LIKE_MACRO_1"), + (None, "FUNCTION_LIKE_MACRO_2"), + (None, "VARIADIC_FUNCTION_LIKE_MACRO_1"), + (None, "VARIADIC_FUNCTION_LIKE_MACRO_2"), + (None, "MACRO_WITH_KEYWORD_PARAM"), ) # Assert that all names above are present in _CXX_SOURCE
diff --git a/tests/test_parser.py b/tests/test_parser.py index 5838301..985b4ac 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py
@@ -7,6 +7,8 @@ # List of tuples of: (input, correct output) # Input is a string, output is a tuple. arglists = [ + ('(enum)', ('', '(enum)')), + ('(const)', ('', '(const)')), ('( QUrl source )', ('', '(QUrl)')), ('( QUrl * source )', ('', '(QUrl*)')), ('( QUrl ** source )', ('', '(QUrl**)')), @@ -62,6 +64,8 @@ ('fprintf( std::FILE* stream, const char* format, ... )', ('fprintf', '(std::FILE*, const char*, ...)')), ('sprintf( char* buffer, const char* format, ... )', ('sprintf', '(char*, const char*, ...)')), ('snprintf( char* buffer, std::size_t buf_size, const char* format, ... )', ('snprintf', '(char*, std::size_t, const char*, ...)')), + ('MACRO(...)', ('MACRO', '(...)')), + ('(...)', ('', '(...)')), ] multiple_qualifiers = [