diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-15 11:13:31 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-15 11:13:31 +0900 |
commit | 6034e81193d784e8af78fa8ab56438ab1e0d7839 (patch) | |
tree | 27f894681430b733eb8711442a4c9312b7cc3535 /src | |
parent | 3b6ea7abb3d529f7805ed54071d597f01b578740 (diff) | |
download | doxygen-6034e81193d784e8af78fa8ab56438ab1e0d7839.tar.gz doxygen-6034e81193d784e8af78fa8ab56438ab1e0d7839.tar.bz2 doxygen-6034e81193d784e8af78fa8ab56438ab1e0d7839.zip |
Imported Upstream version 1.8.18upstream/1.8.18
Diffstat (limited to 'src')
154 files changed, 13368 insertions, 17026 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23460d0..b7d4af2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,7 +107,6 @@ set(LEX_FILES scanner fortranscanner fortrancode vhdlcode - tclscanner pre declinfo defargs @@ -148,13 +147,6 @@ add_library(doxycfg STATIC ) add_library(_doxygen STATIC - # custom generated files - ${GENERATED_SRC}/lang_cfg.h - ${GENERATED_SRC}/settings.h - ${GENERATED_SRC}/layout_default.xml.h - ${GENERATED_SRC}/ce_parse.h - ${GENERATED_SRC}/configvalues.h - ${GENERATED_SRC}/resources.cpp # generated for/by flex/bison #${LEX_FILES_H} #unfortunately doesn't work in older versions of CMake (like 3.6.2) #${LEX_FILES_CPP} #unfortunately doesn't work in older versions of CMake (like 3.6.2) @@ -173,7 +165,6 @@ add_library(_doxygen STATIC ${GENERATED_SRC}/pyscanner.l.h ${GENERATED_SRC}/scanner.l.h ${GENERATED_SRC}/sqlcode.l.h - ${GENERATED_SRC}/tclscanner.l.h ${GENERATED_SRC}/vhdlcode.l.h ${GENERATED_SRC}/xmlcode.l.h ${GENERATED_SRC}/code.cpp @@ -191,11 +182,17 @@ add_library(_doxygen STATIC ${GENERATED_SRC}/pyscanner.cpp ${GENERATED_SRC}/scanner.cpp ${GENERATED_SRC}/sqlcode.cpp - ${GENERATED_SRC}/tclscanner.cpp ${GENERATED_SRC}/vhdlcode.cpp ${GENERATED_SRC}/xmlcode.cpp # ${GENERATED_SRC}/ce_parse.cpp + # custom generated files + ${GENERATED_SRC}/lang_cfg.h + ${GENERATED_SRC}/settings.h + ${GENERATED_SRC}/layout_default.xml.h + ${GENERATED_SRC}/ce_parse.h + ${GENERATED_SRC}/configvalues.h + ${GENERATED_SRC}/resources.cpp # arguments.cpp cite.cpp @@ -235,7 +232,6 @@ add_library(_doxygen STATIC emoji.cpp entry.cpp filedef.cpp - filename.cpp fileparser.cpp formula.cpp ftextstream.cpp @@ -262,7 +258,6 @@ add_library(_doxygen STATIC message.cpp msc.cpp namespacedef.cpp - objcache.cpp outputgen.cpp outputlist.cpp pagedef.cpp @@ -295,6 +290,7 @@ add_library(_doxygen STATIC add_executable(doxygen main.cpp) + if (use_libclang) find_package(LLVM REQUIRED CONFIG) find_package(Clang REQUIRED CONFIG) @@ -329,6 +325,12 @@ target_link_libraries(doxygen ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBS} ${CLANG_LIBS} + ${DOXYGEN_EXTRA_LINK_OPTIONS} ) +set_project_warnings(doxycfg) +set_project_warnings(_doxygen) +set_project_warnings(doxygen) + install(TARGETS doxygen DESTINATION bin) + diff --git a/src/bufstr.h b/src/bufstr.h index 331def2..e64a049 100644 --- a/src/bufstr.h +++ b/src/bufstr.h @@ -30,7 +30,7 @@ class BufStr { public: - BufStr(int size) + BufStr(uint size) : m_size(size), m_writeOffset(0), m_spareRoom(10240), m_buf(0) { m_buf = (char *)calloc(size,1); @@ -44,7 +44,7 @@ class BufStr makeRoomFor(1); m_buf[m_writeOffset++]=c; } - void addArray(const char *a,int len) + void addArray(const char *a,uint len) { makeRoomFor(len); memcpy(m_buf+m_writeOffset,a,len); @@ -74,7 +74,7 @@ class BufStr memset(m_buf+oldsize,0,m_size-oldsize); } } - int size() const + uint size() const { return m_size; } @@ -115,7 +115,7 @@ class BufStr } uint m_size; uint m_writeOffset; - const int m_spareRoom; // 10Kb extra room to avoid frequent resizing + const uint m_spareRoom; // 10Kb extra room to avoid frequent resizing char *m_buf; }; diff --git a/src/cite.cpp b/src/cite.cpp index 797881f..dac2bcd 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2011 by Dimitri van Heesch + * Copyright (C) 2020 by Dimitri van Heesch * Based on a patch by David Munger * * Permission to use, copy, modify, and distribute this software and its @@ -15,116 +15,112 @@ */ #include "cite.h" -#include "portable.h" #include "config.h" -#include "message.h" -#include "util.h" -#include "language.h" #include "ftextstream.h" +#include "language.h" +#include "message.h" +#include "portable.h" #include "resourcemgr.h" -#include "doxygen.h" +#include "util.h" + +#include <qfile.h> +#include <qfileinfo.h> #include <qdir.h> -//-------------------------------------------------------------------------- +#include <map> +#include <string> + +// Remove the temporary files +#define RM_TMP_FILES (true) +//#define RM_TMP_FILES (false) + +const char *bibTmpFile = "bibTmpFile_"; +const char *bibTmpDir = "bibTmpDir/"; + +class CiteInfoImpl : public CiteInfo +{ + public: + CiteInfoImpl(const char *label, const char *text=0) + : m_label(label), m_text(text) { } + + virtual QCString label() const { return m_label; } + virtual QCString text() const { return m_text; } -const QCString CiteConsts::fileName("citelist"); -/* when changing this also take doxygen.bst into account */ -const QCString CiteConsts::anchorPrefix("CITEREF_"); -const QCString bibTmpFile("bibTmpFile_"); -const QCString bibTmpDir("bibTmpDir/"); + void setText(const char *s) { m_text = s; } -//-------------------------------------------------------------------------- + private: + QCString m_label; + QCString m_text; +}; + +struct CitationManager::Private +{ + std::map< std::string,std::unique_ptr<CiteInfoImpl> > entries; +}; -CiteDict::CiteDict(int size) : m_entries(size, FALSE) -{ - m_entries.setAutoDelete(TRUE); +CitationManager &CitationManager::instance() +{ + static CitationManager ct; + return ct; } -void CiteDict::writeLatexBibliography(FTextStream &t) +CitationManager::CitationManager() : p(new Private) { - if (m_entries.isEmpty()) - return; +} - QCString style = Config_getString(LATEX_BIB_STYLE); - if (style.isEmpty()) - style="plain"; - QCString unit; - if (Config_getBool(COMPACT_LATEX)) - unit = "section"; - else - unit = "chapter"; - t << "% Bibliography\n" - "\\newpage\n" - "\\phantomsection\n"; - bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - if (!pdfHyperlinks) - { - t << "\\clearemptydoublepage\n"; - t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; - } - t << "\\bibliographystyle{" << style << "}\n" - "\\bibliography{"; - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); - int i = 0; - const char *bibdata = citeDataList.first(); - while (bibdata) - { - QCString bibFile = bibdata; - // Note: file can now have multiple dots - if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; - QFileInfo fi(bibFile); - if (fi.exists()) - { - if (!bibFile.isEmpty()) - { - if (i) t << ","; - i++; - t << bibTmpFile << QCString().setNum(i); - } - } - bibdata = citeDataList.next(); - } - t << "}\n"; - if (pdfHyperlinks) +void CitationManager::insert(const char *label) +{ + p->entries.insert( + std::make_pair( + std::string(label), + std::make_unique<CiteInfoImpl>(label) + )); +} + +const CiteInfo *CitationManager::find(const char *label) const +{ + auto it = p->entries.find(label); + if (it!=p->entries.end()) { - t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; + return it->second.get(); } - t << "\n"; + return 0; } -void CiteDict::insert(const char *label) +void CitationManager::clear() { - m_entries.insert(label,new CiteInfo(label)); + p->entries.clear(); } -CiteInfo *CiteDict::find(const char *label) const +bool CitationManager::isEmpty() const { - return label ? m_entries.find(label) : 0; + uint numFiles = Config_getList(CITE_BIB_FILES).count(); + return (numFiles==0 || p->entries.empty()); } -void CiteDict::clear() +const char *CitationManager::fileName() const { - m_entries.clear(); + return "citelist"; } -bool CiteDict::isEmpty() const +const char *CitationManager::anchorPrefix() const { - QStrList &citeBibFiles = Config_getList(CITE_BIB_FILES); - return (citeBibFiles.count()==0 || m_entries.isEmpty()); + return "CITEREF_"; } -void CiteDict::generatePage() const +void CitationManager::generatePage() { - //printf("** CiteDict::generatePage() count=%d\n",m_ordering.count()); + //printf("** CitationManager::generatePage() count=%d\n",m_ordering.count()); // do not generate an empty citations page if (isEmpty()) return; // nothing to cite // 0. add cross references from the bib files to the cite dictionary QFile f; - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); - const char *bibdata = citeDataList.first(); - while (bibdata) + const QStrList &citeDataList = Config_getList(CITE_BIB_FILES); + QStrListIterator li(citeDataList); + const char *bibdata = 0; + for (li.toFirst() ; (bibdata = li.current()) ; ++li) { QCString bibFile = bibdata; if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; @@ -139,16 +135,16 @@ void CiteDict::generatePage() const err("could not open file %s for reading\n",bibFile.data()); } QCString doc; - QFileInfo fi(bibFile); QCString input(fi.size()+1); f.readBlock(input.rawData(),fi.size()); f.close(); input.at(fi.size())='\0'; - int p=0,s; - while ((s=input.find('\n',p))!=-1) + int pos=0; + int s; + while ((s=input.find('\n',pos))!=-1) { - QCString line = input.mid(p,s-p); - p=s+1; + QCString line = input.mid((uint)pos,(uint)(s-pos)); + pos=s+1; int i; if ((i = line.find("crossref")) != -1) /* assumption cross reference is on one line and the only item */ @@ -157,8 +153,11 @@ void CiteDict::generatePage() const int k=line.find("}",i); if (j!=-1 && k!=-1) { - QCString label = line.mid(j+1,k-j-1); - if (!m_entries.find(label)) Doxygen::citeDict->insert(label.data()); + QCString label = line.mid((uint)(j+1),(uint)(k-j-1)); + if (p->entries.find(label.data())==p->entries.end()) // not found yet + { + insert(label); + } } } } @@ -168,7 +167,6 @@ void CiteDict::generatePage() const { err("bib file %s not found!\n",bibFile.data()); } - bibdata = citeDataList.next(); } // 1. generate file with markers and citations to OUTPUT_DIRECTORY @@ -182,11 +180,9 @@ void CiteDict::generatePage() const FTextStream t(&f); t << "<!-- BEGIN CITATIONS -->" << endl; t << "<!--" << endl; - QDictIterator<CiteInfo> it(m_entries); - CiteInfo *ci; - for (it.toFirst();(ci=it.current());++it) + for (const auto &it : p->entries) { - t << "\\citation{" << ci->label << "}" << endl; + t << "\\citation{" << it.second->label() << "}" << endl; } t << "-->" << endl; t << "<!-- END CITATIONS -->" << endl; @@ -210,9 +206,8 @@ void CiteDict::generatePage() const QCString bibOutputFiles = ""; QDir thisDir; thisDir.mkdir(bibOutputDir); - bibdata = citeDataList.first(); int i = 0; - while (bibdata) + for (li.toFirst() ; (bibdata = li.current()) ; ++li) { QCString bibFile = bibdata; if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; @@ -226,7 +221,6 @@ void CiteDict::generatePage() const bibOutputFiles = bibOutputFiles + " " + bibTmpDir + bibTmpFile + QCString().setNum(i) + ".bib"; } } - bibdata = citeDataList.next(); } QString oldDir = QDir::currentDirPath(); @@ -252,25 +246,25 @@ void CiteDict::generatePage() const { err("could not open file %s for reading\n",citeListFile.data()); } - bool insideBib=FALSE; - + QCString doc; QFileInfo fi(citeListFile); QCString input(fi.size()+1); f.readBlock(input.rawData(),fi.size()); f.close(); input.at(fi.size())='\0'; - int p=0,s; + + bool insideBib=FALSE; + int pos=0,s; //printf("input=[%s]\n",input.data()); - while ((s=input.find('\n',p))!=-1) + while ((s=input.find('\n',pos))!=-1) { - QCString line = input.mid(p,s-p); - //printf("p=%d s=%d line=[%s]\n",p,s,line.data()); - p=s+1; + QCString line = input.mid((uint)pos,(uint)(s-pos)); + //printf("pos=%d s=%d line=[%s]\n",pos,s,line.data()); + pos=s+1; if (line.find("<!-- BEGIN BIBLIOGRAPHY")!=-1) insideBib=TRUE; else if (line.find("<!-- END BIBLIOGRAPH")!=-1) insideBib=FALSE; - int i; // determine text to use at the location of the @cite command if (insideBib && (i=line.find("name=\"CITEREF_"))!=-1) { @@ -278,15 +272,18 @@ void CiteDict::generatePage() const int k=line.find("]</a>"); if (j!=-1 && k!=-1) { - QCString label = line.mid(i+14,j-i-14); - QCString number = line.mid(j+2,k-j-1); + uint ui=(uint)i; + uint uj=(uint)j; + uint uk=(uint)k; + QCString label = line.mid(ui+14,uj-ui-14); + QCString number = line.mid(uj+2,uk-uj-1); label = substitute(substitute(label,"–","--"),"—","---"); - CiteInfo *ci = m_entries.find(label); - //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),ci); - line = line.left(i+14) + label + line.right(line.length()-j); - if (ci) + line = line.left(ui+14) + label + line.right(line.length()-uj); + auto it = p->entries.find(label.data()); + //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),it->second.get()); + if (it!=p->entries.end()) { - ci->text = number; + it->second->setText(number); } } } @@ -295,24 +292,21 @@ void CiteDict::generatePage() const //printf("doc=[%s]\n",doc.data()); // 7. add it as a page - addRelatedPage(CiteConsts::fileName, - theTranslator->trCiteReferences(),doc,CiteConsts::fileName,1); + addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1); // 8. for latex we just copy the bib files to the output and let // latex do this work. if (Config_getBool(GENERATE_LATEX)) { // copy bib files to the latex output dir - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); QCString latexOutputDir = Config_getString(LATEX_OUTPUT)+"/"; - int i = 0; - const char *bibdata = citeDataList.first(); - while (bibdata) + i = 0; + for (li.toFirst() ; (bibdata = li.current()) ; ++li) { QCString bibFile = bibdata; // Note: file can now have multiple dots if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; - QFileInfo fi(bibFile); + fi.setFile(bibFile); if (fi.exists()) { if (!bibFile.isEmpty()) @@ -327,21 +321,80 @@ void CiteDict::generatePage() const { err("bib file %s not found!\n",bibFile.data()); } - bibdata = citeDataList.next(); } } // 9. Remove temporary files - thisDir.remove(citeListFile); - thisDir.remove(doxygenBstFile); - thisDir.remove(bib2xhtmlFile); - // we might try to remove too many files as empty files didn't get a corresponding new file - // but the remove function does not emit an error for it and we don't catch the error return - // so no problem. - for (unsigned int j = 1; j <= citeDataList.count(); j++) + if (RM_TMP_FILES) + { + thisDir.remove(citeListFile); + thisDir.remove(doxygenBstFile); + thisDir.remove(bib2xhtmlFile); + // we might try to remove too many files as empty files didn't get a corresponding new file + // but the remove function does not emit an error for it and we don't catch the error return + // so no problem. + for (unsigned int j = 1; j <= citeDataList.count(); j++) + { + thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(j) + ".bib"); + } + thisDir.rmdir(bibOutputDir); + } +} + +void CitationManager::writeLatexBibliography(FTextStream &t) const +{ + if (p->entries.empty()) return; + + QCString style = Config_getString(LATEX_BIB_STYLE); + if (style.isEmpty()) + { + style="plain"; + } + QCString unit; + if (Config_getBool(COMPACT_LATEX)) + { + unit = "section"; + } + else + { + unit = "chapter"; + } + t << "% Bibliography\n" + "\\newpage\n" + "\\phantomsection\n"; + bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + if (!pdfHyperlinks) + { + t << "\\clearemptydoublepage\n"; + t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; + } + t << "\\bibliographystyle{" << style << "}\n" + "\\bibliography{"; + QStrList &citeDataList = Config_getList(CITE_BIB_FILES); + int i = 0; + QStrListIterator li(citeDataList); + const char *bibdata = 0; + for (li.toFirst() ; (bibdata = li.current()) ; ++li) + { + QCString bibFile = bibdata; + // Note: file can now have multiple dots + if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; + QFileInfo fi(bibFile); + if (fi.exists()) + { + if (!bibFile.isEmpty()) + { + if (i) t << ","; + i++; + t << bibTmpFile << QCString().setNum(i); + } + } + } + t << "}\n"; + if (pdfHyperlinks) { - thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(j) + ".bib"); + t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; } - thisDir.rmdir(bibOutputDir); + t << "\n"; } @@ -1,8 +1,6 @@ /****************************************************************************** * - * - * - * Copyright (C) 2011 by Dimitri van Heesch + * Copyright (C) 2020 by Dimitri van Heesch * Based on a patch by David Munger * * Permission to use, copy, modify, and distribute this software and its @@ -16,83 +14,64 @@ * */ -#ifndef CITEDB_H -#define CITEDB_H +#ifndef CITE_H +#define CITE_H -#include <qdict.h> +#include <memory> -class FTextStream; +#include <qcstring.h> -/// String constants for citations -struct CiteConsts -{ - static const QCString fileName; - static const QCString anchorPrefix; -}; +class FTextStream; /// Citation-related data. struct CiteInfo { - CiteInfo(const char *label_, const char *text_=0, const char *fullText_=0, - const char *ref_=0) : - label(label_), text(text_), fullText(fullText_), ref(ref_) - { } - - CiteInfo(const CiteInfo &o) - { label=o.label.copy(); text=o.text.copy(); fullText=o.fullText.copy(); ref=o.ref.copy(); } - - QCString label; - QCString text; - QCString fullText; - QCString ref; - + virtual ~CiteInfo() {} + virtual QCString label() const = 0; + virtual QCString text() const = 0; }; /** - * @brief Cite database access class. - * @details This class provides access do the database of bibliographic + * @brief Citation manager class. + * @details This class provides access do the database of bibliographic * references through the bibtex backend. */ -class CiteDict +class CitationManager { public: - /** Create the database, with an expected maximum of \a size entries */ - CiteDict(int size); - -// /** Resolve references to citations */ -// void resolve(); + static CitationManager &instance(); /** Insert a citation identified by \a label into the database */ void insert(const char *label); - /** Return the citation info for a given \a label */ - CiteInfo *find(const char *label) const; + /** Return the citation info for a given \a label. + * Ownership of the info stays with the manager. + */ + const CiteInfo *find(const char *label) const; /** Generate the citations page */ - void generatePage() const; + void generatePage(); /** clears the database */ void clear(); - /** return TRUE if there are no citations. - * Only valid after calling resolve() + /** return TRUE if there are no citations. */ bool isEmpty() const; - /** writes the latex code for the standard bibliography - * section to text stream \a t + /** writes the latex code for the standard bibliography + * section to text stream \a t */ - void writeLatexBibliography(FTextStream &t); + void writeLatexBibliography(FTextStream &t) const; + + const char *fileName() const; + const char *anchorPrefix() const; private: -// bool writeAux(); -// bool writeBst(); -// bool execute(); -// void parse(); -// void clean(); - QDict<CiteInfo> m_entries; -// QList<QCString> m_ordering; - QCString m_baseFileName; + /** Create the database, with an expected maximum of \a size entries */ + CitationManager(); + struct Private; + std::unique_ptr<Private> p; }; -#endif +#endif // CITE_H diff --git a/src/clangparser.cpp b/src/clangparser.cpp index f6020dd..c7639ea 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -44,7 +44,7 @@ class ClangParser::Private { public: enum DetectedLang { Detected_Cpp, Detected_ObjC, Detected_ObjCpp }; - Private() : tu(0), tokens(0), numTokens(0), cursors(0), + Private() : tu(0), tokens(0), numTokens(0), cursors(0), ufs(0), sources(0), numFiles(0), fileMapping(257), detectedLang(Detected_Cpp) { fileMapping.setAutoDelete(TRUE); } @@ -84,7 +84,7 @@ static QCString detab(const QCString &s) int stop = tabSize - (col%tabSize); //printf("expand at %d stop=%d\n",col,stop); col+=stop; - while (stop--) out.addChar(' '); + while (stop--) out.addChar(' '); } break; case '\n': // reset column counter @@ -134,7 +134,7 @@ static void inclusionVisitor(CXFile includedFile, /** filter the \a files and only keep those that are found as include files * within the current translation unit. * @param[in,out] files The list of files to filter. - */ + */ void ClangParser::determineInputFilesInSameTu(QStrList &files) { // put the files in this translation unit in a dictionary @@ -241,7 +241,7 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp) { QCString fn = fileName; - if (p->detectedLang==ClangParser::Private::Detected_Cpp && + if (p->detectedLang==ClangParser::Private::Detected_Cpp && (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" || fn.right(3).lower()==".cc" || fn.right(2).lower()==".c")) { // fall back to C/C++ once we see an extension that indicates this @@ -258,14 +258,14 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) } switch(p->detectedLang) { - case ClangParser::Private::Detected_Cpp: - argv[argc++]=qstrdup("c++"); + case ClangParser::Private::Detected_Cpp: + argv[argc++]=qstrdup("c++"); break; - case ClangParser::Private::Detected_ObjC: - argv[argc++]=qstrdup("objective-c"); + case ClangParser::Private::Detected_ObjC: + argv[argc++]=qstrdup("objective-c"); break; - case ClangParser::Private::Detected_ObjCpp: - argv[argc++]=qstrdup("objective-c++"); + case ClangParser::Private::Detected_ObjCpp: + argv[argc++]=qstrdup("objective-c++"); break; } @@ -276,7 +276,7 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); //printf("source %s ----------\n%s\n-------------\n\n", // fileName,p->source.data()); - uint numUnsavedFiles = filesInTranslationUnit.count()+1; + int numUnsavedFiles = filesInTranslationUnit.count()+1; p->numFiles = numUnsavedFiles; p->sources = new QCString[numUnsavedFiles]; p->ufs = new CXUnsavedFile[numUnsavedFiles]; @@ -285,7 +285,7 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) p->ufs[0].Contents = p->sources[0].data(); p->ufs[0].Length = p->sources[0].length(); QStrListIterator it(filesInTranslationUnit); - uint i=1; + int i=1; for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++) { p->fileMapping.insert(it.current(),new uint(i)); @@ -297,10 +297,10 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) // let libclang do the actual parsing p->tu = clang_parseTranslationUnit(p->index, 0, - argv, argc, p->ufs, numUnsavedFiles, + argv, argc, p->ufs, numUnsavedFiles, CXTranslationUnit_DetailedPreprocessingRecord); // free arguments - for (int i=0;i<argc;++i) + for (i=0;i<argc;++i) { free(argv[i]); } @@ -312,11 +312,12 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) determineInputFilesInSameTu(filesInTranslationUnit); // show any warnings that the compiler produced - for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) + int n=clang_getNumDiagnostics(p->tu); + for (i=0; i!=n; ++i) { - CXDiagnostic diag = clang_getDiagnostic(p->tu, i); + CXDiagnostic diag = clang_getDiagnostic(p->tu, i); CXString string = clang_formatDiagnostic(diag, - clang_defaultDiagnosticDisplayOptions()); + clang_defaultDiagnosticDisplayOptions()); err("%s [clang]\n",clang_getCString(string)); clang_disposeString(string); clang_disposeDiagnostic(diag); @@ -436,7 +437,7 @@ QCString ClangParser::lookup(uint line,const char *symbol) p->curToken--; // linear search to start of the line l = p->getCurrentTokenLine(); } - else + else { p->curToken/=2; // binary search backward l = p->getCurrentTokenLine(); @@ -702,17 +703,19 @@ void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd, FileDef *ifd=0; if (!incName.isEmpty()) { - FileName *fn = Doxygen::inputNameDict->find(incName); + FileName *fn = Doxygen::inputNameLinkedMap->find(incName); if (fn) { - bool found=false; - FileNameIterator fni(*fn); - // for each include name - for (fni.toFirst();!found && (ifd=fni.current());++fni) + // see if this source file actually includes the file + auto it = std::find_if(fn->begin(), + fn->end(), + [&fd](const auto &ifd) + { return fd->isIncluded(ifd->absFilePath()); }); + bool found = it!=fn->end(); + if (found) { - // see if this source file actually includes the file - found = fd->isIncluded(ifd->absFilePath()); - //printf(" include file %s found=%d\n",ifd->absFilePath().data(),found); + //printf(" include file %s found=%d\n",(*it)->absFilePath().data(),found); + ifd = it->get(); } } } @@ -729,16 +732,14 @@ void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd, void ClangParser::linkMacro(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text) { - MemberName *mn=Doxygen::functionNameSDict->find(text); + MemberName *mn=Doxygen::functionNameLinkedMap->find(text); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->isDefine()) { - writeMultiLineCodeLink(ol,fd,line,column,md,text); + writeMultiLineCodeLink(ol,fd,line,column,md.get(),text); return; } } @@ -759,7 +760,7 @@ void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd, CXCursor t = clang_getSpecializedCursorTemplate(c); if (!clang_Cursor_isNull(t) && !clang_equalCursors(t,c)) { - c=t; // link to template + c=t; // link to template } CXString usr = clang_getCursorUSR(c); const char *usrStr = clang_getCString(usr); @@ -779,7 +780,7 @@ void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd, if (d && d->isLinkable()) { if (g_insideBody && - g_currentMemberDef && d->definitionType()==Definition::TypeMember && + g_currentMemberDef && d->definitionType()==Definition::TypeMember && (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference { addDocCrossReference(g_currentMemberDef,dynamic_cast<MemberDef *>(d)); @@ -843,13 +844,13 @@ void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) unsigned int l, c; clang_getSpellingLocation(start, 0, &l, &c, 0); if (l > line) column = 1; - while (line<l) - { - line++; + while (line<l) + { + line++; ol.endCodeLine(); ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); - } + } while (column<c) { ol.codify(" "); column++; } CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]); char const *s = clang_getCString(tokenString); @@ -858,7 +859,7 @@ void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) //printf("%d:%d %s cursorKind=%d tokenKind=%d\n",line,column,s,cursorKind,tokenKind); switch (tokenKind) { - case CXToken_Keyword: + case CXToken_Keyword: if (strcmp(s,"operator")==0) { linkIdentifier(ol,fd,line,column,s,i); @@ -870,21 +871,21 @@ void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) keywordToType(s)); } break; - case CXToken_Literal: + case CXToken_Literal: if (cursorKind==CXCursor_InclusionDirective) { linkInclude(ol,fd,line,column,s); } - else if (s[0]=='"' || s[0]=='\'') + else if (s[0]=='"' || s[0]=='\'') { codifyLines(ol,fd,s,line,column,"stringliteral"); } - else + else { codifyLines(ol,fd,s,line,column); } break; - case CXToken_Comment: + case CXToken_Comment: codifyLines(ol,fd,s,line,column,"comment"); break; default: // CXToken_Punctuation or CXToken_Identifier diff --git a/src/classdef.cpp b/src/classdef.cpp index 61ae528..52d2f49 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -66,8 +66,8 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual ClassDef *resolveAlias() { return this; } virtual DefType definitionType() const { return TypeClass; } virtual QCString getOutputFileBase() const; - virtual QCString getInstanceOutputFileBase() const; - virtual QCString getSourceFileBase() const; + virtual QCString getInstanceOutputFileBase() const; + virtual QCString getSourceFileBase() const; virtual QCString getReference() const; virtual bool isReference() const; virtual bool isLocal() const; @@ -106,7 +106,7 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual Definition *findInnerCompound(const char *name) const; virtual std::vector<ArgumentList> getTemplateParameterLists() const; virtual QCString qualifiedNameWithTemplateParameters( - const std::vector<ArgumentList> *actualParams=0,int *actualParamIndex=0) const; + const std::vector<ArgumentList> *actualParams=0,uint *actualParamIndex=0) const; virtual bool isAbstract() const; virtual bool isObjectiveC() const; virtual bool isFortran() const; @@ -149,7 +149,7 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0); virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0); - virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); + virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); virtual void insertMember(MemberDef *); virtual void insertUsedFile(FileDef *); virtual bool addExample(const char *anchor,const char *name, const char *file); @@ -368,7 +368,7 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef virtual std::vector<ArgumentList> getTemplateParameterLists() const { return getCdAlias()->getTemplateParameterLists(); } virtual QCString qualifiedNameWithTemplateParameters( - const std::vector<ArgumentList> *actualParams=0,int *actualParamIndex=0) const + const std::vector<ArgumentList> *actualParams=0,uint *actualParamIndex=0) const { return getCdAlias()->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex); } virtual bool isAbstract() const { return getCdAlias()->isAbstract(); } @@ -448,37 +448,37 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef const QCString &templSpec,bool &freshInstance) const { return getCdAlias()->insertTemplateInstance(fileName,startLine,startColumn,templSpec,freshInstance); } - virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0) { } - virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0) { } - virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force) {} + virtual void insertBaseClass(ClassDef *,const char *,Protection,Specifier,const char *) { } + virtual void insertSubClass(ClassDef *,Protection,Specifier,const char *) { } + virtual void setIncludeFile(FileDef *,const char *,bool,bool) {} virtual void insertMember(MemberDef *) {} virtual void insertUsedFile(FileDef *) {} - virtual bool addExample(const char *anchor,const char *name, const char *file) { return FALSE; } - virtual void mergeCategory(ClassDef *category) {} - virtual void setNamespace(NamespaceDef *nd) {} - virtual void setFileDef(FileDef *fd) {} - virtual void setSubGrouping(bool enabled) {} - virtual void setProtection(Protection p) {} - virtual void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs) {} - virtual void addInnerCompound(const Definition *d) {} - virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot) {} - virtual void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot) {} - virtual void setIsStatic(bool b) {} - virtual void setCompoundType(CompoundType t) {} - virtual void setClassName(const char *name) {} - virtual void setClassSpecifier(uint64 spec) {} - virtual void setTemplateArguments(const ArgumentList &al) {} - virtual void setTemplateBaseClassNames(QDict<int> *templateNames) {} - virtual void setTemplateMaster(const ClassDef *tm) {} - virtual void setTypeConstraints(const ArgumentList &al) {} - virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec) {} - virtual void makeTemplateArgument(bool b=TRUE) {} - virtual void setCategoryOf(ClassDef *cd) {} - virtual void setUsedOnly(bool b) {} - virtual void addTaggedInnerClass(ClassDef *cd) {} - virtual void setTagLessReference(ClassDef *cd) {} - virtual void setName(const char *name) {} - virtual void setMetaData(const char *md) {} + virtual bool addExample(const char *,const char *, const char *) { return FALSE; } + virtual void mergeCategory(ClassDef *) {} + virtual void setNamespace(NamespaceDef *) {} + virtual void setFileDef(FileDef *) {} + virtual void setSubGrouping(bool) {} + virtual void setProtection(Protection) {} + virtual void setGroupDefForAllMembers(GroupDef *,Grouping::GroupPri_t,const QCString &,int,bool) {} + virtual void addInnerCompound(const Definition *) {} + virtual void addUsedClass(ClassDef *,const char *,Protection) {} + virtual void addUsedByClass(ClassDef *,const char *,Protection) {} + virtual void setIsStatic(bool) {} + virtual void setCompoundType(CompoundType) {} + virtual void setClassName(const char *) {} + virtual void setClassSpecifier(uint64) {} + virtual void setTemplateArguments(const ArgumentList &) {} + virtual void setTemplateBaseClassNames(QDict<int> *) {} + virtual void setTemplateMaster(const ClassDef *) {} + virtual void setTypeConstraints(const ArgumentList &) {} + virtual void addMembersToTemplateInstance(const ClassDef *,const char *) {} + virtual void makeTemplateArgument(bool=TRUE) {} + virtual void setCategoryOf(ClassDef *) {} + virtual void setUsedOnly(bool) {} + virtual void addTaggedInnerClass(ClassDef *) {} + virtual void setTagLessReference(ClassDef *) {} + virtual void setName(const char *) {} + virtual void setMetaData(const char *) {} virtual void findSectionsInDocumentation() {} virtual void addMembersToMemberGroup() {} virtual void addListReferences() {} @@ -487,24 +487,24 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef virtual void mergeMembers() {} virtual void sortMemberLists() {} virtual void distributeMemberGroupDocumentation() {} - virtual void writeDocumentation(OutputList &ol) const {} - virtual void writeDocumentationForInnerClasses(OutputList &ol) const {} - virtual void writeMemberPages(OutputList &ol) const {} - virtual void writeMemberList(OutputList &ol) const {} - virtual void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup, - const ClassDef *inheritedFrom,const char *inheritId) const {} - virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const {} - virtual void writeSummaryLinks(OutputList &ol) const {} - virtual void reclassifyMember(MemberDef *md,MemberType t) {} - virtual void writeInlineDocumentation(OutputList &ol) const {} + virtual void writeDocumentation(OutputList &) const {} + virtual void writeDocumentationForInnerClasses(OutputList &) const {} + virtual void writeMemberPages(OutputList &) const {} + virtual void writeMemberList(OutputList &) const {} + virtual void writeDeclaration(OutputList &,const MemberDef *,bool, + const ClassDef *,const char *) const {} + virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const {} + virtual void writeSummaryLinks(OutputList &) const {} + virtual void reclassifyMember(MemberDef *,MemberType) {} + virtual void writeInlineDocumentation(OutputList &) const {} virtual void writeDeclarationLink(OutputList &ol,bool &found, const char *header,bool localNames) const { getCdAlias()->writeDeclarationLink(ol,found,header,localNames); } - virtual void removeMemberFromLists(MemberDef *md) {} + virtual void removeMemberFromLists(MemberDef *) {} virtual void setAnonymousEnumType() {} virtual void countMembers() {} - virtual void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, - const ClassDef *inheritedFrom,const QCString &inheritId) const {} + virtual void addGroupedInheritedMembers(OutputList &,MemberListType, + const ClassDef *,const QCString &) const {} virtual void writeTagFile(FTextStream &) {} virtual void setVisited(bool visited) const { m_visited = visited; } @@ -516,10 +516,8 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const { return getCdAlias()->countMemberDeclarations(lt,inheritedFrom,lt2,invert,showAlways,visitedClasses); } - virtual void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, - const char *subTitle=0,bool showInline=FALSE,const ClassDef *inheritedFrom=0, - int lt2=-1,bool invert=FALSE,bool showAlways=FALSE, - QPtrDict<void> *visitedClasses=0) const {} + virtual void writeMemberDeclarations(OutputList &,MemberListType,const QCString &, + const char *,bool,const ClassDef *, int,bool,bool, QPtrDict<void> *) const {} private: mutable bool m_visited = false; @@ -1743,7 +1741,7 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const ol.startParagraph(); //parseText(ol,theTranslator->trInherits()+" "); - QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count()); + QCString inheritLine = theTranslator->trInheritsList((int)m_impl->inherits->count()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes @@ -1780,7 +1778,7 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const } index=newIndex+matchLen; } - ol.parseText(inheritLine.right(inheritLine.length()-index)); + ol.parseText(inheritLine.right(inheritLine.length()-(uint)index)); ol.endParagraph(); } @@ -1788,7 +1786,7 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const if (m_impl->inheritedBy && m_impl->inheritedBy->count()>0) { ol.startParagraph(); - QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count()); + QCString inheritLine = theTranslator->trInheritedByList((int)m_impl->inheritedBy->count()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes @@ -1813,7 +1811,7 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const } index=newIndex+matchLen; } - ol.parseText(inheritLine.right(inheritLine.length()-index)); + ol.parseText(inheritLine.right(inheritLine.length()-(uint)index)); ol.endParagraph(); } @@ -2235,7 +2233,7 @@ void ClassDefImpl::writeTagFile(FTextStream &tagFile) { if (!isLinkableInProject()) return; tagFile << " <compound kind=\""; - if (isFortran() && (compoundTypeString() == "type")) + if (isFortran() && (compoundTypeString() == "type")) tagFile << "struct"; else tagFile << compoundTypeString(); @@ -3301,7 +3299,9 @@ bool ClassDefImpl::hasExamples() const { bool result=FALSE; if (m_impl->exampleSDict) - result = m_impl->exampleSDict->count()>0; + { + result = m_impl->exampleSDict->count()>0; + } return result; } @@ -3354,7 +3354,7 @@ void ClassDefImpl::addTypeConstraints() addTypeConstraint(typeConstraint,a.type); p=i+1; } - typeConstraint = a.typeConstraint.right(a.typeConstraint.length()-p).stripWhiteSpace(); + typeConstraint = a.typeConstraint.right(a.typeConstraint.length()-(uint)p).stripWhiteSpace(); addTypeConstraint(typeConstraint,a.type); } } @@ -3606,7 +3606,7 @@ void ClassDefImpl::mergeMembers() //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); SrcLangExt lang = getLanguage(); QCString sep=getLanguageSpecificSeparator(lang,TRUE); - int sepLen = sep.length(); + uint sepLen = sep.length(); m_impl->membersMerged=TRUE; //printf(" mergeMembers for %s\n",name().data()); @@ -3683,7 +3683,7 @@ void ClassDefImpl::mergeMembers() // dstMd->name().data(), // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen); + QCString scope=dstMi->scopePath.left((uint)dstMi->scopePath.find(sep)+sepLen); if (scope!=dstMi->ambiguityResolutionScope.left(scope.length())) dstMi->ambiguityResolutionScope.prepend(scope); ambiguous=TRUE; @@ -3710,7 +3710,7 @@ void ClassDefImpl::mergeMembers() // dstMd->name().data(), // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen); + QCString scope=dstMi->scopePath.left((uint)dstMi->scopePath.find(sep)+sepLen); if (scope!=dstMi->ambiguityResolutionScope.left(scope.length())) { dstMi->ambiguityResolutionScope.prepend(scope); @@ -3908,16 +3908,6 @@ void ClassDefImpl::mergeCategory(ClassDef *category) //printf("Existing member %s\n",srcMni->memberName()); MemberInfo *dstMi = dstMni->getFirst(); MemberInfo *srcMi = srcMni->getFirst(); - //if (dstMi) - //{ - // Protection prot = dstMi->prot; - // if (makePrivate || isExtension) - // { - // prot = Private; - // removeMemberFromLists(dstMi->memberDef); - // internalInsertMember(dstMi->memberDef,prot,FALSE); - // } - //} if (srcMi && dstMi) { combineDeclarationAndDefinition(srcMi->memberDef,dstMi->memberDef); @@ -3941,13 +3931,13 @@ void ClassDefImpl::mergeCategory(ClassDef *category) //printf("Adding '%s'\n",mi->memberDef->name().data()); Protection prot = mi->prot; //if (makePrivate) prot = Private; - MemberDef *newMd = mi->memberDef->deepCopy(); + std::unique_ptr<MemberDef> newMd { mi->memberDef->deepCopy() }; if (newMd) { //printf("Copying member %s\n",mi->memberDef->name().data()); newMd->moveTo(this); - MemberInfo *newMi=new MemberInfo(newMd,prot,mi->virt,mi->inherited); + MemberInfo *newMi=new MemberInfo(newMd.get(),prot,mi->virt,mi->inherited); newMi->scopePath=mi->scopePath; newMi->ambigClass=mi->ambigClass; newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope; @@ -3955,29 +3945,20 @@ void ClassDefImpl::mergeCategory(ClassDef *category) // also add the newly created member to the global members list - MemberName *mn; QCString name = newMd->name(); - if ((mn=Doxygen::memberNameSDict->find(name))) - { - mn->append(newMd); - } - else - { - mn = new MemberName(newMd->name()); - mn->append(newMd); - Doxygen::memberNameSDict->append(name,mn); - } - + MemberName *mn = Doxygen::memberNameLinkedMap->add(name); + newMd->setCategory(category); newMd->setCategoryRelation(mi->memberDef); - mi->memberDef->setCategoryRelation(newMd); + mi->memberDef->setCategoryRelation(newMd.get()); if (makePrivate || isExtension) { - newMd->makeImplementationDetail(); + newMd->makeImplementationDetail(); } - internalInsertMember(newMd,prot,FALSE); + internalInsertMember(newMd.get(),prot,FALSE); + mn->push_back(std::move(newMd)); } - } + } // add it to the dictionary dstMnd->append(newMni->memberName(),newMni); @@ -4276,8 +4257,8 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *t ArgumentList actualArguments; stringToArgumentList(getLanguage(),templSpec,actualArguments); MemberDef *md = mi->memberDef; - MemberDef *imd = md->createTemplateInstanceMember( - cd->templateArguments(),actualArguments); + std::unique_ptr<MemberDef> imd { md->createTemplateInstanceMember( + cd->templateArguments(),actualArguments) }; //printf("%s->setMemberClass(%p)\n",imd->name().data(),this); imd->setMemberClass(this); imd->setTemplateMaster(md); @@ -4286,19 +4267,14 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *t imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine()); imd->setMemberSpecifiers(md->getMemberSpecifiers()); imd->setMemberGroupId(md->getMemberGroupId()); - insertMember(imd); + insertMember(imd.get()); //printf("Adding member=%s %s%s to class %s templSpec %s\n", // imd->typeString(),imd->name().data(),imd->argsString(), // imd->getClassDef()->name().data(),templSpec); // insert imd in the list of all members //printf("Adding member=%s class=%s\n",imd->name().data(),name().data()); - MemberName *mn = Doxygen::memberNameSDict->find(imd->name()); - if (mn==0) - { - mn = new MemberName(imd->name()); - Doxygen::memberNameSDict->append(imd->name(),mn); - } - mn->append(imd); + MemberName *mn = Doxygen::memberNameLinkedMap->add(imd->name()); + mn->push_back(std::move(imd)); } } } @@ -4344,7 +4320,7 @@ std::vector<ArgumentList> ClassDefImpl::getTemplateParameterLists() const } QCString ClassDefImpl::qualifiedNameWithTemplateParameters( - const std::vector<ArgumentList> *actualParams,int *actualParamIndex) const + const std::vector<ArgumentList> *actualParams,uint *actualParamIndex) const { //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); @@ -4380,7 +4356,7 @@ QCString ClassDefImpl::qualifiedNameWithTemplateParameters( scName+=clName; if (!templateArguments().empty()) { - if (actualParams && *actualParamIndex<(int)actualParams->size()) + if (actualParams && *actualParamIndex<actualParams->size()) { const ArgumentList &al = actualParams->at(*actualParamIndex); if (!isSpecialization) @@ -4411,7 +4387,7 @@ QCString ClassDefImpl::className() const { return m_impl->className; } -}; +} void ClassDefImpl::setClassName(const char *name) { @@ -4424,7 +4400,7 @@ void ClassDefImpl::addListReferences() if (!isLinkableInProject()) return; //printf("ClassDef(%s)::addListReferences()\n",name().data()); { - const std::vector<ListItemInfo> &xrefItems = xrefListItems(); + const std::vector<RefItem*> &xrefItems = xrefListItems(); addRefItem(xrefItems, qualifiedName(), lang==SrcLangExt_Fortran ? theTranslator->trType(TRUE,TRUE) @@ -4836,7 +4812,7 @@ void ClassDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,cons MemberList * ml = getMemberList(lt); MemberList * ml2 = getMemberList((MemberListType)lt2); if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function - { + { static const ClassDef *cdef; if (cdef!=this) { // only one inline link diff --git a/src/classdef.h b/src/classdef.h index 3158c50..72ee92d 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -232,7 +232,7 @@ class ClassDef : virtual public Definition virtual std::vector<ArgumentList> getTemplateParameterLists() const = 0; virtual QCString qualifiedNameWithTemplateParameters( - const std::vector<ArgumentList> *actualParams=0,int *actualParamIndex=0) const = 0; + const std::vector<ArgumentList> *actualParams=0,uint *actualParamIndex=0) const = 0; /** Returns TRUE if there is at least one pure virtual member in this * class. @@ -465,7 +465,7 @@ struct UsesClassDef class UsesClassDict : public QDict<UsesClassDef> { public: - UsesClassDict(int size) : QDict<UsesClassDef>(size) {} + UsesClassDict(uint size) : QDict<UsesClassDef>(size) {} ~UsesClassDict() {} }; @@ -575,7 +575,7 @@ struct ConstraintClassDef class ConstraintClassDict : public QDict<ConstraintClassDef> { public: - ConstraintClassDict(int size) : QDict<ConstraintClassDef>(size) {} + ConstraintClassDict(uint size) : QDict<ConstraintClassDef>(size) {} ~ConstraintClassDict() {} }; diff --git a/src/classlist.cpp b/src/classlist.cpp index f06f744..5e14051 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -168,7 +168,7 @@ void GenericsSDict::insert(const QCString &key,ClassDef *cd) if (i==-1) return; ArgumentList argList; stringToArgumentList(SrcLangExt_CSharp, key.mid(i),argList); - int c = argList.size(); + int c = (int)argList.size(); if (c==0) return; GenericsCollection *collection = m_dict.find(key.left(i)); if (collection==0) // new name @@ -201,7 +201,7 @@ ClassDef *GenericsSDict::find(const QCString &key) { ArgumentList argList; stringToArgumentList(SrcLangExt_CSharp,key.mid(i),argList); - int c = argList.size(); + int c = (int)argList.size(); return collection->find(c); } } diff --git a/src/classlist.h b/src/classlist.h index 11c8305..6e4281f 100644 --- a/src/classlist.h +++ b/src/classlist.h @@ -48,7 +48,7 @@ class ClassListIterator : public QListIterator<ClassDef> class ClassDict : public QDict<ClassDef> { public: - ClassDict(int size) : QDict<ClassDef>(size) {} + ClassDict(uint size) : QDict<ClassDef>(size) {} ~ClassDict() {} }; @@ -56,7 +56,7 @@ class ClassDict : public QDict<ClassDef> class ClassSDict : public SDict<ClassDef> { public: - ClassSDict(int size=17) : SDict<ClassDef>(size) {} + ClassSDict(uint size=17) : SDict<ClassDef>(size) {} ~ClassSDict() {} void writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter=0, const char *header=0,bool localNames=FALSE) const; diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp index e62aa4f..372ba5b 100644 --- a/src/cmdmapper.cpp +++ b/src/cmdmapper.cpp @@ -149,6 +149,10 @@ CommandMap cmdMap[] = { "---", CMD_MDASH }, { "_setscope", CMD_SETSCOPE }, { "emoji", CMD_EMOJI }, + { "rtfinclude", CMD_RTFINCLUDE }, + { "docbookinclude",CMD_DOCBOOKINCLUDE }, + { "maninclude", CMD_MANINCLUDE }, + { "xmlinclude", CMD_XMLINCLUDE }, { 0, 0 }, }; diff --git a/src/cmdmapper.h b/src/cmdmapper.h index 246be9d..a86c20a 100644 --- a/src/cmdmapper.h +++ b/src/cmdmapper.h @@ -138,7 +138,11 @@ enum CommandType CMD_SNIPPETDOC = 108, CMD_SNIPWITHLINES= 109, CMD_EMOJI = 110, - CMD_EQUAL = 111 + CMD_EQUAL = 111, + CMD_RTFINCLUDE = 112, + CMD_DOCBOOKINCLUDE= 113, + CMD_MANINCLUDE = 114, + CMD_XMLINCLUDE = 115 }; enum HtmlTagType @@ -18,12 +18,19 @@ %option prefix="codeYY" %option reentrant %option extra-type="struct codeYY_state *" +%top{ +#include <stdint.h> +} %{ /* * includes */ + +#include <memory> +#include <algorithm> + #include <stdio.h> #include <assert.h> #include <ctype.h> @@ -57,6 +64,8 @@ #define SCOPEBLOCK (int *)8 #define INNERBLOCK (int *)12 +#define USE_STATE2STRING 0 + /* ----------------------------------------------------------------- * statics */ @@ -134,7 +143,7 @@ class VariableContext void addVariable(yyscan_t yyscanner,const QCString &type,const QCString &name); ClassDef *findVariable(const QCString &name); - int count() const { return m_scopes.count(); } + uint count() const { return m_scopes.count(); } private: Scope m_globalScope; @@ -221,7 +230,7 @@ struct codeYY_state QCString parmName; const char * inputString = 0; //!< the code fragment as text - int inputPosition = 0; //!< read offset during parsing + yy_size_t inputPosition = 0; //!< read offset during parsing int inputLines = 0; //!< number of line in the code fragment int yyLineNr = 0; //!< current line number int yyColNr = 0; //!< current column number @@ -303,10 +312,12 @@ struct codeYY_state static bool isCastKeyword(const QCString &s); //------------------------------------------------------------------- +#if USE_STATE2STRING +static const char *stateToString(yyscan_t yyscanner,int state); +#endif static void saveObjCContext(yyscan_t yyscanner); static void restoreObjCContext(yyscan_t yyscanner); -static const char *stateToString(yyscan_t yyscanner,int state); static void addUsingDirective(yyscan_t yyscanner,const char *name); static void pushScope(yyscan_t yyscanner,const char *s); static void popScope(yyscan_t yyscanner); @@ -356,7 +367,7 @@ static QCString escapeObject(yyscan_t yyscanner,const char *s); static QCString escapeWord(yyscan_t yyscanner,const char *s); static QCString escapeComment(yyscan_t yyscanner,const char *s); static bool skipLanguageSpecificKeyword(yyscan_t yyscanner,const QCString &kw); -static int yyread(yyscan_t yyscanner,char *buf,int max_size); +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); /* ----------------------------------------------------------------- @@ -560,7 +571,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" // absPath = QDir::cleanDirPath(yyextra->sourceFileDef->getPath()+"/"+absPath); //} - FileDef *fd=findFileDef(Doxygen::inputNameDict,yytext,ambig); + FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,yytext,ambig); //printf("looking for include %s -> %s fd=%p\n",yytext,absPath.data(),fd); if (fd && fd->isLinkable()) { @@ -570,17 +581,16 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" QCString name = QDir::cleanDirPath(yytext).utf8(); if (!name.isEmpty() && yyextra->sourceFileDef) { - FileName *fn = Doxygen::inputNameDict->find(name); + FileName *fn = Doxygen::inputNameLinkedMap->find(name); if (fn) { - FileNameIterator fni(*fn); - // for each include name - for (fni.toFirst();!found && (fd=fni.current());++fni) - { - // see if this source file actually includes the file - found = yyextra->sourceFileDef->isIncluded(fd->absFilePath()); - //printf(" include file %s found=%d\n",fd->absFilePath().data(),found); - } + // see if this source file actually includes the file + auto it = std::find_if(fn->begin(), + fn->end(), + [&sfd=yyextra->sourceFileDef] + (const auto &lfd) + { return sfd->isIncluded(lfd->absFilePath()); }); + found = it!=fn->end(); } } } @@ -598,7 +608,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" { yyextra->code->codify(yytext); } - char c=yyinput(yyscanner); + char c=(char)yyinput(yyscanner); QCString text; text+=c; yyextra->code->codify(text); @@ -1192,10 +1202,10 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); yyextra->name+=yytext; } -<Body>"("{B}*("*"{B}*)+{SCOPENAME}*{B}*")"/{B}* { // (*p)->func() but not "if (p) ..." +<Body>"("{B}*("*"{B}*)+{SCOPENAME}+{B}*")"/{B}* { // (*p)->func() but not "if (p) ..." yyextra->code->codify(yytext); - int s=0;while (s<(int)yyleng && !isId(yytext[s])) s++; - int e=(int)yyleng-1;while (e>=0 && !isId(yytext[e])) e--; + uint s=0;while (s<(uint)yyleng && !isId(yytext[s])) s++; + uint e=(uint)yyleng-1;while (e>1 && !isId(yytext[e])) e--; QCString varname = ((QCString)yytext).mid(s,e-s+1); addType(yyscanner); yyextra->name=varname; @@ -1215,7 +1225,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{RAWBEGIN} { QCString text=yytext; - int i=text.find('R'); + uint i=(uint)text.find('R'); yyextra->code->codify(text.left(i+1)); startFontClass(yyscanner,"stringliteral"); yyextra->code->codify(yytext+i+1); @@ -1764,7 +1774,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" DBG_CTX((stderr,"yyextra->name=%s\n",yyextra->name.data())); if (index!=-1) { - QCString scope = yyextra->name.left(index); + QCString scope = yyextra->name.left((uint)index); if (!yyextra->classScope.isEmpty()) scope.prepend(yyextra->classScope+"::"); const ClassDef *cd=getResolvedClass(Doxygen::globalScope,yyextra->sourceFileDef,scope); if (cd) @@ -1889,10 +1899,10 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); BEGIN( MemberCall2 ); } -<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { +<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") { yyextra->code->codify(yytext); - int s=0;while (!isId(yytext[s])) s++; - int e=(int)yyleng-1;while (!isId(yytext[e])) e--; + uint s=0;while (!isId(yytext[s])) s++; + uint e=(uint)yyleng-1;while (e>1 && !isId(yytext[e])) e--; yyextra->name=((QCString)yytext).mid(s,e-s+1); BEGIN( MemberCall2 ); } @@ -2104,8 +2114,8 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file yyextra->forceTagReference=yytext; - int s=yyextra->forceTagReference.find(':'); - int e=yyextra->forceTagReference.findRev(']'); + uint s=(uint)yyextra->forceTagReference.find(':'); + uint e=(uint)yyextra->forceTagReference.findRev(']'); yyextra->forceTagReference = yyextra->forceTagReference.mid(s+1,e-s-1); } <*>\n{B}*"/*"[!*]/[^/*] { @@ -2749,24 +2759,22 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) } // look for a global member - if ((mn=Doxygen::functionNameSDict->find(name))) + if ((mn=Doxygen::functionNameLinkedMap->find(name))) { //printf("global var '%s'\n",name.data()); - if (mn->count()==1) // global defined only once + if (mn->size()==1) // global defined only once { - MemberDef *md=mn->getFirst(); + const std::unique_ptr<MemberDef> &md=mn->front(); if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) { yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - return md; + return md.get(); } return 0; } - else if (mn->count()>1) // global defined more than once + else if (mn->size()>1) // global defined more than once { - MemberNameIterator it(*mn); - MemberDef *md; - for (;(md=it.current());++it) + for (const auto &md : *mn) { //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n", // mn,md, @@ -2781,7 +2789,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) { yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); - return md; + return md.get(); } } return 0; @@ -3225,7 +3233,7 @@ static void generateMemberLink(yyscan_t yyscanner, if (vcd && vcd->isLinkable()) { //printf("Found class %s for variable '%s'\n",yyextra->classScope.data(),varName.data()); - MemberName *vmn=Doxygen::memberNameSDict->find(varName); + MemberName *vmn=Doxygen::memberNameLinkedMap->find(varName); if (vmn==0) { int vi; @@ -3234,16 +3242,13 @@ static void generateMemberLink(yyscan_t yyscanner, { ClassDef *jcd = getClass(vn.left(vi)); vn=vn.right(vn.length()-vi-2); - vmn=Doxygen::memberNameSDict->find(vn); + vmn=Doxygen::memberNameLinkedMap->find(vn); //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); if (vmn) { - MemberNameIterator vmni(*vmn); - const MemberDef *vmd; - for (;(vmd=vmni.current());++vmni) + for (const auto &vmd : *vmn) { - if (/*(vmd->isVariable() || vmd->isFunction()) && */ - vmd->getClassDef()==jcd) + if (vmd->getClassDef()==jcd) { //printf("Found variable type=%s\n",vmd->typeString()); const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); @@ -3259,12 +3264,9 @@ static void generateMemberLink(yyscan_t yyscanner, if (vmn) { //printf("There is a variable with name '%s'\n",varName); - MemberNameIterator vmni(*vmn); - const MemberDef *vmd; - for (;(vmd=vmni.current());++vmni) + for (const auto &vmd : *vmn) { - if (/*(vmd->isVariable() || vmd->isFunction()) && */ - vmd->getClassDef()==vcd) + if (vmd->getClassDef()==vcd) { //printf("Found variable type=%s\n",vmd->typeString()); const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); @@ -3667,14 +3669,14 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) if (QCString(ictx->method->typeString())=="id") { // see if the method name is unique, if so we link to it - MemberName *mn=Doxygen::memberNameSDict->find(ctx->methodName); + MemberName *mn=Doxygen::memberNameLinkedMap->find(ctx->methodName); //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n", // mn==0?-1:(int)mn->count(), // ictx->method->name().data(), // ctx->methodName.data()); - if (mn && mn->count()==1) // member name unique + if (mn && mn->size()==1) // member name unique { - ctx->method = mn->getFirst(); + ctx->method = mn->front().get(); } } else @@ -3723,7 +3725,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) } else // illegal marker { - ASSERT(!"invalid escape sequence"); + ASSERT("invalid escape sequence"==0); } } } @@ -3797,12 +3799,12 @@ static bool isCastKeyword(const QCString &s) return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast"; } -static int yyread(yyscan_t yyscanner,char *buf,int max_size) +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int inputPosition = yyextra->inputPosition; - const char *s = yyextra->inputString + yyextra->inputPosition; - int c=0; + yy_size_t inputPosition = yyextra->inputPosition; + const char *s = yyextra->inputString + inputPosition; + yy_size_t c=0; while( c < max_size && *s ) { *buf++ = *s++; @@ -4004,4 +4006,6 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const return; } +#if USE_STATE2STRING #include "code.l.h" +#endif diff --git a/src/commentcnv.l b/src/commentcnv.l index f3367a4..59d1a8b 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -18,6 +18,9 @@ %option prefix="commentcnvYY" %option reentrant %option extra-type="struct commentcnvYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -45,6 +48,8 @@ #define ADDCHAR(c) yyextra->outBuf->addChar(c) #define ADDARRAY(a,s) yyextra->outBuf->addArray(a,s) + +#define USE_STATE2STRING 0 struct CondCtx { @@ -99,7 +104,9 @@ struct commentcnvYY_state bool isFixedForm = FALSE; // For Fortran }; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif static inline int computeIndent(const char *s); static void replaceCommentMarker(yyscan_t yyscanner,const char *s,int len); @@ -108,7 +115,7 @@ static void startCondSection(yyscan_t yyscanner,const char *sectId); static void endCondSection(yyscan_t yyscanner); static void handleCondSectionId(yyscan_t yyscanner,const char *expression); static void replaceAliases(yyscan_t yyscanner,const char *s); -static int yyread(yyscan_t yyscanner,char *buf,int max_size); +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); static void replaceComment(yyscan_t yyscanner,int offset); @@ -284,7 +291,7 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z copyToOutput(yyscanner,yytext,(int)yyleng); } <Scan>"/*"[*!]? { /* start of a C comment */ - if ((yyextra->lang==SrcLangExt_Python) || (yyextra->lang==SrcLangExt_Tcl)) + if (yyextra->lang==SrcLangExt_Python) { REJECT; } @@ -349,6 +356,17 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z yyextra->blockName=&yytext[1]; BEGIN(VerbatimCode); } +<CComment,ReadLine>^[ \t]*("```"[`]*|"~~~"[~]*) { /* start of markdown code block */ + if (!Config_getBool(MARKDOWN_SUPPORT)) + { + REJECT; + } + copyToOutput(yyscanner,yytext,(int)yyleng); + yyextra->lastCommentContext = YY_START; + yyextra->javaBlock=0; + yyextra->blockName=QCString(yytext).stripWhiteSpace().left(3); + BEGIN(VerbatimCode); + } <CComment,ReadLine>[\\@]("dot"|"code"|"msc"|"startuml")/[^a-z_A-Z0-9] { /* start of a verbatim block */ copyToOutput(yyscanner,yytext,(int)yyleng); yyextra->lastCommentContext = YY_START; @@ -427,6 +445,13 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z } } } +<VerbatimCode>("```"[`]*|"~~~"[~]*) { /* end of markdown code block */ + copyToOutput(yyscanner,yytext,(int)yyleng); + if (yytext[0]==yyextra->blockName[0]) + { + BEGIN(yyextra->lastCommentContext); + } + } <VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc"|"enduml") { /* end of verbatim block */ copyToOutput(yyscanner,yytext,(int)yyleng); if (&yytext[4]==yyextra->blockName) @@ -457,7 +482,7 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z } } } -<Verbatim,VerbatimCode>[^@\/\\\n{}]* { /* any character not a backslash or new line or } */ +<Verbatim,VerbatimCode>[^`~@\/\\\n{}]* { /* any character not a backslash or new line or } */ copyToOutput(yyscanner,yytext,(int)yyleng); } <Verbatim,VerbatimCode>\n { /* new line in verbatim block */ @@ -526,7 +551,7 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z copyToOutput(yyscanner,yytext,(int)yyleng); } -<CComment>[^ <\\!@*\n{\"\/]* { /* anything that is not a '*' or command */ +<CComment>[^ `~<\\!@*\n{\"\/]* { /* anything that is not a '*' or command */ copyToOutput(yyscanner,yytext,(int)yyleng); } <CComment>"*"+[^*/\\@\n{\"]* { /* stars without slashes */ @@ -546,7 +571,7 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z } } <CComment>\n { /* new line in comment */ - copyToOutput(yyscanner,yytext,(int)yyleng); + copyToOutput(yyscanner,yytext,(int)yyleng); /* in case of Fortran always end of comment */ if (yyextra->lang==SrcLangExt_Fortran) { @@ -554,16 +579,18 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z } } <CComment>"/"+"*" { /* nested C comment */ - if ((yyextra->lang==SrcLangExt_Python) || (yyextra->lang==SrcLangExt_Tcl)) + if (yyextra->lang==SrcLangExt_Python || + yyextra->lang==SrcLangExt_Markdown) { REJECT; } yyextra->nestingCount++; yyextra->commentStack.push(new CommentCtx(yyextra->lineNr)); - copyToOutput(yyscanner,yytext,(int)yyleng); + copyToOutput(yyscanner,yytext,(int)yyleng); } <CComment>"*"+"/" { /* end of C comment */ - if ((yyextra->lang==SrcLangExt_Python) || (yyextra->lang==SrcLangExt_Tcl)) + if (yyextra->lang==SrcLangExt_Python || + yyextra->lang==SrcLangExt_Markdown) { REJECT; } @@ -1011,11 +1038,11 @@ static void replaceAliases(yyscan_t yyscanner,const char *s) } -static int yyread(yyscan_t yyscanner,char *buf,int max_size) +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int bytesInBuf = yyextra->inBuf->curPos()-yyextra->inBufPos; - int bytesToCopy = QMIN(max_size,bytesInBuf); + yy_size_t bytesInBuf = yyextra->inBuf->curPos()-yyextra->inBufPos; + yy_size_t bytesToCopy = QMIN(max_size,bytesInBuf); memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy); yyextra->inBufPos+=bytesToCopy; return bytesToCopy; @@ -1039,7 +1066,7 @@ static void replaceComment(yyscan_t yyscanner,int offset) else { copyToOutput(yyscanner," */",3); - int i;for (i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); + for (i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); yyextra->inSpecialComment=FALSE; BEGIN(Scan); } @@ -1175,4 +1202,6 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) //---------------------------------------------------------------------------- +#if USE_STATE2STRING #include "commentcnv.l.h" +#endif diff --git a/src/commentscan.h b/src/commentscan.h index f471890..be92920 100644 --- a/src/commentscan.h +++ b/src/commentscan.h @@ -16,74 +16,78 @@ #ifndef COMMENTSCAN_H #define COMMENTSCAN_H +#include <memory> #include "types.h" class Entry; class OutlineParserInterface; /** @file - * @brief Interface for the comment block parser */ + * @brief Interface for the comment block scanner */ -/** Invokes the comment block parser with the request to preprocess a - * single comment block. - * @param[in] comment A string representing the actual comment block. - * Note that leading *'s are already stripped from the comment block. - * @param[in] fileName The name of the file in which the comment is found. - * Mainly used for producing warnings. - * @param[in] lineNr The line number at which the comment block was found. - * @returns The prepocessed comment block - */ -QCString preprocessCommentBlock(const QCString &comment, - const QCString &fileName, - int lineNr); - -/** Invokes the comment block parser with the request to parse a - * single comment block. - * @param[in] parser The language parse that invoked this function. - * The comment block parse may invoke - * ParserInterface::parsePrototype() in order to parse - * the argument of a @@fn command. - * @param[in] curEntry The Entry to which the comment block belongs. - * Any information (like documentation) that is found in - * the comment block will be stored in this entry. - * @param[in] comment A string representing the actual comment block. - * Note that leading *'s are already stripped from the comment block. - * @param[in] fileName The name of the file in which the comment is found. - * Mainly used for producing warnings. - * @param[in,out] lineNr The line number at which the comment block was found. - * When the function returns it will be set to the last line parsed. - * @param[in] isBrief TRUE iff this comment block represents a brief description. - * @param[in] isJavadocStyle TRUE iff this comment block is in "Javadoc" style. - * This means that it starts as a brief description until the end of - * the sentences is found and then proceeds as a detailed description. - * @param[in] isInbody TRUE iff this comment block is located in the body of - * a function. - * @param[in,out] prot The protection level in which this comment block was - * found. Commands in the comment block may override this. - * @param[in,out] position The character position within \a comment where the - * comment block starts. Typically used in case the comment block - * contains multiple structural commands. - * @param[out] newEntryNeeded Boolean that is TRUE if the comment block parser - * finds that a the comment block finishes the entry and a new one - * needs to be started. - * @returns TRUE if the comment requires further processing. The - * parameter \a newEntryNeeded will typically be true in this case and - * \a position will indicate the offset inside the \a comment string - * where to proceed parsing. FALSE indicates no further processing is - * needed. - */ -bool parseCommentBlock(OutlineParserInterface *parser, - Entry *curEntry, - const QCString &comment, - const QCString &fileName, - int &lineNr, - bool isBrief, - bool isJavadocStyle, - bool isInbody, - Protection &prot, - int &position, - bool &newEntryNeeded - ); +class CommentScanner +{ + public: + CommentScanner(); + ~CommentScanner(); + /** Invokes the comment block parser with the request to parse a + * single comment block. + * @param[in] parser The language parse that invoked this function. + * The comment block parse may invoke + * ParserInterface::parsePrototype() in order to parse + * the argument of a @@fn command. + * @param[in] curEntry The Entry to which the comment block belongs. + * Any information (like documentation) that is found in + * the comment block will be stored in this entry. + * @param[in] comment A string representing the actual comment block. + * Note that leading *'s are already stripped from the comment block. + * @param[in] fileName The name of the file in which the comment is found. + * Mainly used for producing warnings. + * @param[in,out] lineNr The line number at which the comment block was found. + * When the function returns it will be set to the last line parsed. + * @param[in] isBrief TRUE iff this comment block represents a brief description. + * @param[in] isJavadocStyle TRUE iff this comment block is in "Javadoc" style. + * This means that it starts as a brief description until the end of + * the sentences is found and then proceeds as a detailed description. + * @param[in] isInbody TRUE iff this comment block is located in the body of + * a function. + * @param[in,out] prot The protection level in which this comment block was + * found. Commands in the comment block may override this. + * @param[in,out] position The character position within \a comment where the + * comment block starts. Typically used in case the comment block + * contains multiple structural commands. + * @param[out] newEntryNeeded Boolean that is TRUE if the comment block parser + * finds that a the comment block finishes the entry and a new one + * needs to be started. + * @returns TRUE if the comment requires further processing. The + * parameter \a newEntryNeeded will typically be true in this case and + * \a position will indicate the offset inside the \a comment string + * where to proceed parsing. FALSE indicates no further processing is + * needed. + */ + bool parseCommentBlock(OutlineParserInterface *parser, + Entry *curEntry, + const QCString &comment, + const QCString &fileName, + int &lineNr, + bool isBrief, + bool isJavadocStyle, + bool isInbody, + Protection &prot, + int &position, + bool &newEntryNeeded + ); + void initGroupInfo(Entry *entry); + void enterFile(const char *fileName,int lineNr); + void leaveFile(const char *fileName,int lineNr); + void enterCompound(const char *fileName,int line,const char *name); + void leaveCompound(const char *fileName,int line,const char *name); + void open(Entry *e,const char *fileName,int line,bool implicit=false); + void close(Entry *e,const char *fileName,int line,bool foundInline,bool implicit=false); + private: + struct Private; + std::unique_ptr<Private> p; +}; #endif diff --git a/src/commentscan.l b/src/commentscan.l index d7cf3c8..309a334 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -15,342 +15,292 @@ %option never-interactive %option prefix="commentscanYY" +%option reentrant +%option extra-type="struct commentscanYY_state *" +%top{ +#include <stdint.h> +} %{ /* * includes */ + +#include <map> +#include <stack> +#include <string> + #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <ctype.h> -#include <qarray.h> -#include <qstack.h> -#include <qregexp.h> -#include <qfile.h> +#include <qcstring.h> #include <qcstringlist.h> -#include "scanner.h" -#include "entry.h" + +#include "cite.h" +#include "commentscan.h" +#include "condparser.h" +#include "config.h" +#include "debug.h" +#include "docgroup.h" #include "doxygen.h" +#include "entry.h" +#include "formula.h" +#include "language.h" #include "message.h" -#include "config.h" +#include "parserintf.h" +#include "reflist.h" +#include "section.h" #include "util.h" -#include "index.h" -#include "defargs.h" -#include "language.h" -#include "outputlist.h" -#include "membergroup.h" #include "reflist.h" -#include "debug.h" -#include "parserintf.h" -#include "cite.h" -#include "markdown.h" -#include "condparser.h" -#include "formula.h" -#define YY_NO_INPUT 1 -#define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 // forward declarations -static bool handleBrief(const QCString &, const QCStringList &); -static bool handleFn(const QCString &, const QCStringList &); -static bool handleDef(const QCString &, const QCStringList &); -static bool handleOverload(const QCString &, const QCStringList &); -static bool handleEnum(const QCString &, const QCStringList &); -static bool handleDefGroup(const QCString &, const QCStringList &); -static bool handleAddToGroup(const QCString &, const QCStringList &); -static bool handleWeakGroup(const QCString &, const QCStringList &); -static bool handleNamespace(const QCString &, const QCStringList &); -static bool handlePackage(const QCString &, const QCStringList &); -static bool handleClass(const QCString &, const QCStringList &); -static bool handleHeaderFile(const QCString &, const QCStringList &); -static bool handleProtocol(const QCString &, const QCStringList &); -static bool handleCategory(const QCString &, const QCStringList &); -static bool handleUnion(const QCString &, const QCStringList &); -static bool handleStruct(const QCString &, const QCStringList &); -static bool handleInterface(const QCString &, const QCStringList &); -static bool handleIdlException(const QCString &, const QCStringList &); -static bool handlePage(const QCString &, const QCStringList &); -static bool handleMainpage(const QCString &, const QCStringList &); -static bool handleFile(const QCString &, const QCStringList &); -static bool handleDir(const QCString &, const QCStringList &); -static bool handleExample(const QCString &, const QCStringList &); -static bool handleDetails(const QCString &, const QCStringList &); -static bool handleNoop(const QCString &, const QCStringList &); -static bool handleName(const QCString &, const QCStringList &); -static bool handleTodo(const QCString &, const QCStringList &); -static bool handleTest(const QCString &, const QCStringList &); -static bool handleBug(const QCString &, const QCStringList &); -static bool handleSubpage(const QCString &s, const QCStringList &); -static bool handleDeprecated(const QCString &, const QCStringList &); -static bool handleXRefItem(const QCString &, const QCStringList &); -static bool handleRelated(const QCString &, const QCStringList &); -static bool handleRelatedAlso(const QCString &, const QCStringList &); -static bool handleMemberOf(const QCString &, const QCStringList &); -static bool handleRefItem(const QCString &, const QCStringList &); -static bool handleSection(const QCString &, const QCStringList &); -static bool handleAnchor(const QCString &, const QCStringList &); -static bool handleCite(const QCString &, const QCStringList &); -static bool handleFormatBlock(const QCString &, const QCStringList &); -static bool handleAddIndex(const QCString &, const QCStringList &); -static bool handleIf(const QCString &, const QCStringList &); -static bool handleIfNot(const QCString &, const QCStringList &); -static bool handleElseIf(const QCString &, const QCStringList &); -static bool handleElse(const QCString &, const QCStringList &); -static bool handleEndIf(const QCString &, const QCStringList &); -static bool handleIngroup(const QCString &, const QCStringList &); -static bool handleNoSubGrouping(const QCString &, const QCStringList &); -static bool handleShowInitializer(const QCString &, const QCStringList &); -static bool handleHideInitializer(const QCString &, const QCStringList &); -static bool handleCallgraph(const QCString &, const QCStringList &); -static bool handleHideCallgraph(const QCString &, const QCStringList &); -static bool handleCallergraph(const QCString &, const QCStringList &); -static bool handleHideCallergraph(const QCString &, const QCStringList &); -static bool handleReferencedByRelation(const QCString &, const QCStringList &); -static bool handleHideReferencedByRelation(const QCString &, const QCStringList &); -static bool handleReferencesRelation(const QCString &, const QCStringList &); -static bool handleHideReferencesRelation(const QCString &, const QCStringList &); -static bool handleInternal(const QCString &, const QCStringList &); -static bool handleLineBr(const QCString &, const QCStringList &); -static bool handleStatic(const QCString &, const QCStringList &); -static bool handlePure(const QCString &, const QCStringList &); -static bool handlePrivate(const QCString &, const QCStringList &); -static bool handlePrivateSection(const QCString &, const QCStringList &); -static bool handleProtected(const QCString &, const QCStringList &); -static bool handleProtectedSection(const QCString &, const QCStringList &); -static bool handlePublic(const QCString &s, const QCStringList &); -static bool handlePublicSection(const QCString &s, const QCStringList &); -static bool handleToc(const QCString &s, const QCStringList &); -static bool handleInherit(const QCString &, const QCStringList &); -static bool handleExtends(const QCString &, const QCStringList &); -static bool handleCopyDoc(const QCString &, const QCStringList &); -static bool handleCopyBrief(const QCString &, const QCStringList &); -static bool handleCopyDetails(const QCString &, const QCStringList &); -static bool handleParBlock(const QCString &, const QCStringList &); -static bool handleEndParBlock(const QCString &, const QCStringList &); -static bool handleParam(const QCString &, const QCStringList &); -static bool handleRetval(const QCString &, const QCStringList &); - +static bool handleBrief(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleFn(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleDef(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleOverload(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleEnum(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleDefGroup(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleAddToGroup(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleWeakGroup(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleNamespace(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handlePackage(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleClass(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleHeaderFile(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleProtocol(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCategory(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleUnion(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleStruct(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleInterface(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleIdlException(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handlePage(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleMainpage(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleFile(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleDir(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleExample(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleDetails(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleNoop(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleName(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleTodo(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleTest(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleBug(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleSubpage(yyscan_t yyscanner,const QCString &s, const QCStringList &); +static bool handleDeprecated(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleXRefItem(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleRelated(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleRelatedAlso(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleMemberOf(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleRefItem(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleSection(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleAnchor(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCite(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleFormatBlock(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleAddIndex(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleIf(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleIfNot(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleElseIf(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleElse(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleEndIf(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleIngroup(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleNoSubGrouping(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleShowInitializer(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleHideInitializer(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCallgraph(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleHideCallgraph(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCallergraph(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleHideCallergraph(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleReferencedByRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleHideReferencedByRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleHideReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleInternal(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleLineBr(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleStatic(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handlePure(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handlePrivate(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handlePrivateSection(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleProtected(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleProtectedSection(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handlePublic(yyscan_t yyscanner,const QCString &s, const QCStringList &); +static bool handlePublicSection(yyscan_t yyscanner,const QCString &s, const QCStringList &); +static bool handleToc(yyscan_t yyscanner,const QCString &s, const QCStringList &); +static bool handleInherit(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleExtends(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCopyDoc(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCopyBrief(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleCopyDetails(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleParBlock(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleEndParBlock(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleParam(yyscan_t yyscanner,const QCString &, const QCStringList &); +static bool handleRetval(yyscan_t yyscanner,const QCString &, const QCStringList &); + +#if USE_STATE2STRING static const char *stateToString(int state); +#endif -typedef bool (*DocCmdFunc)(const QCString &name, const QCStringList &optList); +typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const QCStringList &optList); struct DocCmdMap { - const char *cmdName; + DocCmdMap(DocCmdFunc h,bool b) : handler(h), endsBrief(b) {} DocCmdFunc handler; bool endsBrief; }; // map of command to handler function -static DocCmdMap docCmdMap[] = +static const std::map< std::string, DocCmdMap > docCmdMap = { // command name handler function ends brief description - { "brief", &handleBrief, FALSE }, - { "short", &handleBrief, FALSE }, - { "fn", &handleFn, TRUE }, - { "var", &handleFn, TRUE }, - { "typedef", &handleFn, TRUE }, - { "property", &handleFn, TRUE }, - { "def", &handleDef, TRUE }, - { "overload", &handleOverload, FALSE }, - { "enum", &handleEnum, TRUE }, - { "defgroup", &handleDefGroup, TRUE }, - { "addtogroup", &handleAddToGroup, TRUE }, - { "weakgroup", &handleWeakGroup, TRUE }, - { "namespace", &handleNamespace, TRUE }, - { "package", &handlePackage, TRUE }, - { "class", &handleClass, TRUE }, - { "headerfile", &handleHeaderFile, FALSE }, - { "protocol", &handleProtocol, TRUE }, - { "category", &handleCategory, TRUE }, - { "union", &handleUnion, TRUE }, - { "struct", &handleStruct, TRUE }, - { "interface", &handleInterface, TRUE }, - { "idlexcept", &handleIdlException, TRUE }, - { "page", &handlePage, TRUE }, - { "mainpage", &handleMainpage, TRUE }, - { "file", &handleFile, TRUE }, - { "dir", &handleDir, TRUE }, - { "example", &handleExample, FALSE }, - { "details", &handleDetails, TRUE }, - { "name", &handleName, FALSE }, - { "todo", &handleTodo, FALSE }, // end brief will be done differently - { "test", &handleTest, FALSE }, // end brief will be done differently - { "bug", &handleBug, FALSE }, // end brief will be done differently - { "deprecated", &handleDeprecated, FALSE }, // end brief will be done differently - { "xrefitem", &handleXRefItem, FALSE }, // end brief will be done differently - { "related", &handleRelated, TRUE }, - { "relates", &handleRelated, TRUE }, - { "relatedalso", &handleRelatedAlso, TRUE }, - { "relatesalso", &handleRelatedAlso, TRUE }, - { "parblock", &handleParBlock, TRUE }, - { "endparblock", &handleEndParBlock, TRUE }, - { "refitem", &handleRefItem, TRUE }, - { "cite", &handleCite, FALSE }, - { "subpage", &handleSubpage, TRUE }, - { "section", &handleSection, TRUE }, - { "subsection", &handleSection, TRUE }, - { "subsubsection", &handleSection, TRUE }, - { "paragraph", &handleSection, TRUE }, - { "anchor", &handleAnchor, TRUE }, - { "verbatim", &handleFormatBlock, TRUE }, - { "latexonly", &handleFormatBlock, FALSE }, - { "htmlonly", &handleFormatBlock, FALSE }, - { "xmlonly", &handleFormatBlock, FALSE }, - { "docbookonly", &handleFormatBlock, FALSE }, - { "rtfonly", &handleFormatBlock, FALSE }, - { "manonly", &handleFormatBlock, FALSE }, - { "dot", &handleFormatBlock, TRUE }, - { "msc", &handleFormatBlock, TRUE }, - { "startuml", &handleFormatBlock, TRUE }, - { "code", &handleFormatBlock, TRUE }, - { "addindex", &handleAddIndex, FALSE }, - { "if", &handleIf, FALSE }, - { "ifnot", &handleIfNot, FALSE }, - { "elseif", &handleElseIf, FALSE }, - { "else", &handleElse, FALSE }, - { "endif", &handleEndIf, FALSE }, - { "ingroup", &handleIngroup, TRUE }, - { "nosubgrouping", &handleNoSubGrouping, FALSE }, - { "showinitializer", &handleShowInitializer, FALSE }, - { "hideinitializer", &handleHideInitializer, FALSE }, - { "callgraph", &handleCallgraph, FALSE }, - { "hidecallgraph", &handleHideCallgraph, FALSE }, - { "callergraph", &handleCallergraph, FALSE }, - { "hidecallergraph", &handleHideCallergraph, FALSE }, - { "showrefby", &handleReferencedByRelation, FALSE }, - { "hiderefby", &handleHideReferencedByRelation, FALSE }, - { "showrefs", &handleReferencesRelation, FALSE }, - { "hiderefs", &handleHideReferencesRelation, FALSE }, - { "internal", &handleInternal, TRUE }, - { "_linebr", &handleLineBr, FALSE }, - { "static", &handleStatic, FALSE }, - { "pure", &handlePure, FALSE }, - { "private", &handlePrivate, FALSE }, - { "privatesection", &handlePrivateSection, FALSE }, - { "protected", &handleProtected, FALSE }, - { "protectedsection",&handleProtectedSection, FALSE }, - { "public", &handlePublic, FALSE }, - { "publicsection", &handlePublicSection, FALSE }, - { "tableofcontents", &handleToc, FALSE }, - { "inherit", &handleInherit, TRUE }, - { "extends", &handleExtends, TRUE }, - { "implements", &handleExtends, TRUE }, - { "memberof", &handleMemberOf, TRUE }, - { "arg", 0, TRUE }, - { "attention", 0, TRUE }, - { "author", 0, TRUE }, - { "authors", 0, TRUE }, - { "copydoc", &handleCopyDoc, TRUE }, - { "copybrief", &handleCopyBrief, FALSE }, - { "copydetails", &handleCopyDetails, TRUE }, - { "copyright", 0, TRUE }, - { "date", 0, TRUE }, - { "dotfile", 0, TRUE }, - { "htmlinclude", 0, FALSE }, - { "image", 0, TRUE }, - { "include", 0, TRUE }, - { "includelineno", 0, TRUE }, - { "invariant", 0, TRUE }, - { "latexinclude", 0, FALSE }, - { "li", 0, TRUE }, - { "line", 0, TRUE }, - { "note", 0, TRUE }, - { "par", 0, TRUE }, - { "param", &handleParam, TRUE }, - { "tparam", 0, TRUE }, - { "post", 0, TRUE }, - { "pre", 0, TRUE }, - { "remark", 0, TRUE }, - { "remarks", 0, TRUE }, - { "result", 0, TRUE }, - { "return", 0, TRUE }, - { "returns", 0, TRUE }, - { "exception", 0, TRUE }, - { "retval", &handleRetval, TRUE }, - { "sa", 0, TRUE }, - { "see", 0, TRUE }, - { "since", 0, TRUE }, - { "throw", 0, TRUE }, - { "throws", 0, TRUE }, - { "until", 0, TRUE }, - { "verbinclude", 0, FALSE }, - { "version", 0, TRUE }, - { "warning", 0, TRUE }, - { "snippet", 0, TRUE }, - { "snippetlineno", 0, TRUE }, - { "noop", &handleNoop, TRUE }, - { 0, 0, FALSE } + { "brief", { &handleBrief, FALSE }}, + { "short", { &handleBrief, FALSE }}, + { "fn", { &handleFn, TRUE }}, + { "var", { &handleFn, TRUE }}, + { "typedef", { &handleFn, TRUE }}, + { "property", { &handleFn, TRUE }}, + { "def", { &handleDef, TRUE }}, + { "overload", { &handleOverload, FALSE }}, + { "enum", { &handleEnum, TRUE }}, + { "defgroup", { &handleDefGroup, TRUE }}, + { "addtogroup", { &handleAddToGroup, TRUE }}, + { "weakgroup", { &handleWeakGroup, TRUE }}, + { "namespace", { &handleNamespace, TRUE }}, + { "package", { &handlePackage, TRUE }}, + { "class", { &handleClass, TRUE }}, + { "headerfile", { &handleHeaderFile, FALSE }}, + { "protocol", { &handleProtocol, TRUE }}, + { "category", { &handleCategory, TRUE }}, + { "union", { &handleUnion, TRUE }}, + { "struct", { &handleStruct, TRUE }}, + { "interface", { &handleInterface, TRUE }}, + { "idlexcept", { &handleIdlException, TRUE }}, + { "page", { &handlePage, TRUE }}, + { "mainpage", { &handleMainpage, TRUE }}, + { "file", { &handleFile, TRUE }}, + { "dir", { &handleDir, TRUE }}, + { "example", { &handleExample, FALSE }}, + { "details", { &handleDetails, TRUE }}, + { "name", { &handleName, FALSE }}, + { "todo", { &handleTodo, FALSE }}, // end brief will be done differently + { "test", { &handleTest, FALSE }}, // end brief will be done differently + { "bug", { &handleBug, FALSE }}, // end brief will be done differently + { "deprecated", { &handleDeprecated, FALSE }}, // end brief will be done differently + { "xrefitem", { &handleXRefItem, FALSE }}, // end brief will be done differently + { "related", { &handleRelated, TRUE }}, + { "relates", { &handleRelated, TRUE }}, + { "relatedalso", { &handleRelatedAlso, TRUE }}, + { "relatesalso", { &handleRelatedAlso, TRUE }}, + { "parblock", { &handleParBlock, TRUE }}, + { "endparblock", { &handleEndParBlock, TRUE }}, + { "refitem", { &handleRefItem, TRUE }}, + { "cite", { &handleCite, FALSE }}, + { "subpage", { &handleSubpage, TRUE }}, + { "section", { &handleSection, TRUE }}, + { "subsection", { &handleSection, TRUE }}, + { "subsubsection", { &handleSection, TRUE }}, + { "paragraph", { &handleSection, TRUE }}, + { "anchor", { &handleAnchor, TRUE }}, + { "verbatim", { &handleFormatBlock, TRUE }}, + { "latexonly", { &handleFormatBlock, FALSE }}, + { "htmlonly", { &handleFormatBlock, FALSE }}, + { "xmlonly", { &handleFormatBlock, FALSE }}, + { "docbookonly", { &handleFormatBlock, FALSE }}, + { "rtfonly", { &handleFormatBlock, FALSE }}, + { "manonly", { &handleFormatBlock, FALSE }}, + { "dot", { &handleFormatBlock, TRUE }}, + { "msc", { &handleFormatBlock, TRUE }}, + { "startuml", { &handleFormatBlock, TRUE }}, + { "code", { &handleFormatBlock, TRUE }}, + { "addindex", { &handleAddIndex, FALSE }}, + { "if", { &handleIf, FALSE }}, + { "ifnot", { &handleIfNot, FALSE }}, + { "elseif", { &handleElseIf, FALSE }}, + { "else", { &handleElse, FALSE }}, + { "endif", { &handleEndIf, FALSE }}, + { "ingroup", { &handleIngroup, TRUE }}, + { "nosubgrouping", { &handleNoSubGrouping, FALSE }}, + { "showinitializer", { &handleShowInitializer, FALSE }}, + { "hideinitializer", { &handleHideInitializer, FALSE }}, + { "callgraph", { &handleCallgraph, FALSE }}, + { "hidecallgraph", { &handleHideCallgraph, FALSE }}, + { "callergraph", { &handleCallergraph, FALSE }}, + { "hidecallergraph", { &handleHideCallergraph, FALSE }}, + { "showrefby", { &handleReferencedByRelation, FALSE }}, + { "hiderefby", { &handleHideReferencedByRelation, FALSE }}, + { "showrefs", { &handleReferencesRelation, FALSE }}, + { "hiderefs", { &handleHideReferencesRelation, FALSE }}, + { "internal", { &handleInternal, TRUE }}, + { "_linebr", { &handleLineBr, FALSE }}, + { "static", { &handleStatic, FALSE }}, + { "pure", { &handlePure, FALSE }}, + { "private", { &handlePrivate, FALSE }}, + { "privatesection", { &handlePrivateSection, FALSE }}, + { "protected", { &handleProtected, FALSE }}, + { "protectedsection",{ &handleProtectedSection, FALSE }}, + { "public", { &handlePublic, FALSE }}, + { "publicsection", { &handlePublicSection, FALSE }}, + { "tableofcontents", { &handleToc, FALSE }}, + { "inherit", { &handleInherit, TRUE }}, + { "extends", { &handleExtends, TRUE }}, + { "implements", { &handleExtends, TRUE }}, + { "memberof", { &handleMemberOf, TRUE }}, + { "arg", { 0, TRUE }}, + { "attention", { 0, TRUE }}, + { "author", { 0, TRUE }}, + { "authors", { 0, TRUE }}, + { "copydoc", { &handleCopyDoc, TRUE }}, + { "copybrief", { &handleCopyBrief, FALSE }}, + { "copydetails", { &handleCopyDetails, TRUE }}, + { "copyright", { 0, TRUE }}, + { "date", { 0, TRUE }}, + { "dotfile", { 0, TRUE }}, + { "htmlinclude", { 0, FALSE }}, + { "image", { 0, TRUE }}, + { "include", { 0, TRUE }}, + { "includelineno", { 0, TRUE }}, + { "invariant", { 0, TRUE }}, + { "latexinclude", { 0, FALSE }}, + { "li", { 0, TRUE }}, + { "line", { 0, TRUE }}, + { "note", { 0, TRUE }}, + { "par", { 0, TRUE }}, + { "param", { &handleParam, TRUE }}, + { "tparam", { 0, TRUE }}, + { "post", { 0, TRUE }}, + { "pre", { 0, TRUE }}, + { "remark", { 0, TRUE }}, + { "remarks", { 0, TRUE }}, + { "result", { 0, TRUE }}, + { "return", { 0, TRUE }}, + { "returns", { 0, TRUE }}, + { "exception", { 0, TRUE }}, + { "retval", { &handleRetval, TRUE }}, + { "sa", { 0, TRUE }}, + { "see", { 0, TRUE }}, + { "since", { 0, TRUE }}, + { "throw", { 0, TRUE }}, + { "throws", { 0, TRUE }}, + { "until", { 0, TRUE }}, + { "verbinclude", { 0, FALSE }}, + { "version", { 0, TRUE }}, + { "warning", { 0, TRUE }}, + { "snippet", { 0, TRUE }}, + { "snippetlineno", { 0, TRUE }}, + { "noop", { &handleNoop, TRUE }}, + { "rtfinclude", { 0, FALSE }}, + { "docbookinclude", { 0, FALSE }}, + { "maninclude", { 0, FALSE }}, + { "xmlinclude", { 0, FALSE }} }; -/** @brief Command mapper. - * - * Maps a command name (as found in a comment block) onto a - * specific handler function. - */ -class DocCmdMapper -{ - public: - struct Cmd - { - DocCmdFunc func; - bool endsBrief; - }; - - /** maps a command name to a handler function */ - static Cmd *map(const char *name) - { - return instance()->find(name); - } - - /** release the singleton */ - static void freeInstance() - { - delete s_instance; s_instance=0; - } - - private: - static DocCmdMapper *instance() - { - if (s_instance==0) s_instance = new DocCmdMapper; - return s_instance; - } - - DocCmdMapper() : m_map(113) - { - m_map.setAutoDelete(TRUE); - DocCmdMap *p = docCmdMap; - while (p->cmdName) - { - if (m_map.find(p->cmdName)!=0) - { - term("DocCmdMapper: command %s already added\n",p->cmdName); - } - Cmd *cmd = new Cmd; - cmd->func = p->handler; - cmd->endsBrief = p->endsBrief; - m_map.insert(p->cmdName,cmd); - p++; - } - } - - Cmd *find(const char *name) - { - return m_map.find(name); - } - QDict<Cmd> m_map; - static DocCmdMapper *s_instance; -}; - -DocCmdMapper *DocCmdMapper::s_instance=0; - -bool inInternalDocs = FALSE; - +#define YY_NO_INPUT 1 +#define YY_NO_UNISTD_H 1 #define YY_NEVER_INTERACTIVE 1 + enum XRefKind { XRef_Item, @@ -394,522 +344,97 @@ class GuardedSection * statics */ -static OutlineParserInterface *langParser; // the language parser that is calling us -static QCString inputString; // input string -static int inputPosition; // read pointer -static QCString yyFileName; // file name that is read from -static int yyLineNr; // line number in the input -static bool inBody; // was the comment found inside the body of a function? -static OutputContext inContext; // are we inside the brief, details or xref part -static bool briefEndsAtDot; // does the brief description stop at a dot? -static QCString formulaText; // Running text of a formula -static QCString formulaEnv; // environment name -static int formulaNewLines; // amount of new lines in the formula -static QCString *pOutputString; // pointer to string to which the output is appended. -static QCString outputXRef; // temp argument of todo/test/../xrefitem commands -static QCString blockName; // preformatted block name (e.g. verbatim, latexonly,...) -static XRefKind xrefKind; // kind of cross-reference command -static XRefKind newXRefKind; // -static GuardType guardType; // kind of guard for conditional section -static bool enabledSectionFound; -static QCString functionProto; // function prototype -static QStack<GuardedSection> guards; // tracks nested conditional sections (if,ifnot,..) -static Entry *current = 0; // working entry - -static bool needNewEntry; - -static QCString g_sectionLabel; -static QCString g_sectionTitle; -static int g_sectionLevel; -static QCString xrefItemKey; -static QCString newXRefItemKey; -static QCString xrefItemTitle; -static QCString xrefListTitle; -static Protection protection; - -static bool xrefAppendFlag; -static bool inGroupParamFound; -static int braceCount; -static bool insidePre; -static bool parseMore; -static int g_condCount; - -static int g_commentCount; -static QCString g_spaceBeforeCmd; -static QCString g_spaceBeforeIf; -static QCString g_copyDocArg; - -static QCString g_guardExpr; -static int g_roundCount; - -static bool g_insideParBlock; - -//----------------------------------------------------------------------------- - -static void initParser() -{ - g_sectionLabel.resize(0); - g_sectionTitle.resize(0); - Doxygen::docGroup.clearHeader(); - g_insideParBlock = FALSE; -} - -//----------------------------------------------------------------------------- - -static bool getDocSectionName(int s) -{ - switch(s) - { - case Entry::CLASSDOC_SEC: - case Entry::STRUCTDOC_SEC: - case Entry::UNIONDOC_SEC: - case Entry::EXCEPTIONDOC_SEC: - case Entry::NAMESPACEDOC_SEC: - case Entry::PROTOCOLDOC_SEC: - case Entry::CATEGORYDOC_SEC: - case Entry::ENUMDOC_SEC: - case Entry::PAGEDOC_SEC: - case Entry::VARIABLEDOC_SEC: - case Entry::MEMBERDOC_SEC: - case Entry::OVERLOADDOC_SEC: - case Entry::FILEDOC_SEC: - case Entry::DEFINEDOC_SEC: - case Entry::GROUPDOC_SEC: - case Entry::MAINPAGEDOC_SEC: - case Entry::PACKAGEDOC_SEC: - case Entry::DIRDOC_SEC: - case Entry::EXAMPLE_SEC: - case Entry::MEMBERGRP_SEC: - return TRUE; - default: - return FALSE; - } -} - -//----------------------------------------------------------------------------- - -static bool makeStructuralIndicator(Entry::Sections s) -{ - //printf("current->section=%x\n",current->section); - if (getDocSectionName(current->section)) - { - return TRUE; - } - else - { - needNewEntry = TRUE; - current->section = s; - current->fileName = yyFileName; - current->startLine = yyLineNr; - return FALSE; - } -} - -static void lineCount() -{ - for( const char* c = yytext ; *c ; ++c ) - yyLineNr += (*c == '\n') ; -} - - -static QCString stripQuotes(const char *s) -{ - QCString name; - if (s==0 || *s==0) return name; - name=s; - if (name.at(0)=='"' && name.at(name.length()-1)=='"') - { - name=name.mid(1,name.length()-2); - } - return name; -} - -//----------------------------------------------------------------- - -static void addXRefItem(const char *listName,const char *itemTitle, - const char *listTitle,bool append) -{ - if (listName==0) return; - //printf("addXRefItem(%s,%s,%s,%d)\n",listName,itemTitle,listTitle,append); - - const ListItemInfo *lii=0; - RefList *refList = Doxygen::xrefLists->find(listName); - if (refList==0) // new list - { - refList = new RefList(listName,listTitle,itemTitle); - Doxygen::xrefLists->insert(listName,refList); - //printf("new list!\n"); - } - for (const ListItemInfo &item : current->sli) - { - if (qstrcmp(item.type,listName)==0) - { - //printf("found %s lii->type=%s\n",listName,lii->type); - lii = &item; - break; - } - } - if (lii && append) // already found item of same type just before this one - { - //printf("listName=%s item id = %d existing\n",listName,lii->itemId); - RefItem *item = refList->getRefItem(lii->itemId); - ASSERT(item!=0); - item->text += " <p>"; - item->text += outputXRef; - //printf("%s: text +=%s\n",listName,item->text.data()); - } - else // new item - { - int itemId = refList->addRefItem(); - //printf("listName=%s item id = %d new current=%p\n",listName,itemId,current); - - // if we have already an item from the same list type (e.g. a second @todo) - // in the same Entry (i.e. lii!=0) then we reuse its link anchor. - char anchorLabel[1024]; - //sprintf(anchorLabel,"_%s%06d",listName,lii ? lii->itemId : itemId); - sprintf(anchorLabel,"_%s%06d",listName,itemId); - RefItem *item = refList->getRefItem(itemId); - ASSERT(item!=0); - item->text = outputXRef; - item->listAnchor = anchorLabel; - current->addSpecialListItem(listName,itemId); - QCString cmdString; - cmdString.sprintf(" \\xrefitem %s %d.",listName,itemId); - if (inBody) - { - current->inbodyDocs += cmdString; - } - else - { - current->doc += cmdString; - } - SectionInfo *si = Doxygen::sectionDict->find(anchorLabel); - if (si) - { - if (si->lineNr != -1) - { - warn(listName,yyLineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",anchorLabel,si->fileName.data(),si->lineNr); - } - else - { - warn(listName,yyLineNr,"multiple use of section label '%s', (first occurrence: %s)",anchorLabel,si->fileName.data()); - } - } - else - { - si=new SectionInfo(listName,yyLineNr,anchorLabel, - g_sectionTitle,SectionInfo::Anchor, - g_sectionLevel); - Doxygen::sectionDict->append(anchorLabel,si); - current->anchors.push_back(si); - } - } - outputXRef.resize(0); -} - -//----------------------------------------------------------------------------- - -// Adds a formula text to the list/dictionary of formulas if it was -// not already added. Returns the label of the formula. -static QCString addFormula() -{ - QCString formLabel; - QCString fText=formulaText.simplifyWhiteSpace(); - Formula *f=0; - if ((f=Doxygen::formulaDict->find(fText))==0) - { - f = new Formula(fText); - Doxygen::formulaList->append(f); - Doxygen::formulaDict->insert(fText,f); - formLabel.sprintf("\\_form#%d",f->getId()); - Doxygen::formulaNameDict->insert(formLabel,f); - } - else - { - formLabel.sprintf("\\_form#%d",f->getId()); - } - int i; - for (i=0;i<formulaNewLines;i++) formLabel+="@_fakenl"; // add fake newlines to - // keep the warnings - // correctly aligned. - return formLabel; -} - -//----------------------------------------------------------------------------- +struct commentscanYY_state +{ + OutlineParserInterface *langParser = 0; // the language parser that is calling us + QCString inputString; // input string + int inputPosition = 0; // read pointer + QCString fileName; // file name that is read from + int lineNr = 0; // line number in the input + bool inBody = FALSE; // was the comment found inside the body of a function? + OutputContext inContext; // are we inside the brief, details or xref part + bool briefEndsAtDot = FALSE; // does the brief description stop at a dot? + QCString formulaText; // Running text of a formula + QCString formulaEnv; // environment name + int formulaNewLines = 0; // amount of new lines in the formula + QCString *pOutputString = 0; // pointer to string to which the output is appended. + QCString outputXRef; // temp argument of todo/test/../xrefitem commands + QCString blockName; // preformatted block name (e.g. verbatim, latexonly,...) + XRefKind xrefKind = XRef_Item; // kind of cross-reference command + XRefKind newXRefKind = XRef_Item; // + GuardType guardType = Guard_If; // kind of guards for conditional section + bool enabledSectionFound = FALSE; + QCString functionProto; // function prototype + std::stack<GuardedSection> guards; // tracks nested conditional sections (if,ifnot,..) + Entry *current = 0; // working entry + + bool needNewEntry = FALSE; + + QCString sectionLabel; + QCString sectionTitle; + int sectionLevel = 0; + QCString xrefItemKey; + QCString newXRefItemKey; + QCString xrefItemTitle; + QCString xrefListTitle; + Protection protection = Public; + + bool xrefAppendFlag = FALSE; + bool inGroupParamFound = FALSE; + int braceCount = 0; + bool insidePre = FALSE; + bool parseMore = FALSE; + int condCount = 0; + + int commentCount = 0; + QCString spaceBeforeCmd; + QCString spaceBeforeIf; + QCString copyDocArg; + + QCString guardExpr; + int roundCount = 0; + + bool insideParBlock = FALSE; + bool inInternalDocs = FALSE; + int prevPosition = 0; + DocGroup docGroup; +}; -static void checkFormula(); //----------------------------------------------------------------------------- -static SectionInfo::SectionType sectionLevelToType(int level) -{ - if (level>=0 && level<5) return (SectionInfo::SectionType)level; - return SectionInfo::Anchor; -} - -static void addSection() -{ - SectionInfo *si = Doxygen::sectionDict->find(g_sectionLabel); - if (si) - { - if (si->lineNr != -1) - { - warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding section, (first occurrence: %s, line %d)",g_sectionLabel.data(),si->fileName.data(),si->lineNr); - } - else - { - warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding section, (first occurrence: %s)",g_sectionLabel.data(),si->fileName.data()); - } - } - else - { - // create a new section element - g_sectionTitle+=yytext; - g_sectionTitle=g_sectionTitle.stripWhiteSpace(); - si = new SectionInfo(yyFileName,yyLineNr,g_sectionLabel, - g_sectionTitle,sectionLevelToType(g_sectionLevel),g_sectionLevel); - - // add section to this entry - current->anchors.push_back(si); - - // add section to the global dictionary - Doxygen::sectionDict->append(g_sectionLabel,si); - } -} +static QCString stripQuotes(const char *s); +static bool getDocSectionName(int s); +static SectionType sectionLevelToType(int level); +static void stripTrailingWhiteSpace(QCString &s); + +static void initParser(yyscan_t yyscanner); +static bool makeStructuralIndicator(yyscan_t yyscanner,Entry::Sections s); +static void lineCount(yyscan_t yyscanner); +static void addXRefItem(yyscan_t yyscanner, + const char *listName,const char *itemTitle, + const char *listTitle,bool append); +static QCString addFormula(yyscan_t yyscanner); +static void checkFormula(yyscan_t yyscanner); +static void addSection(yyscan_t yyscanner); +static inline void setOutput(yyscan_t yyscanner,OutputContext ctx); +static void addAnchor(yyscan_t yyscanner,const char *anchor); +static inline void addOutput(yyscan_t yyscanner,const char *s); +static inline void addOutput(yyscan_t yyscanner,char c); +static void endBrief(yyscan_t yyscanner,bool addToOutput=TRUE); +static void handleGuard(yyscan_t yyscanner,const QCString &expr); +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +static void addCite(yyscan_t yyscanner); //----------------------------------------------------------------------------- -static void addCite() -{ - QCString name=yytext; - if (yytext[0] =='"') - { - name=yytext+1; - name=name.left(yyleng-2); - } - Doxygen::citeDict->insert(name.data()); -} - -//----------------------------------------------------------------------------- -// strip trailing whitespace (excluding newlines) from string s -static void stripTrailingWhiteSpace(QCString &s) -{ - uint len = s.length(); - int i = (int)len-1; - char c; - while (i>=0 && ((c = s.at(i))==' ' || c=='\t' || c=='\r')) i--; - if (i!=(int)len-1) - { - s.resize(i+2); // string up to and including char at pos i and \0 terminator - } -} - -// selects the output to write to -static inline void setOutput(OutputContext ctx) -{ - bool xrefAppendToPrev = xrefAppendFlag; - // determine append flag for the next item (i.e. the end of this item) - xrefAppendFlag = !inBody && - inContext==OutputXRef && ctx==OutputXRef && // two consecutive xref items - newXRefKind==xrefKind && // of the same kind - (xrefKind!=XRef_Item || - newXRefItemKey==xrefItemKey); // with the same key if \xrefitem - //printf("%d && %d && %d && (%d || %d)\n", - // inContext==OutputXRef, - // ctx==OutputXRef, - // newXRefKind==xrefKind, - // xrefKind!=XRef_Item, - // newXRefItemKey==xrefItemKey); - - //printf("refKind=%d newXRefKind=%d xrefAppendToPrev=%d xrefAppendFlag=%d\n", - // xrefKind,newXRefKind,xrefAppendToPrev,xrefAppendFlag); - - //printf("setOutput(inContext=%d ctx=%d)\n",inContext,ctx); - if (inContext==OutputXRef) // end of XRef section => add the item - { - // See if we can append this new xref item to the previous one. - // We know this at the start of the next item of the same - // type and need to remember this until the end of that item. - switch(xrefKind) - { - case XRef_Todo: - addXRefItem("todo", - theTranslator->trTodo(), - theTranslator->trTodoList(), - xrefAppendToPrev - ); - break; - case XRef_Test: - addXRefItem("test", - theTranslator->trTest(), - theTranslator->trTestList(), - xrefAppendToPrev - ); - break; - case XRef_Bug: - addXRefItem("bug", - theTranslator->trBug(), - theTranslator->trBugList(), - xrefAppendToPrev - ); - break; - case XRef_Deprecated: - addXRefItem("deprecated", - theTranslator->trDeprecated(), - theTranslator->trDeprecatedList(), - xrefAppendToPrev - ); - break; - case XRef_Item: // user defined list - addXRefItem(xrefItemKey, - xrefItemTitle, - xrefListTitle, - xrefAppendToPrev - ); - break; - case XRef_None: - ASSERT(0); - break; - } - } - xrefItemKey = newXRefItemKey; - - int oldContext = inContext; - inContext = ctx; - if (inContext!=OutputXRef && inBody) inContext=OutputInbody; - switch(inContext) - { - case OutputDoc: - if (oldContext!=inContext) - { - stripTrailingWhiteSpace(current->doc); - if (current->docFile.isEmpty()) - { - current->docFile = yyFileName; - current->docLine = yyLineNr; - } - } - pOutputString = ¤t->doc; - break; - case OutputBrief: - if (oldContext!=inContext) - { - if (current->briefFile.isEmpty()) - { - current->briefFile = yyFileName; - current->briefLine = yyLineNr; - } - } - if (current->brief.stripWhiteSpace().isEmpty()) // we only want one brief - // description even if multiple - // are given... - { - pOutputString = ¤t->brief; - } - else - { - if (!current->doc.isEmpty()) // when appending parts add a new line - { - current->doc += "\n"; - } - pOutputString = ¤t->doc; - inContext = OutputDoc; // need to switch to detailed docs, see bug 631380 - } - break; - case OutputXRef: - pOutputString = &outputXRef; - // first item found, so can't append to previous - //xrefAppendFlag = FALSE; - break; - case OutputInbody: - pOutputString = ¤t->inbodyDocs; - break; - } -} - - -static void addAnchor(const char *anchor) -{ - SectionInfo *si = Doxygen::sectionDict->find(anchor); - if (si) - { - if (si->lineNr != -1) - { - warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding anchor, (first occurrence: %s, line %d)",anchor,si->fileName.data(),si->lineNr); - } - else - { - warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding anchor, (first occurrence: %s)",anchor,si->fileName.data()); - } - } - else - { - si = new SectionInfo(yyFileName,yyLineNr,anchor,0,SectionInfo::Anchor,0); - Doxygen::sectionDict->append(anchor,si); - current->anchors.push_back(si); - } -} - -// add a string to the output -static inline void addOutput(const char *s) -{ - //printf("addOutput(%s)\n",s); - *pOutputString+=s; -} - -// add a character to the output -static inline void addOutput(char c) -{ - *pOutputString+=c; -} - -static void endBrief(bool addToOutput=TRUE) -{ - if (!current->brief.stripWhiteSpace().isEmpty()) - { // only go to the detailed description if we have - // found some brief description and not just whitespace - briefEndsAtDot=FALSE; - setOutput(OutputDoc); - if (addToOutput) addOutput(yytext); - } -} - -static void handleGuard(const QCString &expr); -/* ----------------------------------------------------------------- */ #undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); - -static int prevPosition=0; - -static int yyread(char *buf,int max_size) -{ - prevPosition=inputPosition; - int c=0; - while( c < max_size && inputString[inputPosition] ) - { - *buf = inputString[inputPosition++] ; - //printf("%d (%c)\n",*buf,*buf); - c++; buf++; - } - return c; -} +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); %} /* start command character */ CMD ("\\"|"@") -DCMD1 ("arg"|"attention"|"author"|"cite"|"code") -DCMD2 ("date"|"dot"|"msc"|"dotfile"|"example"|"startuml") -DCMD3 ("htmlinclude"|"htmlonly"|"image"|"include") -DCMD4 ("includelineno"|"internal"|"invariant") -DCMD5 ("latexinclude"|"latexonly"|"li"|"line"|"manonly"|"name") -DCMD6 ("note"|"par"|"paragraph"|"param"|"post") -DCMD7 ("pre"|"remarks"|(("relate"[sd])("also")?)) -DCMD8 ("remarks"|("return"[s]?)|"retval"|"sa"|"section") -DCMD9 ("see"|"since"|"subsection"|"subsubsection") -DCMD10 ("throw"|"until"|"verbatim") -DCMD11 ("verbinclude"|"version"|"warning") -DETAILEDCMD {CMD}({DCMD1}|{DCMD2}|{DCMD3}|{DCMD4}|{DCMD5}|{DCMD6}|{DCMD7}|{DCMD8}|{DCMD9}|{DCMD10}|{DCMD11}) XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem") PRE [pP][rR][eE] TABLE [tT][aA][bB][lL][eE] @@ -1016,50 +541,50 @@ RCSTAG "$"{ID}":"[^\n$]+"$" */ <Comment>{CMD}{CMD}[a-z_A-Z]+{B}* { // escaped command - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>{MAILADDR} { // mail address - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>"\""[^"\n]*"\"" { // quoted text - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!) - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description - setOutput(OutputDoc); + setOutput(yyscanner,OutputDoc); // continue with the same input REJECT; } <Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML command that ends a brief description - if (current->lang==SrcLangExt_CSharp) + if (yyextra->current->lang==SrcLangExt_CSharp) { - setOutput(OutputDoc); + setOutput(yyscanner,OutputDoc); } // continue with the same input REJECT; } <Comment>"<summary>" { // start of a .NET XML style brief description - setOutput(OutputBrief); - addOutput(yytext); + setOutput(yyscanner,OutputBrief); + addOutput(yyscanner,yytext); } <Comment>"<remarks>" { // start of a .NET XML style detailed description - setOutput(OutputDoc); - addOutput(yytext); + setOutput(yyscanner,OutputDoc); + addOutput(yyscanner,yytext); } <Comment>"</summary>" { // start of a .NET XML style detailed description - setOutput(OutputBrief); - addOutput(yytext); - setOutput(OutputDoc); + setOutput(yyscanner,OutputBrief); + addOutput(yyscanner,yytext); + setOutput(yyscanner,OutputDoc); } <Comment>"</remarks>" { // end of a brief or detailed description - setOutput(OutputDoc); - addOutput(yytext); + setOutput(yyscanner,OutputDoc); + addOutput(yyscanner,yytext); } <Comment>"<"{CAPTION}{ATTR}">" { QCString tag=yytext; @@ -1073,22 +598,22 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (e!=-1) // found matching end { QCString id=tag.mid(s+4,e-s-4); // extract id - addAnchor(id); + addAnchor(yyscanner,id); } } } - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>"<"{PRE}{ATTR}">" { - insidePre=TRUE; - addOutput(yytext); + yyextra->insidePre=TRUE; + addOutput(yyscanner,yytext); } <Comment>"</"{PRE}">" { - insidePre=FALSE; - addOutput(yytext); + yyextra->insidePre=FALSE; + addOutput(yyscanner,yytext); } <Comment>{RCSTAG} { // RCS tag which end a brief description - setOutput(OutputDoc); + setOutput(yyscanner,OutputDoc); REJECT; } <Comment>"<!--" { @@ -1098,12 +623,12 @@ RCSTAG "$"{ID}":"[^\n$]+"$" BEGIN(CdataSection); } <Comment>{B}*{CMD}"endinternal"{B}* { - addOutput(" \\endinternal "); - if (!inInternalDocs) - warn(yyFileName,yyLineNr, + addOutput(yyscanner," \\endinternal "); + if (!yyextra->inInternalDocs) + warn(yyextra->fileName,yyextra->lineNr, "found \\endinternal without matching \\internal" ); - inInternalDocs = FALSE; + yyextra->inInternalDocs = FALSE; } <Comment>{B}*{CMD}[a-z_A-Z]+"{"[a-zA-Z_,:0-9\. ]*"}"{B}* | <Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command @@ -1125,51 +650,51 @@ RCSTAG "$"{ID}":"[^\n$]+"$" QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); optList = QCStringList::split(',',optStr); } - DocCmdMapper::Cmd *cmdPtr = DocCmdMapper::map(cmdName); - if (cmdPtr) // special action is required + auto it = docCmdMap.find(cmdName.data()); + if (it!=docCmdMap.end()) // special action is required { int i=0; while (yytext[i]==' ' || yytext[i]=='\t') i++; - g_spaceBeforeCmd = QCString(yytext).left(i); - if (cmdPtr->endsBrief && !(inContext==OutputXRef && cmdName=="parblock")) + yyextra->spaceBeforeCmd = QCString(yytext).left(i); + if (it->second.endsBrief && !(yyextra->inContext==OutputXRef && cmdName=="parblock")) { - briefEndsAtDot=FALSE; + yyextra->briefEndsAtDot=FALSE; // this command forces the end of brief description - setOutput(OutputDoc); + setOutput(yyscanner,OutputDoc); } - //if (i>0) addOutput(QCString(yytext).left(i)); // removed for bug 689341 - if (cmdPtr->func && cmdPtr->func(cmdName, optList)) + //if (i>0) addOutput(yyscanner,QCString(yytext).left(i)); // removed for bug 689341 + if (it->second.handler && it->second.handler(yyscanner, cmdName, optList)) { // implicit split of the comment block into two // entries. Restart the next block at the start // of this command. - parseMore=TRUE; + yyextra->parseMore=TRUE; // yuk, this is probably not very portable across lex implementations, // but we need to know the position in the input buffer where this // rule matched. // for flex 2.5.33+ we should use YY_CURRENT_BUFFER_LVALUE #if YY_FLEX_MAJOR_VERSION>=2 && (YY_FLEX_MINOR_VERSION>5 || (YY_FLEX_MINOR_VERSION==5 && YY_FLEX_SUBMINOR_VERSION>=33)) - inputPosition=prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); + yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); #else - inputPosition=prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf); + yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf); #endif yyterminate(); } - else if (cmdPtr->func==0) + else if (it->second.handler==0) { // command without handler, to be processed // later by parsedoc.cpp - addOutput(yytext); + addOutput(yyscanner,yytext); } } else // command not relevant { - addOutput(yytext); + addOutput(yyscanner,yytext); } } <Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command QCString langId = QCString(yytext).stripWhiteSpace().data()+2; @@ -1180,54 +705,54 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } } <Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment - setOutput(OutputDoc); - formulaText="\\begin"; - formulaEnv=QCString(yytext).stripWhiteSpace().data()+2; - if (formulaEnv.at(formulaEnv.length()-1)=='{') + setOutput(yyscanner,OutputDoc); + yyextra->formulaText="\\begin"; + yyextra->formulaEnv=QCString(yytext).stripWhiteSpace().data()+2; + if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{') { // remove trailing open brace - formulaEnv=formulaEnv.left(formulaEnv.length()-1); + yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1); } - formulaText+=formulaEnv; - formulaNewLines=0; + yyextra->formulaText+=yyextra->formulaEnv; + yyextra->formulaNewLines=0; BEGIN(ReadFormulaLong); } <Comment>{B}*{CMD}"f$" { // start of a inline formula - formulaText="$"; - formulaNewLines=0; + yyextra->formulaText="$"; + yyextra->formulaNewLines=0; BEGIN(ReadFormulaShort); } <Comment>{B}*{CMD}"f[" { // start of a block formula - setOutput(OutputDoc); - formulaText="\\["; - formulaNewLines=0; + setOutput(yyscanner,OutputDoc); + yyextra->formulaText="\\["; + yyextra->formulaNewLines=0; BEGIN(ReadFormulaLong); } <Comment>{B}*{CMD}"{" { // begin of a group - //langParser->handleGroupStartCommand(g_memberGroupHeader); - Doxygen::docGroup.open(current,yyFileName,yyLineNr); + //yyextra->langParser->handleGroupStartCommand(yyextra->memberGroupHeader); + yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr); } <Comment>{B}*{CMD}"}" { // end of a group - //langParser->handleGroupEndCommand(); - Doxygen::docGroup.close(current,yyFileName,yyLineNr,TRUE); - Doxygen::docGroup.clearHeader(); - parseMore=TRUE; - needNewEntry = TRUE; + //yyextra->langParser->handleGroupEndCommand(); + yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,TRUE); + yyextra->docGroup.clearHeader(); + yyextra->parseMore=TRUE; + yyextra->needNewEntry = TRUE; #if YY_FLEX_MAJOR_VERSION>=2 && (YY_FLEX_MINOR_VERSION>5 || (YY_FLEX_MINOR_VERSION==5 && YY_FLEX_SUBMINOR_VERSION>=33)) - inputPosition=prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + strlen(yytext); + yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext); #else - inputPosition=prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf) + strlen(yytext); + yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf) + (int)strlen(yytext); #endif yyterminate(); } <Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>[a-z_A-Z]+ { // normal word - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>^{B}*"."{B}*/\n { // explicit end autolist: e.g " ." - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>^{B}*[1-9][0-9]*"."{B}+ | <Comment>^{B}*[*+]{B}+ { // start of autolist @@ -1237,106 +762,106 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } else { - if (inContext!=OutputXRef) + if (yyextra->inContext!=OutputXRef) { - briefEndsAtDot=FALSE; - setOutput(OutputDoc); + yyextra->briefEndsAtDot=FALSE; + setOutput(yyscanner,OutputDoc); } - addOutput(yytext); + addOutput(yyscanner,yytext); } } <Comment>^{B}*"-"{B}+ { // start of autolist - if (inContext!=OutputXRef) + if (yyextra->inContext!=OutputXRef) { - briefEndsAtDot=FALSE; - setOutput(OutputDoc); + yyextra->briefEndsAtDot=FALSE; + setOutput(yyscanner,OutputDoc); } - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{B}*/\n { // horizontal line (dashed) - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>{CMD}"---" { // escaped mdash - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>{CMD}"--" { // escaped mdash - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>"---" { // mdash - addOutput(insidePre || Doxygen::markdownSupport ? yytext : "—"); + addOutput(yyscanner,yyextra->insidePre || Doxygen::markdownSupport ? yytext : "—"); } <Comment>"--" { // ndash - addOutput(insidePre || Doxygen::markdownSupport ? yytext : "–"); + addOutput(yyscanner,yyextra->insidePre || Doxygen::markdownSupport ? yytext : "–"); } <Comment>"-#"{B}+ { // numbered item - if (inContext!=OutputXRef) + if (yyextra->inContext!=OutputXRef) { - briefEndsAtDot=FALSE; - setOutput(OutputDoc); + yyextra->briefEndsAtDot=FALSE; + setOutput(yyscanner,OutputDoc); } - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>".\\"[ \t] { // . with escaped space. - addOutput(yytext[0]); - addOutput(yytext[2]); + addOutput(yyscanner,yytext[0]); + addOutput(yyscanner,yytext[2]); } <Comment>".," { // . with comma such as "e.g.," - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>"...\\"[ \t] { // ellipsis with escaped space. - addOutput("... "); + addOutput(yyscanner,"... "); } <Comment>".."[\.]?/[^ \t\n] { // internal ellipsis - addOutput(yytext); + addOutput(yyscanner,yytext); } <Comment>(\n|\\_linebr)({B}*(\n|\\_linebr))+ { // at least one blank line (or blank line command) - if (inContext==OutputXRef) + if (yyextra->inContext==OutputXRef) { // see bug 613024, we need to put the newlines after ending the XRef section. - if (!g_insideParBlock) setOutput(OutputDoc); - int i; - for (i=0;i<yyleng;) + if (!yyextra->insideParBlock) setOutput(yyscanner,OutputDoc); + yy_size_t i; + for (i=0;i<(yy_size_t)yyleng;) { - if (yytext[i]=='\n') addOutput('\n'),i++; - else if (strcmp(yytext+i,"\\_linebr")==0) addOutput('\n'),i+=8; + if (yytext[i]=='\n') addOutput(yyscanner,'\n'),i++; + else if (strcmp(yytext+i,"\\_linebr")==0) addOutput(yyscanner,'\n'),i+=8; else i++; } } - else if (inContext!=OutputBrief) + else if (yyextra->inContext!=OutputBrief) { - int i; - for (i=0;i<yyleng;) + yy_size_t i; + for (i=0;i<(yy_size_t)yyleng;) { - if (yytext[i]=='\n') addOutput('\n'),i++; - else if (strcmp(yytext+i,"\\_linebr")==0) addOutput('\n'),i+=8; + if (yytext[i]=='\n') addOutput(yyscanner,'\n'),i++; + else if (strcmp(yytext+i,"\\_linebr")==0) addOutput(yyscanner,'\n'),i+=8; else i++; } - setOutput(OutputDoc); + setOutput(yyscanner,OutputDoc); } - else // inContext==OutputBrief + else // yyextra->inContext==OutputBrief { // only go to the detailed description if we have // found some brief description and not just whitespace - endBrief(FALSE); + endBrief(yyscanner,FALSE); } - lineCount(); + lineCount(yyscanner); } <Comment>"." { // potential end of a JavaDoc style comment - addOutput(*yytext); - if (briefEndsAtDot) + addOutput(yyscanner,*yytext); + if (yyextra->briefEndsAtDot) { - setOutput(OutputDoc); - briefEndsAtDot=FALSE; + setOutput(yyscanner,OutputDoc); + yyextra->briefEndsAtDot=FALSE; } } <Comment>\n { // newline - addOutput(*yytext); - yyLineNr++; + addOutput(yyscanner,*yytext); + yyextra->lineNr++; } <Comment>. { // catch-all for anything else - addOutput(*yytext); + addOutput(yyscanner,*yytext); } @@ -1344,7 +869,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); } <HtmlComment>{DOCNL} { - if (*yytext=='\n') yyLineNr++; + if (*yytext=='\n') yyextra->lineNr++; } <HtmlComment>[^\\\n\-]+ { // ignore unimportant characters } @@ -1355,66 +880,66 @@ RCSTAG "$"{ID}":"[^\n$]+"$" BEGIN( Comment ); } <CdataSection>{DOCNL} { - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; } <CdataSection>[<>&] { // the special XML characters for iwhich the CDATA section is especially used - addOutput('\\'); - addOutput(*yytext); + addOutput(yyscanner,'\\'); + addOutput(yyscanner,*yytext); } <CdataSection>[^\\\n\]<>&]+ { - addOutput(yytext); + addOutput(yyscanner,yytext); } <CdataSection>. { - addOutput(*yytext); + addOutput(yyscanner,*yytext); } /* -------------- Rules for handling formulas ---------------- */ <ReadFormulaShort>{CMD}"f$" { // end of inline formula - formulaText+="$"; - addOutput(" "+addFormula()); + yyextra->formulaText+="$"; + addOutput(yyscanner," "+addFormula(yyscanner)); BEGIN(Comment); } <ReadFormulaLong>{CMD}"f]" { // end of block formula - formulaText+="\\]"; - addOutput(" "+addFormula()); + yyextra->formulaText+="\\]"; + addOutput(yyscanner," "+addFormula(yyscanner)); BEGIN(Comment); } <ReadFormulaLong>{CMD}"f}" { // end of custom env formula - formulaText+="\\end"; - formulaText+=formulaEnv; - addOutput(" "+addFormula()); + yyextra->formulaText+="\\end"; + yyextra->formulaText+=yyextra->formulaEnv; + addOutput(yyscanner," "+addFormula(yyscanner)); BEGIN(Comment); } <ReadFormulaLong,ReadFormulaShort>[^\\@\n]+ { // any non-special character - formulaText+=yytext; + yyextra->formulaText+=yytext; } <ReadFormulaLong,ReadFormulaShort>\n { // new line - formulaNewLines++; - formulaText+=*yytext; - yyLineNr++; + yyextra->formulaNewLines++; + yyextra->formulaText+=*yytext; + yyextra->lineNr++; } <ReadFormulaLong,ReadFormulaShort>. { // any other character - formulaText+=*yytext; + yyextra->formulaText+=*yytext; } /* ------------ handle argument of enum command --------------- */ <EnumDocArg1>{SCOPEID} { // handle argument - current->name = yytext; + yyextra->current->name = yytext; BEGIN( Comment ); } <EnumDocArg1>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <EnumDocArg1>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing argument after \\enum." ); - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <EnumDocArg1>. { // ignore other stuff @@ -1423,20 +948,20 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ------------ handle argument of namespace command --------------- */ <NameSpaceDocArg1>{SCOPENAME} { // handle argument - current->name = substitute(yytext,".","::"); + yyextra->current->name = substitute(yytext,".","::"); BEGIN( Comment ); } <NameSpaceDocArg1>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <NameSpaceDocArg1>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing argument after " "\\namespace." ); - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <NameSpaceDocArg1>. { // ignore other stuff @@ -1445,20 +970,20 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ------------ handle argument of package command --------------- */ <PackageDocArg1>{ID}("."{ID})* { // handle argument - current->name = yytext; + yyextra->current->name = yytext; BEGIN( Comment ); } <PackageDocArg1>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <PackageDocArg1>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing argument after " "\\package." ); - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <PackageDocArg1>. { // ignore other stuff @@ -1467,64 +992,64 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ------ handle argument of class/struct/union command --------------- */ <ClassDocArg1>{SCOPENAME}{TMPLSPEC} { - current->name = substitute(removeRedundantWhiteSpace(yytext),".","::"); + yyextra->current->name = substitute(removeRedundantWhiteSpace(yytext),".","::"); BEGIN( ClassDocArg2 ); } <ClassDocArg1>{SCOPENAME} { // first argument - current->name = substitute(yytext,".","::"); - if (current->section==Entry::PROTOCOLDOC_SEC) + yyextra->current->name = substitute(yytext,".","::"); + if (yyextra->current->section==Entry::PROTOCOLDOC_SEC) { - current->name+="-p"; + yyextra->current->name+="-p"; } // prepend outer scope name BEGIN( ClassDocArg2 ); } <CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" { - current->name = substitute(yytext,".","::"); + yyextra->current->name = substitute(yytext,".","::"); BEGIN( ClassDocArg2 ); } <ClassDocArg1,CategoryDocArg1>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <ClassDocArg1,CategoryDocArg1>{DOCNL} { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing argument after " "\\%s.",YY_START==ClassDocArg1?"class":"category" ); - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <ClassDocArg1,CategoryDocArg1>. { // ignore other stuff } <ClassDocArg2>{FILE}|"<>" { // second argument; include file - current->includeFile = yytext; + yyextra->current->includeFile = yytext; BEGIN( ClassDocArg3 ); } <ClassDocArg2>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <ClassDocArg2>{DOCNL} { - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <ClassDocArg2>. { // ignore other stuff } <ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name - current->includeName = yytext; + yyextra->current->includeName = yytext; BEGIN( Comment ); } <ClassDocArg3>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <ClassDocArg3>{DOCNL} { - if (*yytext=='\n') yyLineNr++; + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <ClassDocArg3>. { // ignore other stuff @@ -1533,83 +1058,83 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* --------- handle arguments of {def,add,weak}group commands --------- */ <GroupDocArg1>{LABELID}(".html"?) { // group name - current->name = yytext; + yyextra->current->name = yytext; //lastDefGroup.groupname = yytext; - //lastDefGroup.pri = current->groupingPri(); + //lastDefGroup.pri = yyextra->current->groupingPri(); // the .html stuff is for Qt compatibility - if (current->name.right(5)==".html") + if (yyextra->current->name.right(5)==".html") { - current->name=current->name.left(current->name.length()-5); + yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5); } - current->type.resize(0); + yyextra->current->type.resize(0); BEGIN(GroupDocArg2); } <GroupDocArg1>"\\"{B}*"\n" { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <GroupDocArg1>{DOCNL} { // missing argument! - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing group name after %s", - current->groupDocCmd() + yyextra->current->groupDocCmd() ); - addOutput('\n'); - if (*yytext=='\n') yyLineNr++; + addOutput(yyscanner,'\n'); + if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); } <GroupDocArg1>. { // ignore other stuff } <GroupDocArg2>"\\"{B}*"\n" { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <GroupDocArg2>[^\n\\]+ { // title (stored in type) - current->type += yytext; - current->type = current->type.stripWhiteSpace(); + yyextra->current->type += yytext; + yyextra->current->type = yyextra->current->type.stripWhiteSpace(); } <GroupDocArg2>{DOCNL} { - if ( current->groupDocType==Entry::GROUPDOC_NORMAL && - current->type.isEmpty() + if ( yyextra->current->groupDocType==Entry::GROUPDOC_NORMAL && + yyextra->current->type.isEmpty() ) // defgroup requires second argument { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing title after " - "\\defgroup %s", current->name.data() + "\\defgroup %s", yyextra->current->name.data() ); } - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <GroupDocArg2>. { // title (stored in type) - current->type += yytext; - current->type = current->type.stripWhiteSpace(); + yyextra->current->type += yytext; + yyextra->current->type = yyextra->current->type.stripWhiteSpace(); } /* --------- handle arguments of page/mainpage command ------------------- */ <PageDocArg1>{FILE} { // first argument; page name - current->name = stripQuotes(yytext); - current->args = ""; + yyextra->current->name = stripQuotes(yytext); + yyextra->current->args = ""; BEGIN( PageDocArg2 ); } -<PageDocArg1>{LC} { yyLineNr++; - addOutput('\n'); +<PageDocArg1>{LC} { yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <PageDocArg1>{DOCNL} { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "missing argument after " "\\page." ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <PageDocArg1>. { // ignore other stuff } <PageDocArg2>{DOCNL} { // second argument; page title - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <PageDocArg2>{CMD}[<>] { @@ -1617,20 +1142,20 @@ RCSTAG "$"{ID}":"[^\n$]+"$" QCString tmp = yytext; tmp = substitute(substitute(tmp,"@<","<"),"@>",">"); tmp = substitute(substitute(tmp,"\\<","<"),"\\>",">"); - current->args += tmp; + yyextra->current->args += tmp; } <PageDocArg2>. { - current->args += yytext; + yyextra->current->args += yytext; } /* --------- handle arguments of the param command ------------ */ <ParamArg1>{ID}/{B}*"," { - addOutput(yytext); + addOutput(yyscanner,yytext); } <ParamArg1>"," { - addOutput(" , "); + addOutput(yyscanner," , "); } <ParamArg1>{ID} { - addOutput(yytext); + addOutput(yyscanner,yytext); BEGIN( Comment ); } <ParamArg1>. { @@ -1641,16 +1166,16 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* --------- handle arguments of the file/dir/example command ------------ */ <FileDocArg1>{DOCNL} { // no file name specified - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <FileDocArg1>{FILE} { // first argument; name - current->name = stripQuotes(yytext); + yyextra->current->name = stripQuotes(yytext); BEGIN( Comment ); } -<FileDocArg1>{LC} { yyLineNr++; - addOutput('\n'); +<FileDocArg1>{LC} { yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <FileDocArg1>. { // ignore other stuff } @@ -1658,62 +1183,62 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* --------- handle arguments of the xrefitem command ------------ */ <XRefItemParam1>{LABELID} { // first argument - newXRefItemKey=yytext; - setOutput(OutputXRef); + yyextra->newXRefItemKey=yytext; + setOutput(yyscanner,OutputXRef); BEGIN(XRefItemParam2); } <XRefItemParam1>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <XRefItemParam1>{DOCNL} { // missing arguments - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Missing first argument of \\xrefitem" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); - inContext = OutputDoc; + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); + yyextra->inContext = OutputDoc; BEGIN( Comment ); } <XRefItemParam1>. { // ignore other stuff } <XRefItemParam2>"\""[^\n\"]*"\"" { // second argument - xrefItemTitle = stripQuotes(yytext); + yyextra->xrefItemTitle = stripQuotes(yytext); BEGIN(XRefItemParam3); } <XRefItemParam2>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <XRefItemParam2>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Missing second argument of \\xrefitem" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); - inContext = OutputDoc; + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); + yyextra->inContext = OutputDoc; BEGIN( Comment ); } <XRefItemParam2>. { // ignore other stuff } <XRefItemParam3>"\""[^\n\"]*"\"" { // third argument - xrefListTitle = stripQuotes(yytext); - xrefKind = XRef_Item; + yyextra->xrefListTitle = stripQuotes(yytext); + yyextra->xrefKind = XRef_Item; BEGIN( Comment ); } <XRefItemParam2,XRefItemParam3>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <XRefItemParam3>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Missing third argument of \\xrefitem" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); - inContext = OutputDoc; + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); + yyextra->inContext = OutputDoc; BEGIN( Comment ); } <XRefItemParam3>. { // ignore other stuff @@ -1723,23 +1248,23 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the relates(also)/memberof command ------- */ <RelatesParam1>({ID}("::"|"."))*{ID} { // argument - current->relates = yytext; - //if (current->mGrpId!=DOX_NOGROUP) + yyextra->current->relates = yytext; + //if (yyextra->current->mGrpId!=DOX_NOGROUP) //{ // memberGroupRelates = yytext; //} BEGIN( Comment ); } <RelatesParam1>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <RelatesParam1>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Missing argument of \\relates or \\memberof command" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <RelatesParam1>. { // ignore other stuff @@ -1749,94 +1274,94 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the relates(also)/addindex commands ----- */ <LineParam>{DOCNL} { // end of argument - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <LineParam>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <LineParam>. { // ignore other stuff - addOutput(*yytext); + addOutput(yyscanner,*yytext); } /* ----- handle arguments of the section/subsection/.. commands ------- */ <SectionLabel>{LABELID} { // first argument - g_sectionLabel=yytext; - addOutput(yytext); - g_sectionTitle.resize(0); + yyextra->sectionLabel=yytext; + addOutput(yyscanner,yytext); + yyextra->sectionTitle.resize(0); BEGIN(SectionTitle); } <SectionLabel>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "\\section command has no label" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <SectionLabel>. { // invalid character for section label - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Invalid or missing section label" ); BEGIN(Comment); } <SectionTitle>[^\n@\\*]*/"\n" { // end of section title - addSection(); - addOutput(yytext); + addSection(yyscanner); + addOutput(yyscanner,yytext); BEGIN( Comment ); } <SectionTitle>[^\n@\\]*/"\\_linebr" { // end of section title - addSection(); - addOutput(yytext); + addSection(yyscanner); + addOutput(yyscanner,yytext); BEGIN( Comment ); } <SectionTitle>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <SectionTitle>[^\n@\\]* { // any character without special meaning - g_sectionTitle+=yytext; - addOutput(yytext); + yyextra->sectionTitle+=yytext; + addOutput(yyscanner,yytext); } <SectionTitle>({CMD}{CMD}){ID} { // unescape escaped command - g_sectionTitle+=&yytext[1]; - addOutput(yytext); + yyextra->sectionTitle+=&yytext[1]; + addOutput(yyscanner,yytext); } <SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character - g_sectionTitle+=yytext[1]; - addOutput(yytext); + yyextra->sectionTitle+=yytext[1]; + addOutput(yyscanner,yytext); } <SectionTitle>. { // anything else - g_sectionTitle+=yytext; - addOutput(*yytext); + yyextra->sectionTitle+=yytext; + addOutput(yyscanner,*yytext); } /* ----- handle arguments of the subpage command ------- */ <SubpageLabel>{LABELID} { // first argument - addOutput(yytext); + addOutput(yyscanner,yytext); // we add subpage labels as a kind of "inheritance" relation to prevent // needing to add another list to the Entry class. - current->extends.push_back(BaseInfo(yytext,Public,Normal)); + yyextra->current->extends.push_back(BaseInfo(yytext,Public,Normal)); BEGIN(SubpageTitle); } <SubpageLabel>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "\\subpage command has no label" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <SubpageTitle>{DOCNL} { // no title, end command - addOutput(yytext); + addOutput(yyscanner,yytext); BEGIN( Comment ); } <SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command - addOutput(yytext); + addOutput(yyscanner,yytext); BEGIN( Comment ); } <SubpageTitle>. { // no title, end of command @@ -1847,20 +1372,20 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the anchor command ------- */ <AnchorLabel>{LABELID} { // found argument - addAnchor(yytext); - addOutput(yytext); + addAnchor(yyscanner,yytext); + addOutput(yyscanner,yytext); BEGIN( Comment ); } <AnchorLabel>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "\\anchor command has no label" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <AnchorLabel>. { // invalid character for anchor label - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Invalid or missing anchor label" ); BEGIN(Comment); @@ -1870,51 +1395,51 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the preformatted block commands ------- */ <FormatBlock>{CMD}("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endmsc"|"endvhdlflow")/{NW} { // possible ends - addOutput(yytext); - if (&yytext[4]==blockName) // found end of the block + addOutput(yyscanner,yytext); + if (&yytext[4]==yyextra->blockName) // found end of the block { BEGIN(Comment); } } <FormatBlock>{CMD}"enduml" { - addOutput(yytext); - if (blockName=="startuml") // found end of the block + addOutput(yyscanner,yytext); + if (yyextra->blockName=="startuml") // found end of the block { BEGIN(Comment); } } <FormatBlock>[^ \@\*\/\\\n]* { // some word - addOutput(yytext); + addOutput(yyscanner,yytext); } <FormatBlock>{DOCNL} { // new line - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <FormatBlock>"/*" { // start of a C-comment - if (!(blockName=="code" || blockName=="verbatim")) g_commentCount++; - addOutput(yytext); + if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim")) yyextra->commentCount++; + addOutput(yyscanner,yytext); } <FormatBlock>"*/" { // end of a C-comment - addOutput(yytext); - if (!(blockName=="code" || blockName=="verbatim")) + addOutput(yyscanner,yytext); + if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim")) { - g_commentCount--; - if (g_commentCount<0) + yyextra->commentCount--; + if (yyextra->commentCount<0) { - warn(yyFileName,yyLineNr, - "found */ without matching /* while inside a \\%s block! Perhaps a missing \\end%s?\n",blockName.data(),blockName.data()); + warn(yyextra->fileName,yyextra->lineNr, + "found */ without matching /* while inside a \\%s block! Perhaps a missing \\end%s?\n",yyextra->blockName.data(),yyextra->blockName.data()); } } } <FormatBlock>. { - addOutput(*yytext); + addOutput(yyscanner,*yytext); } <FormatBlock><<EOF>> { - QCString endTag = "end"+blockName; - if (blockName=="startuml") endTag="enduml"; - warn(yyFileName,yyLineNr, + QCString endTag = "end"+yyextra->blockName; + if (yyextra->blockName=="startuml") endTag="enduml"; + warn(yyextra->fileName,yyextra->lineNr, "reached end of comment while inside a \\%s block; check for missing \\%s tag!", - blockName.data(),endTag.data() + yyextra->blockName.data(),endTag.data() ); yyterminate(); } @@ -1922,58 +1447,58 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of if/ifnot commands ------- */ <GuardParam>{B}*"(" { - g_guardExpr=yytext; - g_roundCount=1; + yyextra->guardExpr=yytext; + yyextra->roundCount=1; BEGIN(GuardExpr); } <GuardExpr>[^()]* { - g_guardExpr+=yytext; + yyextra->guardExpr+=yytext; } <GuardExpr>"(" { - g_guardExpr+=yytext; - g_roundCount++; + yyextra->guardExpr+=yytext; + yyextra->roundCount++; } <GuardExpr>")" { - g_guardExpr+=yytext; - g_roundCount--; - if (g_roundCount==0) + yyextra->guardExpr+=yytext; + yyextra->roundCount--; + if (yyextra->roundCount==0) { - handleGuard(g_guardExpr); + handleGuard(yyscanner,yyextra->guardExpr); } } <GuardExpr>\n { - warn(yyFileName,yyLineNr, - "invalid expression '%s' for guard",g_guardExpr.data()); + warn(yyextra->fileName,yyextra->lineNr, + "invalid expression '%s' for yyextra->guards",yyextra->guardExpr.data()); unput(*yytext); BEGIN(GuardParam); } -<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot guard - handleGuard(yytext); +<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot yyextra->guards + handleGuard(yyscanner,yytext); } <GuardParam>{DOCNL} { // end of argument - if (*yytext=='\n') yyLineNr++; + if (*yytext=='\n') yyextra->lineNr++; //next line is commented out due to bug620924 - //addOutput('\n'); + //addOutput(yyscanner,'\n'); BEGIN( Comment ); } <GuardParam>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <GuardParam>. { // ignore other stuff - addOutput(*yytext); + addOutput(yyscanner,*yytext); } <GuardParamEnd>{B}*{DOCNL} { - lineCount(); - g_spaceBeforeIf.resize(0); + lineCount(yyscanner); + yyextra->spaceBeforeIf.resize(0); BEGIN(Comment); } <GuardParamEnd>{B}* { - if (!g_spaceBeforeIf.isEmpty()) // needed for 665313 in combination with bug620924 + if (!yyextra->spaceBeforeIf.isEmpty()) // needed for 665313 in combination with bug620924 { - addOutput(g_spaceBeforeIf); + addOutput(yyscanner,yyextra->spaceBeforeIf); } - g_spaceBeforeIf.resize(0); + yyextra->spaceBeforeIf.resize(0); BEGIN(Comment); } <GuardParamEnd>. { @@ -1984,67 +1509,67 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle skipping of conditional sections ------- */ <SkipGuardedSection>{CMD}"ifnot"/{NW} { - guardType = Guard_IfNot; + yyextra->guardType = Guard_IfNot; BEGIN( GuardParam ); } <SkipGuardedSection>{CMD}"if"/{NW} { - guardType = Guard_If; + yyextra->guardType = Guard_If; BEGIN( GuardParam ); } <SkipGuardedSection>{CMD}"endif"/{NW} { - if (guards.isEmpty()) + if (yyextra->guards.empty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\endif without matching start command"); } else { - GuardedSection *s = guards.pop(); - bool parentVisible = s->parentVisible(); - delete s; + GuardedSection s = yyextra->guards.top(); + yyextra->guards.pop(); + bool parentVisible = s.parentVisible(); if (parentVisible) { - enabledSectionFound=TRUE; + yyextra->enabledSectionFound=TRUE; BEGIN( GuardParamEnd ); } } } <SkipGuardedSection>{CMD}"else"/{NW} { - if (guards.isEmpty()) + if (yyextra->guards.empty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\else without matching start command"); } else { - if (!enabledSectionFound && guards.top()->parentVisible()) + if (!yyextra->enabledSectionFound && yyextra->guards.top().parentVisible()) { - delete guards.pop(); - guards.push(new GuardedSection(TRUE,TRUE)); - enabledSectionFound=TRUE; + yyextra->guards.pop(); + yyextra->guards.push(GuardedSection(TRUE,TRUE)); + yyextra->enabledSectionFound=TRUE; BEGIN( GuardParamEnd ); } } } <SkipGuardedSection>{CMD}"elseif"/{NW} { - if (guards.isEmpty()) + if (yyextra->guards.empty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\elseif without matching start command"); } else { - if (!enabledSectionFound && guards.top()->parentVisible()) + if (!yyextra->enabledSectionFound && yyextra->guards.top().parentVisible()) { - guardType=Guard_If; - delete guards.pop(); + yyextra->guardType=Guard_If; + yyextra->guards.pop(); BEGIN( GuardParam ); } } } <SkipGuardedSection>{DOCNL} { // skip line - if (*yytext=='\n') yyLineNr++; - //addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + //addOutput(yyscanner,'\n'); } <SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters } @@ -2055,46 +1580,46 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle skipping of internal section ------- */ <SkipInternal>{DOCNL} { // skip line - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <SkipInternal>[@\\]"if"/[ \t] { - g_condCount++; + yyextra->condCount++; } <SkipInternal>[@\\]"ifnot"/[ \t] { - g_condCount++; + yyextra->condCount++; } <SkipInternal>[@\\]/"endif" { - g_condCount--; - if (g_condCount<0) // handle conditional section around of \internal, see bug607743 + yyextra->condCount--; + if (yyextra->condCount<0) // handle conditional section around of \internal, see bug607743 { unput('\\'); BEGIN(Comment); } } <SkipInternal>[@\\]/"section"[ \t] { - if (g_sectionLevel>0) + if (yyextra->sectionLevel>0) { unput('\\'); BEGIN(Comment); } } <SkipInternal>[@\\]/"subsection"[ \t] { - if (g_sectionLevel>1) + if (yyextra->sectionLevel>1) { unput('\\'); BEGIN(Comment); } } <SkipInternal>[@\\]/"subsubsection"[ \t] { - if (g_sectionLevel>2) + if (yyextra->sectionLevel>2) { unput('\\'); BEGIN(Comment); } } <SkipInternal>[@\\]/"paragraph"[ \t] { - if (g_sectionLevel>3) + if (yyextra->sectionLevel>3) { unput('\\'); BEGIN(Comment); @@ -2112,24 +1637,24 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle argument of name command ------- */ <NameParam>{DOCNL} { // end of argument - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <NameParam>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); - Doxygen::docGroup.appendHeader(' '); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); + yyextra->docGroup.appendHeader(' '); } <NameParam>. { // ignore other stuff - Doxygen::docGroup.appendHeader(*yytext); - current->name+=*yytext; + yyextra->docGroup.appendHeader(*yytext); + yyextra->current->name+=*yytext; } /* ----- handle argument of noop command ------- */ <Noop>{DOCNL} { // end of argument - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <Noop>. { // ignore other stuff @@ -2137,58 +1662,58 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle argument of ingroup command ------- */ <InGroupParam>{LABELID} { // group id - current->groups.push_back( + yyextra->current->groups.push_back( Grouping(yytext, Grouping::GROUPING_INGROUP) ); - inGroupParamFound=TRUE; + yyextra->inGroupParamFound=TRUE; } <InGroupParam>{DOCNL} { // missing argument - if (!inGroupParamFound) + if (!yyextra->inGroupParamFound) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Missing group name for \\ingroup command" ); } - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <InGroupParam>{LC} { // line continuation - yyLineNr++; - addOutput('\n'); + yyextra->lineNr++; + addOutput(yyscanner,'\n'); } <InGroupParam>. { // ignore other stuff - addOutput(*yytext); + addOutput(yyscanner,*yytext); } /* ----- handle argument of fn command ------- */ <FnParam>{DOCNL} { // end of argument - if (braceCount==0) + if (yyextra->braceCount==0) { - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); - langParser->parsePrototype(functionProto); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); + yyextra->langParser->parsePrototype(yyextra->functionProto); BEGIN( Comment ); } } <FnParam>{LC} { // line continuation - yyLineNr++; - functionProto+=' '; + yyextra->lineNr++; + yyextra->functionProto+=' '; } <FnParam>[^@\\\n()]+ { // non-special characters - functionProto+=yytext; + yyextra->functionProto+=yytext; } <FnParam>"(" { - functionProto+=yytext; - braceCount++; + yyextra->functionProto+=yytext; + yyextra->braceCount++; } <FnParam>")" { - functionProto+=yytext; - braceCount--; + yyextra->functionProto+=yytext; + yyextra->braceCount--; } <FnParam>. { // add other stuff - functionProto+=*yytext; + yyextra->functionProto+=*yytext; } @@ -2196,45 +1721,45 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <OverloadParam>{DOCNL} { // end of argument - if (*yytext=='\n') yyLineNr++; - if (functionProto.stripWhiteSpace().isEmpty()) + if (*yytext=='\n') yyextra->lineNr++; + if (yyextra->functionProto.stripWhiteSpace().isEmpty()) { // plain overload command - addOutput(getOverloadDocs()); - addOutput('\n'); + addOutput(yyscanner,getOverloadDocs()); + addOutput(yyscanner,'\n'); } else // overload declaration { - makeStructuralIndicator(Entry::OVERLOADDOC_SEC); - langParser->parsePrototype(functionProto); + makeStructuralIndicator(yyscanner,Entry::OVERLOADDOC_SEC); + yyextra->langParser->parsePrototype(yyextra->functionProto); } BEGIN( Comment ); } <OverloadParam>{LC} { // line continuation - yyLineNr++; - functionProto+=' '; + yyextra->lineNr++; + yyextra->functionProto+=' '; } <OverloadParam>. { // add other stuff - functionProto+=*yytext; + yyextra->functionProto+=*yytext; } /* ----- handle argument of inherit command ------- */ <InheritParam>({ID}("::"|"."))*{ID} { // found argument - current->extends.push_back( + yyextra->current->extends.push_back( BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal) ); BEGIN( Comment ); } <InheritParam>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "\\inherit command has no argument" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <InheritParam>. { // invalid character for anchor label - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Invalid or missing name for \\inherit command" ); BEGIN(Comment); @@ -2243,17 +1768,17 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle argument of extends and implements commands ------- */ <ExtendsParam>({ID}("::"|"."))*{ID} { // found argument - current->extends.push_back( + yyextra->current->extends.push_back( BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal) ); BEGIN( Comment ); } <ExtendsParam>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "\\extends or \\implements command has no argument" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <ExtendsParam>. { // ignore other stuff @@ -2272,7 +1797,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */ } <SkipLang>{DOCNL} { /* new line in verbatim block */ - if (*yytext=='\n') yyLineNr++; + if (*yytext=='\n') yyextra->lineNr++; } <SkipLang>. { /* any other character */ } @@ -2280,20 +1805,20 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the cite command ------- */ <CiteLabel>{CITEID} { // found argument - addCite(); - addOutput(yytext); + addCite(yyscanner); + addOutput(yyscanner,yytext); BEGIN(Comment); } <CiteLabel>{DOCNL} { // missing argument - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "\\cite command has no label" ); - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); BEGIN( Comment ); } <CiteLabel>. { // invalid character for cite label - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Invalid or missing cite label" ); BEGIN(Comment); @@ -2303,21 +1828,21 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <CopyDoc><<EOF>> | <CopyDoc>{DOCNL} { - if (*yytext=='\n') yyLineNr++; - addOutput('\n'); - setOutput(OutputDoc); - addOutput(" \\copydetails "); - addOutput(g_copyDocArg); - addOutput("\n"); + if (*yytext=='\n') yyextra->lineNr++; + addOutput(yyscanner,'\n'); + setOutput(yyscanner,OutputDoc); + addOutput(yyscanner," \\copydetails "); + addOutput(yyscanner,yyextra->copyDocArg); + addOutput(yyscanner,"\n"); BEGIN(Comment); } <CopyDoc>[^\n\\]+ { - g_copyDocArg+=yytext; - addOutput(yytext); + yyextra->copyDocArg+=yytext; + addOutput(yyscanner,yytext); } <CopyDoc>. { - g_copyDocArg+=yytext; - addOutput(yytext); + yyextra->copyDocArg+=yytext; + addOutput(yyscanner,yytext); } @@ -2325,194 +1850,218 @@ RCSTAG "$"{ID}":"[^\n$]+"$" //---------------------------------------------------------------------------- -static bool handleBrief(const QCString &, const QCStringList &) +static bool handleBrief(yyscan_t yyscanner,const QCString &, const QCStringList &) { //printf("handleBrief\n"); - setOutput(OutputBrief); + setOutput(yyscanner,OutputBrief); return FALSE; } -static bool handleFn(const QCString &, const QCStringList &) +static bool handleFn(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::MEMBERDOC_SEC); - functionProto.resize(0); - braceCount=0; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::MEMBERDOC_SEC); + yyextra->functionProto.resize(0); + yyextra->braceCount=0; BEGIN(FnParam); return stop; } -static bool handleDef(const QCString &, const QCStringList &) +static bool handleDef(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::DEFINEDOC_SEC); - functionProto.resize(0); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::DEFINEDOC_SEC); + yyextra->functionProto.resize(0); BEGIN(FnParam); return stop; } -static bool handleOverload(const QCString &, const QCStringList &) +static bool handleOverload(yyscan_t yyscanner,const QCString &, const QCStringList &) { - functionProto.resize(0); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->functionProto.resize(0); BEGIN(OverloadParam); return FALSE; } -static bool handleEnum(const QCString &, const QCStringList &) +static bool handleEnum(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::ENUMDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::ENUMDOC_SEC); BEGIN(EnumDocArg1); return stop; } -static bool handleDefGroup(const QCString &, const QCStringList &) +static bool handleDefGroup(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); - current->groupDocType = Entry::GROUPDOC_NORMAL; - setOutput(OutputBrief); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::GROUPDOC_SEC); + yyextra->current->groupDocType = Entry::GROUPDOC_NORMAL; + setOutput(yyscanner,OutputBrief); BEGIN( GroupDocArg1 ); return stop; } -static bool handleAddToGroup(const QCString &, const QCStringList &) +static bool handleAddToGroup(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); - current->groupDocType = Entry::GROUPDOC_ADD; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::GROUPDOC_SEC); + yyextra->current->groupDocType = Entry::GROUPDOC_ADD; BEGIN( GroupDocArg1 ); return stop; } -static bool handleWeakGroup(const QCString &, const QCStringList &) +static bool handleWeakGroup(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); - current->groupDocType = Entry::GROUPDOC_WEAK; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::GROUPDOC_SEC); + yyextra->current->groupDocType = Entry::GROUPDOC_WEAK; BEGIN( GroupDocArg1 ); return stop; } -static bool handleNamespace(const QCString &, const QCStringList &) +static bool handleNamespace(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::NAMESPACEDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::NAMESPACEDOC_SEC); BEGIN( NameSpaceDocArg1 ); return stop; } -static bool handlePackage(const QCString &, const QCStringList &) +static bool handlePackage(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::PACKAGEDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::PACKAGEDOC_SEC); BEGIN( PackageDocArg1 ); return stop; } -static bool handleClass(const QCString &, const QCStringList &) +static bool handleClass(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::CLASSDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::CLASSDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleHeaderFile(const QCString &, const QCStringList &) +static bool handleHeaderFile(yyscan_t yyscanner,const QCString &, const QCStringList &) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; BEGIN( ClassDocArg2 ); return FALSE; } -static bool handleProtocol(const QCString &, const QCStringList &) +static bool handleProtocol(yyscan_t yyscanner,const QCString &, const QCStringList &) { // Obj-C protocol - bool stop=makeStructuralIndicator(Entry::PROTOCOLDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::PROTOCOLDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleCategory(const QCString &, const QCStringList &) +static bool handleCategory(yyscan_t yyscanner,const QCString &, const QCStringList &) { // Obj-C category - bool stop=makeStructuralIndicator(Entry::CATEGORYDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::CATEGORYDOC_SEC); BEGIN( CategoryDocArg1 ); return stop; } -static bool handleUnion(const QCString &, const QCStringList &) +static bool handleUnion(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::UNIONDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::UNIONDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleStruct(const QCString &, const QCStringList &) +static bool handleStruct(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::STRUCTDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::STRUCTDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleInterface(const QCString &, const QCStringList &) +static bool handleInterface(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::INTERFACEDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::INTERFACEDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleIdlException(const QCString &, const QCStringList &) +static bool handleIdlException(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::EXCEPTIONDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::EXCEPTIONDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handlePage(const QCString &, const QCStringList &) +static bool handlePage(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::PAGEDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::PAGEDOC_SEC); BEGIN( PageDocArg1 ); return stop; } -static bool handleMainpage(const QCString &, const QCStringList &) +static bool handleMainpage(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::MAINPAGEDOC_SEC); - current->name = ""; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::MAINPAGEDOC_SEC); + yyextra->current->name = ""; if (!stop) { - current->name = "mainpage"; + yyextra->current->name = "mainpage"; } BEGIN( PageDocArg2 ); return stop; } -static bool handleFile(const QCString &, const QCStringList &) +static bool handleFile(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::FILEDOC_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::FILEDOC_SEC); if (!stop) { - current->name = yyFileName; + yyextra->current->name = yyextra->fileName; } BEGIN( FileDocArg1 ); return stop; } -static bool handleParam(const QCString &, const QCStringList &) +static bool handleParam(yyscan_t yyscanner,const QCString &, const QCStringList &) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; // we need process param and retval arguments to escape leading underscores in case of // markdown processing, see bug775493 - addOutput("@param "); + addOutput(yyscanner,"@param "); BEGIN( ParamArg1 ); return FALSE; } -static bool handleRetval(const QCString &, const QCStringList &) +static bool handleRetval(yyscan_t yyscanner,const QCString &, const QCStringList &) { - addOutput("@retval "); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + addOutput(yyscanner,"@retval "); BEGIN( ParamArg1 ); return FALSE; } -static bool handleDir(const QCString &, const QCStringList &) +static bool handleDir(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::DIRDOC_SEC); - if (!stop) current->name = yyFileName; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::DIRDOC_SEC); + if (!stop) yyextra->current->name = yyextra->fileName; BEGIN( FileDocArg1 ); return stop; } -static bool handleExample(const QCString &cmd, const QCStringList &optList) +static bool handleExample(yyscan_t yyscanner,const QCString &cmd, const QCStringList &optList) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; Entry::Sections section=Entry::EXAMPLE_SEC; QCStringList::ConstIterator it; for ( it = optList.begin(); it != optList.end(); ++it ) @@ -2524,458 +2073,507 @@ static bool handleExample(const QCString &cmd, const QCStringList &optList) } else { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "unsupported option '%s' for command '\\%s'",qPrint(opt),qPrint(cmd)); } } - bool stop=makeStructuralIndicator(section); - if (!stop) current->name = yyFileName; + bool stop=makeStructuralIndicator(yyscanner,section); + if (!stop) yyextra->current->name = yyextra->fileName; BEGIN( FileDocArg1 ); return stop; } -static bool handleDetails(const QCString &, const QCStringList &) +static bool handleDetails(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (inContext!=OutputBrief) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->inContext!=OutputBrief) { - addOutput("\n\n"); // treat @details outside brief description + addOutput(yyscanner,"\n\n"); // treat @details outside brief description // as a new paragraph } - setOutput(OutputDoc); + setOutput(yyscanner,OutputDoc); return FALSE; } -static bool handleNoop(const QCString &, const QCStringList &) +static bool handleNoop(yyscan_t yyscanner,const QCString &, const QCStringList &) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; BEGIN( Noop ); return FALSE; } -static bool handleName(const QCString &, const QCStringList &) +static bool handleName(yyscan_t yyscanner,const QCString &, const QCStringList &) { - bool stop=makeStructuralIndicator(Entry::MEMBERGRP_SEC); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool stop=makeStructuralIndicator(yyscanner,Entry::MEMBERGRP_SEC); if (!stop) { - Doxygen::docGroup.clearHeader(); + yyextra->docGroup.clearHeader(); BEGIN( NameParam ); - if (!Doxygen::docGroup.isEmpty()) // end of previous member group + if (!yyextra->docGroup.isEmpty()) // end of previous member group { - Doxygen::docGroup.close(current,yyFileName,yyLineNr,TRUE,true); + yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,TRUE,true); } } return stop; } -static bool handleTodo(const QCString &, const QCStringList &) +static bool handleTodo(yyscan_t yyscanner,const QCString &, const QCStringList &) { - newXRefKind = XRef_Todo; - setOutput(OutputXRef); - xrefKind = XRef_Todo; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->newXRefKind = XRef_Todo; + setOutput(yyscanner,OutputXRef); + yyextra->xrefKind = XRef_Todo; return FALSE; } -static bool handleTest(const QCString &, const QCStringList &) +static bool handleTest(yyscan_t yyscanner,const QCString &, const QCStringList &) { - newXRefKind = XRef_Test; - setOutput(OutputXRef); - xrefKind = XRef_Test; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->newXRefKind = XRef_Test; + setOutput(yyscanner,OutputXRef); + yyextra->xrefKind = XRef_Test; return FALSE; } -static bool handleBug(const QCString &, const QCStringList &) +static bool handleBug(yyscan_t yyscanner,const QCString &, const QCStringList &) { - newXRefKind = XRef_Bug; - setOutput(OutputXRef); - xrefKind = XRef_Bug; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->newXRefKind = XRef_Bug; + setOutput(yyscanner,OutputXRef); + yyextra->xrefKind = XRef_Bug; return FALSE; } -static bool handleDeprecated(const QCString &, const QCStringList &) +static bool handleDeprecated(yyscan_t yyscanner,const QCString &, const QCStringList &) { - newXRefKind = XRef_Deprecated; - setOutput(OutputXRef); - xrefKind = XRef_Deprecated; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->newXRefKind = XRef_Deprecated; + setOutput(yyscanner,OutputXRef); + yyextra->xrefKind = XRef_Deprecated; return FALSE; } -static bool handleXRefItem(const QCString &, const QCStringList &) +static bool handleXRefItem(yyscan_t yyscanner,const QCString &, const QCStringList &) { - newXRefKind = XRef_Item; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->newXRefKind = XRef_Item; BEGIN(XRefItemParam1); return FALSE; } -static bool handleParBlock(const QCString &, const QCStringList &) +static bool handleParBlock(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (g_insideParBlock) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->insideParBlock) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\parblock command while already in a parblock!"); } - if (!g_spaceBeforeCmd.isEmpty()) + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } - addOutput("@parblock "); - g_insideParBlock = TRUE; + addOutput(yyscanner,"@parblock "); + yyextra->insideParBlock = TRUE; return FALSE; } -static bool handleEndParBlock(const QCString &, const QCStringList &) +static bool handleEndParBlock(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (!g_insideParBlock) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->insideParBlock) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\endparblock command without matching \\parblock!"); } - addOutput("@endparblock"); - setOutput(OutputDoc); // to end a parblock inside a xrefitem like context - g_insideParBlock = FALSE; + addOutput(yyscanner,"@endparblock"); + setOutput(yyscanner,OutputDoc); // to end a parblock inside a xrefitem like context + yyextra->insideParBlock = FALSE; return FALSE; } -static bool handleRelated(const QCString &, const QCStringList &) +static bool handleRelated(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (!current->relates.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->current->relates.isEmpty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition"); } - current->relatesType = Simple; + yyextra->current->relatesType = Simple; BEGIN(RelatesParam1); return FALSE; } -static bool handleRelatedAlso(const QCString &, const QCStringList &) +static bool handleRelatedAlso(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (!current->relates.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->current->relates.isEmpty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition"); } - current->relatesType = Duplicate; + yyextra->current->relatesType = Duplicate; BEGIN(RelatesParam1); return FALSE; } -static bool handleMemberOf(const QCString &, const QCStringList &) +static bool handleMemberOf(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (!current->relates.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->current->relates.isEmpty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition"); } - current->relatesType = MemberOf; + yyextra->current->relatesType = MemberOf; BEGIN(RelatesParam1); return FALSE; } -static bool handleRefItem(const QCString &, const QCStringList &) +static bool handleRefItem(yyscan_t yyscanner,const QCString &, const QCStringList &) { - addOutput("@refitem "); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + addOutput(yyscanner,"@refitem "); BEGIN(LineParam); return FALSE; } -static bool handleSection(const QCString &s, const QCStringList &) +static bool handleSection(yyscan_t yyscanner,const QCString &s, const QCStringList &) { - setOutput(OutputDoc); - addOutput("@"+s+" "); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + setOutput(yyscanner,OutputDoc); + addOutput(yyscanner,"@"+s+" "); BEGIN(SectionLabel); - if (s=="section") g_sectionLevel=1; - else if (s=="subsection") g_sectionLevel=2; - else if (s=="subsubsection") g_sectionLevel=3; - else if (s=="paragraph") g_sectionLevel=4; + if (s=="section") yyextra->sectionLevel=1; + else if (s=="subsection") yyextra->sectionLevel=2; + else if (s=="subsubsection") yyextra->sectionLevel=3; + else if (s=="paragraph") yyextra->sectionLevel=4; return FALSE; } -static bool handleSubpage(const QCString &s, const QCStringList &) +static bool handleSubpage(yyscan_t yyscanner,const QCString &s, const QCStringList &) { - if (current->section!=Entry::EMPTY_SEC && - current->section!=Entry::PAGEDOC_SEC && - current->section!=Entry::MAINPAGEDOC_SEC + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->current->section!=Entry::EMPTY_SEC && + yyextra->current->section!=Entry::PAGEDOC_SEC && + yyextra->current->section!=Entry::MAINPAGEDOC_SEC ) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\subpage command in a comment block that is not marked as a page!"); } - if (!g_spaceBeforeCmd.isEmpty()) + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } - addOutput("@"+s+" "); + addOutput(yyscanner,"@"+s+" "); BEGIN(SubpageLabel); return FALSE; } -static bool handleAnchor(const QCString &s, const QCStringList &) +static bool handleAnchor(yyscan_t yyscanner,const QCString &s, const QCStringList &) { - addOutput("@"+s+" "); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + addOutput(yyscanner,"@"+s+" "); BEGIN(AnchorLabel); return FALSE; } -static bool handleCite(const QCString &s, const QCStringList &) +static bool handleCite(yyscan_t yyscanner,const QCString &s, const QCStringList &) { - if (!g_spaceBeforeCmd.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } - addOutput("@"+s+" "); + addOutput(yyscanner,"@"+s+" "); BEGIN(CiteLabel); return FALSE; } -static bool handleFormatBlock(const QCString &s, const QCStringList &optList) +static bool handleFormatBlock(yyscan_t yyscanner,const QCString &s, const QCStringList &optList) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (optList.isEmpty()) { - addOutput("@"+s+" "); + addOutput(yyscanner,"@"+s+" "); } else { - addOutput("@"+s+"{"+optList.join(",")+"} "); + addOutput(yyscanner,"@"+s+"{"+optList.join(",")+"} "); } //printf("handleFormatBlock(%s) with option(%s)\n",s.data(),opt.data()); - blockName=s; - g_commentCount=0; + yyextra->blockName=s; + yyextra->commentCount=0; BEGIN(FormatBlock); return FALSE; } -static bool handleAddIndex(const QCString &, const QCStringList &) +static bool handleAddIndex(yyscan_t yyscanner,const QCString &, const QCStringList &) { - addOutput("@addindex "); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + addOutput(yyscanner,"@addindex "); BEGIN(LineParam); return FALSE; } -static bool handleIf(const QCString &, const QCStringList &) +static bool handleIf(yyscan_t yyscanner,const QCString &, const QCStringList &) { - enabledSectionFound=FALSE; - guardType = Guard_If; - g_spaceBeforeIf = g_spaceBeforeCmd; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->enabledSectionFound=FALSE; + yyextra->guardType = Guard_If; + yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd; BEGIN(GuardParam); return FALSE; } -static bool handleIfNot(const QCString &, const QCStringList &) +static bool handleIfNot(yyscan_t yyscanner,const QCString &, const QCStringList &) { - enabledSectionFound=FALSE; - guardType = Guard_IfNot; - g_spaceBeforeIf = g_spaceBeforeCmd; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->enabledSectionFound=FALSE; + yyextra->guardType = Guard_IfNot; + yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd; BEGIN(GuardParam); return FALSE; } -static bool handleElseIf(const QCString &, const QCStringList &) +static bool handleElseIf(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (guards.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->guards.empty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\else without matching start command"); } else { - guardType = enabledSectionFound ? Guard_Skip : Guard_If; + yyextra->guardType = yyextra->enabledSectionFound ? Guard_Skip : Guard_If; + yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd; BEGIN(GuardParam); } return FALSE; } -static bool handleElse(const QCString &, const QCStringList &) +static bool handleElse(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (guards.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->guards.empty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\else without matching start command"); } else { + yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd; BEGIN( SkipGuardedSection ); } return FALSE; } -static bool handleEndIf(const QCString &, const QCStringList &) +static bool handleEndIf(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (guards.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->guards.empty()) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "found \\endif without matching start command"); } else { - delete guards.pop(); + yyextra->guards.pop(); } - enabledSectionFound=FALSE; - if (!g_spaceBeforeCmd.isEmpty()) + yyextra->enabledSectionFound=FALSE; + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } BEGIN( GuardParamEnd ); return FALSE; } -static bool handleIngroup(const QCString &, const QCStringList &) +static bool handleIngroup(yyscan_t yyscanner,const QCString &, const QCStringList &) { - inGroupParamFound=FALSE; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->inGroupParamFound=FALSE; BEGIN( InGroupParam ); return FALSE; } -static bool handleNoSubGrouping(const QCString &, const QCStringList &) +static bool handleNoSubGrouping(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->subGrouping = FALSE; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->subGrouping = FALSE; return FALSE; } -static bool handleShowInitializer(const QCString &, const QCStringList &) +static bool handleShowInitializer(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->initLines = 100000; // ON + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->initLines = 100000; // ON return FALSE; } -static bool handleHideInitializer(const QCString &, const QCStringList &) +static bool handleHideInitializer(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->initLines = 0; // OFF + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->initLines = 0; // OFF return FALSE; } -static bool handleCallgraph(const QCString &, const QCStringList &) +static bool handleCallgraph(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->callGraph = TRUE; // ON + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->callGraph = TRUE; // ON return FALSE; } -static bool handleHideCallgraph(const QCString &, const QCStringList &) +static bool handleHideCallgraph(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->callGraph = FALSE; // OFF + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->callGraph = FALSE; // OFF return FALSE; } -static bool handleCallergraph(const QCString &, const QCStringList &) +static bool handleCallergraph(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->callerGraph = TRUE; // ON + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->callerGraph = TRUE; // ON return FALSE; } -static bool handleHideCallergraph(const QCString &, const QCStringList &) +static bool handleHideCallergraph(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->callerGraph = FALSE; // OFF + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->callerGraph = FALSE; // OFF return FALSE; } -static bool handleReferencedByRelation(const QCString &, const QCStringList &) +static bool handleReferencedByRelation(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->referencedByRelation = TRUE; // ON + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->referencedByRelation = TRUE; // ON return FALSE; } -static bool handleHideReferencedByRelation(const QCString &, const QCStringList &) +static bool handleHideReferencedByRelation(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->referencedByRelation = FALSE; // OFF + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->referencedByRelation = FALSE; // OFF return FALSE; } -static bool handleReferencesRelation(const QCString &, const QCStringList &) +static bool handleReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->referencesRelation = TRUE; // ON + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->referencesRelation = TRUE; // ON return FALSE; } -static bool handleHideReferencesRelation(const QCString &, const QCStringList &) +static bool handleHideReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->referencesRelation = FALSE; // OFF + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->referencesRelation = FALSE; // OFF return FALSE; } -static bool handleInternal(const QCString &, const QCStringList &) +static bool handleInternal(yyscan_t yyscanner,const QCString &, const QCStringList &) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (!Config_getBool(INTERNAL_DOCS)) { // make sure some whitespace before a \internal command // is not treated as "documentation" - if (current->doc.stripWhiteSpace().isEmpty()) + if (yyextra->current->doc.stripWhiteSpace().isEmpty()) { - current->doc.resize(0); + yyextra->current->doc.resize(0); } - g_condCount=0; + yyextra->condCount=0; BEGIN( SkipInternal ); } else { // re-enabled for bug640828 - addOutput(" \\internal "); - inInternalDocs = TRUE; + addOutput(yyscanner," \\internal "); + yyextra->inInternalDocs = TRUE; } return FALSE; } -static bool handleLineBr(const QCString &, const QCStringList &) +static bool handleLineBr(yyscan_t yyscanner,const QCString &, const QCStringList &) { - addOutput('\n'); + addOutput(yyscanner,'\n'); return FALSE; } -static bool handleStatic(const QCString &, const QCStringList &) +static bool handleStatic(yyscan_t yyscanner,const QCString &, const QCStringList &) { - endBrief(); - current->stat = TRUE; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + endBrief(yyscanner); + yyextra->current->stat = TRUE; return FALSE; } -static bool handlePure(const QCString &, const QCStringList &) +static bool handlePure(yyscan_t yyscanner,const QCString &, const QCStringList &) { - endBrief(); - current->virt = Pure; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + endBrief(yyscanner); + yyextra->current->virt = Pure; return FALSE; } -static bool handlePrivate(const QCString &, const QCStringList &) +static bool handlePrivate(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->protection = Private; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->protection = Private; return FALSE; } -static bool handlePrivateSection(const QCString &, const QCStringList &) +static bool handlePrivateSection(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->protection = protection = Private; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->protection = yyextra->protection = Private; return FALSE; } -static bool handleProtected(const QCString &, const QCStringList &) +static bool handleProtected(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->protection = Protected; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->protection = Protected; return FALSE; } -static bool handleProtectedSection(const QCString &, const QCStringList &) +static bool handleProtectedSection(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->protection = protection = Protected ; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->protection = yyextra->protection = Protected ; return FALSE; } -static bool handlePublic(const QCString &, const QCStringList &) +static bool handlePublic(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->protection = Public; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->protection = Public; return FALSE; } -static bool handlePublicSection(const QCString &, const QCStringList &) +static bool handlePublicSection(yyscan_t yyscanner,const QCString &, const QCStringList &) { - current->protection = protection = Public; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->protection = yyextra->protection = Public; return FALSE; } -static bool handleToc(const QCString &, const QCStringList &optList) +static bool handleToc(yyscan_t yyscanner,const QCString &, const QCStringList &optList) { - if (current->section==Entry::PAGEDOC_SEC || - current->section==Entry::MAINPAGEDOC_SEC) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->current->section==Entry::PAGEDOC_SEC || + yyextra->current->section==Entry::MAINPAGEDOC_SEC) { QCStringList::ConstIterator it; for ( it = optList.begin(); it != optList.end(); ++it ) @@ -2988,7 +2586,7 @@ static bool handleToc(const QCString &, const QCStringList &optList) { if (sscanf(opt.right(opt.length() - i - 1).data(),"%d%c",&level,&dum) != 1) { - warn(yyFileName,yyLineNr,"Unknown option:level specified with \\tableofcontents: '%s'", (*it).stripWhiteSpace().data()); + warn(yyextra->fileName,yyextra->lineNr,"Unknown option:level specified with \\tableofcontents: '%s'", (*it).stripWhiteSpace().data()); opt = ""; } else @@ -3002,131 +2600,560 @@ static bool handleToc(const QCString &, const QCStringList &optList) { if (opt == "html") { - current->localToc.enableHtml(level); + yyextra->current->localToc.enableHtml(level); } else if (opt == "latex") { - current->localToc.enableLatex(level); + yyextra->current->localToc.enableLatex(level); } else if (opt == "xml") { - current->localToc.enableXml(level); + yyextra->current->localToc.enableXml(level); } else if (opt == "docbook") { - current->localToc.enableDocbook(level); + yyextra->current->localToc.enableDocbook(level); } else { - warn(yyFileName,yyLineNr,"Unknown option specified with \\tableofcontents: '%s'", (*it).stripWhiteSpace().data()); + warn(yyextra->fileName,yyextra->lineNr,"Unknown option specified with \\tableofcontents: '%s'", (*it).stripWhiteSpace().data()); } } } - if (current->localToc.nothingEnabled()) + if (yyextra->current->localToc.nothingEnabled()) { // for backward compatibility - current->localToc.enableHtml(5); - current->localToc.enableXml(5); + yyextra->current->localToc.enableHtml(5); + yyextra->current->localToc.enableXml(5); } } return FALSE; } -static bool handleInherit(const QCString &, const QCStringList &) +static bool handleInherit(yyscan_t yyscanner,const QCString &, const QCStringList &) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; BEGIN(InheritParam); return FALSE; } -static bool handleExtends(const QCString &, const QCStringList &) +static bool handleExtends(yyscan_t yyscanner,const QCString &, const QCStringList &) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; BEGIN(ExtendsParam); return FALSE; } -static bool handleCopyBrief(const QCString &, const QCStringList &) +static bool handleCopyBrief(yyscan_t yyscanner,const QCString &, const QCStringList &) { - if (current->brief.isEmpty() && current->doc.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->current->brief.isEmpty() && yyextra->current->doc.isEmpty()) { // if we don't have a brief or detailed description yet, // then the @copybrief should end up in the brief description. // otherwise it will be copied inline (see bug691315 & bug700788) - setOutput(OutputBrief); + setOutput(yyscanner,OutputBrief); } - if (!g_spaceBeforeCmd.isEmpty()) + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } - addOutput("\\copybrief "); + addOutput(yyscanner,"\\copybrief "); return FALSE; } -static bool handleCopyDetails(const QCString &, const QCStringList &) +static bool handleCopyDetails(yyscan_t yyscanner,const QCString &, const QCStringList &) { - setOutput(OutputDoc); - if (!g_spaceBeforeCmd.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + setOutput(yyscanner,OutputDoc); + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } - addOutput("\\copydetails "); + addOutput(yyscanner,"\\copydetails "); return FALSE; } -static bool handleCopyDoc(const QCString &, const QCStringList &) +static bool handleCopyDoc(yyscan_t yyscanner,const QCString &, const QCStringList &) { - setOutput(OutputBrief); - if (!g_spaceBeforeCmd.isEmpty()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + setOutput(yyscanner,OutputBrief); + if (!yyextra->spaceBeforeCmd.isEmpty()) { - addOutput(g_spaceBeforeCmd); - g_spaceBeforeCmd.resize(0); + addOutput(yyscanner,yyextra->spaceBeforeCmd); + yyextra->spaceBeforeCmd.resize(0); } - addOutput("\\copybrief "); - g_copyDocArg.resize(0); + addOutput(yyscanner,"\\copybrief "); + yyextra->copyDocArg.resize(0); BEGIN(CopyDoc); return FALSE; } -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- -static void checkFormula() +static void initParser(yyscan_t yyscanner) { - if (YY_START==ReadFormulaShort || YY_START==ReadFormulaLong) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->sectionLabel.resize(0); + yyextra->sectionTitle.resize(0); + yyextra->docGroup.clearHeader(); + yyextra->insideParBlock = FALSE; +} + + +static bool getDocSectionName(int s) +{ + switch(s) { - warn(yyFileName,yyLineNr,"End of comment block while inside formula."); + case Entry::CLASSDOC_SEC: + case Entry::STRUCTDOC_SEC: + case Entry::UNIONDOC_SEC: + case Entry::EXCEPTIONDOC_SEC: + case Entry::NAMESPACEDOC_SEC: + case Entry::PROTOCOLDOC_SEC: + case Entry::CATEGORYDOC_SEC: + case Entry::ENUMDOC_SEC: + case Entry::PAGEDOC_SEC: + case Entry::VARIABLEDOC_SEC: + case Entry::MEMBERDOC_SEC: + case Entry::OVERLOADDOC_SEC: + case Entry::FILEDOC_SEC: + case Entry::DEFINEDOC_SEC: + case Entry::GROUPDOC_SEC: + case Entry::MAINPAGEDOC_SEC: + case Entry::PACKAGEDOC_SEC: + case Entry::DIRDOC_SEC: + case Entry::EXAMPLE_SEC: + case Entry::MEMBERGRP_SEC: + return TRUE; + default: + return FALSE; } } -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +static bool makeStructuralIndicator(yyscan_t yyscanner,Entry::Sections s) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //printf("yyextra->current->section=%x\n",yyextra->current->section); + if (getDocSectionName(yyextra->current->section)) + { + return TRUE; + } + else + { + yyextra->needNewEntry = TRUE; + yyextra->current->section = s; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->startLine = yyextra->lineNr; + return FALSE; + } +} + +//----------------------------------------------------------------- + +static void lineCount(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + for( const char* c = yytext ; *c ; ++c ) + yyextra->lineNr += (*c == '\n') ; +} + +//----------------------------------------------------------------- + +static QCString stripQuotes(const char *s) +{ + QCString name; + if (s==0 || *s==0) return name; + name=s; + if (name.at(0)=='"' && name.at(name.length()-1)=='"') + { + name=name.mid(1,name.length()-2); + } + return name; +} + +//----------------------------------------------------------------- + +static void addXRefItem(yyscan_t yyscanner, + const char *listName,const char *itemTitle, + const char *listTitle,bool append) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (listName==0) return; + //printf("addXRefItem(%s,%s,%s,%d)\n",listName,itemTitle,listTitle,append); + + RefList *refList = RefListManager::instance().add(listName,listTitle,itemTitle); + RefItem *item = 0; + for (RefItem *i : yyextra->current->sli) + { + if (i && qstrcmp(i->list()->listName(),listName)==0) + { + //printf("found %s lii->type=%s\n",listName,lii->type); + item = i; + break; + } + } + if (item && append) // already found item of same type just before this one + { + //printf("listName=%s item id = %d existing\n",listName,lii->itemId); + item->setText(item->text() + " <p>" + yyextra->outputXRef); + //printf("%s: text +=%s\n",listName,item->text.data()); + } + else // new item + { + //printf("listName=%s item id = %d new yyextra->current=%p\n",listName,itemId,yyextra->current); + + // if we have already an item from the same list type (e.g. a second @todo) + // in the same Entry (i.e. lii!=0) then we reuse its link anchor. + item = refList->add(); + QCString anchorLabel; + anchorLabel.sprintf("_%s%06d",listName,item->id()); + item->setText(yyextra->outputXRef); + item->setAnchor(anchorLabel); + yyextra->current->sli.push_back(item); + QCString cmdString; + cmdString.sprintf(" \\xrefitem %s %d.",listName,item->id()); + if (yyextra->inBody) + { + yyextra->current->inbodyDocs += cmdString; + } + else + { + yyextra->current->doc += cmdString; + } + + SectionManager &sm = SectionManager::instance(); + const SectionInfo *si = sm.find(anchorLabel); + if (si) + { + if (si->lineNr() != -1) + { + warn(listName,yyextra->lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",anchorLabel.data(),si->fileName().data(),si->lineNr()); + } + else + { + warn(listName,yyextra->lineNr,"multiple use of section label '%s', (first occurrence: %s)",anchorLabel.data(),si->fileName().data()); + } + } + else + { + si = sm.add(anchorLabel,listName,yyextra->lineNr, + yyextra->sectionTitle,SectionType::Anchor, + yyextra->sectionLevel); + yyextra->current->anchors.push_back(si); + } + } + yyextra->outputXRef.resize(0); +} + +//----------------------------------------------------------------------------- + +// Adds a formula text to the list/dictionary of formulas if it was +// not already added. Returns the label of the formula. +static QCString addFormula(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + QCString formLabel; + QCString fText=yyextra->formulaText.simplifyWhiteSpace(); + int id = FormulaManager::instance().addFormula(fText); + formLabel.sprintf("\\_form#%d",id); + for (int i=0;i<yyextra->formulaNewLines;i++) formLabel+="@_fakenl"; // add fake newlines to + // keep the warnings + // correctly aligned. + return formLabel; +} + +//----------------------------------------------------------------------------- + +static SectionType sectionLevelToType(int level) +{ + if (level>=0 && level<5) return (SectionType)level; + return SectionType::Anchor; +} + +static void addSection(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + SectionManager &sm = SectionManager::instance(); + const SectionInfo *si = sm.find(yyextra->sectionLabel); + if (si) + { + if (si->lineNr() != -1) + { + warn(yyextra->fileName,yyextra->lineNr,"multiple use of section label '%s' while adding section, (first occurrence: %s, line %d)",yyextra->sectionLabel.data(),si->fileName().data(),si->lineNr()); + } + else + { + warn(yyextra->fileName,yyextra->lineNr,"multiple use of section label '%s' while adding section, (first occurrence: %s)",yyextra->sectionLabel.data(),si->fileName().data()); + } + } + else + { + // create a new section element + yyextra->sectionTitle+=yytext; + yyextra->sectionTitle=yyextra->sectionTitle.stripWhiteSpace(); + si = sm.add(yyextra->sectionLabel,yyextra->fileName,yyextra->lineNr, + yyextra->sectionTitle,sectionLevelToType(yyextra->sectionLevel), + yyextra->sectionLevel); -QCString preprocessCommentBlock(const QCString &comment, - const QCString &fileName, - int lineNr) + // add section to this entry + yyextra->current->anchors.push_back(si); + } +} + +//----------------------------------------------------------------------------- + +static void addCite(yyscan_t yyscanner) { - if (!comment.isEmpty() && Doxygen::markdownSupport) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + QCString name=yytext; + if (yytext[0] =='"') { - QCString result = processMarkdown(fileName,lineNr,0,comment); - const char *p = result.data(); - if (p) + name=yytext+1; + name=name.left((int)yyleng-2); + } + CitationManager::instance().insert(name.data()); +} + +//----------------------------------------------------------------------------- + +// strip trailing whitespace (excluding newlines) from string s +static void stripTrailingWhiteSpace(QCString &s) +{ + uint len = s.length(); + int i = (int)len-1; + char c; + while (i>=0 && ((c = s.at(i))==' ' || c=='\t' || c=='\r')) i--; + if (i!=(int)len-1) + { + s.resize(i+2); // string up to and including char at pos i and \0 terminator + } +} + +// selects the output to write to +static inline void setOutput(yyscan_t yyscanner,OutputContext ctx) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool xrefAppendToPrev = yyextra->xrefAppendFlag; + // determine append flag for the next item (i.e. the end of this item) + yyextra->xrefAppendFlag = !yyextra->inBody && + yyextra->inContext==OutputXRef && ctx==OutputXRef && // two consecutive xref items + yyextra->newXRefKind==yyextra->xrefKind && // of the same kind + (yyextra->xrefKind!=XRef_Item || + yyextra->newXRefItemKey==yyextra->xrefItemKey); // with the same key if \xrefitem + //printf("%d && %d && %d && (%d || %d)\n", + // yyextra->inContext==OutputXRef, + // ctx==OutputXRef, + // yyextra->newXRefKind==yyextra->xrefKind, + // yyextra->xrefKind!=XRef_Item, + // yyextra->newXRefItemKey==yyextra->xrefItemKey); + //printf("refKind=%d yyextra->newXRefKind=%d xrefAppendToPrev=%d yyextra->xrefAppendFlag=%d\n", + // yyextra->xrefKind,yyextra->newXRefKind,xrefAppendToPrev,yyextra->xrefAppendFlag); + + //printf("setOutput(yyscanner,yyextra->inContext=%d ctx=%d)\n",yyextra->inContext,ctx); + if (yyextra->inContext==OutputXRef) // end of XRef section => add the item + { + // See if we can append this new xref item to the previous one. + // We know this at the start of the next item of the same + // type and need to remember this until the end of that item. + switch(yyextra->xrefKind) { - while (*p==' ') p++; // skip over spaces - while (*p=='\n') p++; // skip over newlines - if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br> + case XRef_Todo: + addXRefItem(yyscanner,"todo", + theTranslator->trTodo(), + theTranslator->trTodoList(), + xrefAppendToPrev + ); + break; + case XRef_Test: + addXRefItem(yyscanner,"test", + theTranslator->trTest(), + theTranslator->trTestList(), + xrefAppendToPrev + ); + break; + case XRef_Bug: + addXRefItem(yyscanner,"bug", + theTranslator->trBug(), + theTranslator->trBugList(), + xrefAppendToPrev + ); + break; + case XRef_Deprecated: + addXRefItem(yyscanner,"deprecated", + theTranslator->trDeprecated(), + theTranslator->trDeprecatedList(), + xrefAppendToPrev + ); + break; + case XRef_Item: // user defined list + addXRefItem(yyscanner,yyextra->xrefItemKey, + yyextra->xrefItemTitle, + yyextra->xrefListTitle, + xrefAppendToPrev + ); + break; + case XRef_None: + ASSERT(0); + break; } - if (p>result.data()) + } + yyextra->xrefItemKey = yyextra->newXRefItemKey; + + int oldContext = yyextra->inContext; + yyextra->inContext = ctx; + if (yyextra->inContext!=OutputXRef && yyextra->inBody) yyextra->inContext=OutputInbody; + switch(yyextra->inContext) + { + case OutputDoc: + if (oldContext!=yyextra->inContext) + { + stripTrailingWhiteSpace(yyextra->current->doc); + if (yyextra->current->docFile.isEmpty()) + { + yyextra->current->docFile = yyextra->fileName; + yyextra->current->docLine = yyextra->lineNr; + } + } + yyextra->pOutputString = &yyextra->current->doc; + break; + case OutputBrief: + if (oldContext!=yyextra->inContext) + { + if (yyextra->current->briefFile.isEmpty()) + { + yyextra->current->briefFile = yyextra->fileName; + yyextra->current->briefLine = yyextra->lineNr; + } + } + if (yyextra->current->brief.stripWhiteSpace().isEmpty()) // we only want one brief + // description even if multiple + // are given... + { + yyextra->pOutputString = &yyextra->current->brief; + } + else + { + if (!yyextra->current->doc.isEmpty()) // when appending parts add a new line + { + yyextra->current->doc += "\n"; + } + yyextra->pOutputString = &yyextra->current->doc; + yyextra->inContext = OutputDoc; // need to switch to detailed docs, see bug 631380 + } + break; + case OutputXRef: + yyextra->pOutputString = &yyextra->outputXRef; + // first item found, so can't append to previous + //yyextra->xrefAppendFlag = FALSE; + break; + case OutputInbody: + yyextra->pOutputString = &yyextra->current->inbodyDocs; + break; + } +} + + +static void addAnchor(yyscan_t yyscanner,const char *anchor) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + SectionManager &sm = SectionManager::instance(); + const SectionInfo *si = sm.find(anchor); + if (si) + { + if (si->lineNr() != -1) + { + warn(yyextra->fileName,yyextra->lineNr,"multiple use of section label '%s' while adding anchor, (first occurrence: %s, line %d)",anchor,si->fileName().data(),si->lineNr()); + } + else { - // strip part of the input - result = result.mid(p-result.data()); + warn(yyextra->fileName,yyextra->lineNr,"multiple use of section label '%s' while adding anchor, (first occurrence: %s)",anchor,si->fileName().data()); } - return result; } else { - return comment; + si = sm.add(anchor,yyextra->fileName,yyextra->lineNr,nullptr,SectionType::Anchor,0); + yyextra->current->anchors.push_back(si); + } +} + +// add a string to the output +static inline void addOutput(yyscan_t yyscanner,const char *s) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //printf("addOutput(yyscanner,%s)\n",s); + *yyextra->pOutputString+=s; +} + +// add a character to the output +static inline void addOutput(yyscan_t yyscanner,char c) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + *yyextra->pOutputString+=c; +} + +static void endBrief(yyscan_t yyscanner,bool addToOutput) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->current->brief.stripWhiteSpace().isEmpty()) + { // only go to the detailed description if we have + // found some brief description and not just whitespace + yyextra->briefEndsAtDot=FALSE; + setOutput(yyscanner,OutputDoc); + if (addToOutput) addOutput(yyscanner,yytext); + } +} + +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->prevPosition=yyextra->inputPosition; + yy_size_t c=0; + while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) + { + *buf = yyextra->inputString[yyextra->inputPosition++] ; + //printf("%d (%c)\n",*buf,*buf); + c++; buf++; + } + return c; +} + +//---------------------------------------------------------------------------- + +static void checkFormula(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (YY_START==ReadFormulaShort || YY_START==ReadFormulaLong) + { + warn(yyextra->fileName,yyextra->lineNr,"End of comment block while inside formula."); } } -bool parseCommentBlock(/* in */ OutlineParserInterface *parser, +//---------------------------------------------------------------------------- + +struct CommentScanner::Private +{ + yyscan_t yyscanner; + commentscanYY_state extra; +}; + +CommentScanner::CommentScanner() : p(std::make_unique<Private>()) +{ + commentscanYYlex_init_extra(&p->extra,&p->yyscanner); +#ifdef FLEX_DEBUG + commentscanYYset_debug(1,p->yyscanner); +#endif +} + +CommentScanner::~CommentScanner() +{ + commentscanYYlex_destroy(p->yyscanner); +} + +bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *parser, /* in */ Entry *curEntry, /* in */ const QCString &comment, /* in */ const QCString &fileName, @@ -3139,145 +3166,191 @@ bool parseCommentBlock(/* in */ OutlineParserInterface *parser, /* out */ bool &newEntryNeeded ) { + yyscan_t yyscanner = p->yyscanner; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("parseCommentBlock() isBrief=%d isAutoBriefOn=%d lineNr=%d\n", // isBrief,isAutoBriefOn,lineNr); - initParser(); - guards.setAutoDelete(TRUE); - guards.clear(); - langParser = parser; - current = curEntry; + initParser(yyscanner); + yyextra->guards = std::stack<GuardedSection>(); + yyextra->langParser = parser; + yyextra->current = curEntry; if (comment.isEmpty()) return FALSE; // avoid empty strings - inputString = comment; - inputString.append(" "); - inputPosition = position; - yyLineNr = lineNr; - yyFileName = fileName; - protection = prot; - needNewEntry = FALSE; - xrefKind = XRef_None; - xrefAppendFlag = FALSE; - insidePre = FALSE; - parseMore = FALSE; - inBody = isInbody; - outputXRef.resize(0); - if (!isBrief && !isAutoBriefOn && !current->doc.isEmpty()) + yyextra->inputString = comment; + yyextra->inputString.append(" "); + yyextra->inputPosition = position; + yyextra->lineNr = lineNr; + yyextra->fileName = fileName; + yyextra->protection = prot; + yyextra->needNewEntry = FALSE; + yyextra->xrefKind = XRef_None; + yyextra->xrefAppendFlag = FALSE; + yyextra->insidePre = FALSE; + yyextra->parseMore = FALSE; + yyextra->inBody = isInbody; + yyextra->outputXRef.resize(0); + if (!isBrief && !isAutoBriefOn && !yyextra->current->doc.isEmpty()) { // add newline separator between detailed comment blocks - current->doc += '\n'; + yyextra->current->doc += '\n'; } - setOutput( isBrief || isAutoBriefOn ? OutputBrief : OutputDoc ); - briefEndsAtDot = isAutoBriefOn; - g_condCount = 0; - g_sectionLevel = 0; - g_spaceBeforeCmd.resize(0); - g_spaceBeforeIf.resize(0); + setOutput(yyscanner, isBrief || isAutoBriefOn ? OutputBrief : OutputDoc ); + yyextra->briefEndsAtDot = isAutoBriefOn; + yyextra->condCount = 0; + yyextra->sectionLevel = 0; + yyextra->spaceBeforeCmd.resize(0); + yyextra->spaceBeforeIf.resize(0); printlex(yy_flex_debug, TRUE, __FILE__, fileName ? fileName.data(): NULL); - if (!current->inbodyDocs.isEmpty() && isInbody) // separate in body fragments + if (!yyextra->current->inbodyDocs.isEmpty() && isInbody) // separate in body fragments { - current->inbodyDocs+="\n\n"; + yyextra->current->inbodyDocs+="\n\n"; } Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\n" - "input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(inputString) + "input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(yyextra->inputString) ); - commentscanYYrestart( commentscanYYin ); + commentscanYYrestart( 0, yyscanner ); BEGIN( Comment ); - commentscanYYlex(); - setOutput( OutputDoc ); + commentscanYYlex(yyscanner); + setOutput(yyscanner, OutputDoc ); if (YY_START==OverloadParam) // comment ended with \overload { - addOutput(getOverloadDocs()); + addOutput(yyscanner,getOverloadDocs()); } - if (!guards.isEmpty()) + if (!yyextra->guards.empty()) { - warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); + warn(yyextra->fileName,yyextra->lineNr,"Documentation block ended in the middle of a conditional section!"); } - if (g_insideParBlock) + if (yyextra->insideParBlock) { - warn(yyFileName,yyLineNr, + warn(yyextra->fileName,yyextra->lineNr, "Documentation block ended while inside a \\parblock. Missing \\endparblock"); } - current->doc=stripLeadingAndTrailingEmptyLines(current->doc,current->docLine); + yyextra->current->doc=stripLeadingAndTrailingEmptyLines(yyextra->current->doc,yyextra->current->docLine); - if (current->section==Entry::FILEDOC_SEC && current->doc.isEmpty()) + if (yyextra->current->section==Entry::FILEDOC_SEC && yyextra->current->doc.isEmpty()) { // to allow a comment block with just a @file command. - current->doc="\n\n"; + yyextra->current->doc="\n\n"; } - if (current->section==Entry::MEMBERGRP_SEC && - Doxygen::docGroup.isEmpty()) // @name section but no group started yet + if (yyextra->current->section==Entry::MEMBERGRP_SEC && + yyextra->docGroup.isEmpty()) // @name section but no group started yet { - Doxygen::docGroup.open(current,yyFileName,yyLineNr,true); + yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr,true); } Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\noutput=[\n" "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n]\n===========\n", qPrint(fileName),lineNr, - current->briefLine,qPrint(current->brief), - current->docLine,qPrint(current->doc), - current->inbodyLine,qPrint(current->inbodyDocs) + yyextra->current->briefLine,qPrint(yyextra->current->brief), + yyextra->current->docLine,qPrint(yyextra->current->doc), + yyextra->current->inbodyLine,qPrint(yyextra->current->inbodyDocs) ); - checkFormula(); - prot = protection; + checkFormula(yyscanner); + prot = yyextra->protection; - Doxygen::docGroup.addDocs(curEntry); + yyextra->docGroup.addDocs(curEntry); - newEntryNeeded = needNewEntry; + newEntryNeeded = yyextra->needNewEntry; // if we did not proceed during this call, it does not make // sense to continue, since we get stuck. See bug 567346 for situations // were this happens - if (parseMore && position==inputPosition) parseMore=FALSE; + if (yyextra->parseMore && position==yyextra->inputPosition) yyextra->parseMore=FALSE; - if (parseMore) position=inputPosition; else position=0; + if (yyextra->parseMore) position=yyextra->inputPosition; else position=0; - lineNr = yyLineNr; - //printf("position=%d parseMore=%d newEntryNeeded=%d\n", - // position,parseMore,newEntryNeeded); + lineNr = yyextra->lineNr; + //printf("position=%d yyextra->parseMore=%d newEntryNeeded=%d\n", + // position,yyextra->parseMore,newEntryNeeded); printlex(yy_flex_debug, FALSE, __FILE__, fileName ? fileName.data(): NULL); - return parseMore; + return yyextra->parseMore; } -static void handleGuard(const QCString &expr) +static void handleGuard(yyscan_t yyscanner,const QCString &expr) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; CondParser prs; - bool sectionEnabled=prs.parse(yyFileName,yyLineNr,expr.stripWhiteSpace()); + bool sectionEnabled=prs.parse(yyextra->fileName,yyextra->lineNr,expr.stripWhiteSpace()); bool parentEnabled = TRUE; - if (!guards.isEmpty()) parentEnabled = guards.top()->isEnabled(); + if (!yyextra->guards.empty()) parentEnabled = yyextra->guards.top().isEnabled(); if (parentEnabled) { if ( - (sectionEnabled && guardType==Guard_If) || - (!sectionEnabled && guardType==Guard_IfNot) + (sectionEnabled && yyextra->guardType==Guard_If) || + (!sectionEnabled && yyextra->guardType==Guard_IfNot) ) // section is visible { - guards.push(new GuardedSection(TRUE,TRUE)); - enabledSectionFound=TRUE; + yyextra->guards.push(GuardedSection(TRUE,TRUE)); + yyextra->enabledSectionFound=TRUE; BEGIN( GuardParamEnd ); } else // section is invisible { - if (guardType!=Guard_Skip) + if (yyextra->guardType!=Guard_Skip) { - guards.push(new GuardedSection(FALSE,TRUE)); + yyextra->guards.push(GuardedSection(FALSE,TRUE)); } BEGIN( SkipGuardedSection ); } } else // invisible because of parent { - guards.push(new GuardedSection(FALSE,FALSE)); + yyextra->guards.push(GuardedSection(FALSE,FALSE)); BEGIN( SkipGuardedSection ); } } +void CommentScanner::initGroupInfo(Entry *entry) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.initGroupInfo(entry); +} + +void CommentScanner::enterFile(const char *fileName,int lineNr) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.enterFile(fileName,lineNr); +} + +void CommentScanner::leaveFile(const char *fileName,int lineNr) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.leaveFile(fileName,lineNr); +} + +void CommentScanner::enterCompound(const char *fileName,int lineNr,const char *name) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.enterCompound(fileName,lineNr,name); +} + +void CommentScanner::leaveCompound(const char *fileName,int lineNr,const char *name) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.leaveCompound(fileName,lineNr,name); +} + +void CommentScanner::open(Entry *e,const char *fileName,int lineNr,bool implicit) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.open(e,fileName,lineNr,implicit); +} + +void CommentScanner::close(Entry *e,const char *fileName,int lineNr,bool foundInline,bool implicit) +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->docGroup.close(e,fileName,lineNr,foundInline,implicit); +} + +#if USE_STATE2STRING #include "commentscan.l.h" +#endif diff --git a/src/condparser.cpp b/src/condparser.cpp index 9d7ac45..e76b164 100644 --- a/src/condparser.cpp +++ b/src/condparser.cpp @@ -102,8 +102,7 @@ static bool isAlpha(const char c) static bool isAlphaNumSpec(const char c) { - return isAlpha(c) || (c>='0' && c<='9') || c=='-' || c=='.' || - (((unsigned char)c)>=0x80 && ((unsigned char)c)<=0xFF); + return isAlpha(c) || (c>='0' && c<='9') || c=='-' || c=='.' || (((unsigned char)c)>=0x80); } /** diff --git a/src/config.xml b/src/config.xml index f40744d..61ee9fa 100644 --- a/src/config.xml +++ b/src/config.xml @@ -585,16 +585,6 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> - <option type='list' id='TCL_SUBST' format='string'> - <docs> -<![CDATA[ - This tag can be used to specify a number of word-keyword mappings (TCL only). - A mapping has the form <code>"name=value"</code>. For example adding - <code>"class=itcl::class"</code> will allow you to use the command class in the - <code>itcl::class</code> meaning. -]]> - </docs> - </option> <option type='bool' id='OPTIMIZE_OUTPUT_FOR_C' defval='0'> <docs> <![CDATA[ @@ -649,10 +639,10 @@ Go to the <a href="commands.html">next</a> section or return to the Doxygen has a built-in mapping, but you can override or extend it using this tag. The format is <code>ext=language</code>, where \c ext is a file extension, and language is one of the parsers supported by doxygen: IDL, Java, JavaScript, Csharp (C#), C, C++, D, PHP, - md (Markdown), Objective-C, Python, Slice, Fortran (fixed format Fortran: FortranFixed, + md (Markdown), Objective-C, Python, Slice, VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In the later case the parser tries to guess whether the code is fixed or free - formatted code, this is the default for Fortran type files), VHDL, tcl. + formatted code, this is the default for Fortran type files). For instance to make doxygen treat <code>.inc</code> files as Fortran files (default is PHP), and <code>.f</code> files as C (default is Fortran), @@ -1413,9 +1403,9 @@ FILE_VERSION_FILTER = "cleartool desc -fmt \%Vn" <value name='*.f95'/> <value name='*.f03'/> <value name='*.f08'/> + <value name='*.f18'/> <value name='*.f'/> <value name='*.for'/> - <value name='*.tcl'/> <value name='*.vhd'/> <value name='*.vhdl'/> <value name='*.ucf'/> @@ -2357,6 +2347,18 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. ]]> </docs> </option> + <option type='enum' id='HTML_FORMULA_FORMAT' defval='png' depends='GENERATE_HTML'> + <docs> +<![CDATA[ + If the \c HTML_FORMULA_FORMAT option is set to \c svg, doxygen will use the pdf2svg + tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see https://inkscape.org) + to generate formulas as SVG images instead of + PNGs for the HTML output. These images will generally look nicer at scaled resolutions. +]]> + </docs> + <value name="png" desc="The default"/> + <value name="svg" desc="Looks nicer but requires the pdf2svg tool"/> + </option> <option type='int' id='FORMULA_FONTSIZE' minval='8' maxval='50' defval='10' depends='GENERATE_HTML'> <docs> <![CDATA[ @@ -2415,7 +2417,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <value name="NativeMML" desc="(i.e. MathML)"/> <value name="SVG"/> </option> - <option type='string' id='MATHJAX_RELPATH' format='string' defval='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/' depends='USE_MATHJAX'> + <option type='string' id='MATHJAX_RELPATH' format='string' defval='https://cdn.jsdelivr.net/npm/mathjax@2' depends='USE_MATHJAX'> <docs> <![CDATA[ When MathJax is enabled you need to specify the location relative to the @@ -3643,5 +3645,6 @@ remove the intermediate dot files that are used to generate the various graphs. <option type='obsolete' id='XML_DTD'/> <option type='obsolete' id='PERL_PATH'/> <option type='obsolete' id='MSCGEN_PATH'/> + <option type='obsolete' id='TCL_SUBST'/> </group> </doxygenconfig> diff --git a/src/configimpl.h b/src/configimpl.h index 6b85d8a..6134088 100644 --- a/src/configimpl.h +++ b/src/configimpl.h @@ -158,6 +158,7 @@ class ConfigEnum : public ConfigOption QCString *valueRef() { return &m_value; } void substEnvVars(); void writeTemplate(FTextStream &t,bool sl,bool); + void convertStrToVal(); void compareDoxyfile(FTextStream &t); void init() { m_value = m_defValue.copy(); } diff --git a/src/configimpl.l b/src/configimpl.l index 4da1634..d07e25c 100644 --- a/src/configimpl.l +++ b/src/configimpl.l @@ -11,6 +11,9 @@ */ %option never-interactive %option prefix="configimplYY" +%top{ +#include <stdint.h> +} %{ @@ -30,8 +33,8 @@ #include <qregexp.h> #include <qstack.h> #include <qglobal.h> -#include <qthread.h> - +#include <thread> + #include "configimpl.h" #include "version.h" #include "portable.h" @@ -44,7 +47,11 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + +#if USE_STATE2STRING static const char *stateToString(int state); +#endif static const char *warning_str = "warning: "; static const char *error_str = "error: "; @@ -93,20 +100,27 @@ static QCString convertToComment(const QCString &s, const QCString &u) QCString tmp=s.stripWhiteSpace(); const char *p=tmp.data(); char c; - result+="#"; - if (*p && *p!='\n') - result+=" "; - while ((c=*p++)) + if (p) { - if (c=='\n') + result+="#"; + if (*p && *p!='\n') { - result+="\n#"; - if (*p && *p!='\n') - result+=" "; + result+=" "; + } + while ((c=*p++)) + { + if (c=='\n') + { + result+="\n#"; + if (*p && *p!='\n') + { + result+=" "; + } + } + else result+=c; } - else result+=c; + result+='\n'; } - result+='\n'; } if (!u.isEmpty()) { @@ -131,7 +145,7 @@ void ConfigOption::writeStringValue(FTextStream &t,QCString &s) { char c; bool needsEscaping=FALSE; - // convert the string back to it original encoding + // convert the string back to it original g_encoding QCString se = configStringRecode(s,"UTF-8",m_encoding); const char *p=se.data(); if (p) @@ -218,6 +232,25 @@ void ConfigBool::convertStrToVal() } } +void ConfigEnum::convertStrToVal() +{ + QCString val = m_value.stripWhiteSpace().lower(); + const char *s=m_valueRange.first(); + while (s) + { + if (QCString(s).lower() == val) + { + m_value = s; + return; + } + s = m_valueRange.next(); + } + + config_warn("argument '%s' for option %s is not a valid enum value\n" + "Using the default: %s!\n",m_value.data(),m_name.data(),m_defValue.data()); + m_value = m_defValue; +} + QCString &ConfigImpl::getString(const char *fileName,int num,const char *name) const { ConfigOption *opt = m_dict->find(name); @@ -508,47 +541,47 @@ struct ConfigFileState QCString fileName; }; -static const char *inputString; -static int inputPosition; -static int yyLineNr; -static QCString yyFileName; -static QCString tmpString; -static QCString *s=0; -static bool *b=0; -static QStrList *l=0; -static int lastState; -static QCString elemStr; -static QStrList includePathList; -static QStack<ConfigFileState> includeStack; -static int includeDepth; -static bool config_upd = FALSE; -static QCString encoding; -static ConfigImpl *config; +static const char *g_inputString; +static int g_inputPosition; +static int g_yyLineNr; +static QCString g_yyFileName; +static QCString g_tmpString; +static QCString *g_string=0; +static bool *g_bool=0; +static QStrList *g_list=0; +static int g_lastState; +static QCString g_elemStr; +static QStrList g_includePathList; +static QStack<ConfigFileState> g_includeStack; +static int g_includeDepth; +static bool g_configUpdate = FALSE; +static QCString g_encoding; +static ConfigImpl *g_config; /* ----------------------------------------------------------------- */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -static int yyread(char *buf,int max_size) +static yy_size_t yyread(char *buf,yy_size_t max_size) { - // no file included - if (includeStack.isEmpty()) - { - int c=0; - if (inputString==0) return c; - while( c < max_size && inputString[inputPosition] ) - { - *buf = inputString[inputPosition++] ; - c++; buf++; - } - return c; - } - else + // no file included + if (g_includeStack.isEmpty()) + { + yy_size_t c=0; + if (g_inputString==0) return c; + while( c < max_size && g_inputString[g_inputPosition] ) { - //assert(includeStack.current()->newState==YY_CURRENT_BUFFER); - return (int)fread(buf,1,max_size,includeStack.current()->filePtr); + *buf = g_inputString[g_inputPosition++] ; + c++; buf++; } + return c; + } + else + { + //assert(g_includeStack.current()->newState==YY_CURRENT_BUFFER); + return (yy_size_t)fread(buf,1,max_size,g_includeStack.current()->filePtr); + } } @@ -591,8 +624,8 @@ static QCString configStringRecode( static void checkEncoding() { - ConfigString *option = (ConfigString*)config->get("DOXYFILE_ENCODING"); - encoding = *option->valueRef(); + ConfigString *option = (ConfigString*)g_config->get("DOXYFILE_ENCODING"); + g_encoding = *option->valueRef(); } static FILE *tryPath(const char *path,const char *fileName) @@ -621,21 +654,21 @@ static FILE *findFile(const char *fileName) { return tryPath(NULL, fileName); } - substEnvVarsInStrList(includePathList); - char *s=includePathList.first(); + substEnvVarsInStrList(g_includePathList); + char *s=g_includePathList.first(); while (s) // try each of the include paths { FILE *f = tryPath(s,fileName); if (f) return f; - s=includePathList.next(); + s=g_includePathList.next(); } - // try cwd if includePathList fails + // try cwd if g_includePathList fails return tryPath(".",fileName); } static void readIncludeFile(const char *incName) { - if (includeDepth==MAX_INCLUDE_DEPTH) { + if (g_includeDepth==MAX_INCLUDE_DEPTH) { config_term("maximum include depth (%d) reached, %s is not included. Aborting...\n", MAX_INCLUDE_DEPTH,incName); } @@ -655,23 +688,23 @@ static void readIncludeFile(const char *incName) { // For debugging #if SHOW_INCLUDES - for (i=0;i<includeStack.count();i++) msg(" "); + for (i=0;i<g_includeStack.count();i++) msg(" "); msg("@INCLUDE = %s: parsing...\n",inc.data()); #endif // store the state of the old file ConfigFileState *fs=new ConfigFileState; fs->oldState=YY_CURRENT_BUFFER; - fs->lineNr=yyLineNr; - fs->fileName=yyFileName; + fs->lineNr=g_yyLineNr; + fs->fileName=g_yyFileName; fs->filePtr=f; // push the state on the stack - includeStack.push(fs); + g_includeStack.push(fs); // set the scanner to the include file yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); fs->newState=YY_CURRENT_BUFFER; - yyFileName=inc; - includeDepth++; + g_yyFileName=inc; + g_includeDepth++; } else { @@ -691,6 +724,7 @@ static void readIncludeFile(const char *incName) %x GetString %x GetBool %x GetStrList +%x GetStrList1 %x GetQuotedString %x GetEnvVar %x Include @@ -698,26 +732,26 @@ static void readIncludeFile(const char *incName) %% <*>\0x0d -<PreStart>"##".*"\n" { config->appendStartComment(yytext);yyLineNr++;} +<PreStart>"##".*"\n" { g_config->appendStartComment(yytext);g_yyLineNr++;} <PreStart>. { BEGIN(Start); unput(*yytext); } -<Start,GetString,GetStrList,GetBool,SkipInvalid>"##".*"\n" { config->appendUserComment(yytext);yyLineNr++;} -<Start,GetString,GetStrList,GetBool,SkipInvalid>"#" { BEGIN(SkipComment); } +<Start,GetString,GetStrList,GetStrList1,GetBool,SkipInvalid>"##".*"\n" { g_config->appendUserComment(yytext);g_yyLineNr++;} +<Start,GetString,GetStrList,GetStrList1,GetBool,SkipInvalid>"#" { BEGIN(SkipComment); } <Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QCString cmd=yytext; cmd=cmd.left(cmd.length()-1).stripWhiteSpace(); - ConfigOption *option = config->get(cmd); + ConfigOption *option = g_config->get(cmd); if (option==0) // oops not known { config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", - cmd.data(),yyLineNr,yyFileName.data()); + cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); } else // known tag { - option->setUserComment(config->takeUserComment()); - option->setEncoding(encoding); + option->setUserComment(g_config->takeUserComment()); + option->setEncoding(g_encoding); switch(option->kind()) { case ConfigOption::O_Info: @@ -725,56 +759,63 @@ static void readIncludeFile(const char *incName) BEGIN(SkipInvalid); break; case ConfigOption::O_List: - l = ((ConfigList *)option)->valueRef(); - l->clear(); - elemStr=""; - BEGIN(GetStrList); + g_list = ((ConfigList *)option)->valueRef(); + g_list->clear(); + g_elemStr=""; + if (cmd == "PREDEFINED") + { + BEGIN(GetStrList1); + } + else + { + BEGIN(GetStrList); + } break; case ConfigOption::O_Enum: - s = ((ConfigEnum *)option)->valueRef(); - s->resize(0); + g_string = ((ConfigEnum *)option)->valueRef(); + g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_String: - s = ((ConfigString *)option)->valueRef(); - s->resize(0); + g_string = ((ConfigString *)option)->valueRef(); + g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_Int: - s = ((ConfigInt *)option)->valueStringRef(); - s->resize(0); + g_string = ((ConfigInt *)option)->valueStringRef(); + g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_Bool: - s = ((ConfigBool *)option)->valueStringRef(); - s->resize(0); + g_string = ((ConfigBool *)option)->valueStringRef(); + g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_Obsolete: - if (config_upd) + if (g_configUpdate) { config_warn("Tag '%s' at line %d of file '%s' has become obsolete.\n" - " This tag has been removed.\n", cmd.data(),yyLineNr,yyFileName.data()); + " This tag has been removed.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); } else { config_warn("Tag '%s' at line %d of file '%s' has become obsolete.\n" " To avoid this warning please remove this line from your configuration " - "file or upgrade it using \"doxygen -u\"\n", cmd.data(),yyLineNr,yyFileName.data()); + "file or upgrade it using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); } BEGIN(SkipInvalid); break; case ConfigOption::O_Disabled: - if (config_upd) + if (g_configUpdate) { config_warn("Tag '%s' at line %d of file '%s' belongs to an option that was not enabled at compile time.\n" - " This tag has been removed.\n", cmd.data(),yyLineNr,yyFileName.data()); + " This tag has been removed.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); } else { config_warn("Tag '%s' at line %d of file '%s' belongs to an option that was not enabled at compile time.\n" " To avoid this warning please remove this line from your configuration " - "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),yyLineNr,yyFileName.data()); + "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); } BEGIN(SkipInvalid); break; @@ -783,16 +824,16 @@ static void readIncludeFile(const char *incName) } <Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QCString cmd=yytext; cmd=cmd.left(cmd.length()-2).stripWhiteSpace(); - ConfigOption *option = config->get(cmd); + ConfigOption *option = g_config->get(cmd); if (option==0) // oops not known { config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", - cmd.data(),yyLineNr,yyFileName.data()); + cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); } else // known tag { - option->setUserComment(config->takeUserComment()); + option->setUserComment(g_config->takeUserComment()); switch(option->kind()) { case ConfigOption::O_Info: @@ -800,135 +841,153 @@ static void readIncludeFile(const char *incName) BEGIN(SkipInvalid); break; case ConfigOption::O_List: - l = ((ConfigList *)option)->valueRef(); - elemStr=""; - BEGIN(GetStrList); + g_list = ((ConfigList *)option)->valueRef(); + g_elemStr=""; + if (cmd == "PREDEFINED") + { + BEGIN(GetStrList1); + } + else + { + BEGIN(GetStrList); + } break; case ConfigOption::O_Enum: case ConfigOption::O_String: case ConfigOption::O_Int: case ConfigOption::O_Bool: config_warn("operator += not supported for '%s'. Ignoring line at line %d, file %s\n", - yytext,yyLineNr,yyFileName.data()); + yytext,g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); break; case ConfigOption::O_Obsolete: config_warn("Tag '%s' at line %d of file %s has become obsolete.\n" "To avoid this warning please update your configuration " - "file using \"doxygen -u\"\n", cmd.data(),yyLineNr,yyFileName.data()); + "file using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); break; case ConfigOption::O_Disabled: config_warn("Tag '%s' at line %d of file %s belongs to an option that was not enabled at compile time.\n" "To avoid this warning please remove this line from your configuration " - "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),yyLineNr,yyFileName.data()); + "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); break; } } } -<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&includePathList; l->clear(); elemStr=""; } - /* include a config file */ +<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_list=&g_includePathList; g_list->clear(); g_elemStr=""; } + /* include a g_config file */ <Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);} <Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") { - readIncludeFile(configStringRecode(yytext,encoding,"UTF-8")); + readIncludeFile(configStringRecode(yytext,g_encoding,"UTF-8")); BEGIN(Start); } <<EOF>> { //printf("End of include file\n"); //printf("Include stack depth=%d\n",g_includeStack.count()); - if (includeStack.isEmpty()) + if (g_includeStack.isEmpty()) { //printf("Terminating scanner!\n"); yyterminate(); } else { - ConfigFileState *fs=includeStack.pop(); + ConfigFileState *fs=g_includeStack.pop(); fclose(fs->filePtr); YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER; yy_switch_to_buffer( fs->oldState ); yy_delete_buffer( oldBuf ); - yyLineNr=fs->lineNr; - yyFileName=fs->fileName; + g_yyLineNr=fs->lineNr; + g_yyFileName=fs->fileName; delete fs; fs=0; - includeDepth--; + g_includeDepth--; } } -<Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag '%s' at line %d, file %s\n",yytext,yyLineNr,yyFileName.data()); } -<GetString,GetBool,SkipInvalid>\n { yyLineNr++; BEGIN(Start); } -<GetStrList>\n { - yyLineNr++; - if (!elemStr.isEmpty()) +<Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag '%s' at line %d, file %s\n",yytext,g_yyLineNr,g_yyFileName.data()); } +<GetString,GetBool,SkipInvalid>\n { g_yyLineNr++; BEGIN(Start); } +<GetStrList,GetStrList1>\n { + g_yyLineNr++; + if (!g_elemStr.isEmpty()) { - //printf("elemStr1='%s'\n",elemStr.data()); - l->append(elemStr); + //printf("elemStr1='%s'\n",g_elemStr.data()); + g_list->append(g_elemStr); } BEGIN(Start); } +<GetStrList1>[ \t]+ { + if (!g_elemStr.isEmpty()) + { + //printf("elemStr2='%s'\n",g_elemStr.data()); + g_list->append(g_elemStr); + } + g_elemStr.resize(0); + } <GetStrList>[ \t,]+ { - if (!elemStr.isEmpty()) + if (!g_elemStr.isEmpty()) { - //printf("elemStr2='%s'\n",elemStr.data()); - l->append(elemStr); + //printf("elemStr2='%s'\n",g_elemStr.data()); + g_list->append(g_elemStr); } - elemStr.resize(0); + g_elemStr.resize(0); } -<GetString>[^ \"\t\r\n]+ { (*s)+=configStringRecode(yytext,encoding,"UTF-8"); +<GetString>[^ \"\t\r\n]+ { (*g_string)+=configStringRecode(yytext,g_encoding,"UTF-8"); checkEncoding(); } -<GetString,GetStrList,SkipInvalid>"\"" { lastState=YY_START; +<GetString,GetStrList,GetStrList1,SkipInvalid>"\"" { g_lastState=YY_START; BEGIN(GetQuotedString); - tmpString.resize(0); + g_tmpString.resize(0); } <GetQuotedString>"\""|"\n" { // we add a bogus space to signal that the string was quoted. This space will be stripped later on. - tmpString+=" "; - //printf("Quoted String = '%s'\n",tmpString.data()); - if (lastState==GetString) + g_tmpString+=" "; + //printf("Quoted String = '%s'\n",g_tmpString.data()); + if (g_lastState==GetString) { - (*s)+=configStringRecode(tmpString,encoding,"UTF-8"); + (*g_string)+=configStringRecode(g_tmpString,g_encoding,"UTF-8"); checkEncoding(); } else { - elemStr+=configStringRecode(tmpString,encoding,"UTF-8"); + g_elemStr+=configStringRecode(g_tmpString,g_encoding,"UTF-8"); } if (*yytext=='\n') { - config_warn("Missing end quote (\") on line %d, file %s\n",yyLineNr,yyFileName.data()); - yyLineNr++; + config_warn("Missing end quote (\") on line %d, file %s\n",g_yyLineNr,g_yyFileName.data()); + g_yyLineNr++; } - BEGIN(lastState); + BEGIN(g_lastState); } <GetQuotedString>"\\\"" { - tmpString+='"'; + g_tmpString+='"'; } -<GetQuotedString>. { tmpString+=*yytext; } +<GetQuotedString>. { g_tmpString+=*yytext; } <GetBool>[a-zA-Z]+ { QCString bs=yytext; bs=bs.upper(); if (bs=="YES" || bs=="1") - *b=TRUE; + *g_bool=TRUE; else if (bs=="NO" || bs=="0") - *b=FALSE; + *g_bool=FALSE; else { - *b=FALSE; + *g_bool=FALSE; config_warn("Invalid value '%s' for " "boolean tag in line %d, file %s; use YES or NO\n", - bs.data(),yyLineNr,yyFileName.data()); + bs.data(),g_yyLineNr,g_yyFileName.data()); } } +<GetStrList1>[^ \#\"\t\r\n]+ { + g_elemStr+=configStringRecode(yytext,g_encoding,"UTF-8"); + } <GetStrList>[^ \#\"\t\r\n,]+ { - elemStr+=configStringRecode(yytext,encoding,"UTF-8"); + g_elemStr+=configStringRecode(yytext,g_encoding,"UTF-8"); } -<SkipComment>\n { yyLineNr++; BEGIN(Start); } -<SkipComment>\\[ \r\t]*\n { yyLineNr++; BEGIN(Start); } -<*>\\[ \r\t]*\n { yyLineNr++; } +<SkipComment>\n { g_yyLineNr++; BEGIN(Start); } +<SkipComment>\\[ \r\t]*\n { g_yyLineNr++; BEGIN(Start); } +<*>\\[ \r\t]*\n { g_yyLineNr++; } <*>. -<*>\n { yyLineNr++ ; } +<*>\n { g_yyLineNr++ ; } %% @@ -942,7 +1001,7 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd) { t << takeStartComment() << endl; } - t << "# Doxyfile " << getVersion() << endl << endl; + t << "# Doxyfile " << getDoxygenVersion() << endl << endl; if (!sl) { t << convertToComment(m_header,""); @@ -963,11 +1022,7 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd) void ConfigImpl::compareDoxyfile(FTextStream &t) { - t << "# Difference with default Doxyfile " << getVersion(); - if (strlen(getGitVersion())) - { - t << " (" << getGitVersion() << ")"; - } + t << "# Difference with default Doxyfile " << getFullVersion(); t << endl; QListIterator<ConfigOption> it = iterator(); ConfigOption *option; @@ -1231,27 +1286,27 @@ static QCString configFileToString(const char *name) bool ConfigImpl::parseString(const char *fn,const char *str,bool update) { - config = ConfigImpl::instance(); - inputString = str; - inputPosition = 0; - yyFileName = fn; - yyLineNr = 1; - includeStack.setAutoDelete(TRUE); - includeStack.clear(); - includeDepth = 0; + g_config = ConfigImpl::instance(); + g_inputString = str; + g_inputPosition = 0; + g_yyFileName = fn; + g_yyLineNr = 1; + g_includeStack.setAutoDelete(TRUE); + g_includeStack.clear(); + g_includeDepth = 0; configimplYYrestart( configimplYYin ); BEGIN( PreStart ); - config_upd = update; + g_configUpdate = update; configimplYYlex(); - config_upd = FALSE; - inputString = 0; + g_configUpdate = FALSE; + g_inputString = 0; return TRUE; } bool ConfigImpl::parse(const char *fn,bool update) { int retval; - encoding = "UTF-8"; + g_encoding = "UTF-8"; printlex(yy_flex_debug, TRUE, __FILE__, fn); retval = parseString(fn,configFileToString(fn), update); printlex(yy_flex_debug, FALSE, __FILE__, fn); @@ -1284,13 +1339,13 @@ static void cleanUpPaths(QStrList &str) if (fi.exists() && fi.isDir()) { int i = str.at(); - QCString p = fi.absFilePath().utf8(); - if (p[p.length()-1]!='/') p+='/'; + QCString path_str = fi.absFilePath().utf8(); + if (path_str[path_str.length()-1]!='/') path_str+='/'; str.remove(); if (str.at()==i) // did not remove last item - str.insert(i,p); + str.insert(i,path_str); else - str.append(p); + str.append(path_str); } } sfp = str.next(); @@ -1541,6 +1596,9 @@ void Config::checkAndCorrect() s=aliasList.next(); } + // check EXTENSION_MAPPING + checkList(Config_getList(EXTENSION_MAPPING),"EXTENSION_MAPPING",TRUE,TRUE); + // check FILTER_PATTERNS checkList(Config_getList(FILTER_PATTERNS),"FILTER_PATTERNS",TRUE,TRUE); @@ -1556,9 +1614,6 @@ void Config::checkAndCorrect() checkList(Config_getList(EXTRA_SEARCH_MAPPINGS),"EXTRA_SEARCH_MAPPING",TRUE,TRUE); } - // check TCL_SUBST - checkList(Config_getList(TCL_SUBST),"TCL_SUBST",TRUE,TRUE); - // check if GENERATE_TREEVIEW and GENERATE_HTMLHELP are both enabled if (Config_getBool(GENERATE_TREEVIEW) && Config_getBool(GENERATE_HTMLHELP)) { @@ -1623,7 +1678,7 @@ void Config::checkAndCorrect() } else if (dotNumThreads<=0) { - dotNumThreads=QMAX(2,QThread::idealThreadCount()+1); + dotNumThreads=QMAX(2,std::thread::hardware_concurrency()+1); } // check dot path @@ -1952,7 +2007,7 @@ void Config::postProcess(bool clearHeaderAndFooter, bool compare) if (!compare)ConfigImpl::instance()->emptyValueToDefault(); ConfigImpl::instance()->convertStrToVal(); - // avoid bootstrapping issues when the config file already + // avoid bootstrapping issues when the g_config file already // refers to the files that we are supposed to parse. if (clearHeaderAndFooter) { @@ -1968,4 +2023,6 @@ void Config::deinit() ConfigImpl::instance()->deleteInstance(); } +#if USE_STATE2STRING #include "configimpl.l.h" +#endif diff --git a/src/constexp.l b/src/constexp.l index eae8a3b..a14f8d3 100644 --- a/src/constexp.l +++ b/src/constexp.l @@ -20,6 +20,9 @@ %option nounput %option reentrant bison-bridge %option extra-type="struct constexpYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -32,8 +35,13 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + +#if USE_STATE2STRING static const char *stateToString(int state); -static int yyread(char *buf,int max_size,yyscan_t yyscanner); +#endif + +static yy_size_t yyread(char *buf,yy_size_t max_size,yyscan_t yyscanner); #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner); @@ -93,10 +101,10 @@ CONSTSUFFIX ([uU][lL]?[lL]?)|([lL][lL]?[uU]?) %% -static int yyread(char *buf,int max_size,yyscan_t yyscanner) +static yy_size_t yyread(char *buf,yy_size_t max_size,yyscan_t yyscanner) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int c=0; + yy_size_t c=0; while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) { *buf = yyextra->inputString[yyextra->inputPosition++] ; @@ -153,4 +161,7 @@ bool ConstExpressionParser::parse(const char *fileName,int lineNr,const QCString extern "C" { int constexpYYwrap(yyscan_t yyscanner) { return 1; } } + +#if USE_STATE2STRING #include "constexp.l.h" +#endif diff --git a/src/context.cpp b/src/context.cpp index 5ee89cd..0577531 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -180,14 +180,14 @@ class GenericNodeListContext : public TemplateListIntf } // TemplateListIntf methods - int count() const + uint count() const { - return (int)m_children.count(); + return m_children.count(); } - TemplateVariant at(int index) const + TemplateVariant at(uint index) const { TemplateVariant result; - if (index>=0 && index<count()) + if (index<count()) { result = *m_children.at(index); } @@ -380,7 +380,7 @@ class DoxygenContext::Private public: TemplateVariant version() const { - return getVersion(); + return getDoxygenVersion(); } TemplateVariant date() const { @@ -1397,6 +1397,7 @@ class DefinitionContext { assert(d!=0); } + virtual ~DefinitionContext() {} void addBaseProperties(PropertyMapper<T> &inst) { //%% string name: the name of the symbol @@ -1544,7 +1545,6 @@ class DefinitionContext case SrcLangExt_VHDL: result="vhdl"; break; case SrcLangExt_XML: result="xml"; break; case SrcLangExt_SQL: result="sql"; break; - case SrcLangExt_Tcl: result="tcl"; break; case SrcLangExt_Markdown: result="markdown"; break; case SrcLangExt_Slice: result="slice"; break; } @@ -1794,12 +1794,12 @@ IncludeInfoListContext::~IncludeInfoListContext() } // TemplateListIntf -int IncludeInfoListContext::count() const +uint IncludeInfoListContext::count() const { return p->count(); } -TemplateVariant IncludeInfoListContext::at(int index) const +TemplateVariant IncludeInfoListContext::at(uint index) const { return p->at(index); } @@ -2007,7 +2007,6 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> { case ContextOutputFormat_Html: { - QGString result; FTextStream tt(&result); QCString name = convertToHtml(m_classDef->displayName()); @@ -2136,7 +2135,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> return cache.inheritedByList.get(); } TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list, - MemberListType type,const char *title,bool detailed=FALSE) const + MemberListType type,const char *title,bool=FALSE) const { if (!list) { @@ -2834,7 +2833,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri return cache.constantgroups.get(); } TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list, - MemberListType type,const char *title,bool detailed=FALSE) const + MemberListType type,const char *title,bool=FALSE) const { if (!list) { @@ -3293,7 +3292,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> return cache.constantgroups.get(); } TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list, - MemberListType type,const char *title,bool detailed=FALSE) const + MemberListType type,const char *title,bool=FALSE) const { if (!list) { @@ -5564,7 +5563,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> } TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list, - MemberListType type,const char *title,bool detailed=FALSE) const + MemberListType type,const char *title,bool=FALSE) const { if (!list) { @@ -5852,12 +5851,12 @@ ClassListContext::~ClassListContext() } // TemplateListIntf -int ClassListContext::count() const +uint ClassListContext::count() const { return p->count(); } -TemplateVariant ClassListContext::at(int index) const +TemplateVariant ClassListContext::at(uint index) const { return p->at(index); } @@ -6608,19 +6607,15 @@ class NestingContext::Private : public GenericNodeListContext m_index++; } } - void addFiles(const FileNameList &fnList) + void addFiles(const FileNameLinkedMap &fnList) { - FileNameListIterator fnli(fnList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const FileNameLinkedMap::Ptr &fn : fnList) { - FileNameIterator fni(*fn); - const FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->getDirDef()==0) // top level file { - append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE,FALSE,FALSE)); + append(NestingNodeContext::alloc(m_parent,fd.get(),m_index,m_level,FALSE,FALSE,FALSE)); m_index++; } } @@ -6760,12 +6755,12 @@ NestingContext::~NestingContext() } // TemplateListIntf -int NestingContext::count() const +uint NestingContext::count() const { return p->count(); } -TemplateVariant NestingContext::at(int index) const +TemplateVariant NestingContext::at(uint index) const { return p->at(index); } @@ -6795,7 +6790,7 @@ void NestingContext::addDirs(const DirList &dirs) p->addDirs(dirs); } -void NestingContext::addFiles(const FileNameList &files) +void NestingContext::addFiles(const FileNameLinkedMap &files) { p->addFiles(files); } @@ -6987,12 +6982,12 @@ NamespaceListContext::~NamespaceListContext() } // TemplateListIntf -int NamespaceListContext::count() const +uint NamespaceListContext::count() const { return p->count(); } -TemplateVariant NamespaceListContext::at(int index) const +TemplateVariant NamespaceListContext::at(uint index) const { return p->at(index); } @@ -7131,23 +7126,19 @@ TemplateVariant NamespaceTreeContext::get(const char *name) const class FileListContext::Private : public GenericNodeListContext { public: - void addFiles(const FileNameList &fnList) + void addFiles(const FileNameLinkedMap &fnMap) { // TODO: if FULL_PATH_NAMES is enabled, the ordering should be dir+file - FileNameListIterator fnli(fnList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : fnMap) { - FileNameIterator fni(*fn); - const FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { bool doc = fd->isLinkableInProject(); bool src = fd->generateSourceFile(); bool nameOk = !fd->isDocumentationFile(); if (nameOk && (doc || src) && !fd->isReference()) { - append(FileContext::alloc(fd)); + append(FileContext::alloc(fd.get())); } } } @@ -7157,7 +7148,7 @@ class FileListContext::Private : public GenericNodeListContext FileListContext::FileListContext() : RefCountedContext("FileListContext") { p = new Private; - if (Doxygen::inputNameList) p->addFiles(*Doxygen::inputNameList); + if (Doxygen::inputNameLinkedMap) p->addFiles(*Doxygen::inputNameLinkedMap); } FileListContext::~FileListContext() @@ -7166,12 +7157,12 @@ FileListContext::~FileListContext() } // TemplateListIntf -int FileListContext::count() const +uint FileListContext::count() const { return p->count(); } -TemplateVariant FileListContext::at(int index) const +TemplateVariant FileListContext::at(uint index) const { return p->at(index); } @@ -7209,12 +7200,12 @@ DirListContext::~DirListContext() } // TemplateListIntf -int DirListContext::count() const +uint DirListContext::count() const { return p->count(); } -TemplateVariant DirListContext::at(int index) const +TemplateVariant DirListContext::at(uint index) const { return p->at(index); } @@ -7257,12 +7248,12 @@ UsedFilesContext::~UsedFilesContext() } // TemplateListIntf -int UsedFilesContext::count() const +uint UsedFilesContext::count() const { return p->count(); } -TemplateVariant UsedFilesContext::at(int index) const +TemplateVariant UsedFilesContext::at(uint index) const { return p->at(index); } @@ -7292,9 +7283,9 @@ class FileTreeContext::Private { m_dirFileTree->addDirs(*Doxygen::directories); } - if (Doxygen::inputNameList) + if (Doxygen::inputNameLinkedMap) { - m_dirFileTree->addFiles(*Doxygen::inputNameList); + m_dirFileTree->addFiles(*Doxygen::inputNameLinkedMap); } //%% DirFile tree: static bool init=FALSE; @@ -7532,12 +7523,12 @@ PageListContext::~PageListContext() } // TemplateListIntf -int PageListContext::count() const +uint PageListContext::count() const { return p->count(); } -TemplateVariant PageListContext::at(int index) const +TemplateVariant PageListContext::at(uint index) const { return p->at(index); } @@ -7581,12 +7572,12 @@ ExampleListContext::~ExampleListContext() } // TemplateListIntf -int ExampleListContext::count() const +uint ExampleListContext::count() const { return p->count(); } -TemplateVariant ExampleListContext::at(int index) const +TemplateVariant ExampleListContext::at(uint index) const { return p->at(index); } @@ -7628,12 +7619,12 @@ ModuleListContext::~ModuleListContext() } // TemplateListIntf -int ModuleListContext::count() const +uint ModuleListContext::count() const { return p->count(); } -TemplateVariant ModuleListContext::at(int index) const +TemplateVariant ModuleListContext::at(uint index) const { return p->at(index); } @@ -7997,21 +7988,17 @@ class GlobalsIndexContext::Private if (!listRef) { TemplateList *list = TemplateList::alloc(); - MemberName *mn; - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { const FileDef *fd=md->getFileDef(); if (fd && fd->isLinkableInProject() && !md->name().isEmpty() && !md->getNamespaceDef() && md->isLinkableInProject()) { - if (filter==0 || (md->*filter)()) + if (filter==0 || (md.get()->*filter)()) { - list->append(MemberContext::alloc(md)); + list->append(MemberContext::alloc(md.get())); } } } @@ -8154,21 +8141,17 @@ class ClassMembersIndexContext::Private if (!listRef) { TemplateList *list = TemplateList::alloc(); - MemberName *mn; - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { const ClassDef *cd = md->getClassDef(); if (cd && cd->isLinkableInProject() && cd->templateMaster()==0 && md->isLinkableInProject() && !md->name().isEmpty()) { - if (filter==0 || (md->*filter)()) + if (filter==0 || (md.get()->*filter)()) { - list->append(MemberContext::alloc(md)); + list->append(MemberContext::alloc(md.get())); } } } @@ -8313,21 +8296,17 @@ class NamespaceMembersIndexContext::Private if (!listRef) { TemplateList *list = TemplateList::alloc(); - MemberName *mn; - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { const NamespaceDef *nd=md->getNamespaceDef(); if (nd && nd->isLinkableInProject() && !md->name().isEmpty() && md->isLinkableInProject()) { - if (filter==0 || (md->*filter)()) + if (filter==0 || (md.get()->*filter)()) { - list->append(MemberContext::alloc(md)); + list->append(MemberContext::alloc(md.get())); } } } @@ -8594,12 +8573,12 @@ InheritanceListContext::~InheritanceListContext() } // TemplateListIntf -int InheritanceListContext::count() const +uint InheritanceListContext::count() const { return p->count(); } -TemplateVariant InheritanceListContext::at(int index) const +TemplateVariant InheritanceListContext::at(uint index) const { return p->at(index); } @@ -8670,12 +8649,12 @@ MemberListContext::~MemberListContext() } // TemplateListIntf -int MemberListContext::count() const +uint MemberListContext::count() const { return p->count(); } -TemplateVariant MemberListContext::at(int index) const +TemplateVariant MemberListContext::at(uint index) const { return p->at(index); } @@ -8831,12 +8810,12 @@ AllMembersListContext::~AllMembersListContext() } // TemplateListIntf -int AllMembersListContext::count() const +uint AllMembersListContext::count() const { return p->count(); } -TemplateVariant AllMembersListContext::at(int index) const +TemplateVariant AllMembersListContext::at(uint index) const { return p->at(index); } @@ -9013,12 +8992,12 @@ MemberGroupListContext::~MemberGroupListContext() } // TemplateListIntf -int MemberGroupListContext::count() const +uint MemberGroupListContext::count() const { return p->count(); } -TemplateVariant MemberGroupListContext::at(int index) const +TemplateVariant MemberGroupListContext::at(uint index) const { return p->at(index); } @@ -9376,12 +9355,12 @@ InheritedMemberInfoListContext::~InheritedMemberInfoListContext() } // TemplateListIntf -int InheritedMemberInfoListContext::count() const +uint InheritedMemberInfoListContext::count() const { return p->count(); } -TemplateVariant InheritedMemberInfoListContext::at(int index) const +TemplateVariant InheritedMemberInfoListContext::at(uint index) const { return p->at(index); } @@ -9458,7 +9437,7 @@ class ArgumentContext::Private TemplateVariant namePart() const { QCString result = m_argument.attrib; - int l = result.length(); + uint l = result.length(); if (l>2 && result.at(0)=='[' && result.at(l-1)==']') { result = result.mid(1,l-2); @@ -9529,12 +9508,12 @@ ArgumentListContext::~ArgumentListContext() } // TemplateListIntf -int ArgumentListContext::count() const +uint ArgumentListContext::count() const { return p->count(); } -TemplateVariant ArgumentListContext::at(int index) const +TemplateVariant ArgumentListContext::at(uint index) const { return p->at(index); } @@ -9723,12 +9702,12 @@ SymbolListContext::~SymbolListContext() } // TemplateListIntf -int SymbolListContext::count() const +uint SymbolListContext::count() const { return p->count(); } -TemplateVariant SymbolListContext::at(int index) const +TemplateVariant SymbolListContext::at(uint index) const { return p->at(index); } @@ -9822,7 +9801,7 @@ class SymbolGroupListContext::Private : public GenericNodeListContext } }; -SymbolGroupListContext::SymbolGroupListContext(const SearchIndexList *sil) +SymbolGroupListContext::SymbolGroupListContext(const SearchIndexList *sil) : RefCountedContext("SymbolGroupListContext") { p = new Private(sil); @@ -9834,12 +9813,12 @@ SymbolGroupListContext::~SymbolGroupListContext() } // TemplateListIntf -int SymbolGroupListContext::count() const +uint SymbolGroupListContext::count() const { return p->count(); } -TemplateVariant SymbolGroupListContext::at(int index) const +TemplateVariant SymbolGroupListContext::at(uint index) const { return p->at(index); } @@ -9946,12 +9925,12 @@ SymbolIndicesContext::~SymbolIndicesContext() } // TemplateListIntf -int SymbolIndicesContext::count() const +uint SymbolIndicesContext::count() const { return p->count(); } -TemplateVariant SymbolIndicesContext::at(int index) const +TemplateVariant SymbolIndicesContext::at(uint index) const { return p->at(index); } @@ -10055,12 +10034,12 @@ SearchIndicesContext::~SearchIndicesContext() } // TemplateListIntf -int SearchIndicesContext::count() const +uint SearchIndicesContext::count() const { return p->count(); } -TemplateVariant SearchIndicesContext::at(int index) const +TemplateVariant SearchIndicesContext::at(uint index) const { return p->at(index); } diff --git a/src/context.h b/src/context.h index fc1278b..8af74f8 100644 --- a/src/context.h +++ b/src/context.h @@ -32,7 +32,7 @@ class BaseClassList; class NamespaceSDict; class FileDef; class FileList; -class FileNameList; +class FileNameLinkedMap; class DirSDict; class DirList; class DirDef; @@ -189,8 +189,8 @@ class UsedFilesContext : public RefCountedContext, public TemplateListIntf static UsedFilesContext *alloc(const ClassDef *cd) { return new UsedFilesContext(cd); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -234,8 +234,8 @@ class IncludeInfoListContext : public RefCountedContext, public TemplateListIntf { return new IncludeInfoListContext(list,lang); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -390,8 +390,8 @@ class ClassListContext : public RefCountedContext, public TemplateListIntf static ClassListContext *alloc() { return new ClassListContext; } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -472,8 +472,8 @@ class ClassInheritanceContext : public RefCountedContext, public TemplateListInt static ClassInheritanceContext *alloc() { return new ClassInheritanceContext; } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -537,8 +537,8 @@ class NestingContext : public RefCountedContext, public TemplateListIntf { return new NestingContext(parent,level); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -547,7 +547,7 @@ class NestingContext : public RefCountedContext, public TemplateListIntf void addClasses(const ClassSDict &clDict,bool rootOnly); void addDirs(const DirSDict &); void addDirs(const DirList &); - void addFiles(const FileNameList &); + void addFiles(const FileNameLinkedMap &); void addFiles(const FileList &); void addPages(const PageSDict &pages,bool rootOnly); void addModules(const GroupSDict &modules); @@ -589,8 +589,8 @@ class NamespaceListContext : public RefCountedContext, public TemplateListIntf static NamespaceListContext *alloc() { return new NamespaceListContext; } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -629,8 +629,8 @@ class DirListContext : public RefCountedContext, public TemplateListIntf static DirListContext *alloc() { return new DirListContext; } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -650,8 +650,8 @@ class FileListContext : public RefCountedContext, public TemplateListIntf static FileListContext *alloc() { return new FileListContext; } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -690,8 +690,8 @@ class PageListContext : public RefCountedContext, public TemplateListIntf static PageListContext *alloc(const PageSDict *pages) { return new PageListContext(pages); } // TemplateListIntf methods - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -751,8 +751,8 @@ class ModuleListContext : public RefCountedContext, public TemplateListIntf static ModuleListContext *alloc() { return new ModuleListContext(); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -794,8 +794,8 @@ class ExampleListContext : public RefCountedContext, public TemplateListIntf static ExampleListContext *alloc() { return new ExampleListContext; } // TemplateListIntf methods - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -933,8 +933,8 @@ class InheritanceListContext : public RefCountedContext, public TemplateListIntf { return new InheritanceListContext(list,baseClasses); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -959,8 +959,8 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf { return new MemberListContext(ml,doSort); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1007,8 +1007,8 @@ class MemberGroupListContext : public RefCountedContext, public TemplateListIntf { return new MemberGroupListContext(def,relPath,dict,subGrouping); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1095,8 +1095,8 @@ class InheritedMemberInfoListContext : public RefCountedContext, public Template void addMemberList(const ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList=TRUE); // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1119,8 +1119,8 @@ class AllMembersListContext : public RefCountedContext, public TemplateListIntf { return new AllMembersListContext(ml); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1163,8 +1163,8 @@ class ArgumentListContext : public RefCountedContext, public TemplateListIntf { return new ArgumentListContext(al,def,relPath); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1206,8 +1206,8 @@ class SymbolListContext : public RefCountedContext, public TemplateListIntf { return new SymbolListContext(sdl); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1248,8 +1248,8 @@ class SymbolGroupListContext : public RefCountedContext, public TemplateListIntf { return new SymbolGroupListContext(sil); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1290,8 +1290,8 @@ class SymbolIndicesContext : public RefCountedContext, public TemplateListIntf { return new SymbolIndicesContext(info); } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } @@ -1331,8 +1331,8 @@ class SearchIndicesContext : public RefCountedContext, public TemplateListIntf static SearchIndicesContext *alloc() { return new SearchIndicesContext; } // TemplateListIntf - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } diff --git a/src/declinfo.l b/src/declinfo.l index af94569..2f497f9 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -20,6 +20,9 @@ %option noyywrap %option reentrant %option extra-type="struct declinfoYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -39,7 +42,9 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 #define YY_NEVER_INTERACTIVE 1 - + +#define USE_STATE2STRING 0 + /* ----------------------------------------------------------------- * * statics @@ -63,10 +68,13 @@ struct declinfoYY_state bool insidePHP; }; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif + static void addType(yyscan_t yyscanner); static void addTypeName(yyscan_t yyscanner); -static int yyread(char *buf,int max_size, yyscan_t yyscanner); +static yy_size_t yyread(char *buf,yy_size_t max_size, yyscan_t yyscanner); /* ----------------------------------------------------------------- */ @@ -234,16 +242,16 @@ static void addTypeName(yyscan_t yyscanner) yyextra->name.resize(0); } -static int yyread(char *buf,int max_size, yyscan_t yyscanner) +static yy_size_t yyread(char *buf,yy_size_t max_size, yyscan_t yyscanner) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int c=0; - while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) - { - *buf = yyextra->inputString[yyextra->inputPosition++] ; - c++; buf++; - } - return c; + yy_size_t c=0; + while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) + { + *buf = yyextra->inputString[yyextra->inputPosition++] ; + c++; buf++; + } + return c; } /*@ public interface------------------------------------------------------------ @@ -380,5 +388,6 @@ int main() } #endif - +#if USE_STATE2STRING #include "declinfo.l.h" +#endif diff --git a/src/defargs.l b/src/defargs.l index 9745f44..2541a43 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -41,6 +41,11 @@ */ %option never-interactive %option prefix="defargsYY" +%option reentrant +%option extra-type="struct defargsYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -62,81 +67,51 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 + +#define USE_STATE2STRING 0 /* ----------------------------------------------------------------- * state variables */ -static const char *g_inputString; -static int g_inputPosition; -static ArgumentList *g_argList; -static QCString *g_copyArgValue; -static QCString g_curArgTypeName; -static QCString g_curArgDefValue; -static QCString g_curArgName; -static QCString g_curArgDocs; -static QCString g_curArgAttrib; -static QCString g_curArgArray; -static QCString g_curTypeConstraint; -static QCString g_extraTypeChars; -static int g_argRoundCount; -static int g_argSharpCount; -static int g_argCurlyCount; -static int g_readArgContext; -static int g_lastDocContext; -static int g_lastDocChar; -static int g_lastExtendsContext; -static QCString g_delimiter; -static SrcLangExt g_lang; +struct defargsYY_state +{ + defargsYY_state(const char *inStr,ArgumentList &al,SrcLangExt l) + : inputString(inStr), argList(al), lang(l) {} + const char *inputString; + ArgumentList &argList; + SrcLangExt lang; + int inputPosition = 0; + QCString *copyArgValue = 0; + QCString curArgTypeName; + QCString curArgDefValue; + QCString curArgName; + QCString curArgDocs; + QCString curArgAttrib; + QCString curArgArray; + QCString curTypeConstraint; + QCString extraTypeChars; + int argRoundCount = 0; + int argSharpCount = 0; + int argCurlyCount = 0; + int readArgContext = 0; + int lastDocContext = 0; + int lastDocChar = 0; + int lastExtendsContext = 0; + QCString delimiter; +}; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif + +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +static bool nameIsActuallyPartOfType(QCString &name); + /* ----------------------------------------------------------------- */ #undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); - -static int yyread(char *buf,int max_size) -{ - int c=0; - while( c < max_size && g_inputString[g_inputPosition] ) - { - *buf = g_inputString[g_inputPosition++] ; - c++; buf++; - } - return c; -} +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); -/* bug_520975 */ -static bool nameIsActuallyPartOfType(QCString &name) -{ - static bool first=TRUE; - static QDict<void> keywords(17); - if (first) // fill keyword dict first time - { - #define DUMMY_ADDR (void*)0x8 - keywords.insert("unsigned", DUMMY_ADDR); // foo(... unsigned) - keywords.insert("signed", DUMMY_ADDR); // foo(... signed) - keywords.insert("bool", DUMMY_ADDR); // foo(... bool) - keywords.insert("char", DUMMY_ADDR); // foo(... char) - keywords.insert("char8_t", DUMMY_ADDR); // foo(... char8_t) - keywords.insert("char16_t", DUMMY_ADDR); // foo(... char16_t) - keywords.insert("char32_t", DUMMY_ADDR); // foo(... char32_t) - keywords.insert("int", DUMMY_ADDR); // foo(... int) - keywords.insert("short", DUMMY_ADDR); // foo(... short) - keywords.insert("long", DUMMY_ADDR); // foo(... long) - keywords.insert("float", DUMMY_ADDR); // foo(... float) - keywords.insert("double", DUMMY_ADDR); // foo(... double) - keywords.insert("int8_t", DUMMY_ADDR); // foo(... int8_t) - keywords.insert("uint8_t", DUMMY_ADDR); // foo(... uint8_t) - keywords.insert("int16_t", DUMMY_ADDR); // foo(... int16_t) - keywords.insert("uint16_t", DUMMY_ADDR); // foo(... uint16_t) - keywords.insert("int32_t", DUMMY_ADDR); // foo(... int32_t) - keywords.insert("uint32_t", DUMMY_ADDR); // foo(... uint32_t) - keywords.insert("const", DUMMY_ADDR); // foo(... const) - keywords.insert("volatile", DUMMY_ADDR); // foo(... volatile) - first=FALSE; - } - return name.length()>0 && keywords.find(name)!=0; -} %} B [ \t] @@ -168,124 +143,124 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <Start>[<(] { BEGIN(ReadFuncArgType); } <ReadFuncArgType>{B}* { - g_curArgTypeName+=" "; + yyextra->curArgTypeName+=" "; } <ReadFuncArgType>"["[^\]]*"]" { - if (g_curArgTypeName.stripWhiteSpace().isEmpty()) + if (yyextra->curArgTypeName.stripWhiteSpace().isEmpty()) { - g_curArgAttrib=yytext; // for M$-IDL + yyextra->curArgAttrib=yytext; // for M$-IDL } else // array type { - g_curArgArray+=yytext; + yyextra->curArgArray+=yytext; } } -<ReadFuncArgDef>"'"\\[0-7]{1,3}"'" { g_curArgDefValue+=yytext; } -<ReadFuncArgDef>"'"\\."'" { g_curArgDefValue+=yytext; } -<ReadFuncArgDef>"'"."'" { g_curArgDefValue+=yytext; } -<ReadFuncArgDef>{RAWBEGIN} { g_curArgDefValue+=yytext; +<ReadFuncArgDef>"'"\\[0-7]{1,3}"'" { yyextra->curArgDefValue+=yytext; } +<ReadFuncArgDef>"'"\\."'" { yyextra->curArgDefValue+=yytext; } +<ReadFuncArgDef>"'"."'" { yyextra->curArgDefValue+=yytext; } +<ReadFuncArgDef>{RAWBEGIN} { yyextra->curArgDefValue+=yytext; QCString text=yytext; int i=text.find('"'); - g_delimiter = yytext+i+1; - g_delimiter=g_delimiter.left(g_delimiter.length()-1); + yyextra->delimiter = yytext+i+1; + yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1); BEGIN( CopyRawString ); } <ReadFuncArgDef>\" { - g_curArgDefValue+=*yytext; + yyextra->curArgDefValue+=*yytext; BEGIN( CopyArgString ); } <ReadFuncArgType>"("([^:)]+{B}*"::")*{B}*[&*\^]+{B}*/{ID} { // function pointer as argument - g_curArgTypeName+=yytext; - //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace(); + yyextra->curArgTypeName+=yytext; + //yyextra->curArgTypeName=yyextra->curArgTypeName.simplifyWhiteSpace(); BEGIN( ReadFuncArgPtr ); } <ReadFuncArgPtr>{ID} { - g_curArgName=yytext; + yyextra->curArgName=yytext; } <ReadFuncArgPtr>")"{B}*"(" { // function pointer - g_curArgTypeName+=yytext; - //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace(); - g_readArgContext = ReadFuncArgType; - g_copyArgValue=&g_curArgTypeName; - g_argRoundCount=0; + yyextra->curArgTypeName+=yytext; + //yyextra->curArgTypeName=yyextra->curArgTypeName.simplifyWhiteSpace(); + yyextra->readArgContext = ReadFuncArgType; + yyextra->copyArgValue=&yyextra->curArgTypeName; + yyextra->argRoundCount=0; BEGIN( CopyArgRound2 ); } <ReadFuncArgPtr>")"/{B}*"[" { // pointer to fixed size array - g_curArgTypeName+=yytext; - g_curArgTypeName+=g_curArgName; - //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace(); + yyextra->curArgTypeName+=yytext; + yyextra->curArgTypeName+=yyextra->curArgName; + //yyextra->curArgTypeName=yyextra->curArgTypeName.simplifyWhiteSpace(); BEGIN( ReadFuncArgType ); } <ReadFuncArgPtr>")" { // redundant braces detected / remove them - int i=g_curArgTypeName.findRev('('),l=g_curArgTypeName.length(); + int i=yyextra->curArgTypeName.findRev('('),l=yyextra->curArgTypeName.length(); if (i!=-1) - g_curArgTypeName=g_curArgTypeName.left(i)+ - g_curArgTypeName.right(l-i-1); - g_curArgTypeName+=g_curArgName; + yyextra->curArgTypeName=yyextra->curArgTypeName.left(i)+ + yyextra->curArgTypeName.right(l-i-1); + yyextra->curArgTypeName+=yyextra->curArgName; BEGIN( ReadFuncArgType ); } <ReadFuncArgType>"<="|">="|"->"|">>"|"<<" { // handle operators in defargs - g_curArgTypeName+=yytext; + yyextra->curArgTypeName+=yytext; } <ReadFuncArgType,ReadFuncArgDef>[({<] { if (YY_START==ReadFuncArgType) { - g_curArgTypeName+=*yytext; - g_copyArgValue=&g_curArgTypeName; + yyextra->curArgTypeName+=*yytext; + yyextra->copyArgValue=&yyextra->curArgTypeName; } else // YY_START==ReadFuncArgDef { - g_curArgDefValue+=*yytext; - g_copyArgValue=&g_curArgDefValue; + yyextra->curArgDefValue+=*yytext; + yyextra->copyArgValue=&yyextra->curArgDefValue; } - g_readArgContext = YY_START; + yyextra->readArgContext = YY_START; if (*yytext=='(') { - g_argRoundCount=0; + yyextra->argRoundCount=0; BEGIN( CopyArgRound ); } else if (*yytext=='{') { - g_argCurlyCount=0; + yyextra->argCurlyCount=0; BEGIN( CopyArgCurly ); } else // yytext=='<' { - g_argSharpCount=0; - g_argRoundCount=0; + yyextra->argSharpCount=0; + yyextra->argRoundCount=0; BEGIN( CopyArgSharp ); } } <CopyArgRound,CopyArgRound2>"(" { - g_argRoundCount++; - *g_copyArgValue += *yytext; + yyextra->argRoundCount++; + *yyextra->copyArgValue += *yytext; } <CopyArgRound,CopyArgRound2>")"({B}*{ID})* { - *g_copyArgValue += yytext; - if (g_argRoundCount>0) + *yyextra->copyArgValue += yytext; + if (yyextra->argRoundCount>0) { - g_argRoundCount--; + yyextra->argRoundCount--; } else { if (YY_START==CopyArgRound2) { - *g_copyArgValue+=" "+g_curArgName; + *yyextra->copyArgValue+=" "+yyextra->curArgName; } - BEGIN( g_readArgContext ); + BEGIN( yyextra->readArgContext ); } } <CopyArgRound>")"/{B}* { - *g_copyArgValue += *yytext; - if (g_argRoundCount>0) g_argRoundCount--; - else BEGIN( g_readArgContext ); + *yyextra->copyArgValue += *yytext; + if (yyextra->argRoundCount>0) yyextra->argRoundCount--; + else BEGIN( yyextra->readArgContext ); } <CopyArgSharp>"<<" { - if (g_argRoundCount>0) + if (yyextra->argRoundCount>0) { // for e.g. < typename A = (i<<3) > - *g_copyArgValue += yytext; + *yyextra->copyArgValue += yytext; } else { @@ -293,10 +268,10 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } } <CopyArgSharp>">>" { - if (g_argRoundCount>0) + if (yyextra->argRoundCount>0) { // for e.g. < typename A = (i>>3) > - *g_copyArgValue += yytext; + *yyextra->copyArgValue += yytext; } else { @@ -305,66 +280,66 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <CopyArgSharp>"<" { // don't count < inside (, e.g. for things like: < typename A=(i<6) > - if (g_argRoundCount==0) g_argSharpCount++; - *g_copyArgValue += *yytext; + if (yyextra->argRoundCount==0) yyextra->argSharpCount++; + *yyextra->copyArgValue += *yytext; } <CopyArgSharp>">" { - *g_copyArgValue += *yytext; - if (g_argRoundCount>0 && g_argSharpCount==0) + *yyextra->copyArgValue += *yytext; + if (yyextra->argRoundCount>0 && yyextra->argSharpCount==0) { // don't count > inside ) } else { - if (g_argSharpCount>0) + if (yyextra->argSharpCount>0) { - g_argSharpCount--; + yyextra->argSharpCount--; } else { - BEGIN( g_readArgContext ); + BEGIN( yyextra->readArgContext ); } } } <CopyArgSharp>"(" { - g_argRoundCount++; - *g_copyArgValue += *yytext; + yyextra->argRoundCount++; + *yyextra->copyArgValue += *yytext; } <CopyArgSharp>")" { - g_argRoundCount--; - *g_copyArgValue += *yytext; + yyextra->argRoundCount--; + *yyextra->copyArgValue += *yytext; } <CopyArgCurly>"{" { - g_argCurlyCount++; - *g_copyArgValue += *yytext; + yyextra->argCurlyCount++; + *yyextra->copyArgValue += *yytext; } <CopyArgCurly>"}" { - *g_copyArgValue += *yytext; - if (g_argCurlyCount>0) g_argCurlyCount--; - else BEGIN( g_readArgContext ); + *yyextra->copyArgValue += *yytext; + if (yyextra->argCurlyCount>0) yyextra->argCurlyCount--; + else BEGIN( yyextra->readArgContext ); } <CopyArgString>\\. { - g_curArgDefValue+=yytext; + yyextra->curArgDefValue+=yytext; } <CopyRawString>{RAWEND} { - g_curArgDefValue+=yytext; + yyextra->curArgDefValue+=yytext; QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); - if (delimiter==g_delimiter) + if (delimiter==yyextra->delimiter) { BEGIN( ReadFuncArgDef ); } } <CopyArgString>\" { - g_curArgDefValue+=*yytext; + yyextra->curArgDefValue+=*yytext; BEGIN( ReadFuncArgDef ); } <ReadFuncArgType>"=" { BEGIN( ReadFuncArgDef ); } <ReadFuncArgType,ReadFuncArgDef>[,)>]{B}*("/*"[*!]|"//"[/!])"<" { - g_lastDocContext=YY_START; - g_lastDocChar=*yytext; + yyextra->lastDocContext=YY_START; + yyextra->lastDocChar=*yytext; QCString text=yytext; if (text.find("//")!=-1) BEGIN( ReadDocLine ); @@ -372,49 +347,49 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" BEGIN( ReadDocBlock ); } <ReadFuncArgType,ReadFuncArgDef>[,)>] { - if (*yytext==')' && g_curArgTypeName.stripWhiteSpace().isEmpty()) + if (*yytext==')' && yyextra->curArgTypeName.stripWhiteSpace().isEmpty()) { - g_curArgTypeName+=*yytext; + yyextra->curArgTypeName+=*yytext; BEGIN(FuncQual); } else { - g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName); - g_curArgDefValue=g_curArgDefValue.stripWhiteSpace(); - //printf("curArgType='%s' curArgDefVal='%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data()); - int l=g_curArgTypeName.length(); + yyextra->curArgTypeName=removeRedundantWhiteSpace(yyextra->curArgTypeName); + yyextra->curArgDefValue=yyextra->curArgDefValue.stripWhiteSpace(); + //printf("curArgType='%s' curArgDefVal='%s'\n",yyextra->curArgTypeName.data(),yyextra->curArgDefValue.data()); + int l=yyextra->curArgTypeName.length(); if (l>0) { int i=l-1; - while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--; - while (i>=0 && (isId(g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='$')) i--; + while (i>=0 && (isspace((uchar)yyextra->curArgTypeName.at(i)) || yyextra->curArgTypeName.at(i)=='.')) i--; + while (i>=0 && (isId(yyextra->curArgTypeName.at(i)) || yyextra->curArgTypeName.at(i)=='$')) i--; Argument a; - a.attrib = g_curArgAttrib.copy(); - a.typeConstraint = g_curTypeConstraint.stripWhiteSpace(); + a.attrib = yyextra->curArgAttrib.copy(); + a.typeConstraint = yyextra->curTypeConstraint.stripWhiteSpace(); //printf("a->type=%s a->name=%s i=%d l=%d\n", // a->type.data(),a->name.data(),i,l); a.array.resize(0); - if (i==l-1 && g_curArgTypeName.at(i)==')') // function argument + if (i==l-1 && yyextra->curArgTypeName.at(i)==')') // function argument { - int bi=g_curArgTypeName.find('('); + int bi=yyextra->curArgTypeName.find('('); int fi=bi-1; //printf("func arg fi=%d\n",fi); - while (fi>=0 && (isId(g_curArgTypeName.at(fi)) || g_curArgTypeName.at(fi)==':')) fi--; + while (fi>=0 && (isId(yyextra->curArgTypeName.at(fi)) || yyextra->curArgTypeName.at(fi)==':')) fi--; if (fi>=0) { - a.type = g_curArgTypeName.left(fi+1); - a.name = g_curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace(); - a.array = g_curArgTypeName.right(l-bi); + a.type = yyextra->curArgTypeName.left(fi+1); + a.name = yyextra->curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace(); + a.array = yyextra->curArgTypeName.right(l-bi); } else { - a.type = g_curArgTypeName; + a.type = yyextra->curArgTypeName; } } - else if (i>=0 && g_curArgTypeName.at(i)!=':') + else if (i>=0 && yyextra->curArgTypeName.at(i)!=':') { // type contains a name - a.type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1)).stripWhiteSpace(); - a.name = g_curArgTypeName.right(l-i-1).stripWhiteSpace(); + a.type = removeRedundantWhiteSpace(yyextra->curArgTypeName.left(i+1)).stripWhiteSpace(); + a.name = yyextra->curArgTypeName.right(l-i-1).stripWhiteSpace(); // if the type becomes a type specifier only then we make a mistake // and need to correct it to avoid seeing a nameless parameter @@ -437,20 +412,20 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } else // assume only the type was specified, try to determine name later { - a.type = removeRedundantWhiteSpace(g_curArgTypeName); + a.type = removeRedundantWhiteSpace(yyextra->curArgTypeName); } if (!a.type.isEmpty() && a.type.at(0)=='$') // typeless PHP name? { a.name = a.type; a.type = ""; } - a.array += removeRedundantWhiteSpace(g_curArgArray); + a.array += removeRedundantWhiteSpace(yyextra->curArgArray); //printf("array=%s\n",a->array.data()); int alen = a.array.length(); if (alen>2 && a.array.at(0)=='(' && a.array.at(alen-1)==')') // fix-up for int *(a[10]) { - int i=a.array.find('[')-1; + i=a.array.find('[')-1; a.array = a.array.mid(1,alen-2); if (i>0 && a.name.isEmpty()) { @@ -458,18 +433,18 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" a.array = a.array.mid(i); } } - a.defval = g_curArgDefValue.copy(); + a.defval = yyextra->curArgDefValue.copy(); //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data()); - a.docs = g_curArgDocs.stripWhiteSpace(); + a.docs = yyextra->curArgDocs.stripWhiteSpace(); //printf("Argument '%s' '%s' adding docs='%s'\n",a->type.data(),a->name.data(),a->docs.data()); - g_argList->push_back(a); + yyextra->argList.push_back(a); } - g_curArgAttrib.resize(0); - g_curArgTypeName.resize(0); - g_curArgDefValue.resize(0); - g_curArgArray.resize(0); - g_curArgDocs.resize(0); - g_curTypeConstraint.resize(0); + yyextra->curArgAttrib.resize(0); + yyextra->curArgTypeName.resize(0); + yyextra->curArgDefValue.resize(0); + yyextra->curArgArray.resize(0); + yyextra->curArgDocs.resize(0); + yyextra->curTypeConstraint.resize(0); if (*yytext==')') { BEGIN(FuncQual); @@ -482,72 +457,72 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } } <ReadFuncArgType,ReadFuncArgPtr>"extends" { - if (g_lang!=SrcLangExt_Java) + if (yyextra->lang!=SrcLangExt_Java) { REJECT; } else { - g_curTypeConstraint.resize(0); - g_lastExtendsContext=YY_START; + yyextra->curTypeConstraint.resize(0); + yyextra->lastExtendsContext=YY_START; BEGIN(ReadTypeConstraint); } } <ReadFuncArgType,ReadFuncArgPtr>"$"?{ID} { QCString name=yytext; //resolveDefines(yytext); - if (YY_START==ReadFuncArgType && g_curArgArray=="[]") // Java style array + if (YY_START==ReadFuncArgType && yyextra->curArgArray=="[]") // Java style array { - g_curArgTypeName+=" []"; - g_curArgArray.resize(0); + yyextra->curArgTypeName+=" []"; + yyextra->curArgArray.resize(0); } //printf("resolveName '%s'->'%s'\n",yytext,name.data()); - g_curArgTypeName+=name; + yyextra->curArgTypeName+=name; } <ReadFuncArgType,ReadFuncArgPtr>. { - g_curArgTypeName+=*yytext; + yyextra->curArgTypeName+=*yytext; } <ReadFuncArgDef,CopyArgString>"<="|"->"|">="|">>"|"<<" { - g_curArgDefValue+=yytext; + yyextra->curArgDefValue+=yytext; } <ReadFuncArgDef,CopyArgString,CopyRawString>. { - g_curArgDefValue+=*yytext; + yyextra->curArgDefValue+=*yytext; } <CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>{ID} { QCString name=yytext; //resolveDefines(yytext); - *g_copyArgValue+=name; + *yyextra->copyArgValue+=name; } <CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>. { - *g_copyArgValue += *yytext; + *yyextra->copyArgValue += *yytext; } <ReadTypeConstraint>[,)>] { unput(*yytext); - BEGIN(g_lastExtendsContext); + BEGIN(yyextra->lastExtendsContext); } <ReadTypeConstraint>. { - g_curTypeConstraint+=yytext; + yyextra->curTypeConstraint+=yytext; } <ReadTypeConstraint>\n { - g_curTypeConstraint+=' '; + yyextra->curTypeConstraint+=' '; } <FuncQual>"const" { - g_argList->constSpecifier=TRUE; + yyextra->argList.constSpecifier=TRUE; } <FuncQual>"volatile" { - g_argList->volatileSpecifier=TRUE; + yyextra->argList.volatileSpecifier=TRUE; } <FuncQual>"&" { - g_argList->refQualifier=RefQualifierLValue; + yyextra->argList.refQualifier=RefQualifierLValue; } <FuncQual>"&&" { - g_argList->refQualifier=RefQualifierRValue; + yyextra->argList.refQualifier=RefQualifierRValue; } <FuncQual,TrailingReturn>"="{B}*"0" { - g_argList->pureSpecifier=TRUE; + yyextra->argList.pureSpecifier=TRUE; BEGIN(FuncQual); } <FuncQual>"->" { // C++11 trailing return type - g_argList->trailingReturnType=" -> "; + yyextra->argList.trailingReturnType=" -> "; BEGIN(TrailingReturn); } <TrailingReturn>{B}/("final"|"override"){B}* { @@ -555,40 +530,40 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" BEGIN(FuncQual); } <TrailingReturn>. { - g_argList->trailingReturnType+=yytext; + yyextra->argList.trailingReturnType+=yytext; } <TrailingReturn>\n { - g_argList->trailingReturnType+=yytext; + yyextra->argList.trailingReturnType+=yytext; } <FuncQual>")"{B}*"["[^]]*"]" { // for functions returning a pointer to an array, // i.e. ")[]" in "int (*f(int))[4]" with argsString="(int))[4]" - g_extraTypeChars=yytext; + yyextra->extraTypeChars=yytext; } <ReadDocBlock>[^\*\n]+ { - g_curArgDocs+=yytext; + yyextra->curArgDocs+=yytext; } <ReadDocLine>[^\n]+ { - g_curArgDocs+=yytext; + yyextra->curArgDocs+=yytext; } <ReadDocBlock>"*/" { - if (g_lastDocChar!=0) - unput(g_lastDocChar); - BEGIN(g_lastDocContext); + if (yyextra->lastDocChar!=0) + unput(yyextra->lastDocChar); + BEGIN(yyextra->lastDocContext); } <ReadDocLine>\n { - if (g_lastDocChar!=0) - unput(g_lastDocChar); - BEGIN(g_lastDocContext); + if (yyextra->lastDocChar!=0) + unput(yyextra->lastDocChar); + BEGIN(yyextra->lastDocContext); } <ReadDocBlock>\n { - g_curArgDocs+=*yytext; + yyextra->curArgDocs+=*yytext; } <ReadDocBlock>. { - g_curArgDocs+=*yytext; + yyextra->curArgDocs+=*yytext; } <*>("/*"[*!]|"//"[/!])("<"?) { - g_lastDocContext=YY_START; - g_lastDocChar=0; + yyextra->lastDocContext=YY_START; + yyextra->lastDocChar=0; if (yytext[1]=='/') BEGIN( ReadDocLine ); else @@ -602,6 +577,190 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" /* ---------------------------------------------------------------------------- */ +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yy_size_t c=0; + while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) + { + *buf = yyextra->inputString[yyextra->inputPosition++] ; + c++; buf++; + } + return c; +} + +/* +The following code is generated using 'gperf keywords.txt' +where keywords.txt has the following content + +--------------------------------- +%define class-name KeywordHash +%define lookup-function-name find +%readonly-tables +%language=C++ +%% +unsigned +signed +bool +char +char8_t +char16_t +char32_t +wchar_t +int +short +long +float +double +int8_t +int16_t +int32_t +int64_t +intmax_t +intptr_t +uint8_t +uint16_t +uint32_t +uint64_t +uintmax_t +uintptr_t +const +volatile +void +%% +--------------------------------- +*/ +//--- begin gperf generated code ---------------------------------------------------------- + +#define TOTAL_KEYWORDS 28 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 9 +#define MIN_HASH_VALUE 3 +#define MAX_HASH_VALUE 48 +/* maximum key range = 46, duplicates = 0 */ + +class KeywordHash +{ + private: + static inline unsigned int hash (const char *str, unsigned int len); + public: + static const char *find (const char *str, unsigned int len); +}; + +inline unsigned int +KeywordHash::hash (const char *str, unsigned int len) +{ + static const unsigned char asso_values[] = + { + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, + 5, 30, 0, 49, 25, 49, 10, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 0, 49, 0, 5, 49, + 15, 0, 49, 10, 49, 30, 49, 49, 0, 20, + 0, 49, 15, 49, 5, 10, 0, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49 + }; + unsigned int hval = len; + + switch (hval) + { + default: + hval += asso_values[static_cast<unsigned char>(str[4])]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[static_cast<unsigned char>(str[3])]; + /*FALLTHROUGH*/ + case 3: + break; + } + return hval; +} + +const char * +KeywordHash::find (const char *str, unsigned int len) +{ + static const char * const wordlist[] = + { + "", "", "", + "int", + "bool", + "float", + "signed", + "", + "volatile", + "char", + "short", + "double", + "wchar_t", + "uint16_t", + "long", + "const", + "int8_t", + "uint8_t", + "char16_t", + "void", + "", "", + "char8_t", + "intptr_t", + "uintptr_t", + "", "", "", + "intmax_t", + "uintmax_t", + "", "", + "int64_t", + "uint64_t", + "", "", "", + "int16_t", + "uint32_t", + "", "", "", + "int32_t", + "char32_t", + "", "", "", "", + "unsigned" + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + unsigned int key = hash (str, len); + + if (key <= MAX_HASH_VALUE) + { + const char *s = wordlist[key]; + + if (*str == *s && !qstrcmp (str + 1, s + 1)) + return s; + } + } + return 0; +} + +//--- end gperf generated code ---------------------------------------------------------- + +/* bug_520975 */ +static bool nameIsActuallyPartOfType(QCString &name) +{ + return KeywordHash::find(name.data(),name.length())!=0; +} + /*! Converts an argument string into an ArgumentList. * \param[in] argsString the list of Arguments. * \param[out] al a reference to resulting argument list pointer. @@ -612,36 +771,29 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" void stringToArgumentList(SrcLangExt lang, const char *argsString,ArgumentList& al,QCString *extraTypeChars) { if (argsString==0) return; + + yyscan_t yyscanner; + defargsYY_state extra(argsString,al,lang); + defargsYYlex_init_extra(&extra,&yyscanner); +#ifdef FLEX_DEBUG + defargsYYset_debug(1,yyscanner); +#endif + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; printlex(yy_flex_debug, TRUE, __FILE__, NULL); - g_copyArgValue=0; - g_curArgDocs.resize(0); - g_curArgAttrib.resize(0); - g_curArgArray.resize(0); - g_curTypeConstraint.resize(0); - g_extraTypeChars.resize(0); - g_argRoundCount = 0; - g_argSharpCount = 0; - g_argCurlyCount = 0; - g_lastDocChar = 0; - - g_inputString = argsString; - g_inputPosition = 0; - g_curArgTypeName.resize(0); - g_curArgDefValue.resize(0); - g_curArgName.resize(0); - g_argList = &al; - g_lang = lang; - defargsYYrestart( defargsYYin ); + defargsYYrestart( 0, yyscanner ); BEGIN( Start ); - defargsYYlex(); - if (g_argList->empty()) + defargsYYlex(yyscanner); + if (yyextra->argList.empty()) { - g_argList->noParameters = TRUE; + yyextra->argList.noParameters = TRUE; } - if (extraTypeChars) *extraTypeChars=g_extraTypeChars; + if (extraTypeChars) *extraTypeChars=yyextra->extraTypeChars; //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data()); printlex(yy_flex_debug, FALSE, __FILE__, NULL); + defargsYYlex_destroy(yyscanner); } +#if USE_STATE2STRING #include "defargs.l.h" +#endif diff --git a/src/defgen.cpp b/src/defgen.cpp index cc3d5af..96f9da3 100644 --- a/src/defgen.cpp +++ b/src/defgen.cpp @@ -1,13 +1,13 @@ /****************************************************************************** * - * + * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -71,14 +71,14 @@ void generateDEFForMember(MemberDef *md, // + source definition // - source references // - source referenced by - // - include code + // - include code if (md->memberType()==MemberType_EnumValue) return; QCString scopeName; - if (md->getClassDef()) + if (md->getClassDef()) scopeName=md->getClassDef()->name(); - else if (md->getNamespaceDef()) + else if (md->getNamespaceDef()) scopeName=md->getNamespaceDef()->name(); t << " " << Prefix << "-member = {" << endl; @@ -185,7 +185,7 @@ void generateDEFForMember(MemberDef *md, if (!a.array.isEmpty()) { t << fcnPrefix << "array = "; - writeDEFString(t,a.array); + writeDEFString(t,a.array); t << ';' << endl; } if (!a.defval.isEmpty()) @@ -612,7 +612,7 @@ void generateDEF() FTextStream t(&f); t << "AutoGen Definitions dummy;" << endl; - if (Doxygen::classSDict->count()+Doxygen::inputNameList->count()>0) + if (Doxygen::classSDict->count()+Doxygen::inputNameLinkedMap->size()>0) { ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; @@ -620,15 +620,11 @@ void generateDEF() { generateDEFForClass(cd,t); } - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { - generateDEFForFile(fd,t); + generateDEFForFile(fd.get(),t); } } } diff --git a/src/define.h b/src/define.h index cc1e390..3627140 100644 --- a/src/define.h +++ b/src/define.h @@ -1,12 +1,10 @@ /****************************************************************************** * - * - * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -18,8 +16,11 @@ #ifndef DEFINE_H #define DEFINE_H -#include <qdict.h> -#include <qlist.h> +#include <map> +#include <string> +#include <memory> + +#include <qcstring.h> class FileDef; @@ -48,52 +49,10 @@ class Define bool nonRecursive; }; -/** A list of Define objects. */ -class DefineList : public QList<Define> -{ - public: - DefineList() : QList<Define>() {} - ~DefineList() {} - private: - int compareValues(const Define *d1,const Define *d2) const - { - return qstricmp(d1->name,d2->name); - } -}; - -/** A list of Define objects associated with a specific name. */ -class DefineName : public QList<Define> -{ - public: - DefineName(const char *n) : QList<Define>() { name=n; } - ~DefineName() {} - const char *nameString() const { return name; } - - private: - int compareValues(const Define *d1,const Define *d2) const - { - return qstricmp(d1->name,d2->name); - } - QCString name; -}; - -/** A list of DefineName objects. */ -class DefineNameList : public QList<DefineName> -{ - public: - DefineNameList() : QList<DefineName>() {} - ~DefineNameList() {} - private: - int compareValues(const DefineName *n1,const DefineName *n2) const - { - return qstricmp(n1->nameString(),n2->nameString()); - } -}; - -/** An unsorted dictionary of Define objects. */ -typedef QDict<Define> DefineDict; +/** A dictionary of references to Define objects. */ +typedef std::map< std::string,Define* > DefineMapRef; -/** A sorted dictionary of DefineName object. */ -typedef QDict<DefineName> DefineNameDict; +/** A dictionary of managed Define objects. */ +typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning; #endif diff --git a/src/definition.cpp b/src/definition.cpp index 7540eff..22a1435 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -44,6 +44,7 @@ #include "dirdef.h" #include "pagedef.h" #include "bufstr.h" +#include "reflist.h" //----------------------------------------------------------------------------------------- @@ -55,11 +56,11 @@ class DefinitionImpl::IMPL void init(const char *df, const char *n); void setDefFileName(const QCString &df); - SectionDict *sectionDict = 0; // dictionary of all sections, not accessible + SectionRefs sectionRefs; MemberSDict *sourceRefByDict = 0; MemberSDict *sourceRefsDict = 0; - std::vector<ListItemInfo> xrefListItems; + std::vector<RefItem*> xrefListItems; GroupList *partOfGroups = 0; DocInfo *details = 0; // not exported @@ -99,7 +100,6 @@ class DefinitionImpl::IMPL DefinitionImpl::IMPL::~IMPL() { - delete sectionDict; delete sourceRefByDict; delete sourceRefsDict; delete partOfGroups; @@ -122,8 +122,8 @@ void DefinitionImpl::IMPL::setDefFileName(const QCString &df) void DefinitionImpl::IMPL::init(const char *df, const char *n) { setDefFileName(df); - QCString name = n; - if (name!="<globalScope>") + QCString lname = n; + if (lname!="<globalScope>") { //extractNamespaceName(m_name,m_localName,ns); localName=stripScope(n); @@ -140,7 +140,6 @@ void DefinitionImpl::IMPL::init(const char *df, const char *n) inbodyDocs = 0; sourceRefByDict = 0; sourceRefsDict = 0; - sectionDict = 0, outerScope = Doxygen::globalScope; partOfGroups = 0; hidden = FALSE; @@ -176,15 +175,16 @@ static bool matchExcludedSymbols(const char *name) if (pattern.find('*')!=-1) // wildcard mode { QRegExp re(substitute(pattern,"*",".*"),TRUE); - int i,pl; - i = re.match(symName,0,&pl); + int pl; + int i = re.match(symName,0,&pl); //printf(" %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data()); if (i!=-1) // wildcard match { - int sl=symName.length(); + uint ui=(uint)i; + uint sl=symName.length(); // check if it is a whole word match - if ((i==0 || pattern.at(0)=='*' || (!isId(symName.at(i-1)) && !forceStart)) && - (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd)) + if ((ui==0 || pattern.at(0)=='*' || (!isId(symName.at(ui-1)) && !forceStart)) && + (ui+pl==sl || pattern.at(ui+pl)=='*' || (!isId(symName.at(ui+pl)) && !forceEnd)) ) { //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i); @@ -197,11 +197,12 @@ static bool matchExcludedSymbols(const char *name) int i = symName.find(pattern); if (i!=-1) // we have a match! { - int pl=pattern.length(); - int sl=symName.length(); + uint ui=(uint)i; + uint pl=pattern.length(); + uint sl=symName.length(); // check if it is a whole word match - if ((i==0 || (!isId(symName.at(i-1)) && !forceStart)) && - (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd)) + if ((ui==0 || (!isId(symName.at(ui-1)) && !forceStart)) && + (ui+pl==sl || (!isId(symName.at(ui+pl)) && !forceEnd)) ) { //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i); @@ -315,7 +316,6 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) { m_impl = new DefinitionImpl::IMPL; *m_impl = *d.m_impl; - m_impl->sectionDict = 0; m_impl->sourceRefByDict = 0; m_impl->sourceRefsDict = 0; m_impl->partOfGroups = 0; @@ -323,16 +323,6 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) m_impl->details = 0; m_impl->body = 0; m_impl->inbodyDocs = 0; - if (d.m_impl->sectionDict) - { - m_impl->sectionDict = new SectionDict(17); - SDict<SectionInfo>::Iterator it(*d.m_impl->sectionDict); - SectionInfo *si; - for (it.toFirst();(si=it.current());++it) - { - m_impl->sectionDict->append(si->label,si); - } - } if (d.m_impl->sourceRefByDict) { m_impl->sourceRefByDict = new MemberSDict; @@ -426,22 +416,18 @@ void DefinitionImpl::addSectionsToDefinition(const std::vector<const SectionInfo for (const SectionInfo *si : anchorList) { //printf("Add section '%s' to definition '%s'\n", - // si->label.data(),name().data()); - SectionInfo *gsi=Doxygen::sectionDict->find(si->label); + // si->label().data(),name().data()); + SectionManager &sm = SectionManager::instance(); + SectionInfo *gsi=sm.find(si->label()); //printf("===== label=%s gsi=%p\n",si->label.data(),gsi); if (gsi==0) { - gsi = new SectionInfo(*si); - Doxygen::sectionDict->append(si->label,gsi); - } - if (m_impl->sectionDict==0) - { - m_impl->sectionDict = new SectionDict(17); + gsi = sm.add(*si); } - if (m_impl->sectionDict->find(gsi->label)==0) + if (m_impl->sectionRefs.find(gsi->label())==0) { - m_impl->sectionDict->append(gsi->label,gsi); - gsi->definition = this; + m_impl->sectionRefs.add(gsi); + gsi->setDefinition(this); } } } @@ -449,16 +435,11 @@ void DefinitionImpl::addSectionsToDefinition(const std::vector<const SectionInfo bool DefinitionImpl::hasSections() const { //printf("DefinitionImpl::hasSections(%s) #sections=%d\n",name().data(), - // m_impl->sectionDict ? m_impl->sectionDict->count() : 0); - if (m_impl->sectionDict==0) return FALSE; - SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); - SectionInfo *si; - for (li.toFirst();(si=li.current());++li) - { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + // m_impl->sectionRefs.size()); + if (m_impl->sectionRefs.empty()) return FALSE; + for (const SectionInfo *si : m_impl->sectionRefs) + { + if (isSection(si->type())) { return TRUE; } @@ -468,20 +449,17 @@ bool DefinitionImpl::hasSections() const void DefinitionImpl::addSectionsToIndex() { - if (m_impl->sectionDict==0) return; + if (m_impl->sectionRefs.empty()) return; //printf("DefinitionImpl::addSectionsToIndex()\n"); - SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); - SectionInfo *si; int level=1; - for (li.toFirst();(si=li.current());++li) + for (auto it = m_impl->sectionRefs.begin(); it!=m_impl->sectionRefs.end(); ++it) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + const SectionInfo *si = *it; + SectionType type = si->type(); + if (isSection(type)) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)type; int i; if (nextLevel>level) { @@ -497,16 +475,16 @@ void DefinitionImpl::addSectionsToIndex() Doxygen::indexList->decContentsDepth(); } } - QCString title = si->title; - if (title.isEmpty()) title = si->label; + QCString title = si->title(); + if (title.isEmpty()) title = si->label(); // determine if there is a next level inside this item - ++li; - bool isDir = ((li.current()) ? (int)(li.current()->type > nextLevel):FALSE); - --li; + auto it_next = std::next(it); + bool isDir = (it_next!=m_impl->sectionRefs.end()) ? + ((int)((*it_next)->type()) > nextLevel) : FALSE; Doxygen::indexList->addContentsItem(isDir,title, getReference(), getOutputFileBase(), - si->label, + si->label(), FALSE, TRUE); level = nextLevel; @@ -521,23 +499,21 @@ void DefinitionImpl::addSectionsToIndex() void DefinitionImpl::writeDocAnchorsToTagFile(FTextStream &tagFile) const { - if (m_impl->sectionDict) + if (!m_impl->sectionRefs.empty()) { - //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_impl->sectionDict->count()); - SDict<SectionInfo>::Iterator sdi(*m_impl->sectionDict); - SectionInfo *si; - for (;(si=sdi.current());++sdi) + //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_impl->sectionRef.size()); + for (const SectionInfo *si : m_impl->sectionRefs) { - if (!si->generated && si->ref.isEmpty() && !si->label.startsWith("autotoc_md")) + if (!si->generated() && si->ref().isEmpty() && !si->label().startsWith("autotoc_md")) { //printf("write an entry!\n"); if (definitionType()==TypeMember) tagFile << " "; - tagFile << " <docanchor file=\"" << addHtmlExtensionIfMissing(si->fileName) << "\""; - if (!si->title.isEmpty()) + tagFile << " <docanchor file=\"" << addHtmlExtensionIfMissing(si->fileName()) << "\""; + if (!si->title().isEmpty()) { - tagFile << " title=\"" << convertToXML(si->title) << "\""; + tagFile << " title=\"" << convertToXML(si->title()) << "\""; } - tagFile << ">" << si->label << "</docanchor>" << endl; + tagFile << ">" << si->label() << "</docanchor>" << endl; } } } @@ -623,10 +599,10 @@ void DefinitionImpl::setDocumentation(const char *d,const char *docFile,int docL // if that is a multibyte one. static bool lastCharIsMultibyte(const QCString &s) { - int l = s.length(); + uint l = s.length(); int p = 0; int pp = -1; - while ((p=nextUtf8CharPosition(s,l,p))<l) pp=p; + while ((p=nextUtf8CharPosition(s,l,(uint)p))<(int)l) pp=p; if (pp==-1 || ((uchar)s[pp])<0x80) return FALSE; return TRUE; } @@ -640,7 +616,7 @@ void DefinitionImpl::_setBriefDescription(const char *b,const char *briefFile,in QCString brief = b; brief = brief.stripWhiteSpace(); if (brief.isEmpty()) return; - int bl = brief.length(); + uint bl = brief.length(); if (bl>0 && needsDot) // add punctuation if needed { int c = brief.at(bl-1); @@ -721,7 +697,7 @@ void DefinitionImpl::setInbodyDocumentation(const char *d,const char *inbodyFile struct FilterCacheItem { portable_off_t filePos; - uint fileSize; + size_t fileSize; }; /*! Cache for storing the result of filtering a file */ @@ -748,7 +724,7 @@ class FilterCache if (f) { bool success=TRUE; - str.resize(item->fileSize+1); + str.resize(static_cast<uint>(item->fileSize+1)); if (Portable::fseek(f,item->filePos,SEEK_SET)==-1) { err("Failed to seek to position %d in filter database file %s\n",(int)item->filePos,qPrint(Doxygen::filterDBFileName)); @@ -756,11 +732,11 @@ class FilterCache } if (success) { - int numBytes = fread(str.data(),1,item->fileSize,f); + size_t numBytes = fread(str.data(),1,item->fileSize,f); if (numBytes!=item->fileSize) { err("Failed to read %d bytes from position %d in filter database file %s: got %d bytes\n", - (int)item->fileSize,(int)item->filePos,qPrint(Doxygen::filterDBFileName),numBytes); + (int)item->fileSize,(int)item->filePos,qPrint(Doxygen::filterDBFileName),(int)numBytes); success=FALSE; } } @@ -782,7 +758,7 @@ class FilterCache Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd)); f = Portable::popen(cmd,"r"); FILE *bf = Portable::fopen(Doxygen::filterDBFileName,"a+b"); - FilterCacheItem *item = new FilterCacheItem; + item = new FilterCacheItem; item->filePos = m_endPos; if (bf==0) { @@ -794,16 +770,16 @@ class FilterCache return FALSE; } // append the filtered output to the database file - int size=0; + size_t size=0; while (!feof(f)) { - int bytesRead = fread(buf,1,blockSize,f); - int bytesWritten = fwrite(buf,1,bytesRead,bf); + size_t bytesRead = fread(buf,1,blockSize,f); + size_t bytesWritten = fwrite(buf,1,bytesRead,bf); if (bytesRead!=bytesWritten) { // handle error err("Failed to write to filter database %s. Wrote %d out of %d bytes\n", - qPrint(Doxygen::filterDBFileName),bytesWritten,bytesRead); + qPrint(Doxygen::filterDBFileName),(int)bytesWritten,(int)bytesRead); str.addChar('\0'); delete item; Portable::pclose(f); @@ -811,7 +787,7 @@ class FilterCache return FALSE; } size+=bytesWritten; - str.addArray(buf,bytesWritten); + str.addArray(buf,static_cast<uint>(bytesWritten)); } str.addChar('\0'); item->fileSize = size; @@ -831,8 +807,8 @@ class FilterCache f = Portable::fopen(fileName,"r"); while (!feof(f)) { - int bytesRead = fread(buf,1,blockSize,f); - str.addArray(buf,bytesRead); + size_t bytesRead = fread(buf,1,blockSize,f); + str.addArray(buf,static_cast<uint>(bytesRead)); } str.addChar('\0'); fclose(f); @@ -874,14 +850,13 @@ bool readCodeFragment(const char *fileName, g_filterCache.getFileContents(fileName,str); bool found = lang==SrcLangExt_VHDL || - lang==SrcLangExt_Tcl || lang==SrcLangExt_Python || lang==SrcLangExt_Fortran; - // for VHDL, TCL, Python, and Fortran no bracket search is possible + // for VHDL, Python, and Fortran no bracket search is possible char *p=str.data(); if (p) { - int c=0; + char c=0; int col=0; int lineNr=1; // skip until the startLine has reached @@ -984,7 +959,7 @@ bool readCodeFragment(const char *fileName, int braceIndex = result.findRev('}'); if (braceIndex > newLineIndex) { - result.truncate(braceIndex+1); + result.truncate((uint)braceIndex+1); } endLine=lineNr-1; } @@ -1023,11 +998,11 @@ QCString DefinitionImpl::getSourceAnchor() const { if (Htags::useHtags) { - qsnprintf(anchorStr,maxAnchorStrLen,"L%d",m_impl->body->startLine); + qsnprintf(anchorStr,maxAnchorStrLen,"L%d",m_impl->body->defLine); } else { - qsnprintf(anchorStr,maxAnchorStrLen,"l%05d",m_impl->body->startLine); + qsnprintf(anchorStr,maxAnchorStrLen,"l%05d",m_impl->body->defLine); } } return anchorStr; @@ -1050,7 +1025,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this. { QCString lineStr; - lineStr.sprintf("%d",m_impl->body->startLine); + lineStr.sprintf("%d",m_impl->body->defLine); QCString anchorStr = getSourceAnchor(); ol.startParagraph("definition"); if (lineMarkerPos<fileMarkerPos) // line marker before file marker @@ -1128,10 +1103,9 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const // write normal text (Man, Latex optionally, RTF optionally) ol.docify(m_impl->body->fileDef->name()); ol.popGeneratorState(); - + // write text right from file marker - ol.parseText(refText.right( - refText.length()-fileMarkerPos-2)); + ol.parseText(refText.right(refText.length()-(uint)fileMarkerPos-2)); } else // file marker before line marker { @@ -1211,8 +1185,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.popGeneratorState(); // write text right from linePos marker - ol.parseText(refText.right( - refText.length()-lineMarkerPos-2)); + ol.parseText(refText.right(refText.length()-(uint)lineMarkerPos-2)); } ol.endParagraph(); } @@ -1224,12 +1197,13 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.popGeneratorState(); } -void DefinitionImpl::setBodySegment(int bls,int ble) +void DefinitionImpl::setBodySegment(int defLine, int bls,int ble) { //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data()); if (m_impl->body==0) m_impl->body = new BodyInfo; - m_impl->body->startLine=bls; - m_impl->body->endLine=ble; + m_impl->body->defLine = defLine; + m_impl->body->startLine = bls; + m_impl->body->endLine = ble; } void DefinitionImpl::setBodyDef(FileDef *fd) @@ -1308,15 +1282,17 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, ol.parseText(text); ol.docify(" "); - QCString ldefLine=theTranslator->trWriteList(members->count()); + QCString ldefLine=theTranslator->trWriteList((int)members->count()); QRegExp marker("@[0-9]+"); - int index=0,newIndex,matchLen; + uint index=0; + int matchLen; + int newIndex; // now replace all markers in inheritLine with links to the classes while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1) { bool ok; - ol.parseText(ldefLine.mid(index,newIndex-index)); + ol.parseText(ldefLine.mid(index,(uint)newIndex-index)); uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); MemberDef *md=members->at(entryIndex); if (ok && md) @@ -1434,7 +1410,7 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, ol.docify(name); } } - index=newIndex+matchLen; + index=(uint)newIndex+matchLen; } ol.parseText(ldefLine.right(ldefLine.length()-index)); ol.writeString("."); @@ -1604,7 +1580,7 @@ void DefinitionImpl::makePartOfGroup(GroupDef *gd) m_impl->partOfGroups->append(gd); } -void DefinitionImpl::setRefItems(const std::vector<ListItemInfo> &sli) +void DefinitionImpl::setRefItems(const std::vector<RefItem*> &sli) { m_impl->xrefListItems.insert(m_impl->xrefListItems.end(), sli.cbegin(), sli.cend()); } @@ -1620,31 +1596,34 @@ void DefinitionImpl::mergeRefItems(Definition *d) // sort results on itemId std::sort(m_impl->xrefListItems.begin(),m_impl->xrefListItems.end(), - [](const ListItemInfo &left,const ListItemInfo &right) - { return left.itemId<right.itemId || - (left.itemId==right.itemId && qstrcmp(left.type,right.type)<0); + [](RefItem *left,RefItem *right) + { return left->id() <right->id() || + (left->id()==right->id() && + qstrcmp(left->list()->listName(),right->list()->listName())<0); }); // filter out duplicates auto last = std::unique(m_impl->xrefListItems.begin(),m_impl->xrefListItems.end(), - [](const ListItemInfo &left,const ListItemInfo &right) - { return left.itemId==right.itemId && left.type==right.type; }); + [](const RefItem *left,const RefItem *right) + { return left->id()==right->id() && + left->list()->listName()==right->list()->listName(); + }); m_impl->xrefListItems.erase(last, m_impl->xrefListItems.end()); } int DefinitionImpl::_getXRefListId(const char *listName) const { - for (const ListItemInfo &lii : m_impl->xrefListItems) + for (const RefItem *item : m_impl->xrefListItems) { - if (lii.type==listName) + if (item->list()->listName()==listName) { - return lii.itemId; + return item->id(); } } return -1; } -const std::vector<ListItemInfo> &DefinitionImpl::xrefListItems() const +const std::vector<RefItem*> &DefinitionImpl::xrefListItems() const { return m_impl->xrefListItems; } @@ -1756,8 +1735,7 @@ void DefinitionImpl::writeNavigationPath(OutputList &ol) const // TODO: move to htmlgen void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const { - SectionDict *sectionDict = m_impl->sectionDict; - if (sectionDict==0) return; + if (m_impl->sectionRefs.empty()) return; if (localToc.isHtmlEnabled()) { int maxLevel = localToc.htmlLevel(); @@ -1768,21 +1746,17 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const ol.writeString(theTranslator->trRTFTableOfContents()); ol.writeString("</h3>\n"); ol.writeString("<ul>"); - SDict<SectionInfo>::Iterator li(*sectionDict); - SectionInfo *si; int level=1,l; char cs[2]; cs[1]='\0'; - bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; - for (li.toFirst();(si=li.current());++li) + std::vector<bool> inLi(maxLevel+1,false); + for (const SectionInfo *si : m_impl->sectionRefs) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + SectionType type = si->type(); + if (isSection(type)) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)type; if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1795,28 +1769,39 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const for (l=level;l>nextLevel;l--) { if (l <= maxLevel && inLi[l]) ol.writeString("</li>\n"); - inLi[l]=FALSE; + inLi[l]=false; if (l <= maxLevel) ol.writeString("</ul>\n"); } } - cs[0]='0'+nextLevel; - if (nextLevel <= maxLevel && inLi[nextLevel]) ol.writeString("</li>\n"); - QCString titleDoc = convertToHtml(si->title); - if (nextLevel <= maxLevel) ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>"); - inLi[nextLevel]=TRUE; + cs[0]=(char)('0'+nextLevel); + if (nextLevel <= maxLevel && inLi[nextLevel]) + { + ol.writeString("</li>\n"); + } + QCString titleDoc = convertToHtml(si->title()); + if (nextLevel <= maxLevel) + { + ol.writeString("<li class=\"level"+QCString(cs)+"\">" + "<a href=\"#"+si->label()+"\">"+ + (si->title().isEmpty()?si->label():titleDoc)+"</a>"); + } + inLi[nextLevel]=true; level = nextLevel; } } if (level > maxLevel) level = maxLevel; while (level>1 && level <= maxLevel) { - if (inLi[level]) ol.writeString("</li>\n"); + if (inLi[level]) + { + ol.writeString("</li>\n"); + } inLi[level]=FALSE; ol.writeString("</ul>\n"); level--; } if (level <= maxLevel && inLi[level]) ol.writeString("</li>\n"); - inLi[level]=FALSE; + inLi[level]=false; ol.writeString("</ul>\n"); ol.writeString("</div>\n"); ol.popGeneratorState(); @@ -1828,21 +1813,16 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const ol.disableAllBut(OutputGenerator::Docbook); ol.writeString(" <toc>\n"); ol.writeString(" <title>" + theTranslator->trRTFTableOfContents() + "</title>\n"); - SectionDict *sectionDict = getSectionDict(); - SDict<SectionInfo>::Iterator li(*sectionDict); - SectionInfo *si; int level=1,l; - bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; int maxLevel = localToc.docbookLevel(); - for (li.toFirst();(si=li.current());++li) + std::vector<bool> inLi(maxLevel+1,false); + for (const SectionInfo *si : m_impl->sectionRefs) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + SectionType type = si->type(); + if (isSection(type)) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)type; if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1860,8 +1840,10 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const } if (nextLevel <= maxLevel) { - QCString titleDoc = convertToDocBook(si->title); - ol.writeString(" <tocentry>" + (si->title.isEmpty()?si->label:titleDoc) + "</tocentry>\n"); + QCString titleDoc = convertToDocBook(si->title()); + ol.writeString(" <tocentry>" + + (si->title().isEmpty()?si->label():titleDoc) + + "</tocentry>\n"); } inLi[nextLevel]=TRUE; level = nextLevel; @@ -1894,9 +1876,9 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const //---------------------------------------------------------------------------------------- -SectionDict * DefinitionImpl::getSectionDict() const +const SectionRefs &DefinitionImpl::getSectionRefs() const { - return m_impl->sectionDict; + return m_impl->sectionRefs; } QCString DefinitionImpl::symbolName() const @@ -1952,17 +1934,17 @@ QCString abbreviate(const char *s,const char *name) const char *p = briefDescAbbrev.first(); while (p) { - QCString s = p; - s.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name - s += " "; - stripWord(result,s); + QCString str = p; + str.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name + str += " "; + stripWord(result,str); p = briefDescAbbrev.next(); } // capitalize first word if (!result.isEmpty()) { - int c=result[0]; + char c=result[0]; if (c>='a' && c<='z') c+='A'-'a'; result[0]=c; } @@ -2075,6 +2057,11 @@ bool DefinitionImpl::isReference() const return !m_impl->ref.isEmpty(); } +int DefinitionImpl::getStartDefLine() const +{ + return m_impl->body ? m_impl->body->defLine : -1; +} + int DefinitionImpl::getStartBodyLine() const { return m_impl->body ? m_impl->body->startLine : -1; @@ -2181,7 +2168,7 @@ QCString DefinitionImpl::externalReference(const QCString &relPath) const if (dest) { QCString result = *dest; - int l = result.length(); + uint l = result.length(); if (!relPath.isEmpty() && l>0 && result.at(0)=='.') { // relative path -> prepend relPath. result.prepend(relPath); diff --git a/src/definition.h b/src/definition.h index b3ece2c..318a35b 100644 --- a/src/definition.h +++ b/src/definition.h @@ -32,15 +32,15 @@ class FileDef; class OutputList; -class SectionDict; +class SectionRefs; class MemberSDict; class MemberDef; class GroupDef; class GroupList; -struct ListItemInfo; -struct SectionInfo; +class SectionInfo; class Definition; class FTextStream; +class RefItem; /** Data associated with a detailed description. */ struct DocInfo @@ -62,8 +62,9 @@ struct BriefInfo /** Data associated with description found in the body. */ struct BodyInfo { - int startLine; //!< line number of the start of the definition - int endLine; //!< line number of the end of the definition + int defLine; //!< line number of the start of the definition + int startLine; //!< line number of the start of the definition's body + int endLine; //!< line number of the end of the definition's body FileDef *fileDef; //!< file definition containing the function body }; @@ -188,7 +189,7 @@ class Definition : public DefinitionIntf /*! returns the extension of the file in which this definition was found */ virtual QCString getDefFileExtension() const = 0; - /*! returns the line number at which the definition was found */ + /*! returns the line number at which the definition was found (can be the declaration) */ virtual int getDefLine() const = 0; /*! returns the column number at which the definition was found */ @@ -242,6 +243,9 @@ class Definition : public DefinitionIntf /*! Convenience method to return a resolved external link */ virtual QCString externalReference(const QCString &relPath) const = 0; + /*! Returns the first line of the implementation of this item. See also getDefLine() */ + virtual int getStartDefLine() const = 0; + /*! Returns the first line of the body of this item (applicable to classes and * functions). */ @@ -263,7 +267,7 @@ class Definition : public DefinitionIntf virtual GroupList *partOfGroups() const = 0; virtual bool isLinkableViaGroup() const = 0; - virtual const std::vector<ListItemInfo> &xrefListItems() const = 0; + virtual const std::vector<RefItem*> &xrefListItems() const = 0; virtual Definition *findInnerCompound(const char *name) const = 0; virtual Definition *getOuterScope() const = 0; @@ -280,7 +284,7 @@ class Definition : public DefinitionIntf virtual QCString id() const = 0; /** returns the section dictionary, only of importance for pagedef */ - virtual SectionDict * getSectionDict() const = 0; + virtual const SectionRefs &getSectionRefs() const = 0; virtual QCString navigationPathAsString() const = 0; virtual QCString pathFragment() const = 0; @@ -316,10 +320,10 @@ class Definition : public DefinitionIntf virtual void setReference(const char *r) = 0; // source references - virtual void setBodySegment(int bls,int ble) = 0; + virtual void setBodySegment(int defLine, int bls,int ble) = 0; virtual void setBodyDef(FileDef *fd) = 0; - virtual void setRefItems(const std::vector<ListItemInfo> &sli) = 0; + virtual void setRefItems(const std::vector<RefItem*> &sli) = 0; virtual void setOuterScope(Definition *d) = 0; virtual void setHidden(bool b) = 0; diff --git a/src/definitionimpl.h b/src/definitionimpl.h index 2d8886d..28d60b6 100644 --- a/src/definitionimpl.h +++ b/src/definitionimpl.h @@ -61,13 +61,14 @@ class DefinitionImpl : virtual public Definition virtual QCString getReference() const; virtual bool isReference() const; virtual QCString externalReference(const QCString &relPath) const; + virtual int getStartDefLine() const; virtual int getStartBodyLine() const; virtual int getEndBodyLine() const; virtual FileDef *getBodyDef() const; virtual SrcLangExt getLanguage() const; virtual GroupList *partOfGroups() const; virtual bool isLinkableViaGroup() const; - virtual const std::vector<ListItemInfo> &xrefListItems() const; + virtual const std::vector<RefItem*> &xrefListItems() const; virtual Definition *findInnerCompound(const char *name) const; virtual Definition *getOuterScope() const; virtual MemberSDict *getReferencesMembers() const; @@ -76,7 +77,7 @@ class DefinitionImpl : virtual public Definition virtual bool hasSources() const; virtual bool hasBriefDescription() const; virtual QCString id() const; - virtual SectionDict * getSectionDict() const; + virtual const SectionRefs &getSectionRefs() const; virtual void setName(const char *name); virtual void setId(const char *name); virtual void setDefFile(const QCString& df,int defLine,int defColumn); @@ -85,11 +86,11 @@ class DefinitionImpl : virtual public Definition virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine); virtual void setReference(const char *r); virtual void addSectionsToDefinition(const std::vector<const SectionInfo*> &anchorList); - virtual void setBodySegment(int bls,int ble); + virtual void setBodySegment(int defLine,int bls,int ble); virtual void setBodyDef(FileDef *fd); virtual void addSourceReferencedBy(const MemberDef *d); virtual void addSourceReferences(const MemberDef *d); - virtual void setRefItems(const std::vector<ListItemInfo> &sli); + virtual void setRefItems(const std::vector<RefItem*> &sli); virtual void mergeRefItems(Definition *d); virtual void addInnerCompound(const Definition *d); virtual void setOuterScope(Definition *d); @@ -201,6 +202,8 @@ class DefinitionAliasImpl : virtual public Definition { return m_def->isReference(); } virtual QCString externalReference(const QCString &relPath) const { return m_def->externalReference(relPath); } + virtual int getStartDefLine() const + { return m_def->getStartDefLine(); } virtual int getStartBodyLine() const { return m_def->getStartBodyLine(); } virtual int getEndBodyLine() const @@ -213,7 +216,7 @@ class DefinitionAliasImpl : virtual public Definition { return m_def->partOfGroups(); } virtual bool isLinkableViaGroup() const { return m_def->isLinkableViaGroup(); } - virtual const std::vector<ListItemInfo> &xrefListItems() const + virtual const std::vector<RefItem*> &xrefListItems() const { return m_def->xrefListItems(); } virtual Definition *findInnerCompound(const char *name) const { return m_def->findInnerCompound(name); } @@ -231,43 +234,43 @@ class DefinitionAliasImpl : virtual public Definition { return m_def->hasBriefDescription(); } virtual QCString id() const { return m_def->id(); } - virtual SectionDict * getSectionDict() const - { return m_def->getSectionDict(); } + virtual const SectionRefs &getSectionRefs() const + { return m_def->getSectionRefs(); } virtual QCString navigationPathAsString() const { return m_def->navigationPathAsString(); } virtual QCString pathFragment() const { return m_def->pathFragment(); } - virtual void setName(const char *name) { } - virtual void setId(const char *name) { } - virtual void setDefFile(const QCString& df,int defLine,int defColumn) {} - virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) {} - virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) {} - virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine) {} - virtual void setReference(const char *r) {} - virtual void addSectionsToDefinition(const std::vector<const SectionInfo*> &anchorList) {} - virtual void setBodySegment(int bls,int ble) {} - virtual void setBodyDef(FileDef *fd) {} - virtual void addSourceReferencedBy(const MemberDef *d) {} - virtual void addSourceReferences(const MemberDef *d) {} - virtual void setRefItems(const std::vector<ListItemInfo> &sli) {} - virtual void mergeRefItems(Definition *d) {} - virtual void addInnerCompound(const Definition *d) {} - virtual void setOuterScope(Definition *d) {} - virtual void setHidden(bool b) {} - virtual void setArtificial(bool b) {} - virtual void setLanguage(SrcLangExt lang) {} - virtual void writeSourceDef(OutputList &ol,const char *scopeName) const {} - virtual void writeInlineCode(OutputList &ol,const char *scopeName) const {} - virtual void writeSourceRefs(OutputList &ol,const char *scopeName) const {} - virtual void writeSourceReffedBy(OutputList &ol,const char *scopeName) const {} - virtual void makePartOfGroup(GroupDef *gd) {} - virtual void writeNavigationPath(OutputList &ol) const {} + virtual void setName(const char *) { } + virtual void setId(const char *) { } + virtual void setDefFile(const QCString&,int,int) {} + virtual void setDocumentation(const char *,const char *,int,bool=TRUE) {} + virtual void setBriefDescription(const char *,const char *,int) {} + virtual void setInbodyDocumentation(const char *,const char *,int) {} + virtual void setReference(const char *) {} + virtual void addSectionsToDefinition(const std::vector<const SectionInfo*> &) {} + virtual void setBodySegment(int,int,int) {} + virtual void setBodyDef(FileDef *) {} + virtual void addSourceReferencedBy(const MemberDef *) {} + virtual void addSourceReferences(const MemberDef *) {} + virtual void setRefItems(const std::vector<RefItem*> &) {} + virtual void mergeRefItems(Definition *) {} + virtual void addInnerCompound(const Definition *) {} + virtual void setOuterScope(Definition *) {} + virtual void setHidden(bool) {} + virtual void setArtificial(bool) {} + virtual void setLanguage(SrcLangExt) {} + virtual void writeSourceDef(OutputList &,const char *) const {} + virtual void writeInlineCode(OutputList &,const char *) const {} + virtual void writeSourceRefs(OutputList &,const char *) const {} + virtual void writeSourceReffedBy(OutputList &,const char *) const {} + virtual void makePartOfGroup(GroupDef *) {} + virtual void writeNavigationPath(OutputList &) const {} virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const {} virtual void writeSummaryLinks(OutputList &) const {} virtual void writeDocAnchorsToTagFile(FTextStream &) const {} - virtual void setLocalName(const QCString name) {} + virtual void setLocalName(const QCString) {} virtual void addSectionsToIndex() {} - virtual void writeToc(OutputList &ol, const LocalToc <) const {} + virtual void writeToc(OutputList &, const LocalToc &) const {} virtual void setCookie(Cookie *cookie) const { delete m_cookie; m_cookie = cookie; } virtual Cookie *cookie() const { return m_cookie; } protected: diff --git a/src/diagram.cpp b/src/diagram.cpp index 18817e9..d0b7a08 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -42,20 +42,20 @@ class DiagramItemList; class DiagramItem { public: - DiagramItem(DiagramItem *p,int number,const ClassDef *cd, + DiagramItem(DiagramItem *p,uint number,const ClassDef *cd, Protection prot,Specifier virt,const char *ts); ~DiagramItem(); QCString label() const; QCString fileName() const; DiagramItem *parentItem() { return parent; } DiagramItemList *getChildren() { return children; } - void move(int dx,int dy) { x+=dx; y+=dy; } - int xPos() const { return x; } - int yPos() const { return y; } - int avgChildPos() const; - int numChildren() const; + void move(int dx,int dy) { x+=(uint)dx; y+=(uint)dy; } + uint xPos() const { return x; } + uint yPos() const { return y; } + uint avgChildPos() const; + uint numChildren() const; void addChild(DiagramItem *di); - int number() const { return num; } + uint number() const { return num; } Protection protection() const { return prot; } Specifier virtualness() const { return virt; } void putInList() { inList=TRUE; } @@ -64,8 +64,8 @@ class DiagramItem private: DiagramItemList *children; DiagramItem *parent; - int x,y; - int num; + uint x,y; + uint num; Protection prot; Specifier virt; QCString templSpec; @@ -85,8 +85,8 @@ class DiagramItemList : public QList<DiagramItem> class DiagramRow : public QList<DiagramItem> { public: - DiagramRow(TreeDiagram *d,int l) : QList<DiagramItem>() - { + DiagramRow(TreeDiagram *d,uint l) : QList<DiagramItem>() + { diagram=d; level=l; setAutoDelete(TRUE); @@ -129,7 +129,7 @@ class TreeDiagram : public QList<DiagramRow> uint baseRows,uint superRows, uint cellWidth,uint cellheight); private: - bool layoutTree(DiagramItem *root,int row); + bool layoutTree(DiagramItem *root,uint row); TreeDiagram &operator=(const TreeDiagram &); TreeDiagram(const TreeDiagram &); }; @@ -139,8 +139,8 @@ class TreeDiagram : public QList<DiagramRow> //----------------------------------------------------------------------------- const uint maxTreeWidth = 8; -const int gridWidth = 100; -const int gridHeight = 100; +const uint gridWidth = 100; +const uint gridHeight = 100; const uint labelHorSpacing = 10; // horizontal distance between labels const uint labelVertSpacing = 32; // vertical distance between labels @@ -171,7 +171,7 @@ static uint protToMask(Protection p) return 0; } -static uint protToColor(Protection p) +static uchar protToColor(Protection p) { switch(p) { @@ -225,21 +225,23 @@ static Protection getMinProtectionLevel(DiagramItemList *dil) } static void writeBitmapBox(DiagramItem *di,Image *image, - int x,int y,int w,int h,bool firstRow, + uint x,uint y,uint w,uint h,bool firstRow, bool hasDocs,bool children=FALSE) { - int colFill = hasDocs ? (firstRow ? 0 : 2) : 7; - int colBorder = (firstRow || !hasDocs) ? 1 : 3; - int l = Image::stringLength(di->label()); + uchar colFill = hasDocs ? (firstRow ? 0 : 2) : 7; + uchar colBorder = (firstRow || !hasDocs) ? 1 : 3; + uint l = Image::stringLength(di->label()); uint mask=virtToMask(di->virtualness()); image->fillRect(x+1,y+1,w-2,h-2,colFill,mask); image->drawRect(x,y,w,h,colBorder,mask); image->writeString(x+(w-l)/2, y+(h-fontHeight)/2, di->label(),1); if (children) { - int i; + uint i; for (i=0;i<5;i++) + { image->drawHorzLine(y+h+i-6,x+w-2-i,x+w-2,firstRow?1:3,0xffffffff); + } } } @@ -253,7 +255,7 @@ static void writeVectorBox(FTextStream &t,DiagramItem *di, } static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, - int x,int y,int w,int h) + uint x,uint y,uint w,uint h) { if (cd->isLinkable()) { @@ -261,7 +263,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, t << "<area "; if (!ref.isEmpty()) { - t << externalLinkTarget(); + t << externalLinkTarget(true); } t << "href=\""; t << externalRef(relPath,ref,TRUE); @@ -283,12 +285,11 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, } //----------------------------------------------------------------------------- -DiagramItem::DiagramItem(DiagramItem *p,int number,const ClassDef *cd, +DiagramItem::DiagramItem(DiagramItem *p,uint number,const ClassDef *cd, Protection pr,Specifier vi,const char *ts) -{ - parent=p; - x=y=0; - //name=n; +{ + parent=p; + x=y=0; num=number; children = new DiagramItemList; prot=pr; @@ -297,9 +298,9 @@ DiagramItem::DiagramItem(DiagramItem *p,int number,const ClassDef *cd, classDef=cd; templSpec=ts; } - + DiagramItem::~DiagramItem() -{ +{ delete children; } @@ -330,10 +331,10 @@ QCString DiagramItem::fileName() const return classDef->getOutputFileBase(); } -int DiagramItem::avgChildPos() const +uint DiagramItem::avgChildPos() const { DiagramItem *di; - int c=children->count(); + uint c=children->count(); if (c==0) // no children -> don't move return xPos(); if ((di=children->getFirst())->isInList()) // children should be in a list @@ -344,7 +345,7 @@ int DiagramItem::avgChildPos() const return (children->at(c/2-1)->xPos()+children->at(c/2)->xPos())/2; } -int DiagramItem::numChildren() const +uint DiagramItem::numChildren() const { return children->count(); } @@ -363,7 +364,7 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases cd,prot,virt,ts); //cd->visited=TRUE; if (parent) parent->addChild(di); - di->move(count()*gridWidth,level*gridHeight); + di->move((int)(count()*gridWidth),(int)(level*gridHeight)); append(di); BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses(); int count=0; @@ -431,7 +432,7 @@ void TreeDiagram::moveChildren(DiagramItem *root,int dx) } } -bool TreeDiagram::layoutTree(DiagramItem *root,int r) +bool TreeDiagram::layoutTree(DiagramItem *root,uint r) { bool moved=FALSE; //printf("layoutTree(%s,%d)\n",root->label().data(),r); @@ -440,15 +441,15 @@ bool TreeDiagram::layoutTree(DiagramItem *root,int r) if (dil->count()>0) { uint k; - int pPos=root->xPos(); - int cPos=root->avgChildPos(); + uint pPos=root->xPos(); + uint cPos=root->avgChildPos(); if (pPos>cPos) // move children { DiagramRow *row=at(r+1); //printf("Moving children %d-%d in row %d\n", // dil->getFirst()->number(),row->count()-1,r+1); for (k=dil->getFirst()->number();k<row->count();k++) - row->at(k)->move(pPos-cPos,0); + row->at(k)->move((int)(pPos-cPos),0); moved=TRUE; } else if (pPos<cPos) // move parent @@ -457,7 +458,7 @@ bool TreeDiagram::layoutTree(DiagramItem *root,int r) //printf("Moving parents %d-%d in row %d\n", // root->number(),row->count()-1,r); for (k=root->number();k<row->count();k++) - row->at(k)->move(cPos-pPos,0); + row->at(k)->move((int)(cPos-pPos),0); moved=TRUE; } @@ -525,7 +526,7 @@ void TreeDiagram::computeLayout() uint TreeDiagram::computeRows() { //printf("TreeDiagram::computeRows()=%d\n",count()); - int count=0; + uint count=0; QListIterator<DiagramRow> it(*this); DiagramRow *row; for (;(row=it.current()) && !row->getFirst()->isInList();++it) @@ -535,8 +536,8 @@ uint TreeDiagram::computeRows() //printf("count=%d row=%p\n",count,row); if (row) { - int maxListLen=0; - int curListLen=0; + uint maxListLen=0; + uint curListLen=0; DiagramItem *opi=0; QListIterator<DiagramItem> rit(*row); DiagramItem *di; @@ -587,7 +588,7 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image, bool firstRow = doBase; for (;(dr=it.current()) && !done;++it) { - int x=0,y=0; + uint x=0,y=0; float xf=0.0f,yf=0.0f; QListIterator<DiagramItem> rit(*dr); DiagramItem *di = rit.current(); @@ -617,7 +618,7 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image, x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth; if (doBase) { - y = image->getHeight()- + y = image->height()- superRows*cellHeight- (superRows-1)*labelVertSpacing- di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; @@ -669,7 +670,7 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image, x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth; if (doBase) { - y = image->getHeight()- + y = image->height()- superRows*cellHeight- (superRows-1)*labelVertSpacing- di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; @@ -717,7 +718,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, DiagramItem *di = rit.current(); if (di->isInList()) // row consists of list connectors { - int x=0,y=0,ys=0; + uint x=0,y=0,ys=0; float xf=0.0f,yf=0.0f,ysf=0.0f; for (;(di=rit.current());++rit) { @@ -731,7 +732,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2; if (doBase) // base classes { - y = image->getHeight()- + y = image->height()- (superRows-1)*(cellHeight+labelVertSpacing)- di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; image->drawVertArrow(x,y,y+labelVertSpacing/2, @@ -759,7 +760,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, else { t << "0 " << (di->xPos()/(float)gridWidth) << " " - << ((float)superRows-0.25-di->yPos()/(float)gridHeight) + << ((float)superRows-0.25f-di->yPos()/(float)gridHeight) << " in\n"; } } @@ -772,7 +773,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, (cellWidth+labelHorSpacing)/gridWidth+cellWidth/2; if (doBase) // base classes { - ys = image->getHeight()- + ys = image->height()- (superRows-1)*(cellHeight+labelVertSpacing)- di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; y = ys - cellHeight/2; @@ -873,7 +874,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, } else { - t << xf << " " << (ysf + 0.25) << " " << yf << " vedge\n"; + t << xf << " " << (ysf + 0.25f) << " " << yf << " vedge\n"; } } } @@ -884,7 +885,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, { for (;(di=rit.current());++rit) { - int x=0,y=0; + uint x=0,y=0; DiagramItemList *dil = di->getChildren(); DiagramItem *parent = di->parentItem(); if (parent) // item has a parent -> connect to it @@ -894,7 +895,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2; if (doBase) // base classes { - y = image->getHeight()- + y = image->height()- (superRows-1)*(cellHeight+labelVertSpacing)- di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; /* write input line */ @@ -924,7 +925,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, else { t << "0 " << di->xPos()/(float)gridWidth << " " - << ((float)superRows-0.25-di->yPos()/(float)gridHeight) + << ((float)superRows-0.25f-di->yPos()/(float)gridHeight) << " in\n"; } } @@ -933,13 +934,13 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, { Protection p=getMinProtectionLevel(dil); uint mask=protToMask(p); - uint col=protToColor(p); + uchar col=protToColor(p); if (bitmap) { x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2; if (doBase) // base classes { - y = image->getHeight()- + y = image->height()- (superRows-1)*(cellHeight+labelVertSpacing)- cellHeight-labelVertSpacing/2- di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; @@ -964,7 +965,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, else { t << "1 " << di->xPos()/(float)gridWidth << " " - << ((float)superRows-1.75-di->yPos()/(float)gridHeight) + << ((float)superRows-1.75f-di->yPos()/(float)gridHeight) << " out\n"; } } @@ -975,9 +976,9 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, { if (bitmap) { - int xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth + uint xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2; - int xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth + uint xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2; if (doBase) // base classes { @@ -1034,17 +1035,17 @@ ClassDiagram::ClassDiagram(const ClassDef *root) super->computeLayout(); DiagramItem *baseItem = base->getFirst()->getFirst(); DiagramItem *superItem = super->getFirst()->getFirst(); - int xbase = baseItem->xPos(); - int xsuper = superItem->xPos(); + uint xbase = baseItem->xPos(); + uint xsuper = superItem->xPos(); if (xbase>xsuper) { - superItem->move(xbase-xsuper,0); - super->moveChildren(superItem,xbase-xsuper); + superItem->move((int)(xbase-xsuper),0); + super->moveChildren(superItem,(int)(xbase-xsuper)); } else if (xbase<xsuper) { - baseItem->move(xsuper-xbase,0); - base->moveChildren(baseItem,xsuper-xbase); + baseItem->move((int)(xsuper-xbase),0); + base->moveChildren(baseItem,(int)(xsuper-xbase)); } } @@ -1116,7 +1117,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, t << "%%For: \n"; t << "%Magnification: 1.00\n"; t << "%%Orientation: Portrait\n"; - t << "%%BoundingBox: 0 0 500 " << estHeight*500.0/(float)estWidth << "\n"; + t << "%%BoundingBox: 0 0 500 " << estHeight*500.0f/(float)estWidth << "\n"; t << "%%Pages: 0\n"; t << "%%BeginSetup\n"; t << "%%EndSetup\n"; diff --git a/src/dirdef.cpp b/src/dirdef.cpp index ba792e1..70ca3c0 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -14,6 +14,7 @@ #include "config.h" #include "docparser.h" #include "definitionimpl.h" +#include "filedef.h" //---------------------------------------------------------------------- @@ -103,7 +104,7 @@ DirDefImpl::DirDefImpl(const char *path) : DefinitionImpl(path,1,1,path) m_shortName = m_shortName.left(m_shortName.length()-1); } int pi=m_shortName.findRev('/'); - if (pi!=-1) + if (pi!=-1) { // remove everything till the last / m_shortName = m_shortName.mid(pi+1); } @@ -113,7 +114,7 @@ DirDefImpl::DirDefImpl(const char *path) : DefinitionImpl(path,1,1,path) { // strip trailing / m_dispName = m_dispName.left(m_dispName.length()-1); } - + m_fileList = new FileList; m_usedDirs = new QDict<UsedDir>(257); m_usedDirs->setAutoDelete(TRUE); @@ -128,14 +129,14 @@ DirDefImpl::~DirDefImpl() delete m_usedDirs; } -bool DirDefImpl::isLinkableInProject() const -{ - return !isReference(); +bool DirDefImpl::isLinkableInProject() const +{ + return !isReference(); } -bool DirDefImpl::isLinkable() const -{ - return isReference() || isLinkableInProject(); +bool DirDefImpl::isLinkable() const +{ + return isReference() || isLinkableInProject(); } void DirDefImpl::addSubDir(DirDef *subdir) @@ -203,7 +204,7 @@ QCString DirDefImpl::getOutputFileBase() const void DirDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) { - if ((!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF)) || + if ((!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF)) || !documentation().isEmpty()) { ol.pushGeneratorState(); @@ -224,7 +225,7 @@ void DirDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE); } // separator between brief and details - if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) && + if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) && !documentation().isEmpty()) { ol.pushGeneratorState(); @@ -373,9 +374,7 @@ void DirDefImpl::writeFileList(OutputList &ol) ol.parseText(theTranslator->trFile(TRUE,FALSE)); ol.endMemberHeader(); ol.startMemberList(); - QListIterator<FileDef> it(*m_fileList); - FileDef *fd; - for (;(fd=it.current());++it) + for (it.toFirst();(fd=it.current());++it) { if (fd->hasDocumentation()) { @@ -497,7 +496,7 @@ void DirDefImpl::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); - + QCString title=theTranslator->trDirReference(m_dispName); startFile(ol,getOutputFileBase(),name(),title,HLI_Files,!generateTreeView); @@ -529,25 +528,25 @@ void DirDefImpl::writeDocumentation(OutputList &ol) { switch (lde->kind()) { - case LayoutDocEntry::BriefDesc: + case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); - break; - case LayoutDocEntry::DirGraph: + break; + case LayoutDocEntry::DirGraph: writeDirectoryGraph(ol); - break; - case LayoutDocEntry::MemberDeclStart: + break; + case LayoutDocEntry::MemberDeclStart: startMemberDeclarations(ol); - break; - case LayoutDocEntry::DirSubDirs: + break; + case LayoutDocEntry::DirSubDirs: writeSubDirList(ol); - break; - case LayoutDocEntry::DirFiles: + break; + case LayoutDocEntry::DirFiles: writeFileList(ol); - break; - case LayoutDocEntry::MemberDeclEnd: + break; + case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; - case LayoutDocEntry::DetailedDesc: + case LayoutDocEntry::DetailedDesc: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeDetailedDescription(ol,ls->title(lang)); @@ -575,16 +574,16 @@ void DirDefImpl::writeDocumentation(OutputList &ol) case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: case LayoutDocEntry::FileIncludeGraph: - case LayoutDocEntry::FileIncludedByGraph: + case LayoutDocEntry::FileIncludedByGraph: case LayoutDocEntry::FileSourceLink: case LayoutDocEntry::FileInlineClasses: - case LayoutDocEntry::GroupClasses: - case LayoutDocEntry::GroupInlineClasses: + case LayoutDocEntry::GroupClasses: + case LayoutDocEntry::GroupInlineClasses: case LayoutDocEntry::GroupNamespaces: - case LayoutDocEntry::GroupDirs: - case LayoutDocEntry::GroupNestedGroups: + case LayoutDocEntry::GroupDirs: + case LayoutDocEntry::GroupNestedGroups: case LayoutDocEntry::GroupFiles: - case LayoutDocEntry::GroupGraph: + case LayoutDocEntry::GroupGraph: case LayoutDocEntry::GroupPageDocs: case LayoutDocEntry::AuthorSection: case LayoutDocEntry::MemberGroups: @@ -626,7 +625,7 @@ void DirDefImpl::setLevel() /** Add as "uses" dependency between \a this dir and \a dir, * that was caused by a dependency on file \a fd. - */ + */ void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd, FileDef *dstFd,bool inherited) { @@ -648,7 +647,7 @@ void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd, if (usedPair==0) // new file dependency { //printf(" => new file\n"); - usedDir->addFileDep(srcFd,dstFd); + usedDir->addFileDep(srcFd,dstFd); added=TRUE; } else @@ -660,7 +659,7 @@ void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd, { //printf(" => new file\n"); usedDir = new UsedDir(dir,inherited); - usedDir->addFileDep(srcFd,dstFd); + usedDir->addFileDep(srcFd,dstFd); m_usedDirs->insert(dir->getOutputFileBase(),usedDir); added=TRUE; } @@ -684,7 +683,7 @@ void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd, void DirDefImpl::computeDependencies() { FileList *fl = m_fileList; - if (fl) + if (fl) { QListIterator<FileDef> fli(*fl); FileDef *fd; @@ -695,7 +694,7 @@ void DirDefImpl::computeDependencies() QList<IncludeInfo> *ifl = fd->includeFileList(); if (ifl) { - QListIterator<IncludeInfo> ifli(*ifl); + QListIterator<IncludeInfo> ifli(*ifl); IncludeInfo *ii; for (ifli.toFirst();(ii=ifli.current());++ifli) // foreach include file { @@ -729,10 +728,10 @@ void DirDefImpl::computeDependencies() bool DirDefImpl::isParentOf(const DirDef *dir) const { - if (dir->parent()==this) // this is a parent of dir + if (dir->parent()==this) // this is a parent of dir return TRUE; else if (dir->parent()) // repeat for the parent of dir - return isParentOf(dir->parent()); + return isParentOf(dir->parent()); else return FALSE; } @@ -824,7 +823,7 @@ DirDef *DirDefImpl::mergeDirectoryInTree(const QCString &path) QCString part=path.left(i+1); if (!matchPath(part,Config_getList(STRIP_FROM_PATH)) && (part!="/" && part!="//")) { - dir=createNewDir(part); + dir=createNewDir(part); } p=i+1; } @@ -835,7 +834,7 @@ DirDef *DirDefImpl::mergeDirectoryInTree(const QCString &path) static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target) { - if (target->parent()!=root) + if (target->parent()!=root) { writePartialDirPath(ol,root,target->parent()); ol.writeString(" / "); @@ -912,7 +911,7 @@ void DirRelation::writeDocumentation(OutputList &ol) ol.writeString("</table>"); ol.endContents(); - + endFileWithNavPath(m_src,ol); ol.popGeneratorState(); @@ -935,10 +934,10 @@ static void computeCommonDirPrefix() sdi.toFirst(); dir=sdi.current(); path=dir->name(); - int i=path.findRev('/',path.length()-2); + int i=path.findRev('/',(int)path.length()-2); path=path.left(i+1); bool done=FALSE; - if (i==-1) + if (i==-1) { path=""; } @@ -946,8 +945,8 @@ static void computeCommonDirPrefix() { while (!done) { - int l = path.length(); - int count=0; + uint l = path.length(); + uint count=0; for (sdi.toFirst();(dir=sdi.current());++sdi) { QCString dirName = dir->name(); @@ -955,7 +954,7 @@ static void computeCommonDirPrefix() { if (qstrncmp(dirName,path,l)!=0) // dirName does not start with path { - int i=path.findRev('/',l-2); + i=path.findRev('/',(int)l-2); if (i==-1) // no unique prefix -> stop { path=""; @@ -972,7 +971,7 @@ static void computeCommonDirPrefix() { path=dir->name(); l=path.length(); - int i=path.findRev('/',l-2); + i=path.findRev('/',(int)l-2); if (i==-1) // no unique prefix -> stop { path=""; @@ -1005,13 +1004,9 @@ static void computeCommonDirPrefix() void buildDirectories() { // for each input file - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { //printf("buildDirectories %s\n",fd->name().data()); if (fd->getReference().isEmpty()) @@ -1021,7 +1016,7 @@ void buildDirectories() { dir = DirDefImpl::mergeDirectoryInTree(fd->getPath()); } - if (dir && !fd->isDocumentationFile()) dir->addFile(fd); + if (dir && !fd->isDocumentationFile()) dir->addFile(fd.get()); } else { @@ -1037,14 +1032,14 @@ void buildDirectories() for (sdi.toFirst();(dir=sdi.current());++sdi) { QCString name = dir->name(); - int i=name.findRev('/',name.length()-2); + int i=name.findRev('/',(int)name.length()-2); if (i>0) { DirDef *parent = Doxygen::directories->find(name.left(i+1)); //if (parent==0) parent=root; - if (parent) + if (parent) { - parent->addSubDir(dir); + parent->addSubDir(dir); //printf("DirDefImpl::addSubdir(): Adding subdir\n%s to\n%s\n", // dir->displayName().data(), parent->displayName().data()); } diff --git a/src/dirdef.h b/src/dirdef.h index 2ea54af..692cd90 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -97,7 +97,7 @@ class FilePair class FilePairDict : public SDict<FilePair> { public: - FilePairDict(int size) : SDict<FilePair>(size) {} + FilePairDict(uint size) : SDict<FilePair>(size) {} private: int compareValues(const FilePair *item1,const FilePair *item2) const; }; @@ -147,7 +147,7 @@ inline int DirList::compareValues(const DirDef *item1,const DirDef *item2) const class DirSDict : public SDict<DirDef> { public: - DirSDict(int size) : SDict<DirDef>(size) {} + DirSDict(uint size) : SDict<DirDef>(size) {} int compareValues(const DirDef *item1,const DirDef *item2) const { return qstricmp(item1->shortName(),item2->shortName()); diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index fff9728..53b2957 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -132,15 +132,13 @@ void writeDocbookLink(FTextStream &t,const char * /*extRef*/,const char *compoun t << "</link>"; } -DocbookCodeGenerator::DocbookCodeGenerator(FTextStream &t) : m_lineNumber(-1), m_col(0), - m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE) +DocbookCodeGenerator::DocbookCodeGenerator(FTextStream &t) { m_prettyCode=Config_getBool(DOCBOOK_PROGRAMLISTING); setTextStream(t); } -DocbookCodeGenerator::DocbookCodeGenerator() : m_lineNumber(-1), m_col(0), - m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE), m_streamSet(FALSE) +DocbookCodeGenerator::DocbookCodeGenerator() { m_prettyCode=Config_getBool(DOCBOOK_PROGRAMLISTING); } @@ -160,9 +158,9 @@ void DocbookCodeGenerator::writeCodeLink(const char *ref,const char *file, writeDocbookLink(m_t,ref,file,anchor,name,tooltip); m_col+=(int)strlen(name); } -void DocbookCodeGenerator::writeCodeLinkLine(const char *ref,const char *file, - const char *anchor,const char *name, - const char *tooltip) +void DocbookCodeGenerator::writeCodeLinkLine(const char *,const char *file, + const char *,const char *name, + const char *) { Docbook_DB(("(writeCodeLinkLine)\n")); m_t << "<anchor xml:id=\"_" << stripExtensionGeneral(stripPath(file),".xml"); @@ -274,8 +272,8 @@ DB_GEN_C m_descTable = FALSE; m_inLevel = -1; m_firstMember = FALSE; - for (int i = 0 ; i < sizeof(m_inListItem) / sizeof(*m_inListItem) ; i++) m_inListItem[i] = FALSE; - for (int i = 0 ; i < sizeof(m_inSimpleSect) / sizeof(*m_inSimpleSect) ; i++) m_inSimpleSect[i] = FALSE; + for (size_t i = 0 ; i < sizeof(m_inListItem) / sizeof(*m_inListItem) ; i++) m_inListItem[i] = FALSE; + for (size_t i = 0 ; i < sizeof(m_inSimpleSect) / sizeof(*m_inSimpleSect) ; i++) m_inSimpleSect[i] = FALSE; } DocbookGenerator::~DocbookGenerator() @@ -574,13 +572,9 @@ DB_GEN_C2("IndexSections " << is) { t << "</title>" << endl; bool isFirst=TRUE; - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - const FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isLinkableInProject()) { @@ -655,7 +649,8 @@ DB_GEN_C } } } -void DocbookGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) + +void DocbookGenerator::writeDoc(DocNode *n,const Definition *,const MemberDef *) { DB_GEN_C DocbookDocVisitor *visitor = @@ -680,7 +675,7 @@ void DocbookGenerator::writeString(const char *text) DB_GEN_C t << text; } -void DocbookGenerator::startMemberHeader(const char *name,int) +void DocbookGenerator::startMemberHeader(const char *,int) { DB_GEN_C t << "<simplesect>" << endl; @@ -698,7 +693,7 @@ void DocbookGenerator::docify(const char *str) DB_GEN_C t << convertToDocBook(str); } -void DocbookGenerator::writeObjectLink(const char *ref, const char *f, +void DocbookGenerator::writeObjectLink(const char *, const char *f, const char *anchor, const char *text) { DB_GEN_C @@ -813,7 +808,7 @@ DB_GEN_C t << "<programlisting>"; } } -void DocbookGenerator::endTextBlock(bool dense) +void DocbookGenerator::endTextBlock(bool) { DB_GEN_C if (m_denseText) @@ -822,8 +817,8 @@ DB_GEN_C t << "</programlisting>"; } } -void DocbookGenerator::startMemberDoc(const char *clname, const char *memname, const char *anchor, const char *title, - int memCount, int memTotal, bool showInline) +void DocbookGenerator::startMemberDoc(const char *clname, const char *memname, const char *, const char *title, + int memCount, int memTotal, bool) { DB_GEN_C2("m_inLevel " << m_inLevel) t << " <section>" << endl; @@ -849,15 +844,15 @@ void DocbookGenerator::startTitleHead(const char *) DB_GEN_C t << "<title>"; } -void DocbookGenerator::endTitleHead(const char *fileName,const char *name) +void DocbookGenerator::endTitleHead(const char *,const char *name) { DB_GEN_C t << "</title>" << endl; if (name) addIndexTerm(t, name); } -void DocbookGenerator::startDoxyAnchor(const char *fName,const char *manName, - const char *anchor,const char *name, - const char *args) +void DocbookGenerator::startDoxyAnchor(const char *fName,const char *, + const char *anchor,const char *, + const char *) { DB_GEN_C if (!m_inListItem[m_levelListItem] && !m_descTable) @@ -870,7 +865,7 @@ DB_GEN_C t << "<anchor xml:id=\"_" << stripPath(fName) << "_1" << anchor << "\"/>"; } } -void DocbookGenerator::endDoxyAnchor(const char *fileName,const char *anchor) +void DocbookGenerator::endDoxyAnchor(const char *,const char *) { DB_GEN_C } @@ -883,7 +878,7 @@ void DocbookGenerator::endMemberDocName() { DB_GEN_C } -void DocbookGenerator::startMemberGroupHeader(bool hasHeader) +void DocbookGenerator::startMemberGroupHeader(bool) { DB_GEN_C t << "<simplesect><title>"; @@ -914,7 +909,7 @@ DB_GEN_C t << " <informalfigure>" << endl; t << " <mediaobject>" << endl; t << " <imageobject>" << endl; - t << " <imagedata width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" + t << " <imagedata width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << fileName << ".png\">" << "</imagedata>" << endl; t << " </imageobject>" << endl; d.writeImage(t,m_dir,relPath,fileName,FALSE); @@ -1025,13 +1020,13 @@ DB_GEN_C t << "</para>"; t << "<para>"; } -void DocbookGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) +void DocbookGenerator::startSection(const char *lab,const char *,SectionType) { DB_GEN_C t << " <section xml:id=\"_" << stripPath(lab) << "\">"; t << "<title>"; } -void DocbookGenerator::endSection(const char *lab,SectionInfo::SectionType) +void DocbookGenerator::endSection(const char *,SectionType) { DB_GEN_C t << "</title>"; diff --git a/src/docbookgen.h b/src/docbookgen.h index 64e9e67..bed2f5f 100644 --- a/src/docbookgen.h +++ b/src/docbookgen.h @@ -57,16 +57,16 @@ class DocbookCodeGenerator : public CodeOutputInterface private: FTextStream m_t; - bool m_streamSet; + bool m_streamSet = FALSE; QCString m_refId; QCString m_external; - int m_lineNumber; - int m_col; - bool m_insideCodeLine; - bool m_insideSpecialHL; + int m_lineNumber = -1; + int m_col = 0; + bool m_insideCodeLine = FALSE; + bool m_insideSpecialHL = FALSE; QCString m_relPath; QCString m_sourceFileName; - bool m_prettyCode; + bool m_prettyCode = FALSE; }; @@ -145,14 +145,14 @@ class DocbookGenerator : public OutputGenerator void startFile(const char *name,const char *manName, const char *title); void writeSearchInfo(){DB_GEN_EMPTY}; - void writeFooter(const char *navPath){DB_GEN_NEW}; + void writeFooter(const char *){DB_GEN_NEW}; void endFile(); void startIndexSection(IndexSections); void endIndexSection(IndexSections); void writePageLink(const char *,bool); void startProjectNumber(){DB_GEN_NEW}; void endProjectNumber(){DB_GEN_NEW}; - void writeStyleInfo(int part){DB_GEN_EMPTY}; + void writeStyleInfo(int){DB_GEN_EMPTY}; void startTitleHead(const char *); void endTitleHead(const char *fileName,const char *name); void startIndexListItem(){DB_GEN_NEW}; @@ -166,8 +166,8 @@ class DocbookGenerator : public OutputGenerator void startItemList() {DB_GEN_EMPTY}; void endItemList() {DB_GEN_EMPTY}; - void startIndexItem(const char *ref,const char *file){DB_GEN_NEW}; - void endIndexItem(const char *ref,const char *file){DB_GEN_NEW}; + void startIndexItem(const char *,const char *){DB_GEN_NEW}; + void endIndexItem(const char *,const char *){DB_GEN_NEW}; void startItemListItem() {DB_GEN_EMPTY}; void endItemListItem() {DB_GEN_EMPTY}; void docify(const char *text); @@ -204,8 +204,8 @@ class DocbookGenerator : public OutputGenerator void startTitle(void){DB_GEN_NEW}; void endTitle(void){DB_GEN_NEW}; void writeAnchor(const char *,const char *){DB_GEN_EMPTY}; - void startSection(const char *,const char *,SectionInfo::SectionType); - void endSection(const char *,SectionInfo::SectionType); + void startSection(const char *,const char *,SectionType); + void endSection(const char *,SectionType); void lineBreak(const char *); void addIndexItem(const char *,const char *); void writeNonBreakableSpace(int); @@ -258,23 +258,23 @@ class DocbookGenerator : public OutputGenerator void insertMemberAlign(bool){DB_GEN_EMPTY}; void insertMemberAlignLeft(int,bool){DB_GEN_EMPTY}; void startMemberDoc(const char *,const char *, - const char *,const char *,int,int,bool); + const char *,const char *,int,int,bool); void endMemberDoc(bool); void startDoxyAnchor(const char *fName,const char *manName, - const char *anchor,const char *name, - const char *args); + const char *anchor,const char *name, + const char *args); void endDoxyAnchor(const char *fileName,const char *anchor); void writeLatexSpacing(){DB_GEN_EMPTY} - void writeStartAnnoItem(const char *type,const char *file, - const char *path,const char *name){DB_GEN_NEW}; - void writeEndAnnoItem(const char *name){DB_GEN_NEW}; - void startMemberDescription(const char *anchor,const char *inheritId, bool typ){DB_GEN_EMPTY}; + void writeStartAnnoItem(const char *,const char *, + const char *,const char *){DB_GEN_NEW}; + void writeEndAnnoItem(const char *){DB_GEN_NEW}; + void startMemberDescription(const char *,const char *,bool){DB_GEN_EMPTY}; void endMemberDescription(){DB_GEN_EMPTY}; void startMemberDeclaration(){DB_GEN_EMPTY}; - void endMemberDeclaration(const char *anchor,const char *inheritId){DB_GEN_EMPTY}; - void writeInheritedSectionTitle(const char *id,const char *ref, - const char *file,const char *anchor, - const char *title,const char *name){DB_GEN_NEW}; + void endMemberDeclaration(const char *,const char *){DB_GEN_EMPTY}; + void writeInheritedSectionTitle(const char *,const char *, + const char *,const char *, + const char *,const char *){DB_GEN_NEW}; void startIndent(){DB_GEN_EMPTY}; void endIndent(){DB_GEN_EMPTY}; void writeSynopsis(){DB_GEN_EMPTY}; @@ -290,17 +290,17 @@ class DocbookGenerator : public OutputGenerator void endCallGraph(DotCallGraph &g); void startDirDepGraph(); void endDirDepGraph(DotDirDeps &g); - void writeGraphicalHierarchy(DotGfxHierarchyTable &g){DB_GEN_NEW}; + void writeGraphicalHierarchy(DotGfxHierarchyTable &){DB_GEN_NEW}; void startQuickIndices(){DB_GEN_EMPTY}; void endQuickIndices(){DB_GEN_EMPTY}; void writeSplitBar(const char *){DB_GEN_EMPTY}; void writeNavigationPath(const char *){DB_GEN_NEW}; void writeLogo(){DB_GEN_NEW}; - void writeQuickLinks(bool compact,HighlightedItem hli,const char *file){DB_GEN_EMPTY}; - void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first){DB_GEN_EMPTY}; + void writeQuickLinks(bool,HighlightedItem,const char *){DB_GEN_EMPTY}; + void writeSummaryLink(const char *,const char *,const char *,bool){DB_GEN_EMPTY}; void startContents(){DB_GEN_EMPTY}; void endContents(){DB_GEN_EMPTY}; - void startPageDoc(const char *pageTitle){DB_GEN_EMPTY} + void startPageDoc(const char *){DB_GEN_EMPTY} void endPageDoc() {DB_GEN_EMPTY} void startTextBlock(bool); void endTextBlock(bool); @@ -309,7 +309,7 @@ class DocbookGenerator : public OutputGenerator void endMemberDocPrefixItem(); void startMemberDocName(bool); void endMemberDocName(); - void startParameterType(bool,const char *key){DB_GEN_EMPTY}; + void startParameterType(bool,const char *){DB_GEN_EMPTY}; void endParameterType(){DB_GEN_EMPTY}; void startParameterName(bool); void endParameterName(bool,bool,bool); diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index 9de0a16..78af6e0 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -1,9 +1,6 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -16,6 +13,7 @@ * */ + #include <qfileinfo.h> #include "docbookvisitor.h" @@ -55,7 +53,7 @@ static QCString filterId(const char *s) static GrowBuf growBuf; growBuf.clear(); if (s==0) return ""; - const unsigned char *p=(const unsigned char *)s; + const char *p=s; char c; while ((c=*p++)) { @@ -69,6 +67,23 @@ static QCString filterId(const char *s) return growBuf.get(); } +static bool supportedHtmlAttribute(const QCString &name) +{ + return (name=="align" || + name=="bgcolor" || + name=="border" || + name=="cellpadding" || + name=="cellspacing" || + name=="class" || + name=="frame" || + name=="label" || + name=="style" || + name=="width" || + name=="tabstyle" || + name=="title"); +} + + void DocbookDocVisitor::visitCaption(const QList<DocNode> &children) { QListIterator<DocNode> cli(children); @@ -138,7 +153,7 @@ void DocbookDocVisitor::visitPostEnd(FTextStream &t, bool hasCaption, bool inlin } DocbookDocVisitor::DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci) - : DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) + : DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci) { DB_VIS_C // m_t << "<section>" << endl; @@ -311,17 +326,17 @@ DB_VIS_C filter(s->text()); m_t << "</computeroutput></literallayout>"; break; - case DocVerbatim::HtmlOnly: + case DocVerbatim::HtmlOnly: break; - case DocVerbatim::RtfOnly: + case DocVerbatim::RtfOnly: break; - case DocVerbatim::ManOnly: + case DocVerbatim::ManOnly: break; - case DocVerbatim::LatexOnly: + case DocVerbatim::LatexOnly: break; - case DocVerbatim::XmlOnly: + case DocVerbatim::XmlOnly: break; - case DocVerbatim::DocbookOnly: + case DocVerbatim::DocbookOnly: m_t << s->text(); break; case DocVerbatim::Dot: @@ -381,7 +396,7 @@ DB_VIS_C int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right(shortName.length()-i-1); + shortName=shortName.right((int)shortName.length()-i-1); } m_t << "<para>" << endl; writePlantUMLFile(baseName,s); @@ -434,6 +449,12 @@ DB_VIS_C case DocInclude::DontIncWithLines: case DocInclude::HtmlInclude: case DocInclude::LatexInclude: + case DocInclude::RtfInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + break; + case DocInclude::DocbookInclude: + m_t << inc->text(); break; case DocInclude::VerbInclude: m_t << "<literallayout>"; @@ -463,7 +484,7 @@ DB_VIS_C extractBlock(inc->text(),inc->blockId()), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine @@ -475,8 +496,8 @@ DB_VIS_C m_t << "</computeroutput></literallayout>"; } break; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" "Please create a bug report\n",__FILE__); break; @@ -657,152 +678,152 @@ DB_VIS_C switch(s->type()) { case DocSimpleSect::See: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trSeeAlso() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSeeAlso()) << "</title>" << endl; } break; case DocSimpleSect::Return: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trReturns()<< "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trReturns()) << "</title>" << endl; } break; case DocSimpleSect::Author: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, TRUE) << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, TRUE)) << "</title>" << endl; } break; case DocSimpleSect::Authors: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, FALSE) << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, FALSE)) << "</title>" << endl; } break; case DocSimpleSect::Version: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trVersion() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trVersion()) << "</title>" << endl; } break; case DocSimpleSect::Since: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trSince() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSince()) << "</title>" << endl; } break; case DocSimpleSect::Date: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trDate() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trDate()) << "</title>" << endl; } break; case DocSimpleSect::Note: - if (m_insidePre) + if (m_insidePre) { m_t << "<note><title>" << theTranslator->trNote() << "</title>" << endl; - } - else + } + else { m_t << "<note><title>" << convertToDocBook(theTranslator->trNote()) << "</title>" << endl; } break; case DocSimpleSect::Warning: - if (m_insidePre) + if (m_insidePre) { m_t << "<warning><title>" << theTranslator->trWarning() << "</title>" << endl; - } - else + } + else { m_t << "<warning><title>" << convertToDocBook(theTranslator->trWarning()) << "</title>" << endl; } break; case DocSimpleSect::Pre: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trPrecondition() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPrecondition()) << "</title>" << endl; } break; case DocSimpleSect::Post: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trPostcondition() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPostcondition()) << "</title>" << endl; } break; case DocSimpleSect::Copyright: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trCopyright() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trCopyright()) << "</title>" << endl; } break; case DocSimpleSect::Invar: - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trInvariant() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trInvariant()) << "</title>" << endl; } break; case DocSimpleSect::Remark: // <remark> is miising the <title> possibility - if (m_insidePre) + if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trRemarks() << "</title>" << endl; - } - else + } + else { m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trRemarks()) << "</title>" << endl; } break; case DocSimpleSect::Attention: - if (m_insidePre) + if (m_insidePre) { m_t << "<caution><title>" << theTranslator->trAttention() << "</title>" << endl; - } - else + } + else { m_t << "<caution><title>" << convertToDocBook(theTranslator->trAttention()) << "</title>" << endl; } @@ -983,12 +1004,10 @@ DB_VIS_C m_t << "</listitem></varlistentry>\n"; } -static int colCnt = 0; -static bool bodySet = FALSE; // it is possible to have tables without a header void DocbookDocVisitor::visitPre(DocHtmlTable *t) { DB_VIS_C - bodySet = FALSE; + m_bodySet.push(false); if (m_hide) return; m_t << "<informaltable frame=\"all\">" << endl; m_t << " <tgroup cols=\"" << t->numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl; @@ -1003,8 +1022,8 @@ void DocbookDocVisitor::visitPost(DocHtmlTable *) { DB_VIS_C if (m_hide) return; - if (bodySet) m_t << " </tbody>" << endl; - bodySet = FALSE; + if (m_bodySet.top()) m_t << " </tbody>" << endl; + m_bodySet.pop(); m_t << " </tgroup>" << endl; m_t << "</informaltable>" << endl; } @@ -1012,13 +1031,18 @@ DB_VIS_C void DocbookDocVisitor::visitPre(DocHtmlRow *tr) { DB_VIS_C - colCnt = 0; + m_colCnt = 0; if (m_hide) return; - if (tr->isHeading()) m_t << "<thead>\n"; - else if (!bodySet) + if (tr->isHeading()) { - bodySet = TRUE; + if (m_bodySet.top()) m_t << "</tbody>\n"; + m_bodySet.top() = false; + m_t << "<thead>\n"; + } + else if (!m_bodySet.top()) + { + m_bodySet.top() = true; m_t << "<tbody>\n"; } @@ -1028,25 +1052,10 @@ DB_VIS_C HtmlAttrib *opt; for (li.toFirst();(opt=li.current());++li) { - if (opt->name=="class") - { - // just skip it - } - else if (opt->name=="style") - { - // just skip it - } - else if (opt->name=="height") - { - // just skip it - } - else if (opt->name=="filter") + if (supportedHtmlAttribute(opt->name)) { - // just skip it - } - else - { - m_t << " " << opt->name << "='" << opt->value << "'"; + // process supported attributes only + m_t << " " << opt->name << "='" << convertToDocBook(opt->value) << "'"; } } m_t << ">\n"; @@ -1059,15 +1068,15 @@ DB_VIS_C m_t << "</row>\n"; if (tr->isHeading()) { - bodySet = TRUE; m_t << "</thead><tbody>\n"; + m_bodySet.top() = true; } } void DocbookDocVisitor::visitPre(DocHtmlCell *c) { DB_VIS_C - colCnt++; + m_colCnt++; if (m_hide) return; m_t << "<entry"; @@ -1077,10 +1086,10 @@ DB_VIS_C { if (opt->name=="colspan") { - m_t << " namest='c" << colCnt << "'"; + m_t << " namest='c" << m_colCnt << "'"; int cols = opt->value.toInt(); - colCnt += (cols - 1); - m_t << " nameend='c" << colCnt << "'"; + m_colCnt += (cols - 1); + m_t << " nameend='c" << m_colCnt << "'"; } else if (opt->name=="rowspan") { @@ -1089,63 +1098,44 @@ DB_VIS_C } else if (opt->name=="class") { - if (opt->value == "markdownTableBodyRight") + if (opt->value.left(13)=="markdownTable") // handle markdown generated attributes { - m_t << " align='right'"; - } - else if (opt->value == "markdownTableBodyLeftt") - { - m_t << " align='left'"; - } - else if (opt->value == "markdownTableBodyCenter") - { - m_t << " align='center'"; - } - else if (opt->value == "markdownTableHeadRight") - { - m_t << " align='right'"; - } - else if (opt->value == "markdownTableHeadLeftt") - { - m_t << " align='left'"; + if (opt->value.right(5)=="Right") + { + m_t << " align='right'"; + } + else if (opt->value.right(4)=="Left") + { + m_t << " align='left'"; + } + else if (opt->value.right(6)=="Center") + { + m_t << " align='center'"; + } + // skip 'markdownTable*' value ending with "None" } - else if (opt->value == "markdownTableHeadCenter") + else { - m_t << " align='center'"; + m_t << " class='" << convertToDocBook(opt->value) << "'"; } } - else if (opt->name=="style") - { - // just skip it - } - else if (opt->name=="width") - { - // just skip it - } - else if (opt->name=="height") - { - // just skip it - } - else if (opt->name=="nowrap" && opt->value.isEmpty()) + else if (supportedHtmlAttribute(opt->name)) { - m_t << " " << opt->name << "='nowrap'"; - } - else - { - m_t << " " << opt->name << "='" << opt->value << "'"; + // process supported attributes only + m_t << " " << opt->name << "='" << convertToDocBook(opt->value) << "'"; } } m_t << ">"; } -void DocbookDocVisitor::visitPost(DocHtmlCell *c) +void DocbookDocVisitor::visitPost(DocHtmlCell *) { DB_VIS_C if (m_hide) return; m_t << "</entry>"; } -void DocbookDocVisitor::visitPre(DocHtmlCaption *c) +void DocbookDocVisitor::visitPre(DocHtmlCaption *) { DB_VIS_C if (m_hide) return; @@ -1212,7 +1202,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) { - baseName=baseName.right(baseName.length()-i-1); + baseName=baseName.right((int)baseName.length()-i-1); } visitPreStart(m_t, img->children(), img->hasCaption(), img->relPath() + baseName, img->width(), img->height(), img->isInlineImage()); } @@ -1235,12 +1225,12 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) { - baseName=baseName.right(baseName.length()-i-1); + baseName=baseName.right((int)baseName.length()-i-1); } QCString m_file; bool ambig; - FileDef *fd=findFileDef(Doxygen::imageNameDict, baseName, ambig); - if (fd) + FileDef *fd=findFileDef(Doxygen::imageNameLinkedMap, baseName, ambig); + if (fd) { m_file=fd->absFilePath(); } @@ -1257,8 +1247,8 @@ DB_VIS_C delete[] buffer; } } - } - else + } + else { popEnabled(); } @@ -1342,7 +1332,7 @@ DB_VIS_C if (!ref->file().isEmpty()) endLink(); } -void DocbookDocVisitor::visitPre(DocSecRefItem *ref) +void DocbookDocVisitor::visitPre(DocSecRefItem *) { DB_VIS_C if (m_hide) return; @@ -1425,11 +1415,9 @@ DB_VIS_C if (m_hide) return; m_t << " <row>" << endl; - DocParamSect::Type parentType = DocParamSect::Unknown; DocParamSect *sect = 0; if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) { - parentType = ((DocParamSect*)pl->parent())->type(); sect=(DocParamSect*)pl->parent(); } @@ -1632,16 +1620,14 @@ DB_VIS_C void DocbookDocVisitor::pushEnabled() { DB_VIS_C - m_enabled.push(new bool(m_hide)); + m_enabled.push(m_hide); } void DocbookDocVisitor::popEnabled() { DB_VIS_C - bool *v=m_enabled.pop(); - ASSERT(v!=0); - m_hide = *v; - delete v; + m_hide=m_enabled.top(); + m_enabled.pop(); } void DocbookDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s) @@ -1651,7 +1637,7 @@ DB_VIS_C int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right(shortName.length()-i-1); + shortName=shortName.right((int)shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_BITMAP); @@ -1667,7 +1653,7 @@ DB_VIS_C int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right(shortName.length()-i-1); + shortName=shortName.right((int)shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); PlantumlManager::instance()->generatePlantUMLOutput(baseName,outDir,PlantumlManager::PUML_BITMAP); @@ -1688,7 +1674,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1) { - baseName=baseName.right(baseName.length()-i-1); + baseName=baseName.right((int)baseName.length()-i-1); } if ((i=baseName.find('.'))!=-1) { @@ -1716,7 +1702,7 @@ DB_VIS_C int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right(shortName.length()-i-1); + shortName=shortName.right((int)shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_BITMAP); @@ -1737,7 +1723,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1) { - baseName=baseName.right(baseName.length()-i-1); + baseName=baseName.right((int)baseName.length()-i-1); } if ((i=baseName.find('.'))!=-1) { @@ -1765,7 +1751,7 @@ DB_VIS_C int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right(shortName.length()-i-1); + shortName=shortName.right((int)shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeDotGraphFromFile(baseName+".dot",outDir,shortName,GOF_BITMAP); @@ -1786,7 +1772,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1) { - baseName=baseName.right(baseName.length()-i-1); + baseName=baseName.right((int)baseName.length()-i-1); } if ((i=baseName.find('.'))!=-1) { diff --git a/src/docbookvisitor.h b/src/docbookvisitor.h index 47275f7..a338bbf 100644 --- a/src/docbookvisitor.h +++ b/src/docbookvisitor.h @@ -1,8 +1,6 @@ /****************************************************************************** * -* -* -* Copyright (C) 1997-2015 by Dimitri van Heesch. +* Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -18,6 +16,8 @@ #ifndef _DOCBOOKDOCVISITOR_H #define _DOCBOOKDOCVISITOR_H +#include <stack> + #include "docvisitor.h" #include <qstack.h> #include <qlist.h> @@ -173,10 +173,12 @@ class DocbookDocVisitor : public DocVisitor //-------------------------------------- FTextStream &m_t; CodeOutputInterface &m_ci; - bool m_insidePre; - bool m_hide; - QStack<bool> m_enabled; + bool m_insidePre = false; + bool m_hide = false; + std::stack<bool> m_enabled; QCString m_langExt; + int m_colCnt = 0; + std::stack<bool> m_bodySet; // it is possible to have tables without a header, needs to be an array as we can have tables in tables }; #endif diff --git a/src/docgroup.cpp b/src/docgroup.cpp index fbdb842..d82d1b3 100644 --- a/src/docgroup.cpp +++ b/src/docgroup.cpp @@ -13,12 +13,14 @@ * */ +#include <atomic> #include "doxygen.h" #include "util.h" #include "entry.h" #include "message.h" #include "docgroup.h" +static std::atomic_int g_groupId; void DocGroup::enterFile(const char *fileName,int) { @@ -84,7 +86,7 @@ void DocGroup::leaveCompound(const char *,int,const char * /*name*/) m_compoundName.resize(0); } -int DocGroup::findExistingGroup(int &groupId,const MemberGroupInfo *info) +int DocGroup::findExistingGroup(const MemberGroupInfo *info) { //printf("findExistingGroup %s:%s\n",info->header.data(),info->compoundName.data()); QIntDictIterator<MemberGroupInfo> di(Doxygen::memGrpInfoDict); @@ -100,8 +102,7 @@ int DocGroup::findExistingGroup(int &groupId,const MemberGroupInfo *info) return (int)di.currentKey(); // put the item in this group } } - groupId++; // start new group - return groupId; + return ++g_groupId; // start new group } void DocGroup::open(Entry *e,const char *,int, bool implicit) @@ -118,12 +119,10 @@ void DocGroup::open(Entry *e,const char *,int, bool implicit) //printf(" membergroup id=%d %s\n",m_memberGroupId,m_memberGroupHeader.data()); if (m_memberGroupId==DOX_NOGROUP) // no group started yet { - static int curGroupId=0; - MemberGroupInfo *info = new MemberGroupInfo; info->header = m_memberGroupHeader.stripWhiteSpace(); info->compoundName = m_compoundName; - m_memberGroupId = findExistingGroup(curGroupId,info); + m_memberGroupId = findExistingGroup(info); //printf(" use membergroup %d\n",m_memberGroupId); Doxygen::memGrpInfoDict.insert(m_memberGroupId,info); diff --git a/src/docgroup.h b/src/docgroup.h index 3ccef0d..c724348 100644 --- a/src/docgroup.h +++ b/src/docgroup.h @@ -41,7 +41,7 @@ class DocGroup void addDocs(Entry *e); private: - int findExistingGroup(int &groupId,const MemberGroupInfo *info); + int findExistingGroup(const MemberGroupInfo *info); int m_openCount = 0; QCString m_memberGroupHeader; int m_memberGroupId = 0; diff --git a/src/docparser.cpp b/src/docparser.cpp index 5498adb..029dc3f 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1,13 +1,13 @@ /****************************************************************************** * - * + * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -70,11 +70,11 @@ //#define DBG(x) myprintf x #define INTERNAL_ASSERT(x) do {} while(0) -//#define INTERNAL_ASSERT(x) if (!(x)) DBG(("INTERNAL_ASSERT(%s) failed retval=0x%x: file=%s line=%d\n",#x,retval,__FILE__,__LINE__)); +//#define INTERNAL_ASSERT(x) if (!(x)) DBG(("INTERNAL_ASSERT(%s) failed retval=0x%x: file=%s line=%d\n",#x,retval,__FILE__,__LINE__)); //--------------------------------------------------------------------------- -static const char *sectionLevelToName[] = +static const char *sectionLevelToName[] = { "page", "section", @@ -106,18 +106,17 @@ static QDict<void> g_paramsFound; static const MemberDef * g_memberDef; static bool g_isExample; static QCString g_exampleName; -static SectionDict * g_sectionDict; static QCString g_searchUrl; static QCString g_includeFileName; static QCString g_includeFileText; static uint g_includeFileOffset; static uint g_includeFileLength; -static uint g_includeFileLine; +static int g_includeFileLine; static bool g_includeFileShowLineNo; -/** Parser's context to store all global variables. +/** Parser's context to store all global variables. */ struct DocParserContext { @@ -141,13 +140,12 @@ struct DocParserContext QDict<void> paramsFound; bool isExample; QCString exampleName; - SectionDict *sectionDict; QCString searchUrl; QCString includeFileText; uint includeFileOffset; uint includeFileLength; - uint includeFileLine; + int includeFileLine; bool includeFileLineNo; TokenInfo *token; @@ -191,7 +189,6 @@ static void docParserPushContext(bool saveParamInfo=TRUE) ctx->memberDef = g_memberDef; ctx->isExample = g_isExample; ctx->exampleName = g_exampleName; - ctx->sectionDict = g_sectionDict; ctx->searchUrl = g_searchUrl; ctx->includeFileText = g_includeFileText; @@ -199,7 +196,7 @@ static void docParserPushContext(bool saveParamInfo=TRUE) ctx->includeFileLength = g_includeFileLength; ctx->includeFileLine = g_includeFileLine; ctx->includeFileLineNo = g_includeFileShowLineNo; - + ctx->token = g_token; g_token = new TokenInfo; @@ -232,7 +229,6 @@ static void docParserPopContext(bool keepParamInfo=FALSE) g_memberDef = ctx->memberDef; g_isExample = ctx->isExample; g_exampleName = ctx->exampleName; - g_sectionDict = ctx->sectionDict; g_searchUrl = ctx->searchUrl; g_includeFileText = ctx->includeFileText; @@ -285,7 +281,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool { QCString result; bool ambig; - FileDef *fd = findFileDef(Doxygen::imageNameDict,fileName,ambig); + FileDef *fd = findFileDef(Doxygen::imageNameLinkedMap,fileName,ambig); //printf("Search for %s\n",fileName); if (fd) { @@ -294,8 +290,8 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool QCString text; text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName)); text+="Possible candidates:\n"; - text+=showFileDefMatches(Doxygen::imageNameDict,fileName); - warn_doc_error(g_fileName,doctokenizerYYlineno,text); + text+=showFileDefMatches(Doxygen::imageNameLinkedMap,fileName); + warn_doc_error(g_fileName,doctokenizerYYlineno,"%s", text.data()); } QCString inputFile = fd->absFilePath(); @@ -306,7 +302,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool int i; if ((i=result.findRev('/'))!=-1 || (i=result.findRev('\\'))!=-1) { - result = result.right(result.length()-i-1); + result = result.right((int)result.length()-i-1); } //printf("fileName=%s result=%s\n",fileName,result.data()); QCString outputDir; @@ -368,7 +364,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool "could not open image %s",qPrint(fileName)); } - if (type==DocImage::Latex && Config_getBool(USE_PDFLATEX) && + if (type==DocImage::Latex && Config_getBool(USE_PDFLATEX) && fd->name().right(4)==".eps" ) { // we have an .eps image in pdflatex mode => convert it to a pdf. @@ -393,7 +389,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool if (result.left(5)!="http:" && result.left(6)!="https:" && dowarn) { warn_doc_error(g_fileName,doctokenizerYYlineno, - "image file %s is not found in IMAGE_PATH: " + "image file %s is not found in IMAGE_PATH: " "assuming external image.",qPrint(fileName) ); } @@ -408,7 +404,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool * are disabled altogether). */ static void checkArgumentName(const QCString &name) -{ +{ if (!Config_getBool(WARN_IF_DOC_ERROR)) return; if (g_memberDef==0) return; // not a member const ArgumentList &al=g_memberDef->isDocsForDefinition() ? @@ -478,9 +474,10 @@ static void checkRetvalName(const QCString &name) { warn_doc_error(g_memberDef->getDefFileName(), g_memberDef->getDefLine(), - "return value '" + name + "' of " + + "%s", + ("return value '" + name + "' of " + QCString(g_memberDef->qualifiedName()) + - " has multiple documentation sections"); + " has multiple documentation sections").data()); } g_retvalsFound.insert(name,(void *)(0x8)); } @@ -514,7 +511,7 @@ static void checkUnOrMultipleDocumentedParams() { // allow undocumented self / cls parameter for Python } - else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a.docs.isEmpty()) + else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a.docs.isEmpty()) { notArgCnt++; } @@ -531,10 +528,11 @@ static void checkUnOrMultipleDocumentedParams() { warn_doc_error(g_memberDef->getDefFileName(), g_memberDef->getDefLine(), - "argument '" + aName + + "%s", + ("argument '" + aName + "' from the argument list of " + QCString(g_memberDef->qualifiedName()) + - " has multiple @param documentation sections"); + " has multiple @param documentation sections").data()); } } if (notArgCnt>0) @@ -544,7 +542,7 @@ static void checkUnOrMultipleDocumentedParams() "The following parameter"; errMsg+= (notArgCnt>1 ? "s" : ""); errMsg+=" of "+ - QCString(g_memberDef->qualifiedName()) + + QCString(g_memberDef->qualifiedName()) + QCString(argListToString(al)) + (notArgCnt>1 ? " are" : " is") + " not documented:\n"; for (const Argument &a : al) @@ -571,7 +569,8 @@ static void checkUnOrMultipleDocumentedParams() } warn_doc_error(g_memberDef->getDefFileName(), g_memberDef->getDefLine(), - substitute(errMsg,"%","%%")); + "%s", + substitute(errMsg,"%","%%").data()); } } } @@ -588,7 +587,7 @@ static QCString stripKnownExtensions(const char *text) result=result.left(result.length()-4); } else if (result.right(Doxygen::htmlFileExtension.length())== - QCString(Doxygen::htmlFileExtension)) + QCString(Doxygen::htmlFileExtension)) { result=result.left(result.length()-Doxygen::htmlFileExtension.length()); } @@ -629,7 +628,7 @@ static bool insideUL(DocNode *n) { while (n) { - if (n->kind()==DocNode::Kind_HtmlList && + if (n->kind()==DocNode::Kind_HtmlList && ((DocHtmlList *)n)->type()==DocHtmlList::Unordered) return TRUE; n=n->parent(); } @@ -643,7 +642,7 @@ static bool insideOL(DocNode *n) { while (n) { - if (n->kind()==DocNode::Kind_HtmlList && + if (n->kind()==DocNode::Kind_HtmlList && ((DocHtmlList *)n)->type()==DocHtmlList::Ordered) return TRUE; n=n->parent(); } @@ -663,7 +662,6 @@ static bool insideTable(DocNode *n) } //--------------------------------------------------------------------------- - /*! Looks for a documentation block with name commandName in the current * context (g_context). The resulting documentation string is * put in pDoc, the definition in which the documentation was found is @@ -680,14 +678,47 @@ static bool findDocsForMemberOrCompound(const char *commandName, *pDoc=""; *pBrief=""; *pDef=0; - QCString cmdArg=substitute(commandName,"#","::"); - cmdArg = replaceScopeSeparator(cmdArg); + QCString cmdArg=commandName; + if (cmdArg.isEmpty()) return FALSE; + + const FileDef *fd=0; + const GroupDef *gd=0; + const PageDef *pd=0; + gd = Doxygen::groupSDict->find(cmdArg); + if (gd) // group + { + *pDoc=gd->documentation(); + *pBrief=gd->briefDescription(); + *pDef=gd; + return TRUE; + } + pd = Doxygen::pageSDict->find(cmdArg); + if (pd) // page + { + *pDoc=pd->documentation(); + *pBrief=pd->briefDescription(); + *pDef=pd; + return TRUE; + } + bool ambig; + fd = findFileDef(Doxygen::inputNameLinkedMap,cmdArg,ambig); + if (fd && !ambig) // file + { + *pDoc=fd->documentation(); + *pBrief=fd->briefDescription(); + *pDef=fd; + return TRUE; + } + + // for symbols we need to normalize the separator, so A#B, or A\B, or A.B becomes A::B + cmdArg = substitute(cmdArg,"#","::"); + cmdArg = substitute(cmdArg,"\\","::"); + cmdArg = substitute(cmdArg,".","::"); - int l=cmdArg.length(); - if (l==0) return FALSE; + int l=(int)cmdArg.length(); int funcStart=cmdArg.find('('); - if (funcStart==-1) + if (funcStart==-1) { funcStart=l; } @@ -697,9 +728,9 @@ static bool findDocsForMemberOrCompound(const char *commandName, // beware of scenarios like operator()((foo)bar) int secondParen = cmdArg.find('(', funcStart+1); int leftParen = cmdArg.find(')', funcStart+1); - if (leftParen!=-1 && secondParen!=-1) + if (leftParen!=-1 && secondParen!=-1) { - if (leftParen<secondParen) + if (leftParen<secondParen) { funcStart=secondParen; } @@ -711,10 +742,7 @@ static bool findDocsForMemberOrCompound(const char *commandName, // try if the link is to a member const MemberDef *md=0; const ClassDef *cd=0; - const FileDef *fd=0; const NamespaceDef *nd=0; - const GroupDef *gd=0; - const PageDef *pd=0; bool found = getDefs( g_context.find('.')==-1?g_context.data():"", // find('.') is a hack to detect files name, @@ -730,7 +758,7 @@ static bool findDocsForMemberOrCompound(const char *commandName, } - int scopeOffset=g_context.length(); + int scopeOffset=(int)g_context.length(); do // for each scope { QCString fullName=cmdArg; @@ -742,7 +770,7 @@ static bool findDocsForMemberOrCompound(const char *commandName, // try class, namespace, group, page, file reference cd = Doxygen::classSDict->find(fullName); - if (cd) // class + if (cd) // class { *pDoc=cd->documentation(); *pBrief=cd->briefDescription(); @@ -757,32 +785,6 @@ static bool findDocsForMemberOrCompound(const char *commandName, *pDef=nd; return TRUE; } - gd = Doxygen::groupSDict->find(cmdArg); - if (gd) // group - { - *pDoc=gd->documentation(); - *pBrief=gd->briefDescription(); - *pDef=gd; - return TRUE; - } - pd = Doxygen::pageSDict->find(cmdArg); - if (pd) // page - { - *pDoc=pd->documentation(); - *pBrief=pd->briefDescription(); - *pDef=pd; - return TRUE; - } - bool ambig; - fd = findFileDef(Doxygen::inputNameDict,cmdArg,ambig); - if (fd && !ambig) // file - { - *pDoc=fd->documentation(); - *pBrief=fd->briefDescription(); - *pDef=fd; - return TRUE; - } - if (scopeOffset==0) { scopeOffset=-1; @@ -794,9 +796,10 @@ static bool findDocsForMemberOrCompound(const char *commandName, } } while (scopeOffset>=0); - + return FALSE; } + //--------------------------------------------------------------------------- inline void errorHandleDefaultToken(DocNode *parent,int tok, QList<DocNode> &children,const char *txt) @@ -825,7 +828,7 @@ inline void errorHandleDefaultToken(DocNode *parent,int tok, //--------------------------------------------------------------------------- // forward declaration -static bool defaultHandleToken(DocNode *parent,int tok, +static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool handleWord=TRUE); @@ -841,15 +844,15 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, qPrint(saveCmdName)); return tok; } - while ((tok=doctokenizerYYlex()) && - tok!=TK_WHITESPACE && + while ((tok=doctokenizerYYlex()) && + tok!=TK_WHITESPACE && tok!=TK_NEWPARA && - tok!=TK_LISTITEM && + tok!=TK_LISTITEM && tok!=TK_ENDLIST ) { static QRegExp specialChar("[.,|()\\[\\]:;\\?]"); - if (tok==TK_WORD && g_token->name.length()==1 && + if (tok==TK_WORD && g_token->name.length()==1 && g_token->name.find(specialChar)!=-1) { // special character that ends the markup command @@ -862,7 +865,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, case TK_HTMLTAG: if (insideLI(parent) && Mappers::htmlTagMapper->map(g_token->name) && g_token->endTag) { // ignore </li> as the end of a style command - continue; + continue; } return tok; break; @@ -875,7 +878,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, } DBG(("handleStyleArgument(%s) end tok=%x\n",qPrint(saveCmdName),tok)); return (tok==TK_NEWPARA || tok==TK_LISTITEM || tok==TK_ENDLIST - ) ? tok : RetVal_OK; + ) ? tok : RetVal_OK; } /*! Called when a style change starts. For instance a \<b\> command is @@ -942,7 +945,7 @@ static void handlePendingStyleCommands(DocNode *parent,QList<DocNode> &children) if (!g_styleStack.isEmpty()) { DocStyleChange *sc = g_styleStack.top(); - while (sc && sc->position()>=g_nodeStack.count()) + while (sc && sc->position()>=g_nodeStack.count()) { // there are unclosed style modifiers in the paragraph children.append(new DocStyleChange(parent,g_nodeStack.count(),sc->style(),sc->tagName(),FALSE)); g_initialStyleStack.push(sc); @@ -965,7 +968,7 @@ static int handleAHref(DocNode *parent,QList<DocNode> &children,const HtmlAttrib { HtmlAttribListIterator li(tagHtmlAttribs); HtmlAttrib *opt; - int index=0; + uint index=0; int retval = RetVal_OK; for (li.toFirst();(opt=li.current());++li,++index) { @@ -1058,12 +1061,12 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor const Definition *compound=0; const MemberDef *member=0; - int len = g_token->name.length(); + uint len = g_token->name.length(); ClassDef *cd=0; bool ambig; - FileDef *fd = findFileDef(Doxygen::inputNameDict,g_fileName,ambig); + FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,g_fileName,ambig); //printf("handleLinkedWord(%s) g_context=%s\n",g_token->name.data(),g_context.data()); - if (!g_insideHtmlLink && + if (!g_insideHtmlLink && (resolveRef(g_context,g_token->name,g_inSeeBlock,&compound,&member,TRUE,fd,TRUE) || (!g_context.isEmpty() && // also try with global scope resolveRef("",g_token->name,g_inSeeBlock,&compound,&member,FALSE,0,TRUE)) @@ -1073,12 +1076,12 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor //printf("resolveRef %s = %p (linkable?=%d)\n",qPrint(g_token->name),member,member ? member->isLinkable() : FALSE); if (member && member->isLinkable()) // member link { - if (member->isObjCMethod()) + if (member->isObjCMethod()) { bool localLink = g_memberDef ? member->getClassDef()==g_memberDef->getClassDef() : FALSE; name = member->objCMethodName(localLink,g_inSeeBlock); } - children.append(new + children.append(new DocLinkedWord(parent,name, member->getReference(), member->getOutputFileBase(), @@ -1098,7 +1101,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor { name=(dynamic_cast<const GroupDef*>(compound))->groupTitle(); } - children.append(new + children.append(new DocLinkedWord(parent,name, compound->getReference(), compound->getOutputFileBase(), @@ -1111,7 +1114,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor (dynamic_cast<const FileDef*>(compound))->generateSourceFile() ) // undocumented file that has source code we can link to { - children.append(new + children.append(new DocLinkedWord(parent,g_token->name, compound->getReference(), compound->getSourceFileBase(), @@ -1127,7 +1130,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor } else if (!g_insideHtmlLink && len>1 && g_token->name.at(len-1)==':') { - // special case, where matching Foo: fails to be an Obj-C reference, + // special case, where matching Foo: fails to be an Obj-C reference, // but Foo itself might be linkable. g_token->name=g_token->name.left(len-1); handleLinkedWord(parent,children,ignoreAutoLinkFlag); @@ -1137,7 +1140,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor { // special case 2, where the token name is not a class, but could // be a Obj-C protocol - children.append(new + children.append(new DocLinkedWord(parent,name, cd->getReference(), cd->getOutputFileBase(), @@ -1149,7 +1152,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor // { // // special case 3, where the token name is not a class, but could // // be a C# generic -// children.append(new +// children.append(new // DocLinkedWord(parent,name, // cd->getReference(), // cd->getOutputFileBase(), @@ -1401,7 +1404,7 @@ reparsetoken: children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,tokenName,FALSE)); if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," ")); if (tok==TK_NEWPARA) goto handlepara; - else if (tok==TK_WORD || tok==TK_HTMLTAG) + else if (tok==TK_WORD || tok==TK_HTMLTAG) { DBG(("CMD_EMPHASIS: reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -1415,7 +1418,7 @@ reparsetoken: children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,tokenName,FALSE)); if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," ")); if (tok==TK_NEWPARA) goto handlepara; - else if (tok==TK_WORD || tok==TK_HTMLTAG) + else if (tok==TK_WORD || tok==TK_HTMLTAG) { DBG(("CMD_BOLD: reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -1429,7 +1432,7 @@ reparsetoken: children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,tokenName,FALSE)); if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," ")); if (tok==TK_NEWPARA) goto handlepara; - else if (tok==TK_WORD || tok==TK_HTMLTAG) + else if (tok==TK_WORD || tok==TK_HTMLTAG) { DBG(("CMD_CODE: reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -1468,7 +1471,7 @@ reparsetoken: doctokenizerYYsetStateLatexOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"latexonly section ended without end marker",doctokenizerYYlineno); + if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"latexonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1477,7 +1480,7 @@ reparsetoken: doctokenizerYYsetStateXmlOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"xmlonly section ended without end marker",doctokenizerYYlineno); + if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"xmlonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1486,7 +1489,7 @@ reparsetoken: doctokenizerYYsetStateDbOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::DocbookOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker",doctokenizerYYlineno); + if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1563,6 +1566,7 @@ reparsetoken: { handleStyleLeave(parent,children,DocStyleChange::S,tokenName); } + break; case HTML_STRIKE: if (!g_token->endTag) { @@ -1674,7 +1678,7 @@ reparsetoken: } } break; - case TK_SYMBOL: + case TK_SYMBOL: { DocSymbol::SymType s = DocSymbol::decodeSymbol(tokenName); if (s!=DocSymbol::Sym_Unknown) @@ -1687,15 +1691,15 @@ reparsetoken: } } break; - case TK_WHITESPACE: - case TK_NEWPARA: + case TK_WHITESPACE: + case TK_NEWPARA: handlepara: if (insidePRE(parent) || !children.isEmpty()) { children.append(new DocWhiteSpace(parent,g_token->chars)); } break; - case TK_LNKWORD: + case TK_LNKWORD: if (handleWord) { handleLinkedWord(parent,children); @@ -1703,7 +1707,7 @@ handlepara: else return FALSE; break; - case TK_WORD: + case TK_WORD: if (handleWord) { children.append(new DocWord(parent,g_token->name)); @@ -1734,7 +1738,7 @@ static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribL HtmlAttribListIterator li(tagHtmlAttribs); HtmlAttrib *opt; bool found=FALSE; - int index=0; + uint index=0; for (li.toFirst();(opt=li.current());++li,++index) { //printf("option name=%s value=%s\n",opt->name.data(),opt->value.data()); @@ -1772,7 +1776,7 @@ DocEmoji::DocEmoji(DocNode *parent,const QCString &symName) : { m_parent = parent; QCString locSymName = symName; - int len=locSymName.length(); + uint len=locSymName.length(); if (len>0) { if (locSymName.at(len-1)!=':') locSymName.append(":"); @@ -1810,7 +1814,7 @@ static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children, DocPara *par = new DocPara(parent); if (isFirst) { par->markFirst(); isFirst=FALSE; } retval=par->parse(); - if (!par->isEmpty()) + if (!par->isEmpty()) { children.append(par); if (lastPar) lastPar->markLast(FALSE); @@ -1853,12 +1857,12 @@ static void readTextFileByName(const QCString &file,QCString &text) text = fileToString(absFileName,Config_getBool(FILTER_SOURCE_FILES)); return; } - s=examplePathList.next(); + s=examplePathList.next(); } // as a fallback we also look in the exampleNameDict bool ambig; - FileDef *fd = findFileDef(Doxygen::exampleNameDict,file,ambig); + FileDef *fd = findFileDef(Doxygen::exampleNameLinkedMap,file,ambig); if (fd) { text = fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)); @@ -1866,7 +1870,7 @@ static void readTextFileByName(const QCString &file,QCString &text) { warn_doc_error(g_fileName,doctokenizerYYlineno,"included file name %s is ambiguous" "Possible candidates:\n%s",qPrint(file), - qPrint(showFileDefMatches(Doxygen::exampleNameDict,file)) + qPrint(showFileDefMatches(Doxygen::exampleNameLinkedMap,file)) ); } } @@ -1879,10 +1883,10 @@ static void readTextFileByName(const QCString &file,QCString &text) //--------------------------------------------------------------------------- -DocWord::DocWord(DocNode *parent,const QCString &word) : - m_word(word) +DocWord::DocWord(DocNode *parent,const QCString &word) : + m_word(word) { - m_parent = parent; + m_parent = parent; //printf("new word %s url=%s\n",word.data(),g_searchUrl.data()); if (Doxygen::searchIndex && !g_searchUrl.isEmpty()) { @@ -1894,12 +1898,12 @@ DocWord::DocWord(DocNode *parent,const QCString &word) : DocLinkedWord::DocLinkedWord(DocNode *parent,const QCString &word, const QCString &ref,const QCString &file, - const QCString &anchor,const QCString &tooltip) : - m_word(word), m_ref(ref), + const QCString &anchor,const QCString &tooltip) : + m_word(word), m_ref(ref), m_file(file), m_relPath(g_relPath), m_anchor(anchor), m_tooltip(tooltip) { - m_parent = parent; + m_parent = parent; //printf("DocLinkedWord: new word %s url=%s tooltip='%s'\n", // word.data(),g_searchUrl.data(),tooltip.data()); if (Doxygen::searchIndex && !g_searchUrl.isEmpty()) @@ -1912,22 +1916,24 @@ DocLinkedWord::DocLinkedWord(DocNode *parent,const QCString &word, DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) { - m_parent = parent; + m_parent = parent; if (id.isEmpty()) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label"); return; } - if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) + const CitationManager &ct = CitationManager::instance(); + QCString anchorPrefix = ct.anchorPrefix(); + if (id.left(anchorPrefix.length()) == anchorPrefix) { - CiteInfo *cite = Doxygen::citeDict->find(id.mid(CiteConsts::anchorPrefix.length())); - if (cite) + const CiteInfo *cite = ct.find(id.mid(anchorPrefix.length())); + if (cite) { - m_file = convertNameToFile(CiteConsts::fileName,FALSE,TRUE); + m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); m_anchor = id; } - else + else { warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid cite anchor id '%s'",qPrint(id)); m_anchor = "invalid"; @@ -1940,17 +1946,12 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) } else // found \anchor label { - SectionInfo *sec = Doxygen::sectionDict->find(id); + const SectionInfo *sec = SectionManager::instance().find(id); if (sec) { //printf("Found anchor %s\n",id.data()); - m_file = sec->fileName; - m_anchor = sec->label; - if (g_sectionDict && g_sectionDict->find(id)==0) - { - //printf("Inserting in dictionary!\n"); - g_sectionDict->append(id,sec); - } + m_file = sec->fileName(); + m_anchor = sec->label(); } else { @@ -1997,12 +1998,14 @@ void DocInclude::parse() g_includeFileShowLineNo = (m_type == DontIncWithLines || m_type == IncWithLines); //printf("g_includeFile=<<%s>>\n",g_includeFileText.data()); break; - case VerbInclude: + case VerbInclude: // fall through case HtmlInclude: - readTextFileByName(m_file,m_text); - break; case LatexInclude: + case DocInclude::RtfInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: readTextFileByName(m_file,m_text); break; case Snippet: @@ -2017,8 +2020,8 @@ void DocInclude::parse() m_blockId.data(),m_file.data(),count); } break; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" "Please create a bug report\n",__FILE__); break; @@ -2040,7 +2043,7 @@ void DocIncOperator::parse() const char *p = g_includeFileText; uint l = g_includeFileLength; uint o = g_includeFileOffset; - uint il = g_includeFileLine; + int il = g_includeFileLine; DBG(("DocIncOperator::parse() text=%s off=%d len=%d\n",qPrint(p),o,l)); uint so = o,bo; bool nonEmpty = FALSE; @@ -2050,7 +2053,7 @@ void DocIncOperator::parse() while (o<l) { char c = p[o]; - if (c=='\n') + if (c=='\n') { g_includeFileLine++; if (nonEmpty) break; // we have a pattern to match @@ -2167,26 +2170,26 @@ void DocIncOperator::parse() //--------------------------------------------------------------------------- -DocXRefItem::DocXRefItem(DocNode *parent,int id,const char *key) : +DocXRefItem::DocXRefItem(DocNode *parent,int id,const char *key) : m_id(id), m_key(key), m_relPath(g_relPath) { - m_parent = parent; + m_parent = parent; } bool DocXRefItem::parse() { - RefList *refList = Doxygen::xrefLists->find(m_key); - if (refList && + RefList *refList = RefListManager::instance().find(m_key); + if (refList && ( // either not a built-in list or the list is enabled - (m_key!="todo" || Config_getBool(GENERATE_TODOLIST)) && - (m_key!="test" || Config_getBool(GENERATE_TESTLIST)) && - (m_key!="bug" || Config_getBool(GENERATE_BUGLIST)) && + (m_key!="todo" || Config_getBool(GENERATE_TODOLIST)) && + (m_key!="test" || Config_getBool(GENERATE_TESTLIST)) && + (m_key!="bug" || Config_getBool(GENERATE_BUGLIST)) && (m_key!="deprecated" || Config_getBool(GENERATE_DEPRECATEDLIST)) - ) + ) ) { - RefItem *item = refList->getRefItem(m_id); + RefItem *item = refList->find(m_id); ASSERT(item!=0); if (item) { @@ -2198,16 +2201,16 @@ bool DocXRefItem::parse() else { m_file = refList->fileName(); - m_anchor = item->listAnchor; + m_anchor = item->anchor(); } m_title = refList->sectionTitle(); //printf("DocXRefItem: file=%s anchor=%s title=%s\n", // m_file.data(),m_anchor.data(),m_title.data()); - if (!item->text.isEmpty()) + if (!item->text().isEmpty()) { docParserPushContext(); - internalValidatingParseDoc(this,m_children,item->text); + internalValidatingParseDoc(this,m_children,item->text()); docParserPopContext(); } } @@ -2221,15 +2224,13 @@ bool DocXRefItem::parse() DocFormula::DocFormula(DocNode *parent,int id) : m_relPath(g_relPath) { - m_parent = parent; - QCString formCmd; - formCmd.sprintf("\\_form#%d",id); - Formula *formula=Doxygen::formulaNameDict->find(formCmd); - if (formula) + m_parent = parent; + QCString text = FormulaManager::instance().findFormula(id); + if (!text.isEmpty()) { - m_id = formula->getId(); + m_id = id; m_name.sprintf("form_%d",m_id); - m_text = formula->getFormulaText(); + m_text = text; } else // wrong \_form#<n> command { @@ -2284,30 +2285,26 @@ void DocSecRefItem::parse() doctokenizerYYsetStatePara(); handlePendingStyleCommands(this,m_children); - SectionInfo *sec=0; + const SectionInfo *sec=0; if (!m_target.isEmpty()) { - sec=Doxygen::sectionDict->find(m_target); + sec = SectionManager::instance().find(m_target); if (sec) { - m_file = sec->fileName; - m_anchor = sec->label; - if (g_sectionDict && g_sectionDict->find(m_target)==0) - { - g_sectionDict->append(m_target,sec); - } + m_file = sec->fileName(); + m_anchor = sec->label(); } else { warn_doc_error(g_fileName,doctokenizerYYlineno,"reference to unknown section %s", qPrint(m_target)); } - } + } else { warn_doc_error(g_fileName,doctokenizerYYlineno,"reference to empty target"); } - + DBG(("DocSecRefItem::parse() end\n")); DocNode *n = g_nodeStack.pop(); ASSERT(n==this); @@ -2333,7 +2330,7 @@ void DocSecRefList::parse() { case CMD_SECREFITEM: { - int tok=doctokenizerYYlex(); + tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\refitem command"); @@ -2381,14 +2378,14 @@ endsecreflist: //--------------------------------------------------------------------------- -DocInternalRef::DocInternalRef(DocNode *parent,const QCString &ref) +DocInternalRef::DocInternalRef(DocNode *parent,const QCString &ref) : m_relPath(g_relPath) { - m_parent = parent; + m_parent = parent; int i=ref.find('#'); if (i!=-1) { - m_anchor = ref.right(ref.length()-i-1); + m_anchor = ref.right((int)ref.length()-i-1); m_file = ref.left(i); } else @@ -2419,38 +2416,38 @@ void DocInternalRef::parse() //--------------------------------------------------------------------------- -DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : +DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_refType(Unknown), m_isSubPage(FALSE) { - m_parent = parent; + m_parent = parent; const Definition *compound = 0; QCString anchor; //printf("DocRef::DocRef(target=%s,context=%s)\n",target.data(),context.data()); ASSERT(!target.isEmpty()); SrcLangExt lang = getLanguageFromFileName(target); m_relPath = g_relPath; - SectionInfo *sec = Doxygen::sectionDict->find(target); + const SectionInfo *sec = SectionManager::instance().find(target); if (sec==0 && lang==SrcLangExt_Markdown) // lookup as markdown file { - sec = Doxygen::sectionDict->find(markdownFileNameToId(target)); + sec = SectionManager::instance().find(markdownFileNameToId(target)); } if (sec) // ref to section or anchor { PageDef *pd = 0; - if (sec->type==SectionInfo::Page) + if (sec->type()==SectionType::Page) { pd = Doxygen::pageSDict->find(target); } - m_text = sec->title; - if (m_text.isEmpty()) m_text = sec->label; + m_text = sec->title(); + if (m_text.isEmpty()) m_text = sec->label(); - m_ref = sec->ref; - m_file = stripKnownExtensions(sec->fileName); - if (sec->type==SectionInfo::Anchor) + m_ref = sec->ref(); + m_file = stripKnownExtensions(sec->fileName()); + if (sec->type()==SectionType::Anchor) { m_refType = Anchor; } - else if (sec->type==SectionInfo::Table) + else if (sec->type()==SectionType::Table) { m_refType = Table; } @@ -2459,16 +2456,16 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_refType = Section; } m_isSubPage = pd && pd->hasParentPage(); - if (sec->type!=SectionInfo::Page || m_isSubPage) m_anchor = sec->label; + if (sec->type()!=SectionType::Page || m_isSubPage) m_anchor = sec->label(); //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d type=%d\n", // m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor,sec->type); return; } else if (resolveLink(context,target,TRUE,&compound,anchor)) { - bool isFile = compound ? + bool isFile = compound ? (compound->definitionType()==Definition::TypeFile || - compound->definitionType()==Definition::TypePage ? TRUE : FALSE) : + compound->definitionType()==Definition::TypePage ? TRUE : FALSE) : FALSE; m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile); m_anchor = anchor; @@ -2507,7 +2504,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : } m_text = target; warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to '%s' for \\ref command", - qPrint(target)); + qPrint(target)); } static void flattenParagraphs(DocNode *root,QList<DocNode> &children) @@ -2571,7 +2568,7 @@ void DocRef::parse() } handlePendingStyleCommands(this,m_children); - + DocNode *n=g_nodeStack.pop(); ASSERT(n==this); } @@ -2585,14 +2582,15 @@ DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //cont //printf("DocCite::DocCite(target=%s)\n",target.data()); ASSERT(!target.isEmpty()); m_relPath = g_relPath; - CiteInfo *cite = Doxygen::citeDict->find(target); + const CitationManager &ct = CitationManager::instance(); + const CiteInfo *cite = ct.find(target); //printf("cite=%p text='%s' numBibFiles=%d\n",cite,cite?cite->text.data():"<null>",numBibFiles); - if (numBibFiles>0 && cite && !cite->text.isEmpty()) // ref to citation + if (numBibFiles>0 && cite && !cite->text().isEmpty()) // ref to citation { - m_text = cite->text; - m_ref = cite->ref; - m_anchor = CiteConsts::anchorPrefix+cite->label; - m_file = convertNameToFile(CiteConsts::fileName,FALSE,TRUE); + m_text = cite->text(); + m_ref = ""; + m_anchor = ct.anchorPrefix()+cite->label(); + m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); //printf("CITE ==> m_text=%s,m_ref=%s,m_file=%s,m_anchor=%s\n", // m_text.data(),m_ref.data(),m_file.data(),m_anchor.data()); return; @@ -2616,7 +2614,7 @@ DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //cont //--------------------------------------------------------------------------- -DocLink::DocLink(DocNode *parent,const QCString &target) +DocLink::DocLink(DocNode *parent,const QCString &target) { m_parent = parent; const Definition *compound = 0; @@ -2648,7 +2646,7 @@ DocLink::DocLink(DocNode *parent,const QCString &target) // bogus link target warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve link to '%s' for \\link command", - qPrint(target)); + qPrint(target)); } @@ -2684,7 +2682,7 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) break; } break; - case TK_SYMBOL: + case TK_SYMBOL: warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found as part of a \\link", qPrint(g_token->name)); break; @@ -2695,8 +2693,8 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) qPrint(g_token->name)); } goto endlink; - case TK_LNKWORD: - case TK_WORD: + case TK_LNKWORD: + case TK_WORD: if (isJavaLink) // special case to detect closing } { QCString w = g_token->name; @@ -2711,7 +2709,7 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) m_children.append(new DocWord(this,w.left(p))); if ((uint)p<l-1) // something left after the } (for instance a .) { - result=w.right(l-p-1); + result=w.right((int)l-p-1); } goto endlink; } @@ -2728,7 +2726,7 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" - " link command\n"); + " link command\n"); } endlink: @@ -2747,10 +2745,10 @@ endlink: //--------------------------------------------------------------------------- -DocDotFile::DocDotFile(DocNode *parent,const QCString &name,const QCString &context) : +DocDotFile::DocDotFile(DocNode *parent,const QCString &name,const QCString &context) : m_name(name), m_relPath(g_relPath), m_context(context) { - m_parent = parent; + m_parent = parent; } bool DocDotFile::parse() @@ -2759,10 +2757,10 @@ bool DocDotFile::parse() defaultHandleTitleAndSize(CMD_DOTFILE,this,m_children,m_width,m_height); bool ambig; - FileDef *fd = findFileDef(Doxygen::dotFileNameDict,m_name,ambig); + FileDef *fd = findFileDef(Doxygen::dotFileNameLinkedMap,m_name,ambig); if (fd==0 && m_name.right(4)!=".dot") // try with .dot extension as well { - fd = findFileDef(Doxygen::dotFileNameDict,m_name+".dot",ambig); + fd = findFileDef(Doxygen::dotFileNameLinkedMap,m_name+".dot",ambig); } if (fd) { @@ -2772,7 +2770,7 @@ bool DocDotFile::parse() { warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::dotFileNameDict,m_name)) + qPrint(showFileDefMatches(Doxygen::dotFileNameLinkedMap,m_name)) ); } } @@ -2784,10 +2782,10 @@ bool DocDotFile::parse() return ok; } -DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &context) : +DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &context) : m_name(name), m_relPath(g_relPath), m_context(context) { - m_parent = parent; + m_parent = parent; } bool DocMscFile::parse() @@ -2796,10 +2794,10 @@ bool DocMscFile::parse() defaultHandleTitleAndSize(CMD_MSCFILE,this,m_children,m_width,m_height); bool ambig; - FileDef *fd = findFileDef(Doxygen::mscFileNameDict,m_name,ambig); + FileDef *fd = findFileDef(Doxygen::mscFileNameLinkedMap,m_name,ambig); if (fd==0 && m_name.right(4)!=".msc") // try with .msc extension as well { - fd = findFileDef(Doxygen::mscFileNameDict,m_name+".msc",ambig); + fd = findFileDef(Doxygen::mscFileNameLinkedMap,m_name+".msc",ambig); } if (fd) { @@ -2809,7 +2807,7 @@ bool DocMscFile::parse() { warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::mscFileNameDict,m_name)) + qPrint(showFileDefMatches(Doxygen::mscFileNameLinkedMap,m_name)) ); } } @@ -2835,10 +2833,10 @@ bool DocDiaFile::parse() defaultHandleTitleAndSize(CMD_DIAFILE,this,m_children,m_width,m_height); bool ambig; - FileDef *fd = findFileDef(Doxygen::diaFileNameDict,m_name,ambig); + FileDef *fd = findFileDef(Doxygen::diaFileNameLinkedMap,m_name,ambig); if (fd==0 && m_name.right(4)!=".dia") // try with .dia extension as well { - fd = findFileDef(Doxygen::diaFileNameDict,m_name+".dia",ambig); + fd = findFileDef(Doxygen::diaFileNameLinkedMap,m_name+".dia",ambig); } if (fd) { @@ -2848,7 +2846,7 @@ bool DocDiaFile::parse() { warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::diaFileNameDict,m_name)) + qPrint(showFileDefMatches(Doxygen::diaFileNameLinkedMap,m_name)) ); } } @@ -2907,7 +2905,7 @@ DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString bool DocImage::isSVG() const { QCString locName = m_url.isEmpty() ? m_name : m_url; - int len = locName.length(); + int len = (int)locName.length(); int fnd = locName.find('?'); // ignore part from ? until end if (fnd==-1) fnd=len; return fnd>=4 && locName.mid(fnd-4,4)==".svg"; @@ -2942,7 +2940,7 @@ int DocHtmlHeader::parse() if (m_level!=1) { warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h1>", - m_level); + m_level); } goto endheader; } @@ -2951,7 +2949,7 @@ int DocHtmlHeader::parse() if (m_level!=2) { warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h2>", - m_level); + m_level); } goto endheader; } @@ -2960,7 +2958,7 @@ int DocHtmlHeader::parse() if (m_level!=3) { warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h3>", - m_level); + m_level); } goto endheader; } @@ -2969,7 +2967,7 @@ int DocHtmlHeader::parse() if (m_level!=4) { warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h4>", - m_level); + m_level); } goto endheader; } @@ -2978,7 +2976,7 @@ int DocHtmlHeader::parse() if (m_level!=5) { warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h5>", - m_level); + m_level); } goto endheader; } @@ -2987,7 +2985,7 @@ int DocHtmlHeader::parse() if (m_level!=6) { warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h6>", - m_level); + m_level); } goto endheader; } @@ -3020,7 +3018,7 @@ int DocHtmlHeader::parse() if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" - " <h%d> tag\n",m_level); + " <h%d> tag\n",m_level); } endheader: handlePendingStyleCommands(this,m_children); @@ -3055,7 +3053,7 @@ int DocHRef::parse() else { warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <a href=...> context", - g_token->endTag?"/":"",qPrint(g_token->name),doctokenizerYYlineno); + g_token->endTag?"/":"",qPrint(g_token->name)); } } break; @@ -3068,7 +3066,7 @@ int DocHRef::parse() if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" - " <a href=...> tag",doctokenizerYYlineno); + " <a href=...> tag"); } endhref: handlePendingStyleCommands(this,m_children); @@ -3094,7 +3092,7 @@ int DocInternal::parse(int level) DocPara *par = new DocPara(this); if (isFirst) { par->markFirst(); isFirst=FALSE; } retval=par->parse(); - if (!par->isEmpty()) + if (!par->isEmpty()) { m_children.append(par); lastPar=par; @@ -3105,9 +3103,9 @@ int DocInternal::parse(int level) } if (retval==TK_LISTITEM) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found",doctokenizerYYlineno); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found"); } - } while (retval!=0 && + } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Subsection && retval!=RetVal_Subsubsection && @@ -3117,7 +3115,7 @@ int DocInternal::parse(int level) if (lastPar) lastPar->markLast(); // then parse any number of level-n sections - while ((level==1 && retval==RetVal_Section) || + while ((level==1 && retval==RetVal_Section) || (level==2 && retval==RetVal_Subsection) || (level==3 && retval==RetVal_Subsubsection) || (level==4 && retval==RetVal_Paragraph) @@ -3162,8 +3160,8 @@ int DocIndexEntry::parse() case TK_WHITESPACE: m_entry+=" "; break; - case TK_WORD: - case TK_LNKWORD: + case TK_WORD: + case TK_LNKWORD: m_entry+=g_token->name; break; case TK_SYMBOL: @@ -3246,18 +3244,13 @@ DocHtmlCaption::DocHtmlCaption(DocNode *parent,const HtmlAttribList &attribs) { if (opt->name=="id" && !opt->value.isEmpty()) // interpret id attribute as an anchor { - SectionInfo *sec = Doxygen::sectionDict->find(opt->value); + const SectionInfo *sec = SectionManager::instance().find(opt->value); if (sec) { //printf("Found anchor %s\n",id.data()); - m_file = sec->fileName; - m_anchor = sec->label; + m_file = sec->fileName(); + m_anchor = sec->label(); m_hasCaptionId = TRUE; - if (g_sectionDict && g_sectionDict->find(opt->value)==0) - { - //printf("Inserting in dictionary!\n"); - g_sectionDict->append(opt->value,sec); - } } else { @@ -3308,7 +3301,7 @@ int DocHtmlCaption::parse() if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" - " <caption> tag",doctokenizerYYlineno); + " <caption> tag"); } endcaption: handlePendingStyleCommands(this,m_children); @@ -3394,32 +3387,32 @@ int DocHtmlCell::parseXml() return retval; } -int DocHtmlCell::rowSpan() const +uint DocHtmlCell::rowSpan() const { - int retval = 0; + uint retval = 0; HtmlAttribList attrs = attribs(); uint i; - for (i=0; i<attrs.count(); ++i) + for (i=0; i<attrs.count(); ++i) { if (attrs.at(i)->name.lower()=="rowspan") { - retval = attrs.at(i)->value.toInt(); + retval = attrs.at(i)->value.toUInt(); break; } } return retval; } -int DocHtmlCell::colSpan() const +uint DocHtmlCell::colSpan() const { - int retval = 1; + uint retval = 1; HtmlAttribList attrs = attribs(); uint i; - for (i=0; i<attrs.count(); ++i) + for (i=0; i<attrs.count(); ++i) { if (attrs.at(i)->name.lower()=="colspan") { - retval = QMAX(1,attrs.at(i)->value.toInt()); + retval = QMAX(1,attrs.at(i)->value.toUInt()); break; } } @@ -3602,7 +3595,7 @@ int DocHtmlTable::parse() int retval=RetVal_OK; g_nodeStack.push(this); DBG(("DocHtmlTable::parse() start\n")); - + getrow: // get next token int tok=doctokenizerYYlex(); @@ -3650,14 +3643,14 @@ getrow: warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <tr> tag but found %s token instead!", tokToString(tok)); } - + // parse one or more rows while (retval==RetVal_TableRow) { DocHtmlRow *tr=new DocHtmlRow(this,g_token->attribs); m_children.append(tr); retval=tr->parse(); - } + } computeTableGrid(); @@ -3672,7 +3665,7 @@ int DocHtmlTable::parseXml() int retval=RetVal_OK; g_nodeStack.push(this); DBG(("DocHtmlTable::parseXml() start\n")); - + // get next token int tok=doctokenizerYYlex(); // skip whitespace @@ -3701,7 +3694,7 @@ int DocHtmlTable::parseXml() m_children.append(tr); retval=tr->parseXml(isHeader); isHeader=FALSE; - } + } computeTableGrid(); @@ -3715,9 +3708,9 @@ int DocHtmlTable::parseXml() /** Helper class to compute the grid for an HTML style table */ struct ActiveRowSpan { - ActiveRowSpan(int rows,int col) : rowsLeft(rows), column(col) {} - int rowsLeft; - int column; + ActiveRowSpan(uint rows,uint col) : rowsLeft(rows), column(col) {} + uint rowsLeft; + uint column; }; /** List of ActiveRowSpan classes. */ @@ -3732,14 +3725,14 @@ void DocHtmlTable::computeTableGrid() //printf("computeTableGrid()\n"); RowSpanList rowSpans; rowSpans.setAutoDelete(TRUE); - int maxCols=0; - int rowIdx=1; + uint maxCols=0; + uint rowIdx=1; QListIterator<DocNode> li(children()); DocNode *rowNode; for (li.toFirst();(rowNode=li.current());++li) { - int colIdx=1; - int cells=0; + uint colIdx=1; + uint cells=0; if (rowNode->kind()==DocNode::Kind_HtmlRow) { uint i; @@ -3751,13 +3744,13 @@ void DocHtmlTable::computeTableGrid() if (cellNode->kind()==DocNode::Kind_HtmlCell) { DocHtmlCell *cell = (DocHtmlCell*)cellNode; - int rs = cell->rowSpan(); - int cs = cell->colSpan(); + uint rs = cell->rowSpan(); + uint cs = cell->colSpan(); for (i=0;i<rowSpans.count();i++) { - if (rowSpans.at(i)->rowsLeft>0 && - rowSpans.at(i)->column==colIdx) + if (rowSpans.at(i)->rowsLeft>0 && + rowSpans.at(i)->column==colIdx) { colIdx=rowSpans.at(i)->column+1; cells++; @@ -3767,7 +3760,7 @@ void DocHtmlTable::computeTableGrid() //printf("found cell at (%d,%d)\n",rowIdx,colIdx); cell->setRowIndex(rowIdx); cell->setColumnIndex(colIdx); - colIdx+=cs; + colIdx+=cs; cells++; } } @@ -3784,9 +3777,9 @@ void DocHtmlTable::computeTableGrid() m_numCols = maxCols; } -void DocHtmlTable::accept(DocVisitor *v) -{ - v->visitPre(this); +void DocHtmlTable::accept(DocVisitor *v) +{ + v->visitPre(this); // for HTML output we put the caption first //if (m_caption && v->id()==DocVisitor_Html) m_caption->accept(v); // doxygen 1.8.11: always put the caption first @@ -3796,7 +3789,7 @@ void DocHtmlTable::accept(DocVisitor *v) for (cli.toFirst();(n=cli.current());++cli) n->accept(v); // for other output formats we put the caption last //if (m_caption && v->id()!=DocVisitor_Html) m_caption->accept(v); - v->visitPost(this); + v->visitPost(this); } //--------------------------------------------------------------------------- @@ -3826,7 +3819,7 @@ int DocHtmlDescTitle::parse() { case CMD_REF: { - int tok=doctokenizerYYlex(); + tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", @@ -3856,7 +3849,7 @@ int DocHtmlDescTitle::parse() // fall through case CMD_LINK: { - int tok=doctokenizerYYlex(); + tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", @@ -3892,7 +3885,7 @@ int DocHtmlDescTitle::parse() } } break; - case TK_SYMBOL: + case TK_SYMBOL: warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol \\%s found as part of a <dt> tag", qPrint(g_token->name)); break; @@ -3943,7 +3936,7 @@ int DocHtmlDescTitle::parse() if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" - " <dt> tag"); + " <dt> tag"); } endtitle: handlePendingStyleCommands(this,m_children); @@ -3973,7 +3966,7 @@ int DocHtmlDescData::parse() } while (retval==TK_NEWPARA); if (par) par->markLast(); - + DBG(("DocHtmlDescData::parse() end\n")); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); @@ -4178,7 +4171,7 @@ int DocHtmlList::parse() m_children.append(li); retval=li->parse(); } while (retval==RetVal_ListItem); - + if (retval==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <%cl> block", @@ -4241,7 +4234,7 @@ int DocHtmlList::parseXml() if (retval==0) break; //printf("retval=%x g_token->name=%s\n",retval,qPrint(g_token->name)); } while (retval==RetVal_ListItem); - + if (retval==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <list type=\"%s\"> block", @@ -4252,8 +4245,8 @@ endlist: DBG(("DocHtmlList::parseXml() end retval=%x\n",retval)); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); - return retval==RetVal_EndList || - (retval==RetVal_CloseXml || g_token->name=="list") ? + return retval==RetVal_EndList || + (retval==RetVal_CloseXml || g_token->name=="list") ? RetVal_OK : retval; } @@ -4265,7 +4258,7 @@ int DocHtmlBlockQuote::parse() int retval=0; g_nodeStack.push(this); - // parse one or more paragraphs + // parse one or more paragraphs bool isFirst=TRUE; DocPara *par=0; do @@ -4292,7 +4285,7 @@ int DocParBlock::parse() int retval=0; g_nodeStack.push(this); - // parse one or more paragraphs + // parse one or more paragraphs bool isFirst=TRUE; DocPara *par=0; do @@ -4343,17 +4336,17 @@ int DocSimpleList::parse() //-------------------------------------------------------------------------- -DocAutoListItem::DocAutoListItem(DocNode *parent,int indent,int num) +DocAutoListItem::DocAutoListItem(DocNode *parent,int indent,int num) : m_indent(indent), m_itemNum(num) -{ - m_parent = parent; +{ + m_parent = parent; } int DocAutoListItem::parse() { int retval = RetVal_OK; g_nodeStack.push(this); - + // first parse any number of paragraphs bool isFirst=TRUE; DocPara *lastPar=0; @@ -4362,7 +4355,7 @@ int DocAutoListItem::parse() DocPara *par = new DocPara(this); if (isFirst) { par->markFirst(); isFirst=FALSE; } retval=par->parse(); - if (!par->isEmpty()) + if (!par->isEmpty()) { m_children.append(par); if (lastPar) lastPar->markLast(FALSE); @@ -4386,11 +4379,11 @@ int DocAutoListItem::parse() //-------------------------------------------------------------------------- DocAutoList::DocAutoList(DocNode *parent,int indent,bool isEnumList, - int depth) : + int depth) : m_indent(indent), m_isEnumList(isEnumList), m_depth(depth) -{ - m_parent = parent; +{ + m_parent = parent; } int DocAutoList::parse() @@ -4410,11 +4403,11 @@ int DocAutoList::parse() m_children.append(li); retval=li->parse(); //printf("DocAutoList::parse(): retval=0x%x g_token->indent=%d m_indent=%d " - // "m_isEnumList=%d g_token->isEnumList=%d g_token->name=%s\n", + // "m_isEnumList=%d g_token->isEnumList=%d g_token->name=%s\n", // retval,g_token->indent,m_indent,m_isEnumList,g_token->isEnumList, // g_token->name.data()); //printf("num=%d g_token->id=%d\n",num,g_token->id); - } + } while (retval==TK_LISTITEM && // new list item m_indent==g_token->indent && // at same indent level m_isEnumList==g_token->isEnumList && // of the same kind @@ -4456,16 +4449,16 @@ void DocTitle::parseFromString(const QCString &text) //-------------------------------------------------------------------------- -DocSimpleSect::DocSimpleSect(DocNode *parent,Type t) : +DocSimpleSect::DocSimpleSect(DocNode *parent,Type t) : m_type(t) -{ - m_parent = parent; - m_title=0; +{ + m_parent = parent; + m_title=0; } DocSimpleSect::~DocSimpleSect() -{ - delete m_title; +{ + delete m_title; } void DocSimpleSect::accept(DocVisitor *v) @@ -4489,10 +4482,10 @@ int DocSimpleSect::parse(bool userTitle,bool needsSeparator) m_title = new DocTitle(this); m_title->parse(); } - + // add new paragraph as child DocPara *par = new DocPara(this); - if (m_children.isEmpty()) + if (m_children.isEmpty()) { par->markFirst(); } @@ -4504,7 +4497,7 @@ int DocSimpleSect::parse(bool userTitle,bool needsSeparator) par->markLast(); if (needsSeparator) m_children.append(new DocSimpleSectSep(this)); m_children.append(par); - + // parse the contents of the paragraph int retval = par->parse(); @@ -4530,7 +4523,7 @@ int DocSimpleSect::parseRcs() DBG(("DocSimpleSect::parseRcs()\n")); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); - return RetVal_OK; + return RetVal_OK; } int DocSimpleSect::parseXml() @@ -4539,11 +4532,11 @@ int DocSimpleSect::parseXml() g_nodeStack.push(this); int retval = RetVal_OK; - for (;;) + for (;;) { // add new paragraph as child DocPara *par = new DocPara(this); - if (m_children.isEmpty()) + if (m_children.isEmpty()) { par->markFirst(); } @@ -4558,17 +4551,17 @@ int DocSimpleSect::parseXml() // parse the contents of the paragraph retval = par->parse(); if (retval == 0) break; - if (retval == RetVal_CloseXml) + if (retval == RetVal_CloseXml) { retval = RetVal_OK; break; } } - + DBG(("DocSimpleSect::parseXml() end retval=%d\n",retval)); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); - return retval; + return retval; } void DocSimpleSect::appendLinkWord(const QCString &word) @@ -4582,12 +4575,12 @@ void DocSimpleSect::appendLinkWord(const QCString &word) else { p = (DocPara *)m_children.getLast(); - + // Comma-separate <seealso> links. p->injectToken(TK_WORD,","); p->injectToken(TK_WHITESPACE," "); } - + g_inSeeBlock=TRUE; p->injectToken(TK_LNKWORD,word); g_inSeeBlock=FALSE; @@ -4713,7 +4706,7 @@ int DocParamList::parseXml(const QCString ¶mName) g_hasReturnCommand=TRUE; checkRetvalName(g_token->name); } - + handleLinkedWord(this,m_params); do @@ -4742,11 +4735,11 @@ int DocParamList::parseXml(const QCString ¶mName) if (retval == 0) break; - } while (retval==RetVal_CloseXml && + } while (retval==RetVal_CloseXml && Mappers::htmlTagMapper->map(g_token->name)!=XML_PARAM && Mappers::htmlTagMapper->map(g_token->name)!=XML_TYPEPARAM && Mappers::htmlTagMapper->map(g_token->name)!=XML_EXCEPTION); - + if (retval==0) /* premature end of comment block */ { @@ -4802,7 +4795,7 @@ int DocParamSect::parse(const QCString &cmdName,bool xmlContext, Direction d) { retval = RetVal_OK; } - + DBG(("DocParamSect::parse() end retval=%d\n",retval)); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); @@ -4937,7 +4930,7 @@ int DocPara::handleXRefItem() { m_children.append(ref); } - else + else { delete ref; } @@ -5331,7 +5324,7 @@ int DocPara::handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level) // For XML tags whose content is stored in attributes rather than // contained within the element, we need a way to inject the attribute // text into the current paragraph. -bool DocPara::injectToken(int tok,const QCString &tokText) +bool DocPara::injectToken(int tok,const QCString &tokText) { g_token->name = tokText; return defaultHandleToken(this,tok,m_children); @@ -5400,23 +5393,23 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) { case CMD_UNKNOWN: m_children.append(new DocWord(this,TK_COMMAND_CHAR(tok) + cmdName)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command '\\%s'",qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command '%c%s'",TK_COMMAND_CHAR(tok),qPrint(cmdName)); break; case CMD_EMPHASIS: m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,cmdName,TRUE)); - retval=handleStyleArgument(this,m_children,cmdName); + retval=handleStyleArgument(this,m_children,cmdName); m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,cmdName,FALSE)); if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," ")); break; case CMD_BOLD: m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,cmdName,TRUE)); - retval=handleStyleArgument(this,m_children,cmdName); + retval=handleStyleArgument(this,m_children,cmdName); m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,cmdName,FALSE)); if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," ")); break; case CMD_CODE: m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,cmdName,TRUE)); - retval=handleStyleArgument(this,m_children,cmdName); + retval=handleStyleArgument(this,m_children,cmdName); m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,cmdName,FALSE)); if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," ")); break; @@ -5612,7 +5605,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateDbOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::DocbookOnly,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker",doctokenizerYYlineno); + if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5702,7 +5695,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) case CMD_ENDMSC: case CMD_ENDUML: warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name)); - break; + break; case CMD_PARAM: retval = handleParamSection(cmdName,DocParamSect::Param,FALSE,g_token->paramDir); break; @@ -5776,6 +5769,18 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) case CMD_LATEXINCLUDE: handleInclude(cmdName,DocInclude::LatexInclude); break; + case CMD_RTFINCLUDE: + handleInclude(cmdName,DocInclude::RtfInclude); + break; + case CMD_MANINCLUDE: + handleInclude(cmdName,DocInclude::ManInclude); + break; + case CMD_XMLINCLUDE: + handleInclude(cmdName,DocInclude::XmlInclude); + break; + case CMD_DOCBOOKINCLUDE: + handleInclude(cmdName,DocInclude::DocbookInclude); + break; case CMD_VERBINCLUDE: handleInclude(cmdName,DocInclude::VerbInclude); break; @@ -5876,26 +5881,26 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) ASSERT(0); break; } - INTERNAL_ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec || + INTERNAL_ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec || retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_NEWPARA || - retval==RetVal_Section || retval==RetVal_EndList || - retval==RetVal_Internal || retval==RetVal_SwitchLang || + retval==RetVal_Section || retval==RetVal_EndList || + retval==RetVal_Internal || retval==RetVal_SwitchLang || retval==RetVal_EndInternal ); DBG(("handleCommand(%s) end retval=%x\n",qPrint(cmdName),retval)); return retval; } -static bool findAttribute(const HtmlAttribList &tagHtmlAttribs, - const char *attrName, - QCString *result) +static bool findAttribute(const HtmlAttribList &tagHtmlAttribs, + const char *attrName, + QCString *result) { HtmlAttribListIterator li(tagHtmlAttribs); HtmlAttrib *opt; for (li.toFirst();(opt=li.current());++li) { - if (opt->name==attrName) + if (opt->name==attrName) { *result = opt->value; return TRUE; @@ -5909,7 +5914,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta DBG(("handleHtmlStartTag(%s,%d)\n",qPrint(tagName),tagHtmlAttribs.count())); int retval=RetVal_OK; int tagId = Mappers::htmlTagMapper->map(tagName); - if (g_token->emptyTag && !(tagId&XML_CmdMask) && + if (g_token->emptyTag && !(tagId&XML_CmdMask) && tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_HR && tagId!=HTML_P) { warn_doc_error(g_fileName,doctokenizerYYlineno,"HTML tag ('<%s/>') may not use the 'empty tag' XHTML syntax.", @@ -5917,7 +5922,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } switch (tagId) { - case HTML_UL: + case HTML_UL: if (!g_token->emptyTag) { DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,DocHtmlList::Unordered); @@ -5925,7 +5930,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta retval=list->parse(); } break; - case HTML_OL: + case HTML_OL: if (!g_token->emptyTag) { DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,DocHtmlList::Ordered); @@ -5964,8 +5969,8 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta break; case HTML_CODE: if (g_token->emptyTag) break; - if (/*getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp ||*/ g_xmlComment) - // for C# source or inside a <summary> or <remark> section we + if (/*getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp ||*/ g_xmlComment) + // for C# source or inside a <summary> or <remark> section we // treat <code> as an XML tag (so similar to @code) { doctokenizerYYsetStateXmlCode(); @@ -6143,7 +6148,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta { //printf("paramName=%s\n",paramName.data()); m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,tagName,TRUE)); - m_children.append(new DocWord(this,paramName)); + m_children.append(new DocWord(this,paramName)); m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,tagName,FALSE)); if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," ")); } @@ -6198,7 +6203,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta case XML_SEE: // I'm not sure if <see> is the same as <seealso> or if it // should you link a member without producing a section. The - // C# specification is extremely vague about this (but what else + // C# specification is extremely vague about this (but what else // can we expect from Microsoft...) { QCString cref; @@ -6330,7 +6335,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) int retval=RetVal_OK; switch (tagId) { - case HTML_UL: + case HTML_UL: if (!insideUL(this)) { warn_doc_error(g_fileName,doctokenizerYYlineno,"found </ul> tag without matching <ul>"); @@ -6340,7 +6345,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) retval=RetVal_EndList; } break; - case HTML_OL: + case HTML_OL: if (!insideOL(this)) { warn_doc_error(g_fileName,doctokenizerYYlineno,"found </ol> tag without matching <ol>"); @@ -6558,8 +6563,8 @@ reparsetoken: DocNode::Kind k; if (insidePRE(this) || // all whitespace is relevant ( - // remove leading whitespace - !m_children.isEmpty() && + // remove leading whitespace + !m_children.isEmpty() && // and whitespace after certain constructs (k=m_children.getLast()->kind())!=DocNode::Kind_HtmlDescList && k!=DocNode::Kind_HtmlTable && @@ -6588,7 +6593,7 @@ reparsetoken: { DocAutoList *al = (DocAutoList *)n; DBG(("previous list item at %d\n",al->indent())); - if (al->indent()>=g_token->indent) + if (al->indent()>=g_token->indent) // new item at the same or lower indent level { retval=TK_LISTITEM; @@ -6599,9 +6604,9 @@ reparsetoken: // determine list depth int depth = 0; n=parent(); - while(n) + while(n) { - if (n->kind() == DocNode::Kind_AutoList && + if (n->kind() == DocNode::Kind_AutoList && ((DocAutoList*)n)->isEnumList()) depth++; n=n->parent(); } @@ -6654,7 +6659,7 @@ reparsetoken: } } break; - case TK_ENDLIST: + case TK_ENDLIST: DBG(("Found end of list inside of paragraph at line %d\n",doctokenizerYYlineno)); if (parent()->kind()==DocNode::Kind_AutoListItem) { @@ -6685,10 +6690,10 @@ reparsetoken: // see if we have to start a simple section int cmd = Mappers::cmdMapper->map(g_token->name); DocNode *n=parent(); - while (n && - n->kind()!=DocNode::Kind_SimpleSect && + while (n && + n->kind()!=DocNode::Kind_SimpleSect && n->kind()!=DocNode::Kind_ParamSect - ) + ) { n=n->parent(); } @@ -6739,25 +6744,25 @@ reparsetoken: DBG(("reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; } - else if (retval==RetVal_OK) + else if (retval==RetVal_OK) { // the command ended normally, keep scanning for new tokens. retval = 0; } else if (retval>0 && retval<RetVal_OK) - { + { // the command ended with a new command, reparse this token tok = retval; goto reparsetoken; } - else // end of file, end of paragraph, start or end of section + else // end of file, end of paragraph, start or end of section // or some auto list marker { goto endparagraph; } } break; - case TK_HTMLTAG: + case TK_HTMLTAG: { if (!g_token->endTag) // found a start tag { @@ -6767,7 +6772,7 @@ reparsetoken: { retval = handleHtmlEndTag(g_token->name); } - if (retval==RetVal_OK) + if (retval==RetVal_OK) { // the command ended normally, keep scanner for new tokens. retval = 0; @@ -6778,7 +6783,7 @@ reparsetoken: } } break; - case TK_SYMBOL: + case TK_SYMBOL: { DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name); if (s!=DocSymbol::Sym_Unknown) @@ -6792,16 +6797,16 @@ reparsetoken: } break; } - case TK_NEWPARA: + case TK_NEWPARA: retval=TK_NEWPARA; goto endparagraph; case TK_RCSTAG: { DocNode *n=parent(); - while (n && - n->kind()!=DocNode::Kind_SimpleSect && + while (n && + n->kind()!=DocNode::Kind_SimpleSect && n->kind()!=DocNode::Kind_ParamSect - ) + ) { n=n->parent(); } @@ -6838,11 +6843,11 @@ endparagraph: { ((DocPara *)n)->setAttribs(g_token->attribs); } - INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || - retval==TK_ENDLIST || retval>RetVal_OK + INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || + retval==TK_ENDLIST || retval>RetVal_OK ); - return retval; + return retval; } //-------------------------------------------------------------------------- @@ -6853,20 +6858,15 @@ int DocSection::parse() int retval=RetVal_OK; g_nodeStack.push(this); - SectionInfo *sec; if (!m_id.isEmpty()) { - sec=Doxygen::sectionDict->find(m_id); + const SectionInfo *sec = SectionManager::instance().find(m_id); if (sec) { - m_file = sec->fileName; - m_anchor = sec->label; - m_title = sec->title; - if (m_title.isEmpty()) m_title = sec->label; - if (g_sectionDict && g_sectionDict->find(m_id)==0) - { - g_sectionDict->append(m_id,sec); - } + m_file = sec->fileName(); + m_anchor = sec->label(); + m_title = sec->title(); + if (m_title.isEmpty()) m_title = sec->label(); } } @@ -6878,7 +6878,7 @@ int DocSection::parse() DocPara *par = new DocPara(this); if (isFirst) { par->markFirst(); isFirst=FALSE; } retval=par->parse(); - if (!par->isEmpty()) + if (!par->isEmpty()) { m_children.append(par); lastPar=par; @@ -6901,7 +6901,7 @@ int DocSection::parse() retval=RetVal_OK; } } - } while (retval!=0 && + } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Subsection && retval!=RetVal_Subsubsection && @@ -6920,7 +6920,6 @@ int DocSection::parse() // then parse any number of nested sections while (retval==RetVal_Subsection) // more sections follow { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; DocSection *s=new DocSection(this, QMIN(2+Doxygen::subpageNestingLevel,5),g_token->sectionId); m_children.append(s); @@ -6935,7 +6934,6 @@ int DocSection::parse() // then parse any number of nested sections while (retval==RetVal_Subsubsection) // more sections follow { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; DocSection *s=new DocSection(this, QMIN(3+Doxygen::subpageNestingLevel,5),g_token->sectionId); m_children.append(s); @@ -6950,13 +6948,12 @@ int DocSection::parse() // then parse any number of nested sections while (retval==RetVal_Paragraph) // more sections follow { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; DocSection *s=new DocSection(this, QMIN(4+Doxygen::subpageNestingLevel,5),g_token->sectionId); m_children.append(s); retval = s->parse(); } - if (!(m_level<Doxygen::subpageNestingLevel+3 && (retval == RetVal_Subsection || retval == RetVal_Subsubsection))) break; + if (!(m_level<Doxygen::subpageNestingLevel+3 && (retval == RetVal_Subsection || retval == RetVal_Subsubsection))) break; } else { @@ -6964,11 +6961,11 @@ int DocSection::parse() } } - INTERNAL_ASSERT(retval==0 || - retval==RetVal_Section || - retval==RetVal_Subsection || - retval==RetVal_Subsubsection || - retval==RetVal_Paragraph || + INTERNAL_ASSERT(retval==0 || + retval==RetVal_Section || + retval==RetVal_Subsection || + retval==RetVal_Subsubsection || + retval==RetVal_Paragraph || retval==RetVal_Internal || retval==RetVal_EndInternal ); @@ -6986,19 +6983,19 @@ void DocText::parse() DBG(("DocText::parse() start\n")); g_nodeStack.push(this); doctokenizerYYsetStateText(); - + int tok; while ((tok=doctokenizerYYlex())) // get the next token { switch(tok) { - case TK_WORD: + case TK_WORD: m_children.append(new DocWord(this,g_token->name)); break; - case TK_WHITESPACE: + case TK_WHITESPACE: m_children.append(new DocWhiteSpace(this,g_token->chars)); break; - case TK_SYMBOL: + case TK_SYMBOL: { DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name); if (s!=DocSymbol::Sym_Unknown) @@ -7119,13 +7116,13 @@ void DocRoot::parse() { if (!g_token->sectionId.startsWith("autotoc_md")) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found paragraph command outside of subsubsection context!"); + warn_doc_error(g_fileName,doctokenizerYYlineno,"found paragraph command (id: '%s') outside of subsubsection context!",qPrint(g_token->sectionId)); } while (retval==RetVal_Paragraph) { if (!g_token->sectionId.isEmpty()) { - SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + const SectionInfo *sec=SectionManager::instance().find(g_token->sectionId); if (sec) { DocSection *s=new DocSection(this, @@ -7149,12 +7146,12 @@ void DocRoot::parse() if (retval==RetVal_Subsubsection) { if (!(g_token->sectionId.startsWith("autotoc_md"))) - warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsubsection command outside of subsection context!"); + warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsubsection command (id: '%s') outside of subsection context!",qPrint(g_token->sectionId)); while (retval==RetVal_Subsubsection) { if (!g_token->sectionId.isEmpty()) { - SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + const SectionInfo *sec=SectionManager::instance().find(g_token->sectionId); if (sec) { DocSection *s=new DocSection(this, @@ -7179,13 +7176,13 @@ void DocRoot::parse() { if (!g_token->sectionId.startsWith("autotoc_md")) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsection command outside of section context!"); + warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsection command (id: '%s') outside of section context!",qPrint(g_token->sectionId)); } while (retval==RetVal_Subsection) { if (!g_token->sectionId.isEmpty()) { - SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + const SectionInfo *sec=SectionManager::instance().find(g_token->sectionId); if (sec) { DocSection *s=new DocSection(this, @@ -7225,7 +7222,7 @@ void DocRoot::parse() { if (!g_token->sectionId.isEmpty()) { - SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + const SectionInfo *sec=SectionManager::instance().find(g_token->sectionId); if (sec) { DocSection *s=new DocSection(this, @@ -7273,7 +7270,7 @@ static QCString extractCopyDocId(const char *data, uint &j, uint len) case '\'': insideSQuote=TRUE; break; case ' ': // fall through case '\t': // fall through - case '\n': + case '\n': found=(round==0); break; } @@ -7592,10 +7589,10 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, docParserPushContext(); if (ctx && ctx!=Doxygen::globalScope && - (ctx->definitionType()==Definition::TypeClass || + (ctx->definitionType()==Definition::TypeClass || ctx->definitionType()==Definition::TypeNamespace - ) - ) + ) + ) { g_context = ctx->name(); } @@ -7633,7 +7630,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, { g_searchUrl=md->getOutputFileBase(); Doxygen::searchIndex->setCurrentDoc( - (md->getLanguage()==SrcLangExt_Fortran ? + (md->getLanguage()==SrcLangExt_Fortran ? theTranslator->trSubprogram(TRUE,TRUE): theTranslator->trMember(TRUE,TRUE))+" "+md->qualifiedName(), g_searchUrl, @@ -7713,8 +7710,8 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, } g_fileName = fileName; - g_relPath = (!linkFromIndex && ctx) ? - QCString(relativePathToRoot(ctx->getOutputFileBase())) : + g_relPath = (!linkFromIndex && ctx) ? + QCString(relativePathToRoot(ctx->getOutputFileBase())) : QCString(""); //printf("ctx->name=%s relPath=%s\n",ctx->name().data(),g_relPath.data()); g_memberDef = md; @@ -7735,8 +7732,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, g_retvalsFound.clear(); g_paramsFound.setAutoDelete(FALSE); g_paramsFound.clear(); - g_sectionDict = 0; //sections; - + //printf("Starting comment block at %s:%d\n",g_fileName.data(),startLine); doctokenizerYYlineno=startLine; uint inpLen=qstrlen(input); @@ -7774,7 +7770,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, //printf(">>>>>> end validatingParseDoc(%s,%s)\n",ctx?ctx->name().data():"<none>", // md?md->name().data():"<none>"); - + return root; } @@ -7839,4 +7835,3 @@ void docFindSections(const char *input, { doctokenizerYYFindSections(input,d,fileName); } - diff --git a/src/docparser.h b/src/docparser.h index b7164d7..d05dea9 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -32,7 +32,6 @@ class DocNode; class MemberDef; class Definition; class MemberGroup; -class SectionDict; //--------------------------------------------------------------------------- QString::Direction getTextDirByConfig(const QString &text); @@ -197,20 +196,20 @@ template<class T> class CompAccept : public DocNode } const QList<DocNode> &children() const { return m_children; } QList<DocNode> &children() { return m_children; } - QString::Direction getTextDir(int nodeIndex) const + QString::Direction getTextDir(uint nodeIndex) const { unsigned char resultDir = QString::DirNeutral; for (uint i = nodeIndex; i < m_children.count(); i++) { DocNode* node = m_children.at(i); QString::Direction nodeDir = node->getTextDir(); - resultDir |= nodeDir; + resultDir |= (unsigned char)nodeDir; if (resultDir == QString::DirMixed) return QString::DirMixed; } return static_cast<QString::Direction>(resultDir); } - QString::Direction getTextBasicDir(int nodeIndex) const + QString::Direction getTextBasicDir(uint nodeIndex) const { for (uint i = nodeIndex; i < m_children.count(); i++) { @@ -530,7 +529,7 @@ class DocSeparator : public DocNode m_chars(chars) { m_parent = parent; } Kind kind() const { return Kind_Sep; } QCString chars() const { return m_chars; } - void accept(DocVisitor *v) { } + void accept(DocVisitor *) { } private: QCString m_chars; }; @@ -583,21 +582,21 @@ class DocInclude : public DocNode public: enum Type { Include, DontInclude, VerbInclude, HtmlInclude, LatexInclude, IncWithLines, Snippet , IncludeDoc, SnippetDoc, SnipWithLines, - DontIncWithLines}; + DontIncWithLines, RtfInclude, ManInclude, DocbookInclude, XmlInclude}; DocInclude(DocNode *parent,const QCString &file, const QCString context, Type t, bool isExample,const QCString exampleFile, - const QCString blockId, bool isBlock) : + const QCString blockId, bool isBlock) : m_file(file), m_context(context), m_type(t), - m_isExample(isExample), m_exampleFile(exampleFile), - m_blockId(blockId), m_isBlock(isBlock) { m_parent = parent; } + m_isExample(isExample), m_isBlock(isBlock), + m_exampleFile(exampleFile), m_blockId(blockId) { m_parent = parent; } Kind kind() const { return Kind_Include; } QCString file() const { return m_file; } - QCString extension() const { int i=m_file.findRev('.'); - if (i!=-1) - return m_file.right(m_file.length()-i); - else - return ""; + QCString extension() const { int i=m_file.findRev('.'); + if (i!=-1) + return m_file.right(m_file.length()-(uint)i); + else + return ""; } Type type() const { return m_type; } QCString text() const { return m_text; } @@ -613,9 +612,9 @@ class DocInclude : public DocNode QCString m_file; QCString m_context; QCString m_text; - Type m_type = Include; - bool m_isExample = false; - bool m_isBlock = false; + Type m_type; + bool m_isExample; + bool m_isBlock; QCString m_exampleFile; QCString m_blockId; }; @@ -1337,9 +1336,7 @@ class DocHtmlCell : public CompAccept<DocHtmlCell> public: enum Alignment { Left, Right, Center }; DocHtmlCell(DocNode *parent,const HtmlAttribList &attribs,bool isHeading) : - m_isHeading(isHeading), - m_isFirst(FALSE), m_isLast(FALSE), m_attribs(attribs), - m_rowIdx(-1), m_colIdx(-1) { m_parent = parent; } + m_isHeading(isHeading), m_attribs(attribs) { m_parent = parent; } bool isHeading() const { return m_isHeading; } bool isFirst() const { return m_isFirst; } bool isLast() const { return m_isLast; } @@ -1349,21 +1346,21 @@ class DocHtmlCell : public CompAccept<DocHtmlCell> const HtmlAttribList &attribs() const { return m_attribs; } int parse(); int parseXml(); - int rowIndex() const { return m_rowIdx; } - int columnIndex() const { return m_colIdx; } - int rowSpan() const; - int colSpan() const; + uint rowIndex() const { return m_rowIdx; } + uint columnIndex() const { return m_colIdx; } + uint rowSpan() const; + uint colSpan() const; Alignment alignment() const; private: - void setRowIndex(int idx) { m_rowIdx = idx; } - void setColumnIndex(int idx) { m_colIdx = idx; } + void setRowIndex(uint idx) { m_rowIdx = idx; } + void setColumnIndex(uint idx) { m_colIdx = idx; } bool m_isHeading = false; bool m_isFirst = false; bool m_isLast = false; HtmlAttribList m_attribs; - int m_rowIdx = -1; - int m_colIdx = -1; + uint m_rowIdx = (uint)-1; + uint m_colIdx = (uint)-1; }; /** Node representing a HTML table caption */ @@ -1391,7 +1388,7 @@ class DocHtmlRow : public CompAccept<DocHtmlRow> friend class DocHtmlTable; public: DocHtmlRow(DocNode *parent,const HtmlAttribList &attribs) : - m_attribs(attribs), m_visibleCells(-1), m_rowIdx(-1) { m_parent = parent; } + m_attribs(attribs) { m_parent = parent; } Kind kind() const { return Kind_HtmlRow; } uint numCells() const { return m_children.count(); } const HtmlAttribList &attribs() const { return m_attribs; } @@ -1410,15 +1407,15 @@ class DocHtmlRow : public CompAccept<DocHtmlRow> } return m_children.count()>0 && heading; } - void setVisibleCells(int n) { m_visibleCells = n; } - int visibleCells() const { return m_visibleCells; } - int rowIndex() const { return m_rowIdx; } + void setVisibleCells(uint n) { m_visibleCells = n; } + uint visibleCells() const { return m_visibleCells; } + uint rowIndex() const { return m_rowIdx; } private: - void setRowIndex(int idx) { m_rowIdx = idx; } + void setRowIndex(uint idx) { m_rowIdx = idx; } HtmlAttribList m_attribs; - int m_visibleCells = -1; - int m_rowIdx = -1; + uint m_visibleCells = 0; + uint m_rowIdx = (uint)-1; }; /** Node representing a HTML table */ @@ -1447,7 +1444,7 @@ class DocHtmlTable : public CompAccept<DocHtmlTable> void computeTableGrid(); DocHtmlCaption *m_caption = 0; HtmlAttribList m_attribs; - int m_numCols = 0; + uint m_numCols = 0; }; /** Node representing an HTML blockquote */ diff --git a/src/docsets.cpp b/src/docsets.cpp index a838923..d92e4f3 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -328,7 +328,6 @@ void DocSets::addIndexItem(const Definition *context,const MemberDef *md, case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL case SrcLangExt_XML: lang="xml"; break; // DBUS XML case SrcLangExt_SQL: lang="sql"; break; // Sql - case SrcLangExt_Tcl: lang="tcl"; break; // Tcl case SrcLangExt_Markdown:lang="markdown"; break; // Markdown case SrcLangExt_Slice: lang="slice"; break; // Slice case SrcLangExt_Unknown: lang="unknown"; break; // should not happen! diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 4882570..de7d162 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -18,6 +18,9 @@ %option never-interactive %option prefix="doctokenizerYY" +%top{ +#include <stdint.h> +} %{ @@ -43,6 +46,8 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + #define TK_COMMAND_SEL() (yytext[0] == '@' ? TK_COMMAND_AT : TK_COMMAND_BS) //-------------------------------------------------------------------------- @@ -60,7 +65,7 @@ static int g_sharpCount=0; static const Definition *g_definition; static QCString g_secLabel; static QCString g_secTitle; -static SectionInfo::SectionType g_secType; +static SectionType g_secType; static QCString g_endMarker; static int g_autoListLevel; @@ -76,7 +81,9 @@ struct DocLexerContext static QStack<DocLexerContext> g_lexerStack; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif //-------------------------------------------------------------------------- void doctokenizerYYpushContext() @@ -167,11 +174,11 @@ static void processSection() { warn(g_fileName,yylineno,"Found section/anchor %s without context\n",g_secLabel.data()); } - SectionInfo *si=0; - if ((si=Doxygen::sectionDict->find(g_secLabel))) + SectionInfo *si = SectionManager::instance().find(g_secLabel); + if (si) { - si->fileName = file; - si->type = g_secType; + si->setFileName(file); + si->setType(g_secType); } } @@ -320,9 +327,9 @@ static QCString stripEmptyLines(const QCString &s) #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -static int yyread(char *buf,int max_size) +static yy_size_t yyread(char *buf,yy_size_t max_size) { - int c=0; + yy_size_t c=0; const char *src=g_inputString+g_inputPos; while ( c < max_size && *src ) *buf++ = *src++, c++; g_inputPos+=c; @@ -630,7 +637,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } return TK_COMMAND_SEL(); } -<St_Para>{URLPROTOCOL}{URLMASK}/\. { // URL. +<St_Para>{URLPROTOCOL}{URLMASK}/[,\.] { // URL, or URL. g_token->name=yytext; g_token->isEMailAddr=FALSE; return TK_URL; @@ -1030,7 +1037,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} if (yytext[0] =='"') { g_token->name=yytext+1; - g_token->name=g_token->name.left(yyleng-2); + g_token->name=g_token->name.left(static_cast<uint>(yyleng)-2); } else { @@ -1167,9 +1174,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } <St_Param>[^ \t\n,@\\]+ { g_token->name = yytext; - if (g_token->name.at(yyleng-1)==':') + if (g_token->name.at(static_cast<uint>(yyleng)-1)==':') { - g_token->name=g_token->name.left(yyleng-1); + g_token->name=g_token->name.left(static_cast<uint>(yyleng)-1); } return TK_WORD; } @@ -1245,7 +1252,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} int e=tag.find(c,s+4); if (e!=-1) // found matching end { - g_secType = SectionInfo::Table; + g_secType = SectionType::Table; g_secLabel=tag.mid(s+4,e-s-4); // extract id processSection(); } @@ -1253,23 +1260,23 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } } <St_Sections>{CMD}"anchor"{BLANK}+ { - g_secType = SectionInfo::Anchor; + g_secType = SectionType::Anchor; BEGIN(St_SecLabel1); } <St_Sections>{CMD}"section"{BLANK}+ { - g_secType = SectionInfo::Section; + g_secType = SectionType::Section; BEGIN(St_SecLabel2); } <St_Sections>{CMD}"subsection"{BLANK}+ { - g_secType = SectionInfo::Subsection; + g_secType = SectionType::Subsection; BEGIN(St_SecLabel2); } <St_Sections>{CMD}"subsubsection"{BLANK}+ { - g_secType = SectionInfo::Subsubsection; + g_secType = SectionType::Subsubsection; BEGIN(St_SecLabel2); } <St_Sections>{CMD}"paragraph"{BLANK}+ { - g_secType = SectionInfo::Paragraph; + g_secType = SectionType::Paragraph; BEGIN(St_SecLabel2); } <St_Sections>{CMD}"verbatim"/[^a-z_A-Z0-9] { @@ -1296,6 +1303,14 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_endMarker="endlatexonly"; BEGIN(St_SecSkip); } +<St_Sections>{CMD}"manonly"/[^a-z_A-Z0-9] { + g_endMarker="endmanonly"; + BEGIN(St_SecSkip); + } +<St_Sections>{CMD}"rtfonly"/[^a-z_A-Z0-9] { + g_endMarker="endrtfonly"; + BEGIN(St_SecSkip); + } <St_Sections>{CMD}"xmlonly"/[^a-z_A-Z0-9] { g_endMarker="endxmlonly"; BEGIN(St_SecSkip); @@ -1620,4 +1635,6 @@ void doctokenizerYYendAutoList() // return retval; //} +#if USE_STATE2STRING #include "doctokenizer.l.h" +#endif diff --git a/src/dot.cpp b/src/dot.cpp index f26bee4..acf4db9 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -83,10 +83,8 @@ DotManager *DotManager::instance() return m_theInstance; } -DotManager::DotManager() : m_runners(1009), m_filePatchers(1009) +DotManager::DotManager() : m_runners(), m_filePatchers() { - m_runners.setAutoDelete(TRUE); - m_filePatchers.setAutoDelete(TRUE); m_queue = new DotRunnerQueue; int i; int dotNumThreads = Config_getInt(DOT_NUM_THREADS); @@ -114,40 +112,44 @@ DotManager::~DotManager() delete m_queue; } -DotRunner* DotManager::createRunner(const QCString& absDotName, const QCString& md5Hash) +DotRunner* DotManager::createRunner(const std::string &absDotName, const std::string& md5Hash) { - DotRunner * run = m_runners.find(absDotName); - if (run == 0) + DotRunner* rv = nullptr; + auto const runit = m_runners.find(absDotName); + if (runit == m_runners.end()) { - run = new DotRunner(absDotName, md5Hash); - m_runners.insert(absDotName, run); + auto insobj = std::make_unique<DotRunner>(absDotName, md5Hash); + rv = insobj.get(); + m_runners.emplace(absDotName, std::move(insobj)); } else { // we have a match - if (md5Hash != QCString(run->getMd5Hash().data())) + if (md5Hash != runit->second->getMd5Hash()) { err("md5 hash does not match for two different runs of %s !\n", absDotName.data()); } + rv = runit->second.get(); } - return run; + assert(rv); + return rv; } -DotFilePatcher *DotManager::createFilePatcher(const QCString &fileName) +DotFilePatcher *DotManager::createFilePatcher(const std::string &fileName) { - DotFilePatcher *patcher = m_filePatchers.find(fileName); - if (patcher==0) - { - patcher = new DotFilePatcher(fileName); - m_filePatchers.append(fileName,patcher); - } - return patcher; + auto patcher = m_filePatchers.find(fileName); + + if (patcher != m_filePatchers.end()) return &(patcher->second); + + auto rv = m_filePatchers.emplace(fileName, fileName.c_str()); + assert(rv.second); + return &(rv.first->second); } bool DotManager::run() const { - uint numDotRuns = m_runners.count(); - uint numFilePatchers = m_filePatchers.count(); + uint numDotRuns = m_runners.size(); + uint numFilePatchers = m_filePatchers.size(); if (numDotRuns+numFilePatchers>1) { if (m_workers.count()==0) @@ -160,7 +162,6 @@ bool DotManager::run() const } } int i=1; - QDictIterator<DotRunner> li(m_runners); bool setPath=FALSE; if (Config_getBool(GENERATE_HTML)) @@ -185,22 +186,21 @@ bool DotManager::run() const } Portable::sysTimerStart(); // fill work queue with dot operations - DotRunner *dr; int prev=1; if (m_workers.count()==0) // no threads to work with { - for (li.toFirst();(dr=li.current());++li) + for (auto & dr : m_runners) { msg("Running dot for graph %d/%d\n",prev,numDotRuns); - dr->run(); + dr.second->run(); prev++; } } else // use multiple threads to run instances of dot in parallel { - for (li.toFirst();(dr=li.current());++li) + for (auto & dr: m_runners) { - m_queue->enqueue(dr); + m_queue->enqueue(dr.second.get()); } // wait for the queue to become empty while ((i=m_queue->count())>0) @@ -237,27 +237,25 @@ bool DotManager::run() const // patch the output file and insert the maps and figures i=1; - SDict<DotFilePatcher>::Iterator di(m_filePatchers); - const DotFilePatcher *fp; // since patching the svg files may involve patching the header of the SVG // (for zoomable SVGs), and patching the .html files requires reading that // header after the SVG is patched, we first process the .svg files and // then the other files. - for (di.toFirst();(fp=di.current());++di) + for (auto & fp : m_filePatchers) { - if (fp->isSVGFile()) + if (fp.second.isSVGFile()) { msg("Patching output file %d/%d\n",i,numFilePatchers); - if (!fp->run()) return FALSE; + if (!fp.second.run()) return FALSE; i++; } } - for (di.toFirst();(fp=di.current());++di) + for (auto& fp : m_filePatchers) { - if (!fp->isSVGFile()) + if (!fp.second.isSVGFile()) { msg("Patching output file %d/%d\n",i,numFilePatchers); - if (!fp->run()) return FALSE; + if (!fp.second.run()) return FALSE; i++; } } @@ -280,7 +278,7 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir, QCString absImgName = d.absPath().utf8()+"/"+imgName; QCString absOutFile = d.absPath().utf8()+"/"+outFile; - DotRunner dotRun(inFile, QCString()); + DotRunner dotRun(inFile); if (format==GOF_BITMAP) { dotRun.addJob(Config_getEnum(DOT_IMAGE_FORMAT),absImgName); @@ -333,7 +331,7 @@ void writeDotImageMapFromFile(FTextStream &t, QCString imgName = baseName+"."+imgExt; QCString absOutFile = d.absPath().utf8()+"/"+mapName; - DotRunner dotRun(inFile, QCString()); + DotRunner dotRun(inFile.data()); dotRun.addJob(MAP_CMD,absOutFile); dotRun.preventCleanUp(); if (!dotRun.run()) @@ -17,8 +17,8 @@ #define DOT_H #include <qlist.h> -#include <qdict.h> #include <qcstring.h> +#include <map> #include "sortdict.h" @@ -35,16 +35,16 @@ class DotManager { public: static DotManager *instance(); - DotRunner* createRunner(const QCString& absDotName, const QCString& md5Hash); - DotFilePatcher *createFilePatcher(const QCString &fileName); + DotRunner* createRunner(const std::string& absDotName, const std::string& md5Hash); + DotFilePatcher *createFilePatcher(const std::string &fileName); bool run() const; private: DotManager(); virtual ~DotManager(); - QDict<DotRunner> m_runners; - SDict<DotFilePatcher> m_filePatchers; + std::map<std::string, std::unique_ptr<DotRunner>> m_runners; + std::map<std::string, DotFilePatcher> m_filePatchers; static DotManager *m_theInstance; DotRunnerQueue *m_queue; QList<DotWorkerThread> m_workers; diff --git a/src/dotclassgraph.cpp b/src/dotclassgraph.cpp index da272b4..eb6c179 100644 --- a/src/dotclassgraph.cpp +++ b/src/dotclassgraph.cpp @@ -13,6 +13,8 @@ * */ +#include <vector> + #include "dotclassgraph.h" #include "dotnode.h" @@ -149,8 +151,8 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, { QList<DotNode> childQueue; QList<DotNode> parentQueue; - QArray<int> childTreeWidth; - QArray<int> parentTreeWidth; + std::vector<int> childTreeWidth; + std::vector<int> parentTreeWidth; childQueue.append(rootNode); if (includeParents) parentQueue.append(rootNode); bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop diff --git a/src/dotdirdeps.cpp b/src/dotdirdeps.cpp index c70128c..66a68df 100644 --- a/src/dotdirdeps.cpp +++ b/src/dotdirdeps.cpp @@ -90,50 +90,52 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) } // add nodes for other used directories - QDictIterator<UsedDir> udi(*dd->usedDirs()); - UsedDir *udir; - //printf("*** For dir %s\n",shortName().data()); - for (udi.toFirst();(udir=udi.current());++udi) - // for each used dir (=directly used or a parent of a directly used dir) { - const DirDef *usedDir=udir->dir(); - const DirDef *dir=dd; - while (dir) + QDictIterator<UsedDir> udi(*dd->usedDirs()); + UsedDir *udir; + //printf("*** For dir %s\n",shortName().data()); + for (udi.toFirst();(udir=udi.current());++udi) + // for each used dir (=directly used or a parent of a directly used dir) { - //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n", - // dir->shortName().data(),usedDir->shortName().data(), - // dir->parent()==usedDir->parent(), - // usedDir->shortName().data(), - // shortName().data(), - // !usedDir->isParentOf(this) - // ); - if (dir!=usedDir && dir->parent()==usedDir->parent() && - !usedDir->isParentOf(dd)) - // include if both have the same parent (or no parent) + const DirDef *usedDir=udir->dir(); + const DirDef *dir=dd; + while (dir) { - t << " " << usedDir->getOutputFileBase() << " [shape=box label=\"" - << usedDir->shortName() << "\""; - if (usedDir->isCluster()) + //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n", + // dir->shortName().data(),usedDir->shortName().data(), + // dir->parent()==usedDir->parent(), + // usedDir->shortName().data(), + // shortName().data(), + // !usedDir->isParentOf(this) + // ); + if (dir!=usedDir && dir->parent()==usedDir->parent() && + !usedDir->isParentOf(dd)) + // include if both have the same parent (or no parent) { - if (!Config_getBool(DOT_TRANSPARENT)) + t << " " << usedDir->getOutputFileBase() << " [shape=box label=\"" + << usedDir->shortName() << "\""; + if (usedDir->isCluster()) { - t << " fillcolor=\"white\" style=\"filled\""; + if (!Config_getBool(DOT_TRANSPARENT)) + { + t << " fillcolor=\"white\" style=\"filled\""; + } + t << " color=\"red\""; } - t << " color=\"red\""; + t << " URL=\"" << usedDir->getOutputFileBase() + << Doxygen::htmlFileExtension << "\"];\n"; + dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir); + break; } - t << " URL=\"" << usedDir->getOutputFileBase() - << Doxygen::htmlFileExtension << "\"];\n"; - dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir); - break; + dir=dir->parent(); } - dir=dir->parent(); } } // add relations between all selected directories const DirDef *dir; QDictIterator<DirDef> di(dirsInGraph); - for (di.toFirst();(dir=di.current());++di) // foreach dir in the graph + for (;(dir=di.current());++di) // foreach dir in the graph { QDictIterator<UsedDir> udi(*dir->usedDirs()); UsedDir *udir; diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp index efc6341..e386af9 100644 --- a/src/dotfilepatcher.cpp +++ b/src/dotfilepatcher.cpp @@ -173,7 +173,7 @@ static QCString replaceRef(const QCString &buf,const QCString relPath, QCString url = link.mid(marker+1); if (!ref.isEmpty()) { - result = externalLinkTarget(); + result = externalLinkTarget(true); if (result != "") setTarget = TRUE; } result+= href+"=\""; @@ -506,8 +506,8 @@ bool DotFilePatcher::run() const fo.close(); // keep original SVG file so we can refer to it, we do need to replace // dummy link by real ones - QFile fi(tmpName); - QFile fo(orgName); + fi.setName(tmpName); + fo.setName(orgName); if (!fi.open(IO_ReadOnly)) { err("problem opening file %s for reading!\n",tmpName.data()); @@ -518,7 +518,7 @@ bool DotFilePatcher::run() const err("problem opening file %s for writing!\n",orgName.data()); return FALSE; } - FTextStream t(&fo); + FTextStream to(&fo); while (!fi.atEnd()) // foreach line { QCString line(maxLineLen); @@ -529,7 +529,7 @@ bool DotFilePatcher::run() const } line.resize(numBytes+1); Map *map = m_maps.at(0); // there is only one 'map' for a SVG file - t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); + to << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); } fi.close(); fo.close(); diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp index 0bfa712..e622dd4 100644 --- a/src/dotgraph.cpp +++ b/src/dotgraph.cpp @@ -186,14 +186,14 @@ bool DotGraph::prepareDotFile() if (m_graphFormat == GOF_BITMAP) { // run dot to create a bitmap image - DotRunner * dotRun = DotManager::instance()->createRunner(absDotName(), sigStr); + DotRunner * dotRun = DotManager::instance()->createRunner(absDotName().data(), sigStr.data()); dotRun->addJob(Config_getEnum(DOT_IMAGE_FORMAT), absImgName()); if (m_generateImageMap) dotRun->addJob(MAP_CMD, absMapName()); } else if (m_graphFormat == GOF_EPS) { // run dot to create a .eps image - DotRunner *dotRun = DotManager::instance()->createRunner(absDotName(), sigStr); + DotRunner *dotRun = DotManager::instance()->createRunner(absDotName().data(), sigStr.data()); if (Config_getBool(USE_PDFLATEX)) { dotRun->addJob("pdf",absImgName()); @@ -233,11 +233,11 @@ void DotGraph::generateCode(FTextStream &t) if (m_regenerate) { DotManager::instance()-> - createFilePatcher(absImgName())-> + createFilePatcher(absImgName().data())-> addSVGConversion(m_relPath,FALSE,QCString(),m_zoomable,m_graphId); } int mapId = DotManager::instance()-> - createFilePatcher(m_fileName)-> + createFilePatcher(m_fileName.data())-> addSVGObject(m_baseName,absImgName(),m_relPath); t << "<!-- SVG " << mapId << " -->" << endl; } @@ -252,7 +252,7 @@ void DotGraph::generateCode(FTextStream &t) if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, getMapLabel())) { int mapId = DotManager::instance()-> - createFilePatcher(m_fileName)-> + createFilePatcher(m_fileName.data())-> addMap(absMapName(), m_relPath, m_urlOnly, QCString(), getMapLabel()); t << "<!-- MAP " << mapId << " -->" << endl; } @@ -263,7 +263,7 @@ void DotGraph::generateCode(FTextStream &t) if (m_regenerate || !DotFilePatcher::writeVecGfxFigure(t,m_baseName,absBaseName())) { int figId = DotManager::instance()-> - createFilePatcher(m_fileName)-> + createFilePatcher(m_fileName.data())-> addFigure(m_baseName,absBaseName(),FALSE /*TRUE*/); t << endl << "% FIG " << figId << endl; } diff --git a/src/dotgraph.h b/src/dotgraph.h index edba009..b90d980 100644 --- a/src/dotgraph.h +++ b/src/dotgraph.h @@ -31,7 +31,8 @@ enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, C class DotGraph { public: - DotGraph() : m_curNodeNumber(0), m_doNotAddImageToIndex(FALSE), m_noDivTag(FALSE), m_zoomable(TRUE), m_urlOnly(FALSE) {} + DotGraph() : m_doNotAddImageToIndex(FALSE), m_noDivTag(FALSE), + m_zoomable(TRUE), m_urlOnly(FALSE) {} virtual ~DotGraph() {} protected: @@ -98,7 +99,7 @@ class DotGraph bool prepareDotFile(); void generateCode(FTextStream &t); - int m_curNodeNumber; + int m_curNodeNumber = 0; }; #endif diff --git a/src/dotlegendgraph.cpp b/src/dotlegendgraph.cpp index 98e1f88..b17a293 100644 --- a/src/dotlegendgraph.cpp +++ b/src/dotlegendgraph.cpp @@ -29,7 +29,7 @@ void DotLegendGraph::writeGraph(const char *path) if (getDotImageExtension()=="svg") { DotManager::instance()-> - createFilePatcher(absBaseName()+Config_getString(HTML_FILE_EXTENSION))-> + createFilePatcher((absBaseName()+Config_getString(HTML_FILE_EXTENSION)).data())-> addSVGObject("graph_legend", absImgName(),QCString()); } } diff --git a/src/dotnode.cpp b/src/dotnode.cpp index 9eccdde..86ae43a 100644 --- a/src/dotnode.cpp +++ b/src/dotnode.cpp @@ -258,23 +258,12 @@ static QCString stripProtectionPrefix(const QCString &s) DotNode::DotNode(int n,const char *lab,const char *tip, const char *url, bool isRoot,const ClassDef *cd) - : m_subgraphId(-1) - , m_number(n) + : m_number(n) , m_label(lab) , m_tooltip(tip) , m_url(url) - , m_parents(0) - , m_children(0) - , m_edgeInfo(0) - , m_deleted(FALSE) - , m_written(FALSE) - , m_hasDoc(FALSE) , m_isRoot(isRoot) , m_classDef(cd) - , m_visible(FALSE) - , m_truncated(Unknown) - , m_distance(1000) - , m_renumbered(false) { } @@ -408,14 +397,14 @@ void DotNode::writeBox(FTextStream &t, { if (!ei->label().isEmpty()) // labels joined by \n { - int li=ei->label().find('\n'); + int i=ei->label().find('\n'); int p=0; QCString lab; - while ((li=ei->label().find('\n',p))!=-1) + while ((i=ei->label().find('\n',p))!=-1) { - lab = stripProtectionPrefix(ei->label().mid(p,li-p)); + lab = stripProtectionPrefix(ei->label().mid(p,i-p)); arrowNames.insert(lab,(void*)0x8); - p=li+1; + p=i+1; } lab = stripProtectionPrefix(ei->label().right(ei->label().length()-p)); arrowNames.insert(lab,(void*)0x8); diff --git a/src/dotnode.h b/src/dotnode.h index 334fdef..92f268e 100644 --- a/src/dotnode.h +++ b/src/dotnode.h @@ -107,22 +107,22 @@ class DotNode private: int m_number; - QCString m_label; //!< label text - QCString m_tooltip; //!< node's tooltip - QCString m_url; //!< url of the node (format: remote$local) - QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows) - QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows) - QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child - bool m_deleted; //!< used to mark a node as deleted - mutable bool m_written; //!< used to mark a node as written - bool m_hasDoc; //!< used to mark a node as documented - bool m_isRoot; //!< indicates if this is a root node - const ClassDef * m_classDef; //!< class representing this node (can be 0) - bool m_visible; //!< is the node visible in the output - TruncState m_truncated; //!< does the node have non-visible children/parents - int m_distance; //!< shortest path to the root node - bool m_renumbered;//!< indicates if the node has been renumbered (to prevent endless loops) - int m_subgraphId; + QCString m_label; //!< label text + QCString m_tooltip; //!< node's tooltip + QCString m_url; //!< url of the node (format: remote$local) + QList<DotNode> *m_parents = 0; //!< list of parent nodes (incoming arrows) + QList<DotNode> *m_children = 0; //!< list of child nodes (outgoing arrows) + QList<EdgeInfo> *m_edgeInfo = 0; //!< edge info for each child + bool m_deleted = false; //!< used to mark a node as deleted + mutable bool m_written = false; //!< used to mark a node as written + bool m_hasDoc = false; //!< used to mark a node as documented + bool m_isRoot; //!< indicates if this is a root node + const ClassDef * m_classDef; //!< class representing this node (can be 0) + bool m_visible = false; //!< is the node visible in the output + TruncState m_truncated = Unknown; //!< does the node have non-visible children/parents + int m_distance = 1000; //!< shortest path to the root node + bool m_renumbered = false; //!< indicates if the node has been renumbered (to prevent endless loops) + int m_subgraphId = -1; }; /** Class representing a list of DotNode objects. */ diff --git a/src/dotrunner.cpp b/src/dotrunner.cpp index fbfeaca..c9ff284 100644 --- a/src/dotrunner.cpp +++ b/src/dotrunner.cpp @@ -15,6 +15,7 @@ #include "dotrunner.h" +#include "qstring.h" #include "util.h" #include "portable.h" #include "dot.h" @@ -72,7 +73,7 @@ static bool resetPDFSize(const int width,const int height, const char *base) } QFile fi(tmpName); QFile fo(patchFile); - if (!fi.open(IO_ReadOnly)) + if (!fi.open(IO_ReadOnly)) { err("problem opening file %s for patching!\n",tmpName.data()); QDir::current().rename(tmpName,patchFile); @@ -114,9 +115,9 @@ static bool resetPDFSize(const int width,const int height, const char *base) bool DotRunner::readBoundingBox(const char *fileName,int *width,int *height,bool isEps) { const char *bb = isEps ? "%%PageBoundingBox:" : "/MediaBox ["; - int bblen = strlen(bb); + int bblen = (int)strlen(bb); FILE *f = Portable::fopen(fileName,"rb"); - if (!f) + if (!f) { //printf("readBoundingBox: could not open %s\n",fileName); return FALSE; @@ -145,29 +146,31 @@ bool DotRunner::readBoundingBox(const char *fileName,int *width,int *height,bool //--------------------------------------------------------------------------------- -DotRunner::DotRunner(const QCString& absDotName, const QCString& md5Hash) - : m_file(absDotName), m_md5Hash(md5Hash), m_cleanUp(Config_getBool(DOT_CLEANUP)), - m_dotExe(Config_getString(DOT_PATH)+"dot") +DotRunner::DotRunner(const std::string& absDotName, const std::string& md5Hash) + : m_file(absDotName.data()) + , m_md5Hash(md5Hash.data()) + , m_dotExe(Config_getString(DOT_PATH)+"dot") + , m_cleanUp(Config_getBool(DOT_CLEANUP)) + , m_jobs() { - m_jobs.setAutoDelete(TRUE); } -void DotRunner::addJob(const char *format,const char *output) + +void DotRunner::addJob(const char *format, const char *output) { - QListIterator<DotJob> li(m_jobs); - DotJob *s; - for (li.toFirst(); (s = li.current()); ++li) + + for (auto& s: m_jobs) { - if (qstrcmp(s->format.data(), format) != 0) continue; - if (qstrcmp(s->output.data(), output) != 0) continue; + if (s.format != format) continue; + if (s.output != output) continue; // we have this job already return; } - QCString args = QCString("-T")+format+" -o \""+output+"\""; - m_jobs.append(new DotJob(format, output, args)); + auto args = std::string ("-T") + format + " -o \"" + output + "\""; + m_jobs.emplace_back(format, output, args); } -QCString getBaseNameOfOutput(QCString const& output) +QCString getBaseNameOfOutput(const QCString &output) { int index = output.findRev('.'); if (index < 0) return output; @@ -179,66 +182,64 @@ bool DotRunner::run() int exitCode=0; QCString dotArgs; - QListIterator<DotJob> li(m_jobs); - DotJob *s; // create output if (Config_getBool(DOT_MULTI_TARGETS)) { dotArgs=QCString("\"")+m_file.data()+"\""; - for (li.toFirst();(s=li.current());++li) + for (auto& s: m_jobs) { dotArgs+=' '; - dotArgs+=s->args.data(); + dotArgs+=s.args.data(); } if ((exitCode=Portable::system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; } else { - for (li.toFirst();(s=li.current());++li) + for (auto& s : m_jobs) { - dotArgs=QCString("\"")+m_file.data()+"\" "+s->args.data(); + dotArgs=QCString("\"")+m_file.data()+"\" "+s.args.data(); if ((exitCode=Portable::system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; } } // check output // As there should be only one pdf file be generated, we don't need code for regenerating multiple pdf files in one call - for (li.toFirst();(s=li.current());++li) + for (auto& s : m_jobs) { - if (qstrncmp(s->format.data(), "pdf", 3) == 0) + if (s.format.compare(0, 3, "pdf") == 0) { int width=0,height=0; - if (!readBoundingBox(s->output.data(),&width,&height,FALSE)) goto error; + if (!readBoundingBox(s.output.data(),&width,&height,FALSE)) goto error; if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) { - if (!resetPDFSize(width,height,getBaseNameOfOutput(s->output.data()))) goto error; - dotArgs=QCString("\"")+m_file.data()+"\" "+s->args.data(); + if (!resetPDFSize(width,height,getBaseNameOfOutput(s.output.data()))) goto error; + dotArgs=QCString("\"")+m_file.data()+"\" "+s.args.data(); if ((exitCode=Portable::system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; } } - if (qstrncmp(s->format.data(), "png", 3) == 0) + if (s.format.compare(0, 3, "png") == 0) { - checkPngResult(s->output.data()); + checkPngResult(s.output.data()); } } // remove .dot files - if (m_cleanUp) + if (m_cleanUp) { //printf("removing dot file %s\n",m_file.data()); Portable::unlink(m_file.data()); } // create checksum file - if (!m_md5Hash.isEmpty()) + if (!m_md5Hash.empty()) { QCString md5Name = getBaseNameOfOutput(m_file.data()) + ".md5"; FILE *f = Portable::fopen(md5Name,"w"); if (f) { - fwrite(m_md5Hash.data(),1,32,f); + fwrite(m_md5Hash.data(),1,32,f); fclose(f); } } @@ -254,27 +255,27 @@ error: void DotRunnerQueue::enqueue(DotRunner *runner) { - QMutexLocker locker(&m_mutex); - m_queue.enqueue(runner); - m_bufferNotEmpty.wakeAll(); + std::lock_guard<std::mutex> locker(m_mutex); + m_queue.push(runner); + m_bufferNotEmpty.notify_all(); } DotRunner *DotRunnerQueue::dequeue() { - QMutexLocker locker(&m_mutex); - while (m_queue.isEmpty()) - { - // wait until something is added to the queue - m_bufferNotEmpty.wait(&m_mutex); - } - DotRunner *result = m_queue.dequeue(); + std::unique_lock<std::mutex> locker(m_mutex); + + // wait until something is added to the queue + m_bufferNotEmpty.wait(locker, [this]() { return !m_queue.empty(); }); + + DotRunner *result = m_queue.front(); + m_queue.pop(); return result; } uint DotRunnerQueue::count() const { - QMutexLocker locker(&m_mutex); - return m_queue.count(); + std::lock_guard<std::mutex> locker(m_mutex); + return m_queue.size(); } //-------------------------------------------------------------------- @@ -292,3 +293,9 @@ void DotWorkerThread::run() runner->run(); } } + +void DotWorkerThread::start() +{ + assert(!m_thread); + m_thread = std::make_unique<std::thread>(&DotWorkerThread::run, this); +} diff --git a/src/dotrunner.h b/src/dotrunner.h index 1b68c18..555ea78 100644 --- a/src/dotrunner.h +++ b/src/dotrunner.h @@ -16,70 +16,30 @@ #ifndef DOTRUNNER_H #define DOTRUNNER_H -#include "qcstring.h" -#include "qlist.h" -#include "qwaitcondition.h" -#include "qthread.h" -#include "qqueue.h" -#include "qmutex.h" - -/** Minimal constant string class that is thread safe, once initialized. */ -class DotConstString -{ - public: - DotConstString() { m_str=0;} - ~DotConstString() { delete[] m_str;} - DotConstString(char const* s) : m_str(0) { set(s); } - DotConstString(const QCString &s) : m_str(0) { set(s); } - DotConstString(const DotConstString &s) : m_str(0) { set(s.data()); } - const char *data() const { return m_str; } - bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; } - - private: - void set(char const* s) - { - delete[] m_str; - m_str=0; - if (s) - { - m_str=new char[strlen(s) + 1]; - qstrcpy(m_str,s); - } - } - - void set(const QCString &s) - { - delete[] m_str; - m_str=0; - if (!s.isEmpty()) - { - m_str=new char[s.length()+1]; - qstrcpy(m_str,s.data()); - } - } - - DotConstString &operator=(const DotConstString &); - - char *m_str; -}; +#include <qglobal.h> //uint +#include <string> +#include <thread> +#include <list> +#include <queue> +#include <mutex> +#include <condition_variable> +#include <memory> /** Helper class to run dot from doxygen from multiple threads. */ class DotRunner { - public: struct DotJob { - DotJob(const DotConstString & format, - const DotConstString & output, - const DotConstString & args) - : format(format), output(output), args(args) {} - DotConstString format; - DotConstString output; - DotConstString args; + DotJob(std::string f, std::string o, std::string a) + : format(f), output(o), args(a) {} + std::string format; + std::string output; + std::string args; }; + public: /** Creates a runner for a dot \a file. */ - DotRunner(const QCString& absDotName, const QCString& md5Hash); + DotRunner(const std::string& absDotName, const std::string& md5Hash = std::string()); /** Adds an additional job to the run. * Performing multiple jobs one file can be faster. @@ -87,22 +47,22 @@ class DotRunner void addJob(const char *format,const char *output); /** Prevent cleanup of the dot file (for user provided dot files) */ - void preventCleanUp() { m_cleanUp = FALSE; } + void preventCleanUp() { m_cleanUp = false; } /** Runs dot for all jobs added. */ bool run(); // DotConstString const& getFileName() { return m_file; } - DotConstString const& getMd5Hash() { return m_md5Hash; } + std::string const & getMd5Hash() { return m_md5Hash; } static bool readBoundingBox(const char* fileName, int* width, int* height, bool isEps); private: - DotConstString m_file; - DotConstString m_md5Hash; - DotConstString m_dotExe; - bool m_cleanUp; - QList<DotJob> m_jobs; + std::string m_file; + std::string m_md5Hash; + std::string m_dotExe; + bool m_cleanUp; + std::vector<DotJob> m_jobs; }; /** Queue of dot jobs to run. */ @@ -114,18 +74,22 @@ class DotRunnerQueue DotRunner *dequeue(); uint count() const; private: - QWaitCondition m_bufferNotEmpty; - QQueue<DotRunner> m_queue; - mutable QMutex m_mutex; + std::condition_variable m_bufferNotEmpty; + std::queue<DotRunner *> m_queue; + mutable std::mutex m_mutex; }; /** Worker thread to execute a dot run */ -class DotWorkerThread : public QThread +class DotWorkerThread { public: DotWorkerThread(DotRunnerQueue *queue); void run(); + void start(); + bool isRunning() { return m_thread && m_thread->joinable(); } + void wait() { m_thread->join(); } private: + std::unique_ptr<std::thread> m_thread; DotRunnerQueue *m_queue; }; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 6388ce3..6163e81 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -33,6 +33,7 @@ #include <qptrdict.h> #include <qtextstream.h> +#include <algorithm> #include <unordered_map> #include <memory> @@ -81,12 +82,11 @@ #include "fortranscanner.h" #include "xmlcode.h" #include "sqlcode.h" -#include "tclscanner.h" #include "code.h" -#include "objcache.h" #include "portable.h" #include "vhdljjparser.h" #include "vhdldocgen.h" +#include "vhdlcode.h" #include "eclipsehelp.h" #include "cite.h" #include "markdown.h" @@ -120,26 +120,20 @@ extern void initResources(); ClassSDict *Doxygen::classSDict = 0; ClassSDict *Doxygen::hiddenClasses = 0; NamespaceSDict *Doxygen::namespaceSDict = 0; -MemberNameSDict *Doxygen::memberNameSDict = 0; -MemberNameSDict *Doxygen::functionNameSDict = 0; -FileNameList *Doxygen::inputNameList = 0; // all input files -FileNameDict *Doxygen::inputNameDict = 0; +MemberNameLinkedMap *Doxygen::memberNameLinkedMap = 0; +MemberNameLinkedMap *Doxygen::functionNameLinkedMap = 0; +FileNameLinkedMap *Doxygen::inputNameLinkedMap = 0; GroupSDict *Doxygen::groupSDict = 0; -FormulaList *Doxygen::formulaList = 0; // all formulas -FormulaDict *Doxygen::formulaDict = 0; // all formulas -FormulaDict *Doxygen::formulaNameDict = 0; // the label name of all formulas PageSDict *Doxygen::pageSDict = 0; PageSDict *Doxygen::exampleSDict = 0; -SectionDict *Doxygen::sectionDict = 0; // all page sections -CiteDict *Doxygen::citeDict=0; // database of bibliographic references StringDict Doxygen::aliasDict(257); // aliases QDict<void> Doxygen::inputPaths(1009); -FileNameDict *Doxygen::includeNameDict = 0; // include names -FileNameDict *Doxygen::exampleNameDict = 0; // examples -FileNameDict *Doxygen::imageNameDict = 0; // images -FileNameDict *Doxygen::dotFileNameDict = 0; // dot files -FileNameDict *Doxygen::mscFileNameDict = 0; // msc files -FileNameDict *Doxygen::diaFileNameDict = 0; // dia files +FileNameLinkedMap *Doxygen::includeNameLinkedMap = 0; // include names +FileNameLinkedMap *Doxygen::exampleNameLinkedMap = 0; // examples +FileNameLinkedMap *Doxygen::imageNameLinkedMap = 0; // images +FileNameLinkedMap *Doxygen::dotFileNameLinkedMap = 0; // dot files +FileNameLinkedMap *Doxygen::mscFileNameLinkedMap = 0; // msc files +FileNameLinkedMap *Doxygen::diaFileNameLinkedMap = 0; // dia files StringDict Doxygen::namespaceAliasDict(257); // all namespace aliases StringDict Doxygen::tagDestinationDict(257); // all tag locations QDict<void> Doxygen::expandAsDefinedDict(257); // all macros that should be expanded @@ -147,7 +141,6 @@ QIntDict<MemberGroupInfo> Doxygen::memGrpInfoDict(1009); // dictionary of the me PageDef *Doxygen::mainPage = 0; bool Doxygen::insideMainPage = FALSE; // are we generating docs for the main page? NamespaceDef *Doxygen::globalScope = 0; -QDict<RefList> *Doxygen::xrefLists = new QDict<RefList>; // dictionary of cross-referenced item lists bool Doxygen::parseSourcesNeeded = FALSE; QTime Doxygen::runningTime; SearchIndexIntf *Doxygen::searchIndex=0; @@ -165,7 +158,6 @@ bool Doxygen::suppressDocWarnings = FALSE; QCString Doxygen::objDBFileName; QCString Doxygen::entryDBFileName; QCString Doxygen::filterDBFileName; -bool Doxygen::gatherDefines = TRUE; IndexList *Doxygen::indexList; int Doxygen::subpageNestingLevel = 0; bool Doxygen::userComments = FALSE; @@ -173,7 +165,6 @@ QCString Doxygen::spaces; bool Doxygen::generatingXmlOutput = FALSE; bool Doxygen::markdownSupport = TRUE; GenericsSDict *Doxygen::genericsDict; -DocGroup Doxygen::docGroup; Preprocessor *Doxygen::preprocessor = 0; // locally accessible globals @@ -196,21 +187,18 @@ void clearAll() Doxygen::namespaceSDict->clear(); Doxygen::pageSDict->clear(); Doxygen::exampleSDict->clear(); - Doxygen::inputNameList->clear(); - Doxygen::formulaList->clear(); - Doxygen::sectionDict->clear(); - Doxygen::inputNameDict->clear(); - Doxygen::includeNameDict->clear(); - Doxygen::exampleNameDict->clear(); - Doxygen::imageNameDict->clear(); - Doxygen::dotFileNameDict->clear(); - Doxygen::mscFileNameDict->clear(); - Doxygen::diaFileNameDict->clear(); - Doxygen::formulaDict->clear(); - Doxygen::formulaNameDict->clear(); + Doxygen::inputNameLinkedMap->clear(); + Doxygen::includeNameLinkedMap->clear(); + Doxygen::exampleNameLinkedMap->clear(); + Doxygen::imageNameLinkedMap->clear(); + Doxygen::dotFileNameLinkedMap->clear(); + Doxygen::mscFileNameLinkedMap->clear(); + Doxygen::diaFileNameLinkedMap->clear(); Doxygen::tagDestinationDict.clear(); - delete Doxygen::citeDict; + SectionManager::instance().clear(); + CitationManager::instance().clear(); delete Doxygen::mainPage; Doxygen::mainPage=0; + FormulaManager::instance().clear(); } class Statistics @@ -219,7 +207,7 @@ class Statistics Statistics() { stats.setAutoDelete(TRUE); } void begin(const char *name) { - msg(name); + msg("%s", name); stat *entry= new stat(name,0); stats.append(entry); time.restart(); @@ -260,8 +248,9 @@ class Statistics void statistics() { - fprintf(stderr,"--- inputNameDict stats ----\n"); - Doxygen::inputNameDict->statistics(); +#if 0 + fprintf(stderr,"--- inputNameLinkedMap stats ----\n"); + Doxygen::inputNameLinkedMap->statistics(); fprintf(stderr,"--- includeNameDict stats ----\n"); Doxygen::includeNameDict->statistics(); fprintf(stderr,"--- exampleNameDict stats ----\n"); @@ -274,6 +263,7 @@ void statistics() Doxygen::mscFileNameDict->statistics(); fprintf(stderr,"--- diaFileNameDict stats ----\n"); Doxygen::diaFileNameDict->statistics(); +#endif //fprintf(stderr,"--- g_excludeNameDict stats ----\n"); //g_excludeNameDict.statistics(); fprintf(stderr,"--- aliasDict stats ----\n"); @@ -281,10 +271,6 @@ void statistics() fprintf(stderr,"--- typedefDict stats ----\n"); fprintf(stderr,"--- namespaceAliasDict stats ----\n"); Doxygen::namespaceAliasDict.statistics(); - fprintf(stderr,"--- formulaDict stats ----\n"); - Doxygen::formulaDict->statistics(); - fprintf(stderr,"--- formulaNameDict stats ----\n"); - Doxygen::formulaNameDict->statistics(); fprintf(stderr,"--- tagDestinationDict stats ----\n"); Doxygen::tagDestinationDict.statistics(); fprintf(stderr,"--- g_compoundKeywordDict stats ----\n"); @@ -520,7 +506,7 @@ static void buildFileList(const Entry *root) ) { bool ambig; - FileDef *fd=findFileDef(Doxygen::inputNameDict,root->name,ambig); + FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,root->name,ambig); if (!fd || ambig) { int save_ambig = ambig; @@ -528,7 +514,7 @@ static void buildFileList(const Entry *root) // directory as the describing file. QCString fn = root->fileName; int newIndex=fn.findRev('/'); - fd=findFileDef(Doxygen::inputNameDict,fn.left(newIndex) + "/" + root->name,ambig); + fd=findFileDef(Doxygen::inputNameLinkedMap,fn.left(newIndex) + "/" + root->name,ambig); if (!fd) ambig = save_ambig; } //printf("**************** root->name=%s fd=%p\n",root->name.data(),fd); @@ -563,7 +549,7 @@ static void buildFileList(const Entry *root) if (ambig) // name is ambiguous { text+="matches the following input files:\n"; - text+=showFileDefMatches(Doxygen::inputNameDict,root->name); + text+=showFileDefMatches(Doxygen::inputNameLinkedMap,root->name); text+="Please use a more specific name by " "including a (larger) part of the path!"; } @@ -571,7 +557,7 @@ static void buildFileList(const Entry *root) { text+="is not an input file"; } - warn(fn,root->startLine,text); + warn(fn,root->startLine,"%s", text.data()); } } for (const auto &e : root->children()) buildFileList(e.get()); @@ -606,7 +592,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,const Entry *root) // see if we need to include a verbatim copy of the header file //printf("root->includeFile=%s\n",root->includeFile.data()); if (!includeFile.isEmpty() && - (fd=findFileDef(Doxygen::inputNameDict,includeFile,ambig))==0 + (fd=findFileDef(Doxygen::inputNameLinkedMap,includeFile,ambig))==0 ) { // explicit request QCString text; @@ -617,7 +603,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,const Entry *root) if (ambig) // name is ambiguous { text+="matches the following input files:\n"; - text+=showFileDefMatches(Doxygen::inputNameDict,root->includeFile); + text+=showFileDefMatches(Doxygen::inputNameLinkedMap,root->includeFile); text+="Please use a more specific name by " "including a (larger) part of the path!"; } @@ -625,7 +611,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,const Entry *root) { text+="is not an input file"; } - warn(root->fileName,root->startLine,text); + warn(root->fileName,root->startLine, "%s", text.data()); } else if (includeFile.isEmpty() && ifd && // see if the file extension makes sense @@ -1011,7 +997,7 @@ static void addClassToContext(const Entry *root) if (root->bodyLine!=-1 && cd->getStartBodyLine()==-1) { - cd->setBodySegment(root->bodyLine,root->endBodyLine); + cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); cd->setBodyDef(fd); } //cd->setName(fullName); // change name to match docs @@ -1088,7 +1074,7 @@ static void addClassToContext(const Entry *root) cd->setIsStatic(root->stat); // file definition containing the class cd - cd->setBodySegment(root->bodyLine,root->endBodyLine); + cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); cd->setBodyDef(fd); cd->setMetaData(root->metaData); @@ -1294,7 +1280,7 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine()); cd->setLanguage(templ->getLanguage()); - cd->setBodySegment(templ->getStartBodyLine(),templ->getEndBodyLine()); + cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine()); cd->setBodyDef(templ->getBodyDef()); cd->setOuterScope(rootCd->getOuterScope()); @@ -1524,7 +1510,7 @@ static void buildNamespaceList(const Entry *root) tagFileName = tagInfo->fileName; } //printf("++ new namespace %s lang=%s tagName=%s\n",fullName.data(),langToString(root->lang).data(),tagName.data()); - NamespaceDef *nd=createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine, + nd=createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine, root->startColumn,fullName,tagName,tagFileName, root->type,root->spec&Entry::Published); nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition @@ -1549,7 +1535,7 @@ static void buildNamespaceList(const Entry *root) // the empty string test is needed for extract all case nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->insertUsedFile(fd); - nd->setBodySegment(root->bodyLine,root->endBodyLine); + nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); nd->setBodyDef(fd); // add class to the list Doxygen::namespaceSDict->inSort(fullName,nd); @@ -1560,7 +1546,7 @@ static void buildNamespaceList(const Entry *root) if (d==0) // we didn't find anything, create the scope artificially // anyway, so we can at least relate scopes properly. { - Definition *d = buildScopeFromQualifiedName(fullName,fullName.contains("::"),nd->getLanguage(),tagInfo); + d = buildScopeFromQualifiedName(fullName,fullName.contains("::"),nd->getLanguage(),tagInfo); d->addInnerCompound(nd); nd->setOuterScope(d); // TODO: Due to the order in which the tag file is written @@ -1716,7 +1702,7 @@ static void findUsingDirectives(const Entry *root) else // unknown namespace, but add it anyway. { //printf("++ new unknown namespace %s lang=%s\n",name.data(),langToString(root->lang).data()); - NamespaceDef *nd=createNamespaceDef(root->fileName,root->startLine,root->startColumn,name); + nd=createNamespaceDef(root->fileName,root->startLine,root->startColumn,name); nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->addSectionsToDefinition(root->anchors); @@ -1941,7 +1927,7 @@ static void findUsingDeclImports(const Entry *root) newMd->enableReferencesRelation(root->referencesRelation); newMd->setBitfields(md->bitfieldString()); newMd->addSectionsToDefinition(root->anchors); - newMd->setBodySegment(md->getStartBodyLine(),md->getEndBodyLine()); + newMd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine()); newMd->setBodyDef(md->getBodyDef()); newMd->setInitializer(md->initializer()); newMd->setMaxInitLines(md->initializerLines()); @@ -1966,24 +1952,18 @@ static void findUsingDeclImports(const Entry *root) static void findIncludedUsingDirectives() { // first mark all files as not visited - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->setVisited(FALSE); } } // then recursively add using directives found in #include files // to files that have not been visited. - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (!fd->isVisited()) { @@ -2039,7 +2019,7 @@ static MemberDef *addVariableToClass( } else { - def=type+" "+name+root->args; + def=type+" "+name+args; } } else @@ -2070,12 +2050,10 @@ static MemberDef *addVariableToClass( // see if the member is already found in the same scope // (this may be the case for a static member that is initialized // outside the class) - MemberName *mn=Doxygen::memberNameSDict->find(name); + MemberName *mn=Doxygen::memberNameLinkedMap->find(name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n", // md->getClassDef(),cd,type.data(),md->typeString()); @@ -2091,11 +2069,11 @@ static MemberDef *addVariableToClass( { // Objective-C 2.0 property // turn variable into a property md->setProtection(root->protection); - cd->reclassifyMember(md,MemberType_Property); + cd->reclassifyMember(md.get(),MemberType_Property); } - addMemberDocs(root,md,def,0,FALSE,root->spec); + addMemberDocs(root,md.get(),def,0,FALSE,root->spec); //printf(" Member already found!\n"); - return md; + return md.get(); } } } @@ -2107,12 +2085,12 @@ static MemberDef *addVariableToClass( } // new member variable, typedef or enum value - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,root->exception, prot,Normal,root->stat,related, mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - ArgumentList(), root->metaData); + ArgumentList(), root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope()) //md->setDefFile(root->fileName); @@ -2126,7 +2104,7 @@ static MemberDef *addVariableToClass( md->setFromAnonymousScope(fromAnnScope); md->setFromAnonymousMember(fromAnnMemb); //md->setIndentDepth(indentDepth); - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setInitializer(root->initializer); md->setMaxInitLines(root->initLines); md->setMemberGroupId(root->mGrpId); @@ -2141,38 +2119,24 @@ static MemberDef *addVariableToClass( md->setArtificial(root->artificial); md->setLanguage(root->lang); md->setId(root->id); - addMemberToGroups(root,md); - //if (root->mGrpId!=-1) - //{ - // printf("memberdef %s in memberGroup %d\n",name.data(),root->mGrpId); - // md->setMemberGroup(memberGroupDict[root->mGrpId]); - // + addMemberToGroups(root,md.get()); md->setBodyDef(root->fileDef()); - //printf(" Adding member=%s\n",md->name().data()); - // add the member to the global list - if (mn) - { - mn->append(md); - } - else // new variable name - { - mn = new MemberName(name); - mn->append(md); - //printf("Adding memberName=%s\n",mn->memberName()); - //Doxygen::memberNameDict.insert(name,mn); - //Doxygen::memberNameList.append(mn); - Doxygen::memberNameSDict->append(name,mn); - // add the member to the class - } //printf(" New member adding to %s (%p)!\n",cd->name().data(),cd); - cd->insertMember(md); + cd->insertMember(md.get()); md->setRefItems(root->sli); //TODO: insert FileDef instead of filename strings. cd->insertUsedFile(root->fileDef()); root->markAsProcessed(); - return md; + + //printf(" Adding member=%s\n",md->name().data()); + // add the member to the global list + MemberDef *result = md.get(); + mn = Doxygen::memberNameLinkedMap->add(name); + mn->push_back(std::move(md)); + + return result; } //---------------------------------------------------------------------- @@ -2297,7 +2261,7 @@ static MemberDef *addVariableToFile( } def.stripPrefix("static "); - MemberName *mn=Doxygen::functionNameSDict->find(name); + MemberName *mn=Doxygen::functionNameLinkedMap->find(name); if (mn) { //QCString nscope=removeAnonymousScopes(scope); @@ -2307,9 +2271,7 @@ static MemberDef *addVariableToFile( { nd = getResolvedNamespace(scope); } - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (!md->isAlias() && ((nd==0 && md->getNamespaceDef()==0 && md->getFileDef() && @@ -2337,7 +2299,7 @@ static MemberDef *addVariableToFile( { Debug::print(Debug::Variables,0, " variable already found: scope=%s\n",qPrint(md->getOuterScope()->name())); - addMemberDocs(root,md,def,0,FALSE,root->spec); + addMemberDocs(root,md.get(),def,0,FALSE,root->spec); md->setRefItems(root->sli); // if md is a variable forward declaration and root is the definition that // turn md into the definition @@ -2352,7 +2314,7 @@ static MemberDef *addVariableToFile( { md->setDeclFile(root->fileName,root->startLine,root->startColumn); } - return md; + return md.get(); } } } @@ -2367,12 +2329,12 @@ static MemberDef *addVariableToFile( Debug::print(Debug::Variables,0, " new variable, nd=%s tagInfo=%p!\n",nd?qPrint(nd->name()):"<global>",root->tagInfo()); // new global variable, enum value or typedef - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,0, root->protection, Normal,root->stat,Member, mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - ArgumentList(), root->metaData); + ArgumentList(), root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberSpecifiers(root->spec); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -2395,16 +2357,16 @@ static MemberDef *addVariableToFile( //md->setOuterScope(fd); if (!root->explicitExternal) { - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(fd); } - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); md->setRefItems(root->sli); if (nd && !nd->isAnonymous()) { md->setNamespace(nd); - nd->insertMember(md); + nd->insertMember(md.get()); } // add member to the file (we do this even if we have already inserted @@ -2412,22 +2374,17 @@ static MemberDef *addVariableToFile( if (fd) { md->setFileDef(fd); - fd->insertMember(md); + fd->insertMember(md.get()); } - // add member definition to the list of globals - if (mn) - { - mn->append(md); - } - else - { - mn = new MemberName(name); - mn->append(md); - Doxygen::functionNameSDict->append(name,mn); - } root->markAsProcessed(); - return md; + + // add member definition to the list of globals + MemberDef *result = md.get(); + mn = Doxygen::functionNameLinkedMap->add(name); + mn->push_back(std::move(md)); + + return result; } /*! See if the return type string \a type is that of a function pointer @@ -2612,11 +2569,13 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) type=name; static const QRegExp reName("[a-z_A-Z][a-z_A-Z0-9]*"); int l=0; + int j=0; int i=args.isEmpty() ? -1 : reName.match(args,0,&l); if (i!=-1) { name=args.mid(i,l); - args=args.mid(i+l,args.find(')',i+l)-i-l); + j=args.find(')',i+l)-i-l; + if (j >= 0) args=args.mid(i+l,j); } //printf("new: type='%s' name='%s' args='%s'\n", // type.data(),name.data(),args.data()); @@ -2900,17 +2859,17 @@ static void addInterfaceOrServiceToServiceOrSingleton( { fileName = root->tagInfo()->tagName; } - MemberDef *const md = createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName, root->startLine, root->startColumn, root->type, rname, "", "", root->protection, root->virt, root->stat, Member, - type, ArgumentList(), root->argList, root->metaData); + type, ArgumentList(), root->argList, root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(false); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setMemberSpecifiers(root->spec); md->setMemberGroupId(root->mGrpId); md->setTypeConstraints(root->typeConstr); @@ -2935,21 +2894,9 @@ static void addInterfaceOrServiceToServiceOrSingleton( qPrint(def) ); - // add member to the global list of all members - MemberName *mn; - if ((mn=Doxygen::memberNameSDict->find(rname))) - { - mn->append(md); - } - else - { - mn = new MemberName(rname); - mn->append(md); - Doxygen::memberNameSDict->append(rname,mn); - } // add member to the class cd - cd->insertMember(md); + cd->insertMember(md.get()); // also add the member as a "base" (to get nicer diagrams) // "optional" interface/service get Protected which turns into dashed line BaseInfo base(rname, @@ -2958,9 +2905,13 @@ static void addInterfaceOrServiceToServiceOrSingleton( // add file to list of used files cd->insertUsedFile(fd); - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); root->markAsProcessed(); md->setRefItems(root->sli); + + // add member to the global list of all members + MemberName *mn = Doxygen::memberNameLinkedMap->add(rname); + mn->push_back(std::move(md)); } static void buildInterfaceAndServiceList(const Entry *root) @@ -3084,7 +3035,7 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, // ); // adding class member - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,root->exception, protection,virt, @@ -3092,14 +3043,14 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, relates.isEmpty() ? Member : root->relatesType == MemberOf ? Foreign : Related, mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - root->argList, root->metaData); + root->argList, root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setMemberSpecifiers(spec); md->setMemberGroupId(root->mGrpId); md->setTypeConstraints(root->typeConstr); @@ -3164,30 +3115,142 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, qPrint(def) ); + // add member to the class cd + cd->insertMember(md.get()); + // add file to list of used files + cd->insertUsedFile(fd); + + addMemberToGroups(root,md.get()); + root->markAsProcessed(); + md->setRefItems(root->sli); + // add member to the global list of all members //printf("Adding member=%s class=%s\n",md->name().data(),cd->name().data()); - MemberName *mn; - if ((mn=Doxygen::memberNameSDict->find(name))) + MemberName *mn = Doxygen::memberNameLinkedMap->add(name); + mn->push_back(std::move(md)); +} + +//------------------------------------------------------------------------------------------ + +void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &sc, + NamespaceDef *nd) +{ + QCString scope = sc; + Debug::print(Debug::Functions,0," --> new function %s found!\n",qPrint(rname)); + //printf("New function type='%s' name='%s' args='%s' bodyLine=%d\n", + // root->type.data(),rname.data(),root->args.data(),root->bodyLine); + + // new global function + QCString name=removeRedundantWhiteSpace(rname); + std::unique_ptr<MemberDef> md { createMemberDef( + root->fileName,root->startLine,root->startColumn, + root->type,name,root->args,root->exception, + root->protection,root->virt,root->stat,Member, + MemberType_Function, + !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), + root->argList,root->metaData) }; + + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + //md->setDefFile(root->fileName); + //md->setDefLine(root->startLine); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->setDocsForDefinition(!root->proto); + md->setTypeConstraints(root->typeConstr); + //md->setBody(root->body); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->addSectionsToDefinition(root->anchors); + md->setMemberSpecifiers(root->spec); + md->setMemberGroupId(root->mGrpId); + + // see if the function is inside a namespace that was not part of + // the name already (in that case nd should be non-zero already) + if (nd==0 && root->parent()->section == Entry::NAMESPACE_SEC ) { - mn->append(md); + //QCString nscope=removeAnonymousScopes(root->parent()->name); + QCString nscope=root->parent()->name; + if (!nscope.isEmpty()) + { + nd = getResolvedNamespace(nscope); + } } - else + + if (!scope.isEmpty()) { - mn = new MemberName(name); - mn->append(md); - Doxygen::memberNameSDict->append(name,mn); + QCString sep = getLanguageSpecificSeparator(root->lang); + if (sep!="::") + { + scope = substitute(scope,"::",sep); + } + scope+=sep; } - // add member to the class cd - cd->insertMember(md); - // add file to list of used files - cd->insertUsedFile(fd); + QCString def; + //QCString optArgs = root->argList.empty() ? QCString() : root->args; + if (!root->type.isEmpty()) + { + def=root->type+" "+scope+name; //+optArgs; + } + else + { + def=scope+name; //+optArgs; + } + Debug::print(Debug::Functions,0, + " Global Function:\n" + " '%s' '%s'::'%s' '%s' proto=%d\n" + " def='%s'\n", + qPrint(root->type), + qPrint(root->parent()->name), + qPrint(rname), + qPrint(root->args), + root->proto, + qPrint(def) + ); + md->setDefinition(def); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + //if (root->mGrpId!=-1) + //{ + // md->setMemberGroup(memberGroupDict[root->mGrpId]); + //} - addMemberToGroups(root,md); - root->markAsProcessed(); md->setRefItems(root->sli); + if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + { + // add member to namespace + md->setNamespace(nd); + nd->insertMember(md.get()); + } + if (fd) + { + // add member to the file (we do this even if we have already + // inserted it into the namespace) + md->setFileDef(fd); + fd->insertMember(md.get()); + } + + addMemberToGroups(root,md.get()); + if (root->relatesType == Simple) // if this is a relatesalso command, + // allow find Member to pick it up + { + root->markAsProcessed(); // Otherwise we have finished with this entry. + } + + // add member to the list of file members + //printf("Adding member=%s\n",md->name().data()); + MemberName *mn = Doxygen::functionNameLinkedMap->add(name); + mn->push_back(std::move(md)); } +//------------------------------------------------------------------------------------------ static void buildFunctionList(const Entry *root) { @@ -3298,12 +3361,11 @@ static void buildFunctionList(const Entry *root) */ bool found=FALSE; MemberName *mn; - MemberDef *md=0; - if ((mn=Doxygen::functionNameSDict->find(rname))) + MemberDef *md_found=0; + if ((mn=Doxygen::functionNameLinkedMap->find(rname))) { Debug::print(Debug::Functions,0," --> function %s already found!\n",qPrint(rname)); - MemberNameIterator mni(*mn); - for (mni.toFirst();(!found && (md=mni.current()));++mni) + for (const auto &md : *mn) { if (!md->isAlias()) { @@ -3405,7 +3467,7 @@ static void buildFunctionList(const Entry *root) md->setDocsForDefinition(!root->proto); if (md->getStartBodyLine()==-1 && root->bodyLine!=-1) { - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(rfd); } @@ -3425,7 +3487,7 @@ static void buildFunctionList(const Entry *root) // merge ingroup specifiers if (md->getGroupDef()==0 && !root->groups.empty()) { - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } else if (md->getGroupDef()!=0 && root->groups.empty()) { @@ -3451,130 +3513,16 @@ static void buildFunctionList(const Entry *root) } } } + if (found) + { + md_found = md.get(); + break; + } } } if (!found) /* global function is unique with respect to the file */ { - Debug::print(Debug::Functions,0," --> new function %s found!\n",qPrint(rname)); - //printf("New function type='%s' name='%s' args='%s' bodyLine=%d\n", - // root->type.data(),rname.data(),root->args.data(),root->bodyLine); - - // new global function - QCString name=removeRedundantWhiteSpace(rname); - md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - root->type,name,root->args,root->exception, - root->protection,root->virt,root->stat,Member, - MemberType_Function, - !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - root->argList,root->metaData); - - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - //md->setDefFile(root->fileName); - //md->setDefLine(root->startLine); - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->setDocsForDefinition(!root->proto); - md->setTypeConstraints(root->typeConstr); - //md->setBody(root->body); - md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->addSectionsToDefinition(root->anchors); - md->setMemberSpecifiers(root->spec); - md->setMemberGroupId(root->mGrpId); - - // see if the function is inside a namespace that was not part of - // the name already (in that case nd should be non-zero already) - if (nd==0 && root->parent()->section == Entry::NAMESPACE_SEC ) - { - //QCString nscope=removeAnonymousScopes(root->parent()->name); - QCString nscope=root->parent()->name; - if (!nscope.isEmpty()) - { - nd = getResolvedNamespace(nscope); - } - } - - if (!scope.isEmpty()) - { - QCString sep = getLanguageSpecificSeparator(root->lang); - if (sep!="::") - { - scope = substitute(scope,"::",sep); - } - scope+=sep; - } - - QCString def; - //QCString optArgs = root->argList.empty() ? QCString() : root->args; - if (!root->type.isEmpty()) - { - def=root->type+" "+scope+name; //+optArgs; - } - else - { - def=scope+name; //+optArgs; - } - Debug::print(Debug::Functions,0, - " Global Function:\n" - " '%s' '%s'::'%s' '%s' proto=%d\n" - " def='%s'\n", - qPrint(root->type), - qPrint(root->parent()->name), - qPrint(rname), - qPrint(root->args), - root->proto, - qPrint(def) - ); - md->setDefinition(def); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - //if (root->mGrpId!=-1) - //{ - // md->setMemberGroup(memberGroupDict[root->mGrpId]); - //} - - md->setRefItems(root->sli); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') - { - // add member to namespace - md->setNamespace(nd); - nd->insertMember(md); - } - if (fd) - { - // add member to the file (we do this even if we have already - // inserted it into the namespace) - md->setFileDef(fd); - fd->insertMember(md); - } - - // add member to the list of file members - //printf("Adding member=%s\n",md->name().data()); - MemberName *mn; - if ((mn=Doxygen::functionNameSDict->find(name))) - { - mn->append(md); - } - else - { - mn = new MemberName(name); - mn->append(md); - Doxygen::functionNameSDict->append(name,mn); - } - addMemberToGroups(root,md); - if (root->relatesType == Simple) // if this is a relatesalso command, - // allow find Member to pick it up - { - root->markAsProcessed(); // Otherwise we have finished with this entry. - } + addGlobalFunction(root,rname,scope,nd); } else { @@ -3583,7 +3531,7 @@ static void buildFunctionList(const Entry *root) { // add member to the file (we do this even if we have already // inserted it into the namespace) - fd->insertMember(md); + fd->insertMember(md_found); } } @@ -3610,25 +3558,21 @@ static void buildFunctionList(const Entry *root) static void findFriends() { //printf("findFriends()\n"); - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *fn; - for (;(fn=fnli.current());++fnli) // for each global function name + for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name { //printf("Function name='%s'\n",fn->memberName()); MemberName *mn; - if ((mn=Doxygen::memberNameSDict->find(fn->memberName()))) + if ((mn=Doxygen::memberNameLinkedMap->find(fn->memberName()))) { // there are members with the same name //printf("Function name is also a member name\n"); - MemberNameIterator fni(*fn); - MemberDef *fmd; - for (;(fmd=fni.current());++fni) // for each function with that name + // for each function with that name + for (const auto &fmd : *fn) { - const MemberDef *cfmd = const_cast<const MemberDef*>(fmd); - MemberNameIterator mni(*mn); - MemberDef *mmd; - for (;(mmd=mni.current());++mni) // for each member with that name + const MemberDef *cfmd = fmd.get(); + // for each member with that name + for (const auto &mmd : *mn) { - const MemberDef *cmmd = const_cast<const MemberDef*>(mmd); + const MemberDef *cmmd = mmd.get(); //printf("Checking for matching arguments // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n", // mmd->isRelated(),mmd->isFriend(),mmd->isFunction()); @@ -3672,13 +3616,13 @@ static void findFriends() //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine()); if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1) { - mmd->setBodySegment(fmd->getStartBodyLine(),fmd->getEndBodyLine()); + mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine()); mmd->setBodyDef(fmd->getBodyDef()); //mmd->setBodyMember(fmd); } else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1) { - fmd->setBodySegment(mmd->getStartBodyLine(),mmd->getEndBodyLine()); + fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine()); fmd->setBodyDef(mmd->getBodyDef()); //fmd->setBodyMember(mmd); } @@ -3707,26 +3651,23 @@ static void transferFunctionDocumentation() //printf("---- transferFunctionDocumentation()\n"); // find matching function declaration and definitions. - MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); - MemberName *mn; - for (;(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { //printf("memberName=%s count=%d\n",mn->memberName(),mn->count()); - MemberDef *mdef=0,*mdec=0; - MemberNameIterator mni1(*mn); /* find a matching function declaration and definition for this function */ - for (;(mdec=mni1.current());++mni1) + for (const auto &mdec : *mn) { if (mdec->isPrototype() || (mdec->isVariable() && mdec->isExternal()) ) { - MemberNameIterator mni2(*mn); - for (;(mdef=mni2.current());++mni2) + for (const auto &mdef : *mn) { - if (mdec!=mdef && !mdec->isAlias() && !mdef->isAlias()) + if (mdec!=mdef && + !mdec->isAlias() && !mdef->isAlias() && + mdec->getNamespaceDef()==mdef->getNamespaceDef()) { - combineDeclarationAndDefinition(mdec,mdef); + combineDeclarationAndDefinition(mdec.get(),mdef.get()); } } } @@ -3738,24 +3679,23 @@ static void transferFunctionDocumentation() static void transferFunctionReferences() { - MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); - MemberName *mn; - for (;(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md,*mdef=0,*mdec=0; - MemberNameIterator mni(*mn); + MemberDef *mdef=0,*mdec=0; /* find a matching function declaration and definition for this function */ - for (;(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->isPrototype()) - mdec=md; + mdec=md.get(); else if (md->isVariable() && md->isExternal()) - mdec=md; + mdec=md.get(); if (md->isFunction() && !md->isStatic() && !md->isPrototype()) - mdef=md; + mdef=md.get(); else if (md->isVariable() && !md->isExternal() && !md->isStatic()) - mdef=md; + mdef=md.get(); + + if (mdef && mdec) break; } if (mdef && mdec) { @@ -3832,23 +3772,19 @@ static void transferRelatedFunctionDocumentation() { // find match between function declaration and definition for // related functions - MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); - MemberName *mn; - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); /* find a matching function declaration and definition for this function */ - for (mni.toFirst();(md=mni.current());++mni) // for each global function + // for each global function + for (const auto &md : *mn) { //printf(" Function '%s'\n",md->name().data()); MemberName *rmn; - if ((rmn=Doxygen::memberNameSDict->find(md->name()))) // check if there is a member with the same name + if ((rmn=Doxygen::memberNameLinkedMap->find(md->name()))) // check if there is a member with the same name { //printf(" Member name found\n"); - MemberDef *rmd; - MemberNameIterator rmni(*rmn); - for (rmni.toFirst();(rmd=rmni.current());++rmni) // for each member with the same name + // for each member with the same name + for (const auto &rmd : *rmn) { //printf(" Member found: related='%d'\n",rmd->isRelated()); if ((rmd->isRelated() || rmd->isForeign()) && // related function @@ -4021,7 +3957,6 @@ static void findUsedClassesForClass(const Entry *root, BaseInfo bi(usedName,Public,Normal); findClassRelation(root,context,instanceCd,&bi,templateNames,TemplateInstances,isArtificial); - int count=0; for (const Argument &arg : masterCd->templateArguments()) { if (arg.name==usedName) // type is a template argument @@ -4609,7 +4544,7 @@ static bool findClassRelation( Doxygen::classSDict->append(baseClassName,baseClass); if (isArtificial) baseClass->setArtificial(TRUE); baseClass->setLanguage(root->lang); - int si = baseClassName.findRev("::"); + si = baseClassName.findRev("::"); if (si!=-1) // class is nested { Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo()); @@ -4887,13 +4822,9 @@ static void computeMemberReferences() { cd->computeAnchors(); } - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->computeAnchors(); } @@ -4926,13 +4857,9 @@ static void addListReferences() } } - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->addListReferences(); } @@ -4965,7 +4892,7 @@ static void addListReferences() name = pd->getGroupDef()->getOutputFileBase(); } { - const std::vector<ListItemInfo> &xrefItems = pd->xrefListItems(); + const std::vector<RefItem*> &xrefItems = pd->xrefListItems(); addRefItem(xrefItems, name, theTranslator->trPage(TRUE,TRUE), @@ -4982,7 +4909,7 @@ static void addListReferences() //{ // name = dd->getGroupDef()->getOutputFileBase(); //} - const std::vector<ListItemInfo> &xrefItems = dd->xrefListItems(); + const std::vector<RefItem*> &xrefItems = dd->xrefListItems(); addRefItem(xrefItems, name, theTranslator->trDir(TRUE,TRUE), @@ -4994,9 +4921,7 @@ static void addListReferences() static void generateXRefPages() { - QDictIterator<RefList> di(*Doxygen::xrefLists); - RefList *rl; - for (di.toFirst();(rl=di.current());++di) + for (RefListManager::Ptr &rl : RefListManager::instance()) { rl->generatePage(); } @@ -5109,7 +5034,7 @@ static void addMemberDocs(const Entry *root, ) { //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine); - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(rfd); } @@ -5180,19 +5105,17 @@ static bool findGlobalMember(const Entry *root, QCString n=name; if (n.isEmpty()) return FALSE; if (n.find("::")!=-1) return FALSE; // skip undefined class members - MemberName *mn=Doxygen::functionNameSDict->find(n+tempArg); // look in function dictionary + MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary if (mn==0) { - mn=Doxygen::functionNameSDict->find(n); // try without template arguments + mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments } if (mn) // function name defined { Debug::print(Debug::FindMembers,0,"3. Found symbol scope\n"); //int count=0; - MemberNameIterator mni(*mn); - MemberDef *md; bool found=FALSE; - for (mni.toFirst();(md=mni.current()) && !found;++mni) + for (const auto &md : *mn) { const NamespaceDef *nd=0; if (md->isAlias() && md->getOuterScope() && @@ -5228,11 +5151,11 @@ static bool findGlobalMember(const Entry *root, NamespaceDef *rnd = 0; if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName); - const ArgumentList &mdAl = const_cast<const MemberDef *>(md)->argumentList(); + const ArgumentList &mdAl = const_cast<const MemberDef *>(md.get())->argumentList(); bool matching= (mdAl.empty() && root->argList.empty()) || md->isVariable() || md->isTypedef() || /* in case of function pointers */ - matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md)->getFileDef(),mdAl, + matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md.get())->getFileDef(),mdAl, rnd ? rnd : Doxygen::globalScope,fd,root->argList, FALSE); @@ -5258,7 +5181,7 @@ static bool findGlobalMember(const Entry *root, // put the comment block at the first syntactically matching member. if (matching && md->isStatic() && md->getDefFileName()!=root->fileName && - mn->count()>1) + mn->size()>1) { matching = FALSE; } @@ -5281,6 +5204,7 @@ static bool findGlobalMember(const Entry *root, Debug::print(Debug::FindMembers,0,"5. Match found\n"); addMemberDocs(root,md->resolveAlias(),decl,&root->argList,FALSE,root->spec); found=TRUE; + break; } } } @@ -5290,10 +5214,10 @@ static bool findGlobalMember(const Entry *root, if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,TRUE); QCString warnMsg = QCString("no matching file member found for \n")+substitute(fullFuncDecl,"%","%%"); - if (mn->count()>0) + if (mn->size()>0) { warnMsg+="\nPossible candidates:\n"; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { warnMsg+=" '"; warnMsg+=substitute(md->declaration(),"%","%%"); @@ -5301,7 +5225,7 @@ static bool findGlobalMember(const Entry *root, " of file "+md->getDefFileName()+"\n"; } } - warn(root->fileName,root->startLine,warnMsg); + warn(root->fileName,root->startLine, "%s", warnMsg.data()); } } else // got docs for an undefined member! @@ -5467,7 +5391,506 @@ static void substituteTemplatesInArgList( // ); } +//------------------------------------------------------------------------------------------- + +static void addLocalObjCMethod(const Entry *root, + const QCString &scopeName, + const QCString &funcType,const QCString &funcName,const QCString &funcArgs, + const QCString &exceptions,const QCString &funcDecl, + uint64 spec) +{ + //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); + ClassDef *cd=0; + if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClass(scopeName))) + { + Debug::print(Debug::FindMembers,0,"4. Local objective C method %s\n" + " scopeName=%s\n",qPrint(root->name),qPrint(scopeName)); + //printf("Local objective C method '%s' of class '%s' found\n",root->name.data(),cd->name().data()); + std::unique_ptr<MemberDef> md { createMemberDef( + root->fileName,root->startLine,root->startColumn, + funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,Member, + MemberType_Function,ArgumentList(),root->argList,root->metaData) }; + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + md->makeImplementationDetail(); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->setMemberSpecifiers(spec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md.get()); + cd->insertUsedFile(fd); + md->setRefItems(root->sli); + + MemberName *mn = Doxygen::memberNameLinkedMap->add(root->name); + mn->push_back(std::move(md)); + } + else + { + // local objective C method found for class without interface + } +} + +//------------------------------------------------------------------------------------------- + +static void addMemberFunction(const Entry *root, + MemberName *mn, + const QCString &scopeName, + const QCString &namespaceName, + const QCString &className, + const QCString &funcTyp, + const QCString &funcName, + const QCString &funcArgs, + const QCString &funcTempList, + const QCString &exceptions, + const QCString &type, + const QCString &args, + bool isFriend, + uint64 spec, + const QCString &relates, + const QCString &funcDecl, + bool overloaded, + bool isFunc) +{ + QCString funcType = funcTyp; + int count=0; + int noMatchCount=0; + bool memFound=FALSE; + for (const auto &md : *mn) + { + ClassDef *cd=md->getClassDef(); + Debug::print(Debug::FindMembers,0, + "3. member definition found, " + "scope needed='%s' scope='%s' args='%s' fileName=%s\n", + qPrint(scopeName),cd ? qPrint(cd->name()) : "<none>", + qPrint(md->argsString()), + qPrint(root->fileName)); + //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data()); + FileDef *fd=root->fileDef(); + NamespaceDef *nd=0; + if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); + + //printf("scopeName %s->%s\n",scopeName.data(), + // stripTemplateSpecifiersFromScope(scopeName,FALSE).data()); + + const ClassDef *tcd=findClassDefinition(fd,nd,scopeName); + if (tcd==0 && cd && stripAnonymousNamespaceScope(cd->name())==scopeName) + { + // don't be fooled by anonymous scopes + tcd=cd; + } + //printf("Looking for %s inside nd=%s result=%p (%s) cd=%p\n", + // scopeName.data(),nd?nd->name().data():"<none>",tcd,tcd?tcd->name().data():"",cd); + + if (cd && tcd==cd) // member's classes match + { + Debug::print(Debug::FindMembers,0, + "4. class definition %s found\n",cd->name().data()); + + // get the template parameter lists found at the member declaration + std::vector<ArgumentList> declTemplArgs = cd->getTemplateParameterLists(); + const ArgumentList &templAl = md->templateArguments(); + if (!templAl.empty()) + { + declTemplArgs.push_back(templAl); + } + + // get the template parameter lists found at the member definition + const std::vector<ArgumentList> &defTemplArgs = root->tArgLists; + //printf("defTemplArgs=%p\n",defTemplArgs); + + // do we replace the decl argument lists with the def argument lists? + bool substDone=FALSE; + ArgumentList argList; + + /* substitute the occurrences of class template names in the + * argument list before matching + */ + const ArgumentList &mdAl = md->argumentList(); + if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size()) + { + /* the function definition has template arguments + * and the class definition also has template arguments, so + * we must substitute the template names of the class by that + * of the function definition before matching. + */ + substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList); + + substDone=TRUE; + } + else /* no template arguments, compare argument lists directly */ + { + argList = mdAl; + } + + Debug::print(Debug::FindMembers,0, + "5. matching '%s'<=>'%s' className=%s namespaceName=%s\n", + qPrint(argListToString(argList,TRUE)),qPrint(argListToString(root->argList,TRUE)), + qPrint(className),qPrint(namespaceName) + ); + bool matching= + md->isVariable() || md->isTypedef() || // needed for function pointers + matchArguments2( + md->getClassDef(),md->getFileDef(),argList, + cd,fd,root->argList, + TRUE); + + if (md->getLanguage()==SrcLangExt_ObjC && md->isVariable() && (root->section&Entry::FUNCTION_SEC)) + { + matching = FALSE; // don't match methods and attributes with the same name + } + + // for template member we also need to check the return type + if (!md->templateArguments().empty() && !root->tArgLists.empty()) + { + QCString memType = md->typeString(); + memType.stripPrefix("static "); // see bug700696 + funcType=substitute(stripTemplateSpecifiersFromScope(funcType,TRUE), + className+"::",""); // see bug700693 & bug732594 + memType=substitute(stripTemplateSpecifiersFromScope(memType,TRUE), + className+"::",""); // see bug758900 + Debug::print(Debug::FindMembers,0, + "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n", + qPrint(md->typeString()),qPrint(funcType), + md->templateArguments().size(),root->tArgLists.back().size()); + if (md->templateArguments().size()!=root->tArgLists.back().size() || + qstrcmp(memType,funcType)) + { + //printf(" ---> no matching\n"); + matching = FALSE; + } + } + bool rootIsUserDoc = (root->section&Entry::MEMBERDOC_SEC)!=0; + bool classIsTemplate = scopeIsTemplate(md->getClassDef()); + bool mdIsTemplate = md->templateArguments().hasParameters(); + bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate; + bool rootIsTemplate = !root->tArgLists.empty(); + //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate); + if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457 + (mdIsTemplate || rootIsTemplate) && // either md or root is a template + ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate)) + ) + { + // Method with template return type does not match method without return type + // even if the parameters are the same. See also bug709052 + Debug::print(Debug::FindMembers,0, + "5b. Comparing return types: template v.s. non-template\n"); + matching = FALSE; + } + + + Debug::print(Debug::FindMembers,0, + "6. match results of matchArguments2 = %d substDone=%d\n",matching,substDone); + + if (substDone) // found a new argument list + { + if (matching) // replace member's argument list + { + md->setDefinitionTemplateParameterLists(root->tArgLists); + md->setArgumentList(argList); + } + else // no match + { + if (!funcTempList.isEmpty() && + isSpecialization(declTemplArgs,defTemplArgs)) + { + // check if we are dealing with a partial template + // specialization. In this case we add it to the class + // even though the member arguments do not match. + + addMethodToClass(root,cd,type,md->name(),args,isFriend, + md->protection(),md->isStatic(),md->virtualness(),spec,relates); + return; + } + } + } + if (matching) + { + addMemberDocs(root,md.get(),funcDecl,0,overloaded,spec); + count++; + memFound=TRUE; + } + } + else if (cd && cd!=tcd) // we did find a class with the same name as cd + // but in a different namespace + { + noMatchCount++; + } + + if (memFound) break; + } + if (count==0 && root->parent() && + root->parent()->section==Entry::OBJCIMPL_SEC) + { + addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec); + return; + } + if (count==0 && !(isFriend && funcType=="class")) + { + int candidates=0; + const ClassDef *ecd = 0, *ucd = 0; + MemberDef *emd = 0, *umd = 0; + //printf("Assume template class\n"); + for (const auto &md : *mn) + { + ClassDef *ccd=md->getClassDef(); + MemberDef *cmd=md.get(); + //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); + if (ccd!=0 && rightScopeMatch(ccd->name(),className)) + { + const ArgumentList &templAl = md->templateArguments(); + if (!root->tArgLists.empty() && !templAl.empty() && + root->tArgLists.back().size()<=templAl.size()) + { + Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); + addMethodToClass(root,ccd,type,md->name(),args,isFriend, + root->protection,root->stat,root->virt,spec,relates); + return; + } + if (md->argsString()==argListToString(root->argList,TRUE,FALSE)) + { // exact argument list match -> remember + ucd = ecd = ccd; + umd = emd = cmd; + Debug::print(Debug::FindMembers,0, + "7. new candidate className=%s scope=%s args=%s exact match\n", + qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); + } + else // arguments do not match, but member name and scope do -> remember + { + ucd = ccd; + umd = cmd; + Debug::print(Debug::FindMembers,0, + "7. new candidate className=%s scope=%s args=%s no match\n", + qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); + } + candidates++; + } + } + static bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING); + if (!strictProtoMatching) + { + if (candidates==1 && ucd && umd) + { + // we didn't find an actual match on argument lists, but there is only 1 member with this + // name in the same scope, so that has to be the one. + addMemberDocs(root,umd,funcDecl,0,overloaded,spec); + return; + } + else if (candidates>1 && ecd && emd) + { + // we didn't find a unique match using type resolution, + // but one of the matches has the exact same signature so + // we take that one. + addMemberDocs(root,emd,funcDecl,0,overloaded,spec); + return; + } + } + + QCString warnMsg = "no "; + if (noMatchCount>1) warnMsg+="uniquely "; + warnMsg+="matching class member found for \n"; + + for (const ArgumentList &al : root->tArgLists) + { + warnMsg+=" template "; + warnMsg+=tempArgListToString(al,root->lang); + warnMsg+='\n'; + } + + QCString fullFuncDecl=funcDecl.copy(); + if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); + + warnMsg+=" "; + warnMsg+=fullFuncDecl; + warnMsg+='\n'; + + if (candidates>0) + { + warnMsg+="Possible candidates:\n"; + for (const auto &md : *mn) + { + ClassDef *cd=md->getClassDef(); + if (cd!=0 && rightScopeMatch(cd->name(),className)) + { + const ArgumentList &templAl = md->templateArguments(); + warnMsg+=" '"; + if (templAl.hasParameters()) + { + warnMsg+="template "; + warnMsg+=tempArgListToString(templAl,root->lang); + warnMsg+='\n'; + warnMsg+=" "; + } + if (md->typeString()) + { + warnMsg+=md->typeString(); + warnMsg+=' '; + } + QCString qScope = cd->qualifiedNameWithTemplateParameters(); + if (!qScope.isEmpty()) + warnMsg+=qScope+"::"+md->name(); + if (md->argsString()) + warnMsg+=md->argsString(); + if (noMatchCount>1) + { + warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + + " of file "+md->getDefFileName(); + } + else + warnMsg += "'"; + + warnMsg+='\n'; + } + } + } + warn_simple(root->fileName,root->startLine,warnMsg); + } +} + +//------------------------------------------------------------------------------------------- + +static void addMemberSpecialization(const Entry *root, + MemberName *mn, + ClassDef *cd, + const QCString &funcType, + const QCString &funcName, + const QCString &funcArgs, + const QCString &funcDecl, + const QCString &exceptions, + uint64 spec + ) +{ + MemberDef *declMd=0; + for (const auto &md : *mn) + { + if (md->getClassDef()==cd) + { + // TODO: we should probably also check for matching arguments + declMd = md.get(); + break; + } + } + MemberType mtype=MemberType_Function; + ArgumentList tArgList; + // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); + std::unique_ptr<MemberDef> md { createMemberDef( + root->fileName,root->startLine,root->startColumn, + funcType,funcName,funcArgs,exceptions, + declMd ? declMd->protection() : root->protection, + root->virt,root->stat,Member, + mtype,tArgList,root->argList,root->metaData) }; + //printf("new specialized member %s args='%s'\n",md->name().data(),funcArgs.data()); + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + md->setMemberClass(cd); + md->setTemplateSpecialization(TRUE); + md->setTypeConstraints(root->typeConstr); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->setMemberSpecifiers(spec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md.get()); + md->setRefItems(root->sli); + + mn->push_back(std::move(md)); +} + +//------------------------------------------------------------------------------------------- + +static void addOverloaded(const Entry *root,MemberName *mn, + const QCString &funcType,const QCString &funcName,const QCString &funcArgs, + const QCString &funcDecl,const QCString &exceptions,uint64 spec) +{ + // for unique overloaded member we allow the class to be + // omitted, this is to be Qt compatible. Using this should + // however be avoided, because it is error prone + bool sameClass=false; + if (mn->size()>0) + { + // check if all members with the same name are also in the same class + sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(), + [](const auto &md1,const auto &md2) + { return md1->getClassDef()->name()==md2->getClassDef()->name(); }); + } + if (sameClass) + { + ClassDef *cd = mn->front()->getClassDef(); + MemberType mtype; + if (root->mtype==Signal) mtype=MemberType_Signal; + else if (root->mtype==Slot) mtype=MemberType_Slot; + else if (root->mtype==DCOP) mtype=MemberType_DCOP; + else mtype=MemberType_Function; + + // new overloaded member function + ArgumentList tArgList = + getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); + //printf("new related member %s args='%s'\n",md->name().data(),funcArgs.data()); + std::unique_ptr<MemberDef> md { createMemberDef( + root->fileName,root->startLine,root->startColumn, + funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,Related, + mtype,tArgList,root->argList,root->metaData) }; + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + md->setTypeConstraints(root->typeConstr); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + QCString doc=getOverloadDocs(); + doc+="<p>"; + doc+=root->doc; + md->setDocumentation(doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->setMemberSpecifiers(spec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md.get()); + cd->insertUsedFile(fd); + md->setRefItems(root->sli); + + mn->push_back(std::move(md)); + } +} + +//------------------------------------------------------------------------------------------- /*! This function tries to find a member (in a documented class/file/namespace) * that corresponds to the function/variable declaration given in \a funcDecl. @@ -5696,7 +6119,7 @@ static void findMember(const Entry *root, { if (funcSpec.isEmpty()) { - int argListIndex=0; + uint argListIndex=0; tempScopeName=cd->qualifiedNameWithTemplateParameters(&root->tArgLists,&argListIndex); } else @@ -5796,366 +6219,27 @@ static void findMember(const Entry *root, } if (!funcTempList.isEmpty()) // try with member specialization { - mn=Doxygen::memberNameSDict->find(funcName+funcTempList); + mn=Doxygen::memberNameLinkedMap->find(funcName+funcTempList); } if (mn==0) // try without specialization { - mn=Doxygen::memberNameSDict->find(funcName); + mn=Doxygen::memberNameLinkedMap->find(funcName); } if (!isRelated && mn) // function name already found { Debug::print(Debug::FindMembers,0, - "2. member name exists (%d members with this name)\n",mn->count()); + "2. member name exists (%d members with this name)\n",mn->size()); if (!className.isEmpty()) // class name is valid { if (funcSpec.isEmpty()) // not a member specialization { - int count=0; - int noMatchCount=0; - MemberNameIterator mni(*mn); - MemberDef *md; - bool memFound=FALSE; - for (mni.toFirst();!memFound && (md=mni.current());++mni) - { - ClassDef *cd=md->getClassDef(); - Debug::print(Debug::FindMembers,0, - "3. member definition found, " - "scope needed='%s' scope='%s' args='%s' fileName=%s\n", - qPrint(scopeName),cd ? qPrint(cd->name()) : "<none>", - qPrint(md->argsString()), - qPrint(root->fileName)); - //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data()); - FileDef *fd=root->fileDef(); - NamespaceDef *nd=0; - if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); - - //printf("scopeName %s->%s\n",scopeName.data(), - // stripTemplateSpecifiersFromScope(scopeName,FALSE).data()); - - const ClassDef *tcd=findClassDefinition(fd,nd,scopeName); - if (tcd==0 && cd && stripAnonymousNamespaceScope(cd->name())==scopeName) - { - // don't be fooled by anonymous scopes - tcd=cd; - } - //printf("Looking for %s inside nd=%s result=%p (%s) cd=%p\n", - // scopeName.data(),nd?nd->name().data():"<none>",tcd,tcd?tcd->name().data():"",cd); - - if (cd && tcd==cd) // member's classes match - { - Debug::print(Debug::FindMembers,0, - "4. class definition %s found\n",cd->name().data()); - - // get the template parameter lists found at the member declaration - std::vector<ArgumentList> declTemplArgs = cd->getTemplateParameterLists(); - const ArgumentList &templAl = md->templateArguments(); - if (!templAl.empty()) - { - declTemplArgs.push_back(templAl); - } - - // get the template parameter lists found at the member definition - const std::vector<ArgumentList> &defTemplArgs = root->tArgLists; - //printf("defTemplArgs=%p\n",defTemplArgs); - - // do we replace the decl argument lists with the def argument lists? - bool substDone=FALSE; - ArgumentList argList; - - /* substitute the occurrences of class template names in the - * argument list before matching - */ - const ArgumentList &mdAl = md->argumentList(); - if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size()) - { - /* the function definition has template arguments - * and the class definition also has template arguments, so - * we must substitute the template names of the class by that - * of the function definition before matching. - */ - substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList); - - substDone=TRUE; - } - else /* no template arguments, compare argument lists directly */ - { - argList = mdAl; - } - - Debug::print(Debug::FindMembers,0, - "5. matching '%s'<=>'%s' className=%s namespaceName=%s\n", - qPrint(argListToString(argList,TRUE)),qPrint(argListToString(root->argList,TRUE)), - qPrint(className),qPrint(namespaceName) - ); - - bool matching= - md->isVariable() || md->isTypedef() || // needed for function pointers - (mdAl.empty() && root->argList.empty()) || - matchArguments2( - md->getClassDef(),md->getFileDef(),argList, - cd,fd,root->argList, - TRUE); - - if (md->getLanguage()==SrcLangExt_ObjC && md->isVariable() && (root->section&Entry::FUNCTION_SEC)) - { - matching = FALSE; // don't match methods and attributes with the same name - } - - // for template member we also need to check the return type - if (!md->templateArguments().empty() && !root->tArgLists.empty()) - { - QCString memType = md->typeString(); - memType.stripPrefix("static "); // see bug700696 - funcType=substitute(stripTemplateSpecifiersFromScope(funcType,TRUE), - className+"::",""); // see bug700693 & bug732594 - memType=substitute(stripTemplateSpecifiersFromScope(memType,TRUE), - className+"::",""); // see bug758900 - Debug::print(Debug::FindMembers,0, - "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n", - qPrint(md->typeString()),qPrint(funcType), - md->templateArguments().size(),root->tArgLists.back().size()); - if (md->templateArguments().size()!=root->tArgLists.back().size() || - qstrcmp(memType,funcType)) - { - //printf(" ---> no matching\n"); - matching = FALSE; - } - } - bool rootIsUserDoc = (root->section&Entry::MEMBERDOC_SEC)!=0; - bool classIsTemplate = scopeIsTemplate(md->getClassDef()); - bool mdIsTemplate = md->templateArguments().hasParameters(); - bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate; - bool rootIsTemplate = !root->tArgLists.empty(); - //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate); - if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457 - (mdIsTemplate || rootIsTemplate) && // either md or root is a template - ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate)) - ) - { - // Method with template return type does not match method without return type - // even if the parameters are the same. See also bug709052 - Debug::print(Debug::FindMembers,0, - "5b. Comparing return types: template v.s. non-template\n"); - matching = FALSE; - } - - - Debug::print(Debug::FindMembers,0, - "6. match results of matchArguments2 = %d substDone=%d\n",matching,substDone); - - if (substDone) // found a new argument list - { - if (matching) // replace member's argument list - { - md->setDefinitionTemplateParameterLists(root->tArgLists); - md->setArgumentList(argList); - } - else // no match - { - if (!funcTempList.isEmpty() && - isSpecialization(declTemplArgs,defTemplArgs)) - { - // check if we are dealing with a partial template - // specialization. In this case we add it to the class - // even though the member arguments do not match. - - addMethodToClass(root,cd,type,md->name(),args,isFriend, - md->protection(),md->isStatic(),md->virtualness(),spec,relates); - return; - } - } - } - if (matching) - { - addMemberDocs(root,md,funcDecl,0,overloaded,spec); - count++; - memFound=TRUE; - } - } - else if (cd && cd!=tcd) // we did find a class with the same name as cd - // but in a different namespace - { - noMatchCount++; - } - } - if (count==0 && root->parent() && - root->parent()->section==Entry::OBJCIMPL_SEC) - { - goto localObjCMethod; - } - if (count==0 && !(isFriend && funcType=="class")) - { - int candidates=0; - const ClassDef *ecd = 0, *ucd = 0; - MemberDef *emd = 0, *umd = 0; - if (mn->count()>0) - { - //printf("Assume template class\n"); - for (mni.toFirst();(md=mni.current());++mni) - { - ClassDef *ccd=md->getClassDef(); - MemberDef *cmd=md; - //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); - if (ccd!=0 && rightScopeMatch(ccd->name(),className)) - { - const ArgumentList &templAl = md->templateArguments(); - if (!root->tArgLists.empty() && !templAl.empty() && - root->tArgLists.back().size()<=templAl.size()) - { - Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); - addMethodToClass(root,ccd,type,md->name(),args,isFriend, - root->protection,root->stat,root->virt,spec,relates); - return; - } - if (md->argsString()==argListToString(root->argList,TRUE,FALSE)) - { // exact argument list match -> remember - ucd = ecd = ccd; - umd = emd = cmd; - Debug::print(Debug::FindMembers,0, - "7. new candidate className=%s scope=%s args=%s exact match\n", - qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); - } - else // arguments do not match, but member name and scope do -> remember - { - ucd = ccd; - umd = cmd; - Debug::print(Debug::FindMembers,0, - "7. new candidate className=%s scope=%s args=%s no match\n", - qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); - } - candidates++; - } - } - } - static bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING); - if (!strictProtoMatching) - { - if (candidates==1 && ucd && umd) - { - // we didn't find an actual match on argument lists, but there is only 1 member with this - // name in the same scope, so that has to be the one. - addMemberDocs(root,umd,funcDecl,0,overloaded,spec); - return; - } - else if (candidates>1 && ecd && emd) - { - // we didn't find a unique match using type resolution, - // but one of the matches has the exact same signature so - // we take that one. - addMemberDocs(root,emd,funcDecl,0,overloaded,spec); - return; - } - } - - QCString warnMsg = "no "; - if (noMatchCount>1) warnMsg+="uniquely "; - warnMsg+="matching class member found for \n"; - - for (const ArgumentList &al : root->tArgLists) - { - warnMsg+=" template "; - warnMsg+=tempArgListToString(al,root->lang); - warnMsg+='\n'; - } - - QCString fullFuncDecl=funcDecl.copy(); - if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); - - warnMsg+=" "; - warnMsg+=fullFuncDecl; - warnMsg+='\n'; - - if (candidates>0) - { - warnMsg+="Possible candidates:\n"; - for (mni.toFirst();(md=mni.current());++mni) - { - const ClassDef *cd=md->getClassDef(); - if (cd!=0 && rightScopeMatch(cd->name(),className)) - { - const ArgumentList &templAl = md->templateArguments(); - warnMsg+=" '"; - if (templAl.hasParameters()) - { - warnMsg+="template "; - warnMsg+=tempArgListToString(templAl,root->lang); - warnMsg+='\n'; - warnMsg+=" "; - } - if (md->typeString()) - { - warnMsg+=md->typeString(); - warnMsg+=' '; - } - QCString qScope = cd->qualifiedNameWithTemplateParameters(); - if (!qScope.isEmpty()) - warnMsg+=qScope+"::"+md->name(); - if (md->argsString()) - warnMsg+=md->argsString(); - if (noMatchCount>1) - { - warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + - " of file "+md->getDefFileName(); - } - else - warnMsg += "'"; - - warnMsg+='\n'; - } - } - } - warn_simple(root->fileName,root->startLine,warnMsg); - } + addMemberFunction(root,mn,scopeName,namespaceName,className,funcType,funcName, + funcArgs,funcTempList,exceptions, + type,args,isFriend,spec,relates,funcDecl,overloaded,isFunc); } else if (cd) // member specialization { - MemberNameIterator mni(*mn); - MemberDef *declMd=0; - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) - { - if (md->getClassDef()==cd) - { - // TODO: we should probably also check for matching arguments - declMd = md; - break; - } - } - MemberType mtype=MemberType_Function; - ArgumentList tArgList; - // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - funcType,funcName,funcArgs,exceptions, - declMd ? declMd->protection() : root->protection, - root->virt,root->stat,Member, - mtype,tArgList,root->argList,root->metaData); - //printf("new specialized member %s args='%s'\n",md->name().data(),funcArgs.data()); - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - md->setMemberClass(cd); - md->setTemplateSpecialization(TRUE); - md->setTypeConstraints(root->typeConstr); - md->setDefinition(funcDecl); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->addSectionsToDefinition(root->anchors); - md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->setMemberSpecifiers(spec); - md->setMemberGroupId(root->mGrpId); - mn->append(md); - cd->insertMember(md); - md->setRefItems(root->sli); + addMemberSpecialization(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec); } else { @@ -6165,68 +6249,7 @@ static void findMember(const Entry *root, } else if (overloaded) // check if the function belongs to only one class { - // for unique overloaded member we allow the class to be - // omitted, this is to be Qt compatible. Using this should - // however be avoided, because it is error prone - MemberNameIterator mni(*mn); - MemberDef *md=mni.toFirst(); - ASSERT(md); - ClassDef *cd=md->getClassDef(); - ASSERT(cd); - QCString className=cd->name().copy(); - ++mni; - bool unique=TRUE; - for (;(md=mni.current());++mni) - { - const ClassDef *cd=md->getClassDef(); - if (className!=cd->name()) unique=FALSE; - } - if (unique) - { - MemberType mtype; - if (root->mtype==Signal) mtype=MemberType_Signal; - else if (root->mtype==Slot) mtype=MemberType_Slot; - else if (root->mtype==DCOP) mtype=MemberType_DCOP; - else mtype=MemberType_Function; - - // new overloaded member function - ArgumentList tArgList = - getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - //printf("new related member %s args='%s'\n",md->name().data(),funcArgs.data()); - MemberDef *md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - funcType,funcName,funcArgs,exceptions, - root->protection,root->virt,root->stat,Related, - mtype,tArgList,root->argList,root->metaData); - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - md->setTypeConstraints(root->typeConstr); - md->setMemberClass(cd); - md->setDefinition(funcDecl); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - QCString doc=getOverloadDocs(); - doc+="<p>"; - doc+=root->doc; - md->setDocumentation(doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->addSectionsToDefinition(root->anchors); - md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->setMemberSpecifiers(spec); - md->setMemberGroupId(root->mGrpId); - mn->append(md); - cd->insertMember(md); - cd->insertUsedFile(fd); - md->setRefItems(root->sli); - } + addOverloaded(root,mn,funcType,funcName,funcArgs,funcDecl,exceptions,spec); } else // unrelated function with the same name as a member { @@ -6246,40 +6269,37 @@ static void findMember(const Entry *root, Debug::print(Debug::FindMembers,0,"2. related function\n" " scopeName=%s className=%s\n",qPrint(scopeName),qPrint(className)); if (className.isEmpty()) className=relates; - ClassDef *cd; //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); if ((cd=getClass(scopeName))) { bool newMember=TRUE; // assume we have a new member - bool newMemberName=FALSE; MemberDef *mdDefine=0; - bool isDefine=FALSE; { - MemberName *mn = Doxygen::functionNameSDict->find(funcName); + mn = Doxygen::functionNameLinkedMap->find(funcName); if (mn) { - MemberNameIterator mni(*mn); - mdDefine = mni.current(); - while (mdDefine && !isDefine) + for (const auto &md : *mn) { - isDefine = isDefine || mdDefine->isDefine(); - if (!isDefine) { ++mni; mdDefine=mni.current(); } + if (md->isDefine()) + { + mdDefine = md.get(); + break; + } } } } FileDef *fd=root->fileDef(); - if ((mn=Doxygen::memberNameSDict->find(funcName))==0) + if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==0) { - mn=new MemberName(funcName); - newMemberName=TRUE; // we create a new member name + mn=Doxygen::memberNameLinkedMap->add(funcName); } else { - MemberNameIterator mni(*mn); - MemberDef *rmd; - while ((rmd=mni.current()) && newMember) // see if we got another member with matching arguments + // see if we got another member with matching arguments + MemberDef *rmd_found = 0; + for (const auto &rmd : *mn) { const ArgumentList &rmdAl = rmd->argumentList(); @@ -6288,20 +6308,23 @@ static void findMember(const Entry *root, !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl, cd,fd,root->argList, TRUE); - if (newMember) ++mni; + if (!newMember) + { + rmd_found = rmd.get(); + } } - if (!newMember && rmd) // member already exists as rmd -> add docs + if (rmd_found) // member already exists as rmd -> add docs { //printf("addMemberDocs for related member %s\n",root->name.data()); //rmd->setMemberDefTemplateArguments(root->mtArgList); - addMemberDocs(root,rmd,funcDecl,0,overloaded,spec); + addMemberDocs(root,rmd_found,funcDecl,0,overloaded,spec); } } if (newMember) // need to create a new member { MemberType mtype; - if (isDefine) + if (mdDefine) mtype=MemberType_Define; else if (root->mtype==Signal) mtype=MemberType_Signal; @@ -6312,7 +6335,7 @@ static void findMember(const Entry *root, else mtype=MemberType_Function; - if (isDefine && mdDefine) + if (mdDefine) { mdDefine->setHidden(TRUE); funcType="#define"; @@ -6329,7 +6352,7 @@ static void findMember(const Entry *root, // this accurately reflects the template arguments of // the related function, which don't have to do with // those of the related class. - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt, @@ -6338,9 +6361,9 @@ static void findMember(const Entry *root, mtype, (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()), funcArgs.isEmpty() ? ArgumentList() : root->argList, - root->metaData); + root->metaData) }; - if (isDefine && mdDefine) + if (mdDefine) { md->setInitializer(mdDefine->initializer()); } @@ -6360,8 +6383,6 @@ static void findMember(const Entry *root, md->setTagInfo(root->tagInfo()); - - //printf("Related member name='%s' decl='%s' bodyLine='%d'\n", // funcName.data(),funcDecl.data(),root->bodyLine); @@ -6370,12 +6391,11 @@ static void findMember(const Entry *root, bool found=FALSE; if (root->bodyLine==-1) { - MemberName *rmn=Doxygen::functionNameSDict->find(funcName); + MemberName *rmn=Doxygen::functionNameLinkedMap->find(funcName); if (rmn) { - MemberNameIterator rmni(*rmn); - const MemberDef *rmd; - while ((rmd=rmni.current()) && !found) // see if we got another member with matching arguments + const MemberDef *rmd_found=0; + for (const auto &rmd : *rmn) { const ArgumentList &rmdAl = rmd->argumentList(); // check for matching argument lists @@ -6386,13 +6406,14 @@ static void findMember(const Entry *root, ) { found=TRUE; + rmd_found = rmd.get(); + break; } - if (!found) ++rmni; } - if (rmd) // member found -> copy line number info + if (rmd_found) // member found -> copy line number info { - md->setBodySegment(rmd->getStartBodyLine(),rmd->getEndBodyLine()); - md->setBodyDef(rmd->getBodyDef()); + md->setBodySegment(rmd_found->getDefLine(),rmd_found->getStartBodyLine(),rmd_found->getEndBodyLine()); + md->setBodyDef(rmd_found->getBodyDef()); //md->setBodyMember(rmd); } } @@ -6400,7 +6421,7 @@ static void findMember(const Entry *root, if (!found) // line number could not be found or is available in this // entry { - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(fd); } @@ -6425,22 +6446,16 @@ static void findMember(const Entry *root, md->setLanguage(root->lang); md->setId(root->id); //md->setMemberDefTemplateArguments(root->mtArgList); - mn->append(md); - cd->insertMember(md); + cd->insertMember(md.get()); cd->insertUsedFile(fd); md->setRefItems(root->sli); if (root->relatesType == Duplicate) md->setRelatedAlso(cd); - if (!isDefine) + if (!mdDefine) { - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } //printf("Adding member=%s\n",md->name().data()); - if (newMemberName) - { - //Doxygen::memberNameList.append(mn); - //Doxygen::memberNameDict.insert(funcName,mn); - Doxygen::memberNameSDict->append(funcName,mn); - } + mn->push_back(std::move(md)); } if (root->relatesType == Duplicate) { @@ -6466,58 +6481,7 @@ static void findMember(const Entry *root, } else if (root->parent() && root->parent()->section==Entry::OBJCIMPL_SEC) { -localObjCMethod: - ClassDef *cd; - //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); - if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClass(scopeName))) - { - Debug::print(Debug::FindMembers,0,"4. Local objective C method %s\n" - " scopeName=%s className=%s\n",qPrint(root->name),qPrint(scopeName),qPrint(className)); - //printf("Local objective C method '%s' of class '%s' found\n",root->name.data(),cd->name().data()); - MemberDef *md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - funcType,funcName,funcArgs,exceptions, - root->protection,root->virt,root->stat,Member, - MemberType_Function,ArgumentList(),root->argList,root->metaData); - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - md->makeImplementationDetail(); - md->setMemberClass(cd); - md->setDefinition(funcDecl); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->addSectionsToDefinition(root->anchors); - md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->setMemberSpecifiers(spec); - md->setMemberGroupId(root->mGrpId); - cd->insertMember(md); - cd->insertUsedFile(fd); - md->setRefItems(root->sli); - if ((mn=Doxygen::memberNameSDict->find(root->name))) - { - mn->append(md); - } - else - { - mn = new MemberName(root->name); - mn->append(md); - Doxygen::memberNameSDict->append(root->name,mn); - } - } - else - { - // local objective C method found for class without interface - } + addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec); } else // unrelated not overloaded member found { @@ -6762,11 +6726,10 @@ static void findEnums(const Entry *root) { if (root->section==Entry::ENUM_SEC) { - MemberDef *md=0; ClassDef *cd=0; FileDef *fd=0; NamespaceDef *nd=0; - MemberNameSDict *mnsd=0; + MemberNameLinkedMap *mnsd=0; bool isGlobal; bool isRelated=FALSE; bool isMemberOf=FALSE; @@ -6809,36 +6772,36 @@ static void findEnums(const Entry *root) { //printf("Enum '%s'::'%s'\n",cd->name().data(),name.data()); fd=0; - mnsd=Doxygen::memberNameSDict; + mnsd=Doxygen::memberNameLinkedMap; isGlobal=FALSE; } else if (nd) // found enum inside namespace { - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } else // found a global enum { fd=root->fileDef(); - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } if (!name.isEmpty()) { // new enum type - md = createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( root->fileName,root->startLine,root->startColumn, 0,name,0,0, root->protection,Normal,FALSE, isMemberOf ? Foreign : isRelated ? Related : Member, MemberType_Enumeration, - ArgumentList(),ArgumentList(),root->metaData); + ArgumentList(),ArgumentList(),root->metaData) }; md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd); - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(root->fileDef()); md->setMemberSpecifiers(root->spec); md->setEnumBaseType(root->args); @@ -6874,7 +6837,7 @@ static void findEnums(const Entry *root) //printf("definition=%s\n",md->definition()); defSet=TRUE; md->setNamespace(nd); - nd->insertMember(md); + nd->insertMember(md.get()); } // even if we have already added the enum to a namespace, we still @@ -6890,7 +6853,7 @@ static void findEnums(const Entry *root) if (fd) { md->setFileDef(fd); - fd->insertMember(md); + fd->insertMember(md.get()); } } else if (cd) @@ -6903,7 +6866,7 @@ static void findEnums(const Entry *root) { md->setDefinition(cd->name()+"::"+name+baseType); } - cd->insertMember(md); + cd->insertMember(md.get()); cd->insertUsedFile(fd); } md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -6912,21 +6875,10 @@ static void findEnums(const Entry *root) md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); //printf("Adding member=%s\n",md->name().data()); - MemberName *mn; - if ((mn=(*mnsd)[name])) - { - // this is used if the same enum is in multiple namespaces/classes - mn->append(md); - } - else // new enum name - { - mn = new MemberName(name); - mn->append(md); - mnsd->append(name,mn); - //printf("add %s to new memberName. Now %d members\n", - // name.data(),mn->count()); - } - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); + + MemberName *mn = mnsd->add(name); + mn->push_back(std::move(md)); } } else @@ -6945,7 +6897,7 @@ static void addEnumValuesToEnums(const Entry *root) ClassDef *cd=0; FileDef *fd=0; NamespaceDef *nd=0; - MemberNameSDict *mnsd=0; + MemberNameLinkedMap *mnsd=0; bool isGlobal; bool isRelated=FALSE; //printf("Found enum with name '%s' relates=%s\n",root->name.data(),root->relates.data()); @@ -6986,20 +6938,20 @@ static void addEnumValuesToEnums(const Entry *root) { //printf("Enum in class '%s'::'%s'\n",cd->name().data(),name.data()); fd=0; - mnsd=Doxygen::memberNameSDict; + mnsd=Doxygen::memberNameLinkedMap; isGlobal=FALSE; } else if (nd && !nd->isAnonymous()) // found enum inside namespace { //printf("Enum in namespace '%s'::'%s'\n",nd->name().data(),name.data()); - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } else // found a global enum { fd=root->fileDef(); //printf("Enum in file '%s': '%s'\n",fd->name().data(),name.data()); - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } @@ -7009,9 +6961,8 @@ static void addEnumValuesToEnums(const Entry *root) MemberName *mn = mnsd->find(name); // for all members with this name if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst(); (md=mni.current()) ; ++mni) // for each enum in this list + // for each enum in this list + for (const auto &md : *mn) { if (!md->isAlias() && md->isEnumerate() && !root->children().empty()) { @@ -7045,11 +6996,11 @@ static void addEnumValuesToEnums(const Entry *root) { fileName = e->tagInfo()->tagName; } - MemberDef *fmd=createMemberDef( + std::unique_ptr<MemberDef> fmd { createMemberDef( fileName,e->startLine,e->startColumn, e->type,e->name,e->args,0, e->protection, Normal,e->stat,Member, - MemberType_EnumValue,ArgumentList(),ArgumentList(),e->metaData); + MemberType_EnumValue,ArgumentList(),ArgumentList(),e->metaData) }; if (md->getClassDef()) fmd->setMemberClass(md->getClassDef()); else if (md->getNamespaceDef()) fmd->setNamespace(md->getNamespaceDef()); else if (md->getFileDef()) fmd->setFileDef(md->getFileDef()); @@ -7066,32 +7017,21 @@ static void addEnumValuesToEnums(const Entry *root) fmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn); fmd->setRefItems(e->sli); fmd->setAnchor(); - md->insertEnumField(fmd); - fmd->setEnumScope(md,TRUE); - MemberName *mn=mnsd->find(e->name); - if (mn) - { - mn->append(fmd); - } - else - { - mn = new MemberName(e->name); - mn->append(fmd); - mnsd->append(e->name,mn); - } + md->insertEnumField(fmd.get()); + fmd->setEnumScope(md.get(),TRUE); + mn=mnsd->add(e->name); + mn->push_back(std::move(fmd)); } } else { //printf("e->name=%s isRelated=%d\n",e->name().data(),isRelated); MemberName *fmn=0; - MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd; - if (!e->name.isEmpty() && (fmn=(*emnsd)[e->name])) + MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd; + if (!e->name.isEmpty() && (fmn=emnsd->find(e->name))) // get list of members with the same name as the field { - MemberNameIterator fmni(*fmn); - MemberDef *fmd; - for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni) + for (const auto &fmd : *fmn) { if (fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope { @@ -7102,8 +7042,8 @@ static void addEnumValuesToEnums(const Entry *root) const NamespaceDef *fnd=fmd->getNamespaceDef(); if (fnd==nd) // enum value is inside a namespace { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + md->insertEnumField(fmd.get()); + fmd->setEnumScope(md.get()); } } else if (isGlobal) @@ -7111,19 +7051,19 @@ static void addEnumValuesToEnums(const Entry *root) const FileDef *ffd=fmd->getFileDef(); if (ffd==fd) // enum value has file scope { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + md->insertEnumField(fmd.get()); + fmd->setEnumScope(md.get()); } } else if (isRelated && cd) // reparent enum value to // match the enum's scope { - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name + md->insertEnumField(fmd.get()); // add field def to list + fmd->setEnumScope(md.get()); // cross ref with enum name fmd->setEnumClassScope(cd); // cross ref with enum name fmd->setOuterScope(cd); fmd->makeRelated(); - cd->insertMember(fmd); + cd->insertMember(fmd.get()); } else { @@ -7132,8 +7072,8 @@ static void addEnumValuesToEnums(const Entry *root) { //printf("Inserting enum field %s in enum scope %s\n", // fmd->name().data(),md->name().data()); - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name + md->insertEnumField(fmd.get()); // add field def to list + fmd->setEnumScope(md.get()); // cross ref with enum name } } } @@ -7194,14 +7134,12 @@ static void findEnumDocumentation(const Entry *root) { //printf("Enum: scope='%s' name='%s'\n",cd->name(),name.data()); QCString className=cd->name().copy(); - MemberName *mn=Doxygen::memberNameSDict->find(name); + MemberName *mn=Doxygen::memberNameLinkedMap->find(name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current()) && !found;++mni) + for (const auto &md : *mn) { - const ClassDef *cd=md->getClassDef(); + cd=md->getClassDef(); if (cd && cd->name()==className && md->isEnumerate()) { // documentation outside a compound overrides the documentation inside it @@ -7238,10 +7176,11 @@ static void findEnumDocumentation(const Entry *root) const GroupDef *gd=md->getGroupDef(); if (gd==0 && !root->groups.empty()) // member not grouped but out-of-line documentation is { - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } found=TRUE; + break; } } } @@ -7253,12 +7192,10 @@ static void findEnumDocumentation(const Entry *root) else // enum outside class { //printf("Enum outside class: %s grpId=%d\n",name.data(),root->mGrpId); - MemberName *mn=Doxygen::functionNameSDict->find(name); + MemberName *mn=Doxygen::functionNameLinkedMap->find(name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current()) && !found;++mni) + for (const auto &md : *mn) { if (md->isEnumerate()) { @@ -7272,10 +7209,11 @@ static void findEnumDocumentation(const Entry *root) const GroupDef *gd=md->getGroupDef(); if (gd==0 && !root->groups.empty()) // member not grouped but out-of-line documentation is { - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } found=TRUE; + break; } } } @@ -7294,17 +7232,13 @@ static void findEnumDocumentation(const Entry *root) // search for each enum (member or function) in mnl if it has documented // enum values. -static void findDEV(const MemberNameSDict &mnsd) +static void findDEV(const MemberNameLinkedMap &mnsd) { - MemberName *mn; - MemberNameSDict::Iterator mnli(mnsd); // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : mnsd) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->isEnumerate()) // member is an enum { @@ -7331,45 +7265,38 @@ static void findDEV(const MemberNameSDict &mnsd) // values. static void findDocumentedEnumValues() { - findDEV(*Doxygen::memberNameSDict); - findDEV(*Doxygen::functionNameSDict); + findDEV(*Doxygen::memberNameLinkedMap); + findDEV(*Doxygen::functionNameLinkedMap); } //---------------------------------------------------------------------- static void addMembersToIndex() { - MemberName *mn; - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - addClassMemberNameToIndex(md); + addClassMemberNameToIndex(md.get()); } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); // for each member name - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (!md->isAlias()) { if (md->getNamespaceDef()) { - addNamespaceMemberNameToIndex(md); + addNamespaceMemberNameToIndex(md.get()); } else { - addFileMemberNameToIndex(md); + addFileMemberNameToIndex(md.get()); } } } @@ -7380,29 +7307,22 @@ static void addMembersToIndex() static void vhdlCorrectMemberProperties() { - MemberName *mn; - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - VhdlDocGen::correctMemberProperties(md); + VhdlDocGen::correctMemberProperties(md.get()); } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); // for each member name - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - VhdlDocGen::correctMemberProperties(md); + VhdlDocGen::correctMemberProperties(md.get()); } } } @@ -7415,61 +7335,60 @@ static void vhdlCorrectMemberProperties() static void computeMemberRelations() { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn; - for ( ; (mn=mnli.current()) ; ++mnli ) // for each member name + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mdi(*mn); - MemberNameIterator bmdi(*mn); - MemberDef *md; - MemberDef *bmd; - for ( ; (md=mdi.current()) ; ++mdi ) // for each member with a specific name - { - for ( bmdi.toFirst() ; (bmd=bmdi.current()); ++bmdi ) // for each other member with the same name - { - const ClassDef *mcd = md->getClassDef(); - if (mcd && mcd->baseClasses()) - { - const ClassDef *bmcd = bmd->getClassDef(); - //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", - // mcd->name().data(),md->name().data(),md, - // bmcd->name().data(),bmd->name().data(),bmd - // ); - if (md!=bmd && bmcd && mcd && bmcd!=mcd && - (bmd->virtualness()!=Normal || bmd->getLanguage()==SrcLangExt_Python || - bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || - bmcd->compoundType()==ClassDef::Interface || - bmcd->compoundType()==ClassDef::Protocol - ) && - md->isFunction() && - mcd->isLinkable() && - bmcd->isLinkable() && - mcd->isBaseClass(bmcd,TRUE)) + // for each member with a specific name + for (const auto &md : *mn) + { + // for each other member with the same name + for ( const auto &bmd : *mn) + { + if (md!=bmd) + { + const ClassDef *mcd = md->getClassDef(); + if (mcd && mcd->baseClasses()) { - //printf(" derived scope\n"); - const ArgumentList &bmdAl = bmd->argumentList(); - const ArgumentList &mdAl = md->argumentList(); - //printf(" Base argList='%s'\n Super argList='%s'\n", - // argListToString(bmdAl.pointer()).data(), - // argListToString(mdAl.pointer()).data() + const ClassDef *bmcd = bmd->getClassDef(); + //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", + // mcd->name().data(),md->name().data(),md, + // bmcd->name().data(),bmd->name().data(),bmd // ); - if ( - matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmdAl, - md->getOuterScope(), md->getFileDef(), mdAl, - TRUE - ) - ) + if (bmcd && mcd && bmcd!=mcd && + (bmd->virtualness()!=Normal || bmd->getLanguage()==SrcLangExt_Python || + bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || + bmcd->compoundType()==ClassDef::Interface || + bmcd->compoundType()==ClassDef::Protocol + ) && + md->isFunction() && + mcd->isLinkable() && + bmcd->isLinkable() && + mcd->isBaseClass(bmcd,TRUE)) { - MemberDef *rmd; - if ((rmd=md->reimplements())==0 || - minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) + //printf(" derived scope\n"); + const ArgumentList &bmdAl = bmd->argumentList(); + const ArgumentList &mdAl = md->argumentList(); + //printf(" Base argList='%s'\n Super argList='%s'\n", + // argListToString(bmdAl.pointer()).data(), + // argListToString(mdAl.pointer()).data() + // ); + if ( + matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmdAl, + md->getOuterScope(), md->getFileDef(), mdAl, + TRUE + ) ) { - //printf("setting (new) reimplements member\n"); - md->setReimplements(bmd); + MemberDef *rmd; + if ((rmd=md->reimplements())==0 || + minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) + ) + { + //printf("setting (new) reimplements member\n"); + md->setReimplements(bmd.get()); + } + //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); + bmd->insertReimplementedBy(md.get()); } - //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); - bmd->insertReimplementedBy(md); } } } @@ -7566,7 +7485,7 @@ static void buildCompleteMemberLists() static void generateFileSources() { - if (Doxygen::inputNameList->count()>0) + if (!Doxygen::inputNameLinkedMap->empty()) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -7576,23 +7495,17 @@ static void generateFileSources() // create a dictionary with files to process QDict<void> g_filesToProcess(10007); - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { g_filesToProcess.insert(fd->absFilePath(),(void*)0x8); } } // process source files (and their include dependencies) - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isSource() && !fd->isReference()) { @@ -7619,7 +7532,7 @@ static void generateFileSources() { QStrList moreFiles; bool ambig; - FileDef *ifd=findFileDef(Doxygen::inputNameDict,incFile,ambig); + FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile,ambig); if (ifd && !ifd->isReference()) { if (ifd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output @@ -7645,11 +7558,9 @@ static void generateFileSources() } } // process remaining files - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (!g_processedFiles.find(fd->absFilePath())) // not yet processed { @@ -7675,13 +7586,9 @@ static void generateFileSources() else #endif { - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { QStrList filesInSameTu; fd->startParsing(); @@ -7710,15 +7617,11 @@ static void generateFileDocs() { if (documentedHtmlFiles==0) return; - if (Doxygen::inputNameList->count()>0) + if (!Doxygen::inputNameLinkedMap->empty()) { - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { bool doc = fd->isLinkableInProject(); if (doc) @@ -7741,9 +7644,9 @@ static void addSourceReferences() for (cli.toFirst();(cd=cli.current());++cli) { FileDef *fd=cd->getBodyDef(); - if (fd && cd->isLinkableInProject() && cd->getStartBodyLine()!=-1) + if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1) { - fd->addSourceRef(cd->getStartBodyLine(),cd,0); + fd->addSourceRef(cd->getStartDefLine(),cd,0); } } // add source references for namespace definitions @@ -7752,20 +7655,16 @@ static void addSourceReferences() for (nli.toFirst();(nd=nli.current());++nli) { FileDef *fd=nd->getBodyDef(); - if (fd && nd->isLinkableInProject() && nd->getStartBodyLine()!=-1) + if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1) { - fd->addSourceRef(nd->getStartBodyLine(),nd,0); + fd->addSourceRef(nd->getStartDefLine(),nd,0); } } // add source references for member names - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn=0; - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { //printf("class member %s: def=%s body=%d link?=%d\n", // md->name().data(), @@ -7773,23 +7672,20 @@ static void addSourceReferences() // md->getStartBodyLine(),md->isLinkableInProject()); FileDef *fd=md->getBodyDef(); if (fd && - md->getStartBodyLine()!=-1 && + md->getStartDefLine()!=-1 && md->isLinkableInProject() && (fd->generateSourceFile() || Doxygen::parseSourcesNeeded) ) { //printf("Found member '%s' in file '%s' at line '%d' def=%s\n", // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data()); - fd->addSourceRef(md->getStartBodyLine(),md->getOuterScope(),md); + fd->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get()); } } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { FileDef *fd=md->getBodyDef(); //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n", @@ -7798,14 +7694,14 @@ static void addSourceReferences() // md->isLinkableInProject(), // Doxygen::parseSourcesNeeded); if (fd && - md->getStartBodyLine()!=-1 && + md->getStartDefLine()!=-1 && md->isLinkableInProject() && (fd->generateSourceFile() || Doxygen::parseSourcesNeeded) ) { //printf("Found member '%s' in file '%s' at line '%d' def=%s\n", // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data()); - fd->addSourceRef(md->getStartBodyLine(),md->getOuterScope(),md); + fd->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get()); } } } @@ -7832,13 +7728,9 @@ static void sortMemberLists() } // sort file member lists - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->sortMemberLists(); } @@ -7863,34 +7755,6 @@ static void setAnonymousEnumType() { cd->setAnonymousEnumType(); } - -#if 0 - NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); - NamespaceDef *nd=0; - for (nli.toFirst();(nd=nli.current());++nli) - { - nd->setAnonymousEnumType(); - } - - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) - { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) - { - fd->setAnonymousEnumType(); - } - } - - GroupSDict::Iterator gli(*Doxygen::groupSDict); - GroupDef *gd; - for (gli.toFirst();(gd=gli.current());++gli) - { - gd->setAnonymousEnumType(); - } -#endif } //---------------------------------------------------------------------------- @@ -7911,13 +7775,9 @@ static void countMembers() nd->countMembers(); } - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->countMembers(); } @@ -7974,14 +7834,9 @@ static void generateClassDocs() static void inheritDocumentation() { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn; - //int count=0; - for (;(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (;(md=mni.current());++mni) + for (const auto &md : *mn) { //printf("%04d Member '%s'\n",count++,md->name().data()); if (md->documentation().isEmpty() && md->briefDescription().isEmpty()) @@ -8013,22 +7868,16 @@ static void inheritDocumentation() static void combineUsingRelations() { // for each file - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->setVisited(FALSE); } } - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->combineUsingRelations(); } @@ -8059,13 +7908,9 @@ static void addMembersToMemberGroup() cd->addMembersToMemberGroup(); } // for each file - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->addMembersToMemberGroup(); } @@ -8098,13 +7943,9 @@ static void distributeMemberGroupDocumentation() cd->distributeMemberGroupDocumentation(); } // for each file - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->distributeMemberGroupDocumentation(); } @@ -8137,13 +7978,9 @@ static void findSectionsInDocumentation() cd->findSectionsInDocumentation(); } // for each file - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { fd->findSectionsInDocumentation(); } @@ -8189,13 +8026,11 @@ static void flushCachedTemplateRelations() } // remove all cached typedef resolutions whose target is a // template class as this may now be a template instance - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *fn; - for (;(fn=fnli.current());++fnli) // for each global function name + // for each global function name + for (const auto &fn : *Doxygen::functionNameLinkedMap) { - MemberNameIterator fni(*fn); - MemberDef *fmd; - for (;(fmd=fni.current());++fni) // for each function with that name + // for each function with that name + for (const auto &fmd : *fn) { if (fmd->isTypedefValCached()) { @@ -8204,17 +8039,16 @@ static void flushCachedTemplateRelations() } } } - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - for (;(fn=mnli.current());++mnli) // for each class method name + // for each class method name + for (const auto &nm : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*fn); - MemberDef *fmd; - for (;(fmd=mni.current());++mni) // for each function with that name + // for each function with that name + for (const auto &md : *nm) { - if (fmd->isTypedefValCached()) + if (md->isTypedefValCached()) { - const ClassDef *cd = fmd->getCachedTypedefVal(); - if (cd->isTemplate()) fmd->invalidateTypedefValCache(); + const ClassDef *cd = md->getCachedTypedefVal(); + if (cd->isTemplate()) md->invalidateTypedefValCache(); } } } @@ -8244,25 +8078,22 @@ static void flushUnresolvedRelations() } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *fn; - for (;(fn=fnli.current());++fnli) // for each global function name + // for each global function name + for (const auto &fn : *Doxygen::functionNameLinkedMap) { - MemberNameIterator fni(*fn); - MemberDef *fmd; - for (;(fmd=fni.current());++fni) // for each function with that name + // for each function with that name + for (const auto &fmd : *fn) { fmd->invalidateCachedArgumentTypes(); } } - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - for (;(fn=mnli.current());++mnli) // for each class method name + // for each class method name + for (const auto &nm : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*fn); - MemberDef *fmd; - for (;(fmd=mni.current());++mni) // for each function with that name + // for each function with that name + for (const auto &md : *nm) { - fmd->invalidateCachedArgumentTypes(); + md->invalidateCachedArgumentTypes(); } } @@ -8281,40 +8112,29 @@ static void findDefineDocumentation(Entry *root) if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file { - MemberDef *md=createMemberDef(root->tagInfo()->tagName,1,1, + std::unique_ptr<MemberDef> md { createMemberDef(root->tagInfo()->tagName,1,1, "#define",root->name,root->args,0, Public,Normal,FALSE,Member,MemberType_Define, - ArgumentList(),ArgumentList(),""); + ArgumentList(),ArgumentList(),"") }; md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); //printf("Searching for '%s' fd=%p\n",filePathName.data(),fd); md->setFileDef(root->parent()->fileDef()); //printf("Adding member=%s\n",md->name().data()); - MemberName *mn; - if ((mn=Doxygen::functionNameSDict->find(root->name))) - { - mn->append(md); - } - else - { - mn = new MemberName(root->name); - mn->append(md); - Doxygen::functionNameSDict->append(root->name,mn); - } + MemberName *mn = Doxygen::functionNameLinkedMap->add(root->name); + mn->push_back(std::move(md)); } - MemberName *mn=Doxygen::functionNameSDict->find(root->name); + MemberName *mn=Doxygen::functionNameLinkedMap->find(root->name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; int count=0; - for (;(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->memberType()==MemberType_Define) count++; } if (count==1) { - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->memberType()==MemberType_Define) { @@ -8325,13 +8145,13 @@ static void findDefineDocumentation(Entry *root) { md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); } - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(root->fileDef()); md->addSectionsToDefinition(root->anchors); md->setMaxInitLines(root->initLines); md->setRefItems(root->sli); if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId); - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } } } @@ -8344,7 +8164,7 @@ static void findDefineDocumentation(Entry *root) // multiple defines don't know where to add docs // but maybe they are in different files together with their documentation { - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->memberType()==MemberType_Define) { @@ -8369,13 +8189,13 @@ static void findDefineDocumentation(Entry *root) { md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); } - md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(root->fileDef()); md->addSectionsToDefinition(root->anchors); md->setRefItems(root->sli); md->setLanguage(root->lang); if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId); - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } } } @@ -8398,7 +8218,7 @@ static void findDefineDocumentation(Entry *root) else { warn(root->fileName,root->startLine, - "found documented #define but ignoring it because " + "found documented #define %s but ignoring it because " "ENABLE_PREPROCESSING is NO.\n", root->name.data() ); @@ -8518,30 +8338,32 @@ static void findMainPage(Entry *root) Doxygen::mainPage->setLocalToc(root->localToc); addPageToContext(Doxygen::mainPage,root); - SectionInfo *si = Doxygen::sectionDict->find(Doxygen::mainPage->name()); + const SectionInfo *si = SectionManager::instance().find(Doxygen::mainPage->name()); if (si) { - if (si->lineNr != -1) + if (si->lineNr() != -1) { - warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s, line %d)",Doxygen::mainPage->name().data(),si->fileName.data(),si->lineNr); + warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s, line %d)", + Doxygen::mainPage->name().data(),si->fileName().data(),si->lineNr()); } else { - warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s)",Doxygen::mainPage->name().data(),si->fileName.data()); + warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s)", + Doxygen::mainPage->name().data(),si->fileName().data()); } } else { // a page name is a label as well! but should no be double either - si=new SectionInfo( - indexName, root->startLine, + SectionManager::instance().add( Doxygen::mainPage->name(), + indexName, + root->startLine, Doxygen::mainPage->title(), - SectionInfo::Page, + SectionType::Page, 0); // level 0 - Doxygen::sectionDict->append(indexName,si); - Doxygen::mainPage->addSectionsToDefinition(root->anchors); } + Doxygen::mainPage->addSectionsToDefinition(root->anchors); } else if (root->tagInfo()==0) { @@ -8624,9 +8446,7 @@ static void checkPageRelations() static void resolveUserReferences() { - SDict<SectionInfo>::Iterator sdi(*Doxygen::sectionDict); - SectionInfo *si; - for (;(si=sdi.current());++sdi) + for (auto &si : SectionManager::instance()) { //printf("si->label='%s' si->definition=%s si->fileName='%s'\n", // si->label.data(),si->definition?si->definition->name().data():"<none>", @@ -8638,44 +8458,42 @@ static void resolveUserReferences() // name (not from the todo/test/bug/deprecated list, but from the file in // which they are defined). We correct this here by looking at the // generated section labels! - QDictIterator<RefList> rli(*Doxygen::xrefLists); - RefList *rl; - for (rli.toFirst();(rl=rli.current());++rli) + for (const RefListManager::Ptr &rl : RefListManager::instance()) { QCString label="_"+rl->listName(); // "_todo", "_test", ... - if (si->label.left(label.length())==label) + if (si->label().left(label.length())==label) { - si->fileName=rl->listName(); - si->generated=TRUE; + si->setFileName(rl->listName()); + si->setGenerated(TRUE); break; } } //printf("start: si->label=%s si->fileName=%s\n",si->label.data(),si->fileName.data()); - if (!si->generated) + if (!si->generated()) { // if this section is in a page and the page is in a group, then we // have to adjust the link file name to point to the group. - if (!si->fileName.isEmpty() && - (pd=Doxygen::pageSDict->find(si->fileName)) && + if (!si->fileName().isEmpty() && + (pd=Doxygen::pageSDict->find(si->fileName())) && pd->getGroupDef()) { - si->fileName=pd->getGroupDef()->getOutputFileBase().copy(); + si->setFileName(pd->getGroupDef()->getOutputFileBase()); } - if (si->definition) + if (si->definition()) { // TODO: there should be one function in Definition that returns // the file to link to, so we can avoid the following tests. const GroupDef *gd=0; - if (si->definition->definitionType()==Definition::TypeMember) + if (si->definition()->definitionType()==Definition::TypeMember) { - gd = (dynamic_cast<MemberDef *>(si->definition))->getGroupDef(); + gd = (dynamic_cast<MemberDef *>(si->definition()))->getGroupDef(); } if (gd) { - si->fileName=gd->getOutputFileBase().copy(); + si->setFileName(gd->getOutputFileBase()); } else { @@ -9032,9 +8850,9 @@ static void copyLatexStyleSheet() else { QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName().data(); - if (!checkExtension(fi.fileName().data(), latexStyleExtension)) + if (!checkExtension(fi.fileName().data(), LATEX_STYLE_EXTENSION)) { - destFileName += latexStyleExtension; + destFileName += LATEX_STYLE_EXTENSION; } copyFile(fileName, destFileName); } @@ -9130,6 +8948,70 @@ static void copyExtraFiles(QStrList files,const QCString &filesOption,const QCSt //---------------------------------------------------------------------------- +static void generateDiskNames() +{ + for (const auto &fn : *Doxygen::inputNameLinkedMap) + { + struct FileEntry + { + FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {} + QCString path; + FileDef *fileDef; + }; + + // collect the entry for which to compute the longest common prefix (LCP) of the path + std::vector<FileEntry> fileEntries; + for (const auto &fd : *fn) + { + if (!fd->isReference()) // skip external references + { + fileEntries.emplace_back(fd->getPath(),fd.get()); + } + } + + size_t size = fileEntries.size(); + + if (size==1) // name if unique, so diskname is simply the name + { + FileDef *fd = fileEntries[0].fileDef; + fd->setDiskName(fn->fileName()); + } + else if (size>1) // multiple occurrences of the same file name + { + // sort the array + std::sort(fileEntries.begin(), + fileEntries.end(), + [](const FileEntry &fe1,const FileEntry &fe2) + { return qstrcmp(fe1.path.data(),fe2.path.data())<0; } + ); + + // since the entries are sorted, the common prefix of the whole array is same + // as the common prefix between the first and last entry + const FileEntry &first = fileEntries[0]; + const FileEntry &last = fileEntries[size-1]; + int j=0; + for (size_t i=0;i<first.path.size() && i<last.path.size();i++) + { + if (first.path[i]=='/') j=i; + if (first.path[i]!=last.path[i]) break; + } + + // add non-common part of the path to the name + for (auto &fileEntry : fileEntries) + { + QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1); + fileEntry.fileDef->setName(prefix+fn->fileName()); + //printf("!!!!!!!! non unique disk name=%s:%s\n",prefix.data(),fn->fileName()); + fileEntry.fileDef->setDiskName(prefix+fn->fileName()); + } + } + } +} + + + +//---------------------------------------------------------------------------- + static OutlineParserInterface &getParserForFile(const char *fn) { QCString fileName=fn; @@ -9231,7 +9113,7 @@ static void parseFiles(const std::shared_ptr<Entry> &root) for (it.toFirst();(s=it.current());++it) { bool ambig; - FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); + FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s->data(),ambig); ASSERT(fd!=0); if (fd->isSource() && !fd->isReference()) // this is a source file { @@ -9248,7 +9130,7 @@ static void parseFiles(const std::shared_ptr<Entry> &root) { if (qstrcmp(incFile,s->data()) && !g_processedFiles.find(incFile)) { - FileDef *ifd=findFileDef(Doxygen::inputNameDict,incFile,ambig); + FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile,ambig); if (ifd && !ifd->isReference()) { QStrList moreFiles; @@ -9270,7 +9152,7 @@ static void parseFiles(const std::shared_ptr<Entry> &root) { bool ambig; QStrList filesInSameTu; - FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); + FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s->data(),ambig); ASSERT(fd!=0); OutlineParserInterface &parser = getParserForFile(s->data()); parser.startTranslationUnit(s->data()); @@ -9289,7 +9171,7 @@ static void parseFiles(const std::shared_ptr<Entry> &root) { bool ambig; QStrList filesInSameTu; - FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); + FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s->data(),ambig); ASSERT(fd!=0); OutlineParserInterface &parser = getParserForFile(s->data()); parser.startTranslationUnit(s->data()); @@ -9375,8 +9257,7 @@ static QDict<void> g_pathsVisited(1009); // The contents of all files is append to the input string int readDir(QFileInfo *fi, - FileNameList *fnList, - FileNameDict *fnDict, + FileNameLinkedMap *fnMap, StringDict *exclDict, QStrList *patList, QStrList *exclPatList, @@ -9434,20 +9315,14 @@ int readDir(QFileInfo *fi, totalSize+=cfi->size()+cfi->absFilePath().length()+4; QCString name=cfi->fileName().utf8(); //printf("New file %s\n",name.data()); - if (fnDict) + if (fnMap) { - FileDef *fd=createFileDef(cfi->dirPath().utf8()+"/",name); + std::unique_ptr<FileDef> fd { createFileDef(cfi->dirPath().utf8()+"/",name) }; FileName *fn=0; - if (!name.isEmpty() && (fn=(*fnDict)[name])) + if (!name.isEmpty()) { - fn->append(fd); - } - else - { - fn = new FileName(cfi->absFilePath().utf8(),name); - fn->append(fd); - if (fnList) fnList->append(fn); - fnDict->insert(name,fn); + fn = fnMap->add(name,cfi->absFilePath().utf8()); + fn->push_back(std::move(fd)); } } QCString *rs=0; @@ -9466,7 +9341,7 @@ int readDir(QFileInfo *fi, cfi->fileName().at(0)!='.') // skip "." ".." and ".dir" { cfi->setFile(cfi->absFilePath()); - totalSize+=readDir(cfi,fnList,fnDict,exclDict, + totalSize+=readDir(cfi,fnMap,exclDict, patList,exclPatList,resultList,resultDict,errorIfNotExist, recursive,killDict,paths); } @@ -9483,8 +9358,7 @@ int readDir(QFileInfo *fi, // input string. The names of the files are appended to the 'fiList' list. int readFileOrDirectory(const char *s, - FileNameList *fnList, - FileNameDict *fnDict, + FileNameLinkedMap *fnMap, StringDict *exclDict, QStrList *patList, QStrList *exclPatList, @@ -9533,20 +9407,13 @@ int readFileOrDirectory(const char *s, //fiList->inSort(new FileInfo(fi)); QCString name=fi.fileName().utf8(); //printf("New file %s\n",name.data()); - if (fnDict) + if (fnMap) { - FileDef *fd=createFileDef(dirPath+"/",name); - FileName *fn=0; - if (!name.isEmpty() && (fn=(*fnDict)[name])) - { - fn->append(fd); - } - else + std::unique_ptr<FileDef> fd { createFileDef(dirPath+"/",name) }; + if (!name.isEmpty()) { - fn = new FileName(filePath,name); - fn->append(fd); - if (fnList) fnList->append(fn); - fnDict->insert(name,fn); + FileName *fn = fnMap->add(name,filePath); + fn->push_back(std::move(fd)); } } QCString *rs=0; @@ -9562,7 +9429,7 @@ int readFileOrDirectory(const char *s, } else if (fi.isDir()) // readable dir { - totalSize+=readDir(&fi,fnList,fnDict,exclDict,patList, + totalSize+=readDir(&fi,fnMap,exclDict,patList, exclPatList,resultList,resultDict,errorIfNotExist, recursive,killDict,paths); } @@ -9574,66 +9441,6 @@ int readFileOrDirectory(const char *s, //---------------------------------------------------------------------------- -void readFormulaRepository(QCString dir, bool cmp) -{ - static int current_repository = 0; - int new_repository = 0; - QFile f(dir+"/formula.repository"); - if (f.open(IO_ReadOnly)) // open repository - { - msg("Reading formula repository...\n"); - QTextStream t(&f); - QCString line; - Formula *f; - while (!t.eof()) - { - line=t.readLine().utf8(); - int se=line.find(':'); // find name and text separator. - if (se==-1) - { - warn_uncond("formula.repository is corrupted!\n"); - break; - } - else - { - QCString formName = line.left(se); - QCString formText = line.right(line.length()-se-1); - if (cmp) - { - if ((f=Doxygen::formulaDict->find(formText))==0) - { - term("discrepancy between formula repositories! Remove " - "formula.repository and from_* files from output directories."); - } - QCString formLabel; - formLabel.sprintf("\\_form#%d",f->getId()); - if (formLabel != formName) - { - term("discrepancy between formula repositories! Remove " - "formula.repository and from_* files from output directories."); - } - new_repository++; - } - else - { - f=new Formula(formText); - Doxygen::formulaList->append(f); - Doxygen::formulaDict->insert(formText,f); - Doxygen::formulaNameDict->insert(formName,f); - current_repository++; - } - } - } - } - if (cmp && (current_repository != new_repository)) - { - term("size discrepancy between formula repositories! Remove " - "formula.repository and from_* files from output directories."); - } -} - -//---------------------------------------------------------------------------- - static void expandAliases() { QDictIterator<QCString> adi(Doxygen::aliasDict); @@ -9891,8 +9698,6 @@ void initDoxygen() std::make_unique<XMLCodeParser>()); Doxygen::parserManager->registerParser("sql", std::make_unique<NullOutlineParser>(), std::make_unique<SQLCodeParser>()); - Doxygen::parserManager->registerParser("tcl", std::make_unique<TclOutlineParser>(), - std::make_unique<TclCodeParser>()); Doxygen::parserManager->registerParser("md", std::make_unique<MarkdownOutlineParser>(), std::make_unique<FileCodeParser>()); @@ -9907,12 +9712,8 @@ void initDoxygen() #ifdef USE_LIBCLANG Doxygen::clangUsrMap = new QDict<Definition>(50177); #endif - Doxygen::inputNameList = new FileNameList; - Doxygen::inputNameList->setAutoDelete(TRUE); - Doxygen::memberNameSDict = new MemberNameSDict(10000); - Doxygen::memberNameSDict->setAutoDelete(TRUE); - Doxygen::functionNameSDict = new MemberNameSDict(10000); - Doxygen::functionNameSDict->setAutoDelete(TRUE); + Doxygen::memberNameLinkedMap = new MemberNameLinkedMap; + Doxygen::functionNameLinkedMap = new MemberNameLinkedMap; Doxygen::groupSDict = new GroupSDict(17); Doxygen::groupSDict->setAutoDelete(TRUE); Doxygen::namespaceSDict = new NamespaceSDict(20); @@ -9930,26 +9731,19 @@ void initDoxygen() Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE); Doxygen::dirRelations.setAutoDelete(TRUE); - Doxygen::citeDict = new CiteDict(257); Doxygen::genericsDict = new GenericsSDict; Doxygen::indexList = new IndexList; - Doxygen::formulaList = new FormulaList; - Doxygen::formulaList->setAutoDelete(TRUE); - Doxygen::formulaDict = new FormulaDict(1009); - Doxygen::formulaNameDict = new FormulaDict(1009); - Doxygen::sectionDict = new SectionDict(257); - Doxygen::sectionDict->setAutoDelete(TRUE); // initialisation of these globals depends on // configuration switches so we need to postpone these Doxygen::globalScope = 0; - Doxygen::inputNameDict = 0; - Doxygen::includeNameDict = 0; - Doxygen::exampleNameDict = 0; - Doxygen::imageNameDict = 0; - Doxygen::dotFileNameDict = 0; - Doxygen::mscFileNameDict = 0; - Doxygen::diaFileNameDict = 0; + Doxygen::inputNameLinkedMap = 0; + Doxygen::includeNameLinkedMap = 0; + Doxygen::exampleNameLinkedMap = 0; + Doxygen::imageNameLinkedMap = 0; + Doxygen::dotFileNameLinkedMap = 0; + Doxygen::mscFileNameLinkedMap = 0; + Doxygen::diaFileNameLinkedMap = 0; /************************************************************************** * Initialize some global constants @@ -9966,24 +9760,22 @@ void initDoxygen() void cleanUpDoxygen() { - delete Doxygen::sectionDict; - delete Doxygen::formulaNameDict; - delete Doxygen::formulaDict; - delete Doxygen::formulaList; + FormulaManager::instance().clear(); + SectionManager::instance().clear(); + delete Doxygen::indexList; delete Doxygen::genericsDict; - delete Doxygen::inputNameDict; - delete Doxygen::includeNameDict; - delete Doxygen::exampleNameDict; - delete Doxygen::imageNameDict; - delete Doxygen::dotFileNameDict; - delete Doxygen::mscFileNameDict; - delete Doxygen::diaFileNameDict; + delete Doxygen::inputNameLinkedMap; + delete Doxygen::includeNameLinkedMap; + delete Doxygen::exampleNameLinkedMap; + delete Doxygen::imageNameLinkedMap; + delete Doxygen::dotFileNameLinkedMap; + delete Doxygen::mscFileNameLinkedMap; + delete Doxygen::diaFileNameLinkedMap; delete Doxygen::mainPage; delete Doxygen::pageSDict; delete Doxygen::exampleSDict; delete Doxygen::globalScope; - delete Doxygen::xrefLists; delete Doxygen::parserManager; delete Doxygen::preprocessor; delete theTranslator; @@ -10010,9 +9802,8 @@ void cleanUpDoxygen() } } - delete Doxygen::inputNameList; - delete Doxygen::memberNameSDict; - delete Doxygen::functionNameSDict; + delete Doxygen::memberNameLinkedMap; + delete Doxygen::functionNameLinkedMap; delete Doxygen::groupSDict; delete Doxygen::classSDict; delete Doxygen::hiddenClasses; @@ -10039,15 +9830,7 @@ static int computeIdealCacheParam(uint v) void readConfiguration(int argc, char **argv) { - QCString versionString; - if (strlen(getGitVersion())>0) - { - versionString = QCString(getVersion())+" ("+getGitVersion()+")"; - } - else - { - versionString = getVersion(); - } + QCString versionString = getFullVersion(); /************************************************************************** * Handle arguments * @@ -10440,18 +10223,13 @@ void checkConfiguration() void adjustConfiguration() { Doxygen::globalScope = createNamespaceDef("<globalScope>",1,1,"<globalScope>"); - Doxygen::inputNameDict = new FileNameDict(10007); - Doxygen::includeNameDict = new FileNameDict(10007); - Doxygen::exampleNameDict = new FileNameDict(1009); - Doxygen::exampleNameDict->setAutoDelete(TRUE); - Doxygen::imageNameDict = new FileNameDict(257); - Doxygen::imageNameDict->setAutoDelete(TRUE); - Doxygen::dotFileNameDict = new FileNameDict(257); - Doxygen::dotFileNameDict->setAutoDelete(TRUE); - Doxygen::mscFileNameDict = new FileNameDict(257); - Doxygen::mscFileNameDict->setAutoDelete(TRUE); - Doxygen::diaFileNameDict = new FileNameDict(257); - Doxygen::diaFileNameDict->setAutoDelete(TRUE); + Doxygen::inputNameLinkedMap = new FileNameLinkedMap; + Doxygen::includeNameLinkedMap = new FileNameLinkedMap; + Doxygen::exampleNameLinkedMap = new FileNameLinkedMap; + Doxygen::imageNameLinkedMap = new FileNameLinkedMap; + Doxygen::dotFileNameLinkedMap = new FileNameLinkedMap; + Doxygen::mscFileNameLinkedMap = new FileNameLinkedMap; + Doxygen::diaFileNameLinkedMap = new FileNameLinkedMap; QCString outputLanguage=Config_getEnum(OUTPUT_LANGUAGE); if (!setTranslator(outputLanguage)) @@ -10472,8 +10250,6 @@ void adjustConfiguration() Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION); - Doxygen::xrefLists->setAutoDelete(TRUE); - Doxygen::parseSourcesNeeded = Config_getBool(CALL_GRAPH) || Config_getBool(CALLER_GRAPH) || Config_getBool(REFERENCES_RELATION) || @@ -10583,13 +10359,9 @@ static void writeTagFile() tagFile << "<tagfile>" << endl; // for each file - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isLinkableInProject()) fd->writeTagFile(tagFile); } @@ -10636,6 +10408,7 @@ static void writeTagFile() << "</title>" << endl << " <filename>" << convertToXML(Doxygen::mainPage->getOutputFileBase()) + << Doxygen::htmlFileExtension << "</filename>" << endl; mainPage->writeDocAnchorsToTagFile(); @@ -10728,7 +10501,7 @@ void searchInputFiles() { pl = Config_getList(FILE_PATTERNS); } - readFileOrDirectory(s,0,Doxygen::includeNameDict,0,&pl, + readFileOrDirectory(s,Doxygen::includeNameLinkedMap,0,&pl, &exclPatterns,0,0, alwaysRecursive, TRUE,killDict); @@ -10742,7 +10515,7 @@ void searchInputFiles() s=examplePathList.first(); while (s) { - readFileOrDirectory(s,0,Doxygen::exampleNameDict,0, + readFileOrDirectory(s,Doxygen::exampleNameLinkedMap,0, &Config_getList(EXAMPLE_PATTERNS), 0,0,0, (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), @@ -10757,7 +10530,7 @@ void searchInputFiles() s=imagePathList.first(); while (s) { - readFileOrDirectory(s,0,Doxygen::imageNameDict,0,0, + readFileOrDirectory(s,Doxygen::imageNameLinkedMap,0,0, 0,0,0, alwaysRecursive, TRUE,killDict); @@ -10771,7 +10544,7 @@ void searchInputFiles() s=dotFileList.first(); while (s) { - readFileOrDirectory(s,0,Doxygen::dotFileNameDict,0,0, + readFileOrDirectory(s,Doxygen::dotFileNameLinkedMap,0,0, 0,0,0, alwaysRecursive, TRUE,killDict); @@ -10785,7 +10558,7 @@ void searchInputFiles() s=mscFileList.first(); while (s) { - readFileOrDirectory(s,0,Doxygen::mscFileNameDict,0,0, + readFileOrDirectory(s,Doxygen::mscFileNameLinkedMap,0,0, 0,0,0, alwaysRecursive, TRUE,killDict); @@ -10799,7 +10572,7 @@ void searchInputFiles() s=diaFileList.first(); while (s) { - readFileOrDirectory(s,0,Doxygen::diaFileNameDict,0,0, + readFileOrDirectory(s,Doxygen::diaFileNameLinkedMap,0,0, 0,0,0, alwaysRecursive, TRUE,killDict); @@ -10812,7 +10585,7 @@ void searchInputFiles() s=excludeList.first(); while (s) { - readFileOrDirectory(s,0,0,0,&Config_getList(FILE_PATTERNS), + readFileOrDirectory(s,0,0,&Config_getList(FILE_PATTERNS), 0,0,&excludeNameDict, alwaysRecursive, FALSE); @@ -10840,8 +10613,7 @@ void searchInputFiles() readFileOrDirectory( path, - Doxygen::inputNameList, - Doxygen::inputNameDict, + Doxygen::inputNameLinkedMap, &excludeNameDict, &Config_getList(FILE_PATTERNS), &exclPatterns, @@ -10853,7 +10625,14 @@ void searchInputFiles() } s=inputList.next(); } - Doxygen::inputNameList->sort(); + std::sort(Doxygen::inputNameLinkedMap->begin(), + Doxygen::inputNameLinkedMap->end(), + [](const auto &f1,const auto &f2) + { + return Config_getBool(FULL_PATH_NAMES) ? + qstricmp(f1->fullName(),f2->fullName())<0 : + qstricmp(f1->fileName(),f2->fileName())<0; + }); g_s.end(); delete killDict; @@ -10864,6 +10643,10 @@ void parseInput() { atexit(exitDoxygen); + // we would like to show the versionString earlier, but we first have to handle the configuration file + // to know the value of the QUIET setting. + QCString versionString = getFullVersion(); + msg("Doxygen version used: %s\n",versionString.data()); /************************************************************************** * Make sure the output directory exists @@ -11034,18 +10817,22 @@ void parseInput() if (Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX)) { - readFormulaRepository(Config_getString(HTML_OUTPUT)); + FormulaManager::instance().readFormulas(Config_getString(HTML_OUTPUT)); } if (Config_getBool(GENERATE_RTF)) { // in case GENERRATE_HTML is set we just have to compare, both repositories should be identical - readFormulaRepository(Config_getString(RTF_OUTPUT),Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX)); + FormulaManager::instance().readFormulas(Config_getString(RTF_OUTPUT), + Config_getBool(GENERATE_HTML) && + !Config_getBool(USE_MATHJAX)); } if (Config_getBool(GENERATE_DOCBOOK)) { // in case GENERRATE_HTML is set we just have to compare, both repositories should be identical - readFormulaRepository(Config_getString(DOCBOOK_OUTPUT), - (Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX)) || Config_getBool(GENERATE_RTF)); + FormulaManager::instance().readFormulas(Config_getString(DOCBOOK_OUTPUT), + (Config_getBool(GENERATE_HTML) && + !Config_getBool(USE_MATHJAX)) || + Config_getBool(GENERATE_RTF)); } /************************************************************************** @@ -11073,10 +10860,6 @@ void parseInput() parseFiles(root); g_s.end(); - // we are done with input scanning now, so free up the buffers used by flex - // (can be around 4MB) - pyscanFreeScanner(); - /************************************************************************** * Gather information * **************************************************************************/ @@ -11250,9 +11033,20 @@ void parseInput() findGroupScope(root.get()); g_s.end(); + auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2) + { + return qstricmp(n1->memberName()+getPrefixIndex(n1->memberName()), + n2->memberName()+getPrefixIndex(n2->memberName()) + )<0; + }; + g_s.begin("Sorting lists...\n"); - Doxygen::memberNameSDict->sort(); - Doxygen::functionNameSDict->sort(); + std::sort(Doxygen::memberNameLinkedMap->begin(), + Doxygen::memberNameLinkedMap->end(), + memberNameComp); + std::sort(Doxygen::functionNameLinkedMap->begin(), + Doxygen::functionNameLinkedMap->end(), + memberNameComp); Doxygen::hiddenClasses->sort(); Doxygen::classSDict->sort(); g_s.end(); @@ -11298,7 +11092,7 @@ void parseInput() // compute the shortest possible names of all files // without losing the uniqueness of the file names. g_s.begin("Generating disk names...\n"); - Doxygen::inputNameList->generateDiskNames(); + generateDiskNames(); g_s.end(); g_s.begin("Adding source references...\n"); @@ -11325,11 +11119,8 @@ void parseInput() g_s.end(); } - //g_s.begin("Resolving citations...\n"); - //Doxygen::citeDict->resolve(); - g_s.begin("Generating citations page...\n"); - Doxygen::citeDict->generatePage(); + CitationManager::instance().generatePage(); g_s.end(); g_s.begin("Counting members...\n"); @@ -11479,6 +11270,29 @@ void generateOutput() } g_s.end(); + const FormulaManager &fm = FormulaManager::instance(); + if (fm.hasFormulas() && generateHtml + && !Config_getBool(USE_MATHJAX)) + { + g_s.begin("Generating images for formulas in HTML...\n"); + fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)=="svg" ? + FormulaManager::Format::Vector : FormulaManager::Format::Bitmap, FormulaManager::HighDPI::On); + g_s.end(); + } + if (fm.hasFormulas() && generateRtf) + { + g_s.begin("Generating images for formulas in RTF...\n"); + fm.generateImages(Config_getString(RTF_OUTPUT),FormulaManager::Format::Bitmap); + g_s.end(); + } + + if (fm.hasFormulas() && generateDocbook) + { + g_s.begin("Generating images for formulas in Docbook...\n"); + fm.generateImages(Config_getString(DOCBOOK_OUTPUT),FormulaManager::Format::Bitmap); + g_s.end(); + } + g_s.begin("Generating example documentation...\n"); generateExampleDocs(); g_s.end(); @@ -11518,27 +11332,6 @@ void generateOutput() generateDirDocs(*g_outputList); g_s.end(); - if (Doxygen::formulaList->count()>0 && generateHtml - && !Config_getBool(USE_MATHJAX)) - { - g_s.begin("Generating bitmaps for formulas in HTML...\n"); - Doxygen::formulaList->generateBitmaps(Config_getString(HTML_OUTPUT)); - g_s.end(); - } - if (Doxygen::formulaList->count()>0 && generateRtf) - { - g_s.begin("Generating bitmaps for formulas in RTF...\n"); - Doxygen::formulaList->generateBitmaps(Config_getString(RTF_OUTPUT)); - g_s.end(); - } - - if (Doxygen::formulaList->count()>0 && generateDocbook) - { - g_s.begin("Generating bitmaps for formulas in Docbook...\n"); - Doxygen::formulaList->generateBitmaps(Config_getString(DOCBOOK_OUTPUT)); - g_s.end(); - } - if (Config_getBool(SORT_GROUP_NAMES)) { Doxygen::groupSDict->sort(); @@ -11743,4 +11536,3 @@ void generateOutput() // delete Doxygen::symbolStorage; g_successfulRun=TRUE; } - diff --git a/src/doxygen.h b/src/doxygen.h index a23a678..a18ac3b 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -27,7 +27,6 @@ #include "membergroup.h" #include "dirdef.h" #include "memberlist.h" -#include "docgroup.h" class RefList; class PageSList; @@ -35,7 +34,6 @@ class PageSDict; class PageDef; class SearchIndexIntf; class ParserManager; -class ObjCache; class Store; class QFileInfo; class BufStr; @@ -47,9 +45,8 @@ class FileDef; class ClassDef; class ClassSDict; class GenericsSDict; -class MemberNameSDict; -class FileNameDict; -class FileNameList; +class MemberNameLinkedMap; +class FileNameLinkedMap; class NamespaceSDict; class NamespaceDef; class DefinitionIntf; @@ -59,7 +56,6 @@ class IndexList; class FormulaList; class FormulaDict; class FormulaNameDict; -class SectionDict; class Preprocessor; struct MemberGroupInfo; @@ -101,31 +97,25 @@ class Doxygen static PageSDict *pageSDict; static PageDef *mainPage; static bool insideMainPage; - static FileNameDict *includeNameDict; - static FileNameDict *exampleNameDict; + static FileNameLinkedMap *includeNameLinkedMap; + static FileNameLinkedMap *exampleNameLinkedMap; static QDict<void> inputPaths; - static FileNameDict *inputNameDict; - static FileNameList *inputNameList; - static FileNameDict *imageNameDict; - static FileNameDict *dotFileNameDict; - static FileNameDict *mscFileNameDict; - static FileNameDict *diaFileNameDict; + static FileNameLinkedMap *inputNameLinkedMap; + static FileNameLinkedMap *imageNameLinkedMap; + static FileNameLinkedMap *dotFileNameLinkedMap; + static FileNameLinkedMap *mscFileNameLinkedMap; + static FileNameLinkedMap *diaFileNameLinkedMap; + static MemberNameLinkedMap *memberNameLinkedMap; + static MemberNameLinkedMap *functionNameLinkedMap; static QStrList tagfileList; - static MemberNameSDict *memberNameSDict; - static MemberNameSDict *functionNameSDict; - static SectionDict *sectionDict; static StringDict namespaceAliasDict; static GroupSDict *groupSDict; static NamespaceSDict *namespaceSDict; - static FormulaList *formulaList; - static FormulaDict *formulaDict; - static FormulaDict *formulaNameDict; static StringDict tagDestinationDict; static StringDict aliasDict; static QIntDict<MemberGroupInfo> memGrpInfoDict; static QDict<void> expandAsDefinedDict; static NamespaceDef *globalScope; - static QDict<RefList> *xrefLists; // array of xref lists: todo, test, bug, deprecated ... static QCString htmlFileExtension; static bool parseSourcesNeeded; static QTime runningTime; @@ -143,8 +133,6 @@ class Doxygen static QCString objDBFileName; static QCString entryDBFileName; static QCString filterDBFileName; - static CiteDict *citeDict; - static bool gatherDefines; static bool userComments; static IndexList *indexList; static int subpageNestingLevel; @@ -152,7 +140,6 @@ class Doxygen static bool generatingXmlOutput; static bool markdownSupport; static GenericsSDict *genericsDict; - static DocGroup docGroup; static Preprocessor *preprocessor; }; @@ -167,8 +154,7 @@ void readAliases(); void readFormulaRepository(QCString dir, bool cmp = FALSE); void cleanUpDoxygen(); int readFileOrDirectory(const char *s, - FileNameList *fnList, - FileNameDict *fnDict, + FileNameLinkedMap *fnDict, StringDict *exclDict, QStrList *patList, QStrList *exclPatList, @@ -180,8 +166,7 @@ int readFileOrDirectory(const char *s, QDict<void> *paths = 0 ); int readDir(QFileInfo *fi, - FileNameList *fnList, - FileNameDict *fnDict, + FileNameLinkedMap *fnDict, StringDict *exclDict, QStrList *patList, QStrList *exclPatList, diff --git a/src/doxygen.md b/src/doxygen.md index c124e09..d8db231 100644 --- a/src/doxygen.md +++ b/src/doxygen.md @@ -223,7 +223,6 @@ Topics TODO - Python - Fortran - VHDL - - TCL - Tag files - Marshaling to/from disk - Portability functions diff --git a/src/entry.cpp b/src/entry.cpp index cc8cd1f..305487e 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -95,6 +95,7 @@ Entry::Entry(const Entry &e) exception = e.exception; typeConstr = e.typeConstr; bodyLine = e.bodyLine; + bodyColumn = e.bodyColumn; endBodyLine = e.endBodyLine; mGrpId = e.mGrpId; anchors = e.anchors; @@ -169,21 +170,6 @@ void Entry::copyToSubEntry(const std::shared_ptr<Entry> ¤t) m_sublist.push_back(copy); } -void Entry::moveFromSubEntry(const Entry *child,std::shared_ptr<Entry> &moveTo) -{ - auto it = std::find_if(m_sublist.begin(),m_sublist.end(), - [child](const std::shared_ptr<Entry>&elem) { return elem.get()==child; }); - if (it!=m_sublist.end()) - { - moveTo = *it; - m_sublist.erase(it); - } - else - { - moveTo.reset(); - } -} - void Entry::removeSubEntry(const Entry *e) { auto it = std::find_if(m_sublist.begin(),m_sublist.end(), @@ -228,6 +214,7 @@ void Entry::reset() startLine = 1; startColumn = 1; bodyLine = -1; + bodyColumn = 1; endBodyLine = -1; mGrpId = -1; callGraph = entryCallGraph; @@ -270,13 +257,4 @@ void Entry::setFileDef(FileDef *fd) } } -void Entry::addSpecialListItem(const char *listName,int itemId) -{ - ListItemInfo ili; - ili.type = listName; - ili.itemId = itemId; - sli.push_back(ili); -} - - //------------------------------------------------------------------ diff --git a/src/entry.h b/src/entry.h index 0391075..71c555c 100644 --- a/src/entry.h +++ b/src/entry.h @@ -26,10 +26,10 @@ #include "types.h" #include "arguments.h" -struct SectionInfo; +class SectionInfo; class QFile; class FileDef; -struct ListItemInfo; +class RefItem; /** This class stores information about an inheritance relation */ @@ -194,8 +194,6 @@ class Entry Entry(const Entry &); ~Entry(); - void addSpecialListItem(const char *listName,int index); - /*! Returns the parent for this Entry or 0 if this entry has no parent. */ Entry *parent() const { return m_parent; } @@ -205,7 +203,7 @@ class Entry const std::vector< std::shared_ptr<Entry> > &children() const { return m_sublist; } /*! @name add entry as a child and pass ownership. - * @note This makes the entry passed invalid! (TODO: tclscanner.l still has use after move!) + * @note This makes the entry passed invalid! * @{ */ void moveToSubEntryAndKeep(Entry* e); @@ -216,9 +214,6 @@ class Entry void moveToSubEntryAndRefresh(Entry* &e); void moveToSubEntryAndRefresh(std::shared_ptr<Entry> &e); - /*! take \a child of of to list of children and move it into \a moveTo */ - void moveFromSubEntry(const Entry *child,std::shared_ptr<Entry> &moveTo); - /*! make a copy of \a e and add it as a child to this entry */ void copyToSubEntry (Entry* e); void copyToSubEntry (const std::shared_ptr<Entry> &e); @@ -283,7 +278,8 @@ class Entry QCString inside; //!< name of the class in which documents are found QCString exception; //!< throw specification ArgumentList typeConstr; //!< where clause (C#) for type constraints - int bodyLine; //!< line number of the definition in the source + int bodyLine; //!< line number of the body in the source + int bodyColumn; //!< column of the body in the source int endBodyLine; //!< line number where the definition ends int mGrpId; //!< member group id std::vector<BaseInfo> extends; //!< list of base classes @@ -292,7 +288,7 @@ class Entry QCString fileName; //!< file this entry was extracted from int startLine; //!< start line of entry in the source int startColumn; //!< start column of entry in the source - std::vector<ListItemInfo> sli; //!< special lists (test/todo/bug/deprecated/..) this entry is in + std::vector<RefItem*> sli; //!< special lists (test/todo/bug/deprecated/..) this entry is in SrcLangExt lang; //!< programming language in which this entry was found bool hidden; //!< does this represent an entity that is hidden from the output bool artificial; //!< Artificially introduced item @@ -337,4 +333,6 @@ class Entry FileDef *m_fileDef; }; +typedef std::vector< std::shared_ptr<Entry> > EntryList; + #endif diff --git a/src/example.h b/src/example.h index 321982b..2af06ba 100644 --- a/src/example.h +++ b/src/example.h @@ -36,7 +36,7 @@ struct Example class ExampleSDict : public SDict<Example> { public: - ExampleSDict(int size=17) : SDict<Example>(size) { setAutoDelete(TRUE); } + ExampleSDict(uint size=17) : SDict<Example>(size) { setAutoDelete(TRUE); } ~ExampleSDict() {} private: int compareValues(const Example *item1,const Example *item2) const diff --git a/src/filedef.cpp b/src/filedef.cpp index fb0e290..454712b 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -213,7 +213,7 @@ class DevNullCodeDocInterface : public CodeOutputInterface //--------------------------------------------------------------------------- -/*! create a new file definition, where \a p is the file path, +/*! create a new file definition, where \a p is the file path, \a nm the file name, and \a lref is an HTML anchor name if the file was read from a tag file or 0 otherwise */ @@ -231,16 +231,16 @@ FileDefImpl::FileDefImpl(const char *p,const char *nm, m_structSDict = 0; m_exceptionSDict = 0; m_includeList = 0; - m_includeDict = 0; + m_includeDict = 0; m_includedByList = 0; - m_includedByDict = 0; - m_namespaceSDict = 0; + m_includedByDict = 0; + m_namespaceSDict = 0; m_srcDefDict = 0; m_srcMemberDict = 0; m_usingDirList = 0; m_usingDeclList = 0; m_package = 0; - m_isSource = guessSection(nm)==Entry::SOURCE_SEC; + m_isSource = guessSection(nm)==Entry::SOURCE_SEC; m_docname = nm; m_dir = 0; m_visited = FALSE; @@ -289,7 +289,7 @@ void FileDefImpl::setDiskName(const QCString &name) } } -/*! Compute the HTML anchor names for all members in the class */ +/*! Compute the HTML anchor names for all members in the class */ void FileDefImpl::computeAnchors() { MemberList *ml = getMemberList(MemberListType_allMembersList); @@ -338,7 +338,7 @@ bool FileDefImpl::hasDetailedDescription() const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); - return ((!briefDescription().isEmpty() && repeatBrief) || + return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().stripWhiteSpace().isEmpty() || // avail empty section (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()) ); @@ -349,7 +349,7 @@ void FileDefImpl::writeTagFile(FTextStream &tagFile) tagFile << " <compound kind=\"file\">" << endl; tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; tagFile << " <path>" << convertToXML(getPath()) << "</path>" << endl; - tagFile << " <filename>" << convertToXML(addHtmlExtensionIfMissing(getOutputFileBase())) << "</filename>" << endl; + tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl; if (m_includeList && m_includeList->count()>0) { QListIterator<IncludeInfo> ili(*m_includeList); @@ -359,20 +359,20 @@ void FileDefImpl::writeTagFile(FTextStream &tagFile) if (!ii->indirect) { FileDef *fd=ii->fileDef; - if (fd && fd->isLinkable() && !fd->isReference()) + if (fd && fd->isLinkable() && !fd->isReference()) { bool isIDLorJava = FALSE; SrcLangExt lang = fd->getLanguage(); isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no"; const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no"; - tagFile << " <includes id=\"" + tagFile << " <includes id=\"" << convertToXML(fd->getOutputFileBase()) << "\" " << "name=\"" << convertToXML(fd->name()) << "\" " << "local=\"" << locStr << "\" " << "imported=\"" << impStr << "\">" << convertToXML(ii->includeName) - << "</includes>" + << "</includes>" << endl; } } @@ -467,7 +467,7 @@ void FileDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) ol.popGeneratorState(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - ol.writeAnchor(0,"details"); + ol.writeAnchor(0,"details"); ol.popGeneratorState(); ol.startGroupHeader(); ol.parseText(title); @@ -478,7 +478,7 @@ void FileDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) { ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE); } - if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) && + if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) && !documentation().isEmpty()) { ol.pushGeneratorState(); @@ -496,20 +496,20 @@ void FileDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE); } //printf("Writing source ref for file %s\n",name().data()); - if (Config_getBool(SOURCE_BROWSER)) + if (Config_getBool(SOURCE_BROWSER)) { //if Latex enabled and LATEX_SOURCE_CODE isn't -> skip, bug_738548 ol.pushGeneratorState(); if (ol.isEnabled(OutputGenerator::Latex) && !Config_getBool(LATEX_SOURCE_CODE)) - { + { ol.disable(OutputGenerator::Latex); } if (ol.isEnabled(OutputGenerator::Docbook) && !Config_getBool(DOCBOOK_PROGRAMLISTING)) - { + { ol.disable(OutputGenerator::Docbook); } if (ol.isEnabled(OutputGenerator::RTF) && !Config_getBool(RTF_SOURCE_CODE)) - { + { ol.disable(OutputGenerator::RTF); } @@ -626,7 +626,7 @@ void FileDefImpl::writeIncludeFiles(OutputList &ol) ol.docify(ii->includeName); ol.enableAll(); ol.disableAllBut(OutputGenerator::Html); - + // Here we use the include file name as it appears in the file. // we could also we the name as it is used within doxygen, // then we should have used fd->docName() instead of ii->includeName @@ -640,13 +640,13 @@ void FileDefImpl::writeIncludeFiles(OutputList &ol) { ol.docify(ii->includeName); } - + ol.enableAll(); if (ii->local || isIDLorJava) ol.docify("\""); else ol.docify(">"); - if (isIDLorJava) + if (isIDLorJava) ol.docify(";"); ol.endTypewriter(); ol.lineBreak(); @@ -669,7 +669,7 @@ void FileDefImpl::writeIncludeGraph(OutputList &ol) } else if (!incDepGraph.isTrivial()) { - ol.startTextBlock(); + ol.startTextBlock(); ol.disable(OutputGenerator::Man); ol.startInclDepGraph(); ol.parseText(theTranslator->trInclDepGraph(name())); @@ -694,7 +694,7 @@ void FileDefImpl::writeIncludedByGraph(OutputList &ol) } else if (!incDepGraph.isTrivial()) { - ol.startTextBlock(); + ol.startTextBlock(); ol.disable(OutputGenerator::Man); ol.startInclDepGraph(); ol.parseText(theTranslator->trInclByDepGraph()); @@ -786,7 +786,7 @@ void FileDefImpl::writeMemberGroups(OutputList &ol) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - if ((!mg->allMembersInSameSection() || !m_subGrouping) + if ((!mg->allMembersInSameSection() || !m_subGrouping) && mg->header()!="[NOHEADER]") { mg->writeDeclarations(ol,0,0,this,0); @@ -872,13 +872,13 @@ void FileDefImpl::writeSummaryLinks(OutputList &ol) const } /*! Write the documentation page for this file to the file of output - generators \a ol. + generators \a ol. */ void FileDefImpl::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //funcList->countDecMembers(); - + //QCString fn = name(); //if (Config_getBool(FULL_PATH_NAMES)) //{ @@ -886,7 +886,7 @@ void FileDefImpl::writeDocumentation(OutputList &ol) //} //printf("WriteDocumentation diskname=%s\n",diskname.data()); - + QCString versionTitle; if (!m_fileVersion.isEmpty()) { @@ -938,16 +938,16 @@ void FileDefImpl::writeDocumentation(OutputList &ol) ol.endProjectNumber(); ol.enableAll(); } - + if (Doxygen::searchIndex) { Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE); Doxygen::searchIndex->addWord(localName(),TRUE); } - + //---------------------------------------- start flexible part ------------------------------- - + SrcLangExt lang = getLanguage(); QListIterator<LayoutDocEntry> eli( LayoutDocManager::instance().docEntries(LayoutDocManager::File)); @@ -956,12 +956,12 @@ void FileDefImpl::writeDocumentation(OutputList &ol) { switch (lde->kind()) { - case LayoutDocEntry::BriefDesc: + case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); - break; - case LayoutDocEntry::MemberDeclStart: + break; + case LayoutDocEntry::MemberDeclStart: startMemberDeclarations(ol); - break; + break; case LayoutDocEntry::FileIncludes: writeIncludeFiles(ol); break; @@ -974,76 +974,76 @@ void FileDefImpl::writeDocumentation(OutputList &ol) case LayoutDocEntry::FileSourceLink: writeSourceLink(ol); break; - case LayoutDocEntry::FileClasses: + case LayoutDocEntry::FileClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),m_classSDict); } break; - case LayoutDocEntry::FileInterfaces: + case LayoutDocEntry::FileInterfaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),m_interfaceSDict); } break; - case LayoutDocEntry::FileStructs: + case LayoutDocEntry::FileStructs: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),m_structSDict); } break; - case LayoutDocEntry::FileExceptions: + case LayoutDocEntry::FileExceptions: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),m_exceptionSDict); } break; - case LayoutDocEntry::FileNamespaces: + case LayoutDocEntry::FileNamespaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),false); } - break; + break; case LayoutDocEntry::FileConstantGroups: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),true); } break; - case LayoutDocEntry::MemberGroups: + case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); - break; - case LayoutDocEntry::MemberDecl: + break; + case LayoutDocEntry::MemberDecl: { LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); } - break; - case LayoutDocEntry::MemberDeclEnd: + break; + case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; - case LayoutDocEntry::DetailedDesc: + case LayoutDocEntry::DetailedDesc: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeDetailedDescription(ol,ls->title(lang)); } break; - case LayoutDocEntry::MemberDefStart: + case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); - break; + break; case LayoutDocEntry::FileInlineClasses: writeInlineClasses(ol); break; - case LayoutDocEntry::MemberDef: + case LayoutDocEntry::MemberDef: { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); } break; - case LayoutDocEntry::MemberDefEnd: + case LayoutDocEntry::MemberDefEnd: endMemberDocumentation(ol); break; - case LayoutDocEntry::AuthorSection: + case LayoutDocEntry::AuthorSection: writeAuthorSection(ol); break; case LayoutDocEntry::ClassIncludes: @@ -1060,13 +1060,13 @@ void FileDefImpl::writeDocumentation(OutputList &ol) case LayoutDocEntry::NamespaceStructs: case LayoutDocEntry::NamespaceExceptions: case LayoutDocEntry::NamespaceInlineClasses: - case LayoutDocEntry::GroupClasses: - case LayoutDocEntry::GroupInlineClasses: + case LayoutDocEntry::GroupClasses: + case LayoutDocEntry::GroupInlineClasses: case LayoutDocEntry::GroupNamespaces: - case LayoutDocEntry::GroupDirs: - case LayoutDocEntry::GroupNestedGroups: + case LayoutDocEntry::GroupDirs: + case LayoutDocEntry::GroupNestedGroups: case LayoutDocEntry::GroupFiles: - case LayoutDocEntry::GroupGraph: + case LayoutDocEntry::GroupGraph: case LayoutDocEntry::GroupPageDocs: case LayoutDocEntry::DirSubDirs: case LayoutDocEntry::DirFiles: @@ -1095,7 +1095,7 @@ void FileDefImpl::writeMemberPages(OutputList &ol) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - + QListIterator<MemberList> mli(m_memberLists); MemberList *ml; for (mli.toFirst();(ml=mli.current());++mli) @@ -1215,7 +1215,7 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu (void)filesInSameTu; #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); - if (clangAssistedParsing && + if (clangAssistedParsing && (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC)) { ol.startCodeFragment(); @@ -1236,7 +1236,7 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); intf.resetCodeParserState(); ol.startCodeFragment(); - bool needs2PassParsing = + bool needs2PassParsing = Doxygen::parseSourcesNeeded && // we need to parse (filtered) sources for cross-references !filterSourceFiles && // but user wants to show sources as-is !getFileFilter(absFilePath(),TRUE).isEmpty(); // and there is a filter used while parsing @@ -1279,7 +1279,7 @@ void FileDefImpl::parseSource(bool sameTu,QStrList &filesInSameTu) (void)filesInSameTu; #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); - if (clangAssistedParsing && + if (clangAssistedParsing && (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC)) { if (!sameTu) @@ -1351,7 +1351,7 @@ void FileDefImpl::insertMember(MemberDef *md) // name().data(),md->name().data(),md,allMemberList.count()); MemberList *allMemberList = getMemberList(MemberListType_allMembersList); if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef! - { + { return; } @@ -1360,38 +1360,38 @@ void FileDefImpl::insertMember(MemberDef *md) allMemberList = new MemberList(MemberListType_allMembersList); m_memberLists.append(allMemberList); } - allMemberList->append(md); + allMemberList->append(md); //::addFileMemberNameToIndex(md); switch (md->memberType()) { - case MemberType_Variable: - case MemberType_Property: + case MemberType_Variable: + case MemberType_Property: addMemberToList(MemberListType_decVarMembers,md); addMemberToList(MemberListType_docVarMembers,md); break; - case MemberType_Function: + case MemberType_Function: addMemberToList(MemberListType_decFuncMembers,md); addMemberToList(MemberListType_docFuncMembers,md); break; - case MemberType_Typedef: + case MemberType_Typedef: addMemberToList(MemberListType_decTypedefMembers,md); addMemberToList(MemberListType_docTypedefMembers,md); break; - case MemberType_Sequence: + case MemberType_Sequence: addMemberToList(MemberListType_decSequenceMembers,md); addMemberToList(MemberListType_docSequenceMembers,md); break; - case MemberType_Dictionary: + case MemberType_Dictionary: addMemberToList(MemberListType_decDictionaryMembers,md); addMemberToList(MemberListType_docDictionaryMembers,md); break; - case MemberType_Enumeration: + case MemberType_Enumeration: addMemberToList(MemberListType_decEnumMembers,md); addMemberToList(MemberListType_docEnumMembers,md); break; case MemberType_EnumValue: // enum values are shown inside their enums break; - case MemberType_Define: + case MemberType_Define: addMemberToList(MemberListType_decDefineMembers,md); addMemberToList(MemberListType_docDefineMembers,md); break; @@ -1446,7 +1446,7 @@ void FileDefImpl::insertClass(ClassDef *cd) void FileDefImpl::insertNamespace(NamespaceDef *nd) { if (nd->isHidden()) return; - if (!nd->name().isEmpty() && + if (!nd->name().isEmpty() && (m_namespaceSDict==0 || m_namespaceSDict->find(nd->name())==0)) { if (m_namespaceSDict==0) @@ -1464,13 +1464,13 @@ void FileDefImpl::insertNamespace(NamespaceDef *nd) } } -QCString FileDefImpl::name() const -{ - if (Config_getBool(FULL_PATH_NAMES)) - return m_fileName; - else - return DefinitionImpl::name(); -} +QCString FileDefImpl::name() const +{ + if (Config_getBool(FULL_PATH_NAMES)) + return m_fileName; + else + return DefinitionImpl::name(); +} void FileDefImpl::addSourceRef(int line,Definition *d,MemberDef *md) { @@ -1522,10 +1522,10 @@ void FileDefImpl::addUsingDirective(const NamespaceDef *nd) //printf("%p: FileDefImpl::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); } -NamespaceSDict *FileDefImpl::getUsedNamespaces() const -{ +NamespaceSDict *FileDefImpl::getUsedNamespaces() const +{ //printf("%p: FileDefImpl::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); - return m_usingDirList; + return m_usingDirList; } void FileDefImpl::addUsingDeclaration(Definition *d) @@ -1667,13 +1667,13 @@ bool FileDefImpl::isIncluded(const QCString &name) const return m_includeDict!=0 && m_includeDict->find(name)!=0; } -bool FileDefImpl::generateSourceFile() const -{ +bool FileDefImpl::generateSourceFile() const +{ static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool verbatimHeaders = Config_getBool(VERBATIM_HEADERS); - return !isReference() && - (sourceBrowser || - (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC) + return !isReference() && + (sourceBrowser || + (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC) ) && !isDocumentationFile(); } @@ -1682,7 +1682,7 @@ bool FileDefImpl::generateSourceFile() const void FileDefImpl::addListReferences() { { - const std::vector<ListItemInfo> &xrefItems = xrefListItems(); + const std::vector<RefItem*> &xrefItems = xrefListItems(); addRefItem(xrefItems, getOutputFileBase(), theTranslator->trFile(TRUE,TRUE), @@ -1754,7 +1754,7 @@ static Directory *findDirNode(Directory *root,const QCString &name) { // recurse into the directory return findDirNode(dir,name.mid(dirName.length()+1)); - } + } else // partial match => we need to split the path into three parts { QCString baseName =dirName.left(sp); @@ -1784,7 +1784,7 @@ static Directory *findDirNode(Directory *root,const QCString &name) // add new branch to the root if (!root->children().isEmpty()) { - root->children().getLast()->setLast(FALSE); + root->children().getLast()->setLast(FALSE); } root->addChild(base); return newBranch; @@ -1797,14 +1797,14 @@ static Directory *findDirNode(Directory *root,const QCString &name) { return root; // put the file under the root node. } - else // need to create a subdir + else // need to create a subdir { QCString baseName = name.left(si); //printf("new subdir %s\n",baseName.data()); Directory *newBranch = new Directory(root,baseName); if (!root->children().isEmpty()) { - root->children().getLast()->setLast(FALSE); + root->children().getLast()->setLast(FALSE); } root->addChild(newBranch); return newBranch; @@ -1818,7 +1818,7 @@ static void mergeFileDef(Directory *root,FileDef *fd) Directory *dirNode = findDirNode(root,filePath); if (!dirNode->children().isEmpty()) { - dirNode->children().getLast()->setLast(FALSE); + dirNode->children().getLast()->setLast(FALSE); } DirEntry *e=new DirEntry(dirNode,fd); dirNode->addChild(e); @@ -1912,7 +1912,7 @@ static void addDirsAsGroups(Directory *root,GroupDef *parent,int level) root->path(), // name root->name() // title ); - if (parent) + if (parent) { parent->addGroup(gd); gd->makePartOfGroup(parent); @@ -1937,15 +1937,11 @@ void generateFileTree() { Directory *root=new Directory(0,"root"); root->setLast(TRUE); - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { - mergeFileDef(root,fd); + mergeFileDef(root,fd.get()); } } //t << "<div class=\"directory\">\n"; @@ -2058,8 +2054,8 @@ QCString FileDefImpl::getOutputFileBase() const } /*! Returns the name of the verbatim copy of this file (if any). */ -QCString FileDefImpl::includeName() const -{ +QCString FileDefImpl::includeName() const +{ return getSourceFileBase(); } @@ -2143,7 +2139,7 @@ void FileDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const { static bool optVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); MemberList * ml = getMemberList(lt); - if (ml) + if (ml) { if (optVhdl) // use specific declarations function { diff --git a/src/filedef.h b/src/filedef.h index b66d7be..2ca33db 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -217,7 +217,7 @@ class OutputNameList : public QList<FileList> class OutputNameDict : public QDict<FileList> { public: - OutputNameDict(int size) : QDict<FileList>(size) {} + OutputNameDict(uint size) : QDict<FileList>(size) {} ~OutputNameDict() {} }; diff --git a/src/filename.cpp b/src/filename.cpp deleted file mode 100644 index 637fe33..0000000 --- a/src/filename.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#include "filename.h" -#include "util.h" -#include "config.h" - -FileName::FileName(const char *fn,const char *n) : FileList() -{ - setAutoDelete(TRUE); - fName=fn; - name=n; -} - -FileName::~FileName() -{ -} - - -void FileName::generateDiskNames() -{ - //QCString commonPrefix; - QListIterator<FileDef> it(*this); - FileDef *fd; - int count=0; - for (;(fd=it.current());++it) - { - if (!fd->isReference()) count++; - } - if (count==1) - { - // skip references - for (it.toFirst();(fd=it.current()) && fd->isReference();++it) { } - if (fd) - { - // name if unique, so diskname is simply the name - //printf("!!!!!!!! Unique disk name=%s for fd=%s\n",name.data(),fd->diskname.data()); - fd->setDiskName(name); - } - } - else if (count>1) // multiple occurrences of the same file name - { - //printf("Multiple occurrences of %s\n",name.data()); - int i=0,j=0; - bool found=FALSE; - while (!found) // search for the common prefix of all paths - { - for (it.toFirst();(fd=it.current()) && fd->isReference();++it) { } - if (fd) - { - char c=fd->getPath().at(i); - if (c=='/') j=i; // remember last position of dirname - ++it; - while ((fd=it.current()) && !found) - { - QCString path = fd->getPath(); - if (!fd->isReference()) - { - //printf("i=%d j=%d fd->path='%s' fd->name='%s'\n",i,j,fd->path.left(i).data(),fd->name().data()); - if (i==(int)path.length()) - { - //warning("Input file %s found multiple times!\n" - // " The generated documentation for this file may not be correct!\n",fd->absFilePath().data()); - found=TRUE; - } - else if (path[i]!=c) - { - found=TRUE; - } - } - ++it; - } - i++; - } - } - for (it.toFirst();(fd=it.current());++it) - { - //printf("fd->setName(%s)\n",(fd->path.right(fd->path.length()-j-1)+name).data()); - if (!fd->isReference()) - { - QCString path = fd->getPath(); - QCString prefix = path.right(path.length()-j-1); - fd->setName(prefix+name); - //printf("!!!!!!!! non unique disk name=%s:%s\n",prefix.data(),name.data()); - fd->setDiskName(prefix+name); - } - } - } -} - -int FileName::compareValues(const FileDef *f1, const FileDef *f2) const -{ - return qstricmp(f1->fileName(),f2->fileName()); -} - -FileNameIterator::FileNameIterator(const FileName &fname) : - QListIterator<FileDef>(fname) -{ -} - -FileNameList::FileNameList() : QList<FileName>() -{ -} - -FileNameList::~FileNameList() -{ -} - -void FileNameList::generateDiskNames() -{ - FileNameListIterator it(*this); - FileName *fn; - for (;(fn=it.current());++it) - { - fn->generateDiskNames(); - } -} - -int FileNameList::compareValues(const FileName *f1, const FileName *f2) const -{ - return Config_getBool(FULL_PATH_NAMES) ? - qstricmp(f1->fullName(),f2->fullName()) : - qstricmp(f1->fileName(),f2->fileName()); -} - -FileNameListIterator::FileNameListIterator(const FileNameList &fnlist) : - QListIterator<FileName>(fnlist) -{ -} - -static bool getCaseSenseNames() -{ - static bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES); - return caseSenseNames; -} - -FileNameDict::FileNameDict(uint size) : QDict<FileName>(size,getCaseSenseNames()) -{ -} - diff --git a/src/filename.h b/src/filename.h index fbee0e1..c3a0d3e 100644 --- a/src/filename.h +++ b/src/filename.h @@ -1,12 +1,10 @@ /****************************************************************************** * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -18,57 +16,31 @@ #ifndef FILENAME_H #define FILENAME_H -#include <qdict.h> -#include <qlist.h> -#include "filedef.h" +#include <memory> +#include <vector> -/** Class representing all files with a certain base name */ -class FileName : public FileList -{ - public: - FileName(const char *fn,const char *name); - ~FileName(); - const char *fileName() const { return name; } - const char *fullName() const { return fName; } - void generateDiskNames(); +#include "linkedmap.h" - private: - int compareValues(const FileDef *item1,const FileDef *item2) const; - QCString name; - QCString fName; -}; +class FileDef; -/** Iterator for FileDef objects in a FileName list. */ -class FileNameIterator : public QListIterator<FileDef> +/** Class representing all files with a certain base name */ +class FileName : public std::vector< std::unique_ptr<FileDef> > { public: - FileNameIterator(const FileName &list); -}; + FileName(const char *nm,const char *fn) : m_name(nm), m_fName(fn), m_pathName("tmp") {} + const char *fileName() const { return m_name; } + const char *fullName() const { return m_fName; } + const char *path() const { return m_pathName; } -/** Class representing a list of FileName objects. */ -class FileNameList : public QList<FileName> -{ - public: - FileNameList(); - ~FileNameList(); - void generateDiskNames(); private: - int compareValues(const FileName *item1,const FileName *item2) const; + QCString m_name; + QCString m_fName; + QCString m_pathName; }; -/** Iterator for FileName objects in a FileNameList. */ -class FileNameListIterator : public QListIterator<FileName> +/** Ordered dictionary of FileName objects. */ +class FileNameLinkedMap : public LinkedMap<FileName> { - public: - FileNameListIterator( const FileNameList &list ); -}; - -/** Unsorted dictionary of FileName objects. */ -class FileNameDict : public QDict<FileName> -{ - public: - FileNameDict(uint size); - ~FileNameDict() {} }; #endif diff --git a/src/formula.cpp b/src/formula.cpp index 64555c9..8d1b0c0 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -1,11 +1,10 @@ /****************************************************************************** - * * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -14,41 +13,135 @@ * */ -#include <stdlib.h> -#include <qfile.h> -#include <qfileinfo.h> -#include <qtextstream.h> -#include <qdir.h> - #include "formula.h" -#include "image.h" -#include "util.h" #include "message.h" #include "config.h" -#include "portable.h" -#include "index.h" -#include "doxygen.h" #include "ftextstream.h" +#include "util.h" +#include "portable.h" +#include "image.h" + +#include <qfile.h> +#include <qtextstream.h> +#include <qdir.h> + +#include <map> +#include <vector> +#include <string> +#include <utility> + +// TODO: remove these dependencies +#include "doxygen.h" // for Doxygen::indexList +#include "index.h" // for Doxygen::indexList -Formula::Formula(const char *text) +// Remove the temporary files +#define RM_TMP_FILES (true) +//#define RM_TMP_FILES (false) + +struct FormulaManager::Private +{ + void storeDisplaySize(int id,int w,int h) + { + displaySizeMap.insert(std::make_pair(id,DisplaySize(w,h))); + } + DisplaySize getDisplaySize(int id) + { + auto it = displaySizeMap.find(id); + if (it!=displaySizeMap.end()) + { + return it->second; + } + return DisplaySize(-1,-1); + } + std::vector<std::string> formulas; + std::map<std::string,int> formulaMap; + std::map<int,DisplaySize> displaySizeMap; +}; + +FormulaManager::FormulaManager() : p(new Private) { - static int count=0; - number = count++; - form=text; } -Formula::~Formula() +FormulaManager &FormulaManager::instance() { + static FormulaManager fm; + return fm; } -int Formula::getId() +void FormulaManager::readFormulas(const char *dir,bool doCompare) { - return number; + QFile f(QCString(dir)+"/formula.repository"); + if (f.open(IO_ReadOnly)) // open repository + { + uint formulaCount=0; + msg("Reading formula repository...\n"); + QTextStream t(&f); + QCString line; + int lineNr=1; + while (!t.eof()) + { + line=t.readLine().utf8(); + // old format: \_form#<digits>:formula + // new format: \_form#<digits>=<digits>x<digits>:formula + int hi=line.find('#'); + int ei=line.find('='); + int se=line.find(':'); // find name and text separator. + if (hi==-1 || se==-1 || hi>se) + { + warn_uncond("%s/formula.repository is corrupted at line %d!\n",dir,lineNr); + break; + } + else + { + QCString formName = line.left(se); + QCString formText = line.right(line.length()-se-1); + int w=-1,h=-1; + if (ei!=-1 && ei>hi && ei<se) // new format + { + int xi=formName.find('x',hi); + if (xi!=-1) + { + w=formName.mid(hi+1,xi-hi-1).toInt(); + h=formName.mid(xi+1).toInt(); + } + formName = formName.left(ei); + } + else + { + ei=formName.length(); + } + if (doCompare) + { + int formId = formName.mid(hi+1,ei-hi-1).toInt(); + QCString storedFormText = FormulaManager::instance().findFormula(formId); + if (storedFormText!=formText) + { + term("discrepancy between formula repositories! Remove " + "formula.repository and from_* files from output directories.\n"); + } + formulaCount++; + } + else + { + int id = addFormula(formText); + if (w!=-1 && h!=-1) + { + p->storeDisplaySize(id,w,h); + } + } + } + lineNr++; + } + if (doCompare && formulaCount!=p->formulas.size()) + { + term("size discrepancy between formula repositories! Remove " + "formula.repository and from_* files from output directories.\n"); + } + } } -void FormulaList::generateBitmaps(const char *path) +void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) const { - int x1,y1,x2,y2; QDir d(path); // store the original directory if (!d.exists()) @@ -70,10 +163,7 @@ void FormulaList::generateBitmaps(const char *path) QDir thisDir; // generate a latex file containing one formula per page. QCString texName="_formulas.tex"; - QList<int> pagesToGenerate; - pagesToGenerate.setAutoDelete(TRUE); - FormulaListIterator fli(*this); - Formula *formula; + std::vector<int> formulasToGenerate; QFile f(texName); bool formulaError=FALSE; if (f.open(IO_WriteOnly)) @@ -91,34 +181,34 @@ void FormulaList::generateBitmaps(const char *path) copyFile(macroFile,stripMacroFile); t << "\\input{" << stripMacroFile << "}" << endl; } - t << "\\pagestyle{empty}" << endl; + t << "\\pagestyle{empty}" << endl; t << "\\begin{document}" << endl; - int page=0; - for (fli.toFirst();(formula=fli.current());++fli) + for (int i=0; i<(int)p->formulas.size(); i++) { QCString resultName; - resultName.sprintf("form_%d.png",formula->getId()); + resultName.sprintf("form_%d.%s",i,format==Format::Vector?"svg":"png"); // only formulas for which no image exists are generated QFileInfo fi(resultName); if (!fi.exists()) { // we force a pagebreak after each formula - t << formula->getFormulaText() << endl << "\\pagebreak\n\n"; - pagesToGenerate.append(new int(page)); + t << p->formulas[i].c_str() << endl << "\\pagebreak\n\n"; + formulasToGenerate.push_back(i); } Doxygen::indexList->addImageFile(resultName); - page++; } t << "\\end{document}" << endl; f.close(); } - if (pagesToGenerate.count()>0) // there are new formulas + if (!formulasToGenerate.empty()) // there are new formulas { //printf("Running latex...\n"); //system("latex _formulas.tex </dev/null >/dev/null"); QCString latexCmd = "latex"; Portable::sysTimerStart(); - if (Portable::system(latexCmd,"_formulas.tex")!=0) + char args[4096]; + sprintf(args,"-interaction=batchmode _formulas.tex >%s",Portable::devNull()); + if (Portable::system(latexCmd,args)!=0) { err("Problems running latex. Check your installation or look " "for typos in _formulas.tex and check _formulas.log!\n"); @@ -127,23 +217,18 @@ void FormulaList::generateBitmaps(const char *path) } Portable::sysTimerStop(); //printf("Running dvips...\n"); - QListIterator<int> pli(pagesToGenerate); - int *pagePtr; int pageIndex=1; - for (;(pagePtr=pli.current());++pli,++pageIndex) + for (int pageNum : formulasToGenerate) { - int pageNum=*pagePtr; msg("Generating image form_%d.png for formula\n",pageNum); - char dviArgs[4096]; - char psArgs[4096]; QCString formBase; formBase.sprintf("_form%d",pageNum); // run dvips to convert the page with number pageIndex to an // postscript file. - sprintf(dviArgs,"-q -D 600 -n 1 -p %d -o %s_tmp.ps _formulas.dvi", + sprintf(args,"-q -D 600 -n 1 -p %d -o %s_tmp.ps _formulas.dvi", pageIndex,formBase.data()); Portable::sysTimerStart(); - if (Portable::system("dvips",dviArgs)!=0) + if (Portable::system("dvips",args)!=0) { err("Problems running dvips. Check your installation!\n"); Portable::sysTimerStop(); @@ -151,180 +236,200 @@ void FormulaList::generateBitmaps(const char *path) return; } Portable::sysTimerStop(); - // run ps2epsi to convert to an encapsulated postscript file with - // boundingbox (dvips with -E has some problems here). - sprintf(psArgs,"%s_tmp.ps %s.eps",formBase.data(),formBase.data()); + + // extract the bounding box for the postscript file + sprintf(args,"-q -dBATCH -dNOPAUSE -P- -dNOSAFER -sDEVICE=bbox %s_tmp.ps 2>%s_tmp.epsi", + formBase.data(),formBase.data()); Portable::sysTimerStart(); - if (Portable::system("ps2epsi",psArgs)!=0) + if (Portable::system(Portable::ghostScriptCommand(),args)!=0) { - err("Problems running ps2epsi. Check your installation!\n"); + err("Problems running %s. Check your installation!\n",Portable::ghostScriptCommand()); Portable::sysTimerStop(); QDir::setCurrent(oldDir); return; } Portable::sysTimerStop(); - // now we read the generated postscript file to extract the bounding box - QFileInfo fi(formBase+".eps"); + + // extract the bounding box info from the generate .epsi file + int x1=0,y1=0,x2=0,y2=0; + QFileInfo fi(formBase+"_tmp.epsi"); if (fi.exists()) { - QCString eps = fileToString(formBase+".eps"); - int i=eps.find("%%BoundingBox:"); + QString eps = fileToString(formBase+"_tmp.epsi"); + int i = eps.find("%%BoundingBox:"); if (i!=-1) { sscanf(eps.data()+i,"%%%%BoundingBox:%d %d %d %d",&x1,&y1,&x2,&y2); } else { - err("Couldn't extract bounding box!\n"); + err("Couldn't extract bounding box from %s_tmp.epsi",formBase.data()); } - } - // next we generate a postscript file which contains the eps - // and displays it in the right colors and the right bounding box - f.setName(formBase+".ps"); - if (f.open(IO_WriteOnly)) - { - FTextStream t(&f); - t << "1 1 1 setrgbcolor" << endl; // anti-alias to white background - t << "newpath" << endl; - t << "-1 -1 moveto" << endl; - t << (x2-x1+2) << " -1 lineto" << endl; - t << (x2-x1+2) << " " << (y2-y1+2) << " lineto" << endl; - t << "-1 " << (y2-y1+2) << " lineto" <<endl; - t << "closepath" << endl; - t << "fill" << endl; - t << -x1 << " " << -y1 << " translate" << endl; - t << "0 0 0 setrgbcolor" << endl; - t << "(" << formBase << ".eps) run" << endl; - f.close(); } - // scale the image so that it is four times larger than needed. - // and the sizes are a multiple of four. - double scaleFactor = 16.0/3.0; + //printf("Bounding box [%d %d %d %d]\n",x1,y1,x2,y2); + + // convert the corrected EPS to a bitmap + double scaleFactor = 1.25; int zoomFactor = Config_getInt(FORMULA_FONTSIZE); if (zoomFactor<8 || zoomFactor>50) zoomFactor=10; scaleFactor *= zoomFactor/10.0; - int gx = (((int)((x2-x1)*scaleFactor))+3)&~1; - int gy = (((int)((y2-y1)*scaleFactor))+3)&~1; - // Then we run ghostscript to convert the postscript to a pixmap - // The pixmap is a truecolor image, where only black and white are - // used. - char gsArgs[4096]; - sprintf(gsArgs,"-q -g%dx%d -r%dx%d -sDEVICE=ppmraw " - "-sOutputFile=%s.pnm -dNOPAUSE -dBATCH -dNOSAFER %s.ps", - gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72), - formBase.data(),formBase.data() - ); - Portable::sysTimerStart(); - if (Portable::system(Portable::ghostScriptCommand(),gsArgs)!=0) + int width = (int)((x2-x1)*scaleFactor+0.5); + int height = (int)((y2-y1)*scaleFactor+0.5); + p->storeDisplaySize(pageNum,width,height); + + if (format==Format::Vector) { - err("Problem running ghostscript %s %s. Check your installation!\n",Portable::ghostScriptCommand(),gsArgs); + // crop the image to its bounding box + sprintf(args,"-q -dBATCH -dNOPAUSE -P- -dNOSAFER -sDEVICE=pdfwrite" + " -o %s_tmp.pdf -c \"[/CropBox [%d %d %d %d] /PAGES pdfmark\" -f %s_tmp.ps", + formBase.data(),x1,y1,x2,y2,formBase.data()); + Portable::sysTimerStart(); + if (Portable::system(Portable::ghostScriptCommand(),args)!=0) + { + err("Problems running %s. Check your installation!\n",Portable::ghostScriptCommand()); + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; + } Portable::sysTimerStop(); - QDir::setCurrent(oldDir); - return; + + if (Portable::checkForExecutable("pdf2svg")) + { + sprintf(args,"%s_tmp.pdf form_%d.svg",formBase.data(),pageNum); + Portable::sysTimerStart(); + if (Portable::system("pdf2svg",args)!=0) + { + err("Problems running pdf2svg. Check your installation!\n"); + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; + } + Portable::sysTimerStop(); + } + else if (Portable::checkForExecutable("inkscape")) + { + sprintf(args,"-l form_%d.svg -z %s_tmp.pdf 2>%s",pageNum,formBase.data(),Portable::devNull()); + Portable::sysTimerStart(); + if (Portable::system("inkscape",args)!=0) + { + err("Problems running inkscape. Check your installation!\n"); + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; + } + Portable::sysTimerStop(); + } + else + { + err("Neither 'pdf2svg' nor 'inkscape' present for conversion of formula to 'svg'\n"); + return; + } + + if (RM_TMP_FILES) + { + thisDir.remove(formBase+"_tmp.pdf"); + } } - Portable::sysTimerStop(); - f.setName(formBase+".pnm"); - uint imageX=0,imageY=0; - // we read the generated image again, to obtain the pixel data. - if (f.open(IO_ReadOnly)) + else // format==Format::Bitmap { - QTextStream t(&f); - QCString s; - if (!t.eof()) - s=t.readLine().utf8(); - if (s.length()<2 || s.left(2)!="P6") - err("ghostscript produced an illegal image format!"); - else + // crop the image to its bounding box + sprintf(args,"-q -dBATCH -dNOPAUSE -P- -dNOSAFER -sDEVICE=eps2write" + " -o %s_tmp.eps -f %s_tmp.ps",formBase.data(),formBase.data()); + Portable::sysTimerStart(); + if (Portable::system(Portable::ghostScriptCommand(),args)!=0) { - // assume the size is after the first line that does not start with - // # excluding the first line of the file. - while (!t.eof() && (s=t.readLine().utf8()) && !s.isEmpty() && s.at(0)=='#') { } - sscanf(s,"%d %d",&imageX,&imageY); + err("Problems running %s. Check your installation!\n",Portable::ghostScriptCommand()); + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; } - if (imageX>0 && imageY>0) + + // read back %s_tmp.eps and replace + // bounding box values with x1,y1,x2,y2 and remove the HiResBoundingBox + QFile epsIn(formBase+"_tmp.eps"); + QFile epsOut(formBase+"_tmp_corr.eps"); + if (epsIn.open(IO_ReadOnly) && epsOut.open(IO_WriteOnly)) { - //printf("Converting image...\n"); - char *data = new char[imageX*imageY*3]; // rgb 8:8:8 format - uint i,x,y,ix,iy; - f.readBlock(data,imageX*imageY*3); - Image srcImage(imageX,imageY), - filteredImage(imageX,imageY), - dstImage(imageX/4,imageY/4); - uchar *ps=srcImage.getData(); - // convert image to black (1) and white (0) index. - for (i=0;i<imageX*imageY;i++) *ps++= (data[i*3]==0 ? 1 : 0); - // apply a simple box filter to the image - static int filterMask[]={1,2,1,2,8,2,1,2,1}; - for (y=0;y<srcImage.getHeight();y++) + int maxLineLen=100*1024; + while (!epsIn.atEnd()) { - for (x=0;x<srcImage.getWidth();x++) + QCString buf(maxLineLen); + FTextStream t(&epsOut); + int numBytes = epsIn.readLine(buf.rawData(),maxLineLen); + if (numBytes>0) { - int s=0; - for (iy=0;iy<2;iy++) + buf.resize(numBytes+1); + if (buf.startsWith("%%BoundingBox")) { - for (ix=0;ix<2;ix++) - { - s+=srcImage.getPixel(x+ix-1,y+iy-1)*filterMask[iy*3+ix]; - } + t << "%%BoundingBox: " << x1 << " " << y1 << " " << x2 << " " << y2 << endl; + } + else if (buf.startsWith("%%HiResBoundingBox")) // skip this one + { + } + else + { + t << buf; } - filteredImage.setPixel(x,y,s); - } - } - // down-sample the image to 1/16th of the area using 16 gray scale - // colors. - // TODO: optimize this code. - for (y=0;y<dstImage.getHeight();y++) - { - for (x=0;x<dstImage.getWidth();x++) - { - int xp=x<<2; - int yp=y<<2; - int c=filteredImage.getPixel(xp+0,yp+0)+ - filteredImage.getPixel(xp+1,yp+0)+ - filteredImage.getPixel(xp+2,yp+0)+ - filteredImage.getPixel(xp+3,yp+0)+ - filteredImage.getPixel(xp+0,yp+1)+ - filteredImage.getPixel(xp+1,yp+1)+ - filteredImage.getPixel(xp+2,yp+1)+ - filteredImage.getPixel(xp+3,yp+1)+ - filteredImage.getPixel(xp+0,yp+2)+ - filteredImage.getPixel(xp+1,yp+2)+ - filteredImage.getPixel(xp+2,yp+2)+ - filteredImage.getPixel(xp+3,yp+2)+ - filteredImage.getPixel(xp+0,yp+3)+ - filteredImage.getPixel(xp+1,yp+3)+ - filteredImage.getPixel(xp+2,yp+3)+ - filteredImage.getPixel(xp+3,yp+3); - // here we scale and clip the color value so the - // resulting image has a reasonable contrast - dstImage.setPixel(x,y,QMIN(15,(c*15)/(16*10))); } } - // save the result as a bitmap - QCString resultName; - resultName.sprintf("form_%d.png",pageNum); - // the option parameter 1 is used here as a temporary hack - // to select the right color palette! - dstImage.save(resultName,1); - delete[] data; + epsIn.close(); + epsOut.close(); } - f.close(); - } + else + { + err("Problems correcting the eps files from %s_tmp.eps to %s_tmp_corr.eps\n", + formBase.data(),formBase.data()); + QDir::setCurrent(oldDir); + return; + } + + if (hd==HighDPI::On) // for high DPI display it looks much better if the + // image resolution is higher than the display resolution + { + scaleFactor*=2; + } + + Portable::sysTimerStop(); + sprintf(args,"-q -dNOSAFER -dBATCH -dNOPAUSE -dEPSCrop -sDEVICE=pnggray -dGraphicsAlphaBits=4 -dTextAlphaBits=4 " + "-r%d -sOutputFile=form_%d.png %s_tmp_corr.eps",(int)(scaleFactor*72),pageNum,formBase.data()); + Portable::sysTimerStart(); + if (Portable::system(Portable::ghostScriptCommand(),args)!=0) + { + err("Problems running %s. Check your installation!\n",Portable::ghostScriptCommand()); + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; + } + Portable::sysTimerStop(); + + if (RM_TMP_FILES) + { + thisDir.remove(formBase+"_tmp.eps"); + thisDir.remove(formBase+"_tmp_corr.eps"); + } + } + // remove intermediate image files - thisDir.remove(formBase+"_tmp.ps"); - thisDir.remove(formBase+".eps"); - thisDir.remove(formBase+".pnm"); - thisDir.remove(formBase+".ps"); + if (RM_TMP_FILES) + { + thisDir.remove(formBase+"_tmp.ps"); + thisDir.remove(formBase+"_tmp.epsi"); + } + pageIndex++; } // remove intermediate files produced by latex - thisDir.remove("_formulas.dvi"); - if (!formulaError) thisDir.remove("_formulas.log"); // keep file in case of errors - thisDir.remove("_formulas.aux"); + if (RM_TMP_FILES) + { + thisDir.remove("_formulas.dvi"); + if (!formulaError) thisDir.remove("_formulas.log"); // keep file in case of errors + thisDir.remove("_formulas.aux"); + } } // remove the latex file itself - if (!formulaError) thisDir.remove("_formulas.tex"); - // write/update the formula repository so we know what text the + if (RM_TMP_FILES && !formulaError) thisDir.remove("_formulas.tex"); + + // write/update the formula repository so we know what text the // generated images represent (we use this next time to avoid regeneration // of the images, and to avoid forcing the user to delete all images in order // to let a browser refresh the images). @@ -332,9 +437,15 @@ void FormulaList::generateBitmaps(const char *path) if (f.open(IO_WriteOnly)) { FTextStream t(&f); - for (fli.toFirst();(formula=fli.current());++fli) + for (int i=0; i<(int)p->formulas.size(); i++) { - t << "\\_form#" << formula->getId() << ":" << formula->getFormulaText() << endl; + DisplaySize size = p->getDisplaySize(i); + t << "\\_form#" << i; + if (size.width!=-1 && size.height!=-1) + { + t << "=" << size.width << "x" << size.height; + } + t << ":" << p->formulas[i].c_str() << endl; } f.close(); } @@ -342,15 +453,43 @@ void FormulaList::generateBitmaps(const char *path) QDir::setCurrent(oldDir); } +void FormulaManager::clear() +{ + p->formulas.clear(); + p->formulaMap.clear(); +} + +int FormulaManager::addFormula(const char *formulaText) +{ + std::string key = toStdString(formulaText); + auto it = p->formulaMap.find(key); + if (it!=p->formulaMap.end()) // already stored + { + return it->second; + } + // store new formula + int id = (int)p->formulas.size(); + p->formulaMap.insert(std::pair<std::string,int>(key,id)); + p->formulas.push_back(key); + return id; +} -#ifdef FORMULA_TEST -int main() +QCString FormulaManager::findFormula(int formulaId) const { - FormulaList fl; - fl.append(new Formula("$x^2$")); - fl.append(new Formula("$y^2$")); - fl.append(new Formula("$\\sqrt{x_0^2+x_1^2+x_2^2}$")); - fl.generateBitmaps("dest"); - return 0; + if (formulaId>=0 && formulaId<(int)p->formulas.size()) + { + return p->formulas[formulaId].c_str(); + } + return QCString(); } -#endif + +bool FormulaManager::hasFormulas() const +{ + return !p->formulas.empty(); +} + +FormulaManager::DisplaySize FormulaManager::displaySize(int formulaId) const +{ + return p->getDisplaySize(formulaId); +} + diff --git a/src/formula.h b/src/formula.h index 422030c..4bd90af 100644 --- a/src/formula.h +++ b/src/formula.h @@ -18,45 +18,33 @@ #ifndef FORMULA_H #define FORMULA_H -#include <qlist.h> -#include <qdict.h> +#include <memory> +#include <qcstring.h> -/** Class representing a formula in the output. */ -class Formula +/*! Manager class to handle formulas */ +class FormulaManager { public: - Formula(const char *text); - ~Formula(); - int getId(); - QCString getFormulaText() const { return form; } - + struct DisplaySize + { + DisplaySize(int w,int h) : width(w), height(h) {} + int width; + int height; + }; + enum class Format { Bitmap, Vector }; + enum class HighDPI { On, Off }; + static FormulaManager &instance(); + void readFormulas(const char *dir,bool doCompare=false); + void clear(); + int addFormula(const char *formulaText); + void generateImages(const char *outputDir,Format format,HighDPI hd = HighDPI::Off) const; + QCString findFormula(int formulaId) const; + bool hasFormulas() const; + DisplaySize displaySize(int formulaId) const; private: - int number; - QCString form; -}; - -/** A list of Formula objects. */ -class FormulaList : public QList<Formula> -{ - public: - void generateBitmaps(const char *path); -}; - -/** Iterator for Formula objects in a FormulaList. */ -class FormulaListIterator : public QListIterator<Formula> -{ - public: - FormulaListIterator(const FormulaList &l) : - QListIterator<Formula>(l) {} -}; - -/** Unsorted dictionary of Formula objects. */ -class FormulaDict : public QDict<Formula> -{ - public: - FormulaDict(uint size) : - QDict<Formula>(size) {} - ~FormulaDict() {} + FormulaManager(); + struct Private; + std::unique_ptr<Private> p; }; #endif diff --git a/src/fortrancode.h b/src/fortrancode.h index 8391a0b..7da6a61 100644 --- a/src/fortrancode.h +++ b/src/fortrancode.h @@ -28,7 +28,6 @@ class Definition; void codeFreeScanner(); -const int fixedCommentAfter = 72; class FortranCodeParser : public CodeParserInterface { diff --git a/src/fortrancode.l b/src/fortrancode.l index c4532f3..b2e2e7b 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -6,8 +6,8 @@ * based on the work of Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -20,12 +20,16 @@ @todo - continuation lines not always recognized - merging of use-statements with same module name and different only-names - rename part of use-statement - - links to interface functions + - links to interface functions - references to variables **/ %option never-interactive %option case-insensitive %option prefix="fortrancodeYY" +%option noyy_top_state +%top{ +#include <stdint.h> +} %{ @@ -55,6 +59,8 @@ #include "tooltip.h" #include "fortrancode.h" +const int fixedCommentAfter = 72; + // Toggle for some debugging info //#define DBG_CTX(x) fprintf x #define DBG_CTX(x) do { } while(0) @@ -63,6 +69,8 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + /* * For fixed formatted code position 6 is of importance (continuation character). * The following variables and macros keep track of the column number @@ -73,18 +81,18 @@ int yy_old_start = 0; int yy_my_start = 0; int yy_end = 1; -#define YY_USER_ACTION {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += yyleng;} +#define YY_USER_ACTION {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += static_cast<int>(yyleng);} #define YY_FTN_RESET {yy_old_start = 0; yy_my_start = 0; yy_end = 1;} #define YY_FTN_REJECT {yy_end = yy_my_start; yy_my_start = yy_old_start; REJECT;} - + //-------------------------------------------------------------------------------- /** data of an use-statement */ -class UseEntry +class UseEntry { - public: + public: QCString module; // just for debug QCStringList onlyNames; /* entries of the ONLY-part */ }; @@ -93,7 +101,7 @@ class UseEntry module name -> list of ONLY/remote entries (module name = name of the module, which can be accessed via use-directive) */ -class UseSDict : public SDict<UseEntry> +class UseSDict : public SDict<UseEntry> { public: UseSDict() : SDict<UseEntry>(17) {} @@ -102,7 +110,7 @@ class UseSDict : public SDict<UseEntry> /** Contains names of used modules and names of local variables. */ -class Scope +class Scope { public: QCStringList useNames; //!< contains names of used modules @@ -113,10 +121,10 @@ class Scope }; /*===================================================================*/ -/* +/* * statics */ - + static QCString docBlock; //!< contents of all lines of a documentation block static QCString currentModule=0; //!< name of the current enclosing module static QCString currentClass=0; //!< name of the current enclosing class @@ -125,7 +133,7 @@ static UseEntry *useEntry = 0; //!< current use statement info static QList<Scope> scopeStack; static bool g_isExternal = false; // static QCStringList *currentUseNames= new QCStringList; //! contains names of used modules of current program unit -static QCString str=""; //!> contents of fortran string +static QCString g_str=""; //!> contents of fortran string static CodeOutputInterface * g_code; @@ -134,7 +142,7 @@ static QCString g_parmType; static QCString g_parmName; static const char * g_inputString; //!< the code fragment as text -static int g_inputPosition; //!< read offset during parsing +static int g_inputPosition; //!< read offset during parsing static int g_inputLines; //!< number of line in the code fragment static int g_yyLineNr; //!< current line number static int g_contLineNr; //!< current, local, line number for continuation determination @@ -166,7 +174,9 @@ static int inTypeDecl = 0; static bool g_endComment; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif static void endFontClass() { @@ -223,7 +233,7 @@ static void startCodeLine() //QCString lineNumber,lineAnchor; //lineNumber.sprintf("%05d",g_yyLineNr); //lineAnchor.sprintf("l%05d",g_yyLineNr); - + Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr); //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>"); if (!g_includeCodeFragment && d) @@ -256,7 +266,7 @@ static void startCodeLine() g_code->writeLineNumber(0,0,0,g_yyLineNr); } } - g_code->startCodeLine(g_sourceFileDef); + g_code->startCodeLine(g_sourceFileDef); if (g_currentFontClass) { g_code->startFontClass(g_currentFontClass); @@ -291,7 +301,7 @@ static void codifyLines(char *text) *(p-1)='\0'; g_code->codify(sp); endCodeLine(); - if (g_yyLineNr<g_inputLines) + if (g_yyLineNr<g_inputLines) { startCodeLine(); } @@ -317,7 +327,7 @@ static void codifyLines(QCString str) } /*! writes a link to a fragment \a text that may span multiple lines, inserting - * line numbers for each line. If \a text contains newlines, the link will be + * line numbers for each line. If \a text contains newlines, the link will be * split into multiple links with the same destination, one for each line. */ static void writeMultiLineCodeLink(CodeOutputInterface &ol, @@ -328,7 +338,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol, QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); - QCString tooltip; + QCString tooltip; if (!sourceTooltips) // fall back to simple "title" tooltips { tooltip = d->briefDescriptionAsTooltip(); @@ -347,7 +357,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol, //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp); ol.writeCodeLink(ref,file,anchor,sp,tooltip); endCodeLine(); - if (g_yyLineNr<g_inputLines) + if (g_yyLineNr<g_inputLines) { startCodeLine(); } @@ -384,27 +394,27 @@ static bool getFortranNamespaceDefs(const QCString &mname, @param moduleName name of enclosing module or null, if global entry @param cd the entry, if found or null @param usedict dictionary of data of USE-statement - @returns true, if type is found + @returns true, if type is found */ -static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName, +static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName, ClassDef *&cd, UseSDict *usedict=0) { if (tname.isEmpty()) return FALSE; /* empty name => nothing to link */ //cout << "=== search for type: " << tname << endl; - // search for type - if ((cd=Doxygen::classSDict->find(tname))) + // search for type + if ((cd=Doxygen::classSDict->find(tname))) { //cout << "=== type found in global module" << endl; return TRUE; } - else if (moduleName && (cd= Doxygen::classSDict->find(moduleName+"::"+tname))) + else if (moduleName && (cd= Doxygen::classSDict->find(moduleName+"::"+tname))) { //cout << "=== type found in local module" << endl; return TRUE; } - else + else { UseEntry *use; for (UseSDict::Iterator di(*usedict); (use=di.current()); ++di) @@ -424,14 +434,13 @@ static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName searches for definition of function memberName @param memberName the name of the function/variable @param moduleName name of enclosing module or null, if global entry - @param md the entry, if found or null @param usedict array of data of USE-statement - @returns true, if found + @returns MemberDef pointer, if found, or nullptr otherwise */ -static bool getFortranDefs(const QCString &memberName, const QCString &moduleName, - MemberDef *&md, UseSDict *usedict=0) +static MemberDef *getFortranDefs(const QCString &memberName, const QCString &moduleName, + UseSDict *usedict=0) { - if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */ + if (memberName.isEmpty()) return nullptr; /* empty name => nothing to link */ // look in local variables QListIterator<Scope> it(scopeStack); @@ -439,81 +448,84 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam for (it.toLast();(scope=it.current());--it) { if (scope->localVars.find(memberName) && (!scope->externalVars.find(memberName))) - return FALSE; + { + return nullptr; + } } // search for function - MemberName *mn = Doxygen::functionNameSDict->find(memberName); + MemberName *mn = Doxygen::functionNameLinkedMap->find(memberName); if (!mn) { - mn = Doxygen::memberNameSDict->find(memberName); + mn = Doxygen::memberNameLinkedMap->find(memberName); } if (mn) // name is known { - MemberNameIterator mli(*mn); - for (mli.toFirst();(md=mli.current());++mli) // all found functions with given name - { - const FileDef *fd=md->getFileDef(); - const GroupDef *gd=md->getGroupDef(); - const ClassDef *cd=md->getClassDef(); - - //cout << "found link with same name: " << fd->fileName() << " " << memberName; - //if (md->getNamespaceDef() != 0) cout << " in namespace " << md->getNamespaceDef()->name();cout << endl; + // all found functions with given name + for (const auto &md : *mn) + { + const FileDef *fd=md->getFileDef(); + const GroupDef *gd=md->getGroupDef(); + const ClassDef *cd=md->getClassDef(); - if ((gd && gd->isLinkable()) || (fd && fd->isLinkable())) - { - const NamespaceDef *nspace= md->getNamespaceDef(); + //cout << "found link with same name: " << fd->fileName() << " " << memberName; + //if (md->getNamespaceDef() != 0) cout << " in namespace " << md->getNamespaceDef()->name();cout << endl; - if (nspace == 0) - { // found function in global scope - if(cd == 0) { // Skip if bound to type - return TRUE; + if ((gd && gd->isLinkable()) || (fd && fd->isLinkable())) + { + const NamespaceDef *nspace= md->getNamespaceDef(); + + if (nspace == 0) + { // found function in global scope + if(cd == 0) + { // Skip if bound to type + return md.get(); + } + } + else if (moduleName == nspace->name()) + { // found in local scope + return md.get(); + } + else + { // else search in used modules + QCString usedModuleName= nspace->name(); + UseEntry *ue= usedict->find(usedModuleName); + if (ue) + { + // check if only-list exists and if current entry exists is this list + QCStringList &only= ue->onlyNames; + if (only.isEmpty()) + { + //cout << " found in module " << usedModuleName << " entry " << memberName << endl; + return md.get(); // whole module used + } + else + { + for ( QCStringList::Iterator lit = only.begin(); lit != only.end(); ++lit) + { + //cout << " search in only: " << usedModuleName << ":: " << memberName << "==" << (*it)<< endl; + if (memberName == *lit) + { + return md.get(); // found in ONLY-part of use list + } } - } - else if (moduleName == nspace->name()) - { // found in local scope - return TRUE; - } - else - { // else search in used modules - QCString moduleName= nspace->name(); - UseEntry *ue= usedict->find(moduleName); - if (ue) - { - // check if only-list exists and if current entry exists is this list - QCStringList &only= ue->onlyNames; - if (only.isEmpty()) - { - //cout << " found in module " << moduleName << " entry " << memberName << endl; - return TRUE; // whole module used - } - else - { - for ( QCStringList::Iterator it = only.begin(); it != only.end(); ++it) - { - //cout << " search in only: " << moduleName << ":: " << memberName << "==" << (*it)<< endl; - if (memberName == *it) - { - return TRUE; // found in ONLY-part of use list - } - } - } - } - } - } // if linkable - } // for + } + } + } + } // if linkable + } // for } - return FALSE; + return nullptr; } /** gets the link to a generic procedure which depends not on the name, but on the parameter list @todo implementation */ -static bool getGenericProcedureLink(const ClassDef *cd, - const char *memberText, - CodeOutputInterface &ol) +static bool getGenericProcedureLink(const ClassDef *cd, + const char *memberText, + CodeOutputInterface &ol) { (void)cd; (void)memberText; @@ -529,8 +541,8 @@ static bool getLink(UseSDict *usedict, // dictionary with used modules MemberDef *md=0; QCString memberName= removeRedundantWhiteSpace(memberText); - if (getFortranDefs(memberName, currentModule, md, usedict) && md->isLinkable()) - { + if ((md=getFortranDefs(memberName, currentModule, usedict)) && md->isLinkable()) + { if (md->isVariable() && (md->getLanguage()!=SrcLangExt_Fortran)) return FALSE; // Non Fortran variables aren't handled yet, // see also linkifyText in util.cpp @@ -539,15 +551,15 @@ static bool getLink(UseSDict *usedict, // dictionary with used modules if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable()) { - if (g_currentDefinition && g_currentMemberDef && + if (g_currentDefinition && g_currentMemberDef && md!=g_currentMemberDef && g_insideBody && g_collectXRefs) - { - addDocCrossReference(g_currentMemberDef,md); - } + { + addDocCrossReference(g_currentMemberDef,md); + } writeMultiLineCodeLink(ol,md,text ? text : memberText); addToSearchIndex(text ? text : memberText); return TRUE; - } + } } return FALSE; } @@ -559,16 +571,16 @@ static void generateLink(CodeOutputInterface &ol, char *lname) NamespaceDef *nsd=0; QCString tmp = lname; tmp = removeRedundantWhiteSpace(tmp.lower()); - + // check if lowercase lname is a linkable type or interface if ( (getFortranTypeDefs(tmp, currentModule, cd, useMembers)) && cd->isLinkable() ) { if ( (cd->compoundType() == ClassDef::Class) && // was Entry::INTERFACE_SEC) && - (getGenericProcedureLink(cd, tmp, ol)) ) + (getGenericProcedureLink(cd, tmp, ol)) ) { - //cout << "=== generic procedure resolved" << endl; - } - else + //cout << "=== generic procedure resolved" << endl; + } + else { // write type or interface link writeMultiLineCodeLink(ol,cd,tmp); addToSearchIndex(tmp.data()); @@ -581,11 +593,11 @@ static void generateLink(CodeOutputInterface &ol, char *lname) addToSearchIndex(tmp.data()); } // check for function/variable - else if (getLink(useMembers, tmp, ol, tmp)) + else if (getLink(useMembers, tmp, ol, tmp)) { //cout << "=== found link for lowercase " << lname << endl; } - else + else { // nothing found, just write out the word //startFontClass("charliteral"); //test @@ -601,23 +613,23 @@ static int countLines() const char *p=g_inputString; char c; int count=1; - while ((c=*p)) - { - p++ ; - if (c=='\n') count++; + while ((c=*p)) + { + p++ ; + if (c=='\n') count++; } - if (p>g_inputString && *(p-1)!='\n') + if (p>g_inputString && *(p-1)!='\n') { // last line does not end with a \n, so we add an extra // line and explicitly terminate the line after parsing. - count++, - g_needsTermination=TRUE; - } + count++, + g_needsTermination=TRUE; + } return count; } //---------------------------------------------------------------------------- /** start scope */ -static void startScope() +static void startScope() { DBG_CTX((stderr, "===> startScope %s",yytext)); Scope *scope = new Scope; @@ -625,31 +637,31 @@ static void startScope() } /** end scope */ -static void endScope() +static void endScope() { DBG_CTX((stderr,"===> endScope %s",yytext)); - if (scopeStack.isEmpty()) + if (scopeStack.isEmpty()) { - DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n")); + DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n")); return; } Scope *scope = scopeStack.getLast(); scopeStack.removeLast(); - for ( QCStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) + for ( QCStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) { useMembers->remove(*it); } delete scope; } -static void addUse(const QCString &moduleName) +static void addUse(const QCString &moduleName) { if (!scopeStack.isEmpty()) scopeStack.getLast()->useNames.append(moduleName); } -static void addLocalVar(const QCString &varName) +static void addLocalVar(const QCString &varName) { if (!scopeStack.isEmpty()) { @@ -664,15 +676,15 @@ static void addLocalVar(const QCString &varName) #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -static int yyread(char *buf,int max_size) +static yy_size_t yyread(char *buf,yy_size_t max_size) { - int c=0; - while( c < max_size && g_inputString[g_inputPosition] ) - { - *buf = g_inputString[g_inputPosition++] ; - c++; buf++; - } - return c; + yy_size_t c=0; + while( c < max_size && g_inputString[g_inputPosition] ) + { + *buf = g_inputString[g_inputPosition++] ; + c++; buf++; + } + return c; } %} @@ -740,7 +752,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") codifyLines(yytext); } /*-------- inner construct ---------------------------------------------------*/ - + <Start>{COMMANDS}/{BS}[,( \t\n] { // highlight /* font class is defined e.g. in doxygen.css */ startFontClass("keyword"); @@ -771,8 +783,8 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") codifyLines(yytext); endFontClass(); } -<Start>"implicit"{BS}("none"|{TYPE_SPEC}) { - startFontClass("keywordtype"); +<Start>"implicit"{BS}("none"|{TYPE_SPEC}) { + startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); } @@ -782,20 +794,20 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); } /*-------- use statement -------------------------------------------*/ -<Start>"use"{BS_} { - startFontClass("keywordtype"); +<Start>"use"{BS_} { + startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); yy_push_state(YY_START); - BEGIN(Use); + BEGIN(Use); } <Use>"ONLY" { // TODO: rename - startFontClass("keywordtype"); + startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); yy_push_state(YY_START); - BEGIN(UseOnly); - } + BEGIN(UseOnly); + } <Use>{ID} { QCString tmp = yytext; tmp = tmp.lower(); @@ -811,7 +823,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") useEntry->module = tmp; useMembers->append(tmp, useEntry); addUse(tmp); - } + } <Use,UseOnly,Import>{BS},{BS} { codifyLines(yytext); } <UseOnly,Import>{BS}&{BS}"\n" { codifyLines(yytext); g_contLineNr++; @@ -849,11 +861,11 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") /*-------- fortran module -----------------------------------------*/ <Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { // startScope(); - startFontClass("keyword"); + startFontClass("keyword"); codifyLines(yytext); endFontClass(); yy_push_state(YY_START); - BEGIN(ClassName); + BEGIN(ClassName); if (!qstricmp(yytext,"module")) currentModule="module"; } <Start>("enum")/{BS_}|{BS}{COMMA}{BS}{LANGUAGE_BIND_SPEC}|\n { // @@ -914,7 +926,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") startFontClass("keyword"); codifyLines(yytext); endFontClass(); - } + } <Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found startFontClass("keyword"); codifyLines(yytext); @@ -932,7 +944,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") codifyLines(yytext); endFontClass(); } -<Subprog>"("[^)]*")" { // ignore rest of line +<Subprog>"("[^)]*")" { // ignore rest of line codifyLines(yytext); } <Subprog,Subprogend>"\n" { codifyLines(yytext); @@ -968,7 +980,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") g_code->codify(yytext); endFontClass(); } -<Start>{TYPE_SPEC}/[,:( ] { +<Start>{TYPE_SPEC}/[,:( ] { QCString typ = yytext; typ = removeRedundantWhiteSpace(typ.lower()); if (typ.startsWith("real")) YY_FTN_REJECT; @@ -979,7 +991,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") g_code->codify(yytext); endFontClass(); } -<Start>{ATTR_SPEC} { +<Start>{ATTR_SPEC} { if (QCString(yytext) == "external") { yy_push_state(YY_START); @@ -1041,7 +1053,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") if (!g_isFixedForm) { yy_push_state(YY_START); - BEGIN(DeclContLine); + BEGIN(DeclContLine); } } <DeclContLine>"\n" { // declaration not yet finished @@ -1115,7 +1127,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") g_contLineNr++; yy_old_start = 0; yy_my_start = 1; - yy_end = yyleng; + yy_end = static_cast<int>(yyleng); } // Actually we should see if ! on position 6, can be continuation // but the chance is very unlikely, so no effort to solve it here @@ -1136,10 +1148,10 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") g_contLineNr++; yy_old_start = 0; yy_my_start = 1; - yy_end = yyleng; + yy_end = static_cast<int>(yyleng); // Actually we should see if ! on position 6, can be continuation // but the chance is very unlikely, so no effort to solve it here - docBlock+=yytext; + docBlock+=yytext; } <DocBlock>"\n" { // comment block ends at the end of this line // remove special comment (default config) @@ -1193,7 +1205,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); } - /*------ preprocessor --------------------------------------------*/ + /*------ preprocessor --------------------------------------------*/ <Start>"#".*\n { if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT; g_contLineNr++; @@ -1202,35 +1214,35 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); YY_FTN_RESET } - /*------ variable references? -------------------------------------*/ + /*------ variable references? -------------------------------------*/ -<Start>"%"{BS}{ID} { // ignore references to elements +<Start>"%"{BS}{ID} { // ignore references to elements g_code->codify(yytext); } -<Start>{ID} { +<Start>{ID} { g_insideBody=TRUE; generateLink(*g_code, yytext); g_insideBody=FALSE; } - /*------ strings --------------------------------------------------*/ + /*------ strings --------------------------------------------------*/ <String>\n { // string with \n inside g_contLineNr++; - str+=yytext; + g_str+=yytext; startFontClass("stringliteral"); - codifyLines(str); + codifyLines(g_str); endFontClass(); - str = ""; + g_str = ""; YY_FTN_RESET - } -<String>\"|\' { // string ends with next quote without previous backspace + } +<String>\"|\' { // string ends with next quote without previous backspace if(yytext[0]!=stringStartSymbol) YY_FTN_REJECT; // single vs double quote - str+=yytext; + g_str+=yytext; startFontClass("stringliteral"); - codifyLines(str); + codifyLines(g_str); endFontClass(); yy_pop_state(); - } -<String>. {str+=yytext;} + } +<String>. {g_str+=yytext;} <*>\"|\' { /* string starts */ /* if(YY_START == StrIgnore) YY_FTN_REJECT; // ignore in simple comments */ @@ -1238,7 +1250,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") yy_push_state(YY_START); stringStartSymbol=yytext[0]; // single or double quote BEGIN(String); - str=yytext; + g_str=yytext; } /*-----------------------------------------------------------------------------*/ @@ -1258,7 +1270,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") } <*>^{BS}"type"{BS}"=" { g_code->codify(yytext); } -<*>. { +<*>. { if (g_isFixedForm && yy_my_start > fixedCommentAfter) { //yy_push_state(YY_START); @@ -1301,7 +1313,6 @@ const char* prepassFixedForm(const char* contents, int *hasContLine); /* prototy static void checkContLines(const char *s) { int numLines = 0; - int curLine = 0; int i = 0; const char *p = s; @@ -1319,7 +1330,7 @@ static void checkContLines(const char *s) g_hasContLine[0] = 0; } -void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, +void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, bool exBlock, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, const MemberDef *,bool,const Definition *searchCtx, @@ -1353,7 +1364,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, else g_inputLines = g_yyLineNr + countLines() - 1; - g_exampleBlock = exBlock; + g_exampleBlock = exBlock; g_exampleName = exName; g_sourceFileDef = fd; if (exBlock && fd==0) @@ -1361,7 +1372,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, // create a dummy filedef for the example g_sourceFileDef = createFileDef("",exName); } - if (g_sourceFileDef) + if (g_sourceFileDef) { setCurrentDoc("l00001"); } @@ -1425,4 +1436,6 @@ void FortranCodeParser::resetCodeParserState() //--------------------------------------------------------- +#if USE_STATE2STRING #include "fortrancode.l.h" +#endif diff --git a/src/fortranscanner.h b/src/fortranscanner.h index 7a13f47..6ffcb1f 100644 --- a/src/fortranscanner.h +++ b/src/fortranscanner.h @@ -27,7 +27,8 @@ class FortranOutlineParser : public OutlineParserInterface { public: - FortranOutlineParser(FortranFormat format=FortranFormat_Unknown) : m_format(format) { } + FortranOutlineParser(FortranFormat format=FortranFormat_Unknown); + ~FortranOutlineParser(); void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char *fileName, @@ -39,7 +40,8 @@ class FortranOutlineParser : public OutlineParserInterface void parsePrototype(const char *text); private: - FortranFormat m_format; + struct Private; + std::unique_ptr<Private> p; }; class FortranOutlineParserFree : public FortranOutlineParser diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 08c7a6a..852c4d9 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -21,8 +21,8 @@ * - Consider using startScope(), endScope() functions with module, program, * subroutine or any other scope in fortran program. * - * - Symbol modifiers (attributes) are collected using SymbolModifiers |= operator during - * substructure parsing. When substructure ends all modifiers are applied to actual + * - Symbol yyextra->modifiers (attributes) are collected using SymbolModifiers |= operator during + * substructure parsing. When substructure ends all yyextra->modifiers are applied to actual * entries in applyModifiers() functions. * * - How case insensitiveness should be handled in code? @@ -35,11 +35,16 @@ * "functionA" or "MyInterface". So constructs like '(^|[ \t])interface({BS_}{ID})?/[ \t\n]' * are desired. * - * - Must track yyLineNr when using REJECT, unput() or similar commands. + * - Must track yyextra->lineNr when using REJECT, unput() or similar commands. */ %option never-interactive %option case-insensitive %option prefix="fortranscannerYY" +%option reentrant +%option extra-type="struct fortranscannerYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -63,10 +68,12 @@ #include "defargs.h" #include "language.h" #include "commentscan.h" -#include "fortrancode.h" #include "pre.h" #include "arguments.h" #include "debug.h" +#include "markdown.h" + +const int fixedCommentAfter = 72; // Toggle for some debugging info //#define DBG_CTX(x) fprintf x @@ -79,12 +86,13 @@ enum ScanVar { V_IGNORE, V_VARIABLE, V_PARAMETER, V_RESULT}; enum InterfaceType { IF_NONE, IF_SPECIFIC, IF_GENERIC, IF_ABSTRACT }; // {{{ ----- Helper structs ----- -//! Holds modifiers (ie attributes) for one symbol (variable, function, etc) -struct SymbolModifiers { +//! Holds yyextra->modifiers (ie attributes) for one symbol (variable, function, etc) +struct SymbolModifiers +{ enum Protection {NONE_P, PUBLIC, PRIVATE}; enum Direction {NONE_D, IN, OUT, INOUT}; - //!< This is only used with function return value. + //! This is only used with function return value. QCString type, returnName; Protection protection; Direction direction; @@ -132,115 +140,108 @@ static const char *directionParam[] = // }}} -/* ----------------------------------------------------------------- - * - * statics - */ -static OutlineParserInterface *g_thisParser; -static const char * inputString; -static int inputPosition; -static bool isFixedForm; -static QCString inputStringPrepass; ///< Input string for prepass of line cont. '&' -static QCString inputStringSemi; ///< Input string after command separator ';' -static unsigned int inputPositionPrepass; -static int lineCountPrepass = 0; - -static std::vector< std::shared_ptr<Entry> > subrCurrent; - -struct CommentInPrepass { +struct CommentInPrepass +{ int column; QCString str; - CommentInPrepass(int column, QCString str) : column(column), str(str) {} + CommentInPrepass(int col, QCString s) : column(col), str(s) {} }; -static QList<CommentInPrepass> comments; - -YY_BUFFER_STATE *include_stack = NULL; -int include_stack_ptr = 0; -int include_stack_cnt = 0; - -static QFile inputFile; -static QCString yyFileName; -static int yyLineNr = 1 ; -static int yyColNr = 0 ; -static Entry *current_root = 0; -static Entry *global_scope = 0; -static std::shared_ptr<Entry> global_root; -static std::shared_ptr<Entry> file_root; -static std::shared_ptr<Entry> last_entry; -static std::shared_ptr<Entry> last_enum; -static std::shared_ptr<Entry> current; -static ScanVar v_type = V_IGNORE; // type of parsed variable -static std::vector<std::shared_ptr<Entry> > moduleProcedures; // list of all interfaces which contain unresolved - // module procedures -static QCString docBlock; -static bool docBlockInBody = FALSE; -static bool docBlockJavaStyle; - -static MethodTypes mtype; -static bool gstat; -static Specifier virt; - -static QCString debugStr; -static QCString result; // function result -static Argument *parameter; // element of parameter list -static QCString argType; // fortran type of an argument of a parameter list -static QCString argName; // last identifier name in variable list -static QCString initializer; // initial value of a variable -static int initializerArrayScope; // number if nested array scopes in initializer -static int initializerScope; // number if nested function calls in initializer -static QCString useModuleName; // name of module in the use statement -static Protection defaultProtection; -static Protection typeProtection; -static int typeMode = false; -static InterfaceType ifType = IF_NONE; -static bool functionLine = FALSE; - -static char stringStartSymbol; // single or double quote -static bool parsingPrototype = FALSE; // see parsePrototype() + +/* ----------------------------------------------------------------- + * + * statics + */ + +struct fortranscannerYY_state +{ + OutlineParserInterface * thisParser; + CommentScanner commentScanner; + const char * inputString; + int inputPosition; + bool isFixedForm; + QCString inputStringPrepass; ///< Input string for prepass of line cont. '&' + QCString inputStringSemi; ///< Input string after command separator ';' + unsigned int inputPositionPrepass; + int lineCountPrepass = 0; + EntryList subrCurrent; + QList<CommentInPrepass> comments; + YY_BUFFER_STATE * includeStack = NULL; + int includeStackPtr = 0; + int includeStackCnt = 0; + QCString fileName; + int lineNr = 1 ; + int colNr = 0 ; + Entry *current_root = 0; + Entry *global_scope = 0; + std::shared_ptr<Entry> global_root; + std::shared_ptr<Entry> file_root; + std::shared_ptr<Entry> last_entry; + std::shared_ptr<Entry> last_enum; + std::shared_ptr<Entry> current; + ScanVar vtype = V_IGNORE; // type of parsed variable + EntryList moduleProcedures; // list of all interfaces which contain unresolved module procedures + QCString docBlock; + bool docBlockInBody = FALSE; + bool docBlockJavaStyle; + QCString debugStr; +// Argument *parameter; // element of parameter list + QCString argType; // fortran type of an argument of a parameter list + QCString argName; // last identifier name in variable list + QCString initializer; // initial value of a variable + int initializerArrayScope; // number if nested array scopes in initializer + int initializerScope; // number if nested function calls in initializer + QCString useModuleName; // name of module in the use statement + Protection defaultProtection; + Protection typeProtection; + bool typeMode = false; + InterfaceType ifType = IF_NONE; + bool functionLine = FALSE; + char stringStartSymbol; // single or double quote + bool parsingPrototype = FALSE; // see parsePrototype() //! Accumulated modifiers of current statement, eg variable declaration. -static SymbolModifiers currentModifiers; + SymbolModifiers currentModifiers; //! Holds program scope->symbol name->symbol modifiers. -static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers; + QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers; + int anonCount = 0 ; +}; -static int anonCount = 0 ; //----------------------------------------------------------------------------- - -static int yyread(char *buf,int max_size); -static void startCommentBlock(bool); -static void handleCommentBlock(const QCString &doc,bool brief); -static void subrHandleCommentBlock(const QCString &doc,bool brief); -static void subrHandleCommentBlockResult(const QCString &doc,bool brief); -static void addCurrentEntry(bool case_insens); -static void addModule(const char *name, bool isModule=FALSE); -static void addSubprogram(const char *text); -static void addInterface(QCString name, InterfaceType type); -static Argument *getParameter(const QCString &name); -static void scanner_abort(); - -static void startScope(Entry *scope); -static bool endScope(Entry *scope, bool isGlobalRoot=FALSE); -//static bool isTypeName(QCString name); -static void resolveModuleProcedures(Entry *current_root); static int getAmpersandAtTheStart(const char *buf, int length); static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch); -static void truncatePrepass(int index); -static void pushBuffer(QCString &buffer); -static void popBuffer(); -//static void extractPrefix(QCString& text); static QCString extractFromParens(const QCString name); static QCString extractBind(const QCString name); -static CommentInPrepass* locatePrepassComment(int from, int to); -static void updateVariablePrepassComment(int from, int to); -static void newLine(); -static void initEntry(); + + +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +static void startCommentBlock(yyscan_t yyscanner,bool); +static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief); +static void subrHandleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief); +static void subrHandleCommentBlockResult(yyscan_t yyscanner,const QCString &doc,bool brief); +static void addCurrentEntry(yyscan_t yyscanner,bool case_insens); +static void addModule(yyscan_t yyscanner,const char *name, bool isModule=FALSE); +static void addSubprogram(yyscan_t yyscanner,const char *text); +static void addInterface(yyscan_t yyscanner,QCString name, InterfaceType type); +static Argument *getParameter(yyscan_t yyscanner,const QCString &name); +static void scanner_abort(yyscan_t yyscanner); + +static void startScope(yyscan_t yyscanner,Entry *scope); +static bool endScope(yyscan_t yyscanner,Entry *scope, bool isGlobalRoot=FALSE); +static void resolveModuleProcedures(yyscan_t yyscanner,Entry *current_root); +static void truncatePrepass(yyscan_t yyscanner,int index); +static void pushBuffer(yyscan_t yyscanner,QCString &buffer); +static void popBuffer(yyscan_t yyscanner); +static CommentInPrepass* locatePrepassComment(yyscan_t yyscanner,int from, int to); +static void updateVariablePrepassComment(yyscan_t yyscanner,int from, int to); +static void newLine(yyscan_t yyscanner); +static void initEntry(yyscan_t yyscanner); static const char *stateToString(int state); //----------------------------------------------------------------------------- -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -#define YY_USER_ACTION yyColNr+=(int)yyleng; +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); +#define YY_USER_ACTION yyextra->colNr+=(int)yyleng; #define INVALID_ENTRY ((Entry*)0x8) //----------------------------------------------------------------------------- @@ -248,7 +249,7 @@ static const char *stateToString(int state); //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -IDSYM [a-z_A-Z0-9] +IDSYM [a-z_A-Z0-9] NOTIDSYM [^a-z_A-Z0-9] SEPARATE [:, \t] ID [a-z_A-Z%]+{IDSYM}* @@ -294,18 +295,18 @@ SCOPENAME ({ID}{BS}"::"{BS})* //--------------------------------------------------------------------------------- /** fortran parsing states */ -%x Subprog -%x SubprogPrefix -%x Parameterlist -%x SubprogBody -%x SubprogBodyContains -%x Start -%x Comment +%x Subprog +%x SubprogPrefix +%x Parameterlist +%x SubprogBody +%x SubprogBodyContains +%x Start +%x Comment %x Module %x Program %x ModuleBody -%x ModuleBodyContains -%x AttributeList +%x ModuleBodyContains +%x AttributeList %x Variable %x Initialization %x ArrayInitializer @@ -323,289 +324,325 @@ SCOPENAME ({ID}{BS}"::"{BS})* %x Prepass /** comment parsing states */ -%x DocBlock -%x DocBackLine -%x EndDoc +%x DocBlock +%x DocBackLine +%x EndDoc %x BlockData /** prototype parsing */ -%x Prototype -%x PrototypeSubprog -%x PrototypeArgs +%x Prototype +%x PrototypeSubprog +%x PrototypeArgs %% /*-----------------------------------------------------------------------------------*/ <Prepass>^{BS}[&]*{BS}!.*\n { /* skip lines with just comment. Note code was in free format or has been converted to it */ - lineCountPrepass ++; + yyextra->lineCountPrepass ++; } <Prepass>^{BS}\n { /* skip empty lines */ - lineCountPrepass ++; + yyextra->lineCountPrepass ++; } <*>^.*\n { // prepass: look for line continuations - functionLine = FALSE; + yyextra->functionLine = FALSE; DBG_CTX((stderr, "---%s", yytext)); - int indexStart = getAmpersandAtTheStart(yytext, (int)yyleng); - int indexEnd = getAmpOrExclAtTheEnd(yytext, (int)yyleng, '\0'); - if (indexEnd>=0 && yytext[indexEnd]!='&') //we are only interested in amp - indexEnd=-1; + int indexStart = getAmpersandAtTheStart(yytext, (int)yyleng); + int indexEnd = getAmpOrExclAtTheEnd(yytext, (int)yyleng, '\0'); + if (indexEnd>=0 && yytext[indexEnd]!='&') //we are only interested in amp + { + indexEnd=-1; + } - if(indexEnd<0){ // ----- no ampersand as line continuation - if(YY_START == Prepass) { // last line in "continuation" + if (indexEnd<0) + { // ----- no ampersand as line continuation + if (YY_START == Prepass) + { // last line in "continuation" - // Only take input after initial ampersand - inputStringPrepass+=(const char*)(yytext+(indexStart+1)); - - //printf("BUFFER:%s\n", (const char*)inputStringPrepass); - pushBuffer(inputStringPrepass); - yyColNr = 0; - yy_pop_state(); - } else { // simple line - yyColNr = 0; - REJECT; - } - - } else { // ----- line with continuation - if(YY_START != Prepass) { - comments.setAutoDelete(TRUE); - comments.clear(); - yy_push_state(Prepass); - } + // Only take input after initial ampersand + yyextra->inputStringPrepass+=(const char*)(yytext+(indexStart+1)); + + //printf("BUFFER:%s\n", (const char*)yyextra->inputStringPrepass); + pushBuffer(yyscanner,yyextra->inputStringPrepass); + yyextra->colNr = 0; + yy_pop_state(yyscanner); + } + else + { // simple line + yyextra->colNr = 0; + REJECT; + } + } + else + { // ----- line with continuation + if (YY_START != Prepass) + { + yyextra->comments.setAutoDelete(TRUE); + yyextra->comments.clear(); + yy_push_state(Prepass,yyscanner); + } - int length = inputStringPrepass.length(); + int length = yyextra->inputStringPrepass.length(); - // Only take input after initial ampersand - inputStringPrepass+=(const char*)(yytext+(indexStart+1)); - lineCountPrepass ++; - - // cut off & and remove following comment if present - truncatePrepass(length+indexEnd-(indexStart+1)); - } + // Only take input after initial ampersand + yyextra->inputStringPrepass+=(const char*)(yytext+(indexStart+1)); + yyextra->lineCountPrepass ++; + // cut off & and remove following comment if present + truncatePrepass(yyscanner,length+indexEnd-(indexStart+1)); + } } /*------ ignore strings that are not initialization strings */ <String>\"|\' { // string ends with next quote without previous backspace - if (yytext[0]!=stringStartSymbol) { yyColNr -= (int)yyleng; REJECT; } // single vs double quote - if (yy_top_state() == Initialization - || yy_top_state() == ArrayInitializer) - initializer+=yytext; - yy_pop_state(); - } -<String>. { if (yy_top_state() == Initialization - || yy_top_state() == ArrayInitializer) - initializer+=yytext; - } + if (yytext[0]!=yyextra->stringStartSymbol) + { + yyextra->colNr -= (int)yyleng; + REJECT; + } // single vs double quote + if (yy_top_state(yyscanner) == Initialization || + yy_top_state(yyscanner) == ArrayInitializer) + { + yyextra->initializer+=yytext; + } + yy_pop_state(yyscanner); + } +<String>. { if (yy_top_state(yyscanner) == Initialization || + yy_top_state(yyscanner) == ArrayInitializer) + { + yyextra->initializer+=yytext; + } + } <*>\"|\' { /* string starts */ - if (YY_START == StrIgnore) { yyColNr -= (int)yyleng; REJECT; }; // ignore in simple comments - yy_push_state(YY_START); - if (yy_top_state() == Initialization - || yy_top_state() == ArrayInitializer) - initializer+=yytext; - stringStartSymbol=yytext[0]; // single or double quote + if (YY_START == StrIgnore) + { yyextra->colNr -= (int)yyleng; + REJECT; + }; // ignore in simple yyextra->comments + yy_push_state(YY_START,yyscanner); + if (yy_top_state(yyscanner) == Initialization || + yy_top_state(yyscanner) == ArrayInitializer) + { + yyextra->initializer+=yytext; + } + yyextra->stringStartSymbol=yytext[0]; // single or double quote BEGIN(String); } - /*------ ignore simple comment (not documentation comments) */ + /*------ ignore simple comment (not documentation yyextra->comments) */ -<*>"!"/[^<>\n] { if (YY_START == String) { yyColNr -= (int)yyleng; REJECT; } // "!" is ignored in strings - // skip comment line (without docu comments "!>" "!<" ) - /* ignore further "!" and ignore comments in Strings */ +<*>"!"/[^<>\n] { if (YY_START == String) + { yyextra->colNr -= (int)yyleng; + REJECT; + } // "!" is ignored in strings + // skip comment line (without docu yyextra->comments "!>" "!<" ) + /* ignore further "!" and ignore yyextra->comments in Strings */ if ((YY_START != StrIgnore) && (YY_START != String)) - { - yy_push_state(YY_START); + { + yy_push_state(YY_START,yyscanner); BEGIN(StrIgnore); - debugStr="*!"; - DBG_CTX((stderr,"start comment %d\n",yyLineNr)); + yyextra->debugStr="*!"; + DBG_CTX((stderr,"start comment %d\n",yyextra->lineNr)); } } -<StrIgnore>.?/\n { yy_pop_state(); // comment ends with endline character - DBG_CTX((stderr,"end comment %d %s\n",yyLineNr,debugStr.data())); +<StrIgnore>.?/\n { yy_pop_state(yyscanner); // comment ends with endline character + DBG_CTX((stderr,"end comment %d %s\n",yyextra->lineNr,yyextra->debugStr.data())); } // comment line ends -<StrIgnore>. { debugStr+=yytext; } +<StrIgnore>. { yyextra->debugStr+=yytext; } /*------ use handling ------------------------------------------------------------*/ <Start,ModuleBody,SubprogBody>"use"{BS_} { - if(YY_START == Start) + if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBody); //anon program + addModule(yyscanner,NULL); + yy_push_state(ModuleBody,yyscanner); //anon program } - yy_push_state(Use); + yy_push_state(Use,yyscanner); } <Use>{ID} { DBG_CTX((stderr,"using dir %s\n",yytext)); - current->name=yytext; - current->fileName = yyFileName; - current->section=Entry::USINGDIR_SEC; - current_root->moveToSubEntryAndRefresh(current); - current->lang = SrcLangExt_Fortran; - yy_pop_state(); + yyextra->current->name=yytext; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->section=Entry::USINGDIR_SEC; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + yyextra->current->lang = SrcLangExt_Fortran; + yy_pop_state(yyscanner); } <Use>{ID}/, { - useModuleName=yytext; + yyextra->useModuleName=yytext; } <Use>,{BS}"ONLY" { BEGIN(UseOnly); } <UseOnly>{BS},{BS} {} <UseOnly>{ID} { - current->name= useModuleName+"::"+yytext; - current->fileName = yyFileName; - current->section=Entry::USINGDECL_SEC; - current_root->moveToSubEntryAndRefresh(current); - current->lang = SrcLangExt_Fortran; - } + yyextra->current->name= yyextra->useModuleName+"::"+yytext; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->section=Entry::USINGDECL_SEC; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + yyextra->current->lang = SrcLangExt_Fortran; + } <Use,UseOnly>"\n" { - yyColNr -= 1; + yyextra->colNr -= 1; unput(*yytext); - yy_pop_state(); + yy_pop_state(yyscanner); } /* INTERFACE definitions */ <Start,ModuleBody,SubprogBody>{ -^{BS}interface{IDSYM}+ { /* variable with interface prefix */ } -^{BS}interface { ifType = IF_SPECIFIC; - yy_push_state(InterfaceBody); +^{BS}interface{IDSYM}+ { /* variable with interface prefix */ } +^{BS}interface { yyextra->ifType = IF_SPECIFIC; + yy_push_state(InterfaceBody,yyscanner); // do not start a scope here, every // interface body is a scope of its own } -^{BS}abstract{BS_}interface { ifType = IF_ABSTRACT; - yy_push_state(InterfaceBody); +^{BS}abstract{BS_}interface { yyextra->ifType = IF_ABSTRACT; + yy_push_state(InterfaceBody,yyscanner); // do not start a scope here, every // interface body is a scope of its own } -^{BS}interface{BS_}{ID}{ARGS}? { ifType = IF_GENERIC; - current->bodyLine = yyLineNr + lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account. - yy_push_state(InterfaceBody); +^{BS}interface{BS_}{ID}{ARGS}? { yyextra->ifType = IF_GENERIC; + yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account. + yy_push_state(InterfaceBody,yyscanner); // extract generic name QCString name = QCString(yytext).stripWhiteSpace(); name = name.right(name.length() - 9).stripWhiteSpace().lower(); - addInterface(name, ifType); - startScope(last_entry.get()); + addInterface(yyscanner,name, yyextra->ifType); + startScope(yyscanner,yyextra->last_entry.get()); } } <InterfaceBody>^{BS}end{BS}interface({BS_}{ID})? { // end scope only if GENERIC interface - if (ifType == IF_GENERIC) last_entry->parent()->endBodyLine = yyLineNr - 1; - if (ifType == IF_GENERIC && !endScope(current_root)) + if (yyextra->ifType == IF_GENERIC) + { + yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr - 1; + } + if (yyextra->ifType == IF_GENERIC && !endScope(yyscanner,yyextra->current_root)) + { yyterminate(); - - ifType = IF_NONE; - yy_pop_state(); + } + yyextra->ifType = IF_NONE; + yy_pop_state(yyscanner); } -<InterfaceBody>module{BS}procedure { yy_push_state(YY_START); +<InterfaceBody>module{BS}procedure { yy_push_state(YY_START,yyscanner); BEGIN(ModuleProcedure); } -<ModuleProcedure>{ID} { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) +<ModuleProcedure>{ID} { if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC) { - addInterface(yytext, ifType); - startScope(last_entry.get()); + addInterface(yyscanner,yytext, yyextra->ifType); + startScope(yyscanner,yyextra->last_entry.get()); } - current->section = Entry::FUNCTION_SEC ; - current->name = yytext; - moduleProcedures.push_back(current); - addCurrentEntry(true); + yyextra->current->section = Entry::FUNCTION_SEC ; + yyextra->current->name = yytext; + yyextra->moduleProcedures.push_back(yyextra->current); + addCurrentEntry(yyscanner,true); } -<ModuleProcedure>"\n" { yyColNr -= 1; - unput(*yytext); - yy_pop_state(); +<ModuleProcedure>"\n" { yyextra->colNr -= 1; + unput(*yytext); + yy_pop_state(yyscanner); } <InterfaceBody>. {} /*-- Contains handling --*/ -<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) { - if(YY_START == Start) +<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) { + if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBodyContains); //anon program - } + addModule(yyscanner,NULL); + yy_push_state(ModuleBodyContains,yyscanner); //anon program + } } <ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(ModuleBodyContains); } <SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(SubprogBodyContains); } <TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(TypedefBodyContains); } /*------ module handling ------------------------------------------------------------*/ -<Start>block{BS}data{BS}{ID_} { // - v_type = V_IGNORE; - yy_push_state(BlockData); - defaultProtection = Public; - } -<Start>module|program{BS_} { // - v_type = V_IGNORE; - if(yytext[0]=='m' || yytext[0]=='M') - yy_push_state(Module); - else - yy_push_state(Program); - defaultProtection = Public; - } +<Start>block{BS}data{BS}{ID_} { // + yyextra->vtype = V_IGNORE; + yy_push_state(BlockData,yyscanner); + yyextra->defaultProtection = Public; + } +<Start>module|program{BS_} { // + yyextra->vtype = V_IGNORE; + if (yytext[0]=='m' || yytext[0]=='M') + { + yy_push_state(Module,yyscanner); + } + else + { + yy_push_state(Program,yyscanner); + } + yyextra->defaultProtection = Public; + } <BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!|;) { // end block data - //if (!endScope(current_root)) - // yyterminate(); - defaultProtection = Public; - yy_pop_state(); - } + //if (!endScope(yyscanner,yyextra->current_root)) + // yyterminate(); + yyextra->defaultProtection = Public; + yy_pop_state(yyscanner); + } <Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module - resolveModuleProcedures(current_root); - if (!endScope(current_root)) - yyterminate(); - defaultProtection = Public; - if (global_scope) + resolveModuleProcedures(yyscanner,yyextra->current_root); + if (!endScope(yyscanner,yyextra->current_root)) + { + yyterminate(); + } + yyextra->defaultProtection = Public; + if (yyextra->global_scope) + { + if (yyextra->global_scope != INVALID_ENTRY) { - if (global_scope != INVALID_ENTRY) - yy_push_state(Start); - else - yy_pop_state(); // cannot pop artrificial entry + yy_push_state(Start,yyscanner); } else { - yy_push_state(Start); - global_scope = INVALID_ENTRY; // signal that the global_scope has already been used. + yy_pop_state(yyscanner); // cannot pop artrificial entry } - } -<Module>{ID} { - addModule(yytext, TRUE); - BEGIN(ModuleBody); - } - + } + else + { + yy_push_state(Start,yyscanner); + yyextra->global_scope = INVALID_ENTRY; // signal that the yyextra->global_scope has already been used. + } + } +<Module>{ID} { + addModule(yyscanner,yytext, TRUE); + BEGIN(ModuleBody); + } <Program>{ID} { - addModule(yytext, FALSE); - BEGIN(ModuleBody); - } + addModule(yyscanner,yytext, FALSE); + BEGIN(ModuleBody); + } /*------- access specification --------------------------------------------------------------------------*/ -<ModuleBody>private/{BS}(\n|"!") { defaultProtection = Private; - current->protection = defaultProtection ; - } -<ModuleBody>public/{BS}(\n|"!") { defaultProtection = Public; - current->protection = defaultProtection ; - } +<ModuleBody>private/{BS}(\n|"!") { yyextra->defaultProtection = Private; + yyextra->current->protection = yyextra->defaultProtection ; + } +<ModuleBody>public/{BS}(\n|"!") { yyextra->defaultProtection = Public; + yyextra->current->protection = yyextra->defaultProtection ; + } /*------- type definition -------------------------------------------------------------------------------*/ -<Start,ModuleBody>^{BS}type/[^a-z0-9_] { - if(YY_START == Start) +<Start,ModuleBody>^{BS}type/[^a-z0-9_] { + if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBody); //anon program + addModule(yyscanner,NULL); + yy_push_state(ModuleBody,yyscanner); //anon program } - yy_push_state(Typedef); - current->protection = defaultProtection; - typeProtection = defaultProtection; - typeMode = true; + yy_push_state(Typedef,yyscanner); + yyextra->current->protection = yyextra->defaultProtection; + yyextra->typeProtection = yyextra->defaultProtection; + yyextra->typeMode = true; } <Typedef>{ {COMMA} {} @@ -613,100 +650,104 @@ SCOPENAME ({ID}{BS}"::"{BS})* {BS}"::"{BS} {} abstract { - current->spec |= Entry::AbstractClass; + yyextra->current->spec |= Entry::AbstractClass; } extends{ARGS} { QCString basename = extractFromParens(yytext).lower(); - current->extends.push_back(BaseInfo(basename, Public, Normal)); + yyextra->current->extends.push_back(BaseInfo(basename, Public, Normal)); } public { - current->protection = Public; - typeProtection = Public; + yyextra->current->protection = Public; + yyextra->typeProtection = Public; } private { - current->protection = Private; - typeProtection = Private; + yyextra->current->protection = Private; + yyextra->typeProtection = Private; } {LANGUAGE_BIND_SPEC} { /* ignored for now */ } {ID} { /* type name found */ - current->section = Entry::CLASS_SEC; - current->spec |= Entry::Struct; - current->name = yytext; - current->fileName = yyFileName; - current->bodyLine = yyLineNr; - current->startLine = yyLineNr; + yyextra->current->section = Entry::CLASS_SEC; + yyextra->current->spec |= Entry::Struct; + yyextra->current->name = yytext; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->bodyLine = yyextra->lineNr; + yyextra->current->startLine = yyextra->lineNr; /* if type is part of a module, mod name is necessary for output */ - if (current_root && - (current_root->section == Entry::CLASS_SEC - || current_root->section == Entry::NAMESPACE_SEC)) + if (yyextra->current_root && + (yyextra->current_root->section == Entry::CLASS_SEC || + yyextra->current_root->section == Entry::NAMESPACE_SEC)) { - current->name = current_root->name + "::" + current->name; + yyextra->current->name = yyextra->current_root->name + "::" + yyextra->current->name; } - addCurrentEntry(true); - startScope(last_entry.get()); + addCurrentEntry(yyscanner,true); + startScope(yyscanner,yyextra->last_entry.get()); BEGIN(TypedefBody); } } <TypedefBodyContains>{ /* Type Bound Procedures */ ^{BS}PROCEDURE{ARGS}? { - current->type = QCString(yytext).simplifyWhiteSpace(); + yyextra->current->type = QCString(yytext).simplifyWhiteSpace(); } ^{BS}final { - current->spec |= Entry::Final; - current->type = QCString(yytext).simplifyWhiteSpace(); + yyextra->current->spec |= Entry::Final; + yyextra->current->type = QCString(yytext).simplifyWhiteSpace(); } ^{BS}generic { - current->type = QCString(yytext).simplifyWhiteSpace(); + yyextra->current->type = QCString(yytext).simplifyWhiteSpace(); } {COMMA} { } {ATTR_SPEC} { - currentModifiers |= QCString(yytext); + yyextra->currentModifiers |= QCString(yytext); } {BS}"::"{BS} { } {ID} { QCString name = yytext; - modifiers[current_root][name.lower()] |= currentModifiers; - current->section = Entry::FUNCTION_SEC; - current->name = name; - current->fileName = yyFileName; - current->bodyLine = yyLineNr; - current->startLine = yyLineNr; - addCurrentEntry(true); + yyextra->modifiers[yyextra->current_root][name.lower()] |= yyextra->currentModifiers; + yyextra->current->section = Entry::FUNCTION_SEC; + yyextra->current->name = name; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->bodyLine = yyextra->lineNr; + yyextra->current->startLine = yyextra->lineNr; + addCurrentEntry(yyscanner,true); } {BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */ QCString args = yytext; - last_entry->args = args.lower(); + yyextra->last_entry->args = args.lower(); } "\n" { - currentModifiers = SymbolModifiers(); - newLine(); - docBlock.resize(0); + yyextra->currentModifiers = SymbolModifiers(); + newLine(yyscanner); + yyextra->docBlock.resize(0); } } <TypedefBody,TypedefBodyContains>{ ^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!|;) { /* end type definition */ - last_entry->parent()->endBodyLine = yyLineNr; - if (!endScope(current_root)) + yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr; + if (!endScope(yyscanner,yyextra->current_root)) + { yyterminate(); - typeMode = false; - yy_pop_state(); + } + yyextra->typeMode = false; + yy_pop_state(yyscanner); } ^{BS}"end"{BS}/(\n|!|;) { /* incorrect end type definition */ - warn(yyFileName,yyLineNr, "Found 'END' instead of 'END TYPE'"); - last_entry->parent()->endBodyLine = yyLineNr; - if (!endScope(current_root)) + warn(yyextra->fileName,yyextra->lineNr, "Found 'END' instead of 'END TYPE'"); + yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr; + if (!endScope(yyscanner,yyextra->current_root)) + { yyterminate(); - typeMode = false; - yy_pop_state(); + } + yyextra->typeMode = false; + yy_pop_state(yyscanner); } } @@ -718,603 +759,594 @@ private { // in a scope of their own, even if multiple // are group in one INTERFACE/END INTERFACE block. // - if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) + if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC) { - endScope(current_root); - last_entry->endBodyLine = yyLineNr - 1; + endScope(yyscanner,yyextra->current_root); + yyextra->last_entry->endBodyLine = yyextra->lineNr - 1; } - current_root->endBodyLine = yyLineNr - 1; + yyextra->current_root->endBodyLine = yyextra->lineNr - 1; - if (!endScope(current_root)) - yyterminate(); - subrCurrent.pop_back(); - yy_pop_state() ; - } + if (!endScope(yyscanner,yyextra->current_root)) + { + yyterminate(); + } + yyextra->subrCurrent.pop_back(); + yy_pop_state(yyscanner) ; + } <BlockData>{ {ID} { } } <Start,ModuleBody,TypedefBody,SubprogBody,Enum>{ ^{BS}{TYPE_SPEC}/{SEPARATE} { - last_enum.reset(); + yyextra->last_enum.reset(); if (YY_START == Enum) { - argType = "@"; // enum marker + yyextra->argType = "@"; // enum marker } else { - argType = QCString(yytext).simplifyWhiteSpace().lower(); + yyextra->argType = QCString(yytext).simplifyWhiteSpace().lower(); } - current->bodyLine = yyLineNr + 1; - current->endBodyLine = yyLineNr + lineCountPrepass; + yyextra->current->bodyLine = yyextra->lineNr + 1; + yyextra->current->endBodyLine = yyextra->lineNr + yyextra->lineCountPrepass; /* variable declaration starts */ - if(YY_START == Start) + if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBody); //anon program + addModule(yyscanner,NULL); + yy_push_state(ModuleBody,yyscanner); //anon program } - yy_push_state(AttributeList); - } - /* Dimitri: macro expansion should already be done during preprocessing not here! -^{BS}{PP_ID}{KIND}? { // check for preprocessor symbol expand to type - QCString str = yytext; - str = str.stripWhiteSpace(); - //DefineDict* defines = getGlobalDefineDict(); - QCString name; - int index = str.find("("); - if (index != -1) - name = str.left(index).stripWhiteSpace(); - else - name = str; - - Define *define = 0; //(*defines)[name]; - if (define != 0 && isTypeName(define->definition)) - { - argType = str; - yy_push_state(AttributeList); - } - else - { - yyColNr -= (int)yyleng; - REJECT; - } - } - */ -{EXTERNAL_STMT}/({BS}"::"|{BS_}{ID}) { + yy_push_state(AttributeList,yyscanner); + } +{EXTERNAL_STMT}/({BS}"::"|{BS_}{ID}) { /* external can be a "type" or an attribute */ - if(YY_START == Start) + if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBody); //anon program + addModule(yyscanner,NULL); + yy_push_state(ModuleBody,yyscanner); //anon program } QCString tmp = yytext; - currentModifiers |= tmp.stripWhiteSpace(); - argType = QCString(yytext).simplifyWhiteSpace().lower(); - yy_push_state(AttributeList); - } -{ATTR_STMT}/{BS_}{ID} | -{ATTR_STMT}/{BS}"::" { + yyextra->currentModifiers |= tmp.stripWhiteSpace(); + yyextra->argType = QCString(yytext).simplifyWhiteSpace().lower(); + yy_push_state(AttributeList,yyscanner); + } +{ATTR_STMT}/{BS_}{ID} | +{ATTR_STMT}/{BS}"::" { /* attribute statement starts */ DBG_CTX((stderr,"5=========> Attribute statement: %s\n", yytext)); QCString tmp = yytext; - currentModifiers |= tmp.stripWhiteSpace(); - argType=""; - yy_push_state(YY_START); - BEGIN( AttributeList ) ; - } -{ID} { - } -^{BS}"type"{BS_}"is"/{BT_} { } -^{BS}"type"{BS}"=" { } -^{BS}"class"{BS_}"is"/{BT_} { } -^{BS}"class"{BS_}"default" { } + yyextra->currentModifiers |= tmp.stripWhiteSpace(); + yyextra->argType=""; + yy_push_state(YY_START,yyscanner); + BEGIN( AttributeList ) ; + } +{ID} { + } +^{BS}"type"{BS_}"is"/{BT_} {} +^{BS}"type"{BS}"=" {} +^{BS}"class"{BS_}"is"/{BT_} {} +^{BS}"class"{BS_}"default" {} } <AttributeList>{ -{COMMA} {} -{BS} {} +{COMMA} {} +{BS} {} {LANGUAGE_BIND_SPEC} { - currentModifiers |= yytext; + yyextra->currentModifiers |= yytext; } -{ATTR_SPEC}. { /* update current modifiers when it is an ATTR_SPEC and not a variable name */ - /* bug_625519 */ +{ATTR_SPEC}. { /* update yyextra->current yyextra->modifiers when it is an ATTR_SPEC and not a variable name */ + /* buyyextra->625519 */ QChar chr = yytext[(int)yyleng-1]; if (chr.isLetter() || chr.isDigit() || (chr == '_')) { - yyColNr -= (int)yyleng; + yyextra->colNr -= (int)yyleng; REJECT; } else { QCString tmp = yytext; tmp = tmp.left(tmp.length() - 1); - yyColNr -= 1; + yyextra->colNr -= 1; unput(yytext[(int)yyleng-1]); - currentModifiers |= (tmp); + yyextra->currentModifiers |= (tmp); } - } -"::" { /* end attribute list */ - BEGIN( Variable ); - } -. { /* unknown attribute, consider variable name */ - //cout<<"start variables, unput "<<*yytext<<endl; - yyColNr -= 1; - unput(*yytext); - BEGIN( Variable ); - } + } +"::" { /* end attribute list */ + BEGIN( Variable ); + } +. { /* unknown attribute, consider variable name */ + //cout<<"start variables, unput "<<*yytext<<endl; + yyextra->colNr -= 1; + unput(*yytext); + BEGIN( Variable ); + } } -<Variable>{BS} { } -<Variable>{ID} { /* parse variable declaration */ - //cout << "5=========> got variable: " << argType << "::" << yytext << endl; - /* work around for bug in QCString.replace (QCString works) */ - QCString name=yytext; +<Variable>{BS} {} +<Variable>{ID} { /* parse variable declaration */ + //cout << "5=========> got variable: " << yyextra->argType << "::" << yytext << endl; + /* work around for bug in QCString.replace (QCString works) */ + QCString name=yytext; name = name.lower(); - /* remember attributes for the symbol */ - modifiers[current_root][name.lower()] |= currentModifiers; - argName= name; + /* remember attributes for the symbol */ + yyextra->modifiers[yyextra->current_root][name.lower()] |= yyextra->currentModifiers; + yyextra->argName= name; - v_type= V_IGNORE; - if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC) + yyextra->vtype= V_IGNORE; + if (!yyextra->argType.isEmpty() && yyextra->current_root->section!=Entry::FUNCTION_SEC) { // new variable entry - v_type = V_VARIABLE; - current->section = Entry::VARIABLE_SEC; - current->name = argName; - current->type = argType; - current->fileName = yyFileName; - current->bodyLine = yyLineNr; // used for source reference - current->startLine = yyLineNr; - if (argType == "@") + yyextra->vtype = V_VARIABLE; + yyextra->current->section = Entry::VARIABLE_SEC; + yyextra->current->name = yyextra->argName; + yyextra->current->type = yyextra->argType; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->bodyLine = yyextra->lineNr; // used for source reference + yyextra->current->startLine = yyextra->lineNr; + if (yyextra->argType == "@") { - current_root->copyToSubEntry(current); + yyextra->current_root->copyToSubEntry(yyextra->current); // add to the scope surrounding the enum (copy!) - last_enum = current; - current_root->parent()->moveToSubEntryAndRefresh(current); - initEntry(); + yyextra->last_enum = yyextra->current; + yyextra->current_root->parent()->moveToSubEntryAndRefresh(yyextra->current); + initEntry(yyscanner); } else { - addCurrentEntry(true); + addCurrentEntry(yyscanner,true); + } + } + else if (!yyextra->argType.isEmpty()) + { // declaration of parameter list: add type for corr. parameter + Argument *parameter = getParameter(yyscanner,yyextra->argName); + if (parameter) + { + yyextra->vtype= V_PARAMETER; + if (!yyextra->argType.isNull()) parameter->type=yyextra->argType.stripWhiteSpace(); + if (!yyextra->docBlock.isNull()) + { + subrHandleCommentBlock(yyscanner,yyextra->docBlock,TRUE); + } + } + // save, it may be function return type + if (parameter) + { + yyextra->modifiers[yyextra->current_root][name.lower()].type = yyextra->argType; + } + else + { + if ((yyextra->current_root->name.lower() == yyextra->argName.lower()) || + (yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower()].returnName.lower() == yyextra->argName.lower())) + { + int strt = yyextra->current_root->type.find("function"); + QCString lft; + QCString rght; + if (strt != -1) + { + yyextra->vtype = V_RESULT; + lft = ""; + rght = ""; + if (strt != 0) lft = yyextra->current_root->type.left(strt).stripWhiteSpace(); + if ((yyextra->current_root->type.length() - strt - strlen("function"))!= 0) + { + rght = yyextra->current_root->type.right(yyextra->current_root->type.length() - strt - (int)strlen("function")).stripWhiteSpace(); + } + yyextra->current_root->type = lft; + if (rght.length() > 0) + { + if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " "; + yyextra->current_root->type += rght; + } + if (yyextra->argType.stripWhiteSpace().length() > 0) + { + if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " "; + yyextra->current_root->type += yyextra->argType.stripWhiteSpace(); + } + if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " "; + yyextra->current_root->type += "function"; + if (!yyextra->docBlock.isNull()) + { + subrHandleCommentBlockResult(yyscanner,yyextra->docBlock,TRUE); + } + } + else + { + yyextra->current_root->type += " " + yyextra->argType.stripWhiteSpace(); + } + yyextra->current_root->type = yyextra->current_root->type.stripWhiteSpace(); + yyextra->modifiers[yyextra->current_root][name.lower()].type = yyextra->current_root->type; + } + else + { + yyextra->modifiers[yyextra->current_root][name.lower()].type = yyextra->argType; + } } + // any accumulated doc for argument should be emptied, + // because it is handled other way and this doc can be + // unexpectedly passed to the next member. + yyextra->current->doc.resize(0); + yyextra->current->brief.resize(0); } - else if (!argType.isEmpty()) - { // declaration of parameter list: add type for corr. parameter - parameter = getParameter(argName); - if (parameter) - { - v_type= V_PARAMETER; - if (!argType.isNull()) parameter->type=argType.stripWhiteSpace(); - if (!docBlock.isNull()) - { - subrHandleCommentBlock(docBlock,TRUE); - } - } - // save, it may be function return type - if (parameter) - { - modifiers[current_root][name.lower()].type = argType; - } - else - { - if ((current_root->name.lower() == argName.lower()) || - (modifiers[current_root->parent()][current_root->name.lower()].returnName.lower() == argName.lower())) - { - int strt = current_root->type.find("function"); - QCString lft; - QCString rght; - if (strt != -1) - { - v_type = V_RESULT; - lft = ""; - rght = ""; - if (strt != 0) lft = current_root->type.left(strt).stripWhiteSpace(); - if ((current_root->type.length() - strt - strlen("function"))!= 0) - { - rght = current_root->type.right(current_root->type.length() - strt - strlen("function")).stripWhiteSpace(); - } - current_root->type = lft; - if (rght.length() > 0) - { - if (current_root->type.length() > 0) current_root->type += " "; - current_root->type += rght; - } - if (argType.stripWhiteSpace().length() > 0) - { - if (current_root->type.length() > 0) current_root->type += " "; - current_root->type += argType.stripWhiteSpace(); - } - if (current_root->type.length() > 0) current_root->type += " "; - current_root->type += "function"; - if (!docBlock.isNull()) - { - subrHandleCommentBlockResult(docBlock,TRUE); - } - } - else - { - current_root->type += " " + argType.stripWhiteSpace(); - } - current_root->type = current_root->type.stripWhiteSpace(); - modifiers[current_root][name.lower()].type = current_root->type; - } - else - { - modifiers[current_root][name.lower()].type = argType; - } - } - // any accumulated doc for argument should be emptied, - // because it is handled other way and this doc can be - // unexpectedly passed to the next member. - current->doc.resize(0); - current->brief.resize(0); - } - } -<Variable>{ARGS} { /* dimension of the previous entry. */ - QCString name(argName); - QCString attr("dimension"); - attr += yytext; - modifiers[current_root][name.lower()] |= attr; - } -<Variable>{COMMA} { //printf("COMMA: %d<=..<=%d\n", yyColNr-(int)yyleng, yyColNr); - // locate !< comment - updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr); - } + } +<Variable>{ARGS} { /* dimension of the previous entry. */ + QCString name(yyextra->argName); + QCString attr("dimension"); + attr += yytext; + yyextra->modifiers[yyextra->current_root][name.lower()] |= attr; + } +<Variable>{COMMA} { //printf("COMMA: %d<=..<=%d\n", yyextra->colNr-(int)yyleng, yyextra->colNr); + // locate !< comment + updateVariablePrepassComment(yyscanner,yyextra->colNr-(int)yyleng, yyextra->colNr); + } <Variable>{BS}"=" { - yy_push_state(YY_START); - initializer="="; - initializerScope = initializerArrayScope = 0; - BEGIN(Initialization); - } -<Variable>"\n" { currentModifiers = SymbolModifiers(); - yy_pop_state(); // end variable declaration list - newLine(); - docBlock.resize(0); - } -<Variable>";".*"\n" { currentModifiers = SymbolModifiers(); - yy_pop_state(); // end variable declaration list - docBlock.resize(0); - inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data(); - yyLineNr--; - pushBuffer(inputStringSemi); + yy_push_state(YY_START,yyscanner); + yyextra->initializer="="; + yyextra->initializerScope = yyextra->initializerArrayScope = 0; + BEGIN(Initialization); + } +<Variable>"\n" { yyextra->currentModifiers = SymbolModifiers(); + yy_pop_state(yyscanner); // end variable declaration list + newLine(yyscanner); + yyextra->docBlock.resize(0); + } +<Variable>";".*"\n" { yyextra->currentModifiers = SymbolModifiers(); + yy_pop_state(yyscanner); // end variable declaration list + yyextra->docBlock.resize(0); + yyextra->inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data(); + yyextra->lineNr--; + pushBuffer(yyscanner,yyextra->inputStringSemi); } <*>";".*"\n" { - if (YY_START == Variable) REJECT; // Just be on the safe side + if (YY_START == Variable) REJECT; // Just be on the safe side if (YY_START == String) REJECT; // ";" ignored in strings - if (YY_START == StrIgnore) REJECT; // ";" ignored in regular comments - inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data(); - yyLineNr--; - pushBuffer(inputStringSemi); + if (YY_START == StrIgnore) REJECT; // ";" ignored in regular yyextra->comments + yyextra->inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data(); + yyextra->lineNr--; + pushBuffer(yyscanner,yyextra->inputStringSemi); } <Initialization,ArrayInitializer>"[" | -<Initialization,ArrayInitializer>"(/" { initializer+=yytext; - initializerArrayScope++; - BEGIN(ArrayInitializer); // initializer may contain comma +<Initialization,ArrayInitializer>"(/" { yyextra->initializer+=yytext; + yyextra->initializerArrayScope++; + BEGIN(ArrayInitializer); // initializer may contain comma } <ArrayInitializer>"]" | -<ArrayInitializer>"/)" { initializer+=yytext; - initializerArrayScope--; - if(initializerArrayScope<=0) - { - initializerArrayScope = 0; // just in case - BEGIN(Initialization); - } +<ArrayInitializer>"/)" { yyextra->initializer+=yytext; + yyextra->initializerArrayScope--; + if (yyextra->initializerArrayScope<=0) + { + yyextra->initializerArrayScope = 0; // just in case + BEGIN(Initialization); + } + } +<ArrayInitializer>. { yyextra->initializer+=yytext; } +<Initialization>"(" { yyextra->initializerScope++; + yyextra->initializer+=yytext; } -<ArrayInitializer>. { initializer+=yytext; } -<Initialization>"(" { initializerScope++; - initializer+=yytext; - } -<Initialization>")" { initializerScope--; - initializer+=yytext; - } -<Initialization>{COMMA} { if (initializerScope == 0) - { - updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr); - yy_pop_state(); // end initialization - if (last_enum) +<Initialization>")" { yyextra->initializerScope--; + yyextra->initializer+=yytext; + } +<Initialization>{COMMA} { if (yyextra->initializerScope == 0) + { + updateVariablePrepassComment(yyscanner,yyextra->colNr-(int)yyleng, yyextra->colNr); + yy_pop_state(yyscanner); // end initialization + if (yyextra->last_enum) { - last_enum->initializer= initializer; + yyextra->last_enum->initializer= yyextra->initializer; } else { - if (v_type == V_VARIABLE) last_entry->initializer= initializer; + if (yyextra->vtype == V_VARIABLE) yyextra->last_entry->initializer= yyextra->initializer; } - } - else - initializer+=", "; - } + } + else + { + yyextra->initializer+=", "; + } + } <Initialization>"\n"|"!" { //| - yy_pop_state(); // end initialization - if (last_enum) + yy_pop_state(yyscanner); // end initialization + if (yyextra->last_enum) { - last_enum->initializer= initializer; + yyextra->last_enum->initializer= yyextra->initializer; } else { - if (v_type == V_VARIABLE) last_entry->initializer= initializer; + if (yyextra->vtype == V_VARIABLE) yyextra->last_entry->initializer= yyextra->initializer; } - yyColNr -= 1; - unput(*yytext); + yyextra->colNr -= 1; + unput(*yytext); } -<Initialization>. { initializer+=yytext; } +<Initialization>. { yyextra->initializer+=yytext; } <*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} { - if(YY_START == Start) + if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBody); //anon program + addModule(yyscanner,NULL); + yy_push_state(ModuleBody,yyscanner); //anon program } - yy_push_state(Enum); - current->protection = defaultProtection; - typeProtection = defaultProtection; - typeMode = true; - - current->spec |= Entry::Struct; - current->name.resize(0); - current->args.resize(0); - current->name.sprintf("@%d",anonCount++); - - current->section = Entry::ENUM_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - if ((current_root) && - (current_root->section == Entry::CLASS_SEC - || current_root->section == Entry::NAMESPACE_SEC)) + yy_push_state(Enum,yyscanner); + yyextra->current->protection = yyextra->defaultProtection; + yyextra->typeProtection = yyextra->defaultProtection; + yyextra->typeMode = true; + + yyextra->current->spec |= Entry::Struct; + yyextra->current->name.resize(0); + yyextra->current->args.resize(0); + yyextra->current->name.sprintf("@%d",yyextra->anonCount++); + + yyextra->current->section = Entry::ENUM_SEC; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->startLine = yyextra->lineNr; + yyextra->current->bodyLine = yyextra->lineNr; + if ((yyextra->current_root) && + (yyextra->current_root->section == Entry::CLASS_SEC || + yyextra->current_root->section == Entry::NAMESPACE_SEC)) { - current->name = current_root->name + "::" + current->name; + yyextra->current->name = yyextra->current_root->name + "::" + yyextra->current->name; } - addCurrentEntry(true); - startScope(last_entry.get()); - BEGIN( Enum ) ; + addCurrentEntry(yyscanner,true); + startScope(yyscanner,yyextra->last_entry.get()); + BEGIN( Enum ) ; } <Enum>"end"{BS}"enum" { - last_entry->parent()->endBodyLine = yyLineNr; - if (!endScope(current_root)) + yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr; + if (!endScope(yyscanner,yyextra->current_root)) + { yyterminate(); - typeMode = false; - yy_pop_state(); + } + yyextra->typeMode = false; + yy_pop_state(yyscanner); } /*------ fortran subroutine/function handling ------------------------------------------------------------*/ /* Start is initial condition */ <Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}({PREFIX}{BS_})?/{SUBPROG}{BS_} { - if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) - { - addInterface("$interface$", ifType); - startScope(last_entry.get()); - } + if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC) + { + addInterface(yyscanner,"$interface$", yyextra->ifType); + startScope(yyscanner,yyextra->last_entry.get()); + } - // TYPE_SPEC is for old function style function result - result = QCString(yytext).stripWhiteSpace().lower(); - current->type = result; - yy_push_state(SubprogPrefix); - } - -<SubprogPrefix>{BS}{SUBPROG}{BS_} { - // Fortran subroutine or function found - v_type = V_IGNORE; - result=yytext; - result=result.stripWhiteSpace(); - addSubprogram(result); - BEGIN(Subprog); - current->bodyLine = yyLineNr + lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account. - current->startLine = yyLineNr; - } + // TYPE_SPEC is for old function style function result + QCString result = QCString(yytext).stripWhiteSpace().lower(); + yyextra->current->type = result; + yy_push_state(SubprogPrefix,yyscanner); + } + +<SubprogPrefix>{BS}{SUBPROG}{BS_} { + // Fortran subroutine or function found + yyextra->vtype = V_IGNORE; + QCString result=yytext; + result=result.stripWhiteSpace(); + addSubprogram(yyscanner,result); + BEGIN(Subprog); + yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account. + yyextra->current->startLine = yyextra->lineNr; + } <Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{SUBPROG}{BS_} { - // Fortran subroutine or function found - v_type = V_IGNORE; - if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) - { - addInterface("$interface$", ifType); - startScope(last_entry.get()); - } + // Fortran subroutine or function found + yyextra->vtype = V_IGNORE; + if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC) + { + addInterface(yyscanner,"$interface$", yyextra->ifType); + startScope(yyscanner,yyextra->last_entry.get()); + } + + QCString result = QCString(yytext).stripWhiteSpace(); + addSubprogram(yyscanner,result); + yy_push_state(Subprog,yyscanner); + yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account. + yyextra->current->startLine = yyextra->lineNr; + } + +<Subprog>{BS} { /* ignore white space */ } +<Subprog>{ID} { yyextra->current->name = yytext; + //cout << "1a==========> got " << yyextra->current->type << " " << yytext << " " << yyextra->lineNr << endl; + yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower()].returnName = yyextra->current->name.lower(); + + if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC) + { + yyextra->current_root->name.replace(QRegExp("\\$interface\\$"), yytext); + } - result = QCString(yytext).stripWhiteSpace(); - addSubprogram(result); - yy_push_state(Subprog); - current->bodyLine = yyLineNr + lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account. - current->startLine = yyLineNr; - } - -<Subprog>{BS} { /* ignore white space */ } -<Subprog>{ID} { current->name = yytext; - //cout << "1a==========> got " << current->type << " " << yytext << " " << yyLineNr << endl; - modifiers[current_root][current->name.lower()].returnName = current->name.lower(); - - if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) - { - current_root->name.replace(QRegExp("\\$interface\\$"), yytext); + BEGIN(Parameterlist); + } +<Parameterlist>"(" { yyextra->current->args = "("; } +<Parameterlist>")" { + yyextra->current->args += ")"; + yyextra->current->args = removeRedundantWhiteSpace(yyextra->current->args); + addCurrentEntry(yyscanner,true); + startScope(yyscanner,yyextra->last_entry.get()); + BEGIN(SubprogBody); + } +<Parameterlist>{COMMA}|{BS} { yyextra->current->args += yytext; + CommentInPrepass *c = locatePrepassComment(yyscanner,yyextra->colNr-(int)yyleng, yyextra->colNr); + if (c!=NULL) + { + if (!yyextra->current->argList.empty()) + { + yyextra->current->argList.back().docs = c->str; + } + } + } +<Parameterlist>{ID} { + //yyextra->current->type not yet available + QCString param = yytext; + // std::cout << "3=========> got parameter " << param << std::endl; + yyextra->current->args += param; + Argument arg; + arg.name = param; + yyextra->current->argList.push_back(arg); + } +<Parameterlist>{NOARGS} { + newLine(yyscanner); + //printf("3=========> without parameterlist \n"); + addCurrentEntry(yyscanner,true); + startScope(yyscanner,yyextra->last_entry.get()); + BEGIN(SubprogBody); + } +<SubprogBody>result{BS}\({BS}{ID} { + if (yyextra->functionLine) + { + QCString result= yytext; + result= result.right(result.length()-result.find("(")-1); + result= result.stripWhiteSpace(); + yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower()].returnName = result; + } + //cout << "=====> got result " << result << endl; } - BEGIN(Parameterlist); - } -<Parameterlist>"(" { current->args = "("; } -<Parameterlist>")" { - current->args += ")"; - current->args = removeRedundantWhiteSpace(current->args); - addCurrentEntry(true); - startScope(last_entry.get()); - BEGIN(SubprogBody); - } -<Parameterlist>{COMMA}|{BS} { current->args += yytext; - CommentInPrepass *c = locatePrepassComment(yyColNr-(int)yyleng, yyColNr); - if (c!=NULL) - { - if (!current->argList.empty()) - { - current->argList.back().docs = c->str; - } - } - } -<Parameterlist>{ID} { - //current->type not yet available - QCString param = yytext; - // std::cout << "3=========> got parameter " << param << std::endl; - current->args += param; - Argument arg; - arg.name = param; - current->argList.push_back(arg); - } -<Parameterlist>{NOARGS} { - newLine(); - //printf("3=========> without parameterlist \n"); - addCurrentEntry(true); - startScope(last_entry.get()); - BEGIN(SubprogBody); -} -<SubprogBody>result{BS}\({BS}{ID} { - if (functionLine) - { - result= yytext; - result= result.right(result.length()-result.find("(")-1); - result= result.stripWhiteSpace(); - modifiers[current_root->parent()][current_root->name.lower()].returnName = result; - } - //cout << "=====> got result " << result << endl; - } - - /*---- documentation comments --------------------------------------------------------------------*/ + /*---- documentation yyextra->comments --------------------------------------------------------------------*/ <Variable,SubprogBody,ModuleBody,TypedefBody,TypedefBodyContains>"!<" { /* backward docu comment */ - if (v_type != V_IGNORE) { - current->docLine = yyLineNr; - docBlockJavaStyle = FALSE; - docBlock.resize(0); - docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF); - startCommentBlock(TRUE); - yy_push_state(DocBackLine); + if (yyextra->vtype != V_IGNORE) + { + yyextra->current->docLine = yyextra->lineNr; + yyextra->docBlockJavaStyle = FALSE; + yyextra->docBlock.resize(0); + yyextra->docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF); + startCommentBlock(yyscanner,TRUE); + yy_push_state(DocBackLine,yyscanner); } else { /* handle out of place !< comment as a normal comment */ - if (YY_START == String) { yyColNr -= (int)yyleng; REJECT; } // "!" is ignored in strings - // skip comment line (without docu comments "!>" "!<" ) - /* ignore further "!" and ignore comments in Strings */ - if ((YY_START != StrIgnore) && (YY_START != String)) - { - yy_push_state(YY_START); - BEGIN(StrIgnore); - debugStr="*!"; - } + if (YY_START == String) + { + yyextra->colNr -= (int)yyleng; + REJECT; + } // "!" is ignored in strings + // skip comment line (without docu yyextra->comments "!>" "!<" ) + /* ignore further "!" and ignore yyextra->comments in Strings */ + if ((YY_START != StrIgnore) && (YY_START != String)) + { + yy_push_state(YY_START,yyscanner); + BEGIN(StrIgnore); + yyextra->debugStr="*!"; + } } - } -<DocBackLine>.* { // contents of current comment line - docBlock+=yytext; - } -<DocBackLine>"\n"{BS}"!"("<"|"!"+) { // comment block (next line is also comment line) - docBlock+="\n"; // \n is necessary for lists - newLine(); - } -<DocBackLine>"\n" { // comment block ends at the end of this line - //cout <<"3=========> comment block : "<< docBlock << endl; - yyColNr -= 1; - unput(*yytext); - if (v_type == V_VARIABLE) - { - std::shared_ptr<Entry> tmp_entry = current; + } +<DocBackLine>.* { // contents of yyextra->current comment line + yyextra->docBlock+=yytext; + } +<DocBackLine>"\n"{BS}"!"("<"|"!"+) { // comment block (next line is also comment line) + yyextra->docBlock+="\n"; // \n is necessary for lists + newLine(yyscanner); + } +<DocBackLine>"\n" { // comment block ends at the end of this line + //cout <<"3=========> comment block : "<< yyextra->docBlock << endl; + yyextra->colNr -= 1; + unput(*yytext); + if (yyextra->vtype == V_VARIABLE) + { + std::shared_ptr<Entry> tmp_entry = yyextra->current; // temporarily switch to the previous entry - if (last_enum) + if (yyextra->last_enum) { - current = last_enum; + yyextra->current = yyextra->last_enum; } else { - current = last_entry; + yyextra->current = yyextra->last_entry; } - handleCommentBlock(docBlock,TRUE); + handleCommentBlock(yyscanner,yyextra->docBlock,TRUE); // switch back - current = tmp_entry; + yyextra->current = tmp_entry; } - else if (v_type == V_PARAMETER) - { - subrHandleCommentBlock(docBlock,TRUE); + else if (yyextra->vtype == V_PARAMETER) + { + subrHandleCommentBlock(yyscanner,yyextra->docBlock,TRUE); } - else if (v_type == V_RESULT) - { - subrHandleCommentBlockResult(docBlock,TRUE); + else if (yyextra->vtype == V_RESULT) + { + subrHandleCommentBlockResult(yyscanner,yyextra->docBlock,TRUE); } - yy_pop_state(); - docBlock.resize(0); + yy_pop_state(yyscanner); + yyextra->docBlock.resize(0); } <Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,Enum>"!>" { - yy_push_state(YY_START); - current->docLine = yyLineNr; - docBlockJavaStyle = FALSE; - if (YY_START==SubprogBody) docBlockInBody = TRUE; - docBlock.resize(0); - docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF); - startCommentBlock(TRUE); - BEGIN(DocBlock); + yy_push_state(YY_START,yyscanner); + yyextra->current->docLine = yyextra->lineNr; + yyextra->docBlockJavaStyle = FALSE; + if (YY_START==SubprogBody) yyextra->docBlockInBody = TRUE; + yyextra->docBlock.resize(0); + yyextra->docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF); + startCommentBlock(yyscanner,TRUE); + BEGIN(DocBlock); //cout << "start DocBlock " << endl; - } - -<DocBlock>.* { // contents of current comment line - docBlock+=yytext; - } -<DocBlock>"\n"{BS}"!"(">"|"!"+) { // comment block (next line is also comment line) - docBlock+="\n"; // \n is necessary for lists - newLine(); - } -<DocBlock>"\n" { // comment block ends at the end of this line - //cout <<"3=========> comment block : "<< docBlock << endl; - yyColNr -= 1; - unput(*yytext); - handleCommentBlock(docBlock,TRUE); - yy_pop_state(); - } + } + +<DocBlock>.* { // contents of yyextra->current comment line + yyextra->docBlock+=yytext; + } +<DocBlock>"\n"{BS}"!"(">"|"!"+) { // comment block (next line is also comment line) + yyextra->docBlock+="\n"; // \n is necessary for lists + newLine(yyscanner); + } +<DocBlock>"\n" { // comment block ends at the end of this line + //cout <<"3=========> comment block : "<< yyextra->docBlock << endl; + yyextra->colNr -= 1; + unput(*yytext); + handleCommentBlock(yyscanner,yyextra->docBlock,TRUE); + yy_pop_state(yyscanner); + } /*-----Prototype parsing -------------------------------------------------------------------------*/ -<Prototype>{BS}{SUBPROG}{BS_} { - BEGIN(PrototypeSubprog); - } +<Prototype>{BS}{SUBPROG}{BS_} { + BEGIN(PrototypeSubprog); + } <Prototype,PrototypeSubprog>{BS}{SCOPENAME}?{BS}{ID} { - current->name = QCString(yytext).lower(); - current->name.stripWhiteSpace(); - BEGIN(PrototypeArgs); - } + yyextra->current->name = QCString(yytext).lower(); + yyextra->current->name.stripWhiteSpace(); + BEGIN(PrototypeArgs); + } <PrototypeArgs>{ -"("|")"|","|{BS_} { current->args += yytext; } -{ID} { current->args += yytext; - Argument a; - a.name = QCString(yytext).lower(); - current->argList.push_back(a); - } +"("|")"|","|{BS_} { yyextra->current->args += yytext; } +{ID} { yyextra->current->args += yytext; + Argument a; + a.name = QCString(yytext).lower(); + yyextra->current->argList.push_back(a); + } } /*------------------------------------------------------------------------------------------------*/ <*>"\n" { - newLine(); - //if (debugStr.stripWhiteSpace().length() > 0) cout << "ignored text: " << debugStr << " state: " <<YY_START << endl; - debugStr=""; + newLine(yyscanner); + //if (yyextra->debugStr.stripWhiteSpace().length() > 0) cout << "ignored text: " << yyextra->debugStr << " state: " <<YY_START << endl; + yyextra->debugStr=""; } /*---- error: EOF in wrong state --------------------------------------------------------------------*/ <*><<EOF>> { - if (parsingPrototype) { - yyterminate(); - - } else if ( include_stack_ptr <= 0 ) { - if (YY_START!=INITIAL && YY_START!=Start) { + if (yyextra->parsingPrototype) + { + yyterminate(); + } + else if ( yyextra->includeStackPtr <= 0 ) + { + if (YY_START!=INITIAL && YY_START!=Start) + { DBG_CTX((stderr,"==== Error: EOF reached in wrong state (end missing)")); - scanner_abort(); + scanner_abort(yyscanner); } yyterminate(); - } else { - popBuffer(); + } + else + { + popBuffer(yyscanner); } } <*>{LOG_OPER} { // Fortran logical comparison keywords } -<*>. { - //debugStr+=yytext; - //printf("I:%c\n", *yytext); +<*>. { + //yyextra->debugStr+=yytext; + //printf("I:%c\n", *yytext); } // ignore remaining text /**********************************************************************************/ @@ -1323,63 +1355,53 @@ private { %% //---------------------------------------------------------------------------- -#if 0 -static void extractPrefix(QCString &text) +static void newLine(yyscan_t yyscanner) { - int prefixIndex = 0; - int curIndex = 0; - bool cont = TRUE; - const char* pre[] = {"RECURSIVE","IMPURE","PURE","ELEMENTAL"}; - while(cont) - { - cont = FALSE; - for(unsigned int i=0; i<4; i++) - { - if((prefixIndex=text.find(pre[i], curIndex, FALSE))==0) - { - text.remove(0,strlen(pre[i])); - text.stripWhiteSpace(); - cont = TRUE; - } - } - } -} -#endif - -static void newLine() { - yyLineNr++; - yyLineNr+=lineCountPrepass; - lineCountPrepass=0; - comments.clear(); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->lineNr++; + yyextra->lineNr+=yyextra->lineCountPrepass; + yyextra->lineCountPrepass=0; + yyextra->comments.clear(); } -static CommentInPrepass* locatePrepassComment(int from, int to) { +static CommentInPrepass* locatePrepassComment(yyscan_t yyscanner,int from, int to) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("Locate %d-%d\n", from, to); - for(uint i=0; i<comments.count(); i++) { // todo: optimize - int c = comments.at(i)->column; + for (uint i=0; i<yyextra->comments.count(); i++) + { // todo: optimize + int c = yyextra->comments.at(i)->column; //printf("Candidate %d\n", c); - if (c>=from && c<=to) { + if (c>=from && c<=to) + { // comment for previous variable or parameter - return comments.at(i); + return yyextra->comments.at(i); } } return NULL; } -static void updateVariablePrepassComment(int from, int to) { - CommentInPrepass *c = locatePrepassComment(from, to); - if (c!=NULL && v_type == V_VARIABLE) { - last_entry->brief = c->str; - } else if (c!=NULL && v_type == V_PARAMETER) { - Argument *parameter = getParameter(argName); +static void updateVariablePrepassComment(yyscan_t yyscanner,int from, int to) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + CommentInPrepass *c = locatePrepassComment(yyscanner,from, to); + if (c!=NULL && yyextra->vtype == V_VARIABLE) + { + yyextra->last_entry->brief = c->str; + } + else if (c!=NULL && yyextra->vtype == V_PARAMETER) + { + Argument *parameter = getParameter(yyscanner,yyextra->argName); if (parameter) parameter->docs = c->str; } } static int getAmpersandAtTheStart(const char *buf, int length) { - for(int i=0; i<length; i++) { - switch(buf[i]) { + for(int i=0; i<length; i++) + { + switch(buf[i]) + { case ' ': case '\t': break; @@ -1395,7 +1417,7 @@ static int getAmpersandAtTheStart(const char *buf, int length) /* Returns ampersand index, comment start index or -1 if neither exist.*/ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch) { - // Avoid ampersands in string and comments + // Avoid ampersands in string and yyextra->comments int parseState = Start; char quoteSymbol = 0; int ampIndex = -1; @@ -1407,9 +1429,9 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch) { // When in string, skip backslashes // Legacy code, not sure whether this is correct? - if(parseState==String) + if (parseState==String) { - if(buf[i]=='\\') i++; + if (buf[i]=='\\') i++; } switch(buf[i]) @@ -1418,13 +1440,13 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch) case '"': // Close string, if quote symbol matches. // Quote symbol is set iff parseState==String - if(buf[i]==quoteSymbol) + if (buf[i]==quoteSymbol) { parseState = Start; quoteSymbol = 0; } // Start new string, if not already in string or comment - else if(parseState==Start) + else if (parseState==Start) { parseState = String; quoteSymbol = buf[i]; @@ -1433,7 +1455,7 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch) break; case '!': // When in string or comment, ignore exclamation mark - if(parseState==Start) + if (parseState==Start) { parseState = Comment; commentIndex = i; @@ -1457,23 +1479,23 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch) return commentIndex; } -/* Although comments at the end of continuation line are grabbed by this function, +/* Although yyextra->comments at the end of continuation line are grabbed by this function, * we still do not know how to use them later in parsing. */ -void truncatePrepass(int index) +void truncatePrepass(yyscan_t yyscanner,int index) { - int length = inputStringPrepass.length(); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + int length = yyextra->inputStringPrepass.length(); for (int i=index+1; i<length; i++) { - if (inputStringPrepass[i]=='!' && i<length-1 && inputStringPrepass[i+1]=='<') { // save comment - struct CommentInPrepass *c=new CommentInPrepass(index, inputStringPrepass.right(length-i-2)); - comments.append(c); + if (yyextra->inputStringPrepass[i]=='!' && i<length-1 && yyextra->inputStringPrepass[i+1]=='<') { // save comment + struct CommentInPrepass *c=new CommentInPrepass(index, yyextra->inputStringPrepass.right(length-i-2)); + yyextra->comments.append(c); } } - inputStringPrepass.truncate(index); + yyextra->inputStringPrepass.truncate(index); } // simplified way to know if this is fixed form -// duplicate in fortrancode.l bool recognizeFixedForm(const char* contents, FortranFormat format) { int column=0; @@ -1500,16 +1522,16 @@ bool recognizeFixedForm(const char* contents, FortranFormat format) case 'C': case 'c': case '*': - if(column==1) return TRUE; - if(skipLine) break; + if (column==1) return TRUE; + if (skipLine) break; return FALSE; case '!': - if(column>1 && column<7) return FALSE; + if (column>1 && column<7) return FALSE; skipLine=TRUE; break; default: - if(skipLine) break; - if(column==7) return TRUE; + if (skipLine) break; + if (column>=7) return TRUE; return FALSE; } } @@ -1526,7 +1548,7 @@ static void insertCharacter(char *contents, int length, int pos, char c) contents[pos] = c; } -/* change comments and bring line continuation character to previous line */ +/* change yyextra->comments and bring line continuation character to previous line */ /* also used to set continuation marks in case of fortran code usage, done here as it is quite complicated code */ const char* prepassFixedForm(const char* contents, int *hasContLine) { @@ -1544,7 +1566,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) bool fullCommentLine=TRUE; bool artificialComment=FALSE; bool spaces=TRUE; - int newContentsSize = strlen(contents)+3; // \000, \n (when necessary) and one spare character (to avoid reallocation) + int newContentsSize = (int)strlen(contents)+3; // \000, \n (when necessary) and one spare character (to avoid reallocation) char* newContents = (char*)malloc(newContentsSize); int curLine = 1; @@ -1572,7 +1594,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) } j++; - if(j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ') + if (j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ') newContents = (char*)realloc(newContents, newContentsSize+1000); newContentsSize = newContentsSize+1000; } @@ -1603,7 +1625,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) spaces=TRUE; fullCommentLine=TRUE; column=0; - emptyLabel=TRUE; + emptyLabel=TRUE; commented=FALSE; newContents[j]=c; prevQuote = thisQuote; @@ -1620,7 +1642,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) return NULL; } newContents[j]='\000'; - newContentsSize = strlen(newContents); + newContentsSize = (int)strlen(newContents); if (newContents[newContentsSize - 1] != '\n') { // to be on the safe side @@ -1633,10 +1655,10 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) case '\'': case '\\': if ((column <= fixedCommentAfter) && (column!=6) && !commented) - { + { // we have some special cases in respect to strings and escaped string characters fullCommentLine=FALSE; - newContents[j]=c; + newContents[j]=c; if (c == '\\') { inBackslash = !inBackslash; @@ -1671,71 +1693,89 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) case '*': case '!': if ((column <= fixedCommentAfter) && (column!=6)) - { - emptyLabel=FALSE; - if(column==1) + { + emptyLabel=FALSE; + if (column==1) { - newContents[j]='!'; + newContents[j]='!'; commented = TRUE; } - else if ((c == '!') && !inDouble && !inSingle) + else if ((c == '!') && !inDouble && !inSingle) { - newContents[j]=c; + newContents[j]=c; commented = TRUE; } - else + else { if (!commented) fullCommentLine=FALSE; - newContents[j]=c; + newContents[j]=c; } - break; - } + break; + } // fallthrough default: - if (!commented && (column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9)) { // remove numbers, i.e. labels from first 5 positions. + if (!commented && (column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9)) + { // remove numbers, i.e. labels from first 5 positions. newContents[j]=' '; } - else if(column==6 && emptyLabel) { // continuation + else if (column==6 && emptyLabel) + { // continuation if (!commented) fullCommentLine=FALSE; - if (c != '0') { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3 + if (c != '0') + { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3 newContents[j]=' '; - if(prevLineAmpOrExclIndex==-1) { // add & just before end of previous line + if (prevLineAmpOrExclIndex==-1) + { // add & just before end of previous line /* first line is not a continuation line in code, just in snippets etc. */ if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-1, '&'); j++; - } else { // add & just before end of previous line comment + } + else + { // add & just before end of previous line comment /* first line is not a continuation line in code, just in snippets etc. */ if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex+skipped, '&'); skipped = 0; j++; } - if (hasContLine) hasContLine[curLine - 1] = 1; - } else { - newContents[j]=c; // , just handle like space + if (hasContLine) + { + hasContLine[curLine - 1] = 1; + } + } + else + { + newContents[j]=c; // , just handle like space } prevLineLength=0; - } else if ((column > fixedCommentAfter) && !commented) { + } + else if ((column > fixedCommentAfter) && !commented) + { // first non commented non blank character after position fixedCommentAfter - if (c == '&') { - newContents[j]=' '; + if (c == '&') + { + newContents[j]=' '; } - else if (c != '!') { + else if (c != '!') + { // I'm not a possible start of doxygen comment - newContents[j]=' '; + newContents[j]=' '; artificialComment = TRUE; spaces=TRUE; skipped = 0; } - else { - newContents[j]=c; + else + { + newContents[j]=c; commented = TRUE; } - } else { + } + else + { if (!commented) fullCommentLine=FALSE; - newContents[j]=c; - emptyLabel=FALSE; - } + newContents[j]=c; + emptyLabel=FALSE; + } break; } } @@ -1745,7 +1785,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) free(newContents); return NULL; } - newContentsSize = strlen(newContents); + newContentsSize = (int)strlen(newContents); if (newContents[newContentsSize - 1] != '\n') { // to be on the safe side @@ -1756,25 +1796,28 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) return newContents; } -static void pushBuffer(QCString& buffer) +static void pushBuffer(yyscan_t yyscanner,QCString& buffer) { - if (include_stack_cnt <= include_stack_ptr) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->includeStackCnt <= yyextra->includeStackPtr) { - include_stack_cnt++; - include_stack = (YY_BUFFER_STATE *)realloc(include_stack, include_stack_cnt * sizeof(YY_BUFFER_STATE)); + yyextra->includeStackCnt++; + yyextra->includeStack = (YY_BUFFER_STATE *)realloc(yyextra->includeStack, yyextra->includeStackCnt * sizeof(YY_BUFFER_STATE)); } - include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_scan_string(buffer)); + yyextra->includeStack[yyextra->includeStackPtr++] = YY_CURRENT_BUFFER; + yy_switch_to_buffer(yy_scan_string(buffer,yyscanner),yyscanner); DBG_CTX((stderr, "--PUSH--%s", (const char *)buffer)); buffer = NULL; } -static void popBuffer() { +static void popBuffer(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; DBG_CTX((stderr, "--POP--")); - include_stack_ptr --; - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( include_stack[include_stack_ptr] ); + yyextra->includeStackPtr --; + yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner ); + yy_switch_to_buffer( yyextra->includeStack[yyextra->includeStackPtr], yyscanner ); } /** used to copy entry to an interface module procedure */ @@ -1795,9 +1838,10 @@ static void copyEntry(std::shared_ptr<Entry> dest, const std::shared_ptr<Entry> corresponding module subprogs @TODO: handle procedures in used modules */ -void resolveModuleProcedures(Entry *current_root) +void resolveModuleProcedures(yyscan_t yyscanner,Entry *current_root) { - for (const auto &ce1 : moduleProcedures) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + for (const auto &ce1 : yyextra->moduleProcedures) { // check all entries in this module for (const auto &ce2 : current_root->children()) @@ -1806,19 +1850,10 @@ void resolveModuleProcedures(Entry *current_root) { copyEntry(ce1, ce2); } - } // for procedures in current module + } // for procedures in yyextra->current module } // for all interface module procedures - moduleProcedures.clear(); -} - -#if 0 -static bool isTypeName(QCString name) -{ - name = name.lower(); - return name=="integer" || name == "real" || - name=="complex" || name == "logical"; + yyextra->moduleProcedures.clear(); } -#endif /*! Extracts string which resides within parentheses of provided string. */ static QCString extractFromParens(const QCString name) @@ -1863,7 +1898,7 @@ static QCString extractBind(const QCString name) } } -/*! Adds passed modifiers to these modifiers.*/ +/*! Adds passed yyextra->modifiers to these yyextra->modifiers.*/ SymbolModifiers& SymbolModifiers::operator|=(const SymbolModifiers &mdfs) { if (mdfs.protection!=NONE_P) protection = mdfs.protection; @@ -1890,7 +1925,7 @@ SymbolModifiers& SymbolModifiers::operator|=(const SymbolModifiers &mdfs) return *this; } -/*! Extracts and adds passed modifier to these modifiers.*/ +/*! Extracts and adds passed modifier to these yyextra->modifiers.*/ SymbolModifiers& SymbolModifiers::operator|=(QCString mdfStringArg) { QCString mdfString = mdfStringArg.lower(); @@ -2012,7 +2047,7 @@ static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = F for (Argument &arg : subprog->argList) { if ((!byTypeName && arg.name.lower() == cname) || - (byTypeName && arg.type.lower() == cname) + (byTypeName && arg.type.lower() == cname) ) { return &arg; @@ -2022,7 +2057,7 @@ static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = F } -/*! Apply modifiers stored in \a mdfs to the \a typeName string. */ +/*! Apply yyextra->modifiers stored in \a mdfs to the \a typeName string. */ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs) { if (!mdfs.dimension.isNull()) @@ -2139,14 +2174,14 @@ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs) return typeName; } -/*! Apply modifiers stored in \a mdfs to the \a arg argument. */ +/*! Apply yyextra->modifiers stored in \a mdfs to the \a arg argument. */ static void applyModifiers(Argument *arg, SymbolModifiers& mdfs) { QCString tmp = arg->type; arg->type = applyModifiers(tmp, mdfs); } -/*! Apply modifiers stored in \a mdfs to the \a ent entry. */ +/*! Apply yyextra->modifiers stored in \a mdfs to the \a ent entry. */ static void applyModifiers(Entry *ent, SymbolModifiers& mdfs) { QCString tmp = ent->type; @@ -2162,47 +2197,49 @@ static void applyModifiers(Entry *ent, SymbolModifiers& mdfs) * starting module, interface, function or other program block. * \see endScope() */ -static void startScope(Entry *scope) +static void startScope(yyscan_t yyscanner,Entry *scope) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //cout<<"start scope: "<<scope->name<<endl; - current_root= scope; /* start substructure */ + yyextra->current_root= scope; /* start substructure */ QMap<QCString,SymbolModifiers> mdfMap; - modifiers.insert(scope, mdfMap); + yyextra->modifiers.insert(scope, mdfMap); } /*! Ends scope in fortran program: may update subprogram arguments or module variable attributes. * \see startScope() */ -static bool endScope(Entry *scope, bool isGlobalRoot) +static bool endScope(yyscan_t yyscanner,Entry *scope, bool isGlobalRoot) { - if (global_scope == scope) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->global_scope == scope) { - global_scope = 0; + yyextra->global_scope = 0; return TRUE; } - if (global_scope == INVALID_ENTRY) + if (yyextra->global_scope == INVALID_ENTRY) { return TRUE; } //cout<<"end scope: "<<scope->name<<endl; - if (current_root->parent() || isGlobalRoot) + if (yyextra->current_root->parent() || isGlobalRoot) { - current_root= current_root->parent(); /* end substructure */ + yyextra->current_root= yyextra->current_root->parent(); /* end substructure */ } - else // if (current_root != scope) + else // if (yyextra->current_root != scope) { fprintf(stderr,"parse error in end <scopename>\n"); - scanner_abort(); + scanner_abort(yyscanner); return FALSE; } - // update variables or subprogram arguments with modifiers - QMap<QCString,SymbolModifiers>& mdfsMap = modifiers[scope]; + // update variables or subprogram arguments with yyextra->modifiers + QMap<QCString,SymbolModifiers>& mdfsMap = yyextra->modifiers[scope]; if (scope->section == Entry::FUNCTION_SEC) { - // iterate all symbol modifiers of the scope + // iterate all symbol yyextra->modifiers of the scope for (QMap<QCString,SymbolModifiers>::Iterator it=mdfsMap.begin(); it!=mdfsMap.end(); it++) { //cout<<it.key()<<": "<<it.data()<<endl; @@ -2215,12 +2252,12 @@ static bool endScope(Entry *scope, bool isGlobalRoot) } // find return type for function - //cout<<"RETURN NAME "<<modifiers[current_root][scope->name.lower()].returnName<<endl; - QCString returnName = modifiers[current_root][scope->name.lower()].returnName.lower(); - if (modifiers[scope].contains(returnName)) + //cout<<"RETURN NAME "<<yyextra->modifiers[yyextra->current_root][scope->name.lower()].returnName<<endl; + QCString returnName = yyextra->modifiers[yyextra->current_root][scope->name.lower()].returnName.lower(); + if (yyextra->modifiers[scope].contains(returnName)) { - scope->type = modifiers[scope][returnName].type; // returning type works - applyModifiers(scope, modifiers[scope][returnName]); // returning array works + scope->type = yyextra->modifiers[scope][returnName].type; // returning type works + applyModifiers(scope, yyextra->modifiers[scope][returnName]); // returning array works } } @@ -2241,17 +2278,17 @@ static bool endScope(Entry *scope, bool isGlobalRoot) Argument *arg = findArgument(scope->parent(), ce->name, TRUE); if (arg != 0) - { + { // set type of dummy procedure argument to interface - arg->name = arg->type; + arg->name = arg->type; arg->type = scope->name; } if (ce->name.lower() == scope->name.lower()) found = TRUE; } if ((count == 1) && found) { - // clear all modifiers of the scope - modifiers.remove(scope); + // clear all yyextra->modifiers of the scope + yyextra->modifiers.remove(scope); scope->parent()->removeSubEntry(scope); scope = 0; return TRUE; @@ -2260,7 +2297,7 @@ static bool endScope(Entry *scope, bool isGlobalRoot) } if (scope->section!=Entry::FUNCTION_SEC) { // not function section - // iterate variables: get and apply modifiers + // iterate variables: get and apply yyextra->modifiers for (const auto &ce : scope->children()) { if (ce->section != Entry::VARIABLE_SEC && ce->section != Entry::FUNCTION_SEC) @@ -2272,165 +2309,156 @@ static bool endScope(Entry *scope, bool isGlobalRoot) } } - // clear all modifiers of the scope - modifiers.remove(scope); + // clear all yyextra->modifiers of the scope + yyextra->modifiers.remove(scope); return TRUE; } -#if 0 -//! Return full name of the entry. Sometimes we must combine several names recursively. -static QCString getFullName(Entry *e) -{ - QCString name = e->name; - if (e->section == Entry::CLASS_SEC // || e->section == Entry::INTERFACE_SEC - || !e->parent() || e->parent()->name.isEmpty()) - return name; - - return getFullName(e->parent())+"::"+name; -} -#endif - -static int yyread(char *buf,int max_size) +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) { - int c=0; - - while ( c < max_size && inputString[inputPosition] ) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yy_size_t c=0; + while ( c < max_size && yyextra->inputString[yyextra->inputPosition] ) { - *buf = inputString[inputPosition++] ; + *buf = yyextra->inputString[yyextra->inputPosition++] ; c++; buf++; } return c; } -static void initParser() +static void initParser(yyscan_t yyscanner) { - last_entry.reset(); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->last_entry.reset(); } -static void initEntry() +static void initEntry(yyscan_t yyscanner) { - if (typeMode) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->typeMode) { - current->protection = typeProtection; + yyextra->current->protection = yyextra->typeProtection; } else { - current->protection = defaultProtection; + yyextra->current->protection = yyextra->defaultProtection; } - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->lang = SrcLangExt_Fortran; - Doxygen::docGroup.initGroupInfo(current.get()); + yyextra->current->mtype = Method; + yyextra->current->virt = Normal; + yyextra->current->stat = FALSE; + yyextra->current->lang = SrcLangExt_Fortran; + yyextra->commentScanner.initGroupInfo(yyextra->current.get()); } /** - adds current entry to current_root and creates new current + adds yyextra->current entry to yyextra->current_root and creates new yyextra->current */ -static void addCurrentEntry(bool case_insens) +static void addCurrentEntry(yyscan_t yyscanner,bool case_insens) { - if (case_insens) current->name = current->name.lower(); - //printf("===Adding entry %s to %s\n", current->name.data(), current_root->name.data()); - last_entry = current; - current_root->moveToSubEntryAndRefresh(current); - initEntry(); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (case_insens) yyextra->current->name = yyextra->current->name.lower(); + //printf("===Adding entry %s to %s\n", yyextra->current->name.data(), yyextra->current_root->name.data()); + yyextra->last_entry = yyextra->current; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + initEntry(yyscanner); } -static int max(int a, int b) {return a>b?a:b;} - -static void addModule(const char *name, bool isModule) +static void addModule(yyscan_t yyscanner,const char *name, bool isModule) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; DBG_CTX((stderr, "0=========> got module %s\n", name)); if (isModule) - current->section = Entry::NAMESPACE_SEC; + yyextra->current->section = Entry::NAMESPACE_SEC; else - current->section = Entry::FUNCTION_SEC; + yyextra->current->section = Entry::FUNCTION_SEC; if (name!=NULL) { - current->name = name; + yyextra->current->name = name; } else { - QCString fname = yyFileName; - int index = max(fname.findRev('/'), fname.findRev('\\')); + QCString fname = yyextra->fileName; + int index = QMAX(fname.findRev('/'), fname.findRev('\\')); fname = fname.right(fname.length()-index-1); fname = fname.prepend("__").append("__"); - current->name = fname; - } - current->type = "program"; - current->fileName = yyFileName; - current->bodyLine = yyLineNr; // used for source reference - current->startLine = yyLineNr; - current->protection = Public ; - addCurrentEntry(true); - startScope(last_entry.get()); + yyextra->current->name = fname; + } + yyextra->current->type = "program"; + yyextra->current->fileName = yyextra->fileName; + yyextra->current->bodyLine = yyextra->lineNr; // used for source reference + yyextra->current->startLine = yyextra->lineNr; + yyextra->current->protection = Public ; + addCurrentEntry(yyscanner,true); + startScope(yyscanner,yyextra->last_entry.get()); } -static void addSubprogram(const char *text) +static void addSubprogram(yyscan_t yyscanner,const char *text) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; DBG_CTX((stderr,"1=========> got subprog, type: %s\n",text)); - subrCurrent.push_back(current); - current->section = Entry::FUNCTION_SEC ; + yyextra->subrCurrent.push_back(yyextra->current); + yyextra->current->section = Entry::FUNCTION_SEC ; QCString subtype = text; subtype=subtype.lower().stripWhiteSpace(); - functionLine = (subtype.find("function") != -1); - current->type += " " + subtype; - current->type = current->type.stripWhiteSpace(); - current->fileName = yyFileName; - current->bodyLine = yyLineNr; // used for source reference start of body of routine - current->startLine = yyLineNr; // used for source reference start of definition - current->args.resize(0); - current->argList.clear(); - docBlock.resize(0); + yyextra->functionLine = (subtype.find("function") != -1); + yyextra->current->type += " " + subtype; + yyextra->current->type = yyextra->current->type.stripWhiteSpace(); + yyextra->current->fileName = yyextra->fileName; + yyextra->current->bodyLine = yyextra->lineNr; // used for source reference start of body of routine + yyextra->current->startLine = yyextra->lineNr; // used for source reference start of definition + yyextra->current->args.resize(0); + yyextra->current->argList.clear(); + yyextra->docBlock.resize(0); } /*! Adds interface to the root entry. * \note Code was brought to this procedure from the parser, * because there was/is idea to use it in several parts of the parser. */ -static void addInterface(QCString name, InterfaceType type) +static void addInterface(yyscan_t yyscanner,QCString name, InterfaceType type) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (YY_START == Start) { - addModule(NULL); - yy_push_state(ModuleBody); //anon program + addModule(yyscanner,NULL); + yy_push_state(ModuleBody,yyscanner); //anon program } - current->section = Entry::CLASS_SEC; // was Entry::INTERFACE_SEC; - current->spec = Entry::Interface; - current->name = name; + yyextra->current->section = Entry::CLASS_SEC; // was Entry::INTERFACE_SEC; + yyextra->current->spec = Entry::Interface; + yyextra->current->name = name; switch (type) { case IF_ABSTRACT: - current->type = "abstract"; + yyextra->current->type = "abstract"; break; case IF_GENERIC: - current->type = "generic"; + yyextra->current->type = "generic"; break; case IF_SPECIFIC: case IF_NONE: default: - current->type = ""; + yyextra->current->type = ""; } /* if type is part of a module, mod name is necessary for output */ - if ((current_root) && - (current_root->section == Entry::CLASS_SEC || - current_root->section == Entry::NAMESPACE_SEC)) + if ((yyextra->current_root) && + (yyextra->current_root->section == Entry::CLASS_SEC || + yyextra->current_root->section == Entry::NAMESPACE_SEC)) { - current->name= current_root->name + "::" + current->name; + yyextra->current->name= yyextra->current_root->name + "::" + yyextra->current->name; } - current->fileName = yyFileName; - current->bodyLine = yyLineNr; - current->startLine = yyLineNr; - addCurrentEntry(true); + yyextra->current->fileName = yyextra->fileName; + yyextra->current->bodyLine = yyextra->lineNr; + yyextra->current->startLine = yyextra->lineNr; + addCurrentEntry(yyscanner,true); } @@ -2438,11 +2466,12 @@ static void addInterface(QCString name, InterfaceType type) /*! Get the argument \a name. */ -static Argument *getParameter(const QCString &name) +static Argument *getParameter(yyscan_t yyscanner,const QCString &name) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; // std::cout<<"addFortranParameter(): "<<name<<" DOCS:"<<(docs.isNull()?QCString("null"):docs)<<std::endl; Argument *ret = 0; - for (Argument &a:current_root->argList) + for (Argument &a:yyextra->current_root->argList) { if (a.name.lower()==name.lower()) { @@ -2455,70 +2484,73 @@ static Argument *getParameter(const QCString &name) } //---------------------------------------------------------------------------- -static void startCommentBlock(bool brief) +static void startCommentBlock(yyscan_t yyscanner,bool brief) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (brief) { - current->briefFile = yyFileName; - current->briefLine = yyLineNr; + yyextra->current->briefFile = yyextra->fileName; + yyextra->current->briefLine = yyextra->lineNr; } else { - current->docFile = yyFileName; - current->docLine = yyLineNr; + yyextra->current->docFile = yyextra->fileName; + yyextra->current->docLine = yyextra->lineNr; } } //---------------------------------------------------------------------------- -static void handleCommentBlock(const QCString &doc,bool brief) +static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief) { - static bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS); - if (docBlockInBody && hideInBodyDocs) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS); + if (yyextra->docBlockInBody && hideInBodyDocs) { - docBlockInBody = FALSE; + yyextra->docBlockInBody = FALSE; return; } DBG_CTX((stderr,"call parseCommentBlock [%s]\n",doc.data())); - int lineNr = brief ? current->briefLine : current->docLine; + int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; int position=0; bool needsEntry = FALSE; - QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); - while (parseCommentBlock( - g_thisParser, - docBlockInBody ? subrCurrent.back().get() : current.get(), - processedDoc, // text - yyFileName, // file - lineNr, - docBlockInBody ? FALSE : brief, - docBlockInBody ? FALSE : docBlockJavaStyle, - docBlockInBody, - defaultProtection, + QCString processedDoc = processMarkdownForCommentBlock(doc,yyextra->fileName,lineNr); + while (yyextra->commentScanner.parseCommentBlock( + yyextra->thisParser, + yyextra->docBlockInBody ? yyextra->subrCurrent.back().get() : yyextra->current.get(), + processedDoc, // text + yyextra->fileName, // file + lineNr, + yyextra->docBlockInBody ? FALSE : brief, + yyextra->docBlockInBody ? FALSE : yyextra->docBlockJavaStyle, + yyextra->docBlockInBody, + yyextra->defaultProtection, position, needsEntry )) { - DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); - if (needsEntry) addCurrentEntry(false); + DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); + if (needsEntry) addCurrentEntry(yyscanner,false); } DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); - if (needsEntry) addCurrentEntry(false); - docBlockInBody = FALSE; + if (needsEntry) addCurrentEntry(yyscanner,false); + yyextra->docBlockInBody = FALSE; } //---------------------------------------------------------------------------- /// Handle parameter description as defined after the declaration of the parameter -static void subrHandleCommentBlock(const QCString &doc,bool brief) +static void subrHandleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - std::shared_ptr<Entry> tmp_entry = current; - current = subrCurrent.back(); // temporarily switch to the entry of the subroutine / function + std::shared_ptr<Entry> tmp_entry = yyextra->current; + yyextra->current = yyextra->subrCurrent.back(); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation - current->inbodyDocs = ""; + yyextra->current->inbodyDocs = ""; // strip \\param or @param, so we can do some extra checking. We will add it later on again. if (!loc_doc.stripPrefix("\\param") && @@ -2527,7 +2559,7 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) loc_doc.stripWhiteSpace(); // direction as defined with the declaration of the parameter - int dir1 = modifiers[current_root][argName.lower()].direction; + int dir1 = yyextra->modifiers[yyextra->current_root][yyextra->argName.lower()].direction; // in description [in] is specified if (loc_doc.lower().find(directionParam[SymbolModifiers::IN]) == 0) { @@ -2536,22 +2568,22 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) (directionParam[dir1] == directionParam[SymbolModifiers::IN])) { // strip direction - loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::IN])); + loc_doc = loc_doc.right(loc_doc.length()-(int)strlen(directionParam[SymbolModifiers::IN])); loc_doc.stripWhiteSpace(); // in case of empty documentation or (now) just name, consider it as no documentation - if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower())) { - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " + - argName + " " + loc_doc,brief); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " + + yyextra->argName + " " + loc_doc,brief); } } else { // something different specified, give warning and leave error. - warn(yyFileName,yyLineNr, "Routine: " + current->name + current->args + - " inconsistency between intent attribute and documentation for parameter: " + argName); - handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " + - argName + " " + loc_doc,brief); + warn(yyextra->fileName,yyextra->lineNr, "%s", ("Routine: " + yyextra->current->name + yyextra->current->args + + " inconsistency between intent attribute and documentation for parameter: " + yyextra->argName).data()); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " + + yyextra->argName + " " + loc_doc,brief); } } // analogous to the [in] case, here [out] direction specified @@ -2560,22 +2592,22 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) if ((directionParam[dir1] == directionParam[SymbolModifiers::NONE_D]) || (directionParam[dir1] == directionParam[SymbolModifiers::OUT])) { - loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::OUT])); + loc_doc = loc_doc.right(loc_doc.length()-(int)strlen(directionParam[SymbolModifiers::OUT])); loc_doc.stripWhiteSpace(); - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) + if (loc_doc.isEmpty() || (loc_doc.lower() == yyextra->argName.lower())) { - current = tmp_entry; + yyextra->current = tmp_entry; return; } - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " + - argName + " " + loc_doc,brief); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " + + yyextra->argName + " " + loc_doc,brief); } else { - warn(yyFileName,yyLineNr, "Routine: " + current->name + current->args + - " inconsistency between intent attribute and documentation for parameter: " + argName); - handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " + - argName + " " + loc_doc,brief); + warn(yyextra->fileName,yyextra->lineNr, "%s", ("Routine: " + yyextra->current->name + yyextra->current->args + + " inconsistency between intent attribute and documentation for parameter: " + yyextra->argName).data()); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " + + yyextra->argName + " " + loc_doc,brief); } } // analogous to the [in] case, here [in,out] direction specified @@ -2584,44 +2616,45 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) if ((directionParam[dir1] == directionParam[SymbolModifiers::NONE_D]) || (directionParam[dir1] == directionParam[SymbolModifiers::INOUT])) { - loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::INOUT])); + loc_doc = loc_doc.right(loc_doc.length()-(int)strlen(directionParam[SymbolModifiers::INOUT])); loc_doc.stripWhiteSpace(); - if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower())) { - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " + - argName + " " + loc_doc,brief); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " + + yyextra->argName + " " + loc_doc,brief); } } else { - warn(yyFileName,yyLineNr, "Routine: " + current->name + current->args + - " inconsistency between intent attribute and documentation for parameter: " + argName); - handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " + - argName + " " + loc_doc,brief); + warn(yyextra->fileName,yyextra->lineNr, "%s", ("Routine: " + yyextra->current->name + yyextra->current->args + + " inconsistency between intent attribute and documentation for parameter: " + yyextra->argName).data()); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " + + yyextra->argName + " " + loc_doc,brief); } } // analogous to the [in] case; here no direction specified - else if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) + else if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower())) { - handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " + - argName + " " + loc_doc,brief); + handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " + + yyextra->argName + " " + loc_doc,brief); } - // reset current back to the part inside the routine - current = tmp_entry; + // reset yyextra->current back to the part inside the routine + yyextra->current = tmp_entry; } //---------------------------------------------------------------------------- /// Handle result description as defined after the declaration of the parameter -static void subrHandleCommentBlockResult(const QCString &doc,bool brief) +static void subrHandleCommentBlockResult(yyscan_t yyscanner,const QCString &doc,bool brief) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - std::shared_ptr<Entry> tmp_entry = current; - current = subrCurrent.back(); // temporarily switch to the entry of the subroutine / function + std::shared_ptr<Entry> tmp_entry = yyextra->current; + yyextra->current = yyextra->subrCurrent.back(); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation - current->inbodyDocs = ""; + yyextra->current->inbodyDocs = ""; // strip \\returns or @returns. We will add it later on again. if (!loc_doc.stripPrefix("\\returns") && @@ -2631,140 +2664,152 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief) ) (void)loc_doc; // Do nothing work has been done by stripPrefix; (void)loc_doc: to overcome 'empty controlled statement' warning loc_doc.stripWhiteSpace(); - if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower())) { - handleCommentBlock(QCString("\n\n@returns ") + loc_doc,brief); + handleCommentBlock(yyscanner,QCString("\n\n@returns ") + loc_doc,brief); } - // reset current back to the part inside the routine - current = tmp_entry; + // reset yyextra->current back to the part inside the routine + yyextra->current = tmp_entry; } //---------------------------------------------------------------------------- -#if 0 -static int level=0; -static void debugCompounds(Entry *rt) // print Entry structure (for debugging) +static void parseMain(yyscan_t yyscanner, const char *fileName,const char *fileBuf, + const std::shared_ptr<Entry> &rt, FortranFormat format) { - level++; - printf("%d) debugCompounds(%s) line %d\n",level, rt->name.data(), rt->bodyLine); - for (const auto &ce : rt->children()) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + char *tmpBuf = NULL; + initParser(yyscanner); + + yyextra->defaultProtection = Public; + yyextra->inputString = fileBuf; + yyextra->inputPosition = 0; + yyextra->inputStringPrepass = NULL; + yyextra->inputPositionPrepass = 0; + + //yyextra->anonCount = 0; // don't reset per file + yyextra->current_root = rt.get(); + yyextra->global_root = rt; + + yyextra->isFixedForm = recognizeFixedForm(fileBuf,format); + + if (yyextra->isFixedForm) { - debugCompounds(ce.get()); + msg("Prepassing fixed form of %s\n", fileName); + //printf("---strlen=%d\n", strlen(fileBuf)); + //clock_t start=clock(); + + //printf("Input fixed form string:\n%s\n", fileBuf); + //printf("===========================\n"); + yyextra->inputString = prepassFixedForm(fileBuf, NULL); + Debug::print(Debug::FortranFixed2Free,0,"======== Fixed to Free format =========\n---- Input fixed form string ------- \n%s\n", fileBuf); + Debug::print(Debug::FortranFixed2Free,0,"---- Resulting free form string ------- \n%s\n", yyextra->inputString); + //printf("Resulting free form string:\n%s\n", yyextra->inputString); + //printf("===========================\n"); + + //clock_t end=clock(); + //printf("CPU time used=%f\n", ((double) (end-start))/CLOCKS_PER_SEC); + } + else if (yyextra->inputString[strlen(fileBuf)-1] != '\n') + { + tmpBuf = (char *)malloc(strlen(fileBuf)+2); + strcpy(tmpBuf,fileBuf); + tmpBuf[strlen(fileBuf)]= '\n'; + tmpBuf[strlen(fileBuf)+1]= '\000'; + yyextra->inputString = tmpBuf; } -level--; -} -#endif + yyextra->lineNr= 1 ; + yyextra->fileName = fileName; + msg("Parsing file %s...\n",yyextra->fileName.data()); -static void parseMain(const char *fileName,const char *fileBuf, - const std::shared_ptr<Entry> &rt, FortranFormat format) -{ - char *tmpBuf = NULL; - initParser(); - - defaultProtection = Public; - inputString = fileBuf; - inputPosition = 0; - inputStringPrepass = NULL; - inputPositionPrepass = 0; - - //anonCount = 0; // don't reset per file - mtype = Method; - gstat = FALSE; - virt = Normal; - current_root = rt.get(); - global_root = rt; - inputFile.setName(fileName); - if (inputFile.open(IO_ReadOnly)) - { - isFixedForm = recognizeFixedForm(fileBuf,format); - - if (isFixedForm) - { - msg("Prepassing fixed form of %s\n", fileName); - //printf("---strlen=%d\n", strlen(fileBuf)); - //clock_t start=clock(); - - //printf("Input fixed form string:\n%s\n", fileBuf); - //printf("===========================\n"); - inputString = prepassFixedForm(fileBuf, NULL); - Debug::print(Debug::FortranFixed2Free,0,"======== Fixed to Free format =========\n---- Input fixed form string ------- \n%s\n", fileBuf); - Debug::print(Debug::FortranFixed2Free,0,"---- Resulting free form string ------- \n%s\n", inputString); - //printf("Resulting free form string:\n%s\n", inputString); - //printf("===========================\n"); - - //clock_t end=clock(); - //printf("CPU time used=%f\n", ((double) (end-start))/CLOCKS_PER_SEC); - } - else if (inputString[strlen(fileBuf)-1] != '\n') - { - tmpBuf = (char *)malloc(strlen(fileBuf)+2); - strcpy(tmpBuf,fileBuf); - tmpBuf[strlen(fileBuf)]= '\n'; - tmpBuf[strlen(fileBuf)+1]= '\000'; - inputString = tmpBuf; - } + yyextra->global_scope = rt.get(); + startScope(yyscanner,rt.get()); // implies yyextra->current_root = rt + initParser(yyscanner); + yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->lineNr); - yyLineNr= 1 ; - yyFileName = fileName; - msg("Parsing file %s...\n",yyFileName.data()); - - global_scope = rt.get(); - startScope(rt.get()); // implies current_root = rt - initParser(); - Doxygen::docGroup.enterFile(yyFileName,yyLineNr); - - // add entry for the file - current = std::make_shared<Entry>(); - current->lang = SrcLangExt_Fortran; - current->name = yyFileName; - current->section = Entry::SOURCE_SEC; - file_root = current; - current_root->moveToSubEntryAndRefresh(current); - current->lang = SrcLangExt_Fortran; - - fortranscannerYYrestart( fortranscannerYYin ); - { - BEGIN( Start ); - } + // add entry for the file + yyextra->current = std::make_shared<Entry>(); + yyextra->current->lang = SrcLangExt_Fortran; + yyextra->current->name = yyextra->fileName; + yyextra->current->section = Entry::SOURCE_SEC; + yyextra->file_root = yyextra->current; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + yyextra->current->lang = SrcLangExt_Fortran; - fortranscannerYYlex(); - Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); + fortranscannerYYrestart( 0, yyscanner ); + { + BEGIN( Start ); + } - if (global_scope && global_scope != INVALID_ENTRY) endScope(current_root, TRUE); // TRUE - global root + fortranscannerYYlex(yyscanner); + yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->lineNr); - //debugCompounds(rt); //debug + if (yyextra->global_scope && yyextra->global_scope != INVALID_ENTRY) + { + endScope(yyscanner,yyextra->current_root, TRUE); // TRUE - global root + } - rt->program.resize(0); - //delete current; current=0; - moduleProcedures.clear(); - if (tmpBuf) { - free((char*)tmpBuf); - inputString=NULL; - } - if (isFixedForm) { - free((char*)inputString); - inputString=NULL; - } + //debugCompounds(rt); //debug - inputFile.close(); + rt->program.resize(0); + //delete yyextra->current; yyextra->current=0; + yyextra->moduleProcedures.clear(); + if (tmpBuf) + { + free((char*)tmpBuf); + yyextra->inputString=NULL; } + if (yyextra->isFixedForm) + { + free((char*)yyextra->inputString); + yyextra->inputString=NULL; + } + } //---------------------------------------------------------------------------- +struct FortranOutlineParser::Private +{ + yyscan_t yyscanner; + fortranscannerYY_state extra; + FortranFormat format; + Private(FortranFormat fmt) : format(fmt) + { + fortranscannerYYlex_init_extra(&extra,&yyscanner); +#ifdef FLEX_DEBUG + fortranscannerYYset_debug(1,yyscanner); +#endif + } + ~Private() + { + fortranscannerYYlex_destroy(yyscanner); + } +}; + +FortranOutlineParser::FortranOutlineParser(FortranFormat format) + : p(std::make_unique<Private>(format)) +{ +} + +FortranOutlineParser::~FortranOutlineParser() +{ +} + void FortranOutlineParser::parseInput(const char *fileName, const char *fileBuf, const std::shared_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { - g_thisParser = this; + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->thisParser = this; printlex(yy_flex_debug, TRUE, __FILE__, fileName); - ::parseMain(fileName,fileBuf,root,m_format); + ::parseMain(p->yyscanner,fileName,fileBuf,root,p->format); printlex(yy_flex_debug, FALSE, __FILE__, fileName); } @@ -2773,35 +2818,38 @@ bool FortranOutlineParser::needsPreprocessing(const QCString &extension) const { return extension!=extension.lower(); // use preprocessor only for upper case extensions } + void FortranOutlineParser::parsePrototype(const char *text) { + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; QCString buffer = QCString(text); - pushBuffer(buffer); - parsingPrototype = TRUE; + pushBuffer(p->yyscanner,buffer); + yyextra->parsingPrototype = TRUE; BEGIN(Prototype); - fortranscannerYYlex(); - parsingPrototype = FALSE; - popBuffer(); + fortranscannerYYlex(p->yyscanner); + yyextra->parsingPrototype = FALSE; + popBuffer(p->yyscanner); } //---------------------------------------------------------------------------- -static void scanner_abort() +static void scanner_abort(yyscan_t yyscanner) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; fprintf(stderr,"********************************************************************\n"); - fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyFileName.data(),yyLineNr,YY_START,stateToString(YY_START)); + fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyextra->fileName.data(),yyextra->lineNr,YY_START,stateToString(YY_START)); fprintf(stderr,"********************************************************************\n"); bool start=FALSE; - for (const auto &ce : global_root->children()) + for (const auto &ce : yyextra->global_root->children()) { - if (ce == file_root) start=TRUE; + if (ce == yyextra->file_root) start=TRUE; if (start) ce->reset(); } // dummy call to avoid compiler warning - (void)yy_top_state(); + (void)yy_top_state(yyscanner); return; //exit(-1); diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 149f43c..cb50af1 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -43,6 +43,32 @@ static int folderId=1; +const char *JAVASCRIPT_LICENSE_TEXT = R"LIC(/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +)LIC"; + struct FTVNode { FTVNode(bool dir,const char *r,const char *f,const char *a, @@ -233,7 +259,7 @@ static QCString node2URL(const FTVNode *n,bool overruleFile=FALSE,bool srcLink=F url = fd->getOutputFileBase(); } } - url+=Doxygen::htmlFileExtension; + url = addHtmlExtensionIfMissing(url); if (!n->anchor.isEmpty()) url+="#"+n->anchor; } return url; @@ -451,6 +477,10 @@ void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,in char icon=compoundIcon(dynamic_cast<const ClassDef*>(n->def)); t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>"; } + else if (n->def && n->def->definitionType()==Definition::TypeDir) + { + t << "<span class=\"iconfclosed\"></span>"; + } else { t << "<span class=\"icondoc\"></span>"; @@ -689,7 +719,7 @@ static void generateJSNavTree(const QList<FTVNode> &nodeList) tsidx << "{" << endl; QListIterator<NavIndexEntry> li(navIndex); NavIndexEntry *e; - bool first=TRUE; + first=TRUE; for (li.toFirst();(e=li.current());) // for each entry { if (elemCount==0) @@ -781,8 +811,7 @@ void FTVHelp::generateTreeViewInline(FTextStream &t) t << "<div class=\"levels\">["; t << theTranslator->trDetailLevel(); t << " "; - int i; - for (i=1;i<=depth;i++) + for (int i=1;i<=depth;i++) { t << "<span onclick=\"javascript:toggleLevel(" << i << ");\">" << i << "</span>"; } @@ -794,9 +823,7 @@ void FTVHelp::generateTreeViewInline(FTextStream &t) for (int i=1;i<=depth;i++) { int num=0; - QListIterator<FTVNode> li(m_indentNodes[0]); - FTVNode *n; - for (;(n=li.current());++li) + for (li.toFirst();(n=li.current());++li) { num+=n->numNodesAtLevel(0,i); } diff --git a/src/ftvhelp.h b/src/ftvhelp.h index 9bcaa5b..42fe707 100644 --- a/src/ftvhelp.h +++ b/src/ftvhelp.h @@ -3,8 +3,8 @@ * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -72,22 +72,7 @@ class FTVHelp : public IndexIntf bool m_topLevelIndex; }; -#define JAVASCRIPT_LICENSE_TEXT \ - "/*\n@licstart The following is the entire license notice for the\n" \ - "JavaScript code in this file.\n\nCopyright (C) 1997-2019 by Dimitri van Heesch\n\n" \ - "This program is free software; you can redistribute it and/or modify\n" \ - "it under the terms of version 2 of the GNU General Public License as published by\n" \ - "the Free Software Foundation\n\n" \ - "This program is distributed in the hope that it will be useful,\n" \ - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ - "GNU General Public License for more details.\n\n" \ - "You should have received a copy of the GNU General Public License along\n" \ - "with this program; if not, write to the Free Software Foundation, Inc.,\n" \ - "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n" \ - "@licend The above is the entire license notice\n" \ - "for the JavaScript code in this file\n" \ - "*/\n" +extern const char *JAVASCRIPT_LICENSE_TEXT; #endif /* FTVHELP_H */ diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 0d6d43f..5af1525 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -54,10 +54,10 @@ class GroupDefImpl : public DefinitionImpl, public GroupDef virtual DefType definitionType() const { return TypeGroup; } virtual QCString getOutputFileBase() const; virtual QCString anchor() const { return QCString(); } - virtual QCString displayName(bool=TRUE) const { return hasGroupTitle() ? title : DefinitionImpl::name(); } - virtual const char *groupTitle() const { return title; } + virtual QCString displayName(bool=TRUE) const { return hasGroupTitle() ? m_title : DefinitionImpl::name(); } + virtual const char *groupTitle() const { return m_title; } virtual void setGroupTitle( const char *newtitle ); - virtual bool hasGroupTitle( ) const { return titleSet; } + virtual bool hasGroupTitle( ) const { return m_titleSet; } virtual void addFile(const FileDef *def); virtual bool addClass(const ClassDef *def); virtual bool addNamespace(const NamespaceDef *def); @@ -87,22 +87,22 @@ class GroupDefImpl : public DefinitionImpl, public GroupDef virtual void sortMemberLists(); virtual bool subGrouping() const { return m_subGrouping; } - virtual void setGroupScope(Definition *d) { groupScope = d; } - virtual Definition *getGroupScope() const { return groupScope; } + virtual void setGroupScope(Definition *d) { m_groupScope = d; } + virtual Definition *getGroupScope() const { return m_groupScope; } virtual MemberList *getMemberList(MemberListType lt) const; virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; } /* user defined member groups */ - virtual MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; } - - virtual FileList * getFiles() const { return fileList; } - virtual ClassSDict * getClasses() const { return classSDict; } - virtual NamespaceSDict * getNamespaces() const { return namespaceSDict; } - virtual GroupList * getSubGroups() const { return groupList; } - virtual PageSDict * getPages() const { return pageDict; } - virtual DirList * getDirs() const { return dirList; } - virtual PageSDict * getExamples() const { return exampleDict; } + virtual MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; } + + virtual FileList * getFiles() const { return m_fileList; } + virtual ClassSDict * getClasses() const { return m_classSDict; } + virtual NamespaceSDict * getNamespaces() const { return m_namespaceSDict; } + virtual GroupList * getSubGroups() const { return m_groupList; } + virtual PageSDict * getPages() const { return m_pageDict; } + virtual DirList * getDirs() const { return m_dirList; } + virtual PageSDict * getExamples() const { return m_exampleDict; } virtual bool hasDetailedDescription() const; virtual void sortSubGroups(); @@ -132,25 +132,22 @@ class GroupDefImpl : public DefinitionImpl, public GroupDef void writeSummaryLinks(OutputList &ol) const; void updateLanguage(const Definition *); - QCString title; // title of the group - bool titleSet; // true if title is not the same as the name - QCString fileName; // base name of the generated file - FileList *fileList; // list of files in the group - ClassSDict *classSDict; // list of classes in the group - NamespaceSDict *namespaceSDict; // list of namespaces in the group - GroupList *groupList; // list of sub groups. - PageSDict *pageDict; // list of pages in the group - PageSDict *exampleDict; // list of examples in the group - DirList *dirList; // list of directories in the group - - MemberList *allMemberList; - MemberNameInfoSDict *allMemberNameInfoSDict; - - Definition *groupScope; - - QList<MemberList> m_memberLists; - MemberGroupSDict *memberGroupSDict; - bool m_subGrouping; + QCString m_title; // title of the group + bool m_titleSet; // true if title is not the same as the name + QCString m_fileName; // base name of the generated file + FileList * m_fileList; // list of files in the group + ClassSDict * m_classSDict; // list of classes in the group + NamespaceSDict * m_namespaceSDict; // list of namespaces in the group + GroupList * m_groupList; // list of sub groups. + PageSDict * m_pageDict; // list of pages in the group + PageSDict * m_exampleDict; // list of examples in the group + DirList * m_dirList; // list of directories in the group + MemberList * m_allMemberList; + MemberNameInfoSDict *m_allMemberNameInfoSDict; + Definition * m_groupScope; + QList<MemberList> m_memberLists; + MemberGroupSDict * m_memberGroupSDict; + bool m_subGrouping; }; @@ -166,67 +163,67 @@ GroupDef *createGroupDef(const char *fileName,int line,const char *name, GroupDefImpl::GroupDefImpl(const char *df,int dl,const char *na,const char *t, const char *refFileName) : DefinitionImpl(df,dl,1,na) { - fileList = new FileList; - classSDict = new ClassSDict(17); - groupList = new GroupList; - namespaceSDict = new NamespaceSDict(17); - pageDict = new PageSDict(17); - exampleDict = new PageSDict(17); - dirList = new DirList; - allMemberNameInfoSDict = new MemberNameInfoSDict(17); - allMemberNameInfoSDict->setAutoDelete(TRUE); + m_fileList = new FileList; + m_classSDict = new ClassSDict(17); + m_groupList = new GroupList; + m_namespaceSDict = new NamespaceSDict(17); + m_pageDict = new PageSDict(17); + m_exampleDict = new PageSDict(17); + m_dirList = new DirList; + m_allMemberNameInfoSDict = new MemberNameInfoSDict(17); + m_allMemberNameInfoSDict->setAutoDelete(TRUE); if (refFileName) { - fileName=stripExtension(refFileName); + m_fileName=stripExtension(refFileName); } else { - fileName = convertNameToFile(QCString("group_")+na); + m_fileName = convertNameToFile(QCString("group_")+na); } setGroupTitle( t ); - memberGroupSDict = new MemberGroupSDict; - memberGroupSDict->setAutoDelete(TRUE); + m_memberGroupSDict = new MemberGroupSDict; + m_memberGroupSDict->setAutoDelete(TRUE); - allMemberList = new MemberList(MemberListType_allMembersList); + m_allMemberList = new MemberList(MemberListType_allMembersList); //visited = 0; - groupScope = 0; + m_groupScope = 0; m_subGrouping=Config_getBool(SUBGROUPING); } GroupDefImpl::~GroupDefImpl() { - delete fileList; - delete classSDict; - delete groupList; - delete namespaceSDict; - delete pageDict; - delete exampleDict; - delete allMemberList; - delete allMemberNameInfoSDict; - delete memberGroupSDict; - delete dirList; + delete m_fileList; + delete m_classSDict; + delete m_groupList; + delete m_namespaceSDict; + delete m_pageDict; + delete m_exampleDict; + delete m_allMemberList; + delete m_allMemberNameInfoSDict; + delete m_memberGroupSDict; + delete m_dirList; } void GroupDefImpl::setGroupTitle( const char *t ) { - if ( t && qstrlen(t) ) + if ( t && *t ) { - title = t; - titleSet = TRUE; + m_title = t; + m_titleSet = TRUE; } else { - title = name(); - title.at(0)=toupper(title.at(0)); - titleSet = FALSE; + m_title = name(); + m_title[0]=(char)toupper(m_title[0]); + m_titleSet = FALSE; } } void GroupDefImpl::distributeMemberGroupDocumentation() { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -237,7 +234,7 @@ void GroupDefImpl::distributeMemberGroupDocumentation() void GroupDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,docFile()); - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -261,9 +258,9 @@ void GroupDefImpl::addFile(const FileDef *def) if (def->isHidden()) return; updateLanguage(def); if (sortBriefDocs) - fileList->inSort(def); + m_fileList->inSort(def); else - fileList->append(def); + m_fileList->append(def); } bool GroupDefImpl::addClass(const ClassDef *cd) @@ -272,12 +269,12 @@ bool GroupDefImpl::addClass(const ClassDef *cd) if (cd->isHidden()) return FALSE; updateLanguage(cd); QCString qn = cd->name(); - if (classSDict->find(qn)==0) + if (m_classSDict->find(qn)==0) { //printf("--- addClass %s sort=%d\n",qn.data(),sortBriefDocs); if (sortBriefDocs) { - classSDict->inSort(qn,cd); + m_classSDict->inSort(qn,cd); } else { @@ -290,23 +287,23 @@ bool GroupDefImpl::addClass(const ClassDef *cd) // add nested classes (e.g. A::B, A::C) after their parent (A) in // order of insertion QCString scope = qn.left(i); - int j=classSDict->findAt(scope); + int j=m_classSDict->findAt(scope); if (j!=-1) { - while (j<(int)classSDict->count() && - classSDict->at(j)->qualifiedName().left(i)==scope) + while (j<(int)m_classSDict->count() && + m_classSDict->at(j)->qualifiedName().left(i)==scope) { //printf("skipping over %s\n",classSDict->at(j)->qualifiedName().data()); j++; } //printf("Found scope at index %d\n",j); - classSDict->insertAt(j,qn,cd); + m_classSDict->insertAt(j,qn,cd); found=TRUE; } } if (!found) // no insertion point found -> just append { - classSDict->append(qn,cd); + m_classSDict->append(qn,cd); } } return TRUE; @@ -319,12 +316,12 @@ bool GroupDefImpl::addNamespace(const NamespaceDef *def) static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); if (def->isHidden()) return FALSE; updateLanguage(def); - if (namespaceSDict->find(def->name())==0) + if (m_namespaceSDict->find(def->name())==0) { if (sortBriefDocs) - namespaceSDict->inSort(def->name(),def); + m_namespaceSDict->inSort(def->name(),def); else - namespaceSDict->append(def->name(),def); + m_namespaceSDict->append(def->name(),def); return TRUE; } return FALSE; @@ -334,23 +331,23 @@ void GroupDefImpl::addDir(const DirDef *def) { if (def->isHidden()) return; if (Config_getBool(SORT_BRIEF_DOCS)) - dirList->inSort(def); + m_dirList->inSort(def); else - dirList->append(def); + m_dirList->append(def); } void GroupDefImpl::addPage(PageDef *def) { if (def->isHidden()) return; //printf("Making page %s part of a group\n",def->name.data()); - pageDict->append(def->name(),def); + m_pageDict->append(def->name(),def); def->makePartOfGroup(this); } void GroupDefImpl::addExample(const PageDef *def) { if (def->isHidden()) return; - exampleDict->append(def->name(),def); + m_exampleDict->append(def->name(),def); } @@ -362,12 +359,12 @@ void GroupDefImpl::addMembersToMemberGroup() { if (ml->listType()&MemberListType_declarationLists) { - ::addMembersToMemberGroup(ml,&memberGroupSDict,this); + ::addMembersToMemberGroup(ml,&m_memberGroupSDict,this); } } //printf("GroupDefImpl::addMembersToMemberGroup() memberGroupList=%d\n",memberGroupList->count()); - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -382,7 +379,7 @@ bool GroupDefImpl::insertMember(MemberDef *md,bool docOnly) updateLanguage(md); //printf("GroupDef(%s)::insertMember(%s)\n", title.data(), md->name().data()); MemberNameInfo *mni=0; - if ((mni=(*allMemberNameInfoSDict)[md->name()])) + if ((mni=(*m_allMemberNameInfoSDict)[md->name()])) { // member with this name already found MemberNameInfoIterator srcMnii(*mni); const MemberInfo *srcMi; @@ -427,10 +424,10 @@ bool GroupDefImpl::insertMember(MemberDef *md,bool docOnly) { mni = new MemberNameInfo(md->name()); mni->append(new MemberInfo(md,md->protection(),md->virtualness(),FALSE)); - allMemberNameInfoSDict->append(mni->memberName(),mni); + m_allMemberNameInfoSDict->append(mni->memberName(),mni); } //printf("Added member!\n"); - allMemberList->append(md); + m_allMemberList->append(md); switch(md->memberType()) { case MemberType_Variable: @@ -542,7 +539,7 @@ bool GroupDefImpl::insertMember(MemberDef *md,bool docOnly) void GroupDefImpl::removeMember(MemberDef *md) { // fprintf(stderr, "GroupDef(%s)::removeMember( %s )\n", title.data(), md->name().data()); - MemberNameInfo *mni = allMemberNameInfoSDict->find(md->name()); + MemberNameInfo *mni = m_allMemberNameInfoSDict->find(md->name()); if (mni) { MemberNameInfoIterator mnii(*mni); @@ -557,7 +554,7 @@ void GroupDefImpl::removeMember(MemberDef *md) } if( mni->isEmpty() ) { - allMemberNameInfoSDict->remove(md->name()); + m_allMemberNameInfoSDict->remove(md->name()); } removeMemberFromList(MemberListType_allMembersList,md); @@ -632,9 +629,9 @@ bool GroupDefImpl::findGroup(const GroupDef *def) const { return TRUE; } - else if (groupList) + else if (m_groupList) { - GroupListIterator it(*groupList); + GroupListIterator it(*m_groupList); GroupDef *gd; for (;(gd=it.current());++it) { @@ -653,7 +650,7 @@ void GroupDefImpl::addGroup(const GroupDef *def) //if (Config_getBool(SORT_MEMBER_DOCS)) // groupList->inSort(def); //else - groupList->append(def); + m_groupList->append(def); } bool GroupDefImpl::isASubGroup() const @@ -671,9 +668,9 @@ void GroupDefImpl::countMembers() ml->countDecMembers(); ml->countDocMembers(); } - if (memberGroupSDict) + if (m_memberGroupSDict) { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -685,27 +682,27 @@ void GroupDefImpl::countMembers() int GroupDefImpl::numDocMembers() const { - return fileList->count()+ - classSDict->count()+ - namespaceSDict->count()+ - groupList->count()+ - allMemberList->count()+ - pageDict->count()+ - exampleDict->count(); + return m_fileList->count()+ + m_classSDict->count()+ + m_namespaceSDict->count()+ + m_groupList->count()+ + m_allMemberList->count()+ + m_pageDict->count()+ + m_exampleDict->count(); } /*! Compute the HTML anchor names for all members in the group */ void GroupDefImpl::computeAnchors() { //printf("GroupDefImpl::computeAnchors()\n"); - setAnchors(allMemberList); + setAnchors(m_allMemberList); } void GroupDefImpl::writeTagFile(FTextStream &tagFile) { tagFile << " <compound kind=\"group\">" << endl; tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; - tagFile << " <title>" << convertToXML(title) << "</title>" << endl; + tagFile << " <title>" << convertToXML(m_title) << "</title>" << endl; tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl; QListIterator<LayoutDocEntry> eli( LayoutDocManager::instance().docEntries(LayoutDocManager::Group)); @@ -716,9 +713,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) { case LayoutDocEntry::GroupClasses: { - if (classSDict) + if (m_classSDict) { - SDict<ClassDef>::Iterator ci(*classSDict); + SDict<ClassDef>::Iterator ci(*m_classSDict); ClassDef *cd; for (ci.toFirst();(cd=ci.current());++ci) { @@ -733,9 +730,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) break; case LayoutDocEntry::GroupNamespaces: { - if (namespaceSDict) + if (m_namespaceSDict) { - SDict<NamespaceDef>::Iterator ni(*namespaceSDict); + SDict<NamespaceDef>::Iterator ni(*m_namespaceSDict); NamespaceDef *nd; for (ni.toFirst();(nd=ni.current());++ni) { @@ -750,9 +747,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) break; case LayoutDocEntry::GroupFiles: { - if (fileList) + if (m_fileList) { - QListIterator<FileDef> it(*fileList); + QListIterator<FileDef> it(*m_fileList); FileDef *fd; for (;(fd=it.current());++it) { @@ -766,9 +763,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) break; case LayoutDocEntry::GroupPageDocs: { - if (pageDict) + if (m_pageDict) { - PageSDict::Iterator pdi(*pageDict); + PageSDict::Iterator pdi(*m_pageDict); PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { @@ -783,9 +780,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) break; case LayoutDocEntry::GroupDirs: { - if (dirList) + if (m_dirList) { - QListIterator<DirDef> it(*dirList); + QListIterator<DirDef> it(*m_dirList); DirDef *dd; for (;(dd=it.current());++it) { @@ -799,9 +796,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) break; case LayoutDocEntry::GroupNestedGroups: { - if (groupList) + if (m_groupList) { - QListIterator<GroupDef> it(*groupList); + QListIterator<GroupDef> it(*m_groupList); GroupDef *gd; for (;(gd=it.current());++it) { @@ -825,9 +822,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile) break; case LayoutDocEntry::MemberGroups: { - if (memberGroupSDict) + if (m_memberGroupSDict) { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -851,7 +848,7 @@ void GroupDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title ) { ol.pushGeneratorState(); - if (pageDict->count()!=numDocMembers()) // not only pages -> classical layout + if (m_pageDict->count()!=(uint)numDocMembers()) // not only pages -> classical layout { ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); @@ -953,7 +950,7 @@ void GroupDefImpl::writeGroupGraph(OutputList &ol) ol.disable(OutputGenerator::Man); //ol.startParagraph(); ol.startGroupCollaboration(); - ol.parseText(theTranslator->trCollaborationDiagram(title)); + ol.parseText(theTranslator->trCollaborationDiagram(m_title)); ol.endGroupCollaboration(graph); //ol.endParagraph(); ol.popGeneratorState(); @@ -964,13 +961,13 @@ void GroupDefImpl::writeGroupGraph(OutputList &ol) void GroupDefImpl::writeFiles(OutputList &ol,const QCString &title) { // write list of files - if (fileList->count()>0) + if (m_fileList->count()>0) { ol.startMemberHeader("files"); ol.parseText(title); ol.endMemberHeader(); ol.startMemberList(); - QListIterator<FileDef> it(*fileList); + QListIterator<FileDef> it(*m_fileList); FileDef *fd; for (;(fd=it.current());++it) { @@ -996,16 +993,16 @@ void GroupDefImpl::writeFiles(OutputList &ol,const QCString &title) void GroupDefImpl::writeNamespaces(OutputList &ol,const QCString &title) { // write list of namespaces - namespaceSDict->writeDeclaration(ol,title); + m_namespaceSDict->writeDeclaration(ol,title); } void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title) { // write list of groups int count=0; - if (groupList->count()>0) + if (m_groupList->count()>0) { - QListIterator<GroupDef> it(*groupList); + QListIterator<GroupDef> it(*m_groupList); GroupDef *gd; for (;(gd=it.current());++it) { @@ -1020,9 +1017,9 @@ void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title) ol.startMemberList(); if (Config_getBool(SORT_GROUP_NAMES)) { - groupList->sort(); + m_groupList->sort(); } - QListIterator<GroupDef> it(*groupList); + QListIterator<GroupDef> it(*m_groupList); GroupDef *gd; for (;(gd=it.current());++it) { @@ -1052,13 +1049,13 @@ void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title) void GroupDefImpl::writeDirs(OutputList &ol,const QCString &title) { // write list of directories - if (dirList->count()>0) + if (m_dirList->count()>0) { ol.startMemberHeader("dirs"); ol.parseText(title); ol.endMemberHeader(); ol.startMemberList(); - QListIterator<DirDef> it(*dirList); + QListIterator<DirDef> it(*m_dirList); DirDef *dd; for (;(dd=it.current());++it) { @@ -1085,29 +1082,29 @@ void GroupDefImpl::writeDirs(OutputList &ol,const QCString &title) void GroupDefImpl::writeClasses(OutputList &ol,const QCString &title) { // write list of classes - classSDict->writeDeclaration(ol,0,title,FALSE); + m_classSDict->writeDeclaration(ol,0,title,FALSE); } void GroupDefImpl::writeInlineClasses(OutputList &ol) { - classSDict->writeDocumentation(ol); + m_classSDict->writeDocumentation(ol); } void GroupDefImpl::writePageDocumentation(OutputList &ol) { PageDef *pd=0; - PageSDict::Iterator pdi(*pageDict); + PageSDict::Iterator pdi(*m_pageDict); for (pdi.toFirst();(pd=pdi.current());++pdi) { if (!pd->isReference()) { - SectionInfo *si=0; + const SectionInfo *si=0; if (pd->hasTitle() && !pd->name().isEmpty() && - (si=Doxygen::sectionDict->find(pd->name()))!=0) + (si=SectionManager::instance().find(pd->name()))!=0) { - ol.startSection(si->label,si->title,SectionInfo::Subsection); - ol.docify(si->title); - ol.endSection(si->label,SectionInfo::Subsection); + ol.startSection(si->label(),si->title(),SectionType::Subsection); + ol.docify(si->title()); + ol.endSection(si->label(),SectionType::Subsection); } ol.startTextBlock(); ol.generateDoc(pd->docFile(),pd->docLine(),pd,0,pd->documentation()+pd->inbodyDocumentation(),TRUE,FALSE,0,TRUE,FALSE); @@ -1119,11 +1116,11 @@ void GroupDefImpl::writePageDocumentation(OutputList &ol) void GroupDefImpl::writeMemberGroups(OutputList &ol) { /* write user defined member groups */ - if (memberGroupSDict) + if (m_memberGroupSDict) { - memberGroupSDict->sort(); + m_memberGroupSDict->sort(); /* write user defined member groups */ - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -1186,11 +1183,11 @@ void GroupDefImpl::writeSummaryLinks(OutputList &ol) const SrcLangExt lang = getLanguage(); for (eli.toFirst();(lde=eli.current());++eli) { - if ((lde->kind()==LayoutDocEntry::GroupClasses && classSDict->declVisible()) || - (lde->kind()==LayoutDocEntry::GroupNamespaces && namespaceSDict->declVisible()) || - (lde->kind()==LayoutDocEntry::GroupFiles && fileList->count()>0) || - (lde->kind()==LayoutDocEntry::GroupNestedGroups && groupList->count()>0) || - (lde->kind()==LayoutDocEntry::GroupDirs && dirList->count()>0) + if ((lde->kind()==LayoutDocEntry::GroupClasses && m_classSDict->declVisible()) || + (lde->kind()==LayoutDocEntry::GroupNamespaces && m_namespaceSDict->declVisible()) || + (lde->kind()==LayoutDocEntry::GroupFiles && m_fileList->count()>0) || + (lde->kind()==LayoutDocEntry::GroupNestedGroups && m_groupList->count()>0) || + (lde->kind()==LayoutDocEntry::GroupDirs && m_dirList->count()>0) ) { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; @@ -1224,19 +1221,19 @@ void GroupDefImpl::writeDocumentation(OutputList &ol) { //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); - startFile(ol,getOutputFileBase(),name(),title,HLI_Modules); + startFile(ol,getOutputFileBase(),name(),m_title,HLI_Modules); ol.startHeaderSection(); writeSummaryLinks(ol); ol.startTitleHead(getOutputFileBase()); ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); - ol.parseText(title); + ol.parseText(m_title); ol.popGeneratorState(); addGroupListToTitle(ol,this); ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); - ol.endTitleHead(getOutputFileBase(),title); + ol.endTitleHead(getOutputFileBase(),m_title); ol.popGeneratorState(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); @@ -1250,14 +1247,14 @@ void GroupDefImpl::writeDocumentation(OutputList &ol) Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE); static QRegExp we("[a-zA-Z_][-a-zA-Z_0-9]*"); int i=0,p=0,l=0; - while ((i=we.match(title,p,&l))!=-1) // foreach word in the title + while ((i=we.match(m_title,p,&l))!=-1) // foreach word in the title { - Doxygen::searchIndex->addWord(title.mid(i,l),TRUE); + Doxygen::searchIndex->addWord(m_title.mid(i,l),TRUE); p=i+l; } } - Doxygen::indexList->addIndexItem(this,0,0,title); + Doxygen::indexList->addIndexItem(this,0,0,m_title); //---------------------------------------- start flexible part ------------------------------- @@ -1391,7 +1388,7 @@ void GroupDefImpl::writeDocumentation(OutputList &ol) if (Config_getBool(SEPARATE_MEMBER_PAGES)) { - allMemberList->sort(); + m_allMemberList->sort(); writeMemberPages(ol); } @@ -1422,7 +1419,7 @@ void GroupDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *current ol.writeString(" <div class=\"navtab\">\n"); ol.writeString(" <table>\n"); - MemberListIterator mli(*allMemberList); + MemberListIterator mli(*m_allMemberList); MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { @@ -1653,13 +1650,13 @@ void addExampleToGroups(const Entry *root,PageDef *eg) QCString GroupDefImpl::getOutputFileBase() const { - return fileName; + return m_fileName; } void GroupDefImpl::addListReferences() { { - const std::vector<ListItemInfo> &xrefItems = xrefListItems(); + const std::vector<RefItem*> &xrefItems = xrefListItems(); addRefItem(xrefItems, getOutputFileBase(), theTranslator->trGroup(TRUE,TRUE), @@ -1668,7 +1665,7 @@ void GroupDefImpl::addListReferences() 0 ); } - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -1763,13 +1760,13 @@ void GroupDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,con void GroupDefImpl::removeMemberFromList(MemberListType lt,MemberDef *md) { - MemberList *ml = getMemberList(lt); - if (ml) ml->remove(md); + MemberList *ml = getMemberList(lt); + if (ml) ml->remove(md); } void GroupDefImpl::sortSubGroups() { - groupList->sort(); + m_groupList->sort(); } bool GroupDefImpl::isLinkableInProject() const diff --git a/src/growbuf.h b/src/growbuf.h index bf6d74e..cd6a67b 100644 --- a/src/growbuf.h +++ b/src/growbuf.h @@ -10,49 +10,49 @@ class GrowBuf { public: - GrowBuf() : str(0), pos(0), len(0) {} - GrowBuf(int initialSize) : pos(0), len(initialSize) { str=(char*)malloc(len); } - ~GrowBuf() { free(str); str=0; pos=0; len=0; } - void clear() { pos=0; } - void addChar(char c) { if (pos>=len) { len+=GROW_AMOUNT; str = (char*)realloc(str,len); } - str[pos++]=c; + GrowBuf() : m_str(0), m_pos(0), m_len(0) {} + GrowBuf(uint initialSize) : m_pos(0), m_len(initialSize) { m_str=(char*)malloc(m_len); } + ~GrowBuf() { free(m_str); } + void clear() { m_pos=0; } + void addChar(char c) { if (m_pos>=m_len) { m_len+=GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + m_str[m_pos++]=c; } void addStr(const QCString &s) { if (!s.isEmpty()) { - int l=s.length(); - if (pos+l>=len) { len+=l+GROW_AMOUNT; str = (char*)realloc(str,len); } - strcpy(&str[pos],s.data()); - pos+=l; + uint l=s.length(); + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + strcpy(&m_str[m_pos],s.data()); + m_pos+=l; } } void addStr(const char *s) { if (s) { - int l=strlen(s); - if (pos+l>=len) { len+=l+GROW_AMOUNT; str = (char*)realloc(str,len); } - strcpy(&str[pos],s); - pos+=l; + uint l=(uint)strlen(s); + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + strcpy(&m_str[m_pos],s); + m_pos+=l; } } - void addStr(const char *s,int n) { + void addStr(const char *s,uint n) { if (s) { - int l=strlen(s); + uint l=(uint)strlen(s); if (n<l) l=n; - if (pos+l>=len) { len+=l+GROW_AMOUNT; str = (char*)realloc(str,len); } - strncpy(&str[pos],s,n); - pos+=l; + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + strncpy(&m_str[m_pos],s,n); + m_pos+=l; } } - const char *get() { return str; } - int getPos() const { return pos; } - void setPos(const int newPos) { pos = newPos; } - char at(int i) const { return str[i]; } + const char *get() { return m_str; } + uint getPos() const { return m_pos; } + void setPos(uint newPos) { m_pos = newPos; } + char at(uint i) const { return m_str[i]; } private: - char *str; - int pos; - int len; + char *m_str; + uint m_pos; + uint m_len; }; #endif diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 424fead..ea2dffb 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -36,6 +36,7 @@ #include "htmlentity.h" #include "emoji.h" #include "plantuml.h" +#include "formula.h" static const int NUM_HTML_LIST_TYPES = 4; static const char types[][NUM_HTML_LIST_TYPES] = {"1", "a", "i", "A"}; @@ -180,6 +181,10 @@ static bool isDocIncludeVisible(DocInclude *s) { case DocInclude::DontInclude: case DocInclude::LatexInclude: + case DocInclude::RtfInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: return FALSE; default: return TRUE; @@ -715,6 +720,10 @@ void HtmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::DontInclude: case DocInclude::LatexInclude: + case DocInclude::RtfInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: case DocInclude::DontIncWithLines: break; case DocInclude::HtmlInclude: @@ -880,10 +889,25 @@ void HtmlDocVisitor::visit(DocFormula *f) m_t << "\" alt=\""; filterQuotedCdataAttr(f->text()); m_t << "\""; - // TODO: cache image dimensions on formula generation and give height/width - // for faster preloading and better rendering of the page - m_t << " src=\"" << f->relPath() << f->name() << ".png\"/>"; - + m_t << " src=\"" << f->relPath() << f->name(); + if (Config_getEnum(HTML_FORMULA_FORMAT)=="svg") + { + m_t << ".svg"; + } + else + { + m_t << ".png"; + } + FormulaManager::DisplaySize size = FormulaManager::instance().displaySize(f->id()); + if (size.width!=-1) + { + m_t << "\" width=\"" << size.width; + } + if (size.height!=-1) + { + m_t << "\" height=\"" << size.height; + } + m_t << "\"/>"; } if (bDisplay) { @@ -1726,7 +1750,7 @@ void HtmlDocVisitor::visitPre(DocImage *img) { src = correctURL(url,img->relPath()); } - if (typeSVG) + if (typeSVG && !inlineImage) { m_t << "<object type=\"image/svg+xml\" data=\"" << convertToHtml(src) << "\"" << sizeAttribs << attrs; @@ -1765,14 +1789,7 @@ void HtmlDocVisitor::visitPre(DocImage *img) } else if (inlineImage) { - if (typeSVG) - { - m_t << ">" << alt << "</object>"; - } - else - { - m_t << "/>"; - } + m_t << "/>"; } } else // other format -> skip @@ -1792,16 +1809,7 @@ void HtmlDocVisitor::visitPost(DocImage *img) { if (inlineImage) { - if (img->isSVG()) - { - QCString alt; - QCString attrs = htmlAttribsToString(img->attribs(),&alt); - m_t << "\">" << alt << "</object>"; - } - else - { - m_t << "\"/>"; - } + m_t << "\"/>"; } else // end <div class="caption"> { @@ -2218,6 +2226,11 @@ void HtmlDocVisitor::filter(const char *str) case '<': m_t << "<"; break; case '>': m_t << ">"; break; case '&': m_t << "&"; break; + case '\\': if ((*p == '(') || (*p == ')')) + m_t << "\\‍" << *p++; + else + m_t << c; + break; default: m_t << c; } } @@ -2239,6 +2252,11 @@ void HtmlDocVisitor::filterQuotedCdataAttr(const char* str) case '"': m_t << """; break; case '<': m_t << "<"; break; case '>': m_t << ">"; break; + case '\\': if ((*p == '(') || (*p == ')')) + m_t << "\\‍" << *p++; + else + m_t << c; + break; default: m_t << c; } } @@ -2437,7 +2455,7 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n) nodeIndex--; } if (nodeIndex<0) return; // first visible node in paragraph - DocNode *n = para->children().at(nodeIndex); + n = para->children().at(nodeIndex); if (mustBeOutsideParagraph(n)) return; // previous node already outside paragraph context nodeIndex--; bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex); @@ -2474,7 +2492,7 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n) } if (nodeIndex<numNodes) { - DocNode *n = para->children().at(nodeIndex); + n = para->children().at(nodeIndex); if (mustBeOutsideParagraph(n)) return; // next element also outside paragraph } else diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index bf52eed..b157881 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -114,20 +114,28 @@ static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlig } //------------------------------------------------------------------------ -/// Convert a set of LaTeX `\(re)newcommand` to a form readable by MathJax +/// Convert a set of LaTeX commands `\(re)newcommand` to a form readable by MathJax /// LaTeX syntax: +/// ``` /// \newcommand{\cmd}{replacement} /// or /// \renewcommand{\cmd}{replacement} +/// ``` /// MathJax syntax: +/// ``` /// cmd: "{replacement}" +/// ``` /// /// LaTeX syntax: +/// ``` /// \newcommand{\cmd}[nr]{replacement} /// or /// \renewcommand{\cmd}[nr]{replacement} +/// ``` /// MathJax syntax: +/// ``` /// cmd: ["{replacement}",nr] +/// ``` static QCString getConvertLatexMacro() { QCString macrofile = Config_getString(FORMULA_MACROFILE); @@ -158,8 +166,14 @@ static QCString getConvertLatexMacro() return ""; } i++; - if (!qstrncmp(data + i, "newcommand", strlen("newcommand"))) i += strlen("newcommand"); - else if (!qstrncmp(data + i, "renewcommand", strlen("renewcommand"))) i += strlen("renewcommand"); + if (!qstrncmp(data + i, "newcommand", (uint)strlen("newcommand"))) + { + i += (int)strlen("newcommand"); + } + else if (!qstrncmp(data + i, "renewcommand", (uint)strlen("renewcommand"))) + { + i += (int)strlen("renewcommand"); + } else { warn(macrofile,line, "file contains non valid code, expected 'newcommand' or 'renewcommand'"); @@ -394,7 +408,7 @@ static QCString removeEmptyLines(const QCString &s) return out.data(); } -static QCString substituteHtmlKeywords(const QCString &s, +static QCString substituteHtmlKeywords(const QCString &str, const QCString &title, const QCString &relPath, const QCString &navPath=QCString()) @@ -562,7 +576,7 @@ static QCString substituteHtmlKeywords(const QCString &s, } // first substitute generic keywords - QCString result = substituteKeywords(s,title, + QCString result = substituteKeywords(str,title, convertToHtml(Config_getString(PROJECT_NAME)), convertToHtml(Config_getString(PROJECT_NUMBER)), convertToHtml(Config_getString(PROJECT_BRIEF))); @@ -654,6 +668,10 @@ void HtmlCodeGenerator::codify(const char *str) { m_t << "<"; p++; } else if (*p=='>') { m_t << ">"; p++; } + else if (*p=='(') + { m_t << "\\‍("; m_col++;p++; } + else if (*p==')') + { m_t << "\\‍)"; m_col++;p++; } else m_t << "\\"; m_col++; @@ -688,6 +706,10 @@ void HtmlCodeGenerator::docify(const char *str) { m_t << "<"; p++; } else if (*p=='>') { m_t << ">"; p++; } + else if (*p=='(') + { m_t << "\\‍("; p++; } + else if (*p==')') + { m_t << "\\‍)"; p++; } else m_t << "\\"; break; @@ -1056,7 +1078,7 @@ void HtmlGenerator::writeSearchData(const char *dir) { searchCss = mgr.getAsString("search.css"); } - searchCss = substitute(replaceColorMarkers(searchCss),"$doxygenversion",getVersion()); + searchCss = substitute(replaceColorMarkers(searchCss),"$doxygenversion",getDoxygenVersion()); t << searchCss; Doxygen::indexList->addStyleSheetFile("search/search.css"); } @@ -1065,20 +1087,20 @@ void HtmlGenerator::writeSearchData(const char *dir) void HtmlGenerator::writeStyleSheetFile(QFile &file) { FTextStream t(&file); - t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",getVersion())); + t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",getDoxygenVersion())); } void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/) { FTextStream t(&file); - t << "<!-- HTML header for doxygen " << getVersion() << "-->" << endl; + t << "<!-- HTML header for doxygen " << getDoxygenVersion() << "-->" << endl; t << ResourceMgr::instance().getAsString("header.html"); } void HtmlGenerator::writeFooterFile(QFile &file) { FTextStream t(&file); - t << "<!-- HTML footer for doxygen " << getVersion() << "-->" << endl; + t << "<!-- HTML footer for doxygen " << getDoxygenVersion() << "-->" << endl; t << ResourceMgr::instance().getAsString("footer.html"); } @@ -1099,7 +1121,7 @@ void HtmlGenerator::startFile(const char *name,const char *, t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),m_relPath); t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " - << getVersion() << " -->" << endl; + << getDoxygenVersion() << " -->" << endl; //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); static bool searchEngine = Config_getBool(SEARCHENGINE); if (searchEngine /*&& !generateTreeView*/) @@ -1163,7 +1185,7 @@ QCString HtmlGenerator::writeLogoAsString(const char *path) "<img class=\"footer\" src=\""; result += path; result += "doxygen.png\" alt=\"doxygen\"/></a> "; - result += getVersion(); + result += getDoxygenVersion(); result += " "; return result; } @@ -1216,7 +1238,7 @@ void HtmlGenerator::writeStyleInfo(int part) //t << "H1 { text-align: center; border-width: thin none thin none;" << endl; //t << " border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl; - t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",getVersion())); + t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",getDoxygenVersion())); endPlainFile(); Doxygen::indexList->addStyleSheetFile("doxygen.css"); } @@ -1435,29 +1457,29 @@ void HtmlGenerator::endGroupHeader(int extraIndentLevel) } } -void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) +void HtmlGenerator::startSection(const char *lab,const char *,SectionType type) { switch(type) { - case SectionInfo::Page: t << "\n\n<h1>"; break; - case SectionInfo::Section: t << "\n\n<h2>"; break; - case SectionInfo::Subsection: t << "\n\n<h3>"; break; - case SectionInfo::Subsubsection: t << "\n\n<h4>"; break; - case SectionInfo::Paragraph: t << "\n\n<h5>"; break; + case SectionType::Page: t << "\n\n<h1>"; break; + case SectionType::Section: t << "\n\n<h2>"; break; + case SectionType::Subsection: t << "\n\n<h3>"; break; + case SectionType::Subsubsection: t << "\n\n<h4>"; break; + case SectionType::Paragraph: t << "\n\n<h5>"; break; default: ASSERT(0); break; } t << "<a id=\"" << lab << "\"></a>"; } -void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type) +void HtmlGenerator::endSection(const char *,SectionType type) { switch(type) { - case SectionInfo::Page: t << "</h1>"; break; - case SectionInfo::Section: t << "</h2>"; break; - case SectionInfo::Subsection: t << "</h3>"; break; - case SectionInfo::Subsubsection: t << "</h4>"; break; - case SectionInfo::Paragraph: t << "</h5>"; break; + case SectionType::Page: t << "</h1>"; break; + case SectionType::Section: t << "</h2>"; break; + case SectionType::Subsection: t << "</h3>"; break; + case SectionType::Subsubsection: t << "</h4>"; break; + case SectionType::Paragraph: t << "</h5>"; break; default: ASSERT(0); break; } } @@ -1488,6 +1510,10 @@ void HtmlGenerator::docify(const char *str,bool inHtmlComment) { t << "<"; p++; } else if (*p=='>') { t << ">"; p++; } + else if (*p=='(') + { t << "\\‍("; p++; } + else if (*p==')') + { t << "\\‍)"; p++; } else t << "\\"; break; @@ -2634,7 +2660,7 @@ void HtmlGenerator::writeSearchPage() t << substituteHtmlKeywords(g_header,"Search",""); t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " - << getVersion() << " -->" << endl; + << getDoxygenVersion() << " -->" << endl; t << "<script type=\"text/javascript\">\n"; t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"; t << "var searchBox = new SearchBox(\"searchBox\", \"" @@ -2679,7 +2705,6 @@ void HtmlGenerator::writeSearchPage() void HtmlGenerator::writeExternalSearchPage() { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); - static bool disableIndex = Config_getBool(DISABLE_INDEX); QCString fileName = Config_getString(HTML_OUTPUT)+"/search"+Doxygen::htmlFileExtension; QFile f(fileName); if (f.open(IO_WriteOnly)) @@ -2688,7 +2713,7 @@ void HtmlGenerator::writeExternalSearchPage() t << substituteHtmlKeywords(g_header,"Search",""); t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " - << getVersion() << " -->" << endl; + << getDoxygenVersion() << " -->" << endl; t << "<script type=\"text/javascript\">\n"; t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"; t << "var searchBox = new SearchBox(\"searchBox\", \"" diff --git a/src/htmlgen.h b/src/htmlgen.h index fe84061..a8268da 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -250,8 +250,8 @@ class HtmlGenerator : public OutputGenerator void endExamples(); void startParamList(ParamListTypes,const char *); void endParamList(); - void startSection(const char *,const char *,SectionInfo::SectionType); - void endSection(const char *,SectionInfo::SectionType); + void startSection(const char *,const char *,SectionType); + void endSection(const char *,SectionType); void addIndexItem(const char *,const char *); void startIndent(); void endIndent(); diff --git a/src/image.cpp b/src/image.cpp index afc67ef..2a8108b 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -207,7 +207,7 @@ static Color palette3[] = }; -Image::Image(int w,int h) +Image::Image(uint w,uint h) { static int hue = Config_getInt(HTML_COLORSTYLE_HUE); static int sat = Config_getInt(HTML_COLORSTYLE_SAT); @@ -236,49 +236,49 @@ Image::Image(int w,int h) palette[3].green = (int)(green2 * 255.0); palette[3].blue = (int)(blue2 * 255.0); - data = new uchar[w*h]; - memset(data,0,w*h); - width = w; - height = h; + m_data = new uchar[w*h]; + memset(m_data,0,w*h); + m_width = w; + m_height = h; } Image::~Image() { - delete[] data; + delete[] m_data; } -void Image::setPixel(int x,int y,uchar val) +void Image::setPixel(uint x,uint y,uchar val) { - if (x>=0 && x<width && y>=0 && y<height) - data[y*width+x] = val; + if (x<m_width && y<m_height) + m_data[y*m_width+x] = val; } -uchar Image::getPixel(int x,int y) const +uchar Image::getPixel(uint x,uint y) const { - if (x>=0 && x<width && y>=0 && y<height) - return data[y*width+x]; + if (x<m_width && y<m_height) + return m_data[y*m_width+x]; else return 0; } -void Image::writeChar(int x,int y,char c,uchar fg) +void Image::writeChar(uint x,uint y,char c,uchar fg) { if (c>=' ') { - int xf,yf,ci=c-' '; - int rowOffset=0; - int cw = charWidth[ci]; - int cp = charPos[ci]; + uint xf,yf,ci=c-' '; + uint rowOffset=0; + uint cw = charWidth[ci]; + uint cp = charPos[ci]; for (yf=0;yf<charHeight;yf++) { unsigned short bitPattern=0; - int bitsLeft=cw; - int byteOffset = rowOffset+(cp>>3); - int bitOffset = cp&7; + uint bitsLeft=cw; + uint byteOffset = rowOffset+(cp>>3); + uint bitOffset = cp&7; // get the bit pattern for row yf of the character from the font data while (bitsLeft>0) { - int bits=8-bitOffset; + uint bits=8-bitOffset; if (bits>bitsLeft) bits=bitsLeft; bitPattern<<=bits; bitPattern|=((fontRaw[byteOffset]<<bitOffset)&0xff)>>(8-bits); @@ -286,7 +286,7 @@ void Image::writeChar(int x,int y,char c,uchar fg) bitOffset=0; byteOffset++; } - int mask=1<<(cw-1); + uint mask=1<<(cw-1); // draw character row yf for (xf=0;xf<cw;xf++) { @@ -298,7 +298,7 @@ void Image::writeChar(int x,int y,char c,uchar fg) } } -void Image::writeString(int x,int y,const char *s,uchar fg) +void Image::writeString(uint x,uint y,const char *s,uchar fg) { if (s) { @@ -313,7 +313,7 @@ void Image::writeString(int x,int y,const char *s,uchar fg) uint Image::stringLength(const char *s) { - int w=0; + uint w=0; if (s) { char c; @@ -322,9 +322,9 @@ uint Image::stringLength(const char *s) return w; } -void Image::drawHorzLine(int y,int xs,int xe,uchar colIndex,uint mask) +void Image::drawHorzLine(uint y,uint xs,uint xe,uchar colIndex,uint mask) { - int x,i=0,j=0; + uint x,i=0,j=0; for (x=xs;x<=xe;x++,j++) { if (j&1) i++; @@ -332,38 +332,38 @@ void Image::drawHorzLine(int y,int xs,int xe,uchar colIndex,uint mask) } } -void Image::drawHorzArrow(int y,int xs,int xe,uchar colIndex,uint mask) +void Image::drawHorzArrow(uint y,uint xs,uint xe,uchar colIndex,uint mask) { drawHorzLine(y,xs,xe,colIndex,mask); - int i; + uint i; for (i=0;i<6;i++) { - int h=i>>1; + uint h=i>>1; drawVertLine(xe-i,y-h,y+h,colIndex,0xffffffff); } } -void Image::drawVertLine(int x,int ys,int ye,uchar colIndex,uint mask) +void Image::drawVertLine(uint x,uint ys,uint ye,uchar colIndex,uint mask) { - int y,i=0; + uint y,i=0; for (y=ys;y<=ye;y++,i++) { if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex); } } -void Image::drawVertArrow(int x,int ys,int ye,uchar colIndex,uint mask) +void Image::drawVertArrow(uint x,uint ys,uint ye,uchar colIndex,uint mask) { drawVertLine(x,ys,ye,colIndex,mask); - int i; + uint i; for (i=0;i<6;i++) { - int h=i>>1; + uint h=i>>1; drawHorzLine(ys+i,x-h,x+h,colIndex,0xffffffff); } } -void Image::drawRect(int x,int y,int w,int h,uchar colIndex,uint mask) +void Image::drawRect(uint x,uint y,uint w,uint h,uchar colIndex,uint mask) { drawHorzLine(y,x,x+w-1,colIndex,mask); drawHorzLine(y+h-1,x,x+w-1,colIndex,mask); @@ -371,44 +371,27 @@ void Image::drawRect(int x,int y,int w,int h,uchar colIndex,uint mask) drawVertLine(x+w-1,y,y+h-1,colIndex,mask); } -void Image::fillRect(int x,int y,int lwidth,int lheight,uchar colIndex,uint mask) +void Image::fillRect(uint x,uint y,uint width,uint height,uchar colIndex,uint mask) { - int xp,yp,xi,yi; - for (yp=y,yi=0;yp<y+lheight;yp++,yi++) - for (xp=x,xi=0;xp<x+lwidth;xp++,xi++) + uint xp,yp,xi,yi; + for (yp=y,yi=0;yp<y+height;yp++,yi++) + for (xp=x,xi=0;xp<x+width;xp++,xi++) if (mask&(1<<((xi+yi)&0x1f))) setPixel(xp,yp,colIndex); } bool Image::save(const char *fileName,int mode) { -#if 0 - GifEncoder gifenc(data, - mode==0 ? palette : palette2, - width,height, - mode==0 ? 3 : 4, - 0); - QFile file(fileName); - if (file.open(IO_WriteOnly)) - { - gifenc.writeGIF(file); - return TRUE; - } - else - { - return FALSE; - } -#endif static bool useTransparency = Config_getBool(FORMULA_TRANSPARENT); uchar* buffer; size_t bufferSize; LodePNG_Encoder encoder; LodePNG_Encoder_init(&encoder); - int numCols = mode==0 ? 8 : 16; + uint numCols = mode==0 ? 8 : 16; Color *pPal = mode==0 ? palette : useTransparency ? palette2 : palette3 ; - int i; + uint i; for (i=0;i<numCols;i++,pPal++) { LodePNG_InfoColor_addPalette(&encoder.infoPng.color, @@ -416,7 +399,7 @@ bool Image::save(const char *fileName,int mode) } encoder.infoPng.color.colorType = 3; encoder.infoRaw.color.colorType = 3; - LodePNG_encode(&encoder, &buffer, &bufferSize, data, width, height); + LodePNG_encode(&encoder, &buffer, &bufferSize, m_data, m_width, m_height); LodePNG_saveFile(buffer, bufferSize, fileName); free(buffer); LodePNG_Encoder_cleanup(&encoder); @@ -489,7 +472,7 @@ void ColoredImage::hsl2rgb(double h,double s,double l, *pBlue = b; } -ColoredImage::ColoredImage(int width,int height, +ColoredImage::ColoredImage(uint width,uint height, const uchar *greyLevels,const uchar *alphaLevels, int saturation,int hue,int gamma) { @@ -497,7 +480,7 @@ ColoredImage::ColoredImage(int width,int height, m_width = width; m_height = height; m_data = (uchar*)malloc(width*height*4); - int i; + uint i; for (i=0;i<width*height;i++) { uchar r,g,b,a; diff --git a/src/image.h b/src/image.h index 35e6ae3..435321a 100644 --- a/src/image.h +++ b/src/image.h @@ -24,37 +24,37 @@ class Image { public: - Image(int w,int h); + Image(uint w,uint h); ~Image(); - void setPixel(int x,int y,uchar val); - uchar getPixel(int x,int y) const; - void writeChar(int x,int y,char c,uchar fg); - void writeString(int x,int y,const char *s,uchar fg); - void drawHorzLine(int y,int xs,int xe,uchar colIndex,uint mask); - void drawHorzArrow(int y,int xs,int xe,uchar colIndex,uint mask); - void drawVertLine(int x,int ys,int ye,uchar colIndex,uint mask); - void drawVertArrow(int x,int ys,int ye,uchar colIndex,uint mask); - void drawRect(int x,int y,int width,int height,uchar colIndex,uint mask); - void fillRect(int x,int y,int width,int height,uchar colIndex,uint mask); + void setPixel(uint x,uint y,uchar val); + uchar getPixel(uint x,uint y) const; + void writeChar(uint x,uint y,char c,uchar fg); + void writeString(uint x,uint y,const char *s,uchar fg); + void drawHorzLine(uint y,uint xs,uint xe,uchar colIndex,uint mask); + void drawHorzArrow(uint y,uint xs,uint xe,uchar colIndex,uint mask); + void drawVertLine(uint x,uint ys,uint ye,uchar colIndex,uint mask); + void drawVertArrow(uint x,uint ys,uint ye,uchar colIndex,uint mask); + void drawRect(uint x,uint y,uint width,uint height,uchar colIndex,uint mask); + void fillRect(uint x,uint y,uint width,uint height,uchar colIndex,uint mask); bool save(const char *fileName,int mode=0); friend uint stringLength(const char *s); - uint getWidth() const { return width; } - uint getHeight() const { return height; } - uchar *getData() const { return data; } + uint width() const { return m_width; } + uint height() const { return m_height; } + uchar *data() const { return m_data; } static uint stringLength(const char *s); private: - int width; - int height; - uchar *data; + uint m_width; + uint m_height; + uchar *m_data; }; /** Class representing a bitmap image colored based on hue/sat/gamma settings. */ class ColoredImage { public: - ColoredImage(int width,int height, + ColoredImage(uint width,uint height, const uchar *greyLevels,const uchar *alphaLevels, int saturation,int hue,int gamma); ~ColoredImage(); @@ -62,8 +62,8 @@ class ColoredImage static void hsl2rgb(double h,double s,double l, double *pRed,double *pGreen,double *pBlue); private: - int m_width; - int m_height; + uint m_width; + uint m_height; uchar *m_data; bool m_hasAlpha; }; diff --git a/src/index.cpp b/src/index.cpp index edc302b..fd61a45 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -760,7 +760,7 @@ static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); } - static bool fullPathNames = Config_getBool(FULL_PATH_NAMES); + bool fullPathNames = Config_getBool(FULL_PATH_NAMES); startIndexHierarchy(ol,0); if (fullPathNames) { @@ -776,19 +776,14 @@ static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) } if (ftv) { - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { - static bool fullPathNames = Config_getBool(FULL_PATH_NAMES); if (!fullPathNames || fd->getDirDef()==0) // top level file { - bool doc,src; - doc = fileVisibleInIndex(fd,src); + bool src; + bool doc = fileVisibleInIndex(fd.get(),src); QCString reference, outputBase; if (doc) { @@ -799,19 +794,19 @@ static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) { ftv->addContentsItem(FALSE,fd->displayName(), reference, outputBase, 0, - FALSE,FALSE,fd); + FALSE,FALSE,fd.get()); } if (addToIndex) { if (doc) { - addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE); + addMembersToIndex(fd.get(),LayoutDocManager::File,fd->displayName(),QCString(),TRUE); } else if (src) { Doxygen::indexList->addContentsItem( FALSE, convertToHtml(fd->name(),TRUE), 0, - fd->getSourceFileBase(), 0, FALSE, TRUE, fd); + fd->getSourceFileBase(), 0, FALSE, TRUE, fd.get()); } } } @@ -1321,16 +1316,12 @@ static void countFiles(int &htmlFiles,int &files) { htmlFiles=0; files=0; - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd: *fn) { bool doc,src; - doc = fileVisibleInIndex(fd,src); + doc = fileVisibleInIndex(fd.get(),src); if (doc || src) { htmlFiles++; @@ -1470,27 +1461,23 @@ static void writeFileIndex(OutputList &ol) if (Config_getBool(FULL_PATH_NAMES)) { // re-sort input files in (dir,file) output order instead of (file,dir) input order - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { QCString path=fd->getPath(); if (path.isEmpty()) path="[external]"; FileList *fl = outputNameDict.find(path); if (fl) { - fl->append(fd); + fl->append(fd.get()); //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data()); } else { //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data()); fl = new FileList(path); - fl->append(fd); + fl->append(fd.get()); outputNameList.append(fl); outputNameDict.insert(path,fl); } @@ -1517,15 +1504,11 @@ static void writeFileIndex(OutputList &ol) } else { - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { - writeSingleFileIndex(ol,fd); + writeSingleFileIndex(ol,fd.get()); } } } @@ -2008,20 +1991,20 @@ class PrefixIgnoreClassList : public ClassList class AlphaIndexTableCell { public: - AlphaIndexTableCell(int row,int col,uint letter,ClassDef *cd) : + AlphaIndexTableCell(int row,int col,uint letter,const ClassDef *cd) : m_letter(letter), m_class(cd), m_row(row), m_col(col) { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-', // cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>"); } - ClassDef *classDef() const { return m_class; } + const ClassDef *classDef() const { return m_class; } uint letter() const { return m_letter; } int row() const { return m_row; } int column() const { return m_col; } private: uint m_letter; - ClassDef *m_class; + const ClassDef *m_class; int m_row; int m_col; }; @@ -2037,8 +2020,8 @@ class AlphaIndexTableRows : public QList<AlphaIndexTableCell> class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell> { public: - AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list) : - QListIterator<AlphaIndexTableCell>(list) {} + AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list_) : + QListIterator<AlphaIndexTableCell>(list_) {} }; /** Class representing the columns in the alphabetical class index. */ @@ -2190,7 +2173,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct row++; ClassListIterator cit(*cl); cit.toFirst(); - ClassDef *cd = cit.current(); + cd = cit.current(); ++cit; tableRows->append(new AlphaIndexTableCell(row,col,0,cd)); row++; @@ -2847,9 +2830,9 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, QCString cl = letterToString(ml->letter()); QCString anchor=(QCString)"index_"+convertToId(cs); QCString title=(QCString)"- "+cl+" -"; - ol.startSection(anchor,title,SectionInfo::Subsection); + ol.startSection(anchor,title,SectionType::Subsection); ol.docify(title); - ol.endSection(anchor,SectionInfo::Subsection); + ol.endSection(anchor,SectionType::Subsection); ol.startItemList(); firstSection=FALSE; firstItem=TRUE; @@ -4059,7 +4042,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* for (mi.toFirst();(md=mi.current());++mi) { const MemberList *enumList = md->enumFieldList(); - bool isDir = enumList!=0 && md->isEnumerate(); + isDir = enumList!=0 && md->isEnumerate(); if (md->isVisible() && !md->isAnonymous()) { Doxygen::indexList->addContentsItem(isDir, @@ -4160,16 +4143,16 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* PageDef *pd; for (;(pd=it.current());++it) { - SectionInfo *si=0; - if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name()); - bool hasSubPages = pd->hasSubPages(); + const SectionInfo *si=0; + if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name()); + hasSubPages = pd->hasSubPages(); bool hasSections = pd->hasSections(); Doxygen::indexList->addContentsItem( hasSubPages || hasSections, convertToHtml(pd->title(),TRUE), gd->getReference(), gd->getOutputFileBase(), - si ? si->label.data() : 0, + si ? si->label().data() : 0, hasSubPages || hasSections, TRUE); // addToNavIndex if (hasSections || hasSubPages) @@ -4556,8 +4539,7 @@ static void writeIndex(OutputList &ol) ol.startTextBlock(); ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0, - Doxygen::mainPage->documentation(),TRUE,FALSE - /*,Doxygen::mainPage->sectionDict*/); + Doxygen::mainPage->documentation(),TRUE,FALSE); ol.endTextBlock(); ol.endPageDoc(); @@ -4639,7 +4621,7 @@ static void writeIndex(OutputList &ol) ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); } - QCString title = pd->title(); + title = pd->title(); if (title.isEmpty()) title=pd->name(); ol.disable(OutputGenerator::Docbook); diff --git a/src/language.cpp b/src/language.cpp index 7457676..299c452 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -417,6 +417,6 @@ bool setTranslator(const char *langName) } QCString msg = theTranslator->updateNeededMessage(); - if (!msg.isEmpty()) warn_uncond(msg); + if (!msg.isEmpty()) warn_uncond("%s", msg.data()); return TRUE; } diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 730f083..b899935 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -503,6 +503,10 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::DontInclude: case DocInclude::DontIncWithLines: case DocInclude::HtmlInclude: + case DocInclude::RtfInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: break; case DocInclude::LatexInclude: m_t << inc->text(); @@ -653,7 +657,8 @@ void LatexDocVisitor::visit(DocCite *cite) { //startLink(cite->ref(),cite->file(),cite->anchor()); QCString anchor = cite->anchor(); - anchor = anchor.mid(CiteConsts::anchorPrefix.length()); // strip prefix + QCString anchorPrefix = CitationManager::instance().anchorPrefix(); + anchor = anchor.mid(anchorPrefix.length()); // strip prefix m_t << "\\cite{" << anchor << "}"; } else diff --git a/src/latexgen.cpp b/src/latexgen.cpp index cdda22c..52a8acf 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -42,6 +42,7 @@ #include "namespacedef.h" #include "filename.h" #include "resourcemgr.h" +#include "portable.h" static bool DoxyCodeOpen = FALSE; static bool DoxyCodeLineOpen = FALSE; @@ -79,12 +80,12 @@ void LatexCodeGenerator::codify(const char *str) { if (str) { - const char *p=str; - char c; + const signed char *p=(const signed char*)str; + signed char c; //char cs[5]; int spacesToNextTabStop; static int tabSize = Config_getInt(TAB_SIZE); - static char *result = NULL; + static signed char *result = NULL; static int lresult = 0; int i; while ((c=*p)) @@ -118,7 +119,7 @@ void LatexCodeGenerator::codify(const char *str) if (lresult < (i + 5)) \ { \ lresult += 512; \ - result = (char *)realloc(result, lresult); \ + result = (signed char *)realloc(result, lresult); \ } \ result[i++]=c; p++; \ if (c<0) /* multibyte utf-8 character */ \ @@ -150,7 +151,7 @@ void LatexCodeGenerator::codify(const char *str) result[i]=0; // add terminator //if (m_prettyCode) //{ - filterLatexString(m_t,result,FALSE,TRUE); + filterLatexString(m_t,(const char *)result,FALSE,TRUE); //} //else //{ @@ -174,8 +175,8 @@ void LatexCodeGenerator::writeCodeLink(const char *ref,const char *f, { m_t << "\\mbox{\\hyperlink{"; if (f) m_t << stripPath(f); - if (f && anchor) m_t << "_"; - if (anchor) m_t << anchor; + if (f && anchor) m_t << "_"; + if (anchor) m_t << anchor; m_t << "}{"; codify(name); m_t << "}}"; @@ -282,7 +283,7 @@ LatexGenerator::~LatexGenerator() static void writeLatexMakefile() { - bool generateBib = !Doxygen::citeDict->isEmpty(); + bool generateBib = !CitationManager::instance().isEmpty(); QCString dir=Config_getString(LATEX_OUTPUT); QCString fileName=dir+"/Makefile"; QFile file(fileName); @@ -371,7 +372,7 @@ static void writeLatexMakefile() t << endl << "clean:" << endl - << "\trm -f " + << "\trm -f " << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl; } @@ -383,7 +384,7 @@ static void writeMakeBat() QCString latex_command = theTranslator->latexCommandName(); QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME); QFile file(fileName); - bool generateBib = !Doxygen::citeDict->isEmpty(); + bool generateBib = !CitationManager::instance().isEmpty(); if (!file.open(IO_WriteOnly)) { term("Could not open file %s for writing\n",fileName.data()); @@ -421,7 +422,8 @@ static void writeMakeBat() t << mkidx_command << " refman.idx\n"; t << "%LATEX_CMD% refman.tex\n"; t << "dvips -o refman.ps refman.dvi\n"; - t << "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite " + t << Portable::ghostScriptCommand(); + t << " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite " "-sOutputFile=refman.pdf -c save pop -f refman.ps\n"; } else // use pdflatex @@ -518,10 +520,10 @@ static void writeDefaultHeaderPart1(FTextStream &t) QFileInfo fi(fileName); if (fi.exists()) { - if (checkExtension(fi.fileName().data(), latexStyleExtension)) + if (checkExtension(fi.fileName().data(), LATEX_STYLE_EXTENSION)) { // strip the extension, it will be added by the usepackage in the tex conversion process - t << "\\usepackage{" << stripExtensionGeneral(fi.fileName().data(), latexStyleExtension) << "}\n"; + t << "\\usepackage{" << stripExtensionGeneral(fi.fileName().data(), LATEX_STYLE_EXTENSION) << "}\n"; } else { @@ -621,7 +623,7 @@ static void writeDefaultHeaderPart1(FTextStream &t) "}\n" "\\makeatother\n" "\n"; - // + // t << "\\makeatletter\n" "\\newcommand\\hrulefilll{\\leavevmode\\leaders\\hrule\\hskip 0pt plus 1filll\\kern\\z@}\n" "\\makeatother\n" @@ -789,7 +791,7 @@ static void writeDefaultHeaderPart3(FTextStream &t) { // part 3 // Finalize project number - t << " Doxygen " << getVersion() << "}\\\\\n"; + t << " Doxygen " << getDoxygenVersion() << "}\\\\\n"; if (Config_getBool(LATEX_TIMESTAMP)) t << "\\vspace*{0.5cm}\n" "{\\small " << dateToString(TRUE) << "}\\\\\n"; @@ -827,7 +829,7 @@ static void writeDefaultFooter(FTextStream &t) "\n"; // Bibliography - Doxygen::citeDict->writeLatexBibliography(t); + CitationManager::instance().writeLatexBibliography(t); // Index t << "% Index\n"; @@ -858,7 +860,7 @@ static void writeDefaultFooter(FTextStream &t) void LatexGenerator::writeHeaderFile(QFile &f) { FTextStream t(&f); - t << "% Latex header for doxygen " << getVersion() << endl; + t << "% Latex header for doxygen " << getDoxygenVersion() << endl; writeDefaultHeaderPart1(t); t << "Your title here"; writeDefaultHeaderPart2(t); @@ -869,14 +871,14 @@ void LatexGenerator::writeHeaderFile(QFile &f) void LatexGenerator::writeFooterFile(QFile &f) { FTextStream t(&f); - t << "% Latex footer for doxygen " << getVersion() << endl; + t << "% Latex footer for doxygen " << getDoxygenVersion() << endl; writeDefaultFooter(t); } void LatexGenerator::writeStyleSheetFile(QFile &f) { FTextStream t(&f); - t << "% stylesheet for doxygen " << getVersion() << endl; + t << "% stylesheet for doxygen " << getDoxygenVersion() << endl; writeDefaultStyleSheet(t); } @@ -903,11 +905,11 @@ void LatexGenerator::endFile() //void LatexGenerator::writeIndex() //{ // startFile("refman.tex"); -//} - +//} + void LatexGenerator::startProjectNumber() { - t << "\\\\[1ex]\\large "; + t << "\\\\[1ex]\\large "; } void LatexGenerator::startIndexSection(IndexSections is) @@ -1019,7 +1021,7 @@ void LatexGenerator::startIndexSection(IndexSections is) t << "{"; // Namespace Documentation}\n": found=TRUE; } - } + } } break; case isClassDocumentation: @@ -1029,7 +1031,7 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject() && + if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isEmbeddedInOuterScope() ) @@ -1044,13 +1046,9 @@ void LatexGenerator::startIndexSection(IndexSections is) case isFileDocumentation: { bool isFirst=TRUE; - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isLinkableInProject()) { @@ -1149,7 +1147,7 @@ void LatexGenerator::endIndexSection(IndexSections is) if (!gd->isReference()) { //if (compactLatex) t << "\\input"; else t << "\\include"; - t << "\\include"; + t << "\\include"; t << "{" << gd->getOutputFileBase() << "}\n"; } } @@ -1173,7 +1171,7 @@ void LatexGenerator::endIndexSection(IndexSections is) if (dd->isLinkableInProject()) { //if (compactLatex) t << "\\input"; else t << "\\include"; - t << "\\input"; + t << "\\input"; t << "{" << dd->getOutputFileBase() << "}\n"; } } @@ -1197,7 +1195,7 @@ void LatexGenerator::endIndexSection(IndexSections is) if (nd->isLinkableInProject()) { //if (compactLatex) t << "\\input"; else t << "\\include"; - t << "\\input"; + t << "\\input"; t << "{" << nd->getOutputFileBase() << "}\n"; } ++nli; @@ -1211,7 +1209,7 @@ void LatexGenerator::endIndexSection(IndexSections is) bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject() && + if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isEmbeddedInOuterScope() ) @@ -1222,28 +1220,24 @@ void LatexGenerator::endIndexSection(IndexSections is) } for (;(cd=cli.current());++cli) { - if (cd->isLinkableInProject() && + if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isEmbeddedInOuterScope() ) { //if (compactLatex) t << "\\input"; else t << "\\include"; - t << "\\input"; + t << "\\input"; t << "{" << cd->getOutputFileBase() << "}\n"; - } + } } } break; case isFileDocumentation: { bool isFirst=TRUE; - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isLinkableInProject()) { @@ -1260,7 +1254,7 @@ void LatexGenerator::endIndexSection(IndexSections is) else { //if (compactLatex) t << "\\input" ; else t << "\\include"; - t << "\\input" ; + t << "\\input" ; t << "{" << fd->getOutputFileBase() << "}\n"; if (sourceBrowser && m_prettyCode && fd->generateSourceFile()) { @@ -1285,7 +1279,7 @@ void LatexGenerator::endIndexSection(IndexSections is) for (++pdi;(pd=pdi.current());++pdi) { //if (compactLatex) t << "\\input" ; else t << "\\include"; - t << "\\input"; + t << "\\input"; t << "{" << pd->getOutputFileBase() << "}\n"; } } @@ -1304,7 +1298,7 @@ void LatexGenerator::endIndexSection(IndexSections is) if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{" << pd->title(); t << "}\n"; - + if (compactLatex || first) t << "\\input" ; else t << "\\include"; t << "{" << pd->getOutputFileBase() << "}\n"; first=FALSE; @@ -1337,7 +1331,7 @@ void LatexGenerator::writePageLink(const char *name, bool /*first*/) //bool &compactLatex = Config_getBool(COMPACT_LATEX); // next is remove for bug615957 //if (compactLatex || first) t << "\\input" ; else t << "\\include"; - t << "\\input" ; + t << "\\input" ; t << "{" << name << "}\n"; } @@ -1440,7 +1434,7 @@ void LatexGenerator::writeStartAnnoItem(const char *,const char *, { t << "\\item\\contentsline{section}\\textbf{ "; if (path) docify(path); - docify(name); + docify(name); t << "} "; } @@ -1475,7 +1469,7 @@ void LatexGenerator::endIndexValue(const char *name,bool /*hasBrief*/) //{ // t << "\\textbf{ "; // docify(name); -// t << "}"; +// t << "}"; //} void LatexGenerator::startTextLink(const char *f,const char *anchor) @@ -1485,7 +1479,7 @@ void LatexGenerator::startTextLink(const char *f,const char *anchor) { t << "\\mbox{\\hyperlink{"; if (f) t << stripPath(f); - if (anchor) t << "_" << anchor; + if (anchor) t << "_" << anchor; t << "}{"; } else @@ -1512,8 +1506,8 @@ void LatexGenerator::writeObjectLink(const char *ref, const char *f, { t << "\\mbox{\\hyperlink{"; if (f) t << stripPath(f); - if (f && anchor) t << "_"; - if (anchor) t << anchor; + if (f && anchor) t << "_"; + if (anchor) t << anchor; t << "}{"; docify(text); t << "}}"; @@ -1523,7 +1517,7 @@ void LatexGenerator::writeObjectLink(const char *ref, const char *f, t << "\\textbf{ "; docify(text); t << "}"; - } + } } void LatexGenerator::startPageRef() @@ -1534,7 +1528,7 @@ void LatexGenerator::startPageRef() void LatexGenerator::endPageRef(const char *clname, const char *anchor) { t << "}{"; - if (clname) t << clname; + if (clname) t << clname; if (anchor) t << "_" << anchor; t << "}"; } @@ -1548,13 +1542,13 @@ void LatexGenerator::startTitleHead(const char *fileName) { t << "\\hypertarget{" << stripPath(fileName) << "}{}"; } - if (Config_getBool(COMPACT_LATEX)) + if (Config_getBool(COMPACT_LATEX)) { - t << "\\doxysubsection{"; + t << "\\doxysubsection{"; } - else + else { - t << "\\doxysection{"; + t << "\\doxysection{"; } } @@ -1573,26 +1567,26 @@ void LatexGenerator::endTitleHead(const char *fileName,const char *name) void LatexGenerator::startTitle() { - if (Config_getBool(COMPACT_LATEX)) + if (Config_getBool(COMPACT_LATEX)) { - t << "\\doxysubsection{"; + t << "\\doxysubsection{"; } - else + else { - t << "\\doxysection{"; + t << "\\doxysection{"; } } void LatexGenerator::startGroupHeader(int extraIndentLevel) { - if (Config_getBool(COMPACT_LATEX)) + if (Config_getBool(COMPACT_LATEX)) { extraIndentLevel++; } if (extraIndentLevel==3) { - t << "\\doxysubparagraph*{"; + t << "\\doxysubparagraph*{"; } else if (extraIndentLevel==2) { @@ -1617,11 +1611,11 @@ void LatexGenerator::endGroupHeader(int) void LatexGenerator::startMemberHeader(const char *,int) { - if (Config_getBool(COMPACT_LATEX)) + if (Config_getBool(COMPACT_LATEX)) { - t << "\\doxysubsubsection*{"; + t << "\\doxysubsubsection*{"; } - else + else { t << "\\doxysubsection*{"; } @@ -1731,9 +1725,9 @@ void LatexGenerator::endDoxyAnchor(const char *fName,const char *anchor) } void LatexGenerator::writeAnchor(const char *fName,const char *name) -{ +{ //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name); - t << "\\label{" << stripPath(name) << "}" << endl; + t << "\\label{" << stripPath(name) << "}" << endl; static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); static bool usePDFLatex = Config_getBool(USE_PDFLATEX); if (usePDFLatex && pdfHyperlinks) @@ -1777,7 +1771,7 @@ void LatexGenerator::addIndexItem(const char *s1,const char *s2) } -void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) +void LatexGenerator::startSection(const char *lab,const char *,SectionType type) { static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); static bool usePDFLatex = Config_getBool(USE_PDFLATEX); @@ -1790,11 +1784,11 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect { switch(type) { - case SectionInfo::Page: t << "doxysubsection"; break; - case SectionInfo::Section: t << "doxysubsubsection"; break; - case SectionInfo::Subsection: t << "doxyparagraph"; break; - case SectionInfo::Subsubsection: t << "doxysubparagraph"; break; - case SectionInfo::Paragraph: t << "doxysubparagraph"; break; + case SectionType::Page: t << "doxysubsection"; break; + case SectionType::Section: t << "doxysubsubsection"; break; + case SectionType::Subsection: t << "doxyparagraph"; break; + case SectionType::Subsubsection: t << "doxysubparagraph"; break; + case SectionType::Paragraph: t << "doxysubparagraph"; break; default: ASSERT(0); break; } t << "{"; @@ -1803,18 +1797,18 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect { switch(type) { - case SectionInfo::Page: t << "doxysection"; break; - case SectionInfo::Section: t << "doxysubsection"; break; - case SectionInfo::Subsection: t << "doxysubsubsection"; break; - case SectionInfo::Subsubsection: t << "doxyparagraph"; break; - case SectionInfo::Paragraph: t << "doxysubparagraph"; break; + case SectionType::Page: t << "doxysection"; break; + case SectionType::Section: t << "doxysubsection"; break; + case SectionType::Subsection: t << "doxysubsubsection"; break; + case SectionType::Subsubsection: t << "doxyparagraph"; break; + case SectionType::Paragraph: t << "doxysubparagraph"; break; default: ASSERT(0); break; } t << "{"; } } -void LatexGenerator::endSection(const char *lab,SectionInfo::SectionType) +void LatexGenerator::endSection(const char *lab,SectionType) { t << "}\\label{" << lab << "}" << endl; } @@ -1883,31 +1877,31 @@ void LatexGenerator::endMemberTemplateParams(const char *,const char *) } } -void LatexGenerator::startMemberItem(const char *,int annoType,const char *) -{ +void LatexGenerator::startMemberItem(const char *,int annoType,const char *) +{ //printf("LatexGenerator::startMemberItem(%d)\n",annType); if (!m_insideTabbing) { - t << "\\item " << endl; + t << "\\item " << endl; templateMemberItem = (annoType == 3); } } -void LatexGenerator::endMemberItem() +void LatexGenerator::endMemberItem() { if (m_insideTabbing) { t << "\\\\"; - } + } templateMemberItem = FALSE; - t << endl; + t << endl; } -void LatexGenerator::startMemberDescription(const char *,const char *,bool) +void LatexGenerator::startMemberDescription(const char *,const char *,bool) { if (!m_insideTabbing) - { - t << "\\begin{DoxyCompactList}\\small\\item\\em "; + { + t << "\\begin{DoxyCompactList}\\small\\item\\em "; } else { @@ -1916,12 +1910,12 @@ void LatexGenerator::startMemberDescription(const char *,const char *,bool) } } -void LatexGenerator::endMemberDescription() -{ +void LatexGenerator::endMemberDescription() +{ if (!m_insideTabbing) { - //t << "\\item\\end{DoxyCompactList}"; - t << "\\end{DoxyCompactList}"; + //t << "\\item\\end{DoxyCompactList}"; + t << "\\end{DoxyCompactList}"; } else { @@ -1930,7 +1924,7 @@ void LatexGenerator::endMemberDescription() } -void LatexGenerator::writeNonBreakableSpace(int) +void LatexGenerator::writeNonBreakableSpace(int) { //printf("writeNonBreakableSpace()\n"); if (m_insideTabbing) @@ -1939,7 +1933,7 @@ void LatexGenerator::writeNonBreakableSpace(int) } else { - t << "~"; + t << "~"; } } @@ -1999,25 +1993,25 @@ void LatexGenerator::endDescTableData() t << "\\\\\n\\hline\n" << endl; } -void LatexGenerator::lastIndexPage() +void LatexGenerator::lastIndexPage() { } -void LatexGenerator::startMemberList() -{ +void LatexGenerator::startMemberList() +{ if (!m_insideTabbing) { - t << "\\begin{DoxyCompactItemize}" << endl; + t << "\\begin{DoxyCompactItemize}" << endl; } } -void LatexGenerator::endMemberList() +void LatexGenerator::endMemberList() { //printf("LatexGenerator::endMemberList(%d)\n",m_insideTabbing); if (!m_insideTabbing) { - t << "\\end{DoxyCompactItemize}" << endl; + t << "\\end{DoxyCompactItemize}" << endl; } } @@ -2027,7 +2021,7 @@ void LatexGenerator::startMemberGroupHeader(bool hasHeader) if (hasHeader) t << "\\begin{Indent}"; t << "\\textbf{ "; // changed back to rev 756 due to bug 660501 - //if (Config_getBool(COMPACT_LATEX)) + //if (Config_getBool(COMPACT_LATEX)) //{ // t << "\\doxysubparagraph*{"; //} @@ -2060,80 +2054,80 @@ void LatexGenerator::startMemberGroup() void LatexGenerator::endMemberGroup(bool hasHeader) { - if (hasHeader)t << "\\end{Indent}"; + if (hasHeader)t << "\\end{Indent}"; t << endl; } -void LatexGenerator::startDotGraph() +void LatexGenerator::startDotGraph() { newParagraph(); } -void LatexGenerator::endDotGraph(DotClassGraph &g) +void LatexGenerator::endDotGraph(DotClassGraph &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),m_fileName,m_relPath); } -void LatexGenerator::startInclDepGraph() +void LatexGenerator::startInclDepGraph() { } -void LatexGenerator::endInclDepGraph(DotInclDepGraph &g) +void LatexGenerator::endInclDepGraph(DotInclDepGraph &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),m_fileName,m_relPath); } -void LatexGenerator::startGroupCollaboration() +void LatexGenerator::startGroupCollaboration() { } -void LatexGenerator::endGroupCollaboration(DotGroupCollaboration &g) +void LatexGenerator::endGroupCollaboration(DotGroupCollaboration &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),m_fileName,m_relPath); } -void LatexGenerator::startCallGraph() +void LatexGenerator::startCallGraph() { } -void LatexGenerator::endCallGraph(DotCallGraph &g) +void LatexGenerator::endCallGraph(DotCallGraph &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),m_fileName,m_relPath); } -void LatexGenerator::startDirDepGraph() +void LatexGenerator::startDirDepGraph() { } -void LatexGenerator::endDirDepGraph(DotDirDeps &g) +void LatexGenerator::endDirDepGraph(DotDirDeps &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),m_fileName,m_relPath); } -void LatexGenerator::startDescription() -{ - t << "\\begin{description}" << endl; +void LatexGenerator::startDescription() +{ + t << "\\begin{description}" << endl; } -void LatexGenerator::endDescription() -{ - t << "\\end{description}" << endl; +void LatexGenerator::endDescription() +{ + t << "\\end{description}" << endl; m_firstDescItem=TRUE; } -void LatexGenerator::startDescItem() -{ +void LatexGenerator::startDescItem() +{ m_firstDescItem=TRUE; - t << "\\item["; + t << "\\item["; } -void LatexGenerator::endDescItem() -{ - if (m_firstDescItem) +void LatexGenerator::endDescItem() +{ + if (m_firstDescItem) { t << "]" << endl; m_firstDescItem=FALSE; - } + } else { lineBreak(); @@ -2276,11 +2270,11 @@ void LatexGenerator::endCodeFragment() void LatexGenerator::startInlineHeader() { - if (Config_getBool(COMPACT_LATEX)) + if (Config_getBool(COMPACT_LATEX)) { - t << "\\doxyparagraph*{"; + t << "\\doxyparagraph*{"; } - else + else { t << "\\doxysubsubsection*{"; } diff --git a/src/latexgen.h b/src/latexgen.h index 7d4cae8..2c32388 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -22,7 +22,7 @@ class QFile; -static const char *latexStyleExtension = ".sty"; +#define LATEX_STYLE_EXTENSION ".sty" class LatexCodeGenerator : public CodeOutputInterface { @@ -241,8 +241,8 @@ class LatexGenerator : public OutputGenerator void endParamList(); void startDescForItem() { t << "\\par" << endl; } void endDescForItem() {} - void startSection(const char *,const char *,SectionInfo::SectionType); - void endSection(const char *,SectionInfo::SectionType); + void startSection(const char *,const char *,SectionType); + void endSection(const char *,SectionType); void addIndexItem(const char *,const char *); void startIndent() {} void endIndent() {} diff --git a/src/layout.cpp b/src/layout.cpp index 946b612..f84fec0 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -1424,15 +1424,15 @@ class LayoutParser : public QXmlDefaultHandler } private: - LayoutParser() : m_sHandler(163), m_eHandler(17), m_invalidEntry(FALSE), m_part(0), m_rootNav(NULL) { } + LayoutParser() : m_sHandler(163), m_eHandler(17) { } ~LayoutParser() { delete m_rootNav; } QDict<StartElementHandler> m_sHandler; QDict<EndElementHandler> m_eHandler; QCString m_scope; - int m_part; - LayoutNavEntry *m_rootNav; - bool m_invalidEntry; + int m_part = 0; + LayoutNavEntry *m_rootNav = 0; + bool m_invalidEntry = false; static int m_userGroupCount; }; @@ -1562,7 +1562,7 @@ void writeDefaultLayoutFile(const char *fileName) } QTextStream t(&f); t.setEncoding(QTextStream::UnicodeUTF8); - t << substitute(layout_default,"$doxygenversion",getVersion()); + t << substitute(layout_default,"$doxygenversion",getDoxygenVersion()); } //---------------------------------------------------------------------------------- diff --git a/src/linkedmap.h b/src/linkedmap.h new file mode 100644 index 0000000..c724a39 --- /dev/null +++ b/src/linkedmap.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2020 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef LINKEDMAP_H +#define LINKEDMAP_H + +#include <unordered_map> +#include <vector> +#include <memory> +#include <string> + +//! @brief Container class representing a vector of objects with unique keys. +//! @details Elements can be quickly looked up given the key. +//! When adding objects the order of addition is kept, and used while iterating. +template<class T> +class LinkedMap +{ + public: + using Ptr = std::unique_ptr<T>; + using Vec = std::vector<Ptr>; + using Map = std::unordered_map<std::string,T*>; + using iterator = typename Vec::iterator; + using const_iterator = typename Vec::const_iterator; + + //! find an element given the key. + //! Returns a pointer to the element if found or nullptr if it is not found. + const T *find(const char *k) const + { + std::string key = k ? std::string(k) : std::string(); + auto it = m_lookup.find(key); + return it!=m_lookup.end() ? it->second : nullptr; + } + + //! non-const wrapper for find() const + T* find(const char *key) + { + return const_cast<T*>(static_cast<const LinkedMap&>(*this).find(key)); + } + + //! Adds a new element to the ordered set if it was not added already. + //! Return a non-owning pointer to the newly added item, or to the existing item if it was + //! already inserted before. + template<class...Args> + T *add(const char *k, Args&&... args) + { + T *result = find(k); + if (result==nullptr) + { + std::string key = k ? std::string(k) : std::string(); + Ptr ptr = std::make_unique<T>(k,std::forward<Args>(args)...); + result = ptr.get(); + m_lookup.insert({key,result}); + m_entries.push_back(std::move(ptr)); + } + return result; + } + + iterator begin() { return m_entries.begin(); } + iterator end() { return m_entries.end(); } + const_iterator begin() const { return m_entries.cbegin(); } + const_iterator end() const { return m_entries.cend(); } + bool empty() const { return m_entries.empty(); } + int size() const { return m_entries.size(); } + + void clear() + { + m_entries.clear(); + m_lookup.clear(); + } + + private: + Map m_lookup; + Vec m_entries; +}; + + +#endif diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index 6b76008..fef857e 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -304,6 +304,12 @@ void ManDocVisitor::visit(DocInclude *inc) case DocInclude::DontIncWithLines: case DocInclude::HtmlInclude: case DocInclude::LatexInclude: + case DocInclude::RtfInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: + break; + case DocInclude::ManInclude: + m_t << inc->text(); break; case DocInclude::VerbInclude: if (!m_firstCol) m_t << endl; diff --git a/src/mangen.cpp b/src/mangen.cpp index 5f07932..6709748 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -593,33 +593,33 @@ void ManGenerator::endMemberGroup(bool) m_firstCol=FALSE; } -void ManGenerator::startSection(const char *,const char *,SectionInfo::SectionType type) +void ManGenerator::startSection(const char *,const char *,SectionType type) { if( !m_inHeader ) { switch(type) { - case SectionInfo::Page: startGroupHeader(FALSE); break; - case SectionInfo::Section: startGroupHeader(FALSE); break; - case SectionInfo::Subsection: startMemberHeader(0, -1); break; - case SectionInfo::Subsubsection: startMemberHeader(0, -1); break; - case SectionInfo::Paragraph: startMemberHeader(0, -1); break; + case SectionType::Page: startGroupHeader(FALSE); break; + case SectionType::Section: startGroupHeader(FALSE); break; + case SectionType::Subsection: startMemberHeader(0, -1); break; + case SectionType::Subsubsection: startMemberHeader(0, -1); break; + case SectionType::Paragraph: startMemberHeader(0, -1); break; default: ASSERT(0); break; } } } -void ManGenerator::endSection(const char *,SectionInfo::SectionType type) +void ManGenerator::endSection(const char *,SectionType type) { if( !m_inHeader ) { switch(type) { - case SectionInfo::Page: endGroupHeader(0); break; - case SectionInfo::Section: endGroupHeader(0); break; - case SectionInfo::Subsection: endMemberHeader(); break; - case SectionInfo::Subsubsection: endMemberHeader(); break; - case SectionInfo::Paragraph: endMemberHeader(); break; + case SectionType::Page: endGroupHeader(0); break; + case SectionType::Section: endGroupHeader(0); break; + case SectionType::Subsection: endMemberHeader(); break; + case SectionType::Subsubsection: endMemberHeader(); break; + case SectionType::Paragraph: endMemberHeader(); break; default: ASSERT(0); break; } } diff --git a/src/mangen.h b/src/mangen.h index eba6c8d..a3a2a33 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -176,8 +176,8 @@ class ManGenerator : public OutputGenerator //void writeDescItem(); void startDescForItem(); void endDescForItem(); - void startSection(const char *,const char *,SectionInfo::SectionType); - void endSection(const char *,SectionInfo::SectionType); + void startSection(const char *,const char *,SectionType); + void endSection(const char *,SectionType); void addIndexItem(const char *,const char *) {} void startIndent() {} void endIndent() {} diff --git a/src/markdown.cpp b/src/markdown.cpp index 8594a15..937e5e0 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -3,8 +3,8 @@ * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -13,7 +13,7 @@ * */ -/* Note: part of the code below is inspired by libupskirt written by +/* Note: part of the code below is inspired by libupskirt written by * Natacha Porté. Original copyright message follows: * * Copyright (c) 2008, Natacha Porté @@ -109,7 +109,7 @@ static Entry *g_current; static QCString g_fileName; static int g_lineNr; static int g_indentLevel=0; // 0 is outside markdown, -1=page level -static const char g_utf8_nbsp[3] = {'\xc2', '\xa0', '\0'}; // UTF-8 nbsp +static const uchar g_utf8_nbsp[3] = { 0xc2, 0xa0, 0}; // UTF-8 nbsp static const char *g_doxy_nsbp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp //---------- @@ -209,11 +209,11 @@ static QCString isBlockCommand(const char *data,int offset,int size) { return "}"; } - else if (blockName=="dot" || - blockName=="code" || + else if (blockName=="dot" || + blockName=="code" || blockName=="msc" || - blockName=="verbatim" || - blockName=="latexonly" || + blockName=="verbatim" || + blockName=="latexonly" || blockName=="htmlonly" || blockName=="xmlonly" || blockName=="rtfonly" || @@ -254,12 +254,12 @@ static int findEmphasisChar(const char *data, int size, char c, int c_size) while (i<size) { - while (i<size && data[i]!=c && data[i]!='`' && + while (i<size && data[i]!=c && data[i]!='`' && data[i]!='\\' && data[i]!='@' && data[i]!='\n') i++; //printf("findEmphasisChar: data=[%s] i=%d c=%c\n",data,i,data[i]); - // not counting escaped chars or characters that are unlikely + // not counting escaped chars or characters that are unlikely // to appear as the end of the emphasis char if (i>0 && ignoreCloseEmphChar(i-1)) { @@ -356,9 +356,9 @@ static int processEmphasis1(GrowBuf &out, const char *data, int size, char c) while (i<size) { len = findEmphasisChar(data+i, size-i, c, 1); - if (len==0) return 0; + if (len==0) return 0; i+=len; - if (i>=size) return 0; + if (i>=size) return 0; if (i+1<size && data[i+1]==c) { @@ -389,7 +389,7 @@ static int processEmphasis2(GrowBuf &out, const char *data, int size, char c) return 0; } i += len; - if (i+1<size && data[i]==c && data[i+1]==c && i && data[i-1]!=' ' && + if (i+1<size && data[i]==c && data[i+1]==c && i && data[i-1]!=' ' && data[i-1]!='\n' ) { @@ -406,7 +406,7 @@ static int processEmphasis2(GrowBuf &out, const char *data, int size, char c) } /** Parsing triple emphasis. - * Finds the first closing tag, and delegates to the other emph + * Finds the first closing tag, and delegates to the other emph */ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c) { @@ -503,7 +503,7 @@ static int processQuoted(GrowBuf &out,const char *data,int,int size) { int i=1; int nl=0; - while (i<size && data[i]!='"' && nl<2) + while (i<size && data[i]!='"' && nl<2) { if (data[i]=='\n') nl++; i++; @@ -622,7 +622,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) if (size>2 && c!='~' && data[1]!=c) // _bla or *bla { // whitespace cannot follow an opening emphasis - if (data[1]==' ' || data[1]=='\n' || + if (data[1]==' ' || data[1]=='\n' || (ret = processEmphasis1(out, data+1, size-1, c)) == 0) { return 0; @@ -631,7 +631,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) } if (size>3 && data[1]==c && data[2]!=c) // __bla or **bla { - if (data[2]==' ' || data[2]=='\n' || + if (data[2]==' ' || data[2]=='\n' || (ret = processEmphasis2(out, data+2, size-2, c)) == 0) { return 0; @@ -640,7 +640,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) } if (size>4 && c!='~' && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla { - if (data[3]==' ' || data[3]=='\n' || + if (data[3]==' ' || data[3]=='\n' || (ret = processEmphasis3(out, data+3, size-3, c)) == 0) { return 0; @@ -652,7 +652,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) static void writeMarkdownImage(GrowBuf &out, const char *fmt, bool explicitTitle, QCString title, QCString content, QCString link, FileDef *fd) { - out.addStr("@image "); + out.addStr("@image{inline} "); out.addStr(fmt); out.addStr(" "); out.addStr(link.mid(fd ? 0 : 5)); @@ -833,7 +833,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) title = lr->title; //printf("processLink: ref: link={%s} title={%s}\n",link.data(),title.data()); } - else // reference not found! + else // reference not found! { //printf("processLink: ref {%s} do not exist\n",link.lower().data()); return 0; @@ -868,22 +868,20 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } if (isToc) // special case for [TOC] { - int level = Config_getInt(TOC_INCLUDE_HEADINGS); - if (level > 0 && level <=5) + int toc_level = Config_getInt(TOC_INCLUDE_HEADINGS); + if (toc_level > 0 && toc_level <=5) { - char levStr[10]; - sprintf(levStr,"%d",level); out.addStr("@tableofcontents{html:"); - out.addStr(levStr); + out.addStr(QCString().setNum(toc_level)); out.addStr("}"); } } - else if (isImageLink) + else if (isImageLink) { bool ambig; FileDef *fd=0; if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1 || - (fd=findFileDef(Doxygen::imageNameDict,link,ambig))) + (fd=findFileDef(Doxygen::imageNameLinkedMap,link,ambig))) // assume doxygen symbol link or local image link { writeMarkdownImage(out, "html", explicitTitle, title, content, link, fd); @@ -911,12 +909,26 @@ static int processLink(GrowBuf &out,const char *data,int,int size) { SrcLangExt lang = getLanguageFromFileName(link); int lp=-1; - if ((lp=link.find("@ref "))!=-1 || (lp=link.find("\\ref "))!=-1 || (lang==SrcLangExt_Markdown && !isURL(link))) + if ((lp=link.find("@ref "))!=-1 || (lp=link.find("\\ref "))!=-1 || (lang==SrcLangExt_Markdown && !isURL(link))) // assume doxygen symbol link { if (lp==-1) // link to markdown page { out.addStr("@ref "); + if (!(Portable::isAbsolutePath(link) || isURL(link))) + { + QFileInfo forg(link); + if (!(forg.exists() && forg.isReadable())) + { + QFileInfo fi(g_fileName); + QCString mdFile = g_fileName.left(g_fileName.length()-fi.fileName().length()) + link; + QFileInfo fmd(mdFile); + if (fmd.exists() && fmd.isReadable()) + { + link = fmd.absFilePath().data(); + } + } + } } out.addStr(link); out.addStr(" \""); @@ -930,7 +942,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } out.addStr("\""); } - else if (link.find('/')!=-1 || link.find('.')!=-1 || link.find('#')!=-1) + else if (link.find('/')!=-1 || link.find('.')!=-1 || link.find('#')!=-1) { // file/url link out.addStr("<a href=\""); out.addStr(link); @@ -971,9 +983,9 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s int nl=0; for (end=nb; end<size && i<nb && nl<2; end++) { - if (data[end]=='`') + if (data[end]=='`') { - i++; + i++; } else if (data[end]=='\n') { @@ -991,7 +1003,7 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s } else { - i=0; + i=0; } } if (i < nb && end >= size) @@ -1038,7 +1050,7 @@ static void addStrEscapeUtf8Nbsp(GrowBuf &out,const char *s,int len) } else // escape needed -> slow { - out.addStr(substitute(QCString(s).left(len),g_doxy_nsbp,g_utf8_nbsp)); + out.addStr(substitute(QCString(s).left(len),g_doxy_nsbp,(const char *)g_utf8_nbsp)); } } @@ -1124,9 +1136,9 @@ static int isHeaderline(const char *data, int size, bool allowAdjustLevel) if (allowAdjustLevel && level==1 && g_indentLevel==-1) { // In case a page starts with a header line we use it as title, promoting it to @page. - // We set g_indentLevel to -1 to promoting the other sections if they have a deeper + // We set g_indentLevel to -1 to promoting the other sections if they have a deeper // nesting level than the page header, i.e. @section..@subsection becomes @page..@section. - // In case a section at the same level is found (@section..@section) however we need + // In case a section at the same level is found (@section..@section) however we need // to undo this (and the result will be @page..@section). g_indentLevel=0; } @@ -1151,14 +1163,14 @@ static bool isBlockQuote(const char *data,int size,int indent) { // count >'s and skip spaces int level=0; - while (i<size && (data[i]=='>' || data[i]==' ')) + while (i<size && (data[i]=='>' || data[i]==' ')) { if (data[i]=='>') level++; i++; } - // last characters should be a space or newline, + // last characters should be a space or newline, // so a line starting with >= does not match - return level>0 && i<size && ((data[i-1]==' ') || data[i]=='\n'); + return level>0 && i<size && ((data[i-1]==' ') || data[i]=='\n'); } else // too much indentation -> code block { @@ -1224,7 +1236,7 @@ static int isLinkRef(const char *data,int size, i++; while (i<size && data[i]==' ') i++; } - if (i>=size) + if (i>=size) { //printf("end of isLinkRef while looking for title! i=%d\n",i); return i; // end of buffer while looking for the optional title @@ -1265,7 +1277,7 @@ static int isHRuler(const char *data,int size) while (i<size && data[i]==' ') i++; if (i>=size) return 0; // empty line char c=data[i]; - if (c!='*' && c!='-' && c!='_') + if (c!='*' && c!='-' && c!='_') { return 0; // not a hrule character } @@ -1319,13 +1331,13 @@ static int isAtxHeader(const char *data,int size, // find start of header text and determine heading level while (i<size && data[i]==' ') i++; - if (i>=size || data[i]!='#') + if (i>=size || data[i]!='#') { return 0; } while (i<size && level<6 && data[i]=='#') i++,level++; while (i<size && data[i]==' ') i++,blanks++; - if (level==1 && blanks==0) + if (level==1 && blanks==0) { return 0; // special case to prevent #someid seen as a header (see bug 671395) } @@ -1397,7 +1409,7 @@ static int computeIndentExcludingListMarkers(const char *data,int size) bool isDigit=FALSE; bool isLi=FALSE; bool listMarkerSkipped=FALSE; - while (i<size && + while (i<size && (data[i]==' ' || // space (!listMarkerSkipped && // first list marker (data[i]=='+' || data[i]=='-' || data[i]=='*' || // unordered list char @@ -1407,7 +1419,7 @@ static int computeIndentExcludingListMarkers(const char *data,int size) ) ) ) - ) + ) { if (isDigit) // skip over ordered list marker '10. ' { @@ -1485,7 +1497,7 @@ static bool isFencedCodeBlock(const char *data,int size,int refIndent, int endTildes=0; while (i<size && data[i]==tildaChar) endTildes++,i++; while (i<size && data[i]==' ') i++; - if (i==size || data[i]=='\n') + if (i==size || data[i]=='\n') { offset=i; return endTildes==startTildes; @@ -1514,7 +1526,7 @@ static bool isCodeBlock(const char *data,int offset,int size,int &indent) //printf("only spaces at the end of a comment block\n"); return FALSE; } - + i=offset; int nl=0; int nl_pos[3]; @@ -1544,7 +1556,7 @@ static bool isCodeBlock(const char *data,int offset,int size,int &indent) // determine the indent of line -2 indent=computeIndentExcludingListMarkers(data+nl_pos[2],nl_pos[1]-nl_pos[2]); - + //printf(">isCodeBlock local_indent %d>=%d+4=%d\n", // indent0,indent2,indent0>=indent2+4); // if the difference is >4 spaces -> code block @@ -1617,7 +1629,7 @@ static bool isTableBlock(const char *data,int size) // the first line should have at least two columns separated by '|' int i = findTableColumns(data,size,start,end,cc0); - if (i>=size || cc0<1) + if (i>=size || cc0<1) { //printf("isTableBlock: no |'s in the header\n"); return FALSE; @@ -1665,7 +1677,7 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) // write table header, in range [start..end] out.addStr("<tr>"); #endif - + // read cell alignments int ret = findTableColumns(data+i,size-i,start,end,cc); k=0; @@ -1679,12 +1691,12 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) if (!startFound) { if (data[j]==':') { leftMarker=TRUE; startFound=TRUE; } - if (data[j]=='-') startFound=TRUE; + if (data[j]=='-') startFound=TRUE; //printf(" data[%d]=%c startFound=%d\n",j,data[j],startFound); } if (data[j]=='-') rightMarker=FALSE; else if (data[j]==':') rightMarker=TRUE; - if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) + if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) { if (k<columns) { @@ -1753,7 +1765,7 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) } out.addStr(">"); } - if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) + if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) { columnStart=j+1; k++; @@ -1802,7 +1814,7 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) int rowNum = 1; while (i<size) { - int ret = findTableColumns(data+i,size-i,start,end,cc); + ret = findTableColumns(data+i,size-i,start,end,cc); if (cc!=columns) break; // end of table j=start+i; @@ -1812,7 +1824,7 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) rowContents->insert(k, new TableCell); while (j<=end+i) { - if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) + if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) { // do the column span test before stripping white space // || is spanning columns, | | is not @@ -1820,7 +1832,7 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) rowContents->at(k)->cellText = rowContents->at(k)->cellText.stripWhiteSpace(); k++; rowContents->insert(k, new TableCell); - } // if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) + } // if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) else { rowContents->at(k)->cellText += data[j]; @@ -1957,20 +1969,15 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) QCString hTag; if (level<5 && !id.isEmpty()) { - SectionInfo::SectionType type = SectionInfo::Anchor; switch(level) { - case 1: out.addStr("@section "); - type=SectionInfo::Section; + case 1: out.addStr("@section "); break; - case 2: out.addStr("@subsection "); - type=SectionInfo::Subsection; + case 2: out.addStr("@subsection "); break; - case 3: out.addStr("@subsubsection "); - type=SectionInfo::Subsubsection; + case 3: out.addStr("@subsubsection "); break; - default: out.addStr("@paragraph "); - type=SectionInfo::Paragraph; + default: out.addStr("@paragraph "); break; } out.addStr(id); @@ -1986,7 +1993,7 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) } hTag.sprintf("h%d",level); out.addStr("<"+hTag+">"); - out.addStr(header); + out.addStr(header); out.addStr("</"+hTag+">\n"); } } @@ -2021,7 +2028,7 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size) else if (j>0 && data[j-1]=='>') indent=j+1; j++; } - if (j>0 && data[j-1]=='>' && + if (j>0 && data[j-1]=='>' && !(j==size || data[j]=='\n')) // disqualify last > if not followed by space { indent--; @@ -2072,7 +2079,7 @@ static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent) while (j<end && data[j]==' ') j++,indent++; //printf("j=%d end=%d indent=%d refIndent=%d tabSize=%d data={%s}\n", // j,end,indent,refIndent,Config_getInt(TAB_SIZE),QCString(data+i).left(end-i-1).data()); - if (j==end-1) // empty line + if (j==end-1) // empty line { emptyLines++; i=end; @@ -2094,7 +2101,7 @@ static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent) break; } } - out.addStr("@endverbatim\n"); + out.addStr("@endverbatim\n"); while (emptyLines>0) // write skipped empty lines { // add empty line @@ -2159,7 +2166,7 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, end++; } } - else if (nb==0 && data[end-1]=='`') + else if (nb==0 && data[end-1]=='`') { while (end<=size && data[end-1]=='`') end++,nb++; } @@ -2262,7 +2269,7 @@ static QCString processBlocks(const QCString &s,int indent) // get indent for the first line end = i+1; int sp=0; - while (end<=size && data[end-1]!='\n') + while (end<=size && data[end-1]!='\n') { if (data[end-1]==' ') sp++; end++; @@ -2299,7 +2306,7 @@ static QCString processBlocks(const QCString &s,int indent) { //printf("Found header at %d-%d\n",i,end); while (pi<size && data[pi]==' ') pi++; - QCString header,id; + QCString header; convertStringFragment(header,data+pi,i-pi-1); id = extractTitleId(header, level); //printf("header='%s' is='%s'\n",header.data(),id.data()); @@ -2421,7 +2428,7 @@ static QCString extractPageTitle(QCString &docs,QCString &id) const char *data = docs.data(); int i=0; int size=docs.size(); - while (i<size && (data[i]==' ' || data[i]=='\n')) + while (i<size && (data[i]==' ' || data[i]=='\n')) { if (data[i]=='\n') ln++; i++; @@ -2472,7 +2479,7 @@ static QCString detab(const QCString &s,int &refIndent) int minIndent=maxIndent; while (i<size) { - char c = data[i++]; + signed char c = (signed char)data[i++]; switch(c) { case '\t': // expand tab @@ -2480,7 +2487,7 @@ static QCString detab(const QCString &s,int &refIndent) int stop = tabSize - (col%tabSize); //printf("expand at %d stop=%d\n",col,stop); col+=stop; - while (stop--) out.addChar(' '); + while (stop--) out.addChar(' '); } break; case '\n': // reset column counter @@ -2494,8 +2501,8 @@ static QCString detab(const QCString &s,int &refIndent) default: // non-whitespace => update minIndent if (c<0 && i<size) // multibyte sequence { - // special handling of the UTF-8 nbsp character 0xc2 0xa0 - if (c == '\xc2' && data[i] == '\xa0') + // special handling of the UTF-8 nbsp character 0xC2 0xA0 + if ((uchar)c == 0xC2 && (uchar)(data[i]) == 0xA0) { out.addStr(g_doxy_nsbp); i++; @@ -2588,9 +2595,52 @@ QCString markdownFileNameToId(const QCString &fileName) return "md_"+baseName; } +//--------------------------------------------------------------------------- + +QCString processMarkdownForCommentBlock(const QCString &comment, + const QCString &fileName, + int lineNr) +{ + if (!comment.isEmpty() && Doxygen::markdownSupport) + { + QCString result = processMarkdown(fileName,lineNr,0,comment); + const char *p = result.data(); + if (p) + { + while (*p==' ') p++; // skip over spaces + while (*p=='\n') p++; // skip over newlines + if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br> + } + if (p>result.data()) + { + // strip part of the input + result = result.mid(p-result.data()); + } + return result; + } + else + { + return comment; + } +} + +//--------------------------------------------------------------------------- + +struct MarkdownOutlineParser::Private +{ + CommentScanner commentScanner; +}; + +MarkdownOutlineParser::MarkdownOutlineParser() : p(std::make_unique<Private>()) +{ +} + +MarkdownOutlineParser::~MarkdownOutlineParser() +{ +} -void MarkdownOutlineParser::parseInput(const char *fileName, - const char *fileBuf, +void MarkdownOutlineParser::parseInput(const char *fileName, + const char *fileBuf, const std::shared_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) @@ -2617,11 +2667,13 @@ void MarkdownOutlineParser::parseInput(const char *fileName, QFileInfo(mdfileAsMainPage).absFilePath()) // file reference with path ) { + docs.prepend("@anchor " + id + "\n"); docs.prepend("@mainpage "+title+"\n"); } else if (id=="mainpage" || id=="index") { if (title.isEmpty()) title = titleFn; + docs.prepend("@anchor " + id + "\n"); docs.prepend("@mainpage "+title+"\n"); } else @@ -2632,7 +2684,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName, } int lineNr=1; - // even without markdown support enabled, we still + // even without markdown support enabled, we still // parse markdown files as such bool markdownEnabled = Doxygen::markdownSupport; Doxygen::markdownSupport = TRUE; @@ -2640,8 +2692,8 @@ void MarkdownOutlineParser::parseInput(const char *fileName, Protection prot=Public; bool needsEntry = FALSE; int position=0; - QCString processedDocs = preprocessCommentBlock(docs,fileName,lineNr); - while (parseCommentBlock( + QCString processedDocs = processMarkdownForCommentBlock(docs,fileName,lineNr); + while (p->commentScanner.parseCommentBlock( this, current.get(), processedDocs, diff --git a/src/markdown.h b/src/markdown.h index 3ffd155..bc1e9bb 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -25,10 +25,23 @@ class Entry; QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &s); QCString markdownFileNameToId(const QCString &fileName); +/** Performs markdown processing for a comment block if markdown processing is enabled. + * @param[in] comment A string representing the actual comment block. + * Note that leading *'s should already be stripped from the comment block. + * @param[in] fileName The name of the file in which the comment is found. + * Mainly used for producing warnings. + * @param[in] lineNr The line number at which the comment block was found. + * @returns The processed comment block + */ +QCString processMarkdownForCommentBlock(const QCString &comment, + const QCString &fileName, + int lineNr); + class MarkdownOutlineParser : public OutlineParserInterface { public: - virtual ~MarkdownOutlineParser() {} + MarkdownOutlineParser(); + virtual ~MarkdownOutlineParser(); void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char *fileName, @@ -38,6 +51,9 @@ class MarkdownOutlineParser : public OutlineParserInterface QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &) const { return FALSE; } void parsePrototype(const char *text); + private: + struct Private; + std::unique_ptr<Private> p; }; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 1c935ac..39b8f70 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -36,7 +36,6 @@ #include "dotcallgraph.h" #include "searchindex.h" #include "parserintf.h" -#include "objcache.h" #include "vhdldocgen.h" #include "arguments.h" @@ -944,30 +943,6 @@ static bool writeDefArgumentList(OutputList &ol,const Definition *scope,const Me return FALSE; // member has no function like argument list } - // simple argument list for tcl - if (md->getLanguage()==SrcLangExt_Tcl) - { - if (defArgList.empty()) return FALSE; - ol.endMemberDocName(); - ol.startParameterList(FALSE); - ol.startParameterType(TRUE,0); - ol.endParameterType(); - ol.startParameterName(FALSE); - for (const Argument &a : defArgList) - { - if (a.defval.isEmpty()) - { - ol.docify(a.name+" "); - } - else - { - ol.docify("?"+a.name+"? "); - } - } - ol.endParameterName(TRUE,FALSE,FALSE); - return TRUE; - } - if (!md->isDefine()) ol.docify(" "); //printf("writeDefArgList(%d)\n",defArgList->count()); @@ -1438,7 +1413,7 @@ MemberDefImpl::IMPL::~IMPL() delete classSectionSDict; } -void MemberDefImpl::IMPL::init(Definition *def, +void MemberDefImpl::IMPL::init(Definition *d, const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberType mt,const ArgumentList &tal, @@ -1473,7 +1448,7 @@ void MemberDefImpl::IMPL::init(Definition *def, type=removeRedundantWhiteSpace(type); args=a; args=removeRedundantWhiteSpace(args); - if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args; + if (type.isEmpty()) decl=d->name()+args; else decl=type+" "+d->name()+args; memberGroup=0; virt=v; @@ -1503,7 +1478,7 @@ void MemberDefImpl::IMPL::init(Definition *def, // convert function declaration arguments (if any) if (!args.isEmpty()) { - stringToArgumentList(def->getLanguage(),args,declArgList,&extraTypeChars); + stringToArgumentList(d->getLanguage(),args,declArgList,&extraTypeChars); //printf("setDeclArgList %s to %s const=%d\n",args.data(), // argListToString(declArgList).data(),declArgList->constSpecifier); } @@ -1519,7 +1494,7 @@ void MemberDefImpl::IMPL::init(Definition *def, hasDocumentedParams = FALSE; hasDocumentedReturnType = FALSE; docProvider = 0; - isDMember = def->getDefFileName().right(2).lower()==".d"; + isDMember = d->getDefFileName().right(2).lower()==".d"; } @@ -2640,7 +2615,6 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, ol.writeDoc(rootNode,getOuterScope()?getOuterScope():d,this); if (detailsVisible) { - static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); //ol.endEmphasis(); @@ -3337,8 +3311,6 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml, { // if this member is in a group find the real scope name. bool hasParameterList = FALSE; - bool inFile = container->definitionType()==Definition::TypeFile; - bool hasDocs = isDetailedSectionVisible(inGroup,inFile); //printf("MemberDefImpl::writeDocumentation(): name='%s' hasDocs='%d' containerType=%d inGroup=%d sectionLinkable=%d\n", // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable()); @@ -3494,7 +3466,6 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml, if (!Config_getBool(HIDE_SCOPE_NAMES)) { bool first=TRUE; - SrcLangExt lang = getLanguage(); if (!m_impl->defTmpArgLists.empty() && lang==SrcLangExt_Cpp) // definition has explicit template parameter declarations { @@ -3567,9 +3538,9 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml, { ldef=ldef.left(dp+1); } - int l=ldef.length(); + int dl=ldef.length(); //printf("start >%s<\n",ldef.data()); - int i=l-1; + i=dl-1; while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--; while (i>=0 && isspace((uchar)ldef.at(i))) i--; if (i>0) @@ -4073,11 +4044,34 @@ void MemberDefImpl::warnIfUndocumented() const } } +static QCString removeReturnTypeKeywords(const QCString &s) +{ + QCString result = s; + bool done; + do + { + done=true; + if (result.stripPrefix("constexpr ") || + result.stripPrefix("consteval ") || + result.stripPrefix("virtual ") || + result.stripPrefix("static ") || + result.stripPrefix("volatile ")) + { + done=false; + } + } + while (!done); + return result; +} + void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const { if (!Config_getBool(WARN_NO_PARAMDOC)) return; - QCString returnType = typeString(); + QCString returnType = removeReturnTypeKeywords(typeString()); bool isPython = getLanguage()==SrcLangExt_Python; + bool isFortran = getLanguage()==SrcLangExt_Fortran; + bool isFortranSubroutine = isFortran && returnType.find("subroutine")!=-1; + bool isVoidReturn = returnType=="void"; if (!m_impl->hasDocumentedParams && hasParamCommand) { @@ -4139,8 +4133,8 @@ void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturn else if ( // see if return type is documented in a function w/o return type hasReturnCommand && ( - returnType=="void" || // void return type - returnType.find("subroutine")!=-1 || // fortran subroutine + isVoidReturn || // void return type + isFortranSubroutine || // fortran subroutine isConstructor() || // a constructor isDestructor() // or destructor ) @@ -4151,10 +4145,10 @@ void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturn } else if ( // see if return needs to documented m_impl->hasDocumentedReturnType || - returnType=="void" || // void return type - returnType.find("subroutine")!=-1 || // fortran subroutine - isConstructor() || // a constructor - isDestructor() // or destructor + isVoidReturn || // void return type + isFortranSubroutine || // fortran subroutine + isConstructor() || // a constructor + isDestructor() // or destructor ) { m_impl->hasDocumentedReturnType = TRUE; @@ -4369,7 +4363,7 @@ MemberDef *MemberDefImpl::createTemplateInstanceMember( imd->setArgumentList(actualArgList); imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs)); imd->setBodyDef(getBodyDef()); - imd->setBodySegment(getStartBodyLine(),getEndBodyLine()); + imd->setBodySegment(getDefLine(),getStartBodyLine(),getEndBodyLine()); //imd->setBodyMember(this); // TODO: init other member variables (if needed). @@ -4456,7 +4450,7 @@ void MemberDefImpl::addListReference(Definition *) memArgs = argsString(); } } - const std::vector<ListItemInfo> &xrefItems = xrefListItems(); + const std::vector<RefItem*> &xrefItems = xrefListItems(); addRefItem(xrefItems, qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624) memLabel, @@ -4467,7 +4461,7 @@ const MemberList *MemberDefImpl::getSectionList() const { const Definition *d= resolveAlias()->getOuterScope(); char key[20]; - sprintf(key,"%p",d); + sprintf(key,"%p",(void*)d); return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0; } @@ -4476,7 +4470,7 @@ void MemberDefImpl::setSectionList(MemberList *sl) //printf("MemberDefImpl::setSectionList(%p,%p) name=%s\n",d,sl,name().data()); const Definition *d= resolveAlias()->getOuterScope(); char key[20]; - sprintf(key,"%p",d); + sprintf(key,"%p",(void*)d); if (m_impl->classSectionSDict==0) { m_impl->classSectionSDict = new SDict<MemberList>(7); @@ -4550,7 +4544,7 @@ void MemberDefImpl::writeTagFile(FTextStream &tagFile) const tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl; } tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; - tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl; + tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</anchorfile>" << endl; tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl; QCString idStr = id(); if (!idStr.isEmpty()) @@ -4571,7 +4565,7 @@ void MemberDefImpl::writeTagFile(FTextStream &tagFile) const { tagFile << " <enumvalue file=\"" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension); tagFile << "\" anchor=\"" << convertToXML(fmd->anchor()); - QCString idStr = fmd->id(); + idStr = fmd->id(); if (!idStr.isEmpty()) { tagFile << "\" clangid=\"" << convertToXML(idStr); @@ -4606,11 +4600,6 @@ void MemberDefImpl::_computeIsConstructor() m_isConstructorCached = 2; // TRUE return; } - else if (getLanguage()==SrcLangExt_Tcl) // for Tcl - { - m_isConstructorCached = name()=="constructor" ? 2 : 1; - return; - } else // for other languages { QCString locName = getClassDef()->localName(); @@ -4651,10 +4640,6 @@ void MemberDefImpl::_computeIsDestructor() { isDestructor = name()=="__destruct"; } - else if (getLanguage()==SrcLangExt_Tcl) // for Tcl - { - isDestructor = name()=="destructor"; - } else if (name()=="__del__" && getLanguage()==SrcLangExt_Python) // for Python { @@ -6032,14 +6017,14 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1) { //printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine()); - mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine()); + mdef->setBodySegment(mdec->getDefLine(),mdec->getStartBodyLine(),mdec->getEndBodyLine()); mdef->setBodyDef(mdec->getBodyDef()); //mdef->setBodyMember(mdec); } else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1) { //printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine()); - mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine()); + mdec->setBodySegment(mdef->getDefLine(),mdef->getStartBodyLine(),mdef->getEndBodyLine()); mdec->setBodyDef(mdef->getBodyDef()); //mdec->setBodyMember(mdef); } diff --git a/src/membergroup.cpp b/src/membergroup.cpp index 05c38c3..930426b 100644 --- a/src/membergroup.cpp +++ b/src/membergroup.cpp @@ -152,10 +152,10 @@ void MemberGroup::addGroupedInheritedMembers(OutputList &ol,const ClassDef *cd, const MemberList *ml = md->getSectionList(); if (ml && lt==ml->listType()) { - MemberList ml(lt); - ml.append(md); - ml.countDecMembers(); - ml.writePlainDeclarations(ol,cd,0,0,0,inheritedFrom,inheritId); + MemberList mml(lt); + mml.append(md); + mml.countDecMembers(); + mml.writePlainDeclarations(ol,cd,0,0,0,inheritedFrom,inheritId); } } } @@ -356,7 +356,7 @@ void MemberGroup::findSectionsInDocumentation(const Definition *d) memberList->findSectionsInDocumentation(d); } -void MemberGroup::setRefItems(const std::vector<ListItemInfo> &sli) +void MemberGroup::setRefItems(const std::vector<RefItem*> &sli) { m_xrefListItems.insert(m_xrefListItems.end(), sli.cbegin(), sli.cend()); } @@ -368,7 +368,7 @@ void MemberGroup::writeTagFile(FTextStream &tagFile) //-------------------------------------------------------------------------- -void MemberGroupInfo::setRefItems(const std::vector<ListItemInfo> &sli) +void MemberGroupInfo::setRefItems(const std::vector<RefItem*> &sli) { m_sli.insert(m_sli.end(), sli.cbegin(), sli.cend()); } diff --git a/src/membergroup.h b/src/membergroup.h index aa30063..c1433cf 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -35,7 +35,7 @@ class GroupDef; class OutputList; class Definition; class FTextStream; -struct ListItemInfo; +class RefItem; /** A class representing a group of members. */ class MemberGroup @@ -81,7 +81,7 @@ class MemberGroup int countInheritableMembers(const ClassDef *inheritedFrom) const; void setInGroup(bool b); void addListReferences(Definition *d); - void setRefItems(const std::vector<ListItemInfo> &sli); + void setRefItems(const std::vector<RefItem*> &sli); MemberList *members() const { return memberList; } QCString anchor() const; @@ -98,10 +98,9 @@ class MemberGroup bool inSameSection = 0; int m_numDecMembers = 0; int m_numDocMembers = 0; - const Definition *m_parent = 0; QCString m_docFile; int m_docLine = 0; - std::vector<ListItemInfo> m_xrefListItems; + std::vector<RefItem*> m_xrefListItems; }; /** A list of MemberGroup objects. */ @@ -133,13 +132,13 @@ class MemberGroupSDict : public SIntDict<MemberGroup> /** Data collected for a member group */ struct MemberGroupInfo { - void setRefItems(const std::vector<ListItemInfo> &sli); + void setRefItems(const std::vector<RefItem*> &sli); QCString header; QCString doc; QCString docFile; int docLine = -1; QCString compoundName; - std::vector<ListItemInfo> m_sli; + std::vector<RefItem*> m_sli; }; #endif diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 278023b..8a76a1d 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -75,8 +75,15 @@ int MemberList::compareValues(const MemberDef *c1, const MemberDef *c2) const return 1; } int cmp = qstricmp(c1->name(),c2->name()); - if (cmp==0) cmp = qstricmp(c1->argsString(),c2->argsString()); - return cmp!=0 ? cmp : c1->getDefLine()-c2->getDefLine(); + if (cmp==0 && c1->argsString() && c2->argsString()) + { + cmp = qstricmp(c1->argsString(),c2->argsString()); + } + if (cmp==0) + { + cmp = c1->getDefLine()-c2->getDefLine(); + } + return cmp; } int MemberList::countInheritableMembers(const ClassDef *inheritedFrom) const @@ -412,7 +419,6 @@ void MemberList::writePlainDeclarations(OutputList &ol, ) const { //printf("----- writePlainDeclaration() ----\n"); - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); if (numDecMembers()==-1) { err("MemberList::numDecMembers()==-1, so the members of this list have not been counted. Please report as a bug.\n"); @@ -551,8 +557,7 @@ void MemberList::writePlainDeclarations(OutputList &ol, // no variables of the anonymous compound type exist. if (cd) { - MemberListIterator mli(*this); - for ( ; (md=mli.current()) ; ++mli ) + for ( mli.toFirst(); (md=mli.current()) ; ++mli ) { if (md->fromAnonymousScope() && !md->anonymousDeclShown()) { diff --git a/src/memberlist.h b/src/memberlist.h index 422c162..4038453 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -131,7 +131,7 @@ class MemberListIterator : public QListIterator<MemberDef> class MemberDict : public QDict<MemberDef> { public: - MemberDict(int size) : QDict<MemberDef>(size) {} + MemberDict(uint size) : QDict<MemberDef>(size) {} virtual ~MemberDict() {} }; @@ -139,7 +139,7 @@ class MemberDict : public QDict<MemberDef> class MemberSDict : public SDict<MemberDef> { public: - MemberSDict(int size=17) : SDict<MemberDef>(size) {} + MemberSDict(uint size=17) : SDict<MemberDef>(size) {} virtual ~MemberSDict() {} private: int compareValues(const MemberDef *item1,const MemberDef *item2) const; diff --git a/src/membername.cpp b/src/membername.cpp index 72809b3..64bf49b 100644 --- a/src/membername.cpp +++ b/src/membername.cpp @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -20,30 +20,6 @@ #include "util.h" #include "filedef.h" -MemberName::MemberName(const char *n) : QList<MemberDef>() -{ - name=n; - setAutoDelete(TRUE); -} - -MemberName::~MemberName() -{ -} - -int MemberName::compareValues(const MemberDef *m1, const MemberDef *m2) const -{ - const ClassDef *c1=m1->getClassDef(); - const ClassDef *c2=m2->getClassDef(); - const FileDef *f1=m1->getFileDef(); - const FileDef *f2=m2->getFileDef(); - if (c1 && c2) - return qstrcmp(c1->name(),c2->name()); - else if (f1 && f2) - return qstrcmp(f1->name(),f2->name()); - else - return 0; -} - MemberNameInfo::MemberNameInfo(const char *n) : QList<MemberInfo>() { name=n; @@ -60,18 +36,7 @@ int MemberNameInfo::compareValues(const MemberInfo *m1,const MemberInfo *m2) con return qstrcmp(c1->name(),c2->name()); else if (f1 && f2) return qstrcmp(f1->name(),f2->name()); - else + else return 0; } -MemberNameIterator::MemberNameIterator(const MemberName &mnlist) : - QListIterator<MemberDef>(mnlist) -{ -} - -int MemberNameSDict::compareValues(const MemberName *n1,const MemberName *n2) const -{ - return qstricmp(n1->memberName()+getPrefixIndex(n1->memberName()), - n2->memberName()+getPrefixIndex(n2->memberName()) - ); -} diff --git a/src/membername.h b/src/membername.h index 143dca1..4094132 100644 --- a/src/membername.h +++ b/src/membername.h @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -21,36 +21,20 @@ #include <qlist.h> #include "memberdef.h" #include "sortdict.h" +#include "linkedmap.h" -/** Class representing all MemberDef objects with the same name */ -class MemberName : public QList<MemberDef> +class MemberName : public std::vector< std::unique_ptr<MemberDef> > { public: - MemberName(const char *name); - ~MemberName(); - const char *memberName() const { return name; } - + MemberName(const char *name) : m_name(name) {} + const char *memberName() const { return m_name; } private: - int compareValues(const MemberDef *item1,const MemberDef *item2) const; - QCString name; + QCString m_name; }; -/** Iterator for MemberDef objects in a MemberName list. */ -class MemberNameIterator : public QListIterator<MemberDef> +/** Ordered dictionary of MemberName objects. */ +class MemberNameLinkedMap : public LinkedMap<MemberName> { - public: - MemberNameIterator( const MemberName &list); -}; - -/** Sorted dictionary of MemberName objects. */ -class MemberNameSDict : public SDict<MemberName> -{ - public: - MemberNameSDict(int size) : SDict<MemberName>(size) {} - ~MemberNameSDict() {} - - private: - int compareValues(const MemberName *item1,const MemberName *item2) const; }; /** Data associated with a MemberDef in an inheritance relation. */ @@ -64,7 +48,7 @@ struct MemberInfo Specifier virt; bool inherited; QCString scopePath; - QCString ambiguityResolutionScope; + QCString ambiguityResolutionScope; ClassDef *ambigClass; }; @@ -72,7 +56,7 @@ struct MemberInfo class MemberNameInfo : public QList<MemberInfo> { public: - MemberNameInfo(const char *name); + MemberNameInfo(const char *name); ~MemberNameInfo() {} const char *memberName() const { return name; } private: @@ -84,7 +68,7 @@ class MemberNameInfo : public QList<MemberInfo> class MemberNameInfoIterator : public QListIterator<MemberInfo> { public: - MemberNameInfoIterator(const MemberNameInfo &mnii) + MemberNameInfoIterator(const MemberNameInfo &mnii) : QListIterator<MemberInfo>(mnii) {} }; @@ -92,7 +76,7 @@ class MemberNameInfoIterator : public QListIterator<MemberInfo> class MemberNameInfoSDict : public SDict<MemberNameInfo> { public: - MemberNameInfoSDict(int size) : SDict<MemberNameInfo>(size) {} + MemberNameInfoSDict(uint size) : SDict<MemberNameInfo>(size) {} ~MemberNameInfoSDict() {} private: int compareValues(const MemberNameInfo *item1,const MemberNameInfo *item2) const diff --git a/src/message.cpp b/src/message.cpp index d8f83ef..4e07d56 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -128,7 +128,7 @@ static void format_warn(const char *file,int line,const char *text) if (file) // get version from file name { bool ambig; - FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig); + FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,file,ambig); if (fd) { versionSubst = fd->getVersion(); @@ -174,7 +174,7 @@ static void do_warn(bool enabled, const char *file, int line, const char *prefix int l=0; if (prefix) { - l=strlen(prefix); + l=(int)strlen(prefix); } // determine needed buffersize based on: // format + arguments @@ -259,7 +259,7 @@ void term(const char *fmt, ...) va_end(args); if (warnFile != stderr) { - for (int i = 0; i < strlen(error_str); i++) fprintf(warnFile, " "); + for (int i = 0; i < (int)strlen(error_str); i++) fprintf(warnFile, " "); fprintf(warnFile, "%s\n", "Exiting..."); } exit(1); diff --git a/src/message.h b/src/message.h index 7b12ba8..5f8c9db 100644 --- a/src/message.h +++ b/src/message.h @@ -21,17 +21,26 @@ #include <stdio.h> #include <stdarg.h> -extern void msg(const char *fmt, ...); -extern void warn(const char *file,int line,const char *fmt, ...); -extern void va_warn(const char *file,int line,const char *fmt, va_list args); +#ifdef __GNUC__ +#define PRINTFLIKE(FORMAT, PARAM ) __attribute__((format(printf, FORMAT, PARAM))) +#else +#define PRINTFLIKE(FORMAT, PARAM ) +#endif + +extern void msg(const char *fmt, ...) PRINTFLIKE(1,2); +extern void warn(const char *file,int line,const char *fmt, ...) PRINTFLIKE(3, 4); +extern void va_warn(const char* file, int line, const char* fmt, va_list args); extern void warn_simple(const char *file,int line,const char *text); -extern void warn_undoc(const char *file,int line,const char *fmt, ...); -extern void warn_doc_error(const char *file,int line,const char *fmt, ...); -extern void warn_uncond(const char *fmt, ...); -extern void err(const char *fmt, ...); -extern void err_full(const char *file,int line,const char *fmt, ...); -extern void term(const char *fmt, ...); +extern void warn_undoc(const char *file,int line,const char *fmt, ...) PRINTFLIKE(3, 4); +extern void warn_doc_error(const char *file,int line,const char *fmt, ...) PRINTFLIKE(3, 4); +extern void warn_uncond(const char *fmt, ...) PRINTFLIKE(1, 2); +extern void err(const char *fmt, ...) PRINTFLIKE(1, 2); +extern void err_full(const char *file,int line,const char *fmt, ...) PRINTFLIKE(3, 4); +extern void term(const char *fmt, ...) PRINTFLIKE(1, 2); void initWarningFormat(); extern void printlex(int dbg, bool enter, const char *lexName, const char *fileName); + +#undef PRINTFLIKE + #endif diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 220f300..50e50a6 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -370,7 +370,7 @@ void NamespaceDefImpl::findSectionsInDocumentation() void NamespaceDefImpl::insertUsedFile(FileDef *fd) { if (fd==0) return; - if (files.find(fd)==-1) + if (files.find(fd)==-1) { if (Config_getBool(SORT_MEMBER_DOCS)) files.inSort(fd); @@ -471,7 +471,7 @@ void NamespaceDefImpl::insertMember(MemberDef *md) // isInline(),hasDocumentation()); if (md->isHidden()) return; - // if this is an inline namespace that is not documented, then insert the + // if this is an inline namespace that is not documented, then insert the // member in the parent scope instead if (isInline() && !hasDocumentation()) { @@ -501,44 +501,44 @@ void NamespaceDefImpl::insertMember(MemberDef *md) allMemberList = new MemberList(MemberListType_allMembersList); m_memberLists.append(allMemberList); } - allMemberList->append(md); + allMemberList->append(md); if (m_allMembersDict==0) { m_allMembersDict = new MemberSDict; } //printf("%s::m_allMembersDict->append(%s)\n",name().data(),md->localName().data()); - m_allMembersDict->append(md->localName(),md); + m_allMembersDict->append(md->localName(),md); //::addNamespaceMemberNameToIndex(md); //static bool sortBriefDocs=Config_getBool(SORT_BRIEF_DOCS); switch(md->memberType()) { - case MemberType_Variable: + case MemberType_Variable: addMemberToList(MemberListType_decVarMembers,md); addMemberToList(MemberListType_docVarMembers,md); break; - case MemberType_Function: + case MemberType_Function: addMemberToList(MemberListType_decFuncMembers,md); addMemberToList(MemberListType_docFuncMembers,md); break; - case MemberType_Typedef: + case MemberType_Typedef: addMemberToList(MemberListType_decTypedefMembers,md); addMemberToList(MemberListType_docTypedefMembers,md); break; - case MemberType_Sequence: + case MemberType_Sequence: addMemberToList(MemberListType_decSequenceMembers,md); addMemberToList(MemberListType_docSequenceMembers,md); break; - case MemberType_Dictionary: + case MemberType_Dictionary: addMemberToList(MemberListType_decDictionaryMembers,md); addMemberToList(MemberListType_docDictionaryMembers,md); break; - case MemberType_Enumeration: + case MemberType_Enumeration: addMemberToList(MemberListType_decEnumMembers,md); addMemberToList(MemberListType_docEnumMembers,md); break; - case MemberType_EnumValue: + case MemberType_EnumValue: break; - case MemberType_Define: + case MemberType_Define: addMemberToList(MemberListType_decDefineMembers,md); addMemberToList(MemberListType_docDefineMembers,md); break; @@ -555,31 +555,23 @@ void NamespaceDefImpl::insertMember(MemberDef *md) Definition *outerScope = getOuterScope(); if (outerScope) { - MemberDef *aliasMd = 0; + std::unique_ptr<MemberDef> aliasMd; if (outerScope->definitionType()==Definition::TypeNamespace) { - aliasMd = createMemberDefAlias(outerScope,md); - dynamic_cast<NamespaceDef*>(outerScope)->insertMember(aliasMd); + aliasMd.reset(createMemberDefAlias(outerScope,md)); + dynamic_cast<NamespaceDef*>(outerScope)->insertMember(aliasMd.get()); } else if (outerScope->definitionType()==Definition::TypeFile) { - aliasMd = createMemberDefAlias(outerScope,md); - dynamic_cast<FileDef*>(outerScope)->insertMember(aliasMd); + aliasMd.reset(createMemberDefAlias(outerScope,md)); + dynamic_cast<FileDef*>(outerScope)->insertMember(aliasMd.get()); } if (aliasMd) { MemberName *mn; QCString name = md->name(); - if ((mn=Doxygen::functionNameSDict->find(name))) - { - mn->append(aliasMd); - } - else - { - mn = new MemberName(name); - mn->append(aliasMd); - Doxygen::functionNameSDict->append(name,mn); - } + mn = Doxygen::functionNameLinkedMap->add(name); + mn->push_back(std::move(aliasMd)); } } } @@ -697,7 +689,7 @@ void NamespaceDefImpl::writeDetailedDescription(OutputList &ol,const QCString &t ol.popGeneratorState(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - ol.writeAnchor(0,"details"); + ol.writeAnchor(0,"details"); ol.popGeneratorState(); ol.startGroupHeader(); ol.parseText(title); @@ -841,7 +833,7 @@ void NamespaceDefImpl::writeMemberGroups(OutputList &ol) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - if ((!mg->allMembersInSameSection() || !m_subGrouping) + if ((!mg->allMembersInSameSection() || !m_subGrouping) && mg->header()!="[NOHEADER]") { mg->writeDeclarations(ol,0,this,0,0); @@ -849,7 +841,7 @@ void NamespaceDefImpl::writeMemberGroups(OutputList &ol) } } } - + void NamespaceDefImpl::writeAuthorSection(OutputList &ol) { // write Author section (Man only) @@ -978,7 +970,7 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) addNamespaceAttributes(ol); endTitle(ol,getOutputFileBase(),displayName()); ol.startContents(); - + if (Doxygen::searchIndex) { Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE); @@ -997,82 +989,82 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) { switch (lde->kind()) { - case LayoutDocEntry::BriefDesc: + case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); - break; - case LayoutDocEntry::MemberDeclStart: + break; + case LayoutDocEntry::MemberDeclStart: startMemberDeclarations(ol); - break; - case LayoutDocEntry::NamespaceClasses: + break; + case LayoutDocEntry::NamespaceClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),classSDict); } - break; - case LayoutDocEntry::NamespaceInterfaces: + break; + case LayoutDocEntry::NamespaceInterfaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),interfaceSDict); } - break; - case LayoutDocEntry::NamespaceStructs: + break; + case LayoutDocEntry::NamespaceStructs: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),structSDict); } - break; - case LayoutDocEntry::NamespaceExceptions: + break; + case LayoutDocEntry::NamespaceExceptions: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),exceptionSDict); } - break; - case LayoutDocEntry::NamespaceNestedNamespaces: + break; + case LayoutDocEntry::NamespaceNestedNamespaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),false); } - break; + break; case LayoutDocEntry::NamespaceNestedConstantGroups: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),true); } break; - case LayoutDocEntry::MemberGroups: + case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); - break; - case LayoutDocEntry::MemberDecl: + break; + case LayoutDocEntry::MemberDecl: { LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); } - break; - case LayoutDocEntry::MemberDeclEnd: + break; + case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; - case LayoutDocEntry::DetailedDesc: + case LayoutDocEntry::DetailedDesc: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeDetailedDescription(ol,ls->title(lang)); } break; - case LayoutDocEntry::MemberDefStart: + case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); - break; + break; case LayoutDocEntry::NamespaceInlineClasses: writeInlineClasses(ol); break; - case LayoutDocEntry::MemberDef: + case LayoutDocEntry::MemberDef: { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); } break; - case LayoutDocEntry::MemberDefEnd: + case LayoutDocEntry::MemberDefEnd: endMemberDocumentation(ol); break; - case LayoutDocEntry::AuthorSection: + case LayoutDocEntry::AuthorSection: writeAuthorSection(ol); break; case LayoutDocEntry::ClassIncludes: @@ -1090,16 +1082,16 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: case LayoutDocEntry::FileIncludeGraph: - case LayoutDocEntry::FileIncludedByGraph: + case LayoutDocEntry::FileIncludedByGraph: case LayoutDocEntry::FileSourceLink: case LayoutDocEntry::FileInlineClasses: - case LayoutDocEntry::GroupClasses: - case LayoutDocEntry::GroupInlineClasses: + case LayoutDocEntry::GroupClasses: + case LayoutDocEntry::GroupInlineClasses: case LayoutDocEntry::GroupNamespaces: - case LayoutDocEntry::GroupDirs: - case LayoutDocEntry::GroupNestedGroups: + case LayoutDocEntry::GroupDirs: + case LayoutDocEntry::GroupNestedGroups: case LayoutDocEntry::GroupFiles: - case LayoutDocEntry::GroupGraph: + case LayoutDocEntry::GroupGraph: case LayoutDocEntry::GroupPageDocs: case LayoutDocEntry::DirSubDirs: case LayoutDocEntry::DirFiles: @@ -1224,10 +1216,10 @@ void NamespaceDefImpl::addUsingDirective(const NamespaceDef *nd) //printf("%p: NamespaceDefImpl::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); } -const NamespaceSDict *NamespaceDefImpl::getUsedNamespaces() const -{ +const NamespaceSDict *NamespaceDefImpl::getUsedNamespaces() const +{ //printf("%p: NamespaceDefImpl::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); - return usingDirList; + return usingDirList; } void NamespaceDefImpl::addUsingDeclaration(const Definition *d) @@ -1269,11 +1261,11 @@ void NamespaceDefImpl::addListReferences() { //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); { - const std::vector<ListItemInfo> &xrefItems = xrefListItems(); + const std::vector<RefItem*> &xrefItems = xrefListItems(); addRefItem(xrefItems, qualifiedName(), - getLanguage()==SrcLangExt_Fortran ? - theTranslator->trModule(TRUE,TRUE) : + getLanguage()==SrcLangExt_Fortran ? + theTranslator->trModule(TRUE,TRUE) : theTranslator->trNamespace(TRUE,TRUE), getOutputFileBase(),displayName(), 0, @@ -1307,7 +1299,7 @@ QCString NamespaceDefImpl::displayName(bool includeScope) const result = substitute(result,"::",sep); } //printf("NamespaceDefImpl::displayName() %s->%s lang=%d\n",name().data(),result.data(),lang); - return result; + return result; } QCString NamespaceDefImpl::localName() const @@ -1378,12 +1370,12 @@ bool NamespaceSDict::declVisible() const void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title, bool const isConstantGroup,bool localName) { - + if (count()==0) return; // no namespaces in the list if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) return; - + SDict<NamespaceDef>::Iterator ni(*this); NamespaceDef *nd; diff --git a/src/namespacedef.h b/src/namespacedef.h index 3be54f2..a35f0b1 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -146,7 +146,7 @@ class NamespaceListIterator : public QListIterator<NamespaceDef> class NamespaceDict : public QDict<NamespaceDef> { public: - NamespaceDict(int size) : QDict<NamespaceDef>(size) {} + NamespaceDict(uint size) : QDict<NamespaceDef>(size) {} ~NamespaceDict() {} }; @@ -154,7 +154,7 @@ class NamespaceDict : public QDict<NamespaceDef> class NamespaceSDict : public SDict<NamespaceDef> { public: - NamespaceSDict(int size=17) : SDict<NamespaceDef>(size) {} + NamespaceSDict(uint size=17) : SDict<NamespaceDef>(size) {} ~NamespaceSDict() {} void writeDeclaration(OutputList &ol,const char *title, bool isConstantGroup=false, bool localName=FALSE); diff --git a/src/objcache.cpp b/src/objcache.cpp deleted file mode 100644 index a5180d6..0000000 --- a/src/objcache.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#include <stdio.h> -#include <assert.h> -#include <qglobal.h> -#include "objcache.h" -#if !defined(_OS_WIN32_) || defined(__MINGW32__) -#include <stdint.h> -#endif - -//---------------------------------------------------------------------- - -ObjCache::ObjCache(unsigned int logSize) - : m_head(-1), m_tail(-1), //m_numEntries(0), - m_size(1<<logSize), m_count(0), m_freeHashNodes(0), m_freeCacheNodes(0), - m_lastHandle(-1) -{ - int i; - m_cache = new CacheNode[m_size]; - m_hash = new HashNode[m_size]; - // add all items to list of free buckets - for (i=0;i<m_size-1;i++) - { - m_hash[i].nextHash = i+1; - m_cache[i].next = i+1; - } - m_misses = 0; - m_hits = 0; -} - -ObjCache::~ObjCache() -{ - delete[] m_cache; - delete[] m_hash; -} - -int ObjCache::add(void *obj,void **victim) -{ - *victim=0; - - HashNode *hnode = hashFind(obj); - //printf("hnode=%p\n",hnode); - if (hnode) // move object to the front of the LRU list, since it is used - // most recently - { - //printf("moveToFront=%d\n",hnode->index); - moveToFront(hnode->index); - m_hits++; - } - else // object not in the cache. - { - void *lruObj=0; - if (m_freeCacheNodes!=-1) // cache not full -> add element to the cache - { - // remove element from free list - int index = m_freeCacheNodes; - m_freeCacheNodes = m_cache[index].next; - - // add to head of the list - if (m_tail==-1) - { - m_tail = index; - } - m_cache[index].prev = -1; - m_cache[index].next = m_head; - if (m_head!=-1) - { - m_cache[m_head].prev = index; - } - m_head = index; - m_count++; - } - else // cache full -> replace element in the cache - { - //printf("Cache full!\n"); - lruObj = m_cache[m_tail].obj; - hashRemove(lruObj); - moveToFront(m_tail); // m_tail indexes the emptied element, which becomes m_head - } - //printf("numEntries=%d size=%d\n",m_numEntries,m_size); - m_cache[m_head].obj = obj; - hnode = hashInsert(obj); - hnode->index = m_head; - *victim = lruObj; - m_misses++; - } - return m_head; -} - -void ObjCache::del(int index) -{ - assert(index!=-1); - assert(m_cache[index].obj!=0); - hashRemove(m_cache[index].obj); - moveToFront(index); - m_head = m_cache[index].next; - if (m_head==-1) - m_tail=-1; - else - m_cache[m_head].prev=-1; - m_cache[index].obj=0; - m_cache[index].prev=-1; - m_cache[index].next = m_freeCacheNodes; - m_freeCacheNodes = index; - m_count--; -} - -#ifdef CACHE_DEBUG -#define cache_debug_printf printf -void ObjCache::printLRU() -{ - cache_debug_printf("MRU->LRU: "); - int index = m_head; - while (index!=-1) - { - cache_debug_printf("%d=%p ",index,m_cache[index].obj); - index = m_cache[index].next; - } - cache_debug_printf("\n"); - - cache_debug_printf("LRU->MRU: "); - index = m_tail; - while (index!=-1) - { - cache_debug_printf("%d=%p ",index,m_cache[index].obj); - index = m_cache[index].prev; - } - cache_debug_printf("\n"); -} -#endif - -#ifdef CACHE_STATS -#define cache_stats_printf printf -void ObjCache::printStats() -{ - cache_stats_printf("ObjCache: hits=%d misses=%d hit ratio=%f\n",m_hits,m_misses,m_hits*100.0/(m_hits+m_misses)); -} -#endif - -void ObjCache::moveToFront(int index) -{ - int prev,next; - if (m_head!=index) - { - next = m_cache[index].next; - prev = m_cache[index].prev; - - // de-chain node at index - m_cache[prev].next = next; - if (next!=-1) m_cache[next].prev = prev; else m_tail = prev; - - // add to head - m_cache[index].prev = -1; - m_cache[index].next = m_head; - m_cache[m_head].prev = index; - m_head = index; - } -} - -unsigned int ObjCache::hash(void *addr) -{ - static bool isPtr64 = sizeof(addr)==8; - if (isPtr64) - { - uint64 key = (uint64)addr; - // Thomas Wang's 64 bit Mix Function - key += ~(key << 32); - key ^= (key >> 22); - key += ~(key << 13); - key ^= (key >> 8); - key += (key << 3); - key ^= (key >> 15); - key += ~(key << 27); - key ^= (key >> 31); - return (unsigned int)(key & (m_size-1)); - } - else - { - // Thomas Wang's 32 bit Mix Function - uintptr_t key = (uintptr_t)addr; - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return (unsigned int)(key & (m_size-1)); - } -} - -ObjCache::HashNode *ObjCache::hashFind(void *obj) -{ - HashNode *node = 0; - int index = m_hash[hash(obj)].head; - //printf("hashFind: obj=%p index=%d\n",obj,index); - while (index!=-1 && - m_hash[index].obj!=obj - ) // search for right object in the list - { - index = m_hash[index].nextHash; - } - // found the obj at index, so it is in the cache! - if (index!=-1) - { - node = &m_hash[index]; - } - return node; -} - -ObjCache::HashNode *ObjCache::hashInsert(void *obj) -{ - int index = hash(obj); - //printf("Inserting %p index=%d\n",obj,index); - - // remove element from empty list - int newElement = m_freeHashNodes; - assert(newElement!=-1); - m_freeHashNodes = m_hash[m_freeHashNodes].nextHash; - - if (m_hash[index].head!=-1) // hash collision -> goto end of the list - { - index = m_hash[index].head; - while (m_hash[index].nextHash!=-1) - { - index = m_hash[index].nextHash; - } - // add to end of the list - m_hash[index].nextHash = newElement; - } - else // first element in the hash list - { - m_hash[index].head = newElement; - } - // add to the end of the list - m_hash[newElement].nextHash = -1; - m_hash[newElement].obj = obj; - return &m_hash[newElement]; -} - -void ObjCache::hashRemove(void *obj) -{ - int index = hash(obj); - - // find element - int curIndex = m_hash[index].head; - int prevIndex=-1; - while (m_hash[curIndex].obj!=obj) - { - prevIndex = curIndex; - curIndex = m_hash[curIndex].nextHash; - } - - if (prevIndex==-1) // remove from start - { - m_hash[index].head = m_hash[curIndex].nextHash; - } - else // remove in the middle - { - m_hash[prevIndex].nextHash = m_hash[curIndex].nextHash; - } - - // add curIndex element to empty list - m_hash[curIndex].nextHash = m_freeHashNodes; - m_hash[curIndex].index = -1; - m_hash[curIndex].obj = 0; - m_freeHashNodes = curIndex; -} - -#ifdef CACHE_TEST -int main() -{ - int i; - struct obj - { - obj() : handle(-1) {} - int handle; - }; - obj *objs = new obj[100]; - ObjCache c(3); - for (i=0;i<32;i++) - { - int objId=(i%3)+(i>>2)*4; - printf("------- use(%d=%p)--------\n",objId,&objs[objId]); -#ifdef CACHE_DEBUG - c.printLRU(); -#endif - obj *victim=0; - if (objs[objId].handle==-1) - { - objs[objId].handle = c.add(&objs[objId],(void**)&victim); - if (victim) victim->handle=-1; - } - else - { - c.use(objs[objId].handle); - } - printf("i=%d objId=%d using %p victim=%p\n",i,objId,&objs[objId],victim); - } - for (i=0;i<100;i++) - { - if (objs[i].handle!=-1) - { - printf("------ del objId=%d handle=%d ------\n",i,objs[i].handle); - c.del(objs[i].handle); - objs[i].handle=-1; -#ifdef CACHE_DEBUG - c.printLRU(); -#endif - } - } - c.printStats(); - return 0; -} -#endif diff --git a/src/objcache.h b/src/objcache.h deleted file mode 100644 index 224b34b..0000000 --- a/src/objcache.h +++ /dev/null @@ -1,127 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#ifndef OBJCACHE_H -#define OBJCACHE_H - -//#define CACHE_TEST -//#define CACHE_DEBUG -#define CACHE_STATS - -/** @brief Cache for objects. - * - * This cache is used to decide which objects should remain in - * memory. It uses a least recently used policy (LRU) to decide - * which object should make room for a new object when the cache - * is full. An object should be added using add(), and then use() - * should be called when the object is used. - */ -class ObjCache -{ - private: - struct CacheNode - { - CacheNode() : next(-1), prev(-1), obj(0) {} - int next; - int prev; - void *obj; - }; - struct HashNode - { - HashNode() : head(-1), nextHash(-1), index(-1), obj(0) {} - int head; - int nextHash; - int index; - void *obj; - }; - - public: - /*! Creates the cache. The number of elements in the cache is 2 to - * the power of \a logSize. - */ - ObjCache(unsigned int logSize); - - /*! Deletes the cache and free all internal data-structures used. */ - ~ObjCache(); - - /*! Adds \a obj to the cache. When victim is not null, this object is - * removed from the cache to make room for \a obj. - * Returns a handle to the object, which can be used by the use() - * function, each time the object is used. - */ - int add(void *obj,void **victim); - - /*! Indicates that this object is used. This will move the object - * to the front of the internal LRU list to make sure it is removed last. - * The parameter \a handle is returned when called add(). - */ - void use(int handle) - { - if (handle==m_lastHandle) return; - m_lastHandle = handle; - m_hits++; - moveToFront(handle); - } - - /*! Removes the item identified by \a handle from the cache. - * @see add() - */ - void del(int handle); - - /*! Debug function. Prints the LRU list */ - void printLRU(); - /*! Print miss/hits statistics */ - void printStats(); - - /*! total size of the cache */ - int size() const { return m_size; } - - /*! number of elements in the cache */ - int count() const { return m_count; } - - int hits() const - { - return m_hits; - } - int misses() const - { - return m_misses; - } - - - private: - void moveToFront(int index); - unsigned int hash(void *addr); - HashNode *hashFind(void *obj); - HashNode *hashInsert(void *obj); - void hashRemove(void *obj); - - CacheNode *m_cache; - HashNode *m_hash; - int m_head; - int m_tail; - int m_size; - int m_count; - int m_freeHashNodes; - int m_freeCacheNodes; - int m_lastHandle; - int m_misses; - int m_hits; -}; - -#endif // OBJCACHE_H - diff --git a/src/outputgen.h b/src/outputgen.h index 576e950..009225f 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -150,7 +150,7 @@ class BaseOutputDocInterface : public CodeOutputInterface Examples }; - virtual void parseText(const QCString &s) {} + virtual void parseText(const QCString &) {} /*! Start of a bullet list: e.g. \c \<ul\> in html. startItemListItem() is * Used for the bullet items. @@ -290,8 +290,8 @@ class BaseOutputDocInterface : public CodeOutputInterface virtual void endTitle() = 0; virtual void writeAnchor(const char *fileName,const char *name) = 0; - virtual void startSection(const char *,const char *,SectionInfo::SectionType) = 0; - virtual void endSection(const char *,SectionInfo::SectionType) = 0; + virtual void startSection(const char *,const char *,SectionType) = 0; + virtual void endSection(const char *,SectionType) = 0; virtual void lineBreak(const char *style) = 0; virtual void addIndexItem(const char *s1,const char *s2) = 0; @@ -447,8 +447,8 @@ class OutputGenerator : public BaseOutputDocInterface virtual void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first) = 0; virtual void startContents() = 0; virtual void endContents() = 0; - virtual void startPageDoc(const char *pageTitle) {}; - virtual void endPageDoc() {}; + virtual void startPageDoc(const char *) {} + virtual void endPageDoc() {} virtual void startTextBlock(bool) = 0; virtual void endTextBlock(bool) = 0; virtual void lastIndexPage() = 0; diff --git a/src/outputlist.cpp b/src/outputlist.cpp index c47c1c9..07d6491 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -33,7 +33,6 @@ OutputList::OutputList(bool) { //printf("OutputList::OutputList()\n"); - m_outputs.setAutoDelete(TRUE); } OutputList::~OutputList() @@ -41,16 +40,14 @@ OutputList::~OutputList() //printf("OutputList::~OutputList()\n"); } -void OutputList::add(const OutputGenerator *og) +void OutputList::add(OutputGenerator *og) { - if (og) m_outputs.append(og); + if (og) m_outputs.emplace_back(og); } void OutputList::disableAllBut(OutputGenerator::OutputType o) { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->disableIfNot(o); } @@ -58,9 +55,7 @@ void OutputList::disableAllBut(OutputGenerator::OutputType o) void OutputList::enableAll() { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->enable(); } @@ -68,9 +63,7 @@ void OutputList::enableAll() void OutputList::disableAll() { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->disable(); } @@ -78,9 +71,7 @@ void OutputList::disableAll() void OutputList::disable(OutputGenerator::OutputType o) { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->disableIf(o); } @@ -88,9 +79,7 @@ void OutputList::disable(OutputGenerator::OutputType o) void OutputList::enable(OutputGenerator::OutputType o) { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->enableIf(o); } @@ -99,9 +88,7 @@ void OutputList::enable(OutputGenerator::OutputType o) bool OutputList::isEnabled(OutputGenerator::OutputType o) { bool result=FALSE; - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { result=result || og->isEnabled(o); } @@ -110,9 +97,7 @@ bool OutputList::isEnabled(OutputGenerator::OutputType o) void OutputList::pushGeneratorState() { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->pushGeneratorState(); } @@ -120,9 +105,7 @@ void OutputList::pushGeneratorState() void OutputList::popGeneratorState() { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { og->popGeneratorState(); } @@ -137,9 +120,7 @@ void OutputList::generateDoc(const char *fileName,int startLine, int count=0; if (docStr.isEmpty()) return; - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { if (og->isEnabled()) count++; } @@ -158,9 +139,7 @@ void OutputList::generateDoc(const char *fileName,int startLine, void OutputList::writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md) { - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { //printf("og->printDoc(extension=%s)\n", // ctx?ctx->getDefFileExtension().data():"<null>"); @@ -172,9 +151,7 @@ void OutputList::writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *m void OutputList::parseText(const QCString &textStr) { int count=0; - QListIterator<OutputGenerator> it(m_outputs); - OutputGenerator *og; - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { if (og->isEnabled()) count++; } @@ -187,7 +164,7 @@ void OutputList::parseText(const QCString &textStr) if (count>0) { - for (it.toFirst();(og=it.current());++it) + for (const auto &og : m_outputs) { if (og->isEnabled()) og->writeDoc(root,0,0); } diff --git a/src/outputlist.h b/src/outputlist.h index cfd3773..58e4425 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -1,12 +1,10 @@ /****************************************************************************** * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -19,38 +17,22 @@ #define OUTPUTLIST_H #include <utility> -#include <qlist.h> +#include <vector> +#include <memory> + #include "index.h" // for IndexSections #include "outputgen.h" -#define FORALLPROTO1(arg1) \ - void forall(void (OutputGenerator::*func)(arg1),arg1) -#define FORALLPROTO2(arg1,arg2) \ - void forall(void (OutputGenerator::*func)(arg1,arg2),arg1,arg2) -#define FORALLPROTO3(arg1,arg2,arg3) \ - void forall(void (OutputGenerator::*func)(arg1,arg2,arg3),arg1,arg2,arg3) -#define FORALLPROTO4(arg1,arg2,arg3,arg4) \ - void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4),arg1,arg2,arg3,arg4) -#define FORALLPROTO5(arg1,arg2,arg3,arg4,arg5) \ - void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5),arg1,arg2,arg3,arg4,arg5) -#define FORALLPROTO6(arg1,arg2,arg3,arg4,arg5,arg6) \ - void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5,arg6),arg1,arg2,arg3,arg4,arg5,arg6) -#define FORALLPROTO7(arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ - void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5,arg6,arg7),arg1,arg2,arg3,arg4,arg5,arg6,arg7) -#define FORALLPROTO8(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \ - void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8),arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) - class ClassDiagram; class DotClassGraph; class DotDirDeps; class DotInclDepGraph; class DotGfxHierarchyTable; -class SectionDict; class DotGroupCollaboration; class DocRoot; /** Class representing a list of output generators that are written to - * in parallel. + * in parallel. */ class OutputList : public OutputDocInterface { @@ -58,9 +40,9 @@ class OutputList : public OutputDocInterface OutputList(bool); virtual ~OutputList(); - void add(const OutputGenerator *); - uint count() const { return m_outputs.count(); } - + void add(OutputGenerator *); + uint count() const { return static_cast<uint>(m_outputs.size()); } + void disableAllBut(OutputGenerator::OutputType o); void enableAll(); void disableAll(); @@ -92,7 +74,7 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startProjectNumber); } void endProjectNumber() { forall(&OutputGenerator::endProjectNumber); } - void writeStyleInfo(int part) + void writeStyleInfo(int part) { forall(&OutputGenerator::writeStyleInfo,part); } void startFile(const char *name,const char *manName,const char *title) { forall(&OutputGenerator::startFile,name,manName,title); } @@ -100,29 +82,29 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::writeSearchInfo); } void writeFooter(const char *navPath) { forall(&OutputGenerator::writeFooter,navPath); } - void endFile() + void endFile() { forall(&OutputGenerator::endFile); } - void startTitleHead(const char *fileName) + void startTitleHead(const char *fileName) { forall(&OutputGenerator::startTitleHead,fileName); } void endTitleHead(const char *fileName,const char *name) { forall(&OutputGenerator::endTitleHead,fileName,name); } - void startTitle() + void startTitle() { forall(&OutputGenerator::startTitle); } - void endTitle() + void endTitle() { forall(&OutputGenerator::endTitle); } void startParagraph(const char *classDef=0) { forall(&OutputGenerator::startParagraph,classDef); } - void endParagraph() + void endParagraph() { forall(&OutputGenerator::endParagraph); } - void writeString(const char *text) + void writeString(const char *text) { forall(&OutputGenerator::writeString,text); } - void startIndexListItem() + void startIndexListItem() { forall(&OutputGenerator::startIndexListItem); } - void endIndexListItem() + void endIndexListItem() { forall(&OutputGenerator::endIndexListItem); } - void startIndexList() + void startIndexList() { forall(&OutputGenerator::startIndexList); } - void endIndexList() + void endIndexList() { forall(&OutputGenerator::endIndexList); } void startIndexKey() { forall(&OutputGenerator::startIndexKey); } @@ -132,9 +114,9 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startIndexValue,b); } void endIndexValue(const char *name,bool b) { forall(&OutputGenerator::endIndexValue,name,b); } - void startItemList() + void startItemList() { forall(&OutputGenerator::startItemList); } - void endItemList() + void endItemList() { forall(&OutputGenerator::endItemList); } void startIndexItem(const char *ref,const char *file) { forall(&OutputGenerator::startIndexItem,ref,file); } @@ -162,22 +144,22 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startHtmlLink,url); } void endHtmlLink() { forall(&OutputGenerator::endHtmlLink); } - void writeStartAnnoItem(const char *type,const char *file, + void writeStartAnnoItem(const char *type,const char *file, const char *path,const char *name) { forall(&OutputGenerator::writeStartAnnoItem,type,file,path,name); } void writeEndAnnoItem(const char *name) { forall(&OutputGenerator::writeEndAnnoItem,name); } - void startTypewriter() + void startTypewriter() { forall(&OutputGenerator::startTypewriter); } - void endTypewriter() + void endTypewriter() { forall(&OutputGenerator::endTypewriter); } void startGroupHeader(int extraLevels=0) { forall(&OutputGenerator::startGroupHeader,extraLevels); } void endGroupHeader(int extraLevels=0) { forall(&OutputGenerator::endGroupHeader,extraLevels); } - void startItemListItem() + void startItemListItem() { forall(&OutputGenerator::startItemListItem); } - void endItemListItem() + void endItemListItem() { forall(&OutputGenerator::endItemListItem); } void startMemberSections() { forall(&OutputGenerator::startMemberSections); } @@ -195,31 +177,31 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startMemberSubtitle); } void endMemberSubtitle() { forall(&OutputGenerator::endMemberSubtitle); } - void startMemberDocList() + void startMemberDocList() { forall(&OutputGenerator::startMemberDocList); } - void endMemberDocList() + void endMemberDocList() { forall(&OutputGenerator::endMemberDocList); } - void startMemberList() + void startMemberList() { forall(&OutputGenerator::startMemberList); } - void endMemberList() + void endMemberList() { forall(&OutputGenerator::endMemberList); } void startInlineHeader() { forall(&OutputGenerator::startInlineHeader); } void endInlineHeader() { forall(&OutputGenerator::endInlineHeader); } - void startAnonTypeScope(int i1) + void startAnonTypeScope(int i1) { forall(&OutputGenerator::startAnonTypeScope,i1); } - void endAnonTypeScope(int i1) + void endAnonTypeScope(int i1) { forall(&OutputGenerator::endAnonTypeScope,i1); } - void startMemberItem(const char *anchor,int i1,const char *id=0) + void startMemberItem(const char *anchor,int i1,const char *id=0) { forall(&OutputGenerator::startMemberItem,anchor,i1,id); } - void endMemberItem() + void endMemberItem() { forall(&OutputGenerator::endMemberItem); } - void startMemberTemplateParams() + void startMemberTemplateParams() { forall(&OutputGenerator::startMemberTemplateParams); } - void endMemberTemplateParams(const char *anchor,const char *inheritId) + void endMemberTemplateParams(const char *anchor,const char *inheritId) { forall(&OutputGenerator::endMemberTemplateParams,anchor,inheritId); } - void startMemberGroupHeader(bool b) + void startMemberGroupHeader(bool b) { forall(&OutputGenerator::startMemberGroupHeader,b); } void endMemberGroupHeader() { forall(&OutputGenerator::endMemberGroupHeader); } @@ -231,28 +213,28 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startMemberGroup); } void endMemberGroup(bool last) { forall(&OutputGenerator::endMemberGroup,last); } - void insertMemberAlign(bool templ=FALSE) + void insertMemberAlign(bool templ=FALSE) { forall(&OutputGenerator::insertMemberAlign,templ); } - void insertMemberAlignLeft(int typ=0, bool templ=FALSE) + void insertMemberAlignLeft(int typ=0, bool templ=FALSE) { forall(&OutputGenerator::insertMemberAlignLeft,typ,templ); } - void writeRuler() + void writeRuler() { forall(&OutputGenerator::writeRuler); } void writeAnchor(const char *fileName,const char *name) { forall(&OutputGenerator::writeAnchor,fileName,name); } - void startCodeFragment() + void startCodeFragment() { forall(&OutputGenerator::startCodeFragment); } - void endCodeFragment() + void endCodeFragment() { forall(&OutputGenerator::endCodeFragment); } - void startCodeLine(bool hasLineNumbers) + void startCodeLine(bool hasLineNumbers) { forall(&OutputGenerator::startCodeLine,hasLineNumbers); } - void endCodeLine() + void endCodeLine() { forall(&OutputGenerator::endCodeLine); } void writeLineNumber(const char *ref,const char *file,const char *anchor, - int lineNumber) + int lineNumber) { forall(&OutputGenerator::writeLineNumber,ref,file,anchor,lineNumber); } - void startEmphasis() + void startEmphasis() { forall(&OutputGenerator::startEmphasis); } - void endEmphasis() + void endEmphasis() { forall(&OutputGenerator::endEmphasis); } void writeChar(char c) { forall(&OutputGenerator::writeChar,c); } @@ -260,7 +242,7 @@ class OutputList : public OutputDocInterface const char *anchor,const char *title, int memCount,int memTotal,bool showInline) { forall(&OutputGenerator::startMemberDoc,clName,memName,anchor,title,memCount,memTotal,showInline); } - void endMemberDoc(bool hasArgs) + void endMemberDoc(bool hasArgs) { forall(&OutputGenerator::endMemberDoc,hasArgs); } void startDoxyAnchor(const char *fName,const char *manName, const char *anchor, const char *name, @@ -268,45 +250,45 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startDoxyAnchor,fName,manName,anchor,name,args); } void endDoxyAnchor(const char *fn,const char *anchor) { forall(&OutputGenerator::endDoxyAnchor,fn,anchor); } - void writeLatexSpacing() + void writeLatexSpacing() { forall(&OutputGenerator::writeLatexSpacing); } - void startDescription() + void startDescription() { forall(&OutputGenerator::startDescription); } - void endDescription() + void endDescription() { forall(&OutputGenerator::endDescription); } - void startDescItem() + void startDescItem() { forall(&OutputGenerator::startDescItem); } - void endDescItem() + void endDescItem() { forall(&OutputGenerator::endDescItem); } - void startDescForItem() + void startDescForItem() { forall(&OutputGenerator::startDescForItem); } - void endDescForItem() + void endDescForItem() { forall(&OutputGenerator::endDescForItem); } - void startSubsection() + void startSubsection() { forall(&OutputGenerator::startSubsection); } - void endSubsection() + void endSubsection() { forall(&OutputGenerator::endSubsection); } - void startSubsubsection() + void startSubsubsection() { forall(&OutputGenerator::startSubsubsection); } - void endSubsubsection() + void endSubsubsection() { forall(&OutputGenerator::endSubsubsection); } - void startCenter() + void startCenter() { forall(&OutputGenerator::startCenter); } - void endCenter() + void endCenter() { forall(&OutputGenerator::endCenter); } - void startSmall() + void startSmall() { forall(&OutputGenerator::startSmall); } - void endSmall() + void endSmall() { forall(&OutputGenerator::endSmall); } - void lineBreak(const char *style=0) + void lineBreak(const char *style=0) { forall(&OutputGenerator::lineBreak,style); } - void startBold() + void startBold() { forall(&OutputGenerator::startBold); } - void endBold() + void endBold() { forall(&OutputGenerator::endBold); } - void startMemberDescription(const char *anchor,const char *inheritId=0, bool typ = false) + void startMemberDescription(const char *anchor,const char *inheritId=0, bool typ = false) { forall(&OutputGenerator::startMemberDescription,anchor,inheritId, typ); } - void endMemberDescription() + void endMemberDescription() { forall(&OutputGenerator::endMemberDescription); } void startMemberDeclaration() { forall(&OutputGenerator::startMemberDeclaration); } @@ -321,21 +303,21 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startExamples); } void endExamples() { forall(&OutputGenerator::endExamples); } - void startParamList(ParamListTypes t,const char *title) + void startParamList(ParamListTypes t,const char *title) { forall(&OutputGenerator::startParamList,t,title); } - void endParamList() + void endParamList() { forall(&OutputGenerator::endParamList); } - void startIndent() + void startIndent() { forall(&OutputGenerator::startIndent); } - void endIndent() + void endIndent() { forall(&OutputGenerator::endIndent); } - void startSection(const char *lab,const char *title,SectionInfo::SectionType t) + void startSection(const char *lab,const char *title,SectionType t) { forall(&OutputGenerator::startSection,lab,title,t); } - void endSection(const char *lab,SectionInfo::SectionType t) + void endSection(const char *lab,SectionType t) { forall(&OutputGenerator::endSection,lab,t); } void addIndexItem(const char *s1,const char *s2) { forall(&OutputGenerator::addIndexItem,s1,s2); } - void writeSynopsis() + void writeSynopsis() { forall(&OutputGenerator::writeSynopsis); } void startClassDiagram() { forall(&OutputGenerator::startClassDiagram); } @@ -436,11 +418,11 @@ class OutputList : public OutputDocInterface void exceptionEntry(const char* prefix,bool closeBracket) { forall(&OutputGenerator::exceptionEntry,prefix,closeBracket); } - void startConstraintList(const char *header) + void startConstraintList(const char *header) { forall(&OutputGenerator::startConstraintList,header); } - void startConstraintParam() + void startConstraintParam() { forall(&OutputGenerator::startConstraintParam); } - void endConstraintParam() + void endConstraintParam() { forall(&OutputGenerator::endConstraintParam); } void startConstraintType() { forall(&OutputGenerator::startConstraintType); } @@ -470,7 +452,7 @@ class OutputList : public OutputDocInterface void endInlineMemberDoc() { forall(&OutputGenerator::endInlineMemberDoc); } - void startLabels() + void startLabels() { forall(&OutputGenerator::startLabels); } void writeLabel(const char *l,bool isLast) { forall(&OutputGenerator::writeLabel,l,isLast); } @@ -504,16 +486,14 @@ class OutputList : public OutputDocInterface template<typename T,class... Ts,class... As> void forall(void (T::*methodPtr)(Ts...),As&&... args) { - QListIterator<OutputGenerator> li(m_outputs); - OutputGenerator *og; - for (li.toFirst();(og=li.current());++li) + for (const auto &og : m_outputs) { - if (og->isEnabled()) (og->*methodPtr)(std::forward<As>(args)...); + if (og->isEnabled()) (og.get()->*methodPtr)(std::forward<As>(args)...); } } OutputList(const OutputList &ol); - QList<OutputGenerator> m_outputs; + std::vector< std::unique_ptr<OutputGenerator> > m_outputs; }; #endif diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 8b6228f..011b647 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -47,7 +47,7 @@ class PageDefImpl : public DefinitionImpl, public PageDef virtual QCString title() const { return m_title; } virtual GroupDef * getGroupDef() const; virtual PageSDict * getSubPages() const { return m_subPageDict; } - virtual void addInnerCompound(Definition *d); + virtual void addInnerCompound(const Definition *d); virtual bool visibleInIndex() const; virtual bool documentedPage() const; virtual bool hasSubPages() const; @@ -121,10 +121,11 @@ void PageDefImpl::setFileName(const char *name) m_fileName = name; } -void PageDefImpl::addInnerCompound(Definition *def) +void PageDefImpl::addInnerCompound(const Definition *const_def) { - if (def->definitionType()==Definition::TypePage) + if (const_def->definitionType()==Definition::TypePage) { + Definition *def = const_cast<Definition*>(const_def); // uck: fix me PageDef *pd = dynamic_cast<PageDef*>(def); m_subPageDict->append(pd->name(),pd); def->setOuterScope(this); @@ -148,9 +149,7 @@ bool PageDefImpl::hasParentPage() const void PageDefImpl::writeTagFile(FTextStream &tagFile) { bool found = name()=="citelist"; - QDictIterator<RefList> rli(*Doxygen::xrefLists); - RefList *rl; - for (rli.toFirst();(rl=rli.current()) && !found;++rli) + for (RefListManager::Ptr &rl : RefListManager::instance()) { if (rl->listName()==name()) { @@ -163,7 +162,7 @@ void PageDefImpl::writeTagFile(FTextStream &tagFile) tagFile << " <compound kind=\"page\">" << endl; tagFile << " <name>" << name() << "</name>" << endl; tagFile << " <title>" << convertToXML(title()) << "</title>" << endl; - tagFile << " <filename>" << convertToXML(getOutputFileBase()) << "</filename>" << endl; + tagFile << " <filename>" << convertToXML(getOutputFileBase())<< Doxygen::htmlFileExtension << "</filename>" << endl; writeDocAnchorsToTagFile(tagFile); tagFile << " </compound>" << endl; } @@ -213,7 +212,7 @@ void PageDefImpl::writeDocumentation(OutputList &ol) } ol.endQuickIndices(); } - SectionInfo *si=Doxygen::sectionDict->find(name()); + const SectionInfo *si=SectionManager::instance().find(name()); // save old generator state and write title only to Man generator ol.pushGeneratorState(); @@ -228,10 +227,10 @@ void PageDefImpl::writeDocumentation(OutputList &ol) ol.writeString(" - "); ol.popGeneratorState(); - if (si->title != manPageName) + if (si->title() != manPageName) { - ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); - ol.endSection(si->label,si->type); + ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE,0,TRUE,FALSE); + ol.endSection(si->label(),si->type()); } } ol.popGeneratorState(); @@ -246,10 +245,10 @@ void PageDefImpl::writeDocumentation(OutputList &ol) ol.disable(OutputGenerator::Man); if (hasTitle() && !name().isEmpty() && si!=0) { - ol.startPageDoc(si->title); + ol.startPageDoc(si->title()); //ol.startSection(si->label,si->title,si->type); startTitle(ol,getOutputFileBase(),this); - ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); + ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE,0,TRUE,FALSE); //stringToSearchIndex(getOutputFileBase(), // theTranslator->trPage(TRUE,TRUE)+" "+si->title, // si->title); @@ -297,7 +296,7 @@ void PageDefImpl::writePageDocumentation(OutputList &ol) ol.startTextBlock(); QCString docStr = documentation()+inbodyDocumentation(); - if (hasBriefDescription() && !Doxygen::sectionDict->find(name())) + if (hasBriefDescription() && !SectionManager::instance().find(name())) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); @@ -331,14 +330,14 @@ void PageDefImpl::writePageDocumentation(OutputList &ol) PageDef *subPage=pdi.toFirst(); for (pdi.toFirst();(subPage=pdi.current());++pdi) { - SectionInfo::SectionType sectionType = SectionInfo::Paragraph; + SectionType sectionType = SectionType::Paragraph; switch (m_nestingLevel) { - case 0: sectionType = SectionInfo::Page; break; - case 1: sectionType = SectionInfo::Section; break; - case 2: sectionType = SectionInfo::Subsection; break; - case 3: sectionType = SectionInfo::Subsubsection; break; - default: sectionType = SectionInfo::Paragraph; break; + case 0: sectionType = SectionType::Page; break; + case 1: sectionType = SectionType::Section; break; + case 2: sectionType = SectionType::Subsection; break; + case 3: sectionType = SectionType::Subsubsection; break; + default: sectionType = SectionType::Paragraph; break; } QCString title = subPage->title(); if (title.isEmpty()) title = subPage->name(); diff --git a/src/pagedef.h b/src/pagedef.h index f0b68d1..e4d0268 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -46,22 +46,22 @@ class PageDef : virtual public Definition virtual QCString title() const = 0; virtual GroupDef * getGroupDef() const = 0; virtual PageSDict * getSubPages() const = 0; - virtual void addInnerCompound(Definition *d) = 0; + virtual void addInnerCompound(const Definition *) = 0; virtual bool visibleInIndex() const = 0; virtual bool documentedPage() const = 0; virtual bool hasSubPages() const = 0; virtual bool hasParentPage() const = 0; virtual bool hasTitle() const = 0; virtual LocalToc localToc() const = 0; - virtual void setPageScope(Definition *d) = 0; + virtual void setPageScope(Definition *) = 0; virtual Definition *getPageScope() const = 0; virtual QCString displayName(bool=TRUE) const = 0; virtual bool showLineNo() const = 0; - virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeDocumentation(OutputList &) = 0; virtual void writeTagFile(FTextStream &) = 0; - virtual void setNestingLevel(int l) = 0; - virtual void writePageDocumentation(OutputList &ol) = 0; + virtual void setNestingLevel(int) = 0; + virtual void writePageDocumentation(OutputList &) = 0; }; @@ -70,7 +70,7 @@ PageDef *createPageDef(const char *f,int l,const char *n,const char *d,const cha class PageSDict : public SDict<PageDef> { public: - PageSDict(int size) : SDict<PageDef>(size) {} + PageSDict(uint size) : SDict<PageDef>(size) {} virtual ~PageSDict() {} private: int compareValues(const PageDef *i1,const PageDef *i2) const diff --git a/src/parserintf.h b/src/parserintf.h index 5095a1e..6dc9569 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -178,10 +178,12 @@ class ParserManager } /** Registers an additional parser. - * @param[in] name A symbolic name of the parser, i.e. "c", - * "python", "fortran", "vhdl", ... - * @param[in] parser The parser that is to be used for the - * given name. + * @param[in] name A symbolic name of the parser, i.e. "c", + * "python", "fortran", "vhdl", ... + * @param[in] outlineParser The language parser (scanner) that is to be used for the + * given name. + * @param[in] codeParser The code parser that is to be used for the + * given name. */ void registerParser(const char *name,std::unique_ptr<OutlineParserInterface> outlineParser, std::unique_ptr<CodeParserInterface> codeParser) diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index 4ecee5e..eb566ff 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -92,7 +92,7 @@ void PerlModOutputStream::add(int n) if (m_t != 0) (*m_t) << n; else - m_s += n; + m_s += QCString().setNum(n); } void PerlModOutputStream::add(unsigned int n) @@ -100,7 +100,7 @@ void PerlModOutputStream::add(unsigned int n) if (m_t != 0) (*m_t) << n; else - m_s += n; + m_s += QCString().setNum(n); } class PerlModOutput @@ -171,10 +171,10 @@ public: inline PerlModOutput &closeHash() { close('}'); return *this; } protected: - + void iopenSave(); void icloseSave(QCString &); - + void incIndent(); void decIndent(); @@ -187,7 +187,7 @@ protected: void iclose(char); private: - + PerlModOutputStream *m_stream; int m_indentation; bool m_blockstart; @@ -226,7 +226,7 @@ void PerlModOutput::decIndent() m_spaces[m_indentation * 2] = 0; } -void PerlModOutput::iaddQuoted(const char *s) +void PerlModOutput::iaddQuoted(const char *s) { char c; while ((c = *s++) != 0) { @@ -235,7 +235,7 @@ void PerlModOutput::iaddQuoted(const char *s) m_stream->add(c); } } - + void PerlModOutput::iaddField(const char *s) { continueBlock(); @@ -276,10 +276,10 @@ void PerlModOutput::iopen(char c, const char *s) void PerlModOutput::iclose(char c) { - decIndent(); + decIndent(); indent(); if (c != 0) - m_stream->add(c); + m_stream->add(c); m_blockstart = false; } @@ -291,11 +291,11 @@ public: virtual ~PerlModDocVisitor() { } void finish(); - + //-------------------------------------- // visitor functions for leaf nodes //-------------------------------------- - + void visit(DocWord *); void visit(DocLinkedWord *); void visit(DocWhiteSpace *); @@ -317,7 +317,7 @@ public: //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - + void visitPre(DocAutoList *); void visitPost(DocAutoList *); void visitPre(DocAutoListItem *); @@ -405,7 +405,7 @@ private: void addLink(const QCString &ref, const QCString &file, const QCString &anchor); - + void enterText(); void leaveText(); @@ -653,7 +653,7 @@ void PerlModDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Preformatted: style = "preformatted"; break; case DocStyleChange::Div: style = "div"; break; case DocStyleChange::Span: style = "span"; break; - + } openItem("style"); m_output.addFieldQuotedString("style", style) @@ -712,12 +712,12 @@ void PerlModDocVisitor::visit(DocInclude *inc) { case DocInclude::IncWithLines: #if 0 - { + { m_t << "<div class=\"fragment\"><pre>"; QFileInfo cfi( inc->file() ); FileDef fd( cfi.dirPath(), cfi.fileName() ); parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd); - m_t << "</pre></div>"; + m_t << "</pre></div>"; } break; #endif @@ -733,11 +733,15 @@ void PerlModDocVisitor::visit(DocInclude *inc) case DocInclude::DontIncWithLines: return; case DocInclude::HtmlInclude: type = "htmlonly"; break; case DocInclude::LatexInclude: type = "latexonly"; break; + case DocInclude::RtfInclude: type = "rtfonly"; break; + case DocInclude::ManInclude: type = "manonly"; break; + case DocInclude::XmlInclude: type = "xmlonly"; break; + case DocInclude::DocbookInclude: type = "docbookonly"; break; case DocInclude::VerbInclude: type = "preformatted"; break; case DocInclude::Snippet: return; case DocInclude::SnipWithLines: return; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" "Please create a bug report\n",__FILE__); break; @@ -760,7 +764,7 @@ void PerlModDocVisitor::visit(DocIncOperator *) { parseCode(m_ci,op->context(),op->text(),FALSE,0); } - if (op->isLast()) + if (op->isLast()) { m_output.add("</programlisting>"); } @@ -775,7 +779,7 @@ void PerlModDocVisitor::visit(DocFormula *f) { openItem("formula"); QCString id; - id += f->id(); + id += QCString().setNum(f->id()); m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f->text()); closeItem(); } @@ -910,7 +914,7 @@ void PerlModDocVisitor::visitPost(DocTitle *) closeItem(); } -void PerlModDocVisitor::visitPre(DocSimpleList *) +void PerlModDocVisitor::visitPre(DocSimpleList *) { openItem("list"); m_output.addFieldQuotedString("style", "itemized"); @@ -1122,7 +1126,7 @@ void PerlModDocVisitor::visitPre(DocImage *) case DocImage::Rtf: m_output.add("rtf"); break; } m_output.add("\""); - + QCString baseName=img->name(); int i; if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) @@ -1480,7 +1484,7 @@ static void addPerlModDocBlock(PerlModOutput &output, } } -static const char *getProtectionName(Protection prot) +static const char *getProtectionName(Protection prot) { switch (prot) { @@ -1534,6 +1538,7 @@ public: inline PerlModGenerator(bool pretty) : m_output(pretty) { } void generatePerlModForMember(const MemberDef *md, const Definition *); + void generatePerlUserDefinedSection(const Definition *d, const MemberGroupSDict *gsd); void generatePerlModSection(const Definition *d, MemberList *ml, const char *name, const char *header=0); void addListOfAllMembers(const ClassDef *cd); @@ -1542,7 +1547,7 @@ public: void generatePerlModForFile(const FileDef *fd); void generatePerlModForGroup(const GroupDef *gd); void generatePerlModForPage(PageDef *pi); - + bool createOutputFile(QFile &f, const char *s); bool createOutputDir(QDir &perlModDir); bool generateDoxyLatexTex(); @@ -1571,7 +1576,7 @@ void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Defini // - body code // - template arguments // (templateArguments(), definitionTemplateParameterLists()) - + QCString memType; bool isFunc=FALSE; switch (md->memberType()) @@ -1600,13 +1605,13 @@ void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Defini .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness())) .addFieldQuotedString("protection", getProtectionName(md->protection())) .addFieldBoolean("static", md->isStatic()); - + addPerlModDocBlock(m_output,"brief",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->briefDescription()); addPerlModDocBlock(m_output,"detailed",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->documentation()); if (md->memberType()!=MemberType_Define && md->memberType()!=MemberType_Enumeration) m_output.addFieldQuotedString("type", md->typeString()); - + const ArgumentList &al = md->argumentList(); if (isFunc) //function { @@ -1645,7 +1650,7 @@ void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Defini if (!a.attrib.isEmpty()) m_output.addFieldQuotedString("attributes", a.attrib); - + m_output.closeHash(); } } @@ -1663,17 +1668,17 @@ void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Defini } m_output.closeList(); } - else if (md->argsString()!=0) + else if (md->argsString()!=0) { m_output.addFieldQuotedString("arguments", md->argsString()); } if (!md->initializer().isEmpty()) m_output.addFieldQuotedString("initializer", md->initializer()); - + if (md->excpString()) m_output.addFieldQuotedString("exceptions", md->excpString()); - + if (md->memberType()==MemberType_Enumeration) // enum { const MemberList *enumFields = md->enumFieldList(); @@ -1686,7 +1691,7 @@ void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Defini { m_output.openHash() .addFieldQuotedString("name", emd->name()); - + if (!emd->initializer().isEmpty()) m_output.addFieldQuotedString("initializer", emd->initializer()); @@ -1717,7 +1722,7 @@ void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Defini .closeHash(); m_output.closeList(); } - + m_output.closeHash(); } @@ -1730,7 +1735,7 @@ void PerlModGenerator::generatePerlModSection(const Definition *d, if (header) m_output.addFieldQuotedString("header", header); - + m_output.openList("members"); MemberListIterator mli(*ml); const MemberDef *md; @@ -1756,9 +1761,9 @@ void PerlModGenerator::addListOfAllMembers(const ClassDef *cd) for (mii.toFirst();(mi=mii.current());++mii) { const MemberDef *md=mi->memberDef; - const ClassDef *cd=md->getClassDef(); + const ClassDef *mcd=md->getClassDef(); const Definition *d=md->getGroupDef(); - if (d==0) d = cd; + if (d==0) d = mcd; m_output.openHash() .addFieldQuotedString("name", md->name()) @@ -1768,7 +1773,7 @@ void PerlModGenerator::addListOfAllMembers(const ClassDef *cd) if (!mi->ambiguityResolutionScope.isEmpty()) m_output.addFieldQuotedString("ambiguity_scope", mi->ambiguityResolutionScope); - m_output.addFieldQuotedString("scope", cd->name()) + m_output.addFieldQuotedString("scope", mcd->name()) .closeHash(); } } @@ -1776,6 +1781,38 @@ void PerlModGenerator::addListOfAllMembers(const ClassDef *cd) m_output.closeList(); } +/* DGA: fix #7490 Perlmod generation issue with multiple grouped functions (member groups) */ +void PerlModGenerator::generatePerlUserDefinedSection(const Definition *d, const MemberGroupSDict *gsd) +{ + if (gsd) + { + MemberGroupSDict::Iterator mgli(*gsd); + MemberGroup *mg; + m_output.openList("user_defined"); + for (; (mg = mgli.current()); ++mgli) + { + m_output.openHash(); + if (mg->header()) + m_output.addFieldQuotedString("header", mg->header()); + + if (mg->members()) + { + m_output.openList("members"); + MemberListIterator mli(*mg->members()); + const MemberDef *md; + for (mli.toFirst(); (md = mli.current()); ++mli) + { + generatePerlModForMember(md, d); + } + m_output.closeList(); + } + m_output.closeHash(); + } + m_output.closeList(); + } +} +/* DGA: end of fix #7490 */ + void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) { // + brief description @@ -1800,7 +1837,7 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) m_output.openHash() .addFieldQuotedString("name", cd->name()); - + if (cd->baseClasses()) { m_output.openList("base"); @@ -1834,10 +1871,10 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) { m_output.openList("inner"); ClassSDict::Iterator cli(*cl); - const ClassDef *cd; - for (cli.toFirst();(cd=cli.current());++cli) + const ClassDef *icd; + for (cli.toFirst();(icd=cli.current());++cli) m_output.openHash() - .addFieldQuotedString("name", cd->name()) + .addFieldQuotedString("name", icd->name()) .closeHash(); m_output.closeList(); } @@ -1862,13 +1899,7 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) addTemplateList(cd,m_output); addListOfAllMembers(cd); - if (cd->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict()); - MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - generatePerlModSection(cd,mg->members(),"user_defined",mg->header()); - } + generatePerlUserDefinedSection(cd, cd->getMemberGroupSDict()); generatePerlModSection(cd,cd->getMemberList(MemberListType_pubTypes),"public_typedefs"); generatePerlModSection(cd,cd->getMemberList(MemberListType_pubMethods),"public_methods"); @@ -1912,12 +1943,12 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) collaborationGraph.writePerlMod(t); t << " </collaborationgraph>" << endl; } - t << " <location file=\"" - << cd->getDefFileName() << "\" line=\"" + t << " <location file=\"" + << cd->getDefFileName() << "\" line=\"" << cd->getDefLine() << "\""; if (cd->getStartBodyLine()!=-1) { - t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" + t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" << cd->getEndBodyLine() << "\""; } t << "/>" << endl; @@ -1941,7 +1972,7 @@ void PerlModGenerator::generatePerlModForNamespace(const NamespaceDef *nd) m_output.openHash() .addFieldQuotedString("name", nd->name()); - + ClassSDict *cl = nd->getClassSDict(); if (cl) { @@ -1960,21 +1991,15 @@ void PerlModGenerator::generatePerlModForNamespace(const NamespaceDef *nd) { m_output.openList("namespaces"); NamespaceSDict::Iterator nli(*nl); - const NamespaceDef *nd; - for (nli.toFirst();(nd=nli.current());++nli) + const NamespaceDef *ind; + for (nli.toFirst();(ind=nli.current());++nli) m_output.openHash() - .addFieldQuotedString("name", nd->name()) + .addFieldQuotedString("name", ind->name()) .closeHash(); m_output.closeList(); } - if (nd->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict()); - const MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - generatePerlModSection(nd,mg->members(),"user-defined",mg->header()); - } + generatePerlUserDefinedSection(nd, nd->getMemberGroupSDict()); generatePerlModSection(nd,nd->getMemberList(MemberListType_decDefineMembers),"defines"); generatePerlModSection(nd,nd->getMemberList(MemberListType_decProtoMembers),"prototypes"); @@ -2004,12 +2029,12 @@ void PerlModGenerator::generatePerlModForFile(const FileDef *fd) // - source code // - location // - number of lines - + if (fd->isReference()) return; m_output.openHash() .addFieldQuotedString("name", fd->name()); - + IncludeInfo *inc; m_output.openList("includes"); if (fd->includeFileList()) @@ -2027,7 +2052,7 @@ void PerlModGenerator::generatePerlModForFile(const FileDef *fd) } } m_output.closeList(); - + m_output.openList("included_by"); if (fd->includedByFileList()) { @@ -2044,7 +2069,10 @@ void PerlModGenerator::generatePerlModForFile(const FileDef *fd) } } m_output.closeList(); - + + /* DGA: fix #7494 Perlmod does not generate grouped members from files */ + generatePerlUserDefinedSection(fd, fd->getMemberGroupSDict()); + generatePerlModSection(fd,fd->getMemberList(MemberListType_decDefineMembers),"defines"); generatePerlModSection(fd,fd->getMemberList(MemberListType_decProtoMembers),"prototypes"); generatePerlModSection(fd,fd->getMemberList(MemberListType_decTypedefMembers),"typedefs"); @@ -2143,13 +2171,7 @@ void PerlModGenerator::generatePerlModForGroup(const GroupDef *gd) m_output.closeList(); } - if (gd->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict()); - MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - generatePerlModSection(gd,mg->members(),"user-defined",mg->header()); - } + generatePerlUserDefinedSection(gd, gd->getMemberGroupSDict()); generatePerlModSection(gd,gd->getMemberList(MemberListType_decDefineMembers),"defines"); generatePerlModSection(gd,gd->getMemberList(MemberListType_decProtoMembers),"prototypes"); @@ -2174,10 +2196,10 @@ void PerlModGenerator::generatePerlModForPage(PageDef *pd) m_output.openHash() .addFieldQuotedString("name", pd->name()); - - SectionInfo *si = Doxygen::sectionDict->find(pd->name()); + + const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) - m_output.addFieldQuotedString("title4", filterTitle(si->title)); + m_output.addFieldQuotedString("title4", filterTitle(si->title())); addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation()); m_output.closeHash(); @@ -2188,12 +2210,12 @@ bool PerlModGenerator::generatePerlModOutput() QFile outputFile; if (!createOutputFile(outputFile, pathDoxyDocsPM)) return false; - + FTextStream outputTextStream(&outputFile); PerlModOutputStream outputStream(&outputTextStream); m_output.setPerlModOutputStream(&outputStream); m_output.add("$doxydocs=").openHash(); - + m_output.openList("classes"); ClassSDict::Iterator cli(*Doxygen::classSDict); const ClassDef *cd; @@ -2209,14 +2231,12 @@ bool PerlModGenerator::generatePerlModOutput() m_output.closeList(); m_output.openList("files"); - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - const FileDef *fd; - for (;(fd=fni.current());++fni) - generatePerlModForFile(fd); + for (const auto &fd : *fn) + { + generatePerlModForFile(fd.get()); + } } m_output.closeList(); @@ -2295,7 +2315,7 @@ bool PerlModGenerator::createOutputDir(QDir &perlModDir) return false; } } - + perlModDir.setPath(outputDirectory+"/perlmod"); if (!perlModDir.exists() && !perlModDir.mkdir(outputDirectory+"/perlmod")) { @@ -2312,7 +2332,7 @@ bool PerlModGenerator::generateDoxyStructurePM() return false; FTextStream doxyModelPMStream(&doxyModelPM); - doxyModelPMStream << + doxyModelPMStream << "sub memberlist($) {\n" " my $prefix = $_[0];\n" " return\n" @@ -2442,7 +2462,7 @@ bool PerlModGenerator::generateDoxyStructurePM() "\t\tclasses =>\n" "\t\t [ \"list\", \"Classes\",\n" "\t\t [ \"hash\", \"Class\",\n" - "\t\t {\n" + "\t\t {\n" "\t\t name => [ \"string\", \"Classname\" ]\n" "\t\t }\n" "\t\t ],\n" @@ -2450,7 +2470,7 @@ bool PerlModGenerator::generateDoxyStructurePM() "\t\tnamespaces =>\n" "\t\t [ \"list\", \"Namespaces\",\n" "\t\t [ \"hash\", \"Namespace\",\n" - "\t\t {\n" + "\t\t {\n" "\t\t name => [ \"string\", \"NamespaceName\" ]\n" "\t\t }\n" "\t\t ],\n" @@ -2620,7 +2640,7 @@ bool PerlModGenerator::generateDoxyLatexStructurePL() return false; FTextStream doxyLatexStructurePLStream(&doxyLatexStructurePL); - doxyLatexStructurePLStream << + doxyLatexStructurePLStream << "use DoxyStructure;\n" "\n" "sub process($) {\n" @@ -2654,7 +2674,7 @@ bool PerlModGenerator::generateDoxyLatexPL() return false; FTextStream doxyLatexPLStream(&doxyLatexPL); - doxyLatexPLStream << + doxyLatexPLStream << "use DoxyStructure;\n" "use DoxyDocs;\n" "\n" @@ -2777,7 +2797,7 @@ bool PerlModGenerator::generateDoxyFormatTex() return false; FTextStream doxyFormatTexStream(&doxyFormatTex); - doxyFormatTexStream << + doxyFormatTexStream << "\\def\\Defcs#1{\\long\\expandafter\\def\\csname#1\\endcsname}\n" "\\Defcs{Empty}{}\n" "\\def\\IfEmpty#1{\\expandafter\\ifx\\csname#1\\endcsname\\Empty}\n" @@ -3023,12 +3043,12 @@ void generatePerlMod() (global-set-key '(control z) (lambda () (interactive) (save-excursion (if (< (mark) (point)) (exchange-point-and-mark)) - (let ((start (point)) (replacers + (let ((start (point)) (replacers '(("\\\\" "\\\\\\\\") ("\"" "\\\\\"") ("\t" "\\\\t") ("^.*$" "\"\\&\\\\n\"")))) - (while replacers + (while replacers (while (re-search-forward (caar replacers) (mark) t) (replace-match (cadar replacers) t)) (goto-char start) diff --git a/src/plantuml.cpp b/src/plantuml.cpp index fa50f2d..7995883 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -76,7 +76,7 @@ QCString PlantumlManager::writePlantUMLSource(const QCString &outDir,const QCStr uint pos = qcOutDir.findRev("/"); QCString generateType(qcOutDir.right(qcOutDir.length() - (pos + 1)) ); Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n","writePlantUMLSource",qPrint(generateType)); - PlantumlManager::instance()->insert(generateType,puName,format,text); + PlantumlManager::instance()->insert(generateType,puName,outDir,format,text); Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n","writePlantUMLSource",qPrint(generateType)); return baseName; @@ -178,7 +178,7 @@ PlantumlManager::~PlantumlManager() } static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles, - const QDict< QCString > &plantumlContent, + const QDict< PlantumlContent > &plantumlContent, PlantumlManager::OutputFormat format) { /* example : running: java -Djava.awt.headless=true @@ -244,25 +244,21 @@ static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles, } { - QDictIterator< QCString > it( plantumlContent); // See QDictIterator - QCString *nb; + QDictIterator< PlantumlContent > it( plantumlContent); // See QDictIterator + PlantumlContent *nb; for (it.toFirst();(nb=it.current());++it) { QCString pumlArguments(pumlArgs); msg("Generating PlantUML %s Files in %s\n",qPrint(pumlType),qPrint(it.currentKey())); pumlArguments+="-o \""; - pumlArguments+=Config_getString(OUTPUT_DIRECTORY); - pumlArguments+="/"; - pumlArguments+=it.currentKey(); + pumlArguments+=nb->outDir.data(); pumlArguments+="\" "; pumlArguments+="-charset UTF-8 -t"; pumlArguments+=pumlType; pumlArguments+=" "; QCString puFileName(""); - puFileName+=Config_getString(OUTPUT_DIRECTORY); - puFileName+="/"; - puFileName+=it.currentKey(); + puFileName+=nb->outDir.data(); puFileName+="/"; pumlOutDir=puFileName; puFileName+="inline_umlgraph_"; @@ -279,7 +275,7 @@ static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles, { err("Could not open file %s for writing\n",puFileName.data()); } - file.writeBlock( *nb, nb->length() ); + file.writeBlock( nb->content, nb->content.length() ); file.close(); Debug::print(Debug::Plantuml,0,"*** %s Running Plantuml arguments:%s\n","PlantumlManager::runPlantumlContent",qPrint(pumlArguments)); @@ -303,12 +299,12 @@ static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles, if (list) { QListIterator<QCString> li(*list); - QCString *nb; - for (li.toFirst();(nb=li.current());++li) + QCString *str_p; + for (li.toFirst();(str_p=li.current());++li) { const int maxCmdLine = 40960; QCString epstopdfArgs(maxCmdLine); - epstopdfArgs.sprintf("\"%s%s.eps\" --outfile=\"%s%s.pdf\"",qPrint(pumlOutDir),qPrint(*nb),qPrint(pumlOutDir),qPrint(*nb)); + epstopdfArgs.sprintf("\"%s%s.eps\" --outfile=\"%s%s.pdf\"",qPrint(pumlOutDir),qPrint(*str_p),qPrint(pumlOutDir),qPrint(*str_p)); Portable::sysTimerStart(); if ((exitCode=Portable::system("epstopdf",epstopdfArgs))!=0) { @@ -358,16 +354,16 @@ static void print(const QDict< QList <QCString> > &plantumlFiles) } } -static void print(const QDict<QCString> &plantumlContent) +static void print(const QDict<PlantumlContent> &plantumlContent) { if (Debug::isFlagSet(Debug::Plantuml)) { - QDictIterator< QCString > it( plantumlContent); // See QDictIterator - QCString *nb; + QDictIterator< PlantumlContent > it( plantumlContent); // See QDictIterator + PlantumlContent *nb; for (it.toFirst();(nb=it.current());++it) { Debug::print(Debug::Plantuml,0,"*** %s PlantumlContent key:%s\n","PlantumlManager::print Content",qPrint(it.currentKey())); - Debug::print(Debug::Plantuml,0,"*** %s Content :%s\n","PlantumlManager::print",qPrint(*nb)); + Debug::print(Debug::Plantuml,0,"*** %s Content :%s\n","PlantumlManager::print",qPrint(nb->content)); } } } @@ -384,22 +380,22 @@ static void addPlantumlFiles(QDict< QList<QCString> > &plantumlFiles, list->append(new QCString(value)); } -static void addPlantumlContent(QDict< QCString > &plantumlContent, - const QCString &key, const QCString &puContent) +static void addPlantumlContent(QDict< PlantumlContent > &plantumlContent, + const QCString &key, const QCString &outDir, const QCString &puContent) { - QCString* content = plantumlContent.find(key); + PlantumlContent* content = plantumlContent.find(key); if (content == 0) { - content = new QCString(""); + content = new PlantumlContent("",outDir); plantumlContent.insert(key,content); } - (*content)+=puContent; + (content->content)+=puContent; } void PlantumlManager::insert(const QCString &key, const QCString &value, - OutputFormat format,const QCString &puContent) + const QCString &outDir,OutputFormat format,const QCString &puContent) { int find; @@ -419,19 +415,19 @@ void PlantumlManager::insert(const QCString &key, const QCString &value, case PUML_BITMAP: addPlantumlFiles(m_pngPlantumlFiles,key,value); print(m_pngPlantumlFiles); - addPlantumlContent(m_pngPlantumlContent,key,puContent); + addPlantumlContent(m_pngPlantumlContent,key,outDir,puContent); print(m_pngPlantumlContent); break; case PUML_EPS: addPlantumlFiles(m_epsPlantumlFiles,key,value); print(m_epsPlantumlFiles); - addPlantumlContent(m_epsPlantumlContent,key,puContent); + addPlantumlContent(m_epsPlantumlContent,key,outDir,puContent); print(m_epsPlantumlContent); break; case PUML_SVG: addPlantumlFiles(m_svgPlantumlFiles,key,value); print(m_svgPlantumlFiles); - addPlantumlContent(m_svgPlantumlContent,key,puContent); + addPlantumlContent(m_svgPlantumlContent,key,outDir,puContent); print(m_svgPlantumlContent); break; } diff --git a/src/plantuml.h b/src/plantuml.h index d3a01f5..f2e9dec 100644 --- a/src/plantuml.h +++ b/src/plantuml.h @@ -24,6 +24,17 @@ #define MIN_PLANTUML_COUNT 8 class QCString; +struct PlantumlContent +{ + QCString outDir; + QCString content; + PlantumlContent(const QCString Content, const QCString OutDir) + { + outDir = OutDir; + content = Content; + }; + ~PlantumlContent(){}; +}; /** Singleton that manages plantuml relation actions */ class PlantumlManager @@ -58,15 +69,16 @@ class PlantumlManager ~PlantumlManager(); void insert(const QCString &key, const QCString &value, + const QCString &outDir, OutputFormat format, const QCString &puContent); static PlantumlManager *m_theInstance; QDict< QList<QCString> > m_pngPlantumlFiles; QDict< QList<QCString> > m_svgPlantumlFiles; QDict< QList<QCString> > m_epsPlantumlFiles; - QDict< QCString > m_pngPlantumlContent; // use circular queue for using multi-processor (multi threading) - QDict< QCString > m_svgPlantumlContent; - QDict< QCString > m_epsPlantumlContent; + QDict< PlantumlContent > m_pngPlantumlContent; // use circular queue for using multi-processor (multi threading) + QDict< PlantumlContent > m_svgPlantumlContent; + QDict< PlantumlContent > m_epsPlantumlContent; QCString m_cachedPlantumlAllContent; // read from CACHE_FILENAME file QCString m_currentPlantumlAllContent; // processing plantuml then write it into CACHE_FILENAME to reuse the next time as cache information }; diff --git a/src/portable.cpp b/src/portable.cpp index 3ee1081..d3799c7 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -207,11 +207,6 @@ unsigned int Portable::pid(void) return pid; } -#if defined(_WIN32) && !defined(__CYGWIN__) -#else - static char **last_environ; -#endif - #if !defined(_WIN32) || defined(__CYGWIN__) void loadEnvironment() { @@ -251,7 +246,7 @@ void Portable::setenv(const char *name,const char *value) loadEnvironment(); } - proc_env[name] = std::string(value); // create or replace exisiting value + proc_env[name] = std::string(value); // create or replace existing value #endif } @@ -261,9 +256,6 @@ void Portable::unsetenv(const char *variable) SetEnvironmentVariable(variable,0); #else /* Some systems don't have unsetenv(), so we do it ourselves */ - size_t len; - char **ep; - if (variable == NULL || *variable == '\0' || strchr (variable, '=') != NULL) { return; // not properly formatted @@ -348,10 +340,71 @@ char Portable::pathListSeparator(void) #endif } +static bool ExistsOnPath(const char *fileName) +{ + QFileInfo fi1(fileName); + if (fi1.exists()) return true; + + const char *p = Portable::getenv("PATH"); + char listSep = Portable::pathListSeparator(); + char pathSep = Portable::pathSeparator(); + QCString paths(p); + int strt = 0; + int idx; + while ((idx = paths.find(listSep,strt)) != -1) + { + QCString locFile(paths.mid(strt,idx-strt)); + locFile += pathSep; + locFile += fileName; + QFileInfo fi(locFile); + if (fi.exists()) return true; + strt = idx + 1; + } + // to be sure the last path component is checked as well + QCString locFile(paths.mid(strt)); + if (!locFile.isEmpty()) + { + locFile += pathSep; + locFile += fileName; + QFileInfo fi(locFile); + if (fi.exists()) return true; + } + return false; +} + +bool Portable::checkForExecutable(const char *fileName) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + char *extensions[] = {".bat",".com",".exe"}; + for (int i = 0; i < sizeof(extensions) / sizeof(*extensions); i++) + { + if (ExistsOnPath(QCString(fileName) + extensions[i])) return true; + } + return false; +#else + return ExistsOnPath(fileName); +#endif +} + const char *Portable::ghostScriptCommand(void) { #if defined(_WIN32) && !defined(__CYGWIN__) - return "gswin32c.exe"; + static char *gsexe = NULL; + if (!gsexe) + { + char *gsExec[] = {"gswin32c.exe","gswin64c.exe"}; + for (int i = 0; i < sizeof(gsExec) / sizeof(*gsExec); i++) + { + if (ExistsOnPath(gsExec[i])) + { + gsexe = gsExec[i]; + return gsexe; + } + } + gsexe = gsExec[0]; + return gsexe; + } + return gsexe; #else return "gs"; #endif @@ -518,3 +571,12 @@ const char *Portable::strnstr(const char *haystack, const char *needle, size_t h } return 0; } + +const char *Portable::devNull() +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + return "NUL"; +#else + return "/dev/null"; +#endif +} diff --git a/src/portable.h b/src/portable.h index 771108e..bf6cfea 100644 --- a/src/portable.h +++ b/src/portable.h @@ -43,6 +43,8 @@ namespace Portable void correct_path(void); void setShortDir(void); const char * strnstr(const char *haystack, const char *needle, size_t haystack_len); + const char * devNull(); + bool checkForExecutable(const char *fileName); } @@ -18,6 +18,8 @@ #ifndef PRE_H #define PRE_H +#include <memory> + class BufStr; class Preprocessor @@ -29,7 +31,7 @@ class Preprocessor void addSearchDir(const char *dir); private: struct Private; - Private *p; + std::unique_ptr<Private> p; }; #endif @@ -1,12 +1,10 @@ /****************************************************************************** * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -18,6 +16,9 @@ %option prefix="preYY" %option reentrant %option extra-type="struct preYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -25,20 +26,23 @@ * includes */ +#include <stack> +#include <deque> +#include <algorithm> +#include <set> +#include <string> +#include <map> +#include <utility> + #include <stdio.h> #include <assert.h> #include <ctype.h> #include <errno.h> -#include <qarray.h> -#include <qstack.h> -#include <qfile.h> -#include <qstrlist.h> -#include <qdict.h> +#include <qcstring.h> #include <qregexp.h> #include <qfileinfo.h> -#include <qdir.h> - + #include "pre.h" #include "constexp.h" #include "define.h" @@ -60,15 +64,19 @@ #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + // Toggle for some debugging info //#define DBG_CTX(x) fprintf x #define DBG_CTX(x) do { } while(0) +#if USE_STATE2STRING static const char *stateToString(int state); +#endif struct CondCtx { - CondCtx(int line,QCString id,bool b) + CondCtx(int line,QCString id,bool b) : lineNr(line),sectionId(id), skip(b) {} int lineNr; QCString sectionId; @@ -77,16 +85,15 @@ struct CondCtx struct FileState { - FileState(int size) : lineNr(1), curlyCount(0),fileBuf(size), - oldFileBuf(0), oldFileBufPos(0), bufState(0) {} - int lineNr; - int curlyCount; + FileState(int size) : fileBuf(size) {} + int lineNr = 1; + int curlyCount = 0; BufStr fileBuf; - BufStr *oldFileBuf; - int oldFileBufPos; - YY_BUFFER_STATE bufState; + BufStr *oldFileBuf = 0; + yy_size_t oldFileBufPos = 0; + YY_BUFFER_STATE bufState = 0; QCString fileName; -}; +}; /** @brief Singleton that manages the defines available while * preprocessing files. @@ -99,9 +106,8 @@ class DefineManager public: /** Creates an empty container for defines */ DefinesPerFile(DefineManager *parent) - : m_parent(parent), m_defines(257), m_includedFiles(17) + : m_parent(parent) { - m_defines.setAutoDelete(TRUE); } /** Destroys the object */ virtual ~DefinesPerFile() @@ -109,38 +115,37 @@ class DefineManager } /** Adds a define in the context of a file. Will replace * an existing define with the same name (redefinition) - * @param def The Define object to add. + * @param def The Define object to add. Ownership will be transferred. */ - void addDefine(Define *def) + void addDefine(std::unique_ptr<Define> &&def) { - Define *d = m_defines.find(def->name); - if (d!=0) // redefine + auto it = m_defines.find(def->name.data()); + if (it!=m_defines.end()) // redefine { - m_defines.remove(d->name); + m_defines.erase(it); } - m_defines.insert(def->name,def); + m_defines.insert(std::make_pair(toStdString(def->name),std::move(def))); } /** Adds an include file for this file * @param fileName The name of the include file */ void addInclude(const char *fileName) { - m_includedFiles.insert(fileName,(void*)0x8); + m_includedFiles.insert(fileName); } - void collectDefines(DefineDict *dict,QDict<void> &includeStack); + void collectDefines(DefineMapRef &map,std::set<std::string> &includeStack); private: DefineManager *m_parent; - DefineDict m_defines; - QDict<void> m_includedFiles; + DefineMapOwning m_defines; + std::set<std::string> m_includedFiles; }; public: friend class DefinesPerFile; /** Creates a new DefineManager object */ - DefineManager() : m_fileMap(1009), m_contextDefines(1009) + DefineManager() { - m_fileMap.setAutoDelete(TRUE); } /** Destroys the object */ @@ -157,12 +162,12 @@ class DefineManager //printf("DefineManager::startContext()\n"); m_contextDefines.clear(); if (fileName==0) return; - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf==0) + //DefinesPerFile *dpf = m_fileMap.find(fileName); + auto it = m_fileMap.find(fileName); + if (it==m_fileMap.end()) { //printf("New file!\n"); - dpf = new DefinesPerFile(this); - m_fileMap.insert(fileName,dpf); + m_fileMap.emplace(toStdString(fileName),std::make_unique<DefinesPerFile>(this)); } } /** Ends the context started with startContext() freeing any @@ -182,43 +187,42 @@ class DefineManager { if (fileName==0) return; //printf("DefineManager::addFileToContext(%s)\n",fileName); - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf==0) + auto it = m_fileMap.find(fileName); + if (it==m_fileMap.end()) { //printf("New file!\n"); - dpf = new DefinesPerFile(this); - m_fileMap.insert(fileName,dpf); + m_fileMap.emplace(toStdString(fileName),std::make_unique<DefinesPerFile>(this)); } else { //printf("existing file!\n"); - QDict<void> includeStack(17); - dpf->collectDefines(&m_contextDefines,includeStack); + std::set<std::string> includeStack; + it->second->collectDefines(m_contextDefines,includeStack); } } /** Add a define to the manager object. * @param fileName The file in which the define was found - * @param def The Define object to add. + * @param def The Define object to add. Ownership will be transferred. */ - void addDefine(const char *fileName,Define *def) + void addDefine(const char *fileName,std::unique_ptr<Define> &&def) { if (fileName==0) return; //printf("DefineManager::addDefine(%s,%s)\n",fileName,def->name.data()); - Define *d = m_contextDefines.find(def->name); - if (d!=0) // redefine + + m_contextDefines[def->name.data()] = def.get(); + + auto it = m_fileMap.find(fileName); + if (it==m_fileMap.end()) { - m_contextDefines.remove(d->name); + auto ptr = std::make_unique<DefinesPerFile>(this); + ptr->addDefine(std::move(def)); + m_fileMap.emplace(toStdString(fileName),std::move(ptr)); } - m_contextDefines.insert(def->name,def); - - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf==0) + else { - dpf = new DefinesPerFile(this); - m_fileMap.insert(fileName,dpf); + it->second->addDefine(std::move(def)); } - dpf->addDefine(def); } /** Add an include relation to the manager object. @@ -229,52 +233,66 @@ class DefineManager { //printf("DefineManager::addInclude(%s,%s)\n",fromFileName,toFileName); if (fromFileName==0 || toFileName==0) return; - DefinesPerFile *dpf = m_fileMap.find(fromFileName); - if (dpf==0) + auto it = m_fileMap.find(fromFileName); + if (it==m_fileMap.end()) { - dpf = new DefinesPerFile(this); - m_fileMap.insert(fromFileName,dpf); + auto ptr = std::make_unique<DefinesPerFile>(this); + ptr->addInclude(toFileName); + m_fileMap.emplace(toStdString(fromFileName),std::move(ptr)); + } + else + { + it->second->addInclude(toFileName); } - dpf->addInclude(toFileName); } - /** Returns a Define object given its name or 0 if the Define does + /** Returns a reference to a Define object given its name or 0 if the Define does * not exist. */ - Define *isDefined(const char *name) const + Define *isDefined(const char *name) { - Define *d = m_contextDefines.find(name); - if (d && d->undef) d=0; + Define *d=0; + auto it = m_contextDefines.find(name); + if (it!=m_contextDefines.end()) + { + d = it->second; + if (d->undef) + { + d=0; + } + } //printf("isDefined(%s)=%p\n",name,d); return d; } + /** Returns a reference to the defines found in the current context. */ - const DefineDict &defineContext() const + const DefineMapRef &defineContext() const { return m_contextDefines; } private: /** Helper function to collect all define for a given file */ - void collectDefinesForFile(const char *fileName,DefineDict *dict) + void collectDefinesForFile(const char *fileName,DefineMapRef &map) { if (fileName==0) return; - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf) + auto it = m_fileMap.find(fileName); + if (it!=m_fileMap.end()) { - QDict<void> includeStack(17); - dpf->collectDefines(dict,includeStack); + std::set<std::string> includeStack; + it->second->collectDefines(map,includeStack); } } /** Helper function to return the DefinesPerFile object for a given file name. */ DefinesPerFile *find(const char *fileName) const { - if (fileName==0) return 0; - return m_fileMap.find(fileName); + if (fileName==0) return nullptr; + auto it = m_fileMap.find(fileName); + return it!=m_fileMap.end() ? it->second.get() : nullptr; } - QDict<DefinesPerFile> m_fileMap; - DefineDict m_contextDefines; + std::map< std::string,std::unique_ptr<DefinesPerFile> > m_fileMap; + DefineMapRef m_contextDefines; }; @@ -286,39 +304,40 @@ class DefineManager * case there is a cyclic include dependency. */ void DefineManager::DefinesPerFile::collectDefines( - DefineDict *dict,QDict<void> &includeStack) + DefineMapRef &map,std::set<std::string> &includeStack) { //printf("DefinesPerFile::collectDefines #defines=%d\n",m_defines.count()); { - QDictIterator<void> di(m_includedFiles); - for (di.toFirst();(di.current());++di) + for (auto incFile : m_includedFiles) { - QCString incFile = di.currentKey(); - DefinesPerFile *dpf = m_parent->find(incFile); - if (dpf && includeStack.find(incFile)==0) + DefinesPerFile *dpf = m_parent->find(incFile.c_str()); + if (dpf && includeStack.find(incFile)==includeStack.end()) { //printf(" processing include %s\n",incFile.data()); - includeStack.insert(incFile,(void*)0x8); - dpf->collectDefines(dict,includeStack); + includeStack.insert(incFile); + dpf->collectDefines(map,includeStack); } } } { - QDictIterator<Define> di(m_defines); - Define *def; - for (di.toFirst();(def=di.current());++di) + for (auto &kv : m_defines) { - Define *d = dict->find(def->name); - if (d!=0) // redefine - { - dict->remove(d->name); - } - dict->insert(def->name,def); + const std::unique_ptr<Define> &def = kv.second; + map[def->name.data()] = def.get(); //printf(" adding define %s\n",def->name.data()); } } } + +/* ----------------------------------------------------------------- + * + * global state + */ +static std::set<std::string> g_allIncludes; +static DefineManager g_defineManager; + + /* ----------------------------------------------------------------- * * scanner's state @@ -326,62 +345,59 @@ void DefineManager::DefinesPerFile::collectDefines( struct preYY_state { - preYY_state() : allIncludes(10009) {} - int yyLineNr = 1; - int yyMLines = 1; - int yyColNr = 1; + int yyLineNr = 1; + int yyMLines = 1; + int yyColNr = 1; QCString yyFileName; - FileDef *yyFileDef; - FileDef *inputFileDef; - int ifcount = 0; - QStrList *pathList = 0; - QStack<FileState> includeStack; - QDict<int> *argDict = 0; - int defArgs = -1; + FileDef *yyFileDef = 0; + FileDef *inputFileDef = 0; + int ifcount = 0; + int defArgs = -1; QCString defName; QCString defText; QCString defLitText; QCString defArgsStr; QCString defExtraSpacing; - bool defVarArgs; - int level; - int lastCContext; - int lastCPPContext; - QArray<int> levelGuard; - BufStr *inputBuf = 0; - int inputBufPos; - BufStr *outputBuf = 0; - int roundCount; - bool quoteArg; - DefineDict *expandedDict = 0; - int findDefArgContext; - bool expectGuard; + bool defVarArgs = false; + int lastCContext = 0; + int lastCPPContext = 0; + BufStr *inputBuf = 0; + yy_size_t inputBufPos = 0; + BufStr *outputBuf = 0; + int roundCount = 0; + bool quoteArg = false; + int findDefArgContext = 0; + bool expectGuard = false; QCString guardName; QCString lastGuardName; QCString incName; QCString guardExpr; - int curlyCount; - bool nospaces; // add extra spaces during macro expansion - - bool macroExpansion; // from the configuration - bool expandOnlyPredef; // from the configuration - int commentCount; - bool insideComment; - bool isImported; + int curlyCount = 0; + bool nospaces = false; // add extra spaces during macro expansion + + bool macroExpansion = false; // from the configuration + bool expandOnlyPredef = false; // from the configuration + int commentCount = 0; + bool insideComment = false; + bool isImported = false; QCString blockName; - int condCtx; - bool skip; - QStack<CondCtx> condStack; - bool insideCS; // C# has simpler preprocessor - bool isSource; - - int fenceSize = 0; - bool ccomment; + int condCtx = 0; + bool skip = false; + bool insideCS = false; // C# has simpler preprocessor + bool insideFtn = false; + bool isSource = false; + + yy_size_t fenceSize = 0; + bool ccomment = false; QCString delimiter; - QDict<void> allIncludes; - QDict<void> expansionDict; - DefineManager defineManager; - ConstExpressionParser constExpParser; + std::vector<std::string> pathList; + std::map<std::string,int> argMap; + std::stack<bool> levelGuard; + std::stack< std::unique_ptr<CondCtx> > condStack; + std::deque< std::unique_ptr<FileState> > includeStack; + std::map<std::string,Define*> expandedDict; + std::set<std::string> expanded; + ConstExpressionParser constExpParser; }; // stateless functions @@ -402,9 +418,9 @@ static bool computeExpression(yyscan_t yyscanner,const QCString &expr); static void startCondSection(yyscan_t yyscanner,const char *sectId); static void endCondSection(yyscan_t yyscanner); static void addDefine(yyscan_t yyscanner); -static Define * newDefine(yyscan_t yyscanner); +static std::unique_ptr<Define> newDefine(yyscan_t yyscanner); static void setFileName(yyscan_t yyscanner,const char *name); -static int yyread(yyscan_t yyscanner,char *buf,int max_size); +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); /* ----------------------------------------------------------------- */ @@ -472,7 +488,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <*>"??"[=/'()!<>-] { // Trigraph unput(resolveTrigraph(yytext[2])); } -<Start>^{B}*"#" { BEGIN(Command); yyextra->yyColNr+=yyleng; yyextra->yyMLines=0;} +<Start>^{B}*"#" { BEGIN(Command); yyextra->yyColNr+=(int)yyleng; yyextra->yyMLines=0;} <Start>^{B}*/[^#] { outputArray(yyscanner,yytext,(int)yyleng); BEGIN(CopyLine); @@ -492,12 +508,12 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) name=name.left(name.find('(')).stripWhiteSpace(); Define *def=0; - if (skipFuncMacros && + if (skipFuncMacros && !yyextra->insideFtn && name!="Q_PROPERTY" && !( - (yyextra->includeStack.isEmpty() || yyextra->curlyCount>0) && + (yyextra->includeStack.empty() || yyextra->curlyCount>0) && yyextra->macroExpansion && - (def=yyextra->defineManager.isDefined(name)) && + (def=g_defineManager.isDefined(name)) && /*macroIsAccessible(def) &&*/ (!yyextra->expandOnlyPredef || def->isPredefined) ) @@ -528,14 +544,14 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(CopyRawString); } <CopyLine>"{" { // count brackets inside the main file - if (yyextra->includeStack.isEmpty()) + if (yyextra->includeStack.empty()) { yyextra->curlyCount++; } outputChar(yyscanner,*yytext); } <CopyLine>"}" { // count brackets inside the main file - if (yyextra->includeStack.isEmpty() && yyextra->curlyCount>0) + if (yyextra->includeStack.empty() && yyextra->curlyCount>0) { yyextra->curlyCount--; } @@ -623,16 +639,16 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) yyextra->expectGuard = FALSE; Define *def=0; //def=yyextra->globalDefineDict->find(yytext); - //def=yyextra->defineManager.isDefined(yytext); - //printf("Search for define %s found=%d yyextra->includeStack.isEmpty()=%d " + //def=g_defineManager.isDefined(yytext); + //printf("Search for define %s found=%d yyextra->includeStack.empty()=%d " // "yyextra->curlyCount=%d yyextra->macroExpansion=%d yyextra->expandOnlyPredef=%d " // "isPreDefined=%d\n",yytext,def ? 1 : 0, - // yyextra->includeStack.isEmpty(),yyextra->curlyCount,yyextra->macroExpansion,yyextra->expandOnlyPredef, + // yyextra->includeStack.empty(),yyextra->curlyCount,yyextra->macroExpansion,yyextra->expandOnlyPredef, // def ? def->isPredefined : -1 // ); - if ((yyextra->includeStack.isEmpty() || yyextra->curlyCount>0) && + if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) && yyextra->macroExpansion && - (def=yyextra->defineManager.isDefined(yytext)) && + (def=g_defineManager.isDefined(yytext)) && /*(def->isPredefined || macroIsAccessible(def)) && */ (!yyextra->expandOnlyPredef || def->isPredefined) ) @@ -658,9 +674,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <CopyLine>{ID} { Define *def=0; - if ((yyextra->includeStack.isEmpty() || yyextra->curlyCount>0) && + if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) && yyextra->macroExpansion && - (def=yyextra->defineManager.isDefined(yytext)) && + (def=g_defineManager.isDefined(yytext)) && def->nargs==-1 && /*(def->isPredefined || macroIsAccessible(def)) &&*/ (!yyextra->expandOnlyPredef || def->isPredefined) @@ -792,7 +808,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <Command>("cmake")?"define"{B}+ { //printf("!!!DefName\n"); - yyextra->yyColNr+=yyleng; + yyextra->yyColNr+=(int)yyleng; BEGIN(DefName); } <Command>"ifdef"/{B}*"(" { @@ -834,7 +850,6 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } } <Command>"else"/[^a-z_A-Z0-9\x80-\xFF] { - //printf("else yyextra->levelGuard[%d]=%d\n",yyextra->level-1,yyextra->levelGuard[yyextra->level-1]); if (otherCaseDone(yyscanner)) { yyextra->ifcount=0; @@ -843,7 +858,6 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) else { setCaseDone(yyscanner,TRUE); - //yyextra->levelGuard[yyextra->level-1]=TRUE; } } <Command>"undef"{B}+ { @@ -876,10 +890,10 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) yyextra->yyLineNr++; } <IgnoreLine>. -<Command>. {yyextra->yyColNr+=yyleng;} +<Command>. {yyextra->yyColNr+=(int)yyleng;} <UndefName>{ID} { Define *def; - if ((def=yyextra->defineManager.isDefined(yytext)) + if ((def=g_defineManager.isDefined(yytext)) /*&& !def->isPredefined*/ && !def->nonRecursive ) @@ -909,7 +923,6 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) // yyextra->guardExpr.data()); bool guard=computeExpression(yyscanner,yyextra->guardExpr); setCaseDone(yyscanner,guard); - //printf("if yyextra->levelGuard[%d]=%d\n",yyextra->level-1,yyextra->levelGuard[yyextra->level-1]); if (guard) { BEGIN(Start); @@ -922,7 +935,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <DefinedExpr1,DefinedExpr2>\\\n { yyextra->yyLineNr++; outputChar(yyscanner,'\n'); } <DefinedExpr1>{ID} { - if (yyextra->defineManager.isDefined(yytext) || yyextra->guardName==yytext) + if (g_defineManager.isDefined(yytext) || yyextra->guardName==yytext) yyextra->guardExpr+=" 1L "; else yyextra->guardExpr+=" 0L "; @@ -930,7 +943,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(Guard); } <DefinedExpr2>{ID} { - if (yyextra->defineManager.isDefined(yytext) || yyextra->guardName==yytext) + if (g_defineManager.isDefined(yytext) || yyextra->guardName==yytext) yyextra->guardExpr+=" 1L "; else yyextra->guardExpr+=" 0L "; @@ -1060,10 +1073,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <DefName>{ID}/("\\\n")*"(" { // define with argument //printf("Define() '%s'\n",yytext); - delete yyextra->argDict; - yyextra->argDict = new QDict<int>(31); - yyextra->argDict->setAutoDelete(TRUE); - yyextra->defArgs = 0; + yyextra->argMap.clear(); + yyextra->defArgs = 0; yyextra->defArgsStr.resize(0); yyextra->defText.resize(0); yyextra->defLitText.resize(0); @@ -1074,7 +1085,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <DefName>{ID}{B}+"1"/[ \r\t\n] { // special case: define with 1 -> can be "guard" //printf("Define '%s'\n",yytext); - delete yyextra->argDict; yyextra->argDict=0; + yyextra->argMap.clear(); yyextra->defArgs = -1; yyextra->defArgsStr.resize(0); yyextra->defName = yytext; @@ -1103,7 +1114,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) yyextra->expectGuard=FALSE; } <DefName>{ID}/{B}*"\n" { // empty define - delete yyextra->argDict; yyextra->argDict=0; + yyextra->argMap.clear(); yyextra->defArgs = -1; yyextra->defName = yytext; yyextra->defArgsStr.resize(0); @@ -1132,7 +1143,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <DefName>{ID}/{B}* { // define with content //printf("Define '%s'\n",yytext); - delete yyextra->argDict; yyextra->argDict=0; + yyextra->argMap.clear(); yyextra->defArgs = -1; yyextra->defArgsStr.resize(0); yyextra->defText.resize(0); @@ -1162,7 +1173,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <DefineArg>"..." { // Variadic macro yyextra->defVarArgs = TRUE; yyextra->defArgsStr+=yytext; - yyextra->argDict->insert("__VA_ARGS__",new int(yyextra->defArgs)); + yyextra->argMap.emplace(std::string("__VA_ARGS__"),yyextra->defArgs); yyextra->defArgs++; } <DefineArg>{ID}{B}*("..."?) { @@ -1175,7 +1186,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } argName = argName.stripWhiteSpace(); yyextra->defArgsStr+=yytext; - yyextra->argDict->insert(argName,new int(yyextra->defArgs)); + yyextra->argMap.emplace(toStdString(argName),yyextra->defArgs); yyextra->defArgs++; } /* @@ -1236,7 +1247,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) else { outputArray(yyscanner,yytext,(int)yyleng); - yyextra->fenceSize=yyleng; + yyextra->fenceSize=(int)yyleng; BEGIN(SkipVerbatim); } } @@ -1249,7 +1260,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) else { outputArray(yyscanner,yytext,(int)yyleng); - yyextra->fenceSize=yyleng; + yyextra->fenceSize=(int)yyleng; BEGIN(SkipVerbatim); } } @@ -1389,14 +1400,14 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <SkipVerbatim>^({B}*"*"+)?{B}{0,3}"~~~"[~]* { outputArray(yyscanner,yytext,(int)yyleng); - if (yyextra->fenceSize==yyleng) + if (yyextra->fenceSize==(yy_size_t)yyleng) { BEGIN(SkipCComment); } } <SkipVerbatim>^({B}*"*"+)?{B}{0,3}"```"[`]* { outputArray(yyscanner,yytext,(int)yyleng); - if (yyextra->fenceSize==yyleng) + if (yyextra->fenceSize==(yy_size_t)yyleng) { BEGIN(SkipCComment); } @@ -1485,15 +1496,12 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } if (yyextra->defArgs>0) { - int *n; - if ((n=(*yyextra->argDict)[yytext])) + auto it = yyextra->argMap.find(yytext); + if (it!=yyextra->argMap.end()) { - //if (!yyextra->quoteArg) yyextra->defText+=' '; + int n = it->second; yyextra->defText+='@'; - QCString numStr; - numStr.sprintf("%d",*n); - yyextra->defText+=numStr; - //if (!yyextra->quoteArg) yyextra->defText+=' '; + yyextra->defText+=QCString().setNum(n); } else { @@ -1532,19 +1540,18 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) outputChar(yyscanner,'\n'); Define *def=0; //printf("Define name='%s' text='%s' litTexti='%s'\n",yyextra->defName.data(),yyextra->defText.data(),yyextra->defLitText.data()); - if (yyextra->includeStack.isEmpty() || yyextra->curlyCount>0) + if (yyextra->includeStack.empty() || yyextra->curlyCount>0) { addDefine(yyscanner); } - def=yyextra->defineManager.isDefined(yyextra->defName); + def=g_defineManager.isDefined(yyextra->defName); if (def==0) // new define { //printf("new define '%s'!\n",yyextra->defName.data()); - Define *nd = newDefine(yyscanner); - yyextra->defineManager.addDefine(yyextra->yyFileName,nd); + g_defineManager.addDefine(yyextra->yyFileName,newDefine(yyscanner)); // also add it to the local file list if it is a source file - //if (yyextra->isSource && yyextra->includeStack.isEmpty()) + //if (yyextra->isSource && yyextra->includeStack.empty()) //{ // yyextra->fileDefineDict->insert(yyextra->defName,nd); //} @@ -1569,7 +1576,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) //printf("error: define %s is defined more than once!\n",yyextra->defName.data()); } } - delete yyextra->argDict; yyextra->argDict=0; + yyextra->argMap.clear(); yyextra->yyLineNr++; yyextra->yyColNr=1; yyextra->lastGuardName.resize(0); @@ -1611,15 +1618,15 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <DefineText>. { yyextra->defText += *yytext; yyextra->defLitText+=yytext; } <<EOF>> { DBG_CTX((stderr,"End of include file\n")); - //printf("Include stack depth=%d\n",yyextra->includeStack.count()); - if (yyextra->includeStack.isEmpty()) + //printf("Include stack depth=%d\n",yyextra->includeStack.size()); + if (yyextra->includeStack.empty()) { DBG_CTX((stderr,"Terminating scanner!\n")); yyterminate(); } else { - FileState *fs=yyextra->includeStack.pop(); + const std::unique_ptr<FileState> &fs=yyextra->includeStack.back(); //fileDefineCache->merge(yyextra->yyFileName,fs->fileName); YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER; yy_switch_to_buffer( fs->bufState, yyscanner ); @@ -1628,17 +1635,17 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) //preYYin = fs->oldYYin; yyextra->inputBuf = fs->oldFileBuf; yyextra->inputBufPos = fs->oldFileBufPos; - yyextra->curlyCount = fs->curlyCount; + yyextra->curlyCount = fs->curlyCount; setFileName(yyscanner,fs->fileName); DBG_CTX((stderr,"######## FileName %s\n",yyextra->yyFileName.data())); - + // Deal with file changes due to // #include's within { .. } blocks QCString lineStr(15+yyextra->yyFileName.length()); lineStr.sprintf("# %d \"%s\" 2",yyextra->yyLineNr,yyextra->yyFileName.data()); outputArray(yyscanner,lineStr.data(),lineStr.length()); - - delete fs; fs=0; + + yyextra->includeStack.pop_back(); } } <*>"/*"/"*/" | @@ -1682,11 +1689,11 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) ///////////////////////////////////////////////////////////////////////////////////// -static int yyread(yyscan_t yyscanner,char *buf,int max_size) +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - int bytesInBuf = state->inputBuf->curPos()-state->inputBufPos; - int bytesToCopy = QMIN(max_size,bytesInBuf); + yy_size_t bytesInBuf = state->inputBuf->curPos()-state->inputBufPos; + yy_size_t bytesToCopy = QMIN(max_size,bytesInBuf); memcpy(buf,state->inputBuf->data()+state->inputBufPos,bytesToCopy); state->inputBufPos+=bytesToCopy; return bytesToCopy; @@ -1698,36 +1705,34 @@ static void setFileName(yyscan_t yyscanner,const char *name) bool ambig; QFileInfo fi(name); state->yyFileName=fi.absFilePath().utf8(); - state->yyFileDef=findFileDef(Doxygen::inputNameDict,state->yyFileName,ambig); + state->yyFileDef=findFileDef(Doxygen::inputNameLinkedMap,state->yyFileName,ambig); if (state->yyFileDef==0) // if this is not an input file check if it is an // include file { - state->yyFileDef=findFileDef(Doxygen::includeNameDict,state->yyFileName,ambig); + state->yyFileDef=findFileDef(Doxygen::includeNameLinkedMap,state->yyFileName,ambig); } //printf("setFileName(%s) state->yyFileName=%s state->yyFileDef=%p\n", // name,state->yyFileName.data(),state->yyFileDef); if (state->yyFileDef && state->yyFileDef->isReference()) state->yyFileDef=0; state->insideCS = getLanguageFromFileName(state->yyFileName)==SrcLangExt_CSharp; + state->insideFtn = getLanguageFromFileName(state->yyFileName)==SrcLangExt_Fortran; state->isSource = guessSection(state->yyFileName); } static void incrLevel(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - state->level++; - state->levelGuard.resize(state->level); - state->levelGuard[state->level-1]=FALSE; - //printf("%s line %d: incrLevel %d\n",yyextra->yyFileName.data(),yyextra->yyLineNr,yyextra->level); + state->levelGuard.push(false); + //printf("%s line %d: incrLevel %d\n",yyextra->yyFileName.data(),yyextra->yyLineNr,yyextra->levelGuard.size()); } static void decrLevel(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - //printf("%s line %d: decrLevel %d\n",state->yyFileName.data(),state->yyLineNr,state->level); - if (state->level > 0) + //printf("%s line %d: decrLevel %d\n",state->yyFileName.data(),state->yyLineNr,state->levelGuard.size()); + if (!state->levelGuard.empty()) { - state->level--; - state->levelGuard.resize(state->level); + state->levelGuard.pop(); } else { @@ -1738,21 +1743,21 @@ static void decrLevel(yyscan_t yyscanner) static bool otherCaseDone(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - if (state->level==0) + if (state->levelGuard.empty()) { warn(state->yyFileName,state->yyLineNr,"Found an #else without a preceding #if.\n"); return TRUE; } else { - return state->levelGuard[state->level-1]; + return state->levelGuard.top(); } } static void setCaseDone(yyscan_t yyscanner,bool value) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - state->levelGuard[state->level-1]=value; + state->levelGuard.top()=value; } @@ -1773,28 +1778,22 @@ static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,b // global guard if (state->curlyCount==0) // not #include inside { ... } { - if (state->allIncludes.find(absName)!=0) + if (g_allIncludes.find(absName.data())!=g_allIncludes.end()) { alreadyIncluded = TRUE; //printf(" already included 1\n"); return 0; // already done } - state->allIncludes.insert(absName,(void *)0x8); + g_allIncludes.insert(absName.data()); } // check include stack for absName - QStack<FileState> tmpStack; - state->includeStack.setAutoDelete(FALSE); - while ((fs=state->includeStack.pop())) - { - if (fs->fileName==absName) alreadyIncluded=TRUE; - tmpStack.push(fs); - } - while ((fs=tmpStack.pop())) - { - state->includeStack.push(fs); - } - state->includeStack.setAutoDelete(TRUE); + alreadyIncluded = std::any_of( + state->includeStack.begin(), + state->includeStack.end(), + [absName](const std::unique_ptr<FileState> &lfs) + { return lfs->fileName==absName; } + ); if (alreadyIncluded) { @@ -1804,7 +1803,6 @@ static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,b //printf("#include %s\n",absName.data()); fs = new FileState(fi.size()+4096); - alreadyIncluded = FALSE; if (!readInputFile(absName,fs->fileBuf)) { // error //printf(" error reading\n"); @@ -1857,19 +1855,18 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn } } } - if (state->pathList==0) + if (state->pathList.empty()) { return 0; } - char *s=state->pathList->first(); - while (s) + for (auto path : state->pathList) { - QCString absName = (QCString)s+"/"+fileName; - //printf(" Looking for %s in %s\n",fileName,s); - FileState *fs = checkAndOpenFile(yyscanner,absName,alreadyIncluded); + std::string absName = path+"/"+fileName; + //printf(" Looking for %s in %s\n",fileName,path.c_str()); + FileState *fs = checkAndOpenFile(yyscanner,absName.c_str(),alreadyIncluded); if (fs) { - setFileName(yyscanner,absName); + setFileName(yyscanner,absName.c_str()); state->yyLineNr=1; //printf(" -> found it\n"); return fs; @@ -1878,16 +1875,14 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn { return 0; } - - s=state->pathList->next(); - } + } return 0; } static QCString extractTrailingComment(const char *s) { if (s==0) return ""; - int i=strlen(s)-1; + int i=(int)strlen(s)-1; while (i>=0) { char c=s[i]; @@ -1989,7 +1984,7 @@ static QCString stringize(const QCString &s) pc=0; while (i<s.length() && inString) { - char c=s.at(i++); + c=s.at(i++); if (c=='"') { result+="\\\""; @@ -2070,7 +2065,7 @@ static inline void addTillEndOfString(yyscan_t yyscanner,const QCString &expr,QC static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result,int level) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - //printf(">replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s') level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),state->level); + //printf(">replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s') level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),state->levelGuard.size()); uint j=pos; len=0; result.resize(0); @@ -2082,13 +2077,12 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin } if (cc!='(') { - unputChar(yyscanner,expr,rest,j,cc); + unputChar(yyscanner,expr,rest,j,(char)cc); return FALSE; } getNextChar(yyscanner,expr,rest,j); // eat the '(' character - QDict<QCString> argTable; // list of arguments - argTable.setAutoDelete(TRUE); + std::map<std::string,std::string> argTable; // list of arguments QCString arg; int argCount=0; bool done=FALSE; @@ -2111,12 +2105,12 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin char c=(char)cc; if (c=='(') // argument is a function => search for matching ) { - int level=1; + int lvl=1; arg+=c; //char term='\0'; while ((cc=getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0) { - char c=(char)cc; + c=(char)cc; //printf("processing %c: term=%c (%d)\n",c,term,term); if (c=='\'' || c=='\"') // skip ('s and )'s inside strings { @@ -2125,13 +2119,13 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin } if (c==')') { - level--; + lvl--; arg+=c; - if (level==0) break; + if (lvl==0) break; } else if (c=='(') { - level++; + lvl++; arg+=c; } else @@ -2151,7 +2145,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin argKey.sprintf("@%d",argCount++); // key name arg=arg.stripWhiteSpace(); // add argument to the lookup table - argTable.insert(argKey, new QCString(arg)); + argTable.emplace(toStdString(argKey), toStdString(arg)); arg.resize(0); if (c==')') // end of the argument list { @@ -2243,7 +2237,6 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin else // argument marker => read the argument number { QCString key="@"; - QCString *subst=0; bool hash=FALSE; int l=k-1; // search for ## backward @@ -2262,9 +2255,10 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin if (l<(int)d.length()-1 && d.at(l)=='#' && d.at(l+1)=='#') hash=TRUE; } //printf("request key %s result %s\n",key.data(),argTable[key]->data()); - if (key.length()>1 && (subst=argTable[key])) + auto it = argTable.find(key.data()); + if (it!=argTable.end()) { - QCString substArg=*subst; + QCString substArg = it->second.c_str(); //printf("substArg='%s'\n",substArg.data()); // only if no ## operator is before or after the argument // marker we do macro expansion. @@ -2313,10 +2307,10 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin } len=j-pos; result=resExpr; - //printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%d return=TRUE\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),result.data(),state->level); + //printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%d return=TRUE\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),result.data(),state->levelGuard.size()); return TRUE; } - //printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%d return=FALSE\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),result.data(),state->level); + //printf("<replaceFunctionMacro(expr='%s',rest='%s',pos=%d,def='%s',result='%s') level=%d return=FALSE\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),result.data(),state->levelGuard.size()); return FALSE; } @@ -2379,6 +2373,8 @@ static int getNextId(const QCString &expr,int p,int *l) return -1; } +#define MAX_EXPANSION_DEPTH 50 + /*! performs recursive macro expansion on the string \a expr * starting at position \a pos. * May read additional characters from the input while re-scanning! @@ -2392,19 +2388,22 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in //printf("<expandExpression: empty\n"); return TRUE; } - if (state->expansionDict.find(expr)!=0) // check for recursive expansions + if (state->expanded.find(expr.data())!=state->expanded.end() && + level>MAX_EXPANSION_DEPTH) // check for too deep recursive expansions { //printf("<expandExpression: already expanded expr='%s'\n",expr.data()); return FALSE; } else { - state->expansionDict.insert(expr,(void*)0x8); + state->expanded.insert(expr.data()); } QCString macroName; QCString expMacro; bool definedTest=FALSE; int i=pos,l,p,len; + int startPos = pos; + int samePosCount=0; while ((p=getNextId(expr,i,&l))!=-1) // search for an macro name { bool replaced=FALSE; @@ -2412,9 +2411,9 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in //printf(" p=%d macroName=%s\n",p,macroName.data()); if (p<2 || !(expr.at(p-2)=='@' && expr.at(p-1)=='-')) // no-rescan marker? { - if (state->expandedDict->find(macroName)==0) // expand macro + if (state->expandedDict.find(macroName.data())==state->expandedDict.end()) // expand macro { - Define *def=state->defineManager.isDefined(macroName); + Define *def=g_defineManager.isDefined(macroName); if (macroName=="defined") { //printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data()); @@ -2463,9 +2462,9 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in bool expanded=false; if (def && !def->nonRecursive) { - state->expandedDict->insert(macroName,def); + state->expandedDict.emplace(toStdString(macroName),def); expanded = expandExpression(yyscanner,resultExpr,&restExpr,0,level+1); - state->expandedDict->remove(macroName); + state->expandedDict.erase(toStdString(macroName)); } if (expanded) { @@ -2492,6 +2491,20 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in i=p+l+2; //i=p+l; } + // check for too many inplace expansions without making progress + if (i==startPos) + { + samePosCount++; + } + else + { + startPos=i; + samePosCount=0; + } + if (samePosCount>MAX_EXPANSION_DEPTH) + { + break; + } } else // no re-scan marker found, skip the macro name { @@ -2650,7 +2663,7 @@ static QCString removeIdsAndMarkers(const char *s) { nextChar: result+=c; - char lc=tolower(c); + char lc=(char)tolower(c); if (!isId(lc) && lc!='.' /*&& lc!='-' && lc!='+'*/) inNum=FALSE; p++; } @@ -2729,7 +2742,7 @@ static bool computeExpression(yyscan_t yyscanner,const QCString &expr) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); QCString e=expr; - state->expansionDict.clear(); + state->expanded.clear(); expandExpression(yyscanner,e,0,0,0); //printf("after expansion '%s'\n",e.data()); e = removeIdsAndMarkers(e); @@ -2746,17 +2759,17 @@ static QCString expandMacro(yyscan_t yyscanner,const QCString &name) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); QCString n=name; - state->expansionDict.clear(); + state->expanded.clear(); expandExpression(yyscanner,n,0,0,0); n=removeMarkers(n); //printf("expandMacro '%s'->'%s'\n",name.data(),n.data()); return n; } -static Define *newDefine(yyscan_t yyscanner) +static std::unique_ptr<Define> newDefine(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - Define *def=new Define; + std::unique_ptr<Define> def = std::make_unique<Define>(); def->name = state->defName; def->definition = state->defText.stripWhiteSpace(); def->nargs = state->defArgs; @@ -2780,15 +2793,14 @@ static void addDefine(yyscan_t yyscanner) YY_EXTRA_TYPE state = preYYget_extra(yyscanner); if (state->skip) return; // do not add this define as it is inside a // conditional section (cond command) that is disabled. - if (!Doxygen::gatherDefines) return; //printf("addDefine '%s' '%s'\n",state->defName.data(),state->defArgsStr.data()); //ArgumentList *al = new ArgumentList; //stringToArgumentList(state->defArgsStr,al); - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( state->yyFileName,state->yyLineNr-state->yyMLines,state->yyColNr, "#define",state->defName,state->defArgsStr,0, - Public,Normal,FALSE,Member,MemberType_Define,ArgumentList(),ArgumentList(),""); + Public,Normal,FALSE,Member,MemberType_Define,ArgumentList(),ArgumentList(),"") }; if (!state->defArgsStr.isEmpty()) { ArgumentList argList; @@ -2826,32 +2838,24 @@ static void addDefine(yyscan_t yyscanner) md->setFileDef(state->inputFileDef); md->setDefinition("#define "+state->defName); - MemberName *mn=Doxygen::functionNameSDict->find(state->defName); - if (mn==0) - { - mn = new MemberName(state->defName); - Doxygen::functionNameSDict->append(state->defName,mn); - } - mn->append(md); + MemberName *mn=Doxygen::functionNameLinkedMap->add(state->defName); if (state->yyFileDef) { - state->yyFileDef->insertMember(md); + state->yyFileDef->insertMember(md.get()); } - - //Define *d; - //if ((d=defineDict[state->defName])==0) defineDict.insert(state->defName,newDefine()); + mn->push_back(std::move(md)); } static inline void outputChar(yyscan_t yyscanner,char c) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - if (state->includeStack.isEmpty() || state->curlyCount>0) state->outputBuf->addChar(c); + if (state->includeStack.empty() || state->curlyCount>0) state->outputBuf->addChar(c); } static inline void outputArray(yyscan_t yyscanner,const char *a,int len) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - if (state->includeStack.isEmpty() || state->curlyCount>0) state->outputBuf->addArray(a,len); + if (state->includeStack.empty() || state->curlyCount>0) state->outputBuf->addArray(a,len); } static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) @@ -2904,30 +2908,30 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) else if (searchIncludes) // search in INCLUDE_PATH as well { QStrList &includePath = Config_getList(INCLUDE_PATH); - char *s=includePath.first(); - while (s) + char *incPath=includePath.first(); + while (incPath) { - QFileInfo fi(s); - if (fi.exists() && fi.isDir()) + QFileInfo fi3(incPath); + if (fi3.exists() && fi3.isDir()) { - QCString absName = QCString(fi.absFilePath().utf8())+"/"+incFileName; + absName = QCString(fi3.absFilePath().utf8())+"/"+incFileName; //printf("trying absName=%s\n",absName.data()); - QFileInfo fi2(absName); - if (fi2.exists()) + QFileInfo fi4(absName); + if (fi4.exists()) { - absIncFileName=fi2.absFilePath().utf8(); + absIncFileName=fi4.absFilePath().utf8(); break; } //printf( "absIncFileName = %s\n", absIncFileName.data() ); } - s=includePath.next(); + incPath=includePath.next(); } } //printf( "absIncFileName = %s\n", absIncFileName.data() ); } } - state->defineManager.addInclude(state->yyFileName,absIncFileName); - state->defineManager.addFileToContext(absIncFileName); + g_defineManager.addInclude(state->yyFileName,absIncFileName); + g_defineManager.addFileToContext(absIncFileName); // findFile will overwrite state->yyFileDef if found FileState *fs; @@ -2938,7 +2942,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) //printf("Found include file!\n"); if (Debug::isFlagSet(Debug::Preprocessor)) { - for (i=0;i<state->includeStack.count();i++) + for (i=0;i<state->includeStack.size();i++) { Debug::print(Debug::Preprocessor,0," "); } @@ -2949,7 +2953,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) // add include dependency to the file in which the #include was found bool ambig; // change to absolute name for bug 641336 - FileDef *incFd = findFileDef(Doxygen::inputNameDict,absIncFileName,ambig); + FileDef *incFd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig); oldFileDef->addIncludeDependency(ambig ? 0 : incFd,incFileName,localInclude,state->isImported,FALSE); // add included by dependency if (state->yyFileDef) @@ -2969,7 +2973,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) fs->curlyCount = state->curlyCount; state->curlyCount = 0; // push the state on the stack - state->includeStack.push(fs); + state->includeStack.emplace_back(fs); // set the scanner to the include file // Deal with file changes due to @@ -2990,15 +2994,9 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) if (oldFileDef) { bool ambig; - //QCString absPath = incFileName; - //if (QDir::isRelativePath(incFileName)) - //{ - // absPath = QDir::cleanDirPath(oldFileDef->getPath()+"/"+incFileName); - // //printf("%s + %s -> resolved path %s\n",oldFileDef->getPath().data(),incFileName.data(),absPath.data()); - //} // change to absolute name for bug 641336 - FileDef *fd = findFileDef(Doxygen::inputNameDict,absIncFileName,ambig); + FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig); //printf("%s::findFileDef(%s)=%p\n",oldFileDef->name().data(),incFileName.data(),fd); // add include dependency to the file in which the #include was found oldFileDef->addIncludeDependency(ambig ? 0 : fd,incFileName,localInclude,state->isImported,FALSE); @@ -3038,10 +3036,10 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) static void startCondSection(yyscan_t yyscanner,const char *sectId) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - //printf("startCondSection: skip=%d stack=%d\n",state->skip,state->condStack.count()); + //printf("startCondSection: skip=%d stack=%d\n",state->skip,state->condStack.size()); CondParser prs; bool expResult = prs.parse(state->yyFileName,state->yyLineNr,sectId); - state->condStack.push(new CondCtx(state->yyLineNr,sectId,state->skip)); + state->condStack.emplace(std::make_unique<CondCtx>(state->yyLineNr,sectId,state->skip)); if (!expResult) { state->skip=TRUE; @@ -3052,15 +3050,15 @@ static void startCondSection(yyscan_t yyscanner,const char *sectId) static void endCondSection(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - if (state->condStack.isEmpty()) + if (state->condStack.empty()) { state->skip=FALSE; } else { - CondCtx *ctx = state->condStack.pop(); + const std::unique_ptr<CondCtx> &ctx = state->condStack.top(); state->skip=ctx->skip; - delete ctx; + state->condStack.pop(); } //printf("endCondSection: skip=%d stack=%d\n",state->skip,state->condStack.count()); } @@ -3068,9 +3066,9 @@ static void endCondSection(yyscan_t yyscanner) static void forceEndCondSection(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - while (!state->condStack.isEmpty()) + while (!state->condStack.empty()) { - delete state->condStack.pop(); + state->condStack.pop(); } state->skip=FALSE; } @@ -3150,8 +3148,7 @@ static int getCurrentChar(yyscan_t yyscanner,const QCString &expr,QCString *rest else { int cc=yyinput(yyscanner); - returnCharToStream(yyscanner,cc); - //unput((char)cc); + returnCharToStream(yyscanner,(char)cc); //printf("%c=yyinput()\n",cc); return cc; } @@ -3178,41 +3175,149 @@ static void unputChar(yyscan_t yyscanner,const QCString &expr,QCString *rest,uin //printf("result: unputChar(%s,%s,%d,%c)\n",expr.data(),rest ? rest->data() : 0,pos,c); } +static void initPredefined(yyscan_t yyscanner,const char *fileName) +{ + YY_EXTRA_TYPE state = preYYget_extra(yyscanner); + + // add predefined macros + char *defStr; + QStrList &predefList = Config_getList(PREDEFINED); + QStrListIterator sli(predefList); + for (sli.toFirst();(defStr=sli.current());++sli) + { + QCString ds = defStr; + int i_equals=ds.find('='); + int i_obrace=ds.find('('); + int i_cbrace=ds.find(')'); + bool nonRecursive = i_equals>0 && ds.at(i_equals-1)==':'; + + if ((i_obrace==0) || (i_equals==0) || (i_equals==1 && ds.at(i_equals-1)==':')) + { + continue; // no define name + } + + if (i_obrace<i_equals && i_cbrace<i_equals && + i_obrace!=-1 && i_cbrace!=-1 && + i_obrace<i_cbrace + ) // predefined function macro definition + { + //printf("predefined function macro '%s'\n",defStr); + QRegExp reId("[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*"); // regexp matching an id + std::map<std::string,int> argMap; + int i=i_obrace+1,pi,l,count=0; + // gather the formal arguments in a dictionary + while (i<i_cbrace && (pi=reId.match(ds,i,&l))) + { + if (l>0) // see bug375037 + { + argMap.emplace(toStdString(ds.mid(pi,l)),count); + count++; + i=pi+l; + } + else + { + i++; + } + } + // strip definition part + QCString tmp=ds.right(ds.length()-i_equals-1); + QCString definition; + i=0; + // substitute all occurrences of formal arguments by their + // corresponding markers + while ((pi=reId.match(tmp,i,&l))!=-1) + { + if (pi>i) definition+=tmp.mid(i,pi-i); + auto it = argMap.find(tmp.mid(pi,l).data()); + if (it!=argMap.end()) + { + int argIndex = it->second; + QCString marker; + marker.sprintf(" @%d ",argIndex); + definition+=marker; + } + else + { + definition+=tmp.mid(pi,l); + } + i=pi+l; + } + if (i<(int)tmp.length()) definition+=tmp.mid(i,tmp.length()-i); + + // add define definition to the dictionary of defines for this file + QCString dname = ds.left(i_obrace); + if (!dname.isEmpty()) + { + std::unique_ptr<Define> def = std::make_unique<Define>(); + def->name = dname; + def->definition = definition; + def->nargs = count; + def->isPredefined = TRUE; + def->nonRecursive = nonRecursive; + def->fileDef = state->yyFileDef; + def->fileName = fileName; + g_defineManager.addDefine(state->yyFileName,std::move(def)); + + //printf("#define '%s' '%s' #nargs=%d\n", + // def->name.data(),def->definition.data(),def->nargs); + } + + } + else if ((i_obrace==-1 || i_obrace>i_equals) && + (i_cbrace==-1 || i_cbrace>i_equals) && + !ds.isEmpty() && (int)ds.length()>i_equals + ) // predefined non-function macro definition + { + //printf("predefined normal macro '%s'\n",defStr); + std::unique_ptr<Define> def = std::make_unique<Define>(); + if (i_equals==-1) // simple define without argument + { + def->name = ds; + def->definition = "1"; // substitute occurrences by 1 (true) + } + else // simple define with argument + { + int ine=i_equals - (nonRecursive ? 1 : 0); + def->name = ds.left(ine); + def->definition = ds.right(ds.length()-i_equals-1); + } + if (!def->name.isEmpty()) + { + def->nargs = -1; + def->isPredefined = TRUE; + def->nonRecursive = nonRecursive; + def->fileDef = state->yyFileDef; + def->fileName = fileName; + g_defineManager.addDefine(state->yyFileName,std::move(def)); + } + } + } +} + /////////////////////////////////////////////////////////////////////////////////////////////// struct Preprocessor::Private { yyscan_t yyscanner; preYY_state state; - bool firstTime = FALSE; }; void Preprocessor::addSearchDir(const char *dir) { YY_EXTRA_TYPE state = preYYget_extra(p->yyscanner); QFileInfo fi(dir); - if (fi.isDir()) state->pathList->append(fi.absFilePath().utf8()); -} + if (fi.isDir()) state->pathList.push_back(fi.absFilePath().utf8().data()); +} -Preprocessor::Preprocessor() +Preprocessor::Preprocessor() : p(std::make_unique<Private>()) { - p = new Private; preYYlex_init_extra(&p->state,&p->yyscanner); - YY_EXTRA_TYPE state = preYYget_extra(p->yyscanner); - state->pathList = new QStrList; addSearchDir("."); - state->expandedDict = new DefineDict(17); } Preprocessor::~Preprocessor() { - YY_EXTRA_TYPE state = preYYget_extra(p->yyscanner); - delete state->expandedDict; - state->expandedDict=0; - delete state->pathList; - state->pathList=0; preYYlex_destroy(p->yyscanner); - delete p; } void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output) @@ -3238,146 +3343,19 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output state->inputBuf=&input; state->inputBufPos=0; state->outputBuf=&output; - state->includeStack.setAutoDelete(TRUE); state->includeStack.clear(); - state->expandedDict->setAutoDelete(FALSE); - state->expandedDict->clear(); - state->condStack.setAutoDelete(TRUE); - state->condStack.clear(); + state->expandedDict.clear(); + while (!state->condStack.empty()) state->condStack.pop(); //state->fileDefineDict->clear(); setFileName(yyscanner,fileName); state->inputFileDef = state->yyFileDef; - state->defineManager.startContext(state->yyFileName); + g_defineManager.startContext(state->yyFileName); - p->firstTime=TRUE; - if (p->firstTime) - { - // add predefined macros - char *defStr; - QStrList &predefList = Config_getList(PREDEFINED); - QStrListIterator sli(predefList); - for (sli.toFirst();(defStr=sli.current());++sli) - { - QCString ds = defStr; - int i_equals=ds.find('='); - int i_obrace=ds.find('('); - int i_cbrace=ds.find(')'); - bool nonRecursive = i_equals>0 && ds.at(i_equals-1)==':'; - - if ((i_obrace==0) || (i_equals==0) || (i_equals==1 && ds.at(i_equals-1)==':')) - { - continue; // no define name - } - - if (i_obrace<i_equals && i_cbrace<i_equals && - i_obrace!=-1 && i_cbrace!=-1 && - i_obrace<i_cbrace - ) // predefined function macro definition - { - //printf("predefined function macro '%s'\n",defStr); - QRegExp reId("[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*"); // regexp matching an id - QDict<int> argDict(17); - argDict.setAutoDelete(TRUE); - int i=i_obrace+1,p,l,count=0; - // gather the formal arguments in a dictionary - while (i<i_cbrace && (p=reId.match(ds,i,&l))) - { - if (l>0) // see bug375037 - { - argDict.insert(ds.mid(p,l),new int(count++)); - i=p+l; - } - else - { - i++; - } - } - // strip definition part - QCString tmp=ds.right(ds.length()-i_equals-1); - QCString definition; - i=0; - // substitute all occurrences of formal arguments by their - // corresponding markers - while ((p=reId.match(tmp,i,&l))!=-1) - { - if (p>i) definition+=tmp.mid(i,p-i); - int *argIndex; - if ((argIndex=argDict[tmp.mid(p,l)])!=0) - { - QCString marker; - marker.sprintf(" @%d ",*argIndex); - definition+=marker; - } - else - { - definition+=tmp.mid(p,l); - } - i=p+l; - } - if (i<(int)tmp.length()) definition+=tmp.mid(i,tmp.length()-i); - - // add define definition to the dictionary of defines for this file - QCString dname = ds.left(i_obrace); - if (!dname.isEmpty()) - { - Define *def = new Define; - def->name = dname; - def->definition = definition; - def->nargs = count; - def->isPredefined = TRUE; - def->nonRecursive = nonRecursive; - def->fileDef = state->yyFileDef; - def->fileName = fileName; - state->defineManager.addDefine(state->yyFileName,def); - - //printf("#define '%s' '%s' #nargs=%d\n", - // def->name.data(),def->definition.data(),def->nargs); - } - - } - else if ((i_obrace==-1 || i_obrace>i_equals) && - (i_cbrace==-1 || i_cbrace>i_equals) && - !ds.isEmpty() && (int)ds.length()>i_equals - ) // predefined non-function macro definition - { - //printf("predefined normal macro '%s'\n",defStr); - Define *def = new Define; - if (i_equals==-1) // simple define without argument - { - def->name = ds; - def->definition = "1"; // substitute occurrences by 1 (true) - } - else // simple define with argument - { - int ine=i_equals - (nonRecursive ? 1 : 0); - def->name = ds.left(ine); - def->definition = ds.right(ds.length()-i_equals-1); - } - if (!def->name.isEmpty()) - { - def->nargs = -1; - def->isPredefined = TRUE; - def->nonRecursive = nonRecursive; - def->fileDef = state->yyFileDef; - def->fileName = fileName; - state->defineManager.addDefine(state->yyFileName,def); - } - else - { - delete def; - } - - //printf("#define '%s' '%s' #nargs=%d\n", - // def->name.data(),def->definition.data(),def->nargs); - } - } - //firstTime=FALSE; - } + initPredefined(yyscanner,fileName); state->yyLineNr = 1; state->yyColNr = 1; - state->level = 0; state->ifcount = 0; BEGIN( Start ); @@ -3389,35 +3367,23 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output preYYlex(yyscanner); - while (!state->condStack.isEmpty()) + while (!state->condStack.empty()) { - CondCtx *ctx = state->condStack.pop(); + const std::unique_ptr<CondCtx> &ctx = state->condStack.top(); QCString sectionInfo = " "; if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label '%s' ",ctx->sectionId.stripWhiteSpace().data()); warn(fileName,ctx->lineNr,"Conditional section%sdoes not have " "a corresponding \\endcond command within this file.",sectionInfo.data()); - delete ctx; + state->condStack.pop(); } // make sure we don't extend a \cond with missing \endcond over multiple files (see bug 624829) forceEndCondSection(yyscanner); - // remove locally defined macros so they can be redefined in another source file - //if (state->fileDefineDict->count()>0) - //{ - // QDictIterator<Define> di(*state->fileDefineDict); - // Define *d; - // for (di.toFirst();(d=di.current());++di) - // { - // state->globalDefineDict->remove(di.currentKey()); - // } - // state->fileDefineDict->clear(); - //} - if (Debug::isFlagSet(Debug::Preprocessor)) { char *orgPos=output.data()+orgOffset; char *newPos=output.data()+output.curPos(); - Debug::print(Debug::Preprocessor,0,"Preprocessor output (size: %d bytes):\n",newPos-orgPos); + Debug::print(Debug::Preprocessor,0,"Preprocessor output of %s (size: %d bytes):\n",fileName,newPos-orgPos); int line=1; Debug::print(Debug::Preprocessor,0,"---------\n00001 "); while (orgPos<newPos) @@ -3427,26 +3393,26 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output orgPos++; } Debug::print(Debug::Preprocessor,0,"\n---------\n"); - if (state->defineManager.defineContext().count()>0) + if (g_defineManager.defineContext().size()>0) { - Debug::print(Debug::Preprocessor,0,"Macros accessible in this file:\n"); + Debug::print(Debug::Preprocessor,0,"Macros accessible in this file (%s):\n", fileName); Debug::print(Debug::Preprocessor,0,"---------\n"); - QDictIterator<Define> di(state->defineManager.defineContext()); - Define *def; - for (di.toFirst();(def=di.current());++di) + for (auto &kv : g_defineManager.defineContext()) { + Define *def = kv.second; Debug::print(Debug::Preprocessor,0,"%s ",qPrint(def->name)); } Debug::print(Debug::Preprocessor,0,"\n---------\n"); } else { - Debug::print(Debug::Preprocessor,0,"No macros accessible in this file.\n"); + Debug::print(Debug::Preprocessor,0,"No macros accessible in this file (%s).\n", fileName); } } - state->defineManager.endContext(); + g_defineManager.endContext(); printlex(yy_flex_debug, FALSE, __FILE__, fileName); } - +#if USE_STATE2STRING #include "pre.l.h" +#endif diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index ed4e76b..7bc5821 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -202,6 +202,10 @@ class PrintDocVisitor : public DocVisitor if (inc->isBlock()) printf(" block=\"yes\""); break; case DocInclude::LatexInclude: printf("latexinclude"); break; + case DocInclude::RtfInclude: printf("rtfinclude"); break; + case DocInclude::DocbookInclude: printf("docbookinclude"); break; + case DocInclude::ManInclude: printf("maninclude"); break; + case DocInclude::XmlInclude: printf("xmlinclude"); break; case DocInclude::VerbInclude: printf("verbinclude"); break; case DocInclude::Snippet: printf("snippet"); break; case DocInclude::SnipWithLines: printf("snipwithlines"); break; diff --git a/src/pycode.l b/src/pycode.l index f7e255f..8cb85a3 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -23,6 +23,10 @@ %option never-interactive %option prefix="pycodeYY" +%option noyy_top_state +%top{ +#include <stdint.h> +} %{ @@ -53,6 +57,8 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + static ClassSDict g_codeClassSDict(17); static QCString g_curClassName; static QStrList g_curClassBases; @@ -97,7 +103,10 @@ static bool g_endComment; static void endFontClass(); static void adjustScopesAndSuites(unsigned indentLength); + +#if USE_STATE2STRING static const char *stateToString(int state); +#endif /*! Represents a stack of variable to class mappings as found in the @@ -685,19 +694,19 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, DBG_CTX((stderr,"scope=%s locName=%s mcd=%p\n",scope.data(),locName.data(),mcd)); if (mcd) { - MemberDef *md = mcd->getMemberByName(locName); - if (md) + MemberDef *mmd = mcd->getMemberByName(locName); + if (mmd) { - g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); - writeMultiLineCodeLink(ol,md,clName); + g_theCallContext.setClass(stripClassName(mmd->typeString(),mmd->getOuterScope())); + writeMultiLineCodeLink(ol,mmd,clName); addToSearchIndex(className); - const Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); - if (md->getGroupDef()) d = md->getGroupDef(); - if (d && d->isLinkable() && md->isLinkable() && + const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ? + mmd->getBodyDef() : mmd->getOuterScope(); + if (mmd->getGroupDef()) d = mmd->getGroupDef(); + if (d && d->isLinkable() && mmd->isLinkable() && g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_currentMemberDef,mmd); } return; } @@ -707,20 +716,20 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, const NamespaceDef *mnd = getResolvedNamespace(scope); if (mnd) { - MemberDef *md=mnd->getMemberByName(locName); - if (md) + MemberDef *mmd=mnd->getMemberByName(locName); + if (mmd) { //printf("name=%s scope=%s\n",locName.data(),scope.data()); - g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); - writeMultiLineCodeLink(ol,md,clName); + g_theCallContext.setClass(stripClassName(mmd->typeString(),mmd->getOuterScope())); + writeMultiLineCodeLink(ol,mmd,clName); addToSearchIndex(className); - const Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); - if (md->getGroupDef()) d = md->getGroupDef(); - if (d && d->isLinkable() && md->isLinkable() && + const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ? + mmd->getBodyDef() : mmd->getOuterScope(); + if (mmd->getGroupDef()) d = mmd->getGroupDef(); + if (d && d->isLinkable() && mmd->isLinkable() && g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_currentMemberDef,mmd); } return; } @@ -843,9 +852,9 @@ static void findMemberLink(CodeOutputInterface &ol,char *symName) #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -static int yyread(char *buf,int max_size) +static yy_size_t yyread(char *buf,yy_size_t max_size) { - int c=0; + yy_size_t c=0; while( c < max_size && g_inputString[g_inputPosition] ) { *buf = g_inputString[g_inputPosition++] ; @@ -1266,7 +1275,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT // level that is about to be // used. codifyLines(yytext); - g_indents.push(yyleng); + g_indents.push(static_cast<int>(yyleng)); // printf("Captured indent of %d [line %d]\n", yyleng, g_yyLineNr); BEGIN( Suite ); } @@ -1280,7 +1289,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT // should be improved. // (translate tabs to space, etc) codifyLines(yytext); - adjustScopesAndSuites((int)yyleng); + adjustScopesAndSuites(static_cast<int>(yyleng)); } "\n"|({BB}"\n") { @@ -1666,5 +1675,6 @@ void PythonCodeParser::resetCodeParserState() ::resetPythonCodeParserState(); } - +#if USE_STATE2STRING #include "pycode.l.h" +#endif diff --git a/src/pyscanner.h b/src/pyscanner.h index 6cfadf6..d6e8672 100644 --- a/src/pyscanner.h +++ b/src/pyscanner.h @@ -34,6 +34,8 @@ class PythonOutlineParser : public OutlineParserInterface { public: + PythonOutlineParser(); + virtual ~PythonOutlineParser(); void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char * fileName, @@ -43,8 +45,9 @@ class PythonOutlineParser : public OutlineParserInterface QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension) const; void parsePrototype(const char *text); + private: + struct Private; + std::unique_ptr<Private> p; }; -void pyscanFreeScanner(); - #endif diff --git a/src/pyscanner.l b/src/pyscanner.l index efdc943..15e1040 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -23,6 +23,11 @@ %option never-interactive %option prefix="pyscannerYY" +%option reentrant +%option extra-type="struct pyscannerYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -49,8 +54,8 @@ #include "defargs.h" #include "language.h" #include "commentscan.h" -#include "pycode.h" #include "arguments.h" +#include "markdown.h" // Toggle for some debugging info //#define DBG_CTX(x) fprintf x @@ -59,358 +64,89 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 -/* ----------------------------------------------------------------- - * - * statics - */ - - -static OutlineParserInterface *g_thisParser; -static const char * inputString; -static int inputPosition; -static QFile inputFile; - -static Protection protection; - -static std::shared_ptr<Entry> current_root; -static std::shared_ptr<Entry> current; -static std::shared_ptr<Entry> previous; -static std::shared_ptr<Entry> bodyEntry; -static int yyLineNr = 1 ; -static QCString yyFileName; -static MethodTypes mtype; -static bool gstat; -static Specifier virt; - -static int docBlockContext; -static QCString docBlock; -static bool docBlockInBody; -static bool docBlockJavaStyle; -static bool docBrief; -static bool docBlockSpecial; - -static bool g_doubleQuote; -static bool g_specialBlock; -static int g_stringContext; -static QGString * g_copyString; -static int g_indent = 0; -static int g_curIndent = 0; -static bool g_importTuple; - -static QDict<QCString> g_packageNameCache(257); - -static char g_atomStart; -static char g_atomEnd; -static int g_atomCount; - - -//static bool g_insideConstructor; - -static QCString g_moduleScope; -static QCString g_packageName; - -//static bool g_hideClassDocs; - -static QGString g_defVal; -static int g_braceCount; - -static bool g_lexInit = FALSE; -static bool g_packageCommentAllowed; - -static bool g_start_init = FALSE; -static int g_search_count = 0; - -static QCString g_argType = ""; -static bool g_funcParamsEnd; -//----------------------------------------------------------------------------- -static const char *stateToString(int state); +#define USE_STATE2STRING 0 +/* ----------------------------------------------------------------- */ -static void initParser() -{ - protection = Public; - mtype = Method; - gstat = FALSE; - virt = Normal; - previous = 0; - g_packageCommentAllowed = TRUE; - g_packageNameCache.setAutoDelete(TRUE); -} - -static void initEntry() -{ - //current->python = TRUE; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->lang = SrcLangExt_Python; - Doxygen::docGroup.initGroupInfo(current.get()); - gstat = FALSE; -} - -static void newEntry() -{ - previous = current; - current_root->moveToSubEntryAndRefresh(current); - initEntry(); -} - -static void newVariable() -{ - if (!current->name.isEmpty() && current->name.at(0)=='_') // mark as private - { - current->protection=Private; - } - if (current_root->section&Entry::COMPOUND_MASK) // mark as class variable - { - current->stat = TRUE; - } - newEntry(); -} - -static void newFunction() -{ - if (current->name.left(2)=="__" && current->name.right(2)=="__") - { - // special method name, see - // http://docs.python.org/ref/specialnames.html - current->protection=Public; - } - else if (current->name.at(0)=='_') - { - current->protection=Private; - } -} - -static inline int computeIndent(const char *s) +struct pyscannerYY_state { - int col=0; - static int tabSize=Config_getInt(TAB_SIZE); - const char *p=s; - char c; - while ((c=*p++)) - { - if (c==' ') col++; - else if (c=='\t') col+=tabSize-(col%tabSize); - else break; - } - return col; -} + pyscannerYY_state() : packageNameCache(257) {} + CommentScanner commentScanner; + OutlineParserInterface *thisParser = 0; + const char * inputString = 0; + yy_size_t inputPosition = 0; + Protection protection = Public; + std::shared_ptr<Entry> current_root; + std::shared_ptr<Entry> current; + std::shared_ptr<Entry> previous; + std::shared_ptr<Entry> bodyEntry; + int yyLineNr = 1 ; + QCString yyFileName; + MethodTypes mtype = Method; + bool stat = FALSE; + Specifier virt = Normal; + int docBlockContext = 0; + QCString docBlock; + bool docBlockInBody = FALSE; + bool docBlockJavaStyle = FALSE; + bool docBrief = FALSE; + bool docBlockSpecial = FALSE; + bool doubleQuote = FALSE; + bool specialBlock = FALSE; + int stringContext = 0; + QGString * copyString = 0; + int indent = 0; + int curIndent = 0; + bool importTuple = FALSE; + QDict<QCString> packageNameCache; + char atomStart = 0; + char atomEnd = 0; + int atomCount = 0; + QCString moduleScope; + QCString packageName; + QGString defVal; + int braceCount = 0; + bool lexInit = FALSE; + bool packageCommentAllowed = FALSE; + bool start_init = FALSE; + int search_count = 0; + QCString argType; + bool funcParamsEnd = FALSE; +}; -static QCString findPackageScopeFromPath(const QCString &path) -{ - QCString *pScope = g_packageNameCache.find(path); - if (pScope) - { - return *pScope; - } - QFileInfo pf(path+"/__init__.py"); // found package initialization file - if (pf.exists()) - { - int i=path.findRev('/'); - if (i!=-1) - { - QCString scope = findPackageScopeFromPath(path.left(i)); - if (!scope.isEmpty()) - { - scope+="::"; - } - scope+=path.mid(i+1); - g_packageNameCache.insert(path,new QCString(scope)); - return scope; - } - } - return ""; -} - -static QCString findPackageScope(const char *fileName) -{ - if (fileName==0) return ""; - QFileInfo fi(fileName); - return findPackageScopeFromPath(fi.dirPath(TRUE).data()); -} - -static void addFrom(bool all) -{ - QCString item=all ? g_packageName : g_packageName+"."+yytext; - current->name=removeRedundantWhiteSpace(substitute(item,".","::")); - current->fileName = yyFileName; - //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); - current->section=all ? Entry::USINGDIR_SEC : Entry::USINGDECL_SEC; - current_root->moveToSubEntryAndRefresh(current); - initEntry(); -} //----------------------------------------------------------------------------- +#if USE_STATE2STRING +static const char *stateToString(int state); +#endif -static void lineCount() -{ - DBG_CTX((stderr,"yyLineNr=%d\n",yyLineNr)); - for (const char *p = yytext; *p; ++p) - { - yyLineNr += (*p == '\n') ; - } -} - -static void incLineNr() -{ - DBG_CTX((stderr,"yyLineNr=%d\n",yyLineNr)); - yyLineNr++; -} - -//----------------------------------------------------------------- -static void startCommentBlock(bool brief) -{ - if (brief) - { - current->briefFile = yyFileName; - current->briefLine = yyLineNr; - } - else - { - current->docFile = yyFileName; - current->docLine = yyLineNr; - } -} - -static void handleCommentBlock(const QCString &doc,bool brief) -{ - //printf("handleCommentBlock(doc=[%s] brief=%d docBlockInBody=%d docBlockJavaStyle=%d\n", - // doc.data(),brief,docBlockInBody,docBlockJavaStyle); - - // TODO: Fix me - docBlockInBody=FALSE; - - if (docBlockInBody && previous && !previous->doc.isEmpty()) - { - previous->doc=previous->doc.stripWhiteSpace()+"\n\n"; - } - - int position = 0; - bool needsEntry; - int lineNr = brief ? current->briefLine : current->docLine; - QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); - while (parseCommentBlock( - g_thisParser, - (docBlockInBody && previous) ? previous.get() : current.get(), - processedDoc, // text - yyFileName, // file - lineNr, - docBlockInBody ? FALSE : brief, - docBlockJavaStyle, // javadoc style // or FALSE, - docBlockInBody, - protection, - position, - needsEntry) - ) // need to start a new entry - { - if (needsEntry) - { - newEntry(); - } - } - if (needsEntry) - { - newEntry(); - } - -} - -static void endOfDef(int correction=0) -{ - //printf("endOfDef at=%d\n",yyLineNr); - if (bodyEntry) - { - bodyEntry->endBodyLine = yyLineNr-correction; - bodyEntry = 0; - } - newEntry(); - //g_insideConstructor = FALSE; -} - -static inline void addToString(const char *s) -{ - if (g_copyString) (*g_copyString)+=s; -} - -static void initTriDoubleQuoteBlock() -{ - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = TRUE; - docBlockSpecial = yytext[strlen(yytext) - 1]=='!'; - docBlock.resize(0); - g_doubleQuote = TRUE; - startCommentBlock(FALSE); -} - -static void initTriSingleQuoteBlock() -{ - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = TRUE; - docBlockSpecial = yytext[strlen(yytext) - 1]=='!'; - docBlock.resize(0); - g_doubleQuote = FALSE; - startCommentBlock(FALSE); -} - -static void initSpecialBlock() -{ - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = TRUE; - docBrief = TRUE; - docBlock.resize(0); - startCommentBlock(TRUE); -} - -static void searchFoundDef() -{ - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - current->section = Entry::FUNCTION_SEC; - current->lang = SrcLangExt_Python; - current->virt = Normal; - current->stat = gstat; - current->mtype = mtype = Method; - current->type.resize(0); - current->name.resize(0); - current->args.resize(0); - current->argList.clear(); - g_packageCommentAllowed = FALSE; - gstat=FALSE; - //printf("searchFoundDef at=%d\n",yyLineNr); -} - -static void searchFoundClass() -{ - current->section = Entry::CLASS_SEC; - current->argList.clear(); - current->type += "class" ; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - g_packageCommentAllowed = FALSE; -} +static inline int computeIndent(const char *s); + +static void initParser(yyscan_t yyscanner); +static void initEntry(yyscan_t yyscanner); +static void newEntry(yyscan_t yyscanner); +static void newVariable(yyscan_t yyscanner); +static void newFunction(yyscan_t yyscanner); +static QCString findPackageScopeFromPath(yyscan_t yyscanner,const QCString &path); +static void addFrom(yyscan_t yyscanner,bool all); +static void lineCount(yyscan_t yyscanner); +static void incLineNr(yyscan_t yyscanner); +static void startCommentBlock(yyscan_t yyscanner,bool brief); +static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief); +static void endOfDef(yyscan_t yyscanner,int correction=0); +static inline void addToString(yyscan_t yyscanner,const char *s); +static void initTriDoubleQuoteBlock(yyscan_t yyscanner); +static void initTriSingleQuoteBlock(yyscan_t yyscanner); +static void initSpecialBlock(yyscan_t yyscanner); +static void searchFoundDef(yyscan_t yyscanner); +static void searchFoundClass(yyscan_t yyscanner); +static QCString findPackageScope(yyscan_t yyscanner,const char *fileName); + +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); //----------------------------------------------------------------------------- /* ----------------------------------------------------------------- */ #undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); - -static int yyread(char *buf,int max_size) -{ - int c=0; - while ( c < max_size && inputString[inputPosition] ) - { - *buf = inputString[inputPosition++] ; - //printf("%d (%c)\n",*buf,*buf); - c++; buf++; - } - return c; -} +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); %} @@ -517,125 +253,125 @@ STARTDOCSYMS "##" <Search>{ ^{B}"def"{BB} { // start of a function/method definition with indent - DBG_CTX((stderr,"Found def at %d\n",yyLineNr)); - g_indent=computeIndent(yytext); - searchFoundDef(); + DBG_CTX((stderr,"Found def at %d\n",yyextra->yyLineNr)); + yyextra->indent=computeIndent(yytext); + searchFoundDef(yyscanner); BEGIN( FunctionDec ); } "def"{BB} { // start of a function/method definition - searchFoundDef(); + searchFoundDef(yyscanner); BEGIN( FunctionDec ); } ^{B}"class"{BB} { // start of a class definition with indent - DBG_CTX((stderr,"Found class at %d\n",yyLineNr)); - g_indent=computeIndent(yytext); - searchFoundClass(); + DBG_CTX((stderr,"Found class at %d\n",yyextra->yyLineNr)); + yyextra->indent=computeIndent(yytext); + searchFoundClass(yyscanner); BEGIN( ClassDec ) ; } "class"{BB} { // start of a class definition - searchFoundClass(); + searchFoundClass(yyscanner); BEGIN( ClassDec ) ; } ^{B}"from"{BB} | "from"{BB} { // start of an from import - g_packageCommentAllowed = FALSE; + yyextra->packageCommentAllowed = FALSE; BEGIN( FromMod ); } ^{B}"import"{BB} | "import"{BB} { // start of an import statement - g_packageCommentAllowed = FALSE; + yyextra->packageCommentAllowed = FALSE; BEGIN( Import ); } ^{B}{IDENTIFIER}/{B}"="{B}"property" { // property - current->section = Entry::VARIABLE_SEC; - current->mtype = Property; - current->name = QCString(yytext).stripWhiteSpace(); - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - g_packageCommentAllowed = FALSE; + yyextra->current->section = Entry::VARIABLE_SEC; + yyextra->current->mtype = Property; + yyextra->current->name = QCString(yytext).stripWhiteSpace(); + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->packageCommentAllowed = FALSE; BEGIN(VariableDec); } ^{B}{IDENTIFIER}/{B}"="[^=] { // variable - if (g_search_count) REJECT; - g_indent=computeIndent(yytext); - current->section = Entry::VARIABLE_SEC; - current->name = QCString(yytext).stripWhiteSpace(); - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - g_packageCommentAllowed = FALSE; + if (yyextra->search_count) REJECT; + yyextra->indent=computeIndent(yytext); + yyextra->current->section = Entry::VARIABLE_SEC; + yyextra->current->name = QCString(yytext).stripWhiteSpace(); + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->packageCommentAllowed = FALSE; BEGIN(VariableDec); } {B}{IDENTIFIER}/({B},{B}{IDENTIFIER})*{B}")"*{B}"="[^=] { // list of variables, we cannot place the default value // so we will skip it later on in a general rule // Also note ")" this is to catch also (a,b). the "(" // is caught in the rule: [(], the ")" will be handled in [)] - if (g_search_count > 1) REJECT; - g_indent=computeIndent(yytext); - current->section = Entry::VARIABLE_SEC; - current->name = QCString(yytext).stripWhiteSpace(); - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - g_packageCommentAllowed = FALSE; - newVariable(); + if (yyextra->search_count > 1) REJECT; + yyextra->indent=computeIndent(yytext); + yyextra->current->section = Entry::VARIABLE_SEC; + yyextra->current->name = QCString(yytext).stripWhiteSpace(); + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->packageCommentAllowed = FALSE; + newVariable(yyscanner); } "'" { // start of a single quoted string - g_stringContext=YY_START; - g_copyString=0; - g_packageCommentAllowed = FALSE; + yyextra->stringContext=YY_START; + yyextra->copyString=0; + yyextra->packageCommentAllowed = FALSE; BEGIN( SingleQuoteString ); } "\"" { // start of a double quoted string - g_stringContext=YY_START; - g_copyString=0; - g_packageCommentAllowed = FALSE; + yyextra->stringContext=YY_START; + yyextra->copyString=0; + yyextra->packageCommentAllowed = FALSE; BEGIN( DoubleQuoteString ); } "@staticmethod" { - gstat=TRUE; + yyextra->stat=TRUE; } {SCRIPTCOMMENT} { // Unix type script comment - if (yyLineNr != 1) REJECT; + if (yyextra->yyLineNr != 1) REJECT; } {POUNDCOMMENT} { // normal comment - g_packageCommentAllowed = FALSE; + yyextra->packageCommentAllowed = FALSE; } {IDENTIFIER} { // some other identifier - g_packageCommentAllowed = FALSE; + yyextra->packageCommentAllowed = FALSE; } ^{BB} { - g_curIndent=computeIndent(yytext); + yyextra->curIndent=computeIndent(yytext); } {NEWLINE}+ { // new line - lineCount(); + lineCount(yyscanner); } {TRIDOUBLEQUOTE} { // start of a comment block - initTriDoubleQuoteBlock(); + initTriDoubleQuoteBlock(yyscanner); BEGIN(TripleComment); } {TRISINGLEQUOTE} { // start of a comment block - initTriSingleQuoteBlock(); + initTriSingleQuoteBlock(yyscanner); BEGIN(TripleComment); } {STARTDOCSYMS}/[^#] { // start of a special comment - g_curIndent=computeIndent(yytext); - g_packageCommentAllowed = FALSE; - initSpecialBlock(); + yyextra->curIndent=computeIndent(yytext); + yyextra->packageCommentAllowed = FALSE; + initSpecialBlock(yyscanner); BEGIN(SpecialComment); } [(] { // we have to do something with ( - g_search_count += 1; + yyextra->search_count += 1; } [)] { // we have to do something with ) - g_search_count -= 1; + yyextra->search_count -= 1; } [^\n] { // any other character... // This is the major default @@ -648,13 +384,13 @@ STARTDOCSYMS "##" "." { // python3 style imports } {IDENTIFIER}({B}"."{B}{IDENTIFIER})* { // from package import - g_packageName=yytext; + yyextra->packageName=yytext; } "import"{B} { BEGIN(FromModItem); } \n { - incLineNr(); + incLineNr(yyscanner); BEGIN(Search); } {B} { @@ -667,25 +403,25 @@ STARTDOCSYMS "##" <FromModItem>{ "*" { // import all - addFrom(TRUE); + addFrom(yyscanner,TRUE); BEGIN(Search); } {IDENTIFIER}/{B}","{B} { - addFrom(FALSE); + addFrom(yyscanner,FALSE); } {IDENTIFIER}/{B}")" { - addFrom(FALSE); + addFrom(yyscanner,FALSE); } {IDENTIFIER} { - addFrom(FALSE); - if (!g_importTuple) + addFrom(yyscanner,FALSE); + if (!yyextra->importTuple) { BEGIN(Search); } } \n { - incLineNr(); - if (!g_importTuple) + incLineNr(yyscanner); + if (!yyextra->importTuple) { BEGIN(Search); } @@ -693,16 +429,16 @@ STARTDOCSYMS "##" {B} { } "(" { - g_importTuple=TRUE; + yyextra->importTuple=TRUE; } ")" { - g_importTuple=FALSE; + yyextra->importTuple=FALSE; BEGIN(Search); } "," { } "\\"{B}\n { // line continuation - incLineNr(); + incLineNr(yyscanner); } . { unput(*yytext); @@ -712,16 +448,16 @@ STARTDOCSYMS "##" <Import>{ {IDENTIFIER}({B}"."{B}{IDENTIFIER})* { - current->name=removeRedundantWhiteSpace(substitute(yytext,".","::")); - current->fileName = yyFileName; - //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); - current->section=Entry::USINGDECL_SEC; - current_root->moveToSubEntryAndRefresh(current); - initEntry(); + yyextra->current->name=removeRedundantWhiteSpace(substitute(yytext,".","::")); + yyextra->current->fileName = yyextra->yyFileName; + //printf("Adding using declaration: found:%s:%d name=%s\n",yyextra->yyFileName.data(),yyextra->yyLineNr,yyextra->current->name.data()); + yyextra->current->section=Entry::USINGDECL_SEC; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + initEntry(yyscanner); BEGIN(Search); } \n { - incLineNr(); + incLineNr(yyscanner); BEGIN(Search); } {B} { @@ -734,60 +470,60 @@ STARTDOCSYMS "##" <SearchMemVars>{ "self."{IDENTIFIER}/{B}"=" { - DBG_CTX((stderr,"Found instance method variable %s in %s at %d\n",&yytext[5],current_root->name.data(),yyLineNr)); - current->name=&yytext[5]; - current->section=Entry::VARIABLE_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - current->type.resize(0); - if (current->name.at(0)=='_') // mark as private + DBG_CTX((stderr,"Found instance method variable %s in %s at %d\n",&yytext[5],yyextra->current_root->name.data(),yyextra->yyLineNr)); + yyextra->current->name=&yytext[5]; + yyextra->current->section=Entry::VARIABLE_SEC; + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->type.resize(0); + if (yyextra->current->name.at(0)=='_') // mark as private { - current->protection=Private; + yyextra->current->protection=Private; } - newEntry(); + newEntry(yyscanner); } "cls."{IDENTIFIER}/{B}"=" { - DBG_CTX((stderr,"Found class method variable %s in %s at %d\n",&yytext[4],current_root->name.data(),yyLineNr)); - current->name=&yytext[4]; - current->section=Entry::VARIABLE_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; - current->type.resize(0); - if (current->name.at(0)=='_') // mark as private + DBG_CTX((stderr,"Found class method variable %s in %s at %d\n",&yytext[4],yyextra->current_root->name.data(),yyextra->yyLineNr)); + yyextra->current->name=&yytext[4]; + yyextra->current->section=Entry::VARIABLE_SEC; + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->type.resize(0); + if (yyextra->current->name.at(0)=='_') // mark as private { - current->protection=Private; + yyextra->current->protection=Private; } - newEntry(); + newEntry(yyscanner); } {TRIDOUBLEQUOTE} { // start of a comment block - initTriDoubleQuoteBlock(); + initTriDoubleQuoteBlock(yyscanner); BEGIN(TripleComment); } {TRISINGLEQUOTE} { // start of a comment block - initTriSingleQuoteBlock(); + initTriSingleQuoteBlock(yyscanner); BEGIN(TripleComment); } {STARTDOCSYMS}/[^#] { // start of a special comment - initSpecialBlock(); + initSpecialBlock(yyscanner); BEGIN(SpecialComment); } {POUNDCOMMENT} { // # } "'" { // start of a single quoted string - g_stringContext=YY_START; - g_copyString=0; + yyextra->stringContext=YY_START; + yyextra->copyString=0; BEGIN( SingleQuoteString ); } "\"" { // start of a double quoted string - g_stringContext=YY_START; - g_copyString=0; + yyextra->stringContext=YY_START; + yyextra->copyString=0; BEGIN( DoubleQuoteString ); } - \n { incLineNr(); } + \n { incLineNr(yyscanner); } {IDENTIFIER} // identifiers [^'"\.#a-z_A-Z\n]+ // other uninteresting stuff . // anything else @@ -795,106 +531,106 @@ STARTDOCSYMS "##" <FunctionBody>{ \n{B}/{IDENTIFIER}{BB} { - DBG_CTX((stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),g_indent)); - if (computeIndent(&yytext[1])<=g_indent) + DBG_CTX((stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),yyextra->indent)); + if (computeIndent(&yytext[1])<=yyextra->indent) { int i; for (i=(int)yyleng-1;i>=0;i--) { unput(yytext[i]); } - endOfDef(); + endOfDef(yyscanner); //YY_CURRENT_BUFFER->yy_at_bol=TRUE; BEGIN(Search); } else { - incLineNr(); - current->program+=yytext; + incLineNr(yyscanner); + yyextra->current->program+=yytext; } } \n{B}/"##" { - if (computeIndent(&yytext[1])<=g_indent) + if (computeIndent(&yytext[1])<=yyextra->indent) { int i; for (i=(int)yyleng-1;i>=0;i--) { unput(yytext[i]); } - endOfDef(); + endOfDef(yyscanner); //YY_CURRENT_BUFFER->yy_at_bol=TRUE; BEGIN(Search); } else { - incLineNr(); - current->program+=yytext; + incLineNr(yyscanner); + yyextra->current->program+=yytext; } } <<EOF>> { - endOfDef(); + endOfDef(yyscanner); yyterminate(); } ^{BB}/\n { // skip empty line - current->program+=yytext; + yyextra->current->program+=yytext; } ^{BB} { // something at indent >0 - current->program+=yytext; - g_curIndent = computeIndent(yytext); - if (g_curIndent<=g_indent) + yyextra->current->program+=yytext; + yyextra->curIndent = computeIndent(yytext); + if (yyextra->curIndent<=yyextra->indent) // jumped out of the function { - endOfDef(1); + endOfDef(yyscanner,1); BEGIN(Search); } } "'" { // start of a single quoted string - current->program+=yytext; - g_stringContext=YY_START; - g_specialBlock = FALSE; - g_copyString=¤t->program; + yyextra->current->program+=yytext; + yyextra->stringContext=YY_START; + yyextra->specialBlock = FALSE; + yyextra->copyString=&yyextra->current->program; BEGIN( SingleQuoteString ); } "\"" { // start of a double quoted string - current->program+=yytext; - g_stringContext=YY_START; - g_specialBlock = FALSE; - g_copyString=¤t->program; + yyextra->current->program+=yytext; + yyextra->stringContext=YY_START; + yyextra->specialBlock = FALSE; + yyextra->copyString=&yyextra->current->program; BEGIN( DoubleQuoteString ); } [^ \t\n#'".]+ { // non-special stuff - current->program+=yytext; - g_specialBlock = FALSE; + yyextra->current->program+=yytext; + yyextra->specialBlock = FALSE; } ^{POUNDCOMMENT} { // normal comment - current->program+=yytext; + yyextra->current->program+=yytext; } "#".* { // comment half way - current->program+=yytext; + yyextra->current->program+=yytext; } {NEWLINE} { - incLineNr(); - current->program+=yytext; + incLineNr(yyscanner); + yyextra->current->program+=yytext; } . { // any character - current->program+=*yytext; - g_specialBlock = FALSE; + yyextra->current->program+=*yytext; + yyextra->specialBlock = FALSE; } {TRIDOUBLEQUOTE} { // start of a comment block - current->program+=yytext; - initTriDoubleQuoteBlock(); + yyextra->current->program+=yytext; + initTriDoubleQuoteBlock(yyscanner); BEGIN(TripleComment); } {TRISINGLEQUOTE} { // start of a comment block - current->program+=yytext; - initTriSingleQuoteBlock(); + yyextra->current->program+=yytext; + initTriSingleQuoteBlock(yyscanner); BEGIN(TripleComment); } {STARTDOCSYMS}/[^#] { // start of a special comment - initSpecialBlock(); + initSpecialBlock(yyscanner); BEGIN(SpecialComment); } @@ -903,37 +639,37 @@ STARTDOCSYMS "##" <FunctionDec>{ {IDENTIFIER} { //found function name - if (current->type.isEmpty()) + if (yyextra->current->type.isEmpty()) { - current->type = "def"; + yyextra->current->type = "def"; } - current->name = yytext; - current->name = current->name.stripWhiteSpace(); - newFunction(); + yyextra->current->name = yytext; + yyextra->current->name = yyextra->current->name.stripWhiteSpace(); + newFunction(yyscanner); } {B}":"{B} { // function without arguments - g_specialBlock = TRUE; // expecting a docstring - bodyEntry = current; + yyextra->specialBlock = TRUE; // expecting a docstring + yyextra->bodyEntry = yyextra->current; BEGIN(FunctionBody); } "->" { - g_defVal.resize(0); - g_braceCount = 0; + yyextra->defVal.resize(0); + yyextra->braceCount = 0; BEGIN(FunctionTypeAnnotation); } {B}"(" { - g_funcParamsEnd = FALSE; - current->bodyLine = yyLineNr; + yyextra->funcParamsEnd = FALSE; + yyextra->current->bodyLine = yyextra->yyLineNr; BEGIN(FunctionParams); } ")" { // end of parameter list - if (current->argList.empty()) + if (yyextra->current->argList.empty()) { - current->argList.noParameters=TRUE; + yyextra->current->argList.noParameters=TRUE; } - current->args = argListToString(current->argList); - g_funcParamsEnd = TRUE; + yyextra->current->args = argListToString(yyextra->current->argList); + yyextra->funcParamsEnd = TRUE; } } @@ -942,21 +678,21 @@ STARTDOCSYMS "##" } [\*]+ { - g_argType = yytext; + yyextra->argType = yytext; } {IDENTIFIER} { // Name of parameter - lineCount(); + lineCount(yyscanner); Argument a; a.name = QCString(yytext).stripWhiteSpace(); - a.type = g_argType; - current->argList.push_back(a); - g_argType = ""; + a.type = yyextra->argType; + yyextra->current->argList.push_back(a); + yyextra->argType = ""; } "=" { // default value // TODO: this rule is too simple, need to be able to // match things like =")" as well! - g_defVal.resize(0); - g_braceCount = 0; + yyextra->defVal.resize(0); + yyextra->braceCount = 0; BEGIN(FunctionParamDefVal); } ")" { @@ -964,8 +700,8 @@ STARTDOCSYMS "##" BEGIN(FunctionDec); } ":"{B} { - g_defVal.resize(0); - g_braceCount = 0; + yyextra->defVal.resize(0); + yyextra->braceCount = 0; BEGIN(FunctionAnnotation); } {POUNDCOMMENT} { // a comment @@ -979,43 +715,43 @@ STARTDOCSYMS "##" "{" | "[" | "(" { - ++g_braceCount; - g_defVal+=*yytext; + ++yyextra->braceCount; + yyextra->defVal+=*yytext; } "}" | "]" | ")" { - --g_braceCount; - g_defVal+=*yytext; + --yyextra->braceCount; + yyextra->defVal+=*yytext; } ":" { - if (g_braceCount == 0) + if (yyextra->braceCount == 0) { - current->type = g_defVal.data(); + yyextra->current->type = yyextra->defVal.data(); unput(*yytext); BEGIN(FunctionDec); } else - g_defVal+=*yytext; + yyextra->defVal+=*yytext; } "'" { - g_defVal+=*yytext; - g_copyString=&g_defVal; - g_stringContext=FunctionTypeAnnotation; + yyextra->defVal+=*yytext; + yyextra->copyString=&yyextra->defVal; + yyextra->stringContext=FunctionTypeAnnotation; BEGIN(SingleQuoteString); } "\"" { - g_defVal+=*yytext; - g_copyString=&g_defVal; - g_stringContext=FunctionTypeAnnotation; + yyextra->defVal+=*yytext; + yyextra->copyString=&yyextra->defVal; + yyextra->stringContext=FunctionTypeAnnotation; BEGIN(DoubleQuoteString); } \n { - g_defVal+=*yytext; - incLineNr(); + yyextra->defVal+=*yytext; + incLineNr(yyscanner); } . { - g_defVal+=*yytext; + yyextra->defVal+=*yytext; } } @@ -1023,21 +759,21 @@ STARTDOCSYMS "##" "{" | "[" | "(" { - ++g_braceCount; - g_defVal+=*yytext; + ++yyextra->braceCount; + yyextra->defVal+=*yytext; } "}" | "]" { - --g_braceCount; - g_defVal+=*yytext; + --yyextra->braceCount; + yyextra->defVal+=*yytext; } ")" | "=" | "," { - if (g_braceCount == 0) + if (yyextra->braceCount == 0) { - if (!current->argList.empty()) - current->argList.back().type += g_defVal; + if (!yyextra->current->argList.empty()) + yyextra->current->argList.back().type += yyextra->defVal; if (*yytext != ',') unput(*yytext); BEGIN(FunctionParams); @@ -1045,28 +781,28 @@ STARTDOCSYMS "##" else { if (*yytext == ')') - --g_braceCount; - g_defVal += *yytext; + --yyextra->braceCount; + yyextra->defVal += *yytext; } } "'" { - g_defVal+=*yytext; - g_copyString=&g_defVal; - g_stringContext=FunctionAnnotation; + yyextra->defVal+=*yytext; + yyextra->copyString=&yyextra->defVal; + yyextra->stringContext=FunctionAnnotation; BEGIN(SingleQuoteString); } "\"" { - g_defVal+=*yytext; - g_copyString=&g_defVal; - g_stringContext=FunctionAnnotation; + yyextra->defVal+=*yytext; + yyextra->copyString=&yyextra->defVal; + yyextra->stringContext=FunctionAnnotation; BEGIN(DoubleQuoteString); } \n { - g_defVal+=*yytext; - incLineNr(); + yyextra->defVal+=*yytext; + incLineNr(yyscanner); } . { - g_defVal+=*yytext; + yyextra->defVal+=*yytext; } } @@ -1074,20 +810,20 @@ STARTDOCSYMS "##" "{" | "[" | "(" { // internal opening brace, assumption is that we have correct code so braces do match - ++g_braceCount; - g_defVal+=*yytext; + ++yyextra->braceCount; + yyextra->defVal+=*yytext; } "}" | "]" { - --g_braceCount; - g_defVal+=*yytext; + --yyextra->braceCount; + yyextra->defVal+=*yytext; } ")" | "," { - if (g_braceCount == 0) + if (yyextra->braceCount == 0) { - if (!current->argList.empty()) - current->argList.back().defval=QCString(g_defVal).stripWhiteSpace(); + if (!yyextra->current->argList.empty()) + yyextra->current->argList.back().defval=QCString(yyextra->defVal).stripWhiteSpace(); if (*yytext == ')') unput(*yytext); BEGIN(FunctionParams); @@ -1095,140 +831,140 @@ STARTDOCSYMS "##" else { if (*yytext == ')') - --g_braceCount; - g_defVal += *yytext; + --yyextra->braceCount; + yyextra->defVal += *yytext; } } "'" { - g_defVal+=*yytext; - g_copyString=&g_defVal; - g_stringContext=FunctionParamDefVal; + yyextra->defVal+=*yytext; + yyextra->copyString=&yyextra->defVal; + yyextra->stringContext=FunctionParamDefVal; BEGIN( SingleQuoteString ); } "\"" { - g_defVal+=*yytext; - g_copyString=&g_defVal; - g_stringContext=FunctionParamDefVal; + yyextra->defVal+=*yytext; + yyextra->copyString=&yyextra->defVal; + yyextra->stringContext=FunctionParamDefVal; BEGIN( DoubleQuoteString ); } \n { - g_defVal+=*yytext; - incLineNr(); + yyextra->defVal+=*yytext; + incLineNr(yyscanner); } . { - g_defVal+=*yytext; + yyextra->defVal+=*yytext; } } <ClassBody>{ \n/{IDENTIFIER}{BB} { // new def at indent 0 - incLineNr(); - endOfDef(); - //g_hideClassDocs = FALSE; + incLineNr(yyscanner); + endOfDef(yyscanner); + //yyextra->hideClassDocs = FALSE; //YY_CURRENT_BUFFER->yy_at_bol=TRUE; BEGIN(Search); } \n/"##"[^#] { // start of a special comment at indent 0 - incLineNr(); - endOfDef(); - //g_hideClassDocs = FALSE; + incLineNr(yyscanner); + endOfDef(yyscanner); + //yyextra->hideClassDocs = FALSE; //YY_CURRENT_BUFFER->yy_at_bol=TRUE; BEGIN(Search); } ^{BB}/\n { // skip empty line - current->program+=yytext; + yyextra->current->program+=yytext; } <<EOF>> { - endOfDef(); + endOfDef(yyscanner); yyterminate(); } ^{BB} { // something at indent >0 - g_curIndent=computeIndent(yytext); - DBG_CTX((stderr,"g_curIndent=%d g_indent=%d\n",g_curIndent,g_indent)); - if (g_curIndent<=g_indent) + yyextra->curIndent=computeIndent(yytext); + DBG_CTX((stderr,"yyextra->curIndent=%d yyextra->indent=%d\n",yyextra->curIndent,yyextra->indent)); + if (yyextra->curIndent<=yyextra->indent) // jumped out of the class/method { - endOfDef(1); - g_indent=g_curIndent; + endOfDef(yyscanner,1); + yyextra->indent=yyextra->curIndent; // make sure the next rule matches ^... //YY_CURRENT_BUFFER->yy_at_bol=TRUE; - //g_hideClassDocs = FALSE; + //yyextra->hideClassDocs = FALSE; BEGIN(Search); } else { - current->program+=yytext; + yyextra->current->program+=yytext; } } "'" { // start of a single quoted string - current->program+=*yytext; - g_stringContext=YY_START; - g_specialBlock = FALSE; - g_copyString=¤t->program; + yyextra->current->program+=*yytext; + yyextra->stringContext=YY_START; + yyextra->specialBlock = FALSE; + yyextra->copyString=&yyextra->current->program; BEGIN( SingleQuoteString ); } "\"" { // start of a double quoted string - current->program+=*yytext; - g_stringContext=YY_START; - g_specialBlock = FALSE; - g_copyString=¤t->program; + yyextra->current->program+=*yytext; + yyextra->stringContext=YY_START; + yyextra->specialBlock = FALSE; + yyextra->copyString=&yyextra->current->program; BEGIN( DoubleQuoteString ); } [^ \t\n#'"]+ { // non-special stuff - current->program+=yytext; - g_specialBlock = FALSE; - //g_hideClassDocs = FALSE; + yyextra->current->program+=yytext; + yyextra->specialBlock = FALSE; + //yyextra->hideClassDocs = FALSE; } {NEWLINE} { - current->program+=*yytext; - incLineNr(); + yyextra->current->program+=*yytext; + incLineNr(yyscanner); } {POUNDCOMMENT} { // normal comment - current->program+=yytext; + yyextra->current->program+=yytext; } . { // any character - g_specialBlock = FALSE; - current->program+=*yytext; + yyextra->specialBlock = FALSE; + yyextra->current->program+=*yytext; } {TRIDOUBLEQUOTE} { // start of a comment block - //if (!g_hideClassDocs) - current->program+=yytext; - initTriDoubleQuoteBlock(); + //if (!yyextra->hideClassDocs) + yyextra->current->program+=yytext; + initTriDoubleQuoteBlock(yyscanner); BEGIN(TripleComment); } {TRISINGLEQUOTE} { // start of a comment block - //if (!g_hideClassDocs) - current->program+=yytext; - initTriSingleQuoteBlock(); + //if (!yyextra->hideClassDocs) + yyextra->current->program+=yytext; + initTriSingleQuoteBlock(yyscanner); BEGIN(TripleComment); } } <ClassDec>{IDENTIFIER} { - if (current->type.isEmpty()) + if (yyextra->current->type.isEmpty()) { - current->type = "class"; + yyextra->current->type = "class"; } - current->section = Entry::CLASS_SEC; - current->name = yytext; + yyextra->current->section = Entry::CLASS_SEC; + yyextra->current->name = yytext; // prepend scope in case of nested classes - if (current_root->section&Entry::SCOPE_MASK) + if (yyextra->current_root->section&Entry::SCOPE_MASK) { - //printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data()); - current->name.prepend(current_root->name+"::"); + //printf("*** Prepending scope %s to class %s\n",yyextra->current_root->name.data(),yyextra->current->name.data()); + yyextra->current->name.prepend(yyextra->current_root->name+"::"); } - current->name = current->name.stripWhiteSpace(); - current->fileName = yyFileName; - docBlockContext = YY_START; - docBlockInBody = FALSE; - docBlockJavaStyle = FALSE; - docBlock.resize(0); + yyextra->current->name = yyextra->current->name.stripWhiteSpace(); + yyextra->current->fileName = yyextra->yyFileName; + yyextra->docBlockContext = YY_START; + yyextra->docBlockInBody = FALSE; + yyextra->docBlockJavaStyle = FALSE; + yyextra->docBlock.resize(0); BEGIN(ClassInheritance); } @@ -1238,37 +974,37 @@ STARTDOCSYMS "##" } ":" { // begin of the class definition - g_specialBlock = TRUE; // expecting a docstring - current->bodyLine = yyLineNr; - current->program.resize(0); + yyextra->specialBlock = TRUE; // expecting a docstring + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->program.resize(0); BEGIN(ClassCaptureIndent); } {SCOPE} { - current->extends.push_back( + yyextra->current->extends.push_back( BaseInfo(substitute(yytext,".","::"),Public,Normal) ); //Has base class-do stuff } "'" { // start of a single quoted string - g_stringContext=YY_START; + yyextra->stringContext=YY_START; BEGIN( SingleQuoteStringIgnore ); } "\"" { // start of a double quoted string - g_stringContext=YY_START; + yyextra->stringContext=YY_START; BEGIN( DoubleQuoteStringIgnore ); } } <SingleQuoteStringIgnore>{ "'" { // end of a single quoted string - BEGIN(g_stringContext); + BEGIN(yyextra->stringContext); } . { } } <DoubleQuoteStringIgnore>{ "\"" { // end of a double quoted string - BEGIN(g_stringContext); + BEGIN(yyextra->stringContext); } . { } } @@ -1276,42 +1012,42 @@ STARTDOCSYMS "##" <ClassCaptureIndent>{ "\n"|({BB}"\n") { // Blankline - ignore, keep looking for indentation. - lineCount(); - current->program+=yytext; + lineCount(yyscanner); + yyextra->current->program+=yytext; } {TRIDOUBLEQUOTE} { // start of a comment block - initTriDoubleQuoteBlock(); - current->program+=yytext; + initTriDoubleQuoteBlock(yyscanner); + yyextra->current->program+=yytext; BEGIN(TripleComment); } {TRISINGLEQUOTE} { // start of a comment block - initTriSingleQuoteBlock(); - current->program+=yytext; + initTriSingleQuoteBlock(yyscanner); + yyextra->current->program+=yytext; BEGIN(TripleComment); } {STARTDOCSYMS}[#]* { // start of a special comment - initSpecialBlock(); + initSpecialBlock(yyscanner); BEGIN(SpecialComment); } {POUNDCOMMENT} { // ignore comment with just one # } ^{BB} { - current->program+=yytext; - //current->startLine = yyLineNr; - g_curIndent=computeIndent(yytext); - bodyEntry = current; - DBG_CTX((stderr,"setting indent %d\n",g_curIndent)); - //printf("current->program=[%s]\n",current->program.data()); - //g_hideClassDocs = TRUE; + yyextra->current->program+=yytext; + //yyextra->current->startLine = yyextra->yyLineNr; + yyextra->curIndent=computeIndent(yytext); + yyextra->bodyEntry = yyextra->current; + DBG_CTX((stderr,"setting indent %d\n",yyextra->curIndent)); + //printf("yyextra->current->program=[%s]\n",yyextra->current->program.data()); + //yyextra->hideClassDocs = TRUE; BEGIN(ClassBody); } ""/({NONEMPTY}|{EXPCHAR}) { // Just pushback an empty class, and // resume parsing the body. - newEntry(); - current->program+=yytext; + newEntry(yyscanner); + yyextra->current->program+=yytext; // printf("Failed to find indent - skipping!"); BEGIN( Search ); @@ -1321,82 +1057,82 @@ STARTDOCSYMS "##" <VariableDec>{ "=" { // the assignment operator - //printf("====== VariableDec at line %d\n",yyLineNr); - g_start_init = TRUE; - current->initializer = yytext; - current->initializer += " "; + //printf("====== VariableDec at line %d\n",yyextra->yyLineNr); + yyextra->start_init = TRUE; + yyextra->current->initializer = yytext; + yyextra->current->initializer += " "; } {B} { // spaces - current->initializer += yytext; + yyextra->current->initializer += yytext; } {INTNUMBER} { // integer value - if (current-> type.isEmpty()) current->type = "int"; - current->initializer += yytext; + if (yyextra->current-> type.isEmpty()) yyextra->current->type = "int"; + yyextra->current->initializer += yytext; } {FLOATNUMBER} { // floating point value - if (current->type.isEmpty()) current->type = "float"; - current->initializer += yytext; + if (yyextra->current->type.isEmpty()) yyextra->current->type = "float"; + yyextra->current->initializer += yytext; } {BOOL} { // boolean value - if (current->type.isEmpty()) current->type = "bool"; - current->initializer += yytext; + if (yyextra->current->type.isEmpty()) yyextra->current->type = "bool"; + yyextra->current->initializer += yytext; } {STRINGPREFIX}?"'" { // string - if (current->type.isEmpty()) current->type = "string"; - current->initializer += yytext; - g_copyString=¤t->initializer; - g_stringContext=VariableDec; + if (yyextra->current->type.isEmpty()) yyextra->current->type = "string"; + yyextra->current->initializer += yytext; + yyextra->copyString=&yyextra->current->initializer; + yyextra->stringContext=VariableDec; BEGIN( SingleQuoteString ); } {STRINGPREFIX}?"\"" { // string - if (current->type.isEmpty()) current->type = "string"; - current->initializer += yytext; - g_copyString=¤t->initializer; - g_stringContext=VariableDec; + if (yyextra->current->type.isEmpty()) yyextra->current->type = "string"; + yyextra->current->initializer += yytext; + yyextra->copyString=&yyextra->current->initializer; + yyextra->stringContext=VariableDec; BEGIN( DoubleQuoteString ); } {TRIDOUBLEQUOTE} { // start of a comment block - if (current->type.isEmpty()) current->type = "string"; - current->initializer += yytext; - g_doubleQuote=TRUE; - g_copyString=¤t->initializer; - g_stringContext=VariableDec; + if (yyextra->current->type.isEmpty()) yyextra->current->type = "string"; + yyextra->current->initializer += yytext; + yyextra->doubleQuote=TRUE; + yyextra->copyString=&yyextra->current->initializer; + yyextra->stringContext=VariableDec; BEGIN(TripleString); } {TRISINGLEQUOTE} { // start of a comment block - if (current->type.isEmpty()) current->type = "string"; - current->initializer += yytext; - g_doubleQuote=FALSE; - g_copyString=¤t->initializer; - g_stringContext=VariableDec; + if (yyextra->current->type.isEmpty()) yyextra->current->type = "string"; + yyextra->current->initializer += yytext; + yyextra->doubleQuote=FALSE; + yyextra->copyString=&yyextra->current->initializer; + yyextra->stringContext=VariableDec; BEGIN(TripleString); } "(" { // tuple, only when direct after = - if (current->mtype!=Property && g_start_init) + if (yyextra->current->mtype!=Property && yyextra->start_init) { - current->type = "tuple"; + yyextra->current->type = "tuple"; } - current->initializer+=*yytext; - g_atomStart='('; - g_atomEnd=')'; - g_atomCount=1; + yyextra->current->initializer+=*yytext; + yyextra->atomStart='('; + yyextra->atomEnd=')'; + yyextra->atomCount=1; BEGIN( VariableAtom ); } "[" { // list - if (g_start_init) current->type = "list"; - current->initializer+=*yytext; - g_atomStart='['; - g_atomEnd=']'; - g_atomCount=1; + if (yyextra->start_init) yyextra->current->type = "list"; + yyextra->current->initializer+=*yytext; + yyextra->atomStart='['; + yyextra->atomEnd=']'; + yyextra->atomCount=1; BEGIN( VariableAtom ); } "{" { // dictionary - if (g_start_init) current->type = "dictionary"; - current->initializer+=*yytext; - g_atomStart='{'; - g_atomEnd='}'; - g_atomCount=1; + if (yyextra->start_init) yyextra->current->type = "dictionary"; + yyextra->current->initializer+=*yytext; + yyextra->atomStart='{'; + yyextra->atomEnd='}'; + yyextra->atomCount=1; BEGIN( VariableAtom ); } "#".* { // comment @@ -1404,26 +1140,26 @@ STARTDOCSYMS "##" } {IDENTIFIER} { // do something based on the type of the IDENTIFIER - if (current->type.isEmpty()) + if (yyextra->current->type.isEmpty()) { - //QListIterator<Entry> eli(*(current_root->children())); + //QListIterator<Entry> eli(*(yyextra->current_root->children())); //Entry *child; - //for (eli.toFirst();(child=eli.current());++eli) - for (const auto &child : current_root->children()) + //for (eli.toFirst();(child=eli.yyextra->current());++eli) + for (const auto &child : yyextra->current_root->children()) { if (child->name == QCString(yytext)) { - current->type = child->type; + yyextra->current->type = child->type; break; } } } - g_start_init = FALSE; - current->initializer+=yytext; + yyextra->start_init = FALSE; + yyextra->current->initializer+=yytext; } . { - g_start_init = FALSE; - current->initializer+=*yytext; + yyextra->start_init = FALSE; + yyextra->current->initializer+=*yytext; } \n { unput('\n'); @@ -1433,71 +1169,71 @@ STARTDOCSYMS "##" <VariableAtom>{ [\(\[\{] { - current->initializer+=*yytext; - if (g_atomStart==*yytext) + yyextra->current->initializer+=*yytext; + if (yyextra->atomStart==*yytext) { - g_atomCount++; + yyextra->atomCount++; } } [\)\]\}] { - current->initializer+=*yytext; - if (g_atomEnd==*yytext) + yyextra->current->initializer+=*yytext; + if (yyextra->atomEnd==*yytext) { - g_atomCount--; + yyextra->atomCount--; } - if (g_atomCount==0) + if (yyextra->atomCount==0) { - g_start_init = FALSE; + yyextra->start_init = FALSE; BEGIN(VariableDec); } } {TRIDOUBLEQUOTE} { // start of a comment block - g_specialBlock = FALSE; - current->program+=yytext; - initTriDoubleQuoteBlock(); + yyextra->specialBlock = FALSE; + yyextra->current->program+=yytext; + initTriDoubleQuoteBlock(yyscanner); BEGIN(TripleComment); } {TRISINGLEQUOTE} { // start of a comment block - g_specialBlock = FALSE; - current->program+=yytext; - initTriSingleQuoteBlock(); + yyextra->specialBlock = FALSE; + yyextra->current->program+=yytext; + initTriSingleQuoteBlock(yyscanner); BEGIN(TripleComment); } "'" { - g_stringContext=YY_START; - current->initializer+="'"; - g_copyString=¤t->initializer; + yyextra->stringContext=YY_START; + yyextra->current->initializer+="'"; + yyextra->copyString=&yyextra->current->initializer; BEGIN( SingleQuoteString ); } "\"" { - g_stringContext=YY_START; - current->initializer+="\""; - g_copyString=¤t->initializer; + yyextra->stringContext=YY_START; + yyextra->current->initializer+="\""; + yyextra->copyString=&yyextra->current->initializer; BEGIN( DoubleQuoteString ); } {IDENTIFIER} { - current->initializer+=yytext; + yyextra->current->initializer+=yytext; } . { - current->initializer+=*yytext; + yyextra->current->initializer+=*yytext; } \n { - current->initializer+=*yytext; - incLineNr(); + yyextra->current->initializer+=*yytext; + incLineNr(yyscanner); } } <VariableEnd>{ \n { - incLineNr(); - newVariable(); + incLineNr(yyscanner); + newVariable(yyscanner); BEGIN(Search); } . { unput(*yytext); - newVariable(); + newVariable(yyscanner); BEGIN(Search); } <<EOF>> { yyterminate(); @@ -1507,78 +1243,78 @@ STARTDOCSYMS "##" <TripleComment>{ {ENDTRIDOUBLEQUOTE} | {ENDTRISINGLEQUOTE} { - // printf("Expected module block %d special=%d\n",g_expectModuleDocs,g_specialBlock); - if (g_doubleQuote==(yytext[0]=='"')) + // printf("Expected module block %d special=%d\n",yyextra->expectModuleDocs,yyextra->specialBlock); + if (yyextra->doubleQuote==(yytext[0]=='"')) { - if (g_specialBlock) // expecting a docstring + if (yyextra->specialBlock) // expecting a docstring { - QCString actualDoc=docBlock; - if (!docBlockSpecial) // legacy unformatted docstring + QCString actualDoc=yyextra->docBlock; + if (!yyextra->docBlockSpecial) // legacy unformatted docstring { actualDoc.prepend("\\verbatim "); actualDoc.append("\\endverbatim "); } - //printf("-------> current=%p bodyEntry=%p\n",current,bodyEntry); - handleCommentBlock(actualDoc, FALSE); + //printf("-------> yyextra->current=%p yyextra->bodyEntry=%p\n",yyextra->current,yyextra->bodyEntry); + handleCommentBlock(yyscanner, actualDoc, FALSE); } - else if (g_packageCommentAllowed) // expecting module docs + else if (yyextra->packageCommentAllowed) // expecting module docs { - QCString actualDoc=docBlock; - if (!docBlockSpecial) // legacy unformatted docstring + QCString actualDoc=yyextra->docBlock; + if (!yyextra->docBlockSpecial) // legacy unformatted docstring { actualDoc.prepend("\\verbatim "); actualDoc.append("\\endverbatim "); } - actualDoc.prepend("\\namespace "+g_moduleScope+" "); - handleCommentBlock(actualDoc, FALSE); + actualDoc.prepend("\\namespace "+yyextra->moduleScope+" "); + handleCommentBlock(yyscanner, actualDoc, FALSE); } - if ((docBlockContext==ClassBody /*&& !g_hideClassDocs*/) || - docBlockContext==FunctionBody) + if ((yyextra->docBlockContext==ClassBody /*&& !yyextra->hideClassDocs*/) || + yyextra->docBlockContext==FunctionBody) { - current->program+=docBlock; - current->program+=yytext; + yyextra->current->program+=yyextra->docBlock; + yyextra->current->program+=yytext; } - //if (g_hideClassDocs) + //if (yyextra->hideClassDocs) //{ - // current->startLine = yyLineNr; + // yyextra->current->startLine = yyextra->yyLineNr; //} - //g_hideClassDocs=FALSE; - BEGIN(docBlockContext); + //yyextra->hideClassDocs=FALSE; + BEGIN(yyextra->docBlockContext); } else { - docBlock += yytext; + yyextra->docBlock += yytext; } - g_packageCommentAllowed = FALSE; + yyextra->packageCommentAllowed = FALSE; } ^{BB} { // leading whitespace int indent = computeIndent(yytext); - if (indent>=g_curIndent) - { // strip g_curIndent amount of whitespace + if (indent>=yyextra->curIndent) + { // strip yyextra->curIndent amount of whitespace int i; - for (i=0;i<indent-g_curIndent;i++) docBlock+=' '; - DBG_CTX((stderr,"stripping indent %d\n",g_curIndent)); + for (i=0;i<indent-yyextra->curIndent;i++) yyextra->docBlock+=' '; + DBG_CTX((stderr,"stripping indent %d\n",yyextra->curIndent)); } else { - DBG_CTX((stderr,"not stripping: %d<%d\n",indent,g_curIndent)); - docBlock += yytext; + DBG_CTX((stderr,"not stripping: %d<%d\n",indent,yyextra->curIndent)); + yyextra->docBlock += yytext; } } [^"'\n \t\\]+ { - docBlock += yytext; + yyextra->docBlock += yytext; } \n { - incLineNr(); - docBlock += yytext; + incLineNr(yyscanner); + yyextra->docBlock += yytext; } \\. { // escaped char - docBlock += yytext; + yyextra->docBlock += yytext; } . { - docBlock += yytext; + yyextra->docBlock += yytext; } } @@ -1586,91 +1322,91 @@ STARTDOCSYMS "##" ^{B}"#"("#")* { // skip leading hashes } \n/{B}"#" { // continuation of the comment on the next line - docBlock+='\n'; - docBrief = FALSE; - startCommentBlock(FALSE); - incLineNr(); + yyextra->docBlock+='\n'; + yyextra->docBrief = FALSE; + startCommentBlock(yyscanner,FALSE); + incLineNr(yyscanner); } [^#\n]+ { // any other stuff - docBlock+=yytext; + yyextra->docBlock+=yytext; } \n { // new line that ends the comment - handleCommentBlock(docBlock, docBrief); - incLineNr(); - BEGIN(docBlockContext); + handleCommentBlock(yyscanner, yyextra->docBlock, yyextra->docBrief); + incLineNr(yyscanner); + BEGIN(yyextra->docBlockContext); } . { // anything we missed - docBlock+=*yytext; + yyextra->docBlock+=*yytext; } } <SingleQuoteString>{ \\{B}\n { // line continuation - addToString(yytext); - incLineNr(); + addToString(yyscanner,yytext); + incLineNr(yyscanner); } \\. { // escaped char - addToString(yytext); + addToString(yyscanner,yytext); } "\"\"\"" { // triple double quotes - addToString(yytext); + addToString(yyscanner,yytext); } "'" { // end of the string - addToString(yytext); - BEGIN(g_stringContext); + addToString(yyscanner,yytext); + BEGIN(yyextra->stringContext); } [^"'\n\\]+ { // normal chars - addToString(yytext); + addToString(yyscanner,yytext); } . { // normal char - addToString(yytext); + addToString(yyscanner,yytext); } } <DoubleQuoteString>{ \\{B}\n { // line continuation - addToString(yytext); - incLineNr(); + addToString(yyscanner,yytext); + incLineNr(yyscanner); } \\. { // escaped char - addToString(yytext); + addToString(yyscanner,yytext); } "'''" { // triple single quotes - addToString(yytext); + addToString(yyscanner,yytext); } "\"" { // end of the string - addToString(yytext); - BEGIN(g_stringContext); + addToString(yyscanner,yytext); + BEGIN(yyextra->stringContext); } [^"'\n\\]+ { // normal chars - addToString(yytext); + addToString(yyscanner,yytext); } . { // normal char - addToString(yytext); + addToString(yyscanner,yytext); } } <TripleString>{ {ENDTRIDOUBLEQUOTE} | {ENDTRISINGLEQUOTE} { - *g_copyString += yytext; - if (g_doubleQuote==(yytext[0]=='"')) + *yyextra->copyString += yytext; + if (yyextra->doubleQuote==(yytext[0]=='"')) { - BEGIN(g_stringContext); + BEGIN(yyextra->stringContext); } } ({LONGSTRINGBLOCK}) { - lineCount(); - *g_copyString += yytext; + lineCount(yyscanner); + *yyextra->copyString += yytext; } \n { - incLineNr(); - *g_copyString += yytext; + incLineNr(yyscanner); + *yyextra->copyString += yytext; } . { - *g_copyString += *yytext; + *yyextra->copyString += *yytext; } } @@ -1679,16 +1415,16 @@ STARTDOCSYMS "##" /* <*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time. // printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n", - // yytext, YY_START, yyLineNr); + // yytext, YY_START, yyextra->yyLineNr); } */ <*>{NEWLINE} { //printf("[pyscanner] %d NEWLINE [line %d] no match\n", - // YY_START, yyLineNr); + // YY_START, yyextra->yyLineNr); - lineCount(); + lineCount(yyscanner); } <*>"'" { @@ -1697,7 +1433,7 @@ STARTDOCSYMS "##" <*>. { //printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n", - // yytext, YY_START, yyLineNr); + // yytext, YY_START, yyextra->yyLineNr); } @@ -1706,10 +1442,310 @@ STARTDOCSYMS "##" //---------------------------------------------------------------------------- -static void parseCompounds(std::shared_ptr<Entry> rt) +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yy_size_t c=0; + const char *p = yyextra->inputString + yyextra->inputPosition; + while ( c < max_size && *p ) { *buf++ = *p++; c++; } + yyextra->inputPosition+=c; + return c; +} + +static void initParser(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->protection = Public; + yyextra->mtype = Method; + yyextra->stat = FALSE; + yyextra->virt = Normal; + yyextra->previous = 0; + yyextra->packageCommentAllowed = TRUE; + yyextra->packageNameCache.setAutoDelete(TRUE); +} + +static void initEntry(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //yyextra->current->python = TRUE; + yyextra->current->protection = yyextra->protection ; + yyextra->current->mtype = yyextra->mtype; + yyextra->current->virt = yyextra->virt; + yyextra->current->stat = yyextra->stat; + yyextra->current->lang = SrcLangExt_Python; + yyextra->commentScanner.initGroupInfo(yyextra->current.get()); + yyextra->stat = FALSE; +} + +static void newEntry(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->previous = yyextra->current; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + initEntry(yyscanner); +} + +static void newVariable(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->current->name.isEmpty() && yyextra->current->name.at(0)=='_') // mark as private + { + yyextra->current->protection=Private; + } + if (yyextra->current_root->section&Entry::COMPOUND_MASK) // mark as class variable + { + yyextra->current->stat = TRUE; + } + newEntry(yyscanner); +} + +static void newFunction(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->current->name.left(2)=="__" && yyextra->current->name.right(2)=="__") + { + // special method name, see + // http://docs.python.org/ref/specialnames.html + yyextra->current->protection=Public; + } + else if (yyextra->current->name.at(0)=='_') + { + yyextra->current->protection=Private; + } +} + +static inline int computeIndent(const char *s) +{ + int col=0; + static int tabSize=Config_getInt(TAB_SIZE); + const char *p=s; + char c; + while ((c=*p++)) + { + if (c==' ') col++; + else if (c=='\t') col+=tabSize-(col%tabSize); + else break; + } + return col; +} + +static QCString findPackageScopeFromPath(yyscan_t yyscanner,const QCString &path) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + QCString *pScope = yyextra->packageNameCache.find(path); + if (pScope) + { + return *pScope; + } + QFileInfo pf(path+"/__init__.py"); // found package initialization file + if (pf.exists()) + { + int i=path.findRev('/'); + if (i!=-1) + { + QCString scope = findPackageScopeFromPath(yyscanner,path.left(i)); + if (!scope.isEmpty()) + { + scope+="::"; + } + scope+=path.mid(i+1); + yyextra->packageNameCache.insert(path,new QCString(scope)); + return scope; + } + } + return ""; +} + +static QCString findPackageScope(yyscan_t yyscanner,const char *fileName) +{ + if (fileName==0) return ""; + QFileInfo fi(fileName); + return findPackageScopeFromPath(yyscanner,fi.dirPath(TRUE).data()); +} + +static void addFrom(yyscan_t yyscanner,bool all) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + QCString item=all ? yyextra->packageName : yyextra->packageName+"."+yytext; + yyextra->current->name=removeRedundantWhiteSpace(substitute(item,".","::")); + yyextra->current->fileName = yyextra->yyFileName; + //printf("Adding using declaration: found:%s:%d name=%s\n",yyextra->yyFileName.data(),yyextra->yyLineNr,yyextra->current->name.data()); + yyextra->current->section=all ? Entry::USINGDIR_SEC : Entry::USINGDECL_SEC; + yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + initEntry(yyscanner); +} +//----------------------------------------------------------------------------- + +static void lineCount(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr)); + for (const char *p = yytext; *p; ++p) + { + yyextra->yyLineNr += (*p == '\n') ; + } +} + +static void incLineNr(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr)); + yyextra->yyLineNr++; +} + +//----------------------------------------------------------------- +static void startCommentBlock(yyscan_t yyscanner,bool brief) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (brief) + { + yyextra->current->briefFile = yyextra->yyFileName; + yyextra->current->briefLine = yyextra->yyLineNr; + } + else + { + yyextra->current->docFile = yyextra->yyFileName; + yyextra->current->docLine = yyextra->yyLineNr; + } +} + +static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //printf("handleCommentBlock(doc=[%s] brief=%d yyextra->docBlockInBody=%d yyextra->docBlockJavaStyle=%d\n", + // doc.data(),brief,yyextra->docBlockInBody,yyextra->docBlockJavaStyle); + + // TODO: Fix me + yyextra->docBlockInBody=FALSE; + + if (yyextra->docBlockInBody && yyextra->previous && !yyextra->previous->doc.isEmpty()) + { + yyextra->previous->doc=yyextra->previous->doc.stripWhiteSpace()+"\n\n"; + } + + int position = 0; + bool needsEntry; + int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; + QCString processedDoc = processMarkdownForCommentBlock(doc,yyextra->yyFileName,lineNr); + while (yyextra->commentScanner.parseCommentBlock( + yyextra->thisParser, + (yyextra->docBlockInBody && yyextra->previous) ? yyextra->previous.get() : yyextra->current.get(), + processedDoc, // text + yyextra->yyFileName, // file + lineNr, + yyextra->docBlockInBody ? FALSE : brief, + yyextra->docBlockJavaStyle, // javadoc style // or FALSE, + yyextra->docBlockInBody, + yyextra->protection, + position, + needsEntry) + ) // need to start a new entry + { + if (needsEntry) + { + newEntry(yyscanner); + } + } + if (needsEntry) + { + newEntry(yyscanner); + } + +} + +static void endOfDef(yyscan_t yyscanner,int correction) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //printf("endOfDef at=%d\n",yyextra->yyLineNr); + if (yyextra->bodyEntry) + { + yyextra->bodyEntry->endBodyLine = yyextra->yyLineNr-correction; + yyextra->bodyEntry = 0; + } + newEntry(yyscanner); + //yyextra->insideConstructor = FALSE; +} + +static inline void addToString(yyscan_t yyscanner,const char *s) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->copyString) (*yyextra->copyString)+=s; +} + +static void initTriDoubleQuoteBlock(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->docBlockContext = YY_START; + yyextra->docBlockInBody = FALSE; + yyextra->docBlockJavaStyle = TRUE; + yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!'; + yyextra->docBlock.resize(0); + yyextra->doubleQuote = TRUE; + startCommentBlock(yyscanner,FALSE); +} + +static void initTriSingleQuoteBlock(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->docBlockContext = YY_START; + yyextra->docBlockInBody = FALSE; + yyextra->docBlockJavaStyle = TRUE; + yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!'; + yyextra->docBlock.resize(0); + yyextra->doubleQuote = FALSE; + startCommentBlock(yyscanner,FALSE); +} + +static void initSpecialBlock(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->docBlockContext = YY_START; + yyextra->docBlockInBody = FALSE; + yyextra->docBlockJavaStyle = TRUE; + yyextra->docBrief = TRUE; + yyextra->docBlock.resize(0); + startCommentBlock(yyscanner,TRUE); +} + +static void searchFoundDef(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->section = Entry::FUNCTION_SEC; + yyextra->current->lang = SrcLangExt_Python; + yyextra->current->virt = Normal; + yyextra->current->stat = yyextra->stat; + yyextra->current->mtype = yyextra->mtype = Method; + yyextra->current->type.resize(0); + yyextra->current->name.resize(0); + yyextra->current->args.resize(0); + yyextra->current->argList.clear(); + yyextra->packageCommentAllowed = FALSE; + yyextra->stat=FALSE; + //printf("searchFoundDef at=%d\n",yyextra->yyLineNr); +} + +static void searchFoundClass(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->current->section = Entry::CLASS_SEC; + yyextra->current->argList.clear(); + yyextra->current->type += "class" ; + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->packageCommentAllowed = FALSE; +} + +//---------------------------------------------------------------------------- + +static void parseCompounds(yyscan_t yyscanner,std::shared_ptr<Entry> rt) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("parseCompounds(%s)\n",rt->name.data()); - for (int i=0; i<rt->children().size(); ++i) + for (size_t i=0; i<rt->children().size(); ++i) { std::shared_ptr<Entry> ce = rt->children()[i]; if (!ce->program.isEmpty()) @@ -1717,174 +1753,179 @@ static void parseCompounds(std::shared_ptr<Entry> rt) //printf("-- %s ---------\n%s\n---------------\n", // ce->name.data(),ce->program.data()); // init scanner state - inputString = ce->program; - inputPosition = 0; - pyscannerYYrestart( pyscannerYYin ) ; + yyextra->inputString = ce->program; + yyextra->inputPosition = 0; + pyscannerYYrestart( 0, yyscanner ); if (ce->section&Entry::COMPOUND_MASK) { - current_root = ce; + yyextra->current_root = ce; BEGIN( Search ); } else if (ce->parent()) { - current_root = rt; + yyextra->current_root = rt; //printf("Searching for member variables in %s parent=%s\n", // ce->name.data(),ce->parent->name.data()); BEGIN( SearchMemVars ); } - yyFileName = ce->fileName; - yyLineNr = ce->bodyLine ; - current = std::make_shared<Entry>(); - initEntry(); + yyextra->yyFileName = ce->fileName; + yyextra->yyLineNr = ce->bodyLine ; + yyextra->current = std::make_shared<Entry>(); + initEntry(yyscanner); QCString name = ce->name; - Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,name); + yyextra->commentScanner.enterCompound(yyextra->yyFileName,yyextra->yyLineNr,name); - pyscannerYYlex() ; - g_lexInit=TRUE; + pyscannerYYlex(yyscanner) ; + yyextra->lexInit=TRUE; ce->program.resize(0); - Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,name); + yyextra->commentScanner.leaveCompound(yyextra->yyFileName,yyextra->yyLineNr,name); } - parseCompounds(ce); + parseCompounds(yyscanner,ce); } } //---------------------------------------------------------------------------- -static void parseMain(const char *fileName,const char *fileBuf,const std::shared_ptr<Entry> &rt) +static void parseMain(yyscan_t yyscanner, const char *fileName,const char *fileBuf,const std::shared_ptr<Entry> &rt) { - initParser(); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + initParser(yyscanner); + + yyextra->inputString = fileBuf; + yyextra->inputPosition = 0; - inputString = fileBuf; - inputPosition = 0; + yyextra->protection = Public; + yyextra->mtype = Method; + yyextra->stat = FALSE; + yyextra->virt = Normal; + yyextra->current_root = rt; + yyextra->specialBlock = FALSE; - protection = Public; - mtype = Method; - gstat = FALSE; - virt = Normal; - current_root = rt; - g_specialBlock = FALSE; + yyextra->yyLineNr= 1 ; + yyextra->yyFileName = fileName; + //setContext(); + msg("Parsing file %s...\n",yyextra->yyFileName.data()); - inputFile.setName(fileName); - if (inputFile.open(IO_ReadOnly)) + QFileInfo fi(fileName); + yyextra->moduleScope = findPackageScope(yyscanner,fileName); + QCString baseName=fi.baseName().utf8(); + if (baseName!="__init__") // package initializer file is not a package itself { - yyLineNr= 1 ; - yyFileName = fileName; - //setContext(); - msg("Parsing file %s...\n",yyFileName.data()); - - QFileInfo fi(fileName); - g_moduleScope = findPackageScope(fileName); - QCString baseName=fi.baseName().utf8(); - if (baseName!="__init__") // package initializer file is not a package itself + if (!yyextra->moduleScope.isEmpty()) { - if (!g_moduleScope.isEmpty()) - { - g_moduleScope+="::"; - } - g_moduleScope+=baseName; + yyextra->moduleScope+="::"; } + yyextra->moduleScope+=baseName; + } - current = std::make_shared<Entry>(); - initEntry(); - current->name = g_moduleScope; - current->section = Entry::NAMESPACE_SEC; - current->type = "namespace"; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->bodyLine = yyLineNr; + yyextra->current = std::make_shared<Entry>(); + initEntry(yyscanner); + yyextra->current->name = yyextra->moduleScope; + yyextra->current->section = Entry::NAMESPACE_SEC; + yyextra->current->type = "namespace"; + yyextra->current->fileName = yyextra->yyFileName; + yyextra->current->startLine = yyextra->yyLineNr; + yyextra->current->bodyLine = yyextra->yyLineNr; - current_root = current; + yyextra->current_root = yyextra->current; - rt->moveToSubEntryAndRefresh(current); + rt->moveToSubEntryAndRefresh(yyextra->current); - initParser(); + initParser(yyscanner); - Doxygen::docGroup.enterFile(yyFileName,yyLineNr); - - current->reset(); - initEntry(); - pyscannerYYrestart( pyscannerYYin ); - BEGIN( Search ); - pyscannerYYlex(); - g_lexInit=TRUE; + yyextra->commentScanner.enterFile(yyextra->yyFileName,yyextra->yyLineNr); - Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); + yyextra->current->reset(); + initEntry(yyscanner); + pyscannerYYrestart(0,yyscanner); + BEGIN( Search ); + pyscannerYYlex(yyscanner); + yyextra->lexInit=TRUE; - current_root->program.resize(0); + yyextra->commentScanner.leaveFile(yyextra->yyFileName,yyextra->yyLineNr); - parseCompounds(current_root); + yyextra->current_root->program.resize(0); - inputFile.close(); - } - + parseCompounds(yyscanner, yyextra->current_root); } //---------------------------------------------------------------------------- -static void parsePrototype(const QCString &text) +static void parsePrototype(yyscan_t yyscanner,const QCString &text) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("**** parsePrototype(%s) begin\n",text.data()); if (text.isEmpty()) { - warn(yyFileName,yyLineNr,"Empty prototype found!"); + warn(yyextra->yyFileName,yyextra->yyLineNr,"Empty prototype found!"); return; } - g_specialBlock = FALSE; - g_packageCommentAllowed = FALSE; + yyextra->specialBlock = FALSE; + yyextra->packageCommentAllowed = FALSE; const char *orgInputString; - int orgInputPosition; + yy_size_t orgInputPosition; YY_BUFFER_STATE orgState; // save scanner state orgState = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(pyscannerYYin, YY_BUF_SIZE)); - orgInputString = inputString; - orgInputPosition = inputPosition; + yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE, yyscanner), yyscanner); + orgInputString = yyextra->inputString; + orgInputPosition = yyextra->inputPosition; // set new string - inputString = text; - inputPosition = 0; - pyscannerYYrestart( pyscannerYYin ); + yyextra->inputString = text; + yyextra->inputPosition = 0; + pyscannerYYrestart( 0, yyscanner ); BEGIN( FunctionDec ); - pyscannerYYlex(); - g_lexInit=TRUE; + pyscannerYYlex(yyscanner); + yyextra->lexInit=TRUE; - current->name = current->name.stripWhiteSpace(); - if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty()) - current->section = Entry::VARIABLEDOC_SEC; + yyextra->current->name = yyextra->current->name.stripWhiteSpace(); + if (yyextra->current->section == Entry::MEMBERDOC_SEC && yyextra->current->args.isEmpty()) + yyextra->current->section = Entry::VARIABLEDOC_SEC; // restore original scanner state YY_BUFFER_STATE tmpBuf = YY_CURRENT_BUFFER; - yy_switch_to_buffer(orgState); - yy_delete_buffer(tmpBuf); + yy_switch_to_buffer(orgState, yyscanner); + yy_delete_buffer(tmpBuf, yyscanner); - inputString = orgInputString; - inputPosition = orgInputPosition; + yyextra->inputString = orgInputString; + yyextra->inputPosition = orgInputPosition; //printf("**** parsePrototype end\n"); } -void pyscanFreeScanner() +//---------------------------------------------------------------------------- + +struct PythonOutlineParser::Private { -#if defined(YY_FLEX_SUBMINOR_VERSION) - if (g_lexInit) - { - pyscannerYYlex_destroy(); - } + yyscan_t yyscanner; + pyscannerYY_state state; +}; + +PythonOutlineParser::PythonOutlineParser() : p(std::make_unique<PythonOutlineParser::Private>()) +{ + pyscannerYYlex_init_extra(&p->state,&p->yyscanner); +#ifdef FLEX_DEBUG + pyscannerYYset_debug(1,p->yyscanner); #endif } -//---------------------------------------------------------------------------- +PythonOutlineParser::~PythonOutlineParser() +{ + pyscannerYYlex_destroy(p->yyscanner); +} + void PythonOutlineParser::parseInput(const char *fileName, const char *fileBuf, @@ -1892,9 +1933,10 @@ void PythonOutlineParser::parseInput(const char *fileName, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { - g_thisParser = this; + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->thisParser = this; printlex(yy_flex_debug, TRUE, __FILE__, fileName); - ::parseMain(fileName,fileBuf,root); + ::parseMain(p->yyscanner, fileName,fileBuf,root); printlex(yy_flex_debug, FALSE, __FILE__, fileName); // May print the AST for debugging purposes @@ -1908,10 +1950,12 @@ bool PythonOutlineParser::needsPreprocessing(const QCString &) const void PythonOutlineParser::parsePrototype(const char *text) { - ::parsePrototype(text); + ::parsePrototype(p->yyscanner,text); } //---------------------------------------------------------------------------- +#if USE_STATE2STRING #include "pyscanner.l.h" +#endif diff --git a/src/reflist.cpp b/src/reflist.cpp index 016ef49..55e9708 100644 --- a/src/reflist.cpp +++ b/src/reflist.cpp @@ -1,13 +1,10 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -16,196 +13,77 @@ * */ +#include <algorithm> + #include <stdio.h> #include "reflist.h" -#include "util.h" #include "ftextstream.h" #include "definition.h" - -/*! Create a list of items that are cross referenced with documentation blocks - * @param listName String representing the name of the list. - * @param pageTitle String representing the title of the list page. - * @param secTitle String representing the title of the section. - */ -RefList::RefList(const char *listName, - const char *pageTitle, - const char *secTitle - ) -{ - m_itemList = 0; - m_dict = 0; - m_dictIterator = 0; - m_id = 0; - m_listName = listName; - m_fileName = convertNameToFile(listName,FALSE,TRUE); - m_pageTitle = pageTitle; - m_secTitle = secTitle; -} - -/*! Destroy the todo list. Currently not called! */ -RefList::~RefList() -{ - delete m_dictIterator; - delete m_dict; - delete m_itemList; -} - -/*! Adds a new item to the list. - * \returns A unique id for this item. - */ -int RefList::addRefItem() -{ - if (m_dict==0) - { - m_dict = new QIntDict<RefItem>(1009); - m_dict->setAutoDelete(TRUE); - m_dictIterator = new QIntDictIterator<RefItem>(*m_dict); - } - RefItem *item = new RefItem; - m_id++; - m_dict->insert(m_id,item); - return m_id; -} - -/*! Returns an item given it's id that is obtained with addRefItem() - * \param itemId item's identifier. - * \returns A pointer to the todo item's structure. - */ -RefItem *RefList::getRefItem(int itemId) -{ - return m_dict ? m_dict->find(itemId) : 0; -} - -/*! Returns the first item in the dictionary or 0 if - * non is available. - * Items are not sorted. - */ -RefItem *RefList::getFirstRefItem() -{ - return m_dictIterator ? m_dictIterator->toFirst() : 0; -} - -/*! Returns the next item in the dictionary or 0 if - * we are at the end of the list. - * Items are not sorted. - */ -RefItem *RefList::getNextRefItem() -{ - return m_dictIterator ? m_dictIterator->operator++() : 0; -} - -/*! Returns the name of the list as set in the constructor. */ -QCString RefList::listName() const -{ - return m_listName; -} - -QCString RefList::fileName() const -{ - return m_fileName; -} - -QCString RefList::pageTitle() const -{ - return m_pageTitle; -} - -QCString RefList::sectionTitle() const -{ - return m_secTitle; -} - -void RefList::insertIntoList(const char *key,RefItem *item) -{ - if (m_itemList==0) - { - m_itemList = new SortedRefItems(1009); - } - RefItem *ri = m_itemList->find(key); - if (ri==0) - { - m_itemList->append(key,item); - } - else // item already added to the list (i.e. multiple item for the same - // entity) - { - if (ri!=item) - { - // We also have to check if the item is not already in the "extra" list - QListIterator<RefItem> li(ri->extraItems); - RefItem *extraItem; - bool doubleItem = false; - for (li.toFirst();(extraItem=li.current());++li) - { - if (item == extraItem) doubleItem = true; - } - if (!doubleItem) ri->extraItems.append(item); - } - } -} - +#include "sortdict.h" void RefList::generatePage() { - if (m_itemList==0) return; - m_itemList->sort(); - SDict<RefItem>::Iterator it(*m_itemList); - RefItem *item; + std::sort(m_entries.begin(),m_entries.end(), + [](std::unique_ptr<RefItem> &left,std::unique_ptr<RefItem> &right) + { return qstricmp(left->title(),left->title()); }); + //RefItem *item; QCString doc; doc += "<dl class=\"reflist\">"; - for (it.toFirst();(item=it.current());++it) + QCString lastGroup; + bool first=true; + for (const std::unique_ptr<RefItem> &item : m_entries) { - doc += " <dt>"; - doc += "\n"; - if (item->scope) + bool startNewGroup = item->group()!=lastGroup; + if (startNewGroup) { - if (item->scope->name() != "<globalScope>") + if (!first) { - doc += "\\_setscope "; - doc += item->scope->name(); - doc += " "; + doc += "</dd>"; + first=false; } + doc += " <dt>"; + doc += "\n"; + if (item->scope()) + { + if (item->scope()->name() != "<globalScope>") + { + doc += "\\_setscope "; + doc += item->scope()->name(); + doc += " "; + } + } + doc += item->prefix(); + doc += " \\_internalref "; + doc += item->name(); + // escape \'s in title, see issue #5901 + QCString escapedTitle = substitute(item->title(),"\\","\\\\"); + doc += " \""+escapedTitle+"\" "; + // write declaration in case a function with arguments + if (!item->args().isEmpty()) + { + // escape @'s in argument list, needed for Java annotations (see issue #6208) + // escape \'s in argument list (see issue #6533) + doc += substitute(substitute(item->args(),"@","@@"),"\\","\\\\"); + } + doc += "</dt><dd>"; } - doc += item->prefix; - doc += " \\_internalref "; - doc += item->name; - // escape \'s in title, see issue #5901 - QCString escapedTitle = substitute(item->title,"\\","\\\\"); - if (item->scope && - (item->scope->definitionType()==Definition::TypeClass || - item->scope->definitionType()==Definition::TypeNamespace || - item->scope->definitionType()==Definition::TypeMember || - item->scope->definitionType()==Definition::TypePackage) - ) - { - // prevent Obj-C names in e.g. todo list are seen as emoji - escapedTitle = substitute(escapedTitle,":","∷"); - } - doc += " \""+escapedTitle+"\" "; - // write declaration in case a function with arguments - if (!item->args.isEmpty()) + else { - // escape @'s in argument list, needed for Java annotations (see issue #6208) - // escape \'s in argument list (see issue #6533) - doc += substitute(substitute(item->args,"@","@@"),"\\","\\\\"); + doc += "<p>"; } - doc += "</dt><dd> \\anchor "; - doc += item->listAnchor; + doc += " \\anchor "; + doc += item->anchor(); doc += " "; - doc += item->text; - QListIterator<RefItem> li(item->extraItems); - RefItem *extraItem; - for (li.toFirst();(extraItem=li.current());++li) - { - doc += "<p> \\anchor "; - doc += extraItem->listAnchor; - doc += " "; - doc += extraItem->text; - } + doc += item->text(); + lastGroup = item->group(); + first = false; + } + if (!first) + { doc += "</dd>"; } doc += "</dl>\n"; //printf("generatePage('%s')\n",doc.data()); - addRelatedPage(m_listName,m_pageTitle,doc,m_fileName,1,std::vector<ListItemInfo>(),0,0,TRUE); + addRelatedPage(m_listName,m_pageTitle,doc,m_fileName,1,std::vector<RefItem*>(),0,0,TRUE); } diff --git a/src/reflist.h b/src/reflist.h index d064c58..49c3036 100644 --- a/src/reflist.h +++ b/src/reflist.h @@ -1,9 +1,6 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -19,39 +16,55 @@ #ifndef _REFLIST_H #define _REFLIST_H +#include <vector> +#include <unordered_map> +#include <memory> + #include <qintdict.h> #include <qlist.h> -#include "sortdict.h" +#include "util.h" +#include "linkedmap.h" class Definition; +class RefList; /** This struct represents an item in the list of references. */ -struct RefItem -{ - RefItem() : scope(0) {} - QCString text; //!< text of the item. - QCString listAnchor; //!< anchor in the list - - QCString prefix; //!< type prefix for the name - Definition *scope; //!< scope to use for references. - QCString name; //!< name of the entity containing the reference - QCString title; //!< display name of the entity - QCString args; //!< optional arguments for the entity (if function) - //bool written; - QList<RefItem> extraItems; //!< more items belonging to the same entity -}; - -/** List of items sorted by title */ -class SortedRefItems : public SDict<RefItem> +class RefItem { public: - SortedRefItems(int size=17) : SDict<RefItem>(size) {} - virtual ~SortedRefItems() {} + RefItem(int id,RefList *list) : m_id(id), m_list(list) {} + + void setText (const char *text) { m_text = text; } + void setAnchor(const char *anchor) { m_anchor = anchor; } + void setPrefix(const char *prefix) { m_prefix = prefix; } + void setName (const char *name) { m_name = name; } + void setTitle (const char *title) { m_title = title; } + void setArgs (const char *args) { m_args = args; } + void setGroup (const char *group) { m_group = group; } + void setScope (const Definition *scope) { m_scope = scope; } + + QCString text() const { return m_text; } + QCString anchor() const { return m_anchor; } + QCString prefix() const { return m_prefix; } + QCString name() const { return m_name; } + QCString title() const { return m_title; } + QCString args() const { return m_args; } + QCString group() const { return m_group; } + int id() const { return m_id; } + RefList *list() const { return m_list; } + const Definition *scope() const { return m_scope; } + private: - int compareValues(const RefItem *r1,const RefItem *r2) const - { - return qstricmp(r1->title,r2->title); - } + int m_id = 0; //!< unique identifier for this item within its list + RefList *m_list; //!< list owning this item + QCString m_text; //!< text of the item. + QCString m_anchor; //!< anchor in the list + QCString m_prefix; //!< type prefix for the name + QCString m_name; //!< name of the entity containing the reference + QCString m_title; //!< display name of the entity + QCString m_args; //!< optional arguments for the entity (if function) + QCString m_group; //!< group id used to combine item under a single header + const Definition *m_scope = 0; //!< scope to use for references. }; /** List of cross-referenced items @@ -67,31 +80,68 @@ class SortedRefItems : public SDict<RefItem> class RefList { public: - int addRefItem(); - RefItem *getRefItem(int todoItemId); - RefItem *getFirstRefItem(); - RefItem *getNextRefItem(); - QCString listName() const; - QCString fileName() const; - QCString pageTitle() const; - QCString sectionTitle() const; - - RefList(const char *listName, - const char *pageTitle,const char *secTitle - ); - ~RefList(); - void insertIntoList(const char *key,RefItem *item); + /*! Create a list of items that are cross referenced with documentation blocks + * @param listName String representing the name of the list. + * @param pageTitle String representing the title of the list page. + * @param secTitle String representing the title of the section. + */ + RefList(const char *listName, const char *pageTitle, const char *secTitle) : + m_listName(listName), m_fileName(convertNameToFile(listName,FALSE,TRUE)), + m_pageTitle(pageTitle), m_secTitle(secTitle) {} + + /*! Adds a new item to the list. + * @returns A unique id for this item. + */ + RefItem *add() + { + m_id++; + std::unique_ptr<RefItem> item = std::make_unique<RefItem>(m_id,this); + RefItem *result = item.get(); + m_entries.push_back(std::move(item)); + m_lookup.insert({m_id,result}); + return result; + } + + /*! Returns an item given it's id that is obtained with addRefItem() + * @param itemId item's identifier. + * @returns A pointer to the todo item's structure. + */ + RefItem *find(int itemId) + { + auto it = m_lookup.find(itemId); + return it!=m_lookup.end() ? it->second : nullptr; + } + + QCString listName() const { return m_listName; } + QCString fileName() const { return m_fileName; } + QCString pageTitle() const { return m_pageTitle; } + QCString sectionTitle() const { return m_secTitle; } + void generatePage(); private: - int m_id; + int m_id = 0; QCString m_listName; QCString m_fileName; QCString m_pageTitle; QCString m_secTitle; - SortedRefItems *m_itemList; - QIntDict<RefItem> *m_dict; - QIntDictIterator<RefItem> *m_dictIterator; + std::vector< std::unique_ptr< RefItem > > m_entries; + std::unordered_map< int, RefItem* > m_lookup; +}; + +class RefListManager : public LinkedMap<RefList> +{ + public: + static RefListManager &instance() + { + static RefListManager rlm; + return rlm; + } + + private: + RefListManager() {} + RefListManager(const RefListManager &other) = delete; + RefListManager &operator=(const RefListManager &other) = delete; }; #endif diff --git a/src/resourcemgr.cpp b/src/resourcemgr.cpp index 8cb831e..4ba3388 100644 --- a/src/resourcemgr.cpp +++ b/src/resourcemgr.cpp @@ -97,14 +97,14 @@ bool ResourceMgr::copyResourceAs(const char *name,const char *targetDir,const ch { QCString n = name; n = n.left(n.length()-4)+".png"; // replace .lum by .png - uchar *p = (uchar*)res->data; - int width = (p[0]<<8)+p[1]; - int height = (p[2]<<8)+p[3]; + uchar *data = (uchar*)res->data; + ushort width = (data[0]<<8)+data[1]; + ushort height = (data[2]<<8)+data[3]; ColoredImgDataItem images[2]; images[0].name = n; images[0].width = width; images[0].height = height; - images[0].content = &p[4]; + images[0].content = &data[4]; images[0].alpha = 0; images[1].name = 0; // terminator writeColoredImgData(targetDir,images); @@ -115,15 +115,15 @@ bool ResourceMgr::copyResourceAs(const char *name,const char *targetDir,const ch { QCString n = name; n = n.left(n.length()-5)+".png"; // replace .luma by .png - uchar *p = (uchar*)res->data; - int width = (p[0]<<8)+p[1]; - int height = (p[2]<<8)+p[3]; + uchar *data = (uchar*)res->data; + ushort width = (data[0]<<8)+data[1]; + ushort height = (data[2]<<8)+data[3]; ColoredImgDataItem images[2]; images[0].name = n; images[0].width = width; images[0].height = height; - images[0].content = &p[4]; - images[0].alpha = &p[4+width*height]; + images[0].content = &data[4]; + images[0].alpha = &data[4+width*height]; images[1].name = 0; // terminator writeColoredImgData(targetDir,images); return TRUE; @@ -144,7 +144,7 @@ bool ResourceMgr::copyResourceAs(const char *name,const char *targetDir,const ch } else { - t << substitute(buf,"$doxygenversion",getVersion()); + t << substitute(buf,"$doxygenversion",getDoxygenVersion()); } return TRUE; } diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 471cf85..fbe7cc1 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -1,13 +1,13 @@ /****************************************************************************** * - * + * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -44,13 +44,13 @@ static QCString align(DocHtmlCell *cell) { HtmlAttribList attrs = cell->attribs(); uint i; - for (i=0; i<attrs.count(); ++i) + for (i=0; i<attrs.count(); ++i) { if (attrs.at(i)->name.lower()=="align") { - if (attrs.at(i)->value.lower()=="center") + if (attrs.at(i)->value.lower()=="center") return "\\qc "; - else if (attrs.at(i)->value.lower()=="right") + else if (attrs.at(i)->value.lower()=="right") return "\\qr "; else return ""; } @@ -59,8 +59,8 @@ static QCString align(DocHtmlCell *cell) } RTFDocVisitor::RTFDocVisitor(FTextStream &t,CodeOutputInterface &ci, - const char *langExt) - : DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_insidePre(FALSE), + const char *langExt) + : DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_indentLevel(0), m_lastIsPara(FALSE), m_langExt(langExt) { } @@ -71,7 +71,7 @@ QCString RTFDocVisitor::getStyle(const char *name) n.sprintf("%s%d",name,m_indentLevel); StyleData *sd = rtf_Style[n]; ASSERT(sd!=0); - return sd->reference; + return sd->reference(); } void RTFDocVisitor::incIndentLevel() @@ -213,7 +213,7 @@ void RTFDocVisitor::visit(DocLineBreak *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n"); - m_t << "\\par" << endl; + m_t << "\\par" << endl; m_lastIsPara=TRUE; } @@ -309,34 +309,34 @@ void RTFDocVisitor::visit(DocVerbatim *s) Doxygen::parserManager->getCodeParser(lang) .parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); - //m_t << "\\par" << endl; + //m_t << "\\par" << endl; m_t << "}" << endl; break; - case DocVerbatim::Verbatim: + case DocVerbatim::Verbatim: m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); filter(s->text(),TRUE); - //m_t << "\\par" << endl; + //m_t << "\\par" << endl; m_t << "}" << endl; break; - case DocVerbatim::RtfOnly: - m_t << s->text(); + case DocVerbatim::RtfOnly: + m_t << s->text(); break; - case DocVerbatim::HtmlOnly: - case DocVerbatim::LatexOnly: - case DocVerbatim::XmlOnly: + case DocVerbatim::HtmlOnly: + case DocVerbatim::LatexOnly: + case DocVerbatim::XmlOnly: case DocVerbatim::ManOnly: case DocVerbatim::DocbookOnly: /* nothing */ break; - case DocVerbatim::Dot: + case DocVerbatim::Dot: { static int dotindex = 1; QCString fileName(4096); - fileName.sprintf("%s%d%s", - (Config_getString(RTF_OUTPUT)+"/inline_dotgraph_").data(), + fileName.sprintf("%s%d%s", + (Config_getString(RTF_OUTPUT)+"/inline_dotgraph_").data(), dotindex++, ".dot" ); @@ -355,13 +355,13 @@ void RTFDocVisitor::visit(DocVerbatim *s) if (Config_getBool(DOT_CLEANUP)) file.remove(); } break; - case DocVerbatim::Msc: + case DocVerbatim::Msc: { static int mscindex = 1; QCString baseName(4096); baseName.sprintf("%s%d%s", - (Config_getString(RTF_OUTPUT)+"/inline_mscgraph_").data(), + (Config_getString(RTF_OUTPUT)+"/inline_mscgraph_").data(), mscindex++, ".msc" ); @@ -427,7 +427,7 @@ void RTFDocVisitor::visit(DocInclude *inc) switch(inc->type()) { case DocInclude::IncWithLines: - { + { m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); @@ -451,7 +451,7 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "}" << endl; } break; - case DocInclude::Include: + case DocInclude::Include: m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); @@ -473,8 +473,14 @@ void RTFDocVisitor::visit(DocInclude *inc) case DocInclude::DontIncWithLines: case DocInclude::HtmlInclude: case DocInclude::LatexInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: break; - case DocInclude::VerbInclude: + case DocInclude::RtfInclude: + m_t << inc->text(); + break; + case DocInclude::VerbInclude: m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); @@ -509,7 +515,7 @@ void RTFDocVisitor::visit(DocInclude *inc) extractBlock(inc->text(),inc->blockId()), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine @@ -521,8 +527,8 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "}"; } break; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" "Please create a bug report\n",__FILE__); break; @@ -538,7 +544,7 @@ void RTFDocVisitor::visit(DocIncOperator *op) QCString locLangExt = getFileNameExtension(op->includeFileName()); if (locLangExt.isEmpty()) locLangExt = m_langExt; SrcLangExt langExt = getLanguageFromFileName(locLangExt); - if (op->isFirst()) + if (op->isFirst()) { if (!m_hide) { @@ -549,10 +555,10 @@ void RTFDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide = TRUE; } - if (op->type()!=DocIncOperator::Skip) + if (op->type()!=DocIncOperator::Skip) { popEnabled(); - if (!m_hide) + if (!m_hide) { FileDef *fd = 0; if (!op->includeFileName().isEmpty()) @@ -576,7 +582,7 @@ void RTFDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide=TRUE; } - if (op->isLast()) + if (op->isLast()) { popEnabled(); if (!m_hide) @@ -598,7 +604,7 @@ void RTFDocVisitor::visit(DocFormula *f) if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocFormula)}\n"); bool bDisplay = !f->isInline(); - if (bDisplay) + if (bDisplay) { m_t << "\\par"; m_t << "{"; @@ -607,7 +613,7 @@ void RTFDocVisitor::visit(DocFormula *f) m_t << "\\qc"; } m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << f->relPath() << f->name() << ".png\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}"; - if (bDisplay) + if (bDisplay) { m_t << "\\par}"; } @@ -630,7 +636,7 @@ void RTFDocVisitor::visit(DocCite *cite) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocCite)}\n"); - if (!cite->file().isEmpty()) + if (!cite->file().isEmpty()) { startLink(cite->ref(),cite->file(),cite->anchor()); } @@ -639,7 +645,7 @@ void RTFDocVisitor::visit(DocCite *cite) m_t << "{\\b "; } filter(cite->text()); - if (!cite->file().isEmpty()) + if (!cite->file().isEmpty()) { endLink(cite->ref()); } @@ -671,7 +677,7 @@ void RTFDocVisitor::visitPost(DocAutoList *) if (!m_lastIsPara) m_t << "\\par"; m_t << "}" << endl; m_lastIsPara=TRUE; - if (!m_indentLevel) m_t << "\\par"; + if (!m_indentLevel) m_t << "\\par" << endl; } void RTFDocVisitor::visitPre(DocAutoListItem *) @@ -694,13 +700,13 @@ void RTFDocVisitor::visitPre(DocAutoListItem *) m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocAutoListItem *) +void RTFDocVisitor::visitPost(DocAutoListItem *) { decIndentLevel(); DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoListItem)}\n"); } -void RTFDocVisitor::visitPre(DocPara *) +void RTFDocVisitor::visitPre(DocPara *) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n"); } @@ -714,7 +720,7 @@ void RTFDocVisitor::visitPost(DocPara *p) !(p->parent() && // and for parameters & sections p->parent()->kind()==DocNode::Kind_ParamSect ) - ) + ) { m_t << "\\par" << endl; m_lastIsPara=TRUE; @@ -726,7 +732,7 @@ void RTFDocVisitor::visitPre(DocRoot *r) if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRoot)}\n"); if (r->indent()) incIndentLevel(); - m_t << "{" << rtf_Style["BodyText"]->reference << endl; + m_t << "{" << rtf_Style["BodyText"]->reference() << endl; } void RTFDocVisitor::visitPost(DocRoot *r) @@ -746,24 +752,24 @@ void RTFDocVisitor::visitPre(DocSimpleSect *s) if (!m_lastIsPara) m_t << "\\par" << endl; m_t << "{"; // start desc //m_t << "{\\b "; // start bold - m_t << "{" << rtf_Style["Heading5"]->reference << endl; + m_t << "{" << rtf_Style["Heading5"]->reference() << endl; switch(s->type()) { - case DocSimpleSect::See: + case DocSimpleSect::See: m_t << theTranslator->trSeeAlso(); break; - case DocSimpleSect::Return: + case DocSimpleSect::Return: m_t << theTranslator->trReturns(); break; - case DocSimpleSect::Author: + case DocSimpleSect::Author: m_t << theTranslator->trAuthor(TRUE,TRUE); break; - case DocSimpleSect::Authors: + case DocSimpleSect::Authors: m_t << theTranslator->trAuthor(TRUE,FALSE); break; - case DocSimpleSect::Version: + case DocSimpleSect::Version: m_t << theTranslator->trVersion(); break; - case DocSimpleSect::Since: + case DocSimpleSect::Since: m_t << theTranslator->trSince(); break; - case DocSimpleSect::Date: + case DocSimpleSect::Date: m_t << theTranslator->trDate(); break; - case DocSimpleSect::Note: + case DocSimpleSect::Note: m_t << theTranslator->trNote(); break; case DocSimpleSect::Warning: m_t << theTranslator->trWarning(); break; @@ -850,7 +856,7 @@ void RTFDocVisitor::visitPre(DocSimpleListItem *) incIndentLevel(); } -void RTFDocVisitor::visitPost(DocSimpleListItem *) +void RTFDocVisitor::visitPost(DocSimpleListItem *) { decIndentLevel(); DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleListItem)}\n"); @@ -869,7 +875,7 @@ void RTFDocVisitor::visitPre(DocSection *s) int level = QMIN(s->level()+1,4); heading.sprintf("Heading%d",level); // set style - m_t << rtf_Style[heading]->reference << endl; + m_t << rtf_Style[heading]->reference() << endl; // make table of contents entry filter(s->title()); m_t << endl << "\\par" << "}" << endl; @@ -879,7 +885,7 @@ void RTFDocVisitor::visitPre(DocSection *s) m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPost(DocSection *) +void RTFDocVisitor::visitPost(DocSection *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSection)}\n"); @@ -892,12 +898,12 @@ void RTFDocVisitor::visitPre(DocHtmlList *l) if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlList)}\n"); m_t << "{" << endl; - rtf_listItemInfo[m_indentLevel].isEnum = l->type()==DocHtmlList::Ordered; + rtf_listItemInfo[m_indentLevel].isEnum = l->type()==DocHtmlList::Ordered; rtf_listItemInfo[m_indentLevel].number = 1; m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlList *) +void RTFDocVisitor::visitPost(DocHtmlList *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlList)}\n"); @@ -925,7 +931,7 @@ void RTFDocVisitor::visitPre(DocHtmlListItem *) m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlListItem *) +void RTFDocVisitor::visitPost(DocHtmlListItem *) { decIndentLevel(); DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlListItem)}\n"); @@ -940,7 +946,7 @@ void RTFDocVisitor::visitPre(DocHtmlDescList *) //m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlDescList *) +void RTFDocVisitor::visitPost(DocHtmlDescList *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescList)}\n"); @@ -955,11 +961,11 @@ void RTFDocVisitor::visitPre(DocHtmlDescTitle *) DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescTitle)}\n"); //m_t << "\\par" << endl; //m_t << "{\\b "; - m_t << "{" << rtf_Style["Heading5"]->reference << endl; + m_t << "{" << rtf_Style["Heading5"]->reference() << endl; m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlDescTitle *) +void RTFDocVisitor::visitPost(DocHtmlDescTitle *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescTitle)}\n"); @@ -976,7 +982,7 @@ void RTFDocVisitor::visitPre(DocHtmlDescData *) m_t << "{" << rtf_Style_Reset << getStyle("DescContinue"); } -void RTFDocVisitor::visitPost(DocHtmlDescData *) +void RTFDocVisitor::visitPost(DocHtmlDescData *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescData)}\n"); @@ -994,7 +1000,7 @@ void RTFDocVisitor::visitPre(DocHtmlTable *) m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPost(DocHtmlTable *) +void RTFDocVisitor::visitPost(DocHtmlTable *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlTable)}\n"); @@ -1010,7 +1016,7 @@ void RTFDocVisitor::visitPre(DocHtmlCaption *) m_t << "{Table \\field\\flddirty{\\*\\fldinst { SEQ Table \\\\*Arabic }}{\\fldrslt {\\noproof 1}} "; } -void RTFDocVisitor::visitPost(DocHtmlCaption *) +void RTFDocVisitor::visitPost(DocHtmlCaption *) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCaption)}\n"); m_t << "}\n\\par" << endl; @@ -1045,7 +1051,7 @@ void RTFDocVisitor::visitPre(DocHtmlRow *r) m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlRow *) +void RTFDocVisitor::visitPost(DocHtmlRow *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlRow)}\n"); @@ -1063,7 +1069,7 @@ void RTFDocVisitor::visitPre(DocHtmlCell *c) m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlCell *) +void RTFDocVisitor::visitPost(DocHtmlCell *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCell)}\n"); @@ -1085,7 +1091,7 @@ void RTFDocVisitor::visitPre(DocInternal *) //m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocInternal *) +void RTFDocVisitor::visitPost(DocInternal *) { if (m_hide) return; //DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternal)}\n"); @@ -1101,14 +1107,30 @@ void RTFDocVisitor::visitPre(DocHRef *href) DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHRef)}\n"); if (Config_getBool(RTF_HYPERLINKS)) { - m_t << "{\\field " - "{\\*\\fldinst " - "{ HYPERLINK \"" << href->url() << "\" " - "}{}" - "}" - "{\\fldrslt " - "{\\cs37\\ul\\cf2 "; - + if (href->url().startsWith("#CITEREF")) + { + // when starting with #CITEREF it is a doxygen generated "url"a + // so a local link + QCString cite; + cite = "citelist_" + href->url().right(href->url().length()-1); + m_t << "{\\field " + "{\\*\\fldinst " + "{ HYPERLINK \\\\l \"" << rtfFormatBmkStr(cite) << "\" " + "}{}" + "}" + "{\\fldrslt " + "{\\cs37\\ul\\cf2 "; + } + else + { + m_t << "{\\field " + "{\\*\\fldinst " + "{ HYPERLINK \"" << href->url() << "\" " + "}{}" + "}" + "{\\fldrslt " + "{\\cs37\\ul\\cf2 "; + } } else { @@ -1117,12 +1139,12 @@ void RTFDocVisitor::visitPre(DocHRef *href) m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHRef *) +void RTFDocVisitor::visitPost(DocHRef *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHRef)}\n"); if (Config_getBool(RTF_HYPERLINKS)) - { + { m_t << "}" "}" "}"; @@ -1144,13 +1166,13 @@ void RTFDocVisitor::visitPre(DocHtmlHeader *header) int level = QMIN(header->level(),5); heading.sprintf("Heading%d",level); // set style - m_t << rtf_Style[heading]->reference; + m_t << rtf_Style[heading]->reference(); // make open table of contents entry that will be closed in visitPost method m_t << "{\\tc\\tcl" << level << " "; m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocHtmlHeader *) +void RTFDocVisitor::visitPost(DocHtmlHeader *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n"); @@ -1242,7 +1264,7 @@ void RTFDocVisitor::visitPre(DocDotFile *df) writeDotFile(df); } -void RTFDocVisitor::visitPost(DocDotFile *df) +void RTFDocVisitor::visitPost(DocDotFile *df) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDotFile)}\n"); includePicturePostRTF(true, df->hasCaption()); @@ -1253,7 +1275,7 @@ void RTFDocVisitor::visitPre(DocMscFile *df) writeMscFile(df); } -void RTFDocVisitor::visitPost(DocMscFile *df) +void RTFDocVisitor::visitPost(DocMscFile *df) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocMscFile)}\n"); includePicturePostRTF(true, df->hasCaption()); @@ -1278,7 +1300,7 @@ void RTFDocVisitor::visitPre(DocLink *lnk) startLink(lnk->ref(),lnk->file(),lnk->anchor()); } -void RTFDocVisitor::visitPost(DocLink *lnk) +void RTFDocVisitor::visitPost(DocLink *lnk) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLink)}\n"); @@ -1302,7 +1324,7 @@ void RTFDocVisitor::visitPre(DocRef *ref) if (!ref->hasLinkText()) filter(ref->targetTitle()); } -void RTFDocVisitor::visitPost(DocRef *ref) +void RTFDocVisitor::visitPost(DocRef *ref) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRef)}\n"); @@ -1316,7 +1338,7 @@ void RTFDocVisitor::visitPre(DocSecRefItem *) DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefItem)}\n"); } -void RTFDocVisitor::visitPost(DocSecRefItem *) +void RTFDocVisitor::visitPost(DocSecRefItem *) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefItem)}\n"); } @@ -1332,7 +1354,7 @@ void RTFDocVisitor::visitPre(DocSecRefList *) m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPost(DocSecRefList *) +void RTFDocVisitor::visitPost(DocSecRefList *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefList)}\n"); @@ -1353,7 +1375,7 @@ void RTFDocVisitor::visitPost(DocSecRefList *) // } //} // -//void RTFDocVisitor::visitPost(DocLanguage *l) +//void RTFDocVisitor::visitPost(DocLanguage *l) //{ // DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLanguage)}\n"); // QCString langId = Config_getEnum(OUTPUT_LANGUAGE); @@ -1370,16 +1392,16 @@ void RTFDocVisitor::visitPre(DocParamSect *s) m_t << "{"; // start param list if (!m_lastIsPara) m_t << "\\par" << endl; //m_t << "{\\b "; // start bold - m_t << "{" << rtf_Style["Heading5"]->reference << endl; + m_t << "{" << rtf_Style["Heading5"]->reference() << endl; switch(s->type()) { - case DocParamSect::Param: + case DocParamSect::Param: m_t << theTranslator->trParameters(); break; - case DocParamSect::RetVal: + case DocParamSect::RetVal: m_t << theTranslator->trReturnValues(); break; - case DocParamSect::Exception: + case DocParamSect::Exception: m_t << theTranslator->trExceptions(); break; - case DocParamSect::TemplateParam: + case DocParamSect::TemplateParam: m_t << theTranslator->trTemplateParameters(); break; default: ASSERT(0); @@ -1416,7 +1438,7 @@ void RTFDocVisitor::visitPost(DocParamSect *s) void RTFDocVisitor::visitPre(DocParamList *pl) { - static int columnPos[4][5] = + static int columnPos[4][5] = { { 2, 25, 100, 100, 100 }, // no inout, no type { 3, 14, 35, 100, 100 }, // inout, no type { 3, 25, 50, 100, 100 }, // no inout, type @@ -1503,11 +1525,11 @@ void RTFDocVisitor::visitPre(DocParamList *pl) { if (type->kind()==DocNode::Kind_Word) { - visit((DocWord*)type); + visit((DocWord*)type); } else if (type->kind()==DocNode::Kind_LinkedWord) { - visit((DocLinkedWord*)type); + visit((DocLinkedWord*)type); } else if (type->kind()==DocNode::Kind_Sep) { @@ -1519,7 +1541,7 @@ void RTFDocVisitor::visitPre(DocParamList *pl) m_t << "\\cell }"; } } - + if (useTable) { @@ -1537,11 +1559,11 @@ void RTFDocVisitor::visitPre(DocParamList *pl) if (!first) m_t << ","; else first=FALSE; if (param->kind()==DocNode::Kind_Word) { - visit((DocWord*)param); + visit((DocWord*)param); } else if (param->kind()==DocNode::Kind_LinkedWord) { - visit((DocLinkedWord*)param); + visit((DocLinkedWord*)param); } } m_t << "} "; @@ -1596,7 +1618,7 @@ void RTFDocVisitor::visitPre(DocXRefItem *x) } m_t << "{"; // start param list //m_t << "{\\b "; // start bold - m_t << "{" << rtf_Style["Heading5"]->reference << endl; + m_t << "{" << rtf_Style["Heading5"]->reference() << endl; if (Config_getBool(RTF_HYPERLINKS) && !anonymousEnum) { QCString refName; @@ -1615,7 +1637,7 @@ void RTFDocVisitor::visitPre(DocXRefItem *x) m_t << "{\\field " "{\\*\\fldinst " - "{ HYPERLINK \\\\l \"" << refName << "\" " + "{ HYPERLINK \\\\l \"" << rtfFormatBmkStr(refName) << "\" " "}{}" "}" "{\\fldrslt " @@ -1655,7 +1677,7 @@ void RTFDocVisitor::visitPre(DocInternalRef *ref) startLink("",ref->file(),ref->anchor()); } -void RTFDocVisitor::visitPost(DocInternalRef *) +void RTFDocVisitor::visitPost(DocInternalRef *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternalRef)}\n"); @@ -1682,7 +1704,7 @@ void RTFDocVisitor::visitPre(DocHtmlBlockQuote *) if (!m_lastIsPara) m_t << "\\par" << endl; m_t << "{"; // start desc incIndentLevel(); - m_t << rtf_Style_Reset << getStyle("DescContinue"); + m_t << rtf_Style_Reset << getStyle("DescContinue"); } void RTFDocVisitor::visitPost(DocHtmlBlockQuote *) @@ -1724,7 +1746,7 @@ void RTFDocVisitor::visitPost(DocParBlock *) //} void RTFDocVisitor::filter(const char *str,bool verbatim) -{ +{ if (str) { const unsigned char *p=(const unsigned char *)str; @@ -1755,7 +1777,7 @@ void RTFDocVisitor::filter(const char *str,bool verbatim) case '\\': m_t << "\\\\"; break; case '\n': if (verbatim) { - m_t << "\\par" << endl; + m_t << "\\par" << endl; } else { @@ -1836,7 +1858,7 @@ void RTFDocVisitor::writeDotFile(const QCString &filename, bool hasCaption) if ((i=baseName.findRev('/'))!=-1) { baseName=baseName.right(baseName.length()-i-1); - } + } QCString outDir = Config_getString(RTF_OUTPUT); writeDotGraphFromFile(filename,outDir,baseName,GOF_BITMAP); QCString imgExt = getDotImageExtension(); @@ -1854,7 +1876,7 @@ void RTFDocVisitor::writeMscFile(const QCString &fileName, bool hasCaption) if ((i=baseName.findRev('/'))!=-1) { baseName=baseName.right(baseName.length()-i-1); - } + } QCString outDir = Config_getString(RTF_OUTPUT); writeMscGraphFromFile(fileName,outDir,baseName,MSC_BITMAP); includePicturePreRTF(baseName + ".png", true, hasCaption); diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 79411c6..ecf2d32 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Parker Waechter & Dimitri van Heesch. * @@ -61,7 +61,7 @@ static QCString dateToRTFDateString() d.date().year(), d.date().month(), d.date().day(), d.time().hour(),d.time().minute(),d.time().second()); return result; -} +} RTFGenerator::RTFGenerator() : OutputGenerator() { @@ -79,10 +79,20 @@ RTFGenerator::~RTFGenerator() { } +void RTFGenerator::setRelativePath(const QCString &path) +{ + m_relPath = path; +} + +void RTFGenerator::setSourceFileName(const QCString &name) +{ + m_sourceFileName = name; +} + void RTFGenerator::writeStyleSheetFile(QFile &file) { FTextStream t(&file); - t << "# Generated by doxygen " << getVersion() << "\n\n"; + t << "# Generated by doxygen " << getDoxygenVersion() << "\n\n"; t << "# This file describes styles used for generating RTF output.\n"; t << "# All text after a hash (#) is considered a comment and will be ignored.\n"; t << "# Remove a hash to activate a line.\n\n"; @@ -99,7 +109,7 @@ void RTFGenerator::writeStyleSheetFile(QFile &file) void RTFGenerator::writeExtensionsFile(QFile &file) { FTextStream t(&file); - t << "# Generated by doxygen " << getVersion() << "\n\n"; + t << "# Generated by doxygen " << getDoxygenVersion() << "\n\n"; t << "# This file describes extensions used for generating RTF output.\n"; t << "# All text after a hash (#) is considered a comment and will be ignored.\n"; t << "# Remove a hash to activate a line.\n\n"; @@ -164,9 +174,14 @@ void RTFGenerator::init() while(def->reference != 0) { if (def->definition == 0) + { err("Internal: rtf_Style_Default[%s] has no definition.\n", def->name); - StyleData* styleData = new StyleData(def->reference, def->definition); - rtf_Style.insert(def->name, styleData); + } + else + { + StyleData* styleData = new StyleData(def->reference, def->definition); + rtf_Style.insert(def->name, styleData); + } def++; } @@ -273,21 +288,20 @@ void RTFGenerator::beginRTFDocument() // sort styles ascending by \s-number via an intermediate QArray QDictIterator<StyleData> iter(rtf_Style); - const StyleData* style; + const StyleData* style = 0; unsigned maxIndex = 0; for(; (style = iter.current()); ++iter) { - unsigned index = style->index; + uint index = style->index(); if (maxIndex < index) maxIndex = index; } - QArray<const StyleData*> array(maxIndex + 1); - array.fill(0); + std::vector<const StyleData*> array(maxIndex + 1, 0); ASSERT(maxIndex < array.size()); iter.toFirst(); for(; (style = iter.current()); ++iter) { - unsigned index = style->index; + uint index = style->index(); if (array.at(index) != 0) { QCString key(iter.currentKey()); @@ -297,12 +311,14 @@ void RTFGenerator::beginRTFDocument() } // write array elements - unsigned size = array.size(); - for(unsigned i = 0; i < size; i++) + size_t size = array.size(); + for(size_t i = 0; i < size; i++) { - const StyleData* style = array.at(i); + style = array.at(i); if (style != 0) - t <<"{" << style->reference << style->definition << ";}\n"; + { + t <<"{" << style->reference() << style->definition() << ";}\n"; + } } t <<"}" << endl; @@ -328,7 +344,7 @@ void RTFGenerator::beginRTFChapter() t <<"\\sect\\sbkpage\n"; //t <<"\\sect\\sectd\\sbkpage\n"; - t << rtf_Style["Heading1"]->reference << "\n"; + t << rtf_Style["Heading1"]->reference() << "\n"; } void RTFGenerator::beginRTFSection() @@ -340,15 +356,15 @@ void RTFGenerator::beginRTFSection() // if we are compact, no extra page breaks... if (Config_getBool(COMPACT_RTF)) { - // t <<"\\sect\\sectd\\sbknone\n"; t <<"\\sect\\sbknone\n"; rtfwriteRuler_emboss(); } else + { t <<"\\sect\\sbkpage\n"; - //t <<"\\sect\\sectd\\sbkpage\n"; + } - t << rtf_Style["Heading2"]->reference << "\n"; + t << rtf_Style["Heading2"]->reference() << "\n"; } void RTFGenerator::startFile(const char *name,const char *,const char *) @@ -359,6 +375,8 @@ void RTFGenerator::startFile(const char *name,const char *,const char *) if (fileName.right(4)!=".rtf" ) fileName+=".rtf"; startPlainFile(fileName); + setRelativePath(m_relPath); + setSourceFileName(stripPath(fileName)); beginRTFDocument(); } @@ -368,6 +386,7 @@ void RTFGenerator::endFile() t << "}"; endPlainFile(); + setSourceFileName(""); } void RTFGenerator::startProjectNumber() @@ -500,7 +519,7 @@ void RTFGenerator::startIndexSection(IndexSections is) bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject() && + if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isEmbeddedInOuterScope() ) @@ -515,13 +534,9 @@ void RTFGenerator::startIndexSection(IndexSections is) { //File Documentation bool isFirst=TRUE; - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isLinkableInProject()) { @@ -561,7 +576,7 @@ void RTFGenerator::startIndexSection(IndexSections is) void RTFGenerator::endIndexSection(IndexSections is) { bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static QCString projectName = Config_getString(PROJECT_NAME); @@ -576,18 +591,18 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isTitlePageAuthor: { - t << " doxygen.}\n"; + t << " doxygen" << getDoxygenVersion() << ".}\n"; t << "{\\creatim " << dateToRTFDateString() << "}\n}"; DBG_RTF(t << "{\\comment end of infoblock}\n"); // setup for this section t << rtf_Style_Reset <<"\n"; t <<"\\sectd\\pgnlcrm\n"; - t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n"; + t <<"{\\footer "<<rtf_Style["Footer"]->reference() << "{\\chpgn}}\n"; // the title entry DBG_RTF(t << "{\\comment begin title page}\n") - t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style + t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference() << endl; // set to title style t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n"; if (rtf_logoFilename) @@ -600,7 +615,7 @@ void RTFGenerator::endIndexSection(IndexSections is) t << rtf_company << "\\par\\par\n"; } - t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style + t << rtf_Style_Reset << rtf_Style["Title"]->reference() << endl; // set to title style if (rtf_title) // User has overridden document title in extensions file t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par" << endl; @@ -610,10 +625,10 @@ void RTFGenerator::endIndexSection(IndexSections is) t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt "; writeDoc(root,0,0); t << "}}\\par" << endl; - + } - t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style + t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference() << endl; // set to title style t << "\\par\n"; if (rtf_documentType) { @@ -625,7 +640,7 @@ void RTFGenerator::endIndexSection(IndexSections is) } t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n"; - t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style + t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference() << endl; // set to subtitle style if (rtf_author) t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt "<< rtf_author << " }}\\par" << endl; else @@ -641,7 +656,7 @@ void RTFGenerator::endIndexSection(IndexSections is) DBG_RTF(t << "{\\comment Table of contents}\n") t << "\\vertalt\n"; t << rtf_Style_Reset << endl; - t << rtf_Style["Heading1"]->reference; + t << rtf_Style["Heading1"]->reference(); t << theTranslator->trRTFTableOfContents() << "\\par"<< endl; t << rtf_Style_Reset << "\\par" << endl; t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n"; @@ -688,7 +703,7 @@ void RTFGenerator::endIndexSection(IndexSections is) { t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}" << endl; } - + t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; break; case isClassHierarchyIndex: @@ -801,7 +816,7 @@ void RTFGenerator::endIndexSection(IndexSections is) } for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject() && + if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isEmbeddedInOuterScope() ) @@ -815,7 +830,7 @@ void RTFGenerator::endIndexSection(IndexSections is) } for (;(cd=cli.current());++cli) { - if (cd->isLinkableInProject() && + if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isEmbeddedInOuterScope() ) @@ -834,13 +849,9 @@ void RTFGenerator::endIndexSection(IndexSections is) bool isFirst=TRUE; t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl; - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (fnli.toFirst();(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (fd->isLinkableInProject()) { @@ -927,7 +938,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isEndIndex: beginRTFChapter(); - t << rtf_Style["Heading1"]->reference; + t << rtf_Style["Heading1"]->reference(); t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl; t << rtf_Style_Reset << endl; t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl; @@ -953,8 +964,7 @@ void RTFGenerator::lastIndexPage() t <<"\\sect \\sectd \\sbknone\n"; // set new footer with arabic numbers - t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n"; - //t << rtf_Style["Heading1"]->reference << "\n"; + t <<"{\\footer "<< rtf_Style["Footer"]->reference() << "{\\chpgn}}\n"; } @@ -1212,7 +1222,7 @@ void RTFGenerator::startSubsection() t <<"\n"; DBG_RTF(t << "{\\comment Begin SubSection}\n") t << rtf_Style_Reset; - t << rtf_Style["Heading3"]->reference << "\n"; + t << rtf_Style["Heading3"]->reference() << "\n"; } void RTFGenerator::endSubsection() @@ -1227,7 +1237,7 @@ void RTFGenerator::startSubsubsection() t << "\n"; DBG_RTF(t << "{\\comment Begin SubSubSection}\n") t << "{" << endl; - t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n"; + t << rtf_Style_Reset << rtf_Style["Heading4"]->reference() << "\n"; } void RTFGenerator::endSubsubsection() @@ -1245,22 +1255,22 @@ void RTFGenerator::endSubsubsection() // t << "}"; //} -//void RTFGenerator::startTable(bool,int colNumbers) +//void RTFGenerator::startTable(bool,int colNumbers) //{ // DBG_RTF(t << "{\\comment startTable}\n";) // m_numCols=colNumbers; // t << "\\par\n"; //} // -//void RTFGenerator::endTable(bool hasCaption) -//{ +//void RTFGenerator::endTable(bool hasCaption) +//{ // DBG_RTF(t << "{\\comment endTable}\n";) -// if (!hasCaption) -// t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n"; -// t << "\\pard\n" << endl; +// if (!hasCaption) +// t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n"; +// t << "\\pard\n" << endl; //} // -//void RTFGenerator::startCaption() +//void RTFGenerator::startCaption() //{ // DBG_RTF(t << "{\\comment startCaption}\n";) // endTableRow(); @@ -1269,15 +1279,15 @@ void RTFGenerator::endSubsubsection() // nextTableColumn(); //} // -//void RTFGenerator::endCaption() +//void RTFGenerator::endCaption() //{ // DBG_RTF(t << "{\\comment endCaption}\n";) // endTableColumn(); // endTableRow(); //} // -//void RTFGenerator::nextTableRow() -//{ +//void RTFGenerator::nextTableRow() +//{ // DBG_RTF(t << "{\\comment nextTableRow}\n";) // ASSERT(m_numCols>0 && m_numCols<25); // uint columnWidth=rtf_pageWidth/m_numCols; @@ -1285,7 +1295,7 @@ void RTFGenerator::endSubsubsection() // "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 " // "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 " // "\\trbrdrv\\brdrs\\brdrw10 "<<endl; -// for (int i=0;i<m_numCols;i++) +// for (int i=0;i<m_numCols;i++) // { // t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 " // "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb " @@ -1293,21 +1303,21 @@ void RTFGenerator::endSubsubsection() // } // t << "\\pard \\widctlpar\\intbl\\adjustright\n{"; //} -// -//void RTFGenerator::endTableRow() -//{ +// +//void RTFGenerator::endTableRow() +//{ // DBG_RTF(t << "{\\comment endTableRow}\n";) // t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n"; //} -// -//void RTFGenerator::nextTableColumn() +// +//void RTFGenerator::nextTableColumn() //{ // DBG_RTF(t << "{\\comment nextTableColumn}\n";) // t << "{ "; //} // -//void RTFGenerator::endTableColumn() -//{ +//void RTFGenerator::endTableColumn() +//{ // DBG_RTF(t << "{\\comment endTableColumn}\n";) // t << " \\cell }"; //} @@ -1435,7 +1445,7 @@ void RTFGenerator::startTitleHead(const char *) DBG_RTF(t <<"{\\comment startTitleHead}" << endl) // beginRTFSection(); - t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl; + t << rtf_Style_Reset << rtf_Style["Heading2"]->reference() << endl; } void RTFGenerator::endTitleHead(const char *fileName,const char *name) @@ -1480,15 +1490,15 @@ void RTFGenerator::startGroupHeader(int extraIndent) t << rtf_Style_Reset; if (extraIndent==2) { - t << rtf_Style["Heading5"]->reference; + t << rtf_Style["Heading5"]->reference(); } else if (extraIndent==1) { - t << rtf_Style["Heading4"]->reference; + t << rtf_Style["Heading4"]->reference(); } else // extraIndent==0 { - t << rtf_Style["Heading3"]->reference; + t << rtf_Style["Heading3"]->reference(); } t << endl; } @@ -1514,10 +1524,10 @@ void RTFGenerator::startMemberDoc(const char *clname, addIndexItem(memname,clname); addIndexItem(clname,memname); } - t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference; + t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference(); //styleStack.push(rtf_Style_Heading4); t << "{" << endl; - //printf("RTFGenerator::startMemberDoc() '%s'\n",rtf_Style["Heading4"]->reference); + //printf("RTFGenerator::startMemberDoc() '%s'\n",rtf_Style["Heading4"]->reference()); startBold(); t << endl; } @@ -1527,7 +1537,7 @@ void RTFGenerator::endMemberDoc(bool) DBG_RTF(t << "{\\comment endMemberDoc}" << endl) //const char *style = styleStack.pop(); //printf("RTFGenerator::endMemberDoc() '%s'\n",style); - //ASSERT(style==rtf_Style["Heading4"]->reference); + //ASSERT(style==rtf_Style["Heading4"]->reference()); endBold(); t << "}" << endl; newParagraph(); @@ -1686,7 +1696,7 @@ void RTFGenerator::endDescForItem() //} -void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type) +void RTFGenerator::startSection(const char *,const char *title,SectionType type) { DBG_RTF(t << "{\\comment (startSection)}" << endl) t << "{"; @@ -1694,24 +1704,24 @@ void RTFGenerator::startSection(const char *,const char *title,SectionInfo::Sect int num=4; switch(type) { - case SectionInfo::Page: num=2; break; - case SectionInfo::Section: num=3; break; - case SectionInfo::Subsection: num=4; break; - case SectionInfo::Subsubsection: num=4; break; - case SectionInfo::Paragraph: num=4; break; + case SectionType::Page: num=2; break; + case SectionType::Section: num=3; break; + case SectionType::Subsection: num=4; break; + case SectionType::Subsubsection: num=4; break; + case SectionType::Paragraph: num=4; break; default: ASSERT(0); break; } QCString heading; heading.sprintf("Heading%d",num); // set style - t << rtf_Style[heading]->reference; + t << rtf_Style[heading]->reference(); // make table of contents entry t << "{\\tc\\tcl" << num << " \\v "; docify(title); t << "}" << endl; } -void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType) +void RTFGenerator::endSection(const char *lab,SectionType) { DBG_RTF(t << "{\\comment (endSection)}" << endl) // make bookmark @@ -2012,7 +2022,7 @@ void RTFGenerator::startDescTable(const char *title) { DBG_RTF(t << "{\\comment (startDescTable) }" << endl) t << "{\\par" << endl; - t << "{" << rtf_Style["Heading5"]->reference << endl; + t << "{" << rtf_Style["Heading5"]->reference() << endl; docify(title); t << ":\\par}" << endl; t << rtf_Style_Reset << rtf_DList_DepthStyle(); @@ -2100,40 +2110,40 @@ void RTFGenerator::decrementIndentLevel() const char * RTFGenerator::rtf_CList_DepthStyle() { QCString n=makeIndexName("ListContinue",m_listLevel); - return rtf_Style[n]->reference; + return rtf_Style[n]->reference(); } // a style for list formatted as a "latext style" table of contents const char * RTFGenerator::rtf_LCList_DepthStyle() { QCString n=makeIndexName("LatexTOC",m_listLevel); - return rtf_Style[n]->reference; + return rtf_Style[n]->reference(); } // a style for list formatted as a "bullet" style const char * RTFGenerator::rtf_BList_DepthStyle() { QCString n=makeIndexName("ListBullet",m_listLevel); - return rtf_Style[n]->reference; + return rtf_Style[n]->reference(); } // a style for list formatted as a "enumeration" style const char * RTFGenerator::rtf_EList_DepthStyle() { QCString n=makeIndexName("ListEnum",m_listLevel); - return rtf_Style[n]->reference; + return rtf_Style[n]->reference(); } const char * RTFGenerator::rtf_DList_DepthStyle() { QCString n=makeIndexName("DescContinue",m_listLevel); - return rtf_Style[n]->reference; + return rtf_Style[n]->reference(); } const char * RTFGenerator::rtf_Code_DepthStyle() { QCString n=makeIndexName("CodeExample",m_listLevel); - return rtf_Style[n]->reference; + return rtf_Style[n]->reference(); } void RTFGenerator::startTextBlock(bool dense) @@ -2143,11 +2153,11 @@ void RTFGenerator::startTextBlock(bool dense) t << rtf_Style_Reset; if (dense) // no spacing between "paragraphs" { - t << rtf_Style["DenseText"]->reference; + t << rtf_Style["DenseText"]->reference(); } else // some spacing { - t << rtf_Style["BodyText"]->reference; + t << rtf_Style["BodyText"]->reference(); } } @@ -2463,7 +2473,7 @@ static bool preProcessFile(QDir &d,QCString &infName, FTextStream &t, bool bIncl { // null terminate at the last '}' //char *str = strrchr(buffer,'}'); - int pos = lineBuf.findRev('}'); + pos = lineBuf.findRev('}'); if (pos != -1) lineBuf.at(pos) = '\0'; @@ -2681,7 +2691,7 @@ void RTFGenerator::startMemberGroupHeader(bool hasHeader) DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl) t << "{" << endl; if (hasHeader) incrementIndentLevel(); - t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference; + t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference(); } void RTFGenerator::endMemberGroupHeader() @@ -2795,32 +2805,32 @@ void RTFGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString("")); n->accept(visitor); - delete visitor; + delete visitor; m_omitParagraph = TRUE; } -void RTFGenerator::rtfwriteRuler_doubleline() -{ +void RTFGenerator::rtfwriteRuler_doubleline() +{ DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}" << endl) - t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl; + t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl; } -void RTFGenerator::rtfwriteRuler_emboss() -{ +void RTFGenerator::rtfwriteRuler_emboss() +{ DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}" << endl) - t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl; + t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl; } -void RTFGenerator::rtfwriteRuler_thick() -{ +void RTFGenerator::rtfwriteRuler_thick() +{ DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}" << endl) - t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl; + t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl; } -void RTFGenerator::rtfwriteRuler_thin() -{ +void RTFGenerator::rtfwriteRuler_thin() +{ DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}" << endl) - t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl; + t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl; } #if 0 @@ -2833,9 +2843,9 @@ void RTFGenerator::postProcess(QByteArray &a) for (i=0;i<a.size();i++) { unsigned char c = (unsigned char)a.at(i); - + // treat characters > 0x80 as multibyte characters, except when they - // are control characters + // are control characters if (c>0x80 || (mbFlag && c!='\\' && c!='{' && c!='}')) { char s[10]; @@ -2858,7 +2868,7 @@ void RTFGenerator::startConstraintList(const char *header) { DBG_RTF(t << "{\\comment (startConstraintList)}" << endl) t << "{"; // ends at endConstraintList - t << "{"; + t << "{"; startBold(); newParagraph(); docify(header); @@ -2926,15 +2936,15 @@ void RTFGenerator::endIndexListItem() t << "\\par" << endl; } -void RTFGenerator::startInlineHeader() +void RTFGenerator::startInlineHeader() { DBG_RTF(t << "{\\comment (startInlineHeader)}" << endl) t << "{" << endl; - t << rtf_Style_Reset << rtf_Style["Heading5"]->reference; + t << rtf_Style_Reset << rtf_Style["Heading5"]->reference(); startBold(); } -void RTFGenerator::endInlineHeader() +void RTFGenerator::endInlineHeader() { DBG_RTF(t << "{\\comment (endInlineHeader)}" << endl) endBold(); @@ -2946,7 +2956,7 @@ void RTFGenerator::startMemberDocSimple(bool isEnum) { DBG_RTF(t << "{\\comment (startMemberDocSimple)}" << endl) t << "{\\par" << endl; - t << "{" << rtf_Style["Heading5"]->reference << endl; + t << "{" << rtf_Style["Heading5"]->reference() << endl; if (isEnum) { t << theTranslator->trEnumerationValues(); @@ -3025,12 +3035,33 @@ void RTFGenerator::endInlineMemberDoc() t << "\\cell }{\\row }" << endl; } -void RTFGenerator::writeLineNumber(const char *,const char *,const char *,int l) +void RTFGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l) { + static bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS); + DoxyCodeLineOpen = TRUE; QCString lineNumber; lineNumber.sprintf("%05d",l); - t << lineNumber << " "; + if (m_prettyCode) + { + if (fileName && !m_sourceFileName.isEmpty() && rtfHyperlinks) + { + QCString lineAnchor; + lineAnchor.sprintf("_l%05d",l); + lineAnchor.prepend(stripExtensionGeneral(m_sourceFileName, ".rtf")); + t << "{\\bkmkstart "; + t << rtfFormatBmkStr(lineAnchor); + t << "}"; + t << "{\\bkmkend "; + t << rtfFormatBmkStr(lineAnchor); + t << "}" << endl; + } + t << lineNumber << " "; + } + else + { + t << l << " "; + } m_col=0; } void RTFGenerator::startCodeLine(bool) diff --git a/src/rtfgen.h b/src/rtfgen.h index c6cb76b..9330b13 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -32,6 +32,8 @@ class RTFGenerator : public OutputGenerator static void writeStyleSheetFile(QFile &f); static void writeExtensionsFile(QFile &file); + void setRelativePath(const QCString &path); + void setSourceFileName(const QCString &sourceFileName); void enable() { if (m_genStack->top()) m_active=*m_genStack->top(); else m_active=TRUE; } void disable() { m_active=FALSE; } @@ -171,8 +173,8 @@ class RTFGenerator : public OutputGenerator //void writeDescItem(); void startDescForItem(); void endDescForItem(); - void startSection(const char *,const char *,SectionInfo::SectionType); - void endSection(const char *,SectionInfo::SectionType); + void startSection(const char *,const char *,SectionType); + void endSection(const char *,SectionType); void addIndexItem(const char *,const char *); void startIndent(); void endIndent(); @@ -279,6 +281,7 @@ class RTFGenerator : public OutputGenerator const char *rtf_Code_DepthStyle(); void incrementIndentLevel(); void decrementIndentLevel(); + QCString m_sourceFileName; int m_col; bool m_prettyCode; diff --git a/src/rtfstyle.cpp b/src/rtfstyle.cpp index 47a8166..98581bb 100644 --- a/src/rtfstyle.cpp +++ b/src/rtfstyle.cpp @@ -1,13 +1,13 @@ /****************************************************************************** * - * + * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -224,27 +224,22 @@ Rtf_Style_Default rtf_Style_Default[] = } }; -const QRegExp StyleData::s_clause("\\\\s[0-9]+\\s*"); +static const QRegExp s_clause("\\\\s[0-9]+\\s*"); StyleData::StyleData(const char* reference, const char* definition) { - int start = s_clause.match(reference); ASSERT(start >= 0); - reference += start; - index = (int)atol(reference + 2); ASSERT(index > 0); + const char *ref = reference; - ASSERT(reference != 0); - size_t size = 1 + strlen(reference); - memcpy(this->reference = new char[size], reference, size); + int start = s_clause.match(ref); ASSERT(start >= 0); + ref += start; + m_index = (int)atol(ref + 2); ASSERT(m_index > 0); - ASSERT(definition != 0); - size = 1 + strlen(definition); - memcpy(this->definition = new char[size], definition, size); + m_reference = ref; + m_definition = definition; } StyleData::~StyleData() { - delete[] reference; - delete[] definition; } bool StyleData::setStyle(const char* s, const char* styleName) @@ -261,7 +256,7 @@ bool StyleData::setStyle(const char* s, const char* styleName) return FALSE; } s += start; - index = (int)atol(s + 2); ASSERT(index > 0); + m_index = (int)atol(s + 2); ASSERT(m_index > 0); // search for the end of pure formatting codes const char* end = s + len; @@ -299,16 +294,10 @@ bool StyleData::setStyle(const char* s, const char* styleName) else // plain name without leading \\snext break; } - delete[] reference; - reference = new char[ref_len + 1]; - memcpy(reference, s, ref_len); - reference[ref_len] = 0; + m_reference = s; if (haveNewDefinition) { - delete[] definition; - size_t size = 1 + strlen(end); - definition = new char[size]; - memcpy(definition, end, size); + m_definition = end; } return TRUE; } diff --git a/src/rtfstyle.h b/src/rtfstyle.h index 1058351..d45972c 100644 --- a/src/rtfstyle.h +++ b/src/rtfstyle.h @@ -1,13 +1,10 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -63,15 +60,18 @@ struct StyleData // to define a tag in the header reference + definition is required // to use a tag in the body of the document only reference is required - unsigned index; // index in style-sheet, i.e. number in s-clause - char* reference; // everything required to apply the style - char* definition; // additional tags like \snext and style name - - StyleData(const char* reference, const char* definition); - ~StyleData(); - bool setStyle(const char* s, const char* styleName); - - static const QRegExp s_clause; + public: + StyleData(const char* reference, const char* definition); + ~StyleData(); + bool setStyle(const char* s, const char* styleName); + const char *reference() const { return m_reference.c_str(); } + const char *definition() const { return m_definition.c_str(); } + uint index() const { return m_index; } + + private: + uint m_index; // index in style-sheet, i.e. number in s-clause + std::string m_reference; // everything required to apply the style + std::string m_definition; // additional tags like \snext and style name }; extern QDict<StyleData> rtf_Style; diff --git a/src/scanner.l b/src/scanner.l index 7b24d39..25109bc 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -18,6 +18,9 @@ %option prefix="scannerYY" %option reentrant %option extra-type="struct scannerYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -48,17 +51,20 @@ #include "defargs.h" #include "language.h" #include "commentscan.h" -#include "code.h" #include "arguments.h" #include "clangparser.h" +#include "markdown.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + struct scannerYY_state { OutlineParserInterface *thisParser; + CommentScanner commentScanner; const char * inputString = 0; int inputPosition = 0; int lastContext = 0; @@ -186,12 +192,14 @@ struct scannerYY_state int column = 0; - int fencedSize = 0; + uint fencedSize = 0; bool nestedComment = false; std::vector< std::pair<Entry*,std::shared_ptr<Entry> > > outerScopeEntries; }; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif //----------------------------------------------------------------------------- // forward declarations for stateless functions @@ -214,7 +222,7 @@ static bool checkForKnRstyleC(yyscan_t yyscanner); static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName); static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name, const QCString &brief,const QCString &docs); -static int yyread(yyscan_t yyscanner,char *buf,int max_size); +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); /* ----------------------------------------------------------------- */ @@ -619,6 +627,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(yyscanner) ; yyextra->current->mtype = yyextra->mtype = Event; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->curlyCount=0; BEGIN( CliPropertyType ); } @@ -627,6 +636,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(yyscanner) ; yyextra->current->mtype = Event; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; } else { @@ -640,6 +650,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(yyscanner) ; yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->curlyCount=0; BEGIN( CliPropertyType ); } @@ -733,6 +744,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->section = Entry::FUNCTION_SEC; yyextra->current->protection = yyextra->protection = Public ; yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; @@ -869,6 +881,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { lineCount(yyscanner); yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->fileName = yyextra->yyFileName ; yyextra->current->startLine = yyextra->yyLineNr ; yyextra->current->startColumn = yyextra->yyColNr; @@ -885,6 +898,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { lineCount(yyscanner); yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->fileName = yyextra->yyFileName ; yyextra->current->startLine = yyextra->yyLineNr ; yyextra->current->startColumn = yyextra->yyColNr; @@ -998,6 +1012,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); } <PackageName>";" { @@ -1025,9 +1040,16 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->explicitExternal = TRUE; lineCount(yyscanner); } -<FindMembers>{B}*"const"{BN}+ { yyextra->current->type += " const "; - if (yyextra->insideCS) yyextra->current->stat = TRUE; - lineCount(yyscanner); +<FindMembers>{B}*"const"{BN}+ { if (yyextra->insideCS) + { + yyextra->current->type += " const "; + if (yyextra->insideCS) yyextra->current->stat = TRUE; + lineCount(yyscanner); + } + else + { + REJECT; + } } <FindMembers>{B}*"virtual"{BN}+ { yyextra->current->type += " virtual "; yyextra->current->virt = Virtual; @@ -1109,6 +1131,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); if (yyextra->insidePHP) { @@ -1130,6 +1153,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else if (yyextra->insideD) @@ -1154,6 +1178,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else @@ -1173,6 +1198,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else @@ -1195,6 +1221,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else // TODO is addType right? just copy/pasted @@ -1216,6 +1243,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else // TODO is addType right? just copy/pasted @@ -1239,6 +1267,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else @@ -1259,6 +1288,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } <FindMembers>{B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute @@ -1278,6 +1308,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } <FindMembers>{B}*"@protocol"{BN}+ { // Objective-C protocol definition @@ -1294,6 +1325,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } <FindMembers>{B}*"exception"{BN}+ { // Corba IDL/Slice exception @@ -1309,6 +1341,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); BEGIN( CompoundName ); } @@ -1344,6 +1377,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; if (yytext[0]=='@') { yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; @@ -1364,6 +1398,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1379,6 +1414,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1394,6 +1430,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1409,6 +1446,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; BEGIN( CompoundName ) ; } @@ -1426,7 +1464,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; - uint64 spec = yyextra->current->spec; yyextra->current->section = Entry::CLASS_SEC ; // preserve UNO IDL & Inline attributes, Slice local yyextra->current->spec = Entry::Struct | @@ -1449,6 +1486,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1464,6 +1502,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1479,6 +1518,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1494,6 +1534,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1522,6 +1563,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1550,6 +1592,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; @@ -1730,6 +1773,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->previous->args.resize(0); yyextra->previous->name=yyextra->previous->name.stripWhiteSpace(); yyextra->previous->bodyLine = yyextra->yyLineNr; + yyextra->previous->bodyColumn = yyextra->yyColNr; yyextra->previous->spec |= Entry::Alias; BEGIN(FindMembers); } @@ -1864,6 +1908,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->roundCount==0 && --yyextra->sharpCount<=0) { yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->args = "("; yyextra->currentArgumentContext = FuncQual; yyextra->fullArgString = yyextra->current->args.copy(); @@ -1903,6 +1948,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->insidePHP) { yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( DefinePHP ); } else @@ -2237,6 +2283,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->insidePHP) REJECT; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->lastDefineContext = YY_START; BEGIN( Define ); } @@ -2289,6 +2336,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace(); yyextra->current->args = "("; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = DefineEnd; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; @@ -2311,6 +2359,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->name = yytext; BEGIN(DefineEnd); } @@ -2367,6 +2416,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace(); yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1); yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->lastRoundContext = DefinePHPEnd; yyextra->pCopyRoundGString = &yyextra->current->initializer; yyextra->roundCount = 0; @@ -2392,6 +2442,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->current->bodyLine==-1) { yyextra->current->bodyLine=yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; } yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; @@ -2455,6 +2506,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->current->bodyLine==-1) { yyextra->current->bodyLine=yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; } yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; @@ -2483,12 +2535,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->previous && yyextra->previous->section==Entry::GROUPDOC_SEC) { // link open command to the group defined in the yyextra->previous entry - Doxygen::docGroup.open(yyextra->previous.get(),yyextra->yyFileName,yyextra->yyLineNr); + yyextra->commentScanner.open(yyextra->previous.get(),yyextra->yyFileName,yyextra->yyLineNr); } else { // link open command to the yyextra->current entry - Doxygen::docGroup.open(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr); + yyextra->commentScanner.open(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr); } //yyextra->current = tmp; initEntry(yyscanner); @@ -2532,11 +2584,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers,FindFields,ReadInitializer>"//"([!/]){B}*{CMD}"}".*|"/*"([!*]){B}*{CMD}"}"[^*]*"*/" { bool insideEnum = YY_START==FindFields || (YY_START==ReadInitializer && yyextra->lastInitializerContext==FindFields); // see bug746226 - Doxygen::docGroup.close(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr,insideEnum); + yyextra->commentScanner.close(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr,insideEnum); lineCount(yyscanner); } <FindMembers>"=" { // in PHP code this could also be due to "<?=" yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->initializer = yytext; yyextra->lastInitializerContext = YY_START; yyextra->initBracketCount=0; @@ -3108,6 +3161,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->current->bodyLine==-1) { yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; } if ( yyextra->insidePHP && yyextra->current->type.left(3) == "var" ) { @@ -3420,6 +3474,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->name = yytext; } <FindFields>"(" { @@ -3614,10 +3669,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->name = yyextra->current->name.left(split_point); if (!yyextra->current_root->name.isEmpty()) yyextra->current->name.prepend(yyextra->current_root->name+"::"); - std::shared_ptr<Entry> tmp = yyextra->current; yyextra->current_root->moveToSubEntryAndKeep(yyextra->current); - yyextra->current_root = tmp; - + yyextra->current_root = yyextra->current; yyextra->current = new_current; } // restore documentation values @@ -3661,7 +3714,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { yyextra->memspecEntry = yyextra->current; - yyextra->current_root->copyToSubEntry( yyextra->current ) ; + yyextra->current_root->moveToSubEntryAndKeep( yyextra->current ) ; + yyextra->current = std::make_shared<Entry>(*yyextra->current); if (yyextra->current->section==Entry::NAMESPACE_SEC || (yyextra->current->spec==Entry::Interface) || yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideJS || @@ -3946,6 +4000,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); addType(yyscanner); yyextra->funcPtrType=yytext; @@ -4013,6 +4068,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //yyextra->roundCount=0; //BEGIN( FuncFunc ); yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = FuncFuncEnd; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; @@ -4077,12 +4133,14 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // the bodyLine check is to prevent this guard to be true more than once { yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( GetCallType ); } else if (!yyextra->current->name.isEmpty()) // normal function { yyextra->current->args = yytext; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = FuncQual; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; @@ -4103,6 +4161,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { yyextra->current->args = yytext; yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = FuncQual; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; @@ -4272,7 +4331,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) unput(yyextra->lastCopyArgChar); BEGIN( yyextra->lastCommentInArgContext ); } -<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) +<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) yyextra->docBlockName=&yytext[1]; yyextra->fullArgString+=yytext; BEGIN(CopyArgVerbatim); @@ -4290,7 +4349,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->fullArgString+=yytext; BEGIN(CopyArgVerbatim); } -<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9\-] { // end of verbatim block +<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9\-] { // end of verbatim block yyextra->fullArgString+=yytext; if (yytext[1]=='f') // end of formula { @@ -4743,23 +4802,25 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->startLine = yyextra->yyBegLineNr; yyextra->current->startColumn = yyextra->yyBegColNr; static QRegExp re("([^)]*[*&][^)]*)"); // (...*...) + int ts=yyextra->current->type.find('<'); + int te=yyextra->current->type.findRev('>'); + int ti=yyextra->current->type.find(re,0); + + // bug677315: A<int(void *, char *)> get(); is not a function pointer + bool isFunction = ti==-1 || // not a (...*...) pattern + (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list + bool isVariable = (!yyextra->current->type.isEmpty() && + (!isFunction || yyextra->current->type.left(8)=="typedef ")); + + //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n", + // yyextra->current->type.data(),ts,te,ti,isFunction); + if (*yytext!=';' || (yyextra->current_root->section&Entry::COMPOUND_MASK) ) { int tempArg=yyextra->current->name.find('<'); - int ts=yyextra->current->type.find('<'); - int te=yyextra->current->type.findRev('>'); - int ti=yyextra->current->type.find(re,0); - - // bug677315: A<int(void *, char *)> get(); is not a function pointer - bool isFunction = ti==-1 || // not a (...*...) pattern - (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list - - //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n", - // yyextra->current->type.data(),ts,te,ti,isFunction); QCString tempName; if (tempArg==-1) tempName=yyextra->current->name; else tempName=yyextra->current->name.left(tempArg); - if (!yyextra->current->type.isEmpty() && - (!isFunction || yyextra->current->type.left(8)=="typedef ")) + if (isVariable) { //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ") @@ -4768,7 +4829,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } yyextra->current->section = Entry::VARIABLE_SEC ; } - else + else { //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); yyextra->current->section = Entry::FUNCTION_SEC ; @@ -4778,8 +4839,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else // a global function prototype or function variable { //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); - if (!yyextra->current->type.isEmpty() && - (yyextra->current->type.find(re,0)!=-1 || yyextra->current->type.left(8)=="typedef ")) + if (isVariable) { if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ") { @@ -4912,7 +4972,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <SkipCurly>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { lineCount(yyscanner); - if ( yyextra->curlyCount ) + if ( yyextra->curlyCount ) { //addToBody(yytext); --yyextra->curlyCount ; @@ -4920,10 +4980,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { yyextra->current->endBodyLine=yyextra->yyLineNr; - // take yyextra->previous out of yyextra->current_root and move it into yyextra->current - yyextra->tempEntry = yyextra->current; // remember yyextra->current - yyextra->current_root->moveFromSubEntry(yyextra->previous.get(),yyextra->current); - yyextra->previous.reset(); + yyextra->tempEntry = yyextra->current; // temporarily switch to the previous entry + yyextra->current = yyextra->previous; yyextra->docBlockContext = SkipCurlyEndDoc; yyextra->docBlockInBody = FALSE; @@ -5576,8 +5634,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <CompoundName,ClassVar>{B}*"{"{B}* { yyextra->current->fileName = yyextra->yyFileName ; - yyextra->current->startLine = yyextra->yyLineNr ; - yyextra->current->startColumn = yyextra->yyColNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name); if (yyextra->current->name.isEmpty() && !yyextra->isTypedef) // anonymous compound { @@ -5827,8 +5885,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <Bases>{B}*"{"{B}* { yyextra->current->fileName = yyextra->yyFileName ; - yyextra->current->startLine = yyextra->yyLineNr ; - yyextra->current->startColumn = yyextra->yyColNr; + yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name); if (!yyextra->baseName.isEmpty()) yyextra->current->extends.push_back( @@ -6027,6 +6085,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->mtype = yyextra->mtype = Property; } yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->curlyCount=0; BEGIN( CSAccessorDecl ); } @@ -6070,6 +6129,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // C++11 style initializer list yyextra->current->bodyLine = yyextra->yyLineNr; + yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->initializer = yytext; yyextra->lastInitializerContext = YY_START; yyextra->initBracketCount=1; @@ -6252,7 +6312,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->nestedComment=FALSE; BEGIN(DocCopyBlock); } -<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) +<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) yyextra->docBlock+=yytext; yyextra->docBlockName=&yytext[1]; yyextra->fencedSize=0; @@ -6320,7 +6380,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->docBlock+=yytext; BEGIN(DocBlock); } -<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block +<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block yyextra->docBlock+=yytext; if (&yytext[4]==yyextra->docBlockName) { @@ -6586,10 +6646,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) %% //---------------------------------------------------------------------------- -static int yyread(yyscan_t yyscanner,char *buf,int max_size) +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int c=0; + yy_size_t c=0; while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) { *buf = yyextra->inputString[yyextra->inputPosition++] ; @@ -6639,7 +6699,7 @@ static void initEntry(yyscan_t yyscanner) yyextra->current->stat = yyextra->stat; yyextra->current->lang = yyextra->language; //printf("*** initEntry(yyscanner) yyextra->language=%d\n",yyextra->language); - Doxygen::docGroup.initGroupInfo(yyextra->current.get()); + yyextra->commentScanner.initGroupInfo(yyextra->current.get()); yyextra->isTypedef=FALSE; } @@ -6822,7 +6882,6 @@ static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &ol else // normal "int *var" { int l=si,i=l-1,j; - char c; // look for start of name in "type *name" while (i>=0 && isId(yyextra->current->args.at(i))) i--; j=i+1; @@ -6965,8 +7024,8 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief int position=0; bool needsEntry=FALSE; - QCString processedDoc = preprocessCommentBlock(stripIndentation(doc),yyextra->yyFileName,lineNr); - while (parseCommentBlock( + QCString processedDoc = processMarkdownForCommentBlock(stripIndentation(doc),yyextra->yyFileName,lineNr); + while (yyextra->commentScanner.parseCommentBlock( yyextra->thisParser, yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(), processedDoc, // text @@ -7025,7 +7084,7 @@ static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al) yyextra->current->brief.resize(0); //printf("handleParametersCommentBlock [%s]\n",doc.data()); - while (parseCommentBlock( + while (yyextra->commentScanner.parseCommentBlock( yyextra->thisParser, yyextra->current.get(), a.docs, // text @@ -7084,8 +7143,8 @@ static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt) yyextra->current_root = ce; yyextra->yyFileName = ce->fileName; //setContext(); - yyextra->yyLineNr = ce->startLine ; - yyextra->yyColNr = ce->startColumn ; + yyextra->yyLineNr = ce->bodyLine; + yyextra->yyColNr = ce->bodyColumn; yyextra->insideObjC = ce->lang==SrcLangExt_ObjC; //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC); yyextra->current = std::make_shared<Entry>(); @@ -7151,13 +7210,13 @@ static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt) //memberGroupRelates.resize(0); //memberGroupInside.resize(0); QCString name = ce->name; - Doxygen::docGroup.enterCompound(yyextra->yyFileName,yyextra->yyLineNr,name); + yyextra->commentScanner.enterCompound(yyextra->yyFileName,yyextra->yyLineNr,name); scannerYYlex(yyscanner); yyextra->lexInit=TRUE; //forceEndGroup(); - Doxygen::docGroup.leaveCompound(yyextra->yyFileName,yyextra->yyLineNr,name); + yyextra->commentScanner.leaveCompound(yyextra->yyFileName,yyextra->yyLineNr,name); ce->program.resize(0); @@ -7217,7 +7276,7 @@ static void parseMain(yyscan_t yyscanner, yyextra->current_root = rt; initParser(yyscanner); - Doxygen::docGroup.enterFile(yyextra->yyFileName,yyextra->yyLineNr); + yyextra->commentScanner.enterFile(yyextra->yyFileName,yyextra->yyLineNr); yyextra->current = std::make_shared<Entry>(); //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root); int sec=guessSection(yyextra->yyFileName); @@ -7247,7 +7306,7 @@ static void parseMain(yyscan_t yyscanner, } //forceEndGroup(); - Doxygen::docGroup.leaveFile(yyextra->yyFileName,yyextra->yyLineNr); + yyextra->commentScanner.leaveFile(yyextra->yyFileName,yyextra->yyLineNr); rt->program.resize(0); @@ -7397,4 +7456,6 @@ void COutlineParser::parsePrototype(const char *text) //---------------------------------------------------------------------------- +#if USE_STATE2STRING #include "scanner.l.h" +#endif diff --git a/src/searchindex.cpp b/src/searchindex.cpp index eee1aa1..ec7f7d6 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -394,8 +394,6 @@ void SearchIndex::write(const char *fileName) } } // write urls - QIntDictIterator<URL> udi(m_urls); - URL *url; for (udi.toFirst();(url=udi.current());++udi) { writeString(f,url->name); @@ -833,53 +831,41 @@ void createJavaScriptSearchIndex() } // index files - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { uint letter = getUtf8CodeToLower(fd->name(),0); if (fd->isLinkable() && isId(letter)) { - g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,fd); - g_searchIndexInfo[SEARCH_INDEX_FILES].symbolList.append(letter,fd); + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,fd.get()); + g_searchIndexInfo[SEARCH_INDEX_FILES].symbolList.append(letter,fd.get()); } } } // index class members { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn; // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - addMemberToSearchIndex(md); + addMemberToSearchIndex(md.get()); } } } // index file/namespace members { - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *mn; // for each member name - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - addMemberToSearchIndex(md); + addMemberToSearchIndex(md.get()); } } } @@ -984,7 +970,7 @@ void writeJavaScriptSearchIndex() " \"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl; t << "<html><head><title></title>" << endl; t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl; - t << "<meta name=\"generator\" content=\"Doxygen " << getVersion() << "\"/>" << endl; + t << "<meta name=\"generator\" content=\"Doxygen " << getDoxygenVersion() << "\"/>" << endl; t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl; t << "<script type=\"text/javascript\" src=\"" << baseName << ".js\"></script>" << endl; t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl; @@ -1009,6 +995,12 @@ void writeJavaScriptSearchIndex() t << "document.getElementById(\"NoMatches\").style.display=\"none\";" << endl; t << "var searchResults = new SearchResults(\"searchResults\");" << endl; t << "searchResults.Search();" << endl; + t << "window.addEventListener(\"message\", function(event) {" << endl; + t << " if (event.data == \"take_focus\") {" << endl; + t << " var elem = searchResults.NavNext(0);" << endl; + t << " if (elem) elem.focus();" << endl; + t << " }" << endl; + t << "});" << endl; t << "/* @license-end */\n"; t << "--></script>" << endl; t << "</div>" << endl; // SRIndex @@ -1036,7 +1028,7 @@ void writeJavaScriptSearchIndex() int itemCount=0; for (li.toFirst();(dl=li.current());++li) { - Definition *d = dl->getFirst(); + const Definition *d = dl->getFirst(); if (!firstEntry) { @@ -1048,11 +1040,11 @@ void writeJavaScriptSearchIndex() if (dl->count()==1) // item with a unique name { - MemberDef *md = dynamic_cast<MemberDef*>(d); + const MemberDef *md = dynamic_cast<const MemberDef*>(d); QCString anchor = d->anchor(); ti << "'" << externalRef("../",d->getReference(),TRUE) - << d->getOutputFileBase() << Doxygen::htmlFileExtension; + << addHtmlExtensionIfMissing(d->getOutputFileBase()); if (!anchor.isEmpty()) { ti << "#" << anchor; @@ -1092,15 +1084,15 @@ void writeJavaScriptSearchIndex() { QListIterator<Definition> di(*dl); bool overloadedFunction = FALSE; - Definition *prevScope = 0; + const Definition *prevScope = 0; int childCount=0; for (di.toFirst();(d=di.current());) { ++di; - Definition *scope = d->getOuterScope(); - Definition *next = di.current(); - Definition *nextScope = 0; - MemberDef *md = dynamic_cast<MemberDef*>(d); + const Definition *scope = d->getOuterScope(); + const Definition *next = di.current(); + const Definition *nextScope = 0; + const MemberDef *md = dynamic_cast<const MemberDef*>(d); if (next) nextScope = next->getOuterScope(); QCString anchor = d->anchor(); @@ -1109,7 +1101,7 @@ void writeJavaScriptSearchIndex() ti << "],["; } ti << "'" << externalRef("../",d->getReference(),TRUE) - << d->getOutputFileBase() << Doxygen::htmlFileExtension; + << addHtmlExtensionIfMissing(d->getOutputFileBase()); if (!anchor.isEmpty()) { ti << "#" << anchor; @@ -1144,12 +1136,12 @@ void writeJavaScriptSearchIndex() QCString name; if (d->definitionType()==Definition::TypeClass) { - name = convertToXML((dynamic_cast<ClassDef*>(d))->displayName()); + name = convertToXML((dynamic_cast<const ClassDef*>(d))->displayName()); found = TRUE; } else if (d->definitionType()==Definition::TypeNamespace) { - name = convertToXML((dynamic_cast<NamespaceDef*>(d))->displayName()); + name = convertToXML((dynamic_cast<const NamespaceDef*>(d))->displayName()); found = TRUE; } else if (scope==0 || scope==Doxygen::globalScope) // in global scope diff --git a/src/section.h b/src/section.h index 9e6c695..cf453bc 100644 --- a/src/section.h +++ b/src/section.h @@ -1,13 +1,10 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -19,42 +16,144 @@ #ifndef SECTION_H #define SECTION_H -#include "sortdict.h" +#include <string> +#include <unordered_map> + +#include <qcstring.h> + +#include "linkedmap.h" class Definition; -/** Class representing a section in a page */ -struct SectionInfo +//! enum representing the various types of sections and entities that can be referred to. +enum class SectionType { - enum SectionType { Page = 0, - Section = 1, - Subsection = 2, - Subsubsection = 3, - Paragraph = 4, - Anchor = 5, - Table = 6 - }; - SectionInfo(const char *f,const int lin,const char *l,const char *t, - SectionType st,int lev,const char *r=0) : - label(l), title(t), type(st), ref(r), definition(0), - fileName(f), lineNr(lin), generated(FALSE), level(lev) {} - QCString label; - QCString title; - SectionType type; - QCString ref; - Definition *definition; - QCString fileName; - int lineNr; - bool generated; - int level; + Page = 0, + Section = 1, + Subsection = 2, + Subsubsection = 3, + Paragraph = 4, + Anchor = 5, + Table = 6 }; -/** Unsorted dictionary of SectionInfo objects. */ -class SectionDict : public SDict<SectionInfo> +//! return true if type is a section, and false if it is a page, anchor or table. +inline constexpr bool isSection(SectionType type) +{ + return (type==SectionType::Section || + type==SectionType::Subsection || + type==SectionType::Subsubsection || + type==SectionType::Paragraph); +} + +//! class that provide information about a section. +class SectionInfo { public: - SectionDict(int size) : SDict<SectionInfo>(size) {} - ~SectionDict() {} + SectionInfo(const char *label, const char *fileName, int lineNr, + const char *title, SectionType type, int level,const char *ref) : + m_label(label), m_title(title), m_type(type), m_ref(ref), + m_lineNr(lineNr), m_fileName(fileName), m_level(level) + { + //printf("SectionInfo(%p)\n",this); + } + ~SectionInfo() + { + //printf("~SectionInfo(%p)\n",this); + } + + // getters + QCString label() const { return m_label; } + QCString title() const { return m_title; } + SectionType type() const { return m_type; } + QCString ref() const { return m_ref; } + int lineNr() const { return m_lineNr; } + QCString fileName() const { return m_fileName; } + bool generated() const { return m_generated; } + int level() const { return m_level; } + Definition *definition() const { return m_definition; } + + // setters + void setFileName(const char *fn) { m_fileName = fn; } + void setType(SectionType t) { m_type = t; } + void setGenerated(bool b) { m_generated = b; } + void setDefinition(Definition *d) { m_definition = d; } + + private: + QCString m_label; + QCString m_title; + SectionType m_type; + QCString m_ref; + int m_lineNr; + QCString m_fileName; + bool m_generated = false; + int m_level; + Definition *m_definition = 0; }; +//! class that represents a list of constant references to sections. +class SectionRefs +{ + using SectionInfoVec = std::vector<const SectionInfo*>; + public: + using const_iterator = SectionInfoVec::const_iterator; + + //! Returns a constant pointer to the section info given a section label or nullptr + //! if no section with the given label can be found. + const SectionInfo *find(const char *label) const + { + auto it = m_lookup.find(label); + return it!=m_lookup.end() ? it->second : nullptr; + } + + //! Adds a non-owning section reference. + void add(const SectionInfo *si) + { + m_lookup.insert({toStdString(si->label()),si}); + m_entries.push_back(si); + } + + const_iterator begin() const { return m_entries.cbegin(); } + const_iterator end() const { return m_entries.cend(); } + bool empty() const { return m_entries.empty(); } + int size() const { return (int)m_entries.size(); } + + private: + SectionInfoVec m_entries; + std::unordered_map< std::string, const SectionInfo* > m_lookup; +}; + +//! singleton class that owns the list of all sections +class SectionManager : public LinkedMap<SectionInfo> +{ + public: + //! Add a new section given the data of an existing section. + //! Returns a non-owning pointer to the newly added section. + SectionInfo *add(const SectionInfo &si) + { + return LinkedMap<SectionInfo>::add(si.label(),si.fileName(),si.lineNr(),si.title(),si.type(),si.level(),si.ref()); + } + + //! Add a new section + //! Return a non-owning pointer to the newly added section + SectionInfo *add(const char *label, const char *fileName, int lineNr, + const char *title, SectionType type, int level,const char *ref=0) + { + return LinkedMap<SectionInfo>::add(label,fileName,lineNr,title,type,level,ref); + } + + //! returns a reference to the singleton + static SectionManager &instance() + { + static SectionManager sm; + return sm; + } + + private: + SectionManager() {} + SectionManager(const SectionManager &other) = delete; + SectionManager &operator=(const SectionManager &other) = delete; +}; + + #endif diff --git a/src/sortdict.h b/src/sortdict.h index 203ae5e..15282ec 100644 --- a/src/sortdict.h +++ b/src/sortdict.h @@ -99,7 +99,7 @@ class SDict private: SList<T> *m_list; QDict<T> *m_dict; - int m_sizeIndex; + uint m_sizeIndex; public: /*! Create an ordered dictionary. @@ -108,7 +108,7 @@ class SDict * \param caseSensitive indicated whether the keys should be sorted * in a case sensitive way. */ - SDict(int size=17,bool caseSensitive=TRUE) : m_sizeIndex(0) + SDict(uint size=17,bool caseSensitive=TRUE) : m_sizeIndex(0) { m_list = new SList<T>(this); #if AUTORESIZE @@ -277,7 +277,7 @@ class SDict /*! Returns the number of items stored in the dictionary */ - int count() const + uint count() const { return m_list->count(); } diff --git a/src/sqlcode.l b/src/sqlcode.l index 02c2c14..58a2fce 100644 --- a/src/sqlcode.l +++ b/src/sqlcode.l @@ -19,6 +19,9 @@ %option nounput %option reentrant %option extra-type="struct sqlcodeYY_state *" +%top{ +#include <stdint.h> +} %{ @@ -41,6 +44,8 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define USE_STATE2STRING 0 + struct sqlcodeYY_state { CodeOutputInterface * code; @@ -62,8 +67,10 @@ struct sqlcodeYY_state const char *currentFontClass; }; -static void codify(const char* text); +#if USE_STATE2STRING static const char *stateToString(int state); +#endif + static void setCurrentDoc(const QCString &anchor,yyscan_t yyscanner); static void startCodeLine(yyscan_t yyscanner); static void endFontClass(yyscan_t yyscanner); @@ -72,7 +79,7 @@ static void nextCodeLine(yyscan_t yyscanner); static void codifyLines(char *text,yyscan_t yyscanner); static void startFontClass(const char *s,yyscan_t yyscanner); static int countLines(yyscan_t yyscanner); -static int yyread(char *buf,int max_size,yyscan_t yyscanner); +static yy_size_t yyread(char *buf,yy_size_t max_size,yyscan_t yyscanner); #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner); @@ -190,12 +197,6 @@ commentclose "\*/" %% -static void codify(const char* text, yyscan_t yyscanner) -{ - struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - yyextra->code->codify(text); -} - static void setCurrentDoc(const QCString &anchor, yyscan_t yyscanner) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; @@ -345,10 +346,10 @@ static int countLines(yyscan_t yyscanner) return count; } -static int yyread(char *buf,int max_size,yyscan_t yyscanner) +static yy_size_t yyread(char *buf,yy_size_t max_size,yyscan_t yyscanner) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int c=0; + yy_size_t c=0; while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) { *buf = yyextra->inputString[yyextra->inputPosition++] ; @@ -484,4 +485,6 @@ void SQLCodeParser::resetCodeParserState() //--------------------------------------------------------------------------------- +#if USE_STATE2STRING #include "sqlcode.l.h" +#endif diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index 14a73d8..62e5576 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -501,9 +501,9 @@ const char * table_schema[][2] = { ////////////////////////////////////////////////////// struct SqlStmt { - const char *query; - sqlite3_stmt *stmt; - sqlite3 *db; + const char *query = 0; + sqlite3_stmt *stmt = 0; + sqlite3 *db = 0; }; ////////////////////////////////////////////////////// /* If you add a new statement below, make sure to add it to @@ -924,7 +924,7 @@ static int insertPath(QCString name, bool local=TRUE, bool found=TRUE, int type= static void recordMetadata() { - bindTextParameter(meta_insert,":doxygen_version",getVersion()); + bindTextParameter(meta_insert,":doxygen_version",getFullVersion()); bindTextParameter(meta_insert,":schema_version","0.2.0"); //TODO: this should be a constant somewhere; not sure where bindTextParameter(meta_insert,":generated_at",dateToString(TRUE), FALSE); bindTextParameter(meta_insert,":generated_on",dateToString(FALSE), FALSE); @@ -1218,8 +1218,6 @@ static void pragmaTuning(sqlite3 *db) static int initializeTables(sqlite3* db) { int rc; - sqlite3_stmt *stmt = 0; - msg("Initializing DB schema (tables)...\n"); for (unsigned int k = 0; k < sizeof(table_schema) / sizeof(table_schema[0]); k++) { @@ -1238,8 +1236,6 @@ static int initializeTables(sqlite3* db) static int initializeViews(sqlite3* db) { int rc; - sqlite3_stmt *stmt = 0; - msg("Initializing DB schema (views)...\n"); for (unsigned int k = 0; k < sizeof(view_schema) / sizeof(view_schema[0]); k++) { @@ -1740,7 +1736,7 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref } const MemberDef *rmd = md->reimplements(); - if(rmd) + if (rmd) { QCString qreimplemented_refid = rmd->getOutputFileBase() + "_1" + rmd->anchor(); @@ -1866,7 +1862,6 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref if (mdict!=0) { MemberSDict::IteratorDict mdi(*mdict); - const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { insertMemberReference(md,rmd, "inline"); @@ -1877,7 +1872,6 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref if (mdict!=0) { MemberSDict::IteratorDict mdi(*mdict); - const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { insertMemberReference(rmd,md, "inline"); @@ -2486,10 +2480,10 @@ static void generateSqlite3ForPage(const PageDef *pd,bool isExample) } else { - SectionInfo *si = Doxygen::sectionDict->find(pd->name()); + SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) { - title = si->title; + title = si->title(); } if(!title){title = pd->title();} @@ -2612,16 +2606,12 @@ void generateSqlite3() } // + files - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - const FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { msg("Generating Sqlite3 output for file %s\n",fd->name().data()); - generateSqlite3ForFile(fd); + generateSqlite3ForFile(fd.get()); } } diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 3f9a7a1..3a35a27 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -1,13 +1,13 @@ /****************************************************************************** * - * + * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -50,7 +50,7 @@ class TagAnchorInfo public: TagAnchorInfo(const QCString &f, const QCString &l, - const QCString &t=QCString()) + const QCString &t=QCString()) : label(l), fileName(f), title(t) {} QCString label; QCString fileName; @@ -60,7 +60,7 @@ class TagAnchorInfo /** List of TagAnchorInfo objects. */ class TagAnchorInfoList : public QList<TagAnchorInfo> { - public: + public: TagAnchorInfoList() : QList<TagAnchorInfo>() { setAutoDelete(TRUE); } virtual ~TagAnchorInfoList() {} }; @@ -79,7 +79,7 @@ class TagEnumValueInfo class TagMemberInfo { public: - TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) + TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) { enumValues.setAutoDelete(TRUE); } QCString type; QCString name; @@ -91,7 +91,7 @@ class TagMemberInfo TagAnchorInfoList docAnchors; Protection prot; Specifier virt; - bool isStatic; + bool isStatic; QList<TagEnumValueInfo> enumValues; }; @@ -207,10 +207,10 @@ class TagDirInfo TagAnchorInfoList docAnchors; }; -/** Tag file parser. +/** Tag file parser. * * Reads an XML-structured tagfile and builds up the structure in - * memory. The method buildLists() is used to transfer/translate + * memory. The method buildLists() is used to transfer/translate * the structures to the doxygen engine. */ class TagFileParser : public QXmlDefaultHandler @@ -229,7 +229,7 @@ class TagFileParser : public QXmlDefaultHandler }; class StartElementHandler { - typedef void (TagFileParser::*Handler)(const QXmlAttributes &attrib); + typedef void (TagFileParser::*Handler)(const QXmlAttributes &attrib); public: StartElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {} void operator()(const QXmlAttributes &attrib) { (m_parent->*m_handler)(attrib); } @@ -240,7 +240,7 @@ class TagFileParser : public QXmlDefaultHandler class EndElementHandler { - typedef void (TagFileParser::*Handler)(); + typedef void (TagFileParser::*Handler)(); public: EndElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {} void operator()() { (m_parent->*m_handler)(); } @@ -282,7 +282,7 @@ class TagFileParser : public QXmlDefaultHandler void warn(const char *fmt) { - ::warn(m_inputFileName,m_locator->lineNumber(),fmt); + ::warn(m_inputFileName,m_locator->lineNumber(),"%s", fmt); } void warn(const char *fmt,const char *s) { @@ -391,7 +391,7 @@ class TagFileParser : public QXmlDefaultHandler } if (isObjC=="yes" && m_curClass) { - m_curClass->isObjC = TRUE; + m_curClass->isObjC = TRUE; } } @@ -399,20 +399,20 @@ class TagFileParser : public QXmlDefaultHandler { switch (m_state) { - case InClass: m_tagFileClasses.append(m_curClass); - m_curClass=0; break; - case InFile: m_tagFileFiles.append(m_curFile); - m_curFile=0; break; - case InNamespace: m_tagFileNamespaces.append(m_curNamespace); - m_curNamespace=0; break; - case InGroup: m_tagFileGroups.append(m_curGroup); - m_curGroup=0; break; - case InPage: m_tagFilePages.append(m_curPage); - m_curPage=0; break; + case InClass: m_tagFileClasses.append(m_curClass); + m_curClass=0; break; + case InFile: m_tagFileFiles.append(m_curFile); + m_curFile=0; break; + case InNamespace: m_tagFileNamespaces.append(m_curNamespace); + m_curNamespace=0; break; + case InGroup: m_tagFileGroups.append(m_curGroup); + m_curGroup=0; break; + case InPage: m_tagFilePages.append(m_curPage); + m_curPage=0; break; case InDir: m_tagFileDirs.append(m_curDir); m_curDir=0; break; - case InPackage: m_tagFilePackages.append(m_curPackage); - m_curPackage=0; break; + case InPackage: m_tagFilePackages.append(m_curPackage); + m_curPackage=0; break; default: warn("tag 'compound' was not expected!"); } @@ -460,7 +460,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->members.append(m_curMember); break; case InGroup: m_curGroup->members.append(m_curMember); break; case InPackage: m_curPackage->members.append(m_curMember); break; - default: warn("Unexpected tag 'member' found"); break; + default: warn("Unexpected tag 'member' found"); break; } } @@ -484,7 +484,7 @@ class TagFileParser : public QXmlDefaultHandler void endEnumValue() { - m_curEnumValue->name = m_curString.stripWhiteSpace(); + m_curEnumValue->name = m_curString.stripWhiteSpace(); m_state = *m_stateStack.top(); m_stateStack.remove(); if (m_state==InMember) @@ -536,7 +536,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->classList.append(m_curString); break; case InGroup: m_curGroup->classList.append(m_curString); break; case InPackage: m_curPackage->classList.append(m_curString); break; - default: warn("Unexpected tag 'class' found"); break; + default: warn("Unexpected tag 'class' found"); break; } } @@ -547,7 +547,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->classList.append(m_curString); break; case InFile: m_curFile->namespaceList.append(m_curString); break; case InGroup: m_curGroup->namespaceList.append(m_curString); break; - default: warn("Unexpected tag 'namespace' found"); break; + default: warn("Unexpected tag 'namespace' found"); break; } } @@ -557,7 +557,7 @@ class TagFileParser : public QXmlDefaultHandler { case InGroup: m_curGroup->fileList.append(m_curString); break; case InDir: m_curDir->fileList.append(m_curString); break; - default: warn("Unexpected tag 'file' found"); break; + default: warn("Unexpected tag 'file' found"); break; } } @@ -566,7 +566,7 @@ class TagFileParser : public QXmlDefaultHandler switch(m_state) { case InGroup: m_curGroup->fileList.append(m_curString); break; - default: warn("Unexpected tag 'page' found"); break; + default: warn("Unexpected tag 'page' found"); break; } } @@ -575,7 +575,7 @@ class TagFileParser : public QXmlDefaultHandler switch(m_state) { case InDir: m_curDir->subdirList.append(m_curString); break; - default: warn("Unexpected tag 'dir' found"); break; + default: warn("Unexpected tag 'dir' found"); break; } } @@ -595,7 +595,7 @@ class TagFileParser : public QXmlDefaultHandler { if (m_state==InMember) { - m_curMember->type = m_curString; + m_curMember->type = m_curString; } else { @@ -615,7 +615,7 @@ class TagFileParser : public QXmlDefaultHandler case InDir: m_curDir->name = m_curString; break; case InMember: m_curMember->name = m_curString; break; case InPackage: m_curPackage->name = m_curString; break; - default: warn("Unexpected tag 'name' found"); break; + default: warn("Unexpected tag 'name' found"); break; } } @@ -687,7 +687,7 @@ class TagFileParser : public QXmlDefaultHandler { if (m_state==InClass && m_curClass) { - if (m_curClass->templateArguments==0) + if (m_curClass->templateArguments==0) { m_curClass->templateArguments = new QList<QCString>; m_curClass->templateArguments->setAutoDelete(TRUE); @@ -711,7 +711,7 @@ class TagFileParser : public QXmlDefaultHandler case InPage: m_curPage->filename = m_curString; break; case InPackage: m_curPackage->filename = m_curString; break; case InDir: m_curDir->filename = m_curString; break; - default: warn("Unexpected tag 'filename' found"); break; + default: warn("Unexpected tag 'filename' found"); break; } } @@ -721,19 +721,19 @@ class TagFileParser : public QXmlDefaultHandler { case InFile: m_curFile->path = m_curString; break; case InDir: m_curDir->path = m_curString; break; - default: warn("Unexpected tag 'path' found"); break; + default: warn("Unexpected tag 'path' found"); break; } } - + void endAnchor() { if (m_state==InMember) { - m_curMember->anchor = m_curString; + m_curMember->anchor = m_curString; } else if (m_state==InClass) { - m_curClass->anchor = m_curString; + m_curClass->anchor = m_curString; } else { @@ -745,7 +745,7 @@ class TagFileParser : public QXmlDefaultHandler { if (m_state==InMember) { - m_curMember->clangId = m_curString; + m_curMember->clangId = m_curString; } else if (m_state==InClass) { @@ -762,24 +762,24 @@ class TagFileParser : public QXmlDefaultHandler } - + void endAnchorFile() { if (m_state==InMember) { - m_curMember->anchorFile = m_curString; + m_curMember->anchorFile = m_curString; } else { warn("Unexpected tag 'anchorfile' found"); } } - + void endArglist() { if (m_state==InMember) { - m_curMember->arglist = m_curString; + m_curMember->arglist = m_curString; } else { @@ -792,7 +792,7 @@ class TagFileParser : public QXmlDefaultHandler { case InGroup: m_curGroup->title = m_curString; break; case InPage: m_curPage->title = m_curString; break; - default: warn("Unexpected tag 'title' found"); break; + default: warn("Unexpected tag 'title' found"); break; } } @@ -888,7 +888,7 @@ class TagFileParser : public QXmlDefaultHandler return TRUE; } - bool startElement( const QString&, const QString&, + bool startElement( const QString&, const QString&, const QString&name, const QXmlAttributes& attrib ) { //printf("startElement '%s'\n",name.data()); @@ -897,7 +897,7 @@ class TagFileParser : public QXmlDefaultHandler { (*handler)(attrib); } - else + else { warn("Unknown tag '%s' found!",name.data()); } @@ -912,14 +912,14 @@ class TagFileParser : public QXmlDefaultHandler { (*handler)(); } - else + else { warn("Unknown tag '%s' found!",name.data()); } return TRUE; } - bool characters ( const QString & ch ) + bool characters ( const QString & ch ) { m_curString+=ch.utf8(); return TRUE; @@ -928,7 +928,7 @@ class TagFileParser : public QXmlDefaultHandler void dump(); void buildLists(const std::shared_ptr<Entry> &root); void addIncludes(); - + private: void buildMemberList(const std::shared_ptr<Entry> &ce,QList<TagMemberInfo> &members); void addDocAnchors(const std::shared_ptr<Entry> &e,const TagAnchorInfoList &l); @@ -961,7 +961,7 @@ class TagFileParser : public QXmlDefaultHandler QCString m_inputFileName; }; -/** Error handler for the XML tag file parser. +/** Error handler for the XML tag file parser. * * Basically dumps all fatal error to stderr using err(). */ @@ -1026,8 +1026,8 @@ void TagFileParser::dump() msg("namespace '%s'\n",nd->name.data()); msg(" filename '%s'\n",nd->filename.data()); QCStringList::Iterator it; - for ( it = nd->classList.begin(); - it != nd->classList.end(); ++it ) + for ( it = nd->classList.begin(); + it != nd->classList.end(); ++it ) { msg( " class: %s \n", (*it).data() ); } @@ -1051,13 +1051,13 @@ void TagFileParser::dump() msg("file '%s'\n",fd->name.data()); msg(" filename '%s'\n",fd->filename.data()); QCStringList::Iterator it; - for ( it = fd->namespaceList.begin(); - it != fd->namespaceList.end(); ++it ) + for ( it = fd->namespaceList.begin(); + it != fd->namespaceList.end(); ++it ) { msg( " namespace: %s \n", (*it).data() ); } - for ( it = fd->classList.begin(); - it != fd->classList.end(); ++it ) + for ( it = fd->classList.begin(); + it != fd->classList.end(); ++it ) { msg( " class: %s \n", (*it).data() ); } @@ -1089,28 +1089,28 @@ void TagFileParser::dump() msg("group '%s'\n",gd->name.data()); msg(" filename '%s'\n",gd->filename.data()); QCStringList::Iterator it; - for ( it = gd->namespaceList.begin(); - it != gd->namespaceList.end(); ++it ) + for ( it = gd->namespaceList.begin(); + it != gd->namespaceList.end(); ++it ) { msg( " namespace: %s \n", (*it).data() ); } - for ( it = gd->classList.begin(); - it != gd->classList.end(); ++it ) + for ( it = gd->classList.begin(); + it != gd->classList.end(); ++it ) { msg( " class: %s \n", (*it).data() ); } - for ( it = gd->fileList.begin(); - it != gd->fileList.end(); ++it ) + for ( it = gd->fileList.begin(); + it != gd->fileList.end(); ++it ) { msg( " file: %s \n", (*it).data() ); } - for ( it = gd->subgroupList.begin(); - it != gd->subgroupList.end(); ++it ) + for ( it = gd->subgroupList.begin(); + it != gd->subgroupList.end(); ++it ) { msg( " subgroup: %s \n", (*it).data() ); } - for ( it = gd->pageList.begin(); - it != gd->pageList.end(); ++it ) + for ( it = gd->pageList.begin(); + it != gd->pageList.end(); ++it ) { msg( " page: %s \n", (*it).data() ); } @@ -1143,13 +1143,13 @@ void TagFileParser::dump() msg("dir '%s'\n",dd->name.data()); msg(" path '%s'\n",dd->path.data()); QCStringList::Iterator it; - for ( it = dd->fileList.begin(); - it != dd->fileList.end(); ++it ) + for ( it = dd->fileList.begin(); + it != dd->fileList.end(); ++it ) { msg( " file: %s \n", (*it).data() ); } - for ( it = dd->subdirList.begin(); - it != dd->subdirList.end(); ++it ) + for ( it = dd->subdirList.begin(); + it != dd->subdirList.end(); ++it ) { msg( " subdir: %s \n", (*it).data() ); } @@ -1162,13 +1162,13 @@ void TagFileParser::addDocAnchors(const std::shared_ptr<Entry> &e,const TagAncho TagAnchorInfo *ta; for (tli.toFirst();(ta=tli.current());++tli) { - if (Doxygen::sectionDict->find(ta->label)==0) + if (SectionManager::instance().find(ta->label)==0) { //printf("New sectionInfo file=%s anchor=%s\n", // ta->fileName.data(),ta->label.data()); - SectionInfo *si=new SectionInfo(ta->fileName,-1,ta->label,ta->title, - SectionInfo::Anchor,0,m_tagName); - Doxygen::sectionDict->append(ta->label,si); + SectionInfo *si=SectionManager::instance().add( + ta->label,ta->fileName,-1,ta->title, + SectionType::Anchor,0,m_tagName); e->anchors.push_back(si); } else @@ -1310,7 +1310,7 @@ static QCString stripPath(const QCString &s) } /*! Injects the info gathered by the XML parser into the Entry tree. - * This tree contains the information extracted from the input in a + * This tree contains the information extracted from the input in a * "unrelated" form. */ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) @@ -1388,21 +1388,18 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name); fe->fileName = fullName; //printf("createFileDef() filename=%s\n",tfi->filename.data()); - FileDef *fd = createFileDef(m_tagName+":"+tfi->path, + std::unique_ptr<FileDef> fd { createFileDef(m_tagName+":"+tfi->path, tfi->name,m_tagName, - tfi->filename - ); + tfi->filename) }; FileName *mn; - if ((mn=Doxygen::inputNameDict->find(tfi->name))) + if ((mn=Doxygen::inputNameLinkedMap->find(tfi->name))) { - mn->append(fd); + mn->push_back(std::move(fd)); } else { - mn = new FileName(fullName,tfi->name); - mn->append(fd); - Doxygen::inputNameList->inSort(mn); - Doxygen::inputNameDict->insert(tfi->name,mn); + mn = Doxygen::inputNameLinkedMap->add(tfi->name,fullName); + mn->push_back(std::move(fd)); } buildMemberList(fe,tfi->members); root->moveToSubEntryAndKeep(fe); @@ -1486,7 +1483,8 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) for (pgit.toFirst();(tpi=pgit.current());++pgit) { std::shared_ptr<Entry> pe = std::make_shared<Entry>(); - pe->section = tpi->filename=="index" ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC; + bool isIndex = (stripExtensionGeneral(tpi->filename,getFileNameExtension(tpi->filename))=="index"); + pe->section = isIndex ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC; pe->name = tpi->name; pe->args = tpi->title; addDocAnchors(pe,tpi->docAnchors); @@ -1504,13 +1502,10 @@ void TagFileParser::addIncludes() for (fit.toFirst();(tfi=fit.current());++fit) { //printf("tag file tagName=%s path=%s name=%s\n",m_tagName.data(),tfi->path.data(),tfi->name.data()); - FileName *fn = Doxygen::inputNameDict->find(tfi->name); + FileName *fn = Doxygen::inputNameLinkedMap->find(tfi->name); if (fn) { - //printf("found\n"); - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { //printf("input file path=%s name=%s\n",fd->getPath().data(),fd->name().data()); if (fd->getPath()==QCString(m_tagName+":"+tfi->path)) @@ -1521,19 +1516,17 @@ void TagFileParser::addIncludes() for (;(ii=mii.current());++mii) { //printf("ii->name='%s'\n",ii->name.data()); - FileName *ifn = Doxygen::inputNameDict->find(ii->name); + FileName *ifn = Doxygen::inputNameLinkedMap->find(ii->name); ASSERT(ifn!=0); if (ifn) { - FileNameIterator ifni(*ifn); - FileDef *ifd; - for (;(ifd=ifni.current());++ifni) + for (const auto &ifd : *ifn) { //printf("ifd->getOutputFileBase()=%s ii->id=%s\n", // ifd->getOutputFileBase().data(),ii->id.data()); if (ifd->getOutputFileBase()==QCString(ii->id)) { - fd->addIncludeDependency(ifd,ii->text,ii->isLocal,ii->isImported,FALSE); + fd->addIncludeDependency(ifd.get(),ii->text,ii->isLocal,ii->isImported,FALSE); } } } @@ -1561,5 +1554,3 @@ void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullName) handler.addIncludes(); //handler.dump(); } - - diff --git a/src/tclscanner.h b/src/tclscanner.h deleted file mode 100644 index cdd56d8..0000000 --- a/src/tclscanner.h +++ /dev/null @@ -1,63 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * Copyright (C) 2010-2011 by Rene Zaumseil - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#ifndef SCANNER_TCL_H -#define SCANNER_TCL_H - -#include "parserintf.h" - -/** \brief Tcl language parser using state-based lexical scanning. - * - * This is the Tcl language parser for doxygen. - */ -class TclOutlineParser : public OutlineParserInterface -{ - public: - void startTranslationUnit(const char *) {} - void finishTranslationUnit() {} - void parseInput(const char *fileName, - const char *fileBuf, - const std::shared_ptr<Entry> &root, - bool sameTranslationUnit, - QStrList &filesInSameTranslationUnit); - bool needsPreprocessing(const QCString &extension) const; - void parsePrototype(const char *text); -}; - -class TclCodeParser : public CodeParserInterface -{ - public: - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ); - void resetCodeParserState(); -}; - -#endif diff --git a/src/tclscanner.l b/src/tclscanner.l deleted file mode 100644 index a4709ce..0000000 --- a/src/tclscanner.l +++ /dev/null @@ -1,3143 +0,0 @@ -/***************************************************************************** - * Parser for Tcl subset - * - * Copyright (C) 2010 by Rene Zaumseil - * based on the work of Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ -%option never-interactive -%option case-insensitive -%option prefix="tclscannerYY" - -%{ -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <ctype.h> - -#include <qstring.h> -#include <qcstringlist.h> -#include <qlist.h> -#include <qmap.h> -#include <qarray.h> -#include <qstack.h> -#include <qregexp.h> -#include <qfile.h> -#include <qdict.h> - -#include "entry.h" -#include "message.h" -#include "config.h" -#include "doxygen.h" -#include "util.h" -#include "defargs.h" -#include "language.h" -#include "commentscan.h" -#include "pre.h" -#include "tclscanner.h" -#include "outputlist.h" -#include "membername.h" -#include "searchindex.h" -#include "commentcnv.h" -#include "bufstr.h" -#include "portable.h" -#include "arguments.h" -#include "namespacedef.h" -#include "filedef.h" - -#define YY_NO_INPUT 1 -#define YY_NO_UNISTD_H 1 - -#define MAX_INCLUDE_DEPTH 10 - -static const char *stateToString(int state); - -//! Application error. -#define tcl_err \ - printf("Error %d %s() at line %d! ",__LINE__,tcl.file_name.data(),yylineno); \ - yy_push_state(ERROR); \ - yyless(0); \ - printf - -//! Application warning. -#define tcl_war \ - printf("Warning %d %s() at line %d: ",__LINE__,tcl.file_name.data(),yylineno); \ - printf - -//! Application message. -#define tcl_inf \ - if (0) printf("--- %.4d %d@%d: ",__LINE__,yylineno,yy_start_stack_ptr) && printf - -//! Debug message. -#define D\ - if (0) printf("--- %.4d %d@%d: %s\n",__LINE__,yylineno,yy_start_stack_ptr,yytext); - -// BEGIN of copy from tclUtil.c -// - Tcl_Interp removed -// - changes are marked with RZ -// #define's to adapt the code: -#define CONST const -#define UCHAR (unsigned char) -#define TCL_ERROR 1 -#define TCL_OK 0 -#define ckalloc malloc -#define ckfree free -#define TclCopyAndCollapse(size,src,dest) memcpy(dest,src,size); *(dest+size)=0 -int TclFindElement( - CONST char *list, /* Points to the first byte of a string - * containing a Tcl list with zero or more - * elements (possibly in braces). */ - int listLength, /* Number of bytes in the list's string. */ - CONST char **elementPtr, /* Where to put address of first significant - * character in first element of list. */ - CONST char **nextPtr, /* Fill in with location of character just - * after all white space following end of - * argument (next arg or end of list). */ - int *sizePtr, /* If non-zero, fill in with size of - * element. */ - int *bracePtr) /* If non-zero, fill in with non-zero/zero to - * indicate that arg was/wasn't in braces. */ -{ - CONST char *p = list; - CONST char *elemStart; /* Points to first byte of first element. */ - CONST char *limit; /* Points just after list's last byte. */ - int openBraces = 0; /* Brace nesting level during parse. */ - int inQuotes = 0; - int size = 0; /* lint. */ - //RZ int numChars; - - /* - * Skim off leading white space and check for an opening brace or quote. - * We treat embedded NULLs in the list as bytes belonging to a list - * element. - */ - - limit = (list + listLength); - while ((p < limit) && (isspace(UCHAR(*p)))) - { /* INTL: ISO space. */ - p++; - } - if (p == limit) - { /* no element found */ - elemStart = limit; - goto done; - } - - if (*p == '{') /* } to keep vi happy */ - { - openBraces = 1; - p++; - } - else if (*p == '"') - { - inQuotes = 1; - p++; - } - elemStart = p; - if (bracePtr != 0) - { - *bracePtr = openBraces; - } - - /* - * Find element's end (a space, close brace, or the end of the string). - */ - - while (p < limit) - { - switch (*p) - { - /* - * Open brace: don't treat specially unless the element is in - * braces. In this case, keep a nesting count. - */ - - case '{': - if (openBraces != 0) - { - openBraces++; - } - break; - - /* - * Close brace: if element is in braces, keep nesting count and - * quit when the last close brace is seen. - */ - - case '}': - if (openBraces > 1) - { - openBraces--; - } - else if (openBraces == 1) - { - size = (int)(p - elemStart); - p++; - if ((p >= limit) || isspace(UCHAR(*p))) - { /* INTL: ISO space. */ - goto done; - } - - /* - * Garbage after the closing brace; return an error. - */ - - return TCL_ERROR; - } - break; - - /* - * Backslash: skip over everything up to the end of the backslash - * sequence. - */ - - case '\\': - //RZ Tcl_UtfBackslash(p, &numChars, NULL); - //RZ p += (numChars - 1); - p++; //RZ - break; - - /* - * Space: ignore if element is in braces or quotes; otherwise - * terminate element. - */ - - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - case '\v': - if ((openBraces == 0) && !inQuotes) - { - size = (int)(p - elemStart); - goto done; - } - break; - - /* - * Double-quote: if element is in quotes then terminate it. - */ - - case '"': - if (inQuotes) - { - size = (int)(p - elemStart); - p++; - if ((p >= limit) || isspace(UCHAR(*p))) - { /* INTL: ISO space */ - goto done; - } - - /* - * Garbage after the closing quote; return an error. - */ - return TCL_ERROR; - } - break; - } - p++; - } - - /* - * End of list: terminate element. - */ - - if (p == limit) - { - if (openBraces != 0) - { - return TCL_ERROR; - } - else if (inQuotes) - { - return TCL_ERROR; - } - size = (int)(p - elemStart); - } - -done: - while ((p < limit) && (isspace(UCHAR(*p)))) - { /* INTL: ISO space. */ - p++; - } - *elementPtr = elemStart; - *nextPtr = p; - if (sizePtr != 0) - { - *sizePtr = size; - } - return TCL_OK; -} - -int Tcl_SplitList( - CONST char *list, /* Pointer to string with list structure. */ - int *argcPtr, /* Pointer to location to fill in with the - * number of elements in the list. */ - CONST char ***argvPtr) /* Pointer to place to store pointer to array - * of pointers to list elements. */ -{ - CONST char **argv, *l, *element; - char *p; - int length, size, i, result, elSize, brace; - - /* - * Figure out how much space to allocate. There must be enough space for - * both the array of pointers and also for a copy of the list. To estimate - * the number of pointers needed, count the number of space characters in - * the list. - */ - - for (size = 2, l = list; *l != 0; l++) - { - if (isspace(UCHAR(*l))) - { /* INTL: ISO space. */ - size++; - - /* - * Consecutive space can only count as a single list delimiter. - */ - - while (1) - { - char next = *(l + 1); - - if (next == '\0') - { - break; - } - ++l; - if (isspace(UCHAR(next))) - { /* INTL: ISO space. */ - continue; - } - break; - } - } - } - length = (int)(l - list); - argv = (CONST char **) ckalloc((unsigned) - ((size * sizeof(char *)) + length + 1)); - for (i = 0, p = ((char *) argv) + size*sizeof(char *); - *list != 0; i++) - { - CONST char *prevList = list; - - result = TclFindElement(list, length, &element, &list, - &elSize, &brace); - length -= (int)(list - prevList); - if (result != TCL_OK) - { - ckfree((char *) argv); - return result; - } - if (*element == 0) - { - break; - } - if (i >= size) - { - ckfree((char *) argv); - return TCL_ERROR; - } - argv[i] = p; - if (brace) - { - memcpy(p, element, (size_t) elSize); - p += elSize; - *p = 0; - p++; - } - else - { - TclCopyAndCollapse(elSize, element, p); - p += elSize+1; - } - } - - argv[i] = NULL; - *argvPtr = argv; - *argcPtr = i; - return TCL_OK; -} -// END of tclUtil.c - -void tcl_split_list(QCString &str, QCStringList &list) -{ - int argc; - const char **argv; - - list.clear(); - if (str.left(1)=="{" && str.right(1)=="}") - { - str=str.mid(1,str.length()-2); - } - else if (str.left(1)=="\"" && str.right(1)=="\"") - { - str=str.mid(1,str.length()-2); - } - if (!str.isEmpty()) - { - if (Tcl_SplitList(str,&argc,&argv) != TCL_OK) - { - list.append(str); - } - else - { - for (int i = 0; i < argc; i++) - { - list.append(argv[i]); - } - ckfree((char *) argv); - } - } -} - -//! Structure containing information about current scan context. -typedef struct -{ - char type[2]; // type of scan context: "\"" "{" "[" "?" " " - int line0; // start line of scan context - int line1; // end line of scan context - YY_BUFFER_STATE buffer_state; // value of scan context - QCString ns; // current namespace - Entry *entry_fn; // if set contains the current proc/method/constructor/destructor - Entry *entry_cl; // if set contain the current class - Entry *entry_scan; // current scan entry - Protection protection; // current protections state - QCStringList after; // option/value list (options: NULL comment keyword script) -} tcl_scan; - -//* Structure containing all internal global variables. -static struct -{ - CodeOutputInterface * code; // if set then we are codifying the file - int code_line; // current line of code - int code_linenumbers; // if true create line numbers in code - const char *code_font; // used font to codify - bool config_autobrief; // value of configuration option - QMap<QCString,QCString> config_subst; // map of configuration option values - QCString input_string; // file contents - int input_position; // position in file - QCString file_name; // name of used file - OutlineParserInterface *this_parser; // myself - int command; // true if command was found - int comment; // set true if comment was scanned - int brace_level; // bookkeeping of braces - int bracket_level; // bookkeeping of brackets - int bracket_quote; // bookkeeping of quotes (toggles) - char word_is; // type of current word: "\"" "{" "[" "?" " " - int line_comment; // line number of comment - int line_commentline; // line number of comment after command - int line_command; // line number of command - int line_body0; // start line of body - int line_body1; // end line of body - QCString string_command; // contain current command - QCString string_commentline; // contain current comment after command - QCString string_commentcodify; // current comment string used in codifying - QCString string_comment; // contain current comment - QCString string_last; // contain last read word or part of word - QCString string; // temporary string value - Entry* entry_main; // top level entry - Entry* entry_file; // entry of current file - Entry* entry_current; // currently used entry - Entry* entry_inside; // contain entry of current scan context - QCStringList list_commandwords; // list of command words - QList<tcl_scan> scan; // stack of scan contexts - QAsciiDict<Entry> ns; // all read namespace entries - QAsciiDict<Entry> cl; // all read class entries - QAsciiDict<Entry> fn; // all read function entries - QList<Entry> entry; // list of all created entries, will be deleted after codifying - Protection protection; // current protections state - const MemberDef *memberdef; // contain current MemberDef when codifying - bool collectXRefs; -} tcl; - -// scanner functions -static int yyread(char *buf,int max_size); -static tcl_scan *tcl_scan_start(char type, QCString content, QCString ns, Entry *entry_cls, Entry *entry_fn); -static void tcl_scan_end(); -static void tcl_comment(int what,const char *text); -static void tcl_word(int what,const char *text); -static void tcl_command(int what,const char *text); - -// helper functions - -//! Create new entry. -// @return new initialised entry -Entry* tcl_entry_new() -{ - Entry *myEntry = new Entry; - myEntry->section = Entry::EMPTY_SEC; - myEntry->name = ""; -// myEntry->type = ""; - myEntry->brief = ""; -// myEntry->doc = ""; - myEntry->protection = Public; -// myEntry->mtype = Method; -// myEntry->virt = Normal; -// myEntry->stat = FALSE; - myEntry->docFile = tcl.file_name; - myEntry->inbodyFile = tcl.file_name; - myEntry->fileName = tcl.file_name; - myEntry->lang = SrcLangExt_Tcl; - Doxygen::docGroup.initGroupInfo(myEntry); - // collect entries - if (!tcl.code) - { - tcl.entry.insert(0,myEntry); - } - return myEntry; -} - -//! Set protection level. -void tcl_protection(Entry *entry) -{ - if (entry->protection!=Public&&entry->protection!=Protected&&entry->protection!=Private) - { - entry->protection = tcl.protection; - } - if (entry->protection!=Protected&&entry->protection!=Private) - { - entry->protection = Public; - } -} - -//! Check name. -// @return 'ns' and 'name' of given current 'ns0' and 'name0' -static void tcl_name(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name) -{ - QCString myNm; - int myStart; - - if (qstrncmp(name0.data(),"::",2)==0) - { - myNm = name0.mid(2); - } - else if (ns0.length() && ns0 != " ") - { - myNm = ns0 + "::" + name0; - } - else - { - myNm = name0; - } - myStart = myNm.findRev("::"); - if (myStart == -1) - { - ns = ""; - name = myNm; - } - else if (myNm.length()-myStart == 2) - { - // ending with :: so get name equal to last component - ns = myNm.mid(0,myStart); - myStart = ns.findRev("::"); - name = myNm.mid(myStart+2); - } - else - { - ns = myNm.mid(0,myStart); - name = myNm.mid(myStart+2); - } -} - -//! Check name. Strip namespace qualifiers from name0 if inside inlined code segment. -// @return 'ns' and 'name' of given current 'ns0' and 'name0' -static void tcl_name_SnippetAware(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name) -{ - // If we are inside an inlined code snippet then ns0 - // already contains the complete namespace path. - // Any namespace qualifiers in name0 are redundant. - int i = name0.findRev("::"); - if (i>=0 && tcl.memberdef) - { - tcl_name(ns0, name0.mid(i+2), ns, name); - } - else - { - tcl_name(ns0, name0, ns, name); - } -} - -// Check and return namespace entry. -// @return namespace entry -Entry* tcl_entry_namespace(const QCString ns) -{ - Entry *myEntry; - if (ns.length()) - { - myEntry = tcl.ns.find(ns); - } - else - { - myEntry = tcl.ns.find("::"); - } - if (myEntry == NULL) - { - myEntry = tcl_entry_new(); - myEntry->section = Entry::NAMESPACE_SEC; - myEntry->name = ns; - tcl.entry_main->moveToSubEntryAndKeep(myEntry); - tcl.ns.insert(ns,myEntry); - } - return myEntry; -} - -// Check and return class entry. -// @return class entry -Entry* tcl_entry_class(const QCString cl) -{ - Entry *myEntry; - if (!cl.length()) return(NULL); - - myEntry = tcl.cl.find(cl); - if (myEntry == NULL) - { - myEntry = tcl_entry_new(); - myEntry->section = Entry::CLASS_SEC; - myEntry->name = cl; - tcl.entry_main->moveToSubEntryAndKeep(myEntry); - tcl.cl.insert(cl,myEntry); - } - return myEntry; -} - -//! Check for keywords. -// @return 1 if keyword and 0 otherwise -static int tcl_keyword(QCString str) -{ - static QCStringList myList; - static int myInit=1; - if (myInit) - { - // tcl keywords - myList <<"append"<<"apply"<<"array"<<"auto_execok"<<"auto_import"<<"auto_load"<<"auto_mkindex"<<"auto_qualify"<<"auto_reset"; - myList <<"binary"; - myList <<"catch"<<"cd"<<"close"<<"clock"<<"concat"; - myList <<"eof"<<"eval"<<"exec"<<"exit"<<"expr"; - myList <<"fblocked"<<"fconfigure"<<"file"<<"fileevent"<<"flush"<<"for"<<"foreach"<<"format"; - myList <<"gets"<<"global"; - myList <<"http"; - myList <<"if"<<"incr"<<"info"<<"interp"; - myList <<"join"; - myList <<"lappend"<<"lassign"<<"lindex"<<"linsert"<<"llength"<<"load"<<"lrange"<<"lrepeat"<<"lreplace"<<"lreverse"<<"lset"; - myList <<"namespace"; - myList <<"package"<<"parray"<<"pid"<<"pkg_mkIndex"<<"proc"<<"puts"<<"pwd"; - myList <<"registry"<<"rename"<<"return"; - myList <<"scan"<<"set"<<"split"<<"string"<<"switch"; - myList <<"tclLog"<<"tcl_endOfWord"<<"tcl_findLibrary"<<"tcl_startOfNextWord"<<"tcl_startOfPreviousWord"<<"tcl_wordBreakAfter"<<"tcl_wordBreakBefore"<<"tell"<<"time"; - myList <<"unknown"<<"upvar"; - myList <<"variable"<<"vwait"; -// tk keywords - myList <<"bell"<<"bind"<<"bindtags"; - myList <<"clipboard"<<"console"<<"consoleinterp"; - myList <<"destroy"; - myList <<"event"; - myList <<"focus"; - myList <<"grid"; - myList <<"lower"; - myList <<"option"; - myList <<"pack"<<"place"; - myList <<"raise"; - myList <<"send"; - myList <<"tkerror"<<"tkwait"<<"tk_bisque"<<"tk_focusNext"<<"tk_focusPrev"<<"tk_focusFollowsMouse"<<"tk_popup"<<"tk_setPalette"<<"tk_textCut"<<"tk_TextCopy"<<"tk_textPaste"<<"chooseColor"<<"tk_chooseColor"<<"tk_chooseDirectory"<<"tk_dialog"<<"tk_getOpenFile"<<"tkDialog"<<"tk_getSaveFile"<<"tk_messageBox"; - myList <<"winfo"<<"wm"; - myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel"; - //myList.sort(); - myInit=0; - } - str=str.stripWhiteSpace(); - if (str.left(2)=="::") {str=str.mid(2);} - if (myList.findIndex(str) != -1) return(1); - return 0; -} - -//! End codifying with special font class. -static void tcl_font_end() -{ - if (!tcl.code) return; - if (tcl.code_font) - { - tcl.code->endFontClass(); - tcl.code_font=NULL; - } -} - -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const char *str) -{ - if (!tcl.code || !str) return; - if (s && qstrcmp(s,"NULL")!=0) - { - tcl_font_end(); - tcl.code->startFontClass(s); - tcl.code_font=s; - } - char *tmp = (char *) malloc(strlen(str)+1); - strcpy(tmp, str); - char *p=tmp,*sp=p; - char c; - bool done=FALSE; - while (!done) - { - sp=p; - while ((c=*p++) && c!='\n') {} - if (c=='\n') - { - tcl.code_line++; - *(p-1)='\0'; // Dimitri: is this really needed? - // wtschueller: As far as I can see: yes. - // Deletes that \n that would produce ugly source listings otherwise. - // However, there may exist more sophisticated solutions. - tcl.code->codify(sp); - if (tcl.code_font) - { - tcl.code->endFontClass(); - } - tcl.code->endCodeLine(); - tcl.code->startCodeLine(tcl.code_linenumbers); - if (tcl.code_linenumbers) - { - tcl.code->writeLineNumber(0,0,0,tcl.code_line); - } - if (tcl.code_font) - { - tcl.code->startFontClass(tcl.code_font); - } - } - else - { - if (*(p-2)==0x1A) *(p-2) = '\0'; // remove ^Z - tcl.code->codify(sp); - done=TRUE; - } - } - free(tmp); - tcl_font_end(); -} - -#if 0 -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const char *str) -{ - if (tcl.code==NULL) return; - char *tmp= (char *) malloc(strlen(str)+1); - strcpy(tmp, str); - tcl_codify(s,tmp); - free(tmp); -} - -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const QCString &str) -{ - if (tcl.code==NULL) return; - tcl_codify(s,str); -} - -//! Codify 'str' with special font class 's'. -static void tcl_codify(const char *s,const QCString &str) -{ - if (!tcl.code) return; - tcl_codify(s,str.data()); -} -#endif - -static void tcl_codify_cmd(const char *s,int i) -{ - tcl_codify(s,(*tcl.list_commandwords.at(i))); -} -//! codify a string token -// -// codifies string according to type. -// Starts a new scan context if needed (*myScan==0 and type == "script"). -// Returns NULL or the created scan context. -// -static tcl_scan *tcl_codify_token(tcl_scan *myScan, const QCString type, const QCString string) -{ - if (myScan != NULL) - { - if (type != NULL) - { - myScan->after << type << string; - } - else - { - myScan->after << "NULL" << string; - } - } - else - { - if (qstrcmp(type, "script") == 0) - { - myScan = tcl.scan.at(0); - myScan = tcl_scan_start('?', string, - myScan->ns, myScan->entry_cl, myScan->entry_fn); - } - else - { - tcl_codify((const char*)type, string); - } - } - return myScan; -} - -//----------------------------------------------------------------------------- -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -//----------------------------------------------------------------------------- -%} -ws ([ \t]|\\\n) - -%option yylineno -%option noyywrap -%option stack - -%x ERROR -%x TOP -%x COMMAND -%x WORD -%x COMMENT -%x COMMENT_NL -%x COMMENT_CODE -%x COMMENT_VERB -%x COMMENTLINE -%x COMMENTLINE_NL -%% -<ERROR>. { -D - yyterminate(); -} -<<EOF>> { -D - if (tcl.scan.count()<1) - {// error -D - tcl_err("Tcl parser stack empty! Parser error in file '%s'.\n",tcl.file_name.data()); - yyterminate(); - } - else if (tcl.scan.count()==1) - {// exit, check on input? -D - yyterminate(); - } - else - {// continue -D - tcl_command(-1,""); - tcl_scan_end(); - } -} -<TOP>"#" { -D - yyless(0); - tcl.line_comment=yylineno; - tcl_comment(0,""); -} -<TOP>({ws}|[\;\n])+ { -D - tcl_codify(NULL,yytext); -} -<TOP>. { -D - yyless(0); - tcl.line_command=yylineno; - tcl_command(0,""); -} - -<COMMENT>[ \t]* { -D - tcl_codify("comment",yytext); -} -<COMMENT>"###".*\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext+1); -} -<COMMENT>"##".*\\\n { -D - tcl_codify("comment",yytext); - QCString t=yytext; - t = t.mid(2,t.length()-3); - t.append("\n"); - tcl_comment(1,t.data()); - yy_push_state(COMMENT_NL); -} -<COMMENT>"##".*\n { -D - tcl_codify("comment",yytext); - tcl_comment(1,yytext+2); -} -<COMMENT>"#"[@\\]"code"\n[ \t]*[^#] { -D - QCString t=yytext; - tcl_codify("comment",t.left(7)); - tcl_comment(2,"\n@code\n"); - yyless(7); - yy_push_state(COMMENT_CODE); -} -<COMMENT>"#"[@\\]"verbatim"\n[ \t]*[^#] { -D - QCString t=yytext; - tcl_codify("comment",t.left(11)); - tcl_comment(2,"\n@verbatim\n"); - yyless(11); - yy_push_state(COMMENT_VERB); -} -<COMMENT>"#".*\\\n { -D - tcl_codify("comment",yytext); - QCString t=yytext; - t = t.mid(1,t.length()-3); - t.append("\n"); - tcl_comment(2,t.data()); - yy_push_state(COMMENT_NL); -} -<COMMENT>"#".*\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext+1); -} -<COMMENT>"#".*\x1A { -D - QCString t=yytext; - t = t.mid(0,t.length()-1); - tcl_codify("comment",t.data()); - t = t.mid(1,t.length()); - tcl_comment(-2,t.data()); - unput(0x1A); -} -<COMMENT>\x1A { -D - tcl_comment(-2,""); - unput(0x1A); -} -<COMMENT>.|\n { -D - tcl_comment(-2,yytext); - yyless(0); -} - -<COMMENT_CODE>"#"[@\\]"endcode"\n { -D - QCString t=yytext; - t = t.left(t.length()-10); - tcl_comment(2,t.data()); - tcl_comment(2,"\n@endcode\n"); - yy_pop_state(); - yyless(0); -} -<COMMENT_CODE>.*\n { -D - yymore(); -} -<COMMENT_CODE>.*\x1A { -D - yy_pop_state(); - yyless(0); -} - -<COMMENT_VERB>"#"[@\\]"endverbatim"\n { -D - QCString t=yytext; - t = t.left(t.length()-14); - tcl_comment(2,t.data()); - tcl_comment(2,"\n@endverbatim\n"); - yy_pop_state(); - yyless(0); -} -<COMMENT_VERB>.*\n { -D - yymore(); -} -<COMMENT_VERB>.*\x1A { -D - yy_pop_state(); - yyless(0); -} - -<COMMENT_NL>.*\\\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext); -} -<COMMENT_NL>.*\n { -D - tcl_codify("comment",yytext); - tcl_comment(2,yytext); - yy_pop_state(); -} -<COMMENT_NL>.*\x1A { -D - yy_pop_state(); - yyless(0); -} - -<COMMENTLINE>.*\x1A { -D - yy_pop_state(); - yyless(0); -} -<COMMENTLINE>[ \t]* { -D - tcl.string_commentcodify += yytext; -} -<COMMENTLINE>"#<".*\\\n { -D - tcl.string_commentcodify += yytext; - QCString t=yytext; - t = t.mid(2,t.length()-4); - t.append("\n"); - tcl.string_commentline += t; - yy_push_state(COMMENTLINE_NL); -} -<COMMENTLINE>"#<".*\n { -D - tcl.string_commentcodify += yytext; - tcl.string_commentline += (yytext+2); -} -<COMMENTLINE>.|\n { -D - yy_pop_state(); - if (tcl.string_commentline.length()) - { - tcl.entry_current->brief = tcl.string_commentline; - tcl.entry_current->briefLine = tcl.line_commentline; - tcl.entry_current->briefFile = tcl.file_name; - } - yyless(0); - tcl_command(-1,tcl.string_commentcodify.data()); - tcl.string_commentline=""; - tcl.string_commentcodify=""; -} - -<COMMENTLINE_NL>.*\\\n { -D - tcl.string_commentcodify += yytext; - QCString t=yytext; - t = t.left(t.length()-3); - t.append("\n"); - tcl.string_commentline += t; -} -<COMMENTLINE_NL>.*\n { -D - tcl.string_commentcodify += yytext; - tcl.string_commentline += yytext; - yy_pop_state(); -} -<COMMENTLINE_NL>.*\x1A { -D - QCString t=yytext; - t = t.left(t.length()-1); - tcl.string_commentcodify += t; - tcl.string_commentline += t; - yy_pop_state(); - unput(0x1A); -} - -<COMMAND>{ws}*[\;]{ws}*"#<" { -D - tcl.string_commentcodify = yytext; - tcl.string_commentcodify = tcl.string_commentcodify.left(tcl.string_commentcodify.length()-2); - tcl.string_commentline = ""; - tcl.line_commentline = yylineno; - tcl.line_body1=yylineno; - unput('<'); - unput('#'); - yy_push_state(COMMENTLINE); -} -<COMMAND>{ws}*\x1A { -D - tcl.string_commentcodify = ""; - tcl.string_commentline = ""; - tcl.line_body1=yylineno; - tcl_command(-1,yytext); -} -<COMMAND>{ws}*; { -D - tcl.string_commentcodify = ""; - tcl.string_commentline = ""; - tcl.line_body1=yylineno; - tcl_command(-1,yytext); -} -<COMMAND>{ws}*\n { -D - tcl.string_commentcodify = ""; - tcl.string_commentline = ""; - tcl.line_body1=yylineno-1; - tcl_command(-1,yytext); -} -<COMMAND>{ws}+ { -D - tcl_command(1,yytext); -} -<COMMAND>"{*}". { -D - tcl.word_is = ' '; - tcl.string_last = "{*}"; - tcl_word(0,&yytext[3]); -} -<COMMAND>"\\"[\{\}\[\]\;\" \t] { -D - tcl.word_is=' '; - tcl.string_last = ""; - tcl_word(0,yytext); -} -<COMMAND>. { -D - tcl.word_is=' '; - if (yytext[0]=='{'||yytext[0]=='['||yytext[0]=='"') tcl.word_is = yytext[0]; - tcl.string_last = ""; - tcl_word(0,yytext); -} - -<WORD>"\\\\" | -<WORD>"\\"[\{\}\[\]\;\" \t] { - tcl_word(1,yytext); -} -<WORD>"\\\n" { - tcl_word(2,yytext); -} -<WORD>"{" { - tcl_word(3,yytext); -} -<WORD>"}" { - tcl_word(4,yytext); -} -<WORD>"[" { - tcl_word(5,yytext); -} -<WORD>"]" { - tcl_word(6,yytext); -} -<WORD>"\"" { - tcl_word(7,yytext); -} -<WORD>" " { - tcl_word(8,yytext); -} -<WORD>"\t" { - tcl_word(9,yytext); -} -<WORD>";" { - tcl_word(10,yytext); -} -<WORD>"\n" { - tcl_word(11,yytext); -} -<WORD>\x1A { - tcl_word(12,yytext); -} -<WORD>. { - tcl_word(1,yytext); -} -%% - -//! Start new scan context for given 'content'. -// @return created new scan context. -static tcl_scan *tcl_scan_start(char type, QCString content, QCString ns, Entry *entry_cl, Entry *entry_fn) -{ - tcl_scan *myScan=tcl.scan.at(0); -tcl_inf("line=%d type=%d '%s'\n",tcl.line_body0,type,content.data()); - - myScan->line1=yylineno; - yy_push_state(TOP); - - myScan=new tcl_scan; - myScan->type[0] =' '; - myScan->type[1] = '\0'; - switch (type) { - case '"': - case '{': - case '[': - myScan->type[0] = type; - break; - case '?': - if (content[0]=='"' && content[content.length()-1]=='"') myScan->type[0]='"'; - if (content[0]=='{' && content[content.length()-1]=='}') myScan->type[0]='{'; - if (content[0]=='[' && content[content.length()-1]==']') myScan->type[0]='['; - } - if (myScan->type[0]!=' ') - { - tcl_codify(NULL,&myScan->type[0]); - content = content.mid(1,content.length()-2); - } - content += (char)0x1A;// for detection end of scan context - myScan->ns = ns; - myScan->entry_cl = entry_cl; - myScan->entry_fn = entry_fn; - myScan->entry_scan = tcl.entry_current; - myScan->buffer_state=yy_scan_string(content.data()); - myScan->line0=tcl.line_body0; - myScan->line1=tcl.line_body1; - myScan->after.clear(); - yylineno=myScan->line0; - myScan->protection = tcl.protection; - - tcl.entry_inside = myScan->entry_scan; - tcl.entry_current = tcl_entry_new(); - tcl.scan.insert(0,myScan); - yy_switch_to_buffer(myScan->buffer_state); - return (myScan); -} - -//! Close current scan context. -static void tcl_scan_end() -{ - tcl_scan *myScan=tcl.scan.at(0); - tcl_scan *myScan1=tcl.scan.at(1); -tcl_inf("line=%d\n",myScan->line1); - - if (myScan->type[0]=='{') myScan->type[0]='}'; - if (myScan->type[0]=='[') myScan->type[0]=']'; - if (myScan->type[0]!=' ') tcl_codify(NULL,&myScan->type[0]); - int myStart=-1; - for (unsigned int i=0;i<myScan->after.count();i=i+2) - { - if (myScan->after[i]=="script") { - myStart=i; - break; - } - tcl_codify(myScan->after[i],myScan->after[i+1]); - } - yy_delete_buffer(myScan->buffer_state); - yy_pop_state(); - tcl.entry_inside = myScan1->entry_scan; - yy_switch_to_buffer(myScan1->buffer_state); - yylineno=myScan1->line1; - tcl.protection = myScan1->protection; - if (myStart>=0) - { - myScan1 = tcl_scan_start('?', myScan->after[myStart+1], myScan->ns, myScan->entry_cl, myScan->entry_fn); - for (unsigned int i=myStart+2;i<myScan->after.count();i++) - { - myScan1->after.append(myScan->after[i]); - } - tcl.scan.remove(1); - } - else - { - tcl.scan.removeFirst(); - } -} - -//! Handling of word parsing. -static void tcl_word(int what,const char *text) -{ - static char myList[1024]="";// nesting level list - static int myLevel=0;// number of current nesting level - static int myWhite=0;// set true when next char should be whitespace - static char myWord;// internal state - - switch (what) - { - case 0:// start - yy_push_state(WORD); - switch (text[0]) - { - case '{': - case '[': - case '"': myWord = text[0]; break; - default: myWord = '.'; - } - myList[0]=myWord; - myLevel=1; - myWhite=0; - break; - case 1:// all other chars - if (myWhite) - {// {x}y "x"y - tcl_err("expected word separator: %s\n",text); - return; - } - if (myLevel==0) - { - myWord='.'; - myList[0]=myWord; - myLevel=1; - } - break; - case 2:// \\\n - if (myLevel==0) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data()); - return; - } - switch (myList[myLevel-1]) - { - case '{': - case '[': - case '"': - break; - case '.': - if (myLevel==1) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data()); - return; - } - break; - } - myWhite=0; - break; - case 3:// { - if (myWhite) - {// {x}{ "x"{ - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - case '[': - myList[myLevel++]='{'; - break; - case '"': - case '.': - break; - } - myWhite=0; - break; - case 4:// } - if (myWhite) - {// {x}{ "x"{ - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{':// {{x}} - myLevel--; - if (myLevel==0 && !tcl.code) - { - myWhite=1; - } - break; - case '[': - case '"': - case '.': - break; - } - break; - case 5:// [ - if (myWhite) - {// {x}[ - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - break; - case '[': - case '"': - case '.': - myList[myLevel++]='['; - break; - } - myWhite=0; - break; - case 6:// ] - if (myWhite) - {// {x}] - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - break; - case '[': - myLevel--; - break; - case '"': - case '.': - break; - } - myWhite=0; - break; - case 7:// " - if (myWhite) - {// {x}" - tcl_err("expected word separator: %s\n",text); - return; - } - switch (myList[myLevel-1]) - { - case '{': - break; - case '[': - myList[myLevel++]='"'; - break; - case '"': - myLevel--; - case '.': - break; - } - break; - case 8:// ' ' - case 9:// \t - case 10:// ; - case 11:// \n - if (myLevel==0) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data()); - return; - } - switch (myList[myLevel-1]) - { - case '{': - case '[': - case '"': - break; - case '.': - if (myLevel==1) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data()); - return; - } - else - { - myLevel--; - } - break; - } - myWhite=0; - break; - case 12:// \x1A - if (myLevel==0) - { - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data()); - return; - } - if (myLevel!=1 || myList[0] != '.') - { - tcl_war("level=%d expected=%c\n",myLevel,myList[myLevel-1]); - } - myWord=' '; - yy_pop_state(); - yyless(0); -tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data()); - return; - break; - default: - tcl_err("wrong state: %d\n",what); - return; - } - tcl.string_last += text; -} - -//! Handling of comment parsing. -static void tcl_comment(int what,const char *text) -{ - if (what==0) - { // begin of comment - if (tcl.comment) - { - tcl_err("comment in comment\n"); - return; - } - yy_push_state(COMMENT); -tcl_inf("<- %s\n",text); - tcl.string_comment=""; - tcl.comment=0; - } - else if (what==1) - { // start new comment - if (tcl.comment) - { - tcl_comment(99,""); // inbody - } - tcl.string_comment=text; - tcl.comment=1; - } - else if (what==2) - { // add to comment - if (tcl.comment) - { - tcl.string_comment+=text; - } - } - else if (what==-1 || what == -2) - { // end of comment without/with command - if (tcl.comment) - { - tcl.string_last=tcl.string_comment; - tcl_comment(100+what,""); - } - else - { - tcl.string_last = ""; -tcl_inf("-> %s\n",(const char *)tcl.string_comment); - } - yy_pop_state(); - tcl.string_comment=""; - tcl.comment=0; - } - else if (what==98 || what==99) - { // 98=new 99=inbody - if (tcl.this_parser && tcl.string_comment.length()) - { -tcl_inf("-> %s\n",(const char *)tcl.string_comment); - int myPos=0; - bool myNew=false; - int myLine=tcl.line_comment; - BufStr myI(1024); - BufStr myO(1024); - Protection myProt=tcl.protection; - - // resolve ALIASES - myI.addArray("/*!",3); - myI.addArray(tcl.string_comment.data(),tcl.string_comment.length()); - myI.addArray("*/",2); - convertCppComments(&myI,&myO,tcl.file_name); - myO.dropFromStart(3); - myO.shrink(myO.curPos()-2); - myO.addChar('\0'); - QCString myDoc = myO.data(); - QCString processedDoc; - if (what==99) - { // inbody comment file or namespace or class or proc/method - int myPos0; - int myLine0; - Entry myEntry0; // used to test parsing - Entry *myEntry; - - Entry *myEntry1=NULL; - if (tcl.scan.at(0)->entry_fn) - { - myEntry1=tcl.scan.at(0)->entry_fn; - } - else if (tcl.scan.at(0)->entry_cl) - { - myEntry1=tcl.scan.at(0)->entry_cl; - } - - myPos0=myPos; - myLine0=myLine; - processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine); - while (parseCommentBlock(tcl.this_parser, &myEntry0, processedDoc, tcl.file_name, - myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew)) - { - if (myNew) - { // we need a new entry in this case - myNew=0; - myEntry = tcl_entry_new(); - processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); - parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - tcl.entry_inside->moveToSubEntryAndRefresh(myEntry); - } - else - { // we can add to current entry in this case - if (!myEntry1) - { - myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns); - } - processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); - parseCommentBlock(tcl.this_parser, myEntry1, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - } - myPos0=myPos; - myLine0=myLine; - } - if (myNew) - { // we need a new entry - myNew=0; - myEntry = tcl_entry_new(); - processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); - parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - tcl.entry_inside->moveToSubEntryAndKeep(myEntry); - } - else - { // we can add to current entry - if (!myEntry1) - { - myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns); - } - processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); - parseCommentBlock(tcl.this_parser, myEntry1, processedDoc, tcl.file_name, - myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - } - } - else - { // new entry - tcl.entry_current = tcl_entry_new(); - processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine); - while (parseCommentBlock(tcl.this_parser, tcl.entry_current, processedDoc, - tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE, - myProt, myPos, myNew)) - { - if (myNew) - { - tcl.entry_inside->moveToSubEntryAndKeep(tcl.entry_current); - tcl.entry_current = tcl_entry_new(); - } - else - { - tcl.entry_current->section = tcl.entry_inside->section; - tcl.entry_current->name = tcl.entry_inside->name; - } - } - if (myNew) - { - tcl.entry_inside->moveToSubEntryAndKeep(tcl.entry_current); - tcl.entry_current = tcl_entry_new(); - } - else - { - tcl.entry_current->section = tcl.entry_inside->section; - tcl.entry_current->name = tcl.entry_inside->name; - } - } - if (tcl.protection != myProt) - { - tcl.scan.at(0)->protection = tcl.protection = myProt; - } - } - } - else - { - tcl_err("what %d\n",what); - return; - } -} - -//! Parse given \c arglist . -static void tcl_command_ARGLIST(QCString &arglist) -{ -D - QCStringList myArgs; - QCString myArglist=""; - - tcl_split_list(arglist,myArgs); - for (uint i=0;i<myArgs.count();i++) - { - QCStringList myArgs1; - Argument myArg; - - tcl_split_list(*myArgs.at(i),myArgs1); - if (myArgs1.count()==2) - { - myArg.name= (*myArgs1.at(0)); - myArg.defval= (*myArgs1.at(1)); - if (myArg.defval.isEmpty()) - { - myArg.defval = " "; - } - myArglist += "?" + QCString(myArg.name) + "? "; - } - else - { - myArg.name= (*myArgs.at(i)); - myArglist += myArg.name + " "; - } - tcl.entry_current->argList.push_back(myArg); - } - arglist = myArglist; - tcl.entry_current->args = arglist; -} - -//! Create link. -static void tcl_codify_link(QCString name) -{ - if (tcl.code == NULL || name.isEmpty()) return; - static int init=0; - static QAsciiDict<MemberDef> fn; - if (init==0) - { - init=1; - MemberNameSDict::Iterator mni(*Doxygen::memberNameSDict); - MemberNameSDict::Iterator fni(*Doxygen::functionNameSDict); - MemberName *mn=0; - MemberDef *md; - for (mni.toFirst();(mn=mni.current());++mni) - { - MemberNameIterator mi(*mn); - for (mi.toFirst();(md=mi.current());++mi) - { - fn.insert(md->qualifiedName(),md); - } - } - for (fni.toFirst();(mn=fni.current());++fni) - { - MemberNameIterator fi(*mn); - for (fi.toFirst();(md=fi.current());++fi) - { - fn.insert(md->qualifiedName(),md); - } - } - } - MemberDef *myDef; - QCString myName=name; - if (name.mid(0,2)=="::") // fully qualified global command - { - myName = myName.mid(2); - myDef = fn.find(myName); - } - else // not qualified name - { - QCString myName1=myName; - myDef = NULL; - myName1 = tcl.scan.at(0)->ns; - if (myName1 == " " || myName1 == "") - { - myName1 = myName; - } - else - { - myName1 = myName1 + "::" + myName; - } - myDef = fn.find(myName1); // search namespace command - if (myDef == NULL) - { - myDef = fn.find(myName); // search global command - } - } - if (myDef != NULL) // documented command - { - tcl.code->writeCodeLink(myDef->getReference().data(), - myDef->getOutputFileBase().data(), - myDef->anchor().data(), - name, - myDef->qualifiedName().data()); - if (tcl.memberdef) - { - myDef->addSourceReferencedBy(tcl.memberdef); - //tcl.memberdef->addSourceReferences(myDef); - } else { - Entry* callerEntry; - unsigned int i; - // walk the stack of scan contexts and find the enclosing method or proc - for (i=0;i<tcl.scan.count();i++) - { - callerEntry=tcl.scan.at(i)->entry_scan; - if (callerEntry->mtype==Method && !callerEntry->name.isEmpty()) - { - break; - } - } - if (i<tcl.scan.count()) - { - // enclosing method found - QCString callerName = callerEntry->name; - if (callerName.mid(0,2)=="::") // fully qualified global command - { - callerName = callerName.mid(2); - } - else - { - if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty())) - { - callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name; - } - } - MemberDef *callerDef=NULL; - callerDef = fn.find(callerName); - if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs) - { - addDocCrossReference(callerDef,myDef); - } - } - } - } - else if (tcl_keyword(myName)) // check keyword - { - tcl_codify("keyword",name); - } - else - { - tcl_codify(NULL,name); // something else - } - -} - -//! scan general argument for brackets -// -// parses (*tcl.list_commandwords.at(i)) and checks for brackets. -// Starts a new scan context if needed (*myScan==0 and brackets found). -// Returns NULL or the created scan context. -// -static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces) -{ - QCString myName; - bool insideQuotes=false; - unsigned int insideBrackets=0; - unsigned int insideBraces=0; - myName = (*tcl.list_commandwords.at(i)); - if (i%2 != 0) - { - // handle white space - myScan = tcl_codify_token(myScan, "NULL", myName); - } - else - { - QCString myStr = ""; - unsigned int j; - for (j=0;j<myName.length();j++) - { - QChar c = myName[j]; - bool backslashed = false; - if (j>0) - { - backslashed = myName[j-1]=='\\'; - } - // this is a state machine - // input is c - // internal state is myScan and insideXXX - // these are the transitions: - if (c=='[' && !backslashed && insideBraces==0) - { - insideBrackets++; - } - if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0) - { - insideBrackets--; - } - if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0)) - { - insideBraces++; - } - if (c=='}' && !backslashed && !insideQuotes && insideBraces>0) - { - insideBraces--; - } - if (c=='"' && !backslashed && insideBraces==0) - { - insideQuotes=!insideQuotes; - } - // all output, depending on state and input - if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0) - { - // the first opening bracket, output what we have so far - myStr+=c; - myScan = tcl_codify_token(myScan, "NULL", myStr); - myStr=""; - } - else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0) - { - // the last closing bracket, start recursion, switch to deferred - myScan = tcl_codify_token(myScan, "script", myStr); - myStr=""; - myStr+=c; - } - else - { - myStr+=c; - } - } - if (i == 0 && myScan == NULL) - { - tcl_codify_link(myStr); - } - else - { - myScan = tcl_codify_token(myScan, "NULL", myStr); - } - } - return (myScan); -} - -//! Handle internal tcl commands. -// "eval arg ?arg ...?" -static void tcl_command_EVAL() -{ -D - tcl_codify_cmd("keyword", 0); - tcl_scan *myScan = tcl.scan.at(0); - QCString myString = ""; - // we simply rescan the line without the eval - // we include leading whitespace because tcl_scan_start will examine - // the first char. If it finds a bracket it will assume one expression in brackets. - // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked] - for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++) - { - myString += (*tcl.list_commandwords.at(i)); - } - myScan = tcl_scan_start('?', myString, - myScan->ns, myScan->entry_cl, myScan->entry_fn); -} - -//! Handle internal tcl commands. -// switch ?options? string pattern body ?pattern body ...? -// switch ?options? string {pattern body ?pattern body ...?} -static void tcl_command_SWITCH() -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan=NULL; - unsigned int i; - QCString token; - // first: find the last option token - unsigned int lastOptionIndex = 0; - for (i = 2; i<tcl.list_commandwords.count(); i += 2) - { - token = (*tcl.list_commandwords.at(i)); - if (token == "--") - { - lastOptionIndex = i; - break; - } - if (token[0] == '-' && i - lastOptionIndex == 2) - { - // options start with dash and should form a continuous chain - lastOptionIndex = i; - } - } - // second: eat up options - for (i = 2; i <= lastOptionIndex; i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } - // third: how many tokens are left? - if (tcl.list_commandwords.count() - lastOptionIndex == 5) - { - //printf("syntax: switch ?options? string {pattern body ?pattern body ...?}\n"); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 3, false); - // walk trough the list step by step - // this way we can preserve whitespace - bool inBraces = false; - bool nextIsPattern = true; - int size; - const char *elem; - const char *next; - token = (*tcl.list_commandwords.at(lastOptionIndex + 4)); - if (token[0] == '{') - { - inBraces = true; - token = token.mid(1, token.length() - 2); - myScan = tcl_codify_token(myScan, "NULL", QCString("{")); - } - // ToDo: check if multibyte chars are handled correctly - while (token.length() > 0) - { - TclFindElement((const char*)token, token.length(), &elem, &next, &size, NULL); - //printf("%s\nstart=%d, elem=%d, next=%d, size=%d, brace=%d\n", - // (const char*) token, (const char*) token, elem, next, size, brace); - // - // handle leading whitespace/opening brace/double quotes - if (elem - token > 0) - { - myScan = tcl_codify_token(myScan, "NULL", token.left(elem - token)); - } - // handle actual element without braces/double quotes - if (nextIsPattern) - { - myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token,size)); - //printf("pattern=%s\n",(const char*) token.mid(elem - token, size)); - } - else { - myScan = tcl_codify_token(myScan, "script", token.mid(elem - token, size)); - //printf("script =%s\n", (const char*) token.mid(elem - token, size)); - } - // handle trailing whitespace/closing brace/double quotes - if (next - elem - size > 0) - { - myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token + size, next - elem - size)); - } - nextIsPattern = !nextIsPattern; - token = token.mid(next - token); - } - if (inBraces) - { - myScan = tcl_codify_token(myScan, "NULL", QCString("}")); - } - if (!nextIsPattern) - { - tcl_war("Invalid switch syntax: last token is not a list of even elements.\n"); - //tcl_war("%s\n", tcl.list_commandwords.join(" ").ascii()); - } - } - else if ((tcl.list_commandwords.count() - lastOptionIndex > 6) && - ((tcl.list_commandwords.count() - lastOptionIndex-3) % 4 == 0)) - { - //printf("detected: switch ?options? string pattern body ?pattern body ...?\n"); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false); - myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false); - //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2))); - for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4) - { - myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace - myScan = tcl_command_ARG(myScan, i + 1, false); // pattern - myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace - myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3))); // script - //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)))); - //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3))); - } - } - else - { - // not properly detected syntax - tcl_war("Invalid switch syntax: %d options followed by %d tokens.\n", - lastOptionIndex / 2, (tcl.list_commandwords.count() - 1) / 2 - lastOptionIndex / 2); - for (i = lastOptionIndex + 1; i <= tcl.list_commandwords.count(); i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } - } -} - -//! Handle internal tcl commands. -// "catch script ?resultVarName? ?optionsVarName?" -static void tcl_command_CATCH() -{ -D - tcl_codify_cmd("keyword", 0); - tcl_codify_cmd(NULL, 1); - tcl_scan *myScan = tcl.scan.at(0); - myScan = tcl_scan_start('?', *tcl.list_commandwords.at(2), - myScan->ns, myScan->entry_cl, myScan->entry_fn); - for (unsigned int i = 3; i < tcl.list_commandwords.count(); i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } -} - -//! Handle internal tcl commands. -// "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?" -static void tcl_command_IF(QCStringList type) -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan = NULL; - myScan = tcl_command_ARG(myScan, 2, true); - for (unsigned int i = 3;i<tcl.list_commandwords.count();i++) - { - if (type[i] == "expr") - { - myScan = tcl_command_ARG(myScan, i, true); - } - else - { - if (myScan!=0) - { - myScan->after << type[i] << tcl.list_commandwords[i]; - } - else - { - myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - } - } - } -} -//! Handle internal tcl commands. -// "for start test next body" -static void tcl_command_FOR() -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - myScan->after << "NULL" << tcl.list_commandwords[3]; - myScan = tcl_command_ARG(myScan, 4, true); - myScan->after << "NULL" << tcl.list_commandwords[5]; - myScan->after << "script" << tcl.list_commandwords[6]; - myScan->after << "NULL" << tcl.list_commandwords[7]; - myScan->after << "script" << tcl.list_commandwords[8]; -} - -///! Handle internal tcl commands. -// "foreach varname list body" and -// "foreach varlist1 list1 ?varlist2 list2 ...? body" -static void tcl_command_FOREACH() -{ -D - unsigned int i; - tcl_scan *myScan=NULL; - tcl_codify_cmd("keyword",0); - for (i = 1;i<tcl.list_commandwords.count()-1;i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } - if (myScan!=0) - { - myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1]; - } - else - { - myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - } -} - -///! Handle internal tcl commands. -// "while test body" -static void tcl_command_WHILE() -{ -D - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_scan *myScan = NULL; - myScan = tcl_command_ARG(myScan, 2, true); - myScan = tcl_command_ARG(myScan, 3, false); - if (myScan!=0) - { - myScan->after << "script" << tcl.list_commandwords[4]; - } - else - { - myScan=tcl.scan.at(0); - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - } -} - -//! Handle all other commands. -// Create links of first command word or first command word inside []. -static void tcl_command_OTHER() -{ - tcl_scan *myScan=NULL; - for (unsigned int i=0; i< tcl.list_commandwords.count(); i++) - { - myScan = tcl_command_ARG(myScan, i, false); - } -} - -//! Handle \c proc statements. -static void tcl_command_PROC() -{ -D - QCString myNs, myName; - Entry *myEntryNs; - Entry *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd(NULL,2); - tcl_codify_cmd(NULL,3); - tcl_codify_cmd(NULL,4); - tcl_codify_cmd(NULL,5); - tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myEntryNs = tcl_entry_namespace(myNs); - } - else - { - myEntryNs = tcl_entry_namespace(myScan->ns); - } - //why not needed here? tcl.fn.remove(myName); - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - tcl_command_ARGLIST(*tcl.list_commandwords.at(4)); - myEntryNs->moveToSubEntryAndKeep(tcl.entry_current); - myEntry = tcl.entry_current; - tcl.fn.insert(myName,myEntry); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), - myEntryNs->name,NULL,myEntry); -} - -//! Handle \c itcl::body statements and \c oo::define method and method inside \c itcl::class statements. -static void tcl_command_METHOD() -{ -D - QCString myNs, myName; - Entry *myEntryCl, *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd(NULL,2); - tcl_codify_cmd(NULL,3); - tcl_codify_cmd(NULL,4); - tcl_codify_cmd(NULL,5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myEntryCl = tcl_entry_class(myNs); - } - else - { - myNs = myScan->ns; - myEntryCl = myScan->entry_cl; - } - // needed in case of more then one definition p.e. itcl::method and itcl::body - // see also bug # - tcl.fn.remove(myName); - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - tcl_command_ARGLIST(*tcl.list_commandwords.at(4)); - myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - tcl.fn.insert(myName,tcl.entry_current); - myEntry = tcl.entry_current; - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), - myNs, myEntryCl, myEntry); -} - -//! Handle \c constructor statements inside class definitions. -static void tcl_command_CONSTRUCTOR() -{ -D - QCString myNs, myName; - Entry *myEntryCl, *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd(NULL,2); - tcl_codify_cmd(NULL,3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName); - if (myNs.length()) - { - myEntryCl = tcl_entry_class(myNs); - } - else - { - myNs = myScan->ns; - myEntryCl = myScan->entry_cl; - } - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - tcl_command_ARGLIST(*tcl.list_commandwords.at(2)); - if (myEntryCl) myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - myEntry = tcl.entry_current; - tcl.fn.insert(myName,myEntry); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4), - myNs, myEntryCl, myEntry); -} - -//! Handle \c destructor statements inside class definitions. -static void tcl_command_DESTRUCTOR() -{ -D - QCString myNs, myName; - Entry *myEntryCl, *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName); - if (myNs.length()) - { - myEntryCl = tcl_entry_class(myNs); - } - else - { - myNs = myScan->ns; - myEntryCl = myScan->entry_cl; - } - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - myEntry = tcl.entry_current; - tcl.fn.insert(myName,myEntry); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2), - myNs, myEntryCl, myEntry); -} - -//! Handle \c namespace statements. -static bool tcl_command_NAMESPACE() -{ -D - QCString myNs, myName, myStr; - //Entry *myEntryNs=NULL; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); - if (myName.isEmpty()) return false; // not a namespace - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("keyword",2); - tcl_codify_cmd(NULL,3); - tcl_codify_cmd(NULL,4); - tcl_codify_cmd(NULL,5); - if (!myNs.isEmpty()) - { - myName = myNs+"::"+myName; - } - tcl.entry_current->section = Entry::NAMESPACE_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); - tcl.ns.insert(myName,tcl.entry_current); - //myEntryNs = tcl.entry_current; - myStr = (*tcl.list_commandwords.at(6)); - if (tcl.list_commandwords.count() > 7) - { - for (uint i=7;i<tcl.list_commandwords.count();i++) - { - myStr.append((*tcl.list_commandwords.at(i))); - } - tcl.word_is=' '; - } - myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL); - return true; -} - -//! Handle \c itcl::class statements. -static void tcl_command_ITCL_CLASS() -{ -D - QCString myNs, myName; - Entry *myEntryCl; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("NULL",2); - tcl_codify_cmd("NULL",3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myName = myNs+"::"+myName; - } - tcl.entry_current->section = Entry::CLASS_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); - tcl.cl.insert(myName,tcl.entry_current); - myEntryCl = tcl.entry_current; - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4), - myName, myEntryCl, NULL); -} - -//! Handle \c oo::class statements. -static void tcl_command_OO_CLASS() -{ -D - QCString myNs, myName; - //Entry *myEntryNs; - Entry *myEntryCl; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("NULL",2); - tcl_codify_cmd("NULL",3); - tcl_codify_cmd("NULL",4); - tcl_codify_cmd("NULL",5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); - if (myNs.length()) - { - myName = myNs+"::"+myName; - } - tcl.entry_current->section = Entry::CLASS_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); - //myEntryNs = tcl_entry_namespace(myName); - tcl.cl.insert(myName,tcl.entry_current); - myEntryCl = tcl.entry_current; - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), - myName, myEntryCl, NULL); -} - -//! Handle \c oo::define statements. -static void tcl_command_OO_DEFINE() -{ -D - QCString myNs, myName, myStr; - Entry *myEntryCl; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl_codify_cmd("NULL",2); - tcl_codify_cmd("NULL",3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - { - myName = myNs+"::"+myName; - } - myEntryCl = tcl_entry_class(myName); - myStr = (*tcl.list_commandwords.at(4)); - // - // special cases first - // oo::define classname method methodname args script - // oo::define classname constructor argList bodyScript - // oo::define classname destructor bodyScript - unsigned int n =tcl.list_commandwords.count(); - if ((myStr == "method" && n == 11) || - (myStr == "constructor" && n == 9) || - (myStr == "destructor" && n == 7)) - { - for (unsigned int i = 4; i < n-1; i++) - { - tcl_codify_cmd("NULL",i); - } - Entry *myEntry; - QCString myMethod; - tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)),myNs,myMethod); - // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR - tcl.fn.remove(myMethod); - tcl.entry_current->section = Entry::FUNCTION_SEC; - tcl.entry_current->mtype = Method; - tcl.entry_current->name = myMethod; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - if (n==11) - { - tcl_command_ARGLIST(*tcl.list_commandwords.at(8)); - } - else if (n==9) - { - tcl_command_ARGLIST(*tcl.list_commandwords.at(6)); - } - if (myEntryCl) myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); - tcl.fn.insert(myMethod,tcl.entry_current); - myEntry = tcl.entry_current; - myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1), - myNs, myEntryCl, myEntry); - } - else - { - // The general case - // Simply concat all arguments into a script. - // Note: all documentation collected just before the - // oo::define command is lost - if (tcl.list_commandwords.count() > 5) - { - for (uint i=5;i<tcl.list_commandwords.count();i++) - { - myStr.append((*tcl.list_commandwords.at(i))); - } - tcl.word_is=' '; - } - myScan = tcl_scan_start(tcl.word_is,myStr,myName,myEntryCl,NULL); - } -} - -//! Handle \c variable statements. -static void tcl_command_VARIABLE(int inclass) -{ -D - QCString myNs, myName; - Entry *myEntry; - tcl_scan *myScan = tcl.scan.at(0); - - tcl_codify_cmd("keyword",0); - for (unsigned int i=1; i< tcl.list_commandwords.count(); i++) - { - tcl_codify_cmd(NULL,i); - } - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); - if (myNs.length()) - {// qualified variables go into namespace - myEntry = tcl_entry_namespace(myNs); - tcl.entry_current->stat = true; - } - else - { - if (inclass) - { - myEntry = myScan->entry_cl; - tcl.entry_current->stat = false; - } - else - { - myEntry = tcl_entry_namespace(myScan->ns); - tcl.entry_current->stat = true; - } - } - tcl.entry_current->section = Entry::VARIABLE_SEC; - tcl.entry_current->name = myName; - tcl.entry_current->startLine = tcl.line_command; - tcl.entry_current->docLine = tcl.line_comment; - tcl.entry_current->inbodyLine = tcl.line_comment; - tcl.entry_current->bodyLine = tcl.line_body0; - tcl.entry_current->endBodyLine = tcl.line_body1; - tcl_protection(tcl.entry_current); - myEntry->moveToSubEntryAndKeep(tcl.entry_current); - tcl.entry_current = tcl_entry_new(); -} - -//! Handling of command parsing. -//! what=0 -> ... -//! what=1 -> ... -//! what=-1 -> ... -static void tcl_command(int what,const char *text) -{ - int myLine=0; - if (what==0) - { - tcl.scan.at(0)->line1=yylineno;// current line in scan context - tcl.line_body0=yylineno;// start line of command -tcl_inf("<- %s\n",text); - yy_push_state(COMMAND); - tcl.list_commandwords.clear(); - tcl.string_command=""; - tcl.string_last=""; - tcl.command=1; - return; - } - else if (what==1) - { - if (tcl.string_last.length()) - { - tcl.list_commandwords.append(tcl.string_last); - tcl.string_last=""; - } - if (text) - { - tcl.list_commandwords.append(text); - } - return; - } - else if (what!=-1) - {// should not happen - tcl_err("what %d\n",what); - return; - } - QCString myText = text; -tcl_inf("->\n"); - if (tcl.command==0) - { - return; //TODO check on inside comment - } - if (tcl.string_last != "") - {// get last word - tcl.list_commandwords.append(tcl.string_last); - tcl.string_last=""; - } - yy_pop_state(); - - // check command - QCString myStr = (*tcl.list_commandwords.at(0)); - tcl_scan *myScanBackup=tcl.scan.at(0); - int myLevel = 0; - Protection myProt = tcl.protection; - - if (tcl.list_commandwords.count() < 3) - { - tcl_command_OTHER(); - goto command_end; - } - // remove leading "::" and apply TCL_SUBST - if (myStr.left(2)=="::") myStr = myStr.mid(2); - if (tcl.config_subst.contains(myStr)) - { - myStr=tcl.config_subst[myStr]; - } - if (myStr=="private") - { - tcl.protection = Private; - myLevel = 1; - } - else if (myStr=="protected") - { - tcl.protection = Protected; - myLevel = 1; - } - else if (myStr=="public") - { - tcl.protection = Public; - myLevel = 1; - } - if (myLevel) - { - tcl_codify_cmd("keyword",0); - tcl_codify_cmd(NULL,1); - tcl.list_commandwords.remove(tcl.list_commandwords.at(1)); - tcl.list_commandwords.remove(tcl.list_commandwords.at(0)); - if (tcl.list_commandwords.count()==1) - { - tcl_scan *myScan = tcl.scan.at(0); - myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(0), - myScan->ns,myScan->entry_cl,myScan->entry_fn); - myProt = tcl.protection; - goto command_end; - } - myStr = (*tcl.list_commandwords.at(0)); - // remove leading "::" and apply TCL_SUBST - if (myStr.left(2)=="::") myStr = myStr.mid(2); - if (tcl.config_subst.contains(myStr)) - { - myStr=tcl.config_subst[myStr]; - } - } - if (myStr=="proc") - { - if (tcl.list_commandwords.count() == 5) - {// itcl::proc - tcl.list_commandwords.append(""); - tcl.list_commandwords.append(""); - } - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_PROC(); - goto command_end; - } - if (myStr=="method") - { - if (tcl.list_commandwords.count() == 5) - {// itcl::method - tcl.list_commandwords.append(""); - tcl.list_commandwords.append(""); - } - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_METHOD(); - goto command_end; - } - if (myStr=="constructor") - { - if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;} - tcl_command_CONSTRUCTOR(); - goto command_end; - } - if (myStr=="destructor") - { - if (tcl.list_commandwords.count() != 3) {myLine=__LINE__;goto command_warn;} - tcl_command_DESTRUCTOR(); - goto command_end; - } - if (myStr=="namespace") - { - if ((*tcl.list_commandwords.at(2))=="eval") - { - if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;} - if (tcl_command_NAMESPACE()) - { - goto command_end; - } - } - else - { - tcl_command_OTHER(); - goto command_end; - } - } - if (myStr=="itcl::class") - { - if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;} - tcl_command_ITCL_CLASS(); - goto command_end; - } - if (myStr=="itcl::body") - { - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_METHOD(); - goto command_end; - } - if (myStr=="oo::class") - { - if ((*tcl.list_commandwords.at(2))=="create") - { - if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} - tcl_command_OO_CLASS(); - goto command_end; - } - tcl_command_OTHER(); - goto command_end; - } - if (myStr=="oo::define") - { - if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;} - tcl_command_OO_DEFINE(); - goto command_end; - } - if (myStr=="variable") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - if (tcl.scan.at(0)->entry_fn == NULL) - {// only parsed outside functions - tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!=""); - goto command_end; - } - } - if (myStr=="common") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - if (tcl.scan.at(0)->entry_fn == NULL) - {// only parsed outside functions - tcl_command_VARIABLE(0); - goto command_end; - } - } - if (myStr=="inherit" || myStr=="superclass") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - if (tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="") - { - for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2) - { - tcl.scan.at(0)->entry_cl->extends.push_back(BaseInfo((*tcl.list_commandwords.at(i)),Public,Normal)); - } - } - goto command_end; - } - /* - * Start of internal tcl keywords - * Ready: switch, eval, catch, if, for, foreach, while - */ - if (myStr=="switch") - { - if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;} - tcl_command_SWITCH(); - goto command_end; - } - if (myStr=="eval") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - tcl_command_EVAL(); - goto command_end; - } - if (myStr=="catch") - { - if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;} - tcl_command_CATCH(); - goto command_end; - } - if (myStr=="for") - { - if (tcl.list_commandwords.count() != 9) {myLine=__LINE__;goto command_warn;} - tcl_command_FOR(); - goto command_end; - } - if (myStr=="foreach") - { - if (tcl.list_commandwords.count() < 7 || tcl.list_commandwords.count()%2==0) {myLine=__LINE__;goto command_warn;} - tcl_command_FOREACH(); - goto command_end; - } - /* -if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN? - */ - if (myStr=="if" && tcl.list_commandwords.count() > 4) - { - QCStringList myType; - myType << "keyword" << "NULL" << "expr" << "NULL"; - char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f.. - for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2) - { - QCString myStr=(*tcl.list_commandwords.at(i)); - if (myState=='x') - { - if (myStr=="then") - { - myState='t'; - myType << "keyword" << "NULL"; - } - else - { - myState='b'; - myType << "script" << "NULL"; - } - } - else if (myState=='t') - { - myState='b'; - myType << "script" << "NULL"; - } - else if (myState=='b') - { - if (myStr=="elseif") { - myState='i'; - myType << "keyword" << "NULL"; - } - else if (myStr=="else" && i==tcl.list_commandwords.count()-3) - { - myState = 'b'; - myType << "keyword" << "NULL" << "script"; - i = tcl.list_commandwords.count(); - } - else if (i==tcl.list_commandwords.count()-1) - { - myState = 'b'; - myType << "script"; - i = tcl.list_commandwords.count(); - } - else - { - myLine=__LINE__;goto command_warn; - } - } - else if (myState=='i') - { - myState='x'; - myType << "expr" << "NULL"; - } - } - if (myState != 'b') {myLine=__LINE__;goto command_warn;} - tcl_command_IF(myType); - goto command_end; - } - if (myStr=="while") - { - if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;} - tcl_command_WHILE(); - goto command_end; - } - tcl_command_OTHER(); - goto command_end; - command_warn:// print warning message because of wrong used syntax - tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").data()); - tcl_command_OTHER(); - command_end:// add remaining text to current context - if (!myText.isEmpty()) - { - if(myScanBackup==tcl.scan.at(0)) - { - tcl_codify("comment",myText); - } - else - { - tcl.scan.at(0)->after << "comment" << myText; - } - } - tcl.list_commandwords.clear(); - tcl.command = 0; - tcl.protection = myProt; -} - -//---------------------------------------------------------------------------- -//! Common initializations. -static void tcl_init() -{ - // Get values from option TCL_SUBST - tcl.config_subst.clear(); - QStrList myStrList = Config_getList(TCL_SUBST); - const char *s=myStrList.first(); - while (s) - { - QCString myStr=s; - int i=myStr.find('='); - if (i>0) - { - QCString myName=myStr.left(i).stripWhiteSpace(); - QCString myValue=myStr.right(myStr.length()-i-1).stripWhiteSpace(); - if (!myName.isEmpty() && !myValue.isEmpty()) - tcl_inf("TCL_SUBST: use '%s'\n",s); - tcl.config_subst[myName] = myValue; - } - s = myStrList.next(); - } - - if (tcl.input_string.at(tcl.input_string.length()-1) == 0x1A) - { - } - else if (tcl.input_string.at(tcl.input_string.length()-1) == '\n') - { - tcl.input_string[tcl.input_string.length()-1] = 0x1A; - } - else - { - tcl.input_string += 0x1A; - } - - tcl.code = NULL; - tcl.code_font=NULL; - tcl.code_line=1; - tcl.code_linenumbers=1; - tcl.config_autobrief = Config_getBool(JAVADOC_AUTOBRIEF); - tcl.input_position = 0; - tcl.file_name = NULL; - tcl.this_parser = NULL; - tcl.command=0; - tcl.comment=0; - tcl.brace_level=0; - tcl.bracket_level=0; - tcl.bracket_quote=0; - tcl.word_is=' '; - tcl.string_command=""; - tcl.string_commentline=""; - tcl.string_commentcodify=""; - tcl.string_comment = ""; - tcl.string_last = ""; - tcl.entry_main = NULL; - tcl.entry_file = NULL; - tcl.entry_current = NULL; - tcl.entry_inside = NULL; - tcl.list_commandwords.clear(); - tcl.scan.clear(); - tcl.ns.clear(); - tcl.cl.clear(); - tcl.fn.clear(); - yylineno = 1; - tcl.protection = Public; - tcl.memberdef = NULL; -} - -//! Start parsing. -static void tcl_parse(const QCString ns, const QCString cls) -{ - tcl_scan *myScan; - - tcl.entry_file = tcl_entry_new(); - tcl.entry_file->name = tcl.file_name; - tcl.entry_file->section = Entry::SOURCE_SEC; - tcl.entry_file->protection = Public; - tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_file); - Entry *myEntry=tcl_entry_new(); - myEntry->name=""; - tcl.entry_main->moveToSubEntryAndKeep(myEntry); - tcl.ns.insert("::",myEntry); - tcl.entry_current = tcl_entry_new(); - - tclscannerYYrestart( tclscannerYYin ); - BEGIN( TOP ); - yylineno=1; - myScan = new tcl_scan; - myScan->type[0]=' ';myScan->type[1]='\n'; - myScan->after.clear(); - myScan->line0=yylineno; - myScan->line1=yylineno; - myScan->buffer_state=YY_CURRENT_BUFFER; - myScan->ns=ns; - myScan->entry_cl=tcl_entry_class(cls); - myScan->entry_fn=NULL; - tcl.entry_inside = tcl.entry_file; - myScan->entry_scan = tcl.entry_inside; - tcl.scan.insert(0,myScan); - tclscannerYYlex(); - tcl.scan.clear(); - tcl.ns.clear(); - tcl.cl.clear(); - tcl.fn.clear(); - tcl.entry.clear(); -} - -//! Parse text file and build up entry tree. -void TclOutlineParser::parseInput(const char *fileName, - const char *input, - const std::shared_ptr<Entry> &root, - bool /*sameTranslationUnit*/, - QStrList & /*filesInSameTranslationUnit*/) -{ - QFile myFile; -tcl_inf("%s\n",fileName); - myFile.setName(fileName); - if (!myFile.open(IO_ReadOnly)) return; - if (strlen(input)<1) return; - - tcl.input_string = input; - if (tcl.input_string.length()<1) return; - printlex(yy_flex_debug, TRUE, __FILE__, fileName); - - msg("Parsing %s...\n",fileName); - Doxygen::docGroup.enterFile(fileName,yylineno); - - tcl_init(); - tcl.code = NULL; - tcl.file_name = fileName; - tcl.this_parser = this; - tcl.entry_main = root.get(); /* toplevel entry */ - tcl_parse("",""); - Doxygen::docGroup.leaveFile(tcl.file_name,yylineno); - root->program.resize(0); - myFile.close(); - printlex(yy_flex_debug, FALSE, __FILE__, fileName); -} - - -bool TclOutlineParser::needsPreprocessing(const QCString &extension) const -{ - (void)extension; - return FALSE; -} - -void TclOutlineParser::parsePrototype(const char *text) -{ - (void)text; -} - -static int yyread(char *buf,int max_size) -{ - int c=0; - - *buf = '\0'; - while ( c < max_size && tcl.input_string.at(tcl.input_position) ) - { - *buf = tcl.input_string.at(tcl.input_position++) ; - c++; buf++; - } - //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c); - return c; -} - -//---------------------------------------------------------------------------- - -void TclCodeParser::resetCodeParserState() -{ -} - -//! Parse file and codify. -void TclCodeParser::parseCode(CodeOutputInterface & codeOutIntf, - const char * scopeName, - const QCString & input, - SrcLangExt lang, - bool isExampleBlock, - const char * exampleName, - FileDef * fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) -{ - (void)scopeName; - (void)lang; - (void)exampleName; - (void)fileDef; - (void)endLine; - (void)inlineFragment; - (void)searchCtx; - (void)collectXRefs; - - if (input.length()<1) return; - printlex(yy_flex_debug, TRUE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); - tcl.input_string = input; - - QCString myNs=""; - QCString myCls=""; - if (memberDef) - { - if (memberDef->getClassDef()) - { - myCls = memberDef->getClassDef()->displayName(); - myNs = myCls; - } - else if (memberDef->getNamespaceDef()) - { - myNs = memberDef->getNamespaceDef()->displayName(); - } - } - - QCString myStr="Codifying.."; - if (scopeName) - { - myStr +=" scope="; - myStr+=scopeName; - } - if (exampleName) - { - myStr+=" example="; - myStr+=exampleName; - } - if (memberDef) - { - myStr+=" member="; - myStr+=memberDef->memberTypeName(); - myStr+=" "; - myStr+=memberDef->qualifiedName(); - } - if (fileDef) - { - myStr+=" file="; - myStr+=fileDef->fileName(); - } -tcl_inf("%s (%d,%d) %d %d\n",myStr.data(),startLine,endLine,isExampleBlock,inlineFragment); -//tcl_inf("%s\n"input.data()); - tcl_init(); - tcl.collectXRefs = collectXRefs; - tcl.memberdef = memberDef; - tcl.code = &codeOutIntf; - if (startLine<0) - { - startLine=1; - } - yylineno=startLine; - tcl.code_linenumbers = showLineNumbers; - tcl.code_line=yylineno; - tcl.code->startCodeLine(tcl.code_linenumbers); - if (tcl.code_linenumbers) - { - tcl.code->writeLineNumber(0,0,0,tcl.code_line); - } - tcl.file_name = ""; - tcl.this_parser = NULL; - if (isExampleBlock) - { - tcl_codify(NULL,input); - } - else - { - tcl.entry_main = tcl_entry_new(); - tcl_parse(myNs,myCls); - } - tcl.code->endCodeLine(); - tcl.scan.clear(); - tcl.ns.clear(); - tcl.cl.clear(); - tcl.fn.clear(); - tcl.entry.clear(); - printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); -} -//---------------------------------------------------------------------------- - -// to avoid a warning -void tclDummy() -{ - yy_top_state(); -} - -#include "tclscanner.l.h" diff --git a/src/template.cpp b/src/template.cpp index ca28c73..1763eec 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -336,7 +336,7 @@ int TemplateList::release() return count; } -int TemplateList::count() const +uint TemplateList::count() const { return p->elems.count(); } @@ -406,9 +406,9 @@ TemplateListIntf::ConstIterator *TemplateList::createIterator() const return new TemplateListConstIterator(*this); } -TemplateVariant TemplateList::at(int index) const +TemplateVariant TemplateList::at(uint index) const { - if (index>=0 && index<(int)p->elems.count()) + if (index<p->elems.count()) { return p->elems[index]; } @@ -780,7 +780,7 @@ class FilterLength } if (v.type()==TemplateVariant::List) { - return TemplateVariant(v.toList()->count()); + return TemplateVariant((int)v.toList()->count()); } else if (v.type()==TemplateVariant::String) { @@ -1125,7 +1125,7 @@ class FilterAlphaIndex { int i=0; if (startLetter>='0' && startLetter<='9') s[i++] = 'x'; - s[i++]=tolower((char)startLetter); + s[i++]=(char)tolower((char)startLetter); s[i++]=0; } else @@ -2268,7 +2268,6 @@ class ExpressionParser if (p==q) // still no valid token found -> error { m_curToken.type = ExprToken::Unknown; - char s[2]; s[0]=c; s[1]=0; warn(m_parser->templateName(),m_line,"Found unknown token '%s' (%d) while parsing %s",s,c,m_tokenStream); @@ -2877,19 +2876,21 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf> stopAt.append("else"); // if 'nodes' - GuardedNodes *guardedNodes = new GuardedNodes; - ExpressionParser ex(parser,line); - guardedNodes->line = line; - guardedNodes->guardAst = ex.parse(data); - parser->parse(this,line,stopAt,guardedNodes->trueNodes); - m_ifGuardedNodes.append(guardedNodes); + { + GuardedNodes *guardedNodes = new GuardedNodes; + ExpressionParser ex(parser,line); + guardedNodes->line = line; + guardedNodes->guardAst = ex.parse(data); + parser->parse(this,line,stopAt,guardedNodes->trueNodes); + m_ifGuardedNodes.append(guardedNodes); + } TemplateToken *tok = parser->takeNextToken(); // elif 'nodes' while (tok && tok->data.left(5)=="elif ") { ExpressionParser ex(parser,line); - guardedNodes = new GuardedNodes; + GuardedNodes *guardedNodes = new GuardedNodes; guardedNodes->line = tok->line; guardedNodes->guardAst = ex.parse(tok->data.mid(5)); parser->parse(this,tok->line,stopAt,guardedNodes->trueNodes); @@ -3119,15 +3120,15 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange> while (!done) { // set the forloop meta-data variable - TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc()); - s->set("counter0", (int)index); - s->set("counter", (int)(index+1)); - s->set("revcounter", (int)(l-index)); - s->set("revcounter0", (int)(l-index-1)); - s->set("first",index==0); - s->set("last", (int)index==l-1); - s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant()); - c->set("forloop",s.get()); + TemplateAutoRef<TemplateStruct> ls(TemplateStruct::alloc()); + ls->set("counter0", (int)index); + ls->set("counter", (int)(index+1)); + ls->set("revcounter", (int)(l-index)); + ls->set("revcounter0", (int)(l-index-1)); + ls->set("first",index==0); + ls->set("last", (int)index==l-1); + ls->set("parentloop",parentLoop ? *parentLoop : TemplateVariant()); + c->set("forloop",ls.get()); // set the iterator variable c->set(m_var,i); @@ -3278,7 +3279,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor> } c->push(); //int index = m_reversed ? list.count() : 0; - TemplateVariant v; + //TemplateVariant v; const TemplateVariant *parentLoop = c->getRef("forloop"); uint index = m_reversed ? listSize-1 : 0; TemplateListIntf::ConstIterator *it = list->createIterator(); @@ -3622,7 +3623,6 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> : TemplateNodeCreator<TemplateNodeCreate>(parser,parent,line), m_templateExpr(0), m_fileExpr(0) { TRACE(("TemplateNodeCreate(%s)\n",data.data())); - ExpressionParser ep(parser,line); if (data.isEmpty()) { parser->warn(m_templateName,line,"create tag is missing arguments"); @@ -4979,7 +4979,7 @@ TemplateToken *TemplateParser::takeNextToken() const TemplateToken *TemplateParser::currentToken() const { return m_tokens.getFirst(); -}; +} void TemplateParser::removeNextToken() { diff --git a/src/template.h b/src/template.h index 4602c53..40bd43f 100644 --- a/src/template.h +++ b/src/template.h @@ -355,10 +355,10 @@ class TemplateListIntf virtual ~TemplateListIntf() {} /** Returns the number of elements in the list */ - virtual int count() const = 0; + virtual uint count() const = 0; /** Returns the element at index position \a index. */ - virtual TemplateVariant at(int index) const = 0; + virtual TemplateVariant at(uint index) const = 0; /** Creates a new iterator for this list. * @note the user should call delete on the returned pointer. @@ -377,8 +377,8 @@ class TemplateList : public TemplateListIntf { public: // TemplateListIntf methods - virtual int count() const; - virtual TemplateVariant at(int index) const; + virtual uint count() const; + virtual TemplateVariant at(uint index) const; virtual TemplateListIntf::ConstIterator *createIterator() const; virtual int addRef(); virtual int release(); @@ -457,6 +457,7 @@ class TemplateStruct : public TemplateStructIntf class TemplateEscapeIntf { public: + virtual ~TemplateEscapeIntf() {} /** Returns the \a input after escaping certain characters */ virtual QCString escape(const QCString &input) = 0; /** Setting tabbing mode on or off (for LaTeX) */ @@ -469,6 +470,7 @@ class TemplateEscapeIntf class TemplateSpacelessIntf { public: + virtual ~TemplateSpacelessIntf() {} /** Returns the \a input after removing redundant whitespace */ virtual QCString remove(const QCString &input) = 0; /** Reset filter state */ diff --git a/src/translator_dk.h b/src/translator_dk.h index 70e9032..df063ef 100644 --- a/src/translator_dk.h +++ b/src/translator_dk.h @@ -1775,7 +1775,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 const char* base, const char* plurSuffix) { QCString result(base); - if (first_capital) result.at(0) = toupper(result.at(0)); + if (first_capital) result[0] = (char)toupper(result[0]); if (!singular) result+=plurSuffix; return result; } diff --git a/src/translator_fr.h b/src/translator_fr.h index f355619..0035e23 100644 --- a/src/translator_fr.h +++ b/src/translator_fr.h @@ -129,1077 +129,1088 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 * "\\usepackage[T1]{fontenc}\n" * </pre> */ - virtual QCString latexLanguageSupportCommand() - { - return "\\usepackage[french]{babel}\n" - "\\NoAutoSpaceBeforeFDP\n"; - } + virtual QCString latexLanguageSupportCommand() + { + return "\\usepackage[french]{babel}\n" + "\\NoAutoSpaceBeforeFDP\n"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ - virtual QCString trRelatedFunctions() - { return "Fonctions associées"; } + virtual QCString trRelatedFunctions() + { return "Fonctions associées"; } /*! subscript for the related functions. */ - virtual QCString trRelatedSubscript() - { return "(Notez que ce ne sont pas des fonctions membres)"; } + virtual QCString trRelatedSubscript() + { return "(Notez que ce ne sont pas des fonctions membres)"; } /*! header that is put before the detailed description of files, classes and namespaces. */ - virtual QCString trDetailedDescription() - { return "Description détaillée"; } + virtual QCString trDetailedDescription() + { return "Description détaillée"; } /*! header that is put before the list of typedefs. */ - virtual QCString trMemberTypedefDocumentation() - { return "Documentation des définitions de type membres"; } + virtual QCString trMemberTypedefDocumentation() + { return "Documentation des définitions de type membres"; } /*! header that is put before the list of enumerations. */ - virtual QCString trMemberEnumerationDocumentation() - { return "Documentation des énumérations membres"; } + virtual QCString trMemberEnumerationDocumentation() + { return "Documentation des énumérations membres"; } /*! header that is put before the list of member functions. */ - virtual QCString trMemberFunctionDocumentation() - { return "Documentation des fonctions membres"; } + virtual QCString trMemberFunctionDocumentation() + { return "Documentation des fonctions membres"; } /*! header that is put before the list of member attributes. */ - virtual QCString trMemberDataDocumentation() + virtual QCString trMemberDataDocumentation() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Documentation des champs"; - } - else - { - return "Documentation des données membres"; - } + return "Documentation des champs"; } + else + { + return "Documentation des données membres"; + } + } /*! this is the text of a link put after brief descriptions. */ - virtual QCString trMore() - { return "Plus de détails..."; } + virtual QCString trMore() + { return "Plus de détails..."; } /*! put in the class documentation */ - virtual QCString trListOfAllMembers() - { return "Liste de tous les membres"; } + virtual QCString trListOfAllMembers() + { return "Liste de tous les membres"; } /*! used as the title of the "list of all members" page of a class */ - virtual QCString trMemberList() - { return "Liste des membres"; } + virtual QCString trMemberList() + { return "Liste des membres"; } /*! this is the first part of a sentence that is followed by a class name */ - virtual QCString trThisIsTheListOfAllMembers() - { return "Liste complète des membres de "; } + virtual QCString trThisIsTheListOfAllMembers() + { return "Liste complète des membres de "; } /*! this is the remainder of the sentence after the class name */ - virtual QCString trIncludingInheritedMembers() - { return ", y compris les membres hérités :"; } + virtual QCString trIncludingInheritedMembers() + { return ", y compris les membres hérités :"; } /*! this is put at the author sections at the bottom of man pages. * parameter s is name of the project name. */ - virtual QCString trGeneratedAutomatically(const char *s) - { QCString result="Généré automatiquement par Doxygen"; - if (s) result+=(QCString)" pour "+s; - result+=" à partir du code source."; - return result; - } + virtual QCString trGeneratedAutomatically(const char *s) + { QCString result="Généré automatiquement par Doxygen"; + if (s) result+=(QCString)" pour "+s; + result+=" à partir du code source."; + return result; + } /*! put after an enum name in the list of all members */ - virtual QCString trEnumName() - { return "énumération"; } + virtual QCString trEnumName() + { return "énumération"; } /*! put after an enum value in the list of all members */ - virtual QCString trEnumValue() - { return "valeur énumérée"; } + virtual QCString trEnumValue() + { return "valeur énumérée"; } /*! put after an undocumented member in the list of all members */ - virtual QCString trDefinedIn() - { return "défini dans"; } + virtual QCString trDefinedIn() + { return "défini dans"; } // quick reference sections /*! This is put above each page as a link to the list of all groups of * compounds or files (see the \\group command). */ - virtual QCString trModules() - { return "Modules"; } + virtual QCString trModules() + { return "Modules"; } /*! This is put above each page as a link to the class hierarchy */ - virtual QCString trClassHierarchy() - { return "Hiérarchie des classes"; } + virtual QCString trClassHierarchy() + { return "Hiérarchie des classes"; } /*! This is put above each page as a link to the list of annotated classes */ - virtual QCString trCompoundList() + virtual QCString trCompoundList() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Structures de données"; - } - else - { - return "Liste des classes"; - } + return "Structures de données"; } + else + { + return "Liste des classes"; + } + } /*! This is put above each page as a link to the list of documented files */ - virtual QCString trFileList() - { return "Liste des fichiers"; } + virtual QCString trFileList() + { return "Liste des fichiers"; } /*! This is put above each page as a link to all members of compounds. */ - virtual QCString trCompoundMembers() + virtual QCString trCompoundMembers() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Champs de donnée"; - } - else - { - return "Membres de classe"; - } + return "Champs de donnée"; } + else + { + return "Membres de classe"; + } + } /*! This is put above each page as a link to all members of files. */ - virtual QCString trFileMembers() + virtual QCString trFileMembers() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Variables globale"; - } - else - { - return "Membres de fichier"; - } + return "Variables globale"; } + else + { + return "Membres de fichier"; + } + } /*! This is put above each page as a link to all related pages. */ - virtual QCString trRelatedPages() - { return "Pages associées"; } + virtual QCString trRelatedPages() + { return "Pages associées"; } /*! This is put above each page as a link to all examples. */ - virtual QCString trExamples() - { return "Exemples"; } + virtual QCString trExamples() + { return "Exemples"; } /*! This is put above each page as a link to the search engine. */ - virtual QCString trSearch() - { return "Recherche"; } + virtual QCString trSearch() + { return "Recherche"; } /*! This is an introduction to the class hierarchy. */ - virtual QCString trClassHierarchyDescription() - { return "Cette liste d'héritage est classée " - "approximativement par ordre alphabétique :"; + virtual QCString trClassHierarchyDescription() + { + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return "Liste hiérarchique de toutes les entités :"; } - - /*! This is an introduction to the list with all files. */ - virtual QCString trFileListDescription(bool extractAll) + else { - QCString result="Liste de tous les fichiers "; - if (!extractAll) result+="documentés "; - result+="avec une brève description :"; - return result; + return "Cette liste d'héritage est classée " + "approximativement par ordre alphabétique :"; } + } + + /*! This is an introduction to the list with all files. */ + virtual QCString trFileListDescription(bool extractAll) + { + QCString result="Liste de tous les fichiers "; + if (!extractAll) result+="documentés "; + result+="avec une brève description :"; + return result; + } /*! This is an introduction to the annotated compound list. */ - virtual QCString trCompoundListDescription() + virtual QCString trCompoundListDescription() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Liste des structures de données avec une brève description :"; - } - else - { - return "Liste des classes, structures, " + return "Liste des structures de données avec une brève description :"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Liste des classes avec une brève description :"; + } + else + { + return "Liste des classes, structures, " "unions et interfaces avec une brève description :"; - } } + } /*! This is an introduction to the page with all class members. */ - virtual QCString trCompoundMembersDescription(bool extractAll) + virtual QCString trCompoundMembersDescription(bool extractAll) + { + QCString result="Liste de tous les "; + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="champs de structure et d'union "; + } + else { - QCString result="Liste de tous les "; - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - result+="champs de structure et d'union "; - } - else - { - result+="membres de classe "; - } - if (!extractAll) - { - result+="documentés "; - } - result+="avec des liens vers "; - if (!extractAll) - { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - result+="la documentation de structure/union de chaque champ :"; - } - else - { - result+="la documentation de classe de chaque membre :"; - } - } - else - { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - result+="les structures/unions auxquelles ils appartiennent :"; - } - else - { - result+="les classes auxquelles ils appartiennent :"; - } - } - return result; + result+="membres de classe "; + } + if (!extractAll) + { + result+="documentés "; } + result+="avec des liens vers "; + if (!extractAll) + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="la documentation de structure/union de chaque champ :"; + } + else + { + result+="la documentation de classe de chaque membre :"; + } + } + else + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="les structures/unions auxquelles ils appartiennent :"; + } + else + { + result+="les classes auxquelles ils appartiennent :"; + } + } + return result; + } /*! This is an introduction to the page with all file members. */ - virtual QCString trFileMembersDescription(bool extractAll) + virtual QCString trFileMembersDescription(bool extractAll) + { + QCString result="Liste "; + + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="de toutes les fonctions, variables, macros, enumérations, et définitions de type "; + } + else { - QCString result="Liste "; - - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - result+="de toutes les fonctions, variables, macros, enumérations, et définitions de type "; - } - else - { - result+="de tous les membres de fichier "; - } - if (!extractAll) result+="documentés "; - result+="avec des liens vers "; - if (extractAll) - result+="les fichiers auxquels ils appartiennent :"; - else - result+="la documentation :"; - return result; + result+="de tous les membres de fichier "; } + if (!extractAll) result+="documentés "; + result+="avec des liens vers "; + if (extractAll) + result+="les fichiers auxquels ils appartiennent :"; + else + result+="la documentation :"; + return result; + } /*! This is an introduction to the page with the list of all examples */ - virtual QCString trExamplesDescription() - { return "Liste de tous les exemples :"; } + virtual QCString trExamplesDescription() + { return "Liste de tous les exemples :"; } /*! This is an introduction to the page with the list of related pages */ - virtual QCString trRelatedPagesDescription() - { return "Liste de toutes les pages de documentation associées :"; } + virtual QCString trRelatedPagesDescription() + { return "Liste de toutes les pages de documentation associées :"; } /*! This is an introduction to the page with the list of class/file groups */ - virtual QCString trModulesDescription() - { return "Liste de tous les modules :"; } + virtual QCString trModulesDescription() + { return "Liste de tous les modules :"; } /*! This is used in HTML as the title of index.html. */ - virtual QCString trDocumentation() - { return "Documentation"; } + virtual QCString trDocumentation() + { return "Documentation"; } /*! This is used in LaTeX as the title of the chapter with the * index of all groups. */ - virtual QCString trModuleIndex() - { return "Index des modules"; } + virtual QCString trModuleIndex() + { return "Index des modules"; } /*! This is used in LaTeX as the title of the chapter with the * class hierarchy. */ - virtual QCString trHierarchicalIndex() - { return "Index hiérarchique"; } + virtual QCString trHierarchicalIndex() + { return "Index hiérarchique"; } /*! This is used in LaTeX as the title of the chapter with the * annotated compound index. */ - virtual QCString trCompoundIndex() + virtual QCString trCompoundIndex() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Index des structures de données"; + } + else { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Index des structures de données"; - } - else - { - return "Index des classes"; - } + return "Index des classes"; } + } /*! This is used in LaTeX as the title of the chapter with the * list of all files. */ - virtual QCString trFileIndex() - { return "Index des fichiers"; } + virtual QCString trFileIndex() + { return "Index des fichiers"; } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all groups. */ - virtual QCString trModuleDocumentation() - { return "Documentation des modules"; } + virtual QCString trModuleDocumentation() + { return "Documentation des modules"; } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all classes, structs and unions. */ - virtual QCString trClassDocumentation() + virtual QCString trClassDocumentation() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Documentation des structures de données"; - } - else - { - return "Documentation des classes"; - } + return "Documentation des structures de données"; } + else + { + return "Documentation des classes"; + } + } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all files. */ - virtual QCString trFileDocumentation() - { return "Documentation des fichiers"; } + virtual QCString trFileDocumentation() + { return "Documentation des fichiers"; } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all examples. */ - virtual QCString trExampleDocumentation() - { return "Documentation des exemples"; } + virtual QCString trExampleDocumentation() + { return "Documentation des exemples"; } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all related pages. */ - virtual QCString trPageDocumentation() - { return "Documentation des pages associées"; } + virtual QCString trPageDocumentation() + { return "Documentation des pages associées"; } /*! This is used in LaTeX as the title of the document */ - virtual QCString trReferenceManual() - { return "Manuel de référence"; } + virtual QCString trReferenceManual() + { return "Manuel de référence"; } /*! This is used in the documentation of a file as a header before the * list of defines */ - virtual QCString trDefines() - { return "Macros"; } + virtual QCString trDefines() + { return "Macros"; } /*! This is used in the documentation of a file as a header before the * list of typedefs */ - virtual QCString trTypedefs() - { return "Définitions de type"; } + virtual QCString trTypedefs() + { return "Définitions de type"; } /*! This is used in the documentation of a file as a header before the * list of enumerations */ - virtual QCString trEnumerations() - { return "Énumérations"; } + virtual QCString trEnumerations() + { return "Énumérations"; } /*! This is used in the documentation of a file as a header before the * list of (global) functions */ - virtual QCString trFunctions() - { return "Fonctions"; } + virtual QCString trFunctions() + { return "Fonctions"; } /*! This is used in the documentation of a file as a header before the * list of (global) variables */ - virtual QCString trVariables() - { return "Variables"; } + virtual QCString trVariables() + { return "Variables"; } /*! This is used in the documentation of a file as a header before the * list of (global) variables */ - virtual QCString trEnumerationValues() - { return "Valeurs énumérées"; } + virtual QCString trEnumerationValues() + { return "Valeurs énumérées"; } /*! This is used in the documentation of a file before the list of * documentation blocks for defines */ - virtual QCString trDefineDocumentation() - { return "Documentation des macros"; } + virtual QCString trDefineDocumentation() + { return "Documentation des macros"; } /*! This is used in the documentation of a file/namespace before the list * of documentation blocks for typedefs */ - virtual QCString trTypedefDocumentation() - { return "Documentation des définitions de type"; } + virtual QCString trTypedefDocumentation() + { return "Documentation des définitions de type"; } /*! This is used in the documentation of a file/namespace before the list * of documentation blocks for enumeration types */ - virtual QCString trEnumerationTypeDocumentation() - { return "Documentation du type de l'énumération"; } + virtual QCString trEnumerationTypeDocumentation() + { return "Documentation du type de l'énumération"; } /*! This is used in the documentation of a file/namespace before the list * of documentation blocks for functions */ - virtual QCString trFunctionDocumentation() - { return "Documentation des fonctions"; } + virtual QCString trFunctionDocumentation() + { return "Documentation des fonctions"; } /*! This is used in the documentation of a file/namespace before the list * of documentation blocks for variables */ - virtual QCString trVariableDocumentation() - { return "Documentation des variables"; } + virtual QCString trVariableDocumentation() + { return "Documentation des variables"; } /*! This is used in the documentation of a file/namespace/group before * the list of links to documented compounds */ - virtual QCString trCompounds() + virtual QCString trCompounds() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Structures de données"; - } - else - { - return "Classes"; - } + return "Structures de données"; } + else + { + return "Classes"; + } + } /*! This is used in the standard footer of each page and indicates when * the page was generated */ - virtual QCString trGeneratedAt(const char *date,const char *projName) - { - QCString result=(QCString)"Généré le "+date; - if (projName) result+=(QCString)" pour "+projName; - result+=(QCString)" par"; - return result; - } + virtual QCString trGeneratedAt(const char *date,const char *projName) + { + QCString result=(QCString)"Généré le "+date; + if (projName) result+=(QCString)" pour "+projName; + result+=(QCString)" par"; + return result; + } /*! this text is put before a class diagram */ - virtual QCString trClassDiagram(const char *clName) - { - return (QCString)"Graphe d'héritage de "+clName+":"; - } + virtual QCString trClassDiagram(const char *clName) + { + return (QCString)"Graphe d'héritage de "+clName+":"; + } /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Pour un usage interne uniquement."; } + virtual QCString trForInternalUseOnly() + { return "Pour un usage interne uniquement."; } /*! this text is generated when the \\warning command is used. */ - virtual QCString trWarning() - { return "Avertissement"; } + virtual QCString trWarning() + { return "Avertissement"; } /*! this text is generated when the \\version command is used. */ - virtual QCString trVersion() - { return "Version"; } + virtual QCString trVersion() + { return "Version"; } /*! this text is generated when the \\date command is used. */ - virtual QCString trDate() - { return "Date"; } + virtual QCString trDate() + { return "Date"; } /*! this text is generated when the \\return command is used. */ - virtual QCString trReturns() - { return "Renvoie"; } + virtual QCString trReturns() + { return "Renvoie"; } /*! this text is generated when the \\sa command is used. */ - virtual QCString trSeeAlso() - { return "Voir également"; } + virtual QCString trSeeAlso() + { return "Voir également"; } /*! this text is generated when the \\param command is used. */ - virtual QCString trParameters() - { return "Paramètres"; } + virtual QCString trParameters() + { return "Paramètres"; } /*! this text is generated when the \\exception command is used. */ - virtual QCString trExceptions() - { return "Exceptions"; } + virtual QCString trExceptions() + { return "Exceptions"; } /*! this text is used in the title page of a LaTeX document. */ - virtual QCString trGeneratedBy() - { return "Généré par"; } + virtual QCString trGeneratedBy() + { return "Généré par"; } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-990307 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990307 +////////////////////////////////////////////////////////////////////////// /*! used as the title of page containing all the index of all namespaces. */ - virtual QCString trNamespaceList() - { return "Liste des espaces de nommage"; } + virtual QCString trNamespaceList() + { return "Liste des espaces de nommage"; } /*! used as an introduction to the namespace list */ - virtual QCString trNamespaceListDescription(bool extractAll) - { - QCString result="Liste de tous les espaces de nommage "; - if (!extractAll) result+="documentés "; - result+="avec une brève description:"; - return result; - } + virtual QCString trNamespaceListDescription(bool extractAll) + { + QCString result="Liste de tous les espaces de nommage "; + if (!extractAll) result+="documentés "; + result+="avec une brève description:"; + return result; + } /*! used in the class documentation as a header before the list of all * friends of a class */ - virtual QCString trFriends() - { return "Amis"; } + virtual QCString trFriends() + { return "Amis"; } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-990405 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990405 +////////////////////////////////////////////////////////////////////////// /*! used in the class documentation as a header before the list of all * related classes */ - virtual QCString trRelatedFunctionDocumentation() - { return "Documentation des fonctions amies et associées"; } + virtual QCString trRelatedFunctionDocumentation() + { return "Documentation des fonctions amies et associées"; } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-990425 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990425 +////////////////////////////////////////////////////////////////////////// /*! used as the title of the HTML page of a class/struct/union */ - virtual QCString trCompoundReference(const char *clName, + virtual QCString trCompoundReference(const char *clName, ClassDef::CompoundType compType, bool isTemplate) + { + QCString result="Référence "; + if (isTemplate) result+="du modèle "; + result+="de "; + switch(compType) { - QCString result="Référence "; - if (isTemplate) result+="du modèle "; - result+="de "; - switch(compType) - { - case ClassDef::Class: result+="la classe "; break; - case ClassDef::Struct: result+="la structure "; break; - case ClassDef::Union: result+="l'union "; break; - case ClassDef::Interface: result+="l'interface "; break; - case ClassDef::Protocol: result+="le protocol "; break; - case ClassDef::Category: result+="la catégorie "; break; - case ClassDef::Exception: result+="l'exception "; break; - default: break; - } - result+=(QCString)clName; - return result; + case ClassDef::Class: result+="la classe "; break; + case ClassDef::Struct: result+="la structure "; break; + case ClassDef::Union: result+="l'union "; break; + case ClassDef::Interface: result+="l'interface "; break; + case ClassDef::Protocol: result+="le protocol "; break; + case ClassDef::Category: result+="la catégorie "; break; + case ClassDef::Exception: result+="l'exception "; break; + default: break; } + result+=(QCString)clName; + return result; + } /*! used as the title of the HTML page of a file */ - virtual QCString trFileReference(const char *fileName) - { - QCString result= "Référence du fichier "; - result+=fileName; - return result; - } + virtual QCString trFileReference(const char *fileName) + { + QCString result= "Référence du fichier "; + result+=fileName; + return result; + } /*! used as the title of the HTML page of a namespace */ - virtual QCString trNamespaceReference(const char *namespaceName) - { - QCString result= "Référence de l'espace de nommage "; - result+=namespaceName; - return result; - } + virtual QCString trNamespaceReference(const char *namespaceName) + { + QCString result= "Référence de l'espace de nommage "; + result+=namespaceName; + return result; + } - virtual QCString trPublicMembers() - { return "Fonctions membres publiques"; } - virtual QCString trPublicSlots() - { return "Connecteurs publics"; } - virtual QCString trSignals() - { return "Signaux"; } - virtual QCString trStaticPublicMembers() - { return "Fonctions membres publiques statiques"; } - virtual QCString trProtectedMembers() - { return "Fonctions membres protégées"; } - virtual QCString trProtectedSlots() - { return "Connecteurs protégés"; } - virtual QCString trStaticProtectedMembers() - { return "Fonctions membres protégées statiques"; } - virtual QCString trPrivateMembers() - { return "Fonctions membres privées"; } - virtual QCString trPrivateSlots() - { return "Connecteurs privés"; } - virtual QCString trStaticPrivateMembers() - { return "Fonctions membres privées statiques"; } + virtual QCString trPublicMembers() + { return "Fonctions membres publiques"; } + virtual QCString trPublicSlots() + { return "Connecteurs publics"; } + virtual QCString trSignals() + { return "Signaux"; } + virtual QCString trStaticPublicMembers() + { return "Fonctions membres publiques statiques"; } + virtual QCString trProtectedMembers() + { return "Fonctions membres protégées"; } + virtual QCString trProtectedSlots() + { return "Connecteurs protégés"; } + virtual QCString trStaticProtectedMembers() + { return "Fonctions membres protégées statiques"; } + virtual QCString trPrivateMembers() + { return "Fonctions membres privées"; } + virtual QCString trPrivateSlots() + { return "Connecteurs privés"; } + virtual QCString trStaticPrivateMembers() + { return "Fonctions membres privées statiques"; } /*! this function is used to produce a comma-separated list of items. * use generateMarker(i) to indicate where item i should be put. */ - virtual QCString trWriteList(int numEntries) - { - QCString result; - int i; + virtual QCString trWriteList(int numEntries) + { + QCString result; + int i; // the inherits list contain `numEntries' classes - for (i=0;i<numEntries;i++) - { - // use generateMarker to generate placeholders for the class links! - result+=generateMarker(i); // generate marker for entry i in the list + for (i=0;i<numEntries;i++) + { + // use generateMarker to generate placeholders for the class links! + result+=generateMarker(i); // generate marker for entry i in the list // (order is left to right) - if (i!=numEntries-1) // not the last entry, so we need a separator - { - if (i<numEntries-2) // not the fore last entry - result+=", "; - else // the fore last entry - result+=", et "; - } - } - return result; + if (i!=numEntries-1) // not the last entry, so we need a separator + { + if (i<numEntries-2) // not the fore last entry + result+=", "; + else // the fore last entry + result+=", et "; + } } + return result; + } /*! used in class documentation to produce a list of base classes, * if class diagrams are disabled. */ - virtual QCString trInheritsList(int numEntries) - { - return "Est dérivée de "+trWriteList(numEntries)+"."; - } + virtual QCString trInheritsList(int numEntries) + { + return "Est dérivée de "+trWriteList(numEntries)+"."; + } /*! used in class documentation to produce a list of super classes, * if class diagrams are disabled. */ - virtual QCString trInheritedByList(int numEntries) - { - return "Dérivée par "+trWriteList(numEntries)+"."; - } + virtual QCString trInheritedByList(int numEntries) + { + return "Dérivée par "+trWriteList(numEntries)+"."; + } /*! used in member documentation blocks to produce a list of * members that are hidden by this one. */ - virtual QCString trReimplementedFromList(int numEntries) - { - return "Réimplémentée à partir de "+trWriteList(numEntries)+"."; - } + virtual QCString trReimplementedFromList(int numEntries) + { + return "Réimplémentée à partir de "+trWriteList(numEntries)+"."; + } /*! used in member documentation blocks to produce a list of * all member that overwrite the implementation of this member. */ - virtual QCString trReimplementedInList(int numEntries) - { - return "Réimplémentée dans "+trWriteList(numEntries)+"."; - } + virtual QCString trReimplementedInList(int numEntries) + { + return "Réimplémentée dans "+trWriteList(numEntries)+"."; + } /*! This is put above each page as a link to all members of namespaces. */ - virtual QCString trNamespaceMembers() - { return "Membres de l'espace de nommage"; } + virtual QCString trNamespaceMembers() + { return "Membres de l'espace de nommage"; } /*! This is an introduction to the page with all namespace members */ - virtual QCString trNamespaceMemberDescription(bool extractAll) - { - QCString result="Liste de tous les membres des espaces de nommage "; - if (!extractAll) result+="documentés "; - result+="avec des liens vers "; - if (extractAll) - result+="la documentation de namespace de chaque membre :"; - else - result+="les espaces de nommage auxquels ils appartiennent :"; - return result; - } + virtual QCString trNamespaceMemberDescription(bool extractAll) + { + QCString result="Liste de tous les membres des espaces de nommage "; + if (!extractAll) result+="documentés "; + result+="avec des liens vers "; + if (extractAll) + result+="la documentation de namespace de chaque membre :"; + else + result+="les espaces de nommage auxquels ils appartiennent :"; + return result; + } /*! This is used in LaTeX as the title of the chapter with the * index of all namespaces. */ - virtual QCString trNamespaceIndex() - { return "Index des espaces de nommage"; } + virtual QCString trNamespaceIndex() + { return "Index des espaces de nommage"; } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all namespaces. */ - virtual QCString trNamespaceDocumentation() - { return "Documentation des espaces de nommage"; } + virtual QCString trNamespaceDocumentation() + { return "Documentation des espaces de nommage"; } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-990522 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990522 +////////////////////////////////////////////////////////////////////////// /*! This is used in the documentation before the list of all * namespaces in a file. */ - virtual QCString trNamespaces() - { return "Espaces de nommage"; } + virtual QCString trNamespaces() + { return "Espaces de nommage"; } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-990728 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990728 +////////////////////////////////////////////////////////////////////////// /*! This is put at the bottom of a class documentation page and is * followed by a list of files that were used to generate the page. */ - virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, + virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) - { // here s is one of " Class", " Struct" or " Union" + { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - bool female = true; - QCString result=(QCString)"La documentation de "; - switch(compType) - { - case ClassDef::Class: result+="cette classe"; break; - case ClassDef::Struct: result+="cette structure"; break; - case ClassDef::Union: result+="cette union"; break; - case ClassDef::Interface: result+="cette interface"; break; - case ClassDef::Protocol: result+="ce protocol"; female = false; break; - case ClassDef::Category: result+="cette catégorie"; break; - case ClassDef::Exception: result+="cette exception"; break; - default: break; - } - if (female) result+= " a été générée à partir "; - else result+=" a été généré à partir "; - if (single) result+="du fichier suivant :"; - else result+="des fichiers suivants :"; - return result; + bool feminine = true; + QCString result=(QCString)"La documentation de "; + switch(compType) + { + case ClassDef::Class: result+="cette classe"; break; + case ClassDef::Struct: result+="cette structure"; break; + case ClassDef::Union: result+="cette union"; break; + case ClassDef::Interface: result+="cette interface"; break; + case ClassDef::Protocol: result+="ce protocol"; feminine = false; break; + case ClassDef::Category: result+="cette catégorie"; break; + case ClassDef::Exception: result+="cette exception"; break; + default: break; } + if (feminine) result+= " a été générée à partir "; + else result+=" a été généré à partir "; + if (feminine) result+="du fichier suivant :"; + else result+="des fichiers suivants :"; + return result; + } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-990901 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990901 +////////////////////////////////////////////////////////////////////////// /*! This is used as the heading text for the retval command. */ - virtual QCString trReturnValues() - { return "Valeurs retournées"; } + virtual QCString trReturnValues() + { return "Valeurs retournées"; } /*! This is in the (quick) index as a link to the main page (index.html) */ - virtual QCString trMainPage() - { return "Page principale"; } + virtual QCString trMainPage() + { return "Page principale"; } /*! This is used in references to page that are put in the LaTeX * documentation. It should be an abbreviation of the word page. */ - virtual QCString trPageAbbreviation() - { return "p."; } + virtual QCString trPageAbbreviation() + { return "p."; } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-991003 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-991003 +////////////////////////////////////////////////////////////////////////// - virtual QCString trDefinedAtLineInSourceFile() - { - return "Définition à la ligne @0 du fichier @1."; - } - virtual QCString trDefinedInSourceFile() - { - return "Définition dans le fichier @0."; - } + virtual QCString trDefinedAtLineInSourceFile() + { + return "Définition à la ligne @0 du fichier @1."; + } + virtual QCString trDefinedInSourceFile() + { + return "Définition dans le fichier @0."; + } - ////////////////////////////////////////////////////////////////////////// - // new since 0.49-991205 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 0.49-991205 +////////////////////////////////////////////////////////////////////////// - virtual QCString trDeprecated() - { - return "Obsolète"; - } + virtual QCString trDeprecated() + { + return "Obsolète"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.0.0 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.0.0 +////////////////////////////////////////////////////////////////////////// /*! this text is put before a collaboration diagram */ - virtual QCString trCollaborationDiagram(const char *clName) - { - return (QCString)"Graphe de collaboration de "+clName+":"; - } + virtual QCString trCollaborationDiagram(const char *clName) + { + return (QCString)"Graphe de collaboration de "+clName+":"; + } /*! this text is put before an include dependency graph */ - virtual QCString trInclDepGraph(const char *fName) - { - return (QCString)"Graphe des dépendances par inclusion de "+fName+":"; - } + virtual QCString trInclDepGraph(const char *fName) + { + return (QCString)"Graphe des dépendances par inclusion de "+fName+":"; + } /*! header that is put before the list of constructor/destructors. */ - virtual QCString trConstructorDocumentation() - { - return "Documentation des constructeurs et destructeur"; - } + virtual QCString trConstructorDocumentation() + { + return "Documentation des constructeurs et destructeur"; + } /*! Used in the file documentation to point to the corresponding sources. */ - virtual QCString trGotoSourceCode() - { - return "Aller au code source de ce fichier."; - } + virtual QCString trGotoSourceCode() + { + return "Aller au code source de ce fichier."; + } /*! Used in the file sources to point to the corresponding documentation. */ - virtual QCString trGotoDocumentation() - { - return "Aller à la documentation de ce fichier."; - } + virtual QCString trGotoDocumentation() + { + return "Aller à la documentation de ce fichier."; + } /*! Text for the \\pre command */ - virtual QCString trPrecondition() - { - return "Précondition"; - } + virtual QCString trPrecondition() + { + return "Précondition"; + } /*! Text for the \\post command */ - virtual QCString trPostcondition() - { - return "Postcondition"; - } + virtual QCString trPostcondition() + { + return "Postcondition"; + } /*! Text for the \\invariant command */ - virtual QCString trInvariant() - { - return "Invariant"; - } + virtual QCString trInvariant() + { + return "Invariant"; + } /*! Text shown before a multi-line variable/enum initialization */ - virtual QCString trInitialValue() - { - return "Valeur initiale :"; - } + virtual QCString trInitialValue() + { + return "Valeur initiale :"; + } /*! Text used the source code in the file index */ - virtual QCString trCode() - { - return "code"; - } - virtual QCString trGraphicalHierarchy() - { - return "Graphe hiérarchique des classes"; - } - virtual QCString trGotoGraphicalHierarchy() - { - return "Aller au graphe hiérarchique des classes"; - } - virtual QCString trGotoTextualHierarchy() - { - return "Aller à la hiérarchie des classes en mode texte"; - } - virtual QCString trPageIndex() - { - return "Index des pages"; - } + virtual QCString trCode() + { + return "code"; + } + virtual QCString trGraphicalHierarchy() + { + return "Graphe hiérarchique des classes"; + } + virtual QCString trGotoGraphicalHierarchy() + { + return "Aller au graphe hiérarchique des classes"; + } + virtual QCString trGotoTextualHierarchy() + { + return "Aller à la hiérarchie des classes en mode texte"; + } + virtual QCString trPageIndex() + { + return "Index des pages"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.1.0 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.1.0 +////////////////////////////////////////////////////////////////////////// - virtual QCString trNote() - { - return "Note"; - } - virtual QCString trPublicTypes() - { - return "Types publics"; - } - virtual QCString trPublicAttribs() - { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Champs de données"; - } - else - { - return "Attributs publics"; - } - } - virtual QCString trStaticPublicAttribs() - { - return "Attributs publics statiques"; - } - virtual QCString trProtectedTypes() - { - return "Types protégés"; - } - virtual QCString trProtectedAttribs() - { - return "Attributs protégés"; - } - virtual QCString trStaticProtectedAttribs() - { - return "Attributs protégés statiques"; - } - virtual QCString trPrivateTypes() - { - return "Types privés"; - } - virtual QCString trPrivateAttribs() + virtual QCString trNote() + { + return "Note"; + } + virtual QCString trPublicTypes() + { + return "Types publics"; + } + virtual QCString trPublicAttribs() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - return "Attributs privés"; + return "Champs de données"; } - virtual QCString trStaticPrivateAttribs() + else { - return "Attributs privés statiques"; + return "Attributs publics"; } + } + virtual QCString trStaticPublicAttribs() + { + return "Attributs publics statiques"; + } + virtual QCString trProtectedTypes() + { + return "Types protégés"; + } + virtual QCString trProtectedAttribs() + { + return "Attributs protégés"; + } + virtual QCString trStaticProtectedAttribs() + { + return "Attributs protégés statiques"; + } + virtual QCString trPrivateTypes() + { + return "Types privés"; + } + virtual QCString trPrivateAttribs() + { + return "Attributs privés"; + } + virtual QCString trStaticPrivateAttribs() + { + return "Attributs privés statiques"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.1.3 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.1.3 +////////////////////////////////////////////////////////////////////////// /*! Used as a marker that is put before a \\todo item */ - virtual QCString trTodo() - { - return "A faire"; - } + virtual QCString trTodo() + { + return "A faire"; + } /*! Used as the header of the todo list */ - virtual QCString trTodoList() - { - return "Liste des choses à faire"; - } + virtual QCString trTodoList() + { + return "Liste des choses à faire"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.1.4 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.1.4 +////////////////////////////////////////////////////////////////////////// - virtual QCString trReferencedBy() - { - return "Référencé par"; - } - virtual QCString trRemarks() - { - return "Remarques"; - } - virtual QCString trAttention() - { - return "Attention"; - } - virtual QCString trInclByDepGraph() - { - return "Ce graphe montre quels fichiers incluent directement " + virtual QCString trReferencedBy() + { + return "Référencé par"; + } + virtual QCString trRemarks() + { + return "Remarques"; + } + virtual QCString trAttention() + { + return "Attention"; + } + virtual QCString trInclByDepGraph() + { + return "Ce graphe montre quels fichiers incluent directement " "ou indirectement ce fichier :"; - } - virtual QCString trSince() - { - return "Depuis"; - } + } + virtual QCString trSince() + { + return "Depuis"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.1.5 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.1.5 +////////////////////////////////////////////////////////////////////////// /*! title of the graph legend page */ - virtual QCString trLegendTitle() - { - return "Légende du graphe"; - } + virtual QCString trLegendTitle() + { + return "Légende du graphe"; + } /*! page explaining how the dot graph's should be interpreted * The %A in the text below are to prevent link to classes called "A". */ - virtual QCString trLegendDocs() - { - return - "Cette page explique comment interpréter les graphes générés " - "par doxygen.<p>\n" - "Considérez l'exemple suivant :\n" - "\\code\n" - "/*! Classe invisible à cause d'une troncature */\n" - "class Invisible { };\n\n" - "/*! Classe tronquée, la relation d'héritage est masquée */\n" - "class Truncated : public Invisible { };\n\n" - "/*! Classe non documentée avec des commentaires Doxygen */\n" - "class Undocumented { };\n\n" - "/*! Classe dérivée par héritage public */\n" - "class PublicBase : public Truncated { };\n\n" - "/*! Un modèle de classe */\n" - "template<class T> class Templ { };\n\n" - "/*! Classe dérivée par héritage protégé */\n" - "class ProtectedBase { };\n\n" - "/*! Classe dérivée par héritage privé */\n" - "class PrivateBase { };\n\n" - "/*! Classe utilisée par la classe dérivée */\n" - "class Used { };\n\n" - "/*! Super-classe qui hérite de plusieurs autres classes */\n" - "class Inherited : public PublicBase,\n" - " protected ProtectedBase,\n" - " private PrivateBase,\n" - " public Undocumented,\n" - " public Templ<int>\n" - "{\n" - " private:\n" - " Used *m_usedClass;\n" - "};\n" - "\\endcode\n" - "Cela aboutira au graphe suivant :" - "<p><center><img alt=\"\" src=\"graph_legend."+getDotImageExtension()+"\"></center></p>\n" - "<p>\n" - "Les rectangles du graphe ci-dessus ont la signification suivante :\n" - "<ul>\n" - "<li>Un rectangle plein noir représente la structure ou la classe pour laquelle " - "le graphe est généré.\n" - "<li>Un rectangle avec un bord noir indique une classe ou une structure documentée.\n" - "<li>Un rectangle avec un bord gris indique une classe ou une structure non documentée.\n" - "<li>Un rectangle avec un bord rouge indique une structure ou une classe documentée\n" - "pour laquelle des relations d'héritage ou de collaboration manquent. Un graphe est " - "tronqué s'il n'entre pas dans les limites spécifiées." - "</ul>\n" - "Les flèches ont la signification suivante :\n" - "<ul>\n" - "<li>Une flèche bleu foncé est utilisée pour visualiser une relation d'héritage publique " - "entre deux classes.\n" - "<li>Une flèche vert foncé est utilisée pour une relation d'héritage protégée.\n" - "<li>Une flèche rouge foncé est utilisée pour une relation d'héritage privée.\n" - "<li>Une flèche violette en pointillés est utilisée si une classe est contenue ou " - "utilisée par une autre classe. La flèche est étiquetée avec la ou les variable(s) " - "qui permettent d'accéder à la classe ou structure pointée. \n" - "<li>Une flèche jaune en pointillés indique une relation entre un modèle d'instance et " - "le modèle de classe duquel il est instancié. La flèche est étiquetée avec " - "les paramètres de modèle de l'instance.\n" - "</ul>\n"; - } + virtual QCString trLegendDocs() + { + return + "Cette page explique comment interpréter les graphes générés " + "par doxygen.<p>\n" + "Considérez l'exemple suivant :\n" + "\\code\n" + "/*! Classe invisible à cause d'une troncature */\n" + "class Invisible { };\n\n" + "/*! Classe tronquée, la relation d'héritage est masquée */\n" + "class Truncated : public Invisible { };\n\n" + "/*! Classe non documentée avec des commentaires Doxygen */\n" + "class Undocumented { };\n\n" + "/*! Classe dérivée par héritage public */\n" + "class PublicBase : public Truncated { };\n\n" + "/*! Un modèle de classe */\n" + "template<class T> class Templ { };\n\n" + "/*! Classe dérivée par héritage protégé */\n" + "class ProtectedBase { };\n\n" + "/*! Classe dérivée par héritage privé */\n" + "class PrivateBase { };\n\n" + "/*! Classe utilisée par la classe dérivée */\n" + "class Used { };\n\n" + "/*! Super-classe qui hérite de plusieurs autres classes */\n" + "class Inherited : public PublicBase,\n" + " protected ProtectedBase,\n" + " private PrivateBase,\n" + " public Undocumented,\n" + " public Templ<int>\n" + "{\n" + " private:\n" + " Used *m_usedClass;\n" + "};\n" + "\\endcode\n" + "Cela aboutira au graphe suivant :" + "<p><center><img alt=\"\" src=\"graph_legend."+getDotImageExtension()+"\"></center></p>\n" + "<p>\n" + "Les rectangles du graphe ci-dessus ont la signification suivante :\n" + "<ul>\n" + "<li>Un rectangle plein noir représente la structure ou la classe pour laquelle " + "le graphe est généré.\n" + "<li>Un rectangle avec un bord noir indique une classe ou une structure documentée.\n" + "<li>Un rectangle avec un bord gris indique une classe ou une structure non documentée.\n" + "<li>Un rectangle avec un bord rouge indique une structure ou une classe documentée\n" + "pour laquelle des relations d'héritage ou de collaboration manquent. Un graphe est " + "tronqué s'il n'entre pas dans les limites spécifiées." + "</ul>\n" + "Les flèches ont la signification suivante :\n" + "<ul>\n" + "<li>Une flèche bleu foncé est utilisée pour visualiser une relation d'héritage publique " + "entre deux classes.\n" + "<li>Une flèche vert foncé est utilisée pour une relation d'héritage protégée.\n" + "<li>Une flèche rouge foncé est utilisée pour une relation d'héritage privée.\n" + "<li>Une flèche violette en pointillés est utilisée si une classe est contenue ou " + "utilisée par une autre classe. La flèche est étiquetée avec la ou les variable(s) " + "qui permettent d'accéder à la classe ou structure pointée. \n" + "<li>Une flèche jaune en pointillés indique une relation entre un modèle d'instance et " + "le modèle de classe duquel il est instancié. La flèche est étiquetée avec " + "les paramètres de modèle de l'instance.\n" + "</ul>\n"; + } /*! text for the link to the legend page */ - virtual QCString trLegend() - { - return "légende"; - } + virtual QCString trLegend() + { + return "légende"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.0 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.0 +////////////////////////////////////////////////////////////////////////// /*! Used as a marker that is put before a test item */ - virtual QCString trTest() - { - return "Test"; - } + virtual QCString trTest() + { + return "Test"; + } /*! Used as the header of the test list */ - virtual QCString trTestList() - { - return "Liste des tests"; - } + virtual QCString trTestList() + { + return "Liste des tests"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.2 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.2 +////////////////////////////////////////////////////////////////////////// /*! Used as a section header for IDL properties */ - virtual QCString trProperties() - { - return "Propriétés"; - } + virtual QCString trProperties() + { + return "Propriétés"; + } /*! Used as a section header for IDL property documentation */ - virtual QCString trPropertyDocumentation() - { - return "Documentation des propriétés"; - } + virtual QCString trPropertyDocumentation() + { + return "Documentation des propriétés"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.4 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.4 +////////////////////////////////////////////////////////////////////////// /*! Used for Java classes in the summary section of Java packages */ - virtual QCString trClasses() + virtual QCString trClasses() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Structures de données"; - } - else - { - return "Classes"; - } + return "Structures de données"; } - /*! Used as the title of a Java package */ - virtual QCString trPackage(const char *name) + else { - return (QCString)"Paquetage "+name; + return "Classes"; } + } + /*! Used as the title of a Java package */ + virtual QCString trPackage(const char *name) + { + return (QCString)"Paquetage "+name; + } /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Liste des paquetages"; - } + virtual QCString trPackageList() + { + return "Liste des paquetages"; + } /*! The description of the package index page */ - virtual QCString trPackageListDescription() - { - return "Liste des paquetages avec une brève description (si disponible) :"; - } + virtual QCString trPackageListDescription() + { + return "Liste des paquetages avec une brève description (si disponible) :"; + } /*! The link name in the Quick links header for each page */ - virtual QCString trPackages() - { - return "Paquetages"; - } + virtual QCString trPackages() + { + return "Paquetages"; + } /*! Text shown before a multi-line define */ - virtual QCString trDefineValue() - { - return "Valeur :"; - } + virtual QCString trDefineValue() + { + return "Valeur :"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.5 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.5 +////////////////////////////////////////////////////////////////////////// /*! Used as a marker that is put before a \\bug item */ - virtual QCString trBug() - { - return "Bogue"; - } + virtual QCString trBug() + { + return "Bogue"; + } /*! Used as the header of the bug list */ - virtual QCString trBugList() - { - return "Liste des bogues"; - } + virtual QCString trBugList() + { + return "Liste des bogues"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.6 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.6 +////////////////////////////////////////////////////////////////////////// /*! Used as ansicpg for RTF file * @@ -1226,256 +1237,256 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 * </pre> * */ - virtual QCString trRTFansicp() - { - return "1252"; - } + virtual QCString trRTFansicp() + { + return "1252"; + } /*! Used as ansicpg for RTF fcharset * \see trRTFansicp() for a table of possible values. */ - virtual QCString trRTFCharSet() - { - return "0"; - } + virtual QCString trRTFCharSet() + { + return "0"; + } /*! Used as header RTF general index */ - virtual QCString trRTFGeneralIndex() - { - return "Index"; - } + virtual QCString trRTFGeneralIndex() + { + return "Index"; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trClass(bool first_capital, bool singular) - { - QCString result((first_capital ? "Classe" : "classe")); - if (!singular) result+="s"; - return result; - } + virtual QCString trClass(bool first_capital, bool singular) + { + QCString result((first_capital ? "Classe" : "classe")); + if (!singular) result+="s"; + return result; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trFile(bool first_capital, bool singular) - { - QCString result((first_capital ? "Fichier" : "fichier")); - if (!singular) result+="s"; - return result; - } + virtual QCString trFile(bool first_capital, bool singular) + { + QCString result((first_capital ? "Fichier" : "fichier")); + if (!singular) result+="s"; + return result; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trNamespace(bool first_capital, bool singular) - { - QCString result((first_capital ? "Espace" : "espace")); - if (!singular) result+="s"; - result+=" de nommage"; - return result; - } + virtual QCString trNamespace(bool first_capital, bool singular) + { + QCString result((first_capital ? "Espace" : "espace")); + if (!singular) result+="s"; + result+=" de nommage"; + return result; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trGroup(bool first_capital, bool singular) - { - QCString result((first_capital ? "Groupe" : "groupe")); - if (!singular) result+="s"; - return result; - } + virtual QCString trGroup(bool first_capital, bool singular) + { + QCString result((first_capital ? "Groupe" : "groupe")); + if (!singular) result+="s"; + return result; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trPage(bool first_capital, bool singular) - { - QCString result((first_capital ? "Page" : "page")); - if (!singular) result+="s"; - return result; - } + virtual QCString trPage(bool first_capital, bool singular) + { + QCString result((first_capital ? "Page" : "page")); + if (!singular) result+="s"; + return result; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trMember(bool first_capital, bool singular) - { - QCString result((first_capital ? "Membre" : "membre")); - if (!singular) result+="s"; - return result; - } + virtual QCString trMember(bool first_capital, bool singular) + { + QCString result((first_capital ? "Membre" : "membre")); + if (!singular) result+="s"; + return result; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names * of the category. */ - virtual QCString trGlobal(bool first_capital, bool singular) - { - QCString result((first_capital ? "Globa" : "globa")); - if (!singular) result+="ux(ales)"; else result+="l(e)"; - return result; - } + virtual QCString trGlobal(bool first_capital, bool singular) + { + QCString result((first_capital ? "Globa" : "globa")); + if (!singular) result+="ux(ales)"; else result+="l(e)"; + return result; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.7 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.7 +////////////////////////////////////////////////////////////////////////// /*! This text is generated when the \\author command is used and * for the author section in man pages. */ - virtual QCString trAuthor(bool first_capital, bool singular) - { - QCString result((first_capital ? "Auteur" : "auteur")); - if (!singular) result+="s"; - return result; - } + virtual QCString trAuthor(bool first_capital, bool singular) + { + QCString result((first_capital ? "Auteur" : "auteur")); + if (!singular) result+="s"; + return result; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.11 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.11 +////////////////////////////////////////////////////////////////////////// /*! This text is put before the list of members referenced by a member */ - virtual QCString trReferences() - { - return "Références"; - } + virtual QCString trReferences() + { + return "Références"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.13 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.13 +////////////////////////////////////////////////////////////////////////// /*! used in member documentation blocks to produce a list of * members that are implemented by this one. */ - virtual QCString trImplementedFromList(int numEntries) - { - return "Implémente "+trWriteList(numEntries)+"."; - } + virtual QCString trImplementedFromList(int numEntries) + { + return "Implémente "+trWriteList(numEntries)+"."; + } /*! used in member documentation blocks to produce a list of * all members that implement this abstract member. */ - virtual QCString trImplementedInList(int numEntries) - { - return "Implémenté dans "+trWriteList(numEntries)+"."; - } + virtual QCString trImplementedInList(int numEntries) + { + return "Implémenté dans "+trWriteList(numEntries)+"."; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.16 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.16 +////////////////////////////////////////////////////////////////////////// /*! used in RTF documentation as a heading for the Table * of Contents. */ - virtual QCString trRTFTableOfContents() - { - return "Table des matières"; - } + virtual QCString trRTFTableOfContents() + { + return "Table des matières"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.17 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// /*! Used as the header of the list of item that have been * flagged deprecated */ - virtual QCString trDeprecatedList() - { - return "Liste des éléments obsolètes"; - } + virtual QCString trDeprecatedList() + { + return "Liste des éléments obsolètes"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.2.18 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.2.18 +////////////////////////////////////////////////////////////////////////// /*! Used as a header for declaration section of the events found in * a C# program */ - virtual QCString trEvents() - { - return "Événements"; - } + virtual QCString trEvents() + { + return "Événements"; + } /*! Header used for the documentation section of a class' events. */ - virtual QCString trEventDocumentation() - { - return "Documentation des événements"; - } + virtual QCString trEventDocumentation() + { + return "Documentation des événements"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.3 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.3 +////////////////////////////////////////////////////////////////////////// /*! Used as a heading for a list of Java class types with package scope. */ - virtual QCString trPackageTypes() - { - return "Types de paquetage"; - } + virtual QCString trPackageTypes() + { + return "Types de paquetage"; + } /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() - { - return "Fonctions de paquetage"; - } + virtual QCString trPackageMembers() + { + return "Fonctions de paquetage"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() - { - return "Fonctions statiques de paquetage"; - } + virtual QCString trStaticPackageMembers() + { + return "Fonctions statiques de paquetage"; + } /*! Used as a heading for a list of Java class variables with package * scope. */ - virtual QCString trPackageAttribs() - { - return "Attributs de paquetage"; - } + virtual QCString trPackageAttribs() + { + return "Attributs de paquetage"; + } /*! Used as a heading for a list of static Java class variables with * package scope. */ - virtual QCString trStaticPackageAttribs() - { - return "Attributs statiques de paquetage"; - } + virtual QCString trStaticPackageAttribs() + { + return "Attributs statiques de paquetage"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.3.1 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.3.1 +////////////////////////////////////////////////////////////////////////// /*! Used in the quick index of a class/file/namespace member list page * to link to the unfiltered list of all members. */ - virtual QCString trAll() - { - return "Tout"; - } + virtual QCString trAll() + { + return "Tout"; + } /*! Put in front of the call graph for a function. */ - virtual QCString trCallGraph() - { - return "Voici le graphe d'appel pour cette fonction :"; - } + virtual QCString trCallGraph() + { + return "Voici le graphe d'appel pour cette fonction :"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.3.3 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.3.3 +////////////////////////////////////////////////////////////////////////// /*! This string is used as the title for the page listing the search * results. */ - virtual QCString trSearchResultsTitle() - { - return "Résultats de la recherche"; - } + virtual QCString trSearchResultsTitle() + { + return "Résultats de la recherche"; + } /*! This string is put just before listing the search results. The * text can be different depending on the number of documents found. * Inside the text you can put the special marker $num to insert @@ -1484,104 +1495,104 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 * value 2 represents 2 or more matches. HTML markup is allowed inside * the returned string. */ - virtual QCString trSearchResults(int numDocuments) + virtual QCString trSearchResults(int numDocuments) + { + if (numDocuments==0) { - if (numDocuments==0) - { - return "Désolé, aucun document ne correspond à votre requête."; - } - else if (numDocuments==1) - { - return "Trouvé <b>1</b> document correspondant à votre requête."; - } - else - { - return "Trouvé <b>$num</b> documents correspondant à votre requête. " + return "Désolé, aucun document ne correspond à votre requête."; + } + else if (numDocuments==1) + { + return "Trouvé <b>1</b> document correspondant à votre requête."; + } + else + { + return "Trouvé <b>$num</b> documents correspondant à votre requête. " "Classé par ordre de pertinence décroissant."; - } } + } /*! This string is put before the list of matched words, for each search * result. What follows is the list of words that matched the query. */ - virtual QCString trSearchMatches() - { - return "Correspondances :"; - } + virtual QCString trSearchMatches() + { + return "Correspondances :"; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.3.8 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.3.8 +////////////////////////////////////////////////////////////////////////// - /*! This is used in HTML as the title of page with source code for file filename - */ - virtual QCString trSourceFile(QCString& filename) - { - return " Fichier source de " + filename; - } + /*! This is used in HTML as the title of page with source code for file filename + */ + virtual QCString trSourceFile(QCString& filename) + { + return " Fichier source de " + filename; + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.3.9 - ////////////////////////////////////////////////////////////////////////// - - /*! This is used as the name of the chapter containing the directory - * hierarchy. - */ - virtual QCString trDirIndex() - { return "Hiérarchie de répertoires"; } - - /*! This is used as the name of the chapter containing the documentation - * of the directories. - */ - virtual QCString trDirDocumentation() - { return "Documentation des répertoires"; } - - /*! This is used as the title of the directory index and also in the - * Quick links of a HTML page, to link to the directory hierarchy. - */ - virtual QCString trDirectories() - { return "Répertoires"; } - - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Cette hiérarchie de répertoire est triée approximativement, " - "mais pas complètement, par ordre alphabétique :"; - } +////////////////////////////////////////////////////////////////////////// +// new since 1.3.9 +////////////////////////////////////////////////////////////////////////// - /*! This returns the title of a directory page. The name of the - * directory is passed via \a dirName. - */ - virtual QCString trDirReference(const char *dirName) - { QCString result="Répertoire de référence de "; result+=dirName; return result; } + /*! This is used as the name of the chapter containing the directory + * hierarchy. + */ + virtual QCString trDirIndex() + { return "Hiérarchie de répertoires"; } - /*! This returns the word directory with or without starting capital - * (\a first_capital) and in sigular or plural form (\a singular). - */ - virtual QCString trDir(bool first_capital, bool singular) - { - QCString result((first_capital ? "Répertoire" : "répertoire")); - if (singular) result+=""; else result+="s"; - return result; - } + /*! This is used as the name of the chapter containing the documentation + * of the directories. + */ + virtual QCString trDirDocumentation() + { return "Documentation des répertoires"; } + + /*! This is used as the title of the directory index and also in the + * Quick links of an HTML page, to link to the directory hierarchy. + */ + virtual QCString trDirectories() + { return "Répertoires"; } + + /*! This returns a sentences that introduces the directory hierarchy. + * and the fact that it is sorted alphabetically per level + */ + virtual QCString trDirDescription() + { return "Cette hiérarchie de répertoire est triée approximativement, " + "mais pas complètement, par ordre alphabétique :"; + } + + /*! This returns the title of a directory page. The name of the + * directory is passed via \a dirName. + */ + virtual QCString trDirReference(const char *dirName) + { QCString result="Répertoire de référence de "; result+=dirName; return result; } - ////////////////////////////////////////////////////////////////////////// - // new since 1.4.1 - ////////////////////////////////////////////////////////////////////////// + /*! This returns the word directory with or without starting capital + * (\a first_capital) and in singular or plural form (\a singular). + */ + virtual QCString trDir(bool first_capital, bool singular) + { + QCString result((first_capital ? "Répertoire" : "répertoire")); + if (singular) result+=""; else result+="s"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.1 +////////////////////////////////////////////////////////////////////////// /*! This text is added to the documentation when the \\overload command * is used for a overloaded function. */ - virtual QCString trOverloadText() - { - return "Ceci est une fonction membre surchargée, " + virtual QCString trOverloadText() + { + return "Ceci est une fonction membre surchargée, " "proposée par commodité. Elle diffère de la fonction " "ci-dessus uniquement par le(s) argument(s) qu'elle accepte."; - } + } - ////////////////////////////////////////////////////////////////////////// - // new since 1.4.6 - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.4.6 +////////////////////////////////////////////////////////////////////////// /*! This is used to introduce a caller (or called-by) graph */ virtual QCString trCallerGraph() @@ -1595,9 +1606,9 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 virtual QCString trEnumerationValueDocumentation() { return "Documentation des énumérations"; } - ////////////////////////////////////////////////////////////////////////// - // new since 1.5.4 (mainly for Fortran) - ////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// new since 1.5.4 (mainly for Fortran) +////////////////////////////////////////////////////////////////////////// /*! header that is put before the list of member subprograms (Fortran). */ virtual QCString trMemberFunctionDocumentationFortran() @@ -1832,7 +1843,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 } ////////////////////////////////////////////////////////////////////////// -// new since 1.6.3 +// new since 1.6.3 (missing items for the directory pages) ////////////////////////////////////////////////////////////////////////// /*! when clicking a directory dependency label, a page with a @@ -2269,20 +2280,23 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 } virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result = "Référence de "; - + QCString result = "Référence "; + bool feminine = true; switch(compType) { - case ClassDef::Class: result+="la classe "; break; - case ClassDef::Struct: result+="la structure "; break; - case ClassDef::Interface: result+="l'interface "; break; - case ClassDef::Exception: result+="l'exception "; break; + case ClassDef::Class: result+="de la classe "; break; + case ClassDef::Struct: result+="de la structure "; break; + case ClassDef::Union: result+="de l'union "; break; + case ClassDef::Interface: result+="de l'interface "; break; + case ClassDef::Protocol: result+="du protocole "; feminine=false; break; + case ClassDef::Category: result+="de la catégorie "; break; + case ClassDef::Exception: result+="de l'exception "; break; default: break; } if(isLocal) { - result += "locale "; + result += (feminine) ? "locale " : "local "; } result += (QCString)clName; diff --git a/src/translator_sv.h b/src/translator_sv.h index 5da89df..6277445 100644 --- a/src/translator_sv.h +++ b/src/translator_sv.h @@ -23,6 +23,7 @@ Xet Erixon <xet@xeqt.com> Mikael Hallin <mikaelhallin@yahoo.se> 2003-07-28 Björn Palmqvist <bjorn@aidium.se> 2014-02-01 Magnus Österlund <magnus.osterlund@capgemini.com> 2016-09-12 +Björn Palmqvist <bjorn@aidium.se> 2020-01-08 ================================================================================== Uppdateringar. 1999/04/29 @@ -70,16 +71,34 @@ Problem! * Uppdaterat den till senaste versionen 1.8.9.1 2015/09/12 * Fixat lite särksirvningar och inkonsekvenser +2020/01/08 +* Uppdaterat den till senaste sprÃ¥kversionen 1.8.15 + +Bytte ut Deprecated frÃ¥n FörÃ¥ldrad till Obsolet + +VHDL översättningarna är kanske inte perfekta, dÃ¥ jag endast använt de en gÃ¥ng tidigare. +Jag lämnade use clause orörd, dÃ¥ jag inte hittade en lämplig översättning för den. + +English: +* Updated the language translation to 1.8.15 + +Changed Deprecated from FörÃ¥ldrad to Obsolet + +The VHDL translations may not perfect, as I only used it once before. +I left use clause untouched as I didn't find a suitable translation for it. + =================================================================================== Ordlista =================================================================================== ENGELSKA SVENSKA * Attribute Attribut -* Category Lategori +* Category Kategori * Class Klass * Compound Sammansatt -* Deprecated FörÃ¥ldrad +* Deprecated Obsolet * Directory Katalog +* Dictionary Uppslagsverk // FrÃ¥gan om de är de som menas i de fallet +* Entity Entitet * Enum Enum * Enumeration Egenuppräknande * Event Händelse @@ -89,6 +108,7 @@ Problem! * Function Funktion * Inherited Ärvd * Interface Gränssnitt +* Library Biblotek * Macro Makro * Member Medlem * Member Data Medlemsdata @@ -103,16 +123,19 @@ Problem! * Protected Skyddad * Protocol Protokoll * Public Publik +* Record Post // Ge gärna exempel pÃ¥ bättre översättning * Service Tjänst * Signal Signal -* Slot Slot //Ge gärna exempel pÃ¥ bättre översättning +* Slot Slot // Ge gärna exempel pÃ¥ bättre översättning * Static Statisk * Struct Struktur * Subprogram Underprogram * Subroutine Subrutin +* Subtype Undertyp * Template Mall * Typedef Typdefinition * Union Union +* Unit Enhet // Lämplig översättning i VHDL kontextet? * Variable Variabel =================================================================================== */ @@ -120,7 +143,7 @@ Problem! #ifndef TRANSLATOR_SE_H #define TRANSLATOR_SE_H -class TranslatorSwedish : public TranslatorAdapter_1_8_15 +class TranslatorSwedish : public Translator { public: @@ -881,7 +904,7 @@ class TranslatorSwedish : public TranslatorAdapter_1_8_15 virtual QCString trDeprecated() { - return "FörÃ¥ldrad"; + return "Obsolet"; } ////////////////////////////////////////////////////////////////////////// @@ -1041,7 +1064,7 @@ class TranslatorSwedish : public TranslatorAdapter_1_8_15 virtual QCString trInclByDepGraph() { return "Den här grafen visar vilka filer som direkt eller " - "indirekt inkluderar denna filen:"; + "indirekt inkluderar denna filen:"; } virtual QCString trSince() { @@ -1152,7 +1175,7 @@ class TranslatorSwedish : public TranslatorAdapter_1_8_15 /*! Used as a section header for IDL properties */ virtual QCString trProperties() { - return "Egenskaper"; + return "Egenskaper"; } /*! Used as a section header for IDL property documentation */ virtual QCString trPropertyDocumentation() @@ -1230,8 +1253,8 @@ class TranslatorSwedish : public TranslatorAdapter_1_8_15 * Charset Name Charset Value(hex) Codepage number * ------------------------------------------------------ * ANSI_CHARSET 0 (x00) 1252 - * </pre> - */ + * </pre> + */ virtual QCString trRTFansicp() { return "1252"; @@ -1552,7 +1575,7 @@ class TranslatorSwedish : public TranslatorAdapter_1_8_15 * and the fact that it is sorted alphabetically per level */ virtual QCString trDirDescription() - { return "Den här katalogen är grovt sorterad, " + { return "Den här katalogen är grovt sorterad, " "men inte helt, i alfabetisk ordning:"; } @@ -2055,13 +2078,264 @@ class TranslatorSwedish : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentationen för denna singleton" + QCString result=(QCString)"Dokumentationen för denna singleton " "genererades frÃ¥n följande fil"; if (single) result+=":"; else result+="er:"; return result; } +////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Designenhetshirarki"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Designenhetslista"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Designenhetsmedlemmar"; } + /** VHDL design unit list description + * Orginal: Here is a list of all design unit members with links to + * the Entities they belong to: + */ + virtual QCString trDesignUnitListDescription() + { + return "Här är en lista av alla designenhetsmedlemmar med länkar till " + "entiteterna som de hör till:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Designenhetsindex"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Designenheter"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funktioner/Procedurer/Processer"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + return "Biblotek"; + case VhdlDocGen::PACKAGE: + return "Paket"; + case VhdlDocGen::SIGNAL: + if (single) return "Signal"; + else return "Signaler"; + case VhdlDocGen::COMPONENT: + if (single) return "Komponent"; + else return "Komponenter"; + case VhdlDocGen::CONSTANT: + if (single) return "Konstant"; + else return "Konstanter"; + case VhdlDocGen::ENTITY: + if (single) return "Entitet"; + else return "Entiteter"; + case VhdlDocGen::TYPE: + if (single) return "Typ"; + else return "Typer"; + case VhdlDocGen::SUBTYPE: + if (single) return "Undertyp"; + else return "Undertyper"; + case VhdlDocGen::FUNCTION: + if (single) return "Funktion"; + else return "Funktioner"; + case VhdlDocGen::RECORD: + if (single) return "Post"; + else return "Poster"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedur"; + else return "Procedurer"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Arkitektur"; + else return "Arkitekturer"; + case VhdlDocGen::ATTRIBUTE: + return "Attribut"; + case VhdlDocGen::PROCESS: + if (single) return "Process"; + else return "Processer"; + case VhdlDocGen::PORT: + if (single) return "Port"; + else return "Portar"; + case VhdlDocGen::USE: + if (single) return "use clause"; + else return "Use Clauses"; + case VhdlDocGen::GENERIC: + if (single) return "Generisk"; + else return "Generiska"; + case VhdlDocGen::PACKAGE_BODY: + return "PaketinehÃ¥ll"; + case VhdlDocGen::UNITS: + return "Enheter"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Delad Variabel"; + else return "Delade Variabler"; + case VhdlDocGen::VFILE: + if (single) return "Fil"; + else return "Filer"; + case VhdlDocGen::GROUP: + if (single) return "Grupp"; + else return "Grupper"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instantiation"; + else return "Instantiations"; + case VhdlDocGen::ALIAS: + return "Alias"; + case VhdlDocGen::CONFIG: + if (single) return "Konfiguration"; + else return "Konfigurationer"; + case VhdlDocGen::MISCELLANEOUS: + return "Diverse"; + case VhdlDocGen::UCF_CONST: + return "Begränsningar"; + default: + return "Klass"; + } + } + virtual QCString trCustomReference(const char *name) + { return QCString(name)+"referens"; } + + /* Slice */ + virtual QCString trConstants() + { + return "Konstanter"; + } + virtual QCString trConstantDocumentation() + { + return "Konstantdokumentation"; + } + virtual QCString trSequences() + { + return "Sekvenser"; + } + virtual QCString trSequenceDocumentation() + { + return "Sekvensdokumentation"; + } + virtual QCString trDictionaries() + { + return "Uppslagsverk"; + } + virtual QCString trDictionaryDocumentation() + { + return "Uppslagsverksdokumentation"; + } + virtual QCString trSliceInterfaces() + { + return "Gränssnitt"; + } + virtual QCString trInterfaceIndex() + { + return "Gränssnittsindex"; + } + virtual QCString trInterfaceList() + { + return "Gränssnittslist"; + } + /** Orginal: Here are the interfaces with brief descriptions: */ + virtual QCString trInterfaceListDescription() + { + return "Här är gränssnitten med en kort beskrivning"; + } + virtual QCString trInterfaceHierarchy() + { + return "Gränssnittshirarkin"; + } + /** Orginal: This inheritance list is sorted roughly, but not completely, alphabetically: */ + virtual QCString trInterfaceHierarchyDescription() + { + return "Denna arvslista är grovt sorterad, men inte helt, i alfabetisk ordning:"; + } + virtual QCString trInterfaceDocumentation() + { + return "Gränssnittsdokumentation"; + } + virtual QCString trStructs() + { + return "Strukturer"; + } + virtual QCString trStructIndex() + { + return "Strukturindex"; + } + virtual QCString trStructList() + { + return "Strukturlist"; + } + /** Orginal: Here are the structs with brief descriptions: */ + virtual QCString trStructListDescription() + { + return "Här är strukturerna med en kort beskrivning:"; + } + virtual QCString trStructDocumentation() + { + return "Strukturdokumentation"; + } + virtual QCString trExceptionIndex() + { + return "Undantagsindex"; + } + virtual QCString trExceptionList() + { + return "Undantagslista"; + } + /** Orginal: Here are the exceptions with brief descriptions: */ + virtual QCString trExceptionListDescription() + { + return "Här är undantagen med en kort beskrivning:"; + } + virtual QCString trExceptionHierarchy() + { + return "Undantagshirarki"; + } + /** Orginal: This inheritance list is sorted roughly, but not completely, alphabetically: */ + virtual QCString trExceptionHierarchyDescription() + { + return "Denna arvslista är grovt sorterad, men inte helt, i alfabetisk ordning:"; + } + virtual QCString trExceptionDocumentation() + { + return "Undantagsdokumentation"; + } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result=(QCString)clName; + if (isLocal) result+=" Lokal"; + switch(compType) + { + case ClassDef::Class: result+=" Klass"; break; + case ClassDef::Struct: result+=" Struktur"; break; + case ClassDef::Union: result+=" Unions"; break; + case ClassDef::Interface: result+=" Gränssnitts"; break; + case ClassDef::Protocol: result+=" Protokoll"; break; + case ClassDef::Category: result+=" Kategori"; break; + case ClassDef::Exception: result+=" Undantags"; break; + default: break; + } + result+="referens"; + return result; + } + virtual QCString trOperations() + { + return "Operationer"; + } + virtual QCString trOperationDocumentation() + { + return "Operationsdokumentation"; + } + virtual QCString trDataMembers() + { + return "Datamedlemmar"; + } + virtual QCString trDataMemberDocumentation() + { + return "Datamedlemsdokumentation"; + } }; #endif diff --git a/src/types.h b/src/types.h index 189a93d..d34444c 100644 --- a/src/types.h +++ b/src/types.h @@ -54,7 +54,7 @@ enum SrcLangExt SrcLangExt_Fortran = 0x01000, SrcLangExt_VHDL = 0x02000, SrcLangExt_XML = 0x04000, - SrcLangExt_Tcl = 0x08000, + //SrcLangExt_Tcl = 0x08000, // no longer supported SrcLangExt_Markdown = 0x10000, SrcLangExt_SQL = 0x20000, SrcLangExt_Slice = 0x40000 @@ -97,12 +97,6 @@ struct Grouping }; -struct ListItemInfo -{ - QCString type; - int itemId; -}; - enum MemberListType { MemberListType_privateLists = 0x0800, diff --git a/src/util.cpp b/src/util.cpp index abcd910..6d6112e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,11 +1,11 @@ /***************************************************************************** - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -19,6 +19,8 @@ #include <errno.h> #include <math.h> #include <limits.h> +#include <cinttypes> + #include "md5.h" @@ -84,7 +86,7 @@ #define ALGO_COUNT 1 #define ALGO_CRC16 2 #define ALGO_MD5 3 - + //#define MAP_ALGO ALGO_COUNT //#define MAP_ALGO ALGO_CRC16 #define MAP_ALGO ALGO_MD5 @@ -95,12 +97,12 @@ // TextGeneratorOLImpl implementation //------------------------------------------------------------------------ -TextGeneratorOLImpl::TextGeneratorOLImpl(OutputDocInterface &od) : m_od(od) +TextGeneratorOLImpl::TextGeneratorOLImpl(OutputDocInterface &od) : m_od(od) { } void TextGeneratorOLImpl::writeString(const char *s,bool keepSpaces) const -{ +{ if (s==0) return; //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces); if (keepSpaces) @@ -113,19 +115,19 @@ void TextGeneratorOLImpl::writeString(const char *s,bool keepSpaces) const cs[1]='\0'; while ((c=*p++)) { - if (c==' ') m_od.writeNonBreakableSpace(1); + if (c==' ') m_od.writeNonBreakableSpace(1); else cs[0]=c,m_od.docify(cs); } } } else { - m_od.docify(s); + m_od.docify(s); } } void TextGeneratorOLImpl::writeBreak(int indent) const -{ +{ m_od.lineBreak("typebreak"); int i; for (i=0;i<indent;i++) @@ -146,9 +148,9 @@ void TextGeneratorOLImpl::writeLink(const char *extRef,const char *file, //------------------------------------------------------------------------ // an inheritance tree of depth of 100000 should be enough for everyone :-) -const int maxInheritanceDepth = 100000; +const int maxInheritanceDepth = 100000; -/*! +/*! Removes all anonymous scopes from string s Possible examples: \verbatim @@ -177,9 +179,9 @@ QCString removeAnonymousScopes(const QCString &s) while (c<i+l && s.at(c)!='@') if (s.at(c++)==':') b1=TRUE; c=i+l-1; while (c>=i && s.at(c)!='@') if (s.at(c--)==':') b2=TRUE; - if (b1 && b2) - { - result+="::"; + if (b1 && b2) + { + result+="::"; } p=i+l; } @@ -248,7 +250,7 @@ done: void writePageRef(OutputDocInterface &od,const char *cn,const char *mn) { od.pushGeneratorState(); - + od.disable(OutputGenerator::Html); od.disable(OutputGenerator::Man); od.disable(OutputGenerator::Docbook); @@ -275,7 +277,7 @@ QCString generateMarker(int id) static QCString stripFromPath(const QCString &path,QStrList &l) { - // look at all the strings in the list and strip the longest match + // look at all the strings in the list and strip the longest match const char *s=l.first(); QCString potential; unsigned int length = 0; @@ -311,7 +313,7 @@ QCString stripFromIncludePath(const QCString &path) } /*! try to determine if \a name is a source or a header file name by looking - * at the extension. A number of variations is allowed in both upper and + * at the extension. A number of variations is allowed in both upper and * lower case) If anyone knows or uses another extension please let me know :-) */ int guessSection(const char *name) @@ -331,7 +333,7 @@ int guessSection(const char *name) n.right(4)==".i++" || n.right(4)==".inl" || n.right(4)==".xml" || - n.right(4)==".sql" + n.right(4)==".sql" ) return Entry::SOURCE_SEC; if (n.right(2)==".h" || // header n.right(3)==".hh" || @@ -352,7 +354,7 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, //printf("<<resolveTypeDef(%s,%s)\n", // context ? context->name().data() : "<none>",qualifiedName.data()); QCString result; - if (qualifiedName.isEmpty()) + if (qualifiedName.isEmpty()) { //printf(" qualified name empty!\n"); return result; @@ -379,7 +381,7 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, { // step 1: get the right scope const Definition *resScope=mContext; - if (scopeIndex!=-1) + if (scopeIndex!=-1) { // split-off scope part QCString resScopeName = qualifiedName.left(scopeIndex); @@ -400,38 +402,36 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, } } //printf("resScope=%s\n",resScope?resScope->name().data():"<none>"); - + // step 2: get the member - if (resScope) // no scope or scope found in the current context + if (resScope) // no scope or scope found in the current context { //printf("scope found: %s, look for typedef %s\n", // resScope->qualifiedName().data(),resName.data()); - MemberNameSDict *mnd=0; + MemberNameLinkedMap *mnd=0; if (resScope->definitionType()==Definition::TypeClass) { - mnd=Doxygen::memberNameSDict; + mnd=Doxygen::memberNameLinkedMap; } else { - mnd=Doxygen::functionNameSDict; + mnd=Doxygen::functionNameLinkedMap; } MemberName *mn=mnd->find(resName); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *tmd=0; int minDist=-1; - for (;(tmd=mni.current());++mni) + for (const auto &tmd : *mn) { //printf("Found member %s resScope=%s outerScope=%s mContext=%p\n", - // tmd->name().data(), resScope->name().data(), + // tmd->name().data(), resScope->name().data(), // tmd->getOuterScope()->name().data(), mContext); if (tmd->isTypedef() /*&& tmd->getOuterScope()==resScope*/) { - int dist=isAccessibleFrom(resScope,0,tmd); + int dist=isAccessibleFrom(resScope,0,tmd.get()); if (dist!=-1 && (md==0 || dist<minDist)) { - md = tmd; + md = tmd.get(); minDist = dist; } } @@ -465,11 +465,11 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, // qualifiedName.data(),context ? context->name().data() : "<global>"); } return result; - + } -/*! Get a class definition given its name. +/*! Get a class definition given its name. * Returns 0 if the class is not found. */ ClassDef *getClass(const char *n) @@ -532,7 +532,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop * within file \a fileScope. * * Example: typedef A T; will return the class representing A if it is a class. - * + * * Example: typedef int T; will return 0, since "int" is not a class. */ const ClassDef *newResolveTypedef(const FileDef *fileScope, @@ -560,7 +560,7 @@ const ClassDef *newResolveTypedef(const FileDef *fileScope, if (g_resolvedTypedefs.find(qname)) return 0; // typedef already done g_resolvedTypedefs.insert(qname,md); // put on the trace list - + const ClassDef *typeClass = md->getClassDef(); QCString type = md->typeString(); // get the "value" of the typedef if (typeClass && typeClass->isTemplate() && @@ -572,7 +572,7 @@ const ClassDef *newResolveTypedef(const FileDef *fileScope, QCString typedefValue = type; int tl=type.length(); int ip=tl-1; // remove * and & at the end - while (ip>=0 && (type.at(ip)=='*' || type.at(ip)=='&' || type.at(ip)==' ')) + while (ip>=0 && (type.at(ip)=='*' || type.at(ip)=='&' || type.at(ip)==' ')) { ip--; } @@ -587,7 +587,7 @@ const ClassDef *newResolveTypedef(const FileDef *fileScope, const ClassDef *result = getResolvedClassRec(md->getOuterScope(), fileScope,type,&memTypeDef,0,pResolvedType); // if type is a typedef then return what it resolves to. - if (memTypeDef && memTypeDef->isTypedef()) + if (memTypeDef && memTypeDef->isTypedef()) { result=newResolveTypedef(fileScope,memTypeDef,pMemType,pTemplSpec); goto done; @@ -647,8 +647,8 @@ done: } // remember computed value for next time - if (result && result->getDefFileName()!="<code>") - // this check is needed to prevent that temporary classes that are + if (result && result->getDefFileName()!="<code>") + // this check is needed to prevent that temporary classes that are // introduced while parsing code fragments are being cached here. { //printf("setting cached typedef %p in result %p\n",md,result); @@ -659,9 +659,9 @@ done: pResolvedType ? *pResolvedType : QCString() ); } - + g_resolvedTypedefs.remove(qname); // remove from the trace list - + return result; } @@ -696,11 +696,11 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co { // test accessibility of typedef within scope. int distance = isAccessibleFromWithExpScope(scope,fileScope,d,""); - if (distance!=-1 && distance<minDistance) + if (distance!=-1 && distance<minDistance) // definition is accessible and a better match { minDistance=distance; - bestMatch = md; + bestMatch = md; } } } @@ -715,18 +715,18 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co { // test accessibility of typedef within scope. int distance = isAccessibleFromWithExpScope(scope,fileScope,d,""); - if (distance!=-1) // definition is accessible + if (distance!=-1) // definition is accessible { - bestMatch = md; + bestMatch = md; } } } - if (bestMatch) + if (bestMatch) { result = bestMatch->typeString(); if (pTypeDef) *pTypeDef=bestMatch; } - + //printf("substTypedef(%s,%s)=%s\n",scope?scope->name().data():"<global>", // name.data(),result.data()); return result; @@ -750,8 +750,8 @@ static const Definition *endOfPathIsUsedClass(const SDict<Definition> *cl,const } /*! Starting with scope \a start, the string \a path is interpreted as - * a part of a qualified scope name (e.g. A::B::C), and the scope is - * searched. If found the scope definition is returned, otherwise 0 + * a part of a qualified scope name (e.g. A::B::C), and the scope is + * searched. If found the scope definition is returned, otherwise 0 * is returned. */ static const Definition *followPath(const Definition *start,const FileDef *fileScope,const QCString &path) @@ -782,7 +782,7 @@ static const Definition *followPath(const Definition *start,const FileDef *fileS // qualScopePart.data(), // current->name().data(), // next?next->name().data():"<null>"); - if (next==0) // failed to follow the path + if (next==0) // failed to follow the path { //printf("==> next==0!\n"); if (current->definitionType()==Definition::TypeNamespace) @@ -817,7 +817,7 @@ bool accessibleViaUsingClass(const SDict<Definition> *cl, ) { //printf("accessibleViaUsingClass(%p)\n",cl); - if (cl) // see if the class was imported via a using statement + if (cl) // see if the class was imported via a using statement { SDict<Definition>::Iterator cli(*cl); Definition *ucd; @@ -826,7 +826,7 @@ bool accessibleViaUsingClass(const SDict<Definition> *cl, { //printf("Trying via used class %s\n",ucd->name().data()); const Definition *sc = explicitScopePartEmpty ? ucd : followPath(ucd,fileScope,explicitScopePart); - if (sc && sc==item) return TRUE; + if (sc && sc==item) return TRUE; //printf("Try via used class done\n"); } } @@ -849,10 +849,10 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl, //printf("[Trying via used namespace %s: count=%d/%d\n",und->name().data(), // count,nl->count()); const Definition *sc = explicitScopePart.isEmpty() ? und : followPath(und,fileScope,explicitScopePart); - if (sc && item->getOuterScope()==sc) + if (sc && item->getOuterScope()==sc) { //printf("] found it\n"); - return TRUE; + return TRUE; } if (item->getLanguage()==SrcLangExt_Cpp) { @@ -916,7 +916,7 @@ class AccessStack for (i=0;i<m_index;i++) { AccessElem *e = &m_elements[i]; - if (e->scope==scope && e->fileScope==fileScope && e->item==item) + if (e->scope==scope && e->fileScope==fileScope && e->item==item) { return TRUE; } @@ -929,7 +929,7 @@ class AccessStack for (i=0;i<m_index;i++) { AccessElem *e = &m_elements[i]; - if (e->scope==scope && e->fileScope==fileScope && e->item==item && e->expScope==expScope) + if (e->scope==scope && e->fileScope==fileScope && e->item==item && e->expScope==expScope) { return TRUE; } @@ -951,7 +951,7 @@ class AccessStack }; /* Returns the "distance" (=number of levels up) from item to scope, or -1 - * if item in not inside scope. + * if item in not inside scope. */ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Definition *item) { @@ -969,20 +969,20 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi int i; Definition *itemScope=item->getOuterScope(); - bool memberAccessibleFromScope = + bool memberAccessibleFromScope = (item->definitionType()==Definition::TypeMember && // a member itemScope && itemScope->definitionType()==Definition::TypeClass && // of a class scope->definitionType()==Definition::TypeClass && // accessible (dynamic_cast<const ClassDef*>(scope))->isAccessibleMember(dynamic_cast<const MemberDef *>(item)) // from scope ); - bool nestedClassInsideBaseClass = + bool nestedClassInsideBaseClass = (item->definitionType()==Definition::TypeClass && // a nested class - itemScope && itemScope->definitionType()==Definition::TypeClass && // inside a base + itemScope && itemScope->definitionType()==Definition::TypeClass && // inside a base scope->definitionType()==Definition::TypeClass && // class of scope - (dynamic_cast<const ClassDef*>(scope))->isBaseClass(dynamic_cast<ClassDef*>(itemScope),TRUE) + (dynamic_cast<const ClassDef*>(scope))->isBaseClass(dynamic_cast<ClassDef*>(itemScope),TRUE) ); - if (itemScope==scope || memberAccessibleFromScope || nestedClassInsideBaseClass) + if (itemScope==scope || memberAccessibleFromScope || nestedClassInsideBaseClass) { //printf("> found it\n"); if (nestedClassInsideBaseClass) result++; // penalty for base class to prevent @@ -994,13 +994,13 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi if (fileScope) { SDict<Definition> *cl = fileScope->getUsedClasses(); - if (accessibleViaUsingClass(cl,fileScope,item)) + if (accessibleViaUsingClass(cl,fileScope,item)) { //printf("> found via used class\n"); goto done; } NamespaceSDict *nl = fileScope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item)) + if (accessibleViaUsingNamespace(nl,fileScope,item)) { //printf("> found via used namespace\n"); goto done; @@ -1017,13 +1017,13 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(scope); //printf(" %s is namespace with %d used classes\n",nscope->name().data(),nscope->getUsedClasses()); const SDict<Definition> *cl = nscope->getUsedClasses(); - if (accessibleViaUsingClass(cl,fileScope,item)) + if (accessibleViaUsingClass(cl,fileScope,item)) { //printf("> found via used class\n"); goto done; } const NamespaceSDict *nl = nscope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item)) + if (accessibleViaUsingNamespace(nl,fileScope,item)) { //printf("> found via used namespace\n"); goto done; @@ -1050,10 +1050,10 @@ done: * class B { public: class J {}; }; * * - Looking for item=='J' inside scope=='B' will return 0. - * - Looking for item=='I' inside scope=='B' will return -1 + * - Looking for item=='I' inside scope=='B' will return -1 * (as it is not found in B nor in the global scope). - * - Looking for item=='A::I' inside scope=='B', first the match B::A::I is tried but - * not found and then A::I is searched in the global scope, which matches and + * - Looking for item=='A::I' inside scope=='B', first the match B::A::I is tried but + * not found and then A::I is searched in the global scope, which matches and * thus the result is 1. */ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope, @@ -1097,7 +1097,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop (dynamic_cast<const ClassDef*>(newScope))->isBaseClass(dynamic_cast<const ClassDef*>(itemScope),TRUE,0) ) { - // inheritance is also ok. Example: looking for B::I, where + // inheritance is also ok. Example: looking for B::I, where // class A { public: class I {} }; // class B : public A {} // but looking for B::I, where @@ -1172,7 +1172,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop { const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(scope); const NamespaceSDict *nl = nscope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) + if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) { //printf("> found in used namespace\n"); goto done; @@ -1183,7 +1183,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop if (fileScope) { const NamespaceSDict *nl = fileScope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) + if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) { //printf("> found in used namespace\n"); goto done; @@ -1216,7 +1216,7 @@ int computeQualifiedIndex(const QCString &name) static void getResolvedSymbol(const Definition *scope, const FileDef *fileScope, - Definition *d, + Definition *d, const QCString &explicitScopePart, ArgumentList *actTemplParams, int &minDistance, @@ -1231,8 +1231,8 @@ static void getResolvedSymbol(const Definition *scope, // only look at classes and members that are enums or typedefs if (d->definitionType()==Definition::TypeClass || - (d->definitionType()==Definition::TypeMember && - ((dynamic_cast<MemberDef*>(d))->isTypedef() || (dynamic_cast<MemberDef*>(d))->isEnumerate()) + (d->definitionType()==Definition::TypeMember && + ((dynamic_cast<MemberDef*>(d))->isTypedef() || (dynamic_cast<MemberDef*>(d))->isEnumerate()) ) ) { @@ -1248,23 +1248,23 @@ static void getResolvedSymbol(const Definition *scope, ClassDef *cd = dynamic_cast<ClassDef *>(d); //printf("cd=%s\n",cd->name().data()); if (!cd->isTemplateArgument()) // skip classes that - // are only there to - // represent a template + // are only there to + // represent a template // argument { //printf("is not a templ arg\n"); if (distance<minDistance) // found a definition that is "closer" { minDistance=distance; - bestMatch = cd; + bestMatch = cd; bestTypedef = 0; bestTemplSpec.resize(0); bestResolvedType = cd->qualifiedName(); } else if (distance==minDistance && fileScope && bestMatch && - fileScope->getUsedNamespaces() && - d->getOuterScope()->definitionType()==Definition::TypeNamespace && + fileScope->getUsedNamespaces() && + d->getOuterScope()->definitionType()==Definition::TypeNamespace && bestMatch->getOuterScope()==Doxygen::globalScope ) { @@ -1277,7 +1277,7 @@ static void getResolvedSymbol(const Definition *scope, // Just a non-perfect heuristic but it could help in some situations // (kdecore code is an example). minDistance=distance; - bestMatch = cd; + bestMatch = cd; bestTypedef = 0; bestTemplSpec.resize(0); bestResolvedType = cd->qualifiedName(); @@ -1376,7 +1376,7 @@ static void getResolvedSymbol(const Definition *scope, /* Find the fully qualified class name referred to by the input class * or typedef name against the input scope. * Loops through scope and each of its parent scopes looking for a - * match against the input name. Can recursively call itself when + * match against the input name. Can recursively call itself when * resolving typedefs. */ static const ClassDef *getResolvedClassRec(const Definition *scope, @@ -1411,7 +1411,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, name=name.mid(qualifierIndex+2); } - if (name.isEmpty()) + if (name.isEmpty()) { //printf("] empty name\n"); return 0; // empty name @@ -1419,9 +1419,9 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, //printf("Looking for symbol %s\n",name.data()); DefinitionIntf *di = Doxygen::symbolMap->find(name); - // the -g (for C# generics) and -p (for ObjC protocols) are now already + // the -g (for C# generics) and -p (for ObjC protocols) are now already // stripped from the key used in the symbolMap, so that is not needed here. - if (di==0) + if (di==0) { //di = Doxygen::symbolMap->find(name+"-g"); //if (di==0) @@ -1436,11 +1436,11 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, } //printf("found symbol!\n"); - bool hasUsingStatements = - (fileScope && ((fileScope->getUsedNamespaces() && + bool hasUsingStatements = + (fileScope && ((fileScope->getUsedNamespaces() && fileScope->getUsedNamespaces()->count()>0) || - (fileScope->getUsedClasses() && - fileScope->getUsedClasses()->count()>0)) + (fileScope->getUsedClasses() && + fileScope->getUsedClasses()->count()>0)) ); //printf("hasUsingStatements=%d\n",hasUsingStatements); // Since it is often the case that the same name is searched in the same @@ -1467,7 +1467,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, // if a file scope is given and it contains using statements we should // also use the file part in the key (as a class name can be in - // two different namespaces and a using statement in a file can select + // two different namespaces and a using statement in a file can select // one of them). if (hasUsingStatements) { @@ -1483,19 +1483,19 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, //printf("Searching for %s result=%p\n",key.data(),pval); if (pval) { - //printf("LookupInfo %p %p '%s' %p\n", - // pval->classDef, pval->typeDef, pval->templSpec.data(), - // pval->resolvedType.data()); + //printf("LookupInfo %p %p '%s' %p\n", + // pval->classDef, pval->typeDef, pval->templSpec.data(), + // pval->resolvedType.data()); if (pTemplSpec) *pTemplSpec=pval->templSpec; if (pTypeDef) *pTypeDef=pval->typeDef; if (pResolvedType) *pResolvedType=pval->resolvedType; //printf("] cachedMatch=%s\n", // pval->classDef?pval->classDef->name().data():"<none>"); - //if (pTemplSpec) + //if (pTemplSpec) // printf("templSpec=%s\n",pTemplSpec->data()); - return pval->classDef; + return pval->classDef; } - else // not found yet; we already add a 0 to avoid the possibility of + else // not found yet; we already add a 0 to avoid the possibility of // endless recursion. { Doxygen::lookupCache->insert(key,new LookupInfo); @@ -1529,7 +1529,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, bestResolvedType); } - if (pTypeDef) + if (pTypeDef) { *pTypeDef = bestTypedef; } @@ -1558,7 +1558,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, } //printf("] bestMatch=%s distance=%d\n", // bestMatch?bestMatch->name().data():"<none>",minDistance); - //if (pTemplSpec) + //if (pTemplSpec) // printf("templSpec=%s\n",pTemplSpec->data()); return bestMatch; } @@ -1566,7 +1566,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, /* Find the fully qualified class name referred to by the input class * or typedef name against the input scope. * Loops through scope and each of its parent scopes looking for a - * match against the input name. + * match against the input name. */ const ClassDef *getResolvedClass(const Definition *scope, const FileDef *fileScope, @@ -1581,7 +1581,7 @@ const ClassDef *getResolvedClass(const Definition *scope, static bool optimizeOutputVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); g_resolvedTypedefs.clear(); if (scope==0 || - (scope->definitionType()!=Definition::TypeClass && + (scope->definitionType()!=Definition::TypeClass && scope->definitionType()!=Definition::TypeNamespace ) || (scope->getLanguage()==SrcLangExt_Java && QCString(n).find("::")!=-1) @@ -1610,7 +1610,7 @@ const ClassDef *getResolvedClass(const Definition *scope, { result = getClass(n); } - if (!mayBeUnlinkable && result && !result->isLinkable()) + if (!mayBeUnlinkable && result && !result->isLinkable()) { if (!mayBeHidden || !result->isHidden()) { @@ -1628,34 +1628,6 @@ const ClassDef *getResolvedClass(const Definition *scope, //------------------------------------------------------------------------- //------------------------------------------------------------------------- -static bool findOperator(const QCString &s,int i) -{ - int b = s.findRev("operator",i); - if (b==-1) return FALSE; // not found - b+=8; - while (b<i) // check if there are only spaces in between - // the operator and the > - { - if (!isspace((uchar)s.at(b))) return FALSE; - b++; - } - return TRUE; -} - -static bool findOperator2(const QCString &s,int i) -{ - int b = s.findRev("operator",i); - if (b==-1) return FALSE; // not found - b+=8; - while (b<i) // check if there are only non-ascii - // characters in front of the operator - { - if (isId((uchar)s.at(b))) return FALSE; - b++; - } - return TRUE; -} - static const char constScope[] = { 'c', 'o', 'n', 's', 't', ':' }; static const char virtualScope[] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' }; static const char operatorScope[] = { 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' }; @@ -1664,30 +1636,30 @@ struct CharAroundSpace { CharAroundSpace() { - charMap['('].before=FALSE; - charMap['='].before=FALSE; - charMap['&'].before=FALSE; - charMap['*'].before=FALSE; - charMap['['].before=FALSE; - charMap['|'].before=FALSE; - charMap['+'].before=FALSE; - charMap[';'].before=FALSE; - charMap[':'].before=FALSE; - charMap['/'].before=FALSE; - - charMap['='].after=FALSE; - charMap[' '].after=FALSE; - charMap['['].after=FALSE; - charMap[']'].after=FALSE; - charMap['\t'].after=FALSE; - charMap['\n'].after=FALSE; - charMap[')'].after=FALSE; - charMap[','].after=FALSE; - charMap['<'].after=FALSE; - charMap['|'].after=FALSE; - charMap['+'].after=FALSE; - charMap['('].after=FALSE; - charMap['/'].after=FALSE; + charMap[static_cast<int>('(')].before=FALSE; + charMap[static_cast<int>('=')].before=FALSE; + charMap[static_cast<int>('&')].before=FALSE; + charMap[static_cast<int>('*')].before=FALSE; + charMap[static_cast<int>('[')].before=FALSE; + charMap[static_cast<int>('|')].before=FALSE; + charMap[static_cast<int>('+')].before=FALSE; + charMap[static_cast<int>(';')].before=FALSE; + charMap[static_cast<int>(':')].before=FALSE; + charMap[static_cast<int>('/')].before=FALSE; + + charMap[static_cast<int>('=')].after=FALSE; + charMap[static_cast<int>(' ')].after=FALSE; + charMap[static_cast<int>('[')].after=FALSE; + charMap[static_cast<int>(']')].after=FALSE; + charMap[static_cast<int>('\t')].after=FALSE; + charMap[static_cast<int>('\n')].after=FALSE; + charMap[static_cast<int>(')')].after=FALSE; + charMap[static_cast<int>(',')].after=FALSE; + charMap[static_cast<int>('<')].after=FALSE; + charMap[static_cast<int>('|')].after=FALSE; + charMap[static_cast<int>('+')].after=FALSE; + charMap[static_cast<int>('(')].after=FALSE; + charMap[static_cast<int>('/')].after=FALSE; } struct CharElem { @@ -1994,10 +1966,10 @@ bool rightScopeMatch(const QCString &scope, const QCString &name) { int sl=scope.length(); int nl=name.length(); - return (name==scope || // equal - (scope.right(nl)==name && // substring + return (name==scope || // equal + (scope.right(nl)==name && // substring sl-nl>1 && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope - ) + ) ); } @@ -2005,10 +1977,10 @@ bool leftScopeMatch(const QCString &scope, const QCString &name) { int sl=scope.length(); int nl=name.length(); - return (name==scope || // equal - (scope.left(nl)==name && // substring + return (name==scope || // equal + (scope.left(nl)==name && // substring sl>nl+1 && scope.at(nl)==':' && scope.at(nl+1)==':' // scope - ) + ) ); } @@ -2045,11 +2017,11 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, } // add non-word part to the result - bool insideString=FALSE; + bool insideString=FALSE; int i; - for (i=index;i<newIndex;i++) - { - if (txtStr.at(i)=='"') insideString=!insideString; + for (i=index;i<newIndex;i++) + { + if (txtStr.at(i)=='"') insideString=!insideString; } //printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak); @@ -2069,16 +2041,16 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, out.writeBreak(indentLevel==0 ? 0 : indentLevel+1); out.writeString(splitText.right(splitLength-i-offset),keepSpaces); floatingIndex=splitLength-i-offset+matchLen; - } + } else { - out.writeString(splitText,keepSpaces); + out.writeString(splitText,keepSpaces); } } else { - //ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex)); - out.writeString(txtStr.mid(skipIndex,newIndex-skipIndex),keepSpaces); + //ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex)); + out.writeString(txtStr.mid(skipIndex,newIndex-skipIndex),keepSpaces); } // get word from string QCString word=txtStr.mid(newIndex,matchLen); @@ -2112,7 +2084,7 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, } } } - if (!found && (cd || (cd=getClass(matchWord)))) + if (!found && (cd || (cd=getClass(matchWord)))) { //printf("Found class %s\n",cd->name().data()); // add link to the result @@ -2156,10 +2128,10 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, int m = matchWord.findRev("::"); QCString scopeName; - if (scope && - (scope->definitionType()==Definition::TypeClass || + if (scope && + (scope->definitionType()==Definition::TypeClass || scope->definitionType()==Definition::TypeNamespace - ) + ) ) { scopeName=scope->name(); @@ -2171,19 +2143,19 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, } //printf("ScopeName=%s\n",scopeName.data()); - //if (!found) printf("Trying to link %s in %s\n",word.data(),scopeName.data()); - if (!found && - getDefs(scopeName,matchWord,0,md,cd,fd,nd,gd) && - //(md->isTypedef() || md->isEnumerate() || + //if (!found) printf("Trying to link %s in %s\n",word.data(),scopeName.data()); + if (!found && + getDefs(scopeName,matchWord,0,md,cd,fd,nd,gd) && + //(md->isTypedef() || md->isEnumerate() || // md->isReference() || md->isVariable() - //) && - (external ? md->isLinkable() : md->isLinkableInProject()) + //) && + (external ? md->isLinkable() : md->isLinkableInProject()) ) { //printf("Found ref scope=%s\n",d?d->name().data():"<global>"); //ol.writeObjectLink(d->getReference(),d->getOutputFileBase(), // md->anchor(),word); - if (md!=self && (self==0 || md->name()!=self->name())) + if (md!=self && (self==0 || md->name()!=self->name())) // name check is needed for overloaded members, where getDefs just returns one { /* in case of Fortran scop and the variable is a non Fortran variable: don't link, @@ -2230,7 +2202,7 @@ void writeExample(OutputList &ol,ExampleSDict *ed) ol.parseText(exampleLine.mid(index,newIndex-index)); uint entryIndex = exampleLine.mid(newIndex+1,matchLen-1).toUInt(&ok); Example *e=ed->at(entryIndex); - if (ok && e) + if (ok && e) { ol.pushGeneratorState(); //if (latexEnabled) ol.disable(OutputGenerator::Latex); @@ -2254,7 +2226,7 @@ void writeExample(OutputList &ol,ExampleSDict *ed) ol.popGeneratorState(); } index=newIndex+matchLen; - } + } ol.parseText(exampleLine.right(exampleLine.length()-index)); ol.writeString("."); } @@ -2404,7 +2376,7 @@ int filterCRLF(char *buf,int len) { c = '\n'; // each CR to LF if (src<len && buf[src] == '\n') - ++src; // skip LF just after CR (DOS) + ++src; // skip LF just after CR (DOS) } else if ( c == '\0' && src<len-1) // filter out internal \0 characters, as it will confuse the parser { @@ -2428,8 +2400,8 @@ static QCString getFilterFromList(const char *name,const QStrList &filterList,bo if (i_equals!=-1) { QCString filterPattern = fs.left(i_equals); - QRegExp fpat(filterPattern,Portable::fileSystemIsCaseSensitive(),TRUE); - if (fpat.match(name)!=-1) + QRegExp fpat(filterPattern,Portable::fileSystemIsCaseSensitive(),TRUE); + if (fpat.match(name)!=-1) { // found a match! QCString filterName = fs.mid(i_equals+1); @@ -2497,7 +2469,7 @@ QCString transcodeCharacterStringToUTF8(const QCString &input) int outputSize=inputSize*4+1; QCString output(outputSize); void *cd = portable_iconv_open(outputEncoding,inputEncoding); - if (cd==(void *)(-1)) + if (cd==(void *)(-1)) { err("unsupported character conversion: '%s'->'%s'\n", inputEncoding.data(),outputEncoding); @@ -2529,7 +2501,7 @@ QCString transcodeCharacterStringToUTF8(const QCString &input) /*! reads a file with name \a name and returns it as a string. If \a filter * is TRUE the file will be filtered by any user specified input filter. - * If \a name is "-" the string will be read from standard input. + * If \a name is "-" the string will be read from standard input. */ QCString fileToString(const char *name,bool filter,bool isSourceCode) { @@ -2579,7 +2551,7 @@ QCString fileToString(const char *name,bool filter,bool isSourceCode) return buf.data(); } } - if (!fileOpened) + if (!fileOpened) { err("cannot open file '%s' for reading\n",name); } @@ -2609,7 +2581,7 @@ static QDateTime getCurrentDateTime() static bool warnedOnce=FALSE; if (!warnedOnce) { - warn_uncond("Environment variable SOURCE_DATE_EPOCH must have a value smaller than or equal to %llu; actual value %llu\n",UINT_MAX,epoch); + warn_uncond("Environment variable SOURCE_DATE_EPOCH must have a value smaller than or equal to %d; actual value %" PRIu64 "\n",UINT_MAX, (uint64_t)epoch); warnedOnce=TRUE; } } @@ -2643,24 +2615,24 @@ QCString yearToString() } //---------------------------------------------------------------------- -// recursive function that returns the number of branches in the +// recursive function that returns the number of branches in the // inheritance tree that the base class 'bcd' is below the class 'cd' int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) { - if (bcd->categoryOf()) // use class that is being extended in case of + if (bcd->categoryOf()) // use class that is being extended in case of // an Objective-C category { bcd=bcd->categoryOf(); } - if (cd==bcd) return level; + if (cd==bcd) return level; if (level==256) { warn_uncond("class %s seem to have a recursive " "inheritance relation!\n",cd->name().data()); return -1; } - int m=maxInheritanceDepth; + int m=maxInheritanceDepth; if (cd->baseClasses()) { BaseClassListIterator bcli(*cd->baseClasses()); @@ -2677,12 +2649,12 @@ int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) Protection classInheritedProtectionLevel(const ClassDef *cd,const ClassDef *bcd,Protection prot,int level) { - if (bcd->categoryOf()) // use class that is being extended in case of + if (bcd->categoryOf()) // use class that is being extended in case of // an Objective-C category { bcd=bcd->categoryOf(); } - if (cd==bcd) + if (cd==bcd) { goto exit; } @@ -2707,165 +2679,6 @@ exit: return prot; } -#ifndef NEWMATCH -// strip any template specifiers that follow className in string s -static QCString trimTemplateSpecifiers( - const QCString &namespaceName, - const QCString &className, - const QCString &s - ) -{ - //printf("trimTemplateSpecifiers(%s,%s,%s)\n",namespaceName.data(),className.data(),s.data()); - QCString scopeName=mergeScopes(namespaceName,className); - ClassDef *cd=getClass(scopeName); - if (cd==0) return s; // should not happen, but guard anyway. - - QCString result=s; - - int i=className.length()-1; - if (i>=0 && className.at(i)=='>') // template specialization - { - // replace unspecialized occurrences in s, with their specialized versions. - int count=1; - int cl=i+1; - while (i>=0) - { - char c=className.at(i); - if (c=='>') count++,i--; - else if (c=='<') { count--; if (count==0) break; } - else i--; - } - QCString unspecClassName=className.left(i); - int l=i; - int p=0; - while ((i=result.find(unspecClassName,p))!=-1) - { - if (result.at(i+l)!='<') // unspecialized version - { - result=result.left(i)+className+result.right(result.length()-i-l); - l=cl; - } - p=i+l; - } - } - - //printf("result after specialization: %s\n",result.data()); - - QCString qualName=cd->qualifiedNameWithTemplateParameters(); - //printf("QualifiedName = %s\n",qualName.data()); - // We strip the template arguments following className (if any) - if (!qualName.isEmpty()) // there is a class name - { - int is,ps=0; - int p=0,l,i; - - while ((is=getScopeFragment(qualName,ps,&l))!=-1) - { - QCString qualNamePart = qualName.right(qualName.length()-is); - //printf("qualNamePart=%s\n",qualNamePart.data()); - while ((i=result.find(qualNamePart,p))!=-1) - { - int ql=qualNamePart.length(); - result=result.left(i)+cd->name()+result.right(result.length()-i-ql); - p=i+cd->name().length(); - } - ps=is+l; - } - } - //printf("result=%s\n",result.data()); - - return result.stripWhiteSpace(); -} - -/*! - * @param pattern pattern to look for - * @param s string to search in - * @param p position to start - * @param len resulting pattern length - * @returns position on which string is found, or -1 if not found - */ -static int findScopePattern(const QCString &pattern,const QCString &s, - int p,int *len) -{ - int sl=s.length(); - int pl=pattern.length(); - int sp=0; - *len=0; - while (p<sl) - { - sp=p; // start of match - int pp=0; // pattern position - while (p<sl && pp<pl) - { - if (s.at(p)=='<') // skip template arguments while matching - { - int bc=1; - //printf("skipping pos=%d c=%c\n",p,s.at(p)); - p++; - while (p<sl) - { - if (s.at(p)=='<') bc++; - else if (s.at(p)=='>') - { - bc--; - if (bc==0) - { - p++; - break; - } - } - //printf("skipping pos=%d c=%c\n",p,s.at(p)); - p++; - } - } - else if (s.at(p)==pattern.at(pp)) - { - //printf("match at position p=%d pp=%d c=%c\n",p,pp,s.at(p)); - p++; - pp++; - } - else // no match - { - //printf("restarting at %d c=%c pat=%s\n",p,s.at(p),pattern.data()); - p=sp+1; - break; - } - } - if (pp==pl) // whole pattern matches - { - *len=p-sp; - return sp; - } - } - return -1; -} - -static QCString trimScope(const QCString &name,const QCString &s) -{ - int scopeOffset=name.length(); - QCString result=s; - do // for each scope - { - QCString tmp; - QCString scope=name.left(scopeOffset)+"::"; - //printf("Trying with scope='%s'\n",scope.data()); - - int i,p=0,l; - while ((i=findScopePattern(scope,result,p,&l))!=-1) // for each occurrence - { - tmp+=result.mid(p,i-p); // add part before pattern - p=i+l; - } - tmp+=result.right(result.length()-p); // add trailing part - - scopeOffset=name.findRev("::",scopeOffset-1); - result = tmp; - } while (scopeOffset>0); - //printf("trimScope(name=%s,scope=%s)=%s\n",name.data(),s.data(),result.data()); - return result; -} -#endif - void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0) { //printf("trimBaseClassScope level=%d '%s'\n",level,s.data()); @@ -2884,7 +2697,7 @@ void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0) } //printf("base class '%s'\n",cd->name().data()); if (cd->baseClasses()) - trimBaseClassScope(cd->baseClasses(),s,level+1); + trimBaseClassScope(cd->baseClasses(),s,level+1); } } @@ -2982,7 +2795,7 @@ static void stripIrrelevantString(QCString &target,const QCString &str) if (i1==-1 && i2==-1) { // strip str from target at index i - target=target.left(i)+target.right(target.length()-i-l); + target=target.left(i)+target.right(target.length()-i-l); changed=TRUE; i-=l; } @@ -3011,8 +2824,8 @@ static void stripIrrelevantString(QCString &target,const QCString &str) \code const T param -> T param // not relevant - const T& param -> const T& param // const needed - T* const param -> T* param // not relevant + const T& param -> const T& param // const needed + T* const param -> T* param // not relevant const T* param -> const T* param // const needed \endcode */ @@ -3032,276 +2845,6 @@ void stripIrrelevantConstVolatile(QCString &s) //#define MATCH printf("Match at line %d\n",__LINE__); //#define NOMATCH printf("Nomatch at line %d\n",__LINE__); -#ifndef NEWMATCH -static bool matchArgument(const Argument *srcA,const Argument *dstA, - const QCString &className, - const QCString &namespaceName, - NamespaceSDict *usingNamespaces, - SDict<Definition> *usingClasses) -{ - //printf("match argument start '%s|%s' <-> '%s|%s' using nsp=%p class=%p\n", - // srcA->type.data(),srcA->name.data(), - // dstA->type.data(),dstA->name.data(), - // usingNamespaces, - // usingClasses); - - // TODO: resolve any typedefs names that are part of srcA->type - // before matching. This should use className and namespaceName - // and usingNamespaces and usingClass to determine which typedefs - // are in-scope, so it will not be very efficient :-( - - QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type); - QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type); - QCString srcAName=srcA->name.stripWhiteSpace(); - QCString dstAName=dstA->name.stripWhiteSpace(); - srcAType.stripPrefix("class "); - dstAType.stripPrefix("class "); - - // allow distinguishing "const A" from "const B" even though - // from a syntactic point of view they would be two names of the same - // type "const". This is not fool prove of course, but should at least - // catch the most common cases. - if ((srcAType=="const" || srcAType=="volatile") && !srcAName.isEmpty()) - { - srcAType+=" "; - srcAType+=srcAName; - } - if ((dstAType=="const" || dstAType=="volatile") && !dstAName.isEmpty()) - { - dstAType+=" "; - dstAType+=dstAName; - } - if (srcAName=="const" || srcAName=="volatile") - { - srcAType+=srcAName; - srcAName.resize(0); - } - else if (dstA->name=="const" || dstA->name=="volatile") - { - dstAType+=dstA->name; - dstAName.resize(0); - } - - stripIrrelevantConstVolatile(srcAType); - stripIrrelevantConstVolatile(dstAType); - - // strip typename keyword - if (qstrncmp(srcAType,"typename ",9)==0) - { - srcAType = srcAType.right(srcAType.length()-9); - } - if (qstrncmp(dstAType,"typename ",9)==0) - { - dstAType = dstAType.right(dstAType.length()-9); - } - - srcAType = removeRedundantWhiteSpace(srcAType); - dstAType = removeRedundantWhiteSpace(dstAType); - - //srcAType=stripTemplateSpecifiersFromScope(srcAType,FALSE); - //dstAType=stripTemplateSpecifiersFromScope(dstAType,FALSE); - - //printf("srcA='%s|%s' dstA='%s|%s'\n",srcAType.data(),srcAName.data(), - // dstAType.data(),dstAName.data()); - - if (srcA->array!=dstA->array) // nomatch for char[] against char - { - NOMATCH - return FALSE; - } - if (srcAType!=dstAType) // check if the argument only differs on name - { - - // remove a namespace scope that is only in one type - // (assuming a using statement was used) - //printf("Trimming %s<->%s: %s\n",srcAType.data(),dstAType.data(),namespaceName.data()); - //trimNamespaceScope(srcAType,dstAType,namespaceName); - //printf("After Trimming %s<->%s\n",srcAType.data(),dstAType.data()); - - //QCString srcScope; - //QCString dstScope; - - // strip redundant scope specifiers - if (!className.isEmpty()) - { - srcAType=trimScope(className,srcAType); - dstAType=trimScope(className,dstAType); - //printf("trimScope: '%s' <=> '%s'\n",srcAType.data(),dstAType.data()); - ClassDef *cd; - if (!namespaceName.isEmpty()) - cd=getClass(namespaceName+"::"+className); - else - cd=getClass(className); - if (cd && cd->baseClasses()) - { - trimBaseClassScope(cd->baseClasses(),srcAType); - trimBaseClassScope(cd->baseClasses(),dstAType); - } - //printf("trimBaseClassScope: '%s' <=> '%s'\n",srcAType.data(),dstAType.data()); - } - if (!namespaceName.isEmpty()) - { - srcAType=trimScope(namespaceName,srcAType); - dstAType=trimScope(namespaceName,dstAType); - } - //printf("#usingNamespace=%d\n",usingNamespaces->count()); - if (usingNamespaces && usingNamespaces->count()>0) - { - NamespaceSDict::Iterator nli(*usingNamespaces); - NamespaceDef *nd; - for (;(nd=nli.current());++nli) - { - srcAType=trimScope(nd->name(),srcAType); - dstAType=trimScope(nd->name(),dstAType); - } - } - //printf("#usingClasses=%d\n",usingClasses->count()); - if (usingClasses && usingClasses->count()>0) - { - SDict<Definition>::Iterator cli(*usingClasses); - Definition *cd; - for (;(cd=cli.current());++cli) - { - srcAType=trimScope(cd->name(),srcAType); - dstAType=trimScope(cd->name(),dstAType); - } - } - - //printf("2. srcA=%s|%s dstA=%s|%s\n",srcAType.data(),srcAName.data(), - // dstAType.data(),dstAName.data()); - - if (!srcAName.isEmpty() && !dstA->type.isEmpty() && - (srcAType+" "+srcAName)==dstAType) - { - MATCH - return TRUE; - } - else if (!dstAName.isEmpty() && !srcA->type.isEmpty() && - (dstAType+" "+dstAName)==srcAType) - { - MATCH - return TRUE; - } - - - uint srcPos=0,dstPos=0; - bool equal=TRUE; - while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal) - { - equal=srcAType.at(srcPos)==dstAType.at(dstPos); - if (equal) srcPos++,dstPos++; - } - uint srcATypeLen=srcAType.length(); - uint dstATypeLen=dstAType.length(); - if (srcPos<srcATypeLen && dstPos<dstATypeLen) - { - // if nothing matches or the match ends in the middle or at the - // end of a string then there is no match - if (srcPos==0 || dstPos==0) - { - NOMATCH - return FALSE; - } - if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos))) - { - //printf("partial match srcPos=%d dstPos=%d!\n",srcPos,dstPos); - // check if a name if already found -> if no then there is no match - if (!srcAName.isEmpty() || !dstAName.isEmpty()) - { - NOMATCH - return FALSE; - } - // types only - while (srcPos<srcATypeLen && isId(srcAType.at(srcPos))) srcPos++; - while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++; - if (srcPos<srcATypeLen || - dstPos<dstATypeLen || - (srcPos==srcATypeLen && dstPos==dstATypeLen) - ) - { - NOMATCH - return FALSE; - } - } - else - { - // otherwise we assume that a name starts at the current position. - while (srcPos<srcATypeLen && isId(srcAType.at(srcPos))) srcPos++; - while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++; - - // if nothing more follows for both types then we assume we have - // found a match. Note that now 'signed int' and 'signed' match, but - // seeing that int is not a name can only be done by looking at the - // semantics. - - if (srcPos!=srcATypeLen || dstPos!=dstATypeLen) - { - NOMATCH - return FALSE; - } - } - } - else if (dstPos<dstAType.length()) - { - if (!isspace((uchar)dstAType.at(dstPos))) // maybe the names differ - { - if (!dstAName.isEmpty()) // dst has its name separated from its type - { - NOMATCH - return FALSE; - } - while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++; - if (dstPos!=dstAType.length()) - { - NOMATCH - return FALSE; // more than a difference in name -> no match - } - } - else // maybe dst has a name while src has not - { - dstPos++; - while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++; - if (dstPos!=dstAType.length() || !srcAName.isEmpty()) - { - NOMATCH - return FALSE; // nope not a name -> no match - } - } - } - else if (srcPos<srcAType.length()) - { - if (!isspace((uchar)srcAType.at(srcPos))) // maybe the names differ - { - if (!srcAName.isEmpty()) // src has its name separated from its type - { - NOMATCH - return FALSE; - } - while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++; - if (srcPos!=srcAType.length()) - { - NOMATCH - return FALSE; // more than a difference in name -> no match - } - } - else // maybe src has a name while dst has not - { - srcPos++; - while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++; - if (srcPos!=srcAType.length() || !dstAName.isEmpty()) - { - NOMATCH - return FALSE; // nope not a name -> no match - } - } - } - } - MATCH - return TRUE; -} - -#endif - static QCString stripDeclKeywords(const QCString &s) { int i=s.find(" class "); @@ -3320,11 +2863,11 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec) { - + QCString templSpec = spec.stripWhiteSpace(); // this part had been commented out before... but it is needed to match for instance // std::list<std::string> against list<string> so it is now back again! - if (!templSpec.isEmpty() && templSpec.at(0) == '<') + if (!templSpec.isEmpty() && templSpec.at(0) == '<') { templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace()); } @@ -3346,7 +2889,7 @@ static QCString getCanonicalTypeForIdentifier( QCString symName,result,templSpec,tmpName; //DefinitionList *defList=0; - if (tSpec && !tSpec->isEmpty()) + if (tSpec && !tSpec->isEmpty()) templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec)); if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty()) @@ -3508,7 +3051,7 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr QCString ct = getCanonicalTypeForIdentifier(d,fs,word,&templSpec); // in case the ct is empty it means that "word" represents scope "d" - // and this does not need to be added to the canonical + // and this does not need to be added to the canonical // type (it is redundant), so/ we skip it. This solves problem 589616. if (ct.isEmpty() && type.mid(p,2)=="::") { @@ -3522,7 +3065,7 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr // word.data(),templSpec.data(),canType.data(),ct.data()); if (!templSpec.isEmpty()) // if we didn't use up the templSpec already // (i.e. type is not a template specialization) - // then resolve any identifiers inside. + // then resolve any identifiers inside. { static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*"); int tp=0,tl,ti; @@ -3550,11 +3093,11 @@ static QCString extractCanonicalArgType(const Definition *d,const FileDef *fs,co QCString type = arg.type.stripWhiteSpace(); QCString name = arg.name; //printf("----- extractCanonicalArgType(type=%s,name=%s)\n",type.data(),name.data()); - if ((type=="const" || type=="volatile") && !name.isEmpty()) + if ((type=="const" || type=="volatile") && !name.isEmpty()) { // name is part of type => correct type+=" "; type+=name; - } + } if (name=="const" || name=="volatile") { // name is part of type => correct if (!type.isEmpty()) type+=" "; @@ -3665,7 +3208,7 @@ bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,cons if (checkCV) { - if (srcAl.constSpecifier != dstAl.constSpecifier) + if (srcAl.constSpecifier != dstAl.constSpecifier) { NOMATCH return FALSE; // one member is const, the other not -> no match @@ -3700,7 +3243,7 @@ bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,cons } } MATCH - return TRUE; // all arguments match + return TRUE; // all arguments match } @@ -3853,23 +3396,20 @@ static void findMembersWithSpecificName(MemberName *mn, { //printf(" Function with global scope name '%s' args='%s'\n", // mn->memberName(),args); - MemberNameIterator mli(*mn); - const MemberDef *md = 0; - for (mli.toFirst();(md=mli.current());++mli) + for (const auto &md : *mn) { const FileDef *fd=md->getFileDef(); const GroupDef *gd=md->getGroupDef(); //printf(" md->name()='%s' md->args='%s' fd=%p gd=%p current=%p ref=%s\n", // md->name().data(),args,fd,gd,currentFile,md->getReference().data()); if ( - ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) && + ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) && md->getNamespaceDef()==0 && md->isLinkable() && - (!checkStatics || (!md->isStatic() && !md->isDefine()) || + (!checkStatics || (!md->isStatic() && !md->isDefine()) || currentFile==0 || fd==currentFile) // statics must appear in the same file - ) + ) { bool match=TRUE; - ArgumentList *argList=0; if (args && !md->isDefine() && qstrcmp(args,"()")!=0) { const ArgumentList &mdAl = md->argumentList(); @@ -3880,10 +3420,10 @@ static void findMembersWithSpecificName(MemberName *mn, Doxygen::globalScope,fd,argList, checkCV); } - if (match && (forceTagFile==0 || md->getReference()==forceTagFile)) + if (match && (forceTagFile==0 || md->getReference()==forceTagFile)) { //printf("Found match!\n"); - members.append(md); + members.append(md.get()); } } } @@ -3894,17 +3434,17 @@ static void findMembersWithSpecificName(MemberName *mn, * memberName may also include a (partial) scope to indicate the scope * in which the member is located. * - * The parameter 'scName' is a string representing the name of the scope in + * The parameter 'scName' is a string representing the name of the scope in * which the link was found. * - * In case of a function args contains a string representation of the - * argument list. Passing 0 means the member has no arguments. + * In case of a function args contains a string representation of the + * argument list. Passing 0 means the member has no arguments. * Passing "()" means any argument list will do, but "()" is preferred. * * The function returns TRUE if the member is known and documented or * FALSE if it is not. - * If TRUE is returned parameter 'md' contains a pointer to the member - * definition. Furthermore exactly one of the parameter 'cd', 'nd', or 'fd' + * If TRUE is returned parameter 'md' contains a pointer to the member + * definition. Furthermore exactly one of the parameter 'cd', 'nd', or 'fd' * will be non-zero: * - if 'cd' is non zero, the member was found in a class pointed to by cd. * - if 'nd' is non zero, the member was found in a namespace pointed to by nd. @@ -3912,12 +3452,12 @@ static void findMembersWithSpecificName(MemberName *mn, * file fd. */ bool getDefs(const QCString &scName, - const QCString &mbName, + const QCString &mbName, const char *args, - const MemberDef *&md, - const ClassDef *&cd, - const FileDef *&fd, - const NamespaceDef *&nd, + const MemberDef *&md, + const ClassDef *&cd, + const FileDef *&fd, + const NamespaceDef *&nd, const GroupDef *&gd, bool forceEmptyScope, const FileDef *currentFile, @@ -3937,12 +3477,12 @@ bool getDefs(const QCString &scName, int is,im=0,pm=0; // strip common part of the scope from the scopeName - while ((is=scopeName.findRev("::"))!=-1 && + while ((is=scopeName.findRev("::"))!=-1 && (im=memberName.find("::",pm))!=-1 && (scopeName.right(scopeName.length()-is-2)==memberName.mid(pm,im-pm)) ) { - scopeName=scopeName.left(is); + scopeName=scopeName.left(is); pm=im+2; } //printf("result after scope corrections scope=%s name=%s\n", @@ -3952,11 +3492,11 @@ bool getDefs(const QCString &scName, QCString mScope; if (memberName.left(9)!="operator " && // treat operator conversion methods // as a special case - (im=memberName.findRev("::"))!=-1 && + (im=memberName.findRev("::"))!=-1 && im<(int)memberName.length()-2 // not A:: ) { - mScope=memberName.left(im); + mScope=memberName.left(im); mName=memberName.right(memberName.length()-im-2); } @@ -3965,7 +3505,7 @@ bool getDefs(const QCString &scName, //printf("mScope='%s' mName='%s'\n",mScope.data(),mName.data()); - MemberName *mn = Doxygen::memberNameSDict->find(mName); + MemberName *mn = Doxygen::memberNameLinkedMap->find(mName); //printf("mName=%s mn=%p\n",mName.data(),mn); if ((!forceEmptyScope || scopeName.isEmpty()) && // this was changed for bug638856, forceEmptyScope => empty scopeName @@ -3995,19 +3535,17 @@ bool getDefs(const QCString &scName, //printf("Trying class scope %s: fcd=%p tmd=%p\n",className.data(),fcd,tmd); // todo: fill in correct fileScope! if (fcd && // is it a documented class - fcd->isLinkable() + fcd->isLinkable() ) { //printf(" Found fcd=%p\n",fcd); - MemberNameIterator mmli(*mn); - MemberDef *mmd; - int mdist=maxInheritanceDepth; + int mdist=maxInheritanceDepth; ArgumentList argList; if (args) { stringToArgumentList(fcd->getLanguage(),args,argList); } - for (mmli.toFirst();(mmd=mmli.current());++mmli) + for (const auto &mmd : *mn) { if (!mmd->isStrongEnumValue()) { @@ -4027,7 +3565,7 @@ bool getDefs(const QCString &scName, { mdist=m; cd=mcd; - md=mmd; + md=mmd.get(); } } } @@ -4037,7 +3575,7 @@ bool getDefs(const QCString &scName, // no exact match found, but if args="()" an arbitrary member will do { //printf(" >Searching for arbitrary member\n"); - for (mmli.toFirst();(mmd=mmli.current());++mmli) + for (const auto &mmd : *mn) { //if (mmd->isLinkable()) //{ @@ -4051,16 +3589,16 @@ bool getDefs(const QCString &scName, //printf("Class distance %d\n",m); mdist=m; cd=mcd; - md=mmd; + md=mmd.get(); } } //} } } //printf(" >Success=%d\n",mdist<maxInheritanceDepth); - if (mdist<maxInheritanceDepth) + if (mdist<maxInheritanceDepth) { - if (!md->isLinkable() || md->isStrongEnumValue()) + if (!md->isLinkable() || md->isStrongEnumValue()) { md=0; // avoid returning things we cannot link to cd=0; @@ -4073,7 +3611,7 @@ bool getDefs(const QCString &scName, return TRUE; /* found match */ } } - } + } if (tmd && tmd->isEnumerate() && tmd->isStrong()) // scoped enum { //printf("Found scoped enum!\n"); @@ -4117,8 +3655,7 @@ bool getDefs(const QCString &scName, if (mn && scopeName.isEmpty() && mScope.isEmpty()) // Maybe a related function? { //printf("Global symbol\n"); - MemberNameIterator mmli(*mn); - MemberDef *mmd, *fuzzy_mmd = 0; + MemberDef *fuzzy_mmd = 0; ArgumentList argList; bool hasEmptyArgs = args && qstrcmp(args, "()") == 0; @@ -4127,7 +3664,7 @@ bool getDefs(const QCString &scName, stringToArgumentList(SrcLangExt_Cpp, args, argList); } - for (mmli.toFirst(); (mmd = mmli.current()); ++mmli) + for (const auto &mmd : *mn) { if (!mmd->isLinkable() || (!mmd->isRelated() && !mmd->isForeign()) || !mmd->getClassDef()) @@ -4137,6 +3674,7 @@ bool getDefs(const QCString &scName, if (!args) { + fuzzy_mmd = mmd.get(); break; } @@ -4147,21 +3685,20 @@ bool getDefs(const QCString &scName, ) ) { + fuzzy_mmd = mmd.get(); break; } if (!fuzzy_mmd && hasEmptyArgs) { - fuzzy_mmd = mmd; + fuzzy_mmd = mmd.get(); } } - mmd = mmd ? mmd : fuzzy_mmd; - - if (mmd && !mmd->isStrongEnumValue()) + if (fuzzy_mmd && !fuzzy_mmd->isStrongEnumValue()) { - md = mmd; - cd = mmd->getClassDef(); + md = fuzzy_mmd; + cd = fuzzy_mmd->getClassDef(); return TRUE; } } @@ -4170,7 +3707,7 @@ bool getDefs(const QCString &scName, // maybe an namespace, file or group member ? //printf("Testing for global symbol scopeName='%s' mScope='%s' :: mName='%s'\n", // scopeName.data(),mScope.data(),mName.data()); - if ((mn=Doxygen::functionNameSDict->find(mName))) // name is known + if ((mn=Doxygen::functionNameLinkedMap->find(mName))) // name is known { //printf(" >symbol name found\n"); NamespaceDef *fnd=0; @@ -4187,7 +3724,7 @@ bool getDefs(const QCString &scName, namespaceName=mScope.copy(); } //printf("Trying namespace %s\n",namespaceName.data()); - if (!namespaceName.isEmpty() && + if (!namespaceName.isEmpty() && (fnd=Doxygen::namespaceSDict->find(namespaceName)) && fnd->isLinkable() ) @@ -4195,9 +3732,7 @@ bool getDefs(const QCString &scName, //printf("Symbol inside existing namespace '%s' count=%d\n", // namespaceName.data(),mn->count()); bool found=FALSE; - MemberNameIterator mmli(*mn); - const MemberDef *mmd; - for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) + for (const auto &mmd : *mn) { //printf("mmd->getNamespaceDef()=%p fnd=%p\n", // mmd->getNamespaceDef(),fnd); @@ -4205,13 +3740,14 @@ bool getDefs(const QCString &scName, if (emd && emd->isStrong()) { //printf("yes match %s<->%s!\n",mScope.data(),emd->localName().data()); - if (emd->getNamespaceDef()==fnd && + if (emd->getNamespaceDef()==fnd && rightScopeMatch(mScope,emd->localName())) { //printf("found it!\n"); nd=fnd; - md=mmd; + md=mmd.get(); found=TRUE; + break; } else { @@ -4236,28 +3772,30 @@ bool getDefs(const QCString &scName, if (match) { nd=fnd; - md=mmd; + md=mmd.get(); found=TRUE; + break; } } } - if (!found && args && !qstrcmp(args,"()")) - // no exact match found, but if args="()" an arbitrary + if (!found && args && !qstrcmp(args,"()")) + // no exact match found, but if args="()" an arbitrary // member will do { - for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) + for (const auto &mmd : *mn) { if (mmd->getNamespaceDef()==fnd /*&& mmd->isLinkable() */ ) { nd=fnd; - md=mmd; + md=mmd.get(); found=TRUE; + break; } } } if (found) { - if (!md->isLinkable()) + if (!md->isLinkable()) { md=0; // avoid returning things we cannot link to nd=0; @@ -4274,9 +3812,7 @@ bool getDefs(const QCString &scName, else { //printf("not a namespace\n"); - MemberNameIterator mmli(*mn); - MemberDef *mmd; - for (mmli.toFirst();(mmd=mmli.current());++mmli) + for (const auto &mmd : *mn) { const MemberDef *tmd = mmd->getEnumScope(); //printf("try member %s tmd=%s\n",mmd->name().data(),tmd?tmd->name().data():"<none>"); @@ -4290,7 +3826,7 @@ bool getDefs(const QCString &scName, namespaceName.length()>0 // enum is part of namespace so this should not be empty ) { - md=mmd; + md=mmd.get(); fd=mmd->getFileDef(); gd=mmd->getGroupDef(); if (gd && gd->isLinkable()) fd=0; else gd=0; @@ -4325,20 +3861,22 @@ bool getDefs(const QCString &scName, { // no exact match found, but if args="()" an arbitrary // member will do - MemberNameIterator mni(*mn); - for (mni.toLast();(md=mni.current());--mni) + //MemberNameIterator mni(*mn); + //for (mni.toLast();(md=mni.current());--mni) + for (auto it = mn->rbegin(); it!=mn->rend(); ++it) { - //printf("Found member '%s'\n",md->name().data()); - //printf("member is linkable md->name()='%s'\n",md->name().data()); - fd=md->getFileDef(); - gd=md->getGroupDef(); - const MemberDef *tmd = md->getEnumScope(); + const auto &mmd = *it; + //printf("Found member '%s'\n",mmd->name().data()); + //printf("member is linkable mmd->name()='%s'\n",mmd->name().data()); + fd=mmd->getFileDef(); + gd=mmd->getGroupDef(); + const MemberDef *tmd = mmd->getEnumScope(); if ( (gd && gd->isLinkable()) || (fd && fd->isLinkable()) || (tmd && tmd->isStrong()) ) { - members.append(md); + members.append(mmd.get()); } } } @@ -4351,7 +3889,7 @@ bool getDefs(const QCString &scName, QListIterator<MemberDef> mit(members); for (mit.toFirst();(md=mit.current());++mit) { - if (md->getFileDef() && md->getFileDef()->name() == currentFile->name()) + if (md->getFileDef() && md->getFileDef()->name() == currentFile->name()) { break; // found match in the current file } @@ -4366,7 +3904,7 @@ bool getDefs(const QCString &scName, md=members.getLast(); } } - if (md && (md->getEnumScope()==0 || !md->getEnumScope()->isStrong())) + if (md && (md->getEnumScope()==0 || !md->getEnumScope()->isStrong())) // found a matching global member, that is not a scoped enum value (or uniquely matches) { fd=md->getFileDef(); @@ -4384,14 +3922,14 @@ bool getDefs(const QCString &scName, /*! * Searches for a scope definition given its name as a string via parameter - * `scope`. + * `scope`. * - * The parameter `docScope` is a string representing the name of the scope in + * The parameter `docScope` is a string representing the name of the scope in * which the `scope` string was found. * * The function returns TRUE if the scope is known and documented or * FALSE if it is not. - * If TRUE is returned exactly one of the parameter `cd`, `nd` + * If TRUE is returned exactly one of the parameter `cd`, `nd` * will be non-zero: * - if `cd` is non zero, the scope was a class pointed to by cd. * - if `nd` is non zero, the scope was a namespace pointed to by nd. @@ -4408,7 +3946,7 @@ static bool getScopeDefs(const char *docScope,const char *scope, bool explicitGlobalScope=FALSE; if (scopeName.at(0)==':' && scopeName.at(1)==':') { - scopeName=scopeName.right(scopeName.length()-2); + scopeName=scopeName.right(scopeName.length()-2); explicitGlobalScope=TRUE; } if (scopeName.isEmpty()) @@ -4429,11 +3967,11 @@ static bool getScopeDefs(const char *docScope,const char *scope, //(cd=getClass(fullName+"-g")) // C# generic ) && cd->isLinkable()) { - return TRUE; // class link written => quit + return TRUE; // class link written => quit } else if ((nd=Doxygen::namespaceSDict->find(fullName)) && nd->isLinkable()) { - return TRUE; // namespace link written => quit + return TRUE; // namespace link written => quit } if (scopeOffset==0) { @@ -4454,10 +3992,10 @@ static bool isLowerCase(QCString &s) if (p==0) return TRUE; int c; while ((c=*p++)) if (!islower(c)) return FALSE; - return TRUE; + return TRUE; } -/*! Returns an object to reference to given its name and context +/*! Returns an object to reference to given its name and context * @post return value TRUE implies *resContext!=0 or *resMember!=0 */ bool resolveRef(/* in */ const char *scName, @@ -4501,10 +4039,10 @@ bool resolveRef(/* in */ const char *scName, ClassDef *cd=0; NamespaceDef *nd=0; - // the following if() was commented out for releases in the range + // the following if() was commented out for releases in the range // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787. if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName)) - { // link to lower case only name => do not try to autolink + { // link to lower case only name => do not try to autolink return FALSE; } @@ -4524,7 +4062,7 @@ bool resolveRef(/* in */ const char *scName, } return TRUE; } - else if (scName==fullName || (!inSeeBlock && scopePos==-1)) + else if (scName==fullName || (!inSeeBlock && scopePos==-1)) // nothing to link => output plain text { //printf("found scName=%s fullName=%s scName==fullName=%d " @@ -4544,7 +4082,7 @@ bool resolveRef(/* in */ const char *scName, if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos); // strip template specifier - // TODO: match against the correct partial template instantiation + // TODO: match against the correct partial template instantiation int templPos=nameStr.find('<'); bool tryUnspecializedVersion = FALSE; if (templPos!=-1 && nameStr.find("operator")==-1) @@ -4584,11 +4122,11 @@ bool resolveRef(/* in */ const char *scName, ) { //printf("after getDefs checkScope=%d nameStr=%s cd=%p nd=%p\n",checkScope,nameStr.data(),cd,nd); - if (checkScope && md && md->getOuterScope()==Doxygen::globalScope && + if (checkScope && md && md->getOuterScope()==Doxygen::globalScope && !md->isStrongEnumValue() && (!scopeStr.isEmpty() || nameStr.find("::")>0)) { - // we did find a member, but it is a global one while we were explicitly + // we did find a member, but it is a global one while we were explicitly // looking for a scoped variable. See bug 616387 for an example why this check is needed. // note we do need to support autolinking to "::symbol" hence the >0 //printf("not global member!\n"); @@ -4615,7 +4153,7 @@ bool resolveRef(/* in */ const char *scName, else if (tsName.find('.')!=-1) // maybe a link to a file { bool ambig; - fd=findFileDef(Doxygen::inputNameDict,tsName,ambig); + fd=findFileDef(Doxygen::inputNameLinkedMap,tsName,ambig); if (fd && !ambig) { *resContext=fd; @@ -4667,20 +4205,20 @@ QCString linkToText(SrcLangExt lang,const char *link,bool isFileName) #if 0 /* * generate a reference to a class, namespace or member. - * 'scName' is the name of the scope that contains the documentation + * 'scName' is the name of the scope that contains the documentation * string that is returned. * 'name' is the name that we want to link to. * 'name' may have the following formats: * 1) "ScopeName" - * 2) "memberName()" one of the (overloaded) function or define + * 2) "memberName()" one of the (overloaded) function or define * with name memberName. - * 3) "memberName(...)" a specific (overloaded) function or define + * 3) "memberName(...)" a specific (overloaded) function or define * with name memberName * 4) "::name a global variable or define * 4) "\#memberName member variable, global variable or define - * 5) ("ScopeName::")+"memberName()" - * 6) ("ScopeName::")+"memberName(...)" - * 7) ("ScopeName::")+"memberName" + * 5) ("ScopeName::")+"memberName()" + * 6) ("ScopeName::")+"memberName(...)" + * 7) ("ScopeName::")+"memberName" * instead of :: the \# symbol may also be used. */ @@ -4752,7 +4290,7 @@ bool resolveLink(/* in */ const char *scName, const ClassDef *cd; const DirDef *dir; const NamespaceDef *nd; - SectionInfo *si=0; + const SectionInfo *si=0; bool ambig; if (linkRef.isEmpty()) // no reference name! { @@ -4760,12 +4298,12 @@ bool resolveLink(/* in */ const char *scName, } else if ((pd=Doxygen::pageSDict->find(linkRef))) // link to a page { - const GroupDef *gd = pd->getGroupDef(); + gd = pd->getGroupDef(); if (gd) { - if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name()); + if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name()); *resContext=gd; - if (si) resAnchor = si->label; + if (si) resAnchor = si->label(); } else { @@ -4773,10 +4311,10 @@ bool resolveLink(/* in */ const char *scName, } return TRUE; } - else if ((si=Doxygen::sectionDict->find(linkRef))) + else if ((si=SectionManager::instance().find(linkRef))) { - *resContext=si->definition; - resAnchor = si->label; + *resContext=si->definition(); + resAnchor = si->label(); return TRUE; } else if ((pd=Doxygen::exampleSDict->find(linkRef))) // link to an example @@ -4789,7 +4327,7 @@ bool resolveLink(/* in */ const char *scName, *resContext=gd; return TRUE; } - else if ((fd=findFileDef(Doxygen::inputNameDict,linkRef,ambig)) // file link + else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link && fd->isLinkable()) { *resContext=fd; @@ -4842,7 +4380,7 @@ bool resolveLink(/* in */ const char *scName, //---------------------------------------------------------------------- // General function that generates the HTML code for a reference to some -// file, class or member from text 'lr' within the context of class 'clName'. +// file, class or member from text 'lr' within the context of class 'clName'. // This link has the text 'lt' (if not 0), otherwise 'lr' is used as a // basis for the link's text. // returns TRUE if a link could be generated. @@ -4860,14 +4398,14 @@ bool generateLink(OutputDocInterface &od,const char *clName, if (compound) // link to compound { if (lt==0 && anchor.isEmpty() && /* compound link */ - compound->definitionType()==Definition::TypeGroup /* is group */ + compound->definitionType()==Definition::TypeGroup /* is group */ ) { linkText=(dynamic_cast<const GroupDef *>(compound))->groupTitle(); // use group's title as link } else if (compound->definitionType()==Definition::TypeFile) { - linkText=linkToText(compound->getLanguage(),lt,TRUE); + linkText=linkToText(compound->getLanguage(),lt,TRUE); } od.writeObjectLink(compound->getReference(), compound->getOutputFileBase(),anchor,linkText); @@ -4896,12 +4434,12 @@ void generateFileRef(OutputDocInterface &od,const char *name,const char *text) //FileInfo *fi; FileDef *fd; bool ambig; - if ((fd=findFileDef(Doxygen::inputNameDict,name,ambig)) && - fd->isLinkable()) + if ((fd=findFileDef(Doxygen::inputNameLinkedMap,name,ambig)) && + fd->isLinkable()) // link to documented input file od.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,linkText); else - od.docify(linkText); + od.docify(linkText); } //---------------------------------------------------------------------- @@ -4944,14 +4482,14 @@ struct FindFileCacheElem static QCache<FindFileCacheElem> g_findFileDefCache(5000); -FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) +FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) { ambig=FALSE; if (n==0) return 0; const int maxAddrSize = 20; char addr[maxAddrSize]; - qsnprintf(addr,maxAddrSize,"%p:",fnDict); + qsnprintf(addr,maxAddrSize,"%p:",(void*)fnMap); QCString key = addr; key+=n; @@ -4972,22 +4510,22 @@ FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) QCString name=QDir::cleanDirPath(n).utf8(); QCString path; int slashPos; - FileName *fn; + const FileName *fn; if (name.isEmpty()) goto exit; slashPos=QMAX(name.findRev('/'),name.findRev('\\')); if (slashPos!=-1) { path=name.left(slashPos+1); - name=name.right(name.length()-slashPos-1); + name=name.right(name.length()-slashPos-1); //printf("path=%s name=%s\n",path.data(),name.data()); } if (name.isEmpty()) goto exit; - if ((fn=(*fnDict)[name])) + if ((fn=fnMap->find(name))) { //printf("fn->count()=%d\n",fn->count()); - if (fn->count()==1) + if (fn->size()==1) { - FileDef *fd = fn->getFirst(); + const std::unique_ptr<FileDef> &fd = fn->front(); #if defined(_WIN32) || defined(__MACOSX__) || defined(__CYGWIN__) // Windows or MacOSX bool isSamePath = fd->getPath().right(path.length()).lower()==path.lower(); #else // Unix @@ -4995,26 +4533,24 @@ FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) #endif if (path.isEmpty() || isSamePath) { - cachedResult->fileDef = fd; + cachedResult->fileDef = fd.get(); g_findFileDefCache.insert(key,cachedResult); //printf("=1 ===> add to cache %p\n",fd); - return fd; + return fd.get(); } } else // file name alone is ambiguous { int count=0; - FileNameIterator fni(*fn); - FileDef *fd; FileDef *lastMatch=0; QCString pathStripped = stripFromIncludePath(path); - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { QCString fdStripPath = stripFromIncludePath(fd->getPath()); - if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped) - { - count++; - lastMatch=fd; + if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped) + { + count++; + lastMatch=fd.get(); } } //printf(">1 ===> add to cache %p\n",fd); @@ -5039,7 +4575,7 @@ exit: //---------------------------------------------------------------------- -QCString showFileDefMatches(const FileNameDict *fnDict,const char *n) +QCString showFileDefMatches(const FileNameLinkedMap *fnMap,const char *n) { QCString result; QCString name=n; @@ -5048,14 +4584,12 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n) if (slashPos!=-1) { path=name.left(slashPos+1); - name=name.right(name.length()-slashPos-1); + name=name.right(name.length()-slashPos-1); } - FileName *fn; - if ((fn=(*fnDict)[name])) + const FileName *fn; + if ((fn=fnMap->find(name))) { - FileNameIterator fni(*fn); - FileDef *fd; - for (fni.toFirst();(fd=fni.current());++fni) + for (const auto &fd : *fn) { if (path.isEmpty() || fd->getPath().right(path.length())==path) { @@ -5157,7 +4691,7 @@ QCString substitute(const QCString &s,const QCString &src,const QCString &dst,in r+=dstLen; } qstrcpy(r,p); - result.resize(strlen(result.data())+1); + result.resize((int)strlen(result.data())+1); //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data()); return result; } @@ -5188,7 +4722,7 @@ QCString substituteKeywords(const QCString &s,const char *title, result = substitute(result,"$datetime",dateToString(TRUE)); result = substitute(result,"$date",dateToString(FALSE)); result = substitute(result,"$year",yearToString()); - result = substitute(result,"$doxygenversion",getVersion()); + result = substitute(result,"$doxygenversion",getDoxygenVersion()); result = substitute(result,"$projectname",projName); result = substitute(result,"$projectnumber",projNum); result = substitute(result,"$projectbrief",projBrief); @@ -5201,7 +4735,7 @@ QCString substituteKeywords(const QCString &s,const char *title, /*! Returns the character index within \a name of the first prefix * in Config_getList(IGNORE_PREFIX) that matches \a name at the left hand side, * or zero if no match was found - */ + */ int getPrefixIndex(const QCString &name) { if (name.isEmpty()) return 0; @@ -5249,7 +4783,7 @@ bool classHasVisibleChildren(const ClassDef *cd) if (cd->baseClasses()==0) return FALSE; bcl=cd->baseClasses(); } - else + else { if (cd->subClasses()==0) return FALSE; bcl=cd->subClasses(); @@ -5307,8 +4841,8 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor static GrowBuf growBuf; growBuf.clear(); if (name==0) return ""; - char c; - const char *p=name; + signed char c; + const signed char *p=(const signed char*)name; while ((c=*p++)!=0) { switch(c) @@ -5340,7 +4874,7 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor case '@': growBuf.addStr("_0d"); break; case ']': growBuf.addStr("_0e"); break; case '[': growBuf.addStr("_0f"); break; - default: + default: if (c<0) { char ids[5]; @@ -5348,7 +4882,7 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor bool doEscape = TRUE; if (allowUnicodeNames && uc <= 0xf7) { - const char* pt = p; + const signed char* pt = p; ids[ 0 ] = c; int l = 0; if ((uc&0xE0)==0xC0) @@ -5402,7 +4936,7 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor else { growBuf.addChar('_'); - growBuf.addChar(tolower(c)); + growBuf.addChar((char)tolower(c)); } break; } @@ -5462,7 +4996,7 @@ QCString unescapeCharsInString(const char *s) default: if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A' { - result+=toupper(*p); + result+=(char)toupper(*p); p++; } else // unknown escape, pass underscore character as-is @@ -5482,7 +5016,7 @@ QCString unescapeCharsInString(const char *s) } /*! This function determines the file name on disk of an item - * given its name, which could be a class name with template + * given its name, which could be a class name with template * arguments, so special characters need to be escaped. */ QCString convertNameToFile(const char *name,bool allowDots,bool allowUnderscore) @@ -5508,7 +5042,7 @@ QCString convertNameToFile(const char *name,bool allowDots,bool allowUnderscore) { num = *value; } - result.sprintf("a%05d",num); + result.sprintf("a%05d",num); } else // long names { @@ -5521,17 +5055,17 @@ QCString convertNameToFile(const char *name,bool allowDots,bool allowUnderscore) QCString sigStr(33); MD5Buffer((const unsigned char *)result.data(),resultLen,md5_sig); MD5SigToString(md5_sig,sigStr.rawData(),33); - result=result.left(128-32)+sigStr; + result=result.left(128-32)+sigStr; } } if (createSubdirs) { int l1Dir=0,l2Dir=0; -#if MAP_ALGO==ALGO_COUNT +#if MAP_ALGO==ALGO_COUNT // old algorithm, has the problem that after regeneration the // output can be located in a different dir. - if (Doxygen::htmlDirMap==0) + if (Doxygen::htmlDirMap==0) { Doxygen::htmlDirMap=new QDict<int>(100003); Doxygen::htmlDirMap->setAutoDelete(TRUE); @@ -5540,7 +5074,7 @@ QCString convertNameToFile(const char *name,bool allowDots,bool allowUnderscore) int *dirNum = Doxygen::htmlDirMap->find(result); if (dirNum==0) // new name { - Doxygen::htmlDirMap->insert(result,new int(curDirNum)); + Doxygen::htmlDirMap->insert(result,new int(curDirNum)); l1Dir = (curDirNum)&0xf; // bits 0-3 l2Dir = (curDirNum>>4)&0xff; // bits 4-11 curDirNum++; @@ -5624,7 +5158,7 @@ void extractNamespaceName(const QCString &scopeName, goto done; } p=clName.length()-2; - while (p>=0 && (i=clName.findRev("::",p))!=-1) + while (p>=0 && (i=clName.findRev("::",p))!=-1) // see if the first part is a namespace (and not a class) { //printf("Trying %s\n",clName.left(i).data()); @@ -5634,7 +5168,7 @@ void extractNamespaceName(const QCString &scopeName, namespaceName=nd->name().copy(); className=clName.right(clName.length()-i-2); goto done; - } + } p=i-2; // try a smaller piece of the scope } //printf("not found!\n"); @@ -5671,12 +5205,12 @@ QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &te ((cd=getClass(scope.left(si)))==0 || cd->templateArguments().empty()) ) { - //printf("Tried '%s'\n",(scope.left(si)+templ).data()); - pi=si+2; + //printf("Tried '%s'\n",(scope.left(si)+templ).data()); + pi=si+2; } if (si==-1) // not nested => append template specifier { - result+=templ; + result+=templ; } else // nested => insert template specifier before after first class name { @@ -5705,7 +5239,7 @@ QCString stripScope(const char *name) char c=result.at(p); switch (c) { - case ':': + case ':': //printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data()); return result.right(l-p-1); case '>': @@ -5720,7 +5254,7 @@ QCString stripScope(const char *name) { case '>': count++; break; case '<': count--; if (count<=0) done=TRUE; break; - default: + default: //printf("c=%c count=%d\n",c,count); break; } @@ -5754,7 +5288,7 @@ QCString stripScope(const char *name) char c=result.at(p); switch (c) { - case ':': + case ':': // only exit in the case of :: //printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data()); if (p>0 && result.at(p-1)==':') return result.right(l-p-1); @@ -5781,10 +5315,10 @@ QCString stripScope(const char *name) c=result.at(p--); switch (c) { - case '>': - count++; + case '>': + count++; break; - case '<': + case '<': if (p>0) { if (result.at(p-1) == '<') // skip << operator @@ -5793,10 +5327,10 @@ QCString stripScope(const char *name) break; } } - count--; + count--; foundMatch = count==0; break; - default: + default: //printf("c=%c count=%d\n",c,count); break; } @@ -5886,7 +5420,7 @@ QCString convertToXML(const char *s, bool keepEntities) growBuf.addStr("&"); } break; - case '\'': growBuf.addStr("'"); break; + case '\'': growBuf.addStr("'"); break; case '"': growBuf.addStr("""); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: @@ -5996,10 +5530,10 @@ QCString convertToHtml(const char *s,bool keepEntities) } else { - growBuf.addStr("&"); + growBuf.addStr("&"); } break; - case '\'': growBuf.addStr("'"); break; + case '\'': growBuf.addStr("'"); break; case '"': growBuf.addStr("""); break; default: growBuf.addChar(c); break; } @@ -6241,11 +5775,11 @@ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStri int brCount=1; while (te<typeLen && brCount!=0) { - if (type.at(te)=='<') + if (type.at(te)=='<') { if (te<typeLen-1 && type.at(te+1)=='<') te++; else brCount++; } - if (type.at(te)=='>') + if (type.at(te)=='>') { if (te<typeLen-1 && type.at(te+1)=='>') te++; else brCount--; } @@ -6253,7 +5787,7 @@ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStri } } name = type.mid(i,l); - if (te>ts) + if (te>ts) { templSpec = type.mid(ts,te-ts),tl+=te-ts; pos=i+l+tl; @@ -6340,14 +5874,13 @@ QCString substituteTemplateArgumentsInString( // name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data()); if (formalArgs.empty()) return name; QCString result; - static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*"); + static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9:\\x80-\\xFF]*"); int p=0,l,i; // for each identifier in the base class name (e.g. B<T> -> B and T) while ((i=re.match(name,p,&l))!=-1) { result += name.mid(p,i-p); QCString n = name.mid(i,l); - auto formIt = formalArgs.begin(); auto actIt = actualArgs.begin(); // if n is a template argument, then we substitute it @@ -6378,29 +5911,29 @@ QCString substituteTemplateArgumentsInString( { //printf("n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s'\n", // n.data(),formArg->type.data(),formArg->name.data(),formArg->defval.data()); - //printf(">> formArg->name='%s' actArg->type='%s' actArg->name='%s'\n", - // formArg->name.data(),actArg ? actArg->type.data() : "",actArg ? actArg->name.data() : "" + //printf(">> n='%s' formArg->name='%s' actArg->type='%s' actArg->name='%s'\n", + // n.data(),formArg.name.data(),actIt!=actualArgs.end() ? actIt->type.data() : "",actIt!=actualArgs.end() ? actIt->name.data() : "" // ); if (formArg.name==n && actIt!=actualArgs.end() && !actArg.type.isEmpty()) // base class is a template argument { // replace formal argument with the actual argument of the instance - if (!leftScopeMatch(actArg.type,n)) - // the scope guard is to prevent recursive lockup for - // template<class A> class C : public<A::T>, - // where A::T would become A::T::T here, + if (!leftScopeMatch(actArg.type,n)) + // the scope guard is to prevent recursive lockup for + // template<class A> class C : public<A::T>, + // where A::T would become A::T::T here, // since n==A and actArg->type==A::T // see bug595833 for an example { if (actArg.name.isEmpty()) { - result += actArg.type+" "; + result += actArg.type+" "; found=TRUE; } - else + else // for case where the actual arg is something like "unsigned int" // the "int" part is in actArg->name. { - result += actArg.type+" "+actArg.name+" "; + result += actArg.type+" "+actArg.name+" "; found=TRUE; } } @@ -6441,31 +5974,13 @@ QCString substituteTemplateArgumentsInString( return result.stripWhiteSpace(); } -#if 0 -/*! Makes a deep copy of the list of argument lists \a srcLists. - * Will allocate memory, that is owned by the caller. - */ -QList<ArgumentList> *copyArgumentLists(const QList<ArgumentList> *srcLists) -{ - ASSERT(srcLists!=0); - QList<ArgumentList> *dstLists = new QList<ArgumentList>; - dstLists->setAutoDelete(TRUE); - QListIterator<ArgumentList> sli(*srcLists); - ArgumentList *sl; - for (;(sl=sli.current());++sli) - { - dstLists->append(sl->deepCopy()); - } - return dstLists; -} -#endif -/*! Strips template specifiers from scope \a fullName, except those - * that make up specialized classes. The switch \a parentOnly - * determines whether or not a template "at the end" of a scope - * should be considered, e.g. with \a parentOnly is \c TRUE, A<T>::B<S> will - * try to strip \<T\> and not \<S\>, while \a parentOnly is \c FALSE will - * strip both unless A<T> or B<S> are specialized template classes. +/*! Strips template specifiers from scope \a fullName, except those + * that make up specialized classes. The switch \a parentOnly + * determines whether or not a template "at the end" of a scope + * should be considered, e.g. with \a parentOnly is \c TRUE, \c A<T>::B<S> will + * try to strip `<T>` and not `<S>`, while \a parentOnly is \c FALSE will + * strip both unless `A<T>` or `B<S>` are specialized template classes. */ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, @@ -6484,11 +5999,11 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, while (e<l && !done) { char c=fullName.at(e++); - if (c=='<') + if (c=='<') { count++; } - else if (c=='>') + else if (c=='>') { count--; done = count==0; @@ -6496,7 +6011,7 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, } int si= fullName.find("::",e); - if (parentOnly && si==-1) break; + if (parentOnly && si==-1) break; // we only do the parent scope, so we stop here if needed result+=fullName.mid(p,i-p); @@ -6523,10 +6038,10 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, * Example1: \c A::B and \c B::C will result in \c A::B::C <br> * Example2: \c A and \c B will be \c A::B <br> * Example3: \c A::B and B will be \c A::B - * + * * @param leftScope the left hand part of the scope. * @param rightScope the right hand part of the scope. - * @returns the merged scope. + * @returns the merged scope. */ QCString mergeScopes(const QCString &leftScope,const QCString &rightScope) { @@ -6588,7 +6103,7 @@ int getScopeFragment(const QCString &s,int p,int *l) while (sp<sl && !done) { // TODO: deal with << and >> operators! - char c=s.at(sp++); + c=s.at(sp++); switch(c) { case '<': count++; break; @@ -6613,7 +6128,7 @@ found: PageDef *addRelatedPage(const char *name,const QCString &ptitle, const QCString &doc, const char *fileName,int startLine, - const std::vector<ListItemInfo> &sli, + const std::vector<RefItem*> &sli, GroupDef *gd, const TagInfo *tagInfo, bool xref, @@ -6635,7 +6150,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, else // new page { QCString baseName=name; - if (baseName.right(4)==".tex") + if (baseName.right(4)==".tex") baseName=baseName.left(baseName.length()-4); else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension) baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length()); @@ -6667,32 +6182,31 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, { file=gd->getOutputFileBase(); } - else + else { file=pd->getOutputFileBase(); } - SectionInfo *si = Doxygen::sectionDict->find(pd->name()); + const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) { - if (si->lineNr != -1) + if (si->lineNr() != -1) { - warn(file,-1,"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->name().data(),si->fileName.data(),si->lineNr); + warn(file,-1,"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->name().data(),si->fileName().data(),si->lineNr()); } else { - warn(file,-1,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName.data()); + warn(file,-1,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName().data()); } } else { - si=new SectionInfo( - file,-1,pd->name(),pd->title(),SectionInfo::Page,0,pd->getReference()); + SectionManager::instance().add(pd->name(), + file,-1,pd->title(),SectionType::Page,0,pd->getReference()); //printf("si->label='%s' si->definition=%s si->fileName='%s'\n", // si->label.data(),si->definition?si->definition->name().data():"<none>", // si->fileName.data()); //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data()); //printf("Adding section key=%s si->fileName=%s\n",pageName.data(),si->fileName.data()); - Doxygen::sectionDict->append(pd->name(),si); } } } @@ -6701,39 +6215,21 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, //---------------------------------------------------------------------------- -void addRefItem(const std::vector<ListItemInfo> &sli, - const char *key, - const char *prefix, const char *name,const char *title,const char *args,Definition *scope) +void addRefItem(const std::vector<RefItem*> &sli, + const char *key, + const char *prefix, const char *name,const char *title,const char *args,const Definition *scope) { - //printf("addRefItem(sli=%p,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",sli,key,prefix,name,title,args); + //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args); if (key && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012) { - for (const ListItemInfo &lii : sli) - { - RefList *refList = Doxygen::xrefLists->find(lii.type); - if (refList - && - ( - // either not a built-in list or the list is enabled - (lii.type!="todo" || Config_getBool(GENERATE_TODOLIST)) && - (lii.type!="test" || Config_getBool(GENERATE_TESTLIST)) && - (lii.type!="bug" || Config_getBool(GENERATE_BUGLIST)) && - (lii.type!="deprecated" || Config_getBool(GENERATE_DEPRECATEDLIST)) - ) - ) - { - RefItem *item = refList->getRefItem(lii.itemId); - ASSERT(item!=0); - - item->prefix = prefix; - item->scope = scope; - item->name = name; - item->title = title; - item->args = args; - - refList->insertIntoList(key,item); - - } + for (RefItem *item : sli) + { + item->setPrefix(prefix); + item->setScope(scope); + item->setName(name); + item->setTitle(title); + item->setArgs(args); + item->setGroup(key); } } } @@ -6754,11 +6250,11 @@ bool recursivelyAddGroupListToTitle(OutputList &ol,const Definition *d,bool root bool first=true; for (gli.toFirst();(gd=gli.current());++gli) { + if (!first) { ol.writeString(" | "); } else first=false; if (recursivelyAddGroupListToTitle(ol, gd, FALSE)) { ol.writeString(" » "); } - if (!first) { ol.writeString(" | "); } else first=FALSE; ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); } if (root) @@ -6870,9 +6366,9 @@ void filterLatexString(FTextStream &t,const char *str, } break; case '*': t << "$\\ast$"; break; - case '_': if (!insideTabbing) t << "\\+"; - t << "\\_"; - if (!insideTabbing) t << "\\+"; + case '_': if (!insideTabbing) t << "\\+"; + t << "\\_"; + if (!insideTabbing) t << "\\+"; break; case '{': t << "\\{"; break; case '}': t << "\\}"; break; @@ -6880,8 +6376,8 @@ void filterLatexString(FTextStream &t,const char *str, case '>': t << "$>$"; break; case '|': t << "$\\vert$"; break; case '~': t << "$\\sim$"; break; - case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem) - t << "\\mbox{[}"; + case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem) + t << "\\mbox{[}"; else t << "["; break; @@ -6889,12 +6385,12 @@ void filterLatexString(FTextStream &t,const char *str, if (Config_getBool(PDF_HYPERLINKS) || insideItem) t << "\\mbox{]}"; else - t << "]"; + t << "]"; break; case '-': t << "-\\/"; break; case '\\': t << "\\textbackslash{}"; - break; + break; case '"': t << "\\char`\\\"{}"; break; case '`': t << "\\`{}"; @@ -6904,9 +6400,9 @@ void filterLatexString(FTextStream &t,const char *str, case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' '; break; - default: + default: //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ') - if (!insideTabbing && + if (!insideTabbing && ((c>='A' && c<='Z' && pc!=' ' && pc!='\0' && *p) || (c==':' && pc!=':') || (pc=='.' && isId(c))) ) { @@ -6940,7 +6436,7 @@ QCString latexEscapeLabelName(const char *s) case '}': t << "\\rcurly{}"; break; case '~': t << "````~"; break; // to get it a bit better in index together with other special characters // NOTE: adding a case here, means adding it to while below as well! - default: + default: i=0; // collect as long string as possible, before handing it to docify tmp[i++]=c; @@ -6979,7 +6475,7 @@ QCString latexEscapeIndexChars(const char *s) case '{': t << "\\lcurly{}"; break; case '}': t << "\\rcurly{}"; break; // NOTE: adding a case here, means adding it to while below as well! - default: + default: i=0; // collect as long string as possible, before handing it to docify tmp[i++]=c; @@ -7081,6 +6577,7 @@ QCString rtfFormatBmkStr(const char *name) } } + //printf("Name = %s RTF_tag = %s\n",name,(*tag).data()); return *tag; } @@ -7163,9 +6660,9 @@ bool findAndRemoveWord(QCString &s,const QCString &word) int p=0,i,l; while ((i=wordExp.match(s,p,&l))!=-1) { - if (s.mid(i,l)==word) + if (s.mid(i,l)==word) { - if (i>0 && isspace((uchar)s.at(i-1))) + if (i>0 && isspace((uchar)s.at(i-1))) i--,l++; else if (i+l<(int)s.length() && isspace((uchar)s.at(i+l))) l++; @@ -7249,7 +6746,7 @@ static struct Lang2ExtMap const char *langName; const char *parserName; SrcLangExt parserId; -} +} g_lang2extMap[] = { // language parser parser option @@ -7270,7 +6767,6 @@ g_lang2extMap[] = { "vhdl", "vhdl", SrcLangExt_VHDL }, { "xml", "xml", SrcLangExt_XML }, { "sql", "sql", SrcLangExt_SQL }, - { "tcl", "tcl", SrcLangExt_Tcl }, { "md", "md", SrcLangExt_Markdown }, { 0, 0, (SrcLangExt)0 } }; @@ -7361,9 +6857,9 @@ void initDefaultExtensionMapping() updateLanguageMapping(".f95", "fortran"); updateLanguageMapping(".f03", "fortran"); updateLanguageMapping(".f08", "fortran"); + updateLanguageMapping(".f18", "fortran"); updateLanguageMapping(".vhd", "vhdl"); updateLanguageMapping(".vhdl", "vhdl"); - updateLanguageMapping(".tcl", "tcl"); updateLanguageMapping(".ucf", "vhdl"); updateLanguageMapping(".qsf", "vhdl"); updateLanguageMapping(".md", "md"); @@ -7404,7 +6900,7 @@ QCString getFileNameExtension(QCString fn) //-------------------------------------------------------------------------- -MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope, +MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope, const char *n) { if (scope==0 || @@ -7488,9 +6984,9 @@ bool checkIfTypedef(const Definition *scope,const FileDef *fileScope,const char const char *writeUtf8Char(FTextStream &t,const char *s) { - char c=*s++; - t << c; - if (c<0) // multibyte character + uchar c=(uchar)*s++; + t << (char)c; + if (c>=0x80) // multibyte character { if (((uchar)c&0xE0)==0xC0) { @@ -7516,12 +7012,12 @@ const char *writeUtf8Char(FTextStream &t,const char *s) return s; } -int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos) +int nextUtf8CharPosition(const QCString &utf8Str,uint len,uint startPos) { int bytes=1; if (startPos>=len) return len; - char c = utf8Str[startPos]; - if (c<0) // multibyte utf-8 character + uchar c = (uchar)utf8Str[startPos]; + if (c>=0x80) // multibyte utf-8 character { if (((uchar)c&0xE0)==0xC0) { @@ -7617,8 +7113,8 @@ struct Marker int size; // size of the marker }; -/** For a string \a s that starts with a command name, returns the character - * offset within that string representing the first character after the +/** For a string \a s that starts with a command name, returns the character + * offset within that string representing the first character after the * command. For an alias with argument, this is the offset to the * character just after the argument list. * @@ -7640,13 +7136,13 @@ static int findEndOfCommand(const char *s) QCString args = extractAliasArgs(p,0); i+=args.length(); } - i+=p-s; + i+=(int)(p-s); } return i; } -/** Replaces the markers in an alias definition \a aliasValue - * with the corresponding values found in the comma separated argument +/** Replaces the markers in an alias definition \a aliasValue + * with the corresponding values found in the comma separated argument * list \a argList and the returns the result after recursive alias expansion. */ static QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argList) @@ -7661,7 +7157,7 @@ static QCString replaceAliasArguments(const QCString &aliasValue,const QCString for (i=0;i<l;i++) { char c = argList.at(i); - if (c==',' && (i==0 || argList.at(i-1)!='\\')) + if (c==',' && (i==0 || argList.at(i-1)!='\\')) { args.append(new QCString(argList.mid(s,i-s))); s=i+1; // start of next argument @@ -7789,8 +7285,8 @@ static QCString expandAliasRec(const QCString s,bool allowRecursion) cmd += QCString().sprintf("{%d}",numArgs); // alias name + {n} } QCString *aliasText=Doxygen::aliasDict.find(cmd); - if (numArgs>1 && aliasText==0) - { // in case there is no command with numArgs parameters, but there is a command with 1 parameter, + if (numArgs>1 && aliasText==0) + { // in case there is no command with numArgs parameters, but there is a command with 1 parameter, // we also accept all text as the argument of that command (so you don't have to escape commas) aliasText=Doxygen::aliasDict.find(cmdNoArgs+"{1}"); if (aliasText) @@ -7836,7 +7332,7 @@ int countAliasArguments(const QCString argList) int count=1; int l = argList.length(); int i; - for (i=0;i<l;i++) + for (i=0;i<l;i++) { char c = argList.at(i); if (c==',' && (i==0 || argList.at(i-1)!='\\')) count++; @@ -7870,7 +7366,7 @@ QCString extractAliasArgs(const QCString &args,int pos) prevChar=0; } - if (bc==0) + if (bc==0) { //printf("extractAliasArgs('%s')->'%s'\n",args.data(),args.mid(pos+1,i-pos-1).data()); return args.mid(pos+1,i-pos-1); @@ -7906,7 +7402,7 @@ QCString expandAlias(const QCString &aliasName,const QCString &aliasValue) void writeTypeConstraints(OutputList &ol,const Definition *d,const ArgumentList &al) { if (al.empty()) return; - ol.startConstraintList(theTranslator->trTypeConstraints()); + ol.startConstraintList(theTranslator->trTypeConstraints()); for (const Argument &a : al) { ol.startConstraintParam(); @@ -7932,7 +7428,7 @@ void stackTrace() static char cmd[40960]; char *p = cmd; p += sprintf(p,"/usr/bin/atos -p %d ", (int)getpid()); - for (int x = 0; x < frameCount; x++) + for (int x = 0; x < frameCount; x++) { p += sprintf(p,"%p ", backtraceFrames[x]); } @@ -7965,7 +7461,7 @@ static int transcodeCharacterBuffer(const char *fileName,BufStr &srcBuf,int size if (inputEncoding==0 || outputEncoding==0) return size; if (qstricmp(inputEncoding,outputEncoding)==0) return size; void *cd = portable_iconv_open(outputEncoding,inputEncoding); - if (cd==(void *)(-1)) + if (cd==(void *)(-1)) { term("unsupported character conversion: '%s'->'%s': %s\n" "Check the INPUT_ENCODING setting in the config file!\n", @@ -8181,10 +7677,15 @@ void writeSummaryLink(OutputList &ol,const char *label,const char *title, } #endif -QCString externalLinkTarget() +QCString externalLinkTarget(const bool parent) { static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW); - if (extLinksInWindow) return "target=\"_blank\" "; else return ""; + if (extLinksInWindow) + return "target=\"_blank\" "; + else if (parent) + return "target=\"_parent\" "; + else + return ""; } QCString externalRef(const QCString &relPath,const QCString &ref,bool href) @@ -8213,7 +7714,7 @@ QCString externalRef(const QCString &relPath,const QCString &ref,bool href) return result; } -/** Writes the intensity only bitmap represented by \a data as an image to +/** Writes the intensity only bitmap represented by \a data as an image to * directory \a dir using the colors defined by HTML_COLORSTYLE_*. */ void writeColoredImgData(const char *dir,ColoredImgDataItem data[]) @@ -8242,8 +7743,8 @@ void writeColoredImgData(const char *dir,ColoredImgDataItem data[]) } /** Replaces any markers of the form \#\#AA in input string \a str - * by new markers of the form \#AABBCC, where \#AABBCC represents a - * valid color, based on the intensity represented by hex number AA + * by new markers of the form \#AABBCC, where \#AABBCC represents a + * valid color, based on the intensity represented by hex number AA * and the current HTML_COLORSTYLE_* settings. */ QCString replaceColorMarkers(const char *str) @@ -8264,7 +7765,7 @@ QCString replaceColorMarkers(const char *str) #define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \ ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \ ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0) - + double r,g,b; int red,green,blue; int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]); @@ -8290,7 +7791,7 @@ QCString replaceColorMarkers(const char *str) return result; } -/** Copies the contents of file with name \a src to the newly created +/** Copies the contents of file with name \a src to the newly created * file with name \a dest. Returns TRUE if successful. */ bool copyFile(const QCString &src,const QCString &dest) @@ -8322,7 +7823,7 @@ bool copyFile(const QCString &src,const QCString &dest) return TRUE; } -/** Returns the section of text, in between a pair of markers. +/** Returns the section of text, in between a pair of markers. * Full lines are returned, excluding the lines on which the markers appear. * \sa routine lineBlock */ @@ -8410,7 +7911,6 @@ QCString langToString(SrcLangExt lang) case SrcLangExt_VHDL: return "VHDL"; case SrcLangExt_XML: return "XML"; case SrcLangExt_SQL: return "SQL"; - case SrcLangExt_Tcl: return "Tcl"; case SrcLangExt_Markdown: return "Markdown"; case SrcLangExt_Slice: return "Slice"; } @@ -8433,16 +7933,11 @@ QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope) return "::"; } } -QCString replaceScopeSeparator(QCString str) -{ - // we don't know about the language so we have to go for the worse - return substitute(substitute(str,"\\","::"),".","::"); // PHP and Java, CSharp, VHDL, Python -} /** Checks whether the given url starts with a supported protocol */ bool isURL(const QCString &url) { QCString loc_url = url.stripWhiteSpace(); - return loc_url.left(5)=="http:" || loc_url.left(6)=="https:" || + return loc_url.left(5)=="http:" || loc_url.left(6)=="https:" || loc_url.left(4)=="ftp:" || loc_url.left(5)=="file:"; } /** Corrects URL \a url according to the relative path \a relPath. @@ -8465,8 +7960,8 @@ bool protectionLevelVisible(Protection prot) static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); static bool extractPackage = Config_getBool(EXTRACT_PACKAGE); - return (prot!=Private && prot!=Package) || - (prot==Private && extractPrivate) || + return (prot!=Private && prot!=Package) || + (prot==Private && extractPrivate) || (prot==Package && extractPackage); } @@ -8489,7 +7984,7 @@ QCString stripIndentation(const QCString &s) if (c=='\t') indent+=tabSize - (indent%tabSize); else if (c=='\n') indent=0,searchIndent=TRUE; else if (c==' ') indent++; - else if (searchIndent) + else if (searchIndent) { searchIndent=FALSE; if (indent<minIndent) minIndent=indent; @@ -8546,7 +8041,7 @@ bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile) genSourceFile = !isDocFile && fd->generateSourceFile(); return ( ((allExternals && fd->isLinkable()) || fd->isLinkableInProject() - ) && + ) && !isDocFile ); } @@ -8555,7 +8050,7 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst) { //printf("--> addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data()); if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types - if ((dst->hasReferencedByRelation() || dst->hasCallerGraph()) && + if ((dst->hasReferencedByRelation() || dst->hasCallerGraph()) && src->showInCallGraph() ) { @@ -8571,7 +8066,7 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst) mdDecl->addSourceReferencedBy(src); } } - if ((src->hasReferencesRelation() || src->hasCallGraph()) && + if ((src->hasReferencesRelation() || src->hasCallGraph()) && src->showInCallGraph() ) { @@ -8627,7 +8122,7 @@ uint getUtf8Code( const QCString& s, int idx ) } -/*! @brief Returns one unicode character as an unsigned integer +/*! @brief Returns one unicode character as an unsigned integer * from utf-8 string, making the character lower case if it was upper case. * * @param s utf-8 encoded string @@ -8642,7 +8137,7 @@ uint getUtf8CodeToLower( const QCString& s, int idx ) } -/*! @brief Returns one unicode character as an unsigned integer +/*! @brief Returns one unicode character as an unsigned integer * from utf-8 string, making the character upper case if it was lower case. * * @param s utf-8 encoded string @@ -8963,7 +8458,7 @@ bool openOutputFile(const char *outFile,QFile &f) if (backup.exists()) // remove existing backup dir.remove(backup.fileName()); dir.rename(fi.fileName(),fi.fileName()+".bak"); - } + } f.setName(outFile); fileOpened = f.open(IO_WriteOnly|IO_Translate); } @@ -8974,7 +8469,7 @@ void writeExtraLatexPackages(FTextStream &t) { // User-specified packages QStrList &extraPackages = Config_getList(EXTRA_PACKAGES); - if (!extraPackages.isEmpty()) + if (!extraPackages.isEmpty()) { t << "% Packages requested by user\n"; const char *pkgName=extraPackages.first(); @@ -9016,6 +8511,20 @@ void writeLatexSpecialFormulaChars(FTextStream &t) "\n"; } +QCString getFullVersion() +{ + QCString versionString; + if (strlen(getGitVersion())>0) + { + versionString = QCString(getDoxygenVersion())+" ("+getGitVersion()+")"; + } + else + { + versionString = getDoxygenVersion(); + } + return versionString; +} + //------------------------------------------------------ static int g_usedTableLevels = 0; @@ -9034,5 +8543,3 @@ int usedTableLevels() } //------------------------------------------------------ - - @@ -35,7 +35,7 @@ class ClassDef; class FileDef; class MemberList; class NamespaceDef; -class FileNameDict; +class FileNameLinkedMap; class ArgumentList; class OutputList; class OutputDocInterface; @@ -49,9 +49,8 @@ class ClassList; class MemberGroupSDict; struct TagInfo; class MemberNameInfoSDict; -struct ListItemInfo; class PageDef; -struct SectionInfo; +class SectionInfo; class QDir; class Definition; class BufStr; @@ -119,7 +118,6 @@ class LetterToIndexMap : public SIntDict<T> QCString langToString(SrcLangExt lang); QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE); -QCString replaceScopeSeparator(QCString str); //-------------------------------------------------------------------- @@ -218,10 +216,10 @@ const ClassDef *getResolvedClass(const Definition *scope, NamespaceDef *getResolvedNamespace(const char *key); -FileDef *findFileDef(const FileNameDict *fnDict,const char *n, +FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n, bool &ambig); -QCString showFileDefMatches(const FileNameDict *fnDict,const char *n); +QCString showFileDefMatches(const FileNameLinkedMap *fnMap,const char *n); int guessSection(const char *name); @@ -327,15 +325,19 @@ int getScopeFragment(const QCString &s,int p,int *l); int filterCRLF(char *buf,int len); -void addRefItem(const std::vector<ListItemInfo> &sli,const char *prefix, +void addRefItem(const std::vector<RefItem*> &sli, const char *key, - const char *name,const char *title,const char *args,Definition *scope); + const char *prefix, + const char *name, + const char *title, + const char *args, + const Definition *scope); PageDef *addRelatedPage(const char *name, const QCString &ptitle, const QCString &doc, const char *fileName,int startLine, - const std::vector<ListItemInfo> &sli = std::vector<ListItemInfo>(), + const std::vector<RefItem*> &sli = std::vector<RefItem*>(), GroupDef *gd=0, const TagInfo *tagInfo=0, bool xref=FALSE, @@ -437,9 +439,9 @@ QCString filterTitle(const QCString &title); bool patternMatch(const QFileInfo &fi,const QStrList *patList); -QCString externalLinkTarget(); +QCString externalLinkTarget(const bool parent = false); QCString externalRef(const QCString &relPath,const QCString &ref,bool href); -int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos); +int nextUtf8CharPosition(const QCString &utf8Str,uint len,uint startPos); const char *writeUtf8Char(FTextStream &t,const char *s); @@ -498,4 +500,5 @@ int usedTableLevels(); void incUsedTableLevels(); void decUsedTableLevels(); +QCString getFullVersion(); #endif diff --git a/src/vhdlcode.l b/src/vhdlcode.l index fe5a8d9..808e5a2 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -20,6 +20,9 @@ %option never-interactive %option case-insensitive %option prefix="vhdlcodeYY" +%top{ +#include <stdint.h> +} %{ @@ -50,6 +53,8 @@ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 + +#define USE_STATE2STRING 0 // Toggle for some debugging info //#define DBG_CTX(x) fprintf x @@ -113,7 +118,10 @@ static bool writeColoredWord(QCString& word ); static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE, const char *curr_class=0); static void endFontClass(); static void startFontClass(const char *s); + +#if USE_STATE2STRING static const char *stateToString(int state); +#endif //------------------------------------------------------------------- @@ -852,7 +860,7 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI generateMemLink(*g_code,g_PortMapComp,s1); while (index++<t1.size()) { - char cc=t1.at(index); + cc=t1.at(index); if (cc==' ' || cc=='\t') { char c2[2]; @@ -1644,5 +1652,7 @@ void codeFreeVhdlScanner() #endif } +#if USE_STATE2STRING #include "vhdlcode.l.h" +#endif diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 3c30174..380c77b 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -58,7 +58,7 @@ #include "plantuml.h" #include "vhdljjparser.h" #include "VhdlParser.h" -#include "vhdlcode.h" +//#include "vhdlcode.h" #include "plantuml.h" //#define DEBUGFLOW #define theTranslator_vhdlType theTranslator->trVhdlType @@ -70,7 +70,6 @@ static QDict<QCString> g_vhdlKeyDict3(17,FALSE); static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief); static void writeUCFLink(const MemberDef* mdef,OutputList &ol); -static void assignBinding(VhdlConfNode* conf); static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst, const std::shared_ptr<Entry> &cur); @@ -200,7 +199,7 @@ void VhdlDocGen::writeOverview() if (!f.open(IO_WriteOnly)) { - fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data()); + err("Warning: Cannot open file %s for writing\n",fileName.data()); return; } @@ -768,22 +767,22 @@ MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& mem Definition *d = cd->getOuterScope(); QCString tt=d->name(); - ClassDef *ecd =getClass(tt); - if (!ecd) + ClassDef *acd =getClass(tt); + if (!acd) { tt=tt.upper(); - ecd =getClass(tt); + acd =getClass(tt); } - if (!ecd) + if (!acd) { tt=tt.lower(); - ecd =getClass(tt); + acd =getClass(tt); } - if (ecd) //d && d->definitionType()==Definition::TypeClass) + if (acd) //d && d->definitionType()==Definition::TypeClass) { - if(!packages.contains(ecd)) + if(!packages.contains(acd)) { - VhdlDocGen::findAllPackages(ecd); + VhdlDocGen::findAllPackages(acd); } } } @@ -1154,7 +1153,6 @@ void VhdlDocGen::parseFuncProto(const char* text,QCString& name,QCString& ret,bo } else { - QCString s1(text); s1=s1.stripWhiteSpace(); int i=s1.find("(",0,FALSE); int s=s1.find(QRegExp("[ \\t]")); @@ -1421,7 +1419,7 @@ void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList &al,const MemberDef* mdef) { bool sem=FALSE; - int len=al.size(); + size_t len=al.size(); ol.docify("( "); if (len > 2) { @@ -1477,7 +1475,7 @@ void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList &al,const { if (!al.hasParameters()) return; bool sem=FALSE; - int len=al.size(); + size_t len=al.size(); ol.startBold(); ol.docify(" ( "); ol.endBold(); @@ -1586,7 +1584,7 @@ bool VhdlDocGen::writeFuncProcDocu( //bool sem=FALSE; ol.enableAll(); - int index=al.size(); + size_t index=al.size(); if (index==0) { ol.docify(" ( ) "); @@ -1879,7 +1877,7 @@ void VhdlDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile) tagFile << "\">" << endl; tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl; tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl; - tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl; + tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()) << Doxygen::htmlFileExtension << "</anchorfile>" << endl; tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl; if (VhdlDocGen::isVhdlFunction(mdef)) @@ -1956,9 +1954,10 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, } // *** write type /*VHDL CHANGE */ - bool bRec,bUnit; + QCString ltype(mdef->typeString()); QCString largs(mdef->argsString()); + ClassDef *kl=0; const ArgumentList &al = mdef->argumentList(); QCString nn; @@ -2014,7 +2013,7 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, ol.insertMemberAlign(); if (largs=="context") { - VhdlDocGen::writeRecorUnit(ltype,ol,mdef); + VhdlDocGen::writeRecordUnit(ltype,largs,ol,mdef); } break; @@ -2079,7 +2078,6 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, ol.insertMemberAlign(); ol.docify(" "); - ol.startBold(); ol.docify(ltype); ol.endBold(); @@ -2128,6 +2126,7 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, case VhdlDocGen::SHAREDVARIABLE: case VhdlDocGen::VFILE: case VhdlDocGen::GROUP: + case VhdlDocGen::TYPE: writeLink(mdef,ol); ol.docify(" "); ol.insertMemberAlign(); @@ -2135,32 +2134,7 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, break; case VhdlDocGen::RECORD: case VhdlDocGen::UNITS: - writeLink(mdef,ol); - ol.docify(" "); - ol.startBold(); - if (ltype.isEmpty()) { - ol.docify(" "); - } - ol.insertMemberAlign(); - if (!ltype.isEmpty()) - VhdlDocGen::formatString(ltype,ol,mdef); - ol.endBold(); - break; - case VhdlDocGen::TYPE: - bRec=largs.stripPrefix("record") ; - bUnit=largs.stripPrefix("units") ; - ol.startBold(); - if (bRec) ol.docify("record: "); - if (bUnit) ol.docify("units: "); - writeLink(mdef,ol); - ol.insertMemberAlign(); - if (!bRec && !bUnit) VhdlDocGen::formatString(ltype,ol,mdef); - if (bUnit) ol.lineBreak(); - if (bRec || bUnit) - { - writeRecorUnit(largs,ol,mdef); - } - ol.endBold(); + writeRecordUnit(largs,ltype,ol,mdef); break; default: break; @@ -2479,10 +2453,10 @@ void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,b { if (altera) { - int i=temp.find("-name"); - if (i>0) + int in=temp.find("-name"); + if (in>0) { - temp=temp.remove(0,i+5); + temp=temp.remove(0,in+5); } temp.stripPrefix("set_location_assignment"); @@ -2492,8 +2466,8 @@ void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,b else { QRegExp ee("[\\s=]"); - int i=temp.find(ee); - QCString ff=temp.left(i); + int in=temp.find(ee); + QCString ff=temp.left(in); temp.stripPrefix(ff.data()); ff.append("#"); if (!temp.isEmpty()) @@ -2593,44 +2567,8 @@ static void writeUCFLink(const MemberDef* mdef,OutputList &ol) VhdlDocGen::formatString(largs,ol,mdef); } -bool VhdlDocGen::findConstraintFile(LayoutNavEntry *lne) -{ - FileName *fn=Doxygen::inputNameList->getFirst(); - //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files); - uint count=Doxygen::inputNameList->count(); - LayoutNavEntry *kk = lne->parent();// find(LayoutNavEntry::Files); - // LayoutNavEntry *kks = kk->parent();// find(LayoutNavEntry::Files); - QCString file; - QCString co("Constraints"); - - QCString imgExt = getDotImageExtension(); - if (Config_getBool(HAVE_DOT) && imgExt=="svg") - { - QCString ov = theTranslator->trDesignOverview(); - QCString ofile("vhdl_design_overview"); - LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,TRUE,ofile,ov,""); - kk->addChild(oo); - } - - uint i=0; - while (i<count) - { - FileDef *fd=fn->at(i); - if (fd->name().contains(".ucf") || fd->name().contains(".qsf")) - { - file = convertNameToFile(fd->name().data(),FALSE,FALSE); - LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,""); - kk->addChild(ucf); - break; - } - i++; - } - return FALSE; -} - - // for cell_inst : [entity] work.proto [ (label|expr) ] -QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch) +QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch) { int index; QCString label; @@ -2708,133 +2646,6 @@ QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch) } -//@param arch bit0:flipflop -//@param binding e.g entity work.foo(bar) -//@param label |label0|label1 -// label0:architecture name -//@param confVhdl of configuration file (identifier::entity_name) or -// the architecture if isInlineConf TRUE -//@param isInlineConf -//@param confN List of configurations - -void assignBinding(VhdlConfNode * conf) -{ - ClassDef *archClass=0,*entClass=0; - QCString archName; - QCString arcBind,entBind; - - bool others,all; - entBind=conf->binding; - QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind); - - if (qstricmp(conf2,"configuration")==0) - { - QList<VhdlConfNode> confList = getVhdlConfiguration(); - VhdlConfNode* vconf; - // bool found=false; - for (uint iter=0;iter<confList.count(); iter++) - { - vconf= (VhdlConfNode *)confList.at(iter); - QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0); - if (n==entBind) - { - // found=true; - entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1); - QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0); - QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1); - a=e+"::"+a; - archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data()); - entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data()); - break; - } - } - } - else // conf2!=configuration - { - QCString a,c,e; - if (conf->isInlineConf) - { - c=conf->confVhdl; - e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),0); - } - else - { - a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0); - e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1); - c=e+"::"+a; - } - archClass= VhdlDocGen::findVhdlClass(c.data());//Doxygen::classSDict->find(a.data()); - entClass= VhdlDocGen::findVhdlClass(e.data()); //Doxygen::classSDict->find(e.data()); - } - - QCString label=conf->compSpec.lower(); - //label.prepend("|"); - - if (!archClass) - { - // err("architecture %s not found ! ",conf->confVhdl.data()); - return; - } - - archName=archClass->name(); - QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0); - all=allOt.lower()=="all" ; - others= allOt.lower()=="others"; - - for (const auto &cur : getVhdlInstList()) - { - if (cur->exception.lower()==label || conf->isInlineConf) - { - QCString archy; - - if (all || others) - { - archy=VhdlDocGen::getIndexWord(conf->arch.data(),1); - } - else - { - archy=conf->arch; - } - - QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower(); - QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower(); - - QCStringList ql=QCStringList::split(",",inst1); - - for (uint j=0;j<ql.count();j++) - { - QCString archy1,sign1; - if (all || others) - { - archy1=VhdlDocGen::getIndexWord(conf->arch.data(),1); - sign1=cur->type; - } - else - { - archy1=comp+":"+ql[j]; - sign1=cur->type+":"+cur->name; - } - - if (archy1==sign1.lower() && !cur->stat) - { - // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data()); - ClassDef *ent= VhdlDocGen::findVhdlClass(entBind.data());//Doxygen::classSDict->find(entBind.data()); - - if (entClass==0 || ent==0) - { - continue; - } - - addInstance(ent,archClass,entClass,cur); - cur->stat=TRUE; - break; - } - }// for - } - }//for each element in instList - -}//assignBinding - /* // file foo.vhd @@ -2852,17 +2663,6 @@ void VhdlDocGen::computeVhdlComponentRelations() { QCString entity,arch,inst; - QList<VhdlConfNode> confList = getVhdlConfiguration(); - - for (uint iter=0;iter<confList.count(); iter++) - { - VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter); - if (!(conf->isInlineConf || conf->isLeaf)) - { - continue; - } - assignBinding(conf); - } for (const auto &cur : getVhdlInstList()) { @@ -2959,37 +2759,39 @@ ferr: md->setLanguage(SrcLangExt_VHDL); md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION); md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine); - md->setBodySegment(cur->startLine,-1) ; + md->setBodySegment(cur->startLine,cur->startLine,-1) ; md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine); FileDef *fd=ar->getFileDef(); md->setBodyDef(fd); - - - QCString info="Info: Elaborating entity "+n1; - fd=ar->getFileDef(); - info+=" for hierarchy "; - QRegExp epr("[|]"); - QCString label=cur->type+":"+cur->write+":"+cur->name; - label.replace(epr,":"); - info+=label; - fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data()); - - + //QCString info="Info: Elaborating entity "+n1; + //fd=ar->getFileDef(); + //info+=" for hierarchy "; + //QRegExp epr("[|]"); + //QCString label=cur->type+":"+cur->write+":"+cur->name; + //label.replace(epr,":"); + //info+=label; + //fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data()); ar->insertMember(md); } -void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef) +void VhdlDocGen::writeRecordUnit(QCString & largs,QCString & ltype,OutputList& ol ,const MemberDef *mdef) { - QCStringList ql=QCStringList::split("#",largs,FALSE); - uint len=ql.count(); - for(uint i=0;i<len;i++) - { - QCString n=ql[i]; - VhdlDocGen::formatString(n,ol,mdef); - if ((len-i)>1) ol.lineBreak(); - } + int i=mdef->name().find('~'); + if(i>0){ + //sets the real record member name + const_cast<MemberDef*>(mdef)->setName(mdef->name().left(i).data()); + } + + writeLink(mdef,ol); + ol.startBold(); + ol.insertMemberAlign(); + if (!ltype.isEmpty()){ + VhdlDocGen::formatString(ltype,ol,mdef); + } + ol.endBold(); + } @@ -3630,7 +3432,7 @@ void FlowChart::addFlowChart(int type,const char* text,const char* exp, const ch FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label); - fl->line=vhdl::parser::VhdlParser::getLine(); + fl->line=1; // TODO: use getLine(); of the parser if (type & (START_NO | VARIABLE_NO)) { @@ -3935,7 +3737,7 @@ void FlowChart::writeShape(FTextStream &t,const FlowChart* fl) else { if (fl->text.isEmpty()) return; - bool var=(fl->type & FlowChart::VARIABLE_NO); + bool isVar=(fl->type & FlowChart::VARIABLE_NO); QCString q=fl->text; if (exit) @@ -3951,7 +3753,7 @@ void FlowChart::writeShape(FTextStream &t,const FlowChart* fl) } t << "[shape=none margin=0.1, label=<\n"; t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n "; - if (var) + if (isVar) { t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > "; } @@ -4014,7 +3816,7 @@ void FlowChart::writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom, void FlowChart::alignFuncProc( QCString & q,const ArgumentList &al,bool isFunc) { - int index=al.size(); + size_t index=al.size(); if (index==0) return; int len=q.length()+VhdlDocGen::getFlowMember()->name().length(); @@ -4095,7 +3897,7 @@ int FlowChart::findLabel(int index,QCString &label) return j; } } - err("could not find label: ",label.data()); + err("could not find label: %s",label.data()); return 0; } @@ -4310,5 +4112,3 @@ void FlowChart::writeFlowLinks(FTextStream &t) } } //for } //writeFlowLinks - - diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index 6203196..5442f88 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -3,8 +3,8 @@ * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -16,8 +16,8 @@ #ifndef VHDLDOCGEN_H #define VHDLDOCGEN_H -/** - * This class implements functions for parsing and generating +/** + * This class implements functions for parsing and generating * vhdl documents */ @@ -39,8 +39,35 @@ class FileDef; class NamespaceDef; struct Argument; + + +struct VhdlConfNode +{ + VhdlConfNode(const char* a,const char* b,const char* config,const char* cs,bool leaf) + { + arch=a; // architecture e.g. for iobuffer + arch=arch.lower(); + binding=b; // binding e.g. use entity work.xxx(bev) + binding=binding.lower(); + confVhdl=config; // configuration foo is bar + compSpec=cs; + isInlineConf=false; // primary configuration? + isLeaf=leaf; + }; + + QCString confVhdl; + QCString arch; + QCString binding; + QCString compSpec; + int level = 0; + bool isLeaf = false; + bool isInlineConf = false; + +}; + + /** Class for generating documentation specific for VHDL */ -class VhdlDocGen +class VhdlDocGen { public: @@ -71,11 +98,11 @@ class VhdlDocGen USE, PROCESS, PORT, - UNITS, + UNITS, GENERIC, INSTANTIATION, GROUP, - VFILE, + VFILE, SHAREDVARIABLE, CONFIG, ALIAS, @@ -88,7 +115,7 @@ class VhdlDocGen static void init(); static QCString convertFileNameToClassName(QCString name); // --- used by vhdlscanner.l ----------- - + static bool isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level); static QCString getIndexWord(const char* ,int index); @@ -105,7 +132,7 @@ class VhdlDocGen static QCString* findKeyWord(const QCString& word); static ClassDef* getPackageName(const QCString& name); - static MemberDef* findMember(const QCString& className, + static MemberDef* findMember(const QCString& className, const QCString& memName); static void findAllPackages(ClassDef*); static MemberDef* findMemberDef(ClassDef* cd, @@ -180,19 +207,18 @@ class VhdlDocGen static QCString convertArgumentListToString(const ArgumentList &al,bool f); static QCString getProcessNumber(); static QCString getRecordNumber(); - + static QCString getClassName(const ClassDef*); static bool isNumber(const QCString& s); static QCString getProtectionName(int prot); static void parseUCF(const char* input,Entry* entity,QCString f,bool vendor); - static bool findConstraintFile( LayoutNavEntry *lne); static ClassDef* findArchitecture(const ClassDef *cd); static ClassDef* findArchitecture(QCString identifier, QCString entity_name); static void correctMemberProperties(MemberDef *md); - + static void writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname); static QCString parseForConfig(QCString & entity,QCString & arch); @@ -202,15 +228,15 @@ class VhdlDocGen static void writeOverview(OutputList &ol); static void writeOverview(); - + // flowcharts static void createFlowChart(const MemberDef*); //static void addFlowImage(const FTextStream &,const QCString &); - + static void setFlowMember( const MemberDef *flowMember); static const MemberDef *getFlowMember(); - static bool isVhdlClass (const Entry *cu) + static bool isVhdlClass (const Entry *cu) { return cu->spec==VhdlDocGen::ENTITY || cu->spec==VhdlDocGen::PACKAGE || @@ -226,7 +252,7 @@ class VhdlDocGen static void writeVhdlLink(const ClassDef* cdd ,OutputList& ol,QCString& type,QCString& name,QCString& beh); static void writeStringLink(const MemberDef *mdef,QCString mem,OutputList& ol); static void writeRecUnitDocu( const MemberDef *md, OutputList& ol,QCString largs); - static void writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef); + static void writeRecordUnit(QCString & largs,QCString & ltype,OutputList& ol ,const MemberDef *mdef); }; //------------------------------------------------------------------------------------------------------------------- @@ -263,7 +289,7 @@ class FlowChart BEGIN_NO = 1<<21 }; - //---------- create svg ------------------------------------------------------------- + //---------- create svg ------------------------------------------------------------- static void createSVG(); static void startDot(FTextStream &t); static void endDot(FTextStream &t); diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index 5dfa9f6..725349e 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -14,7 +14,6 @@ #include <qfileinfo.h> #include <qcstringlist.h> #include "vhdljjparser.h" -#include "vhdlcode.h" #include "vhdldocgen.h" #include "message.h" #include "config.h" @@ -28,205 +27,232 @@ #include "outputlist.h" #include "arguments.h" #include "types.h" -#include "VhdlParserIF.h" #include "growbuf.h" +#include "markdown.h" +#include "VhdlParserTokenManager.h" +#include "VhdlParserErrorHandler.hpp" using namespace vhdl::parser; -using namespace std; -static OutlineParserInterface *g_thisParser; - -static QCString yyFileName; -static int yyLineNr = 1; -static int* lineParse; -static int iDocLine = -1; -static QCString inputString; -static Entry* gBlock = 0; -static Entry* previous = 0; -//------------------------------------------------------- +struct VHDLDocInfo +{ + QCString doc; + bool brief; + bool pending = false; + int iDocLine = 1; +}; -static Entry* oldEntry; -static bool varr=FALSE; -static QCString varName; -static std::vector< std::shared_ptr<Entry> > instFiles; -static std::vector< std::shared_ptr<Entry> > libUse; -static std::vector<Entry*> lineEntry; +static bool isConstraintFile(const QCString &fileName,const QCString &ext) +{ + return fileName.right(ext.length())==ext; +} -Entry* VhdlParser::tempEntry=0; -Entry* VhdlParser::lastEntity=0 ; -Entry* VhdlParser::lastCompound=0 ; -Entry* VhdlParser::current_root = 0; -std::shared_ptr<Entry> VhdlParser::current=0; -QCString VhdlParser::compSpec; -QCString VhdlParser::currName; -QCString VhdlParser::confName; -QCString VhdlParser::genLabels; -QCString VhdlParser::lab; -QCString VhdlParser::forL; -int VhdlParser::param_sec = 0; -int VhdlParser::parse_sec=0; -int VhdlParser::currP=0; -int VhdlParser::levelCounter; +//------------------------------------- -static QList<VhdlConfNode> configL; +static EntryList g_instFiles; -static struct +struct VHDLOutlineParser::Private { - QCString doc; - bool brief; - bool pending; - int iDocLine; -} str_doc; + void parseVhdlfile(const char *fileName,const char* inputBuffer,bool inLine); -static QCString strComment; -static int iCodeLen; -static const char *vhdlFileName = 0; + VHDLOutlineParser *thisParser = 0; + VhdlParser *vhdlParser = 0; + CommentScanner commentScanner; -static bool checkMultiComment(QCString& qcs,int line); -static void insertEntryAtLine(const Entry* ce,int line); - -//------------------------------------- + QCString yyFileName; + int yyLineNr = 1; + std::vector<int> lineParse; + int iDocLine = -1; + QCString inputString; + Entry* gBlock = 0; + Entry* previous = 0; +//------------------------------------------------------- -const QList<VhdlConfNode>& getVhdlConfiguration() { return configL; } -const std::vector<std::shared_ptr<Entry> > &getVhdlInstList() { return instFiles; } + Entry* oldEntry = 0; + bool varr = FALSE; + QCString varName; + EntryList libUse; + EntryList lineEntry; + QCString strComment; + int iCodeLen; + VHDLDocInfo str_doc; + VhdlParser::SharedState shared; + QCString forL; + +}; + +void VHDLOutlineParser::Private::parseVhdlfile(const char *fileName, + const char* inputBuffer,bool inLine) +{ + JAVACC_STRING_TYPE s =inputBuffer; + CharStream *stream = new CharStream(s.c_str(), (int)s.size(), 1, 1); + VhdlParserTokenManager *tokenManager = new VhdlParserTokenManager(stream); + VhdlTokenManagerErrorHandler *tokErrHandler=new VhdlTokenManagerErrorHandler(fileName); + vhdlParser=new VhdlParser(tokenManager); + vhdlParser->setOutlineParser(thisParser); + vhdlParser->setSharedState(&shared); + tokenManager->setLexParser(vhdlParser); + tokenManager->ReInit(stream,0); + tokenManager->setErrorHandler(tokErrHandler); + VhdlErrorHandler *parserErrHandler=new VhdlErrorHandler(fileName); + vhdlParser->setErrorHandler(parserErrHandler); + try + { + if(inLine) + { + vhdlParser->parseInline(); + } + else + { + vhdlParser->design_file(); + } + } + catch( std::exception &){ /* fprintf(stderr,"\n[%s]",e.what()); */ } + // fprintf(stderr,"\n\nparsed lines: %d\n",yyLineNr); + // fprintf(stderr,"\n\nerrors : %d\n\n",myErr->getErrorCount()); + delete vhdlParser; +} -Entry* getVhdlCompound() +VHDLOutlineParser::VHDLOutlineParser() : p(std::make_unique<Private>()) { - if (VhdlParser::lastEntity) return VhdlParser::lastEntity; - if (VhdlParser::lastCompound) return VhdlParser::lastCompound; - return NULL; } -bool isConstraintFile(const QCString &fileName,const QCString &ext) +VHDLOutlineParser::~VHDLOutlineParser() { - return fileName.right(ext.length())==ext; } - void VHDLOutlineParser::parseInput(const char *fileName,const char *fileBuf, - const std::shared_ptr<Entry> &root, bool ,QStrList&) + const std::shared_ptr<Entry> &root, bool ,QStrList&) { - g_thisParser=this; - bool inLine=false; - inputString=fileBuf; + VhdlParser::SharedState *s = &p->shared; + p->thisParser=this; + p->inputString=fileBuf; // fprintf(stderr,"\n ============= %s\n ==========\n",fileBuf); - if (strlen(fileName)==0) - { - inLine=true; - } + bool inLine = (fileName==0 || strlen(fileName)==0); - yyFileName+=fileName; + p->yyFileName=fileName; - bool xilinx_ucf=isConstraintFile(yyFileName,".ucf"); - bool altera_qsf=isConstraintFile(yyFileName,".qsf"); + bool xilinx_ucf=isConstraintFile(p->yyFileName,".ucf"); + bool altera_qsf=isConstraintFile(p->yyFileName,".qsf"); // support XILINX(ucf) and ALTERA (qsf) file if (xilinx_ucf) { - VhdlDocGen::parseUCF(fileBuf,root.get(),yyFileName,FALSE); + VhdlDocGen::parseUCF(fileBuf,root.get(),p->yyFileName,FALSE); return; } if (altera_qsf) { - VhdlDocGen::parseUCF(fileBuf,root.get(),yyFileName,TRUE); + VhdlDocGen::parseUCF(fileBuf,root.get(),p->yyFileName,TRUE); return; } - yyLineNr=1; - VhdlParser::current_root=root.get(); - VhdlParser::lastCompound=0; - VhdlParser::lastEntity=0; - VhdlParser::lastEntity=0; - oldEntry = 0; - VhdlParser::current=std::make_shared<Entry>(); - VhdlParser::initEntry(VhdlParser::current.get()); - Doxygen::docGroup.enterFile(fileName,yyLineNr); - vhdlFileName = fileName; - lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h - VhdlParserIF::parseVhdlfile(fileBuf,inLine); - - VhdlParser::current.reset(); + p->yyLineNr=1; + s->current_root=root; + s->lastCompound=0; + s->lastEntity=0; + s->lastEntity=0; + p->oldEntry = 0; + s->current=std::make_shared<Entry>(); + initEntry(s->current.get()); + p->commentScanner.enterFile(fileName,p->yyLineNr); + p->lineParse.reserve(200); + p->parseVhdlfile(fileName,fileBuf,inLine); + p->commentScanner.leaveFile(fileName,p->yyLineNr); + + s->current.reset(); if (!inLine) - VhdlParser::mapLibPackage(root.get()); + mapLibPackage(root.get()); - delete[] lineParse; - yyFileName.resize(0); - libUse.clear(); - VhdlDocGen::resetCodeVhdlParserState(); - vhdlFileName = 0; + p->yyFileName.resize(0); + p->libUse.clear(); } -void VhdlParser::lineCount() +void VHDLOutlineParser::lineCount() { - yyLineNr++; + p->yyLineNr++; } -void VhdlParser::lineCount(const char* text) +void VHDLOutlineParser::lineCount(const char* text) { for (const char* c=text ; *c ; ++c ) { - if (*c == '\n') yyLineNr++; + if (*c == '\n') p->yyLineNr++; } } -void isVhdlDocPending() +void VHDLOutlineParser::initEntry(Entry *e) { - if (!str_doc.pending) return; - - str_doc.pending=FALSE; - oldEntry=0; // prevents endless recursion - iDocLine=str_doc.iDocLine; - VhdlParser::handleCommentBlock(str_doc.doc,str_doc.brief); - iDocLine=-1; -} - -void VhdlParser::initEntry(Entry *e) -{ - e->fileName = yyFileName; + e->fileName = p->yyFileName; e->lang = SrcLangExt_VHDL; - isVhdlDocPending(); - Doxygen::docGroup.initGroupInfo(e); + if (p->str_doc.pending) + { + p->str_doc.pending=FALSE; + p->oldEntry=0; // prevents endless recursion + p->iDocLine=p->str_doc.iDocLine; + handleCommentBlock(p->str_doc.doc,p->str_doc.brief); + p->iDocLine=-1; + } + p->commentScanner.initGroupInfo(e); } -void VhdlParser::newEntry() +void VHDLOutlineParser::newEntry() { - previous = current.get(); - if (current->spec==VhdlDocGen::ENTITY || - current->spec==VhdlDocGen::PACKAGE || - current->spec==VhdlDocGen::ARCHITECTURE || - current->spec==VhdlDocGen::PACKAGE_BODY) + VhdlParser::SharedState *s = &p->shared; + p->previous = s->current.get(); + if (s->current->spec==VhdlDocGen::ENTITY || + s->current->spec==VhdlDocGen::PACKAGE || + s->current->spec==VhdlDocGen::ARCHITECTURE || + s->current->spec==VhdlDocGen::PACKAGE_BODY) { - current_root->moveToSubEntryAndRefresh(current); + s->current_root->moveToSubEntryAndRefresh(s->current); } else { - if (lastCompound) + if (s->lastCompound) { - lastCompound->moveToSubEntryAndRefresh(current); + s->lastCompound->moveToSubEntryAndRefresh(s->current); } else { - if (lastEntity) + if (s->lastEntity) { - lastEntity->moveToSubEntryAndRefresh(current); + s->lastEntity->moveToSubEntryAndRefresh(s->current); } else { - current_root->moveToSubEntryAndRefresh(current); + s->current_root->moveToSubEntryAndRefresh(s->current); } } } - initEntry(current.get()); + initEntry(s->current.get()); +} + +static int idCounter; + +/** returns a unique id for each record member. +* +* type first_rec is record +* RE: data_type; +* end; +* +* type second_rec is record +* RE: data_type; +* end; +*/ + +QString VHDLOutlineParser::getNameID(){ + return QString::number(idCounter++,10); } -void VhdlParser::handleFlowComment(const char* doc) +void VHDLOutlineParser::handleFlowComment(const char* doc) { - lineCount(doc); + lineCount(doc); if (VhdlDocGen::getFlowMember()) { @@ -238,16 +264,15 @@ void VhdlParser::handleFlowComment(const char* doc) } -void VhdlParser::handleCommentBlock(const char* doc1,bool brief) +void VHDLOutlineParser::handleCommentBlock(const char* doc1,bool brief) { - QCString doc; - doc.append(doc1); - // fprintf(stderr,"\n %s",doc.data()); + VhdlParser::SharedState *s = &p->shared; + QCString doc = doc1; if (doc.isEmpty()) return; - if (checkMultiComment(doc,yyLineNr)) + if (checkMultiComment(doc,p->yyLineNr)) { - strComment.resize(0); + p->strComment.resize(0); return; } @@ -255,44 +280,43 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) Protection protection=Public; - if (oldEntry==current.get()) + if (p->oldEntry==s->current.get()) { //printf("\n find pending message < %s > at line: %d \n ",doc.data(),iDocLine); - str_doc.doc=doc; - str_doc.iDocLine=iDocLine; - str_doc.brief=brief; - str_doc.pending=TRUE; + p->str_doc.doc=doc; + p->str_doc.iDocLine=p->iDocLine; + p->str_doc.brief=brief; + p->str_doc.pending=TRUE; return; } - oldEntry=current.get(); + p->oldEntry=s->current.get(); if (brief) { - current->briefLine = yyLineNr; + s->current->briefLine = p->yyLineNr; } else { - current->docLine = yyLineNr; + s->current->docLine = p->yyLineNr; } - // printf("parseCommentBlock file<%s>\n [%s]\n at line [%d] \n ",yyFileName.data(),doc.data(),iDocLine); - + int j=doc.find("[plant]"); if (j>=0) { doc=doc.remove(j,7); - current->stat=true; + s->current->stat=true; } int position=0; bool needsEntry=FALSE; - QCString processedDoc = preprocessCommentBlock(doc,yyFileName,iDocLine); - while (parseCommentBlock( - g_thisParser, - current.get(), + QCString processedDoc = processMarkdownForCommentBlock(doc,p->yyFileName,p->iDocLine); + while (p->commentScanner.parseCommentBlock( + p->thisParser, + s->current.get(), processedDoc, // text - yyFileName, // file - iDocLine, // line of block start + p->yyFileName, // file + p->iDocLine, // line of block start brief, 0, FALSE, @@ -302,62 +326,64 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) ) ) { - //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position); if (needsEntry) newEntry(); } if (needsEntry) { - if (varr) + if (p->varr) { - varr=FALSE; - current->name=varName; - current->section=Entry::VARIABLEDOC_SEC; - varName=""; + p->varr=FALSE; + s->current->name=p->varName; + s->current->section=Entry::VARIABLEDOC_SEC; + p->varName=""; } newEntry(); } - iDocLine=-1; - strComment.resize(0); + p->iDocLine=-1; + p->strComment.resize(0); } void VHDLOutlineParser::parsePrototype(const char *text) { - varName=text; - varr=TRUE; + p->varName=text; + p->varr=TRUE; } -void VhdlParser::addCompInst(const char *n, const char* instName, const char* comp,int iLine) +void VHDLOutlineParser::addCompInst(const char *n, const char* instName, const char* comp,int iLine) { - current->spec=VhdlDocGen::INSTANTIATION; - current->section=Entry::VARIABLE_SEC; - current->startLine=iLine; - current->bodyLine=iLine; - current->type=instName; // foo:instname e.g proto or work. proto(ttt) - current->exception=genLabels.lower(); // |arch|label1:label2... - current->name=n; // foo - if (lastCompound) + VhdlParser::SharedState *s = &p->shared; + s->current->spec=VhdlDocGen::INSTANTIATION; + s->current->section=Entry::VARIABLE_SEC; + s->current->startLine=iLine; + s->current->bodyLine=iLine; + s->current->type=instName; // foo:instname e.g proto or work. proto(ttt) + s->current->exception=s->genLabels.lower(); // |arch|label1:label2... + s->current->name=n; // foo + if (s->lastCompound) { - current->args=lastCompound->name; // architecture name + s->current->args=s->lastCompound->name; // architecture name } - current->includeName=comp; // component/entity/configuration - int u=genLabels.find("|",1); + s->current->includeName=comp; // component/entity/configuration + int u=s->genLabels.find("|",1); if (u>0) { - current->write=genLabels.right(genLabels.length()-u); - current->read=genLabels.left(u); + s->current->write=s->genLabels.right(s->genLabels.length()-u); + s->current->read=s->genLabels.left(u); } //printf (" \n genlabel: [%s] inst: [%s] name: [%s] %d\n",n,instName,comp,iLine); - if (lastCompound) + if (s->lastCompound) { - current->args=lastCompound->name; + s->current->args=s->lastCompound->name; if (true) // !findInstant(current->type)) { - initEntry(current.get()); - instFiles.emplace_back(std::make_shared<Entry>(*current)); + initEntry(s->current.get()); + // TODO: protect with mutex + g_instFiles.emplace_back(std::make_shared<Entry>(*s->current)); + // TODO: end protect with mutex } - current=std::make_shared<Entry>(); + s->current=std::make_shared<Entry>(); } else { @@ -365,13 +391,14 @@ void VhdlParser::addCompInst(const char *n, const char* instName, const char* co } } -void VhdlParser::addVhdlType(const char *n,int startLine,int section, +void VHDLOutlineParser::addVhdlType(const char *n,int startLine,int section, uint64 spec,const char* args,const char* type,Protection prot) { + VhdlParser::SharedState *s = &p->shared; QCString name(n); if (isFuncProcProced() || VhdlDocGen::getFlowMember()) return; - if (parse_sec==GEN_SEC) + if (s->parse_sec==GEN_SEC) { spec= VhdlDocGen::GENERIC; } @@ -380,61 +407,62 @@ void VhdlParser::addVhdlType(const char *n,int startLine,int section, for (uint u=0;u<ql.count();u++) { - current->name=ql[u]; - current->startLine=startLine; - current->bodyLine=startLine; - current->section=section; - current->spec=spec; - current->fileName=yyFileName; - if (current->args.isEmpty()) + s->current->name=ql[u]; + s->current->startLine=startLine; + s->current->bodyLine=startLine; + s->current->section=section; + s->current->spec=spec; + s->current->fileName=p->yyFileName; + if (s->current->args.isEmpty()) { - current->args=args; + s->current->args=args; } - current->type=type; - current->protection=prot; + s->current->type=type; + s->current->protection=prot; - if (!lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) + if (!s->lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) { - libUse.emplace_back(std::make_shared<Entry>(*current)); - current->reset(); + p->libUse.emplace_back(std::make_shared<Entry>(*s->current)); + s->current->reset(); } newEntry(); } } -void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn) +void VHDLOutlineParser::createFunction(const char *imp,uint64 spec,const char *fn) { + VhdlParser::SharedState *s = &p->shared; QCString impure(imp); QCString fname(fn); - current->spec=spec; - current->section=Entry::FUNCTION_SEC; + s->current->spec=spec; + s->current->section=Entry::FUNCTION_SEC; if (impure=="impure" || impure=="pure") { - current->exception=impure; + s->current->exception=impure; } - if (parse_sec==GEN_SEC) + if (s->parse_sec==GEN_SEC) { - current->spec= VhdlDocGen::GENERIC; - current->section=Entry::FUNCTION_SEC; + s->current->spec= VhdlDocGen::GENERIC; + s->current->section=Entry::FUNCTION_SEC; } - if (currP==VhdlDocGen::PROCEDURE) + if (s->currP==VhdlDocGen::PROCEDURE) { - current->name=impure; - current->exception=""; + s->current->name=impure; + s->current->exception=""; } else { - current->name=fname; + s->current->name=fname; } if (spec==VhdlDocGen::PROCESS) { - current->args=fname; - current->name=impure; - VhdlDocGen::deleteAllChars(current->args,' '); + s->current->args=fname; + s->current->name=impure; + VhdlDocGen::deleteAllChars(s->current->args,' '); if (!fname.isEmpty()) { QCStringList q1=QCStringList::split(",",fname); @@ -442,19 +470,19 @@ void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn) { Argument arg; arg.name=q1[ii]; - current->argList.push_back(arg); + s->current->argList.push_back(arg); } } - return; } - } +} -bool VhdlParser::isFuncProcProced() +bool VHDLOutlineParser::isFuncProcProced() { - if (currP==VhdlDocGen::FUNCTION || - currP==VhdlDocGen::PROCEDURE || - currP==VhdlDocGen::PROCESS + VhdlParser::SharedState *s = &p->shared; + if (s->currP==VhdlDocGen::FUNCTION || + s->currP==VhdlDocGen::PROCEDURE || + s->currP==VhdlDocGen::PROCESS ) { return TRUE; @@ -462,13 +490,13 @@ bool VhdlParser::isFuncProcProced() return FALSE; } -void VhdlParser::pushLabel( QCString &label,QCString & val) +void VHDLOutlineParser::pushLabel( QCString &label,QCString & val) { label+="|"; label+=val; } - QCString VhdlParser::popLabel(QCString & q) +QCString VHDLOutlineParser::popLabel(QCString & q) { int i=q.findRev("|"); if (i<0) return ""; @@ -476,63 +504,12 @@ void VhdlParser::pushLabel( QCString &label,QCString & val) return q; } -void VhdlParser::addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf) -{ - VhdlConfNode* co=0; - QCString ent; - ent=a; - if (b) - { - ent=b; - } - int level=0; - if (!configL.isEmpty()) - { - VhdlConfNode* vc=configL.getLast(); - level=vc->level; - if (levelCounter==0) - { - pushLabel(forL,ent); - } - else if (level<levelCounter) - { - if (!isLeaf) - { - pushLabel(forL,ent); - } - } - else if (level>levelCounter) - { - forL=popLabel(forL); - } - } - else - { - pushLabel(forL,ent); - } - - if (inlineConf) - { - confName=lastCompound->name; - } - - //fprintf(stderr,"\n[%s %d %d]\n",forL.data(),levelCounter,level); - co=new VhdlConfNode(a,b,confName.lower().data(),forL.lower().data(),isLeaf); - - if (inlineConf) - { - co->isInlineConf=TRUE; - } - - configL.append(co); -} - - -void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, +void VHDLOutlineParser::addProto(const char *s1,const char *s2,const char *s3, const char *s4,const char *s5,const char *s6) { + VhdlParser::SharedState *s = &p->shared; (void)s5; // avoid unused warning QCString name=s2; QCStringList ql=QCStringList::split(",",name); @@ -551,12 +528,12 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, { arg.type+=s6; } - if (parse_sec==GEN_SEC && param_sec==0) + if (s->parse_sec==GEN_SEC && s->param_sec==0) { arg.defval="gen!"; } - if (parse_sec==PARAM_SEC) + if (s->parse_sec==PARAM_SEC) { // assert(false); } @@ -564,9 +541,9 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, arg.defval+=s1; arg.attrib="";//s6; - current->argList.push_back(arg); - current->args+=s2; - current->args+=","; + s->current->argList.push_back(arg); + s->current->args+=s2; + s->current->args+=","; } } @@ -582,13 +559,13 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, * ..... * and so on.. */ -void VhdlParser::mapLibPackage( Entry* root) +void VHDLOutlineParser::mapLibPackage( Entry* root) { //QList<Entry> epp=libUse; //EntryListIterator eli(epp); //Entry *rt; //for (;(rt=eli.current());++eli) - for (const auto &rt : libUse) + for (const auto &rt : p->libUse) { if (addLibUseClause(rt->name)) { @@ -613,7 +590,7 @@ void VhdlParser::mapLibPackage( Entry* root) }// for }//MapLib -bool VhdlParser::addLibUseClause(const QCString &type) +bool VHDLOutlineParser::addLibUseClause(const QCString &type) { static bool showIEEESTD=Config_getBool(FORCE_LOCAL_INCLUDES); @@ -625,48 +602,50 @@ bool VhdlParser::addLibUseClause(const QCString &type) return TRUE; } -int VhdlParser::getLine() +int VHDLOutlineParser::getLine() { - return yyLineNr; + return p->yyLineNr; } -void VhdlParser::setLineParsed(int tok) +void VHDLOutlineParser::setLineParsed(int tok) { - lineParse[tok]=yyLineNr; + if ((int)p->lineParse.size()<=tok) p->lineParse.resize(tok+1); + p->lineParse[tok]=p->yyLineNr; } -int VhdlParser::getLine(int tok) +int VHDLOutlineParser::getLine(int tok) { - int val=lineParse[tok]; + int val=p->lineParse[tok]; if (val<0) val=0; //assert(val>=0 && val<=yyLineNr); return val; } -void VhdlParser::createFlow() +void VHDLOutlineParser::createFlow() { + VhdlParser::SharedState *s = &p->shared; if (!VhdlDocGen::getFlowMember()) { return; } QCString q,ret; - if (currP==VhdlDocGen::FUNCTION) + if (s->currP==VhdlDocGen::FUNCTION) { q=":function( "; - FlowChart::alignFuncProc(q,tempEntry->argList,true); + FlowChart::alignFuncProc(q,s->tempEntry->argList,true); q+=")"; } - else if (currP==VhdlDocGen::PROCEDURE) + else if (s->currP==VhdlDocGen::PROCEDURE) { q=":procedure ("; - FlowChart::alignFuncProc(q,tempEntry->argList,false); + FlowChart::alignFuncProc(q,s->tempEntry->argList,false); q+=")"; } else { - q=":process( "+tempEntry->args; + q=":process( "+s->tempEntry->args; q+=")"; } @@ -674,11 +653,11 @@ void VhdlParser::createFlow() FlowChart::addFlowChart(FlowChart::START_NO,q,0); - if (currP==VhdlDocGen::FUNCTION) + if (s->currP==VhdlDocGen::FUNCTION) { ret="end function "; } - else if (currP==VhdlDocGen::PROCEDURE) + else if (s->currP==VhdlDocGen::PROCEDURE) { ret="end procedure"; } @@ -690,60 +669,79 @@ void VhdlParser::createFlow() FlowChart::addFlowChart(FlowChart::END_NO,ret,0); // FlowChart::printFlowList(); FlowChart::writeFlowChart(); - currP=0; + s->currP=0; } -void VhdlParser::setMultCommentLine() +void VHDLOutlineParser::setMultCommentLine() { - iDocLine=yyLineNr; + p->iDocLine=p->yyLineNr; } -void VhdlParser::oneLineComment(QCString qcs) +void VHDLOutlineParser::oneLineComment(QCString qcs) { int j=qcs.find("--!"); qcs=qcs.right(qcs.length()-3-j); - if (!checkMultiComment(qcs,iDocLine)) + if (!checkMultiComment(qcs,p->iDocLine)) { handleCommentBlock(qcs,TRUE); } } -bool checkMultiComment(QCString& qcs,int line) +bool VHDLOutlineParser::checkMultiComment(QCString& qcs,int line) { - insertEntryAtLine(VhdlParser::current_root,line); + VhdlParser::SharedState *s = &p->shared; + insertEntryAtLine(s->current_root,line); - if (lineEntry.empty()) return false; + if (p->lineEntry.empty()) return false; VhdlDocGen::prepareComment(qcs); - while (!lineEntry.empty()) + while (!p->lineEntry.empty()) { - Entry *e=lineEntry.back(); + std::shared_ptr<Entry> e=p->lineEntry.back(); e->briefLine=line; e->brief+=qcs; - lineEntry.pop_back(); + p->lineEntry.pop_back(); } return true; } // returns the vhdl parsed types at line xxx -void insertEntryAtLine(const Entry* ce,int line) +void VHDLOutlineParser::insertEntryAtLine(std::shared_ptr<Entry> ce,int line) { for (const auto &rt : ce->children()) { if (rt->bodyLine==line) { - lineEntry.push_back(rt.get()); + p->lineEntry.push_back(rt); } - insertEntryAtLine(rt.get(),line); + insertEntryAtLine(rt,line); } } -const char *getVhdlFileName(void) +const EntryList &getVhdlInstList() { - return vhdlFileName; + return g_instFiles; +} + +void VHDLOutlineParser::error_skipto(int kind) +{ + Token *op; + do + { + p->vhdlParser->getNextToken(); // step to next token + op=p->vhdlParser->getToken(1); // get first token + if (op==0) break; + //fprintf(stderr,"\n %s",t->image.data()); + } while (op->kind != kind); + p->vhdlParser->clearError(); + // The above loop consumes tokens all the way up to a token of + // "kind". We use a do-while loop rather than a while because the + // current token is the one immediately before the erroneous token + // (in our case the token immediately before what should have been + // "if"/"while". } QCString filter2008VhdlComment(const char *s) diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index f3e7d70..c4a55de 100644..100755 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -18,22 +18,10 @@ #include "types.h" #include "entry.h" #include "vhdldocgen.h" -#include "vhdlcode.h" -#include "memberlist.h" #include "config.h" - - - enum { GEN_SEC=0x1, PARAM_SEC,CONTEXT_SEC,PROTECTED_SEC } ; -void parserVhdlfile(const char* inputBuffer); - -class Entry; -class ClassSDict; -class ClassDef; -class MemberDef; -struct VhdlConfNode; - +//void parserVhdlfile(const char* inputBuffer); /** \brief VHDL parser using state-based lexical scanning. * @@ -42,7 +30,8 @@ struct VhdlConfNode; class VHDLOutlineParser : public OutlineParserInterface { public: - virtual ~VHDLOutlineParser() {} + VHDLOutlineParser(); + virtual ~VHDLOutlineParser(); void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char * fileName, @@ -53,35 +42,44 @@ class VHDLOutlineParser : public OutlineParserInterface bool needsPreprocessing(const QCString &) const { return TRUE; } void parsePrototype(const char *text); -}; - -struct VhdlConfNode -{ - VhdlConfNode(const char* a,const char* b,const char* config,const char* cs,bool leaf) - { - arch=a; // architecture e.g. for iobuffer - arch=arch.lower(); - binding=b; // binding e.g. use entity work.xxx(bev) - binding=binding.lower(); - confVhdl=config; // configuration foo is bar - compSpec=cs; - isInlineConf=false; // primary configuration? - isLeaf=leaf; - }; - QCString confVhdl; - QCString arch; - QCString binding; - QCString compSpec; - int level = 0; - bool isLeaf = false; - bool isInlineConf = false; + // interface for generated parser code + + void setLineParsed(int tok); + int getLine(int tok); + int getLine(); + void lineCount(const char*); + void lineCount(); + void addProto(const char *s1,const char *s2,const char *s3,const char *s4,const char *s5,const char *s6); + //void addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf); + void createFunction(const char *impure,uint64 spec,const char *fname); + void addVhdlType(const char *n,int startLine,int section, uint64 spec,const char* args,const char* type,Protection prot); + void addCompInst(const char *n, const char* instName, const char* comp,int iLine); + void handleCommentBlock(const char* doc,bool brief); + void handleFlowComment(const char*); + void initEntry(Entry *e); + void newEntry(); + bool isFuncProcProced(); + void pushLabel(QCString &,QCString&); + QCString popLabel(QCString & q); + bool addLibUseClause(const QCString &type); + void mapLibPackage( Entry* root); + void createFlow(); + void error_skipto(int kind); + void oneLineComment(QCString qcs); + void setMultCommentLine(); + bool checkMultiComment(QCString& qcs,int line); + void insertEntryAtLine(std::shared_ptr<Entry> ce,int line); + QString getNameID(); + private: + struct Private; + std::unique_ptr<Private> p; }; -void vhdlscanFreeScanner(); -const QList<VhdlConfNode>& getVhdlConfiguration(); -const std::vector<std::shared_ptr<Entry> >&getVhdlInstList(); +const EntryList &getVhdlInstList(); + QCString filter2008VhdlComment(const char *s); + #endif diff --git a/src/xmlcode.l b/src/xmlcode.l index 94548f8..b583bf5 100644 --- a/src/xmlcode.l +++ b/src/xmlcode.l @@ -19,6 +19,9 @@ %option never-interactive %option prefix="xmlcodeYY" +%top{ +#include <stdint.h> +} %{ @@ -69,7 +72,9 @@ static MemberDef * g_currentMemberDef; static bool g_includeCodeFragment; static const char * g_currentFontClass; +#if USE_STATE2STRING static const char *stateToString(int state); +#endif static void codify(const char* text) { @@ -435,4 +440,6 @@ void XMLCodeParser::resetCodeParserState() resetXmlCodeParserState(); } +#if USE_STATE2STRING #include "xmlcode.l.h" +#endif diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 409c2fe..045f87c 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -1,13 +1,10 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -16,7 +13,7 @@ * */ -#include <qfileinfo.h> +#include <qfileinfo.h> #include "xmldocvisitor.h" #include "docparser.h" @@ -32,6 +29,7 @@ #include "config.h" #include "htmlentity.h" #include "emoji.h" +#include "filedef.h" static void visitCaption(XmlDocVisitor *parent, QList<DocNode> children) { @@ -40,9 +38,9 @@ static void visitCaption(XmlDocVisitor *parent, QList<DocNode> children) for (cli.toFirst();(n=cli.current());++cli) n->accept(parent); } -static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption, - XmlDocVisitor *parent, QList<DocNode> children, - const QCString &name, bool writeType, DocImage::Type type, const QCString &width, +static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption, + XmlDocVisitor *parent, QList<DocNode> children, + const QCString &name, bool writeType, DocImage::Type type, const QCString &width, const QCString &height, bool inlineImage = FALSE) { t << "<" << cmd; @@ -88,8 +86,8 @@ static void visitPostEnd(FTextStream &t, const char *cmd) t << "</" << cmd << ">" << endl; } -XmlDocVisitor::XmlDocVisitor(FTextStream &t,CodeOutputInterface &ci) - : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) +XmlDocVisitor::XmlDocVisitor(FTextStream &t,CodeOutputInterface &ci) + : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) { } @@ -159,7 +157,7 @@ void XmlDocVisitor::visit(DocEmoji *s) void XmlDocVisitor::visit(DocURL *u) { if (m_hide) return; - m_t << "<ulink url=\""; + m_t << "<ulink url=\""; if (u->isEmail()) m_t << "mailto:"; filter(u->url()); m_t << "\">"; @@ -221,12 +219,12 @@ void XmlDocVisitor::visit(DocStyleChange *s) if (s->enable()) m_t << "<small>"; else m_t << "</small>"; break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s->enable()) { - m_t << "<preformatted>"; + m_t << "<preformatted>"; m_insidePre=TRUE; } - else + else { m_t << "</preformatted>"; m_insidePre=FALSE; @@ -257,21 +255,46 @@ void XmlDocVisitor::visit(DocVerbatim *s) Doxygen::parserManager->getCodeParser(lang) .parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); - m_t << "</programlisting>"; + m_t << "</programlisting>"; break; - case DocVerbatim::Verbatim: + case DocVerbatim::Verbatim: m_t << "<verbatim>"; filter(s->text()); - m_t << "</verbatim>"; + m_t << "</verbatim>"; + break; + case DocVerbatim::HtmlOnly: + if (s->isBlock()) + { + m_t << "<htmlonly block=\"yes\">"; + } + else + { + m_t << "<htmlonly>"; + } + filter(s->text()); + m_t << "</htmlonly>"; + break; + case DocVerbatim::RtfOnly: + m_t << "<rtfonly>"; + filter(s->text()); + m_t << "</rtfonly>"; + break; + case DocVerbatim::ManOnly: + m_t << "<manonly>"; + filter(s->text()); + m_t << "</manonly>"; + break; + case DocVerbatim::LatexOnly: + m_t << "<latexonly>"; + filter(s->text()); + m_t << "</latexonly>"; break; - case DocVerbatim::HtmlOnly: - case DocVerbatim::RtfOnly: - case DocVerbatim::ManOnly: - case DocVerbatim::LatexOnly: case DocVerbatim::DocbookOnly: - /* nothing */ + m_t << "<docbookonly>"; + filter(s->text()); + m_t << "</docbookonly>"; break; - case DocVerbatim::XmlOnly: + case DocVerbatim::XmlOnly: m_t << s->text(); break; case DocVerbatim::Dot: @@ -305,7 +328,7 @@ void XmlDocVisitor::visit(DocInclude *inc) switch(inc->type()) { case DocInclude::IncWithLines: - { + { m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); @@ -323,10 +346,10 @@ void XmlDocVisitor::visit(DocInclude *inc) TRUE // show line numbers ); delete fd; - m_t << "</programlisting>"; + m_t << "</programlisting>"; } - break; - case DocInclude::Include: + break; + case DocInclude::Include: m_t << "<programlisting filename=\"" << inc->file() << "\">"; Doxygen::parserManager->getCodeParser(inc->extension()) .parseCode(m_ci,inc->context(), @@ -341,12 +364,12 @@ void XmlDocVisitor::visit(DocInclude *inc) 0, // memberDef FALSE // show line numbers ); - m_t << "</programlisting>"; + m_t << "</programlisting>"; break; - case DocInclude::DontInclude: - case DocInclude::DontIncWithLines: + case DocInclude::DontInclude: + case DocInclude::DontIncWithLines: break; - case DocInclude::HtmlInclude: + case DocInclude::HtmlInclude: if (inc->isBlock()) { m_t << "<htmlonly block=\"yes\">"; @@ -363,10 +386,28 @@ void XmlDocVisitor::visit(DocInclude *inc) filter(inc->text()); m_t << "</latexonly>"; break; - case DocInclude::VerbInclude: + case DocInclude::RtfInclude: + m_t << "<rtfonly>"; + filter(inc->text()); + m_t << "</rtfonly>"; + break; + case DocInclude::ManInclude: + m_t << "<manonly>"; + filter(inc->text()); + m_t << "</manonly>"; + break; + case DocInclude::XmlInclude: + filter(inc->text()); + break; + case DocInclude::DocbookInclude: + m_t << "<docbookonly>"; + filter(inc->text()); + m_t << "</docbookonly>"; + break; + case DocInclude::VerbInclude: m_t << "<verbatim>"; filter(inc->text()); - m_t << "</verbatim>"; + m_t << "</verbatim>"; break; case DocInclude::Snippet: m_t << "<programlisting filename=\"" << inc->file() << "\">"; @@ -378,7 +419,7 @@ void XmlDocVisitor::visit(DocInclude *inc) inc->isExample(), inc->exampleFile() ); - m_t << "</programlisting>"; + m_t << "</programlisting>"; break; case DocInclude::SnipWithLines: { @@ -391,7 +432,7 @@ void XmlDocVisitor::visit(DocInclude *inc) extractBlock(inc->text(),inc->blockId()), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine @@ -400,11 +441,11 @@ void XmlDocVisitor::visit(DocInclude *inc) TRUE // show line number ); delete fd; - m_t << "</programlisting>"; + m_t << "</programlisting>"; } break; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" "Please create a bug report\n",__FILE__); break; @@ -415,7 +456,7 @@ void XmlDocVisitor::visit(DocIncOperator *op) { //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); - if (op->isFirst()) + if (op->isFirst()) { if (!m_hide) { @@ -427,10 +468,10 @@ void XmlDocVisitor::visit(DocIncOperator *op) QCString locLangExt = getFileNameExtension(op->includeFileName()); if (locLangExt.isEmpty()) locLangExt = m_langExt; SrcLangExt langExt = getLanguageFromFileName(locLangExt); - if (op->type()!=DocIncOperator::Skip) + if (op->type()!=DocIncOperator::Skip) { popEnabled(); - if (!m_hide) + if (!m_hide) { FileDef *fd = 0; if (!op->includeFileName().isEmpty()) @@ -455,10 +496,10 @@ void XmlDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide=TRUE; } - if (op->isLast()) + if (op->isLast()) { popEnabled(); - if (!m_hide) m_t << "</programlisting>"; + if (!m_hide) m_t << "</programlisting>"; } else { @@ -538,13 +579,13 @@ void XmlDocVisitor::visitPre(DocAutoListItem *) m_t << "<listitem>"; } -void XmlDocVisitor::visitPost(DocAutoListItem *) +void XmlDocVisitor::visitPost(DocAutoListItem *) { if (m_hide) return; m_t << "</listitem>"; } -void XmlDocVisitor::visitPre(DocPara *) +void XmlDocVisitor::visitPre(DocPara *) { if (m_hide) return; m_t << "<para>"; @@ -572,21 +613,21 @@ void XmlDocVisitor::visitPre(DocSimpleSect *s) m_t << "<simplesect kind=\""; switch(s->type()) { - case DocSimpleSect::See: + case DocSimpleSect::See: m_t << "see"; break; - case DocSimpleSect::Return: + case DocSimpleSect::Return: m_t << "return"; break; - case DocSimpleSect::Author: + case DocSimpleSect::Author: m_t << "author"; break; - case DocSimpleSect::Authors: + case DocSimpleSect::Authors: m_t << "authors"; break; - case DocSimpleSect::Version: + case DocSimpleSect::Version: m_t << "version"; break; - case DocSimpleSect::Since: + case DocSimpleSect::Since: m_t << "since"; break; - case DocSimpleSect::Date: + case DocSimpleSect::Date: m_t << "date"; break; - case DocSimpleSect::Note: + case DocSimpleSect::Note: m_t << "note"; break; case DocSimpleSect::Warning: m_t << "warning"; break; @@ -602,9 +643,9 @@ void XmlDocVisitor::visitPre(DocSimpleSect *s) m_t << "remark"; break; case DocSimpleSect::Attention: m_t << "attention"; break; - case DocSimpleSect::User: + case DocSimpleSect::User: m_t << "par"; break; - case DocSimpleSect::Rcs: + case DocSimpleSect::Rcs: m_t << "rcs"; break; case DocSimpleSect::Unknown: break; } @@ -647,7 +688,7 @@ void XmlDocVisitor::visitPre(DocSimpleListItem *) m_t << "<listitem>"; } -void XmlDocVisitor::visitPost(DocSimpleListItem *) +void XmlDocVisitor::visitPost(DocSimpleListItem *) { if (m_hide) return; m_t << "</listitem>\n"; @@ -664,7 +705,7 @@ void XmlDocVisitor::visitPre(DocSection *s) m_t << "</title>" << endl; } -void XmlDocVisitor::visitPost(DocSection *s) +void XmlDocVisitor::visitPost(DocSection *s) { m_t << "</sect" << s->level() << ">\n"; } @@ -672,18 +713,18 @@ void XmlDocVisitor::visitPost(DocSection *s) void XmlDocVisitor::visitPre(DocHtmlList *s) { if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) - m_t << "<orderedlist>\n"; - else + if (s->type()==DocHtmlList::Ordered) + m_t << "<orderedlist>\n"; + else m_t << "<itemizedlist>\n"; } -void XmlDocVisitor::visitPost(DocHtmlList *s) +void XmlDocVisitor::visitPost(DocHtmlList *s) { if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) - m_t << "</orderedlist>\n"; - else + if (s->type()==DocHtmlList::Ordered) + m_t << "</orderedlist>\n"; + else m_t << "</itemizedlist>\n"; } @@ -693,7 +734,7 @@ void XmlDocVisitor::visitPre(DocHtmlListItem *) m_t << "<listitem>\n"; } -void XmlDocVisitor::visitPost(DocHtmlListItem *) +void XmlDocVisitor::visitPost(DocHtmlListItem *) { if (m_hide) return; m_t << "</listitem>\n"; @@ -705,7 +746,7 @@ void XmlDocVisitor::visitPre(DocHtmlDescList *) m_t << "<variablelist>\n"; } -void XmlDocVisitor::visitPost(DocHtmlDescList *) +void XmlDocVisitor::visitPost(DocHtmlDescList *) { if (m_hide) return; m_t << "</variablelist>\n"; @@ -717,7 +758,7 @@ void XmlDocVisitor::visitPre(DocHtmlDescTitle *) m_t << "<varlistentry><term>"; } -void XmlDocVisitor::visitPost(DocHtmlDescTitle *) +void XmlDocVisitor::visitPost(DocHtmlDescTitle *) { if (m_hide) return; m_t << "</term></varlistentry>\n"; @@ -729,7 +770,7 @@ void XmlDocVisitor::visitPre(DocHtmlDescData *) m_t << "<listitem>"; } -void XmlDocVisitor::visitPost(DocHtmlDescData *) +void XmlDocVisitor::visitPost(DocHtmlDescData *) { if (m_hide) return; m_t << "</listitem>\n"; @@ -738,11 +779,11 @@ void XmlDocVisitor::visitPost(DocHtmlDescData *) void XmlDocVisitor::visitPre(DocHtmlTable *t) { if (m_hide) return; - m_t << "<table rows=\"" << t->numRows() + m_t << "<table rows=\"" << t->numRows() << "\" cols=\"" << t->numColumns() << "\">" ; } -void XmlDocVisitor::visitPost(DocHtmlTable *) +void XmlDocVisitor::visitPost(DocHtmlTable *) { if (m_hide) return; m_t << "</table>\n"; @@ -754,7 +795,7 @@ void XmlDocVisitor::visitPre(DocHtmlRow *) m_t << "<row>\n"; } -void XmlDocVisitor::visitPost(DocHtmlRow *) +void XmlDocVisitor::visitPost(DocHtmlRow *) { if (m_hide) return; m_t << "</row>\n"; @@ -763,13 +804,51 @@ void XmlDocVisitor::visitPost(DocHtmlRow *) void XmlDocVisitor::visitPre(DocHtmlCell *c) { if (m_hide) return; - if (c->isHeading()) m_t << "<entry thead=\"yes\">"; else m_t << "<entry thead=\"no\">"; + if (c->isHeading()) m_t << "<entry thead=\"yes\""; else m_t << "<entry thead=\"no\""; + HtmlAttribListIterator li(c->attribs()); + HtmlAttrib *opt; + for (li.toFirst();(opt=li.current());++li) + { + if (opt->name=="colspan" || opt->name=="rowspan") + { + m_t << " " << opt->name << "=\"" << opt->value.toInt() << "\""; + } + else if (opt->name=="align" && + (opt->value=="right" || opt->value=="left" || opt->value=="center")) + { + m_t << " align=\"" << opt->value << "\""; + } + else if (opt->name=="class") // handle markdown generated attributes + { + if (opt->value.left(13)=="markdownTable") // handle markdown generated attributes + { + if (opt->value.right(5)=="Right") + { + m_t << " align='right'"; + } + else if (opt->value.right(4)=="Left") + { + m_t << " align='left'"; + } + else if (opt->value.right(6)=="Center") + { + m_t << " align='center'"; + } + // skip 'markdownTable*' value ending with "None" + } + else if (!opt->value.isEmpty()) + { + m_t << " class=\"" << convertToXML(opt->value) << "\""; + } + } + } + m_t << ">"; } -void XmlDocVisitor::visitPost(DocHtmlCell *) +void XmlDocVisitor::visitPost(DocHtmlCell *) { if (m_hide) return; - m_t << "</entry>"; + m_t << "</entry>"; } void XmlDocVisitor::visitPre(DocHtmlCaption *) @@ -778,7 +857,7 @@ void XmlDocVisitor::visitPre(DocHtmlCaption *) m_t << "<caption>"; } -void XmlDocVisitor::visitPost(DocHtmlCaption *) +void XmlDocVisitor::visitPost(DocHtmlCaption *) { if (m_hide) return; m_t << "</caption>\n"; @@ -790,7 +869,7 @@ void XmlDocVisitor::visitPre(DocInternal *) m_t << "<internal>"; } -void XmlDocVisitor::visitPost(DocInternal *) +void XmlDocVisitor::visitPost(DocInternal *) { if (m_hide) return; m_t << "</internal>" << endl; @@ -802,7 +881,7 @@ void XmlDocVisitor::visitPre(DocHRef *href) m_t << "<ulink url=\"" << convertToXML(href->url(), TRUE) << "\">"; } -void XmlDocVisitor::visitPost(DocHRef *) +void XmlDocVisitor::visitPost(DocHRef *) { if (m_hide) return; m_t << "</ulink>"; @@ -814,7 +893,7 @@ void XmlDocVisitor::visitPre(DocHtmlHeader *header) m_t << "<heading level=\"" << header->level() << "\">"; } -void XmlDocVisitor::visitPost(DocHtmlHeader *) +void XmlDocVisitor::visitPost(DocHtmlHeader *) { if (m_hide) return; m_t << "</heading>\n"; @@ -824,18 +903,22 @@ void XmlDocVisitor::visitPre(DocImage *img) { if (m_hide) return; - QCString baseName=img->name(); - int i; - if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) + QCString url = img->url(); + QCString baseName; + if (url.isEmpty()) { - baseName=baseName.right(baseName.length()-i-1); + baseName = img->relPath()+img->name(); + } + else + { + baseName = correctURL(url,img->relPath()); } visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height(), img ->isInlineImage()); // copy the image to the output dir FileDef *fd; bool ambig; - if ((fd=findFileDef(Doxygen::imageNameDict,img->name(),ambig))) + if (url.isEmpty() && (fd=findFileDef(Doxygen::imageNameLinkedMap,img->name(),ambig))) { QFile inImage(fd->absFilePath()); QFile outImage(Config_getString(XML_OUTPUT)+"/"+baseName.data()); @@ -853,7 +936,7 @@ void XmlDocVisitor::visitPre(DocImage *img) } } -void XmlDocVisitor::visitPost(DocImage *) +void XmlDocVisitor::visitPost(DocImage *) { if (m_hide) return; visitPostEnd(m_t, "image"); @@ -865,7 +948,7 @@ void XmlDocVisitor::visitPre(DocDotFile *df) visitPreStart(m_t, "dotfile", FALSE, this, df->children(), df->file(), FALSE, DocImage::Html, df->width(), df->height()); } -void XmlDocVisitor::visitPost(DocDotFile *) +void XmlDocVisitor::visitPost(DocDotFile *) { if (m_hide) return; visitPostEnd(m_t, "dotfile"); @@ -877,7 +960,7 @@ void XmlDocVisitor::visitPre(DocMscFile *df) visitPreStart(m_t, "mscfile", FALSE, this, df->children(), df->file(), FALSE, DocImage::Html, df->width(), df->height()); } -void XmlDocVisitor::visitPost(DocMscFile *) +void XmlDocVisitor::visitPost(DocMscFile *) { if (m_hide) return; visitPostEnd(m_t, "mscfile"); @@ -901,7 +984,7 @@ void XmlDocVisitor::visitPre(DocLink *lnk) startLink(lnk->ref(),lnk->file(),lnk->anchor()); } -void XmlDocVisitor::visitPost(DocLink *) +void XmlDocVisitor::visitPost(DocLink *) { if (m_hide) return; endLink(); @@ -910,14 +993,14 @@ void XmlDocVisitor::visitPost(DocLink *) void XmlDocVisitor::visitPre(DocRef *ref) { if (m_hide) return; - if (!ref->file().isEmpty()) + if (!ref->file().isEmpty()) { startLink(ref->ref(),ref->file(),ref->isSubPage() ? QCString() : ref->anchor()); } if (!ref->hasLinkText()) filter(ref->targetTitle()); } -void XmlDocVisitor::visitPost(DocRef *ref) +void XmlDocVisitor::visitPost(DocRef *ref) { if (m_hide) return; if (!ref->file().isEmpty()) endLink(); @@ -930,7 +1013,7 @@ void XmlDocVisitor::visitPre(DocSecRefItem *ref) m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">"; } -void XmlDocVisitor::visitPost(DocSecRefItem *) +void XmlDocVisitor::visitPost(DocSecRefItem *) { if (m_hide) return; m_t << "</tocitem>" << endl; @@ -942,7 +1025,7 @@ void XmlDocVisitor::visitPre(DocSecRefList *) m_t << "<toclist>" << endl; } -void XmlDocVisitor::visitPost(DocSecRefList *) +void XmlDocVisitor::visitPost(DocSecRefList *) { if (m_hide) return; m_t << "</toclist>" << endl; @@ -954,7 +1037,7 @@ void XmlDocVisitor::visitPost(DocSecRefList *) // m_t << "<language langid=\"" << l->id() << "\">"; //} // -//void XmlDocVisitor::visitPost(DocLanguage *) +//void XmlDocVisitor::visitPost(DocLanguage *) //{ // if (m_hide) return; // m_t << "</language>" << endl; @@ -966,13 +1049,13 @@ void XmlDocVisitor::visitPre(DocParamSect *s) m_t << "<parameterlist kind=\""; switch(s->type()) { - case DocParamSect::Param: + case DocParamSect::Param: m_t << "param"; break; - case DocParamSect::RetVal: + case DocParamSect::RetVal: m_t << "retval"; break; - case DocParamSect::Exception: + case DocParamSect::Exception: m_t << "exception"; break; - case DocParamSect::TemplateParam: + case DocParamSect::TemplateParam: m_t << "templateparam"; break; default: ASSERT(0); @@ -999,18 +1082,18 @@ void XmlDocVisitor::visitPre(DocParamList *pl) { if (pl->paramTypes().count()>0) { - QListIterator<DocNode> li(pl->paramTypes()); + QListIterator<DocNode> li2(pl->paramTypes()); DocNode *type; m_t << "<parametertype>"; - for (li.toFirst();(type=li.current());++li) + for (li2.toFirst();(type=li2.current());++li2) { if (type->kind()==DocNode::Kind_Word) { - visit((DocWord*)type); + visit((DocWord*)type); } else if (type->kind()==DocNode::Kind_LinkedWord) { - visit((DocLinkedWord*)type); + visit((DocLinkedWord*)type); } else if (type->kind()==DocNode::Kind_Sep) { @@ -1041,11 +1124,11 @@ void XmlDocVisitor::visitPre(DocParamList *pl) m_t << ">"; if (param->kind()==DocNode::Kind_Word) { - visit((DocWord*)param); + visit((DocWord*)param); } else if (param->kind()==DocNode::Kind_LinkedWord) { - visit((DocLinkedWord*)param); + visit((DocLinkedWord*)param); } m_t << "</parametername>" << endl; } @@ -1087,7 +1170,7 @@ void XmlDocVisitor::visitPre(DocInternalRef *ref) startLink(0,ref->file(),ref->anchor()); } -void XmlDocVisitor::visitPost(DocInternalRef *) +void XmlDocVisitor::visitPost(DocInternalRef *) { if (m_hide) return; endLink(); @@ -1136,7 +1219,7 @@ void XmlDocVisitor::visitPost(DocParBlock *) void XmlDocVisitor::filter(const char *str) -{ +{ m_t << convertToXML(str); } diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index bf5af84..42d4426 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -3,8 +3,8 @@ * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -154,7 +154,7 @@ static void writeXMLHeader(FTextStream &t) t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "; t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" "; - t << "version=\"" << getVersion() << "\">" << endl; + t << "version=\"" << getDoxygenVersion() << "\">" << endl; } static void writeCombineScript() @@ -195,7 +195,7 @@ void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId, t << "<ref refid=\"" << compoundId; if (anchorId) t << "_1" << anchorId; t << "\" kindref=\""; - if (anchorId) t << "member"; else t << "compound"; + if (anchorId) t << "member"; else t << "compound"; t << "\""; if (extRef) t << " external=\"" << extRef << "\""; if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\""; @@ -211,7 +211,7 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf TextGeneratorXMLImpl(FTextStream &t): m_t(t) {} void writeString(const char *s,bool /*keepSpaces*/) const { - writeXMLString(m_t,s); + writeXMLString(m_t,s); } void writeBreak(int) const {} void writeLink(const char *extRef,const char *file, @@ -412,7 +412,7 @@ static void writeXMLDocBlock(FTextStream &t, delete visitor; delete xmlCodeGen; delete root; - + } void writeXMLCodeBlock(FTextStream &t,FileDef *fd) @@ -448,7 +448,7 @@ static void writeMemberReference(FTextStream &t,const Definition *def,const Memb } t << " <" << tagName << " refid=\""; t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\""; - if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) + if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) { t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\""; t << " startline=\"" << rmd->getStartBodyLine() << "\""; @@ -458,7 +458,7 @@ static void writeMemberReference(FTextStream &t,const Definition *def,const Memb } } t << ">" << convertToXML(name) << "</" << tagName << ">" << endl; - + } static void stripQualifiers(QCString &typeStr) @@ -477,18 +477,18 @@ static void stripQualifiers(QCString &typeStr) static QCString classOutputFileBase(const ClassDef *cd) { //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - //if (inlineGroupedClasses && cd->partOfGroups()!=0) + //if (inlineGroupedClasses && cd->partOfGroups()!=0) return cd->getOutputFileBase(); - //else + //else // return cd->getOutputFileBase(); } static QCString memberOutputFileBase(const MemberDef *md) { //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0) + //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0) // return md->getClassDef()->getXmlOutputFileBase(); - //else + //else // return md->getOutputFileBase(); return md->getOutputFileBase(); } @@ -506,11 +506,11 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream // + source definition // + source references // + source referenced by - // - body code - // + template arguments + // - body code + // + template arguments // (templateArguments(), definitionTemplateParameterLists()) // - call graph - + // enum values are written as part of the enum if (md->memberType()==MemberType_EnumValue) return; if (md->isHidden()) return; @@ -540,16 +540,16 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream case MemberType_Dictionary: memType="dictionary"; break; } - ti << " <member refid=\"" << memberOutputFileBase(md) - << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>" + ti << " <member refid=\"" << memberOutputFileBase(md) + << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>" << convertToXML(md->name()) << "</name></member>" << endl; - + QCString scopeName; - if (md->getClassDef()) + if (md->getClassDef()) scopeName=md->getClassDef()->name(); - else if (md->getNamespaceDef()) + else if (md->getNamespaceDef()) scopeName=md->getNamespaceDef()->name(); - + t << " <memberdef kind=\""; //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t; t << memType << "\" id=\""; @@ -586,7 +586,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream { const ArgumentList &al = md->argumentList(); t << " const=\""; - if (al.constSpecifier) t << "yes"; else t << "no"; + if (al.constSpecifier) t << "yes"; else t << "no"; t << "\""; t << " explicit=\""; @@ -661,12 +661,12 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream { //ArgumentList *al = md->argumentList(); //t << " volatile=\""; - //if (al && al->volatileSpecifier) t << "yes"; else t << "no"; + //if (al && al->volatileSpecifier) t << "yes"; else t << "no"; t << " mutable=\""; if (md->isMutable()) t << "yes"; else t << "no"; t << "\""; - + if (md->isInitonly()) { t << " initonly=\"yes\""; @@ -796,7 +796,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream } t << " <name>" << convertToXML(md->name()) << "</name>" << endl; - + if (md->memberType() == MemberType_Property) { if (md->isReadable()) @@ -811,11 +811,11 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream if (bitfield.at(0)==':') bitfield=bitfield.mid(1); t << " <bitfield>" << convertToXML(bitfield) << "</bitfield>" << endl; } - + const MemberDef *rmd = md->reimplements(); if (rmd) { - t << " <reimplements refid=\"" + t << " <reimplements refid=\"" << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">" << convertToXML(rmd->name()) << "</reimplements>" << endl; } @@ -825,7 +825,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream MemberListIterator mli(*rbml); for (mli.toFirst();(rmd=mli.current());++mli) { - t << " <reimplementedby refid=\"" + t << " <reimplementedby refid=\"" << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">" << convertToXML(rmd->name()) << "</reimplementedby>" << endl; } @@ -863,7 +863,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream if (!a.name.isEmpty()) { t << " <declname>"; - writeXMLString(t,a.name); + writeXMLString(t,a.name); t << "</declname>" << endl; } if (defArg && !defArg->name.isEmpty() && defArg->name!=a.name) @@ -874,8 +874,8 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream } if (!a.array.isEmpty()) { - t << " <array>"; - writeXMLString(t,a.array); + t << " <array>"; + writeXMLString(t,a.array); t << "</array>" << endl; } if (!a.defval.isEmpty()) @@ -895,7 +895,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream } } } - else if (md->memberType()==MemberType_Define && + else if (md->memberType()==MemberType_Define && md->argsString()) // define { if (md->argumentList().empty()) // special case for "foo()" to @@ -925,7 +925,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString()); t << "</exceptions>" << endl; } - + if (md->memberType()==MemberType_Enumeration) // enum { const MemberList *enumFields = md->enumFieldList(); @@ -979,9 +979,9 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream t << " </inbodydescription>" << endl; if (md->getDefLine()!=-1) { - t << " <location file=\"" + t << " <location file=\"" << convertToXML(stripFromPath(md->getDefFileName())) << "\" line=\"" - << md->getDefLine() << "\" column=\"" + << md->getDefLine() << "\" column=\"" << md->getDefColumn() << "\"" ; if (md->getStartBodyLine()!=-1) { @@ -990,7 +990,7 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream { t << " bodyfile=\"" << convertToXML(stripFromPath(bodyDef->absFilePath())) << "\""; } - t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\"" + t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\"" << md->getEndBodyLine() << "\""; } if (md->getDeclLine()!=-1) @@ -1007,7 +1007,6 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream if (mdict) { MemberSDict::Iterator mdi(*mdict); - const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { writeMemberReference(t,def,rmd,"references"); @@ -1017,13 +1016,12 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream if (mdict) { MemberSDict::Iterator mdi(*mdict); - const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { writeMemberReference(t,def,rmd,"referencedby"); } } - + t << " </memberdef>" << endl; } @@ -1114,7 +1112,7 @@ static void writeListOfAllMembers(const ClassDef *cd,FTextStream &t) { t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\""; } - t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" << + t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" << convertToXML(md->name()) << "</name></member>" << endl; } } @@ -1173,7 +1171,7 @@ static void writeInnerFiles(const FileList *fl,FTextStream &t) FileDef *fd; for (fli.toFirst();(fd=fli.current());++fli) { - t << " <innerfile refid=\"" << fd->getOutputFileBase() + t << " <innerfile refid=\"" << fd->getOutputFileBase() << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl; } } @@ -1206,7 +1204,7 @@ static void writeInnerGroups(const GroupList *gl,FTextStream &t) for (gli.toFirst();(sgd=gli.current());++gli) { t << " <innergroup refid=\"" << sgd->getOutputFileBase() - << "\">" << convertToXML(sgd->groupTitle()) + << "\">" << convertToXML(sgd->groupTitle()) << "</innergroup>" << endl; } } @@ -1220,12 +1218,12 @@ static void writeInnerDirs(const DirList *dl,FTextStream &t) DirDef *subdir; for (subdirs.toFirst();(subdir=subdirs.current());++subdirs) { - t << " <innerdir refid=\"" << subdir->getOutputFileBase() + t << " <innerdir refid=\"" << subdir->getOutputFileBase() << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl; } } } - + static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) { // + brief description @@ -1252,10 +1250,10 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) msg("Generating XML output for class %s\n",cd->name().data()); - ti << " <compound refid=\"" << classOutputFileBase(cd) + ti << " <compound refid=\"" << classOutputFileBase(cd) << "\" kind=\"" << cd->compoundTypeString() << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl; - + QCString outputDirectory = Config_getString(XML_OUTPUT); QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml"; QFile f(fileName); @@ -1268,8 +1266,8 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) //t.setEncoding(FTextStream::UnicodeUTF8); writeXMLHeader(t); - t << " <compounddef id=\"" - << classOutputFileBase(cd) << "\" kind=\"" + t << " <compounddef id=\"" + << classOutputFileBase(cd) << "\" kind=\"" << cd->compoundTypeString() << "\" language=\"" << langToString(cd->getLanguage()) << "\" prot=\""; switch (cd->protection()) @@ -1283,8 +1281,8 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) if (cd->isSealed()) t << "\" sealed=\"yes"; if (cd->isAbstract()) t << "\" abstract=\"yes"; t << "\">" << endl; - t << " <compoundname>"; - writeXMLString(t,cd->name()); + t << " <compoundname>"; + writeXMLString(t,cd->name()); t << "</compoundname>" << endl; if (cd->baseClasses()) { @@ -1333,7 +1331,7 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) BaseClassDef *bcd; for (bcli.toFirst();(bcd=bcli.current());++bcli) { - t << " <derivedcompoundref refid=\"" + t << " <derivedcompoundref refid=\"" << classOutputFileBase(bcd->classDef) << "\" prot=\""; switch (bcd->prot) @@ -1350,7 +1348,7 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) case Virtual: t << "virtual"; break; case Pure: t << "pure-virtual"; break; } - t << "\">" << convertToXML(bcd->classDef->displayName()) + t << "\">" << convertToXML(bcd->classDef->displayName()) << "</derivedcompoundref>" << endl; } } @@ -1417,9 +1415,9 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) collaborationGraph.writeXML(t); t << " </collaborationgraph>" << endl; } - t << " <location file=\"" + t << " <location file=\"" << convertToXML(stripFromPath(cd->getDefFileName())) << "\" line=\"" - << cd->getDefLine() << "\"" << " column=\"" + << cd->getDefLine() << "\"" << " column=\"" << cd->getDefColumn() << "\"" ; if (cd->getStartBodyLine()!=-1) { @@ -1428,7 +1426,7 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) { t << " bodyfile=\"" << convertToXML(stripFromPath(bodyDef->absFilePath())) << "\""; } - t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" + t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" << cd->getEndBodyLine() << "\""; } t << "/>" << endl; @@ -1452,10 +1450,10 @@ static void generateXMLForNamespace(const NamespaceDef *nd,FTextStream &ti) if (nd->isReference() || nd->isHidden()) return; // skip external references - ti << " <compound refid=\"" << nd->getOutputFileBase() - << "\" kind=\"namespace\"" << "><name>" + ti << " <compound refid=\"" << nd->getOutputFileBase() + << "\" kind=\"namespace\"" << "><name>" << convertToXML(nd->name()) << "</name>" << endl; - + QCString outputDirectory = Config_getString(XML_OUTPUT); QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml"; QFile f(fileName); @@ -1466,10 +1464,10 @@ static void generateXMLForNamespace(const NamespaceDef *nd,FTextStream &ti) } FTextStream t(&f); //t.setEncoding(FTextStream::UnicodeUTF8); - + writeXMLHeader(t); - t << " <compounddef id=\"" << nd->getOutputFileBase() - << "\" kind=\"namespace\" language=\"" + t << " <compounddef id=\"" << nd->getOutputFileBase() + << "\" kind=\"namespace\" language=\"" << langToString(nd->getLanguage()) << "\">" << endl; t << " <compoundname>"; writeXMLString(t,nd->name()); @@ -1530,13 +1528,13 @@ static void generateXMLForFile(FileDef *fd,FTextStream &ti) // + source code // + location // - number of lines - + if (fd->isReference()) return; // skip external references - - ti << " <compound refid=\"" << fd->getOutputFileBase() - << "\" kind=\"file\"><name>" << convertToXML(fd->name()) + + ti << " <compound refid=\"" << fd->getOutputFileBase() + << "\" kind=\"file\"><name>" << convertToXML(fd->name()) << "</name>" << endl; - + QCString outputDirectory = Config_getString(XML_OUTPUT); QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml"; QFile f(fileName); @@ -1550,7 +1548,7 @@ static void generateXMLForFile(FileDef *fd,FTextStream &ti) writeXMLHeader(t); t << " <compounddef id=\"" << fd->getOutputFileBase() - << "\" kind=\"file\" language=\"" + << "\" kind=\"file\" language=\"" << langToString(fd->getLanguage()) << "\">" << endl; t << " <compoundname>"; writeXMLString(t,fd->name()); @@ -1671,9 +1669,9 @@ static void generateXMLForGroup(const GroupDef *gd,FTextStream &ti) if (gd->isReference()) return; // skip external references - ti << " <compound refid=\"" << gd->getOutputFileBase() + ti << " <compound refid=\"" << gd->getOutputFileBase() << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl; - + QCString outputDirectory = Config_getString(XML_OUTPUT); QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml"; QFile f(fileName); @@ -1686,7 +1684,7 @@ static void generateXMLForGroup(const GroupDef *gd,FTextStream &ti) FTextStream t(&f); //t.setEncoding(FTextStream::UnicodeUTF8); writeXMLHeader(t); - t << " <compounddef id=\"" + t << " <compounddef id=\"" << gd->getOutputFileBase() << "\" kind=\"group\">" << endl; t << " <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl; t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl; @@ -1733,8 +1731,8 @@ static void generateXMLForGroup(const GroupDef *gd,FTextStream &ti) static void generateXMLForDir(DirDef *dd,FTextStream &ti) { if (dd->isReference()) return; // skip external references - ti << " <compound refid=\"" << dd->getOutputFileBase() - << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName()) + ti << " <compound refid=\"" << dd->getOutputFileBase() + << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName()) << "</name>" << endl; QCString outputDirectory = Config_getString(XML_OUTPUT); @@ -1749,7 +1747,7 @@ static void generateXMLForDir(DirDef *dd,FTextStream &ti) FTextStream t(&f); //t.setEncoding(FTextStream::UnicodeUTF8); writeXMLHeader(t); - t << " <compounddef id=\"" + t << " <compounddef id=\"" << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl; t << " <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl; @@ -1778,18 +1776,18 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) const char *kindName = isExample ? "example" : "page"; if (pd->isReference()) return; - + QCString pageName = pd->getOutputFileBase(); if (pd->getGroupDef()) { pageName+=(QCString)"_"+pd->name(); } if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page. - + ti << " <compound refid=\"" << pageName - << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name()) + << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name()) << "</name>" << endl; - + QCString outputDirectory = Config_getString(XML_OUTPUT); QCString fileName=outputDirectory+"/"+pageName+".xml"; QFile f(fileName); @@ -1804,7 +1802,7 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) writeXMLHeader(t); t << " <compounddef id=\"" << pageName; t << "\" kind=\"" << kindName << "\">" << endl; - t << " <compoundname>" << convertToXML(pd->name()) + t << " <compoundname>" << convertToXML(pd->name()) << "</compoundname>" << endl; if (pd==Doxygen::mainPage) // main page is special @@ -1818,37 +1816,32 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) { title = Config_getString(PROJECT_NAME); } - t << " <title>" << convertToXML(convertCharEntitiesToUTF8(title)) + t << " <title>" << convertToXML(convertCharEntitiesToUTF8(title)) << "</title>" << endl; } else { - SectionInfo *si = Doxygen::sectionDict->find(pd->name()); + const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) { - t << " <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title))) + t << " <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title()))) << "</title>" << endl; } } writeInnerPages(pd->getSubPages(),t); - SectionDict *sectionDict = pd->getSectionDict(); - if (pd->localToc().isXmlEnabled() && sectionDict) + const SectionRefs §ionRefs = pd->getSectionRefs(); + if (pd->localToc().isXmlEnabled() && !sectionRefs.empty()) { t << " <tableofcontents>" << endl; - SDict<SectionInfo>::Iterator li(*sectionDict); - SectionInfo *si; int level=1,l; bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; int maxLevel = pd->localToc().xmlLevel(); - for (li.toFirst();(si=li.current());++li) + for (const SectionInfo *si : sectionRefs) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + if (isSection(si->type())) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)si->type(); if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1868,10 +1861,10 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) if (nextLevel <= maxLevel) { if (inLi[nextLevel]) t << " </tocsect>" << endl; - QCString titleDoc = convertToXML(si->title); + QCString titleDoc = convertToXML(si->title()); t << " <tocsect>" << endl; - t << " <name>" << (si->title.isEmpty()?si->label:titleDoc) << "</name>" << endl; - t << " <reference>" << convertToXML(pageName) << "_1" << convertToXML(si -> label) << "</reference>" << endl; + t << " <name>" << (si->title().isEmpty()?si->label():titleDoc) << "</name>" << endl; + t << " <reference>" << convertToXML(pageName) << "_1" << convertToXML(si->label()) << "</reference>" << endl; inLi[nextLevel]=TRUE; level = nextLevel; } @@ -1918,7 +1911,7 @@ void generateXML() // + groups // + related pages // - examples - + QCString outputDirectory = Config_getString(XML_OUTPUT); QDir xmlDir(outputDirectory); createSubDirs(xmlDir); @@ -1975,7 +1968,7 @@ void generateXML() t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "; t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" "; - t << "version=\"" << getVersion() << "\">" << endl; + t << "version=\"" << getDoxygenVersion() << "\">" << endl; { ClassSDict::Iterator cli(*Doxygen::classSDict); @@ -2001,16 +1994,12 @@ void generateXML() msg("Generating XML output for namespace %s\n",nd->name().data()); generateXMLForNamespace(nd,t); } - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - for (;(fn=fnli.current());++fnli) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) + for (const auto &fd : *fn) { msg("Generating XML output for file %s\n",fd->name().data()); - generateXMLForFile(fd,t); + generateXMLForFile(fd.get(),t); } } GroupSDict::Iterator gli(*Doxygen::groupSDict); |