diff options
-rw-r--r-- | src/context.cpp | 5 | ||||
-rw-r--r-- | src/debug.cpp | 10 | ||||
-rw-r--r-- | src/debug.h | 2 | ||||
-rw-r--r-- | src/define.h | 7 | ||||
-rw-r--r-- | src/doxygen.cpp | 100 | ||||
-rw-r--r-- | src/doxygen.h | 5 | ||||
-rw-r--r-- | src/filedef.cpp | 147 | ||||
-rw-r--r-- | src/filedef.h | 5 | ||||
-rw-r--r-- | src/htmlgen.cpp | 18 | ||||
-rw-r--r-- | src/message.cpp | 2 | ||||
-rw-r--r-- | src/pre.l | 647 | ||||
-rw-r--r-- | src/scanner.l | 15 | ||||
-rw-r--r-- | src/sqlite3gen.cpp | 2 | ||||
-rw-r--r-- | src/tagreader.cpp | 2 | ||||
-rw-r--r-- | src/vhdldocgen.cpp | 6 | ||||
-rw-r--r-- | templates/html/close.svg | 31 | ||||
-rw-r--r-- | templates/html/htmlbase.tpl | 6 | ||||
-rw-r--r-- | templates/html/htmllayout.tpl | 6 | ||||
-rw-r--r-- | templates/html/htmltabs.tpl | 6 | ||||
-rw-r--r-- | templates/html/mag.svg | 37 | ||||
-rw-r--r-- | templates/html/mag_sel.svg | 74 | ||||
-rw-r--r-- | templates/html/menu.js | 4 | ||||
-rw-r--r-- | templates/html/search.css | 100 | ||||
-rw-r--r-- | templates/html/search.js | 2 | ||||
-rw-r--r-- | templates/html/search_functions.php | 8 |
25 files changed, 643 insertions, 604 deletions
diff --git a/src/context.cpp b/src/context.cpp index f0b697a..83e8e7a 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -1774,10 +1774,7 @@ class IncludeInfoListContext::Private : public GenericNodeListContext IncludeInfo *ii; for (li.toFirst();(ii=li.current());++li) { - if (!ii->indirect) - { - append(IncludeInfoContext::alloc(ii,lang)); - } + append(IncludeInfoContext::alloc(ii,lang)); } } }; diff --git a/src/debug.cpp b/src/debug.cpp index ca3c1e9..6815b3b 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -114,11 +114,11 @@ class Timer { m_startTime = std::chrono::system_clock::now(); } - int elapsedTimeMs() + double elapsedTimeS() { - return std::chrono::duration_cast< + return (std::chrono::duration_cast< std::chrono::milliseconds>( - std::chrono::system_clock::now() - m_startTime).count(); + std::chrono::system_clock::now() - m_startTime).count()) / 1000.0; } private: std::chrono::time_point<std::chrono::system_clock> m_startTime; @@ -131,8 +131,8 @@ void Debug::startTimer() g_runningTime.start(); } -int Debug::elapsedTime() +double Debug::elapsedTime() { - return g_runningTime.elapsedTimeMs(); + return g_runningTime.elapsedTimeS(); } diff --git a/src/debug.h b/src/debug.h index 0c046f4..edc95e2 100644 --- a/src/debug.h +++ b/src/debug.h @@ -47,7 +47,7 @@ class Debug static void setPriority(int p); static void startTimer(); - static int elapsedTime(); + static double elapsedTime(); private: static DebugMask curMask; diff --git a/src/define.h b/src/define.h index 0a3d62c..015d399 100644 --- a/src/define.h +++ b/src/define.h @@ -16,11 +16,13 @@ #ifndef DEFINE_H #define DEFINE_H -#include <map> -#include <string> +#include <vector> #include <memory> +#include <string> +#include <unordered_map> #include <qcstring.h> +#include "containers.h" class FileDef; @@ -44,5 +46,6 @@ class Define /** List of all macro definitions */ using DefineList = std::vector< std::unique_ptr<Define> >; +using DefinesPerFileList = std::unordered_map< std::string, DefineList >; #endif diff --git a/src/doxygen.cpp b/src/doxygen.cpp index d8436bb..5ac1980 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -159,7 +159,8 @@ bool Doxygen::userComments = FALSE; QCString Doxygen::spaces; bool Doxygen::generatingXmlOutput = FALSE; GenericsSDict *Doxygen::genericsDict; -DefineList Doxygen::macroDefinitions; +DefinesPerFileList Doxygen::macroDefinitions; +bool Doxygen::clangAssistedParsing = FALSE; // locally accessible globals static std::unordered_map< std::string, const Entry* > g_classEntries; @@ -7477,18 +7478,18 @@ static void generateFileSources() if (!Doxygen::inputNameLinkedMap->empty()) { #if USE_LIBCLANG - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); - if (clangAssistedParsing) + if (Doxygen::clangAssistedParsing) { - QDict<void> g_processedFiles(10007); + StringUnorderedSet processedFiles; // create a dictionary with files to process - QDict<void> g_filesToProcess(10007); + StringUnorderedSet filesToProcess; + for (const auto &fn : *Doxygen::inputNameLinkedMap) { for (const auto &fd : *fn) { - g_filesToProcess.insert(fd->absFilePath(),(void*)0x8); + filesToProcess.insert(fd->absFilePath().str()); } } // process source files (and their include dependencies) @@ -7515,9 +7516,9 @@ static void generateFileSources() } char *incFile = filesInSameTu.first(); - while (incFile && g_filesToProcess.find(incFile)) + while (incFile && filesToProcess.find(incFile)!=filesToProcess.end()) { - if (fd->absFilePath()!=incFile && !g_processedFiles.find(incFile)) + if (fd->absFilePath()!=incFile && processedFiles.find(incFile)==processedFiles.end()) { QStrList moreFiles; bool ambig; @@ -7536,13 +7537,13 @@ static void generateFileSources() msg(" Parsing code for file %s...\n",ifd->docName().data()); ifd->parseSource(TRUE,moreFiles); } - g_processedFiles.insert(incFile,(void*)0x8); + processedFiles.insert(incFile); } } incFile = filesInSameTu.next(); } fd->finishParsing(); - g_processedFiles.insert(fd->absFilePath(),(void*)0x8); + processedFiles.insert(fd->absFilePath().str()); } } } @@ -7551,7 +7552,7 @@ static void generateFileSources() { for (const auto &fd : *fn) { - if (!g_processedFiles.find(fd->absFilePath())) // not yet processed + if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed { QStrList filesInSameTu; fd->startParsing(); @@ -7701,28 +7702,35 @@ static void addSourceReferences() // add the macro definitions found during preprocessing as file members static void buildDefineList() { - for (const auto &def : Doxygen::macroDefinitions) + for (const auto &s : g_inputFiles) { - std::unique_ptr<MemberDef> md { createMemberDef( - def->fileName,def->lineNr,def->columnNr, - "#define",def->name,def->args,0, - Public,Normal,FALSE,Member,MemberType_Define, - ArgumentList(),ArgumentList(),"") }; - - if (!def->args.isEmpty()) + auto it = Doxygen::macroDefinitions.find(s); + if (it!=Doxygen::macroDefinitions.end()) { - md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, def->args)); - } - md->setInitializer(def->definition); - md->setFileDef(def->fileDef); - md->setDefinition("#define "+def->name); + for (const auto &def : it->second) + { + std::unique_ptr<MemberDef> md { createMemberDef( + def->fileName,def->lineNr,def->columnNr, + "#define",def->name,def->args,0, + Public,Normal,FALSE,Member,MemberType_Define, + ArgumentList(),ArgumentList(),"") }; - MemberName *mn=Doxygen::functionNameLinkedMap->add(def->name); - if (def->fileDef) - { - def->fileDef->insertMember(md.get()); + if (!def->args.isEmpty()) + { + md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, def->args)); + } + md->setInitializer(def->definition); + md->setFileDef(def->fileDef); + md->setDefinition("#define "+def->name); + + MemberName *mn=Doxygen::functionNameLinkedMap->add(def->name); + if (def->fileDef) + { + def->fileDef->insertMember(md.get()); + } + mn->push_back(std::move(md)); + } } - mn->push_back(std::move(md)); } } @@ -9056,11 +9064,6 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser, FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { -#if USE_LIBCLANG - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); -#else - static bool clangAssistedParsing = FALSE; -#endif QCString fileName=fn; QCString extension; int ei = fileName.findRev('.'); @@ -9107,7 +9110,7 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser, convBuf.addChar('\0'); - if (clangAssistedParsing && !sameTu) + if (Doxygen::clangAssistedParsing && !sameTu) { fd->getAllIncludeFilesRecursively(filesInSameTu); } @@ -9123,16 +9126,15 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser, static void parseFiles(const std::shared_ptr<Entry> &root) { #if USE_LIBCLANG - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); - if (clangAssistedParsing) + if (Doxygen::clangAssistedParsing) { - QDict<void> g_processedFiles(10007); + StringUnorderedSet processedFiles; // create a dictionary with files to process - QDict<void> g_filesToProcess(10007); + StringUnorderedSet filesToProcess; for (const auto &s : g_inputFiles) { - g_filesToProcess.insert(s.c_str(),(void*)0x8); + filesToProcess.insert(s); } // process source files (and their include dependencies) @@ -9153,9 +9155,9 @@ static void parseFiles(const std::shared_ptr<Entry> &root) // Now process any include files in the same translation unit // first. When libclang is used this is much more efficient. char *incFile = filesInSameTu.first(); - while (incFile && g_filesToProcess.find(incFile)) + while (incFile && filesToProcess.find(incFile)!=filesToProcess.end()) { - if (qstrcmp(incFile,s.c_str()) && !g_processedFiles.find(incFile)) + if (qstrcmp(incFile,s.c_str()) && processedFiles.find(incFile)==processedFiles.end()) { FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile,ambig); if (ifd && !ifd->isReference()) @@ -9164,19 +9166,19 @@ static void parseFiles(const std::shared_ptr<Entry> &root) //printf(" Processing %s in same translation unit as %s\n",incFile,s->c_str()); fileRoot = parseFile(*parser.get(),ifd,incFile,TRUE,moreFiles); root->moveToSubEntryAndKeep(fileRoot); - g_processedFiles.insert(incFile,(void*)0x8); + processedFiles.insert(incFile); } } incFile = filesInSameTu.next(); } parser->finishTranslationUnit(); - g_processedFiles.insert(s.c_str(),(void*)0x8); + processedFiles.insert(s); } } // process remaining files for (const auto &s : g_inputFiles) { - if (!g_processedFiles.find(s.c_str())) // not yet processed + if (processedFiles.find(s)==processedFiles.end()) // not yet processed { bool ambig; QStrList filesInSameTu; @@ -9187,7 +9189,7 @@ static void parseFiles(const std::shared_ptr<Entry> &root) std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),FALSE,filesInSameTu); root->moveToSubEntryAndKeep(fileRoot); parser->finishTranslationUnit(); - g_processedFiles.insert(s.c_str(),(void*)0x8); + processedFiles.insert(s); } } } @@ -10700,6 +10702,10 @@ void parseInput() { atexit(exitDoxygen); +#if USE_LIBCLANG + Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); +#endif + // 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(); @@ -11578,7 +11584,7 @@ void generateOutput() if (Debug::isFlagSet(Debug::Time)) { msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n", - ((double)Debug::elapsedTime())/1000.0, + ((double)Debug::elapsedTime()), Portable::getSysElapsedTime() ); g_s.print(); diff --git a/src/doxygen.h b/src/doxygen.h index 3198c82..e5757c3 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -30,7 +30,9 @@ #include "memberlist.h" #include "define.h" +#ifndef MULTITHREADED_INPUT #define MULTITHREADED_INPUT 0 +#endif #if MULTITHREADED_INPUT #define THREAD_LOCAL thread_local @@ -149,7 +151,8 @@ class Doxygen static QCString spaces; static bool generatingXmlOutput; static GenericsSDict *genericsDict; - static DefineList macroDefinitions; + static DefinesPerFileList macroDefinitions; + static bool clangAssistedParsing; }; void initDoxygen(); diff --git a/src/filedef.cpp b/src/filedef.cpp index 91a7835..08f022b 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -117,7 +117,7 @@ class FileDefImpl : public DefinitionImpl, public FileDef virtual void combineUsingRelations(); virtual bool generateSourceFile() const; virtual void sortMemberLists(); - virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect); + virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported); virtual void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported); virtual void addMembersToMemberGroup(); virtual void distributeMemberGroupDocumentation(); @@ -357,25 +357,22 @@ void FileDefImpl::writeTagFile(FTextStream &tagFile) IncludeInfo *ii; for (;(ii=ili.current());++ili) { - if (!ii->indirect) + FileDef *fd=ii->fileDef; + if (fd && fd->isLinkable() && !fd->isReference()) { - FileDef *fd=ii->fileDef; - 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=\"" - << convertToXML(fd->getOutputFileBase()) << "\" " - << "name=\"" << convertToXML(fd->name()) << "\" " - << "local=\"" << locStr << "\" " - << "imported=\"" << impStr << "\">" - << convertToXML(ii->includeName) - << "</includes>" - << endl; - } + 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=\"" + << convertToXML(fd->getOutputFileBase()) << "\" " + << "name=\"" << convertToXML(fd->name()) << "\" " + << "local=\"" << locStr << "\" " + << "imported=\"" << impStr << "\">" + << convertToXML(ii->includeName) + << "</includes>" + << endl; } } } @@ -600,61 +597,58 @@ void FileDefImpl::writeIncludeFiles(OutputList &ol) IncludeInfo *ii; for (;(ii=ili.current());++ili) { - if (!ii->indirect) + FileDef *fd=ii->fileDef; + bool isIDLorJava = FALSE; + if (fd) { - FileDef *fd=ii->fileDef; - bool isIDLorJava = FALSE; - if (fd) - { - SrcLangExt lang = fd->getLanguage(); - isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; - } - ol.startTypewriter(); - if (isIDLorJava) // IDL/Java include - { - ol.docify("import "); - } - else if (ii->imported) // Objective-C include - { - ol.docify("#import "); - } - else // C/C++ include - { - ol.docify("#include "); - } - if (ii->local || isIDLorJava) - ol.docify("\""); - else - ol.docify("<"); - ol.disable(OutputGenerator::Html); - 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 - if (fd && fd->isLinkable()) - { - ol.writeObjectLink(fd->getReference(), - fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(), - 0,ii->includeName); - } - else - { - ol.docify(ii->includeName); - } + SrcLangExt lang = fd->getLanguage(); + isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; + } + ol.startTypewriter(); + if (isIDLorJava) // IDL/Java include + { + ol.docify("import "); + } + else if (ii->imported) // Objective-C include + { + ol.docify("#import "); + } + else // C/C++ include + { + ol.docify("#include "); + } + if (ii->local || isIDLorJava) + ol.docify("\""); + else + ol.docify("<"); + ol.disable(OutputGenerator::Html); + ol.docify(ii->includeName); + ol.enableAll(); + ol.disableAllBut(OutputGenerator::Html); - ol.enableAll(); - if (ii->local || isIDLorJava) - ol.docify("\""); - else - ol.docify(">"); - if (isIDLorJava) - ol.docify(";"); - ol.endTypewriter(); - ol.lineBreak(); + // 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 + if (fd && fd->isLinkable()) + { + ol.writeObjectLink(fd->getReference(), + fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(), + 0,ii->includeName); + } + else + { + ol.docify(ii->includeName); } + + ol.enableAll(); + if (ii->local || isIDLorJava) + ol.docify("\""); + else + ol.docify(">"); + if (isIDLorJava) + ol.docify(";"); + ol.endTypewriter(); + ol.lineBreak(); } ol.endTextBlock(); } @@ -1218,8 +1212,7 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu (void)sameTu; (void)filesInSameTu; #if USE_LIBCLANG - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); - if (clangAssistedParsing && + if (Doxygen::clangAssistedParsing && (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC)) { ol.startCodeFragment(); @@ -1282,8 +1275,7 @@ void FileDefImpl::parseSource(bool sameTu,QStrList &filesInSameTu) (void)sameTu; (void)filesInSameTu; #if USE_LIBCLANG - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); - if (clangAssistedParsing && + if (Doxygen::clangAssistedParsing && (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC)) { if (!sameTu) @@ -1544,8 +1536,7 @@ void FileDefImpl::addUsingDeclaration(Definition *d) } } -void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool local, - bool imported,bool indirect) +void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported) { //printf("FileDefImpl::addIncludeDependency(%p,%s,%d)\n",fd,incName,local); QCString iName = fd ? fd->absFilePath().data() : incName; @@ -1562,7 +1553,6 @@ void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool loca ii->includeName = incName; ii->local = local; ii->imported = imported; - ii->indirect = indirect; m_includeList->append(ii); m_includeDict->insert(iName,ii); } @@ -1659,7 +1649,6 @@ void FileDefImpl::addIncludedByDependency(FileDef *fd,const char *incName, ii->includeName = incName; ii->local = local; ii->imported = imported; - ii->indirect = FALSE; m_includedByList->append(ii); m_includedByDict->insert(iName,ii); } diff --git a/src/filedef.h b/src/filedef.h index 2510d85..c03e7ef 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -44,13 +44,12 @@ class FTextStream; /** Class representing the data associated with a \#include statement. */ struct IncludeInfo { - IncludeInfo() : fileDef(0), local(FALSE), imported(FALSE), indirect(FALSE) {} + IncludeInfo() : fileDef(0), local(FALSE), imported(FALSE) {} ~IncludeInfo() {} FileDef *fileDef; QCString includeName; bool local; bool imported; - bool indirect; }; /** A model of a file symbol. @@ -170,7 +169,7 @@ class FileDef : virtual public Definition virtual bool generateSourceFile() const = 0; virtual void sortMemberLists() = 0; - virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect) = 0; + virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported) = 0; virtual void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported) = 0; virtual void addMembersToMemberGroup() = 0; diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 900ea48..d869a2b 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -67,7 +67,7 @@ static void writeClientSearchBox(FTextStream &t,const char *relPath) { t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n"; t << " <span class=\"left\">\n"; - t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n"; + t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.svg\"\n"; t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n"; t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n"; t << " alt=\"\"/>\n"; @@ -78,7 +78,7 @@ static void writeClientSearchBox(FTextStream &t,const char *relPath) t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n"; t << " </span><span class=\"right\">\n"; t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">" - << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n"; + << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.svg\" alt=\"\"/></a>\n"; t << " </span>\n"; t << " </div>\n"; } @@ -100,7 +100,7 @@ static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlig t << "search.php"; } t << "\" method=\"get\">\n"; - t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n"; + t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.svg\" alt=\"\"/>\n"; if (!highlightSearch) { t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"" @@ -1046,15 +1046,15 @@ void HtmlGenerator::writeSearchData(const char *dir) Doxygen::indexList->addImageFile("search/search_r.png"); if (serverBasedSearch) { - mgr.copyResource("mag.png",dir); - Doxygen::indexList->addImageFile("search/mag.png"); + mgr.copyResource("mag.svg",dir); + Doxygen::indexList->addImageFile("search/mag.svg"); } else { - mgr.copyResource("close.png",dir); - Doxygen::indexList->addImageFile("search/close.png"); - mgr.copyResource("mag_sel.png",dir); - Doxygen::indexList->addImageFile("search/mag_sel.png"); + mgr.copyResource("close.svg",dir); + Doxygen::indexList->addImageFile("search/close.svg"); + mgr.copyResource("mag_sel.svg",dir); + Doxygen::indexList->addImageFile("search/mag_sel.svg"); } QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search"; diff --git a/src/message.cpp b/src/message.cpp index bbf578b..96c54a1 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -117,7 +117,7 @@ void msg(const char *fmt, ...) #endif if (Debug::isFlagSet(Debug::Time)) { - printf("%.3f sec: ",((double)Debug::elapsedTime())/1000.0); + printf("%.3f sec: ",((double)Debug::elapsedTime())); } va_list args; va_start(args, fmt); @@ -26,11 +26,16 @@ * includes */ +#include "doxygen.h" + #include <stack> #include <deque> #include <algorithm> #include <utility> +#if MULTITHREADED_INPUT #include <mutex> +#include <thread> +#endif #include <stdio.h> #include <assert.h> @@ -45,7 +50,6 @@ #include "pre.h" #include "constexp.h" #include "define.h" -#include "doxygen.h" #include "message.h" #include "util.h" #include "defargs.h" @@ -92,280 +96,138 @@ struct FileState QCString fileName; }; -/** A dictionary of references to Define objects. */ -typedef std::map< std::string,Define* > DefineMapRef; +struct PreIncludeInfo +{ + PreIncludeInfo(const char *fn,FileDef *srcFd, FileDef *dstFd,const char *iName,bool loc, bool imp) + : fileName(fn), fromFileDef(srcFd), toFileDef(dstFd), includeName(iName), local(loc), imported(imp) + { + } + QCString fileName; // file name in which the include statement was found + FileDef *fromFileDef; // filedef in which the include statement was found + FileDef *toFileDef; // filedef to which the include is pointing + QCString includeName; // name used in the #include statement + bool local; // is it a "local" or <global> include + bool imported; // include via "import" keyword (Objective-C) +}; /** A dictionary of managed Define objects. */ typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning; -/** @brief Singleton that manages the defines available while +/** @brief Class that manages the defines available while * preprocessing files. */ class DefineManager { - /** Local class used to hold the defines for a single file */ - class DefinesPerFile - { - public: - /** Creates an empty container for defines */ - DefinesPerFile(DefineManager *parent) - : m_parent(parent) - { - } - /** Destroys the object */ - virtual ~DefinesPerFile() - { - } - /** 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. Ownership will be transferred. - */ - void addDefine(std::unique_ptr<Define> &&def) - { - auto it = m_defines.find(def->name.data()); - if (it!=m_defines.end()) // redefine - { - m_defines.erase(it); - } - 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 collectDefines(DefineMapRef &map,StringSet &includeStack); - private: - DefineManager *m_parent; - DefineMapOwning m_defines; - StringSet m_includedFiles; - }; - - public: - friend class DefinesPerFile; - - /** Creates a new DefineManager object */ - DefineManager() + private: + /** Local class used to hold the defines for a single file */ + class DefinesPerFile { - } + public: + /** Creates an empty container for defines */ + DefinesPerFile(DefineManager *parent) + : m_parent(parent) + { + } + void addInclude(std::string fileName) + { + m_includedFiles.insert(fileName); + } + void store(const DefineMapOwning &fromMap) + { + for (auto &kv : fromMap) + { + m_defines.emplace(kv.first,std::make_unique<Define>(*kv.second.get())); + } + } + void retrieve(DefineMapOwning &toMap) + { + StringSet includeStack; + retrieveRec(toMap,includeStack); + } + void retrieveRec(DefineMapOwning &toMap,StringSet &includeStack) + { + for (auto incFile : m_includedFiles) + { + DefinesPerFile *dpf = m_parent->find(incFile); + if (dpf && includeStack.find(incFile)==includeStack.end()) + { + //printf(" processing include %s\n",incFile.data()); + includeStack.insert(incFile); + dpf->retrieveRec(toMap,includeStack); + } + } + for (auto &kv : m_defines) + { + toMap.emplace(kv.first,std::make_unique<Define>(*kv.second.get())); + } + } + private: + DefineManager *m_parent; + DefineMapOwning m_defines; + StringSet m_includedFiles; + }; - /** Destroys the object */ - virtual ~DefineManager() - { - } + friend class DefinesPerFile; + public: - /** Starts a context in which defines are collected. - * Called at the start of a new file that is preprocessed. - * @param fileName the name of the file to process. - */ - void startContext(const char *fileName) - { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(m_mutex); -#endif - //printf("DefineManager::startContext()\n"); - m_contextDefines.clear(); - if (fileName==0) return; - //DefinesPerFile *dpf = m_fileMap.find(fileName); - auto it = m_fileMap.find(fileName); - if (it==m_fileMap.end()) - { - //printf("New file!\n"); - m_fileMap.emplace(toStdString(fileName),std::make_unique<DefinesPerFile>(this)); - } - } - /** Ends the context started with startContext() freeing any - * defines collected within in this context. - */ - void endContext() + void addInclude(std::string fromFileName,std::string toFileName) { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(m_mutex); -#endif - //printf("DefineManager::endContext()\n"); - m_contextDefines.clear(); - } - /** Add an included file to the current context. - * If the file has been pre-processed already, all defines are added - * to the context. - * @param fileName The name of the include file to add to the context. - */ - void addFileToContext(const char *fileName) - { - if (fileName==0) return; -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(m_mutex); -#endif - - //printf("DefineManager::addFileToContext(%s)\n",fileName); - auto it = m_fileMap.find(fileName); - if (it==m_fileMap.end()) - { - //printf("New file!\n"); - m_fileMap.emplace(toStdString(fileName),std::make_unique<DefinesPerFile>(this)); - } - else + auto it = m_fileMap.find(fromFileName); + if (it!=m_fileMap.end()) { - //printf("existing file!\n"); - StringSet includeStack; - it->second->collectDefines(m_contextDefines,includeStack); + auto &dpf = it->second; + dpf->addInclude(toFileName); } } - /** Add a define to the manager object. - * @param fileName The file in which the define was found - * @param def The Define object to add. Ownership will be transferred. - */ - void addDefine(const char *fileName,std::unique_ptr<Define> &&def) + void store(std::string fileName,const DefineMapOwning &fromMap) { - if (fileName==0) return; - -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(m_mutex); -#endif - //printf("DefineManager::addDefine(%s,%s)\n",fileName,def->name.data()); - - m_contextDefines[def->name.data()] = def.get(); - auto it = m_fileMap.find(fileName); if (it==m_fileMap.end()) { - auto ptr = std::make_unique<DefinesPerFile>(this); - ptr->addDefine(std::move(def)); - m_fileMap.emplace(toStdString(fileName),std::move(ptr)); - } - else - { - it->second->addDefine(std::move(def)); + it = m_fileMap.emplace(fileName,std::make_unique<DefinesPerFile>(this)).first; } + it->second->store(fromMap); } - /** Add an include relation to the manager object. - * @param fromFileName file name in which the include was found. - * @param toFileName file name that is included. - */ - void addInclude(const char *fromFileName,const char *toFileName) + void retrieve(std::string fileName,DefineMapOwning &toMap) { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(m_mutex); -#endif - //printf("DefineManager::addInclude(%s,%s)\n",fromFileName,toFileName); - if (fromFileName==0 || toFileName==0) return; - auto it = m_fileMap.find(fromFileName); - if (it==m_fileMap.end()) - { - auto ptr = std::make_unique<DefinesPerFile>(this); - ptr->addInclude(toFileName); - m_fileMap.emplace(toStdString(fromFileName),std::move(ptr)); - } - else - { - it->second->addInclude(toFileName); - } - } - /** Returns a reference to a Define object given its name or 0 if the Define does - * not exist. - */ - Define *isDefined(const char *name) - { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(m_mutex); -#endif - Define *d=0; - auto it = m_contextDefines.find(name); - if (it!=m_contextDefines.end()) + auto it = m_fileMap.find(fileName); + if (it!=m_fileMap.end()) { - d = it->second; - if (d->undef) - { - d=0; - } + auto &dpf = it->second; + dpf->retrieve(toMap); } - //printf("isDefined(%s)=%p\n",name,d); - return d; } - /** Returns a reference to the defines found in the current context. */ - const DefineMapRef &defineContext() const + bool alreadyProcessed(std::string fileName) const { - return m_contextDefines; + return m_fileMap.find(fileName)!=m_fileMap.end(); } private: - /** Helper function to collect all define for a given file */ - void collectDefinesForFile(const char *fileName,DefineMapRef &map) - { - if (fileName==0) return; - auto it = m_fileMap.find(fileName); - if (it!=m_fileMap.end()) - { - StringSet includeStack; - it->second->collectDefines(map,includeStack); - } - } - /** Helper function to return the DefinesPerFile object for a given file name. */ - DefinesPerFile *find(const char *fileName) const + DefinesPerFile *find(std::string fileName) const { - if (fileName==0) return nullptr; auto it = m_fileMap.find(fileName); return it!=m_fileMap.end() ? it->second.get() : nullptr; } - std::map< std::string,std::unique_ptr<DefinesPerFile> > m_fileMap; - DefineMapRef m_contextDefines; -#if MULTITHREADED_INPUT - std::mutex m_mutex; -#endif + std::unordered_map< std::string, std::unique_ptr<DefinesPerFile> > m_fileMap; }; -/** Collects all defines for a file and all files that the file includes. - * This function will recursively call itself for each file. - * @param dict The dictionary to fill with the defines. A redefine will - * replace a previous definition. - * @param includeStack The stack of includes, used to stop recursion in - * case there is a cyclic include dependency. - */ -void DefineManager::DefinesPerFile::collectDefines( - DefineMapRef &map,StringSet &includeStack) -{ - //printf("DefinesPerFile::collectDefines #defines=%d\n",m_defines.count()); - { - for (auto incFile : m_includedFiles) - { - 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); - dpf->collectDefines(map,includeStack); - } - } - } - { - for (auto &kv : m_defines) - { - const std::unique_ptr<Define> &def = kv.second; - map[def->name.data()] = def.get(); - //printf(" adding define %s\n",def->name.data()); - } - } -} - - /* ----------------------------------------------------------------- * * global state */ #if MULTITHREADED_INPUT -static std::mutex g_allIncludesMutex; -static std::mutex g_addIncludeRelationMutex; -static std::mutex g_macroDefinitionsMutex; +static std::mutex g_debugMutex; +static std::mutex g_globalDefineMutex; +//static std::mutex g_addIncludeRelationMutex; +//static std::mutex g_macroDefinitionsMutex; +static std::mutex g_updateGlobals; #endif -static StringUnorderedSet g_allIncludes; static DefineManager g_defineManager; @@ -429,6 +291,9 @@ struct preYY_state std::unordered_map<std::string,Define*> expandedDict; StringUnorderedSet expanded; ConstExpressionParser constExpParser; + DefineMapOwning contextDefines; + DefineList macroDefinitions; + LinkedMap<PreIncludeInfo> includeRelations; }; // stateless functions @@ -449,9 +314,10 @@ 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 addMacroDefinition(yyscan_t yyscanner); -static std::unique_ptr<Define> newDefine(yyscan_t yyscanner); +static void addDefine(yyscan_t yyscanner); static void setFileName(yyscan_t yyscanner,const char *name); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +static Define * isDefined(yyscan_t yyscanner,const char *name); /* ----------------------------------------------------------------- */ @@ -544,7 +410,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) !( (yyextra->includeStack.empty() || yyextra->curlyCount>0) && yyextra->macroExpansion && - (def=g_defineManager.isDefined(name)) && + (def=isDefined(yyscanner,name)) && /*macroIsAccessible(def) &&*/ (!yyextra->expandOnlyPredef || def->isPredefined) ) @@ -670,7 +536,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) yyextra->expectGuard = FALSE; Define *def=0; //def=yyextra->globalDefineDict->find(yytext); - //def=g_defineManager.isDefined(yytext); + //def=isDefined(yyscanner,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, @@ -679,7 +545,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) // ); if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) && yyextra->macroExpansion && - (def=g_defineManager.isDefined(yytext)) && + (def=isDefined(yyscanner,yytext)) && /*(def->isPredefined || macroIsAccessible(def)) && */ (!yyextra->expandOnlyPredef || def->isPredefined) ) @@ -707,7 +573,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) Define *def=0; if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) && yyextra->macroExpansion && - (def=g_defineManager.isDefined(yytext)) && + (def=isDefined(yyscanner,yytext)) && def->nargs==-1 && /*(def->isPredefined || macroIsAccessible(def)) &&*/ (!yyextra->expandOnlyPredef || def->isPredefined) @@ -924,7 +790,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <Command>. {yyextra->yyColNr+=(int)yyleng;} <UndefName>{ID} { Define *def; - if ((def=g_defineManager.isDefined(yytext)) + if ((def=isDefined(yyscanner,yytext)) /*&& !def->isPredefined*/ && !def->nonRecursive ) @@ -966,7 +832,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <DefinedExpr1,DefinedExpr2>\\\n { yyextra->yyLineNr++; outputChar(yyscanner,'\n'); } <DefinedExpr1>{ID} { - if (g_defineManager.isDefined(yytext) || yyextra->guardName==yytext) + if (isDefined(yyscanner,yytext) || yyextra->guardName==yytext) yyextra->guardExpr+=" 1L "; else yyextra->guardExpr+=" 0L "; @@ -974,7 +840,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(Guard); } <DefinedExpr2>{ID} { - if (g_defineManager.isDefined(yytext) || yyextra->guardName==yytext) + if (isDefined(yyscanner,yytext) || yyextra->guardName==yytext) yyextra->guardExpr+=" 1L "; else yyextra->guardExpr+=" 0L "; @@ -1575,17 +1441,11 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) { addMacroDefinition(yyscanner); } - def=g_defineManager.isDefined(yyextra->defName); + def=isDefined(yyscanner,yyextra->defName); if (def==0) // new define { //printf("new define '%s'!\n",yyextra->defName.data()); - 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.empty()) - //{ - // yyextra->fileDefineDict->insert(yyextra->defName,nd); - //} + addDefine(yyscanner); } else if (def /*&& macroIsAccessible(def)*/) // name already exists @@ -1657,6 +1517,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } else { + QCString toFileName = yyextra->yyFileName; const std::unique_ptr<FileState> &fs=yyextra->includeStack.back(); //fileDefineCache->merge(yyextra->yyFileName,fs->fileName); YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER; @@ -1677,6 +1538,31 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) outputArray(yyscanner,lineStr.data(),lineStr.length()); yyextra->includeStack.pop_back(); + +#if MULTITHREADED_INPUT + { + std::lock_guard<std::mutex> lock(g_globalDefineMutex); +#endif + // to avoid deadlocks we allow multiple threads to process the same header file. + // The first one to finish will store the results globally. After that the + // next time the same file is encountered, the stored data is used and the file + // is not processed again. + if (!g_defineManager.alreadyProcessed(toFileName.str())) + { + // now that the file is completely processed, prevent it from processing it again + g_defineManager.addInclude(yyextra->yyFileName.str(),toFileName.str()); + g_defineManager.store(toFileName.str(),yyextra->contextDefines); + } + else + { + if (Debug::isFlagSet(Debug::Preprocessor)) + { + Debug::print(Debug::Preprocessor,0,"#include %s: was already processed by another thread! not storing data...\n",qPrint(toFileName)); + } + } +#if MULTITHREADED_INPUT + } +#endif } } <*>"/*"/"*/" | @@ -1792,10 +1678,10 @@ static void setCaseDone(yyscan_t yyscanner,bool value) } -static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,bool &alreadyIncluded) +static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,bool &alreadyProcessed) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - alreadyIncluded = FALSE; + alreadyProcessed = FALSE; FileState *fs = 0; //printf("checkAndOpenFile(%s)\n",fileName.data()); QFileInfo fi(fileName); @@ -1810,27 +1696,26 @@ static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,b if (state->curlyCount==0) // not #include inside { ... } { #if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(g_allIncludesMutex); + std::lock_guard<std::mutex> lock(g_globalDefineMutex); #endif - if (g_allIncludes.find(absName.data())!=g_allIncludes.end()) + if (g_defineManager.alreadyProcessed(absName.str())) { - alreadyIncluded = TRUE; + alreadyProcessed = TRUE; //printf(" already included 1\n"); return 0; // already done } - g_allIncludes.insert(absName.data()); } // check include stack for absName - alreadyIncluded = std::any_of( + alreadyProcessed = std::any_of( state->includeStack.begin(), state->includeStack.end(), [absName](const std::unique_ptr<FileState> &lfs) { return lfs->fileName==absName; } ); - if (alreadyIncluded) + if (alreadyProcessed) { //printf(" already included 2\n"); return 0; @@ -1853,20 +1738,20 @@ static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,b return fs; } -static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localInclude,bool &alreadyIncluded) +static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localInclude,bool &alreadyProcessed) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); //printf("** findFile(%s,%d) state->yyFileName=%s\n",fileName,localInclude,state->yyFileName.data()); if (Portable::isAbsolutePath(fileName)) { - FileState *fs = checkAndOpenFile(yyscanner,fileName,alreadyIncluded); + FileState *fs = checkAndOpenFile(yyscanner,fileName,alreadyProcessed); if (fs) { setFileName(yyscanner,fileName); state->yyLineNr=1; return fs; } - else if (alreadyIncluded) + else if (alreadyProcessed) { return 0; } @@ -1877,14 +1762,14 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn if (fi.exists()) { QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+fileName; - FileState *fs = checkAndOpenFile(yyscanner,absName,alreadyIncluded); + FileState *fs = checkAndOpenFile(yyscanner,absName,alreadyProcessed); if (fs) { setFileName(yyscanner,absName); state->yyLineNr=1; return fs; } - else if (alreadyIncluded) + else if (alreadyProcessed) { return 0; } @@ -1898,7 +1783,7 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn { std::string absName = path+"/"+fileName; //printf(" Looking for %s in %s\n",fileName,path.c_str()); - FileState *fs = checkAndOpenFile(yyscanner,absName.c_str(),alreadyIncluded); + FileState *fs = checkAndOpenFile(yyscanner,absName.c_str(),alreadyProcessed); if (fs) { setFileName(yyscanner,absName.c_str()); @@ -1906,7 +1791,7 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn //printf(" -> found it\n"); return fs; } - else if (alreadyIncluded) + else if (alreadyProcessed) { return 0; } @@ -2448,7 +2333,7 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in { if (state->expandedDict.find(macroName.data())==state->expandedDict.end()) // expand macro { - Define *def=g_defineManager.isDefined(macroName); + Define *def=isDefined(yyscanner,macroName); if (macroName=="defined") { //printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data()); @@ -2801,7 +2686,7 @@ static QCString expandMacro(yyscan_t yyscanner,const QCString &name) return n; } -static std::unique_ptr<Define> newDefine(yyscan_t yyscanner) +static void addDefine(yyscan_t yyscanner) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); std::unique_ptr<Define> def = std::make_unique<Define>(); @@ -2817,11 +2702,16 @@ static std::unique_ptr<Define> newDefine(yyscan_t yyscanner) // def->fileDef ? def->fileDef->name().data() : def->fileName.data()); //printf("newDefine: '%s'->'%s'\n",def->name.data(),def->definition.data()); if (!def->name.isEmpty() && - Doxygen::expandAsDefinedSet.find(def->name.data())!=Doxygen::expandAsDefinedSet.end()) + Doxygen::expandAsDefinedSet.find(def->name.str())!=Doxygen::expandAsDefinedSet.end()) { def->isPredefined=TRUE; } - return def; + auto it = state->contextDefines.find(def->name.str()); + if (it!=state->contextDefines.end()) // redefine + { + state->contextDefines.erase(it); + } + state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def))); } static void addMacroDefinition(yyscan_t yyscanner) @@ -2864,10 +2754,7 @@ static void addMacroDefinition(yyscan_t yyscanner) define->definition = litTextStripped; } { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(g_macroDefinitionsMutex); -#endif - Doxygen::macroDefinitions.push_back(std::move(define)); + state->macroDefinitions.push_back(std::move(define)); } } @@ -2883,10 +2770,47 @@ static inline void outputArray(yyscan_t yyscanner,const char *a,int len) if (state->includeStack.empty() || state->curlyCount>0) state->outputBuf->addArray(a,len); } +static QCString determineAbsoluteIncludeName(const QCString &curFile,const QCString &incFileName) +{ + bool searchIncludes = Config_getBool(SEARCH_INCLUDES); + QCString absIncFileName = incFileName; + QFileInfo fi(curFile); + if (fi.exists()) + { + QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+incFileName; + QFileInfo fi2(absName); + if (fi2.exists()) + { + absIncFileName=fi2.absFilePath().utf8(); + } + else if (searchIncludes) // search in INCLUDE_PATH as well + { + const StringVector &includePath = Config_getList(INCLUDE_PATH); + for (const auto &incPath : includePath) + { + QFileInfo fi3(incPath.c_str()); + if (fi3.exists() && fi3.isDir()) + { + absName = QCString(fi3.absFilePath().utf8())+"/"+incFileName; + //printf("trying absName=%s\n",absName.data()); + QFileInfo fi4(absName); + if (fi4.exists()) + { + absIncFileName=fi4.absFilePath().utf8(); + break; + } + //printf( "absIncFileName = %s\n", absIncFileName.data() ); + } + } + } + //printf( "absIncFileName = %s\n", absIncFileName.data() ); + } + return absIncFileName; +} + static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); - bool searchIncludes = Config_getBool(SEARCH_INCLUDES); uint i=0; // find the start of the include file name @@ -2918,49 +2842,13 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) int oldLineNr = state->yyLineNr; //printf("Searching for '%s'\n",incFileName.data()); - // absIncFileName avoids difficulties for incFileName starting with "../" (bug 641336) - QCString absIncFileName = incFileName; - { - QFileInfo fi(state->yyFileName); - if (fi.exists()) - { - QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+incFileName; - QFileInfo fi2(absName); - if (fi2.exists()) - { - absIncFileName=fi2.absFilePath().utf8(); - } - else if (searchIncludes) // search in INCLUDE_PATH as well - { - const StringVector &includePath = Config_getList(INCLUDE_PATH); - for (const auto &incPath : includePath) - { - QFileInfo fi3(incPath.c_str()); - if (fi3.exists() && fi3.isDir()) - { - absName = QCString(fi3.absFilePath().utf8())+"/"+incFileName; - //printf("trying absName=%s\n",absName.data()); - QFileInfo fi4(absName); - if (fi4.exists()) - { - absIncFileName=fi4.absFilePath().utf8(); - break; - } - //printf( "absIncFileName = %s\n", absIncFileName.data() ); - } - } - } - //printf( "absIncFileName = %s\n", absIncFileName.data() ); - } - } - g_defineManager.addInclude(state->yyFileName,absIncFileName); - g_defineManager.addFileToContext(absIncFileName); + QCString absIncFileName = determineAbsoluteIncludeName(state->yyFileName,incFileName); // findFile will overwrite state->yyFileDef if found FileState *fs; - bool alreadyIncluded = FALSE; + bool alreadyProcessed = FALSE; //printf("calling findFile(%s)\n",incFileName.data()); - if ((fs=findFile(yyscanner,incFileName,localInclude,alreadyIncluded))) // see if the include file can be found + if ((fs=findFile(yyscanner,incFileName,localInclude,alreadyProcessed))) // see if the include file can be found { //printf("Found include file!\n"); if (Debug::isFlagSet(Debug::Preprocessor)) @@ -2971,30 +2859,25 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) } //msg("#include %s: parsing...\n",incFileName.data()); } - if (oldFileDef) + + if (state->includeStack.empty() && oldFileDef) { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(g_addIncludeRelationMutex); -#endif - // 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::inputNameLinkedMap,absIncFileName,ambig); - oldFileDef->addIncludeDependency(ambig ? 0 : incFd,incFileName,localInclude,state->isImported,FALSE); - // add included by dependency - if (state->yyFileDef) + PreIncludeInfo *ii = state->includeRelations.find(absIncFileName); + if (ii==0) { - //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data()); - state->yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,state->isImported); + bool ambig; + FileDef *incFd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig); + state->includeRelations.add( + absIncFileName, + oldFileDef, + ambig?nullptr:incFd, + incFileName, + localInclude, + state->isImported + ); } } - else if (state->inputFileDef) - { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(g_addIncludeRelationMutex); -#endif - state->inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,state->isImported,TRUE); - } + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; fs->bufState = YY_CURRENT_BUFFER; fs->lineNr = oldLineNr; @@ -3019,38 +2902,37 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) } else { - //printf(" calling findFile(%s) alreadyInc=%d\n",incFileName.data(),alreadyIncluded); - if (oldFileDef) + if (alreadyProcessed) // if this header was already process we can just copy the stored macros + // in the local context { #if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(g_addIncludeRelationMutex); + std::lock_guard<std::mutex> lock(g_globalDefineMutex); #endif - bool ambig; - - // change to absolute name for bug 641336 - 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); - // add included by dependency - if (fd) - { - //printf("Adding include dependency (2) %s->%s ambig=%d\n",oldFileDef->name().data(),fd->name().data(),ambig); - fd->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,state->isImported); - } + g_defineManager.retrieve(absIncFileName.str(),state->contextDefines); } - else if (state->inputFileDef) + + if (state->includeStack.empty() && oldFileDef) { -#if MULTITHREADED_INPUT - std::unique_lock<std::mutex> lock(g_addIncludeRelationMutex); -#endif - state->inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,state->isImported,TRUE); + PreIncludeInfo *ii = state->includeRelations.find(absIncFileName); + if (ii==0) + { + bool ambig; + FileDef *incFd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig); + ii = state->includeRelations.add(absIncFileName, + oldFileDef, + ambig?0:incFd, + incFileName, + localInclude, + state->isImported + ); + } } + if (Debug::isFlagSet(Debug::Preprocessor)) { - if (alreadyIncluded) + if (alreadyProcessed) { - Debug::print(Debug::Preprocessor,0,"#include %s: already included! skipping...\n",qPrint(incFileName)); + Debug::print(Debug::Preprocessor,0,"#include %s: already processed! skipping...\n",qPrint(incFileName)); } else { @@ -3058,10 +2940,11 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc) } //printf("error: include file %s not found\n",yytext); } - if (state->curlyCount>0 && !alreadyIncluded) // failed to find #include inside { ... } + if (state->curlyCount>0 && !alreadyProcessed) // failed to find #include inside { ... } { warn(state->yyFileName,state->yyLineNr,"include file %s not found, perhaps you forgot to add its directory to INCLUDE_PATH?",incFileName.data()); } + } } } @@ -3210,6 +3093,25 @@ 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); } +/** Returns a reference to a Define object given its name or 0 if the Define does + * not exist. + */ +static Define *isDefined(yyscan_t yyscanner,const char *name) +{ + YY_EXTRA_TYPE state = preYYget_extra(yyscanner); + Define *d=0; + auto it = state->contextDefines.find(name); + if (it!=state->contextDefines.end()) + { + d = it->second.get(); + if (d->undef) + { + d=0; + } + } + return d; +} + static void initPredefined(yyscan_t yyscanner,const char *fileName) { YY_EXTRA_TYPE state = preYYget_extra(yyscanner); @@ -3289,7 +3191,7 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName) def->nonRecursive = nonRecursive; def->fileDef = state->yyFileDef; def->fileName = fileName; - g_defineManager.addDefine(state->yyFileName,std::move(def)); + state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def))); //printf("#define '%s' '%s' #nargs=%d\n", // def->name.data(),def->definition.data(),def->nargs); @@ -3321,7 +3223,7 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName) def->nonRecursive = nonRecursive; def->fileDef = state->yyFileDef; def->fileName = fileName; - g_defineManager.addDefine(state->yyFileName,std::move(def)); + state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def))); } } } @@ -3355,6 +3257,7 @@ Preprocessor::~Preprocessor() void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output) { +// printf("Preprocessor::processFile(%s)\n",fileName); yyscan_t yyscanner = p->yyscanner; YY_EXTRA_TYPE state = preYYget_extra(p->yyscanner); struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; @@ -3378,12 +3281,13 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output state->outputBuf=&output; state->includeStack.clear(); state->expandedDict.clear(); + state->contextDefines.clear(); while (!state->condStack.empty()) state->condStack.pop(); - //state->fileDefineDict->clear(); setFileName(yyscanner,fileName); + state->inputFileDef = state->yyFileDef; - g_defineManager.startContext(state->yyFileName); + //yyextra->defineManager.startContext(state->yyFileName); initPredefined(yyscanner,fileName); @@ -3414,6 +3318,9 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output if (Debug::isFlagSet(Debug::Preprocessor)) { +#if MULTITHREADED_INPUT + std::lock_guard<std::mutex> lock(g_debugMutex); +#endif char *orgPos=output.data()+orgOffset; char *newPos=output.data()+output.curPos(); Debug::print(Debug::Preprocessor,0,"Preprocessor output of %s (size: %d bytes):\n",fileName,newPos-orgPos); @@ -3426,14 +3333,13 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output orgPos++; } Debug::print(Debug::Preprocessor,0,"\n---------\n"); - if (g_defineManager.defineContext().size()>0) + if (yyextra->contextDefines.size()>0) { Debug::print(Debug::Preprocessor,0,"Macros accessible in this file (%s):\n", fileName); Debug::print(Debug::Preprocessor,0,"---------\n"); - for (auto &kv : g_defineManager.defineContext()) + for (auto &kv : yyextra->contextDefines) { - Define *def = kv.second; - Debug::print(Debug::Preprocessor,0,"%s ",qPrint(def->name)); + Debug::print(Debug::Preprocessor,0,"%s ",qPrint(kv.second->name)); } Debug::print(Debug::Preprocessor,0,"\n---------\n"); } @@ -3442,8 +3348,29 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output Debug::print(Debug::Preprocessor,0,"No macros accessible in this file (%s).\n", fileName); } } - g_defineManager.endContext(); + + { +#if MULTITHREADED_INPUT + std::lock_guard<std::mutex> lock(g_updateGlobals); +#endif + for (const auto &inc : state->includeRelations) + { + if (inc->fromFileDef) + { + inc->fromFileDef->addIncludeDependency(inc->toFileDef,inc->includeName,inc->local,inc->imported); + } + if (inc->toFileDef) + { + inc->toFileDef->addIncludedByDependency(inc->fromFileDef,inc->includeName,inc->local,inc->imported); + } + } + // add the macro definition for this file to the global map + Doxygen::macroDefinitions.emplace(std::make_pair(state->yyFileName.str(),std::move(state->macroDefinitions))); + } + + //yyextra->defineManager.endContext(); printlex(yy_flex_debug, FALSE, __FILE__, fileName); +// printf("Preprocessor::processFile(%s) finished\n",fileName); } #if USE_STATE2STRING diff --git a/src/scanner.l b/src/scanner.l index 4f64503..d26a9b2 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -2045,7 +2045,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN(FindMembers); } <FindMembers,FindMemberName>{SCOPENAME} { - if (yyextra->insideCpp || yyextra->insideObjC) + if (Doxygen::clangAssistedParsing && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } @@ -2348,7 +2348,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) */ <Define>{ID} { //printf("Define '%s' without args\n",yytext); - if (yyextra->insideCpp || yyextra->insideObjC) + if (Doxygen::clangAssistedParsing && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } @@ -2359,7 +2359,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <DefineEnd>\n { //printf("End define: doc=%s docFile=%s docLine=%d\n",yyextra->current->doc.data(),yyextra->current->docFile.data(),yyextra->current->docLine); - lineCount(yyscanner); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; @@ -2368,6 +2367,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::DEFINE_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); + lineCount(yyscanner); initEntry(yyscanner); BEGIN(yyextra->lastDefineContext); } @@ -3463,7 +3463,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <Sharp>. { yyextra->current->type += *yytext ; } <FindFields>{ID} { - if (yyextra->insideCpp || yyextra->insideObjC) + if (Doxygen::clangAssistedParsing && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } @@ -5334,7 +5334,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <CompoundName>{SCOPENAME} { yyextra->current->name = yytext ; - if (yyextra->insideCpp || yyextra->insideObjC) + if (Doxygen::clangAssistedParsing && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } @@ -5399,7 +5399,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <ClassVar>{ID} { - if (yyextra->insideCpp || yyextra->insideObjC) + if (Doxygen::clangAssistedParsing && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext); } @@ -7255,8 +7255,7 @@ static void parseMain(yyscan_t yyscanner, yyextra->yyBegColNr = 0; yyextra->yyFileName = fileName; setContext(yyscanner); - bool processWithClang = yyextra->insideCpp || yyextra->insideObjC; - if (processWithClang) + if (Doxygen::clangAssistedParsing && (yyextra->insideCpp || yyextra->insideObjC)) { if (!sameTranslationUnit) // new file { diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index 70c6561..77aab68 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -1995,7 +1995,6 @@ static void generateSqlite3ForClass(const ClassDef *cd) DBG_CTX(("-----> ClassDef includeInfo for %s\n", nm.data())); DBG_CTX((" local : %d\n", ii->local)); DBG_CTX((" imported : %d\n", ii->imported)); - DBG_CTX((" indirect : %d\n", ii->indirect)); DBG_CTX(("header: %s\n", ii->fileDef->absFilePath().data())); DBG_CTX((" file_id : %d\n", file_id)); DBG_CTX((" header_id: %d\n", header_id)); @@ -2211,7 +2210,6 @@ static void generateSqlite3ForFile(const FileDef *fd) DBG_CTX(("-----> FileDef includeInfo for %s\n", ii->includeName.data())); DBG_CTX((" local: %d\n", ii->local)); DBG_CTX((" imported: %d\n", ii->imported)); - DBG_CTX((" indirect: %d\n", ii->indirect)); if(ii->fileDef) { DBG_CTX(("include: %s\n", ii->fileDef->absFilePath().data())); diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 12010e8..3c493b4 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -1526,7 +1526,7 @@ void TagFileParser::addIncludes() // ifd->getOutputFileBase().data(),ii->id.data()); if (ifd->getOutputFileBase()==QCString(ii->id)) { - fd->addIncludeDependency(ifd.get(),ii->text,ii->isLocal,ii->isImported,FALSE); + fd->addIncludeDependency(ifd.get(),ii->text,ii->isLocal,ii->isImported); } } } diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index ff96331..28a2028 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -3174,20 +3174,18 @@ void FlowChart::printFlowTree() void FlowChart::colTextNodes() { - QCString text; - FlowChart *flno; + FlowChart *flno = NULL; bool found=FALSE; for (uint j=0;j<flowList.count();j++) { FlowChart *flo=flowList.at(j); if (flo->type&TEXT_NO) { - text+=flo->text+'\n'; if (!found) { flno=flo; } - if (found) + else { flno->text+=flo->text; flowList.remove(flo); diff --git a/templates/html/close.svg b/templates/html/close.svg new file mode 100644 index 0000000..a933eea --- /dev/null +++ b/templates/html/close.svg @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 11 11" + height="11" + width="11" + id="svg2" + version="1.1"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <path + id="path12" + d="M 5.5 0.5 A 5 5 0 0 0 0.5 5.5 A 5 5 0 0 0 5.5 10.5 A 5 5 0 0 0 10.5 5.5 A 5 5 0 0 0 5.5 0.5 z M 3.5820312 3 A 0.58291923 0.58291923 0 0 1 4 3.1757812 L 5.5 4.6757812 L 7 3.1757812 A 0.58291923 0.58291923 0 0 1 7.4003906 3 A 0.58291923 0.58291923 0 0 1 7.8242188 4 L 6.3242188 5.5 L 7.8242188 7 A 0.58291923 0.58291923 0 1 1 7 7.8242188 L 5.5 6.3242188 L 4 7.8242188 A 0.58291923 0.58291923 0 1 1 3.1757812 7 L 4.6757812 5.5 L 3.1757812 4 A 0.58291923 0.58291923 0 0 1 3.5820312 3 z " + style="stroke-width:1.09870648;fill:#bababa;fill-opacity:1" /> +</svg> diff --git a/templates/html/htmlbase.tpl b/templates/html/htmlbase.tpl index 47939fd..02741d2 100644 --- a/templates/html/htmlbase.tpl +++ b/templates/html/htmlbase.tpl @@ -100,7 +100,7 @@ $(function() { <div id="MSearchBox" class="MSearchBoxInactive"> <div class="left"> <form id="FSearchBox" action="{{ page.relPath }}{% if config.EXTERNAL_SEARCH %}search{{ doxygen.htmlFileExtension }}{% else %}search.php{% endif %}" method="get"> - <img id="MSearchSelect" src="{{ page.relPath }}search/mag.png" alt=""/> + <img id="MSearchSelect" src="{{ page.relPath }}search/mag.svg" alt=""/> <input type="text" id="MSearchField" name="query" value="{{ tr.search }}" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)"/> @@ -111,7 +111,7 @@ $(function() { {% else %}{# !SERVER_BASED_SEARCH #} <div id="MSearchBox" class="MSearchBoxInactive"> <span class="left"> - <img id="MSearchSelect" src="{{ page.relPath }}search/mag_sel.png" + <img id="MSearchSelect" src="{{ page.relPath }}search/mag_sel.svg" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/> @@ -121,7 +121,7 @@ $(function() { onkeyup="searchBox.OnSearchFieldChange(event)"/> </span><span class="right"> <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img - id="MSearchCloseImg" border="0" src="{{ page.relPath }}search/close.png" + id="MSearchCloseImg" border="0" src="{{ page.relPath }}search/close.svg" alt=""/></a> </span> </div> diff --git a/templates/html/htmllayout.tpl b/templates/html/htmllayout.tpl index b434d0c..74d83c6 100644 --- a/templates/html/htmllayout.tpl +++ b/templates/html/htmllayout.tpl @@ -44,14 +44,14 @@ {% if config.SERVER_BASED_SEARCH %} {# server side search resources #} - {% resource 'mag.png' as 'search/mag.png' %} + {% resource 'mag.svg' as 'search/mag.svg' %} {% resource 'extsearch.js as 'search/search.js' %} {% resource 'search_functions.php' as 'search/search_functions.php' %} {% resource 'search_opensearch.php' as 'search/search_opensearch.php' %} {% else %} {# client side search resources #} - {% resource 'mag_sel.png' as 'search/mag_sel.png' %} - {% resource 'close.png' as 'search/close.png' %} + {% resource 'mag_sel.svg' as 'search/mag_sel.svg' %} + {% resource 'close.svg' as 'search/close.svg' %} {% resource 'search.js' as 'search/search.js' %} {% endif %} diff --git a/templates/html/htmltabs.tpl b/templates/html/htmltabs.tpl index e7539d9..b8632cb 100644 --- a/templates/html/htmltabs.tpl +++ b/templates/html/htmltabs.tpl @@ -35,7 +35,7 @@ <div id="MSearchBox" class="MSearchBoxInactive"> <div class="left"> <form id="FSearchBox" action="{{ page.relPath }}search{% if config.EXTERNAL_SEARCH %}{{ config.HTML_FILE_EXTENSION }}{% else %}.php{% endif %}" method="get"> - <img id="MSearchSelect" src="{{ page.relPath }}search/mag.png" alt=""/> + <img id="MSearchSelect" src="{{ page.relPath }}search/mag.svg" alt=""/> {% if page.highlight!='search' %} <input type="text" id="MSearchField" name="query" value="{{ tr.search }}" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" @@ -50,7 +50,7 @@ <li> <div id="MSearchBox" class="MSearchBoxInactive"> <span class="left"> - <img id="MSearchSelect" src="{{ page.relPath }}search/mag_sel.png" + <img id="MSearchSelect" src="{{ page.relPath }}search/mag_sel.svg" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/> @@ -60,7 +60,7 @@ onkeyup="searchBox.OnSearchFieldChange(event)"/> </span><span class="right"> <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img - id="MSearchCloseImg" border="0" src="{{ page.relPath }}search/close.png" alt=""/></a> + id="MSearchCloseImg" border="0" src="{{ page.relPath }}search/close.svg" alt=""/></a> </span> </div> </li> diff --git a/templates/html/mag.svg b/templates/html/mag.svg new file mode 100644 index 0000000..9f46b30 --- /dev/null +++ b/templates/html/mag.svg @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 20 19" + height="19" + width="20" + id="svg2" + version="1.1"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <circle + r="3.5" + cy="8.5" + cx="5.5" + id="path4611" + style="fill:#000000;fill-opacity:0;stroke:#656565;stroke-width:1.4;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /> + <path + id="path4630" + d="m 8.1085854,11.109059 2.7823556,2.782356" + style="fill:none;stroke:#656565;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +</svg> diff --git a/templates/html/mag_sel.svg b/templates/html/mag_sel.svg new file mode 100644 index 0000000..03626f6 --- /dev/null +++ b/templates/html/mag_sel.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg2" + width="20" + height="19" + viewBox="0 0 20 19" + sodipodi:docname="mag_sel.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="2096" + id="namedview4" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:zoom="32" + inkscape:cx="5.9792688" + inkscape:cy="1.1436277" + inkscape:window-x="1920" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg2" /> + <circle + style="fill:#000000;fill-opacity:0;stroke:#656565;stroke-width:1.4;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + id="path4611" + cx="5.5" + cy="8.5" + r="3.5" /> + <path + style="fill:#656565;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 11,7 13.5,10 16,7 Z" + id="path4609" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" /> + <path + style="fill:none;stroke:#656565;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.1085854,11.109059 2.7823556,2.782356" + id="path4630" + inkscape:connector-curvature="0" /> +</svg> diff --git a/templates/html/menu.js b/templates/html/menu.js index d18a2fe..2fe2214 100644 --- a/templates/html/menu.js +++ b/templates/html/menu.js @@ -41,9 +41,9 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); if (searchEnabled) { if (serverSide) { - $('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><div class="left"><form id="FSearchBox" action="'+relPath+searchPage+'" method="get"><img id="MSearchSelect" src="'+relPath+'search/mag.png" alt=""/><input type="text" id="MSearchField" name="query" value="'+search+'" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)"></form></div><div class="right"></div></div></li>'); + $('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><div class="left"><form id="FSearchBox" action="'+relPath+searchPage+'" method="get"><img id="MSearchSelect" src="'+relPath+'search/mag.svg" alt=""/><input type="text" id="MSearchField" name="query" value="'+search+'" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)"></form></div><div class="right"></div></div></li>'); } else { - $('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><span class="left"><img id="MSearchSelect" src="'+relPath+'search/mag_sel.png" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/><input type="text" id="MSearchField" value="'+search+'" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/></span><span class="right"><a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="'+relPath+'search/close.png" alt=""/></a></span></div></li>'); + $('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><span class="left"><img id="MSearchSelect" src="'+relPath+'search/mag_sel.svg" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/><input type="text" id="MSearchField" value="'+search+'" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/></span><span class="right"><a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="'+relPath+'search/close.svg" alt=""/></a></span></div></li>'); } } $('#main-menu').smartmenus(); diff --git a/templates/html/search.css b/templates/html/search.css index 859cf6a..8af75a7 100644 --- a/templates/html/search.css +++ b/templates/html/search.css @@ -1,98 +1,82 @@ /*---------------- Search Box */ -#FSearchBox { - float: left; -} - #MSearchBox { white-space : nowrap; - float: none; - margin-top: 8px; - right: 0px; - width: 170px; - height: 24px; + background: white; + border-radius: 0.65em; + box-shadow: inset 0.5px 0.5px 3px 0px #555; z-index: 102; } -#MSearchBox .left -{ - display:block; - position:absolute; - left:10px; - width:20px; - height:19px; - background:url('search_l.png') no-repeat; - background-position:right; +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; } #MSearchSelect { - display:block; - position:absolute; - width:20px; - height:19px; -} - -.left #MSearchSelect { - left:4px; -} - -.right #MSearchSelect { - right:5px; + display: inline-block; + vertical-align: middle; + height: 1.4em; + padding: 0 0 0 0.3em; + margin: 0; } #MSearchField { - display:block; - position:absolute; - height:19px; - background:url('search_m.png') repeat-x; + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 1.1em; + margin: 0 0.15em; + padding: 0; + line-height: 1em; border:none; - width:115px; - margin-left:20px; - padding-left:4px; color: #909090; outline: none; - font: 9pt Arial, Verdana, sans-serif; + font-family: Arial, Verdana, sans-serif; -webkit-border-radius: 0px; + border-radius: 0px; + background: none; } -#FSearchBox #MSearchField { - margin-left:15px; -} #MSearchBox .right { - display:block; - position:absolute; - right:10px; - top:8px; - width:20px; - height:19px; - background:url('search_r.png') no-repeat; - background-position:left; + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; } #MSearchClose { display: none; - position: absolute; - top: 4px; + font-size: inherit; background : none; border: none; - margin: 0px 4px 0px 0px; - padding: 0px 0px; + margin: 0; + padding: 0; outline: none; -} -.left #MSearchClose { - left: 6px; } -.right #MSearchClose { - right: 2px; +#MSearchCloseImg { + height: 1.4em; + padding: 0.3em; + margin: 0; } .MSearchBoxActive #MSearchField { color: #000000; } +#main-menu > li:last-child { + /* This <li> object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + /*---------------- Search filter selection */ #MSearchSelectWindow { diff --git a/templates/html/search.js b/templates/html/search.js index ff2b8c8..92b6094 100644 --- a/templates/html/search.js +++ b/templates/html/search.js @@ -364,7 +364,7 @@ function SearchBox(name, resultsPath, inFrame, label) if (domPopupSearchResultsWindow.style.display!='block') { var domSearchBox = this.DOMSearchBox(); - this.DOMSearchClose().style.display = 'inline'; + this.DOMSearchClose().style.display = 'inline-block'; if (this.insideFrame) { var domPopupSearchResults = this.DOMPopupSearchResults(); diff --git a/templates/html/search_functions.php b/templates/html/search_functions.php index 7374de9..22481db 100644 --- a/templates/html/search_functions.php +++ b/templates/html/search_functions.php @@ -7,7 +7,7 @@ function end_form($value) global $translator; if ($config['DISABLE_INDEX'] == false) { - echo " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"$value\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n </form>\n </div><div class=\"right\"></div>\n </div>\n </li>\n </ul>\n </div>\n</div>\n"; + echo "</div>\n"; } if ($config['GENERATE_TREEVIEW']) { @@ -15,11 +15,6 @@ function end_form($value) } } -function end_page() -{ - echo "</body></html>"; -} - function search_results() { global $translator; @@ -361,6 +356,5 @@ function main() end_form(preg_replace("/[^a-zA-Z0-9\-\_\.\x80-\xFF]/i", " ", $query )); // report results to the user report_results($sorted); - end_page(); } ?> |