File 040cdc3acd4d417df447199eefb4af08fbbe6907.patch of Package doxygen

From 040cdc3acd4d417df447199eefb4af08fbbe6907 Mon Sep 17 00:00:00 2001
From: Dimitri van Heesch <doxygen@gmail.com>
Date: Fri, 20 Sep 2024 21:10:32 +0200
Subject: [PATCH] issue #11138 Non-reproducible file names in doxygen output

---
 src/doxygen.cpp                               | 17 +++++++-------
 src/namespacedef.cpp                          |  4 ++++
 src/scanner.l                                 | 22 ++++++++++---------
 src/sitemap.cpp                               | 12 +++++-----
 src/util.cpp                                  | 21 ++++++++++++++++++
 src/util.h                                    |  2 ++
 src/xmlgen.cpp                                |  4 ++--
 ...6227335362355006121037335073327177063.xml} | 10 ++++-----
 testing/071_enum_in_anon_ns.cpp               |  2 +-
 testing/073/073__typed__enum_8cpp.xml         |  8 +++----
 10 files changed, 67 insertions(+), 35 deletions(-)
 rename testing/071/{namespace_a_namespace_1_1_0d0.xml => namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063.xml} (62%)

Index: doxygen-1.12.0/src/doxygen.cpp
===================================================================
--- doxygen-1.12.0.orig/src/doxygen.cpp
+++ doxygen-1.12.0/src/doxygen.cpp
@@ -1544,6 +1544,7 @@ static void processTagLessClasses(const
     MemberList *ml = cd->getMemberList(MemberListType::PubAttribs());
     if (ml)
     {
+      int pos=0;
       for (const auto &md : *ml)
       {
         QCString type = md->typeString();
@@ -1556,7 +1557,7 @@ static void processTagLessClasses(const
             if (type.find(icd->name())!=-1) // matching tag less struct/union
             {
               QCString name = md->name();
-              if (md->isAnonymous()) name = "__unnamed" + name.right(name.length()-1)+"__";
+              if (md->isAnonymous()) name = "__unnamed" + QCString().setNum(pos++)+"__";
               if (!prefix.isEmpty()) name.prepend(prefix+".");
               //printf("    found %s for class %s\n",qPrint(name),qPrint(cd->name()));
               ClassDefMutable *ncd = createTagLessInstance(rootCd,icd,name);
@@ -8627,7 +8628,7 @@ static void generateDocsForClassList(con
         auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
         auto processFile = [ctx]()
         {
-          msg("Generating docs for compound %s...\n",qPrint(ctx->cd->name()));
+          msg("Generating docs for compound %s...\n",qPrint(ctx->cd->displayName()));
 
           // skip external references, anonymous compounds and
           // template instances
@@ -8665,7 +8666,7 @@ static void generateDocsForClassList(con
         if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
               cd->isLinkableInProject() && cd->templateMaster()==nullptr)
         {
-          msg("Generating docs for compound %s...\n",qPrint(cd->name()));
+          msg("Generating docs for compound %s...\n",qPrint(cd->displayName()));
 
           cd->writeDocumentation(*g_outputList);
           cd->writeMemberList(*g_outputList);
@@ -8733,7 +8734,7 @@ static void generateConceptDocs()
         ) && !cd->isHidden() && cd->isLinkableInProject()
        )
     {
-      msg("Generating docs for concept %s...\n",qPrint(cd->name()));
+      msg("Generating docs for concept %s...\n",qPrint(cd->displayName()));
       cd->writeDocumentation(*g_outputList);
     }
   }
@@ -9702,7 +9703,7 @@ static void generateNamespaceClassDocs(c
               && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
              )
           {
-            msg("Generating docs for compound %s...\n",qPrint(ctx->cdm->name()));
+            msg("Generating docs for compound %s...\n",qPrint(ctx->cdm->displayName()));
             ctx->cdm->writeDocumentation(ctx->ol);
             ctx->cdm->writeMemberList(ctx->ol);
           }
@@ -9733,7 +9734,7 @@ static void generateNamespaceClassDocs(c
             && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
            )
         {
-          msg("Generating docs for compound %s...\n",qPrint(cd->name()));
+          msg("Generating docs for compound %s...\n",qPrint(cd->displayName()));
 
           cdm->writeDocumentation(*g_outputList);
           cdm->writeMemberList(*g_outputList);
@@ -9772,7 +9773,7 @@ static void generateNamespaceDocs()
       NamespaceDefMutable *ndm = toNamespaceDefMutable(nd.get());
       if (ndm)
       {
-        msg("Generating docs for namespace %s\n",qPrint(nd->name()));
+        msg("Generating docs for namespace %s\n",qPrint(nd->displayName()));
         ndm->writeDocumentation(*g_outputList);
       }
     }
Index: doxygen-1.12.0/src/namespacedef.cpp
===================================================================
--- doxygen-1.12.0.orig/src/namespacedef.cpp
+++ doxygen-1.12.0/src/namespacedef.cpp
@@ -44,6 +44,10 @@ static QCString makeDisplayName(const Na
   {
     result = substitute(result,"::",sep);
   }
+  if (nd->isAnonymous())
+  {
+    result = removeAnonymousScopes(result);
+  }
   //printf("makeDisplayName() %s->%s lang=%d\n",qPrint(name()),qPrint(result),lang);
   return result;
 }
Index: doxygen-1.12.0/src/scanner.l
===================================================================
--- doxygen-1.12.0.orig/src/scanner.l
+++ doxygen-1.12.0/src/scanner.l
@@ -33,7 +33,6 @@ typedef yyguts_t *yyscan_t;
 #include <algorithm>
 #include <vector>
 #include <utility>
-#include <atomic>
 #include <cstdint>
 #include <cstdio>
 #include <cstdlib>
@@ -61,9 +60,6 @@ typedef yyguts_t *yyscan_t;
 #define YY_NO_INPUT 1
 #define YY_NO_UNISTD_H 1
 
-static AtomicInt  anonCount;
-static AtomicInt  anonNSCount;
-
 struct scannerYY_state
 {
   OutlineParserInterface *thisParser;
@@ -213,6 +209,9 @@ struct scannerYY_state
 
   int              fakeNS  = 0; //<! number of file scoped namespaces in CSharp file
   TextStream       dummyTextStream;
+
+  int              anonCount = 0;
+  int              anonNSCount = 0;
 };
 
 [[maybe_unused]] static const char *stateToString(int state);
@@ -247,6 +246,7 @@ static void storeClangId(yyscan_t yyscan
 static void startVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize=0);
 static bool endVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize=0);
 
+
 /* ----------------------------------------------------------------- */
 #undef  YY_INPUT
 #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
@@ -4320,7 +4320,7 @@ NONLopt [^\n]*
                                           BEGIN(MemberSpecSkip);
                                         }
 <TypedefName>";"                        { /* typedef of anonymous type */
-                                          yyextra->current->name.sprintf("@%d",anonCount++);
+                                          yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
                                           if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
                                           {
                                             yyextra->current->program << ','; // add field terminator
@@ -4395,7 +4395,7 @@ NONLopt [^\n]*
                                                 {
                                                   // anonymous compound yyextra->inside -> insert dummy variable name
                                                   //printf("Adding anonymous variable for scope %s\n",qPrint(p->name));
-                                                  yyextra->msName.sprintf("@%d",anonCount++);
+                                                  yyextra->msName = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
                                                   break;
                                                 }
                                               }
@@ -6305,12 +6305,12 @@ NONLopt [^\n]*
                                               }
                                               else // use invisible name
                                               {
-                                                yyextra->current->name.sprintf("@%d",anonNSCount.load());
+                                                yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonNSCount);
                                               }
                                             }
                                             else
                                             {
-                                              yyextra->current->name.sprintf("@%d",anonCount++);
+                                              yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
                                             }
                                           }
                                           yyextra->curlyCount=0;
@@ -7812,7 +7812,6 @@ static void addKnRArgInfo(yyscan_t yysca
 
 //-----------------------------------------------------------------------------
 
-
 void fixArgumentListForJavaScript(ArgumentList &al)
 {
   for (Argument &a : al)
@@ -7825,6 +7824,7 @@ void fixArgumentListForJavaScript(Argume
   }
 }
 
+//-----------------------------------------------------------------------------
 
 static void startCommentBlock(yyscan_t yyscanner,bool brief)
 {
@@ -8134,6 +8134,8 @@ static void parseMain(yyscan_t yyscanner
   yyextra->yyLineNr      = 1 ;
   yyextra->yyBegLineNr   = 1;
   yyextra->yyBegColNr    = 0;
+  yyextra->anonCount     = 0;
+  yyextra->anonNSCount   = 0;
   yyextra->fileName = fileName;
   yyextra->clangParser = clangParser;
   setContext(yyscanner);
@@ -8188,7 +8190,7 @@ static void parseMain(yyscan_t yyscanner
 
   parseCompounds(yyscanner,rt);
 
-  anonNSCount++;
+  yyextra->anonNSCount++;
 
   // add additional entries that were created during processing
   for (auto &[parent,child]: yyextra->outerScopeEntries)
Index: doxygen-1.12.0/src/sitemap.cpp
===================================================================
--- doxygen-1.12.0.orig/src/sitemap.cpp
+++ doxygen-1.12.0/src/sitemap.cpp
@@ -86,7 +86,7 @@ class Crawlmap::Private
   public:
     std::ofstream crawlFile;
     TextStream crawl;
-    StringSet crawlLinks;
+    StringVector crawlLinks;
 };
 
 Crawlmap::Crawlmap() : p(std::make_unique<Private>()) {}
@@ -117,6 +117,8 @@ void Crawlmap::initialize()
 
 void Crawlmap::finalize()
 {
+  std::sort(p->crawlLinks.begin(),p->crawlLinks.end());
+  p->crawlLinks.erase(std::unique(p->crawlLinks.begin(),p->crawlLinks.end()),p->crawlLinks.end());
   for (auto &s : p->crawlLinks)
   {
     p->crawl << "<a href=\"" << s << "\"/>\n";
@@ -132,7 +134,7 @@ void Crawlmap::addIndexFile(const QCStri
 {
   QCString fn = fileName;
   addHtmlExtensionIfMissing(fn);
-  p->crawl << "<a href=\"" << fn << "\"/>\n";
+  p->crawlLinks.push_back(fn.str());
 }
 
 void Crawlmap::addContentsItem(bool, const QCString &, const QCString & ref,
@@ -161,7 +163,7 @@ void Crawlmap::addContentsItem(bool, con
         link += currAnc.str();
       }
     }
-    p->crawlLinks.insert(link);
+    p->crawlLinks.push_back(link);
   }
 }
 
@@ -211,12 +213,12 @@ void Crawlmap::addIndexItem(const Defini
     QCString ref;
 
     ref = makeRef(contRef, anchor);
-    p->crawlLinks.insert(ref.str());
+    p->crawlLinks.push_back(ref.str());
   }
   else if (context) // container
   {
     QCString contRef = context->getOutputFileBase();
     QCString ref = makeRef(contRef,sectionAnchor);
-    p->crawlLinks.insert(ref.str());
+    p->crawlLinks.push_back(ref.str());
   }
 }
Index: doxygen-1.12.0/src/util.cpp
===================================================================
--- doxygen-1.12.0.orig/src/util.cpp
+++ doxygen-1.12.0/src/util.cpp
@@ -3869,6 +3869,27 @@ QCString convertNameToFile(const QCStrin
   return result;
 }
 
+QCString generateAnonymousAnchor(const QCString &fileName,int count)
+{
+  QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
+  const int sig_size=16;
+  uint8_t md5_sig[sig_size];
+  MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
+  char result[sig_size*3+2];
+  char *p = result;
+  *p++='@';
+  for (int i=0;i<sig_size;i++)
+  {
+    static const char oct[]="01234567";
+    uint8_t byte = md5_sig[i];
+    *p++=oct[(byte>>6)&7];
+    *p++=oct[(byte>>3)&7];
+    *p++=oct[(byte>>0)&7];
+  }
+  *p='\0';
+  return result;
+}
+
 QCString relativePathToRoot(const QCString &name)
 {
   QCString result;
Index: doxygen-1.12.0/src/util.h
===================================================================
--- doxygen-1.12.0.orig/src/util.h
+++ doxygen-1.12.0/src/util.h
@@ -253,6 +253,8 @@ QCString replaceAnonymousScopes(const QC
 
 QCString convertNameToFile(const QCString &name,bool allowDots=FALSE,bool allowUnderscore=FALSE);
 
+QCString generateAnonymousAnchor(const QCString &fileName,int count);
+
 void extractNamespaceName(const QCString &scopeName,
                           QCString &className,QCString &namespaceName,
                           bool allowEmptyClass=FALSE);
Index: doxygen-1.12.0/src/xmlgen.cpp
===================================================================
--- doxygen-1.12.0.orig/src/xmlgen.cpp
+++ doxygen-1.12.0/src/xmlgen.cpp
@@ -2243,12 +2243,12 @@ void generateXML()
     }
     for (const auto &cd : *Doxygen::conceptLinkedMap)
     {
-      msg("Generating XML output for concept %s\n",qPrint(cd->name()));
+      msg("Generating XML output for concept %s\n",qPrint(cd->displayName()));
       generateXMLForConcept(cd.get(),t);
     }
     for (const auto &nd : *Doxygen::namespaceLinkedMap)
     {
-      msg("Generating XML output for namespace %s\n",qPrint(nd->name()));
+      msg("Generating XML output for namespace %s\n",qPrint(nd->displayName()));
       generateXMLForNamespace(nd.get(),t);
     }
     for (const auto &fn : *Doxygen::inputNameLinkedMap)
Index: doxygen-1.12.0/testing/071/namespace_a_namespace_1_1_0d0.xml
===================================================================
--- doxygen-1.12.0.orig/testing/071/namespace_a_namespace_1_1_0d0.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
-  <compounddef id="namespace_a_namespace_1_1_0d0" kind="namespace" language="C++">
-    <compoundname>ANamespace</compoundname>
-    <sectiondef kind="enum">
-      <memberdef kind="enum" id="namespace_a_namespace_1_1_0d0_1a96ab6574751fdf6a53ceec8a3896c45d" prot="public" static="no" strong="yes">
-        <type/>
-        <name>Boolean</name>
-        <qualifiedname>ANamespace::Boolean</qualifiedname>
-        <enumvalue id="namespace_a_namespace_1_1_0d0_1a96ab6574751fdf6a53ceec8a3896c45daf8320b26d30ab433c5a54546d21f414c" prot="public">
-          <name>False</name>
-          <briefdescription>
-          </briefdescription>
-          <detaileddescription>
-          </detaileddescription>
-        </enumvalue>
-        <enumvalue id="namespace_a_namespace_1_1_0d0_1a96ab6574751fdf6a53ceec8a3896c45daf827cf462f62848df37c5e1e94a4da74" prot="public">
-          <name>True</name>
-          <briefdescription>
-          </briefdescription>
-          <detaileddescription>
-          </detaileddescription>
-        </enumvalue>
-        <enumvalue id="namespace_a_namespace_1_1_0d0_1a96ab6574751fdf6a53ceec8a3896c45da2767828026039e8ba7b38973cbb701f2" prot="public">
-          <name>FileNotFound</name>
-          <briefdescription>
-          </briefdescription>
-          <detaileddescription>
-          </detaileddescription>
-        </enumvalue>
-        <briefdescription>
-        </briefdescription>
-        <detaileddescription>
-        </detaileddescription>
-        <inbodydescription>
-        </inbodydescription>
-        <location file="071_enum_in_anon_ns.cpp" line="6" column="1" bodyfile="071_enum_in_anon_ns.cpp" bodystart="6" bodyend="10"/>
-      </memberdef>
-    </sectiondef>
-    <briefdescription>
-    </briefdescription>
-    <detaileddescription>
-    </detaileddescription>
-    <location file="071_enum_in_anon_ns.cpp" line="4" column="20"/>
-  </compounddef>
-</doxygen>
Index: doxygen-1.12.0/testing/071/namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063.xml
===================================================================
--- /dev/null
+++ doxygen-1.12.0/testing/071/namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
+  <compounddef id="namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063" kind="namespace" language="C++">
+    <compoundname>ANamespace</compoundname>
+    <sectiondef kind="enum">
+      <memberdef kind="enum" id="namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063_1a80c23b2c34d4baaf4e21819ff9c3dcd6" prot="public" static="no" strong="yes">
+        <type/>
+        <name>Boolean</name>
+        <qualifiedname>ANamespace::Boolean</qualifiedname>
+        <enumvalue id="namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063_1a80c23b2c34d4baaf4e21819ff9c3dcd6af8320b26d30ab433c5a54546d21f414c" prot="public">
+          <name>False</name>
+          <briefdescription>
+          </briefdescription>
+          <detaileddescription>
+          </detaileddescription>
+        </enumvalue>
+        <enumvalue id="namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063_1a80c23b2c34d4baaf4e21819ff9c3dcd6af827cf462f62848df37c5e1e94a4da74" prot="public">
+          <name>True</name>
+          <briefdescription>
+          </briefdescription>
+          <detaileddescription>
+          </detaileddescription>
+        </enumvalue>
+        <enumvalue id="namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063_1a80c23b2c34d4baaf4e21819ff9c3dcd6a2767828026039e8ba7b38973cbb701f2" prot="public">
+          <name>FileNotFound</name>
+          <briefdescription>
+          </briefdescription>
+          <detaileddescription>
+          </detaileddescription>
+        </enumvalue>
+        <briefdescription>
+        </briefdescription>
+        <detaileddescription>
+        </detaileddescription>
+        <inbodydescription>
+        </inbodydescription>
+        <location file="071_enum_in_anon_ns.cpp" line="6" column="1" bodyfile="071_enum_in_anon_ns.cpp" bodystart="6" bodyend="10"/>
+      </memberdef>
+    </sectiondef>
+    <briefdescription>
+    </briefdescription>
+    <detaileddescription>
+    </detaileddescription>
+    <location file="071_enum_in_anon_ns.cpp" line="4" column="20"/>
+  </compounddef>
+</doxygen>
Index: doxygen-1.12.0/testing/071_enum_in_anon_ns.cpp
===================================================================
--- doxygen-1.12.0.orig/testing/071_enum_in_anon_ns.cpp
+++ doxygen-1.12.0/testing/071_enum_in_anon_ns.cpp
@@ -1,5 +1,5 @@
 // objective: test that enum values in anonymous namespaces produce no warning
-// check: namespace_a_namespace_1_1_0d0.xml
+// check: namespace_a_namespace_1_1_0d130315250316227335362355006121037335073327177063.xml
 
 namespace ANamespace { namespace {
 
Index: doxygen-1.12.0/testing/073/073__typed__enum_8cpp.xml
===================================================================
--- doxygen-1.12.0.orig/testing/073/073__typed__enum_8cpp.xml
+++ doxygen-1.12.0/testing/073/073__typed__enum_8cpp.xml
@@ -75,10 +75,10 @@
         </inbodydescription>
         <location file="073_typed_enum.cpp" line="10" column="1" bodyfile="073_typed_enum.cpp" bodystart="10" bodyend="17"/>
       </memberdef>
-      <memberdef kind="enum" id="073__typed__enum_8cpp_1a06fc87d81c62e9abb8790b6e5713c55b" prot="public" static="no" strong="no">
+      <memberdef kind="enum" id="073__typed__enum_8cpp_1a28976fb6fcf15c9e79931f757d4a240a" prot="public" static="no" strong="no">
         <type/>
         <name/>
-        <enumvalue id="073__typed__enum_8cpp_1a06fc87d81c62e9abb8790b6e5713c55ba52c998ad250c15a855ff5559e6d0d1d6" prot="public">
+        <enumvalue id="073__typed__enum_8cpp_1a28976fb6fcf15c9e79931f757d4a240aa52c998ad250c15a855ff5559e6d0d1d6" prot="public">
           <name>Unnamed1</name>
           <briefdescription>
           </briefdescription>
@@ -93,10 +93,10 @@
         </inbodydescription>
         <location file="073_typed_enum.cpp" line="19" column="1" bodyfile="073_typed_enum.cpp" bodystart="19" bodyend="21"/>
       </memberdef>
-      <memberdef kind="enum" id="073__typed__enum_8cpp_1adf764cbdea00d65edcd07bb9953ad2b7" prot="public" static="no" strong="no">
+      <memberdef kind="enum" id="073__typed__enum_8cpp_1a3e3cdcfeacb546b98944a745f81d0492" prot="public" static="no" strong="no">
         <type/>
         <name/>
-        <enumvalue id="073__typed__enum_8cpp_1adf764cbdea00d65edcd07bb9953ad2b7a7b130af0c5cb18bfee8c60994fe1d5ee" prot="public">
+        <enumvalue id="073__typed__enum_8cpp_1a3e3cdcfeacb546b98944a745f81d0492a7b130af0c5cb18bfee8c60994fe1d5ee" prot="public">
           <name>Unnamed2</name>
           <briefdescription>
           </briefdescription>
openSUSE Build Service is sponsored by