chiark / gitweb /
doxygen: parse function attributes also without leading space.
authorVladimír Vondruš <mosra@centrum.cz>
Fri, 22 Feb 2019 23:23:43 +0000 (00:23 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Sat, 23 Feb 2019 00:10:00 +0000 (01:10 +0100)
doxygen/dox2html5.py
doxygen/test/cpp_function_attributes_nospace/Doxyfile [new file with mode: 0644]
doxygen/test/cpp_function_attributes_nospace/input.h [new file with mode: 0644]
doxygen/test/cpp_function_attributes_nospace/structFoo.html [new file with mode: 0644]
doxygen/test/test_cpp.py

index 804d95fa00c0d935f5334641fc271e43430a4bee..20917dd8ba8476933c04efb233849b90d31a2fad 100755 (executable)
@@ -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 (file)
index 0000000..ee1cb76
--- /dev/null
@@ -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 (file)
index 0000000..a3ab3cb
--- /dev/null
@@ -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 (file)
index 0000000..6d465c0
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Foo struct | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+doxygen.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          Foo <span class="m-thin">struct</span>
+        </h1>
+        <p>Keywords without spaces.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#base-classes">Base classes</a></li>
+                <li><a href="#pub-methods">Public functions</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="base-classes">
+          <h2><a href="#base-classes">Base classes</a></h2>
+          <dl class="m-dox">
+            <dt>
+              class <a href="classBase.html" class="m-dox">Base</a>
+            </dt>
+            <dd>Base class.</dd>
+          </dl>
+        </section>
+        <section id="pub-methods">
+          <h2><a href="#pub-methods">Public functions</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#ae23bc23eb33a7d7a77e2610a9661c078" class="m-dox-self" name="ae23bc23eb33a7d7a77e2610a9661c078">doThing</a>(</span><span class="m-dox-wrap">) &amp;&amp; <span class="m-label m-flat m-warning">final</span> <span class="m-label m-flat m-success">noexcept</span></span>
+            </dt>
+            <dd>Final w/o override (will cause a compiler warning), w/o a space.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a13f62f7c5cb7e663de9e5dc51219ce68" class="m-dox-self" name="a13f62f7c5cb7e663de9e5dc51219ce68">doMoreStuff</a>(</span><span class="m-dox-wrap">) &amp;&amp; <span class="m-label m-flat m-success">noexcept(…)</span></span>
+            </dt>
+            <dd>Do more things, without a space.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a1a47d2d7ced7b4e05c6e09d828f4e6eb" class="m-dox-self" name="a1a47d2d7ced7b4e05c6e09d828f4e6eb">doAnotherThing</a>(</span><span class="m-dox-wrap">) &amp;&amp; <span class="m-label m-flat m-warning">final</span></span>
+            </dt>
+            <dd>Final override, without a space.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a32e5414e9916365aa2c041da60572a1b" class="m-dox-self" name="a32e5414e9916365aa2c041da60572a1b">doYetAnotherThing</a>(</span><span class="m-dox-wrap">) &amp;&amp; <span class="m-label m-flat m-warning">final</span></span>
+            </dt>
+            <dd>Override final, without a space.</dd>
+          </dl>
+        </section>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index e8bdb5f218c3255e91dc9405a561f315c6fa5004..a764dd1e7121b2c465ae54dfbc5abca196079d84 100644 (file)
@@ -101,3 +101,11 @@ class FunctionAttributes(IntegrationTestCase):
         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'))