Page 1 of 1

[C++] Creating a link to a function inside namespace

Posted: Wed Sep 02 2020 7:08 pm
by kyeast
Hi,
I can't get links to functions inside namespaces to work. Other symbols (classes inside namespaces, global functions) cause no problems. I've read the docs about links (https://www.copperspice.com/docs/doxypress/topic-autolink.html), however I couldn't find there specific examples about namespaces.

I'm using doxypress 1.3.8 and default html output.
Also, with clang parsing enabled no link actually works, but when I disable it, all links work except for the links to functions inside namespaces. This is actually another problem - when clang is enabled the comments are interpreted slightly differently and the html output is a bit different (I can make screenshots if needed).

I've created an example header file to show the problem. There are links inside @file section and inside class section (they are exactly the same). I tried many different forms of links as you can see in the example below.

Code: Select all

#pragma once

/** @file
* Links to member functions:
     
     Project::Module1::Item::method
     
     Project::Module1::Item::method()
     
     ::Project::Module1::Item::method
     
     ::Project::Module1::Item::method()
         
     Project#Module1#Item#method
     
     Project#Module1#Item#method()
     
     #Project#Module1#Item#method
     
     #Project#Module1#Item#method()
     
     * Links to namespace functions:
     
     nameSpaceFunction
     
     nameSpaceFunction()
     
     ::nameSpaceFunction
     
     ::nameSpaceFunction()

     #nameSpaceFunction
     
     #nameSpaceFunction()
     
     Project::Module1::nameSpaceFunction
     
     Project::Module1::nameSpaceFunction()  
     
     ::Project::Module1::nameSpaceFunction
     
     ::Project::Module1::nameSpaceFunction()
     
     Project#Module1#nameSpaceFunction
     
     Project#Module1#nameSpaceFunction()  
     
     #Project#Module1#nameSpaceFunction
     
     #Project#Module1#nameSpaceFunction()
     
     * Links to free functions:
     
     freeFunction
     
     freeFunction()
     
     ::freeFunction
     
     ::freeFunction()
     */
namespace Project::Module1 {
    
    /** @brief Description
     
     * Links to member functions:
     
     Project::Module1::Item::method
     
     Project::Module1::Item::method()
     
     ::Project::Module1::Item::method
     
     ::Project::Module1::Item::method()
         
     Project#Module1#Item#method
     
     Project#Module1#Item#method()
     
     #Project#Module1#Item#method
     
     #Project#Module1#Item#method()
     
     * Links to namespace functions:
     
     nameSpaceFunction
     
     nameSpaceFunction()
     
     ::nameSpaceFunction
     
     ::nameSpaceFunction()

     #nameSpaceFunction
     
     #nameSpaceFunction()
     
     Project::Module1::nameSpaceFunction
     
     Project::Module1::nameSpaceFunction()  
     
     ::Project::Module1::nameSpaceFunction
     
     ::Project::Module1::nameSpaceFunction()
     
     Project#Module1#nameSpaceFunction
     
     Project#Module1#nameSpaceFunction()  
     
     #Project#Module1#nameSpaceFunction
     
     #Project#Module1#nameSpaceFunction()
     
     * Links to free functions:
     
     freeFunction
     
     freeFunction()
     
     ::freeFunction
     
     ::freeFunction()
     
     */
    struct Item {
        /// @brief Description
        Item() {}
        
        /// @brief Description
        ~Item() {}
        
        /// @brief Description
        void method() {}
    };
        
    /// @brief Description
    void nameSpaceFunction() {}
}

/// @brief Description
void freeFunction() {}

So to sum it up there are 2 problems:
1. Links to functions inside namespace doesn't seem to work or I missing something.
2. When clang is enabled the comments are interpreted a bit differently and the html output is slightly different.

Thanks

Re: [C++] Creating a link to a function inside namespace

Posted: Thu Sep 03 2020 11:25 am
by kyeast
OK, so I was trying to find the problem and it seems that the issue is that there must be also available a documentation for "enclosing entity" to make it work. So for free functions without namespaces there must be documenation for the containing file (@file) and for a function inside namespace there must be documentation for that namespace (@namespace).

The problem I see is that the name for the namespace must be provided both in the @namespace directive (e.g. @namespace Project::Submodule1) and in the code which can cause problems when the namespace is renamed. Is there a way to avoid that? Also when parsing with clang the top namespace is removed (e.g. Project::Submodule1 becomes Submodule1) which again breaks the auto links.

Re: [C++] Creating a link to a function inside namespace

Posted: Thu Sep 03 2020 11:45 am
by kyeast
I was thinking about @namespace command issue and it's not clear where namespace documentation should be located as the namespace can possibly be spread across many files. So a separate file for namespace documentation could be a valid solution, of course with the downside of doubling symbol names. Still, different output of clang and lex is a bit confusing.

Re: [C++] Creating a link to a function inside namespace

Posted: Fri Sep 04 2020 10:17 pm
by ansel
Thanks for reporting this. Can you give us a very short test case which shows only the links you expect to work? Also, a copy of the project file that you are using will help us diagnose what is happening.

Re: [C++] Creating a link to a function inside namespace

Posted: Tue Sep 08 2020 11:11 am
by kyeast
Thanks for your reply.

I resolved my issue by adding namespace documentation and the links started to work. I didn't have prior experience with Doxygen so I didn't know about that. Maybe the documentation for \namespace command could contain information that links to symbols in namespaces don't work without first documenting the namespace? Just like \file command documentation does for global symbols. Also auto links documentation (https://www.copperspice.com/docs/doxypress/topic-autolink.html) could contain some namespace examples.

But in general auto links work OK. There is only a small issue with unqualified links without parentheses to functions in namespaces, when used in comments at global scope e.g. with @file command. Using function name alone (e.g. namespaceFunction, #namespaceFunction, ::namespaceFunction) doesn't generate a link but for a global function (e.g. globalFunction, #globalFunction, ::globalFunction) it does.

Also this all assumes that default lex parser is enabled. With clang the top namespace (in this case "Project") is removed altogether and links to namespace items don't work at all, which currently prevents me from enabling clang.

Here is a smallest example I could produce:

Code: Select all

#pragma once

/** @file 

@brief Description of file

@par Undetected links to namespace functions

nameSpaceFunction

::nameSpaceFunction

#nameSpaceFunction

@par Detected links to namespace functions

nameSpaceFunction()

::nameSpaceFunction()

#nameSpaceFunction()

@par Links to global functions (all detected)

globalFunction

::globalFunction

#globalFunction

globalFunction()

::globalFunction()

#globalFunction()
*/

/** @namespace Project::Module1
@brief Description of namespace Project::Module1
*/

namespace Project::Module1 {
    
/// @brief Description of nameSpaceFunction()
void nameSpaceFunction() {}

}

/// @brief Description of globalFunction()
void globalFunction() {}
And the project file (just the default generated by DoxyPressApp):

Code: Select all

{
    "clang": {
        "clang-compilation-path": "",
        "clang-dialect": "-std=c++14",
        "clang-flags": [
            ""
        ],
        "clang-parsing": false,
        "clang-use-headers": true
    },
    "configuration": {
        "allow-sub-grouping": true,
        "allow-unicode-names": false,
        "always-detailed-sec": false,
        "auto-link": true,
        "brief-member-desc": true,
        "built-in-stl-support": false,
        "case-sensitive-fname": true,
        "cpp-cli-support": false,
        "create-subdirs": false,
        "duplicate-docs": false,
        "enabled-sections": [
            ""
        ],
        "extract-all": false,
        "extract-anon-namespaces": false,
        "extract-local-classes": true,
        "extract-local-methods": false,
        "extract-package": false,
        "extract-private": false,
        "extract-static": false,
        "file-version-filter": "",
        "force-local-includes": false,
        "full-path-names": true,
        "generate-bug-list": true,
        "generate-deprecate-list": true,
        "generate-test-list": true,
        "generate-todo-list": true,
        "group-nested-compounds": false,
        "hide-compound-ref": false,
        "hide-friend-compounds": false,
        "hide-in-body-docs": false,
        "hide-navtree-members": false,
        "hide-scope-names": false,
        "hide-undoc-classes": false,
        "hide-undoc-members": false,
        "idl-support": true,
        "inherit-docs": true,
        "inline-grouped-classes": false,
        "inline-info": true,
        "inline-inherited-member": false,
        "inline-simple-struct": false,
        "internal-docs": false,
        "javadoc-auto-brief": false,
        "language-mapping": [
            ""
        ],
        "layout-file": "",
        "main-page-name": "",
        "main-page-omit": false,
        "markdown": true,
        "max-init-lines": 30,
        "multiline-cpp-brief": false,
        "ns-alias": [
            ""
        ],
        "qt-auto-brief": false,
        "repeat-brief": true,
        "separate-member-pages": false,
        "short-names": false,
        "show-file-page": true,
        "show-grouped-members-inc": false,
        "show-include-files": true,
        "show-namespace-page": true,
        "show-used-files": true,
        "sip-support": false,
        "sort-brief-docs": false,
        "sort-by-scope-name": false,
        "sort-class-case-sensitive": false,
        "sort-constructors-first": false,
        "sort-group-names": false,
        "sort-member-docs": true,
        "strict-sig-matching": false,
        "tcl-subst": [
            ""
        ],
        "toc-include-headers": 0,
        "use-typedef-name": false
    },
    "dot": {
        "class-diagrams": true,
        "dia-file-dirs": [
            ""
        ],
        "dia-path": "",
        "directory-graph": true,
        "dot-call": false,
        "dot-called-by": false,
        "dot-class-graph": true,
        "dot-cleanup": true,
        "dot-collaboration": true,
        "dot-file-dirs": [
            ""
        ],
        "dot-font-name": "Helvetica",
        "dot-font-path": "",
        "dot-font-size": 10,
        "dot-graph-max-depth": 0,
        "dot-graph-max-nodes": 50,
        "dot-hierarchy": true,
        "dot-image-format": "png",
        "dot-include": true,
        "dot-included-by": true,
        "dot-multiple-targets": false,
        "dot-num-threads": 0,
        "dot-path": "",
        "dot-transparent": false,
        "generate-legend": true,
        "group-graphs": true,
        "have-dot": false,
        "hide-undoc-relations": true,
        "interactive-svg": false,
        "msc-file-dirs": [
            ""
        ],
        "mscgen-path": "",
        "plantuml-cfg-file": "",
        "plantuml-inc-path": [
            ""
        ],
        "plantuml-jar-path": "",
        "template-relations": false,
        "uml-limit-num-fields": 10,
        "uml-look": false
    },
    "doxypress-format": 1,
    "doxypress-updated": "2018-Jun-30",
    "external": {
        "all-externals": false,
        "external-groups": true,
        "external-pages": true,
        "generate-tagfile": "",
        "perl-path": "/usr/bin/perl",
        "tag-files": [
            ""
        ]
    },
    "general": {
        "abbreviate-brief": [
            "The $name class",
            "The $name widget",
            "The $name file",
            "is",
            "provides",
            "specifies",
            "contains",
            "represents",
            "a",
            "an",
            "the"
        ],
        "aliases": [
            ""
        ],
        "lookup-cache-size": 0,
        "optimize-c": false,
        "optimize-cplus": true,
        "optimize-fortran": false,
        "optimize-java": false,
        "optimize-python": false,
        "output-dir": "",
        "output-language": "English",
        "strip-from-inc-path": [
            ""
        ],
        "strip-from-path": [
            ""
        ],
        "tab-size": 4
    },
    "index": {
        "alpha-index": true,
        "cols-in-index": 5,
        "ignore-prefix": [
            ""
        ]
    },
    "input": {
        "example-patterns": [
            "*"
        ],
        "example-recursive": false,
        "example-source": [
            ""
        ],
        "exclude-files": [
            ""
        ],
        "exclude-patterns": [
            ""
        ],
        "exclude-symbols": [
            ""
        ],
        "exclude-symlinks": false,
        "filter-patterns": [
            ""
        ],
        "filter-program": "",
        "filter-source-files": false,
        "filter-source-patterns": [
            ""
        ],
        "image-path": [
            ""
        ],
        "input-encoding": "UTF-8",
        "input-patterns": [
            "*.as",
            "*.c",
            "*.cc",
            "*.cpp",
            "*.cxx",
            "*.c++",
            "*.cs",
            "*.d",
            "*.ddl",
            "*.dox",
            "*.for",
            "*.f",
            "*.f90",
            "*.h",
            "*.hh",
            "*.hxx",
            "*.hpp",
            "*.h++",
            "*.idl",
            "*.ii",
            "*.ixx",
            "*.ipp",
            "*.i++",
            "*.inc",
            "*.inl",
            "*.java",
            "*.js",
            "*.m",
            "*.md",
            "*.mm",
            "*.markdown",
            "*.odl",
            "*.php",
            "*.php3",
            "*.php4",
            "*.php5",
            "*.phtml",
            "*.py",
            "*.pyw",
            "*.qsf",
            "*.tcl",
            "*.ucf"
        ],
        "input-recursive": false,
        "input-source": [
            ""
        ],
        "mdfile-mainpage": ""
    },
    "messages": {
        "quiet": false,
        "warn-doc-error": true,
        "warn-format": "$file:$line: $text",
        "warn-logfile": "",
        "warn-undoc": true,
        "warn-undoc-param": false,
        "warnings": true
    },
    "output-chm": {
        "binary-toc": false,
        "chm-file": "",
        "chm-index-encoding": "",
        "generate-chi": false,
        "generate-chm": false,
        "hhc-location": "",
        "toc-expanded": false
    },
    "output-docbook": {
        "docbook-output": "docbook",
        "docbook-program-listing": false,
        "generate-docbook": false
    },
    "output-docset": {
        "docset-bundle-id": "org.doxypress.Project",
        "docset-feedname": "DoxyPress generated docs",
        "docset-publisher-id": "org.doxypress.Publisher",
        "docset-publisher-name": "Publisher",
        "generate-docset": false
    },
    "output-eclipse": {
        "eclipse-doc-id": "org.doxypress.Project",
        "generate-eclipse": false
    },
    "output-html": {
        "disable-index": false,
        "enum-values-per-line": 4,
        "external-links-in-window": false,
        "formula-fontsize": 10,
        "formula-transparent": true,
        "generate-html": true,
        "generate-treeview": false,
        "ghostscript": "",
        "html-colorstyle-gamma": 80,
        "html-colorstyle-hue": 220,
        "html-colorstyle-sat": 100,
        "html-dynamic-sections": false,
        "html-extra-files": [
            ""
        ],
        "html-file-extension": ".html",
        "html-footer": "",
        "html-header": "",
        "html-index-num-entries": 100,
        "html-output": "html",
        "html-search": false,
        "html-stylesheets": [
            ""
        ],
        "html-timestamp": true,
        "mathjax-codefile": "",
        "mathjax-extensions": [
            ""
        ],
        "mathjax-format": "HTML-CSS",
        "mathjax-relpath": "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/",
        "search-data-file": "searchdata.xml",
        "search-external": false,
        "search-external-id": "",
        "search-external-url": "",
        "search-mappings": [
            ""
        ],
        "search-server-based": false,
        "treeview-width": 250,
        "use-mathjax": false
    },
    "output-latex": {
        "cite-bib-files": [
            ""
        ],
        "generate-latex": false,
        "latex-batch-mode": false,
        "latex-bib-style": "plain",
        "latex-cmd-name": "latex",
        "latex-compact": false,
        "latex-extra-files": [
            ""
        ],
        "latex-extra-packages": [
            ""
        ],
        "latex-footer": "",
        "latex-header": "",
        "latex-hide-indices": false,
        "latex-hyper-pdf": true,
        "latex-output": "latex",
        "latex-paper-type": "a4",
        "latex-pdf": true,
        "latex-ps": true,
        "latex-source-code": false,
        "latex-stylesheets": [
            ""
        ],
        "latex-timestamp": false,
        "make-index-cmd-name": "makeindex"
    },
    "output-man": {
        "generate-man": false,
        "man-extension": ".3",
        "man-links": false,
        "man-output": "man",
        "man-subdir": ""
    },
    "output-perl": {
        "generate-perl": false,
        "perl-latex": false,
        "perl-prefix": "",
        "perl-pretty": true
    },
    "output-qhelp": {
        "generate-qthelp": false,
        "qch-file": "",
        "qhp-cust-attrib": [
            ""
        ],
        "qhp-cust-filter-name": "",
        "qhp-namespace": "org.doxypress.Project",
        "qhp-sect-attrib": [
            ""
        ],
        "qhp-virtual-folder": "doc",
        "qthelp-gen-path": ""
    },
    "output-rtf": {
        "generate-rtf": false,
        "rtf-compact": false,
        "rtf-extension": "",
        "rtf-hyperlinks": false,
        "rtf-output": "rtf",
        "rtf-paper-type": "a4",
        "rtf-source-code": false,
        "rtf-stylesheet": ""
    },
    "output-xml": {
        "generate-xml": false,
        "xml-output": "xml",
        "xml-program-listing": true
    },
    "preprocessor": {
        "enable-preprocessing": true,
        "expand-as-defined": [
            ""
        ],
        "expand-only-predefined": false,
        "include-path": [
            ""
        ],
        "include-patterns": [
            ""
        ],
        "macro-expansion": false,
        "predefined-macros": [
            ""
        ],
        "search-includes": true,
        "skip-function-macros": true
    },
    "project": {
        "project-brief": "",
        "project-logo": "",
        "project-name": "My Project",
        "project-version": ""
    },
    "source": {
        "inline-source": false,
        "ref-by-relation": false,
        "ref-link-source": true,
        "ref-relation": false,
        "source-code": false,
        "source-tooltips": true,
        "strip-code-comments": true,
        "suffix-exclude-navtree": [
            "doc",
            "dox",
            "md",
            "markdown",
            "txt"
        ],
        "suffix-header-navtree": [
            "h",
            "hh",
            "hxx",
            "hpp",
            "h++",
            "idl",
            "ddl",
            "pidl"
        ],
        "suffix-source-navtree": [
            "c",
            "cc",
            "cxx",
            "cpp",
            "c++",
            "ii",
            "ixx",
            "ipp",
            "i++",
            "inl",
            "java",
            "m",
            "mm",
            "xml"
        ],
        "use-htags": false,
        "verbatim-headers": true
    }
}

And generated html output:
https://postimg.cc/jCf3Phd1