From 38e0d6230473aa2be8b2f30ff374f52ee4ab5ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 23 Feb 2019 00:23:43 +0100 Subject: [PATCH] doxygen: parse function attributes also without leading space. --- doxygen/dox2html5.py | 22 +++--- .../cpp_function_attributes_nospace/Doxyfile | 14 ++++ .../cpp_function_attributes_nospace/input.h | 21 ++++++ .../structFoo.html | 73 +++++++++++++++++++ doxygen/test/test_cpp.py | 8 ++ 5 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 doxygen/test/cpp_function_attributes_nospace/Doxyfile create mode 100644 doxygen/test/cpp_function_attributes_nospace/input.h create mode 100644 doxygen/test/cpp_function_attributes_nospace/structFoo.html diff --git a/doxygen/dox2html5.py b/doxygen/dox2html5.py index 804d95fa..20917dd8 100755 --- a/doxygen/dox2html5.py +++ b/doxygen/dox2html5.py @@ -1839,6 +1839,8 @@ def parse_func(state: State, element: ET.Element): if func.type.startswith('friend '): func.type = func.type[7:] + def is_identifier(a): return a == '_' or a.isalnum() + # Extract function signature to prefix, suffix and various flags. Important # things affecting caller such as static or const (and rvalue overloads) # are put into signature prefix/suffix, other things to various is_* @@ -1882,24 +1884,24 @@ def parse_func(state: State, element: ET.Element): func.is_pure_virtual = False # Final tested twice because it can be both `override final` func.is_final = False - if signature.endswith(' final'): - signature = signature[:-6] + if signature.endswith('final') and not is_identifier(signature[-6]): + signature = signature[:-5].rstrip() func.is_final = True - if signature.endswith(' override'): - signature = signature[:-9] + if signature.endswith('override') and not is_identifier(signature[-9]): + signature = signature[:-8].rstrip() func.is_override = True else: func.is_override = False # ... and `final override` - if signature.endswith(' final'): - signature = signature[:-6] + if signature.endswith('final') and not is_identifier(signature[-6]): + signature = signature[:-5].rstrip() func.is_final = True - if signature.endswith(' noexcept'): - signature = signature[:-9] + if signature.endswith('noexcept') and not is_identifier(signature[-9]): + signature = signature[:-8].rstrip() func.is_noexcept = True func.is_conditional_noexcept = False - elif ' noexcept(' in signature: - signature = signature[:signature.index(' noexcept(')] + elif 'noexcept(' in signature and not is_identifier(signature[signature.index('noexcept(') - 1]): + signature = signature[:signature.index('noexcept(')].rstrip() func.is_noexcept = True func.is_conditional_noexcept = True else: diff --git a/doxygen/test/cpp_function_attributes_nospace/Doxyfile b/doxygen/test/cpp_function_attributes_nospace/Doxyfile new file mode 100644 index 00000000..ee1cb763 --- /dev/null +++ b/doxygen/test/cpp_function_attributes_nospace/Doxyfile @@ -0,0 +1,14 @@ +INPUT = input.h +AUTOLINK_SUPPORT = NO +QUIET = YES +GENERATE_HTML = NO +GENERATE_LATEX = NO +GENERATE_XML = YES +XML_PROGRAMLISTING = NO + +##! M_PAGE_FINE_PRINT = +##! M_THEME_COLOR = +##! M_FAVICON = +##! M_LINKS_NAVBAR1 = +##! M_LINKS_NAVBAR2 = +##! M_SEARCH_DISABLED = YES diff --git a/doxygen/test/cpp_function_attributes_nospace/input.h b/doxygen/test/cpp_function_attributes_nospace/input.h new file mode 100644 index 00000000..a3ab3cb1 --- /dev/null +++ b/doxygen/test/cpp_function_attributes_nospace/input.h @@ -0,0 +1,21 @@ +/** @brief Base class */ +class Base { + virtual void doThing()noexcept; + virtual void doAnotherThing(); + virtual void doYetAnotherThing(); +}; + +/** @brief Keywords without spaces */ +struct Foo: Base { + /** @brief Final w/o override (will cause a compiler warning), w/o a space */ + void doThing() &&noexcept final; + + /** @brief Do more things, without a space */ + void doMoreStuff() &&noexcept(false); + + /** @brief Final override, without a space */ + void doAnotherThing() &&final override; + + /** @brief Override final, without a space */ + void doYetAnotherThing() &&override final; +}; diff --git a/doxygen/test/cpp_function_attributes_nospace/structFoo.html b/doxygen/test/cpp_function_attributes_nospace/structFoo.html new file mode 100644 index 00000000..6d465c05 --- /dev/null +++ b/doxygen/test/cpp_function_attributes_nospace/structFoo.html @@ -0,0 +1,73 @@ + + + + + Foo struct | My Project + + + + + +
+
+
+
+
+

+ Foo struct +

+

Keywords without spaces.

+
+

Contents

+ +
+
+

Base classes

+
+
+ class Base +
+
Base class.
+
+
+
+

Public functions

+
+
+ void doThing() && final noexcept +
+
Final w/o override (will cause a compiler warning), w/o a space.
+
+ void doMoreStuff() && noexcept(…) +
+
Do more things, without a space.
+
+ void doAnotherThing() && final +
+
Final override, without a space.
+
+ void doYetAnotherThing() && final +
+
Override final, without a space.
+
+
+
+
+
+
+ + diff --git a/doxygen/test/test_cpp.py b/doxygen/test/test_cpp.py index e8bdb5f2..a764dd1e 100644 --- a/doxygen/test/test_cpp.py +++ b/doxygen/test/test_cpp.py @@ -101,3 +101,11 @@ def test(self): self.assertEqual(*self.actual_expected_contents('classBase.html')) self.assertEqual(*self.actual_expected_contents('classDerived.html')) self.assertEqual(*self.actual_expected_contents('structFinal.html')) + +class FunctionAttributesNospace(IntegrationTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'function_attributes_nospace', *args, **kwargs) + + def test(self): + self.run_dox2html5(wildcard='structFoo.xml') + self.assertEqual(*self.actual_expected_contents('structFoo.html'))