diff options
Diffstat (limited to 'src')
60 files changed, 3321 insertions, 3028 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 067c6cd..c3d6f13 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -240,6 +240,7 @@ add_library(doxymain STATIC docgroup.cpp docparser.cpp docsets.cpp + docvisitor.cpp dot.cpp dotcallgraph.cpp dotclassgraph.cpp diff --git a/src/cache.h b/src/cache.h new file mode 100644 index 0000000..5f7c834 --- /dev/null +++ b/src/cache.h @@ -0,0 +1,162 @@ +/***************************************************************************** + * + * 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 CACHE_H +#define CACHE_H + +#include <list> +#include <unordered_map> +#include <mutex> +#include <ctype.h> + +/*! Fixed size cache for value type V using keys of type K. + * + * When the maximum capacity has reached, the least recently used value is removed from the cache + * (LRU strategy). + */ +template<typename K,typename V> +class Cache +{ + public: + using kv_pair = std::pair<K,V>; + using iterator = typename std::list<kv_pair>::iterator; + using const_iterator = typename std::list<kv_pair>::const_iterator; + + //! creates a cache that can hold \a capacity elements + Cache(size_t capacity) : m_capacity(capacity) + { + } + + //! Inserts \a value under \a key in the cache + V *insert(const K &key,V &&value) + { + // remove item if it already exists + remove(key); + // store new item + m_cacheItemList.push_front(kv_pair(key,std::move(value))); + V *result = &m_cacheItemList.front().second; + m_cacheItemMap[key] = m_cacheItemList.begin(); + // remove least recently used item if cache is full + resize(); + return result; + } + + //! Inserts \a value under \a key in the cache + V *insert(const K &key,const V &value) + { + // remove item if it already exists + remove(key); + // store new item + m_cacheItemList.push_front(kv_pair(key,value)); + V *result = &m_cacheItemList.front().second; + m_cacheItemMap[key] = m_cacheItemList.begin(); + // remove least recently used item if cache is full + resize(); + return result; + } + + //! Removes entry \a key from the cache. + //! \note this invalidates any iterators + void remove(const K &key) + { + // remove item if it already exists + auto it = m_cacheItemMap.find(key); + if (it != m_cacheItemMap.end()) + { + m_cacheItemList.erase(it->second); + m_cacheItemMap.erase(it); + } + } + + //! Finds a value in the cache given the corresponding \a key. + //! @returns a pointer to the value or nullptr if the key is not found in the cache + //! @note The hit and miss counters are updated, see hits() and misses(). + V *find(const K &key) + { + auto it = m_cacheItemMap.find(key); + if (it != m_cacheItemMap.end()) + { + // move the item to the front of the list + m_cacheItemList.splice(m_cacheItemList.begin(), + m_cacheItemList, + it->second); + m_hits++; + // return the value + return &it->second->second; + } + else + { + m_misses++; + } + return nullptr; + } + + //! Returns the number of values stored in the cache. + size_t size() const + { + return m_cacheItemMap.size(); + } + + //! Returns the maximum number of values that can be stored in the cache. + size_t capacity() const + { + return m_capacity; + } + + //! Returns how many of the find() calls did find a value in the cache. + uint64_t hits() const + { + return m_hits; + } + + //! Returns how many of the find() calls did not found a value in the cache. + uint64_t misses() const + { + return m_misses; + } + + //! Clears all values in the cache. + void clear() + { + m_cacheItemMap.clear(); + m_cacheItemList.clear(); + } + + iterator begin() { return m_cacheItemList.begin(); } + iterator end() { return m_cacheItemList.end(); } + const_iterator begin() const { return m_cacheItemList.cbegin(); } + const_iterator end() const { return m_cacheItemList.cend(); } + + private: + void resize() + { + if (m_cacheItemMap.size() > m_capacity) + { + auto last_it = m_cacheItemList.end(); + --last_it; + m_cacheItemMap.erase(last_it->first); + m_cacheItemList.pop_back(); + } + } + size_t m_capacity; + // list of items in the cache, sorted by most to least recently used. + std::list<kv_pair> m_cacheItemList; + // mapping for each key to a place in the list where item is found + std::unordered_map<K,iterator> m_cacheItemMap; + uint64_t m_hits=0; + uint64_t m_misses=0; +}; + +#endif diff --git a/src/cite.cpp b/src/cite.cpp index 03bdb02..e02641a 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -368,7 +368,7 @@ void CitationManager::generatePage() //printf("doc=[%s]\n",doc.data()); // 7. add it as a page - addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1); + addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1,1); // 8. for latex we just copy the bib files to the output and let // latex do this work. diff --git a/src/clangparser.cpp b/src/clangparser.cpp index 1ac9138..1a91b8f 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -129,7 +129,7 @@ class ClangTUParser::Private std::vector<CXUnsavedFile> ufs; std::vector<CXCursor> cursors; std::unordered_map<std::string,uint> fileMapping; - CXTranslationUnit tu; + CXTranslationUnit tu = 0; CXToken *tokens = 0; uint numTokens = 0; StringVector filesInSameTU; @@ -858,7 +858,7 @@ class ClangParser::Private QCString clangCompileDatabase = Config_getString(CLANG_DATABASE_PATH); // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html) db = clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error); - if (clangCompileDatabase!="0" && db==nullptr) + if (!clangCompileDatabase.isEmpty() && clangCompileDatabase!="0" && db==nullptr) { // user specified a path, but DB file was not found err("%s using clang compilation database path of: \"%s\"\n", error.c_str(), @@ -884,6 +884,7 @@ ClangParser::~ClangParser() std::unique_ptr<ClangTUParser> ClangParser::createTUParser(const FileDef *fd) const { + //printf("ClangParser::createTUParser()\n"); return std::make_unique<ClangTUParser>(*this,fd); } diff --git a/src/clangparser.h b/src/clangparser.h index 8ee1bdb..f948c33 100644 --- a/src/clangparser.h +++ b/src/clangparser.h @@ -30,7 +30,7 @@ class ClangTUParser void parse(); /** Switches to another file within the translation unit started with start(). - * @param[in] fileName The name of the file to switch to. + * @param[in] fd The file definition with the name of the file to switch to. */ void switchToFile(FileDef *fd); diff --git a/src/classdef.cpp b/src/classdef.cpp index c3cd3ee..5e2b2fa 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -1248,6 +1248,7 @@ void ClassDefImpl::distributeMemberGroupDocumentation() void ClassDefImpl::findSectionsInDocumentation() { + docFindSections(briefDescription(),this,docFile()); docFindSections(documentation(),this,docFile()); if (m_impl->memberGroupSDict) { @@ -3,8 +3,8 @@ * 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. * @@ -23,7 +23,7 @@ %{ /* - * includes + * includes */ #include <memory> @@ -69,9 +69,9 @@ #define USE_STATE2STRING 0 /* ----------------------------------------------------------------- - * statics + * statics */ - + // context for an Objective-C method call struct ObjCCallCtx { @@ -102,15 +102,15 @@ class VariableContext void pushScope() { m_scopes.push_back(Scope()); - DBG_CTX((stderr,"** Push var context %d\n",m_scopes.count())); + DBG_CTX((stderr,"** Push var context %zu\n",m_scopes.size())); } void popScope() { if (!m_scopes.empty()) { - DBG_CTX((stderr,"** Pop var context %d\n",m_scopes.count())); - m_scopes.pop_back(); + DBG_CTX((stderr,"** Pop var context %zu\n",m_scopes.size())); + m_scopes.pop_back(); } else { @@ -166,10 +166,10 @@ class CallContext if (m_defList.size()>1) { DBG_CTX((stderr,"** Pop call context %zu\n",m_defList.size())); - const Ctx &ctx = m_defList.back(); - name_ = ctx.name; - type_ = ctx.type; - m_defList.pop_back(); + const Ctx &ctx = m_defList.back(); + name_ = ctx.name; + type_ = ctx.type; + m_defList.pop_back(); } else { @@ -204,10 +204,10 @@ struct codeYY_state QCString parmName; const char * inputString = 0; //!< the code fragment as text - yy_size_t 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 + int yyLineNr = 0; //!< current line number + int yyColNr = 0; //!< current column number bool needsTermination = FALSE; bool exampleBlock = FALSE; @@ -220,12 +220,12 @@ struct codeYY_state QCString args; QCString classScope; QCString realScope; - std::stack<int> scopeStack; //!< 1 if bracket starts a scope, - // 2 for internal blocks + std::stack<int> scopeStack; //!< 1 if bracket starts a scope, + // 2 for internal blocks int anchorCount = 0; FileDef * sourceFileDef = 0; bool lineNumbers = FALSE; - Definition * currentDefinition = 0; + const Definition * currentDefinition = 0; MemberDef * currentMemberDef = 0; bool includeCodeFragment = FALSE; const char * currentFontClass = 0; @@ -236,20 +236,20 @@ struct codeYY_state QCString saveType; QCString delimiter; - int bracketCount = 0; - int curlyCount = 0; - int sharpCount = 0; + int bracketCount = 0; + int curlyCount = 0; + int sharpCount = 0; bool inFunctionTryBlock = FALSE; bool inForEachExpression = FALSE; int lastTemplCastContext = 0; - int lastSpecialCContext = 0; + int lastSpecialCContext = 0; int lastStringContext = 0; int lastSkipCppContext = 0; int lastVerbStringContext = 0; int lastObjCCallContext = 0; int memCallContext = 0; - int lastCContext = 0; + int lastCContext = 0; int skipInlineInitContext = 0; SrcLangExt lang = SrcLangExt_Unknown; @@ -311,21 +311,21 @@ static void addType(yyscan_t yyscanner); static void addParmType(yyscan_t yyscanner); static void addUsingDirective(yyscan_t yyscanner,const char *name); static void setParameterList(yyscan_t yyscanner,const MemberDef *md); -static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,Definition *d); +static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Definition *d); static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name); static void updateCallContextForSmartPointer(yyscan_t yyscanner); static bool getLinkInScope(yyscan_t yyscanner,const QCString &c, // scope const QCString &m, // member - const char *memberText, // exact text - CodeOutputInterface &ol, - const char *text, - bool varOnly=FALSE - ); + const char *memberText, // exact text + CodeOutputInterface &ol, + const char *text, + bool varOnly=FALSE + ); static bool getLink(yyscan_t yyscanner,const char *className, const char *memberName, - CodeOutputInterface &ol, - const char *text=0, - bool varOnly=FALSE); + CodeOutputInterface &ol, + const char *text=0, + bool varOnly=FALSE); static void generateClassOrGlobalLink(yyscan_t yyscanner,CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE,bool varOnly=FALSE); static bool generateClassMemberLink(yyscan_t yyscanner,CodeOutputInterface &ol,MemberDef *xmd,const char *memName); @@ -346,15 +346,15 @@ 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(yyscanner,buf,max_size); +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); %} B [ \t] BN [ \t\n\r] -ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* +ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* SEP ("::"|"\\") SCOPENAME ({SEP}{BN}*)?({ID}{BN}*{SEP}{BN}*)*("~"{BN}*)?{ID} TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" @@ -409,12 +409,12 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} %x SkipString %x SkipStringS %x SkipVerbString -%x SkipCPP -%x SkipComment -%x SkipCxxComment -%x RemoveSpecialCComment -%x StripSpecialCComment -%x Body +%x SkipCPP +%x SkipComment +%x SkipCxxComment +%x RemoveSpecialCComment +%x StripSpecialCComment +%x Body %x FuncCall %x MemberCall %x MemberCall2 @@ -424,22 +424,22 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} %x AlignAsEnd %x PackageName %x ClassVar -%x CppCliTypeModifierFollowup +%x CppCliTypeModifierFollowup %x Bases %x SkipSharp %x ReadInclude %x TemplDecl %x TemplCast -%x CallEnd +%x CallEnd %x ObjCMethod -%x ObjCParams -%x ObjCParamType +%x ObjCParams +%x ObjCParamType %x ObjCCall %x ObjCMName %x ObjCSkipStr %x ObjCCallComment %x OldStyleArgs -%x UsingName +%x UsingName %x RawString %x InlineInit @@ -447,258 +447,258 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} <*>\x0d <Body>^([ \t]*"#"[ \t]*("include"|"import")[ \t]*)("<"|"\"") { - startFontClass(yyscanner,"preprocessor"); - yyextra->code->codify(yytext); - BEGIN( ReadInclude ); - } -<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ { + startFontClass(yyscanner,"preprocessor"); + yyextra->code->codify(yytext); + BEGIN( ReadInclude ); + } +<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ { yyextra->insideObjC=TRUE; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - if (!yyextra->insideTemplate) - BEGIN( ClassName ); - } + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + if (!yyextra->insideTemplate) + BEGIN( ClassName ); + } <Body>(("public"|"private"){B}+)?("ref"|"value"|"interface"|"enum"){B}+("class"|"struct") { - if (yyextra->insideTemplate) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( ClassName ); - } -<Body>"property"|"event"/{BN}* { - if (yyextra->insideTemplate) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -<Body>(KEYWORD_CPPCLI_DATATYPE|("partial"{B}+)?"class"|"struct"|"union"|"namespace"|"interface"){B}+ { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - if (!yyextra->insideTemplate) - BEGIN( ClassName ); - } -<Body>("package")[ \t\n]+ { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( PackageName ); - } -<ClassVar>\n { - if (!yyextra->insideObjC) REJECT; - codifyLines(yyscanner,yytext); - BEGIN(Body); - } -<Body,ClassVar,Bases>"-"|"+" { - if (!yyextra->insideObjC || yyextra->insideBody) - { - yyextra->code->codify(yytext); - } - else // Start of Objective-C method - { - //printf("Method!\n"); - yyextra->code->codify(yytext); - BEGIN(ObjCMethod); - } - } -<ObjCMethod>":" { - yyextra->code->codify(yytext); - BEGIN(ObjCParams); - } -<ObjCParams>"(" { - yyextra->code->codify(yytext); - BEGIN(ObjCParamType); - } -<ObjCParams,ObjCMethod>";"|"{" { - yyextra->code->codify(yytext); - if (*yytext=='{') - { - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - if (!yyextra->curClassName.isEmpty()) // valid class name - { - pushScope(yyscanner,yyextra->curClassName); + if (yyextra->insideTemplate) REJECT; + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( ClassName ); + } +<Body>"property"|"event"/{BN}* { + if (yyextra->insideTemplate) REJECT; + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +<Body>(KEYWORD_CPPCLI_DATATYPE|("partial"{B}+)?"class"|"struct"|"union"|"namespace"|"interface"){B}+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + if (!yyextra->insideTemplate) + BEGIN( ClassName ); + } +<Body>("package")[ \t\n]+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( PackageName ); + } +<ClassVar>\n { + if (!yyextra->insideObjC) REJECT; + codifyLines(yyscanner,yytext); + BEGIN(Body); + } +<Body,ClassVar,Bases>"-"|"+" { + if (!yyextra->insideObjC || yyextra->insideBody) + { + yyextra->code->codify(yytext); + } + else // Start of Objective-C method + { + //printf("Method!\n"); + yyextra->code->codify(yytext); + BEGIN(ObjCMethod); + } + } +<ObjCMethod>":" { + yyextra->code->codify(yytext); + BEGIN(ObjCParams); + } +<ObjCParams>"(" { + yyextra->code->codify(yytext); + BEGIN(ObjCParamType); + } +<ObjCParams,ObjCMethod>";"|"{" { + yyextra->code->codify(yytext); + if (*yytext=='{') + { + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + if (!yyextra->curClassName.isEmpty()) // valid class name + { + pushScope(yyscanner,yyextra->curClassName); DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - yyextra->scopeStack.push(SCOPEBLOCK); - } - } + yyextra->scopeStack.push(SCOPEBLOCK); + } + } yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN(Body); - } -<ObjCParams>{ID}{B}*":" { - yyextra->code->codify(yytext); - } -<ObjCParamType>{TYPEKW} { - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->parmType=yytext; - } -<ObjCParamType>{ID} { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->parmType=yytext; - } -<ObjCParamType>")" { - yyextra->code->codify(yytext); - BEGIN(ObjCParams); - } -<ObjCParams>{ID} { - yyextra->code->codify(yytext); - yyextra->parmName=yytext; - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - } + BEGIN(Body); + } +<ObjCParams>{ID}{B}*":" { + yyextra->code->codify(yytext); + } +<ObjCParamType>{TYPEKW} { + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->parmType=yytext; + } +<ObjCParamType>{ID} { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->parmType=yytext; + } +<ObjCParamType>")" { + yyextra->code->codify(yytext); + BEGIN(ObjCParams); + } +<ObjCParams>{ID} { + yyextra->code->codify(yytext); + yyextra->parmName=yytext; + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + } <ObjCMethod,ObjCParams,ObjCParamType>{ID} { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -<ObjCMethod,ObjCParams,ObjCParamType>. { - yyextra->code->codify(yytext); - } -<ObjCMethod,ObjCParams,ObjCParamType>\n { - codifyLines(yyscanner,yytext); - } -<ReadInclude>[^\n\"\>]+/(">"|"\"") { - //FileInfo *f; - bool ambig; - bool found=FALSE; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +<ObjCMethod,ObjCParams,ObjCParamType>. { + yyextra->code->codify(yytext); + } +<ObjCMethod,ObjCParams,ObjCParamType>\n { + codifyLines(yyscanner,yytext); + } +<ReadInclude>[^\n\"\>]+/(">"|"\"") { + //FileInfo *f; + bool ambig; + bool found=FALSE; const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,yytext,ambig); - //printf("looking for include %s -> %s fd=%p\n",yytext,absPath.data(),fd); - if (fd && fd->isLinkable()) - { - if (ambig) // multiple input files match the name - { - //printf("===== yes %s is ambiguous\n",yytext); - QCString name = QDir::cleanDirPath(yytext).utf8(); - if (!name.isEmpty() && yyextra->sourceFileDef) - { - FileName *fn = Doxygen::inputNameLinkedMap->find(name); - if (fn) - { - // see if this source file actually includes the file + //printf("looking for include %s -> %s fd=%p\n",yytext,absPath.data(),fd); + if (fd && fd->isLinkable()) + { + if (ambig) // multiple input files match the name + { + //printf("===== yes %s is ambiguous\n",yytext); + QCString name = QDir::cleanDirPath(yytext).utf8(); + if (!name.isEmpty() && yyextra->sourceFileDef) + { + const FileName *fn = Doxygen::inputNameLinkedMap->find(name); + if (fn) + { + // 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(); - } - } - } - else // not ambiguous - { - found = TRUE; - } - } - //printf(" include file %s found=%d\n",fd ? fd->absFilePath().data() : "<none>",found); - if (found) - { - writeMultiLineCodeLink(yyscanner,*yyextra->code,fd,yytext); - } - else - { - yyextra->code->codify(yytext); - } - char c=(char)yyinput(yyscanner); - QCString text; - text+=c; - yyextra->code->codify(text); - endFontClass(yyscanner); - BEGIN( Body ); - } -<Body,Bases>^[ \t]*"#" { - startFontClass(yyscanner,"preprocessor"); - yyextra->lastSkipCppContext = YY_START; - yyextra->code->codify(yytext); - BEGIN( SkipCPP ) ; - } -<SkipCPP>\" { - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; - BEGIN( SkipString ) ; - } -<SkipCPP>. { - yyextra->code->codify(yytext); - } -<SkipCPP>[^\n\/\\\"]+ { - yyextra->code->codify(yytext); - } -<SkipCPP>\\[\r]?\n { - codifyLines(yyscanner,yytext); - } -<SkipCPP>"//"/[^/!] { - REJECT; - yyextra->code->codify(yytext); - } -<Body,FuncCall>"{" { + } + } + } + else // not ambiguous + { + found = TRUE; + } + } + //printf(" include file %s found=%d\n",fd ? fd->absFilePath().data() : "<none>",found); + if (found) + { + writeMultiLineCodeLink(yyscanner,*yyextra->code,fd,yytext); + } + else + { + yyextra->code->codify(yytext); + } + char c=(char)yyinput(yyscanner); + QCString text; + text+=c; + yyextra->code->codify(text); + endFontClass(yyscanner); + BEGIN( Body ); + } +<Body,Bases>^[ \t]*"#" { + startFontClass(yyscanner,"preprocessor"); + yyextra->lastSkipCppContext = YY_START; + yyextra->code->codify(yytext); + BEGIN( SkipCPP ) ; + } +<SkipCPP>\" { + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; + BEGIN( SkipString ) ; + } +<SkipCPP>. { + yyextra->code->codify(yytext); + } +<SkipCPP>[^\n\/\\\"]+ { + yyextra->code->codify(yytext); + } +<SkipCPP>\\[\r]?\n { + codifyLines(yyscanner,yytext); + } +<SkipCPP>"//"/[^/!] { + REJECT; + yyextra->code->codify(yytext); + } +<Body,FuncCall>"{" { yyextra->theVarContext.pushScope(); DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - yyextra->code->codify(yytext); - if (yyextra->insideBody) - { - yyextra->bodyCurlyCount++; - } - yyextra->type.resize(0); - yyextra->name.resize(0); - BEGIN( Body ); - } -<Body,FuncCall,MemberCall,MemberCall2>"}" { + yyextra->scopeStack.push(INNERBLOCK); + + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + yyextra->code->codify(yytext); + if (yyextra->insideBody) + { + yyextra->bodyCurlyCount++; + } + yyextra->type.resize(0); + yyextra->name.resize(0); + BEGIN( Body ); + } +<Body,FuncCall,MemberCall,MemberCall2>"}" { yyextra->theVarContext.popScope(); - yyextra->type.resize(0); - yyextra->name.resize(0); + yyextra->type.resize(0); + yyextra->name.resize(0); if (!yyextra->scopeStack.empty()) { - int scope = yyextra->scopeStack.top(); + int scope = yyextra->scopeStack.top(); yyextra->scopeStack.pop(); DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK)); - if (scope==SCOPEBLOCK || scope==CLASSBLOCK) - { - popScope(yyscanner); - } - } - - yyextra->code->codify(yytext); - - DBG_CTX((stderr,"yyextra->bodyCurlyCount=%d\n",yyextra->bodyCurlyCount)); - if (--yyextra->bodyCurlyCount<=0) - { - yyextra->insideBody=FALSE; - yyextra->currentMemberDef=0; - if (yyextra->currentDefinition) - yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); - } - BEGIN(Body); - } -<Body,ClassVar>"@end" { - //printf("End of objc scope fd=%s\n",yyextra->sourceFileDef->name().data()); + if (scope==SCOPEBLOCK || scope==CLASSBLOCK) + { + popScope(yyscanner); + } + } + + yyextra->code->codify(yytext); + + DBG_CTX((stderr,"yyextra->bodyCurlyCount=%d\n",yyextra->bodyCurlyCount)); + if (--yyextra->bodyCurlyCount<=0) + { + yyextra->insideBody=FALSE; + yyextra->currentMemberDef=0; + if (yyextra->currentDefinition) + yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); + } + BEGIN(Body); + } +<Body,ClassVar>"@end" { + //printf("End of objc scope fd=%s\n",yyextra->sourceFileDef->name().data()); if (yyextra->sourceFileDef) - { - FileDef *fd=yyextra->sourceFileDef; - yyextra->insideObjC = fd->name().lower().right(2)==".m" || - fd->name().lower().right(3)==".mm"; - //printf("insideObjC=%d\n",yyextra->insideObjC); - } - else - { - yyextra->insideObjC = FALSE; - } - if (yyextra->insideBody) - { + { + const FileDef *fd=yyextra->sourceFileDef; + yyextra->insideObjC = fd->name().lower().right(2)==".m" || + fd->name().lower().right(3)==".mm"; + //printf("insideObjC=%d\n",yyextra->insideObjC); + } + else + { + yyextra->insideObjC = FALSE; + } + if (yyextra->insideBody) + { yyextra->theVarContext.popScope(); if (!yyextra->scopeStack.empty()) @@ -706,235 +706,235 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} int scope = yyextra->scopeStack.top(); yyextra->scopeStack.pop(); DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK)); - if (scope==SCOPEBLOCK || scope==CLASSBLOCK) + if (scope==SCOPEBLOCK || scope==CLASSBLOCK) { popScope(yyscanner); } } yyextra->insideBody=FALSE; - } - - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - - yyextra->currentMemberDef=0; - if (yyextra->currentDefinition) - yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); - BEGIN(Body); - } -<ClassName,ClassVar>";" { - yyextra->code->codify(yytext); - yyextra->searchingForBody=FALSE; - BEGIN( Body ); - } -<ClassName,ClassVar>[*&^%]+ { - yyextra->type=yyextra->curClassName.copy(); - yyextra->name.resize(0); - yyextra->code->codify(yytext); - BEGIN( Body ); // variable of type struct * - } -<ClassName>"__declspec"{B}*"("{B}*{ID}{B}*")" { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -<ClassName>{ID}("."{ID})* | -<ClassName>{ID}("::"{ID})* { + } + + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + + yyextra->currentMemberDef=0; + if (yyextra->currentDefinition) + yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); + BEGIN(Body); + } +<ClassName,ClassVar>";" { + yyextra->code->codify(yytext); + yyextra->searchingForBody=FALSE; + BEGIN( Body ); + } +<ClassName,ClassVar>[*&^%]+ { + yyextra->type=yyextra->curClassName.copy(); + yyextra->name.resize(0); + yyextra->code->codify(yytext); + BEGIN( Body ); // variable of type struct * + } +<ClassName>"__declspec"{B}*"("{B}*{ID}{B}*")" { + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +<ClassName>{ID}("."{ID})* | +<ClassName>{ID}("::"{ID})* { if (yyextra->lang==SrcLangExt_CSharp) yyextra->curClassName=substitute(yytext,".","::"); else yyextra->curClassName=yytext; - addType(yyscanner); + addType(yyscanner); if (yyextra->curClassName=="alignas") { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); endFontClass(yyscanner); BEGIN( AlignAs ); } else { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( ClassVar ); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( ClassVar ); } - } -<AlignAs>"(" { + } +<AlignAs>"(" { yyextra->bracketCount=1; - yyextra->code->codify(yytext); + yyextra->code->codify(yytext); BEGIN( AlignAsEnd ); } -<AlignAs>\n { yyextra->yyLineNr++; +<AlignAs>\n { yyextra->yyLineNr++; codifyLines(yyscanner,yytext); } <AlignAs>. { yyextra->code->codify(yytext); } <AlignAsEnd>"(" { yyextra->code->codify(yytext); - yyextra->bracketCount++; + yyextra->bracketCount++; } -<AlignAsEnd>")" { +<AlignAsEnd>")" { yyextra->code->codify(yytext); if (--yyextra->bracketCount<=0) { BEGIN(ClassName); } } -<AlignAsEnd>\n { yyextra->yyLineNr++; - codifyLines(yyscanner,yytext); +<AlignAsEnd>\n { yyextra->yyLineNr++; + codifyLines(yyscanner,yytext); } <AlignAsEnd>. { yyextra->code->codify(yytext); } -<ClassName>{ID}("\\"{ID})* { // PHP namespace +<ClassName>{ID}("\\"{ID})* { // PHP namespace yyextra->curClassName=substitute(yytext,"\\","::"); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yyextra->curClassName); - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( ClassVar ); - } + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yyextra->curClassName); + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( ClassVar ); + } <ClassName>{ID}{B}*"("{ID}")" { // Obj-C category yyextra->curClassName=removeRedundantWhiteSpace(yytext); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yyextra->curClassName); - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( ClassVar ); - } -<PackageName>{ID}("."{ID})* { - yyextra->curClassName=substitute(yytext,".","::"); - //printf("found package: %s\n",yyextra->curClassName.data()); - addType(yyscanner); - codifyLines(yyscanner,yytext); - } -<ClassVar>"=" { - unput(*yytext); - BEGIN( Body ); - } -<ClassVar>("extends"|"implements") { // Java, Slice - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->curClassBases.clear(); - BEGIN( Bases ); - } + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yyextra->curClassName); + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( ClassVar ); + } +<PackageName>{ID}("."{ID})* { + yyextra->curClassName=substitute(yytext,".","::"); + //printf("found package: %s\n",yyextra->curClassName.data()); + addType(yyscanner); + codifyLines(yyscanner,yytext); + } +<ClassVar>"=" { + unput(*yytext); + BEGIN( Body ); + } +<ClassVar>("extends"|"implements") { // Java, Slice + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->curClassBases.clear(); + BEGIN( Bases ); + } <ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") { - DBG_CTX((stderr,"***** C++/CLI modifier %s on yyextra->curClassName=%s\n",yytext,yyextra->curClassName.data())); - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( CppCliTypeModifierFollowup ); - } -<ClassVar>{ID} { - yyextra->type = yyextra->curClassName.copy(); - yyextra->name = yytext; - if (yyextra->insideBody) - { - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); - } - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -<ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* { - codifyLines(yyscanner,yytext); - yyextra->curClassBases.clear(); - BEGIN( Bases ); - } -<PackageName>[ \t]*";" | + DBG_CTX((stderr,"***** C++/CLI modifier %s on yyextra->curClassName=%s\n",yytext,yyextra->curClassName.data())); + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( CppCliTypeModifierFollowup ); + } +<ClassVar>{ID} { + yyextra->type = yyextra->curClassName.copy(); + yyextra->name = yytext; + if (yyextra->insideBody) + { + yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + } + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +<ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* { + codifyLines(yyscanner,yytext); + yyextra->curClassBases.clear(); + BEGIN( Bases ); + } +<PackageName>[ \t]*";" | <Bases>^{B}*/"@"{ID} | // Objective-C interface <Bases,ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*"{"{B}* { yyextra->theVarContext.pushScope(); - yyextra->code->codify(yytext); - if (YY_START==ClassVar && yyextra->curClassName.isEmpty()) - { - yyextra->curClassName = yyextra->name.copy(); - } - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - if (!yyextra->curClassName.isEmpty()) // valid class name - { + yyextra->code->codify(yytext); + if (YY_START==ClassVar && yyextra->curClassName.isEmpty()) + { + yyextra->curClassName = yyextra->name.copy(); + } + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + if (!yyextra->curClassName.isEmpty()) // valid class name + { DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n")); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yyextra->curClassName); - DBG_CTX((stderr,"***** yyextra->curClassName=%s\n",yyextra->curClassName.data())); - if (getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->curClassName)==0) - { - DBG_CTX((stderr,"Adding new class %s\n",yyextra->curClassName.data())); + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yyextra->curClassName); + DBG_CTX((stderr,"***** yyextra->curClassName=%s\n",yyextra->curClassName.data())); + if (getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->curClassName)==0) + { + DBG_CTX((stderr,"Adding new class %s\n",yyextra->curClassName.data())); std::unique_ptr<ClassDef> ncd { createClassDef("<code>",1,1, - yyextra->curClassName,ClassDef::Class,0,0,FALSE) }; - // insert base classes. - char *s=yyextra->curClassBases.first(); - while (s) - { - const ClassDef *bcd=0; + yyextra->curClassName,ClassDef::Class,0,0,FALSE) }; + // insert base classes. + char *s=yyextra->curClassBases.first(); + while (s) + { + const ClassDef *bcd=0; auto it = yyextra->codeClassMap.find(s); if (it!=yyextra->codeClassMap.end()) { bcd=it->second.get(); } - if (bcd==0) bcd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s); - if (bcd && bcd!=ncd.get()) - { - ncd->insertBaseClass(const_cast<ClassDef*>(bcd),s,Public,Normal); - } - s=yyextra->curClassBases.next(); - } - yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(ncd))); - } - //printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count()); - } - else // not a class name -> assume inner block - { + if (bcd==0) bcd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s); + if (bcd && bcd!=ncd.get()) + { + ncd->insertBaseClass(const_cast<ClassDef*>(bcd),s,Public,Normal); + } + s=yyextra->curClassBases.next(); + } + yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(ncd))); + } + //printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count()); + } + else // not a class name -> assume inner block + { DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - } - yyextra->curClassName.resize(0); - yyextra->curClassBases.clear(); - BEGIN( Body ); - } -<Bases>"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -<Bases>{SEP}?({ID}{SEP})*{ID} { - DBG_CTX((stderr,"%s:addBase(%s)\n",yyextra->curClassName.data(),yytext)); - yyextra->curClassBases.inSort(yytext); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -<Bases>"<" { - yyextra->code->codify(yytext); - if (!yyextra->insideObjC) - { - yyextra->sharpCount=1; - BEGIN ( SkipSharp ); - } - else - { - yyextra->insideProtocolList=TRUE; - } - } -<Bases>">" { - yyextra->code->codify(yytext); - yyextra->insideProtocolList=FALSE; - } + yyextra->scopeStack.push(INNERBLOCK); + } + yyextra->curClassName.resize(0); + yyextra->curClassBases.clear(); + BEGIN( Body ); + } +<Bases>"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" { + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +<Bases>{SEP}?({ID}{SEP})*{ID} { + DBG_CTX((stderr,"%s:addBase(%s)\n",yyextra->curClassName.data(),yytext)); + yyextra->curClassBases.inSort(yytext); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +<Bases>"<" { + yyextra->code->codify(yytext); + if (!yyextra->insideObjC) + { + yyextra->sharpCount=1; + BEGIN ( SkipSharp ); + } + else + { + yyextra->insideProtocolList=TRUE; + } + } +<Bases>">" { + yyextra->code->codify(yytext); + yyextra->insideProtocolList=FALSE; + } <SkipSharp>"<" { - yyextra->code->codify(yytext); - ++yyextra->sharpCount; - } -<SkipSharp>">" { - yyextra->code->codify(yytext); - if (--yyextra->sharpCount<=0) - BEGIN ( Bases ); - } + yyextra->code->codify(yytext); + ++yyextra->sharpCount; + } +<SkipSharp>">" { + yyextra->code->codify(yytext); + if (--yyextra->sharpCount<=0) + BEGIN ( Bases ); + } <SkipSharp>"\"" { - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; BEGIN(SkipString); } <SkipSharp>"\'" { - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; BEGIN(SkipStringS); } <Bases>"(" { @@ -951,106 +951,106 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} if (--yyextra->sharpCount<=0) BEGIN ( Bases ); } - - -<Bases>"," { - yyextra->code->codify(yytext); - } - + + +<Bases>"," { + yyextra->code->codify(yytext); + } + <Body>{SCOPEPREFIX}?"operator"{B}*"()"{B}*/"(" { - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); - } + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); + } <Body>{SCOPEPREFIX}?"operator"/"(" { - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); } <Body>{SCOPEPREFIX}?"operator"[^a-z_A-Z0-9\(\n]+/"(" { - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); - } -<Body,TemplDecl>("template"|"generic")/([^a-zA-Z0-9]) { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->insideTemplate=TRUE; - yyextra->sharpCount=0; - } -<Body>"using"{BN}+"namespace"{BN}+ { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN(UsingName); - } -<UsingName>{ID}("::"{ID})* { addUsingDirective(yyscanner,yytext); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); + } +<Body,TemplDecl>("template"|"generic")/([^a-zA-Z0-9]) { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->insideTemplate=TRUE; + yyextra->sharpCount=0; + } +<Body>"using"{BN}+"namespace"{BN}+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN(UsingName); + } +<UsingName>{ID}("::"{ID})* { addUsingDirective(yyscanner,yytext); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n")); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yytext); - BEGIN(Body); + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yytext); + BEGIN(Body); } -<UsingName>\n { codifyLines(yyscanner,yytext); BEGIN(Body); } -<UsingName>. { codifyLines(yyscanner,yytext); BEGIN(Body); } -<Body,FuncCall>"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C# - yyextra->prefixed_with_this_keyword = TRUE; +<UsingName>\n { codifyLines(yyscanner,yytext); BEGIN(Body); } +<UsingName>. { codifyLines(yyscanner,yytext); BEGIN(Body); } +<Body,FuncCall>"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C# + yyextra->prefixed_with_this_keyword = TRUE; } -<Body>{KEYWORD}/([^a-z_A-Z0-9]) { +<Body>{KEYWORD}/([^a-z_A-Z0-9]) { if (yyextra->lang==SrcLangExt_Java && qstrcmp("internal",yytext) ==0) REJECT; if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - if (QCString(yytext)=="typedef") - { - addType(yyscanner); - yyextra->name+=yytext; - } - endFontClass(yyscanner); - } -<Body>{KEYWORD}/{B}* { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + if (QCString(yytext)=="typedef") + { + addType(yyscanner); + yyextra->name+=yytext; + } + endFontClass(yyscanner); + } +<Body>{KEYWORD}/{B}* { if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -<Body>{KEYWORD}/{BN}*"(" { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +<Body>{KEYWORD}/{BN}*"(" { if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->name.resize(0);yyextra->type.resize(0); - } -<FuncCall>"in"/{BN}* { - if (!yyextra->inForEachExpression) REJECT; - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - // insert the variable in the parent scope, see bug 546158 - yyextra->theVarContext.popScope(); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - yyextra->theVarContext.pushScope(); - yyextra->name.resize(0);yyextra->type.resize(0); - } -<Body>{FLOWKW}/{BN}*"(" { - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->name.resize(0);yyextra->type.resize(0); - yyextra->inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0); - BEGIN(FuncCall); - } + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->name.resize(0);yyextra->type.resize(0); + } +<FuncCall>"in"/{BN}* { + if (!yyextra->inForEachExpression) REJECT; + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + // insert the variable in the parent scope, see bug 546158 + yyextra->theVarContext.popScope(); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->theVarContext.pushScope(); + yyextra->name.resize(0);yyextra->type.resize(0); + } +<Body>{FLOWKW}/{BN}*"(" { + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->name.resize(0);yyextra->type.resize(0); + yyextra->inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0); + BEGIN(FuncCall); + } <Body>{FLOWCONDITION}/{BN}*"(" { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { @@ -1063,16 +1063,16 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->inForEachExpression = (strcmp(yytext,"for each")==0 || strcmp(yytext, "foreach")==0); BEGIN(FuncCall); } -<Body>{FLOWKW}/([^a-z_A-Z0-9]) { - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - if (yyextra->inFunctionTryBlock && (qstrcmp(yytext,"catch")==0 || qstrcmp(yytext,"finally")==0)) - { - yyextra->inFunctionTryBlock=FALSE; - } - } -<Body>{FLOWCONDITION}/([^a-z_A-Z0-9]) { +<Body>{FLOWKW}/([^a-z_A-Z0-9]) { + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + if (yyextra->inFunctionTryBlock && (qstrcmp(yytext,"catch")==0 || qstrcmp(yytext,"finally")==0)) + { + yyextra->inFunctionTryBlock=FALSE; + } + } +<Body>{FLOWCONDITION}/([^a-z_A-Z0-9]) { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { yyextra->currentMemberDef->incrementFlowKeyWordCount(); @@ -1085,11 +1085,11 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->inFunctionTryBlock=FALSE; } } -<Body>{FLOWKW}/{B}* { - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } +<Body>{FLOWKW}/{B}* { + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } <Body>{FLOWCONDITION}/{B}* { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { @@ -1100,32 +1100,32 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); } <Body>"*"{B}*")" { // end of cast? - yyextra->code->codify(yytext); - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->bracketCount--; + yyextra->code->codify(yytext); + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->bracketCount--; yyextra->parmType = yyextra->name; - BEGIN(FuncCall); + BEGIN(FuncCall); } <Body>"\\)"|"\\(" { yyextra->code->codify(yytext); } -<Body>[\\|\)\+\-\/\%\~\!] { - yyextra->code->codify(yytext); - yyextra->name.resize(0);yyextra->type.resize(0); - if (*yytext==')') - { - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->bracketCount--; - BEGIN(FuncCall); - } - } +<Body>[\\|\)\+\-\/\%\~\!] { + yyextra->code->codify(yytext); + yyextra->name.resize(0);yyextra->type.resize(0); + if (*yytext==')') + { + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->bracketCount--; + BEGIN(FuncCall); + } + } <Body,TemplDecl,ObjCMethod>{TYPEKW}/{B}* { - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - addType(yyscanner); - yyextra->name+=yytext; - } + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + addType(yyscanner); + yyextra->name+=yytext; + } <Body,TemplDecl,ObjCMethod>{TYPEKWSL}/{B}* { if (yyextra->lang!=SrcLangExt_Slice) { @@ -1133,395 +1133,395 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } else { - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - addType(yyscanner); - yyextra->name+=yytext; + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + addType(yyscanner); + yyextra->name+=yytext; } - } + } <Body>"generic"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->sharpCount=0; - BEGIN(TemplDecl); - } + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->sharpCount=0; + BEGIN(TemplDecl); + } <Body>"template"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { // template<...> - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->sharpCount=0; - BEGIN(TemplDecl); - } -<TemplDecl>"class"|"typename" { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -<TemplDecl>"<" { + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->sharpCount=0; + BEGIN(TemplDecl); + } +<TemplDecl>"class"|"typename" { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +<TemplDecl>"<" { yyextra->code->codify(yytext); yyextra->sharpCount++; - } -<TemplDecl>">" { + } +<TemplDecl>">" { yyextra->code->codify(yytext); yyextra->sharpCount--; - if (yyextra->sharpCount<=0) - { - BEGIN(Body); - } - } -<TemplCast>">" { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastTemplCastContext ); - } -<TemplCast>{ID}("::"{ID})* { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -<TemplCast>("const"|"volatile"){B}* { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -<TemplCast>[*^]* { - codifyLines(yyscanner,yytext); - } + if (yyextra->sharpCount<=0) + { + BEGIN(Body); + } + } +<TemplCast>">" { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastTemplCastContext ); + } +<TemplCast>{ID}("::"{ID})* { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +<TemplCast>("const"|"volatile"){B}* { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +<TemplCast>[*^]* { + codifyLines(yyscanner,yytext); + } <Body,MemberCall2,FuncCall>{CASTKW}{B}*"<" { // static_cast<T>( - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); yyextra->lastTemplCastContext = YY_START; - BEGIN(TemplCast); - } + BEGIN(TemplCast); + } <Body>"$this->"{SCOPENAME}/{BN}*[;,)\]] { // PHP member variable - addType(yyscanner); - generatePHPVariableLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext+7; + addType(yyscanner); + generatePHPVariableLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext+7; } <Body,TemplCast>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>\(]*">"("::"{ID})*/{B}* { // A<T> *pt; - if (isCastKeyword(yytext) && YY_START==Body) - { - REJECT; - } - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext; - } -<Body>{SCOPENAME}/{BN}*[:;,)\]] { // "int var;" or "var, var2" or "debug(f) macro" , or int var : 5; - addType(yyscanner); - // changed this to generateFunctionLink, see bug 624514 - //generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,FALSE,TRUE); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext; - } -<Body>{SCOPENAME}/{B}* { // p->func() - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext; - } -<Body>"("{B}*("*"{B}*)+{SCOPENAME}+{B}*")"/{B}* { // (*p)->func() but not "if (p) ..." - yyextra->code->codify(yytext); - uint s=0;while (s<(uint)yyleng && !isId(yytext[s])) s++; + if (isCastKeyword(yytext) && YY_START==Body) + { + REJECT; + } + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } +<Body>{SCOPENAME}/{BN}*[:;,)\]] { // "int var;" or "var, var2" or "debug(f) macro" , or int var : 5; + addType(yyscanner); + // changed this to generateFunctionLink, see bug 624514 + //generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,FALSE,TRUE); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } +<Body>{SCOPENAME}/{B}* { // p->func() + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } +<Body>"("{B}*("*"{B}*)+{SCOPENAME}+{B}*")"/{B}* { // (*p)->func() but not "if (p) ..." + yyextra->code->codify(yytext); + 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; - } + QCString varname = ((QCString)yytext).mid(s,e-s+1); + addType(yyscanner); + yyextra->name=varname; + } <Body>{SCOPETNAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{BN}*"(" | -<Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() or A\B\foo() - if (isCastKeyword(yytext)) - { - REJECT; - } - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); - } -<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{RAWBEGIN} { +<Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() or A\B\foo() + if (isCastKeyword(yytext)) + { + REJECT; + } + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); + } +<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{RAWBEGIN} { QCString text=yytext; uint i=(uint)text.find('R'); yyextra->code->codify(text.left(i+1)); - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext+i+1); - yyextra->lastStringContext=YY_START; - yyextra->inForEachExpression = FALSE; + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext+i+1); + yyextra->lastStringContext=YY_START; + yyextra->inForEachExpression = FALSE; yyextra->delimiter = yytext+i+2; yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1); - BEGIN( RawString ); - } -<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\" { - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; - yyextra->inForEachExpression = FALSE; - BEGIN( SkipString ); - } + BEGIN( RawString ); + } +<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\" { + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; + yyextra->inForEachExpression = FALSE; + BEGIN( SkipString ); + } <FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{NUMBER} { //Note similar code in commentcnv.l if (yyextra->lang!=SrcLangExt_Cpp) REJECT; - yyextra->code->codify(yytext); - } -<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\' { - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; - yyextra->inForEachExpression = FALSE; - BEGIN( SkipStringS ); - } -<SkipString>[^\"\\\r\n]* { - yyextra->code->codify(yytext); - } -<SkipStringS>[^\'\\\r\n]* { - yyextra->code->codify(yytext); - } -<SkipString,SkipStringS>"//"|"/*" { - yyextra->code->codify(yytext); - } -<SkipString>@?\" { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastStringContext ); - } -<SkipStringS>\' { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastStringContext ); - } -<SkipString,SkipStringS>\\. { - yyextra->code->codify(yytext); - } -<RawString>{RAWEND} { + yyextra->code->codify(yytext); + } +<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\' { + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; + yyextra->inForEachExpression = FALSE; + BEGIN( SkipStringS ); + } +<SkipString>[^\"\\\r\n]* { + yyextra->code->codify(yytext); + } +<SkipStringS>[^\'\\\r\n]* { + yyextra->code->codify(yytext); + } +<SkipString,SkipStringS>"//"|"/*" { + yyextra->code->codify(yytext); + } +<SkipString>@?\" { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastStringContext ); + } +<SkipStringS>\' { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastStringContext ); + } +<SkipString,SkipStringS>\\. { + yyextra->code->codify(yytext); + } +<RawString>{RAWEND} { yyextra->code->codify(yytext); QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); if (delimiter==yyextra->delimiter) { - BEGIN( yyextra->lastStringContext ); + BEGIN( yyextra->lastStringContext ); } } <RawString>[^)\n]+ { yyextra->code->codify(yytext); } <RawString>. { yyextra->code->codify(yytext); } <RawString>\n { codifyLines(yyscanner,yytext); } -<SkipVerbString>[^"\n]+ { - yyextra->code->codify(yytext); - } -<SkipVerbString>\"\" { // escaped quote - yyextra->code->codify(yytext); - } -<SkipVerbString>\" { // end of string - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastVerbStringContext ); - } -<SkipVerbString>. { - yyextra->code->codify(yytext); - } -<SkipVerbString>\n { - codifyLines(yyscanner,yytext); - } -<Body>":" { - yyextra->code->codify(yytext); - yyextra->name.resize(0);yyextra->type.resize(0); - } -<Body>"<" { - if (yyextra->insideTemplate) - { - yyextra->sharpCount++; - } - yyextra->code->codify(yytext); - } -<Body>">" { - if (yyextra->insideTemplate) - { - if (--yyextra->sharpCount<=0) - { - yyextra->insideTemplate=FALSE; - } - } - yyextra->code->codify(yytext); - } -<Body,MemberCall,MemberCall2,FuncCall>"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" { - startFontClass(yyscanner,"charliteral"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -<Body>"."|"->" { - if (yytext[0]=='-') // -> could be overloaded - { - updateCallContextForSmartPointer(yyscanner); - } - yyextra->code->codify(yytext); - yyextra->memCallContext = YY_START; - BEGIN( MemberCall ); - } -<MemberCall>{SCOPETNAME}/{BN}*"(" { - if (yyextra->theCallContext.getScope()) - { - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - } - yyextra->name.resize(0); - } - else - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - yyextra->name.resize(0); - } - yyextra->type.resize(0); - if (yyextra->memCallContext==Body) - { - BEGIN(FuncCall); - } - else - { - BEGIN(yyextra->memCallContext); - } - } -<MemberCall>{SCOPENAME}/{B}* { - if (yyextra->theCallContext.getScope()) - { - DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope())); - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - } - yyextra->name.resize(0); - } - else - { - DBG_CTX((stderr,"no class context!\n")); - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - yyextra->name.resize(0); - } - yyextra->type.resize(0); - BEGIN(yyextra->memCallContext); - } -<Body>[,=;\[] { - if (yyextra->insideObjC && *yytext=='[') - { - //printf("Found start of ObjC call!\n"); - // start of a method call - yyextra->contextMap.clear(); - yyextra->nameMap.clear(); - yyextra->objectMap.clear(); - yyextra->wordMap.clear(); +<SkipVerbString>[^"\n]+ { + yyextra->code->codify(yytext); + } +<SkipVerbString>\"\" { // escaped quote + yyextra->code->codify(yytext); + } +<SkipVerbString>\" { // end of string + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastVerbStringContext ); + } +<SkipVerbString>. { + yyextra->code->codify(yytext); + } +<SkipVerbString>\n { + codifyLines(yyscanner,yytext); + } +<Body>":" { + yyextra->code->codify(yytext); + yyextra->name.resize(0);yyextra->type.resize(0); + } +<Body>"<" { + if (yyextra->insideTemplate) + { + yyextra->sharpCount++; + } + yyextra->code->codify(yytext); + } +<Body>">" { + if (yyextra->insideTemplate) + { + if (--yyextra->sharpCount<=0) + { + yyextra->insideTemplate=FALSE; + } + } + yyextra->code->codify(yytext); + } +<Body,MemberCall,MemberCall2,FuncCall>"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" { + startFontClass(yyscanner,"charliteral"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +<Body>"."|"->" { + if (yytext[0]=='-') // -> could be overloaded + { + updateCallContextForSmartPointer(yyscanner); + } + yyextra->code->codify(yytext); + yyextra->memCallContext = YY_START; + BEGIN( MemberCall ); + } +<MemberCall>{SCOPETNAME}/{BN}*"(" { + if (yyextra->theCallContext.getScope()) + { + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + } + yyextra->name.resize(0); + } + else + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + yyextra->name.resize(0); + } + yyextra->type.resize(0); + if (yyextra->memCallContext==Body) + { + BEGIN(FuncCall); + } + else + { + BEGIN(yyextra->memCallContext); + } + } +<MemberCall>{SCOPENAME}/{B}* { + if (yyextra->theCallContext.getScope()) + { + DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope())); + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + } + yyextra->name.resize(0); + } + else + { + DBG_CTX((stderr,"no class context!\n")); + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + yyextra->name.resize(0); + } + yyextra->type.resize(0); + BEGIN(yyextra->memCallContext); + } +<Body>[,=;\[] { + if (yyextra->insideObjC && *yytext=='[') + { + //printf("Found start of ObjC call!\n"); + // start of a method call + yyextra->contextMap.clear(); + yyextra->nameMap.clear(); + yyextra->objectMap.clear(); + yyextra->wordMap.clear(); yyextra->commentMap.clear(); - yyextra->currentCtxId = 0; - yyextra->currentNameId = 0; - yyextra->currentObjId = 0; - yyextra->currentCtx = 0; - yyextra->braceCount = 0; - unput('['); - BEGIN(ObjCCall); - } - else - { - yyextra->code->codify(yytext); - yyextra->saveName = yyextra->name.copy(); - yyextra->saveType = yyextra->type.copy(); - if (*yytext!='[' && !yyextra->type.isEmpty()) - { - //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom()); - //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363 - { - //printf("AddVariable: '%s' '%s' context=%d\n", - // yyextra->type.data(),yyextra->name.data(),yyextra->theVarContext.count()); - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); - } - yyextra->name.resize(0); - } - if (*yytext==';' || *yytext=='=') - { - yyextra->type.resize(0); - yyextra->name.resize(0); - } - else if (*yytext=='[') - { - yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); - } - yyextra->args.resize(0); + yyextra->currentCtxId = 0; + yyextra->currentNameId = 0; + yyextra->currentObjId = 0; + yyextra->currentCtx = 0; + yyextra->braceCount = 0; + unput('['); + BEGIN(ObjCCall); + } + else + { + yyextra->code->codify(yytext); + yyextra->saveName = yyextra->name.copy(); + yyextra->saveType = yyextra->type.copy(); + if (*yytext!='[' && !yyextra->type.isEmpty()) + { + //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom()); + //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363 + { + //printf("AddVariable: '%s' '%s' context=%d\n", + // yyextra->type.data(),yyextra->name.data(),yyextra->theVarContext.count()); + yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + } + yyextra->name.resize(0); + } + if (*yytext==';' || *yytext=='=') + { + yyextra->type.resize(0); + yyextra->name.resize(0); + } + else if (*yytext=='[') + { + yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); + } + yyextra->args.resize(0); yyextra->parmType.resize(0); yyextra->parmName.resize(0); - } - } + } + } /* -<ObjCMemberCall>{ID} { - if (qstrcmp(yytext,"self")==0 || qstrcmp(yytext,"super")==0) - { - // TODO: get proper base class for "super" - yyextra->theCallContext.setClass(getClass(yyextra->curClassName)); - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } - else - { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } - yyextra->name.resize(0); - BEGIN(ObjCMemberCall2); - } -<ObjCMemberCall>"[" { - yyextra->code->codify(yytext); - yyextra->theCallContext.pushScope(yyscanner,yyextra->name, yyextra->type); - } -<ObjCMemberCall2>{ID}":"? { - yyextra->name+=yytext; - if (yyextra->theCallContext.getClass()) - { - //printf("Calling method %s\n",yyextra->name.data()); - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getClass(),yyextra->name)) - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yyextra->name); - } - } - else - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yyextra->name); - } - yyextra->name.resize(0); - BEGIN(ObjCMemberCall3); - } -<ObjCMemberCall2,ObjCMemberCall3>"]" { - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->code->codify(yytext); - BEGIN(Body); - } +<ObjCMemberCall>{ID} { + if (qstrcmp(yytext,"self")==0 || qstrcmp(yytext,"super")==0) + { + // TODO: get proper base class for "super" + yyextra->theCallContext.setClass(getClass(yyextra->curClassName)); + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } + else + { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } + yyextra->name.resize(0); + BEGIN(ObjCMemberCall2); + } +<ObjCMemberCall>"[" { + yyextra->code->codify(yytext); + yyextra->theCallContext.pushScope(yyscanner,yyextra->name, yyextra->type); + } +<ObjCMemberCall2>{ID}":"? { + yyextra->name+=yytext; + if (yyextra->theCallContext.getClass()) + { + //printf("Calling method %s\n",yyextra->name.data()); + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getClass(),yyextra->name)) + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yyextra->name); + } + } + else + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yyextra->name); + } + yyextra->name.resize(0); + BEGIN(ObjCMemberCall3); + } +<ObjCMemberCall2,ObjCMemberCall3>"]" { + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->code->codify(yytext); + BEGIN(Body); + } */ <ObjCCall,ObjCMName>"["|"{" { saveObjCContext(yyscanner); - yyextra->currentCtx->format+=*yytext; - BEGIN(ObjCCall); - //printf("open\n"); + yyextra->currentCtx->format+=*yytext; + BEGIN(ObjCCall); + //printf("open\n"); } <ObjCCall,ObjCMName>"]"|"}" { - yyextra->currentCtx->format+=*yytext; + yyextra->currentCtx->format+=*yytext; restoreObjCContext(yyscanner); - BEGIN(ObjCMName); - if (yyextra->currentCtx==0) - { - // end of call + BEGIN(ObjCMName); + if (yyextra->currentCtx==0) + { + // end of call ObjCCallCtx *ctx = 0; auto it = yyextra->contextMap.find(0); if (it!=yyextra->contextMap.end()) { ctx = it->second.get(); } - writeObjCMethodCall(yyscanner,ctx); - BEGIN(Body); - } - //printf("close\n"); + writeObjCMethodCall(yyscanner,ctx); + BEGIN(Body); + } + //printf("close\n"); } <ObjCCall,ObjCMName>"//".* { yyextra->currentCtx->format+=escapeComment(yyscanner,yytext); @@ -1531,92 +1531,92 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->currentCtx->comment=yytext; BEGIN(ObjCCallComment); } -<ObjCCallComment>"*/" { +<ObjCCallComment>"*/" { yyextra->currentCtx->comment+=yytext; yyextra->currentCtx->format+=escapeComment(yyscanner,yyextra->currentCtx->comment); - BEGIN(yyextra->lastObjCCallContext); - } + BEGIN(yyextra->lastObjCCallContext); + } <ObjCCallComment>[^*\n]+ { yyextra->currentCtx->comment+=yytext; } <ObjCCallComment>"//"|"/*" { yyextra->currentCtx->comment+=yytext; } <ObjCCallComment>\n { yyextra->currentCtx->comment+=*yytext; } <ObjCCallComment>. { yyextra->currentCtx->comment+=*yytext; } -<ObjCCall>{ID} { +<ObjCCall>{ID} { yyextra->currentCtx->format+=escapeObject(yyscanner,yytext); - if (yyextra->braceCount==0) - { - yyextra->currentCtx->objectTypeOrName=yytext; + if (yyextra->braceCount==0) + { + yyextra->currentCtx->objectTypeOrName=yytext; //printf("new type=%s\n",yyextra->currentCtx->objectTypeOrName.data()); - BEGIN(ObjCMName); - } - } -<ObjCMName>{ID}/{BN}*"]" { - if (yyextra->braceCount==0 && - yyextra->currentCtx->methodName.isEmpty()) + BEGIN(ObjCMName); + } + } +<ObjCMName>{ID}/{BN}*"]" { + if (yyextra->braceCount==0 && + yyextra->currentCtx->methodName.isEmpty()) { - yyextra->currentCtx->methodName=yytext; + yyextra->currentCtx->methodName=yytext; yyextra->currentCtx->format+=escapeName(yyscanner,yytext); - } - else - { + } + else + { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); - } + } } -<ObjCMName>{ID}/{BN}*":" { +<ObjCMName>{ID}/{BN}*":" { if (yyextra->braceCount==0) { - yyextra->currentCtx->methodName+=yytext; + yyextra->currentCtx->methodName+=yytext; yyextra->currentCtx->methodName+=":"; - } + } yyextra->currentCtx->format+=escapeName(yyscanner,yytext); } <ObjCSkipStr>[^\n\"$\\]* { yyextra->currentCtx->format+=yytext; } -<ObjCSkipStr>\\. { yyextra->currentCtx->format+=yytext; } -<ObjCSkipStr>"\"" { yyextra->currentCtx->format+=yytext; - BEGIN(yyextra->lastStringContext); +<ObjCSkipStr>\\. { yyextra->currentCtx->format+=yytext; } +<ObjCSkipStr>"\"" { yyextra->currentCtx->format+=yytext; + BEGIN(yyextra->lastStringContext); } <ObjCCall,ObjCMName>{CHARLIT} { yyextra->currentCtx->format+=yytext; } -<ObjCCall,ObjCMName>"@"?"\"" { yyextra->currentCtx->format+=yytext; +<ObjCCall,ObjCMName>"@"?"\"" { yyextra->currentCtx->format+=yytext; yyextra->lastStringContext=YY_START; - BEGIN(ObjCSkipStr); + BEGIN(ObjCSkipStr); } <ObjCCall,ObjCMName,ObjCSkipStr>"$" { yyextra->currentCtx->format+="$$"; } <ObjCCall,ObjCMName>"(" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount++; } <ObjCCall,ObjCMName>")" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount--; } -<ObjCSkipStr>"@"/"\"" { // needed to prevent matching the global rule (for C#) +<ObjCSkipStr>"@"/"\"" { // needed to prevent matching the global rule (for C#) yyextra->currentCtx->format+=yytext; } <ObjCCall,ObjCMName,ObjCSkipStr>{ID} { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); } <ObjCCall,ObjCMName,ObjCSkipStr>. { yyextra->currentCtx->format+=*yytext; } <ObjCCall,ObjCMName,ObjCSkipStr>\n { yyextra->currentCtx->format+=*yytext; } -<Body>"]" { - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->code->codify(yytext); - // TODO: nested arrays like: a[b[0]->func()]->func() - yyextra->name = yyextra->saveName.copy(); - yyextra->type = yyextra->saveType.copy(); - } -<Body>[0-9]+ { - yyextra->code->codify(yytext); - } -<Body>[0-9]+[xX][0-9A-Fa-f]+ { - yyextra->code->codify(yytext); - } +<Body>"]" { + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->code->codify(yytext); + // TODO: nested arrays like: a[b[0]->func()]->func() + yyextra->name = yyextra->saveName.copy(); + yyextra->type = yyextra->saveType.copy(); + } +<Body>[0-9]+ { + yyextra->code->codify(yytext); + } +<Body>[0-9]+[xX][0-9A-Fa-f]+ { + yyextra->code->codify(yytext); + } <MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) { - //addParmType(yyscanner); - //yyextra->parmName=yytext; + //addParmType(yyscanner); + //yyextra->parmName=yytext; if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } <MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKW}/([^a-z_A-Z0-9]) { - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } <MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKWSL}/([^a-z_A-Z0-9]) { if (yyextra->lang!=SrcLangExt_Slice) { @@ -1624,20 +1624,20 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } else { - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); } - } + } <MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) { - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordflow"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordflow"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } <MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { @@ -1650,25 +1650,25 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); } <MemberCall2,FuncCall>{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* { - if (isCastKeyword(yytext)) - { - REJECT; - } - addParmType(yyscanner); - yyextra->parmName=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); - } -<FuncCall>";" { // probably a cast, not a function call - yyextra->code->codify(yytext); - yyextra->inForEachExpression = FALSE; - BEGIN( Body ); - } -<MemberCall2,FuncCall>, { - yyextra->code->codify(yytext); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - } -<MemberCall2,FuncCall>"{" { + if (isCastKeyword(yytext)) + { + REJECT; + } + addParmType(yyscanner); + yyextra->parmName=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); + } +<FuncCall>";" { // probably a cast, not a function call + yyextra->code->codify(yytext); + yyextra->inForEachExpression = FALSE; + BEGIN( Body ); + } +<MemberCall2,FuncCall>, { + yyextra->code->codify(yytext); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + } +<MemberCall2,FuncCall>"{" { if (yyextra->bracketCount>0) { yyextra->code->codify(yytext); @@ -1697,28 +1697,28 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} <InlineInit>. { yyextra->code->codify(yytext); } -<MemberCall2,FuncCall>"(" { - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - yyextra->code->codify(yytext); - yyextra->bracketCount++; - yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); - if (YY_START==FuncCall && !yyextra->insideBody) - { - yyextra->theVarContext.pushScope(); - } - } +<MemberCall2,FuncCall>"(" { + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + yyextra->code->codify(yytext); + yyextra->bracketCount++; + yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); + if (YY_START==FuncCall && !yyextra->insideBody) + { + yyextra->theVarContext.pushScope(); + } + } <MemberCall2,FuncCall>{OPERATOR} { // operator - if (qstrcmp(yytext,"*") && - qstrcmp(yytext,"&") && - qstrcmp(yytext,"^") && - qstrcmp(yytext,"%")) // typically a pointer or reference - { - // not a * or &, or C++/CLI's ^ or % - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - } - yyextra->code->codify(yytext); - } -<MemberCall,MemberCall2,FuncCall>("*"{B}*)?")" { + if (qstrcmp(yytext,"*") && + qstrcmp(yytext,"&") && + qstrcmp(yytext,"^") && + qstrcmp(yytext,"%")) // typically a pointer or reference + { + // not a * or &, or C++/CLI's ^ or % + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + } + yyextra->code->codify(yytext); + } +<MemberCall,MemberCall2,FuncCall>("*"{B}*)?")" { if (yytext[0]==')') // no a pointer cast { //printf("addVariable(%s,%s)\n",yyextra->parmType.data(),yyextra->parmName.data()); @@ -1727,281 +1727,281 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->parmType=yyextra->parmName; yyextra->parmName.resize(0); } - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); } else { yyextra->parmType = yyextra->parmName; yyextra->parmName.resize(0); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - } - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->inForEachExpression = FALSE; - //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b(). - yyextra->code->codify(yytext); - if (--yyextra->bracketCount<=0) - { - if (yyextra->name.isEmpty()) - { - BEGIN( Body ); - } - else - { - BEGIN( CallEnd ); - } - } - } -<CallEnd>[ \t\n]* { codifyLines(yyscanner,yytext); } + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + } + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->inForEachExpression = FALSE; + //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b(). + yyextra->code->codify(yytext); + if (--yyextra->bracketCount<=0) + { + if (yyextra->name.isEmpty()) + { + BEGIN( Body ); + } + else + { + BEGIN( CallEnd ); + } + } + } +<CallEnd>[ \t\n]* { codifyLines(yyscanner,yytext); } /* -<MemberCall2,FuncCall>")"[ \t\n]*[;:] { +<MemberCall2,FuncCall>")"[ \t\n]*[;:] { */ -<CallEnd>[;:] { - codifyLines(yyscanner,yytext); - yyextra->bracketCount=0; - if (*yytext==';') yyextra->searchingForBody=FALSE; - if (!yyextra->type.isEmpty()) - { - DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",yyextra->type.data(),yyextra->name.data())); - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); - } - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - yyextra->theCallContext.setScope(0); - if (*yytext==';' || yyextra->insideBody) - { - if (!yyextra->insideBody) - { +<CallEnd>[;:] { + codifyLines(yyscanner,yytext); + yyextra->bracketCount=0; + if (*yytext==';') yyextra->searchingForBody=FALSE; + if (!yyextra->type.isEmpty()) + { + DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",yyextra->type.data(),yyextra->name.data())); + yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + } + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + yyextra->theCallContext.setScope(0); + if (*yytext==';' || yyextra->insideBody) + { + if (!yyextra->insideBody) + { yyextra->theVarContext.popScope(); - } - yyextra->name.resize(0);yyextra->type.resize(0); - BEGIN( Body ); - } - else - { - yyextra->bracketCount=0; - BEGIN( SkipInits ); - } - } + } + yyextra->name.resize(0);yyextra->type.resize(0); + BEGIN( Body ); + } + else + { + yyextra->bracketCount=0; + BEGIN( SkipInits ); + } + } <CallEnd>("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"sealed"|"override"))*/{BN}*(";"|"="|"throw"{BN}*"(") { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } <CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" { if (yyextra->insideBody) - { - yyextra->theVarContext.pushScope(); - } - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - //yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - int index = yyextra->name.findRev("::"); - DBG_CTX((stderr,"yyextra->name=%s\n",yyextra->name.data())); - if (index!=-1) - { - 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) - { - setClassScope(yyscanner,cd->name()); - yyextra->scopeStack.push(SCOPEBLOCK); + { + yyextra->theVarContext.pushScope(); + } + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + //yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + int index = yyextra->name.findRev("::"); + DBG_CTX((stderr,"yyextra->name=%s\n",yyextra->name.data())); + if (index!=-1) + { + 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) + { + setClassScope(yyscanner,cd->name()); + yyextra->scopeStack.push(SCOPEBLOCK); DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - } - else - { - //setClassScope(yyscanner,yyextra->realScope); - yyextra->scopeStack.push(INNERBLOCK); + } + else + { + //setClassScope(yyscanner,yyextra->realScope); + yyextra->scopeStack.push(INNERBLOCK); DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - } - } - else - { + } + } + else + { DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - } - yytext[yyleng-1]='\0'; - QCString cv(yytext); - if (!cv.stripWhiteSpace().isEmpty()) - { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - else // just whitespace - { - codifyLines(yyscanner,yytext); - } - yyextra->code->codify("{"); - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN( Body ); - } -<CallEnd>"try" { // function-try-block - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->inFunctionTryBlock=TRUE; - } -<CallEnd>{ID} { - if (yyextra->insideBody || !yyextra->parmType.isEmpty()) - { - REJECT; - } - // could be K&R style definition - addParmType(yyscanner); - yyextra->parmName=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); - BEGIN(OldStyleArgs); - } -<OldStyleArgs>{ID} { - addParmType(yyscanner); - yyextra->parmName=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); - } -<OldStyleArgs>[,;] { - yyextra->code->codify(yytext); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - if (*yytext==';') yyextra->parmType.resize(0); - yyextra->parmName.resize(0); - } -<CallEnd,OldStyleArgs>"#" { - startFontClass(yyscanner,"preprocessor"); - yyextra->lastSkipCppContext = Body; - yyextra->code->codify(yytext); - BEGIN( SkipCPP ); - } -<CallEnd>. { - unput(*yytext); - if (!yyextra->insideBody) - { - yyextra->theVarContext.popScope(); - } - yyextra->name.resize(0);yyextra->args.resize(0); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - BEGIN( Body ); - } -<SkipInits>";" { - yyextra->code->codify(yytext); - yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN( Body ); - } -<SkipInits>"{" { - yyextra->code->codify(yytext); - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - if (yyextra->name.find("::")!=-1) - { + yyextra->scopeStack.push(INNERBLOCK); + } + yytext[yyleng-1]='\0'; + QCString cv(yytext); + if (!cv.stripWhiteSpace().isEmpty()) + { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + else // just whitespace + { + codifyLines(yyscanner,yytext); + } + yyextra->code->codify("{"); + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + yyextra->type.resize(0); yyextra->name.resize(0); + BEGIN( Body ); + } +<CallEnd>"try" { // function-try-block + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->inFunctionTryBlock=TRUE; + } +<CallEnd>{ID} { + if (yyextra->insideBody || !yyextra->parmType.isEmpty()) + { + REJECT; + } + // could be K&R style definition + addParmType(yyscanner); + yyextra->parmName=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); + BEGIN(OldStyleArgs); + } +<OldStyleArgs>{ID} { + addParmType(yyscanner); + yyextra->parmName=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); + } +<OldStyleArgs>[,;] { + yyextra->code->codify(yytext); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + if (*yytext==';') yyextra->parmType.resize(0); + yyextra->parmName.resize(0); + } +<CallEnd,OldStyleArgs>"#" { + startFontClass(yyscanner,"preprocessor"); + yyextra->lastSkipCppContext = Body; + yyextra->code->codify(yytext); + BEGIN( SkipCPP ); + } +<CallEnd>. { + unput(*yytext); + if (!yyextra->insideBody) + { + yyextra->theVarContext.popScope(); + } + yyextra->name.resize(0);yyextra->args.resize(0); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + BEGIN( Body ); + } +<SkipInits>";" { + yyextra->code->codify(yytext); + yyextra->type.resize(0); yyextra->name.resize(0); + BEGIN( Body ); + } +<SkipInits>"{" { + yyextra->code->codify(yytext); + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + if (yyextra->name.find("::")!=-1) + { DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - yyextra->scopeStack.push(SCOPEBLOCK); - setClassScope(yyscanner,yyextra->realScope); - } - else - { + yyextra->scopeStack.push(SCOPEBLOCK); + setClassScope(yyscanner,yyextra->realScope); + } + else + { DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - } - yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN( Body ); - } -<SkipInits>{ID} { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -<FuncCall>{ID}/"(" { - generateFunctionLink(yyscanner,*yyextra->code,yytext); - } -<FuncCall>{ID}/("."|"->") { - yyextra->name=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( MemberCall2 ); - } -<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") { - yyextra->code->codify(yytext); - uint s=0;while (!isId(yytext[s])) s++; + yyextra->scopeStack.push(INNERBLOCK); + } + yyextra->type.resize(0); yyextra->name.resize(0); + BEGIN( Body ); + } +<SkipInits>{ID} { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +<FuncCall>{ID}/"(" { + generateFunctionLink(yyscanner,*yyextra->code,yytext); + } +<FuncCall>{ID}/("."|"->") { + yyextra->name=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( MemberCall2 ); + } +<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") { + yyextra->code->codify(yytext); + 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 ); - } -<MemberCall2>{ID}/([ \t\n]*"(") { - if (!yyextra->args.isEmpty()) - generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext); - else - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->args.resize(0); - BEGIN( FuncCall ); - } + yyextra->name=((QCString)yytext).mid(s,e-s+1); + BEGIN( MemberCall2 ); + } +<MemberCall2>{ID}/([ \t\n]*"(") { + if (!yyextra->args.isEmpty()) + generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext); + else + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->args.resize(0); + BEGIN( FuncCall ); + } <MemberCall2>{ID}/([ \t\n]*("."|"->")) { - //yyextra->code->codify(yytext); - yyextra->name=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( MemberCall2 ); - } -<MemberCall2>"->"|"." { - if (yytext[0]=='-') // -> could be overloaded - { - updateCallContextForSmartPointer(yyscanner); - } - yyextra->code->codify(yytext); - yyextra->memCallContext = YY_START; - BEGIN( MemberCall ); - } -<SkipComment>"/*"("!"?)"*/" { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } -<SkipComment>"//"|"/*" { - yyextra->code->codify(yytext); - } -<SkipComment>[^*/\n]+ { - yyextra->code->codify(yytext); - } -<SkipComment>[ \t]*"*/" { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - if (yyextra->lastCContext==SkipCPP) + //yyextra->code->codify(yytext); + yyextra->name=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( MemberCall2 ); + } +<MemberCall2>"->"|"." { + if (yytext[0]=='-') // -> could be overloaded + { + updateCallContextForSmartPointer(yyscanner); + } + yyextra->code->codify(yytext); + yyextra->memCallContext = YY_START; + BEGIN( MemberCall ); + } +<SkipComment>"/*"("!"?)"*/" { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } +<SkipComment>"//"|"/*" { + yyextra->code->codify(yytext); + } +<SkipComment>[^*/\n]+ { + yyextra->code->codify(yytext); + } +<SkipComment>[ \t]*"*/" { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + if (yyextra->lastCContext==SkipCPP) { startFontClass(yyscanner,"preprocessor"); } - BEGIN( yyextra->lastCContext ) ; - } -<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation - codifyLines(yyscanner,yytext); - } -<SkipCxxComment>[^\r\n]+ { - yyextra->code->codify(yytext); - } -<SkipCxxComment>\r -<SkipCxxComment>\n { - unput('\n'); - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } -<SkipCxxComment>. { - yyextra->code->codify(yytext); - } + BEGIN( yyextra->lastCContext ) ; + } +<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation + codifyLines(yyscanner,yytext); + } +<SkipCxxComment>[^\r\n]+ { + yyextra->code->codify(yytext); + } +<SkipCxxComment>\r +<SkipCxxComment>\n { + unput('\n'); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } +<SkipCxxComment>. { + yyextra->code->codify(yytext); + } <RemoveSpecialCComment>"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)?{B}*"/*"[*!]/[^/*] { - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - } + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + } <RemoveSpecialCComment>"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)? { - if (yyextra->lastSpecialCContext==SkipCxxComment) - { // force end of C++ comment here - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - nextCodeLine(yyscanner); - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } - else - { - yyextra->yyLineNr+=QCString(yytext).contains('\n'); + if (yyextra->lastSpecialCContext==SkipCxxComment) + { // force end of C++ comment here + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + nextCodeLine(yyscanner); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } + else + { + yyextra->yyLineNr+=QCString(yytext).contains('\n'); if (yytext[yyleng-1]=='\n') { yyextra->yyLineNr--; @@ -2009,280 +2009,280 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } else { - nextCodeLine(yyscanner); + nextCodeLine(yyscanner); } - BEGIN(yyextra->lastSpecialCContext); - } - } -<RemoveSpecialCComment>"*/" { - BEGIN(yyextra->lastSpecialCContext); - } + BEGIN(yyextra->lastSpecialCContext); + } + } +<RemoveSpecialCComment>"*/" { + BEGIN(yyextra->lastSpecialCContext); + } <RemoveSpecialCComment>[^*\n]+ <RemoveSpecialCComment>"//"|"/*" <RemoveSpecialCComment>\n { yyextra->yyLineNr++; } <RemoveSpecialCComment>. -<MemberCall>[^a-z_A-Z0-9(\n] { - yyextra->code->codify(yytext); - yyextra->type.resize(0); - yyextra->name.resize(0); - BEGIN(yyextra->memCallContext); - } -<*>\n({B}*"//"[!/][^\n]*\n)+ { // remove special one-line comment - if (YY_START==SkipCPP) REJECT; - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - if (YY_START==SkipCxxComment) - { - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } - } -<SkipCPP>\n/.*\n { - endFontClass(yyscanner); - BEGIN( yyextra->lastSkipCppContext ) ; +<MemberCall>[^a-z_A-Z0-9(\n] { + yyextra->code->codify(yytext); + yyextra->type.resize(0); + yyextra->name.resize(0); + BEGIN(yyextra->memCallContext); + } +<*>\n({B}*"//"[!/][^\n]*\n)+ { // remove special one-line comment + if (YY_START==SkipCPP) REJECT; + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + nextCodeLine(yyscanner); + } + else + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + if (YY_START==SkipCxxComment) + { + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } + } +<SkipCPP>\n/.*\n { + endFontClass(yyscanner); + BEGIN( yyextra->lastSkipCppContext ) ; unput('\n'); - } -<*>\n{B}*"//@"[{}].*\n { // remove one-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr+=2; - nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - if (YY_START==SkipCxxComment) - { - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } - } -<*>\n{B}*"/*@"[{}] { // remove one-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - yyextra->yyLineNr++; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"//@"[{}].*\n { // remove one-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr++; - nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - } -<*>^{B}*"/*@"[{}] { // remove multi-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"//"[!/][^\n]*\n { // remove special one-line comment - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr++; - //nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - } -<*>"//"[!/][^\n]*/\n { // strip special one-line comment + } +<*>\n{B}*"//@"[{}].*\n { // remove one-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + yyextra->yyLineNr+=2; + nextCodeLine(yyscanner); + } + else + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + if (YY_START==SkipCxxComment) + { + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } + } +<*>\n{B}*"/*@"[{}] { // remove one-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + yyextra->yyLineNr++; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + BEGIN(SkipComment); + } + } +<*>^{B}*"//@"[{}].*\n { // remove one-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + yyextra->yyLineNr++; + nextCodeLine(yyscanner); + } + else + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + } +<*>^{B}*"/*@"[{}] { // remove multi-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>^{B}*"//"[!/][^\n]*\n { // remove special one-line comment + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + yyextra->yyLineNr++; + //nextCodeLine(yyscanner); + } + else + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + } +<*>"//"[!/][^\n]*/\n { // strip special one-line comment if (YY_START==SkipComment || YY_START==SkipString) REJECT; - if (!Config_getBool(STRIP_CODE_COMMENTS)) - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - } -<*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file - yyextra->forceTagReference=yytext; - uint s=(uint)yyextra->forceTagReference.find(':'); - uint e=(uint)yyextra->forceTagReference.findRev(']'); - yyextra->forceTagReference = yyextra->forceTagReference.mid(s+1,e-s-1); - } -<*>\n{B}*"/*"[!*]/[^/*] { - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - yyextra->yyLineNr++; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"/**"[*]+/[^/] { // special C "banner" comment block at a new line - if (Config_getBool(JAVADOC_BANNER) && Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"/*"[!*]/[^/*] { // special C comment block at a new line - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>"/*"[!*]/[^/*] { // special C comment block half way a line + if (!Config_getBool(STRIP_CODE_COMMENTS)) + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + } +<*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file + yyextra->forceTagReference=yytext; + uint s=(uint)yyextra->forceTagReference.find(':'); + uint e=(uint)yyextra->forceTagReference.findRev(']'); + yyextra->forceTagReference = yyextra->forceTagReference.mid(s+1,e-s-1); + } +<*>\n{B}*"/*"[!*]/[^/*] { + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + yyextra->yyLineNr++; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + BEGIN(SkipComment); + } + } +<*>^{B}*"/**"[*]+/[^/] { // special C "banner" comment block at a new line + if (Config_getBool(JAVADOC_BANNER) && Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>^{B}*"/*"[!*]/[^/*] { // special C comment block at a new line + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>"/*"[!*]/[^/*] { // special C comment block half way a line if (YY_START==SkipString) REJECT; - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>"/*"("!"?)"*/" { + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>"/*"("!"?)"*/" { if (YY_START==SkipString) REJECT; if (!Config_getBool(STRIP_CODE_COMMENTS)) - { - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } - } + { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } + } <SkipComment>[^\*\n]+ { yyextra->code->codify(yytext); } -<*>"/*" { - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - BEGIN( SkipComment ) ; - } -<*>@\" { // C# verbatim string - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext); - yyextra->lastVerbStringContext=YY_START; - BEGIN(SkipVerbString); - } -<*>"//" { - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - yyextra->lastCContext = YY_START ; - BEGIN( SkipCxxComment ) ; - } -<*>"("|"[" { - yyextra->code->codify(yytext); - yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); - } -<*>")"|"]" { - yyextra->code->codify(yytext); - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - } -<*>\n { - yyextra->yyColNr++; - codifyLines(yyscanner,yytext); - } +<*>"/*" { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + BEGIN( SkipComment ) ; + } +<*>@\" { // C# verbatim string + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext); + yyextra->lastVerbStringContext=YY_START; + BEGIN(SkipVerbString); + } +<*>"//" { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + yyextra->lastCContext = YY_START ; + BEGIN( SkipCxxComment ) ; + } +<*>"("|"[" { + yyextra->code->codify(yytext); + yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); + } +<*>")"|"]" { + yyextra->code->codify(yytext); + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + } +<*>\n { + yyextra->yyColNr++; + codifyLines(yyscanner,yytext); + } <*>[\x80-\xFF]* { // keep utf8 characters together... - yyextra->yyColNr+=yyleng; - yyextra->code->codify(yytext); + yyextra->yyColNr+=yyleng; + yyextra->code->codify(yytext); + } +<*>. { + yyextra->yyColNr++; + yyextra->code->codify(yytext); } -<*>. { - yyextra->yyColNr++; - yyextra->code->codify(yytext); - } /* -<*>([ \t\n]*"\n"){2,} { // combine multiple blank lines - //QCString sepLine=yytext; - //yyextra->code->codify("\n\n"); - //yyextra->yyLineNr+=sepLine.contains('\n'); - //char sepLine[3]="\n\n"; - codifyLines(yyscanner,yytext); - } +<*>([ \t\n]*"\n"){2,} { // combine multiple blank lines + //QCString sepLine=yytext; + //yyextra->code->codify("\n\n"); + //yyextra->yyLineNr+=sepLine.contains('\n'); + //char sepLine[3]="\n\n"; + codifyLines(yyscanner,yytext); + } */ %% @@ -2296,7 +2296,7 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const //printf("VariableContext::addVariable(%s,%s)\n",type.data(),name.data()); QCString ltype = type.simplifyWhiteSpace(); QCString lname = name.simplifyWhiteSpace(); - if (ltype.left(7)=="struct ") + if (ltype.left(7)=="struct ") { ltype = ltype.right(ltype.length()-7); } @@ -2305,8 +2305,8 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const ltype = ltype.right(ltype.length()-6); } if (ltype.isEmpty() || lname.isEmpty()) return; - DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n", - ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>")); + DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n", + ltype.data(),lname.data(),yyextra->currentDefinition?yyextra->currentDefinition->name().data():"<none>")); Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back(); const ClassDef *varType = 0; auto it = yyextra->codeClassMap.find(ltype.str()); @@ -2357,9 +2357,9 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const addVariable(yyscanner,typeName,name); } } - else + else { - if (!m_scopes.empty()) // for local variables add a dummy entry so the name + if (!m_scopes.empty()) // for local variables add a dummy entry so the name // is hidden to avoid false links to global variables with the same name // TODO: make this work for namespaces as well! { @@ -2507,7 +2507,7 @@ static void startCodeLine(yyscan_t yyscanner) //QCString lineNumber,lineAnchor; //lineNumber.sprintf("%05d",yyextra->yyLineNr); //lineAnchor.sprintf("l%05d",yyextra->yyLineNr); - + Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr); //printf("%s:startCodeLine(%d)=%p\n",yyextra->sourceFileDef->name().data(),yyextra->yyLineNr,d); if (!yyextra->includeCodeFragment && d) @@ -2530,15 +2530,15 @@ static void startCodeLine(yyscan_t yyscanner) if (yyextra->currentMemberDef) { yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(), - yyextra->currentMemberDef->getOutputFileBase(), - yyextra->currentMemberDef->anchor(),yyextra->yyLineNr); + yyextra->currentMemberDef->getOutputFileBase(), + yyextra->currentMemberDef->anchor(),yyextra->yyLineNr); setCurrentDoc(yyscanner,lineAnchor); } else if (d->isLinkableInProject()) { yyextra->code->writeLineNumber(d->getReference(), - d->getOutputFileBase(), - 0,yyextra->yyLineNr); + d->getOutputFileBase(), + 0,yyextra->yyLineNr); setCurrentDoc(yyscanner,lineAnchor); } } @@ -2548,7 +2548,7 @@ static void startCodeLine(yyscan_t yyscanner) } } DBG_CTX((stderr,"startCodeLine(%d)\n",yyextra->yyLineNr)); - yyextra->code->startCodeLine(yyextra->sourceFileDef && yyextra->lineNumbers); + yyextra->code->startCodeLine(yyextra->sourceFileDef && yyextra->lineNumbers); if (yyextra->currentFontClass) { yyextra->code->startFontClass(yyextra->currentFontClass); @@ -2570,7 +2570,7 @@ static void nextCodeLine(yyscan_t yyscanner) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; const char * fc = yyextra->currentFontClass; endCodeLine(yyscanner); - if (yyextra->yyLineNr<yyextra->inputLines) + if (yyextra->yyLineNr<yyextra->inputLines) { yyextra->currentFontClass = fc; startCodeLine(yyscanner); @@ -2612,7 +2612,7 @@ static void codifyLines(yyscan_t yyscanner,const char *text) } /*! 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(yyscan_t yyscanner,CodeOutputInterface &ol, @@ -2625,7 +2625,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,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(); @@ -2680,7 +2680,7 @@ static void addUsingDirective(yyscan_t yyscanner,const char *name) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (yyextra->sourceFileDef && name) { - NamespaceDef *nd = Doxygen::namespaceSDict->find(name); + const NamespaceDef *nd = Doxygen::namespaceSDict->find(name); if (nd) { yyextra->sourceFileDef->addUsingDirective(nd); @@ -2706,7 +2706,7 @@ static void setParameterList(yyscan_t yyscanner,const MemberDef *md) } } -static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,Definition *d) +static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Definition *d) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; int pos=0; @@ -2747,7 +2747,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) QCString scope = name.left(scopeEnd); QCString locName = name.right(name.length()-scopeEnd-2); //printf("explicit scope: name=%s scope=%s\n",locName.data(),scope.data()); - ClassDef *mcd = getClass(scope); + const ClassDef *mcd = getClass(scope); if (mcd && !locName.isEmpty()) { MemberDef *md=mcd->getMemberByName(locName); @@ -2763,18 +2763,18 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) const NamespaceDef *mnd = getResolvedNamespace(scope); if (mnd && !locName.isEmpty()) { - MemberDef *md=mnd->getMemberByName(locName); - if (md) - { - //printf("name=%s scope=%s\n",locName.data(),scope.data()); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - return md; - } + MemberDef *md=mnd->getMemberByName(locName); + if (md) + { + //printf("name=%s scope=%s\n",locName.data(),scope.data()); + yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + return md; + } } } } - - MemberName *mn; + + const MemberName *mn; const ClassDef *mcd = yyextra->theVarContext.findVariable(name); if (mcd) // local variable { @@ -2788,21 +2788,21 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) else { DBG_CTX((stderr,"class member? scope=%s\n",yyextra->classScope.data())); - // look for a class member + // look for a class member mcd = getClass(yyextra->classScope); if (mcd) { DBG_CTX((stderr,"Inside class %s\n",mcd->name().data())); MemberDef *md=mcd->getMemberByName(name); - if (md) + if (md) { DBG_CTX((stderr,"Found member %s\n",md->name().data())); - if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK) - { + if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK) + { DBG_CTX((stderr,"class member '%s' mcd=%s\n",name.data(),mcd->name().data())); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - } - return md; + yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + } + return md; } } } @@ -2825,19 +2825,19 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) { for (const auto &md : *mn) { - //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n", - // mn,md, - // md->getBodyDef(),yyextra->sourceFileDef); + //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n", + // mn,md, + // md->getBodyDef(),yyextra->sourceFileDef); - // in case there are multiple members we could link to, we - // only link to members if defined in the same file or - // defined as external. + // in case there are multiple members we could link to, we + // only link to members if defined in the same file or + // defined as external. if ((!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) && - (yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference()) - ) + (yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference()) + ) { 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()); + //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); return md.get(); } } @@ -2852,7 +2852,7 @@ static void updateCallContextForSmartPointer(yyscan_t yyscanner) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; const Definition *d = yyextra->theCallContext.getScope(); //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : "<none>"); - MemberDef *md; + const MemberDef *md; if (d && d->definitionType()==Definition::TypeClass && (md=(dynamic_cast<const ClassDef*>(d))->isSmartPointer())) { const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope()); @@ -2867,11 +2867,11 @@ static void updateCallContextForSmartPointer(yyscan_t yyscanner) static bool getLinkInScope(yyscan_t yyscanner, const QCString &c, // scope const QCString &m, // member - const char *memberText, // exact text - CodeOutputInterface &ol, - const char *text, - bool varOnly - ) + const char *memberText, // exact text + CodeOutputInterface &ol, + const char *text, + bool varOnly + ) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; const MemberDef *md = 0; @@ -2880,7 +2880,7 @@ static bool getLinkInScope(yyscan_t yyscanner, const NamespaceDef *nd = 0; const GroupDef *gd = 0; DBG_CTX((stderr,"getLinkInScope: trying '%s'::'%s' varOnly=%d\n",c.data(),m.data(),varOnly)); - if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,yyextra->sourceFileDef,FALSE,yyextra->forceTagReference) && + if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,yyextra->sourceFileDef,FALSE,yyextra->forceTagReference) && (!varOnly || md->isVariable())) { if (md->isLinkable()) @@ -2933,9 +2933,9 @@ static bool getLinkInScope(yyscan_t yyscanner, static bool getLink(yyscan_t yyscanner, const char *className, const char *memberName, - CodeOutputInterface &ol, - const char *text, - bool varOnly) + CodeOutputInterface &ol, + const char *text, + bool varOnly) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("getLink(%s,%s) yyextra->curClassName=%s\n",className,memberName,yyextra->curClassName.data()); @@ -2988,11 +2988,11 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, //printf("generateClassOrGlobalLink(className=%s)\n",className.data()); if (!yyextra->prefixed_with_this_keyword || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable { - Definition *d = yyextra->currentDefinition; + const Definition *d = yyextra->currentDefinition; //printf("d=%s yyextra->sourceFileDef=%s\n",d?d->name().data():"<none>",yyextra->sourceFileDef?yyextra->sourceFileDef->name().data():"<none>"); cd = getResolvedClass(d,yyextra->sourceFileDef,className,&md); - DBG_CTX((stderr,"non-local variable name=%s context=%d cd=%s md=%s!\n", - className.data(),yyextra->theVarContext.count(),cd?cd->name().data():"<none>", + DBG_CTX((stderr,"non-local variable name=%s cd=%s md=%s!\n", + className.data(),cd?cd->name().data():"<none>", md?md->name().data():"<none>")); if (cd==0 && md==0 && (i=className.find('<'))!=-1) { @@ -3000,7 +3000,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, DBG_CTX((stderr,"bareName=%s\n",bareName.data())); if (bareName!=className) { - cd=getResolvedClass(d,yyextra->sourceFileDef,bareName,&md); // try unspecialized version + cd=getResolvedClass(d,yyextra->sourceFileDef,bareName,&md); // try unspecialized version } } const NamespaceDef *nd = getResolvedNamespace(className); @@ -3019,24 +3019,24 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, { if (getLink(yyscanner,yyextra->classScope,clName,ol,clName,varOnly)) { - return; + return; } } } else { //printf("local variable!\n"); - if (lcd!=VariableContext::dummyContext) + if (lcd!=VariableContext::dummyContext) { //printf("non-dummy context lcd=%s!\n",lcd->name().data()); yyextra->theCallContext.setScope(lcd); // to following is needed for links to a global variable, but is // no good for a link to a local variable that is also a global symbol. - + //if (getLink(yyscanner,yyextra->classScope,clName,ol,clName)) //{ - //return; + //return; //} } isLocal=TRUE; @@ -3055,8 +3055,8 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, // yyextra->exampleFile.data()); if (const_cast<ClassDef*>(cd)->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) { - ol.writeCodeAnchor(anchor); - yyextra->anchorCount++; + ol.writeCodeAnchor(anchor); + yyextra->anchorCount++; } } writeMultiLineCodeLink(yyscanner,ol,cd,clName); @@ -3067,7 +3067,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, const Definition *d = md->getOuterScope()==Doxygen::globalScope ? md->getFileDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); - if (d && d->isLinkable() && md->isLinkable() && + if (d && d->isLinkable() && md->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); @@ -3081,55 +3081,55 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, { if (md==0) // not found as a typedef { - md = setCallContextForVar(yyscanner,clName); - //printf("setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",clName,md,yyextra->currentDefinition); - if (md && yyextra->currentDefinition) - { - DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n", - md->name().data(),yyextra->currentDefinition->name().data(), - isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md), - md->getOuterScope()->name().data())); - } - - if (md && yyextra->currentDefinition && - isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1) - { - md=0; // variable not accessible - } + md = setCallContextForVar(yyscanner,clName); + //printf("setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",clName,md,yyextra->currentDefinition); + if (md && yyextra->currentDefinition) + { + DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n", + md->name().data(),yyextra->currentDefinition->name().data(), + isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md), + md->getOuterScope()->name().data())); + } + + if (md && yyextra->currentDefinition && + isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1) + { + md=0; // variable not accessible + } } if (md && (!varOnly || md->isVariable())) { DBG_CTX((stderr,"is a global md=%p yyextra->currentDefinition=%s linkable=%d\n",md,yyextra->currentDefinition?yyextra->currentDefinition->name().data():"<none>",md->isLinkable())); - if (md->isLinkable()) - { - QCString text; - if (!yyextra->forceTagReference.isEmpty()) // explicit reference to symbol in tag file - { - text=yyextra->forceTagReference; - if (text.right(4)==".tag") // strip .tag if present - { - text=text.left(text.length()-4); - } - text+=getLanguageSpecificSeparator(md->getLanguage()); - text+=clName; - const_cast<MemberDef*>(md)->setName(text); + if (md->isLinkable()) + { + QCString text; + if (!yyextra->forceTagReference.isEmpty()) // explicit reference to symbol in tag file + { + text=yyextra->forceTagReference; + if (text.right(4)==".tag") // strip .tag if present + { + text=text.left(text.length()-4); + } + text+=getLanguageSpecificSeparator(md->getLanguage()); + text+=clName; + const_cast<MemberDef*>(md)->setName(text); const_cast<MemberDef*>(md)->setLocalName(text); - } - else // normal reference - { - text=clName; - } - writeMultiLineCodeLink(yyscanner,ol,md,text); + } + else // normal reference + { + text=clName; + } + writeMultiLineCodeLink(yyscanner,ol,md,text); addToSearchIndex(yyscanner,clName); - if (yyextra->currentMemberDef && yyextra->collectXRefs) - { - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); - } - return; - } + if (yyextra->currentMemberDef && yyextra->collectXRefs) + { + addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); + } + return; + } } } - + // nothing found, just write out the word DBG_CTX((stderr,"not found!\n")); codifyLines(yyscanner,clName); @@ -3181,9 +3181,9 @@ static bool generateClassMemberLink(yyscan_t yyscanner, { // add usage reference if (yyextra->currentDefinition && yyextra->currentMemberDef && - /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) + /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,xmd); + addDocCrossReference(yyextra->currentMemberDef,xmd); } // write the actual link @@ -3213,7 +3213,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, } else { - Definition *innerDef = cd->findInnerCompound(memName); + const Definition *innerDef = cd->findInnerCompound(memName); if (innerDef) { yyextra->theCallContext.setScope(innerDef); @@ -3227,7 +3227,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, { const NamespaceDef *nd = dynamic_cast<const NamespaceDef*>(def); //printf("Looking for %s inside namespace %s\n",memName,nd->name().data()); - Definition *innerDef = nd->findInnerCompound(memName); + const Definition *innerDef = nd->findInnerCompound(memName); if (innerDef) { yyextra->theCallContext.setScope(innerDef); @@ -3252,27 +3252,27 @@ static void generateMemberLink(yyscan_t yyscanner, // look for the variable in the current context const ClassDef *vcd = yyextra->theVarContext.findVariable(varName); - if (vcd) + if (vcd) { if (vcd!=VariableContext::dummyContext) { //printf("Class found!\n"); - if (getLink(yyscanner,vcd->name(),memName,ol)) + if (getLink(yyscanner,vcd->name(),memName,ol)) { - //printf("Found result!\n"); - return; + //printf("Found result!\n"); + return; } if (vcd->baseClasses()) { - BaseClassListIterator bcli(*vcd->baseClasses()); - for ( ; bcli.current() ; ++bcli) - { - if (getLink(yyscanner,bcli.current()->classDef->name(),memName,ol)) - { - //printf("Found result!\n"); - return; - } - } + BaseClassListIterator bcli(*vcd->baseClasses()); + for ( ; bcli.current() ; ++bcli) + { + if (getLink(yyscanner,bcli.current()->classDef->name(),memName,ol)) + { + //printf("Found result!\n"); + return; + } + } } } } @@ -3285,46 +3285,46 @@ static void generateMemberLink(yyscan_t yyscanner, MemberName *vmn=Doxygen::memberNameLinkedMap->find(varName); if (vmn==0) { - int vi; - QCString vn=varName; - if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1) // explicit scope A::b(), probably static member - { - ClassDef *jcd = getClass(vn.left(vi)); - vn=vn.right(vn.length()-vi-2); - vmn=Doxygen::memberNameLinkedMap->find(vn); - //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); - if (vmn) - { + int vi; + QCString vn=varName; + if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1) // explicit scope A::b(), probably static member + { + const ClassDef *jcd = getClass(vn.left(vi)); + vn=vn.right(vn.length()-vi-2); + vmn=Doxygen::memberNameLinkedMap->find(vn); + //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); + if (vmn) + { for (const auto &vmd : *vmn) - { - if (vmd->getClassDef()==jcd) - { - //printf("Found variable type=%s\n",vmd->typeString()); - const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); - if (mcd && mcd->isLinkable()) - { - if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; - } - } - } - } - } + { + if (vmd->getClassDef()==jcd) + { + //printf("Found variable type=%s\n",vmd->typeString()); + const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); + if (mcd && mcd->isLinkable()) + { + if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; + } + } + } + } + } } if (vmn) { - //printf("There is a variable with name '%s'\n",varName); + //printf("There is a variable with name '%s'\n",varName); for (const auto &vmd : *vmn) - { - if (vmd->getClassDef()==vcd) - { - //printf("Found variable type=%s\n",vmd->typeString()); - const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); - if (mcd && mcd->isLinkable()) - { - if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; - } - } - } + { + if (vmd->getClassDef()==vcd) + { + //printf("Found variable type=%s\n",vmd->typeString()); + const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); + if (mcd && mcd->isLinkable()) + { + if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; + } + } + } } } } @@ -3362,13 +3362,13 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons int len=2; int i=locFunc.findRev("::"); if (yyextra->currentMemberDef && yyextra->currentMemberDef->resolveAlias()->getClassDef() && - funcName==yyextra->currentMemberDef->localName() && + funcName==yyextra->currentMemberDef->localName() && yyextra->currentMemberDef->getDefLine()==yyextra->yyLineNr && generateClassMemberLink(yyscanner,ol,yyextra->currentMemberDef,funcName) ) { // special case where funcName is the name of a method that is also - // defined on this line. In this case we can directly link to + // defined on this line. In this case we can directly link to // yyextra->currentMemberDef, which is not only faster, but // in case of overloaded methods, this will make sure that we link to // the correct method, and thereby get the correct reimplemented relations. @@ -3446,7 +3446,7 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons BaseClassListIterator bcli(*ccd->baseClasses()); for ( ; bcli.current() ; ++bcli) { - if (getLink(yyscanner,bcli.current()->classDef->name(),funcWithScope,ol,funcName)) + if (getLink(yyscanner,bcli.current()->classDef->name(),funcWithScope,ol,funcName)) { goto exit; } @@ -3458,7 +3458,7 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons { generateClassOrGlobalLink(yyscanner,ol,funcName); } -exit: +exit: yyextra->forceTagReference.resize(0); return; } @@ -3470,17 +3470,17 @@ static int countLines(yyscan_t yyscanner) const char *p=yyextra->inputString; char c; int count=1; - while ((c=*p)) - { - p++ ; - if (c=='\n') count++; + while ((c=*p)) + { + p++ ; + if (c=='\n') count++; } - if (p>yyextra->inputString && *(p-1)!='\n') + if (p>yyextra->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++, - yyextra->needsTermination=TRUE; - } + count++, + yyextra->needsTermination=TRUE; + } return count; } @@ -3518,62 +3518,62 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) if (!ctx->objectTypeOrName.isEmpty() && ctx->objectTypeOrName.at(0)!='$') { //printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(), - // ctx->methodName.data()); + // ctx->methodName.data()); const ClassDef *cd = yyextra->theVarContext.findVariable(ctx->objectTypeOrName); if (cd==0) // not a local variable { - if (ctx->objectTypeOrName=="self") - { - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ctx->objectType = dynamic_cast<ClassDef *>(yyextra->currentDefinition); - } - } - else - { - ctx->objectType = getResolvedClass( - yyextra->currentDefinition, - yyextra->sourceFileDef, - ctx->objectTypeOrName, - &ctx->method); - } - //printf(" object is class? %p\n",ctx->objectType); - if (ctx->objectType) // found class - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - //printf(" yes->method=%s\n",ctx->method?ctx->method->name().data():"<none>"); - } - else if (ctx->method==0) // search for class variable with the same name - { - //printf(" no\n"); - //printf("yyextra->currentDefinition=%p\n",yyextra->currentDefinition); - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ctx->objectVar = (dynamic_cast<ClassDef *>(yyextra->currentDefinition))->getMemberByName(ctx->objectTypeOrName); - //printf(" ctx->objectVar=%p\n",ctx->objectVar); - if (ctx->objectVar) - { - ctx->objectType = stripClassName(yyscanner,ctx->objectVar->typeString(),yyextra->currentDefinition); - //printf(" ctx->objectType=%p\n",ctx->objectType); - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - //printf(" ctx->method=%p\n",ctx->method); - } - } - } - } + if (ctx->objectTypeOrName=="self") + { + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + ctx->objectType = dynamic_cast<const ClassDef *>(yyextra->currentDefinition); + } + } + else + { + ctx->objectType = getResolvedClass( + yyextra->currentDefinition, + yyextra->sourceFileDef, + ctx->objectTypeOrName, + &ctx->method); + } + //printf(" object is class? %p\n",ctx->objectType); + if (ctx->objectType) // found class + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + //printf(" yes->method=%s\n",ctx->method?ctx->method->name().data():"<none>"); + } + else if (ctx->method==0) // search for class variable with the same name + { + //printf(" no\n"); + //printf("yyextra->currentDefinition=%p\n",yyextra->currentDefinition); + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + ctx->objectVar = (dynamic_cast<const ClassDef *>(yyextra->currentDefinition))->getMemberByName(ctx->objectTypeOrName); + //printf(" ctx->objectVar=%p\n",ctx->objectVar); + if (ctx->objectVar) + { + ctx->objectType = stripClassName(yyscanner,ctx->objectVar->typeString(),yyextra->currentDefinition); + //printf(" ctx->objectType=%p\n",ctx->objectType); + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + //printf(" ctx->method=%p\n",ctx->method); + } + } + } + } } else // local variable { - //printf(" object is local variable\n"); - if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty()) - { - ctx->method = cd->getMemberByName(ctx->methodName); - //printf(" class=%p method=%p\n",cd,ctx->method); - } + //printf(" object is local variable\n"); + if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty()) + { + ctx->method = cd->getMemberByName(ctx->methodName); + //printf(" class=%p method=%p\n",cd,ctx->method); + } } } } @@ -3586,215 +3586,215 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) char nc=*p++; if (nc=='$') // escaped $ { - yyextra->code->codify("$"); + yyextra->code->codify("$"); } - else // name fragment or reference to a nested call + else // name fragment or reference to a nested call { - if (nc=='n') // name fragment - { + if (nc=='n') // name fragment + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); - auto it = yyextra->nameMap.find(refId); - if (it!=yyextra->nameMap.end()) - { - QCString name = it->second; - if (ctx->method && ctx->method->isLinkable()) - { + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); + auto it = yyextra->nameMap.find(refId); + if (it!=yyextra->nameMap.end()) + { + QCString name = it->second; + if (ctx->method && ctx->method->isLinkable()) + { writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->method,name); - if (yyextra->currentMemberDef && yyextra->collectXRefs) - { - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->method)); - } - } - else - { - codifyLines(yyscanner,name); - } - } - else - { - //printf("Invalid name: id=%d\n",refId); - } - } - else if (nc=='o') // reference to potential object name - { + if (yyextra->currentMemberDef && yyextra->collectXRefs) + { + addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->method)); + } + } + else + { + codifyLines(yyscanner,name); + } + } + else + { + //printf("Invalid name: id=%d\n",refId); + } + } + else if (nc=='o') // reference to potential object name + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->objectMap.find(refId); - if (it!=yyextra->objectMap.end()) - { - QCString object = it->second; - if (object=="self") - { - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ctx->objectType = dynamic_cast<ClassDef *>(yyextra->currentDefinition); - if (ctx->objectType->categoryOf()) - { - ctx->objectType = ctx->objectType->categoryOf(); - } - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } - } - startFontClass(yyscanner,"keyword"); + if (it!=yyextra->objectMap.end()) + { + QCString object = it->second; + if (object=="self") + { + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + ctx->objectType = dynamic_cast<const ClassDef *>(yyextra->currentDefinition); + if (ctx->objectType->categoryOf()) + { + ctx->objectType = ctx->objectType->categoryOf(); + } + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + } + } + startFontClass(yyscanner,"keyword"); codifyLines(yyscanner,object); - endFontClass(yyscanner); - } - else if (object=="super") - { - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ClassDef *cd = dynamic_cast<ClassDef *>(yyextra->currentDefinition); - if (cd->categoryOf()) - { - cd = cd->categoryOf(); - } - BaseClassList *bcd = cd->baseClasses(); - if (bcd) // get direct base class (there should be only one) - { - BaseClassListIterator bli(*bcd); - BaseClassDef *bclass; - for (bli.toFirst();(bclass=bli.current());++bli) - { - if (bclass->classDef->compoundType()!=ClassDef::Protocol) - { - ctx->objectType = bclass->classDef; - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } - } - } - } - } - startFontClass(yyscanner,"keyword"); + endFontClass(yyscanner); + } + else if (object=="super") + { + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + const ClassDef *cd = dynamic_cast<const ClassDef *>(yyextra->currentDefinition); + if (cd->categoryOf()) + { + cd = cd->categoryOf(); + } + const BaseClassList *bcd = cd->baseClasses(); + if (bcd) // get direct base class (there should be only one) + { + BaseClassListIterator bli(*bcd); + BaseClassDef *bclass; + for (bli.toFirst();(bclass=bli.current());++bli) + { + if (bclass->classDef->compoundType()!=ClassDef::Protocol) + { + ctx->objectType = bclass->classDef; + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + } + } + } + } + } + startFontClass(yyscanner,"keyword"); codifyLines(yyscanner,object); - endFontClass(yyscanner); - } - else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable - { - writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object); - if (yyextra->currentMemberDef && yyextra->collectXRefs) - { - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->objectVar)); - } - } - else if (ctx->objectType && - ctx->objectType!=VariableContext::dummyContext && - ctx->objectType->isLinkable() - ) // object is class name - { - const ClassDef *cd = ctx->objectType; - writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); - } - else // object still needs to be resolved - { - const ClassDef *cd = getResolvedClass(yyextra->currentDefinition, - yyextra->sourceFileDef, object); - if (cd && cd->isLinkable()) - { - if (ctx->objectType==0) ctx->objectType=cd; - writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); - } - else - { - codifyLines(yyscanner,object); - } - } - } - else - { - //printf("Invalid object: id=%d\n",refId); - } - } - else if (nc=='c') // reference to nested call - { + endFontClass(yyscanner); + } + else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable + { + writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object); + if (yyextra->currentMemberDef && yyextra->collectXRefs) + { + addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->objectVar)); + } + } + else if (ctx->objectType && + ctx->objectType!=VariableContext::dummyContext && + ctx->objectType->isLinkable() + ) // object is class name + { + const ClassDef *cd = ctx->objectType; + writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); + } + else // object still needs to be resolved + { + const ClassDef *cd = getResolvedClass(yyextra->currentDefinition, + yyextra->sourceFileDef, object); + if (cd && cd->isLinkable()) + { + if (ctx->objectType==0) ctx->objectType=cd; + writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); + } + else + { + codifyLines(yyscanner,object); + } + } + } + else + { + //printf("Invalid object: id=%d\n",refId); + } + } + else if (nc=='c') // reference to nested call + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->contextMap.find(refId); - if (it!=yyextra->contextMap.end()) // recurse into nested call - { + if (it!=yyextra->contextMap.end()) // recurse into nested call + { ObjCCallCtx *ictx = it->second.get(); - writeObjCMethodCall(yyscanner,ictx); - if (ictx->method) // link to nested call successfully - { - // get the ClassDef representing the method's return type - if (QCString(ictx->method->typeString())=="id") - { - // see if the method name is unique, if so we link to it - 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->size()==1) // member name unique - { - ctx->method = mn->front().get(); - } - } - else - { - ctx->objectType = stripClassName(yyscanner,ictx->method->typeString(),yyextra->currentDefinition); - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } - } - //printf(" ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType); - } - } - else - { - //printf("Invalid context: id=%d\n",refId); - } - } - else if (nc=='w') // some word - { + writeObjCMethodCall(yyscanner,ictx); + if (ictx->method) // link to nested call successfully + { + // get the ClassDef representing the method's return type + if (QCString(ictx->method->typeString())=="id") + { + // see if the method name is unique, if so we link to it + 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->size()==1) // member name unique + { + ctx->method = mn->front().get(); + } + } + else + { + ctx->objectType = stripClassName(yyscanner,ictx->method->typeString(),yyextra->currentDefinition); + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + } + } + //printf(" ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType); + } + } + else + { + //printf("Invalid context: id=%d\n",refId); + } + } + else if (nc=='w') // some word + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->wordMap.find(refId); - if (it!=yyextra->wordMap.end()) - { + if (it!=yyextra->wordMap.end()) + { QCString word = it->second; codifyLines(yyscanner,word); - } - } + } + } else if (nc=='d') // comment block { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->commentMap.find(refId); if (it!=yyextra->commentMap.end()) { - QCString comment = it->second; + QCString comment = it->second; startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,comment); - endFontClass(yyscanner); + codifyLines(yyscanner,comment); + endFontClass(yyscanner); } } - else // illegal marker - { - ASSERT("invalid escape sequence"==0); - } + else // illegal marker + { + ASSERT("invalid escape sequence"==0); + } } } else // normal non-marker character @@ -3811,7 +3811,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) } // Replaces an Objective-C method name fragment s by a marker of the form -// $n12, the number (12) can later be used as a key for obtaining the name +// $n12, the number (12) can later be used as a key for obtaining the name // fragment, from yyextra->nameMap static QCString escapeName(yyscan_t yyscanner,const char *s) { @@ -3964,10 +3964,10 @@ void CCodeParser::resetCodeParserState() yyextra->anchorCount = 0; } -void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const QCString &s, +void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const QCString &s, SrcLangExt lang,bool exBlock, const char *exName,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, + int startLine,int endLine,bool inlineFragment, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs) { yyscan_t yyscanner = p->yyscanner; @@ -4008,7 +4008,7 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const while (!yyextra->scopeStack.empty()) yyextra->scopeStack.pop(); yyextra->classScope = className; //printf("parseCCode %s\n",className); - yyextra->exampleBlock = exBlock; + yyextra->exampleBlock = exBlock; yyextra->exampleName = exName; yyextra->sourceFileDef = fd; yyextra->lineNumbers = fd!=0 && showLineNumbers; @@ -4021,7 +4021,7 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const } yyextra->lang = lang; yyextra->insideObjC = lang==SrcLangExt_ObjC; - if (yyextra->sourceFileDef) + if (yyextra->sourceFileDef) { setCurrentDoc(yyscanner,"l00001"); } diff --git a/src/commentscan.l b/src/commentscan.l index c151294..ccf71f6 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -438,6 +438,8 @@ 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); +#define unput_string(yytext,yyleng) do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0) + //----------------------------------------------------------------------------- #undef YY_INPUT @@ -666,6 +668,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" optList = QCStringList::split(',',optStr); } auto it = docCmdMap.find(cmdName.data()); + //printf("lookup command '%s' found=%d\n",cmdName.data(),it!=docCmdMap.end()); if (it!=docCmdMap.end()) // special action is required { int i=0; @@ -871,9 +874,9 @@ RCSTAG "$"{ID}":"[^\n$]+"$" yyextra->briefEndsAtDot=FALSE; } } -<Comment>\n { // newline - addOutput(yyscanner,*yytext); - yyextra->lineNr++; +<Comment>{DOCNL} { // newline + addOutput(yyscanner,yytext); + if (*yytext == '\n') yyextra->lineNr++; } <Comment>. { // catch-all for anything else addOutput(yyscanner,*yytext); @@ -953,7 +956,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" warn(yyextra->fileName,yyextra->lineNr, "missing argument after \\enum." ); - unput('\n'); + unput_string(yytext,yyleng); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); @@ -976,7 +979,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "missing argument after " "\\namespace." ); - unput('\n'); + unput_string(yytext,yyleng); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); @@ -999,7 +1002,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "missing argument after " "\\package." ); - unput('\n'); + unput_string(yytext,yyleng); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); @@ -1037,7 +1040,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ClassDocArg1,CategoryDocArg1>. { // ignore other stuff @@ -1046,7 +1049,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <ClassDocArg2>{DOCNL} { //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ClassDocArg2>{FILE}|"<>" { // second argument; include file @@ -1070,7 +1073,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } <ClassDocArg3>{DOCNL} { //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ClassDocArg3>. { // ignore other stuff @@ -1101,7 +1104,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <GroupDocArg1>. { // ignore other stuff @@ -1124,7 +1127,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "\\defgroup %s", yyextra->current->name.data() ); } - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1149,7 +1152,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "missing argument after " "\\page." ); - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1157,7 +1160,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <PageDocArg1>. { // ignore other stuff } <PageDocArg2>{DOCNL} { // second argument; page title - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1191,7 +1194,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* --------- handle arguments of the file/dir/example command ------------ */ <FileDocArg1>{DOCNL} { // no file name specified - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1289,7 +1292,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" warn(yyextra->fileName,yyextra->lineNr, "Missing argument of '\\%s' command",yyextra->currentCmd.data() ); - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1303,7 +1306,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <LineParam>{DOCNL} { // end of argument //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <LineParam>{LC} { // line continuation @@ -1667,7 +1670,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <NameParam>{DOCNL} { // end of argument //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <NameParam>{LC} { // line continuation @@ -1705,7 +1708,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <InGroupParam>{LC} { // line continuation @@ -1723,7 +1726,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" { //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); yyextra->langParser->parsePrototype(yyextra->functionProto); BEGIN( Comment ); } @@ -1810,7 +1813,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ExtendsParam>. { // ignore other stuff @@ -1847,7 +1850,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <CiteLabel>. { // invalid character for cite label @@ -2782,6 +2785,7 @@ static bool makeStructuralIndicator(yyscan_t yyscanner,Entry::Sections s) yyextra->current->section = s; yyextra->current->fileName = yyextra->fileName; yyextra->current->startLine = yyextra->lineNr; + yyextra->current->docLine = yyextra->lineNr; return FALSE; } } diff --git a/src/context.cpp b/src/context.cpp index 29a704a..ee394d4 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -1301,8 +1301,8 @@ static TemplateVariant parseDoc(const Definition *def,const QCString &file,int l static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const QCString &relPath, const QCString &code,int startLine=-1,int endLine=-1,bool showLineNumbers=FALSE) { - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(md->getDefFileExtension()); - intf.resetCodeParserState(); + auto intf = Doxygen::parserManager->getCodeParser(md->getDefFileExtension()); + intf->resetCodeParserState(); QGString s; FTextStream t(&s); switch (g_globals.outputFormat) @@ -1310,14 +1310,14 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(t,relPath); - intf.parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), + intf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), startLine,endLine,TRUE,md,showLineNumbers,md); } break; case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(t,relPath,md->docFile()); - intf.parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), + intf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), startLine,endLine,TRUE,md,showLineNumbers,md); } break; @@ -1332,8 +1332,8 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) { static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); - intf.resetCodeParserState(); + auto intf = Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); + intf->resetCodeParserState(); QGString s; FTextStream t(&s); switch (g_globals.outputFormat) @@ -1341,7 +1341,7 @@ static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(t,relPath); - intf.parseCode(codeGen,0, + intf->parseCode(codeGen,0, fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources fd->getLanguage(), // lang FALSE, // isExampleBlock @@ -1360,7 +1360,7 @@ static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(t,relPath,fd->docFile()); - intf.parseCode(codeGen,0, + intf->parseCode(codeGen,0, fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources fd->getLanguage(), // lang FALSE, // isExampleBlock @@ -3896,13 +3896,25 @@ class TextGeneratorLatex : public TextGeneratorIntf if (f && anchor) m_ts << "_"; if (anchor) m_ts << anchor; m_ts << "}{"; - filterLatexString(m_ts,text); + filterLatexString(m_ts,text, + false, // insideTabbing + false, // insidePre + false, // insideItem + false, // insideTable + false // keepSpaces + ); m_ts << "}}"; } else { m_ts << "\\textbf{ "; - filterLatexString(m_ts,text); + filterLatexString(m_ts,text, + false, // insideTabbing + false, // insidePre + false, // insideItem + false, // insideTable + false // keepSpaces + ); m_ts << "}"; } } diff --git a/src/definition.cpp b/src/definition.cpp index dc96839..9e78b74 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -1236,27 +1236,27 @@ void DefinitionImpl::writeInlineCode(OutputList &ol,const char *scopeName) const { //printf("Adding code fragment '%s' ext='%s'\n", // codeFragment.data(),m_impl->defFileExt.data()); - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(m_impl->defFileExt); - intf.resetCodeParserState(); + auto intf = Doxygen::parserManager->getCodeParser(m_impl->defFileExt); + intf->resetCodeParserState(); //printf("Read:\n'%s'\n\n",codeFragment.data()); const MemberDef *thisMd = 0; if (definitionType()==TypeMember) thisMd = dynamic_cast <const MemberDef*>(this); - ol.startCodeFragment(); - intf.parseCode(ol, // codeOutIntf - scopeName, // scope - codeFragment, // input - m_impl->lang, // lang - FALSE, // isExample - 0, // exampleName - m_impl->body->fileDef, // fileDef - actualStart, // startLine - actualEnd, // endLine - TRUE, // inlineFragment - thisMd, // memberDef - TRUE // show line numbers - ); - ol.endCodeFragment(); + ol.startCodeFragment("DoxyCode"); + intf->parseCode(ol, // codeOutIntf + scopeName, // scope + codeFragment, // input + m_impl->lang, // lang + FALSE, // isExample + 0, // exampleName + m_impl->body->fileDef, // fileDef + actualStart, // startLine + actualEnd, // endLine + TRUE, // inlineFragment + thisMd, // memberDef + TRUE // show line numbers + ); + ol.endCodeFragment("DoxyCode"); } } ol.popGeneratorState(); diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index da7987b..b25a43c 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -242,18 +242,23 @@ void DocbookCodeGenerator::finish() { endCodeLine(); } -void DocbookCodeGenerator::startCodeFragment() +void DocbookCodeGenerator::startCodeFragment(const char *) { - m_t << "<literallayout><computeroutput>" << endl; +DB_GEN_C + m_t << "<programlisting>"; } -void DocbookCodeGenerator::endCodeFragment() + +void DocbookCodeGenerator::endCodeFragment(const char *) { +DB_GEN_C //endCodeLine checks is there is still an open code line, if so closes it. endCodeLine(); - m_t << "</computeroutput></literallayout>" << endl; + m_t << "</programlisting>"; } +//------------------------------------------------------------------------------- + DocbookGenerator::DocbookGenerator() : OutputGenerator(Config_getString(DOCBOOK_OUTPUT)) { DB_GEN_C @@ -732,12 +737,12 @@ void DocbookGenerator::endMemberItem() DB_GEN_C t << "</para>" << endl; } -void DocbookGenerator::startBold(void) +void DocbookGenerator::startBold() { DB_GEN_C t << "<emphasis role=\"strong\">"; } -void DocbookGenerator::endBold(void) +void DocbookGenerator::endBold() { DB_GEN_C t << "</emphasis>"; @@ -755,7 +760,7 @@ DB_GEN_C2("extraIndentLevel " << extraIndentLevel) t << "<section>" << endl; t << "<title>"; } -void DocbookGenerator::writeRuler(void) +void DocbookGenerator::writeRuler() { DB_GEN_C2("m_inLevel " << m_inLevel) DB_GEN_C2("m_inGroup " << m_inGroup) @@ -945,12 +950,12 @@ void DocbookGenerator::endExamples() DB_GEN_C t << "</simplesect>" << endl; } -void DocbookGenerator::startSubsubsection(void) +void DocbookGenerator::startSubsubsection() { DB_GEN_C t << "<simplesect><title>"; } -void DocbookGenerator::endSubsubsection(void) +void DocbookGenerator::endSubsubsection() { DB_GEN_C t << "</title></simplesect>" << endl; @@ -995,19 +1000,6 @@ DB_GEN_C if (closeBracket) t << ")"; } } -void DocbookGenerator::startCodeFragment() -{ -DB_GEN_C - t << "<programlisting>"; -} -void DocbookGenerator::endCodeFragment() -{ -DB_GEN_C - //endCodeLine checks is there is still an open code line, if so closes it. - endCodeLine(); - - t << "</programlisting>"; -} void DocbookGenerator::startMemberTemplateParams() { DB_GEN_C diff --git a/src/docbookgen.h b/src/docbookgen.h index 0fefe4b..112d0a0 100644 --- a/src/docbookgen.h +++ b/src/docbookgen.h @@ -53,8 +53,8 @@ class DocbookCodeGenerator : public CodeOutputInterface void setCurrentDoc(const Definition *,const char *,bool); void addWord(const char *,bool); void finish(); - void startCodeFragment(); - void endCodeFragment(); + void startCodeFragment(const char *style); + void endCodeFragment(const char *style); private: FTextStream m_t; @@ -130,6 +130,10 @@ class DocbookGenerator : public OutputGenerator { m_codeGen.endFontClass(); } void writeCodeAnchor(const char *anchor) { m_codeGen.writeCodeAnchor(anchor); } + void startCodeFragment(const char *style) + { m_codeGen.startCodeFragment(style); } + void endCodeFragment(const char *style) + { m_codeGen.endCodeFragment(style); } // --------------------------- void writeDoc(DocNode *,const Definition *ctx,const MemberDef *md); @@ -169,35 +173,33 @@ class DocbookGenerator : public OutputGenerator void writeChar(char); void writeString(const char *); void startParagraph(const char *); - void endParagraph(void); + void endParagraph(); void writeObjectLink(const char *,const char *,const char *,const char *); void startHtmlLink(const char *){DB_GEN_NEW}; - void endHtmlLink(void){DB_GEN_NEW}; - void startBold(void); - void endBold(void); - void startTypewriter(void); - void endTypewriter(void); - void startEmphasis(void){DB_GEN_NEW}; - void endEmphasis(void){DB_GEN_NEW}; - void startCodeFragment(void); - void endCodeFragment(void); - void writeRuler(void); - void startDescription(void){DB_GEN_NEW}; - void endDescription(void){DB_GEN_NEW}; - void startDescItem(void){DB_GEN_NEW}; - void startDescForItem(void){DB_GEN_EMPTY}; - void endDescForItem(void){DB_GEN_EMPTY}; - void endDescItem(void){DB_GEN_NEW}; - void startCenter(void){DB_GEN_NEW}; - void endCenter(void){DB_GEN_NEW}; - void startSmall(void){DB_GEN_NEW}; - void endSmall(void){DB_GEN_NEW}; - void startExamples(void); - void endExamples(void); + void endHtmlLink(){DB_GEN_NEW}; + void startBold(); + void endBold(); + void startTypewriter(); + void endTypewriter(); + void startEmphasis(){DB_GEN_NEW}; + void endEmphasis(){DB_GEN_NEW}; + void writeRuler(); + void startDescription(){DB_GEN_NEW}; + void endDescription(){DB_GEN_NEW}; + void startDescItem(){DB_GEN_NEW}; + void startDescForItem(){DB_GEN_EMPTY}; + void endDescForItem(){DB_GEN_EMPTY}; + void endDescItem(){DB_GEN_NEW}; + void startCenter(){DB_GEN_NEW}; + void endCenter(){DB_GEN_NEW}; + void startSmall(){DB_GEN_NEW}; + void endSmall(){DB_GEN_NEW}; + void startExamples(); + void endExamples(); void startParamList(BaseOutputDocInterface::ParamListTypes,const char *){DB_GEN_NEW}; - void endParamList(void){DB_GEN_NEW}; - void startTitle(void){DB_GEN_NEW}; - void endTitle(void){DB_GEN_NEW}; + void endParamList(){DB_GEN_NEW}; + void startTitle(){DB_GEN_NEW}; + void endTitle(){DB_GEN_NEW}; void writeAnchor(const char *,const char *){DB_GEN_EMPTY}; void startSection(const char *,const char *,SectionType); void endSection(const char *,SectionType); @@ -205,21 +207,21 @@ class DocbookGenerator : public OutputGenerator void addIndexItem(const char *,const char *); void writeNonBreakableSpace(int); void startDescTable(const char *); - void endDescTable(void); - void startDescTableRow(void); - void endDescTableRow(void); - void startDescTableTitle(void); - void endDescTableTitle(void); - void startDescTableData(void); - void endDescTableData(void); + void endDescTable(); + void startDescTableRow(); + void endDescTableRow(); + void startDescTableTitle(); + void endDescTableTitle(); + void startDescTableData(); + void endDescTableData(); void startTextLink(const char *,const char *){DB_GEN_NEW}; - void endTextLink(void){DB_GEN_NEW}; - void startPageRef(void){DB_GEN_NEW}; + void endTextLink(){DB_GEN_NEW}; + void startPageRef(){DB_GEN_NEW}; void endPageRef(const char *,const char *){DB_GEN_NEW}; - void startSubsection(void){DB_GEN_NEW}; - void endSubsection(void){DB_GEN_NEW}; - void startSubsubsection(void); - void endSubsubsection(void); + void startSubsection(){DB_GEN_NEW}; + void endSubsection(){DB_GEN_NEW}; + void startSubsubsection(); + void endSubsubsection(); void startGroupHeader(int); diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index 78af6e0..bf6c827 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -316,9 +316,11 @@ DB_VIS_C { case DocVerbatim::Code: // fall though m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getCodeParser(m_langExt) - .parseCode(m_ci,s->context(),s->text(),langExt, - s->isExample(),s->exampleFile()); + getCodeParser(m_langExt).parseCode(m_ci,s->context(), + s->text(), + langExt, + s->isExample(), + s->exampleFile()); m_t << "</computeroutput></literallayout>"; break; case DocVerbatim::Verbatim: @@ -425,24 +427,22 @@ DB_VIS_C m_t << "<literallayout><computeroutput>"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), - inc->text(), - langExt, - inc->isExample(), - inc->exampleFile(), fd); + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), + inc->text(), + langExt, + inc->isExample(), + inc->exampleFile(), fd); delete fd; m_t << "</computeroutput></literallayout>"; } break; case DocInclude::Include: m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), - inc->text(), - langExt, - inc->isExample(), - inc->exampleFile()); + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), + inc->text(), + langExt, + inc->isExample(), + inc->exampleFile()); m_t << "</computeroutput></literallayout>"; break; case DocInclude::DontInclude: @@ -463,14 +463,13 @@ DB_VIS_C break; case DocInclude::Snippet: m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), - langExt, - inc->isExample(), - inc->exampleFile() - ); + getCodeParser(inc->extension()).parseCode(m_ci, + inc->context(), + extractBlock(inc->text(),inc->blockId()), + langExt, + inc->isExample(), + inc->exampleFile() + ); m_t << "</computeroutput></literallayout>"; break; case DocInclude::SnipWithLines: @@ -478,8 +477,7 @@ DB_VIS_C QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -531,17 +529,16 @@ DB_VIS_C fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getCodeParser(locLangExt) - .parseCode(m_ci,op->context(), - op->text(),langExt,op->isExample(), - op->exampleFile(), - fd, // fileDef - op->line(), // startLine - -1, // endLine - FALSE, // inline fragment - 0, // memberDef - op->showLineNo() // show line numbers - ); + getCodeParser(locLangExt).parseCode(m_ci,op->context(), + op->text(),langExt,op->isExample(), + op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); if (fd) delete fd; } pushEnabled(); diff --git a/src/docparser.cpp b/src/docparser.cpp index a5240c9..b908005 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -2448,8 +2448,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : } m_isSubPage = pd && pd->hasParentPage(); 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); + //printf("m_text=%s,m_ref=%s,m_file=%s,type=%d\n", + // m_text.data(),m_ref.data(),m_file.data(),m_refType); return; } else if (resolveLink(context,target,TRUE,&compound,anchor)) diff --git a/src/doctokenizer.l b/src/doctokenizer.l index a08d909..bf33e86 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -444,6 +444,7 @@ REFWORD4_NOCV (({SCOPEPRE}*"operator"{OPMASKOP2})|(("::"|"#"){SCOPEPRE}*"operat REFWORD4 {REFWORD4_NOCV}{CVSPEC}? REFWORD {FILEMASK}|{LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4} REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} +RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revision"|"Source"|"State")":"[^:\n$][^\n$]*"$" %option noyywrap @@ -694,7 +695,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name=yytext; return TK_WORD; } -<St_Para>"$"{ID}":"[^:\n$][^\n$]*"$" { /* RCS tag */ +<St_Para>{RCSID} { /* RCS tag */ QCString tagName(yytext+1); int index=tagName.find(':'); g_token->name = tagName.left(index); diff --git a/src/docvisitor.cpp b/src/docvisitor.cpp new file mode 100644 index 0000000..17aefc2 --- /dev/null +++ b/src/docvisitor.cpp @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * 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. + */ + + +#include <unordered_map> + +#include "parserintf.h" +#include "docvisitor.h" +#include "util.h" +#include "types.h" +#include "doxygen.h" + +struct DocVisitor::Private +{ + int id; + std::unordered_map< std::string, std::unique_ptr<CodeParserInterface> > parserFactoryMap; +}; + +DocVisitor::DocVisitor(int id) : m_p(std::make_unique<Private>()) +{ + m_p->id = id; +} + +DocVisitor::~DocVisitor() +{ +} + +CodeParserInterface &DocVisitor::getCodeParser(const char *extension) +{ + std::string ext(extension?extension:""); + // for each extension we create a code parser once per visitor, so that + // the context of the same parser object is reused thoughout multiple passes for instance + // for code fragments shown via dontinclude. + auto it = m_p->parserFactoryMap.find(ext); + if (it==m_p->parserFactoryMap.end()) + { + auto factory = Doxygen::parserManager->getCodeParserFactory(extension); + auto result = m_p->parserFactoryMap.insert(std::make_pair(ext,factory())); + it = result.first; + } + return *it->second.get(); +} + +int DocVisitor::id() const +{ + return m_p->id; +} diff --git a/src/docvisitor.h b/src/docvisitor.h index 0a53595..4d4b263 100644 --- a/src/docvisitor.h +++ b/src/docvisitor.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,6 +16,8 @@ #ifndef _DOCVISITOR_H #define _DOCVISITOR_H +#include <memory> + // ids const int DocVisitor_Html = 0; const int DocVisitor_Latex = 1; @@ -84,18 +83,21 @@ class DocSimpleSectSep; class DocHtmlBlockQuote; class DocVhdlFlow; class DocParBlock; +class CodeParserInterface; /*! @brief Abstract visitor that participates in the visitor pattern. */ class DocVisitor { - int m_id; + struct Private; + std::unique_ptr<Private> m_p; public: - DocVisitor(int id) : m_id(id) {} - virtual ~DocVisitor() {} - int id() const { return m_id; } + DocVisitor(int id); + virtual ~DocVisitor(); + int id() const; + CodeParserInterface &getCodeParser(const char *langExt); - /*! @name Visitor functions for leaf nodes + /*! @name Visitor functions for leaf nodes * @{ */ virtual void visit(DocWord *) = 0; @@ -117,7 +119,7 @@ class DocVisitor virtual void visit(DocCite *) = 0; /*! @} */ - /*! @name Visitor functions for internal nodes + /*! @name Visitor functions for internal nodes * @{ */ virtual void visitPre(DocAutoList *) = 0; @@ -167,7 +169,7 @@ class DocVisitor virtual void visitPre(DocDotFile *) = 0; virtual void visitPost(DocDotFile *) = 0; virtual void visitPre(DocMscFile *) = 0; - virtual void visitPost(DocMscFile *) = 0; + virtual void visitPost(DocMscFile *) = 0; virtual void visitPre(DocDiaFile *) = 0; virtual void visitPost(DocDiaFile *) = 0; virtual void visitPre(DocLink *) = 0; diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp index 099359d..285c0bb 100644 --- a/src/dotfilepatcher.cpp +++ b/src/dotfilepatcher.cpp @@ -174,6 +174,7 @@ static QCString replaceRef(const QCString &buf,const QCString relPath, if (!ref.isEmpty()) { result = externalLinkTarget(true); + if (!result.isEmpty())targetAlreadySet=true; } result+= href+"=\""; result+=externalRef(relPath,ref,TRUE); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index a8cda22..16dc0a6 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -32,6 +32,7 @@ #include <algorithm> #include <unordered_map> #include <memory> +#include <cinttypes> #include "version.h" #include "doxygen.h" @@ -145,7 +146,7 @@ QDict<DefinitionIntf> *Doxygen::symbolMap = 0; QDict<Definition> *Doxygen::clangUsrMap = 0; bool Doxygen::outputToWizard=FALSE; QDict<int> * Doxygen::htmlDirMap = 0; -QCache<LookupInfo> *Doxygen::lookupCache; +Cache<std::string,LookupInfo> *Doxygen::lookupCache; DirSDict *Doxygen::directories; SDict<DirRelation> Doxygen::dirRelations(257); ParserManager *Doxygen::parserManager = 0; @@ -346,7 +347,9 @@ static void addRelatedPage(Entry *root) } PageDef *pd = addRelatedPage(root->name,root->args,doc, - root->docFile,root->docLine, + root->docFile, + root->docLine, + root->startLine, root->sli, gd,root->tagInfo(), FALSE, @@ -7506,15 +7509,20 @@ static void generateFileSources() { for (const auto &fd : *fn) { - if (fd->isSource() && !fd->isReference()) + if (fd->isSource() && !fd->isReference() && + ((fd->generateSourceFile() && !g_useOutputTemplate) || + (!fd->isReference() && Doxygen::parseSourcesNeeded) + ) + ) { auto clangParser = ClangParser::instance()->createTUParser(fd.get()); if (fd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output { msg("Generating code for file %s...\n",fd->docName().data()); clangParser->parse(); - fd->writeSource(*g_outputList,clangParser.get()); - + fd->writeSourceHeader(*g_outputList); + fd->writeSourceBody(*g_outputList,clangParser.get()); + fd->writeSourceFooter(*g_outputList); } else if (!fd->isReference() && Doxygen::parseSourcesNeeded) // we needed to parse the sources even if we do not show them @@ -7538,7 +7546,9 @@ static void generateFileSources() if (ifd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output { msg(" Generating code for file %s...\n",ifd->docName().data()); - ifd->writeSource(*g_outputList,clangParser.get()); + ifd->writeSourceHeader(*g_outputList); + ifd->writeSourceBody(*g_outputList,clangParser.get()); + ifd->writeSourceFooter(*g_outputList); } else if (!ifd->isReference() && Doxygen::parseSourcesNeeded) // we needed to parse the sources even if we do not show them @@ -7561,20 +7571,24 @@ static void generateFileSources() { if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed { - auto clangParser = ClangParser::instance()->createTUParser(fd.get()); if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output { + auto clangParser = ClangParser::instance()->createTUParser(fd.get()); msg("Generating code for file %s...\n",fd->docName().data()); clangParser->parse(); - fd->writeSource(*g_outputList,clangParser.get()); - + fd->writeSourceHeader(*g_outputList); + fd->writeSourceBody(*g_outputList,clangParser.get()); + fd->writeSourceFooter(*g_outputList); } else if (!fd->isReference() && Doxygen::parseSourcesNeeded) // we needed to parse the sources even if we do not show them { + auto clangParser = ClangParser::instance()->createTUParser(fd.get()); msg("Parsing code for file %s...\n",fd->docName().data()); clangParser->parse(); - fd->parseSource(clangParser.get()); + fd->writeSourceHeader(*g_outputList); + fd->writeSourceBody(*g_outputList,clangParser.get()); + fd->writeSourceFooter(*g_outputList); } } } @@ -7583,6 +7597,66 @@ static void generateFileSources() else #endif { +#define MULTITHREADED_SOURCE_GENERATOR 0 // not ready to be enabled yet +#if MULTITHREADED_SOURCE_GENERATOR + std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); + if (numThreads==0) + { + numThreads = std::thread::hardware_concurrency(); + } + msg("Generating code files using %zu threads.\n",numThreads); + struct SourceContext + { + SourceContext(FileDef *fd_,bool gen_,OutputList ol_) + : fd(fd_), generateSourceFile(gen_), ol(ol_) {} + FileDef *fd; + bool generateSourceFile; + OutputList ol; + }; + ThreadPool threadPool(numThreads); + std::vector< std::future< std::shared_ptr<SourceContext> > > results; + for (const auto &fn : *Doxygen::inputNameLinkedMap) + { + for (const auto &fd : *fn) + { + bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate; + auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList); + if (generateSourceFile) + { + msg("Generating code for file %s...\n",fd->docName().data()); + fd->writeSourceHeader(ctx->ol); + } + else + { + msg("Parsing code for file %s...\n",fd->docName().data()); + } + auto processFile = [ctx]() { + StringVector filesInSameTu; + ctx->fd->getAllIncludeFilesRecursively(filesInSameTu); + if (ctx->generateSourceFile) // sources need to be shown in the output + { + ctx->fd->writeSourceBody(ctx->ol,nullptr); + } + else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded) + // we needed to parse the sources even if we do not show them + { + ctx->fd->parseSource(nullptr); + } + return ctx; + }; + results.emplace_back(threadPool.queue(processFile)); + } + } + for (auto &f : results) + { + std::shared_ptr<SourceContext> ctx = f.get(); + if (ctx->generateSourceFile) + { + ctx->fd->writeSourceFooter(ctx->ol); + } + } + +#else // single threaded version for (const auto &fn : *Doxygen::inputNameLinkedMap) { for (const auto &fd : *fn) @@ -7592,7 +7666,9 @@ static void generateFileSources() if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output { msg("Generating code for file %s...\n",fd->docName().data()); - fd->writeSource(*g_outputList,nullptr); + fd->writeSourceHeader(*g_outputList); + fd->writeSourceBody(*g_outputList,nullptr); + fd->writeSourceFooter(*g_outputList); } else if (!fd->isReference() && Doxygen::parseSourcesNeeded) // we needed to parse the sources even if we do not show them @@ -7602,6 +7678,7 @@ static void generateFileSources() } } } +#endif } } } @@ -8047,15 +8124,20 @@ static void flushCachedTemplateRelations() // as there can be new template instances in the inheritance path // to this class. Optimization: only remove those classes that // have inheritance instances as direct or indirect sub classes. - QCacheIterator<LookupInfo> ci(*Doxygen::lookupCache); - LookupInfo *li=0; - for (ci.toFirst();(li=ci.current());++ci) + StringVector elementsToRemove; + for (const auto &ci : *Doxygen::lookupCache) { - if (li->classDef) + const LookupInfo &li = ci.second; + if (li.classDef) { - Doxygen::lookupCache->remove(ci.currentKey()); + elementsToRemove.push_back(ci.first); } } + for (const auto &k : elementsToRemove) + { + Doxygen::lookupCache->remove(k); + } + // remove all cached typedef resolutions whose target is a // template class as this may now be a template instance // for each global function name @@ -8099,16 +8181,20 @@ static void flushUnresolvedRelations() // class A { class I {} }; // class B : public A {}; // class C : public B::I {}; - // - QCacheIterator<LookupInfo> ci(*Doxygen::lookupCache); - LookupInfo *li=0; - for (ci.toFirst();(li=ci.current());++ci) + + StringVector elementsToRemove; + for (const auto &ci : *Doxygen::lookupCache) { - if (li->classDef==0 && li->typeDef==0) + const LookupInfo &li = ci.second; + if (li.classDef==0 && li.typeDef==0) { - Doxygen::lookupCache->remove(ci.currentKey()); + elementsToRemove.push_back(ci.first); } } + for (const auto &k : elementsToRemove) + { + Doxygen::lookupCache->remove(k); + } // for each global function name for (const auto &fn : *Doxygen::functionNameLinkedMap) @@ -8358,6 +8444,7 @@ static void findMainPage(Entry *root) { if (Doxygen::mainPage==0 && root->tagInfo()==0) { + //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine); //printf("Found main page! \n======\n%s\n=======\n",root->doc.data()); QCString title=root->args.stripWhiteSpace(); //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index"; @@ -8366,6 +8453,7 @@ static void findMainPage(Entry *root) indexName, root->brief+root->doc+root->inbodyDocs,title); //setFileNameForSections(root->anchors,"index",Doxygen::mainPage); Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine); + Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1); Doxygen::mainPage->setFileName(indexName); Doxygen::mainPage->setLocalToc(root->localToc); addPageToContext(Doxygen::mainPage,root); @@ -8401,7 +8489,7 @@ static void findMainPage(Entry *root) { warn(root->fileName,root->startLine, "found more than one \\mainpage comment block! (first occurrence: %s, line %d), Skipping current block!", - Doxygen::mainPage->docFile().data(),Doxygen::mainPage->docLine()); + Doxygen::mainPage->docFile().data(),Doxygen::mainPage->getStartBodyLine()); } } for (const auto &e : root->children()) findMainPage(e.get()); @@ -8624,8 +8712,8 @@ static void generateExampleDocs() for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating docs for example %s...\n",pd->name().data()); - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(".c"); // TODO: do this on code type - intf.resetCodeParserState(); + auto intf = Doxygen::parserManager->getCodeParser(".c"); // TODO: do this on code type + intf->resetCodeParserState(); QCString n=pd->getOutputFileBase(); startFile(*g_outputList,n,n,pd->name()); startTitle(*g_outputList,n); @@ -9022,8 +9110,8 @@ static void generateDiskNames() // as the common prefix between the first and last entry const FileEntry &first = fileEntries[0]; const FileEntry &last = fileEntries[size-1]; - int first_path_size = static_cast<int>(first.path.size()); - int last_path_size = static_cast<int>(last.path.size()); + int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash + int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash int j=0; for (int i=0;i<first_path_size && i<last_path_size;i++) { @@ -9825,7 +9913,7 @@ class NullOutlineParser : public OutlineParserInterface }; -template<class T> std::function< std::unique_ptr<T>() > make_output_parser_factory() +template<class T> std::function< std::unique_ptr<T>() > make_parser_factory() { return []() { return std::make_unique<T>(); }; } @@ -9842,26 +9930,26 @@ void initDoxygen() Portable::correct_path(); Debug::startTimer(); - Doxygen::parserManager = new ParserManager( make_output_parser_factory<NullOutlineParser>(), - std::make_unique<FileCodeParser>()); - Doxygen::parserManager->registerParser("c", make_output_parser_factory<COutlineParser>(), - std::make_unique<CCodeParser>()); - Doxygen::parserManager->registerParser("python", make_output_parser_factory<PythonOutlineParser>(), - std::make_unique<PythonCodeParser>()); - Doxygen::parserManager->registerParser("fortran", make_output_parser_factory<FortranOutlineParser>(), - std::make_unique<FortranCodeParser>()); - Doxygen::parserManager->registerParser("fortranfree", make_output_parser_factory<FortranOutlineParserFree>(), - std::make_unique<FortranCodeParserFree>()); - Doxygen::parserManager->registerParser("fortranfixed", make_output_parser_factory<FortranOutlineParserFixed>(), - std::make_unique<FortranCodeParserFixed>()); - Doxygen::parserManager->registerParser("vhdl", make_output_parser_factory<VHDLOutlineParser>(), - std::make_unique<VHDLCodeParser>()); - Doxygen::parserManager->registerParser("xml", make_output_parser_factory<NullOutlineParser>(), - std::make_unique<XMLCodeParser>()); - Doxygen::parserManager->registerParser("sql", make_output_parser_factory<NullOutlineParser>(), - std::make_unique<SQLCodeParser>()); - Doxygen::parserManager->registerParser("md", make_output_parser_factory<MarkdownOutlineParser>(), - std::make_unique<FileCodeParser>()); + Doxygen::parserManager = new ParserManager( make_parser_factory<NullOutlineParser>(), + make_parser_factory<FileCodeParser>()); + Doxygen::parserManager->registerParser("c", make_parser_factory<COutlineParser>(), + make_parser_factory<CCodeParser>()); + Doxygen::parserManager->registerParser("python", make_parser_factory<PythonOutlineParser>(), + make_parser_factory<PythonCodeParser>()); + Doxygen::parserManager->registerParser("fortran", make_parser_factory<FortranOutlineParser>(), + make_parser_factory<FortranCodeParser>()); + Doxygen::parserManager->registerParser("fortranfree", make_parser_factory<FortranOutlineParserFree>(), + make_parser_factory<FortranCodeParserFree>()); + Doxygen::parserManager->registerParser("fortranfixed", make_parser_factory<FortranOutlineParserFixed>(), + make_parser_factory<FortranCodeParserFixed>()); + Doxygen::parserManager->registerParser("vhdl", make_parser_factory<VHDLOutlineParser>(), + make_parser_factory<VHDLCodeParser>()); + Doxygen::parserManager->registerParser("xml", make_parser_factory<NullOutlineParser>(), + make_parser_factory<XMLCodeParser>()); + Doxygen::parserManager->registerParser("sql", make_parser_factory<NullOutlineParser>(), + make_parser_factory<SQLCodeParser>()); + Doxygen::parserManager->registerParser("md", make_parser_factory<MarkdownOutlineParser>(), + make_parser_factory<FileCodeParser>()); // register any additional parsers here... @@ -10037,15 +10125,15 @@ void readConfiguration(int argc, char **argv) debugLabel=getArg(argc,argv,optind); if (!debugLabel) { - err("option \"-d\" is missing debug specifier.\n"); devUsage(); cleanUpDoxygen(); - exit(1); + exit(0); } retVal = Debug::setFlag(debugLabel); if (!retVal) { err("option \"-d\" has unknown debug specifier: \"%s\".\n",debugLabel); + devUsage(); cleanUpDoxygen(); exit(1); } @@ -10861,8 +10949,7 @@ void parseInput() if (cacheSize<0) cacheSize=0; if (cacheSize>9) cacheSize=9; uint lookupSize = 65536 << cacheSize; - Doxygen::lookupCache = new QCache<LookupInfo>(lookupSize,lookupSize); - Doxygen::lookupCache->setAutoDelete(TRUE); + Doxygen::lookupCache = new Cache<std::string,LookupInfo>(lookupSize); #ifdef HAS_SIGNALS signal(SIGINT, stopDoxygen); @@ -11504,6 +11591,8 @@ void generateOutput() generateExampleDocs(); g_s.end(); + warn_flush(); + g_s.begin("Generating file sources...\n"); generateFileSources(); g_s.end(); @@ -11608,6 +11697,8 @@ void generateOutput() if (g_useOutputTemplate) generateOutputViaTemplate(); + warn_flush(); + if (generateRtf) { g_s.begin("Combining RTF output...\n"); @@ -11618,10 +11709,14 @@ void generateOutput() g_s.end(); } + warn_flush(); + g_s.begin("Running plantuml with JAVA...\n"); PlantumlManager::instance()->run(); g_s.end(); + warn_flush(); + if (Config_getBool(HAVE_DOT)) { g_s.begin("Running dot...\n"); @@ -11669,6 +11764,9 @@ void generateOutput() QDir::setCurrent(oldDir); g_s.end(); } + + warn_flush(); + if ( generateHtml && Config_getBool(GENERATE_QHP) && !Config_getString(QHG_LOCATION).isEmpty()) @@ -11691,9 +11789,9 @@ void generateOutput() } int cacheParam; - msg("lookup cache used %d/%d hits=%d misses=%d\n", - Doxygen::lookupCache->count(), + msg("lookup cache used %zu/%zu hits=%" PRIu64 " misses=%" PRIu64 "\n", Doxygen::lookupCache->size(), + Doxygen::lookupCache->capacity(), Doxygen::lookupCache->hits(), Doxygen::lookupCache->misses()); cacheParam = computeIdealCacheParam(Doxygen::lookupCache->misses()*2/3); // part of the cache is flushed, hence the 2/3 correction factor diff --git a/src/doxygen.h b/src/doxygen.h index dc05750..f2b7dda 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -17,7 +17,6 @@ #define DOXYGEN_H #include <qdatetime.h> -#include <qcache.h> #include <qstrlist.h> #include <qdict.h> #include <qintdict.h> @@ -29,6 +28,7 @@ #include "dirdef.h" #include "memberlist.h" #include "define.h" +#include "cache.h" #define THREAD_LOCAL thread_local #define AtomicInt std::atomic_int @@ -78,11 +78,11 @@ class StringDict : public QDict<QCString> struct LookupInfo { - LookupInfo() : classDef(0), typeDef(0) {} + LookupInfo() = default; LookupInfo(const ClassDef *cd,const MemberDef *td,QCString ts,QCString rt) : classDef(cd), typeDef(td), templSpec(ts),resolvedType(rt) {} - const ClassDef *classDef; - const MemberDef *typeDef; + const ClassDef *classDef = 0; + const MemberDef *typeDef = 0; QCString templSpec; QCString resolvedType; }; @@ -127,7 +127,7 @@ class Doxygen static QDict<Definition> *clangUsrMap; static bool outputToWizard; static QDict<int> *htmlDirMap; - static QCache<LookupInfo> *lookupCache; + static Cache<std::string,LookupInfo> *lookupCache; static DirSDict *directories; static SDict<DirRelation> dirRelations; static ParserManager *parserManager; diff --git a/src/filedef.cpp b/src/filedef.cpp index f07201d..6ab4e85 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -101,7 +101,9 @@ class FileDefImpl : public DefinitionImpl, public FileDef virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const; virtual void writeSummaryLinks(OutputList &ol) const; virtual void writeTagFile(FTextStream &t); - virtual void writeSource(OutputList &ol,ClangTUParser *clangParser); + virtual void writeSourceHeader(OutputList &ol); + virtual void writeSourceBody(OutputList &ol,ClangTUParser *clangParser); + virtual void writeSourceFooter(OutputList &ol); virtual void parseSource(ClangTUParser *clangParser); virtual void setDiskName(const QCString &name); virtual void insertMember(MemberDef *md); @@ -208,6 +210,8 @@ class DevNullCodeDocInterface : public CodeOutputInterface virtual void linkableSymbol(int, const char *,Definition *,Definition *) {} virtual void setCurrentDoc(const Definition *,const char *,bool) {} virtual void addWord(const char *,bool) {} + virtual void startCodeFragment(const char *) {} + virtual void endCodeFragment(const char *) {} }; //--------------------------------------------------------------------------- @@ -311,6 +315,7 @@ void FileDefImpl::distributeMemberGroupDocumentation() void FileDefImpl::findSectionsInDocumentation() { + docFindSections(briefDescription(),this,docFile()); docFindSections(documentation(),this,docFile()); if (m_memberGroupSDict) { @@ -1149,14 +1154,12 @@ void FileDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentM } /*! Write a source listing of this file to the output */ -void FileDefImpl::writeSource(OutputList &ol,ClangTUParser *clangParser) +void FileDefImpl::writeSourceHeader(OutputList &ol) { bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); - bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); bool rtfSourceCode = Config_getBool(RTF_SOURCE_CODE); - DevNullCodeDocInterface devNullIntf; QCString title = m_docname; if (!m_fileVersion.isEmpty()) { @@ -1206,22 +1209,27 @@ void FileDefImpl::writeSource(OutputList &ol,ClangTUParser *clangParser) ol.endTextLink(); ol.popGeneratorState(); } +} +void FileDefImpl::writeSourceBody(OutputList &ol,ClangTUParser *clangParser) +{ + bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); + DevNullCodeDocInterface devNullIntf; #if USE_LIBCLANG if (Doxygen::clangAssistedParsing && clangParser && (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC)) { - ol.startCodeFragment(); + ol.startCodeFragment("DoxyCode"); clangParser->switchToFile(this); clangParser->writeSources(ol,this); - ol.endCodeFragment(); + ol.endCodeFragment("DoxyCode"); } else #endif { - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); - intf.resetCodeParserState(); - ol.startCodeFragment(); + auto intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); + intf->resetCodeParserState(); + ol.startCodeFragment("DoxyCode"); bool needs2PassParsing = Doxygen::parseSourcesNeeded && // we need to parse (filtered) sources for cross-references !filterSourceFiles && // but user wants to show sources as-is @@ -1230,13 +1238,13 @@ void FileDefImpl::writeSource(OutputList &ol,ClangTUParser *clangParser) if (needs2PassParsing) { // parse code for cross-references only (see bug707641) - intf.parseCode(devNullIntf,0, + intf->parseCode(devNullIntf,0, fileToString(absFilePath(),TRUE,TRUE), getLanguage(), FALSE,0,this ); } - intf.parseCode(ol,0, + intf->parseCode(ol,0, fileToString(absFilePath(),filterSourceFiles,TRUE), getLanguage(), // lang FALSE, // isExampleBlock @@ -1250,8 +1258,12 @@ void FileDefImpl::writeSource(OutputList &ol,ClangTUParser *clangParser) 0, // searchCtx !needs2PassParsing // collectXRefs ); - ol.endCodeFragment(); + ol.endCodeFragment("DoxyCode"); } +} + +void FileDefImpl::writeSourceFooter(OutputList &ol) +{ ol.endContents(); endFileWithNavPath(this,ol); ol.enableAll(); @@ -1271,9 +1283,9 @@ void FileDefImpl::parseSource(ClangTUParser *clangParser) else #endif { - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); - intf.resetCodeParserState(); - intf.parseCode( + auto intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); + intf->resetCodeParserState(); + intf->parseCode( devNullIntf,0, fileToString(absFilePath(),filterSourceFiles,TRUE), getLanguage(), diff --git a/src/filedef.h b/src/filedef.h index e4bb549..2e11b97 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -150,7 +150,9 @@ class FileDef : virtual public Definition virtual void writeSummaryLinks(OutputList &ol) const = 0; virtual void writeTagFile(FTextStream &t) = 0; - virtual void writeSource(OutputList &ol,ClangTUParser *clangParser) = 0; + virtual void writeSourceHeader(OutputList &ol) = 0; + virtual void writeSourceBody(OutputList &ol,ClangTUParser *clangParser) = 0; + virtual void writeSourceFooter(OutputList &ol) = 0; virtual void parseSource(ClangTUParser *clangParser) = 0; virtual void setDiskName(const QCString &name) = 0; diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 9b33356..7cd6cf2 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -228,6 +228,7 @@ void GroupDefImpl::distributeMemberGroupDocumentation() void GroupDefImpl::findSectionsInDocumentation() { + docFindSections(briefDescription(),this,docFile()); docFindSections(documentation(),this,docFile()); MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); MemberGroup *mg; diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index ea2dffb..6f740ba 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.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. * @@ -53,7 +50,7 @@ enum contexts_t INTERDD, // 8 INTERTD // 9 }; -static const char *contexts[10] = +static const char *contexts[10] = { "", // 0 "startli", // 1 "startdd", // 2 @@ -281,8 +278,8 @@ static QCString htmlAttribsToString(const HtmlAttribList &attribs, QCString *pAl //------------------------------------------------------------------------- HtmlDocVisitor::HtmlDocVisitor(FTextStream &t,CodeOutputInterface &ci, - const Definition *ctx) - : DocVisitor(DocVisitor_Html), m_t(t), m_ci(ci), m_insidePre(FALSE), + const Definition *ctx) + : DocVisitor(DocVisitor_Html), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_ctx(ctx) { if (ctx) m_langExt=ctx->getDefFileExtension(); @@ -439,12 +436,12 @@ void HtmlDocVisitor::visit(DocStyleChange *s) if (s->enable()) m_t << "<sup" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</sup>"; break; case DocStyleChange::Center: - if (s->enable()) + if (s->enable()) { forceEndParagraph(s); - m_t << "<center" << htmlAttribsToString(s->attribs()) << ">"; + m_t << "<center" << htmlAttribsToString(s->attribs()) << ">"; } - else + else { m_t << "</center>"; forceStartParagraph(s); @@ -468,12 +465,12 @@ void HtmlDocVisitor::visit(DocStyleChange *s) } break; case DocStyleChange::Div: - if (s->enable()) + if (s->enable()) { forceEndParagraph(s); - m_t << "<div" << htmlAttribsToString(s->attribs()) << ">"; + m_t << "<div" << htmlAttribsToString(s->attribs()) << ">"; } - else + else { m_t << "</div>"; forceStartParagraph(s); @@ -490,7 +487,7 @@ void HtmlDocVisitor::visit(DocStyleChange *s) static void visitPreCaption(FTextStream &t, DocVerbatim *s) { if (s->hasCaption()) - { + { t << "<div class=\"caption\">" << endl; } } @@ -523,11 +520,10 @@ void HtmlDocVisitor::visit(DocVerbatim *s) SrcLangExt langExt = getLanguageFromFileName(lang); switch(s->type()) { - case DocVerbatim::Code: + case DocVerbatim::Code: forceEndParagraph(s); - m_t << PREFRAG_START; - Doxygen::parserManager->getCodeParser(lang) - .parseCode(m_ci, + m_ci.startCodeFragment("DoxyCode"); + getCodeParser(lang).parseCode(m_ci, s->context(), s->text(), langExt, @@ -541,14 +537,14 @@ void HtmlDocVisitor::visit(DocVerbatim *s) TRUE, // show line numbers m_ctx // search context ); - m_t << PREFRAG_END; + m_ci.endCodeFragment("DoxyCode"); forceStartParagraph(s); break; - case DocVerbatim::Verbatim: + case DocVerbatim::Verbatim: forceEndParagraph(s); - m_t << /*PREFRAG_START <<*/ "<pre class=\"fragment\">"; + m_t << "<pre class=\"fragment\">"; filter(s->text()); - m_t << "</pre>" /*<< PREFRAG_END*/; + m_t << "</pre>"; forceStartParagraph(s); break; case DocVerbatim::HtmlOnly: @@ -558,12 +554,12 @@ void HtmlDocVisitor::visit(DocVerbatim *s) if (s->isBlock()) forceStartParagraph(s); } break; - case DocVerbatim::ManOnly: - case DocVerbatim::LatexOnly: - case DocVerbatim::XmlOnly: + case DocVerbatim::ManOnly: + case DocVerbatim::LatexOnly: + case DocVerbatim::XmlOnly: case DocVerbatim::RtfOnly: case DocVerbatim::DocbookOnly: - /* nothing */ + /* nothing */ break; case DocVerbatim::Dot: @@ -572,8 +568,8 @@ void HtmlDocVisitor::visit(DocVerbatim *s) QCString fileName(4096); forceEndParagraph(s); - fileName.sprintf("%s%d%s", - (Config_getString(HTML_OUTPUT)+"/inline_dotgraph_").data(), + fileName.sprintf("%s%d%s", + (Config_getString(HTML_OUTPUT)+"/inline_dotgraph_").data(), dotindex++, ".dot" ); @@ -606,8 +602,8 @@ void HtmlDocVisitor::visit(DocVerbatim *s) static int mscindex = 1; QCString baseName(4096); - baseName.sprintf("%s%d", - (Config_getString(HTML_OUTPUT)+"/inline_mscgraph_").data(), + baseName.sprintf("%s%d", + (Config_getString(HTML_OUTPUT)+"/inline_mscgraph_").data(), mscindex++ ); QFile file(baseName+".msc"); @@ -671,11 +667,10 @@ void HtmlDocVisitor::visit(DocInclude *inc) SrcLangExt langExt = getLanguageFromFileName(inc->extension()); switch(inc->type()) { - case DocInclude::Include: + case DocInclude::Include: forceEndParagraph(inc); - m_t << PREFRAG_START; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + m_ci.startCodeFragment("DoxyCode"); + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), inc->text(), langExt, @@ -687,24 +682,23 @@ void HtmlDocVisitor::visit(DocInclude *inc) TRUE, // inlineFragment 0, // memberDef FALSE, // show line numbers - m_ctx // search context + m_ctx // search context ); - m_t << PREFRAG_END; + m_ci.endCodeFragment("DoxyCode"); forceStartParagraph(inc); break; case DocInclude::IncWithLines: - { + { forceEndParagraph(inc); - m_t << PREFRAG_START; + m_ci.startCodeFragment("DoxyCode"); QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), inc->text(), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), fd, // fileDef, -1, // start line -1, // end line @@ -714,7 +708,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) m_ctx // search context ); delete fd; - m_t << PREFRAG_END; + m_ci.endCodeFragment("DoxyCode"); forceStartParagraph(inc); } break; @@ -733,24 +727,23 @@ void HtmlDocVisitor::visit(DocInclude *inc) if (inc->isBlock()) forceStartParagraph(inc); } break; - case DocInclude::VerbInclude: + case DocInclude::VerbInclude: forceEndParagraph(inc); - m_t << /*PREFRAG_START <<*/ "<pre class=\"fragment\">"; + m_t << "<pre class=\"fragment\">"; filter(inc->text()); - m_t << "</pre>" /*<< PREFRAG_END*/; + m_t << "</pre>"; forceStartParagraph(inc); break; case DocInclude::Snippet: { forceEndParagraph(inc); - m_t << PREFRAG_START; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + m_ci.startCodeFragment("DoxyCode"); + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), 0, -1, // startLine -1, // endLine @@ -759,23 +752,22 @@ void HtmlDocVisitor::visit(DocInclude *inc) FALSE, // show line number m_ctx // search context ); - m_t << PREFRAG_END; + m_ci.endCodeFragment("DoxyCode"); forceStartParagraph(inc); } break; case DocInclude::SnipWithLines: { forceEndParagraph(inc); - m_t << PREFRAG_START; + m_ci.startCodeFragment("DoxyCode"); QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine @@ -785,12 +777,12 @@ void HtmlDocVisitor::visit(DocInclude *inc) m_ctx // search context ); delete fd; - m_t << PREFRAG_END; + m_ci.endCodeFragment("DoxyCode"); forceStartParagraph(inc); } 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; @@ -801,20 +793,20 @@ void HtmlDocVisitor::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()) { forceEndParagraph(op); - if (!m_hide) m_t << PREFRAG_START; + if (!m_hide) m_ci.startCodeFragment("DoxyCode"); pushEnabled(); m_hide=TRUE; } 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()) @@ -822,8 +814,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op) QFileInfo cfi( op->includeFileName() ); fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getCodeParser(locLangExt) - .parseCode( + getCodeParser(locLangExt).parseCode( m_ci, op->context(), op->text(), @@ -843,10 +834,10 @@ void HtmlDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide=TRUE; } - if (op->isLast()) + if (op->isLast()) { popEnabled(); - if (!m_hide) m_t << PREFRAG_END; + if (!m_hide) m_ci.endCodeFragment("DoxyCode"); forceStartParagraph(op); } else @@ -859,7 +850,7 @@ void HtmlDocVisitor::visit(DocFormula *f) { if (m_hide) return; bool bDisplay = !f->isInline(); - if (bDisplay) + if (bDisplay) { forceEndParagraph(f); m_t << "<p class=\"formulaDsp\">" << endl; @@ -869,7 +860,7 @@ void HtmlDocVisitor::visit(DocFormula *f) { QCString text = f->text(); bool closeInline = FALSE; - if (!bDisplay && !text.isEmpty() && text.at(0)=='$' && + if (!bDisplay && !text.isEmpty() && text.at(0)=='$' && text.at(text.length()-1)=='$') { closeInline=TRUE; @@ -884,7 +875,7 @@ void HtmlDocVisitor::visit(DocFormula *f) } else { - m_t << "<img class=\"formula" + m_t << "<img class=\"formula" << (bDisplay ? "Dsp" : "Inl"); m_t << "\" alt=\""; filterQuotedCdataAttr(f->text()); @@ -919,7 +910,7 @@ void HtmlDocVisitor::visit(DocFormula *f) void HtmlDocVisitor::visit(DocIndexEntry *e) { QCString anchor = convertIndexWordToAnchor(e->entry()); - if (e->member()) + if (e->member()) { anchor.prepend(e->member()->anchor()+"_"); } @@ -941,7 +932,7 @@ void HtmlDocVisitor::visit(DocSimpleSectSep *) void HtmlDocVisitor::visit(DocCite *cite) { if (m_hide) return; - if (!cite->file().isEmpty()) + if (!cite->file().isEmpty()) { startLink(cite->ref(),cite->file(),cite->relPath(),cite->anchor()); } @@ -950,7 +941,7 @@ void HtmlDocVisitor::visit(DocCite *cite) m_t << "<b>["; } filter(cite->text()); - if (!cite->file().isEmpty()) + if (!cite->file().isEmpty()) { endLink(); } @@ -978,7 +969,7 @@ void HtmlDocVisitor::visitPre(DocAutoList *l) // 1. // a. // i. - // A. + // A. // 1. (repeat)... // m_t << "<ol type=\"" << types[l->depth() % NUM_HTML_LIST_TYPES] << "\""; @@ -1013,20 +1004,20 @@ void HtmlDocVisitor::visitPre(DocAutoListItem *) m_t << "<li>"; } -void HtmlDocVisitor::visitPost(DocAutoListItem *li) +void HtmlDocVisitor::visitPost(DocAutoListItem *li) { if (m_hide) return; m_t << "</li>"; if (!li->isPreformatted()) m_t << "\n"; } -template<class T> +template<class T> bool isFirstChildNode(T *parent, DocNode *node) { return parent->children().getFirst()==node; } -template<class T> +template<class T> bool isLastChildNode(T *parent, DocNode *node) { return parent->children().getLast()==node; @@ -1070,7 +1061,7 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) isLast=FALSE; if (p && p->parent()) { - switch (p->parent()->kind()) + switch (p->parent()->kind()) { case DocNode::Kind_ParBlock: { // hierarchy: node N -> para -> parblock -> para @@ -1215,7 +1206,7 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) return t; } -void HtmlDocVisitor::visitPre(DocPara *p) +void HtmlDocVisitor::visitPre(DocPara *p) { if (m_hide) return; @@ -1223,9 +1214,9 @@ void HtmlDocVisitor::visitPre(DocPara *p) // p->parent() ? p->parent()->kind() : -1); bool needsTag = FALSE; - if (p && p->parent()) + if (p && p->parent()) { - switch (p->parent()->kind()) + switch (p->parent()->kind()) { case DocNode::Kind_Section: case DocNode::Kind_Internal: @@ -1250,7 +1241,7 @@ void HtmlDocVisitor::visitPre(DocPara *p) } // if the first element of a paragraph is something that should be outside of - // the paragraph (<ul>,<dl>,<table>,..) then that will already started the + // the paragraph (<ul>,<dl>,<table>,..) then that will already started the // paragraph and we don't need to do it here bool paragraphAlreadyStarted = false; uint nodeIndex = 0; @@ -1296,9 +1287,9 @@ void HtmlDocVisitor::visitPost(DocPara *p) // p->parent() ? p->parent()->kind() : -1); bool needsTag = FALSE; - if (p->parent()) + if (p->parent()) { - switch (p->parent()->kind()) + switch (p->parent()->kind()) { case DocNode::Kind_Section: case DocNode::Kind_Internal: @@ -1323,7 +1314,7 @@ void HtmlDocVisitor::visitPost(DocPara *p) } // if the last element of a paragraph is something that should be outside of - // the paragraph (<ul>,<dl>,<table>) then that will already have ended the + // the paragraph (<ul>,<dl>,<table>) then that will already have ended the // paragraph and we don't need to do it here int nodeIndex = p->children().count()-1; if (nodeIndex>=0) @@ -1372,21 +1363,21 @@ void HtmlDocVisitor::visitPre(DocSimpleSect *s) m_t << "<dl class=\"section " << s->typeString() << "\"><dt>"; 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; @@ -1454,7 +1445,7 @@ void HtmlDocVisitor::visitPre(DocSimpleListItem *) m_t << "<li>"; } -void HtmlDocVisitor::visitPost(DocSimpleListItem *li) +void HtmlDocVisitor::visitPost(DocSimpleListItem *li) { if (m_hide) return; m_t << "</li>"; @@ -1472,7 +1463,7 @@ void HtmlDocVisitor::visitPre(DocSection *s) m_t << "</h" << s->level() << ">\n"; } -void HtmlDocVisitor::visitPost(DocSection *s) +void HtmlDocVisitor::visitPost(DocSection *s) { forceStartParagraph(s); } @@ -1481,26 +1472,26 @@ void HtmlDocVisitor::visitPre(DocHtmlList *s) { if (m_hide) return; forceEndParagraph(s); - if (s->type()==DocHtmlList::Ordered) + if (s->type()==DocHtmlList::Ordered) { - m_t << "<ol" << htmlAttribsToString(s->attribs()); + m_t << "<ol" << htmlAttribsToString(s->attribs()); } - else + else { m_t << "<ul" << htmlAttribsToString(s->attribs()); } m_t << getDirHtmlClassOfNode(getTextDirByConfig(s)) << ">\n"; } -void HtmlDocVisitor::visitPost(DocHtmlList *s) +void HtmlDocVisitor::visitPost(DocHtmlList *s) { if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) + if (s->type()==DocHtmlList::Ordered) { - m_t << "</ol>"; + m_t << "</ol>"; } else - { + { m_t << "</ul>"; } if (!s->isPreformatted()) m_t << "\n"; @@ -1514,7 +1505,7 @@ void HtmlDocVisitor::visitPre(DocHtmlListItem *i) if (!i->isPreformatted()) m_t << "\n"; } -void HtmlDocVisitor::visitPost(DocHtmlListItem *) +void HtmlDocVisitor::visitPost(DocHtmlListItem *) { if (m_hide) return; m_t << "</li>\n"; @@ -1527,7 +1518,7 @@ void HtmlDocVisitor::visitPre(DocHtmlDescList *dl) m_t << "<dl" << htmlAttribsToString(dl->attribs()) << ">\n"; } -void HtmlDocVisitor::visitPost(DocHtmlDescList *dl) +void HtmlDocVisitor::visitPost(DocHtmlDescList *dl) { if (m_hide) return; m_t << "</dl>\n"; @@ -1542,7 +1533,7 @@ void HtmlDocVisitor::visitPre(DocHtmlDescTitle *dt) << ">"; } -void HtmlDocVisitor::visitPost(DocHtmlDescTitle *) +void HtmlDocVisitor::visitPost(DocHtmlDescTitle *) { if (m_hide) return; m_t << "</dt>\n"; @@ -1551,12 +1542,12 @@ void HtmlDocVisitor::visitPost(DocHtmlDescTitle *) void HtmlDocVisitor::visitPre(DocHtmlDescData *dd) { if (m_hide) return; - m_t << "<dd" << htmlAttribsToString(dd->attribs()) + m_t << "<dd" << htmlAttribsToString(dd->attribs()) << getDirHtmlClassOfNode(getTextDirByConfig(dd)) << ">"; } -void HtmlDocVisitor::visitPost(DocHtmlDescData *) +void HtmlDocVisitor::visitPost(DocHtmlDescData *) { if (m_hide) return; m_t << "</dd>\n"; @@ -1598,7 +1589,7 @@ void HtmlDocVisitor::visitPre(DocHtmlTable *t) } } -void HtmlDocVisitor::visitPost(DocHtmlTable *t) +void HtmlDocVisitor::visitPost(DocHtmlTable *t) { if (m_hide) return; m_t << "</table>\n"; @@ -1611,7 +1602,7 @@ void HtmlDocVisitor::visitPre(DocHtmlRow *tr) m_t << "<tr" << htmlAttribsToString(tr->attribs()) << ">\n"; } -void HtmlDocVisitor::visitPost(DocHtmlRow *) +void HtmlDocVisitor::visitPost(DocHtmlRow *) { if (m_hide) return; m_t << "</tr>\n"; @@ -1620,17 +1611,17 @@ void HtmlDocVisitor::visitPost(DocHtmlRow *) void HtmlDocVisitor::visitPre(DocHtmlCell *c) { if (m_hide) return; - if (c->isHeading()) + if (c->isHeading()) { - m_t << "<th" << htmlAttribsToString(c->attribs()) << ">"; + m_t << "<th" << htmlAttribsToString(c->attribs()) << ">"; } - else + else { m_t << "<td" << htmlAttribsToString(c->attribs()) << ">"; } } -void HtmlDocVisitor::visitPost(DocHtmlCell *c) +void HtmlDocVisitor::visitPost(DocHtmlCell *c) { if (m_hide) return; if (c->isHeading()) m_t << "</th>"; else m_t << "</td>"; @@ -1642,7 +1633,7 @@ void HtmlDocVisitor::visitPre(DocHtmlCaption *c) m_t << "<caption" << htmlAttribsToString(c->attribs()) << ">"; } -void HtmlDocVisitor::visitPost(DocHtmlCaption *) +void HtmlDocVisitor::visitPost(DocHtmlCaption *) { if (m_hide) return; m_t << "</caption>\n"; @@ -1655,7 +1646,7 @@ void HtmlDocVisitor::visitPre(DocInternal *) //m_t << "<p><b>" << theTranslator->trForInternalUseOnly() << "</b></p>" << endl; } -void HtmlDocVisitor::visitPost(DocInternal *) +void HtmlDocVisitor::visitPost(DocInternal *) { if (m_hide) return; //forceStartParagraph(i); @@ -1676,7 +1667,7 @@ void HtmlDocVisitor::visitPre(DocHRef *href) } } -void HtmlDocVisitor::visitPost(DocHRef *) +void HtmlDocVisitor::visitPost(DocHRef *) { if (m_hide) return; m_t << "</a>"; @@ -1686,13 +1677,13 @@ void HtmlDocVisitor::visitPre(DocHtmlHeader *header) { if (m_hide) return; forceEndParagraph(header); - m_t << "<h" << header->level() - << htmlAttribsToString(header->attribs()) + m_t << "<h" << header->level() + << htmlAttribsToString(header->attribs()) << getDirHtmlClassOfNode(getTextDirByConfig(header)) << ">"; } -void HtmlDocVisitor::visitPost(DocHtmlHeader *header) +void HtmlDocVisitor::visitPost(DocHtmlHeader *header) { if (m_hide) return; m_t << "</h" << header->level() << ">\n"; @@ -1834,12 +1825,12 @@ void HtmlDocVisitor::visitPre(DocDotFile *df) m_t << "<div class=\"dotgraph\">" << endl; writeDotFile(df->file(),df->relPath(),df->context()); if (df->hasCaption()) - { + { m_t << "<div class=\"caption\">" << endl; } } -void HtmlDocVisitor::visitPost(DocDotFile *df) +void HtmlDocVisitor::visitPost(DocDotFile *df) { if (m_hide) return; if (df->hasCaption()) @@ -1855,11 +1846,11 @@ void HtmlDocVisitor::visitPre(DocMscFile *df) m_t << "<div class=\"mscgraph\">" << endl; writeMscFile(df->file(),df->relPath(),df->context()); if (df->hasCaption()) - { + { m_t << "<div class=\"caption\">" << endl; } } -void HtmlDocVisitor::visitPost(DocMscFile *df) +void HtmlDocVisitor::visitPost(DocMscFile *df) { if (m_hide) return; if (df->hasCaption()) @@ -1895,7 +1886,7 @@ void HtmlDocVisitor::visitPre(DocLink *lnk) startLink(lnk->ref(),lnk->file(),lnk->relPath(),lnk->anchor()); } -void HtmlDocVisitor::visitPost(DocLink *) +void HtmlDocVisitor::visitPost(DocLink *) { if (m_hide) return; endLink(); @@ -1904,7 +1895,7 @@ void HtmlDocVisitor::visitPost(DocLink *) void HtmlDocVisitor::visitPre(DocRef *ref) { if (m_hide) return; - if (!ref->file().isEmpty()) + if (!ref->file().isEmpty()) { // when ref->isSubPage()==TRUE we use ref->file() for HTML and // ref->anchor() for LaTeX/RTF @@ -1913,7 +1904,7 @@ void HtmlDocVisitor::visitPre(DocRef *ref) if (!ref->hasLinkText()) filter(ref->targetTitle()); } -void HtmlDocVisitor::visitPost(DocRef *ref) +void HtmlDocVisitor::visitPost(DocRef *ref) { if (m_hide) return; if (!ref->file().isEmpty()) endLink(); @@ -1928,7 +1919,7 @@ void HtmlDocVisitor::visitPre(DocSecRefItem *ref) } -void HtmlDocVisitor::visitPost(DocSecRefItem *) +void HtmlDocVisitor::visitPost(DocSecRefItem *) { if (m_hide) return; m_t << "</a></li>\n"; @@ -1942,7 +1933,7 @@ void HtmlDocVisitor::visitPre(DocSecRefList *s) m_t << "<ul class=\"multicol\">" << endl; } -void HtmlDocVisitor::visitPost(DocSecRefList *s) +void HtmlDocVisitor::visitPost(DocSecRefList *s) { if (m_hide) return; m_t << "</ul>" << endl; @@ -1960,7 +1951,7 @@ void HtmlDocVisitor::visitPost(DocSecRefList *s) // } //} // -//void HtmlDocVisitor::visitPost(DocLanguage *l) +//void HtmlDocVisitor::visitPost(DocLanguage *l) //{ // QCString langId = Config_getEnum(OUTPUT_LANGUAGE); // if (l->id().lower()!=langId.lower()) @@ -1977,19 +1968,19 @@ void HtmlDocVisitor::visitPre(DocParamSect *s) QCString heading; switch(s->type()) { - case DocParamSect::Param: - heading=theTranslator->trParameters(); + case DocParamSect::Param: + heading=theTranslator->trParameters(); className="params"; break; - case DocParamSect::RetVal: - heading=theTranslator->trReturnValues(); + case DocParamSect::RetVal: + heading=theTranslator->trReturnValues(); className="retval"; break; - case DocParamSect::Exception: - heading=theTranslator->trExceptions(); + case DocParamSect::Exception: + heading=theTranslator->trExceptions(); className="exception"; break; - case DocParamSect::TemplateParam: + case DocParamSect::TemplateParam: heading=theTranslator->trTemplateParameters(); className="tparams"; break; @@ -2052,11 +2043,11 @@ void HtmlDocVisitor::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) { @@ -2076,11 +2067,11 @@ void HtmlDocVisitor::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 << "</td><td>"; @@ -2102,12 +2093,12 @@ void HtmlDocVisitor::visitPre(DocXRefItem *x) bool anonymousEnum = x->file()=="@"; if (!anonymousEnum) { - m_t << "<dl" << getDirHtmlClassOfNode(getTextDirByConfig(x), x->key()) + m_t << "<dl" << getDirHtmlClassOfNode(getTextDirByConfig(x), x->key()) << "><dt><b><a class=\"el\" href=\"" << x->relPath() << addHtmlExtensionIfMissing(x->file()) << "#" << x->anchor() << "\">"; } - else + else { m_t << "<dl class=\"" << x->key() << "\"><dt><b>"; } @@ -2131,7 +2122,7 @@ void HtmlDocVisitor::visitPre(DocInternalRef *ref) startLink(0,ref->file(),ref->relPath(),ref->anchor()); } -void HtmlDocVisitor::visitPost(DocInternalRef *) +void HtmlDocVisitor::visitPost(DocInternalRef *) { if (m_hide) return; endLink(); @@ -2180,7 +2171,7 @@ void HtmlDocVisitor::visitPre(DocVhdlFlow *vf) m_t << "<p>"; m_t << "flowchart: " ; // TODO: translate me m_t << "<a href=\""; - m_t << fname.data(); + m_t << fname.data(); m_t << ".svg\">"; m_t << VhdlDocGen::getFlowMember()->name().data(); m_t << "</a>"; @@ -2214,7 +2205,7 @@ void HtmlDocVisitor::visitPost(DocParBlock *) void HtmlDocVisitor::filter(const char *str) -{ +{ if (str==0) return; const char *p=str; char c; diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 2c89507..ea4d895 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -16,8 +16,10 @@ */ #include <stdlib.h> - #include <assert.h> + +#include <mutex> + #include <qdir.h> #include <qregexp.h> #include "message.h" @@ -59,8 +61,6 @@ static QCString g_footer; static QCString g_mathjax_code; static QCString g_latex_macro; -static bool DoxyCodeLineOpen = FALSE; - // note: this is only active if DISABLE_INDEX=YES, if DISABLE_INDEX is disabled, this // part will be rendered inside menu.js static void writeClientSearchBox(FTextStream &t,const char *relPath) @@ -608,12 +608,11 @@ static QCString substituteHtmlKeywords(const QCString &str, //-------------------------------------------------------------------------- HtmlCodeGenerator::HtmlCodeGenerator() - : m_streamSet(FALSE), m_col(0) { } HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath) - : m_col(0), m_relPath(relPath) + : m_relPath(relPath) { setTextStream(t); } @@ -726,10 +725,10 @@ void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename, qsnprintf(lineNumber,maxLineNrStr,"%5d",l); qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l); - if (!DoxyCodeLineOpen) + if (!m_lineOpen) { m_t << "<div class=\"line\">"; - DoxyCodeLineOpen = TRUE; + m_lineOpen = TRUE; } m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">"; @@ -868,10 +867,10 @@ void HtmlCodeGenerator::startCodeLine(bool) if (m_streamSet) { m_col=0; - if (!DoxyCodeLineOpen) + if (!m_lineOpen) { m_t << "<div class=\"line\">"; - DoxyCodeLineOpen = TRUE; + m_lineOpen = TRUE; } } } @@ -885,10 +884,10 @@ void HtmlCodeGenerator::endCodeLine() m_t << " "; m_col++; } - if (DoxyCodeLineOpen) + if (m_lineOpen) { m_t << "</div>\n"; - DoxyCodeLineOpen = FALSE; + m_lineOpen = FALSE; } } } @@ -908,6 +907,20 @@ void HtmlCodeGenerator::writeCodeAnchor(const char *anchor) if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>"; } +void HtmlCodeGenerator::startCodeFragment(const char *) +{ + if (m_streamSet) m_t << "<div class=\"fragment\">"; +} + +void HtmlCodeGenerator::endCodeFragment(const char *) +{ + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + + if (m_streamSet) m_t << "</div><!-- fragment -->"; +} + + //-------------------------------------------------------------------------- HtmlGenerator::HtmlGenerator() : OutputGenerator(Config_getString(HTML_OUTPUT)) @@ -1114,6 +1127,8 @@ void HtmlGenerator::writeFooterFile(QFile &file) t << ResourceMgr::instance().getAsString("footer.html"); } +static std::mutex g_indexLock; + void HtmlGenerator::startFile(const char *name,const char *, const char *title) { @@ -1125,7 +1140,10 @@ void HtmlGenerator::startFile(const char *name,const char *, startPlainFile(fileName); m_codeGen.setTextStream(t); m_codeGen.setRelativePath(m_relPath); - Doxygen::indexList->addIndexFile(fileName); + { + std::lock_guard<std::mutex> lock(g_indexLock); + Doxygen::indexList->addIndexFile(fileName); + } m_lastFile = fileName; t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),m_relPath); @@ -2861,19 +2879,6 @@ void HtmlGenerator::endConstraintList() t << "</div>" << endl; } -void HtmlGenerator::startCodeFragment() -{ - t << PREFRAG_START; -} - -void HtmlGenerator::endCodeFragment() -{ - //endCodeLine checks is there is still an open code line, if so closes it. - endCodeLine(); - - t << PREFRAG_END; -} - void HtmlGenerator::lineBreak(const char *style) { if (style) diff --git a/src/htmlgen.h b/src/htmlgen.h index 9487e60..45899a6 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.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 @@ -21,11 +19,6 @@ #include "outputgen.h" #include "ftextstream.h" -//#define PREFRAG_START "<div class=\"fragment\"><pre class=\"fragment\">" -//#define PREFRAG_END "</pre></div>" -#define PREFRAG_START "<div class=\"fragment\">" -#define PREFRAG_END "</div><!-- fragment -->" - class QFile; class HtmlCodeGenerator : public CodeOutputInterface @@ -54,6 +47,8 @@ class HtmlCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const char *anchor); void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} + void startCodeFragment(const char *style); + void endCodeFragment(const char *); private: void _writeCodeLink(const char *className, @@ -61,10 +56,11 @@ class HtmlCodeGenerator : public CodeOutputInterface const char *anchor,const char *name, const char *tooltip); void docify(const char *str); - bool m_streamSet; + bool m_streamSet = false; FTextStream m_t; - int m_col; + int m_col = 0; QCString m_relPath; + bool m_lineOpen = false; }; /** Generator for HTML output */ @@ -113,6 +109,10 @@ class HtmlGenerator : public OutputGenerator { m_codeGen.endFontClass(); } void writeCodeAnchor(const char *anchor) { m_codeGen.writeCodeAnchor(anchor); } + void startCodeFragment(const char *style) + { m_codeGen.startCodeFragment(style); } + void endCodeFragment(const char *style) + { m_codeGen.endCodeFragment(style); } // --------------------------- void setCurrentDoc(const Definition *context,const char *anchor,bool isSourceFile); @@ -208,8 +208,6 @@ class HtmlGenerator : public OutputGenerator void writeRuler() { t << "<hr/>"; } void writeAnchor(const char *,const char *name) { t << "<a name=\"" << name <<"\" id=\"" << name << "\"></a>"; } - void startCodeFragment(); - void endCodeFragment(); void startEmphasis() { t << "<em>"; } void endEmphasis() { t << "</em>"; } void startBold() { t << "<b>"; } diff --git a/src/index.cpp b/src/index.cpp index 12f35f2..4df2ce4 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -4499,7 +4499,7 @@ static void writeIndex(OutputList &ol) { ol.startHeaderSection(); ol.startTitleHead(0); - ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(), + ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine(), Doxygen::mainPage,0,Doxygen::mainPage->title(),TRUE,FALSE, 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)); headerWritten = TRUE; diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 19f01b0..fbb6530 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -175,7 +175,7 @@ QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) } -LatexDocVisitor::LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci, +LatexDocVisitor::LatexDocVisitor(FTextStream &t,LatexCodeGenerator &ci, const char *langExt,bool insideTabbing) : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE), m_insideItem(FALSE), m_hide(FALSE), m_hideCaption(FALSE), m_insideTabbing(insideTabbing), @@ -351,13 +351,10 @@ void LatexDocVisitor::visit(DocVerbatim *s) { case DocVerbatim::Code: { - m_t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n"; - LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getCodeParser(lang) - .parseCode(m_ci,s->context(),s->text(),langExt, - s->isExample(),s->exampleFile()); - LatexCodeGenerator::setDoxyCodeOpen(FALSE); - m_t << "\\end{DoxyCode}\n"; + m_ci.startCodeFragment("DoxyCode"); + getCodeParser(lang).parseCode(m_ci,s->context(),s->text(),langExt, + s->isExample(),s->exampleFile()); + m_ci.endCodeFragment("DoxyCode"); } break; case DocVerbatim::Verbatim: @@ -461,44 +458,40 @@ void LatexDocVisitor::visit(DocInclude *inc) { case DocInclude::IncWithLines: { - m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; - LatexCodeGenerator::setDoxyCodeOpen(TRUE); - QFileInfo cfi( inc->file() ); - FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), - inc->text(), - langExt, - inc->isExample(), - inc->exampleFile(), - fd, // fileDef, - -1, // start line - -1, // end line - FALSE, // inline fragment - 0, // memberDef - TRUE // show line numbers - ); - delete fd; - LatexCodeGenerator::setDoxyCodeOpen(FALSE); - m_t << "\\end{DoxyCodeInclude}" << endl; + m_ci.startCodeFragment("DoxyCodeInclude"); + QFileInfo cfi( inc->file() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), + inc->text(), + langExt, + inc->isExample(), + inc->exampleFile(), + fd, // fileDef, + -1, // start line + -1, // end line + FALSE, // inline fragment + 0, // memberDef + TRUE // show line numbers + ); + delete fd; + m_ci.endCodeFragment("DoxyCodeInclude"); } break; case DocInclude::Include: - m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; - LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), - inc->text(),langExt,inc->isExample(), - inc->exampleFile(), - 0, // fileDef - -1, // startLine - -1, // endLine - TRUE, // inlineFragment - 0, // memberDef - FALSE - ); - LatexCodeGenerator::setDoxyCodeOpen(FALSE); - m_t << "\\end{DoxyCodeInclude}\n"; + { + m_ci.startCodeFragment("DoxyCodeInclude"); + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), + inc->text(),langExt,inc->isExample(), + inc->exampleFile(), + 0, // fileDef + -1, // startLine + -1, // endLine + TRUE, // inlineFragment + 0, // memberDef + FALSE + ); + m_ci.endCodeFragment("DoxyCodeInclude"); + } break; case DocInclude::DontInclude: case DocInclude::DontIncWithLines: @@ -518,43 +511,37 @@ void LatexDocVisitor::visit(DocInclude *inc) break; case DocInclude::Snippet: { - m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; - LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), - langExt, - inc->isExample(), - inc->exampleFile() - ); - LatexCodeGenerator::setDoxyCodeOpen(FALSE); - m_t << "\\end{DoxyCodeInclude}" << endl; + m_ci.startCodeFragment("DoxyCodeInclude"); + getCodeParser(inc->extension()).parseCode(m_ci, + inc->context(), + extractBlock(inc->text(),inc->blockId()), + langExt, + inc->isExample(), + inc->exampleFile() + ); + m_ci.endCodeFragment("DoxyCodeInclude"); } break; case DocInclude::SnipWithLines: { - QFileInfo cfi( inc->file() ); - FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; - LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), - langExt, - inc->isExample(), - inc->exampleFile(), - fd, - lineBlock(inc->text(),inc->blockId()), - -1, // endLine - FALSE, // inlineFragment - 0, // memberDef - TRUE // show line number - ); - delete fd; - LatexCodeGenerator::setDoxyCodeOpen(FALSE); - m_t << "\\end{DoxyCodeInclude}" << endl; + QFileInfo cfi( inc->file() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + m_ci.startCodeFragment("DoxyCodeInclude"); + getCodeParser(inc->extension()).parseCode(m_ci, + inc->context(), + extractBlock(inc->text(),inc->blockId()), + langExt, + inc->isExample(), + inc->exampleFile(), + fd, + lineBlock(inc->text(),inc->blockId()), + -1, // endLine + FALSE, // inlineFragment + 0, // memberDef + TRUE // show line number + ); + delete fd; + m_ci.endCodeFragment("DoxyCodeInclude"); } break; case DocInclude::SnippetDoc: @@ -571,8 +558,7 @@ void LatexDocVisitor::visit(DocIncOperator *op) // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { - if (!m_hide) m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; - LatexCodeGenerator::setDoxyCodeOpen(TRUE); + if (!m_hide) m_ci.startCodeFragment("DoxyCodeInclude"); pushEnabled(); m_hide = TRUE; } @@ -591,16 +577,15 @@ void LatexDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getCodeParser(locLangExt) - .parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile(), - fd, // fileDef - op->line(), // startLine - -1, // endLine - FALSE, // inline fragment - 0, // memberDef - op->showLineNo() // show line numbers - ); + getCodeParser(locLangExt).parseCode(m_ci,op->context(),op->text(),langExt, + op->isExample(),op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); if (fd) delete fd; } pushEnabled(); @@ -609,8 +594,7 @@ void LatexDocVisitor::visit(DocIncOperator *op) if (op->isLast()) { popEnabled(); - LatexCodeGenerator::setDoxyCodeOpen(FALSE); - if (!m_hide) m_t << "\n\\end{DoxyCodeInclude}\n"; + if (!m_hide) m_ci.endCodeFragment("DoxyCodeInclude"); } else { @@ -1504,7 +1488,7 @@ void LatexDocVisitor::visitPre(DocParamSect *s) if (m_hide) return; bool hasInOutSpecs = s->hasInOutSpecifier(); bool hasTypeSpecs = s->hasTypeSpecifier(); - incUsedTableLevels(); + m_ci.incUsedTableLevel(); switch(s->type()) { case DocParamSect::Param: @@ -1535,7 +1519,7 @@ void LatexDocVisitor::visitPre(DocParamSect *s) void LatexDocVisitor::visitPost(DocParamSect *s) { if (m_hide) return; - decUsedTableLevels(); + m_ci.decUsedTableLevel(); switch(s->type()) { case DocParamSect::Param: @@ -1754,7 +1738,13 @@ void LatexDocVisitor::visitPost(DocParBlock *) void LatexDocVisitor::filter(const char *str) { - filterLatexString(m_t,str,m_insideTabbing,m_insidePre,m_insideItem); + filterLatexString(m_t,str, + m_insideTabbing, + m_insidePre, + m_insideItem, + m_ci.usedTableLevel()>0, // insideTable + false // keepSpaces + ); } void LatexDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor,bool refToTable) diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index 71fb5be..003d780 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -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. * @@ -25,19 +25,19 @@ #include <qlist.h> class FTextStream; -class CodeOutputInterface; +class LatexCodeGenerator; /*! @brief Concrete visitor implementation for LaTeX output. */ class LatexDocVisitor : public DocVisitor { public: - LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci, + LatexDocVisitor(FTextStream &t,LatexCodeGenerator &ci, const char *langExt,bool insideTabbing); - + //-------------------------------------- // visitor functions for leaf nodes //-------------------------------------- - + void visit(DocWord *); void visit(DocLinkedWord *); void visit(DocWhiteSpace *); @@ -59,7 +59,7 @@ class LatexDocVisitor : public DocVisitor //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - + void visitPre(DocAutoList *); void visitPost(DocAutoList *); void visitPre(DocAutoListItem *); @@ -141,7 +141,7 @@ class LatexDocVisitor : public DocVisitor struct ActiveRowSpan { - ActiveRowSpan(DocHtmlCell *c,int rs,int cs,int col) + ActiveRowSpan(DocHtmlCell *c,int rs,int cs,int col) : cell(c), rowSpan(rs), colSpan(cs), column(col) {} DocHtmlCell *cell; int rowSpan; @@ -152,9 +152,9 @@ class LatexDocVisitor : public DocVisitor typedef QList<ActiveRowSpan> RowSpanList; //-------------------------------------- - // helper functions + // helper functions //-------------------------------------- - + void filter(const char *str); void startLink(const QCString &ref,const QCString &file, const QCString &anchor,bool refToTable=FALSE); @@ -184,7 +184,7 @@ class LatexDocVisitor : public DocVisitor //-------------------------------------- FTextStream &m_t; - CodeOutputInterface &m_ci; + LatexCodeGenerator &m_ci; bool m_insidePre; bool m_insideItem; bool m_hide; @@ -195,7 +195,7 @@ class LatexDocVisitor : public DocVisitor struct TableState { - TableState() : numCols(0), currentColumn(0), inRowSpan(FALSE), + TableState() : numCols(0), currentColumn(0), inRowSpan(FALSE), inColSpan(FALSE), firstRow(FALSE) { rowSpans.setAutoDelete(TRUE); } RowSpanList rowSpans; diff --git a/src/latexgen.cpp b/src/latexgen.cpp index b70f82a..3343c1a 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -44,18 +44,14 @@ #include "resourcemgr.h" #include "portable.h" -static bool DoxyCodeOpen = FALSE; -static bool DoxyCodeLineOpen = FALSE; -//------------------------------- - LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName) - : m_relPath(relPath), m_sourceFileName(sourceFileName), m_col(0) + : m_relPath(relPath), m_sourceFileName(sourceFileName) { m_prettyCode=Config_getBool(LATEX_SOURCE_CODE); setTextStream(t); } -LatexCodeGenerator::LatexCodeGenerator() : m_streamSet(FALSE), m_col(0) +LatexCodeGenerator::LatexCodeGenerator() { m_prettyCode=Config_getBool(LATEX_SOURCE_CODE); } @@ -85,8 +81,8 @@ void LatexCodeGenerator::codify(const char *str) //char cs[5]; int spacesToNextTabStop; int tabSize = Config_getInt(TAB_SIZE); - static signed char *result = NULL; - static int lresult = 0; + static THREAD_LOCAL signed char *result = NULL; + static THREAD_LOCAL int lresult = 0; int i; while ((c=*p)) { @@ -108,7 +104,9 @@ void LatexCodeGenerator::codify(const char *str) m_col+=spacesToNextTabStop; p++; break; - case '\n': (usedTableLevels()>0 && !DoxyCodeOpen) ? m_t << "\\newline\n" : m_t << '\n'; m_col=0; p++; + case '\n': m_t << '\n'; + m_col=0; + p++; break; default: i=0; @@ -149,14 +147,13 @@ void LatexCodeGenerator::codify(const char *str) COPYCHAR(); } result[i]=0; // add terminator - //if (m_prettyCode) - //{ - filterLatexString(m_t,(const char *)result,FALSE,TRUE); - //} - //else - //{ - // t << result; - //} + filterLatexString(m_t,(const char *)result, + false, // insideTabbing + true, // insidePre + false, // insideItem + m_usedTableLevel>0, // insideTable + false // keepSpaces + ); break; } } @@ -192,10 +189,10 @@ void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,co { bool usePDFLatex = Config_getBool(USE_PDFLATEX); bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - if (!DoxyCodeLineOpen) + if (!m_doxyCodeLineOpen) { m_t << "\\DoxyCodeLine{"; - DoxyCodeLineOpen = TRUE; + m_doxyCodeLineOpen = TRUE; } if (m_prettyCode) { @@ -231,19 +228,19 @@ void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,co void LatexCodeGenerator::startCodeLine(bool) { m_col=0; - if (!DoxyCodeLineOpen) + if (!m_doxyCodeLineOpen) { m_t << "\\DoxyCodeLine{"; - DoxyCodeLineOpen = TRUE; + m_doxyCodeLineOpen = TRUE; } } void LatexCodeGenerator::endCodeLine() { - if (DoxyCodeLineOpen) + if (m_doxyCodeLineOpen) { m_t << "}"; - DoxyCodeLineOpen = FALSE; + m_doxyCodeLineOpen = FALSE; } codify("\n"); } @@ -258,11 +255,20 @@ void LatexCodeGenerator::endFontClass() m_t << "}"; } -void LatexCodeGenerator::setDoxyCodeOpen(bool val) +void LatexCodeGenerator::startCodeFragment(const char *style) +{ + m_t << "\n\\begin{" << style << "}{" << m_usedTableLevel << "}\n"; +} + +void LatexCodeGenerator::endCodeFragment(const char *style) { - DoxyCodeOpen = val; + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + + m_t << "\\end{" << style << "}\n"; } + //------------------------------- LatexGenerator::LatexGenerator() : OutputGenerator(Config_getString(LATEX_OUTPUT)) @@ -650,7 +656,13 @@ static void writeDefaultHeaderPart1(FTextStream &t) { generatedBy = theTranslator->trGeneratedBy(); } - filterLatexString(tg, generatedBy, FALSE,FALSE,FALSE); + filterLatexString(tg, generatedBy, + false, // insideTabbing + false, // insidePre + false, // insideItem + false, // insideTable + false // keepSpaces + ); t << "% Headers & footers\n" "\\usepackage{fancyhdr}\n" "\\pagestyle{fancyplain}\n" @@ -1823,7 +1835,13 @@ void LatexGenerator::endSection(const char *lab,SectionType) void LatexGenerator::docify(const char *str) { - filterLatexString(t,str,m_insideTabbing,FALSE,FALSE); + filterLatexString(t,str, + m_insideTabbing, // insideTabbing + false, // insidePre + false, // insideItem + m_codeGen.usedTableLevel()>0, // insideTable + false // keepSpaces + ); } void LatexGenerator::writeChar(char c) @@ -1960,13 +1978,13 @@ void LatexGenerator::writeNonBreakableSpace(int) void LatexGenerator::startDescTable(const char *title) { - incUsedTableLevels(); + m_codeGen.incUsedTableLevel(); t << "\\begin{DoxyEnumFields}{" << title << "}" << endl; } void LatexGenerator::endDescTable() { - decUsedTableLevels(); + m_codeGen.decUsedTableLevel(); t << "\\end{DoxyEnumFields}" << endl; } @@ -2214,7 +2232,7 @@ void LatexGenerator::exceptionEntry(const char* prefix,bool closeBracket) void LatexGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { LatexDocVisitor *visitor = - new LatexDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""),m_insideTabbing); + new LatexDocVisitor(t,m_codeGen,ctx?ctx->getDefFileExtension():QCString(""),m_insideTabbing); n->accept(visitor); delete visitor; } @@ -2260,21 +2278,6 @@ void LatexGenerator::endConstraintList() t << "\\end{Desc}" << endl; } -void LatexGenerator::startCodeFragment() -{ - t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n"; - DoxyCodeOpen = TRUE; -} - -void LatexGenerator::endCodeFragment() -{ - //endCodeLine checks is there is still an open code line, if so closes it. - endCodeLine(); - - t << "\\end{DoxyCode}\n"; - DoxyCodeOpen = FALSE; -} - void LatexGenerator::startInlineHeader() { if (Config_getBool(COMPACT_LATEX)) @@ -2306,7 +2309,7 @@ void LatexGenerator::lineBreak(const char *) void LatexGenerator::startMemberDocSimple(bool isEnum) { - incUsedTableLevels(); + m_codeGen.incUsedTableLevel(); if (isEnum) { t << "\\begin{DoxyEnumFields}{"; @@ -2322,7 +2325,7 @@ void LatexGenerator::startMemberDocSimple(bool isEnum) void LatexGenerator::endMemberDocSimple(bool isEnum) { - decUsedTableLevels(); + m_codeGen.decUsedTableLevel(); if (isEnum) { t << "\\end{DoxyEnumFields}" << endl; diff --git a/src/latexgen.h b/src/latexgen.h index 12b34d8..4c793fa 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -52,7 +52,13 @@ class LatexCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const char *) {} void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} - static void setDoxyCodeOpen(bool val); + void startCodeFragment(const char *style); + void endCodeFragment(const char *style); + + // extra methods not part of CodeOutputInterface + void incUsedTableLevel() { m_usedTableLevel++; } + void decUsedTableLevel() { m_usedTableLevel--; } + int usedTableLevel() const { return m_usedTableLevel; } private: void _writeCodeLink(const char *className, @@ -60,12 +66,14 @@ class LatexCodeGenerator : public CodeOutputInterface const char *anchor,const char *name, const char *tooltip); void docify(const char *str); - bool m_streamSet; + bool m_streamSet = false; FTextStream m_t; QCString m_relPath; QCString m_sourceFileName; - int m_col; - bool m_prettyCode; + int m_col = 0; + bool m_prettyCode = false; + bool m_doxyCodeLineOpen = false; + int m_usedTableLevel = 0; }; /** Generator for LaTeX output. */ @@ -108,6 +116,10 @@ class LatexGenerator : public OutputGenerator { m_codeGen.endFontClass(); } void writeCodeAnchor(const char *anchor) { m_codeGen.writeCodeAnchor(anchor); } + void startCodeFragment(const char *style) + { m_codeGen.startCodeFragment(style); } + void endCodeFragment(const char *style) + { m_codeGen.endCodeFragment(style); } // --------------------------- @@ -194,8 +206,6 @@ class LatexGenerator : public OutputGenerator void writeRuler() { t << endl << endl; } void writeAnchor(const char *fileName,const char *name); - void startCodeFragment(); - void endCodeFragment(); void startEmphasis() { t << "{\\em "; } void endEmphasis() { t << "}"; } void startBold() { t << "{\\bfseries "; } diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index fef857e..875cd14 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.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 "mandocvisitor.h" #include "docparser.h" @@ -33,7 +30,7 @@ #include "emoji.h" ManDocVisitor::ManDocVisitor(FTextStream &t,CodeOutputInterface &ci, - const char *langExt) + const char *langExt) : DocVisitor(DocVisitor_Man), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(FALSE), m_indent(0), m_langExt(langExt) { @@ -205,8 +202,7 @@ void ManDocVisitor::visit(DocVerbatim *s) if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; - Doxygen::parserManager->getCodeParser(lang) - .parseCode(m_ci,s->context(),s->text(), + getCodeParser(lang).parseCode(m_ci,s->context(),s->text(), langExt, s->isExample(),s->exampleFile()); if (!m_firstCol) m_t << endl; @@ -214,7 +210,7 @@ void ManDocVisitor::visit(DocVerbatim *s) m_t << ".PP" << endl; m_firstCol=TRUE; break; - case DocVerbatim::Verbatim: + case DocVerbatim::Verbatim: if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; @@ -224,18 +220,18 @@ void ManDocVisitor::visit(DocVerbatim *s) m_t << ".PP" << endl; m_firstCol=TRUE; break; - case DocVerbatim::ManOnly: - m_t << s->text(); + case DocVerbatim::ManOnly: + m_t << s->text(); break; - case DocVerbatim::HtmlOnly: - case DocVerbatim::XmlOnly: - case DocVerbatim::LatexOnly: + case DocVerbatim::HtmlOnly: + case DocVerbatim::XmlOnly: + case DocVerbatim::LatexOnly: case DocVerbatim::RtfOnly: case DocVerbatim::DocbookOnly: - case DocVerbatim::Dot: - case DocVerbatim::Msc: - case DocVerbatim::PlantUML: - /* nothing */ + case DocVerbatim::Dot: + case DocVerbatim::Msc: + case DocVerbatim::PlantUML: + /* nothing */ break; } } @@ -252,14 +248,13 @@ void ManDocVisitor::visit(DocInclude *inc) switch(inc->type()) { case DocInclude::IncWithLines: - { + { if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -278,12 +273,11 @@ void ManDocVisitor::visit(DocInclude *inc) m_firstCol=TRUE; } break; - case DocInclude::Include: + case DocInclude::Include: if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -311,7 +305,7 @@ void ManDocVisitor::visit(DocInclude *inc) case DocInclude::ManInclude: m_t << inc->text(); break; - case DocInclude::VerbInclude: + case DocInclude::VerbInclude: if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; @@ -325,8 +319,7 @@ void ManDocVisitor::visit(DocInclude *inc) if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -345,13 +338,12 @@ void ManDocVisitor::visit(DocInclude *inc) m_t << ".nf" << endl; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, inc->isExample(), - inc->exampleFile(), + inc->exampleFile(), fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine @@ -366,8 +358,8 @@ void ManDocVisitor::visit(DocInclude *inc) m_firstCol=TRUE; } 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; @@ -381,7 +373,7 @@ void ManDocVisitor::visit(DocIncOperator *op) SrcLangExt langExt = getLanguageFromFileName(locLangExt); //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) { @@ -392,10 +384,10 @@ void ManDocVisitor::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()) @@ -404,8 +396,7 @@ void ManDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getCodeParser(locLangExt) - .parseCode(m_ci,op->context(),op->text(),langExt, + getCodeParser(locLangExt).parseCode(m_ci,op->context(),op->text(),langExt, op->isExample(),op->exampleFile(), fd, // fileDef op->line(), // startLine @@ -419,7 +410,7 @@ void ManDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide=TRUE; } - if (op->isLast()) + if (op->isLast()) { popEnabled(); if (!m_hide) @@ -484,7 +475,7 @@ void ManDocVisitor::visitPre(DocAutoListItem *li) QCString ws; ws.fill(' ',m_indent-2); if (!m_firstCol) m_t << endl; - m_t << ".IP \"" << ws; + m_t << ".IP \"" << ws; if (((DocAutoList *)li->parent())->isEnumList()) { m_t << li->itemNumber() << ".\" " << m_indent+2; @@ -497,14 +488,14 @@ void ManDocVisitor::visitPre(DocAutoListItem *li) m_firstCol=TRUE; } -void ManDocVisitor::visitPost(DocAutoListItem *) +void ManDocVisitor::visitPost(DocAutoListItem *) { if (m_hide) return; m_t << endl; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocPara *) +void ManDocVisitor::visitPre(DocPara *) { } @@ -515,7 +506,7 @@ void ManDocVisitor::visitPost(DocPara *p) !(p->parent() && // and for parameter sections p->parent()->kind()==DocNode::Kind_ParamSect ) - ) + ) { if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; @@ -535,28 +526,28 @@ void ManDocVisitor::visitPre(DocSimpleSect *s) { if (m_hide) return; if (!m_firstCol) - { + { m_t << endl; m_t << ".PP" << endl; } m_t << "\\fB"; 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; @@ -630,7 +621,7 @@ void ManDocVisitor::visitPre(DocSimpleListItem *) m_firstCol=TRUE; } -void ManDocVisitor::visitPost(DocSimpleListItem *) +void ManDocVisitor::visitPost(DocSimpleListItem *) { if (m_hide) return; m_t << endl; @@ -649,7 +640,7 @@ void ManDocVisitor::visitPre(DocSection *s) m_firstCol=TRUE; } -void ManDocVisitor::visitPost(DocSection *) +void ManDocVisitor::visitPost(DocSection *) { } @@ -661,7 +652,7 @@ void ManDocVisitor::visitPre(DocHtmlList *) m_t << ".PD 0" << endl; } -void ManDocVisitor::visitPost(DocHtmlList *) +void ManDocVisitor::visitPost(DocHtmlList *) { if (m_hide) return; m_indent-=2; @@ -675,7 +666,7 @@ void ManDocVisitor::visitPre(DocHtmlListItem *li) QCString ws; ws.fill(' ',m_indent-2); if (!m_firstCol) m_t << endl; - m_t << ".IP \"" << ws; + m_t << ".IP \"" << ws; if (((DocHtmlList *)li->parent())->type()==DocHtmlList::Ordered) { m_t << li->itemNumber() << ".\" " << m_indent+2; @@ -688,7 +679,7 @@ void ManDocVisitor::visitPre(DocHtmlListItem *li) m_firstCol=TRUE; } -void ManDocVisitor::visitPost(DocHtmlListItem *) +void ManDocVisitor::visitPost(DocHtmlListItem *) { if (m_hide) return; m_t << endl; @@ -703,7 +694,7 @@ void ManDocVisitor::visitPost(DocHtmlListItem *) // m_insidePre=TRUE; //} // -//void ManDocVisitor::visitPost(DocHtmlPre *) +//void ManDocVisitor::visitPost(DocHtmlPre *) //{ // m_insidePre=FALSE; // if (!m_firstCol) m_t << endl; @@ -716,7 +707,7 @@ void ManDocVisitor::visitPre(DocHtmlDescList *) { } -void ManDocVisitor::visitPost(DocHtmlDescList *) +void ManDocVisitor::visitPost(DocHtmlDescList *) { if (m_hide) return; if (!m_firstCol) m_t << endl; @@ -732,7 +723,7 @@ void ManDocVisitor::visitPre(DocHtmlDescTitle *) m_firstCol=FALSE; } -void ManDocVisitor::visitPost(DocHtmlDescTitle *) +void ManDocVisitor::visitPost(DocHtmlDescTitle *) { if (m_hide) return; m_t << "\\fP\" 1c" << endl; @@ -743,7 +734,7 @@ void ManDocVisitor::visitPre(DocHtmlDescData *) { } -void ManDocVisitor::visitPost(DocHtmlDescData *) +void ManDocVisitor::visitPost(DocHtmlDescData *) { } @@ -751,7 +742,7 @@ void ManDocVisitor::visitPre(DocHtmlTable *) { } -void ManDocVisitor::visitPost(DocHtmlTable *) +void ManDocVisitor::visitPost(DocHtmlTable *) { } @@ -759,7 +750,7 @@ void ManDocVisitor::visitPre(DocHtmlCaption *) { } -void ManDocVisitor::visitPost(DocHtmlCaption *) +void ManDocVisitor::visitPost(DocHtmlCaption *) { } @@ -767,7 +758,7 @@ void ManDocVisitor::visitPre(DocHtmlRow *) { } -void ManDocVisitor::visitPost(DocHtmlRow *) +void ManDocVisitor::visitPost(DocHtmlRow *) { } @@ -775,7 +766,7 @@ void ManDocVisitor::visitPre(DocHtmlCell *) { } -void ManDocVisitor::visitPost(DocHtmlCell *) +void ManDocVisitor::visitPost(DocHtmlCell *) { } @@ -788,7 +779,7 @@ void ManDocVisitor::visitPre(DocInternal *) //m_t << ".RS 4" << endl; } -void ManDocVisitor::visitPost(DocInternal *) +void ManDocVisitor::visitPost(DocInternal *) { if (m_hide) return; //if (!m_firstCol) m_t << endl; @@ -803,7 +794,7 @@ void ManDocVisitor::visitPre(DocHRef *) m_t << "\\fC"; } -void ManDocVisitor::visitPost(DocHRef *) +void ManDocVisitor::visitPost(DocHRef *) { if (m_hide) return; m_t << "\\fP"; @@ -817,7 +808,7 @@ void ManDocVisitor::visitPre(DocHtmlHeader *header) m_t << " \""; } -void ManDocVisitor::visitPost(DocHtmlHeader *header) +void ManDocVisitor::visitPost(DocHtmlHeader *header) { if (m_hide) return; m_t << "\"" << endl; @@ -829,7 +820,7 @@ void ManDocVisitor::visitPre(DocImage *) { } -void ManDocVisitor::visitPost(DocImage *) +void ManDocVisitor::visitPost(DocImage *) { } @@ -837,14 +828,14 @@ void ManDocVisitor::visitPre(DocDotFile *) { } -void ManDocVisitor::visitPost(DocDotFile *) +void ManDocVisitor::visitPost(DocDotFile *) { } void ManDocVisitor::visitPre(DocMscFile *) { } -void ManDocVisitor::visitPost(DocMscFile *) +void ManDocVisitor::visitPost(DocMscFile *) { } @@ -862,7 +853,7 @@ void ManDocVisitor::visitPre(DocLink *) m_t << "\\fB"; } -void ManDocVisitor::visitPost(DocLink *) +void ManDocVisitor::visitPost(DocLink *) { if (m_hide) return; m_t << "\\fP"; @@ -875,7 +866,7 @@ void ManDocVisitor::visitPre(DocRef *ref) if (!ref->hasLinkText()) filter(ref->targetTitle()); } -void ManDocVisitor::visitPost(DocRef *) +void ManDocVisitor::visitPost(DocRef *) { if (m_hide) return; m_t << "\\fP"; @@ -891,7 +882,7 @@ void ManDocVisitor::visitPre(DocSecRefItem *) m_firstCol=TRUE; } -void ManDocVisitor::visitPost(DocSecRefItem *) +void ManDocVisitor::visitPost(DocSecRefItem *) { if (m_hide) return; m_t << endl; @@ -904,7 +895,7 @@ void ManDocVisitor::visitPre(DocSecRefList *) m_indent+=2; } -void ManDocVisitor::visitPost(DocSecRefList *) +void ManDocVisitor::visitPost(DocSecRefList *) { if (m_hide) return; m_indent-=2; @@ -916,20 +907,20 @@ void ManDocVisitor::visitPre(DocParamSect *s) { if (m_hide) return; if (!m_firstCol) - { + { m_t << endl; m_t << ".PP" << endl; } m_t << "\\fB"; 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); @@ -961,11 +952,11 @@ void ManDocVisitor::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 << "\\fP "; @@ -986,7 +977,7 @@ void ManDocVisitor::visitPre(DocXRefItem *x) if (m_hide) return; if (x->title().isEmpty()) return; if (!m_firstCol) - { + { m_t << endl; m_t << ".PP" << endl; } @@ -1012,7 +1003,7 @@ void ManDocVisitor::visitPre(DocInternalRef *) m_t << "\\fB"; } -void ManDocVisitor::visitPost(DocInternalRef *) +void ManDocVisitor::visitPost(DocInternalRef *) { if (m_hide) return; m_t << "\\fP"; @@ -1030,7 +1021,7 @@ void ManDocVisitor::visitPre(DocHtmlBlockQuote *) { if (m_hide) return; if (!m_firstCol) - { + { m_t << endl; m_t << ".PP" << endl; } @@ -1064,12 +1055,12 @@ void ManDocVisitor::visitPost(DocParBlock *) void ManDocVisitor::filter(const char *str) -{ +{ if (str) { const char *p=str; char c=0; - while ((c=*p++)) + while ((c=*p++)) { switch(c) { diff --git a/src/mangen.cpp b/src/mangen.cpp index 8574018..4b01904 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -391,7 +391,7 @@ void ManGenerator::endItemListItem() { } -void ManGenerator::startCodeFragment() +void ManGenerator::startCodeFragment(const char *) { newParagraph(); t << ".nf" << endl; @@ -399,7 +399,7 @@ void ManGenerator::startCodeFragment() m_paragraph=FALSE; } -void ManGenerator::endCodeFragment() +void ManGenerator::endCodeFragment(const char *) { if (!m_firstCol) t << endl; t << ".fi" << endl; diff --git a/src/mangen.h b/src/mangen.h index 9bcdb18..8a8def7 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -123,8 +123,8 @@ class ManGenerator : public OutputGenerator void writeRuler() {} void writeAnchor(const char *,const char *) {} - void startCodeFragment(); - void endCodeFragment(); + void startCodeFragment(const char *); + void endCodeFragment(const char *); void writeLineNumber(const char *,const char *,const char *,int l) { t << l << " "; m_col=0; } void startCodeLine(bool) {} void endCodeLine() { codify("\n"); m_col=0; } diff --git a/src/markdown.cpp b/src/markdown.cpp index 3089b8e..ae78533 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -59,7 +59,7 @@ #ifdef ENABLE_TRACING #define IOSTREAM stdout #define DATA_BUFSIZE 20 -#if defined(_WIN32) && !defined(CYGWIN) +#if defined(_WIN32) && !defined(CYGWIN) && !defined(__MINGW32__) #define PRETTY_FUNC __FUNCSIG__ #else #define PRETTY_FUNC __PRETTY_FUNCTION__ @@ -2264,7 +2264,7 @@ void Markdown::writeFencedCodeBlock(const char *data,const char *lng, } addStrEscapeUtf8Nbsp(data+blockStart,blockEnd-blockStart); m_out.addStr("\n"); - m_out.addStr("@endcode\n"); + m_out.addStr("@endcode"); } QCString Markdown::processQuotations(const QCString &s,int refIndent) @@ -2491,18 +2491,20 @@ static bool isExplicitPage(const QCString &docs) return FALSE; } -QCString Markdown::extractPageTitle(QCString &docs,QCString &id) +QCString Markdown::extractPageTitle(QCString &docs,QCString &id, int &prepend) { TRACE(docs.data()); - int ln=0; // first first non-empty line + prepend = 0; QCString title; - const char *data = docs.data(); int i=0; int size=docs.size(); + QCString docs_org(docs); + const char *data = docs_org.data(); + docs = ""; while (i<size && (data[i]==' ' || data[i]=='\n')) { - if (data[i]=='\n') ln++; + if (data[i]=='\n') prepend++; i++; } if (i>=size) return ""; @@ -2512,16 +2514,13 @@ QCString Markdown::extractPageTitle(QCString &docs,QCString &id) // first line from i..end1 if (end1<size) { - ln++; // second line form end1..end2 int end2=end1+1; while (end2<size && data[end2-1]!='\n') end2++; if (isHeaderline(data+end1,size-end1,FALSE)) { convertStringFragment(title,data+i,end1-i-1); - QCString lns; - lns.fill('\n',ln); - docs=lns+docs.mid(end2); + docs+="\n\n"+docs_org.mid(end2); id = extractTitleId(title, 0); //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); return title; @@ -2529,10 +2528,11 @@ QCString Markdown::extractPageTitle(QCString &docs,QCString &id) } if (i<end1 && isAtxHeader(data+i,end1-i,title,id,FALSE)>0) { - docs=docs.mid(end1); + docs+=docs_org.mid(end1); } else { + docs=docs_org; id = extractTitleId(title, 0); } //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); @@ -2662,6 +2662,7 @@ QCString markdownFileNameToId(const QCString &fileName) int i = baseFn.findRev('.'); if (i!=-1) baseFn = baseFn.left(i); QCString baseName = substitute(substitute(substitute(baseFn," ","_"),"/","_"),":","_"); + //printf("markdownFileNameToId(%s)=md_%s\n",qPrint(fileName),qPrint(baseName)); return "md_"+baseName; } @@ -2686,6 +2687,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName, ClangTUParser* /*clangParser*/) { std::shared_ptr<Entry> current = std::make_shared<Entry>(); + int prepend = 0; // number of empty lines in front current->lang = SrcLangExt_Markdown; current->fileName = fileName; current->docFile = fileName; @@ -2693,7 +2695,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName, QCString docs = fileBuf; QCString id; Markdown markdown(fileName,1,0); - QCString title=markdown.extractPageTitle(docs,id).stripWhiteSpace(); + QCString title=markdown.extractPageTitle(docs,id,prepend).stripWhiteSpace(); if (id.startsWith("autotoc_md")) id = ""; int indentLevel=title.isEmpty() ? 0 : -1; markdown.setIndentLevel(indentLevel); @@ -2710,24 +2712,26 @@ void MarkdownOutlineParser::parseInput(const char *fileName, QFileInfo(mdfileAsMainPage).absFilePath()) // file reference with path ) { - docs.prepend("@anchor " + id + "\n"); - docs.prepend("@mainpage "+title+"\n"); + docs.prepend("@anchor " + id + "\\ilinebr "); + docs.prepend("@mainpage "+title+"\\ilinebr "); } else if (id=="mainpage" || id=="index") { if (title.isEmpty()) title = titleFn; - docs.prepend("@anchor " + id + "\n"); - docs.prepend("@mainpage "+title+"\n"); + docs.prepend("@anchor " + id + "\\ilinebr "); + docs.prepend("@mainpage "+title+"\\ilinebr "); } else { - if (title.isEmpty()) title = titleFn; - if (!wasEmpty) docs.prepend("@anchor " + markdownFileNameToId(fileName) + "\n"); - docs.prepend("@page "+id+" "+title+"\n"); + if (title.isEmpty()) {title = titleFn;prepend=0;} + if (!wasEmpty) docs.prepend("@anchor " + markdownFileNameToId(fileName) + "\\ilinebr "); + docs.prepend("@page "+id+" "+title+"\\ilinebr "); } + for (int i = 0; i < prepend; i++) docs.prepend("\n"); } int lineNr=1; + p->commentScanner.enterFile(fileName,lineNr); Protection prot=Public; bool needsEntry = FALSE; int position=0; @@ -2759,6 +2763,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName, { root->moveToSubEntryAndKeep(current); } + p->commentScanner.leaveFile(fileName,lineNr); } void MarkdownOutlineParser::parsePrototype(const char *text) diff --git a/src/markdown.h b/src/markdown.h index 1210967..dd4ff73 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -34,7 +34,7 @@ class Markdown public: Markdown(const char *fileName,int lineNr,int indentLevel=0); QCString process(const QCString &input, int &startNewlines); - QCString extractPageTitle(QCString &docs,QCString &id); + QCString extractPageTitle(QCString &docs,QCString &id,int &prepend); void setIndentLevel(int level) { m_indentLevel = level; } private: diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 6d179c2..c3c420a 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -3683,12 +3683,12 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml, else ol.parseText(theTranslator->trInitialValue()); ol.endBold(); - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); - intf.resetCodeParserState(); - ol.startCodeFragment(); - intf.parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()), + auto intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); + intf->resetCodeParserState(); + ol.startCodeFragment("DoxyCode"); + intf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()), -1,-1,TRUE,this,FALSE,this); - ol.endCodeFragment(); + ol.endCodeFragment("DoxyCode"); } QCString brief = briefDescription(); @@ -4838,6 +4838,7 @@ ClassDef *MemberDefImpl::accessorClass() const void MemberDefImpl::findSectionsInDocumentation() { + docFindSections(briefDescription(),this,docFile()); docFindSections(documentation(),this,docFile()); } diff --git a/src/message.cpp b/src/message.cpp index 984a00f..e107139 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -161,7 +161,7 @@ static void format_warn(const char *file,int line,const char *text) } } -static void handle_warn_as_error(void) +static void handle_warn_as_error() { static bool warnAsError = Config_getBool(WARN_AS_ERROR); if (warnAsError) @@ -279,6 +279,12 @@ void term(const char *fmt, ...) exit(1); } +void warn_flush() +{ + fflush(warnFile); +} + + void printlex(int dbg, bool enter, const char *lexName, const char *fileName) { const char *enter_txt = "entering"; diff --git a/src/message.h b/src/message.h index e84344b..dd9eeeb 100644 --- a/src/message.h +++ b/src/message.h @@ -35,6 +35,7 @@ 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(); +void warn_flush(); extern void printlex(int dbg, bool enter, const char *lexName, const char *fileName); diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 88eea5d..65456ac 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -349,6 +349,7 @@ void NamespaceDefImpl::distributeMemberGroupDocumentation() void NamespaceDefImpl::findSectionsInDocumentation() { + docFindSections(briefDescription(),this,docFile()); docFindSections(documentation(),this,docFile()); MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; diff --git a/src/outputgen.h b/src/outputgen.h index 4bfed25..ba9f2f4 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -127,6 +127,16 @@ class CodeOutputInterface virtual void setCurrentDoc(const Definition *context,const char *anchor,bool isSourceFile) = 0; virtual void addWord(const char *word,bool hiPriority) = 0; + + /*! Starts a source code fragment. The fragment will be + * fed to the code parser (see code.h) for syntax highlighting + * and cross-referencing. The fragment ends by a call to + * endCodeFragment() + * @param style The kind of code fragment. + */ + virtual void startCodeFragment(const char *style) = 0; + /*! Ends a block of code */ + virtual void endCodeFragment(const char *style) = 0; }; /** Base Interface used for generating output outside of the @@ -240,20 +250,6 @@ class BaseOutputDocInterface : public CodeOutputInterface /*! Ends a section of text displayed in italic. */ virtual void endEmphasis() = 0; - /*! Starts a source code fragment. The fragment will be - * fed to the code parser (see code.h) for syntax highlighting - * and cross-referencing. The fragment ends by a call to - * endCodeFragment() - */ - virtual void startCodeFragment() = 0; - - /*! Ends a source code fragment - */ - virtual void endCodeFragment() = 0; - - - - /*! Writes a horizontal ruler to the output */ virtual void writeRuler() = 0; diff --git a/src/outputlist.h b/src/outputlist.h index 003e508..2d06598 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -229,10 +229,10 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::writeRuler); } void writeAnchor(const char *fileName,const char *name) { forall(&OutputGenerator::writeAnchor,fileName,name); } - void startCodeFragment() - { forall(&OutputGenerator::startCodeFragment); } - void endCodeFragment() - { forall(&OutputGenerator::endCodeFragment); } + void startCodeFragment(const char *style) + { forall(&OutputGenerator::startCodeFragment,style); } + void endCodeFragment(const char *style) + { forall(&OutputGenerator::endCodeFragment,style); } void startCodeLine(bool hasLineNumbers) { forall(&OutputGenerator::startCodeLine,hasLineNumbers); } void endCodeLine() diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 09152de..12a7bdc 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -99,6 +99,7 @@ PageDefImpl::~PageDefImpl() void PageDefImpl::findSectionsInDocumentation() { + docFindSections(briefDescription(),this,docFile()); docFindSections(documentation(),this,docFile()); } @@ -229,7 +230,7 @@ void PageDefImpl::writeDocumentation(OutputList &ol) if (si->title() != manPageName) { - ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE, + ol.generateDoc(docFile(),getStartBodyLine(),this,0,si->title(),TRUE,FALSE, 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)); ol.endSection(si->label(),si->type()); } @@ -249,7 +250,7 @@ void PageDefImpl::writeDocumentation(OutputList &ol) 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, + ol.generateDoc(docFile(),getStartBodyLine(),this,0,si->title(),TRUE,FALSE, 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)); //stringToSearchIndex(getOutputFileBase(), // theTranslator->trPage(TRUE,TRUE)+" "+si->title, diff --git a/src/pagedef.h b/src/pagedef.h index e4d0268..a1f08a5 100644 --- a/src/pagedef.h +++ b/src/pagedef.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. * diff --git a/src/parserintf.h b/src/parserintf.h index 3087aa3..2fde2f1 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -137,6 +137,7 @@ class CodeParserInterface //----------------------------------------------------------------------------- using OutlineParserFactory = std::function<std::unique_ptr<OutlineParserInterface>()>; +using CodeParserFactory = std::function<std::unique_ptr<CodeParserInterface>()>; /** \brief Manages programming language parsers. * @@ -145,39 +146,42 @@ using OutlineParserFactory = std::function<std::unique_ptr<OutlineParserInterfac */ class ParserManager { - public: struct ParserPair { - ParserPair(OutlineParserFactory opf, std::unique_ptr<CodeParserInterface> cpi, const QCString pn) - : outlineParserFactory(opf), codeParserInterface(std::move(cpi)), parserName(pn) + ParserPair(OutlineParserFactory opf, CodeParserFactory cpf, const QCString pn) + : outlineParserFactory(opf), codeParserFactory(cpf), parserName(pn) { } OutlineParserFactory outlineParserFactory; - std::unique_ptr<CodeParserInterface> codeParserInterface; + CodeParserFactory codeParserFactory; QCString parserName; }; + public: + /** Create the parser manager + * @param outlineParserFactory the fallback outline parser factory to use for unknown extensions + * @param codeParserFactory the fallback code parser factory to use for unknown extensions + */ ParserManager(OutlineParserFactory outlineParserFactory, - std::unique_ptr<CodeParserInterface> codeParserInterface) - : m_defaultParsers(outlineParserFactory,std::move(codeParserInterface), "") + CodeParserFactory codeParserFactory) + : m_defaultParsers(outlineParserFactory,codeParserFactory, "") { } /** Registers an additional parser. * @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. + * @param[in] outlineParserFactory A factory method to create a language parser (scanner) that + * is to be used for the given name. + * @param[in] codeParserFactory A factory method to create a code parser that is to be used + * for the given name. */ void registerParser(const char *name,OutlineParserFactory outlineParserFactory, - std::unique_ptr<CodeParserInterface> codeParserInterface) + CodeParserFactory codeParserFactory) { - m_parsers.emplace(std::string(name), - ParserPair(outlineParserFactory,std::move(codeParserInterface),name)); + m_parsers.emplace(std::string(name),ParserPair(outlineParserFactory,codeParserFactory,name)); } /** Registers a file \a extension with a parser with name \a parserName. @@ -199,7 +203,7 @@ class ParserManager return TRUE; } - /** Gets the interface to the parser associated with given \a extension. + /** Gets the interface to the parser associated with a given \a extension. * If there is no parser explicitly registered for the supplied extension, * the interface to the default parser will be returned. */ @@ -208,13 +212,20 @@ class ParserManager return getParsers(extension).outlineParserFactory(); } - /** Gets the interface to the parser associated with given \a extension. + /** Gets the interface to the parser associated with a given \a extension. * If there is no parser explicitly registered for the supplied extension, * the interface to the default parser will be returned. */ - CodeParserInterface &getCodeParser(const char *extension) + std::unique_ptr<CodeParserInterface> getCodeParser(const char *extension) + { + auto factory = getCodeParserFactory(extension); + return factory(); + } + + /** Get the factory for create code parser objects with a given \a extension. */ + CodeParserFactory &getCodeParserFactory(const char *extension) { - return *getParsers(extension).codeParserInterface; + return getParsers(extension).codeParserFactory; } /** Gets the name of the parser associated with given \a extension. diff --git a/src/portable.cpp b/src/portable.cpp index d3799c7..0ffbd49 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -196,7 +196,7 @@ int Portable::system(const char *command,const char *args,bool commandHasConsole } -unsigned int Portable::pid(void) +unsigned int Portable::pid() { unsigned int pid; #if !defined(_WIN32) || defined(__CYGWIN__) @@ -322,7 +322,7 @@ FILE *Portable::fopen(const char *fileName,const char *mode) #endif } -char Portable::pathSeparator(void) +char Portable::pathSeparator() { #if defined(_WIN32) && !defined(__CYGWIN__) return '\\'; @@ -331,7 +331,7 @@ char Portable::pathSeparator(void) #endif } -char Portable::pathListSeparator(void) +char Portable::pathListSeparator() { #if defined(_WIN32) && !defined(__CYGWIN__) return ';'; @@ -386,7 +386,7 @@ bool Portable::checkForExecutable(const char *fileName) #endif } -const char *Portable::ghostScriptCommand(void) +const char *Portable::ghostScriptCommand() { #if defined(_WIN32) && !defined(__CYGWIN__) static char *gsexe = NULL; @@ -410,7 +410,7 @@ const char *Portable::ghostScriptCommand(void) #endif } -const char *Portable::commandExtension(void) +const char *Portable::commandExtension() { #if defined(_WIN32) && !defined(__CYGWIN__) return ".exe"; @@ -419,7 +419,7 @@ const char *Portable::commandExtension(void) #endif } -bool Portable::fileSystemIsCaseSensitive(void) +bool Portable::fileSystemIsCaseSensitive() { #if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__) || defined(__CYGWIN__) return FALSE; @@ -446,17 +446,17 @@ int Portable::pclose(FILE *stream) #endif } -void Portable::sysTimerStart(void) +void Portable::sysTimerStart() { g_time.start(); } -void Portable::sysTimerStop(void) +void Portable::sysTimerStop() { g_sysElapsedTime+=((double)g_time.elapsed())/1000.0; } -double Portable::getSysElapsedTime(void) +double Portable::getSysElapsedTime() { return g_sysElapsedTime; } @@ -492,7 +492,7 @@ bool Portable::isAbsolutePath(const char *fileName) * * This routine was inspired by the cause for bug 766059 was that in the Windows path there were forward slashes. */ -void Portable::correct_path(void) +void Portable::correct_path() { #if defined(_WIN32) && !defined(__CYGWIN__) const char *p = Portable::getenv("PATH"); @@ -511,7 +511,7 @@ void Portable::unlink(const char *fileName) #endif } -void Portable::setShortDir(void) +void Portable::setShortDir() { #if defined(_WIN32) && !defined(__CYGWIN__) long length = 0; diff --git a/src/portable.h b/src/portable.h index bf6cfea..d2b3036 100644 --- a/src/portable.h +++ b/src/portable.h @@ -20,7 +20,7 @@ typedef off_t portable_off_t; namespace Portable { int system(const char *command,const char *args,bool commandHasConsole=true); - unsigned int pid(void); + unsigned int pid(); const char * getenv(const char *variable); void setenv(const char *variable,const char *value); void unsetenv(const char *variable); @@ -28,20 +28,20 @@ namespace Portable portable_off_t ftell(FILE *f); FILE * fopen(const char *fileName,const char *mode); void unlink(const char *fileName); - char pathSeparator(void); - char pathListSeparator(void); - const char * ghostScriptCommand(void); - const char * commandExtension(void); + char pathSeparator(); + char pathListSeparator(); + const char * ghostScriptCommand(); + const char * commandExtension(); bool fileSystemIsCaseSensitive(); FILE * popen(const char *name,const char *type); int pclose(FILE *stream); - void sysTimerStart(void); - void sysTimerStop(void); - double getSysElapsedTime(void); + void sysTimerStart(); + void sysTimerStop(); + double getSysElapsedTime(); void sleep(int ms); bool isAbsolutePath(const char *fileName); - void correct_path(void); - void setShortDir(void); + void correct_path(); + void setShortDir(); const char * strnstr(const char *haystack, const char *needle, size_t haystack_len); const char * devNull(); bool checkForExecutable(const char *fileName); diff --git a/src/reflist.cpp b/src/reflist.cpp index 0aaa75f..5840138 100644 --- a/src/reflist.cpp +++ b/src/reflist.cpp @@ -60,7 +60,7 @@ void RefList::generatePage() std::sort(m_entries.begin(),m_entries.end(), [](std::unique_ptr<RefItem> &left,std::unique_ptr<RefItem> &right) - { return qstricmp(left->title(),left->title()); }); + { return qstricmp(left->title(),right->title()) < 0; }); //RefItem *item; QCString doc; int cnt = 0; @@ -124,6 +124,6 @@ void RefList::generatePage() //printf("generatePage('%s')\n",doc.data()); if (cnt>0) { - addRelatedPage(m_listName,m_pageTitle,doc,m_fileName,1,RefItemVector(),0,0,TRUE); + addRelatedPage(m_listName,m_pageTitle,doc,m_fileName,1,1,RefItemVector(),0,0,TRUE); } } diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index fbe7cc1..2bd2c29 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -306,9 +306,8 @@ void RTFDocVisitor::visit(DocVerbatim *s) m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getCodeParser(lang) - .parseCode(m_ci,s->context(),s->text(),langExt, - s->isExample(),s->exampleFile()); + getCodeParser(lang).parseCode(m_ci,s->context(),s->text(),langExt, + s->isExample(),s->exampleFile()); //m_t << "\\par" << endl; m_t << "}" << endl; break; @@ -433,8 +432,7 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << rtf_Style_Reset << getStyle("CodeExample"); QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -455,8 +453,7 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), inc->text(),langExt,inc->isExample(), inc->exampleFile(), 0, // fileDef @@ -492,8 +489,7 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{" << endl; if (!m_lastIsPara) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -509,8 +505,7 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{" << endl; if (!m_lastIsPara) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -567,8 +562,7 @@ void RTFDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getCodeParser(locLangExt) - .parseCode(m_ci,op->context(),op->text(),langExt, + getCodeParser(locLangExt).parseCode(m_ci,op->context(),op->text(),langExt, op->isExample(),op->exampleFile(), fd, // fileDef op->line(), // startLine diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index dff4cdd..7acd14f 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -48,8 +48,6 @@ #include "filename.h" #include "namespacedef.h" -static bool DoxyCodeLineOpen = FALSE; - //#define DBG_RTF(x) x; #define DBG_RTF(x) @@ -1935,22 +1933,15 @@ void RTFGenerator::writeRTFReference(const char *label) t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}"; } -void RTFGenerator::startCodeFragment() +void RTFGenerator::startCodeFragment(const char *) { DBG_RTF(t << "{\\comment (startCodeFragment) }" << endl) t << "{" << endl; - //newParagraph(); t << rtf_Style_Reset << rtf_Code_DepthStyle(); - //styleStack.push(rtf_Style_CodeExample); } -void RTFGenerator::endCodeFragment() +void RTFGenerator::endCodeFragment(const char *) { - //newParagraph(); - //styleStack.pop(); - //printf("RTFGenerator::endCodeFragment() top=%s\n",styleStack.top()); - //t << rtf_Style_Reset << styleStack.top() << endl; - //endCodeLine checks is there is still an open code line, if so closes it. endCodeLine(); DBG_RTF(t << "{\\comment (endCodeFragment) }" << endl) @@ -3043,7 +3034,7 @@ void RTFGenerator::writeLineNumber(const char *ref,const char *fileName,const ch { bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS); - DoxyCodeLineOpen = TRUE; + m_doxyCodeLineOpen = true; QCString lineNumber; lineNumber.sprintf("%05d",l); if (m_prettyCode) @@ -3070,13 +3061,13 @@ void RTFGenerator::writeLineNumber(const char *ref,const char *fileName,const ch } void RTFGenerator::startCodeLine(bool) { - DoxyCodeLineOpen = TRUE; + m_doxyCodeLineOpen = true; m_col=0; } void RTFGenerator::endCodeLine() { - if (DoxyCodeLineOpen) lineBreak(); - DoxyCodeLineOpen = FALSE; + if (m_doxyCodeLineOpen) lineBreak(); + m_doxyCodeLineOpen = false; } void RTFGenerator::startLabels() diff --git a/src/rtfgen.h b/src/rtfgen.h index ac6f580..8a2c3fe 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -125,8 +125,8 @@ class RTFGenerator : public OutputGenerator void writeRuler() { rtfwriteRuler_thin(); } void writeAnchor(const char *fileName,const char *name); - void startCodeFragment(); - void endCodeFragment(); + void startCodeFragment(const char *style); + void endCodeFragment(const char *style); void writeLineNumber(const char *,const char *,const char *,int l); void startCodeLine(bool); void endCodeLine(); @@ -293,6 +293,7 @@ class RTFGenerator : public OutputGenerator bool m_omitParagraph = false; // should a the next paragraph command be ignored? int m_numCols = 0; // number of columns in a table QCString m_relPath; + bool m_doxyCodeLineOpen = false; }; #endif diff --git a/src/searchindex.cpp b/src/searchindex.cpp index d9e5c99..067370b 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -37,6 +37,8 @@ #include "filename.h" #include "membername.h" #include "resourcemgr.h" +#include "namespacedef.h" +#include "classdef.h" // file format: (all multi-byte values are stored in big endian format) // 4 byte header @@ -49,41 +51,33 @@ // (4 bytes index to url string + 4 bytes frequency counter) // for each url: a \0 terminated string -const int numIndexEntries = 256*256; +const size_t numIndexEntries = 256*256; //-------------------------------------------------------------------- -IndexWord::IndexWord(const char *word) : m_word(word), m_urls(17) +IndexWord::IndexWord(QCString word) : m_word(word) { - m_urls.setAutoDelete(TRUE); //printf("IndexWord::IndexWord(%s)\n",word); } void IndexWord::addUrlIndex(int idx,bool hiPriority) { //printf("IndexWord::addUrlIndex(%d,%d)\n",idx,hiPriority); - URLInfo *ui = m_urls.find(idx); - if (ui==0) + auto it = m_urls.find(idx); + if (it==m_urls.end()) { //printf("URLInfo::URLInfo(%d)\n",idx); - ui=new URLInfo(idx,0); - m_urls.insert(idx,ui); + it = m_urls.insert(std::make_pair(idx,URLInfo(idx,0))).first; } - ui->freq+=2; - if (hiPriority) ui->freq|=1; // mark as high priority document + it->second.freq+=2; + if (hiPriority) it->second.freq|=1; // mark as high priority document } //-------------------------------------------------------------------- -SearchIndex::SearchIndex() : SearchIndexIntf(Internal), - m_words(328829), m_index(numIndexEntries), m_url2IdMap(10007), m_urls(10007), m_urlIndex(-1) +SearchIndex::SearchIndex() : SearchIndexIntf(Internal) { - int i; - m_words.setAutoDelete(TRUE); - m_url2IdMap.setAutoDelete(TRUE); - m_urls.setAutoDelete(TRUE); - m_index.setAutoDelete(TRUE); - for (i=0;i<numIndexEntries;i++) m_index.insert(i,new QList<IndexWord>); + m_index.resize(numIndexEntries); } void SearchIndex::setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) @@ -167,16 +161,16 @@ void SearchIndex::setCurrentDoc(const Definition *ctx,const char *anchor,bool is } } - int *pIndex = m_url2IdMap.find(baseUrl); - if (pIndex==0) + auto it = m_url2IdMap.find(baseUrl.str()); + if (it == m_url2IdMap.end()) { ++m_urlIndex; - m_url2IdMap.insert(baseUrl,new int(m_urlIndex)); - m_urls.insert(m_urlIndex,new URL(name,url)); + m_url2IdMap.insert(std::make_pair(baseUrl.str(),m_urlIndex)); + m_urls.insert(std::make_pair(m_urlIndex,URL(name,url))); } else { - m_urls.insert(*pIndex,new URL(name,url)); + m_urls.insert(std::make_pair(it->second,URL(name,url))); } } @@ -208,17 +202,16 @@ void SearchIndex::addWord(const char *word,bool hiPriority,bool recurse) if (word==0 || word[0]=='\0') return; QCString wStr = QCString(word).lower(); //printf("SearchIndex::addWord(%s,%d) wStr=%s\n",word,hiPriority,wStr.data()); - IndexWord *w = m_words[wStr]; - if (w==0) + int idx=charsToIndex(wStr); + if (idx<0 || idx>=static_cast<int>(m_index.size())) return; + auto it = m_words.find(wStr.str()); + if (it==m_words.end()) { - int idx=charsToIndex(wStr); //fprintf(stderr,"addWord(%s) at index %d\n",word,idx); - if (idx<0) return; - w = new IndexWord(wStr); - m_index[idx]->append(w); - m_words.insert(wStr,w); + m_index[idx].push_back(IndexWord(wStr)); + it = m_words.insert({ wStr.str(), m_index[idx].size()-1 }).first; } - w->addUrlIndex(m_urlIndex,hiPriority); + m_index[idx][it->second].addUrlIndex(m_urlIndex,hiPriority); int i; bool found=FALSE; if (!recurse) // the first time we check if we can strip the prefix @@ -244,12 +237,12 @@ void SearchIndex::addWord(const char *word,bool hiPriority) addWord(word,hiPriority,FALSE); } -static void writeInt(QFile &f,int index) +static void writeInt(QFile &f,size_t index) { - f.putch(((uint)index)>>24); - f.putch((((uint)index)>>16)&0xff); - f.putch((((uint)index)>>8)&0xff); - f.putch(((uint)index)&0xff); + f.putch(index>>24); + f.putch((index>>16)&0xff); + f.putch((index>>8)&0xff); + f.putch(index&0xff); } static void writeString(QFile &f,const char *s) @@ -261,21 +254,19 @@ static void writeString(QFile &f,const char *s) void SearchIndex::write(const char *fileName) { - int i; - int size=4; // for the header + size_t i; + size_t size=4; // for the header size+=4*numIndexEntries; // for the index - int wordsOffset = size; + size_t wordsOffset = size; // first pass: compute the size of the wordlist for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - int ws = iw->word().length()+1; + int ws = iw.word().length()+1; size+=ws+4; // word + url info list offset } size+=1; // zero list terminator @@ -283,19 +274,17 @@ void SearchIndex::write(const char *fileName) } // second pass: compute the offsets in the index - int indexOffsets[numIndexEntries]; - int offset=wordsOffset; + size_t indexOffsets[numIndexEntries]; + size_t offset=wordsOffset; for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { indexOffsets[i]=offset; - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - offset+= iw->word().length()+1; + offset+= iw.word().length()+1; offset+=4; // word + offset to url info array } offset+=1; // zero list terminator @@ -305,42 +294,36 @@ void SearchIndex::write(const char *fileName) indexOffsets[i]=0; } } - int padding = size; + size_t padding = size; size = (size+3)&~3; // round up to 4 byte boundary padding = size - padding; - //int statsOffset = size; - //IndexWord *iw; - int *wordStatOffsets = new int[m_words.count()]; + std::vector<size_t> wordStatOffsets(m_words.size()); int count=0; // third pass: compute offset to stats info for each word for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { //printf("wordStatOffsets[%d]=%d\n",count,size); wordStatOffsets[count++] = size; - size+=4+iw->urls().count()*8; // count + (url_index,freq) per url + size+=4 + iw.urls().size() * 8; // count + (url_index,freq) per url } } } - int *urlOffsets = new int[m_urls.count()]; - //int urlsOffset = size; - QIntDictIterator<URL> udi(m_urls); - URL *url; - for (udi.toFirst();(url=udi.current());++udi) + std::vector<size_t> urlOffsets(m_urls.size()); + for (const auto &udi : m_urls) { - urlOffsets[udi.currentKey()]=size; - size+=url->name.length()+1+ - url->url.length()+1; + urlOffsets[udi.first]=size; + size+=udi.second.name.length()+1+ + udi.second.url.length()+1; } + //printf("Total size %x bytes (word=%x stats=%x urls=%x)\n",size,wordsOffset,statsOffset,urlsOffset); QFile f(fileName); if (f.open(IO_WriteOnly)) @@ -356,14 +339,12 @@ void SearchIndex::write(const char *fileName) count=0; for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - writeString(f,iw->word()); + writeString(f,iw.word()); writeInt(f,wordStatOffsets[count++]); } f.putch(0); @@ -374,35 +355,29 @@ void SearchIndex::write(const char *fileName) // write word statistics for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - int numUrls = iw->urls().count(); + size_t numUrls = iw.urls().size(); writeInt(f,numUrls); - QIntDictIterator<URLInfo> uli(iw->urls()); - URLInfo *ui; - for (uli.toFirst();(ui=uli.current());++uli) + for (const auto &ui : iw.urls()) { - writeInt(f,urlOffsets[ui->urlIdx]); - writeInt(f,ui->freq); + writeInt(f,urlOffsets[ui.second.urlIdx]); + writeInt(f,ui.second.freq); } } } } // write urls - for (udi.toFirst();(url=udi.current());++udi) + for (const auto &udi : m_urls) { - writeString(f,url->name); - writeString(f,url->url); + writeString(f,udi.second.name); + writeString(f,udi.second.url); } } - delete[] urlOffsets; - delete[] wordStatOffsets; } @@ -422,22 +397,12 @@ struct SearchDocEntry struct SearchIndexExternal::Private { - Private() : docEntries(12251) {} - SDict<SearchDocEntry> docEntries; + std::map<std::string,SearchDocEntry> docEntries; SearchDocEntry *current = 0; }; -SearchIndexExternal::SearchIndexExternal() : SearchIndexIntf(External) -{ - p = new SearchIndexExternal::Private; - p->docEntries.setAutoDelete(TRUE); - p->current=0; -} - -SearchIndexExternal::~SearchIndexExternal() +SearchIndexExternal::SearchIndexExternal() : SearchIndexIntf(External), p(std::make_unique<Private>()) { - //printf("p->docEntries.count()=%d\n",p->docEntries.count()); - delete p; } static QCString definitionToName(const Definition *ctx) @@ -497,29 +462,28 @@ static QCString definitionToName(const Definition *ctx) void SearchIndexExternal::setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) { - QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); + static QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); QCString baseName = isSourceFile ? (dynamic_cast<const FileDef*>(ctx))->getSourceFileBase() : ctx->getOutputFileBase(); QCString url = baseName + Doxygen::htmlFileExtension; if (anchor) url+=QCString("#")+anchor; QCString key = extId+";"+url; - p->current = p->docEntries.find(key); - //printf("setCurrentDoc(url=%s,isSourceFile=%d) current=%p\n",url.data(),isSourceFile,p->current); - if (!p->current) + auto it = p->docEntries.find(key.str()); + if (it == p->docEntries.end()) { - SearchDocEntry *e = new SearchDocEntry; - e->type = isSourceFile ? QCString("source") : definitionToName(ctx); - e->name = ctx->qualifiedName(); + SearchDocEntry e; + e.type = isSourceFile ? QCString("source") : definitionToName(ctx); + e.name = ctx->qualifiedName(); if (ctx->definitionType()==Definition::TypeMember) { - e->args = (dynamic_cast<const MemberDef*>(ctx))->argsString(); + e.args = (dynamic_cast<const MemberDef*>(ctx))->argsString(); } - e->extId = extId; - e->url = url; - p->current = e; - p->docEntries.append(key,e); + e.extId = extId; + e.url = url; + it = p->docEntries.insert({key.str(),e}).first; //printf("searchIndexExt %s : %s\n",e->name.data(),e->url.data()); } + p->current = &it->second; } void SearchIndexExternal::addWord(const char *word,bool hiPriority) @@ -539,26 +503,25 @@ void SearchIndexExternal::write(const char *fileName) FTextStream t(&f); t << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl; t << "<add>" << endl; - SDict<SearchDocEntry>::Iterator it(p->docEntries); - SearchDocEntry *doc; - for (it.toFirst();(doc=it.current());++it) + for (auto &kv : p->docEntries) { - doc->normalText.addChar(0); // make sure buffer ends with a 0 terminator - doc->importantText.addChar(0); // make sure buffer ends with a 0 terminator + SearchDocEntry &doc = kv.second; + doc.normalText.addChar(0); // make sure buffer ends with a 0 terminator + doc.importantText.addChar(0); // make sure buffer ends with a 0 terminator t << " <doc>" << endl; - t << " <field name=\"type\">" << doc->type << "</field>" << endl; - t << " <field name=\"name\">" << convertToXML(doc->name) << "</field>" << endl; - if (!doc->args.isEmpty()) + t << " <field name=\"type\">" << doc.type << "</field>" << endl; + t << " <field name=\"name\">" << convertToXML(doc.name) << "</field>" << endl; + if (!doc.args.isEmpty()) { - t << " <field name=\"args\">" << convertToXML(doc->args) << "</field>" << endl; + t << " <field name=\"args\">" << convertToXML(doc.args) << "</field>" << endl; } - if (!doc->extId.isEmpty()) + if (!doc.extId.isEmpty()) { - t << " <field name=\"tag\">" << convertToXML(doc->extId) << "</field>" << endl; + t << " <field name=\"tag\">" << convertToXML(doc.extId) << "</field>" << endl; } - t << " <field name=\"url\">" << convertToXML(doc->url) << "</field>" << endl; - t << " <field name=\"keywords\">" << convertToXML(doc->importantText.get()) << "</field>" << endl; - t << " <field name=\"text\">" << convertToXML(doc->normalText.get()) << "</field>" << endl; + t << " <field name=\"url\">" << convertToXML(doc.url) << "</field>" << endl; + t << " <field name=\"keywords\">" << convertToXML(doc.importantText.get()) << "</field>" << endl; + t << " <field name=\"text\">" << convertToXML(doc.normalText.get()) << "</field>" << endl; t << " </doc>" << endl; } t << "</add>" << endl; @@ -572,14 +535,6 @@ void SearchIndexExternal::write(const char *fileName) //--------------------------------------------------------------------------- // the following part is for the javascript based search engine -#include "memberdef.h" -#include "namespacedef.h" -#include "pagedef.h" -#include "classdef.h" -#include "filedef.h" -#include "language.h" -#include "doxygen.h" -#include "message.h" static SearchIndexInfo g_searchIndexInfo[NUM_SEARCH_INDICES]; diff --git a/src/searchindex.h b/src/searchindex.h index 923973c..71c1ce1 100644 --- a/src/searchindex.h +++ b/src/searchindex.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. * @@ -18,11 +18,15 @@ #ifndef _SEARCHINDEX_H #define _SEARCHINDEX_H +#include <memory> +#include <vector> +#include <map> +#include <unordered_map> +#include <string> + #include <qintdict.h> #include <qlist.h> -#include <qdict.h> #include <qintdict.h> -#include <qvector.h> #include "sortdict.h" #include "definition.h" #include "util.h" @@ -40,7 +44,7 @@ void finalizeSearchIndexer(); struct URL { - URL(const char *n,const char *u) : name(n), url(u) {} + URL(QCString n,QCString u) : name(n), url(u) {} QCString name; QCString url; }; @@ -56,14 +60,15 @@ struct URLInfo class IndexWord { public: - IndexWord(const char *word); + using URLInfoMap = std::unordered_map<int,URLInfo>; + IndexWord(QCString word); void addUrlIndex(int,bool); - const QIntDict<URLInfo> &urls() const { return m_urls; } + URLInfoMap urls() const { return m_urls; } QCString word() const { return m_word; } private: QCString m_word; - QIntDict<URLInfo> m_urls; + URLInfoMap m_urls; }; class SearchIndexIntf @@ -84,16 +89,16 @@ class SearchIndex : public SearchIndexIntf { public: SearchIndex(); - void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile); - void addWord(const char *word,bool hiPriority); - void write(const char *file); + void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) override; + void addWord(const char *word,bool hiPriority) override; + void write(const char *file) override; private: void addWord(const char *word,bool hiPrio,bool recurse); - QDict<IndexWord> m_words; - QVector< QList<IndexWord> > m_index; - QDict<int> m_url2IdMap; - QIntDict<URL> m_urls; - int m_urlIndex; + std::unordered_map<std::string,int> m_words; + std::vector< std::vector< IndexWord> > m_index; + std::unordered_map<std::string,int> m_url2IdMap; + std::map<int,URL> m_urls; + int m_urlIndex = -1; }; @@ -102,12 +107,11 @@ class SearchIndexExternal : public SearchIndexIntf struct Private; public: SearchIndexExternal(); - ~SearchIndexExternal(); void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile); void addWord(const char *word,bool hiPriority); void write(const char *file); private: - Private *p; + std::unique_ptr<Private> p; }; //------- client side search index ---------------------- diff --git a/src/template.cpp b/src/template.cpp index 66347c4..58188fe 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -338,7 +338,7 @@ int TemplateList::release() uint TemplateList::count() const { - return p->elems.size(); + return static_cast<uint>(p->elems.size()); } void TemplateList::append(const TemplateVariant &v) diff --git a/src/util.cpp b/src/util.cpp index d78c80e..78de1a8 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -31,7 +31,6 @@ #include <qfileinfo.h> #include <qdir.h> #include <qdatetime.h> -#include <qcache.h> #include "util.h" #include "message.h" @@ -1028,7 +1027,6 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi } done: accessStack.pop(); - //Doxygen::lookupCache.insert(key,new int(result)); return result; } @@ -1196,7 +1194,6 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop done: //printf(" > result=%d\n",result); accessStack.pop(); - //Doxygen::lookupCache.insert(key,new int(result)); return result; } @@ -1208,7 +1205,7 @@ int computeQualifiedIndex(const QCString &name) static void getResolvedSymbol(const Definition *scope, const FileDef *fileScope, - Definition *d, + const Definition *d, const QCString &explicitScopePart, const std::unique_ptr<ArgumentList> &actTemplParams, int &minDistance, @@ -1224,7 +1221,7 @@ 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()) + ((dynamic_cast<const MemberDef*>(d))->isTypedef() || (dynamic_cast<const MemberDef*>(d))->isEnumerate()) ) ) { @@ -1237,7 +1234,7 @@ static void getResolvedSymbol(const Definition *scope, // see if we are dealing with a class or a typedef if (d->definitionType()==Definition::TypeClass) // d is a class { - ClassDef *cd = dynamic_cast<ClassDef *>(d); + const ClassDef *cd = dynamic_cast<const ClassDef *>(d); //printf("cd=%s\n",cd->name().data()); if (!cd->isTemplateArgument()) // skip classes that // are only there to @@ -1282,7 +1279,7 @@ static void getResolvedSymbol(const Definition *scope, } else if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = dynamic_cast<MemberDef *>(d); + const MemberDef *md = dynamic_cast<const MemberDef *>(d); //printf(" member isTypedef()=%d\n",md->isTypedef()); if (md->isTypedef()) // d is a typedef { @@ -1365,6 +1362,8 @@ static void getResolvedSymbol(const Definition *scope, //printf(" bestMatch=%p bestResolvedType=%s\n",bestMatch,bestResolvedType.data()); } +static std::mutex g_cacheMutex; + /* 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 @@ -1411,7 +1410,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, } //printf("Looking for symbol %s\n",name.data()); - DefinitionIntf *di = Doxygen::symbolMap->find(name); + const DefinitionIntf *di = Doxygen::symbolMap->find(name); // 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) @@ -1468,26 +1467,30 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, } *p='\0'; - LookupInfo *pval=Doxygen::lookupCache->find(key); - //printf("Searching for %s result=%p\n",key.data(),pval); - if (pval) + LookupInfo *pval = 0; { - //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) - // printf("templSpec=%s\n",pTemplSpec->data()); - return pval->classDef; - } - else // not found yet; we already add a 0 to avoid the possibility of - // endless recursion. - { - Doxygen::lookupCache->insert(key,new LookupInfo); + std::lock_guard<std::mutex> lock(g_cacheMutex); + pval=Doxygen::lookupCache->find(key.str()); + //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()); + 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) + // printf("templSpec=%s\n",pTemplSpec->data()); + return pval->classDef; + } + else // not found yet; we already add a 0 to avoid the possibility of + // endless recursion. + { + pval = Doxygen::lookupCache->insert(key.str(),LookupInfo()); + } } const ClassDef *bestMatch=0; @@ -1533,18 +1536,14 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, //printf("getResolvedClassRec: bestMatch=%p pval->resolvedType=%s\n", // bestMatch,bestResolvedType.data()); - pval=Doxygen::lookupCache->find(key); if (pval) { + std::lock_guard<std::mutex> lock(g_cacheMutex); pval->classDef = bestMatch; pval->typeDef = bestTypedef; pval->templSpec = bestTemplSpec; pval->resolvedType = bestResolvedType; } - else - { - Doxygen::lookupCache->insert(key,new LookupInfo(bestMatch,bestTypedef,bestTemplSpec,bestResolvedType)); - } //printf("] bestMatch=%s distance=%d\n", // bestMatch?bestMatch->name().data():"<none>",minDistance); //if (pTemplSpec) @@ -4487,7 +4486,7 @@ struct FindFileCacheElem bool isAmbig; }; -static QCache<FindFileCacheElem> g_findFileDefCache(5000); +static Cache<std::string,FindFileCacheElem> g_findFileDefCache(5000); static std::mutex g_findFileDefMutex; @@ -4504,8 +4503,7 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) QCString key = addr; key+=n; - g_findFileDefCache.setAutoDelete(TRUE); - FindFileCacheElem *cachedResult = g_findFileDefCache.find(key); + FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str()); //printf("key=%s cachedResult=%p\n",key.data(),cachedResult); if (cachedResult) { @@ -4515,7 +4513,7 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) } else { - cachedResult = new FindFileCacheElem(0,FALSE); + cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(0,FALSE)); } QCString name=QDir::cleanDirPath(n).utf8(); @@ -4543,8 +4541,6 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) if (path.isEmpty() || isSamePath) { cachedResult->fileDef = fd.get(); - g_findFileDefCache.insert(key,cachedResult); - //printf("=1 ===> add to cache %p\n",fd); return fd.get(); } } @@ -4563,12 +4559,10 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) lastMatch=fd; } } - //printf(">1 ===> add to cache %p\n",fd); ambig=(count>1); cachedResult->isAmbig = ambig; cachedResult->fileDef = lastMatch; - g_findFileDefCache.insert(key,cachedResult); return lastMatch; } } @@ -4577,8 +4571,6 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) //printf("not found!\n"); } exit: - //printf("0 ===> add to cache %p: %s\n",cachedResult,n); - g_findFileDefCache.insert(key,cachedResult); //delete cachedResult; return 0; } @@ -4732,11 +4724,10 @@ bool hasVisibleRoot(const BaseClassList *bcl) // note that this function is not reentrant due to the use of static growBuf! QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscore) { - static bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES); - static bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES); - static GrowBuf growBuf; - growBuf.clear(); + bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES); + bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES); if (name==0) return ""; + GrowBuf growBuf; signed char c; const signed char *p=(const signed char*)name; while ((c=*p++)!=0) @@ -5230,9 +5221,8 @@ QCString stripScope(const char *name) QCString convertToId(const char *s) { static const char hex[] = "0123456789ABCDEF"; - static GrowBuf growBuf; - growBuf.clear(); if (s==0) return ""; + GrowBuf growBuf; const char *p=s; char c; bool first=TRUE; @@ -5271,9 +5261,8 @@ QCString correctId(QCString s) /*! Converts a string to an XML-encoded string */ QCString convertToXML(const char *s, bool keepEntities) { - static GrowBuf growBuf; - growBuf.clear(); if (s==0) return ""; + GrowBuf growBuf; const char *p=s; char c; while ((c=*p++)) @@ -5323,9 +5312,8 @@ QCString convertToXML(const char *s, bool keepEntities) /*! Converts a string to an DocBook-encoded string */ QCString convertToDocBook(const char *s) { - static GrowBuf growBuf; - growBuf.clear(); if (s==0) return ""; + GrowBuf growBuf; const unsigned char *q; int cnt; const unsigned char *p=(const unsigned char *)s; @@ -5383,9 +5371,8 @@ QCString convertToDocBook(const char *s) /*! Converts a string to a HTML-encoded string */ QCString convertToHtml(const char *s,bool keepEntities) { - static GrowBuf growBuf; - growBuf.clear(); if (s==0) return ""; + GrowBuf growBuf; growBuf.addStr(getHtmlDirEmbeddingChar(getTextDirByConfig(s))); const char *p=s; char c; @@ -5430,9 +5417,8 @@ QCString convertToHtml(const char *s,bool keepEntities) QCString convertToJSString(const char *s, bool applyTextDir) { - static GrowBuf growBuf; - growBuf.clear(); if (s==0) return ""; + GrowBuf growBuf; if (applyTextDir) growBuf.addStr(getJsDirEmbeddingChar(getTextDirByConfig(s))); const char *p=s; @@ -5452,9 +5438,8 @@ QCString convertToJSString(const char *s, bool applyTextDir) QCString convertToPSString(const char *s) { - static GrowBuf growBuf; - growBuf.clear(); if (s==0) return ""; + GrowBuf growBuf; const char *p=s; char c; while ((c=*p++)) @@ -5474,7 +5459,7 @@ QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces) { QGString result; FTextStream t(&result); - filterLatexString(t,s,insideTabbing,FALSE,FALSE,keepSpaces); + filterLatexString(t,s,insideTabbing,false,false,false,keepSpaces); return result.data(); } @@ -5486,8 +5471,7 @@ QCString convertCharEntitiesToUTF8(const QCString &s) static QRegExp entityPat("&[a-zA-Z]+[0-9]*;"); if (s.length()==0) return result; - static GrowBuf growBuf; - growBuf.clear(); + GrowBuf growBuf; int p,i=0,l; while ((p=entityPat.match(s,i,&l))!=-1) { @@ -6020,7 +6004,9 @@ found: PageDef *addRelatedPage(const char *name,const QCString &ptitle, const QCString &doc, - const char *fileName,int startLine, + const char *fileName, + int docLine, + int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, @@ -6033,9 +6019,9 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo) { if (!xref) warn(fileName,startLine,"multiple use of page label '%s', (other occurrence: %s, line: %d)", - name,pd->docFile().data(),pd->docLine()); + name,pd->docFile().data(),pd->getStartBodyLine()); // append documentation block to the page. - pd->setDocumentation(doc,fileName,startLine); + pd->setDocumentation(doc,fileName,docLine); //printf("Adding page docs '%s' pi=%p name=%s\n",doc.data(),pd,name); // append (x)refitems to the page. pd->setRefItems(sli); @@ -6049,7 +6035,8 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length()); QCString title=ptitle.stripWhiteSpace(); - pd=createPageDef(fileName,startLine,baseName,doc,title); + pd=createPageDef(fileName,docLine,baseName,doc,title); + pd->setBodySegment(startLine,startLine,-1); pd->setRefItems(sli); pd->setLanguage(lang); @@ -6071,24 +6058,29 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, // a page name is a label as well! QCString file; + QCString orgFile; + int line = -1; if (gd) { file=gd->getOutputFileBase(); + orgFile=gd->getOutputFileBase(); } else { file=pd->getOutputFileBase(); + orgFile=pd->docFile(); + line = pd->getStartBodyLine(); } const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) { 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(orgFile,line,"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(orgFile,line,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName().data()); } } else @@ -6166,7 +6158,7 @@ void addGroupListToTitle(OutputList &ol,const Definition *d) } void filterLatexString(FTextStream &t,const char *str, - bool insideTabbing,bool insidePre,bool insideItem,bool keepSpaces) + bool insideTabbing,bool insidePre,bool insideItem,bool insideTable,bool keepSpaces) { if (str==0) return; //if (strlen(str)<2) stackTrace(); @@ -6203,7 +6195,7 @@ void filterLatexString(FTextStream &t,const char *str, case '$': t << "\\$"; break; case '"': t << "\"{}"; break; case '-': t << "-\\/"; break; - case '^': (usedTableLevels()>0) ? t << "\\string^" : t << (char)c; break; + case '^': insideTable ? t << "\\string^" : t << (char)c; break; case '~': t << "\\string~"; break; case ' ': if (keepSpaces) t << "~"; else t << ' '; break; @@ -6340,7 +6332,13 @@ QCString latexEscapeLabelName(const char *s) p++; } tmp[i]=0; - filterLatexString(t,tmp,TRUE); + filterLatexString(t,tmp, + true, // insideTabbing + false, // insidePre + false, // insideItem + false, // insideTable + false // keepSpaces + ); break; } } @@ -6379,7 +6377,13 @@ QCString latexEscapeIndexChars(const char *s) p++; } tmp[i]=0; - filterLatexString(t,tmp.data(),TRUE); + filterLatexString(t,tmp.data(), + true, // insideTabbing + false, // insidePre + false, // insideItem + false, // insideTable + false // keepSpaces + ); break; } } @@ -8380,7 +8384,7 @@ bool mainPageHasTitle() return Doxygen::mainPage!=0 && Doxygen::mainPage->hasTitle(); } -QCString getDotImageExtension(void) +QCString getDotImageExtension() { QCString imgExt = Config_getEnum(DOT_IMAGE_FORMAT); int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format @@ -8457,23 +8461,6 @@ void writeLatexSpecialFormulaChars(FTextStream &t) } //------------------------------------------------------ - -static int g_usedTableLevels = 0; - -void incUsedTableLevels() -{ - g_usedTableLevels++; -} -void decUsedTableLevels() -{ - g_usedTableLevels--; -} -int usedTableLevels() -{ - return g_usedTableLevels; -} - -//------------------------------------------------------ // simplified way to know if this is fixed form bool recognizeFixedForm(const char* contents, FortranFormat format) { @@ -337,7 +337,9 @@ void addRefItem(const RefItemVector &sli, PageDef *addRelatedPage(const char *name, const QCString &ptitle, const QCString &doc, - const char *fileName,int startLine, + const char *fileName, + int docLine, + int startLine, const RefItemVector &sli = RefItemVector(), GroupDef *gd=0, const TagInfo *tagInfo=0, @@ -351,10 +353,11 @@ QCString unescapeCharsInString(const char *s); void addGroupListToTitle(OutputList &ol,const Definition *d); void filterLatexString(FTextStream &t,const char *str, - bool insideTabbing=FALSE, - bool insidePre=FALSE, - bool insideItem=FALSE, - bool keepSpaces=FALSE); + bool insideTabbing, + bool insidePre, + bool insideItem, + bool insideTable, + bool keepSpaces); QCString latexEscapeLabelName(const char *s); QCString latexEscapeIndexChars(const char *s); @@ -474,7 +477,7 @@ bool protectionLevelVisible(Protection prot); QCString stripIndentation(const QCString &s); void stripIndentation(QCString &doc,const int indentationLevel); -QCString getDotImageExtension(void); +QCString getDotImageExtension(); bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile); @@ -498,10 +501,6 @@ bool openOutputFile(const char *outFile,QFile &f); void writeExtraLatexPackages(FTextStream &t); void writeLatexSpecialFormulaChars(FTextStream &t); -int usedTableLevels(); -void incUsedTableLevels(); -void decUsedTableLevels(); - bool recognizeFixedForm(const char* contents, FortranFormat format); FortranFormat convertFileNameFortranParserCode(QCString fn); diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index ff47791..12cab2d 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -2357,7 +2357,7 @@ void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname) { - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(".vhd"); + auto intf = Doxygen::parserManager->getCodeParser(".vhd"); // pIntf->resetCodeParserState(); QCString codeFragment=mdef->documentation(); @@ -2382,8 +2382,8 @@ void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString codeFragment.prepend("\n"); ol.pushGeneratorState(); - ol.startCodeFragment(); - intf.parseCode( ol, // codeOutIntf + ol.startCodeFragment("DoxyCode"); + intf->parseCode( ol, // codeOutIntf 0, // scope codeFragment, // input SrcLangExt_VHDL, // lang @@ -2397,7 +2397,7 @@ void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString TRUE // show line numbers ); - ol.endCodeFragment(); + ol.endCodeFragment("DoxyCode"); ol.popGeneratorState(); if (cname.isEmpty()) return; diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 045f87c..73aac7c 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -252,9 +252,8 @@ void XmlDocVisitor::visit(DocVerbatim *s) m_t << " filename=\"" << lang << "\">"; else m_t << ">"; - Doxygen::parserManager->getCodeParser(lang) - .parseCode(m_ci,s->context(),s->text(),langExt, - s->isExample(),s->exampleFile()); + getCodeParser(lang).parseCode(m_ci,s->context(),s->text(),langExt, + s->isExample(),s->exampleFile()); m_t << "</programlisting>"; break; case DocVerbatim::Verbatim: @@ -332,8 +331,7 @@ void XmlDocVisitor::visit(DocInclude *inc) m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -351,8 +349,7 @@ void XmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::Include: m_t << "<programlisting filename=\"" << inc->file() << "\">"; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci,inc->context(), + getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -411,8 +408,7 @@ void XmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::Snippet: m_t << "<programlisting filename=\"" << inc->file() << "\">"; - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -426,8 +422,7 @@ void XmlDocVisitor::visit(DocInclude *inc) m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getCodeParser(inc->extension()) - .parseCode(m_ci, + getCodeParser(inc->extension()).parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -480,17 +475,16 @@ void XmlDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getCodeParser(locLangExt) - .parseCode(m_ci,op->context(), - op->text(),langExt,op->isExample(), - op->exampleFile(), - fd, // fileDef - op->line(), // startLine - -1, // endLine - FALSE, // inline fragment - 0, // memberDef - op->showLineNo() // show line numbers - ); + getCodeParser(locLangExt).parseCode(m_ci,op->context(), + op->text(),langExt,op->isExample(), + op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); if (fd) delete fd; } pushEnabled(); diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 19f1553..5cad4ed 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -226,6 +226,7 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf FTextStream &m_t; }; +//------------------------------------------------------------------------------------------- /** Generator for producing XML formatted source code. */ void XMLCodeGenerator::codify(const char *text) @@ -340,6 +341,18 @@ void XMLCodeGenerator::finish() if (m_insideCodeLine) endCodeLine(); } +void XMLCodeGenerator::startCodeFragment(const char *) +{ + m_t << " <programlisting>" << endl; +} + +void XMLCodeGenerator::endCodeFragment(const char *) +{ + m_t << " </programlisting>" << endl; +} + +//------------------------------------------------------------------------------------------- + static void writeTemplateArgumentList(FTextStream &t, const ArgumentList &al, const Definition *scope, @@ -420,11 +433,12 @@ static void writeXMLDocBlock(FTextStream &t, void writeXMLCodeBlock(FTextStream &t,FileDef *fd) { - CodeParserInterface &intf=Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); + auto intf=Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension()); - intf.resetCodeParserState(); + intf->resetCodeParserState(); XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t); - intf.parseCode(*xmlGen, // codeOutIntf + xmlGen->startCodeFragment("DoxyCode"); + intf->parseCode(*xmlGen, // codeOutIntf 0, // scopeName fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)), langExt, // lang @@ -437,6 +451,7 @@ void writeXMLCodeBlock(FTextStream &t,FileDef *fd) 0, // memberDef TRUE // showLineNumbers ); + xmlGen->endCodeFragment("DoxyCode"); xmlGen->finish(); delete xmlGen; } @@ -1639,9 +1654,7 @@ static void generateXMLForFile(FileDef *fd,FTextStream &ti) t << " </detaileddescription>" << endl; if (Config_getBool(XML_PROGRAMLISTING)) { - t << " <programlisting>" << endl; writeXMLCodeBlock(t,fd); - t << " </programlisting>" << endl; } t << " <location file=\"" << convertToXML(stripFromPath(fd->getDefFileName())) << "\"/>" << endl; t << " </compounddef>" << endl; diff --git a/src/xmlgen.h b/src/xmlgen.h index 4458b9f..27bb10b 100644 --- a/src/xmlgen.h +++ b/src/xmlgen.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. * @@ -41,6 +39,8 @@ class XMLCodeGenerator : public CodeOutputInterface const char *anchorId,int l); void setCurrentDoc(const Definition *,const char *,bool){} void addWord(const char *,bool){} + void startCodeFragment(const char *); + void endCodeFragment(const char *); void finish(); |