diff options
author | JinWang An <jinwang.an@samsung.com> | 2022-12-27 12:33:07 +0900 |
---|---|---|
committer | JinWang An <jinwang.an@samsung.com> | 2022-12-27 12:33:07 +0900 |
commit | 9cf4982ab5fc6d964e1a024ff91a72d1fee5dc00 (patch) | |
tree | a19f0c024ea91acd7177f41fb5f066023f49027b /src | |
parent | 15e5c5601a13a41757e2a5e1a9105d1714d40215 (diff) | |
download | doxygen-upstream/1.9.4.tar.gz doxygen-upstream/1.9.4.tar.bz2 doxygen-upstream/1.9.4.zip |
Imported Upstream version 1.9.4upstream/1.9.4
Diffstat (limited to 'src')
215 files changed, 22259 insertions, 19749 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e0c5f7..9f7e653 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,15 +76,6 @@ add_custom_command( ) set_source_files_properties(${GENERATED_SRC}/ce_parse.h PROPERTIES GENERATED 1) -# lang_cfg.h -add_custom_command( - COMMENT "Generating ${GENERATED_SRC}/lang_cfg.h" - COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/lang_cfg.cmake ${GENERATED_SRC}/lang_cfg.h ${LANG_CODES} - DEPENDS ${LANGUAGE_FILES} - OUTPUT ${GENERATED_SRC}/lang_cfg.h -) -set_source_files_properties(${GENERATED_SRC}/lang_cfg.h PROPERTIES GENERATED 1) - # all resource files if (${CMAKE_VERSION} VERSION_EQUAL "3.11.0" OR ${CMAKE_VERSION} VERSION_GREATER "3.11.0") file(GLOB RESOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/templates/*/*) @@ -157,7 +148,6 @@ add_custom_command( ) add_library(doxycfg STATIC - ${GENERATED_SRC}/lang_cfg.h ${GENERATED_SRC}/configvalues.h ${GENERATED_SRC}/configimpl.cpp ${GENERATED_SRC}/configimpl.l.h @@ -214,7 +204,6 @@ add_library(doxymain STATIC # ${GENERATED_SRC}/ce_parse.cpp # custom generated files - ${GENERATED_SRC}/lang_cfg.h ${GENERATED_SRC}/configvalues.h ${GENERATED_SRC}/ce_parse.h ${GENERATED_SRC}/resources.cpp @@ -238,6 +227,7 @@ add_library(doxymain STATIC docbookgen.cpp docbookvisitor.cpp docgroup.cpp + docnode.cpp docparser.cpp docsets.cpp docvisitor.cpp @@ -289,7 +279,6 @@ add_library(doxymain STATIC plantuml.cpp qcstring.cpp qhp.cpp - qhpxmlwriter.cpp reflist.cpp regex.cpp resourcemgr.cpp @@ -297,6 +286,7 @@ add_library(doxymain STATIC rtfgen.cpp rtfstyle.cpp searchindex.cpp + searchindex_js.cpp sqlite3gen.cpp stlsupport.cpp symbolresolver.cpp @@ -327,6 +317,13 @@ endif() add_executable(doxygen main.cpp ) + +# enable to monitor compilation times +#set_property(TARGET doxymain PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") + +include(ApplyEditbin) +apply_editbin(doxygen console) + add_sanitizers(doxygen) if (use_libclang) @@ -344,6 +341,7 @@ if (use_libclang) add_definitions(${LLVM_DEFINITIONS}) if (static_libclang) set(CLANG_LIBS libclang clangTooling) + add_definitions(-DCINDEX_NO_EXPORTS) else() # dynamically linked version of clang llvm_config(doxymain USE_SHARED support) set(CLANG_LIBS libclang clang-cpp) diff --git a/src/bufstr.h b/src/bufstr.h index 225078f..bc0ef60 100644 --- a/src/bufstr.h +++ b/src/bufstr.h @@ -29,10 +29,10 @@ class BufStr { public: - BufStr(uint size) + BufStr(size_t size) : m_size(size), m_writeOffset(0), m_spareRoom(10240), m_buf(0) { - m_buf = (char *)calloc(size,1); + m_buf = static_cast<char *>(calloc(size,1)); } ~BufStr() { @@ -43,37 +43,37 @@ class BufStr makeRoomFor(1); m_buf[m_writeOffset++]=c; } - void addArray(const char *a,uint len) + void addArray(const char *a,size_t len) { makeRoomFor(len); memcpy(m_buf+m_writeOffset,a,len); m_writeOffset+=len; } - void skip(uint s) + void skip(size_t s) { makeRoomFor(s); m_writeOffset+=s; } - void shrink( uint newlen ) + void shrink( size_t newlen ) { m_writeOffset=newlen; resize(newlen); } - void resize( uint newlen ) + void resize( size_t newlen ) { - uint oldsize = m_size; + size_t oldsize = m_size; m_size=newlen; if (m_writeOffset>=m_size) // offset out of range -> enlarge { m_size=m_writeOffset+m_spareRoom; } - m_buf = (char *)realloc(m_buf,m_size); + m_buf = static_cast<char *>(realloc(m_buf,m_size)); if (m_size>oldsize) { memset(m_buf+oldsize,0,m_size-oldsize); } } - uint size() const + size_t size() const { return m_size; } @@ -81,7 +81,7 @@ class BufStr { return m_buf; } - char &at(uint i) const + char &at(size_t i) const { return m_buf[i]; } @@ -93,28 +93,42 @@ class BufStr { return m_buf; } - uint curPos() const + size_t curPos() const { return m_writeOffset; } - void dropFromStart(uint bytes) + void dropFromStart(size_t bytes) { if (bytes>m_size) bytes=m_size; if (bytes>0) qmemmove(m_buf,m_buf+bytes,m_size-bytes); m_size-=bytes; m_writeOffset-=bytes; } + void addTerminalCharIfMissing(char c) + { + if (m_buf && m_writeOffset>1 && m_buf[m_writeOffset-2]!=c && m_buf[m_writeOffset-1]=='\0') + { + // add missing terminal character and 0 terminator + m_buf[m_writeOffset-1] = '\n'; + addChar('\0'); + } + else if (m_buf && m_writeOffset>0 && m_buf[m_writeOffset-1]!='\0' && m_buf[m_writeOffset-1]!=c) + { + // add missing terminal character without 0 terminator + addChar(c); + } + } private: - void makeRoomFor(uint size) + void makeRoomFor(size_t size) { if (m_writeOffset+size>=m_size) { resize(m_size+size+m_spareRoom); } } - uint m_size; - uint m_writeOffset; - const uint m_spareRoom; // 10Kb extra room to avoid frequent resizing + size_t m_size; + size_t m_writeOffset; + const size_t m_spareRoom; // 10Kb extra room to avoid frequent resizing char *m_buf; }; diff --git a/src/cache.h b/src/cache.h index 5f7c834..0ff3092 100644 --- a/src/cache.h +++ b/src/cache.h @@ -40,11 +40,20 @@ class Cache } //! Inserts \a value under \a key in the cache - V *insert(const K &key,V &&value) + [[maybe_unused]] V *insert(const K &key,V &&value) { - // remove item if it already exists - remove(key); - // store new item + // reuse item if it already exists + 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); + std::exchange(it->second->second,value); + return &it->second->second; + } + // create new item m_cacheItemList.push_front(kv_pair(key,std::move(value))); V *result = &m_cacheItemList.front().second; m_cacheItemMap[key] = m_cacheItemList.begin(); @@ -54,10 +63,19 @@ class Cache } //! Inserts \a value under \a key in the cache - V *insert(const K &key,const V &value) + [[maybe_unused]] V *insert(const K &key,const V &value) { - // remove item if it already exists - remove(key); + // reuse item if it already exists + 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); + it->second->second = value; + return &it->second->second; + } // store new item m_cacheItemList.push_front(kv_pair(key,value)); V *result = &m_cacheItemList.front().second; @@ -140,6 +158,7 @@ class Cache const_iterator end() const { return m_cacheItemList.cend(); } private: + // remove least recently used item if cache is full void resize() { if (m_cacheItemMap.size() > m_capacity) @@ -150,6 +169,7 @@ class Cache 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; diff --git a/src/cite.cpp b/src/cite.cpp index ce7c2e1..611a4da 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -153,11 +153,11 @@ void CitationManager::insertCrossReferencesForBibFile(const QCString &bibFile) { if (k!=-1) { - citeName = line.mid((uint)(j),(uint)(k-j)); + citeName = line.mid(static_cast<size_t>(j),static_cast<size_t>(k-j)); } else { - citeName = line.mid((uint)(j)); + citeName = line.mid(static_cast<size_t>(j)); } citeName = citeName.stripWhiteSpace(); j = 0; @@ -176,7 +176,7 @@ void CitationManager::insertCrossReferencesForBibFile(const QCString &bibFile) int k = line.find('}',i); if (j>i && k>j) { - QCString crossrefName = line.mid((uint)(j+1),(uint)(k-j-1)); + QCString crossrefName = line.mid(static_cast<size_t>(j+1),static_cast<uint>(k-j-1)); // check if the reference with the cross reference is used // insert cross reference when cross reference has not yet been added. if ((p->entries.find(citeName.str())!=p->entries.end()) && @@ -310,9 +310,9 @@ void CitationManager::generatePage() int k=line.find("]</a>"); if (j!=-1 && k!=-1) { - uint ui=(uint)i; - uint uj=(uint)j; - uint uk=(uint)k; + size_t ui=static_cast<size_t>(i); + size_t uj=static_cast<size_t>(j); + size_t uk=static_cast<size_t>(k); QCString label = line.mid(ui+14,uj-ui-14); QCString number = line.mid(uj+2,uk-uj-1); line = line.left(ui+14) + label + line.right(line.length()-uj); @@ -24,7 +24,7 @@ /// Citation-related data. struct CiteInfo { - virtual ~CiteInfo() {} + virtual ~CiteInfo() = default; virtual QCString label() const = 0; virtual QCString text() const = 0; }; diff --git a/src/clangparser.cpp b/src/clangparser.cpp index 42a0bc9..a771d4f 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -44,7 +44,7 @@ enum class DetectedLang { Cpp, ObjC, ObjCpp }; static QCString detab(const QCString &s) { - static int tabSize = Config_getInt(TAB_SIZE); + int tabSize = Config_getInt(TAB_SIZE); GrowBuf out; int size = s.length(); const char *data = s.data(); @@ -184,11 +184,11 @@ void ClangTUParser::parse() clang_option_len = command[command.size()-1].CommandLine.size(); } } - char **argv = (char**)malloc(sizeof(char*)* + char **argv = static_cast<char**>(malloc(sizeof(char*)* (4+Doxygen::inputPaths.size()+ includePath.size()+ clangOptions.size()+ - clang_option_len)); + clang_option_len))); if (!command.empty() ) { std::vector<std::string> options = command[command.size()-1].CommandLine; @@ -262,7 +262,7 @@ void ClangTUParser::parse() case DetectedLang::ObjCpp: argv[argc++]=qstrdup("objective-c++"); break; } - // provide the input and and its dependencies as unsaved files so we can + // provide the input and its dependencies as unsaved files so we can // pass the filtered versions argv[argc++]=qstrdup(fileName.data()); } @@ -324,7 +324,7 @@ void ClangTUParser::parse() ClangTUParser::~ClangTUParser() { //printf("ClangTUParser::~ClangTUParser() this=%p\n",this); - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); + bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); if (!clangAssistedParsing) return; if (p->tu) { @@ -383,7 +383,7 @@ std::string ClangTUParser::lookup(uint line,const char *symbol) //printf("ClangParser::lookup(%d,%s)\n",line,symbol); std::string result; if (symbol==0) return result; - static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); + bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); if (!clangAssistedParsing) return result; auto getCurrentTokenLine = [=]() -> uint @@ -489,7 +489,7 @@ std::string ClangTUParser::lookup(uint line,const char *symbol) void ClangTUParser::writeLineNumber(CodeOutputInterface &ol,const FileDef *fd,uint line,bool writeLineAnchor) { const Definition *d = fd ? fd->getSourceDefinition(line) : 0; - if (d && d->isLinkable()) + if (d && fd->isLinkable()) { p->currentLine=line; const MemberDef *md = fd->getSourceMember(line); @@ -547,9 +547,9 @@ void ClangTUParser::codifyLines(CodeOutputInterface &ol,const FileDef *fd,const if (c=='\n') { line++; - int l = (int)(p-sp-1); + int l = static_cast<int>(p-sp-1); column=l+1; - char *tmp = (char*)malloc(l+1); + char *tmp = static_cast<char *>(malloc(l+1)); memcpy(tmp,sp,l); tmp[l]='\0'; ol.codify(tmp); @@ -574,7 +574,7 @@ void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol, const Definition *d, const char *text) { - static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); + bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); p->tooltipManager.addTooltip(ol,d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); @@ -586,18 +586,17 @@ void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol, } bool inlineCodeFragment = false; bool done=FALSE; - char *p=(char *)text; + const char *p=text; while (!done) { - char *sp=p; + const char *sp=p; char c; while ((c=*p++) && c!='\n') { column++; } if (c=='\n') { line++; - *(p-1)='\0'; //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp); - ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,sp,tooltip); + ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp,p-sp-1),tooltip); ol.endCodeLine(); ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line,inlineCodeFragment); @@ -764,7 +763,7 @@ void ClangTUParser::writeSources(CodeOutputInterface &ol,const FileDef *fd) QCString lineNumber,lineAnchor; bool inlineCodeFragment = false; ol.startCodeLine(TRUE); - writeLineNumber(ol,fd,line,inlineCodeFragment); + writeLineNumber(ol,fd,line,!inlineCodeFragment); for (unsigned int i=0;i<p->numTokens;i++) { CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]); @@ -776,7 +775,7 @@ void ClangTUParser::writeSources(CodeOutputInterface &ol,const FileDef *fd) line++; ol.endCodeLine(); ol.startCodeLine(TRUE); - writeLineNumber(ol,fd,line,inlineCodeFragment); + writeLineNumber(ol,fd,line,!inlineCodeFragment); } while (column<c) { ol.codify(" "); column++; } CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]); diff --git a/src/classdef.cpp b/src/classdef.cpp index 937c531..c9d4906 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -55,7 +55,7 @@ static QCString makeQualifiedNameWithTemplateParameters(const ClassDef *cd, const ArgumentLists *actualParams,uint *actualParamIndex) { - //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); //printf("qualifiedNameWithTemplateParameters() localName=%s\n",qPrint(localName())); QCString scName; @@ -106,9 +106,9 @@ static QCString makeQualifiedNameWithTemplateParameters(const ClassDef *cd, static QCString makeDisplayName(const ClassDef *cd,bool includeScope) { - //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + //bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); SrcLangExt lang = cd->getLanguage(); - //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); QCString n; if (lang==SrcLangExt_VHDL) { @@ -821,7 +821,7 @@ void ClassDefImpl::insertSubClass(ClassDef *cd,Protection p, Specifier s,const QCString &t) { //printf("*** insert sub class %s into %s\n",qPrint(cd->name()),qPrint(name())); - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); if (!extractPrivate && cd->protection()==Private) return; m_impl->inheritedBy.push_back(BaseClassDef(cd,QCString(),p,s,t)); m_impl->isSimple = FALSE; @@ -1385,7 +1385,7 @@ void ClassDefImpl::writeBriefDescription(OutputList &ol,bool exampleFlag) const void ClassDefImpl::writeDetailedDocumentationBody(OutputList &ol) const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); ol.startTextBlock(); @@ -1435,8 +1435,8 @@ void ClassDefImpl::writeDetailedDocumentationBody(OutputList &ol) const bool ClassDefImpl::hasDetailedDescription() const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); - static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool sourceBrowser = Config_getBool(SOURCE_BROWSER); return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty() || (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef())); @@ -1605,8 +1605,8 @@ int ClassDefImpl::countInheritanceNodes() const void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const { - static bool haveDot = Config_getBool(HAVE_DOT); - static auto classGraph = Config_getEnum(CLASS_GRAPH); + bool haveDot = Config_getBool(HAVE_DOT); + auto classGraph = Config_getEnum(CLASS_GRAPH); if (classGraph == CLASS_GRAPH_t::NO) return; // count direct inheritance relations @@ -1678,7 +1678,7 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const ol.startParagraph(); writeMarkerList(ol, - theTranslator->trInheritsList((int)m_impl->inherits.size()).str(), + theTranslator->trInheritsList(static_cast<int>(m_impl->inherits.size())).str(), m_impl->inherits.size(), replaceFunc); ol.endParagraph(); @@ -1705,7 +1705,7 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const ol.startParagraph(); writeMarkerList(ol, - theTranslator->trInheritedByList((int)m_impl->inheritedBy.size()).str(), + theTranslator->trInheritedByList(static_cast<int>(m_impl->inheritedBy.size())).str(), m_impl->inheritedBy.size(), replaceFunc); ol.endParagraph(); @@ -1996,7 +1996,7 @@ void ClassDefImpl::startMemberDeclarations(OutputList &ol) const void ClassDefImpl::endMemberDeclarations(OutputList &ol) const { //printf("%s: ClassDefImpl::endMemberDeclarations()\n",qPrint(name())); - static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); + bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0) { ol.startMemberHeader("inherited"); @@ -2035,9 +2035,12 @@ void ClassDefImpl::writeSummaryLinks(OutputList &ol) const m_impl->innerClasses.declVisible() ) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - ol.writeSummaryLink(QCString(),"nested-classes",ls->title(lang),first); - first=FALSE; + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (ls) + { + ol.writeSummaryLink(QCString(),"nested-classes",ls->title(lang),first); + first=FALSE; + } } else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink && !m_impl->allMemberNameInfoLinkedMap.empty() && @@ -2047,14 +2050,17 @@ void ClassDefImpl::writeSummaryLinks(OutputList &ol) const ol.writeSummaryLink(getMemberListFileName(),"all-members-list",theTranslator->trListOfAllMembers(),first); first=FALSE; } - else if (lde->kind()== LayoutDocEntry::MemberDecl) + else if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml && ml->declVisible()) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); - first=FALSE; + MemberList * ml = getMemberList(lmd->type); + if (ml && ml->declVisible()) + { + ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); + first=FALSE; + } } } } @@ -2150,11 +2156,14 @@ void ClassDefImpl::writeTagFile(TextStream &tagFile) break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ml->writeTagFile(tagFile); + MemberList * ml = getMemberList(lmd->type); + if (ml) + { + ml->writeTagFile(tagFile); + } } } break; @@ -2246,9 +2255,12 @@ void ClassDefImpl::writeInlineDocumentation(OutputList &ol) const break; case LayoutDocEntry::MemberDecl: { - ClassDefSet visitedClasses; - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - if (!isSimple) writeMemberDeclarations(ol,visitedClasses,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE); + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) + { + ClassDefSet visitedClasses; + if (!isSimple) writeMemberDeclarations(ol,visitedClasses,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE); + } } break; case LayoutDocEntry::MemberGroups: @@ -2262,14 +2274,17 @@ void ClassDefImpl::writeInlineDocumentation(OutputList &ol) const break; case LayoutDocEntry::MemberDef: { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - if (isSimple) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - writeSimpleMemberDocumentation(ol,lmd->type); - } - else - { - writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE); + if (isSimple) + { + writeSimpleMemberDocumentation(ol,lmd->type); + } + else + { + writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE); + } } } break; @@ -2294,9 +2309,9 @@ void ClassDefImpl::writeMoreLink(OutputList &ol,const QCString &anchor) const { // TODO: clean up this mess by moving it to // the output generators... - static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - static bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS); - static bool usePDFLatex = Config_getBool(USE_PDFLATEX); + bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS); + bool usePDFLatex = Config_getBool(USE_PDFLATEX); // HTML only ol.pushGeneratorState(); @@ -2336,9 +2351,9 @@ void ClassDefImpl::writeMoreLink(OutputList &ol,const QCString &anchor) const bool ClassDefImpl::visibleInParentsDeclList() const { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); - static bool extractLocalClasses = Config_getBool(EXTRACT_LOCAL_CLASSES); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); + bool extractLocalClasses = Config_getBool(EXTRACT_LOCAL_CLASSES); bool linkable = isLinkable(); return (!isAnonymous() && !isExtension() && (protection()!=::Private || extractPrivate) && @@ -2348,9 +2363,9 @@ bool ClassDefImpl::visibleInParentsDeclList() const void ClassDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCString &header,bool localNames) const { - //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); SrcLangExt lang = getLanguage(); if (visibleInParentsDeclList()) { @@ -2430,22 +2445,22 @@ void ClassDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCStrin { ol.writeString(" "); ol.insertMemberAlign(); - ol.writeString(VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)protection())); + ol.writeString(VhdlDocGen::getProtectionName(VhdlDocGen::convert(protection()))); } ol.endMemberItem(); // add the brief description if available if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC)) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc(*parser.get(), + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), briefFile(),briefLine(),this,0, briefDescription(),FALSE,FALSE, QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + if (!ast->isEmpty()) { ol.startMemberDescription(anchor()); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); if (isLinkableInProject()) { writeMoreLink(ol,anchor()); @@ -2529,14 +2544,20 @@ void ClassDefImpl::writeDocumentationContents(OutputList &ol,const QCString & /* case LayoutDocEntry::MemberDecl: { ClassDefSet visitedClasses; - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - writeMemberDeclarations(ol,visitedClasses,lmd->type,lmd->title(lang),lmd->subtitle(lang)); + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) + { + writeMemberDeclarations(ol,visitedClasses,lmd->type,lmd->title(lang),lmd->subtitle(lang)); + } } break; case LayoutDocEntry::ClassNestedClasses: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNestedClasses(ol,ls->title(lang)); + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (ls) + { + writeNestedClasses(ol,ls->title(lang)); + } } break; case LayoutDocEntry::MemberDeclEnd: @@ -2544,8 +2565,11 @@ void ClassDefImpl::writeDocumentationContents(OutputList &ol,const QCString & /* break; case LayoutDocEntry::DetailedDesc: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang)); + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (ls) + { + writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang)); + } } break; case LayoutDocEntry::MemberDefStart: @@ -2556,8 +2580,11 @@ void ClassDefImpl::writeDocumentationContents(OutputList &ol,const QCString & /* break; case LayoutDocEntry::MemberDef: { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) + { + writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); + } } break; case LayoutDocEntry::MemberDefEnd: @@ -2663,10 +2690,10 @@ QCString ClassDefImpl::title() const // write all documentation for this class void ClassDefImpl::writeDocumentation(OutputList &ol) const { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); - //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); QCString pageTitle = title(); HighlightedItem hli; @@ -2741,7 +2768,7 @@ void ClassDefImpl::writeMemberPages(OutputList &ol) const void ClassDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { - static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); + bool createSubDirs=Config_getBool(CREATE_SUBDIRS); ol.writeString(" <div class=\"navtab\">\n"); ol.writeString(" <table>\n"); @@ -2809,10 +2836,10 @@ void ClassDefImpl::writeDocumentationForInnerClasses(OutputList &ol) const // write the list of all (inherited) members for this class void ClassDefImpl::writeMemberList(OutputList &ol) const { - static bool cOpt = Config_getBool(OPTIMIZE_OUTPUT_FOR_C); - //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool cOpt = Config_getBool(OPTIMIZE_OUTPUT_FOR_C); + //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); if (m_impl->allMemberNameInfoLinkedMap.empty() || cOpt) return; // only for HTML ol.pushGeneratorState(); @@ -3106,7 +3133,7 @@ bool ClassDefImpl::hasExamples() const void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCString &type) { //printf("addTypeConstraint(%s,%s)\n",qPrint(type),qPrint(typeConstraint)); - static bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS); + bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS); if (typeConstraint.isEmpty() || type.isEmpty()) return; SymbolResolver resolver(getFileDef()); ClassDefMutable *cd = resolver.resolveClassMutable(this,typeConstraint); @@ -3160,7 +3187,7 @@ void ClassDefImpl::addTypeConstraints() addTypeConstraint(typeConstraint,a.type); p=i+1; } - typeConstraint = a.typeConstraint.right(a.typeConstraint.length()-(uint)p).stripWhiteSpace(); + typeConstraint = a.typeConstraint.right(a.typeConstraint.length()-p).stripWhiteSpace(); addTypeConstraint(typeConstraint,a.type); } } @@ -3257,8 +3284,11 @@ void ClassDefImpl::writeDeclaration(OutputList &ol,const MemberDef *md,bool inGr { if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - writePlainMemberDeclaration(ol,lmd->type,inGroup,indentLevel,inheritedFrom,inheritId); + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) + { + writePlainMemberDeclaration(ol,lmd->type,inGroup,indentLevel,inheritedFrom,inheritId); + } } } } @@ -3266,9 +3296,9 @@ void ClassDefImpl::writeDeclaration(OutputList &ol,const MemberDef *md,bool inGr /*! a link to this class is possible within this project */ bool ClassDefImpl::isLinkableInProject() const { - static bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); - static bool hideUndoc = Config_getBool(HIDE_UNDOC_CLASSES); + bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES); + bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool hideUndoc = Config_getBool(HIDE_UNDOC_CLASSES); if (m_impl->templateMaster) { return m_impl->templateMaster->isLinkableInProject(); @@ -3388,16 +3418,16 @@ void ClassDefImpl::mergeMembers() { if (m_impl->membersMerged) return; - //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); - //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + //bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); SrcLangExt lang = getLanguage(); QCString sep=getLanguageSpecificSeparator(lang,TRUE); uint sepLen = sep.length(); m_impl->membersMerged=TRUE; //printf(" mergeMembers for %s\n",qPrint(name())); - static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); for (const auto &bcd : baseClasses()) { ClassDefMutable *bClass=toClassDefMutable(bcd.classDef); @@ -3442,7 +3472,7 @@ void ClassDefImpl::mergeMembers() found=matchArguments2( srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl, dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl, - TRUE + TRUE,getLanguage() ); //printf(" Yes, matching (%s<->%s): %d\n", // qPrint(argListToString(srcMd->argumentList())), @@ -3458,7 +3488,7 @@ void ClassDefImpl::mergeMembers() // qPrint(dstMd->name()), // qPrint(dstMi->scopePath.left(dstMi->scopePath.find("::")+2)); - QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); + QCString scope=dstMi->scopePath().left(dstMi->scopePath().find(sep)+sepLen); if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) { dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope()); @@ -3487,7 +3517,7 @@ void ClassDefImpl::mergeMembers() // qPrint(dstMd->name()), // qPrint(dstMi->scopePath.left(dstMi->scopePath.find("::")+2)); - QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); + QCString scope=dstMi->scopePath().left(dstMi->scopePath().find(sep)+sepLen); if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) { dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope); @@ -3619,7 +3649,7 @@ void ClassDefImpl::mergeCategory(ClassDef *cat) ClassDefMutable *category = toClassDefMutable(cat); if (category) { - static bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS); + bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS); bool makePrivate = category->isLocal(); // in case extract local methods is not enabled we don't add the methods // of the category in case it is defined in the .m file. @@ -3732,8 +3762,8 @@ void ClassDefImpl::mergeCategory(ClassDef *cat) void ClassDefImpl::addUsedClass(ClassDef *cd,const QCString &accessName, Protection prot) { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - static bool umlLook = Config_getBool(UML_LOOK); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool umlLook = Config_getBool(UML_LOOK); if (prot==Private && !extractPrivate) return; //printf("%s::addUsedClass(%s,%s)\n",qPrint(name()),qPrint(cd->name()),accessName); @@ -3764,8 +3794,8 @@ void ClassDefImpl::addUsedClass(ClassDef *cd,const QCString &accessName, void ClassDefImpl::addUsedByClass(ClassDef *cd,const QCString &accessName, Protection prot) { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - static bool umlLook = Config_getBool(UML_LOOK); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool umlLook = Config_getBool(UML_LOOK); if (prot==Private && !extractPrivate) return; //printf("%s::addUsedByClass(%s,%s)\n",qPrint(name()),qPrint(cd->name()),accessName); // @@ -3830,8 +3860,8 @@ QCString ClassDefImpl::compoundTypeString() const QCString ClassDefImpl::getOutputFileBase() const { - static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); + bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); if (!Doxygen::generatingXmlOutput) { Definition *scope=0; @@ -4162,8 +4192,8 @@ MemberList *ClassDefImpl::getMemberList(MemberListType lt) const void ClassDefImpl::addMemberToList(MemberListType lt,const MemberDef *md,bool isBrief) { - static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); - static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); + bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); + bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); const auto &ml = m_impl->memberLists.get(lt,MemberListContainer::Class); ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs)); ml->push_back(md); @@ -4201,7 +4231,7 @@ int ClassDefImpl::countMemberDeclarations(MemberListType lt,const ClassDef *inhe //printf("%s: countMemberDeclarations for %d and %d\n",qPrint(name()),lt,lt2); int count=0; MemberList * ml = getMemberList(lt); - MemberList * ml2 = getMemberList((MemberListType)lt2); + MemberList * ml2 = getMemberList(static_cast<MemberListType>(lt2)); if (getLanguage()!=SrcLangExt_VHDL) // use specific declarations function { if (ml) @@ -4220,10 +4250,10 @@ int ClassDefImpl::countMemberDeclarations(MemberListType lt,const ClassDef *inhe for (const auto &mg : m_impl->memberGroups) { count+=mg->countGroupedInheritedMembers(lt); - if (lt2!=-1) count+=mg->countGroupedInheritedMembers((MemberListType)lt2); + if (lt2!=-1) count+=mg->countGroupedInheritedMembers(static_cast<MemberListType>(lt2)); } } - static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); + bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); if (!inlineInheritedMembers) // show inherited members as separate lists { count+=countInheritedDecMembers(lt,inheritedFrom,invert,showAlways,visitedClasses); @@ -4239,11 +4269,14 @@ void ClassDefImpl::setAnonymousEnumType() { if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ml->setAnonymousEnumType(); + MemberList * ml = getMemberList(lmd->type); + if (ml) + { + ml->setAnonymousEnumType(); + } } } else if (lde->kind()==LayoutDocEntry::MemberGroups) @@ -4295,7 +4328,7 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt, visitedClasses.insert(icd); // guard for multiple virtual inheritance if (lt1!=-1) { - inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses); + inhCount+=icd->countMemberDeclarations(static_cast<MemberListType>(lt1),inheritedFrom,lt2,FALSE,TRUE,visitedClasses); } } } @@ -4312,8 +4345,8 @@ void ClassDefImpl::getTitleForMemberListType(MemberListType type, { if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - if (lmd->type==type) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd && lmd->type==type) { title = lmd->title(lang); subtitle = lmd->subtitle(lang); @@ -4332,8 +4365,8 @@ int ClassDefImpl::countAdditionalInheritedMembers() const { if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - if (lmd->type!=MemberListType_friends) // friendship is not inherited + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd && lmd->type!=MemberListType_friends) // friendship is not inherited { ClassDefSet visited; totalCount+=countInheritedDecMembers(lmd->type,this,TRUE,FALSE,visited); @@ -4351,8 +4384,8 @@ void ClassDefImpl::writeAdditionalInheritedMembers(OutputList &ol) const { if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - if (lmd->type!=MemberListType_friends) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd && lmd->type!=MemberListType_friends) { ClassDefSet visited; writeInheritedMemberDeclarations(ol,visited,lmd->type,-1,lmd->title(getLanguage()),this,TRUE,FALSE); @@ -4415,7 +4448,7 @@ void ClassDefImpl::writeInheritedMemberDeclarations(OutputList &ol,ClassDefSet & visitedClasses.insert(icd); // guard for multiple virtual inheritance if (lt1!=-1) { - icd->writeMemberDeclarations(ol,visitedClasses,(MemberListType)lt1, + icd->writeMemberDeclarations(ol,visitedClasses,static_cast<MemberListType>(lt1), title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE); } } @@ -4436,7 +4469,7 @@ void ClassDefImpl::writeMemberDeclarations(OutputList &ol,ClassDefSet &visitedCl { //printf("%s: ClassDefImpl::writeMemberDeclarations lt=%d lt2=%d\n",qPrint(name()),lt,lt2); MemberList * ml = getMemberList(lt); - MemberList * ml2 = getMemberList((MemberListType)lt2); + MemberList * ml2 = getMemberList(static_cast<MemberListType>(lt2)); if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function { static const ClassDef *cdef; @@ -4466,7 +4499,7 @@ void ClassDefImpl::writeMemberDeclarations(OutputList &ol,ClassDefSet &visitedCl //printf(" writeDeclaration type=%d count=%d\n",lt2,ml2->numDecMembers()); ml2->writeDeclarations(ol,this,0,0,0,tt,st,FALSE,showInline,inheritedFrom,lt); } - static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); + bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); if (!inlineInheritedMembers) // show inherited members as separate lists { writeInheritedMemberDeclarations(ol,visitedClasses,lt,lt2,title, @@ -4775,8 +4808,8 @@ QCString ClassDefImpl::anchor() const bool ClassDefImpl::isEmbeddedInOuterScope() const { - static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); + bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); Definition *container = getOuterScope(); diff --git a/src/classdef.h b/src/classdef.h index 7d9c22e..bd1a160 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -115,8 +115,6 @@ class ClassDef : public Definition Singleton, //=Entry::CLASS_SEC }; - virtual ~ClassDef() {} - //----------------------------------------------------------------------------------- // --- getters //----------------------------------------------------------------------------------- diff --git a/src/classlist.cpp b/src/classlist.cpp index b4c2412..9cf46b7 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -53,7 +53,7 @@ bool ClassLinkedRefMap::declVisible(const ClassDef::CompoundType *filter) const void ClassLinkedRefMap::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter, const QCString &header,bool localNames) const { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); bool found=FALSE; for (const auto &cd : *this) { @@ -73,10 +73,10 @@ void ClassLinkedRefMap::writeDeclaration(OutputList &ol,const ClassDef::Compound void ClassLinkedRefMap::writeDocumentation(OutputList &ol,const Definition * container) const { - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); + bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); if (!inlineGroupedClasses && !inlineSimpleClasses) return; bool found=FALSE; @@ -179,7 +179,10 @@ struct codeYY_state std::unordered_map< int, QCString> commentMap; int braceCount=0; + using UsingContext = std::map<std::string,const NamespaceDef*>; + VariableContext theVarContext; + UsingContext theUsingContext; CallContext theCallContext; SymbolResolver symbolResolver; TooltipManager tooltipManager; @@ -213,7 +216,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, const QCString &text); static void addType(yyscan_t yyscanner); static void addParmType(yyscan_t yyscanner); -static void addUsingDirective(yyscan_t yyscanner,const char *name); +static void addUsingDirective(yyscan_t yyscanner,const QCString &name); static void setParameterList(yyscan_t yyscanner,const MemberDef *md); static const ClassDef *stripClassName(yyscan_t yyscanner,const QCString &s,const Definition *d); static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name); @@ -258,7 +261,6 @@ static std::mutex g_searchIndexMutex; static std::mutex g_docCrossReferenceMutex; static std::mutex g_addExampleMutex; static std::mutex g_countFlowKeywordsMutex; -static std::mutex g_usingDirectiveMutex; /* ----------------------------------------------------------------- */ @@ -932,13 +934,18 @@ ENDQopt ("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"seale endFontClass(yyscanner); BEGIN(UsingName); } +<Body>"using"{BN}+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN(UsingName); + } <ConceptName>{ID}("::"{ID})* { - addUsingDirective(yyscanner,yytext); generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); } <ConceptName>"=" { codifyLines(yyscanner,yytext); BEGIN(Body); } -<UsingName>{ID}("::"{ID})* { - addUsingDirective(yyscanner,yytext); +<UsingName>{ID}(("::"|"."){ID})* { + addUsingDirective(yyscanner,substitute(yytext,".","::")); generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); BEGIN(Body); } @@ -1147,6 +1154,18 @@ ENDQopt ("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"seale generateFunctionLink(yyscanner,*yyextra->code,yytext); yyextra->name+=yytext; } +<Body>{ID}("."{ID})+/{BN}+ { // CSharp/Java scope + if (yyextra->lang==SrcLangExt_CSharp || yyextra->lang==SrcLangExt_Java) + { + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } + else + { + REJECT; + } + } <Body>{SCOPENAME}/{B}* { // p->func() if (startsWithKeyword(yytext,"typedef")) REJECT; addType(yyscanner); @@ -2198,6 +2217,7 @@ static void addVariable(yyscan_t yyscanner,QCString type,QCString name) ltype = ltype.right(ltype.length()-6); } if (ltype.isEmpty() || lname.isEmpty()) return; + ltype = substitute(ltype,".","::"); DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n", qPrint(ltype),qPrint(lname),yyextra->currentDefinition?qPrint(yyextra->currentDefinition->name()):"<none>")); auto it = yyextra->codeClassMap.find(ltype.str()); @@ -2208,20 +2228,33 @@ static void addVariable(yyscan_t yyscanner,QCString type,QCString name) } else { - const ClassDef *varDef = yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,ltype); - int i=0; - if (varDef) + auto findVariableType = [&yyscanner,&yyg,<ype,&lname,&name](const Definition *d) -> const ClassDef * { - DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname))); - yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varDef)); // add it to a list - } - else if ((i=ltype.find('<'))!=-1) + const ClassDef *varDef = yyextra->symbolResolver.resolveClass(d,ltype); + int i=0; + if (varDef) + { + DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname))); + yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varDef)); // add it to a list + } + else if ((i=ltype.find('<'))!=-1) + { + // probably a template class + QCString typeName(ltype.left(i)); + addVariable(yyscanner,typeName,name); + } + return varDef; + }; + const ClassDef *varDef = findVariableType(yyextra->currentDefinition); + if (varDef==0) // also check via using directive { - // probably a template class - QCString typeName(ltype.left(i)); - addVariable(yyscanner,typeName,name); + for (const auto &kv : yyextra->theUsingContext) + { + varDef = findVariableType(kv.second); + if (varDef!=0) break; + } } - else + if (varDef==0) { if (!yyextra->theVarContext.atGlobalScope()) // for local variables add a dummy entry so the name // is hidden to avoid false links to global variables with the same name @@ -2544,17 +2577,16 @@ static void addParmType(yyscan_t yyscanner) yyextra->parmName.resize(0) ; } -// TODO: make this have a scope only effect, at least not modifying the FileDef object. -static void addUsingDirective(yyscan_t yyscanner,const char *name) +static void addUsingDirective(yyscan_t yyscanner,const QCString &name) { - std::lock_guard<std::mutex> lock(g_usingDirectiveMutex); + //printf("AddUsingDirective(%s)\n",qPrint(name)); struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - if (yyextra->sourceFileDef && name) + if (yyextra->sourceFileDef && !name.isEmpty()) { const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name); if (nd) { - const_cast<FileDef*>(yyextra->sourceFileDef)->addUsingDirective(nd); + yyextra->theUsingContext.insert(std::make_pair(name.str(),nd)); } } } @@ -2834,7 +2866,6 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, bool varOnly) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - int i=0; QCString className=clName; if (!className.isEmpty() && className[0]=='~') // correct for matching negated values i.s.o. destructors. { @@ -2855,7 +2886,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, } else if (yyextra->lang==SrcLangExt_CSharp || yyextra->lang==SrcLangExt_Java) { - className = substitute(className,".","::"); // for PHP namespaces + className = substitute(className,".","::"); // for C#/Java namespaces } const ScopedTypeVariant *lcd=0; const ClassDef *cd=0; @@ -2865,25 +2896,54 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",qPrint(className))); if (!yyextra->isPrefixedWithThis || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable { - const Definition *d = yyextra->currentDefinition; - DBG_CTX((stderr,"d=%s yyextra->sourceFileDef=%s\n",d?qPrint(d->name()):"<none>",yyextra->sourceFileDef?qPrint(yyextra->sourceFileDef->name()):"<none>")); - cd = yyextra->symbolResolver.resolveClass(d,className); - md = yyextra->symbolResolver.getTypedef(); - DBG_CTX((stderr,"non-local variable name=%s cd=%s md=%s!\n", - qPrint(className),cd?qPrint(cd->name()):"<none>", - md?qPrint(md->name()):"<none>")); - i=className.find('<'); + int i=className.find('<'); QCString bareName = className; if (i!=-1) bareName = bareName.left(i); - if (cd==0 && md==0 && i!=-1) + + auto checkForClass = [&yyg,&bareName,&className](const Definition *d, + const ClassDef *&cd_,const MemberDef *&md_) + { + cd_ = yyextra->symbolResolver.resolveClass(d,className); + md_ = yyextra->symbolResolver.getTypedef(); + DBG_CTX((stderr,"non-local variable name=%s cd=%s md=%s!\n", + qPrint(className),cd_?qPrint(cd_->name()):"<none>", + md_?qPrint(md_->name()):"<none>")); + if (cd_==0 && md_==0 && !bareName.isEmpty()) + { + DBG_CTX((stderr,"bareName=%s\n",qPrint(bareName))); + if (bareName!=className) + { + cd_ = yyextra->symbolResolver.resolveClass(d,bareName); // try unspecialized version + md_ = yyextra->symbolResolver.getTypedef(); + } + } + }; + const Definition *d = yyextra->currentDefinition; + DBG_CTX((stderr,"d=%s yyextra->sourceFileDef=%s\n",d?qPrint(d->name()):"<none>",yyextra->sourceFileDef?qPrint(yyextra->sourceFileDef->name()):"<none>")); + checkForClass(d,cd,md); + if (cd==0 && md==0 && d && d->definitionType()==Definition::TypeClass) + { + const FileDef *fd = toClassDef(d)->getFileDef(); + if (fd) + { + // also check for using directive in the file that defines this class + for (const auto &nd : fd->getUsedNamespaces()) + { + checkForClass(nd,cd,md); + if (cd!=0 || md!=0) break; + } + } + } + if (cd==0 && md==0) { - DBG_CTX((stderr,"bareName=%s\n",qPrint(bareName))); - if (bareName!=className) + // also check via using directive + for (const auto &kv : yyextra->theUsingContext) { - cd = yyextra->symbolResolver.resolveClass(d,bareName); // try unspecialized version - md = yyextra->symbolResolver.getTypedef(); + checkForClass(kv.second,cd,md); + if (cd!=0 || md!=0) break; } } + const NamespaceDef *nd = getResolvedNamespace(className); if (nd && nd->isLinkable()) { @@ -2974,7 +3034,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (md==0) // not found as a typedef { md = setCallContextForVar(yyscanner,clName); - DBG_CTX((stderr,"setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",qPrint(clName),(void*)md,(void*)yyextra->currentDefinition)); + DBG_CTX((stderr,"setCallContextForVar(%s) md=%p yyextra->currentDefinition=%s\n",qPrint(clName),(void*)md,yyextra->currentDefinition ? qPrint(yyextra->currentDefinition->name()) : "<none>")); if (md && yyextra->currentDefinition) { DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n", @@ -3242,7 +3302,7 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons QCString funcWithScope=locFunc; QCString funcWithFullScope=locFunc; QCString fullScope=locScope; - DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",qPrint(locScope),qPrint(locFunc))); + DBG_CTX((stderr,"*** locScope=%s locFunc=%s\n",qPrint(locScope),qPrint(locFunc))); int len=2; int i=locFunc.findRev("::"); if (yyextra->currentMemberDef && yyextra->currentMemberDef->resolveAlias()->getClassDef() && @@ -3734,12 +3794,12 @@ static QCString escapeComment(yyscan_t yyscanner,const char *s) static bool skipLanguageSpecificKeyword(yyscan_t yyscanner,const char *keyword) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - static std::unordered_set<std::string> non_cpp_keywords = { + static const std::unordered_set<std::string> non_cpp_keywords = { "__assume", "__super", "abstract", "function", "gcnew", "gcroot", "generic", "get", "internal", "null", "pin_ptr", "raise", "remove", "self", "set", "transient"}; - static std::unordered_set<std::string> non_java_keywords = { + static const std::unordered_set<std::string> non_java_keywords = { "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto", "bitand", "bitor", "bool", "char8_t", "char16_t", "char32_t", @@ -3902,7 +3962,7 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const QCString &className,co if (s.isEmpty()) return; - printlex(yy_flex_debug, TRUE, __FILE__, fd ? qPrint(fd->fileName()): NULL); + printlex(yy_flex_debug, TRUE, __FILE__, fd ? qPrint(fd->fileName()): !exName.isEmpty() ? qPrint(exName) : NULL); yyextra->code = &od; yyextra->inputString = s.data(); @@ -3951,7 +4011,7 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const QCString &className,co { setCurrentDoc(yyscanner,"l00001"); } - yyextra->currentDefinition = getResolvedNamespace(className); + yyextra->currentDefinition = searchCtx ? searchCtx : getResolvedNamespace(className); yyextra->currentMemberDef = 0; yyextra->searchingForBody = exBlock; yyextra->insideBody = FALSE; diff --git a/src/commentcnv.l b/src/commentcnv.l index ad9b302..ae4c7d3 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -838,6 +838,8 @@ SLASHopt [/]* copyToOutput(yyscanner,yytext,(int)yyleng); yyextra->inSpecialComment=FALSE; yyextra->inRoseComment=FALSE; + yyextra->readLineCtx = Scan; // reset, otherwise there will be problems with: + // static void handleCondSectionId BEGIN(Scan); } <ReadLine>{CCS}"*" { @@ -1009,7 +1011,7 @@ static void replaceCommentMarker(yyscan_t yyscanner,const char *s,int len) static inline int computeIndent(const char *s) { int col=0; - static int tabSize=Config_getInt(TAB_SIZE); + int tabSize=Config_getInt(TAB_SIZE); const char *p=s; char c; while ((c=*p++)) diff --git a/src/commentscan.l b/src/commentscan.l index 1974732..67756a4 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -418,6 +418,9 @@ struct commentscanYY_state bool markdownSupport = TRUE; QCString raiseWarning; + + QCString htmlAnchorStr; + bool htmlAnchor = false; }; @@ -466,14 +469,14 @@ static inline const char *getLexerFILE() {return __FILE__;} %} /* start command character */ -CMD ("\\"|"@") +CMD ("\\"|"@") XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem") PRE [pP][rR][eE] -TABLE [tT][aA][bB][lL][eE] -P [pP] +TABLE [tT][aA][bB][lL][eE] +P [pP] UL [uU][lL] -OL [oO][lL] -DL [dD][lL] +OL [oO][lL] +DL [dD][lL] IMG [iI][mM][gG] HR [hH][rR] PARA [pP][aA][rR][aA] @@ -486,6 +489,8 @@ DETAILEDHTML {CENTER}|{DIV}|{PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR DETAILEDHTMLOPT {CODE} SUMMARY [sS][uU][mM][mM][aA][rR][yY] REMARKS [rR][eE][mM][aA][rR][kK][sS] +AHTML [aA]{BN}* +ANCHTML ([iI][dD]|[nN][aA][mM][eE])"="("\""{LABELID}"\""|"'"{LABELID}"'"|{LABELID}) BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] @@ -494,9 +499,9 @@ BS ^(({B}*"/""/")?)(({B}*"*"+)?){B}* ATTR ({B}+[^>\n]*)? DOCNL "\n"|"\\ilinebr" LC "\\"{B}*"\n" -NW [^a-z_A-Z0-9] -FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+@&#] -FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+@&#] +NW [^a-z_A-Z0-9] +FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=@&#] +FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=@&#] FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]*"\"") ID [$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]* LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]* @@ -564,6 +569,7 @@ STopt [^\n@\\]* %x ReadFormulaLong %x AnchorLabel %x HtmlComment +%x HtmlA %x SkipLang %x CiteLabel %x CopyDoc @@ -628,6 +634,65 @@ STopt [^\n@\\]* if (yyextra->HTMLDetails) yyextra->HTMLDetails--; addOutput(yyscanner,yytext); } +<Comment>"<"{AHTML} { // potential start of HTML anchor, see issue 9200 + yyextra->htmlAnchorStr = yytext; + yyextra->htmlAnchor = false; + BEGIN(HtmlA); + } +<HtmlA>{ANCHTML} { // only labels that can be converted to doxygen anchor + yyextra->htmlAnchorStr += yytext; + QCString tag(yytext); + int s=tag.find("="); + char c=tag[s+1]; + QCString id; + if (c=='\'' || c=='"') // valid start + { + int e=tag.find(c,s+2); + if (e!=-1) // found matching end + { + id=tag.mid(s+2,e-s-2); // extract id + addAnchor(yyscanner,id); + } + } + else + { + id=tag.mid(s+1); + addAnchor(yyscanner,id); + } + if (!id.isEmpty() && !yyextra->htmlAnchor) + { + // only use first analogous to what is in docparser + addOutput(yyscanner,"@anchor "); + addOutput(yyscanner,id.data()); + addOutput(yyscanner," "); + yyextra->htmlAnchor = true; + } + } +<HtmlA>("\""[^\n\"]*"\""|"'"[^\n']*"'") { + yyextra->htmlAnchorStr += yytext; + } +<HtmlA>">"|"/>" { + if (!yyextra->htmlAnchor) + { + addOutput(yyscanner,yyextra->htmlAnchorStr); + addOutput(yyscanner,yytext); + } + else + { + if (yyleng == 1) // to keep <a></a> pairs, otherwise single </a> present + { + addOutput(yyscanner,"<a>"); + } + } + BEGIN(Comment); + } +<HtmlA>{DOCNL} { // newline + yyextra->htmlAnchorStr += yytext; + if (*yytext == '\n') yyextra->lineNr++; + } +<HtmlA>. { // catch-all for anything else + yyextra->htmlAnchorStr += yytext; + } <Comment>"<"{SUMMARY}">" { // start of a .NET XML style brief description if (!yyextra->HTMLDetails) setOutput(yyscanner,OutputBrief); addOutput(yyscanner,yytext); @@ -764,8 +829,13 @@ STopt [^\n@\\]* <Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command QCString langId = QCString(yytext).stripWhiteSpace().mid(2); if (!langId.isEmpty() && - qstricmp(Config_getEnumAsString(OUTPUT_LANGUAGE).data(),langId.data())!=0) + qstricmp(Config_getEnumAsString(OUTPUT_LANGUAGE),langId)!=0) { // enable language specific section + if (!Config_isAvailableEnum(OUTPUT_LANGUAGE,langId)) + { + warn(yyextra->fileName,yyextra->lineNr, + "non supported language '%s' specified in '%s'",langId.data(),QCString(yytext).stripWhiteSpace().data()); + } BEGIN(SkipLang); } } @@ -1480,6 +1550,10 @@ STopt [^\n@\\]* addOutput(yyscanner,'\n'); BEGIN( Comment ); } +<SubpageLabel>. { + unput(yytext[0]); + BEGIN( Comment ); + } <SubpageTitle>{DOCNL} { // no title, end command addOutput(yyscanner,yytext); BEGIN( Comment ); @@ -1935,8 +2009,13 @@ STopt [^\n@\\]* <SkipLang>[\\@]"~"[a-zA-Z-]* { /* language switch */ QCString langId(&yytext[2]); - if (langId.isEmpty() || - qstricmp(Config_getEnumAsString(OUTPUT_LANGUAGE).data(),langId.data())==0) + if (!langId.isEmpty() && !Config_isAvailableEnum(OUTPUT_LANGUAGE,langId)) + { + warn(yyextra->fileName,yyextra->lineNr, + "non supported language '%s' specified in '%s'",langId.data(),QCString(yytext).stripWhiteSpace().data()); + } + else if (langId.isEmpty() || + qstricmp(Config_getEnumAsString(OUTPUT_LANGUAGE),langId)==0) { // enable language specific section BEGIN(Comment); } @@ -2015,9 +2094,9 @@ STopt [^\n@\\]* } /* -<*>. { fprintf(stderr,"Lex scanner %s %sdefault rule for state %s: #%s#\n", __FILE__,yyextra->fileName ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START),yytext);} -<*>\n { fprintf(stderr,"Lex scanner %s %sdefault rule newline for state %s.\n", __FILE__, yyextra->fileName ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START));} - */ +<*>. { fprintf(stderr,"Lex scanner %s %sdefault rule for state %s: #%s#\n", __FILE__,!yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START),yytext);} +<*>\n { fprintf(stderr,"Lex scanner %s %sdefault rule newline for state %s.\n", __FILE__, !yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START));} + */ %% @@ -3097,8 +3176,7 @@ static QCString addFormula(yyscan_t yyscanner) std::unique_lock<std::mutex> lock(g_formulaMutex); struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; QCString formLabel; - QCString fText=yyextra->formulaText.simplifyWhiteSpace(); - int id = FormulaManager::instance().addFormula(fText.str()); + int id = FormulaManager::instance().addFormula(yyextra->formulaText.str()); formLabel.sprintf("\\_form#%d",id); for (int i=0;i<yyextra->formulaNewLines;i++) formLabel+="@_fakenl"; // add fake newlines to // keep the warnings diff --git a/src/conceptdef.cpp b/src/conceptdef.cpp index 977f569..038903b 100644 --- a/src/conceptdef.cpp +++ b/src/conceptdef.cpp @@ -299,19 +299,19 @@ void ConceptDefImpl::writeBriefDescription(OutputList &ol) const { if (hasBriefDescription()) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc( + auto parser { createDocParser() }; + auto ast { validatingParseDoc( *parser.get(),briefFile(),briefLine(),this,0, briefDescription(),TRUE,FALSE, QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + if (!ast->isEmpty()) { ol.startParagraph(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); ol.writeString(" - "); ol.popGeneratorState(); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); ol.pushGeneratorState(); ol.disable(OutputGenerator::RTF); ol.writeString(" \n"); @@ -426,7 +426,7 @@ void ConceptDefImpl::writeDefinition(OutputList &ol,const QCString &title) const void ConceptDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); if (hasDetailedDescription()) { ol.pushGeneratorState(); @@ -485,7 +485,7 @@ void ConceptDefImpl::writeAuthorSection(OutputList &ol) const void ConceptDefImpl::writeDocumentation(OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); QCString pageTitle = theTranslator->trConceptReference(displayName()); startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ConceptVisible,!generateTreeView); @@ -513,22 +513,17 @@ void ConceptDefImpl::writeDocumentation(OutputList &ol) for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Concept)) { + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); switch (lde->kind()) { case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); break; case LayoutDocEntry::ConceptDefinition: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDefinition(ol,ls->title(getLanguage())); - } + if (ls) writeDefinition(ol,ls->title(getLanguage())); break; case LayoutDocEntry::DetailedDesc: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDetailedDescription(ol,ls->title(getLanguage())); - } + if (ls) writeDetailedDescription(ol,ls->title(getLanguage())); break; case LayoutDocEntry::AuthorSection: writeAuthorSection(ol); @@ -636,15 +631,15 @@ void ConceptDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCStr // add the brief description if available if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC)) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc( + auto parser { createDocParser() }; + auto ast { validatingParseDoc( *parser.get(),briefFile(),briefLine(),this,0, briefDescription(),FALSE,FALSE, QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + if (!ast->isEmpty()) { ol.startMemberDescription(anchor()); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); ol.endMemberDescription(); } } diff --git a/src/condparser.cpp b/src/condparser.cpp index 3b260c2..0aca5b7 100644 --- a/src/condparser.cpp +++ b/src/condparser.cpp @@ -81,7 +81,7 @@ static bool isAlpha(const char c) static bool isAlphaNumSpec(const char c) { - return isAlpha(c) || (c>='0' && c<='9') || c=='-' || c=='.' || (((unsigned char)c)>=0x80); + return isAlpha(c) || (c>='0' && c<='9') || c=='-' || c=='.' || (static_cast<unsigned char>(c)>=0x80); } /** diff --git a/src/config.h b/src/config.h index 2de2173..00b3b71 100644 --- a/src/config.h +++ b/src/config.h @@ -40,9 +40,12 @@ #define Config_updateInt(name,value) (ConfigValues::instance().update_##name(value)); #define Config_updateEnum(name,value) (ConfigValues::instance().update_##name(value)); #define Config_updateList(name,...) (ConfigValues::instance().update_##name(__VA_ARGS__)); + +#define Config_isAvailableEnum(name,value) (ConfigValues::instance().isAvailable_##name(value)) //#endif //! @} +enum class DoxyfileSettings { Full, Compressed, CompressedNoEnv }; class TextStream; /** \brief Public function to deal with the configuration file. */ @@ -60,7 +63,7 @@ namespace Config /*! Writes a the differences between the current configuration and the * template configuration to stream \a t. */ - void compareDoxyfile(TextStream &t); + void compareDoxyfile(TextStream &t, DoxyfileSettings diffList); /*! Writes a the used settings of the current configuration as XML format * to stream \a t. @@ -76,10 +79,10 @@ namespace Config /*! Post processed the parsed data. Replaces raw string values by the actual values. * and replaces environment variables. * \param clearHeaderAndFooter set to TRUE when writing header and footer templates. - * \param compare signals if we in Doxyfile compare (`-x`) mode are or not. Influences - * setting of the default value. + * \param compare signals if we in Doxyfile compare (`-x` or `-x_noenv`) mode are or not. + * Influences setting of the default value and replacement of environment variables. */ - void postProcess(bool clearHeaderAndFooter, bool compare = FALSE); + void postProcess(bool clearHeaderAndFooter, DoxyfileSettings compare = DoxyfileSettings::Full); /*! Check the validity of the parsed options and correct or warn the user where needed. * \param quiet setting for the QUIET option (can have been overruled by means of a command line option) diff --git a/src/config.xml b/src/config.xml index 92de131..a10c1ac 100644 --- a/src/config.xml +++ b/src/config.xml @@ -88,6 +88,17 @@ For lists, items can also be appended using: TAG += value [value, ...] \endverbatim Values that contain spaces should be placed between quotes (\" \"). +<br> +Note:<br> +Use doxygen to compare the used configuration file with the template configuration file: +\verbatim + doxygen -x [configFile] +\endverbatim +Use doxygen to compare the used configuration file with the template configuration file +without replacing the environment variables: +\verbatim + doxygen -x_noenv [configFile] +\endverbatim ]]> </docs> </header> @@ -275,11 +286,24 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ If the \c CREATE_SUBDIRS tag is set to \c YES then doxygen will create - 4096 sub-directories (in 2 levels) under the output directory of each output + up to 4096 sub-directories (in 2 levels) under the output directory of each output format and will distribute the generated files over these directories. Enabling this option can be useful when feeding doxygen a huge amount of source files, where putting all generated files in the same directory would otherwise causes performance problems for the file system. + Adapt \c CREATE_SUBDIRS_LEVEL to control the number of sub-directories. +]]> + </docs> + </option> + <option type='int' id='CREATE_SUBDIRS_LEVEL' minval='0' maxval='8' defval='8' + depends='CREATE_SUBDIRS'> + <docs> +<![CDATA[ + Controls the number of sub-directories that will be created when \c CREATE_SUBDIRS tag + is set to \c YES. Level 0 represents 16 directories, and every level increment + doubles the number of directories, resulting in 4096 directories at level 8 which is the + default and also the maximum value. The sub-directories are organized in 2 levels, the first + level always has a fixed numer of 16 directories. ]]> </docs> </option> @@ -305,6 +329,7 @@ Go to the <a href="commands.html">next</a> section or return to the <value name='Arabic'/> <value name='Armenian'/> <value name='Brazilian'/> + <value name='Bulgarian'/> <value name='Catalan'/> <value name='Chinese'/> <value name='Chinese-Traditional'/> @@ -319,6 +344,7 @@ Go to the <a href="commands.html">next</a> section or return to the <value name='French'/> <value name='German'/> <value name='Greek'/> + <value name='Hindi'/> <value name='Hungarian'/> <value name='Indonesian'/> <value name='Italian'/> @@ -421,7 +447,7 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> - <option type='list' id='STRIP_FROM_PATH' format='string' depends='FULL_PATH_NAMES'> + <option type='list' id='STRIP_FROM_PATH' format='dir' depends='FULL_PATH_NAMES'> <docs> <![CDATA[ The \c STRIP_FROM_PATH tag @@ -436,7 +462,7 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> - <option type='list' id='STRIP_FROM_INC_PATH' format='string'> + <option type='list' id='STRIP_FROM_INC_PATH' format='dir'> <docs> <![CDATA[ The \c STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of @@ -817,7 +843,7 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='int' id='NUM_PROC_THREADS' defval='1' minval='0' maxval='32'> <docs> <![CDATA[ - The \c NUM_PROC_THREADS specifies the number threads doxygen is allowed to use during + The \c NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use during processing. When set to \c 0 doxygen will based this on the number of cores available in the system. You can set it explicitly to a value larger than 0 to get more control over the balance between CPU load and processing speed. @@ -979,7 +1005,7 @@ Go to the <a href="commands.html">next</a> section or return to the whose names only differ in casing), the option must be set to \c YES to properly deal with such files in case they appear in the input. - For filesystems that are not case sensitive the option should be be set to \c NO to properly + For filesystems that are not case sensitive the option should be set to \c NO to properly deal with output files written for symbols that only differ in casing, such as for two classes, one named \c CLASS and the other named \c Class, and to also support references to files without having to specify the exact matching casing. @@ -1371,6 +1397,25 @@ FILE_VERSION_FILTER = "cleartool desc -fmt \%Vn" Optionally the format may contain <code>$version</code>, which will be replaced by the version of the file (if it could be obtained via \ref cfg_file_version_filter "FILE_VERSION_FILTER") + + \sa \ref cfg_warn_line_format "WARN_LINE_FORMAT" +]]> + </docs> + </option> + <option type='string' id='WARN_LINE_FORMAT' format='string' defval='at line $line of file $file'> + <docs> +<![CDATA[ + In the `$text` part of the \ref cfg_warn_format "WARN_FORMAT" command it is + possible that a reference to a more specific place is given. To make it easier + to jump to this place (outside of doxygen) the user can define a custom + "cut" / "paste" string. + + Example: + \verbatim + WARN_LINE_FORMAT = "'vi $file +$line'" + \endverbatim + + \sa \ref cfg_warn_format "WARN_FORMAT" ]]> </docs> </option> @@ -1380,7 +1425,7 @@ FILE_VERSION_FILTER = "cleartool desc -fmt \%Vn" The \c WARN_LOGFILE tag can be used to specify a file to which warning and error messages should be written. If left blank the output is written to standard error (`stderr`). In case the file specified cannot be opened for - writing the warning and error messages are written to standard error. When as + writing the warning and error messages are written to standard error. When as file `-` is specified the warning and error messages are written to standard output (`stdout`). ]]> @@ -2534,7 +2579,7 @@ obfuscate email addresses. With \c MATHJAX_VERSION it is possible to specify the MathJax version to be used. Note that the different versions of MathJax have different requirements with regards to the different settings, so it is possible that also other MathJax settings have to be changed - when switching between the different MathJax versions. + when switching between the different MathJax versions. ]]> </docs> <value name="MathJax_2"/> @@ -2882,7 +2927,7 @@ doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty version of the word "Bibliography". This setting is typically used in combination with the block name `CITATIONS_PRESENT`. <dt><code>$latexbibstyle</code><dd>will be replaced with the latex bib style to be used as - as set by \ref cfg_latex_bib_style "LATEX_BIB_STYLE", in case nothing is set the bib style + set by \ref cfg_latex_bib_style "LATEX_BIB_STYLE", in case nothing is set the bib style `plain` is used. This setting is typically used in combination with the block name `CITATIONS_PRESENT`. <dt><code>$latexbibfiles</code><dd>will be replaced by the comma separated list of `bib`. files @@ -3399,6 +3444,9 @@ If set to \c NO, doxygen will warn if an a database file is already found and no The \c INCLUDE_PATH tag can be used to specify one or more directories that contain include files that are not input files but should be processed by the preprocessor. + + Note that the \c INCLUDE_PATH is not recursive, so the setting of \ref cfg_recursive "RECURSIVE" + has no effect here. ]]> </docs> </option> @@ -3596,10 +3644,10 @@ to be found in the default search path. will be shown as texts / links. ]]> </docs> - <value name="NO" /> - <value name="YES" /> - <value name="TEXT" /> - <value name="GRAPH" /> + <value name="NO" bool_representation="NO" /> + <value name="YES" bool_representation="YES" /> + <value name="TEXT" bool_representation="YES" /> + <value name="GRAPH" bool_representation="YES" /> </option> <option type='bool' id='COLLABORATION_GRAPH' defval='1' depends='HAVE_DOT'> <docs> @@ -3616,6 +3664,8 @@ to be found in the default search path. <![CDATA[ If the \c GROUP_GRAPHS tag is set to \c YES then doxygen will generate a graph for groups, showing the direct groups dependencies. + + See also the chapter \ref grouping "Grouping" in the manual. ]]> </docs> </option> @@ -3787,7 +3837,7 @@ UML notation for the relationships. ]]> </docs> </option> - <option type='string' id='DOT_PATH' format='dir' defval='' depends='HAVE_DOT'> + <option type='string' id='DOT_PATH' format='filedir' defval='' depends='HAVE_DOT'> <docs> <![CDATA[ The \c DOT_PATH tag can be used to specify the path where the \c dot tool can be found. diff --git a/src/configgen.py b/src/configgen.py index 66bebce..6a79811 100755 --- a/src/configgen.py +++ b/src/configgen.py @@ -232,6 +232,7 @@ def prepCDocs(node): docC = transformDocs(doc) return docC; + def parseOption(node): # Handling part for Doxyfile name = node.getAttribute('id') @@ -437,12 +438,25 @@ def parseGroupMapSetter(node): type = n.getAttribute('type') name = n.getAttribute('id') if type=='enum': - print(" %-22s update_%-46s { m_%s = %s(v); return v; }" % (name+'_t',name+'('+name+'_t '+' v)',name,name+'_enum2str')) + print(" [[maybe_unused]] %-22s update_%-46s { m_%s = %s(v); return v; }" % (name+'_t',name+'('+name+'_t '+' v)',name,name+'_enum2str')) elif type in map: - print(" %-22s update_%-46s { m_%s = v; return m_%s; }" % (map[type],name+'('+map[type]+' v)',name,name)) + print(" [[maybe_unused]] %-22s update_%-46s { m_%s = v; return m_%s; }" % (map[type],name+'('+map[type]+' v)',name,name)) if len(setting) > 0: print("#endif") +def parseGroupMapAvailable(node): + for n in node.childNodes: + if n.nodeType == Node.ELEMENT_NODE: + setting = n.getAttribute('setting') + type = n.getAttribute('type') + name = n.getAttribute('id') + if type=='enum': + if len(setting) > 0: + print("#if %s" % (setting)) + print(" %-22s isAvailable_%-41s { return v.lower() == %s_enum2str(%s_str2enum(v)).lower(); }" % ('bool',name+'(QCString v)',name,name)); + if len(setting) > 0: + print("#endif") + def parseGroupMapVar(node): map = { 'bool':'bool', 'string':'QCString', 'enum':'QCString', 'int':'int', 'list':'StringVector' } for n in node.childNodes: @@ -471,6 +485,19 @@ def parseGroupInit(node): if len(setting) > 0: print("#endif") +def getEnum2BoolMapping(node): + def escape(value): + return re.sub(r'[^\w]','_',value) + mapping = [] + for nv in node.childNodes: + if nv.nodeName == "value": + name = nv.getAttribute("name") + bool_rep = nv.getAttribute("bool_representation") + if name and bool_rep: + bool_value = "true" if bool_rep and bool_rep.upper() == 'YES' else "false" + mapping.append( "{{ \"{0}\", \"{1}\" }}".format(escape(name),bool_value)) + return mapping + def parseGroupMapInit(node): map = { 'bool':'Bool', 'string':'String', 'enum':'String', 'int':'Int', 'list':'List' } for n in node.childNodes: @@ -481,7 +508,11 @@ def parseGroupMapInit(node): type = n.getAttribute('type') name = n.getAttribute('id') if type in map: - print(" { %-25s Info{ %-13s &ConfigValues::m_%s }}," % ('\"'+name+'\",','Info::'+map[type]+',',name)) + if type == "enum": + mappingStr = "{%s}" % (', '.join(getEnum2BoolMapping(n))) + print(" { %-26s Info{ %-13s &ConfigValues::m_%-23s %s}}," % ('\"'+name+'\",','Info::'+map[type]+',',name+",", mappingStr)) + else: + print(" { %-26s Info{ %-13s &ConfigValues::m_%-24s}}," % ('\"'+name+'\",','Info::'+map[type]+',',name)) if len(setting) > 0: print("#endif") @@ -759,14 +790,19 @@ def main(): if n.nodeType == Node.ELEMENT_NODE: if n.nodeName == "group": parseGroupMapSetter(n) + for n in elem.childNodes: + if n.nodeType == Node.ELEMENT_NODE: + if n.nodeName == "group": + parseGroupMapAvailable(n) print(" void init();") print(" StringVector fields() const;") print(" struct Info") print(" {") print(" enum Type { Bool, Int, String, List, Unknown };") + print(" using Enum2BoolMap = std::unordered_map<std::string,bool>;"); print(" Info(Type t,bool ConfigValues::*b) : type(t), value(b) {}") print(" Info(Type t,int ConfigValues::*i) : type(t), value(i) {}") - print(" Info(Type t,QCString ConfigValues::*s) : type(t), value(s) {}") + print(" Info(Type t,QCString ConfigValues::*s, Enum2BoolMap boolMap = {}) : type(t), value(s), m_boolMap(boolMap) {}") print(" Info(Type t,StringVector ConfigValues::*l) : type(t), value(l) {}") print(" Type type;") print(" union Item") @@ -780,8 +816,12 @@ def main(): print(" QCString ConfigValues::*s;") print(" StringVector ConfigValues::*l;") print(" } value;") + print(" bool getBooleanRepresentation() const;") + print(" private:") + print(" Enum2BoolMap m_boolMap;") print(" };") print(" const Info *get(const QCString &tag) const;") + print("") print(" private:") for n in elem.childNodes: if n.nodeType == Node.ELEMENT_NODE: @@ -843,6 +883,20 @@ def main(): print("") print(" };") print("}") + print("") + print("bool ConfigValues::Info::getBooleanRepresentation() const") + print("{") + print(" if (!m_boolMap.empty())") + print(" {") + print(" auto it = m_boolMap.find((ConfigValues::instance().*(value.s)).str());") + print(" if (it!=m_boolMap.end())") + print(" {") + print(" return it->second;"); + print(" }") + print(" }") + print(" return false;") + print("}") + print("") elif (sys.argv[1] == "-cpp"): print("/* WARNING: This file is generated!") print(" * Do not edit this file, but edit config.xml instead and run") diff --git a/src/configimpl.h b/src/configimpl.h index 4906391..9e737a7 100644 --- a/src/configimpl.h +++ b/src/configimpl.h @@ -116,7 +116,7 @@ class ConfigInfo : public ConfigOption void substEnvVars() {} }; -/** Class respresenting a list type option. +/** Class representing a list type option. */ class ConfigList : public ConfigOption { diff --git a/src/configimpl.l b/src/configimpl.l index f3ce092..9975cd0 100644 --- a/src/configimpl.l +++ b/src/configimpl.l @@ -36,7 +36,6 @@ #include "version.h" #include "portable.h" #include "message.h" -#include "lang_cfg.h" #include "language.h" #include "configoptions.h" #include "fileinfo.h" @@ -281,7 +280,7 @@ QCString &ConfigImpl::getString(const char *fileName,int num,const char *name) c { config_term("%s<%d>: Internal error: Requested option %s not of string type!\n",fileName,num,name); } - return *((ConfigString *)it->second)->valueRef(); + return *(dynamic_cast<ConfigString *>(it->second))->valueRef(); } StringVector &ConfigImpl::getList(const char *fileName,int num,const char *name) const @@ -295,7 +294,7 @@ StringVector &ConfigImpl::getList(const char *fileName,int num,const char *name) { config_term("%s<%d>: Internal error: Requested option %s not of list type!\n",fileName,num,name); } - return *((ConfigList *)it->second)->valueRef(); + return *(dynamic_cast<ConfigList *>(it->second))->valueRef(); } QCString &ConfigImpl::getEnum(const char *fileName,int num,const char *name) const @@ -309,7 +308,7 @@ QCString &ConfigImpl::getEnum(const char *fileName,int num,const char *name) con { config_term("%s<%d>: Internal error: Requested option %s not of enum type!\n",fileName,num,name); } - return *((ConfigEnum *)it->second)->valueRef(); + return *(dynamic_cast<ConfigEnum *>(it->second))->valueRef(); } int &ConfigImpl::getInt(const char *fileName,int num,const char *name) const @@ -323,7 +322,7 @@ int &ConfigImpl::getInt(const char *fileName,int num,const char *name) const { config_term("%s<%d>: Internal error: Requested option %s not of integer type!\n",fileName,num,name); } - return *((ConfigInt *)it->second)->valueRef(); + return *(dynamic_cast<ConfigInt *>(it->second))->valueRef(); } bool &ConfigImpl::getBool(const char *fileName,int num,const char *name) const @@ -337,7 +336,7 @@ bool &ConfigImpl::getBool(const char *fileName,int num,const char *name) const { config_term("%s<%d>: Internal error: Requested option %s not of boolean type!\n",fileName,num,name); } - return *((ConfigBool *)it->second)->valueRef(); + return *(dynamic_cast<ConfigBool *>(it->second))->valueRef(); } /* ------------------------------------------ */ @@ -637,7 +636,7 @@ static yy_size_t yyread(char *buf,yy_size_t max_size) else { //assert(g_includeStack.current()->newState==YY_CURRENT_BUFFER); - return (yy_size_t)fread(buf,1,max_size,g_includeStack.back()->filePtr); + return static_cast<yy_size_t>(fread(buf,1,max_size,g_includeStack.back()->filePtr)); } } @@ -648,22 +647,22 @@ static QCString configStringRecode( const QCString &outputEncoding) { if (inputEncoding.isEmpty() || outputEncoding.isEmpty() || inputEncoding==outputEncoding) return str; - int inputSize=str.length(); - int outputSize=inputSize*4+1; + size_t inputSize=str.length(); + size_t outputSize=inputSize*4+1; QCString output(outputSize); void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data()); - if (cd==(void *)(-1)) + if (cd==reinterpret_cast<void *>(-1)) { config_term("Error: unsupported character conversion: '%s'->'%s'\n", qPrint(inputEncoding),qPrint(outputEncoding)); } - size_t iLeft=(size_t)inputSize; - size_t oLeft=(size_t)outputSize; + size_t iLeft=inputSize; + size_t oLeft=outputSize; const char *inputPtr = str.data(); char *outputPtr = output.rawData(); if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft)) { - outputSize-=(int)oLeft; + outputSize-=oLeft; output.resize(outputSize+1); output.at(outputSize)='\0'; //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf)); @@ -679,7 +678,7 @@ static QCString configStringRecode( static void checkEncoding() { - ConfigString *option = (ConfigString*)g_config->get("DOXYFILE_ENCODING"); + ConfigString *option = dynamic_cast<ConfigString*>(g_config->get("DOXYFILE_ENCODING")); g_encoding = *option->valueRef(); } @@ -989,28 +988,28 @@ static void readIncludeFile(const QCString &incName) BEGIN(SkipInvalid); break; case ConfigOption::O_List: - g_list = ((ConfigList *)option)->valueRef(); + g_list = dynamic_cast<ConfigList *>(option)->valueRef(); g_list->clear(); g_listStr=""; BEGIN(GetStrList); break; case ConfigOption::O_Enum: - g_string = ((ConfigEnum *)option)->valueRef(); + g_string = dynamic_cast<ConfigEnum *>(option)->valueRef(); g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_String: - g_string = ((ConfigString *)option)->valueRef(); + g_string = dynamic_cast<ConfigString *>(option)->valueRef(); g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_Int: - g_string = ((ConfigInt *)option)->valueStringRef(); + g_string = dynamic_cast<ConfigInt *>(option)->valueStringRef(); g_string->resize(0); BEGIN(GetString); break; case ConfigOption::O_Bool: - g_string = ((ConfigBool *)option)->valueStringRef(); + g_string = dynamic_cast<ConfigBool *>(option)->valueStringRef(); g_string->resize(0); BEGIN(GetString); break; @@ -1026,17 +1025,17 @@ static void readIncludeFile(const QCString &incName) " To avoid this warning please remove this line from your configuration " "file or upgrade it using \"doxygen -u\"\n", qPrint(g_cmd),g_yyLineNr,qPrint(g_yyFileName)); } - ((ConfigObsolete*)option)->markAsPresent(); - if (((ConfigObsolete*)option)->orgType()==ConfigOption::O_List) + dynamic_cast<ConfigObsolete*>(option)->markAsPresent(); + if (dynamic_cast<ConfigObsolete*>(option)->orgType()==ConfigOption::O_List) { - g_list = ((ConfigObsolete*)option)->valueListRef(); + g_list = dynamic_cast<ConfigObsolete*>(option)->valueListRef(); g_list->clear(); g_listStr=""; BEGIN(GetStrList); } else { - g_string = ((ConfigObsolete*)option)->valueStringRef(); + g_string = dynamic_cast<ConfigObsolete*>(option)->valueStringRef(); g_string->resize(0); BEGIN(GetString); } @@ -1077,7 +1076,7 @@ static void readIncludeFile(const QCString &incName) BEGIN(SkipInvalid); break; case ConfigOption::O_List: - g_list = ((ConfigList *)option)->valueRef(); + g_list = dynamic_cast<ConfigList *>(option)->valueRef(); g_listStr=""; BEGIN(GetStrList); break; @@ -1093,9 +1092,9 @@ static void readIncludeFile(const QCString &incName) config_warn("Tag '%s' at line %d of file %s has become obsolete.\n" "To avoid this warning please update your configuration " "file using \"doxygen -u\"\n", qPrint(g_cmd),g_yyLineNr,qPrint(g_yyFileName)); - if (((ConfigObsolete*)option)->orgType()==ConfigOption::O_List) + if (dynamic_cast<ConfigObsolete*>(option)->orgType()==ConfigOption::O_List) { - g_list = ((ConfigObsolete*)option)->valueListRef(); + g_list = dynamic_cast<ConfigObsolete*>(option)->valueListRef(); g_listStr=""; BEGIN(GetStrList); } @@ -1809,6 +1808,13 @@ void Config::checkAndCorrect(bool quiet, const bool check) checkList(Config_getList(EXTRA_SEARCH_MAPPINGS),"EXTRA_SEARCH_MAPPING",TRUE,TRUE); } + int numThreads = Config_getInt(NUM_PROC_THREADS); + if (numThreads==0) + { + numThreads = static_cast<int>(std::thread::hardware_concurrency()); + Config_updateInt(NUM_PROC_THREADS,numThreads); + } + //------------------------ // check for settings that are inconsistent with having GENERATE_HTMLHELP enabled @@ -1817,6 +1823,8 @@ void Config::checkAndCorrect(bool quiet, const bool check) const char *depOption = "GENERATE_HTMLHELP"; adjustBoolSetting( depOption, "GENERATE_TREEVIEW", false ); adjustBoolSetting( depOption, "SEARCHENGINE", false ); + adjustBoolSetting( depOption, "HTML_DYNAMIC_MENUS", false ); + adjustBoolSetting( depOption, "HTML_DYNAMIC_SECTIONS",false ); adjustStringSetting(depOption, "HTML_FILE_EXTENSION", ".html"); } @@ -1851,37 +1859,6 @@ void Config::checkAndCorrect(bool quiet, const bool check) Config_updateInt(DOT_NUM_THREADS,dotNumThreads); //------------------------ - // check dot path - QCString dotPath = Config_getString(DOT_PATH); - if (!dotPath.isEmpty()) - { - FileInfo fi(dotPath.str()); - if (fi.exists() && fi.isFile()) // user specified path + exec - { - dotPath=fi.dirPath(TRUE)+"/"; - } - else - { - QCString dotExe = dotPath+"/dot"+Portable::commandExtension(); - FileInfo dp(dotExe.str()); - if (!dp.exists() || !dp.isFile()) - { - warn_uncond("the dot tool could not be found at %s\n",qPrint(dotPath)); - dotPath=""; - } - else - { - dotPath=dp.dirPath(TRUE)+"/"; - } - } -#if defined(_WIN32) // convert slashes - uint i=0,l=dotPath.length(); - for (i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\'; -#endif - Config_updateString(DOT_PATH,dotPath); - } - - //------------------------ // check plantuml path QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); if (!plantumlJarPath.isEmpty()) @@ -2093,9 +2070,9 @@ void Config::writeTemplate(TextStream &t,bool shortList,bool update) ConfigImpl::instance()->writeTemplate(t,shortList,update); } -void Config::compareDoxyfile(TextStream &t) +void Config::compareDoxyfile(TextStream &t,DoxyfileSettings diffList) { - postProcess(FALSE, TRUE); + postProcess(FALSE, diffList); ConfigImpl::instance()->compareDoxyfile(t); } @@ -2111,16 +2088,16 @@ bool Config::parse(const QCString &fileName,bool update) // Internally we use the default format UTF-8 and // when updating etc. the output is in this format as well and not in the read format - ConfigString *option = (ConfigString*)g_config->get("DOXYFILE_ENCODING"); + ConfigString *option = dynamic_cast<ConfigString*>(g_config->get("DOXYFILE_ENCODING")); option->init(); return parseRes; } -void Config::postProcess(bool clearHeaderAndFooter, bool compare) +void Config::postProcess(bool clearHeaderAndFooter, DoxyfileSettings diffList) { - ConfigImpl::instance()->substituteEnvironmentVars(); - if (!compare)ConfigImpl::instance()->emptyValueToDefault(); + if (diffList != DoxyfileSettings::CompressedNoEnv) ConfigImpl::instance()->substituteEnvironmentVars(); + if (diffList == DoxyfileSettings::Full)ConfigImpl::instance()->emptyValueToDefault(); ConfigImpl::instance()->convertStrToVal(); // avoid bootstrapping issues when the g_config file already diff --git a/src/constexp.l b/src/constexp.l index 7382528..a3e0d1b 100644 --- a/src/constexp.l +++ b/src/constexp.l @@ -112,7 +112,7 @@ CONSTSUFFIX ([uU][lL]?[lL]?)|([lL][lL]?[uU]?) static yy_size_t yyread(char *buf,yy_size_t max_size,yyscan_t yyscanner) { - struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t *yyg = static_cast<struct yyguts_t*>(yyscanner); yy_size_t c=0; while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) { @@ -162,7 +162,7 @@ bool ConstExpressionParser::parse(const char *fileName,int lineNr,const std::str //printf("Result: %ld\n",(long)g_resultValue); printlex(yy_flex_debug, false, __FILE__, fileName); - bool result = (long)yyextra->resultValue!=0; + bool result = static_cast<long>(yyextra->resultValue)!=0; return result; } diff --git a/src/context.cpp b/src/context.cpp index 6274ce6..34c351e 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -97,7 +97,7 @@ class CachedItem */ T &get(const TOwner *owner) const { - // create a lamda function to create the cached data + // create a lambda function to create the cached data auto creatorFunc = [this,owner]() { m_item = (owner->*creator)(); }; // use std::call_once to let one thread invoke the creator func std::call_once(m_cache_flag, creatorFunc); @@ -149,7 +149,6 @@ class GenericConstIterator : public TemplateListIntf::ConstIterator { public: GenericConstIterator(const TemplateVariantList &list) : m_list(list) {} - virtual ~GenericConstIterator() {} void toFirst() { m_index=0; @@ -199,11 +198,11 @@ class GenericNodeListContext : public TemplateListIntf } // TemplateListIntf methods - uint count() const + size_t count() const { - return static_cast<uint>(m_children.size()); + return m_children.size(); } - TemplateVariant at(uint index) const + TemplateVariant at(size_t index) const { TemplateVariant result; if (index<count()) @@ -662,7 +661,7 @@ class TranslateContext::Private { if (m_javaOpt || m_vhdlOpt) { - return theTranslator->trPackages(); + return theTranslator->trPackageList(); } else if (m_fortranOpt || m_sliceOpt) { @@ -677,7 +676,7 @@ class TranslateContext::Private { if (m_javaOpt || m_vhdlOpt) { - return theTranslator->trPackageMembers(); + return theTranslator->trPackageFunctions(); } else if (m_fortranOpt || m_sliceOpt) { @@ -706,12 +705,12 @@ class TranslateContext::Private } TemplateVariant fileMembersDescription() const { - static bool extractAll = Config_getBool(EXTRACT_ALL); + bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trFileMembersDescription(extractAll); } TemplateVariant namespaceMembersDescription() const { - static bool extractAll = Config_getBool(EXTRACT_ALL); + bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trNamespaceMemberDescription(extractAll); } TemplateVariant classHierarchyDescription() const @@ -728,8 +727,8 @@ class TranslateContext::Private } TemplateVariant classMembersDescription() const { - static bool extractAll = Config_getBool(EXTRACT_ALL); - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool extractAll = Config_getBool(EXTRACT_ALL); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); if (fortranOpt) { return theTranslator->trCompoundMembersDescriptionFortran(extractAll); @@ -913,15 +912,15 @@ class TranslateContext::Private } TemplateVariant functions() const { - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); return fortranOpt ? theTranslator->trSubprograms() : vhdlOpt ? theTranslator->trFunctionAndProc() : theTranslator->trFunctions(); } TemplateVariant variables() const { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables(); } TemplateVariant typedefs() const @@ -998,7 +997,7 @@ class TranslateContext::Private } TemplateVariant langString() const { - return HtmlHelp::getLanguageString(); + return theTranslator->getLanguageString(); } TemplateVariant code() const { @@ -1242,38 +1241,41 @@ static TemplateVariant parseDoc(const Definition *def,const QCString &file,int l const QCString &relPath,const QCString &docStr,bool isBrief) { TemplateVariant result; - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> root { validatingParseDoc( - *parser.get(),file,line,def,0,docStr,TRUE,FALSE, - QCString(),isBrief,FALSE,Config_getBool(MARKDOWN_SUPPORT)) - }; - TextStream ts; - switch (g_globals.outputFormat) + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(),file,line,def,0,docStr,TRUE,FALSE, + QCString(),isBrief,FALSE,Config_getBool(MARKDOWN_SUPPORT)) + }; + const DocNodeAST *astImpl = dynamic_cast<DocNodeAST*>(ast.get()); + if (astImpl) { - case ContextOutputFormat_Html: - { - HtmlCodeGenerator codeGen(ts,relPath); - HtmlDocVisitor visitor(ts,codeGen,def); - root->accept(&visitor); - } - break; - case ContextOutputFormat_Latex: - { - LatexCodeGenerator codeGen(ts,relPath,file); - LatexDocVisitor visitor(ts,codeGen,def->getDefFileExtension(),FALSE); - root->accept(&visitor); - } - break; - // TODO: support other generators - default: - err("context.cpp: output format not yet supported\n"); - break; + TextStream ts; + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + HtmlCodeGenerator codeGen(ts,relPath); + HtmlDocVisitor visitor(ts,codeGen,def); + std::visit(visitor,astImpl->root); + } + break; + case ContextOutputFormat_Latex: + { + LatexCodeGenerator codeGen(ts,relPath,file); + LatexDocVisitor visitor(ts,codeGen,def->getDefFileExtension(),FALSE); + std::visit(visitor,astImpl->root); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported\n"); + break; + } + bool isEmpty = astImpl->isEmpty(); + if (isEmpty) + result = ""; + else + result = TemplateVariant(ts.str().c_str(),TRUE); } - bool isEmpty = root->isEmpty(); - if (isEmpty) - result = ""; - else - result = TemplateVariant(ts.str().c_str(),TRUE); return result; } @@ -1309,7 +1311,7 @@ static TemplateVariant parseCode(const Definition *d,const QCString &scopeName,c static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) { - static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); + bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); auto intf = Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); intf->resetCodeParserState(); TextStream t; @@ -1404,7 +1406,7 @@ class DefinitionContext m_sourceDef = TemplateImmutableList::alloc( {} ); } } - virtual ~DefinitionContext() {} + virtual ~DefinitionContext() = default; protected: // Property getters @@ -1472,7 +1474,7 @@ class DefinitionContext QCString relPathAsString() const { - static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); + bool createSubdirs = Config_getBool(CREATE_SUBDIRS); return createSubdirs ? QCString("../../") : QCString(""); } virtual TemplateVariant relPath() const { return relPathAsString(); } @@ -1548,7 +1550,7 @@ class DefinitionContext } protected: - struct Cachable : public Definition::Cookie + struct Cachable { using DC = DefinitionContext<T>; CachedItem<TemplateVariant, DC, &DC::createDetails> details; @@ -1692,12 +1694,12 @@ IncludeInfoListContext::~IncludeInfoListContext() } // TemplateListIntf -uint IncludeInfoListContext::count() const +size_t IncludeInfoListContext::count() const { return p->count(); } -TemplateVariant IncludeInfoListContext::at(uint index) const +TemplateVariant IncludeInfoListContext::at(size_t index) const { return p->at(index); } @@ -1716,7 +1718,6 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> m_classDef(cd) { } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -1792,8 +1793,8 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> TemplateVariant hasInheritanceDiagram() const { bool result=FALSE; - static bool haveDot = Config_getBool(HAVE_DOT); - static auto classGraph = Config_getEnum(CLASS_GRAPH); + bool haveDot = Config_getBool(HAVE_DOT); + auto classGraph = Config_getEnum(CLASS_GRAPH); bool classGraphEnabled = classGraph==CLASS_GRAPH_t::YES || classGraph==CLASS_GRAPH_t::GRAPH; if (haveDot && classGraphEnabled) @@ -1810,8 +1811,8 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> TemplateVariant inheritanceDiagram() const { TextStream t; - static bool haveDot = Config_getBool(HAVE_DOT); - static auto classGraph = Config_getEnum(CLASS_GRAPH); + bool haveDot = Config_getBool(HAVE_DOT); + auto classGraph = Config_getEnum(CLASS_GRAPH); bool classGraphEnabled = classGraph==CLASS_GRAPH_t::YES || classGraph==CLASS_GRAPH_t::GRAPH; if (haveDot && classGraphEnabled) @@ -1898,12 +1899,12 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> } TemplateVariant hasCollaborationDiagram() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); return haveDot && !getCollaborationGraph()->isTrivial(); } TemplateVariant collaborationDiagram() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); TextStream t; if (haveDot) { @@ -2093,11 +2094,11 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> } TemplateVariant createPackageMethods() const { - return createMemberList(MemberListType_pacMethods,theTranslator->trPackageMembers()); + return createMemberList(MemberListType_pacMethods,theTranslator->trPackageFunctions()); } TemplateVariant createPackageStaticMethods() const { - return createMemberList(MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()); + return createMemberList(MemberListType_pacStaticMethods,theTranslator->trStaticPackageFunctions()); } TemplateVariant createPackageAttributes() const { @@ -2250,8 +2251,8 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> ctx->addMemberList(m_classDef,MemberListType_proAttribs,theTranslator->trProtectedAttribs()); ctx->addMemberList(m_classDef,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()); ctx->addMemberList(m_classDef,MemberListType_pacTypes,theTranslator->trPackageTypes()); - ctx->addMemberList(m_classDef,MemberListType_pacMethods,theTranslator->trPackageMembers()); - ctx->addMemberList(m_classDef,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()); + ctx->addMemberList(m_classDef,MemberListType_pacMethods,theTranslator->trPackageFunctions()); + ctx->addMemberList(m_classDef,MemberListType_pacStaticMethods,theTranslator->trStaticPackageFunctions()); ctx->addMemberList(m_classDef,MemberListType_pacAttribs,theTranslator->trPackageAttribs()); ctx->addMemberList(m_classDef,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()); ctx->addMemberList(m_classDef,MemberListType_properties,theTranslator->trProperties()); @@ -2495,7 +2496,6 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri m_namespaceDef(nd) { } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -2529,7 +2529,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri private: TemplateVariant createClasses() const { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); TemplateVariantList classList; classList.reserve(m_namespaceDef->getClasses().size()); for (const auto &cd : m_namespaceDef->getClasses()) @@ -2604,7 +2604,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri } TemplateVariant createVariables() const { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return createMemberList(MemberListType_decVarMembers, sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } @@ -2632,7 +2632,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri } TemplateVariant createDetailedVariables() const { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return createMemberList(MemberListType_docVarMembers, sliceOpt ? theTranslator->trConstantDocumentation() : theTranslator->trVariableDocumentation()); } @@ -2742,7 +2742,6 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> { if (fd==0) abort(); } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -2783,13 +2782,13 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> TemplateVariant hasIncludeGraph() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); DotInclDepGraphPtr incGraph = getIncludeGraph(); return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial()); } TemplateVariant includeGraph() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); TextStream t; if (haveDot) { @@ -2825,13 +2824,13 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> } TemplateVariant hasIncludedByGraph() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); DotInclDepGraphPtr incGraph = getIncludedByGraph(); return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial()); } TemplateVariant includedByGraph() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); TextStream t; if (haveDot) { @@ -2962,7 +2961,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> } TemplateVariant createVariables() const { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return createMemberList(MemberListType_decVarMembers, sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } @@ -3118,7 +3117,6 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> Private(const DirDef *dd) : DefinitionContext<DirContext::Private>(dd) , m_dirDef(dd) { } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -3139,8 +3137,8 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> TemplateVariant hasDirGraph() const { bool result=FALSE; - static bool haveDot = Config_getBool(HAVE_DOT); - static bool dirGraph = Config_getBool(DIRECTORY_GRAPH); + bool haveDot = Config_getBool(HAVE_DOT); + bool dirGraph = Config_getBool(DIRECTORY_GRAPH); if (haveDot && dirGraph) { DotDirDepsPtr graph = getDirDepsGraph(); @@ -3151,8 +3149,8 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> TemplateVariant dirGraph() const { TextStream t; - static bool haveDot = Config_getBool(HAVE_DOT); - static bool dirGraph = Config_getBool(DIRECTORY_GRAPH); + bool haveDot = Config_getBool(HAVE_DOT); + bool dirGraph = Config_getBool(DIRECTORY_GRAPH); if (haveDot && dirGraph) { DotDirDepsPtr graph = getDirDepsGraph(); @@ -3275,7 +3273,6 @@ class PageContext::Private : public DefinitionContext<PageContext::Private> m_isExample(isExample) { } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -3495,7 +3492,7 @@ class TextGeneratorLatex : public TextGeneratorIntf const QCString &anchor,const QCString &text ) const { - static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); if (ref.isEmpty() && pdfHyperlinks) { m_ts << "\\mbox{\\hyperlink{"; @@ -3554,8 +3551,8 @@ class TextGeneratorFactory return 0; } private: - TextGeneratorFactory() {} - virtual ~TextGeneratorFactory() {} + TextGeneratorFactory() = default; + virtual ~TextGeneratorFactory() = default; }; TemplateVariant createLinkedText(const Definition *def,const QCString &relPath,const QCString &text) @@ -3580,7 +3577,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Private(const MemberDef *md) : DefinitionContext<MemberContext::Private>(md) , m_memberDef(md) { } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -3727,7 +3723,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } TemplateVariant hasCallGraph() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); if (m_memberDef->hasCallGraph() && haveDot && (m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal())) { @@ -3785,7 +3781,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } TemplateVariant hasCallerGraph() const { - static bool haveDot = Config_getBool(HAVE_DOT); + bool haveDot = Config_getBool(HAVE_DOT); if (m_memberDef->hasCallerGraph() && haveDot && (m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal())) { @@ -4438,7 +4434,6 @@ class ConceptContext::Private : public DefinitionContext<ConceptContext::Private m_conceptDef(cd) { } - virtual ~Private() {} // TemplateStructIntf methods TemplateVariant get(const QCString &n) const { return s_inst.get(this,n); } @@ -4592,8 +4587,8 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> TemplateVariant hasGroupGraph() const { bool result=FALSE; - static bool haveDot = Config_getBool(HAVE_DOT); - static bool groupGraphs = Config_getBool(GROUP_GRAPHS); + bool haveDot = Config_getBool(HAVE_DOT); + bool groupGraphs = Config_getBool(GROUP_GRAPHS); if (haveDot && groupGraphs) { DotGroupCollaborationPtr graph = getGroupGraph(); @@ -4604,8 +4599,8 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> TemplateVariant groupGraph() const { TextStream t; - static bool haveDot = Config_getBool(HAVE_DOT); - static bool groupGraphs = Config_getBool(GROUP_GRAPHS); + bool haveDot = Config_getBool(HAVE_DOT); + bool groupGraphs = Config_getBool(GROUP_GRAPHS); if (haveDot && groupGraphs) { DotGroupCollaborationPtr graph = getGroupGraph(); @@ -4768,7 +4763,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> } TemplateVariant createVariables() const { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return createMemberList(MemberListType_decVarMembers, sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } @@ -5003,8 +4998,8 @@ class ClassListContext::Private : public GenericNodeListContext for (const auto &cd : classLinkedMap) { if (cd->getLanguage()==SrcLangExt_VHDL && - ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) + (VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKAGECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; @@ -5029,12 +5024,12 @@ ClassListContext::~ClassListContext() } // TemplateListIntf -uint ClassListContext::count() const +size_t ClassListContext::count() const { return p->count(); } -TemplateVariant ClassListContext::at(uint index) const +TemplateVariant ClassListContext::at(size_t index) const { return p->at(index); } @@ -5076,8 +5071,8 @@ class ClassIndexContext::Private for (const auto &cd : *Doxygen::classLinkedMap) { if (cd->getLanguage()==SrcLangExt_VHDL && - ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) + (VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKAGECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; @@ -5361,7 +5356,7 @@ class NestingNodeContext::Private } QCString relPathAsString() const { - static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); + bool createSubdirs = Config_getBool(CREATE_SUBDIRS); return createSubdirs ? QCString("../../") : QCString(""); } @@ -5478,11 +5473,14 @@ class NestingNodeContext::Private { if (lde->kind()==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - const MemberList *ml = toNamespaceDef(m_def)->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - m_members->addMembers(*ml,visitedClasses); + const MemberList *ml = toNamespaceDef(m_def)->getMemberList(lmd->type); + if (ml) + { + m_members->addMembers(*ml,visitedClasses); + } } } } @@ -5494,11 +5492,14 @@ class NestingNodeContext::Private { if (lde->kind()==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - const MemberList *ml = toClassDef(m_def)->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - m_members->addMembers(*ml,visitedClasses); + const MemberList *ml = toClassDef(m_def)->getMemberList(lmd->type); + if (ml) + { + m_members->addMembers(*ml,visitedClasses); + } } } } @@ -5510,11 +5511,14 @@ class NestingNodeContext::Private { if (lde->kind()==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - const MemberList *ml = toFileDef(m_def)->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - m_members->addMembers(*ml,visitedClasses); + const MemberList *ml = toFileDef(m_def)->getMemberList(lmd->type); + if (ml) + { + m_members->addMembers(*ml,visitedClasses); + } } } } @@ -5527,11 +5531,14 @@ class NestingNodeContext::Private { if (lde->kind()==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - const MemberList *ml = toGroupDef(m_def)->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - m_members->addMembers(*ml,visitedClasses); + const MemberList *ml = toGroupDef(m_def)->getMemberList(lmd->type); + if (ml) + { + m_members->addMembers(*ml,visitedClasses); + } } } } @@ -5731,8 +5738,8 @@ class NestingContext::Private : public GenericNodeListContext { if (cd->getLanguage()==SrcLangExt_VHDL) { - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKAGECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS )// no architecture { return; @@ -5893,7 +5900,7 @@ class NestingContext::Private : public GenericNodeListContext for (const auto &bcd : bcl) { const ClassDef *cd=bcd.classDef; - if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) + if (cd->getLanguage()==SrcLangExt_VHDL && VhdlDocGen::convert(cd->protection())!=VhdlDocGen::ENTITYCLASS) { continue; } @@ -5923,7 +5930,7 @@ class NestingContext::Private : public GenericNodeListContext bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { - if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) + if (VhdlDocGen::convert(cd->protection())!=VhdlDocGen::ENTITYCLASS) { continue; } @@ -5974,12 +5981,12 @@ NestingContext::~NestingContext() } // TemplateListIntf -uint NestingContext::count() const +size_t NestingContext::count() const { return p->count(); } -TemplateVariant NestingContext::at(uint index) const +TemplateVariant NestingContext::at(size_t index) const { return p->at(index); } @@ -6184,12 +6191,12 @@ ConceptListContext::~ConceptListContext() } // TemplateListIntf -uint ConceptListContext::count() const +size_t ConceptListContext::count() const { return p->count(); } -TemplateVariant ConceptListContext::at(uint index) const +TemplateVariant ConceptListContext::at(size_t index) const { return p->at(index); } @@ -6227,12 +6234,12 @@ NamespaceListContext::~NamespaceListContext() } // TemplateListIntf -uint NamespaceListContext::count() const +size_t NamespaceListContext::count() const { return p->count(); } -TemplateVariant NamespaceListContext::at(uint index) const +TemplateVariant NamespaceListContext::at(size_t index) const { return p->at(index); } @@ -6270,8 +6277,8 @@ class NamespaceTreeContext::Private TemplateVariant preferredDepth() const { return m_preferredDepth.get(this); } TemplateVariant title() const { - return Config_getBool(OPTIMIZE_OUTPUT_JAVA) ? theTranslator->trPackages() : - Config_getBool(OPTIMIZE_OUTPUT_VHDL) ? theTranslator->trPackages() : + return Config_getBool(OPTIMIZE_OUTPUT_JAVA) ? theTranslator->trPackageList() : + Config_getBool(OPTIMIZE_OUTPUT_VHDL) ? theTranslator->trPackageList() : Config_getBool(OPTIMIZE_FOR_FORTRAN) ? theTranslator->trModulesList() : Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? theTranslator->trModulesList() : theTranslator->trNamespaceList(); @@ -6360,12 +6367,12 @@ FileListContext::~FileListContext() } // TemplateListIntf -uint FileListContext::count() const +size_t FileListContext::count() const { return p->count(); } -TemplateVariant FileListContext::at(uint index) const +TemplateVariant FileListContext::at(size_t index) const { return p->at(index); } @@ -6399,12 +6406,12 @@ DirListContext::~DirListContext() } // TemplateListIntf -uint DirListContext::count() const +size_t DirListContext::count() const { return p->count(); } -TemplateVariant DirListContext::at(uint index) const +TemplateVariant DirListContext::at(size_t index) const { return p->at(index); } @@ -6443,12 +6450,12 @@ UsedFilesContext::~UsedFilesContext() } // TemplateListIntf -uint UsedFilesContext::count() const +size_t UsedFilesContext::count() const { return p->count(); } -TemplateVariant UsedFilesContext::at(uint index) const +TemplateVariant UsedFilesContext::at(size_t index) const { return p->at(index); } @@ -6650,12 +6657,12 @@ PageListContext::~PageListContext() } // TemplateListIntf -uint PageListContext::count() const +size_t PageListContext::count() const { return p->count(); } -TemplateVariant PageListContext::at(uint index) const +TemplateVariant PageListContext::at(size_t index) const { return p->at(index); } @@ -6692,12 +6699,12 @@ ExampleListContext::~ExampleListContext() } // TemplateListIntf -uint ExampleListContext::count() const +size_t ExampleListContext::count() const { return p->count(); } -TemplateVariant ExampleListContext::at(uint index) const +TemplateVariant ExampleListContext::at(size_t index) const { return p->at(index); } @@ -6735,12 +6742,12 @@ ModuleListContext::~ModuleListContext() } // TemplateListIntf -uint ModuleListContext::count() const +size_t ModuleListContext::count() const { return p->count(); } -TemplateVariant ModuleListContext::at(uint index) const +TemplateVariant ModuleListContext::at(size_t index) const { return p->at(index); } @@ -7024,7 +7031,7 @@ class NavPathElemContext::Private } QCString relPathAsString() const { - static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); + bool createSubdirs = Config_getBool(CREATE_SUBDIRS); return createSubdirs ? QCString("../../") : QCString(""); } private: @@ -7407,8 +7414,8 @@ class InheritanceGraphContext::Private TemplateVariant createGraph() const { TextStream t; - static bool haveDot = Config_getBool(HAVE_DOT); - static bool graphicalHierarchy = Config_getBool(GRAPHICAL_HIERARCHY); + bool haveDot = Config_getBool(HAVE_DOT); + bool graphicalHierarchy = Config_getBool(GRAPHICAL_HIERARCHY); if (haveDot && graphicalHierarchy) { m_hierarchy->createGraph(m_node,t, @@ -7543,12 +7550,12 @@ InheritanceListContext::~InheritanceListContext() } // TemplateListIntf -uint InheritanceListContext::count() const +size_t InheritanceListContext::count() const { return p->count(); } -TemplateVariant InheritanceListContext::at(uint index) const +TemplateVariant InheritanceListContext::at(size_t index) const { return p->at(index); } @@ -7604,12 +7611,12 @@ MemberListContext::~MemberListContext() } // TemplateListIntf -uint MemberListContext::count() const +size_t MemberListContext::count() const { return p->count(); } -TemplateVariant MemberListContext::at(uint index) const +TemplateVariant MemberListContext::at(size_t index) const { return p->at(index); } @@ -7714,7 +7721,7 @@ class AllMembersListContext::Private : public GenericNodeListContext public: Private(const MemberNameInfoLinkedMap &ml) { - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); for (auto &mni : ml) { for (auto &mi : *mni) @@ -7746,12 +7753,12 @@ AllMembersListContext::~AllMembersListContext() } // TemplateListIntf -uint AllMembersListContext::count() const +size_t AllMembersListContext::count() const { return p->count(); } -TemplateVariant AllMembersListContext::at(uint index) const +TemplateVariant AllMembersListContext::at(size_t index) const { return p->at(index); } @@ -7778,7 +7785,6 @@ class MemberGroupInfoContext::Private TemplateVariant members() const { return m_members.get(this); } TemplateVariant groupTitle() const { return m_memberGroup->header(); } TemplateVariant groupSubtitle() const { return ""; } - TemplateVariant groupAnchor() const { return m_memberGroup->anchor(); } TemplateVariant memberGroups() const { return m_memberGroups.get(this); } TemplateVariant docs() const { return m_docs.get(this); } TemplateVariant inherited() const { return FALSE; } @@ -7815,7 +7821,6 @@ const PropertyMap<MemberGroupInfoContext::Private> MemberGroupInfoContext::Priva { "members", &Private::members }, { "title", &Private::groupTitle }, { "subtitle", &Private::groupSubtitle }, - { "anchor", &Private::groupAnchor }, { "memberGroups", &Private::memberGroups }, { "docs", &Private::docs }, { "inherited", &Private::inherited } @@ -7881,12 +7886,12 @@ MemberGroupListContext::~MemberGroupListContext() } // TemplateListIntf -uint MemberGroupListContext::count() const +size_t MemberGroupListContext::count() const { return p->count(); } -TemplateVariant MemberGroupListContext::at(uint index) const +TemplateVariant MemberGroupListContext::at(size_t index) const { return p->at(index); } @@ -8115,16 +8120,16 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext MemberListType lt1,int lt2,const QCString &title,bool additionalList) { int count = cd->countMembersIncludingGrouped(lt1,inheritedFrom,additionalList); - if (lt2!=-1) count += cd->countMembersIncludingGrouped((MemberListType)lt2,inheritedFrom,additionalList); + if (lt2!=-1) count += cd->countMembersIncludingGrouped(static_cast<MemberListType>(lt2),inheritedFrom,additionalList); if (count>0) { const MemberList *ml = cd->getMemberList(lt1); - const MemberList *ml2 = lt2!=-1 ? cd->getMemberList((MemberListType)lt2) : 0; + const MemberList *ml2 = lt2!=-1 ? cd->getMemberList(static_cast<MemberListType>(lt2)) : 0; std::unique_ptr<MemberList> combinedList = std::make_unique<MemberList>(lt,MemberListContainer::Class); addMemberListIncludingGrouped(inheritedFrom,ml,combinedList.get()); addMemberListIncludingGrouped(inheritedFrom,ml2,combinedList.get()); addMemberGroupsOfClass(inheritedFrom,cd,lt,combinedList.get()); - if (lt2!=-1) addMemberGroupsOfClass(inheritedFrom,cd,(MemberListType)lt2,combinedList.get()); + if (lt2!=-1) addMemberGroupsOfClass(inheritedFrom,cd,static_cast<MemberListType>(lt2),combinedList.get()); append(InheritedMemberInfoContext::alloc(cd,std::move(combinedList),title)); } } @@ -8149,9 +8154,9 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext if (lt1!=-1) { // add member info for members of cd with list type lt - addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList); + addInheritedMembers(inheritedFrom,icd,lt,static_cast<MemberListType>(lt1),lt2,title,additionalList); // recurse down the inheritance tree - findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses); + findInheritedMembers(inheritedFrom,icd,static_cast<MemberListType>(lt1),lt2,title,additionalList,visitedClasses); } } } @@ -8182,12 +8187,12 @@ InheritedMemberInfoListContext::~InheritedMemberInfoListContext() } // TemplateListIntf -uint InheritedMemberInfoListContext::count() const +size_t InheritedMemberInfoListContext::count() const { return p->count(); } -TemplateVariant InheritedMemberInfoListContext::at(uint index) const +TemplateVariant InheritedMemberInfoListContext::at(size_t index) const { return p->at(index); } @@ -8220,7 +8225,7 @@ class ArgumentContext::Private TemplateVariant namePart() const { QCString result = m_argument.attrib; - uint l = result.length(); + size_t l = result.length(); if (l>2 && result.at(0)=='[' && result.at(l-1)==']') { result = result.mid(1,l-2); @@ -8315,12 +8320,12 @@ ArgumentListContext::~ArgumentListContext() } // TemplateListIntf -uint ArgumentListContext::count() const +size_t ArgumentListContext::count() const { return p->count(); } -TemplateVariant ArgumentListContext::at(uint index) const +TemplateVariant ArgumentListContext::at(size_t index) const { return p->at(index); } @@ -8520,12 +8525,12 @@ SymbolListContext::~SymbolListContext() } // TemplateListIntf -uint SymbolListContext::count() const +size_t SymbolListContext::count() const { return p->count(); } -TemplateVariant SymbolListContext::at(uint index) const +TemplateVariant SymbolListContext::at(size_t index) const { return p->at(index); } @@ -8635,12 +8640,12 @@ SymbolGroupListContext::~SymbolGroupListContext() } // TemplateListIntf -uint SymbolGroupListContext::count() const +size_t SymbolGroupListContext::count() const { return p->count(); } -TemplateVariant SymbolGroupListContext::at(uint index) const +TemplateVariant SymbolGroupListContext::at(size_t index) const { return p->at(index); } @@ -8732,12 +8737,12 @@ SymbolIndicesContext::~SymbolIndicesContext() } // TemplateListIntf -uint SymbolIndicesContext::count() const +size_t SymbolIndicesContext::count() const { return p->count(); } -TemplateVariant SymbolIndicesContext::at(uint index) const +TemplateVariant SymbolIndicesContext::at(size_t index) const { return p->at(index); } @@ -8827,12 +8832,12 @@ SearchIndicesContext::~SearchIndicesContext() } // TemplateListIntf -uint SearchIndicesContext::count() const +size_t SearchIndicesContext::count() const { return p->count(); } -TemplateVariant SearchIndicesContext::at(uint index) const +TemplateVariant SearchIndicesContext::at(size_t index) const { return p->at(index); } diff --git a/src/context.h b/src/context.h index fa7ab97..11b5eb1 100644 --- a/src/context.h +++ b/src/context.h @@ -19,7 +19,7 @@ #include "types.h" #include "template.h" #include "classdef.h" -#include "searchindex.h" +#include "searchindex_js.h" #include "memberlist.h" #include "dotgfxhierarchytable.h" @@ -136,8 +136,8 @@ class UsedFilesContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<UsedFilesContext>(cd)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; void addFile(const FileDef *fd); @@ -179,8 +179,8 @@ class IncludeInfoListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<IncludeInfoListContext>(list,lang)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; IncludeInfoListContext(const IncludeInfoList &list,SrcLangExt lang); @@ -362,8 +362,8 @@ class ClassListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<ClassListContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; ClassListContext(); @@ -444,8 +444,8 @@ class ClassInheritanceContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<ClassInheritanceContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; ClassInheritanceContext(); @@ -531,8 +531,8 @@ class NestingContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<NestingContext>(parent,type,level)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; void addNamespaces(const NamespaceLinkedMap &nsLinkedMap,bool rootOnly,bool addClasses,bool addConcepts,ClassDefSet &visitedClasses); @@ -590,8 +590,8 @@ class ConceptListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<ConceptListContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; ConceptListContext(); @@ -611,8 +611,8 @@ class NamespaceListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<NamespaceListContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; NamespaceListContext(); @@ -652,8 +652,8 @@ class DirListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<DirListContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; DirListContext(); @@ -673,8 +673,8 @@ class FileListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<FileListContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; FileListContext(); @@ -714,8 +714,8 @@ class PageListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<PageListContext>(pages)); } // TemplateListIntf methods - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; void addPages(const PageLinkedMap &pages); @@ -777,8 +777,8 @@ class ModuleListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<ModuleListContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; void addModules(const GroupLinkedMap &); @@ -841,8 +841,8 @@ class ExampleListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<ExampleListContext>()); } // TemplateListIntf methods - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; ExampleListContext(); @@ -984,8 +984,8 @@ class InheritanceListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<InheritanceListContext>(list,baseClasses)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; InheritanceListContext(const BaseClassList &list,bool baseClasses); @@ -1009,8 +1009,8 @@ class MemberListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<MemberListContext>(ml)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; MemberListContext(); @@ -1056,8 +1056,8 @@ class MemberGroupListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<MemberGroupListContext>(def,relPath,list,subGrouping)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; MemberGroupListContext(); @@ -1145,8 +1145,8 @@ class InheritedMemberInfoListContext : public TemplateListIntf void addMemberList(const ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList=TRUE); // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; InheritedMemberInfoListContext(); @@ -1166,8 +1166,8 @@ class AllMembersListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<AllMembersListContext>(ml)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; AllMembersListContext(const MemberNameInfoLinkedMap &ml); @@ -1209,8 +1209,8 @@ class ArgumentListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<ArgumentListContext>(al,def,relPath)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; ArgumentListContext(); @@ -1252,8 +1252,8 @@ class SymbolListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<SymbolListContext>(start,end)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; SymbolListContext(const SearchIndexList::const_iterator &start, @@ -1296,8 +1296,8 @@ class SymbolGroupListContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<SymbolGroupListContext>(sil)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; SymbolGroupListContext(const SearchIndexList &sil); @@ -1338,8 +1338,8 @@ class SymbolIndicesContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<SymbolIndicesContext>(info)); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; SymbolIndicesContext(const SearchIndexInfo &info); @@ -1379,8 +1379,8 @@ class SearchIndicesContext : public TemplateListIntf { return std::static_pointer_cast<TemplateListIntf>(std::make_shared<SearchIndicesContext>()); } // TemplateListIntf - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; SearchIndicesContext(); diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp index 8cd7c5c..b3184ee 100644 --- a/src/cppvalue.cpp +++ b/src/cppvalue.cpp @@ -67,17 +67,17 @@ CPPValue parseCharacter(const std::string& token) // does not work for '\n' and { switch(token[2]) { - case 'n': return CPPValue((long)'\n'); - case 't': return CPPValue((long)'\t'); - case 'v': return CPPValue((long)'\v'); - case 'b': return CPPValue((long)'\b'); - case 'r': return CPPValue((long)'\r'); - case 'f': return CPPValue((long)'\f'); - case 'a': return CPPValue((long)'\a'); - case '\\': return CPPValue((long)'\\'); - case '?': return CPPValue((long)'\?'); - case '\'': return CPPValue((long)'\''); - case '"': return CPPValue((long)'"'); + case 'n': return CPPValue('\n'); + case 't': return CPPValue('\t'); + case 'v': return CPPValue('\v'); + case 'b': return CPPValue('\b'); + case 'r': return CPPValue('\r'); + case 'f': return CPPValue('\f'); + case 'a': return CPPValue('\a'); + case '\\': return CPPValue('\\'); + case '?': return CPPValue('\?'); + case '\'': return CPPValue('\''); + case '"': return CPPValue('"'); case '0': // fall through case '1': // fall through case '2': // fall through @@ -93,7 +93,7 @@ CPPValue parseCharacter(const std::string& token) // does not work for '\n' and return CPPValue(0L); } } - return CPPValue((long)token[1]); + return CPPValue(token[1]); } CPPValue parseFloat(const std::string& token) diff --git a/src/cppvalue.h b/src/cppvalue.h index 6cf5ff4..3872f3e 100644 --- a/src/cppvalue.h +++ b/src/cppvalue.h @@ -25,11 +25,12 @@ class CPPValue public: enum Type { Int, Float }; - CPPValue(long val=0) : type(Int) { v.l = val; } - CPPValue(double val) : type(Float) { v.d = val; } + explicit CPPValue(char c) : type(Int) { v.l = c; } + explicit CPPValue(long val=0) : type(Int) { v.l = val; } + explicit CPPValue(double val) : type(Float) { v.d = val; } - operator double () const { return type==Int ? (double)v.l : v.d; } - operator long () const { return type==Int ? v.l : (long)v.d; } + operator double () const { return type==Int ? static_cast<double>(v.l) : v.d; } + operator long () const { return type==Int ? v.l : static_cast<long>(v.d); } bool isInt() const { return type == Int; } diff --git a/src/debug.cpp b/src/debug.cpp index f972156..841bc46 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -46,7 +46,9 @@ static std::map< std::string, Debug::DebugMask > s_labels = { "plantuml", Debug::Plantuml }, { "fortranfixed2free", Debug::FortranFixed2Free }, { "cite", Debug::Cite }, - { "rtf", Debug::Rtf } + { "rtf", Debug::Rtf }, + { "qhp", Debug::Qhp }, + { "tag", Debug::Tag }, }; //------------------------------------------------------------------------ @@ -82,13 +84,13 @@ static int labelToEnumValue(const QCString &l) int Debug::setFlag(const QCString &lab) { int retVal = labelToEnumValue(lab); - curMask = (DebugMask)(curMask | retVal); + curMask = static_cast<DebugMask>(curMask | retVal); return retVal; } void Debug::clearFlag(const QCString &lab) { - curMask = (DebugMask)(curMask & ~labelToEnumValue(lab)); + curMask = static_cast<DebugMask>(curMask & ~labelToEnumValue(lab)); } void Debug::setPriority(int p) diff --git a/src/debug.h b/src/debug.h index 7399cc6..e2f321e 100644 --- a/src/debug.h +++ b/src/debug.h @@ -41,7 +41,9 @@ class Debug FortranFixed2Free = 0x00008000, Cite = 0x00010000, NoLineNo = 0x00020000, - Rtf = 0x00040000 + Rtf = 0x00040000, + Qhp = 0x00080000, + Tag = 0x00100000, }; static void print(DebugMask mask,int prio,const char *fmt,...); diff --git a/src/definition.cpp b/src/definition.cpp index 08ed32e..cd256bf 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -352,7 +352,7 @@ void DefinitionImpl::addSectionsToIndex() if (isSection(type)) { //printf(" level=%d title=%s\n",level,qPrint(si->title)); - int nextLevel = (int)type; + int nextLevel = static_cast<int>(type); int i; if (nextLevel>level) { @@ -373,7 +373,7 @@ void DefinitionImpl::addSectionsToIndex() // determine if there is a next level inside this item auto it_next = std::next(it); bool isDir = (it_next!=m_impl->sectionRefs.end()) ? - ((int)((*it_next)->type()) > nextLevel) : FALSE; + (static_cast<int>((*it_next)->type()) > nextLevel) : FALSE; Doxygen::indexList->addContentsItem(isDir,title, getReference(), m_impl->def->getOutputFileBase(), @@ -419,7 +419,7 @@ bool DefinitionImpl::_docsAlreadyAdded(const QCString &doc,QCString &sigList) // to avoid mismatches due to differences in indenting, we first remove // double whitespaces... QCString docStr = doc.simplifyWhiteSpace(); - MD5Buffer((const unsigned char *)docStr.data(),docStr.length(),md5_sig); + MD5Buffer(docStr.data(),docStr.length(),md5_sig); MD5SigToString(md5_sig,sigStr); //printf("%s:_docsAlreadyAdded doc='%s' sig='%s' docSigs='%s'\n", // qPrint(name()),qPrint(doc),qPrint(sigStr),qPrint(sigList)); @@ -488,25 +488,24 @@ void DefinitionImpl::setDocumentation(const QCString &d,const QCString &docFile, void DefinitionImpl::_setBriefDescription(const QCString &b,const QCString &briefFile,int briefLine) { - static OUTPUT_LANGUAGE_t outputLanguage = Config_getEnum(OUTPUT_LANGUAGE); - static bool needsDot = outputLanguage!=OUTPUT_LANGUAGE_t::Japanese && - outputLanguage!=OUTPUT_LANGUAGE_t::Chinese && - outputLanguage!=OUTPUT_LANGUAGE_t::Korean; QCString brief = b; brief = brief.stripWhiteSpace(); brief = stripLeadingAndTrailingEmptyLines(brief,briefLine); brief = brief.stripWhiteSpace(); if (brief.isEmpty()) return; uint bl = brief.length(); - if (bl>0 && needsDot) // add punctuation if needed + if (bl>0) { - int c = brief.at(bl-1); - switch(c) + if (!theTranslator || theTranslator->needsPunctuation()) // add punctuation if needed { - case '.': case '!': case '?': case '>': case ':': case ')': break; - default: - if (isUTF8CharUpperCase(brief.str(),0) && !lastUTF8CharIsMultibyte(brief.str())) brief+='.'; - break; + int c = brief.at(bl-1); + switch(c) + { + case '.': case '!': case '?': case '>': case ':': case ')': break; + default: + if (isUTF8CharUpperCase(brief.str(),0) && !lastUTF8CharIsMultibyte(brief.str())) brief+='.'; + break; + } } } @@ -588,7 +587,7 @@ class FilterCache FilterCache() : m_endPos(0) { } bool getFileContents(const QCString &fileName,BufStr &str) { - static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); + bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); QCString filter = getFileFilter(fileName,TRUE); bool usePipe = !filter.isEmpty() && filterSourceFiles; FILE *f=0; @@ -600,8 +599,8 @@ class FilterCache auto item = it->second; //printf("getFileContents(%s): cache hit\n",qPrint(fileName)); // file already processed, get the results after filtering from the tmp file - Debug::print(Debug::FilterOutput,0,"Reusing filter result for %s from %s at offset=%d size=%d\n", - qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item.filePos,(int)item.fileSize); + Debug::print(Debug::FilterOutput,0,"Reusing filter result for %s from %s at offset=%lld size=%zu\n", + qPrint(fileName),qPrint(Doxygen::filterDBFileName),item.filePos,item.fileSize); f = Portable::fopen(Doxygen::filterDBFileName,"rb"); if (f) { @@ -609,7 +608,7 @@ class FilterCache str.resize(static_cast<uint>(item.fileSize+1)); if (Portable::fseek(f,item.filePos,SEEK_SET)==-1) { - err("Failed to seek to position %d in filter database file %s\n",(int)item.filePos,qPrint(Doxygen::filterDBFileName)); + err("Failed to seek to position %d in filter database file %s\n",static_cast<int>(item.filePos),qPrint(Doxygen::filterDBFileName)); success=FALSE; } if (success) @@ -617,8 +616,8 @@ class FilterCache size_t numBytes = fread(str.data(),1,item.fileSize,f); if (numBytes!=item.fileSize) { - err("Failed to read %d bytes from position %d in filter database file %s: got %d bytes\n", - (int)item.fileSize,(int)item.filePos,qPrint(Doxygen::filterDBFileName),(int)numBytes); + err("Failed to read %zu bytes from position %d in filter database file %s: got %zu bytes\n", + item.fileSize,static_cast<int>(item.filePos),qPrint(Doxygen::filterDBFileName),numBytes); success=FALSE; } } @@ -659,8 +658,8 @@ class FilterCache if (bytesRead!=bytesWritten) { // handle error - err("Failed to write to filter database %s. Wrote %d out of %d bytes\n", - qPrint(Doxygen::filterDBFileName),(int)bytesWritten,(int)bytesRead); + err("Failed to write to filter database %s. Wrote %zu out of %zu bytes\n", + qPrint(Doxygen::filterDBFileName),bytesWritten,bytesRead); str.addChar('\0'); Portable::pclose(f); fclose(bf); @@ -673,8 +672,8 @@ class FilterCache item.fileSize = size; // add location entry to the dictionary m_cache.insert(std::make_pair(fileName.str(),item)); - Debug::print(Debug::FilterOutput,0,"Storing new filter result for %s in %s at offset=%d size=%d\n", - qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item.filePos,(int)item.fileSize); + Debug::print(Debug::FilterOutput,0,"Storing new filter result for %s in %s at offset=%lld size=%zu\n", + qPrint(fileName),qPrint(Doxygen::filterDBFileName),item.filePos,item.fileSize); // update end of file position m_endPos += size; Portable::pclose(f); @@ -720,7 +719,7 @@ bool readCodeFragment(const QCString &fileName, int &startLine,int &endLine,QCString &result) { //printf("readCodeFragment(%s,startLine=%d,endLine=%d)\n",fileName,startLine,endLine); - static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); + bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); QCString filter = getFileFilter(fileName,TRUE); bool usePipe = !filter.isEmpty() && filterSourceFiles; int tabSize = Config_getInt(TAB_SIZE); @@ -766,7 +765,7 @@ bool readCodeFragment(const QCString &fileName, } else if (pc=='/' && c=='/') // skip single line comment { - while ((c=*p++)!='\n' && c!=0) pc=c; + while ((c=*p++)!='\n' && c!=0); if (c=='\n') lineNr++,col=0; } else if (pc=='/' && c=='*') // skip C style comment @@ -839,7 +838,7 @@ bool readCodeFragment(const QCString &fileName, int braceIndex = result.findRev('}'); if (braceIndex > newLineIndex) { - result.truncate((uint)braceIndex+1); + result.truncate(static_cast<size_t>(braceIndex+1)); } endLine=lineNr-1; } @@ -860,7 +859,7 @@ QCString DefinitionImpl::getSourceFileBase() const { ASSERT(m_impl->def->definitionType()!=Definition::TypeFile); // file overloads this method QCString fn; - static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + bool sourceBrowser = Config_getBool(SOURCE_BROWSER); if (sourceBrowser && m_impl->body && m_impl->body->startLine!=-1 && m_impl->body->fileDef) { @@ -914,7 +913,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const QCString &) const // write file link ol.writeObjectLink(QCString(),fn,QCString(),m_impl->body->fileDef->name()); // write text right from file marker - ol.parseText(refText.right(refText.length()-(uint)fileMarkerPos-2)); + ol.parseText(refText.right(refText.length()-static_cast<size_t>(fileMarkerPos)-2)); } else // file marker before line marker { @@ -927,7 +926,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const QCString &) const // write line link ol.writeObjectLink(QCString(),fn,anchorStr,lineStr); // write text right from linePos marker - ol.parseText(refText.right(refText.length()-(uint)lineMarkerPos-2)); + ol.parseText(refText.right(refText.length()-static_cast<size_t>(lineMarkerPos)-2)); } ol.endParagraph(); } @@ -963,7 +962,7 @@ bool DefinitionImpl::hasSources() const /*! Write code of this definition into the documentation */ void DefinitionImpl::writeInlineCode(OutputList &ol,const QCString &scopeName) const { - static bool inlineSources = Config_getBool(INLINE_SOURCES); + bool inlineSources = Config_getBool(INLINE_SOURCES); ol.pushGeneratorState(); //printf("Source Fragment %s: %d-%d bodyDef=%p\n",qPrint(name()), // m_startBodyLine,m_endBodyLine,m_bodyDef); @@ -1028,14 +1027,14 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const QCString &scopeNam const QCString &text,const std::unordered_map<std::string,const MemberDef *> &membersMap, bool /*funcOnly*/) const { - static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); - static bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE); if (!membersMap.empty()) { auto members = refMapToVector(membersMap); auto replaceFunc = [this,&members,scopeName,&ol](size_t entryIndex) { + bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE); const MemberDef *md=members[entryIndex]; if (md) { @@ -1083,7 +1082,7 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const QCString &scopeNam ol.parseText(text); ol.docify(" "); writeMarkerList(ol, - theTranslator->trWriteList((int)members.size()).str(), + theTranslator->trWriteList(static_cast<int>(members.size())).str(), members.size(), replaceFunc); ol.writeString("."); @@ -1114,8 +1113,8 @@ bool DefinitionImpl::hasSourceRefs() const bool DefinitionImpl::hasDocumentation() const { - static bool extractAll = Config_getBool(EXTRACT_ALL); - //static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + bool extractAll = Config_getBool(EXTRACT_ALL); + //bool sourceBrowser = Config_getBool(SOURCE_BROWSER); bool hasDocs = (m_impl->details && !m_impl->details->doc.isEmpty()) || // has detailed docs (m_impl->brief && !m_impl->brief->doc.isEmpty()) || // has brief description @@ -1429,7 +1428,7 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const if (isSection(type)) { //printf(" level=%d title=%s\n",level,qPrint(si->title)); - int nextLevel = (int)type; + int nextLevel = static_cast<int>(type); if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1446,7 +1445,7 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const if (l <= maxLevel) ol.writeString("</ul>\n"); } } - cs[0]=(char)('0'+nextLevel); + cs[0]=static_cast<char>('0'+nextLevel); if (nextLevel <= maxLevel && inLi[nextLevel]) { ol.writeString("</li>\n"); @@ -1494,7 +1493,7 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const if (isSection(type)) { //printf(" level=%d title=%s\n",level,qPrint(si->title)); - int nextLevel = (int)type; + int nextLevel = static_cast<int>(type); if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1849,7 +1848,7 @@ QCString DefinitionImpl::_symbolName() const bool DefinitionImpl::hasBriefDescription() const { - static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); + bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); return !briefDescription().isEmpty() && briefMemberDesc; } diff --git a/src/definition.h b/src/definition.h index ac91201..e89b4d3 100644 --- a/src/definition.h +++ b/src/definition.h @@ -76,11 +76,6 @@ struct BodyInfo class Definition { public: - struct Cookie - { - virtual ~Cookie() {} - }; - /*! Types of derived classes */ enum DefType { diff --git a/src/definitionimpl.h b/src/definitionimpl.h index a620b81..93cf8b7 100644 --- a/src/definitionimpl.h +++ b/src/definitionimpl.h @@ -147,7 +147,7 @@ class DefinitionMixin : public Base const QCString &defFileName,int defLine,int defColumn, const QCString &name,const char *b=0,const char *d=0, bool isSymbol=TRUE) : m_impl(this,defFileName,defLine,defColumn,name,b,d,isSymbol) {} - virtual ~DefinitionMixin() {} + virtual ~DefinitionMixin() = default; virtual bool isAlias() const { return FALSE; } diff --git a/src/dia.cpp b/src/dia.cpp index effc7a1..ba2c812 100644 --- a/src/dia.cpp +++ b/src/dia.cpp @@ -59,10 +59,9 @@ void writeDiaGraphFromFile(const QCString &inFile,const QCString &outDir, diaArgs+=inFile; diaArgs+="\""; - int exitCode; //printf("*** running: %s %s outDir:%s %s\n",qPrint(diaExe),qPrint(diaArgs),outDir,outFile); Portable::sysTimerStart(); - if ((exitCode=Portable::system(diaExe,diaArgs,FALSE))!=0) + if (Portable::system(diaExe,diaArgs,FALSE)!=0) { err_full(srcFile,srcLine,"Problems running %s. Check your installation or look typos in you dia file %s\n", qPrint(diaExe),qPrint(inFile)); diff --git a/src/diagram.cpp b/src/diagram.cpp index af910f4..6cfbb17 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -46,7 +46,7 @@ class DiagramItem QCString fileName() const; DiagramItem *parentItem() { return m_parent; } DiagramItemList getChildren() { return m_children; } - void move(int dx,int dy) { m_x+=(uint)dx; m_y+=(uint)dy; } + void move(int dx,int dy) { m_x=static_cast<uint>(m_x+dx); m_y=static_cast<uint>(m_y+dy); } uint xPos() const { return m_x; } uint yPos() const { return m_y; } uint avgChildPos() const; @@ -339,7 +339,7 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases cd,prot,virt,ts); DiagramItem *di_ptr = di.get(); if (parent) parent->addChild(di_ptr); - di->move((int)(m_items.size()*gridWidth),(int)(m_level*gridHeight)); + di->move(static_cast<int>(m_items.size()*gridWidth),static_cast<int>(m_level*gridHeight)); m_items.push_back(std::move(di)); int count=0; for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses()) @@ -408,7 +408,9 @@ bool TreeDiagram::layoutTree(DiagramItem *root,uint r) //printf("Moving children %d-%d in row %d\n", // dil->getFirst()->number(),row->count()-1,r+1); for (k=children.front()->number();k<row->numItems();k++) - row->item(k)->move((int)(pPos-cPos),0); + { + row->item(k)->move(static_cast<int>(pPos-cPos),0); + } moved=TRUE; } else if (pPos<cPos) // move parent @@ -417,7 +419,9 @@ bool TreeDiagram::layoutTree(DiagramItem *root,uint r) //printf("Moving parents %d-%d in row %d\n", // root->number(),row->count()-1,r); for (k=root->number();k<row->numItems();k++) - row->item(k)->move((int)(cPos-pPos),0); + { + row->item(k)->move(static_cast<int>(cPos-pPos),0); + } moved=TRUE; } @@ -521,7 +525,7 @@ void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos) for (const auto &di : *dr) // for each item in a row { if (di->isInList()) done=TRUE; - if (maxXPos) mx=std::max(mx,(uint)di->xPos()); + if (maxXPos) mx=std::max(mx,static_cast<uint>(di->xPos())); if (maxLabelLen) ml=std::max(ml,Image::stringLength(di->label())); } if (done) break; @@ -622,14 +626,14 @@ void TreeDiagram::drawBoxes(TextStream &t,Image *image, } else { - xf = di->xPos()/(float)gridWidth; + xf = di->xPos()/static_cast<float>(gridWidth); if (doBase) { - yf = di->yPos()/(float)gridHeight+superRows-1; + yf = di->yPos()/static_cast<float>(gridHeight)+superRows-1; } else { - yf = superRows-1-di->yPos()/(float)gridHeight; + yf = superRows-1-di->yPos()/static_cast<float>(gridHeight); } } } @@ -678,14 +682,14 @@ void TreeDiagram::drawBoxes(TextStream &t,Image *image, } else { - xf=di->xPos()/(float)gridWidth; + xf=di->xPos()/static_cast<float>(gridWidth); if (doBase) { - yf = di->yPos()/(float)gridHeight+superRows-1; + yf = di->yPos()/static_cast<float>(gridHeight)+superRows-1; } else { - yf = superRows-1-di->yPos()/(float)gridHeight; + yf = superRows-1-di->yPos()/static_cast<float>(gridHeight); } writeVectorBox(t,di.get(),xf,yf); } @@ -746,13 +750,13 @@ void TreeDiagram::drawConnectors(TextStream &t,Image *image, t << protToString(di->protection()) << "\n"; if (doBase) { - t << "1 " << (di->xPos()/(float)gridWidth) << " " - << (di->yPos()/(float)gridHeight+superRows-1) << " in\n"; + t << "1 " << (di->xPos()/static_cast<float>(gridWidth)) << " " + << (di->yPos()/static_cast<float>(gridHeight)+superRows-1) << " in\n"; } else { - t << "0 " << (di->xPos()/(float)gridWidth) << " " - << ((float)superRows-0.25f-di->yPos()/(float)gridHeight) + t << "0 " << (di->xPos()/static_cast<float>(gridWidth)) << " " + << (static_cast<float>(superRows)-0.25f-di->yPos()/static_cast<float>(gridHeight)) << " in\n"; } } @@ -779,15 +783,15 @@ void TreeDiagram::drawConnectors(TextStream &t,Image *image, } else { - xf = di->parentItem()->xPos()/(float)gridWidth; + xf = di->parentItem()->xPos()/static_cast<float>(gridWidth); if (doBase) { - ysf = di->yPos()/(float)gridHeight+superRows-1; + ysf = di->yPos()/static_cast<float>(gridHeight)+superRows-1; yf = ysf + 0.5f; } else { - ysf = (float)superRows-0.25f-di->yPos()/(float)gridHeight; + ysf = static_cast<float>(superRows)-0.25f-di->yPos()/static_cast<float>(gridHeight); yf = ysf - 0.25f; } } @@ -913,13 +917,13 @@ void TreeDiagram::drawConnectors(TextStream &t,Image *image, t << protToString(di->protection()) << "\n"; if (doBase) { - t << "1 " << di->xPos()/(float)gridWidth << " " - << (di->yPos()/(float)gridHeight+superRows-1) << " in\n"; + t << "1 " << di->xPos()/static_cast<float>(gridWidth) << " " + << (di->yPos()/static_cast<float>(gridHeight)+superRows-1) << " in\n"; } else { - t << "0 " << di->xPos()/(float)gridWidth << " " - << ((float)superRows-0.25f-di->yPos()/(float)gridHeight) + t << "0 " << di->xPos()/static_cast<float>(gridWidth) << " " + << (static_cast<float>(superRows)-0.25f-di->yPos()/static_cast<float>(gridHeight)) << " in\n"; } } @@ -953,13 +957,13 @@ void TreeDiagram::drawConnectors(TextStream &t,Image *image, t << protToString(p) << "\n"; if (doBase) { - t << "0 " << di->xPos()/(float)gridWidth << " " - << (di->yPos()/(float)gridHeight+superRows-1) << " out\n"; + t << "0 " << di->xPos()/static_cast<float>(gridWidth) << " " + << (di->yPos()/static_cast<float>(gridHeight)+superRows-1) << " out\n"; } else { - t << "1 " << di->xPos()/(float)gridWidth << " " - << ((float)superRows-1.75f-di->yPos()/(float)gridHeight) + t << "1 " << di->xPos()/static_cast<float>(gridWidth) << " " + << (static_cast<float>(superRows)-1.75f-di->yPos()/static_cast<float>(gridHeight)) << " out\n"; } } @@ -988,16 +992,16 @@ void TreeDiagram::drawConnectors(TextStream &t,Image *image, t << protToString(p) << "\n"; if (doBase) { - t << first->xPos()/(float)gridWidth << " " - << last->xPos()/(float)gridWidth << " " - << (first->yPos()/(float)gridHeight+superRows-1) + t << first->xPos()/static_cast<float>(gridWidth) << " " + << last->xPos()/static_cast<float>(gridWidth) << " " + << (first->yPos()/static_cast<float>(gridHeight)+superRows-1) << " conn\n"; } else { - t << first->xPos()/(float)gridWidth << " " - << last->xPos()/(float)gridWidth << " " - << ((float)superRows-first->yPos()/(float)gridHeight) + t << first->xPos()/static_cast<float>(gridWidth) << " " + << last->xPos()/static_cast<float>(gridWidth) << " " + << (static_cast<float>(superRows)-first->yPos()/static_cast<float>(gridHeight)) << " conn\n"; } } @@ -1030,13 +1034,13 @@ ClassDiagram::ClassDiagram(const ClassDef *root) : p(std::make_unique<Private>(r uint xsuper = superItem->xPos(); if (xbase>xsuper) { - superItem->move((int)(xbase-xsuper),0); - p->super.moveChildren(superItem,(int)(xbase-xsuper)); + superItem->move(static_cast<int>(xbase-xsuper),0); + p->super.moveChildren(superItem,static_cast<int>(xbase-xsuper)); } else if (xbase<xsuper) { - baseItem->move((int)(xsuper-xbase),0); - p->base.moveChildren(baseItem,(int)(xsuper-xbase)); + baseItem->move(static_cast<int>(xsuper-xbase),0); + p->base.moveChildren(baseItem,static_cast<int>(xsuper-xbase)); } } @@ -1084,7 +1088,7 @@ void ClassDiagram::writeFigure(TextStream &output,const QCString &path, //printf("writeFigure rows=%d cols=%d\n",rows,cols); - QCString epsBaseName=(QCString)path+"/"+fileName; + QCString epsBaseName=QCString(path)+"/"+fileName; QCString epsName=epsBaseName+".eps"; std::ofstream f(epsName.str(),std::ofstream::out | std::ofstream::binary); if (!f.is_open()) @@ -1106,7 +1110,7 @@ void ClassDiagram::writeFigure(TextStream &output,const QCString &path, t << "%%For: \n"; t << "%Magnification: 1.00\n"; t << "%%Orientation: Portrait\n"; - t << "%%BoundingBox: 0 0 500 " << estHeight*500.0f/(float)estWidth << "\n"; + t << "%%BoundingBox: 0 0 500 " << estHeight*500.0f/static_cast<float>(estWidth) << "\n"; t << "%%Pages: 0\n"; t << "%%BeginSetup\n"; t << "%%EndSetup\n"; @@ -1120,7 +1124,7 @@ void ClassDiagram::writeFigure(TextStream &output,const QCString &path, t << "/marginwidth 10 def\n"; t << "/distx 20 def\n"; t << "/disty 40 def\n"; - t << "/boundaspect " << estWidth/(float)estHeight << " def % aspect ratio of the BoundingBox (width/height)\n"; + t << "/boundaspect " << estWidth/static_cast<float>(estHeight) << " def % aspect ratio of the BoundingBox (width/height)\n"; t << "/boundx 500 def\n"; t << "/boundy boundx boundaspect div def\n"; t << "/xspacing 0 def\n"; @@ -1367,7 +1371,7 @@ void ClassDiagram::writeImage(TextStream &t,const QCString &path, p->super.drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight); #define IMAGE_EXT ".png" - image.save((QCString)path+"/"+fileName+IMAGE_EXT); + image.save(QCString(path)+"/"+fileName+IMAGE_EXT); Doxygen::indexList->addImageFile(QCString(fileName)+IMAGE_EXT); } diff --git a/src/dirdef.cpp b/src/dirdef.cpp index 086b41a..4efd7c9 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -183,7 +183,7 @@ static QCString encodeDirName(const QCString &anchor) // convert to md5 hash uchar md5_sig[16]; char sigStr[33]; - MD5Buffer((const unsigned char *)anchor.data(),anchor.length(),md5_sig); + MD5Buffer(anchor.data(),anchor.length(),md5_sig); MD5SigToString(md5_sig,sigStr); return sigStr; @@ -268,18 +268,18 @@ void DirDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc( + auto parser { createDocParser() }; + auto ast { validatingParseDoc( *parser.get(), briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE, QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + if (!ast->isEmpty()) { ol.startParagraph(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); ol.writeString(" - "); ol.popGeneratorState(); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); ol.pushGeneratorState(); ol.disable(OutputGenerator::RTF); ol.writeString(" \n"); @@ -464,7 +464,7 @@ QCString DirDefImpl::shortTitle() const bool DirDefImpl::hasDetailedDescription() const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty(); } @@ -507,7 +507,7 @@ void DirDefImpl::writeTagFile(TextStream &tagFile) void DirDefImpl::writeDocumentation(OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); QCString title=theTranslator->trDirReference(m_dispName); @@ -558,8 +558,11 @@ void DirDefImpl::writeDocumentation(OutputList &ol) break; case LayoutDocEntry::DetailedDesc: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDetailedDescription(ol,ls->title(lang)); + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (ls) + { + writeDetailedDescription(ol,ls->title(lang)); + } } break; case LayoutDocEntry::ClassIncludes: @@ -675,7 +678,7 @@ void DirDefImpl::addUsesDependency(const DirDef *dir,const FileDef *srcFd, //printf(" => new file\n"); auto newUsedDir = std::make_unique<UsedDir>(dir); newUsedDir->addFileDep(srcFd,dstFd, srcDirect, dstDirect); - usedDir = m_usedDirs.add(dir->getOutputFileBase(),std::move(newUsedDir)); + m_usedDirs.add(dir->getOutputFileBase(),std::move(newUsedDir)); added=TRUE; } if (added) @@ -878,7 +881,7 @@ static void writePartialFilePath(OutputList &ol,const DirDef *root,const FileDef void DirRelation::writeDocumentation(OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -942,7 +945,7 @@ static void computeCommonDirPrefix() { // start will full path of first dir path=(*it)->name(); - int i=path.findRev('/',(int)path.length()-2); + int i=path.findRev('/',path.length()-2); path=path.left(i+1); bool done=FALSE; if (i==-1) @@ -962,7 +965,7 @@ static void computeCommonDirPrefix() { if (dirName.left(l)!=path) // dirName does not start with path { - i=path.findRev('/',(int)l-2); + i=path.findRev('/',l-2); if (i==-1) // no unique prefix -> stop { path=""; @@ -979,7 +982,7 @@ static void computeCommonDirPrefix() { path=dir->name(); l=path.length(); - i=path.findRev('/',(int)l-2); + i=path.findRev('/',l-2); if (i==-1) // no unique prefix -> stop { path=""; @@ -1036,7 +1039,7 @@ void buildDirectories() for (const auto &dir : *Doxygen::dirLinkedMap) { QCString name = dir->name(); - int i=name.findRev('/',(int)name.length()-2); + int i=name.findRev('/',name.length()-2); if (i>0) { DirDef *parent = Doxygen::dirLinkedMap->find(name.left(i+1)); diff --git a/src/dirdef.h b/src/dirdef.h index 2dff286..48749ed 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -110,8 +110,6 @@ class UsedDir class DirDef : public DefinitionMutable, public Definition { public: - virtual ~DirDef() {} - class UsedDirLinkedMap : public LinkedMap<UsedDir> {}; // accessors diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index ff85689..ac502a2 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -147,8 +147,6 @@ DocbookCodeGenerator::DocbookCodeGenerator(TextStream &t) : m_t(t) { } -DocbookCodeGenerator::~DocbookCodeGenerator() {} - void DocbookCodeGenerator::codify(const QCString &text) { Docbook_DB(("(codify \"%s\")\n",text)); @@ -253,14 +251,6 @@ void DocbookCodeGenerator::writeLineNumber(const QCString &ref,const QCString &f m_col=0; } -void DocbookCodeGenerator::setCurrentDoc(const Definition *,const QCString &,bool) -{ -} - -void DocbookCodeGenerator::addWord(const QCString &,bool) -{ -} - void DocbookCodeGenerator::finish() { endCodeLine(); @@ -633,13 +623,15 @@ DB_GEN_C } } -void DocbookGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *,int) +void DocbookGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int) { DB_GEN_C - DocbookDocVisitor *visitor = - new DocbookDocVisitor(m_t,*this,ctx?ctx->getDefFileExtension():QCString()); - n->accept(visitor); - delete visitor; + auto astImpl = dynamic_cast<const DocNodeAST*>(ast); + if (astImpl) + { + auto visitor { DocbookDocVisitor(m_t,*this,ctx?ctx->getDefFileExtension():QCString()) }; + std::visit(visitor,astImpl->root); + } } void DocbookGenerator::startParagraph(const QCString &) diff --git a/src/docbookgen.h b/src/docbookgen.h index ea4efe9..bf25a60 100644 --- a/src/docbookgen.h +++ b/src/docbookgen.h @@ -24,7 +24,6 @@ class DocbookCodeGenerator : public CodeOutputInterface { public: DocbookCodeGenerator(TextStream &t); - virtual ~DocbookCodeGenerator(); void setRelativePath(const QCString &path) { m_relPath = path; } void setSourceFileName(const QCString &sourceFileName) { m_sourceFileName = sourceFileName; } QCString sourceFileName() { return m_sourceFileName; } @@ -48,8 +47,6 @@ class DocbookCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const QCString &); void writeLineNumber(const QCString &extRef,const QCString &compId, const QCString &anchorId,int l, bool writeLineAnchor); - void setCurrentDoc(const Definition *,const QCString &,bool); - void addWord(const QCString &,bool); void finish(); void startCodeFragment(const QCString &style); void endCodeFragment(const QCString &style); @@ -134,7 +131,7 @@ class DocbookGenerator : public OutputGenerator { m_codeGen.endCodeFragment(style); } // --------------------------- - void writeDoc(DocNode *,const Definition *ctx,const MemberDef *md,int id); + void writeDoc(const IDocNodeAST *node,const Definition *ctx,const MemberDef *md,int id); /////////////////////////////////////////////////////////////// // structural output interface diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index 471bd3e..58bf25e 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -51,7 +51,7 @@ static QCString filterId(const QCString &s) { if (s.isEmpty()) return s; - static GrowBuf growBuf; + GrowBuf growBuf; growBuf.clear(); const char *p=s.data(); char c; @@ -86,7 +86,10 @@ static bool supportedHtmlAttribute(const QCString &name) void DocbookDocVisitor::visitCaption(const DocNodeList &children) { - for (const auto &n : children) n->accept(this); + for (const auto &n : children) + { + std::visit(*this,n); + } } void DocbookDocVisitor::visitPreStart(TextStream &t, @@ -151,7 +154,7 @@ void DocbookDocVisitor::visitPostEnd(TextStream &t, bool hasCaption, bool inline } DocbookDocVisitor::DocbookDocVisitor(TextStream &t,CodeOutputInterface &ci,const QCString &langExt) - : DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci),m_langExt(langExt) + : m_t(t), m_ci(ci),m_langExt(langExt) { DB_VIS_C // m_t << "<section>\n"; @@ -166,29 +169,29 @@ DB_VIS_C // visitor functions for leaf nodes //-------------------------------------- -void DocbookDocVisitor::visit(DocWord *w) +void DocbookDocVisitor::operator()(const DocWord &w) { DB_VIS_C if (m_hide) return; - filter(w->word()); + filter(w.word()); } -void DocbookDocVisitor::visit(DocLinkedWord *w) +void DocbookDocVisitor::operator()(const DocLinkedWord &w) { DB_VIS_C if (m_hide) return; - startLink(w->file(),w->anchor()); - filter(w->word()); + startLink(w.file(),w.anchor()); + filter(w.word()); endLink(); } -void DocbookDocVisitor::visit(DocWhiteSpace *w) +void DocbookDocVisitor::operator()(const DocWhiteSpace &w) { DB_VIS_C if (m_hide) return; if (m_insidePre) { - m_t << w->chars(); + m_t << w.chars(); } else { @@ -196,49 +199,49 @@ DB_VIS_C } } -void DocbookDocVisitor::visit(DocSymbol *s) +void DocbookDocVisitor::operator()(const DocSymbol &s) { DB_VIS_C if (m_hide) return; - const char *res = HtmlEntityMapper::instance()->docbook(s->symbol()); + const char *res = HtmlEntityMapper::instance()->docbook(s.symbol()); if (res) { m_t << res; } else { - err("DocBook: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + err("DocBook: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } } -void DocbookDocVisitor::visit(DocEmoji *s) +void DocbookDocVisitor::operator()(const DocEmoji &s) { DB_VIS_C if (m_hide) return; - const char *res = EmojiEntityMapper::instance()->unicode(s->index()); + const char *res = EmojiEntityMapper::instance()->unicode(s.index()); if (res) { m_t << res; } else { - m_t << s->name(); + m_t << s.name(); } } -void DocbookDocVisitor::visit(DocURL *u) +void DocbookDocVisitor::operator()(const DocURL &u) { DB_VIS_C if (m_hide) return; m_t << "<link xlink:href=\""; - if (u->isEmail()) m_t << "mailto:"; - filter(u->url()); + if (u.isEmail()) m_t << "mailto:"; + filter(u.url()); m_t << "\">"; - filter(u->url()); + filter(u.url()); m_t << "</link>"; } -void DocbookDocVisitor::visit(DocLineBreak *) +void DocbookDocVisitor::operator()(const DocLineBreak &) { DB_VIS_C if (m_hide) return; @@ -247,7 +250,7 @@ DB_VIS_C // m_t << "\n" << "<sbr/>\n"; } -void DocbookDocVisitor::visit(DocHorRuler *) +void DocbookDocVisitor::operator()(const DocHorRuler &) { DB_VIS_C if (m_hide) return; @@ -255,33 +258,33 @@ DB_VIS_C m_t << "</entry></row></tbody></tgroup></informaltable>\n"; } -void DocbookDocVisitor::visit(DocStyleChange *s) +void DocbookDocVisitor::operator()(const DocStyleChange &s) { DB_VIS_C if (m_hide) return; - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) m_t << "<emphasis role=\"bold\">"; else m_t << "</emphasis>"; + if (s.enable()) m_t << "<emphasis role=\"bold\">"; else m_t << "</emphasis>"; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>"; + if (s.enable()) m_t << "<emphasis>"; else m_t << "</emphasis>"; break; case DocStyleChange::Code: - if (s->enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>"; + if (s.enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>"; break; case DocStyleChange::Subscript: - if (s->enable()) m_t << "<subscript>"; else m_t << "</subscript>"; + if (s.enable()) m_t << "<subscript>"; else m_t << "</subscript>"; break; case DocStyleChange::Superscript: - if (s->enable()) m_t << "<superscript>"; else m_t << "</superscript>"; + if (s.enable()) m_t << "<superscript>"; else m_t << "</superscript>"; break; case DocStyleChange::Center: - if (s->enable()) m_t << "<informaltable frame='none'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>"; + if (s.enable()) m_t << "<informaltable frame='none'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>"; else m_t << "</entry></row></tbody></tgroup></informaltable>"; break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s.enable()) { m_t << "<literallayout>"; m_insidePre=TRUE; @@ -304,7 +307,7 @@ DB_VIS_C case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; case DocStyleChange::Details: /* emulation of the <details> tag */ - if (s->enable()) + if (s.enable()) { m_t << "\n"; m_t << "<para>"; @@ -316,43 +319,43 @@ DB_VIS_C } break; case DocStyleChange::Summary: /* emulation of the <summary> tag inside a <details> tag */ - if (s->enable()) m_t << "<emphasis role=\"bold\">"; else m_t << "</emphasis>"; + if (s.enable()) m_t << "<emphasis role=\"bold\">"; else m_t << "</emphasis>"; break; } } -void DocbookDocVisitor::visit(DocVerbatim *s) +void DocbookDocVisitor::operator()(const DocVerbatim &s) { DB_VIS_C if (m_hide) return; QCString lang = m_langExt; - if (!s->language().isEmpty()) // explicit language setting + if (!s.language().isEmpty()) // explicit language setting { - lang = s->language(); + lang = s.language(); } SrcLangExt langExt = getLanguageFromCodeLang(lang); - switch(s->type()) + switch(s.type()) { case DocVerbatim::Code: m_t << "<literallayout><computeroutput>"; - getCodeParser(m_langExt).parseCode(m_ci,s->context(), - s->text(), + getCodeParser(m_langExt).parseCode(m_ci,s.context(), + s.text(), langExt, - s->isExample(), - s->exampleFile()); + s.isExample(), + s.exampleFile()); m_t << "</computeroutput></literallayout>"; break; case DocVerbatim::Verbatim: m_t << "<literallayout><computeroutput>"; - filter(s->text()); + filter(s.text()); m_t << "</computeroutput></literallayout>"; break; case DocVerbatim::JavaDocLiteral: - filter(s->text(), true); + filter(s.text(), true); break; case DocVerbatim::JavaDocCode: m_t << "<computeroutput>"; - filter(s->text(), true); + filter(s.text(), true); m_t << "</computeroutput>"; break; case DocVerbatim::HtmlOnly: @@ -366,14 +369,14 @@ DB_VIS_C case DocVerbatim::XmlOnly: break; case DocVerbatim::DocbookOnly: - m_t << s->text(); + m_t << s.text(); break; case DocVerbatim::Dot: { static int dotindex = 1; QCString baseName(4096); QCString name; - QCString stext = s->text(); + QCString stext = s.text(); m_t << "<para>\n"; name.sprintf("%s%d", "dot_inline_dotgraph_", dotindex); baseName.sprintf("%s%d", @@ -398,7 +401,7 @@ DB_VIS_C static int mscindex = 1; QCString baseName(4096); QCString name; - QCString stext = s->text(); + QCString stext = s.text(); m_t << "<para>\n"; name.sprintf("%s%d", "msc_inline_mscgraph_", mscindex); baseName.sprintf("%s%d", @@ -423,13 +426,15 @@ DB_VIS_C break; case DocVerbatim::PlantUML: { - static QCString docbookOutput = Config_getString(DOCBOOK_OUTPUT); - QCString baseName = PlantumlManager::instance().writePlantUMLSource(docbookOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP,s->engine(),s->srcFile(),s->srcLine()); + QCString docbookOutput = Config_getString(DOCBOOK_OUTPUT); + QCString baseName = PlantumlManager::instance().writePlantUMLSource(docbookOutput, + s.exampleFile(),s.text(),PlantumlManager::PUML_BITMAP, + s.engine(),s.srcFile(),s.srcLine()); QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right((int)shortName.length()-i-1); + shortName=shortName.right(shortName.length()-i-1); } m_t << "<para>\n"; writePlantUMLFile(baseName,s); @@ -439,41 +444,41 @@ DB_VIS_C } } -void DocbookDocVisitor::visit(DocAnchor *anc) +void DocbookDocVisitor::operator()(const DocAnchor &anc) { DB_VIS_C if (m_hide) return; - m_t << "<anchor xml:id=\"_" << stripPath(anc->file()) << "_1" << filterId(anc->anchor()) << "\"/>"; + m_t << "<anchor xml:id=\"_" << stripPath(anc.file()) << "_1" << filterId(anc.anchor()) << "\"/>"; } -void DocbookDocVisitor::visit(DocInclude *inc) +void DocbookDocVisitor::operator()(const DocInclude &inc) { DB_VIS_C if (m_hide) return; - SrcLangExt langExt = getLanguageFromFileName(inc->extension()); - switch(inc->type()) + SrcLangExt langExt = getLanguageFromFileName(inc.extension()); + switch(inc.type()) { case DocInclude::IncWithLines: { m_t << "<literallayout><computeroutput>"; - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), fd); + inc.isExample(), + inc.exampleFile(), fd); delete fd; m_t << "</computeroutput></literallayout>"; } break; case DocInclude::Include: m_t << "<literallayout><computeroutput>"; - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile()); + inc.isExample(), + inc.exampleFile()); m_t << "</computeroutput></literallayout>"; break; case DocInclude::DontInclude: @@ -485,37 +490,37 @@ DB_VIS_C case DocInclude::XmlInclude: break; case DocInclude::DocbookInclude: - m_t << inc->text(); + m_t << inc.text(); break; case DocInclude::VerbInclude: m_t << "<literallayout>"; - filter(inc->text()); + filter(inc.text()); m_t << "</literallayout>"; break; case DocInclude::Snippet: m_t << "<literallayout><computeroutput>"; - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile() + inc.isExample(), + inc.exampleFile() ); m_t << "</computeroutput></literallayout>"; break; case DocInclude::SnipWithLines: { - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); m_t << "<literallayout><computeroutput>"; - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, - lineBlock(inc->text(),inc->blockId()), + lineBlock(inc.text(),inc.blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef @@ -533,10 +538,10 @@ DB_VIS_C } } -void DocbookDocVisitor::visit(DocIncOperator *op) +void DocbookDocVisitor::operator()(const DocIncOperator &op) { DB_VIS_C - if (op->isFirst()) + if (op.isFirst()) { if (!m_hide) { @@ -545,37 +550,37 @@ DB_VIS_C pushHidden(m_hide); m_hide = TRUE; } - QCString locLangExt = getFileNameExtension(op->includeFileName()); + 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) { m_hide = popHidden(); if (!m_hide) { FileDef *fd = 0; - if (!op->includeFileName().isEmpty()) + if (!op.includeFileName().isEmpty()) { - FileInfo cfi( op->includeFileName().str() ); + FileInfo cfi( op.includeFileName().str() ); fd = createFileDef( cfi.dirPath(), cfi.fileName() ); } - getCodeParser(locLangExt).parseCode(m_ci,op->context(), - op->text(),langExt,op->isExample(), - op->exampleFile(), + getCodeParser(locLangExt).parseCode(m_ci,op.context(), + op.text(),langExt,op.isExample(), + op.exampleFile(), fd, // fileDef - op->line(), // startLine + op.line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - op->showLineNo() // show line numbers + op.showLineNo() // show line numbers ); if (fd) delete fd; } pushHidden(m_hide); m_hide=TRUE; } - if (op->isLast()) + if (op.isLast()) { m_hide = popHidden(); if (!m_hide) m_t << "</programlisting>"; @@ -586,54 +591,54 @@ DB_VIS_C } } -void DocbookDocVisitor::visit(DocFormula *f) +void DocbookDocVisitor::operator()(const DocFormula &f) { DB_VIS_C if (m_hide) return; - if (f->isInline()) m_t << "<inlinemediaobject>\n"; + if (f.isInline()) m_t << "<inlinemediaobject>\n"; else m_t << " <mediaobject>\n"; m_t << " <imageobject>\n"; m_t << " <imagedata "; - m_t << "align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << f->relPath() << f->name() << ".png\"/>\n"; + m_t << "align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << f.relPath() << f.name() << ".png\"/>\n"; m_t << " </imageobject>\n"; - if (f->isInline()) m_t << "</inlinemediaobject>\n"; + if (f.isInline()) m_t << "</inlinemediaobject>\n"; else m_t << " </mediaobject>\n"; } -void DocbookDocVisitor::visit(DocIndexEntry *ie) +void DocbookDocVisitor::operator()(const DocIndexEntry &ie) { DB_VIS_C if (m_hide) return; m_t << "<indexterm><primary>"; - filter(ie->entry()); + filter(ie.entry()); m_t << "</primary></indexterm>\n"; } -void DocbookDocVisitor::visit(DocSimpleSectSep *) +void DocbookDocVisitor::operator()(const DocSimpleSectSep &) { DB_VIS_C // m_t << "<simplesect/>"; } -void DocbookDocVisitor::visit(DocCite *cite) +void DocbookDocVisitor::operator()(const DocCite &cite) { DB_VIS_C if (m_hide) return; - if (!cite->file().isEmpty()) startLink(cite->file(),filterId(cite->anchor())); - filter(cite->text()); - if (!cite->file().isEmpty()) endLink(); + if (!cite.file().isEmpty()) startLink(cite.file(),filterId(cite.anchor())); + filter(cite.text()); + if (!cite.file().isEmpty()) endLink(); } //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- -void DocbookDocVisitor::visitPre(DocAutoList *l) +void DocbookDocVisitor::operator()(const DocAutoList &l) { DB_VIS_C if (m_hide) return; - if (l->isEnumList()) + if (l.isEnumList()) { m_t << "<orderedlist>\n"; } @@ -641,13 +646,8 @@ DB_VIS_C { m_t << "<itemizedlist>\n"; } -} - -void DocbookDocVisitor::visitPost(DocAutoList *l) -{ -DB_VIS_C - if (m_hide) return; - if (l->isEnumList()) + visitChildren(l); + if (l.isEnumList()) { m_t << "</orderedlist>\n"; } @@ -657,53 +657,37 @@ DB_VIS_C } } -void DocbookDocVisitor::visitPre(DocAutoListItem *) +void DocbookDocVisitor::operator()(const DocAutoListItem &li) { DB_VIS_C if (m_hide) return; m_t << "<listitem>"; -} - -void DocbookDocVisitor::visitPost(DocAutoListItem *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(li); m_t << "</listitem>"; } -void DocbookDocVisitor::visitPre(DocPara *) +void DocbookDocVisitor::operator()(const DocPara &p) { DB_VIS_C if (m_hide) return; m_t << "\n"; m_t << "<para>"; -} - -void DocbookDocVisitor::visitPost(DocPara *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(p); m_t << "</para>"; m_t << "\n"; } -void DocbookDocVisitor::visitPre(DocRoot *) +void DocbookDocVisitor::operator()(const DocRoot &r) { DB_VIS_C - //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n"; + visitChildren(r); } -void DocbookDocVisitor::visitPost(DocRoot *) -{ -DB_VIS_C - //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n"; -} - -void DocbookDocVisitor::visitPre(DocSimpleSect *s) +void DocbookDocVisitor::operator()(const DocSimpleSect &s) { DB_VIS_C if (m_hide) return; - switch(s->type()) + switch(s.type()) { case DocSimpleSect::See: if (m_insidePre) @@ -859,24 +843,25 @@ DB_VIS_C case DocSimpleSect::User: case DocSimpleSect::Rcs: case DocSimpleSect::Unknown: - if (s->hasTitle()) + if (s.hasTitle()) m_t << "<formalpara>\n"; else m_t << "<para>\n"; break; } -} -void DocbookDocVisitor::visitPost(DocSimpleSect *s) -{ -DB_VIS_C - if (m_hide) return; - switch(s->type()) + if (s.title()) + { + std::visit(*this,*s.title()); + } + visitChildren(s); + + switch(s.type()) { case DocSimpleSect::User: case DocSimpleSect::Rcs: case DocSimpleSect::Unknown: - if (s->hasTitle()) + if (s.hasTitle()) m_t << "</formalpara>\n"; else m_t << "</para>\n"; @@ -896,94 +881,74 @@ DB_VIS_C } } -void DocbookDocVisitor::visitPre(DocTitle *t) -{ -DB_VIS_C - if (m_hide) return; - if (t->hasTitle()) m_t << "<title>"; -} - -void DocbookDocVisitor::visitPost(DocTitle *t) +void DocbookDocVisitor::operator()(const DocTitle &t) { DB_VIS_C if (m_hide) return; - if (t->hasTitle()) m_t << "</title>"; + if (t.hasTitle()) m_t << "<title>"; + visitChildren(t); + if (t.hasTitle()) m_t << "</title>"; } -void DocbookDocVisitor::visitPre(DocSimpleList *) +void DocbookDocVisitor::operator()(const DocSimpleList &l) { DB_VIS_C if (m_hide) return; m_t << "<itemizedlist>\n"; -} - -void DocbookDocVisitor::visitPost(DocSimpleList *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(l); m_t << "</itemizedlist>\n"; } -void DocbookDocVisitor::visitPre(DocSimpleListItem *) +void DocbookDocVisitor::operator()(const DocSimpleListItem &li) { DB_VIS_C if (m_hide) return; m_t << "<listitem>"; -} - -void DocbookDocVisitor::visitPost(DocSimpleListItem *) -{ -DB_VIS_C - if (m_hide) return; + if (li.paragraph()) + { + visit(*this,*li.paragraph()); + } m_t << "</listitem>\n"; } -void DocbookDocVisitor::visitPre(DocSection *s) +void DocbookDocVisitor::operator()(const DocSection &s) { DB_VIS_C if (m_hide) return; - m_t << "<section xml:id=\"_" << stripPath(s->file()); - if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor(); + m_t << "<section xml:id=\"_" << stripPath(s.file()); + if (!s.anchor().isEmpty()) m_t << "_1" << s.anchor(); m_t << "\">\n"; m_t << "<title>"; - filter(s->title()); + filter(s.title()); m_t << "</title>\n"; -} - -void DocbookDocVisitor::visitPost(DocSection *) -{ -DB_VIS_C + visitChildren(s); m_t << "</section>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlList *s) -{ -DB_VIS_C - if (m_hide) return; - // This will be handled in DocHtmlListItem -} - -void DocbookDocVisitor::visitPost(DocHtmlList *s) +void DocbookDocVisitor::operator()(const DocHtmlList &s) { DB_VIS_C if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) + if (s.children().empty()) return; + // opening tag will be handled in DocHtmlListItem + visitChildren(s); + if (s.type()==DocHtmlList::Ordered) m_t << "</orderedlist>\n"; else m_t << "</itemizedlist>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlListItem *s) +void DocbookDocVisitor::operator()(const DocHtmlListItem &s) { DB_VIS_C if (m_hide) return; - DocHtmlList *l = (DocHtmlList *)s->parent(); + const DocHtmlList *l = std::get_if<DocHtmlList>(s.parent()); if (l->type()==DocHtmlList::Ordered) { - bool isFirst = l->children().front().get()==s; + bool isFirst = &std::get<DocHtmlListItem>(l->children().front())==&s; int value = 0; QCString type; - for (const auto &opt : s->attribs()) + for (const auto &opt : s.attribs()) { if (opt.name=="value") { @@ -1036,97 +1001,67 @@ DB_VIS_C m_t << "<itemizedlist>\n"; } m_t << "<listitem>\n"; -} - -void DocbookDocVisitor::visitPost(DocHtmlListItem *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(s); m_t << "</listitem>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlDescList *) +void DocbookDocVisitor::operator()(const DocHtmlDescList &l) { DB_VIS_C if (m_hide) return; m_t << "<variablelist>\n"; -} - -void DocbookDocVisitor::visitPost(DocHtmlDescList *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(l); m_t << "</variablelist>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlDescTitle *) +void DocbookDocVisitor::operator()(const DocHtmlDescTitle &dt) { DB_VIS_C if (m_hide) return; m_t << "<varlistentry><term>"; -} - -void DocbookDocVisitor::visitPost(DocHtmlDescTitle *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(dt); m_t << "</term>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlDescData *) +void DocbookDocVisitor::operator()(const DocHtmlDescData &dd) { DB_VIS_C if (m_hide) return; m_t << "<listitem>"; -} - -void DocbookDocVisitor::visitPost(DocHtmlDescData *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(dd); m_t << "</listitem></varlistentry>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlTable *t) +void DocbookDocVisitor::operator()(const DocHtmlTable &t) { DB_VIS_C m_bodySet.push(false); if (m_hide) return; m_t << "<informaltable frame=\"all\">\n"; - m_t << " <tgroup cols=\"" << (unsigned int)t->numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">\n"; - for (uint i = 0; i <t->numColumns(); i++) + m_t << " <tgroup cols=\"" << t.numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">\n"; + for (uint i = 0; i <t.numColumns(); i++) { // do something with colwidth based of cell width specification (be aware of possible colspan in the header)? m_t << " <colspec colname='c" << i+1 << "'/>\n"; } - if (t->hasCaption()) + if (t.caption()) { - DocHtmlCaption *c = t->caption(); - m_t << "<caption>"; - if (!c->file().isEmpty()) - { - m_t << "<anchor xml:id=\"_" << stripPath(c->file()) << "_1" << filterId(c->anchor()) << "\"/>"; - } + std::visit(*this,*t.caption()); } -} - -void DocbookDocVisitor::visitPost(DocHtmlTable *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(t); if (m_bodySet.top()) m_t << " </tbody>\n"; m_bodySet.pop(); m_t << " </tgroup>\n"; m_t << "</informaltable>\n"; } -void DocbookDocVisitor::visitPre(DocHtmlRow *tr) +void DocbookDocVisitor::operator()(const DocHtmlRow &tr) { DB_VIS_C m_colCnt = 0; if (m_hide) return; - if (tr->isHeading()) + if (tr.isHeading()) { if (m_bodySet.top()) m_t << "</tbody>\n"; m_bodySet.top() = false; @@ -1140,7 +1075,7 @@ DB_VIS_C m_t << " <row "; - for (const auto &opt : tr->attribs()) + for (const auto &opt : tr.attribs()) { if (supportedHtmlAttribute(opt.name)) { @@ -1149,28 +1084,23 @@ DB_VIS_C } } m_t << ">\n"; -} - -void DocbookDocVisitor::visitPost(DocHtmlRow *tr) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(tr); m_t << "</row>\n"; - if (tr->isHeading()) + if (tr.isHeading()) { m_t << "</thead><tbody>\n"; m_bodySet.top() = true; } } -void DocbookDocVisitor::visitPre(DocHtmlCell *c) +void DocbookDocVisitor::operator()(const DocHtmlCell &c) { DB_VIS_C m_colCnt++; if (m_hide) return; m_t << "<entry"; - for (const auto &opt : c->attribs()) + for (const auto &opt : c.attribs()) { if (opt.name=="colspan") { @@ -1214,247 +1144,169 @@ DB_VIS_C } } m_t << ">"; -} - -void DocbookDocVisitor::visitPost(DocHtmlCell *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(c); m_t << "</entry>"; } -void DocbookDocVisitor::visitPre(DocHtmlCaption *) -{ -DB_VIS_C - if (m_hide) return; - // start of caption is handled in the DocbookDocVisitor::visitPre(DocHtmlTable *t) -} - -void DocbookDocVisitor::visitPost(DocHtmlCaption *) +void DocbookDocVisitor::operator()(const DocHtmlCaption &c) { DB_VIS_C if (m_hide) return; + m_t << "<caption>"; + if (!c.file().isEmpty()) + { + m_t << "<anchor xml:id=\"_" << stripPath(c.file()) << "_1" << filterId(c.anchor()) << "\"/>"; + } + visitChildren(c); m_t << "</caption>\n"; } -void DocbookDocVisitor::visitPre(DocInternal *) +void DocbookDocVisitor::operator()(const DocInternal &i) { DB_VIS_C if (m_hide) return; - // TODO: to be implemented + visitChildren(i); } -void DocbookDocVisitor::visitPost(DocInternal *) +void DocbookDocVisitor::operator()(const DocHRef &href) { DB_VIS_C if (m_hide) return; - // TODO: to be implemented -} - -void DocbookDocVisitor::visitPre(DocHRef *href) -{ -DB_VIS_C - if (m_hide) return; - if (href->url().at(0) != '#') + if (href.url().at(0) != '#') { - m_t << "<link xlink:href=\"" << convertToDocBook(href->url()) << "\">"; + m_t << "<link xlink:href=\"" << convertToDocBook(href.url()) << "\">"; } else { - startLink(href->file(),filterId(href->url().mid(1))); + startLink(href.file(),filterId(href.url().mid(1))); } -} - -void DocbookDocVisitor::visitPost(DocHRef *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(href); m_t << "</link>"; } -void DocbookDocVisitor::visitPre(DocHtmlHeader *) +void DocbookDocVisitor::operator()(const DocHtmlHeader &h) { DB_VIS_C if (m_hide) return; m_t << "<formalpara><title>"; -} - -void DocbookDocVisitor::visitPost(DocHtmlHeader *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(h); m_t << "</title></formalpara>\n"; } -void DocbookDocVisitor::visitPre(DocImage *img) +void DocbookDocVisitor::operator()(const DocImage &img) { DB_VIS_C - if (img->type()==DocImage::DocBook) + if (img.type()==DocImage::DocBook) { if (m_hide) return; m_t << "\n"; - QCString baseName=img->name(); + QCString baseName=img.name(); int i; if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) { - baseName=baseName.right((int)baseName.length()-i-1); + baseName=baseName.right(baseName.length()-i-1); } - visitPreStart(m_t, img->children(), img->hasCaption(), img->relPath() + baseName, img->width(), img->height(), img->isInlineImage()); - } - else - { - pushHidden(m_hide); - m_hide=TRUE; - } -} - -void DocbookDocVisitor::visitPost(DocImage *img) -{ -DB_VIS_C - if (img->type()==DocImage::DocBook) - { - if (m_hide) return; - visitPostEnd(m_t, img -> hasCaption(),img -> isInlineImage()); - // copy the image to the output dir - QCString baseName=img->name(); - int i; - if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) - { - baseName=baseName.right((int)baseName.length()-i-1); - } - QCString m_file; + visitPreStart(m_t, img.children(), img.hasCaption(), img.relPath() + baseName, img.width(), img.height(), img.isInlineImage()); + visitChildren(img); + visitPostEnd(m_t, img.hasCaption(),img.isInlineImage()); + QCString file; bool ambig; FileDef *fd=findFileDef(Doxygen::imageNameLinkedMap, baseName, ambig); if (fd) { - m_file=fd->absFilePath(); + file=fd->absFilePath(); } - copyFile(m_file,Config_getString(DOCBOOK_OUTPUT)+"/"+baseName); + copyFile(file,Config_getString(DOCBOOK_OUTPUT)+"/"+baseName); } - else + else // skip other formats { - m_hide = popHidden(); } } -void DocbookDocVisitor::visitPre(DocDotFile *df) -{ -DB_VIS_C - if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(DOCBOOK_OUTPUT)+"/"+stripPath(df->file())); - startDotFile(df->file(),df->width(),df->height(),df->hasCaption(),df->children(),df->srcFile(),df->srcLine()); -} - -void DocbookDocVisitor::visitPost(DocDotFile *df) -{ -DB_VIS_C - if (m_hide) return; - endDotFile(df->hasCaption()); -} - -void DocbookDocVisitor::visitPre(DocMscFile *df) -{ -DB_VIS_C - if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(DOCBOOK_OUTPUT)+"/"+stripPath(df->file())); - startMscFile(df->file(),df->width(),df->height(),df->hasCaption(),df->children(),df->srcFile(),df->srcLine()); -} - -void DocbookDocVisitor::visitPost(DocMscFile *df) -{ -DB_VIS_C - if (m_hide) return; - endMscFile(df->hasCaption()); -} -void DocbookDocVisitor::visitPre(DocDiaFile *df) +void DocbookDocVisitor::operator()(const DocDotFile &df) { DB_VIS_C if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(DOCBOOK_OUTPUT)+"/"+stripPath(df->file())); - startDiaFile(df->file(),df->width(),df->height(),df->hasCaption(),df->children(),df->srcFile(),df->srcLine()); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(DOCBOOK_OUTPUT)+"/"+stripPath(df.file())); + startDotFile(df.file(),df.width(),df.height(),df.hasCaption(),df.children(),df.srcFile(),df.srcLine()); + visitChildren(df); + endDotFile(df.hasCaption()); } -void DocbookDocVisitor::visitPost(DocDiaFile *df) +void DocbookDocVisitor::operator()(const DocMscFile &df) { DB_VIS_C if (m_hide) return; - endDiaFile(df->hasCaption()); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(DOCBOOK_OUTPUT)+"/"+stripPath(df.file())); + startMscFile(df.file(),df.width(),df.height(),df.hasCaption(),df.children(),df.srcFile(),df.srcLine()); + visitChildren(df); + endMscFile(df.hasCaption()); } -void DocbookDocVisitor::visitPre(DocLink *lnk) +void DocbookDocVisitor::operator()(const DocDiaFile &df) { DB_VIS_C if (m_hide) return; - startLink(lnk->file(),lnk->anchor()); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(DOCBOOK_OUTPUT)+"/"+stripPath(df.file())); + startDiaFile(df.file(),df.width(),df.height(),df.hasCaption(),df.children(),df.srcFile(),df.srcLine()); + visitChildren(df); + endDiaFile(df.hasCaption()); } -void DocbookDocVisitor::visitPost(DocLink *) +void DocbookDocVisitor::operator()(const DocLink &lnk) { DB_VIS_C if (m_hide) return; + startLink(lnk.file(),lnk.anchor()); + visitChildren(lnk); endLink(); } -void DocbookDocVisitor::visitPre(DocRef *ref) +void DocbookDocVisitor::operator()(const DocRef &ref) { DB_VIS_C if (m_hide) return; - if (ref->isSubPage()) + if (ref.isSubPage()) { - startLink(QCString(),ref->anchor()); + startLink(QCString(),ref.anchor()); } else { - if (!ref->file().isEmpty()) startLink(ref->file(),ref->anchor()); + if (!ref.file().isEmpty()) startLink(ref.file(),ref.anchor()); } - if (!ref->hasLinkText()) filter(ref->targetTitle()); + if (!ref.hasLinkText()) filter(ref.targetTitle()); + visitChildren(ref); + if (!ref.file().isEmpty()) endLink(); } -void DocbookDocVisitor::visitPost(DocRef *ref) -{ -DB_VIS_C - if (m_hide) return; - if (!ref->file().isEmpty()) endLink(); -} - -void DocbookDocVisitor::visitPre(DocSecRefItem *) +void DocbookDocVisitor::operator()(const DocSecRefItem &ref) { DB_VIS_C if (m_hide) return; //m_t << "<tocentry xml:idref=\"_" << stripPath(ref->file()) << "_1" << ref->anchor() << "\">"; m_t << "<tocentry>"; -} - -void DocbookDocVisitor::visitPost(DocSecRefItem *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(ref); m_t << "</tocentry>\n"; } -void DocbookDocVisitor::visitPre(DocSecRefList *) +void DocbookDocVisitor::operator()(const DocSecRefList &l) { DB_VIS_C if (m_hide) return; m_t << "<toc>\n"; -} - -void DocbookDocVisitor::visitPost(DocSecRefList *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(l); m_t << "</toc>\n"; } -void DocbookDocVisitor::visitPre(DocParamSect *s) +void DocbookDocVisitor::operator()(const DocParamSect &s) { DB_VIS_C if (m_hide) return; m_t << "\n"; m_t << " <formalpara>\n"; m_t << " <title>\n"; - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: m_t << theTranslator->trParameters(); break; case DocParamSect::RetVal: m_t << theTranslator->trReturnValues(); break; @@ -1467,10 +1319,10 @@ DB_VIS_C m_t << " <para>\n"; m_t << " <table frame=\"all\">\n"; int ncols = 2; - if (s->type() == DocParamSect::Param) + if (s.type() == DocParamSect::Param) { - bool hasInOutSpecs = s->hasInOutSpecifier(); - bool hasTypeSpecs = s->hasTypeSpecifier(); + bool hasInOutSpecs = s.hasInOutSpecifier(); + bool hasTypeSpecs = s.hasTypeSpecifier(); if (hasInOutSpecs && hasTypeSpecs) ncols += 2; else if (hasInOutSpecs || hasTypeSpecs) ncols += 1; } @@ -1481,12 +1333,7 @@ DB_VIS_C else m_t << " <colspec colwidth=\"1*\"/>\n"; } m_t << " <tbody>\n"; -} - -void DocbookDocVisitor::visitPost(DocParamSect *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(s); m_t << " </tbody>\n"; m_t << " </tgroup>\n"; m_t << " </table>\n"; @@ -1495,32 +1342,34 @@ DB_VIS_C m_t << " "; } -void DocbookDocVisitor::visitPre(DocParamList *pl) +void DocbookDocVisitor::operator()(const DocSeparator &sep) { DB_VIS_C if (m_hide) return; - m_t << " <row>\n"; + m_t << " " << sep.chars() << " "; +} - DocParamSect *sect = 0; - if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) - { - sect=(DocParamSect*)pl->parent(); - } +void DocbookDocVisitor::operator()(const DocParamList &pl) +{ +DB_VIS_C + if (m_hide) return; + m_t << " <row>\n"; + const DocParamSect *sect = std::get_if<DocParamSect>(pl.parent()); if (sect && sect->hasInOutSpecifier()) { m_t << "<entry>"; - if (pl->direction()!=DocParamSect::Unspecified) + if (pl.direction()!=DocParamSect::Unspecified) { - if (pl->direction()==DocParamSect::In) + if (pl.direction()==DocParamSect::In) { m_t << "in"; } - else if (pl->direction()==DocParamSect::Out) + else if (pl.direction()==DocParamSect::Out) { m_t << "out"; } - else if (pl->direction()==DocParamSect::InOut) + else if (pl.direction()==DocParamSect::InOut) { m_t << "in,out"; } @@ -1531,26 +1380,14 @@ DB_VIS_C if (sect && sect->hasTypeSpecifier()) { m_t << "<entry>"; - for (const auto &type : pl->paramTypes()) + for (const auto &type : pl.paramTypes()) { - if (type->kind()==DocNode::Kind_Word) - { - visit((DocWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_Sep) - { - m_t << " " << ((DocSeparator *)type.get())->chars() << " "; - } - + std::visit(*this,type); } m_t << "</entry>"; } - if (pl->parameters().empty()) + if (pl.parameters().empty()) { m_t << "<entry></entry>\n"; } @@ -1558,120 +1395,79 @@ DB_VIS_C { m_t << "<entry>"; int cnt = 0; - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { if (cnt) { m_t << ", "; } - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } + std::visit(*this,param); cnt++; } m_t << "</entry>"; } m_t << "<entry>"; -} - -void DocbookDocVisitor::visitPost(DocParamList *) -{ -DB_VIS_C - if (m_hide) return; + for (const auto &par : pl.paragraphs()) + { + std::visit(*this,par); + } m_t << "</entry>\n"; m_t << " </row>\n"; } -void DocbookDocVisitor::visitPre(DocXRefItem *x) +void DocbookDocVisitor::operator()(const DocXRefItem &x) { DB_VIS_C if (m_hide) return; - if (x->title().isEmpty()) return; + if (x.title().isEmpty()) return; m_t << "<para><link linkend=\"_"; - m_t << stripPath(x->file()) << "_1" << x->anchor(); + m_t << stripPath(x.file()) << "_1" << x.anchor(); m_t << "\">"; - filter(x->title()); + filter(x.title()); m_t << "</link>"; m_t << " "; -} - -void DocbookDocVisitor::visitPost(DocXRefItem *x) -{ -DB_VIS_C - if (m_hide) return; - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; m_t << "</para>"; } -void DocbookDocVisitor::visitPre(DocInternalRef *ref) -{ -DB_VIS_C - if (m_hide) return; - startLink(ref->file(),ref->anchor()); -} - -void DocbookDocVisitor::visitPost(DocInternalRef *) +void DocbookDocVisitor::operator()(const DocInternalRef &ref) { DB_VIS_C if (m_hide) return; + startLink(ref.file(),ref.anchor()); + visitChildren(ref); endLink(); m_t << " "; } -void DocbookDocVisitor::visitPre(DocText *) -{ -DB_VIS_C - // TODO: to be implemented -} - - -void DocbookDocVisitor::visitPost(DocText *) +void DocbookDocVisitor::operator()(const DocText &t) { DB_VIS_C - // TODO: to be implemented + visitChildren(t); } -void DocbookDocVisitor::visitPre(DocHtmlBlockQuote *) +void DocbookDocVisitor::operator()(const DocHtmlBlockQuote &q) { DB_VIS_C if (m_hide) return; m_t << "<blockquote>"; -} - -void DocbookDocVisitor::visitPost(DocHtmlBlockQuote *) -{ -DB_VIS_C - if (m_hide) return; + visitChildren(q); m_t << "</blockquote>"; } -void DocbookDocVisitor::visitPre(DocVhdlFlow *) -{ -DB_VIS_C - // TODO: to be implemented -} - - -void DocbookDocVisitor::visitPost(DocVhdlFlow *) +void DocbookDocVisitor::operator()(const DocVhdlFlow &) { DB_VIS_C // TODO: to be implemented } -void DocbookDocVisitor::visitPre(DocParBlock *) -{ -DB_VIS_C -} - -void DocbookDocVisitor::visitPost(DocParBlock *) +void DocbookDocVisitor::operator()(const DocParBlock &b) { DB_VIS_C + if (m_hide) return; + visitChildren(b); } @@ -1699,36 +1495,36 @@ DB_VIS_C m_t << "</link>"; } -void DocbookDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s) +void DocbookDocVisitor::writeMscFile(const QCString &baseName, const DocVerbatim &s) { DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right((int)shortName.length()-i-1); + shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); - writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_BITMAP,s->srcFile(),s->srcLine()); - visitPreStart(m_t, s->children(), s->hasCaption(), s->relPath() + shortName + ".png", s->width(), s->height()); - visitCaption(s->children()); - visitPostEnd(m_t, s->hasCaption()); + writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_BITMAP,s.srcFile(),s.srcLine()); + visitPreStart(m_t, s.children(), s.hasCaption(), s.relPath() + shortName + ".png", s.width(), s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } -void DocbookDocVisitor::writePlantUMLFile(const QCString &baseName, DocVerbatim *s) +void DocbookDocVisitor::writePlantUMLFile(const QCString &baseName, const DocVerbatim &s) { DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right((int)shortName.length()-i-1); + shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); PlantumlManager::instance().generatePlantUMLOutput(baseName,outDir,PlantumlManager::PUML_BITMAP); - visitPreStart(m_t, s->children(), s->hasCaption(), s->relPath() + shortName + ".png", s->width(),s->height()); - visitCaption(s->children()); - visitPostEnd(m_t, s->hasCaption()); + visitPreStart(m_t, s.children(), s.hasCaption(), s.relPath() + shortName + ".png", s.width(),s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } void DocbookDocVisitor::startMscFile(const QCString &fileName, @@ -1745,7 +1541,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1) { - baseName=baseName.right((int)baseName.length()-i-1); + baseName=baseName.right(baseName.length()-i-1); } if ((i=baseName.find('.'))!=-1) { @@ -1766,20 +1562,20 @@ DB_VIS_C m_t << "</para>\n"; } -void DocbookDocVisitor::writeDiaFile(const QCString &baseName, DocVerbatim *s) +void DocbookDocVisitor::writeDiaFile(const QCString &baseName, const DocVerbatim &s) { DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right((int)shortName.length()-i-1); + shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); - writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_BITMAP,s->srcFile(),s->srcLine()); - visitPreStart(m_t, s->children(), s->hasCaption(), shortName, s->width(),s->height()); - visitCaption(s->children()); - visitPostEnd(m_t, s->hasCaption()); + writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_BITMAP,s.srcFile(),s.srcLine()); + visitPreStart(m_t, s.children(), s.hasCaption(), shortName, s.width(),s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } void DocbookDocVisitor::startDiaFile(const QCString &fileName, @@ -1796,7 +1592,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1) { - baseName=baseName.right((int)baseName.length()-i-1); + baseName=baseName.right(baseName.length()-i-1); } if ((i=baseName.find('.'))!=-1) { @@ -1817,20 +1613,20 @@ DB_VIS_C m_t << "</para>\n"; } -void DocbookDocVisitor::writeDotFile(const QCString &baseName, DocVerbatim *s) +void DocbookDocVisitor::writeDotFile(const QCString &baseName, const DocVerbatim &s) { DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) { - shortName=shortName.right((int)shortName.length()-i-1); + shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); - writeDotGraphFromFile(baseName+".dot",outDir,shortName,GOF_BITMAP,s->srcFile(),s->srcLine()); - visitPreStart(m_t, s->children(), s->hasCaption(), s->relPath() + shortName + "." + getDotImageExtension(), s->width(),s->height()); - visitCaption(s->children()); - visitPostEnd(m_t, s->hasCaption()); + writeDotGraphFromFile(baseName+".dot",outDir,shortName,GOF_BITMAP,s.srcFile(),s.srcLine()); + visitPreStart(m_t, s.children(), s.hasCaption(), s.relPath() + shortName + "." + getDotImageExtension(), s.width(),s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } void DocbookDocVisitor::startDotFile(const QCString &fileName, @@ -1847,7 +1643,7 @@ DB_VIS_C int i; if ((i=baseName.findRev('/'))!=-1) { - baseName=baseName.right((int)baseName.length()-i-1); + baseName=baseName.right(baseName.length()-i-1); } if ((i=baseName.find('.'))!=-1) { diff --git a/src/docbookvisitor.h b/src/docbookvisitor.h index 93ed94e..1a05f00 100644 --- a/src/docbookvisitor.h +++ b/src/docbookvisitor.h @@ -20,7 +20,7 @@ #include "containers.h" #include "docvisitor.h" -#include "docparser.h" +#include "docnode.h" #include "qcstring.h" class CodeOutputInterface; @@ -33,107 +33,76 @@ class DocbookDocVisitor : public DocVisitor public: DocbookDocVisitor(TextStream &t,CodeOutputInterface &ci,const QCString &langExt); ~DocbookDocVisitor(); + //----------------------------------------- + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } //-------------------------------------- // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *) ; - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *); - void visitPost(DocSection *); - void visitPre(DocHtmlList *); - void visitPost(DocHtmlList *) ; - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - //void visitPre(DocHtmlPre *); - //void visitPost(DocHtmlPre *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *); - void visitPost(DocHtmlTable *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *); - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *); - void visitPost(DocLink *); - void visitPre(DocRef *); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - //void visitPre(DocLanguage *); - //void visitPost(DocLanguage *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &) ; + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &); + void operator()(const DocHtmlList &); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocHtmlCaption &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &); + void operator()(const DocRef &); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); private: //-------------------------------------- @@ -147,18 +116,18 @@ class DocbookDocVisitor : public DocVisitor const QCString &height, bool hasCaption,const DocNodeList &children, const QCString &srcFile, int srcLine); void endMscFile(bool hasCaption); - void writeMscFile(const QCString &fileName, DocVerbatim *s); + void writeMscFile(const QCString &fileName, const DocVerbatim &s); void startDiaFile(const QCString &fileName,const QCString &width, const QCString &height, bool hasCaption,const DocNodeList &children, const QCString &srcFile, int srcLine); void endDiaFile(bool hasCaption); - void writeDiaFile(const QCString &fileName, DocVerbatim *s); + void writeDiaFile(const QCString &fileName, const DocVerbatim &s); void startDotFile(const QCString &fileName,const QCString &width, const QCString &height, bool hasCaption,const DocNodeList &children, const QCString &srcFile, int srcLine); void endDotFile(bool hasCaption); - void writeDotFile(const QCString &fileName, DocVerbatim *s); - void writePlantUMLFile(const QCString &fileName, DocVerbatim *s); + void writeDotFile(const QCString &fileName, const DocVerbatim &s); + void writePlantUMLFile(const QCString &fileName, const DocVerbatim &s); void visitPreStart(TextStream &t, const DocNodeList &children, bool hasCaption, diff --git a/src/docnode.cpp b/src/docnode.cpp new file mode 100644 index 0000000..0b9462c --- /dev/null +++ b/src/docnode.cpp @@ -0,0 +1,5764 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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 "docnode.h" +#include "docparser_p.h" +#include "htmlentity.h" +#include "emoji.h" +#include "message.h" +#include "doxygen.h" +#include "cite.h" +#include "util.h" +#include "formula.h" +#include "markdown.h" +#include "pagedef.h" +#include "namespacedef.h" +#include "groupdef.h" +#include "cmdmapper.h" +#include "config.h" +#include "vhdldocgen.h" +#include "doctokenizer.h" +#include "plantuml.h" + +// debug off +#define DBG(x) do {} while(0) + +// debug to stdout +//#define DBG(x) printf x + +// debug to stderr +//#define myprintf(...) fprintf(stderr,__VA_ARGS__) +//#define DBG(x) myprintf x + +#define INTERNAL_ASSERT(x) do {} while(0) +//#define INTERNAL_ASSERT(x) if (!(x)) DBG(("INTERNAL_ASSERT(%s) failed retval=0x%x: file=%s line=%d\n",#x,retval,__FILE__,__LINE__)); + +//--------------------------------------------------------------------------- + +static const char *g_sectionLevelToName[] = +{ + "page", + "section", + "subsection", + "subsubsection", + "paragraph", + "subparagraph" +}; + + +//--------------------------------------------------------------------------- + +static const std::set<std::string> g_plantumlEngine { + "uml", "bpm", "wire", "dot", "ditaa", + "salt", "math", "latex", "gantt", "mindmap", + "wbs", "yaml", "creole", "json", "flow", + "board", "git" +}; + +//--------------------------------------------------------------------------- + +// replaces { with < and } with > and also +// replaces > with < and > with > within string s +static void unescapeCRef(QCString &s) +{ + QCString result; + const char *p = s.data(); + if (p) + { + char c; + while ((c=*p++)) + { + if (c=='{') c='<'; else if (c=='}') c='>'; + result+=c; + } + } + + result=substitute(result,"<","<"); + result=substitute(result,">",">"); + s = result; +} + +//--------------------------------------------------------------------------- + +/*! Strips known html and tex extensions from \a text. */ +static QCString stripKnownExtensions(const QCString &text) +{ + QCString result=text; + if (result.right(4)==".tex") + { + result=result.left(result.length()-4); + } + else if (result.right(Doxygen::htmlFileExtension.length())== + QCString(Doxygen::htmlFileExtension)) + { + result=result.left(result.length()-Doxygen::htmlFileExtension.length()); + } + return result; +} + +static void setParent(DocNodeVariant *n,DocNodeVariant *newParent) +{ + std::visit([&](auto &&x)->decltype(auto) { return x.setParent(newParent); }, *n); +} + +//----------- DocStyleChange + +const char *DocStyleChange::styleString() const +{ + switch (m_style) + { + case DocStyleChange::Bold: return "b"; + case DocStyleChange::Italic: return "em"; + case DocStyleChange::Code: return "code"; + case DocStyleChange::Center: return "center"; + case DocStyleChange::Small: return "small"; + case DocStyleChange::Cite: return "cite"; + case DocStyleChange::Subscript: return "subscript"; + case DocStyleChange::Superscript: return "superscript"; + case DocStyleChange::Preformatted: return "pre"; + case DocStyleChange::Div: return "div"; + case DocStyleChange::Span: return "span"; + case DocStyleChange::Strike: return "strike"; + case DocStyleChange::S: return "s"; + case DocStyleChange::Del: return "del"; + case DocStyleChange::Underline: return "u"; + case DocStyleChange::Ins: return "ins"; + case DocStyleChange::Details: return "details"; + case DocStyleChange::Summary: return "summary"; + } + return "<invalid>"; +} + +//----------- DocSymbol + +HtmlEntityMapper::SymType DocSymbol::decodeSymbol(const QCString &symName) +{ + DBG(("decodeSymbol(%s)\n",qPrint(symName))); + return HtmlEntityMapper::instance()->name2sym(symName); +} + +//----------- DocEmoji + +DocEmoji::DocEmoji(DocParser *parser,DocNodeVariant *parent,const QCString &symName) : + DocNode(parser,parent), m_symName(symName), m_index(-1) +{ + QCString locSymName = symName; + uint len=locSymName.length(); + if (len>0) + { + if (locSymName.at(len-1)!=':') locSymName.append(":"); + if (locSymName.at(0)!=':') locSymName.prepend(":"); + } + m_symName = locSymName; + m_index = EmojiEntityMapper::instance()->symbol2index(m_symName.str()); + if (m_index==-1) + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"Found unsupported emoji symbol '%s'\n",qPrint(m_symName)); + } +} + +//--------------------------------------------------------------------------- + +DocWord::DocWord(DocParser *parser,DocNodeVariant *parent,const QCString &word) : + DocNode(parser,parent), m_word(word) +{ + //printf("new word %s url=%s\n",qPrint(word),qPrint(parser->context.searchUrl)); + if (Doxygen::searchIndex && !parser->context.searchUrl.isEmpty()) + { + parser->searchData.addWord(word,false); + } +} + +//--------------------------------------------------------------------------- + +DocLinkedWord::DocLinkedWord(DocParser *parser,DocNodeVariant *parent,const QCString &word, + const QCString &ref,const QCString &file, + const QCString &anchor,const QCString &tooltip) : + DocNode(parser,parent), m_word(word), m_ref(ref), + m_file(file), m_relPath(parser->context.relPath), m_anchor(anchor), + m_tooltip(tooltip) +{ + //printf("DocLinkedWord: new word %s url=%s tooltip='%s'\n", + // qPrint(word),qPrint(parser->context.searchUrl),qPrint(tooltip)); + if (Doxygen::searchIndex && !parser->context.searchUrl.isEmpty()) + { + parser->searchData.addWord(word,false); + } +} + +//--------------------------------------------------------------------------- + +DocAnchor::DocAnchor(DocParser *parser,DocNodeVariant *parent,const QCString &id,bool newAnchor) : DocNode(parser,parent) +{ + if (id.isEmpty()) + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"Empty anchor label"); + return; + } + + const CitationManager &ct = CitationManager::instance(); + QCString anchorPrefix = ct.anchorPrefix(); + if (id.left(anchorPrefix.length()) == anchorPrefix) + { + const CiteInfo *cite = ct.find(id.mid(anchorPrefix.length())); + if (cite) + { + m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); + m_anchor = id; + } + else + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"Invalid cite anchor id '%s'",qPrint(id)); + m_anchor = "invalid"; + m_file = "invalid"; + } + } + else if (newAnchor) // found <a name="label"> + { + m_anchor = id; + } + else // found \anchor label + { + const SectionInfo *sec = SectionManager::instance().find(id); + if (sec) + { + //printf("Found anchor %s\n",qPrint(id)); + m_file = sec->fileName(); + m_anchor = sec->label(); + } + else + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"Invalid anchor id '%s'",qPrint(id)); + m_anchor = "invalid"; + m_file = "invalid"; + } + } +} + +//--------------------------------------------------------------------------- + +DocVerbatim::DocVerbatim(DocParser *parser,DocNodeVariant *parent,const QCString &context, + const QCString &text, Type t,bool isExample, + const QCString &exampleFile,bool isBlock,const QCString &lang) + : DocNode(parser,parent), p(std::make_unique<Private>(context, text, t, isExample, exampleFile, parser->context.relPath, lang, isBlock)) +{ +} + + +//--------------------------------------------------------------------------- + +void DocInclude::parse(DocNodeVariant *) +{ + DBG(("DocInclude::parse(file=%s,text=%s)\n",qPrint(m_file),qPrint(m_text))); + switch(m_type) + { + case DontIncWithLines: + // fall through + case IncWithLines: + // fall through + case Include: + // fall through + case DontInclude: + parser()->readTextFileByName(m_file,m_text); + parser()->context.includeFileName = m_file; + parser()->context.includeFileText = m_text; + parser()->context.includeFileOffset = 0; + parser()->context.includeFileLength = m_text.length(); + parser()->context.includeFileLine = 0; + parser()->context.includeFileShowLineNo = (m_type == DontIncWithLines || m_type == IncWithLines); + //printf("parser->context.includeFile=<<%s>>\n",qPrint(parser->context.includeFileText)); + break; + case VerbInclude: + // fall through + case HtmlInclude: + case LatexInclude: + case DocInclude::RtfInclude: + case DocInclude::ManInclude: + case DocInclude::XmlInclude: + case DocInclude::DocbookInclude: + parser()->readTextFileByName(m_file,m_text); + break; + case Snippet: + case SnipWithLines: + parser()->readTextFileByName(m_file,m_text); + // check here for the existence of the blockId inside the file, so we + // only generate the warning once. + int count; + if (!m_blockId.isEmpty() && (count=m_text.contains(m_blockId.data()))!=2) + { + warn_doc_error(parser()->context.fileName, + parser()->tokenizer.getLineNr(), + "block marked with %s for \\snippet should appear twice in file %s, found it %d times\n", + qPrint(m_blockId),qPrint(m_file),count); + } + break; + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: + err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" + "Please create a bug report\n",__FILE__); + break; + } +} + +//--------------------------------------------------------------------------- + +void DocIncOperator::parse(DocNodeVariant *) +{ + if (parser()->context.includeFileName.isEmpty()) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(), + "No previous '\\include' or '\\dontinclude' command for '\\%s' present", + typeAsString()); + } + + m_includeFileName = parser()->context.includeFileName; + const char *p = parser()->context.includeFileText.data(); + uint l = parser()->context.includeFileLength; + uint o = parser()->context.includeFileOffset; + int il = parser()->context.includeFileLine; + DBG(("DocIncOperator::parse() text=%s off=%d len=%d\n",p,o,l)); + uint so = o,bo; + bool nonEmpty = FALSE; + switch(type()) + { + case Line: + while (o<l) + { + char c = p[o]; + if (c=='\n') + { + parser()->context.includeFileLine++; + if (nonEmpty) break; // we have a pattern to match + so=o+1; // no pattern, skip empty line + } + else if (!isspace(static_cast<uchar>(c))) // no white space char + { + nonEmpty=TRUE; + } + o++; + } + if (parser()->context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) + { + m_line = il; + m_text = parser()->context.includeFileText.mid(so,o-so); + DBG(("DocIncOperator::parse() Line: %s\n",qPrint(m_text))); + } + parser()->context.includeFileOffset = std::min(l,o+1); // set pointer to start of new line + m_showLineNo = parser()->context.includeFileShowLineNo; + break; + case SkipLine: + while (o<l) + { + so=o; + while (o<l) + { + char c = p[o]; + if (c=='\n') + { + parser()->context.includeFileLine++; + if (nonEmpty) break; // we have a pattern to match + so=o+1; // no pattern, skip empty line + } + else if (!isspace(static_cast<uchar>(c))) // no white space char + { + nonEmpty=TRUE; + } + o++; + } + if (parser()->context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) + { + m_line = il; + m_text = parser()->context.includeFileText.mid(so,o-so); + DBG(("DocIncOperator::parse() SkipLine: %s\n",qPrint(m_text))); + break; + } + o++; // skip new line + } + parser()->context.includeFileOffset = std::min(l,o+1); // set pointer to start of new line + m_showLineNo = parser()->context.includeFileShowLineNo; + break; + case Skip: + while (o<l) + { + so=o; + while (o<l) + { + char c = p[o]; + if (c=='\n') + { + parser()->context.includeFileLine++; + if (nonEmpty) break; // we have a pattern to match + so=o+1; // no pattern, skip empty line + } + else if (!isspace(static_cast<uchar>(c))) // no white space char + { + nonEmpty=TRUE; + } + o++; + } + if (parser()->context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) + { + break; + } + o++; // skip new line + } + parser()->context.includeFileOffset = so; // set pointer to start of new line + m_showLineNo = parser()->context.includeFileShowLineNo; + break; + case Until: + bo=o; + while (o<l) + { + so=o; + while (o<l) + { + char c = p[o]; + if (c=='\n') + { + parser()->context.includeFileLine++; + if (nonEmpty) break; // we have a pattern to match + so=o+1; // no pattern, skip empty line + } + else if (!isspace(static_cast<uchar>(c))) // no white space char + { + nonEmpty=TRUE; + } + o++; + } + if (parser()->context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) + { + m_line = il; + m_text = parser()->context.includeFileText.mid(bo,o-bo); + DBG(("DocIncOperator::parse() Until: %s\n",qPrint(m_text))); + break; + } + o++; // skip new line + } + parser()->context.includeFileOffset = std::min(l,o+1); // set pointer to start of new line + m_showLineNo = parser()->context.includeFileShowLineNo; + break; + } +} + +//--------------------------------------------------------------------------- + +DocXRefItem::DocXRefItem(DocParser *parser,DocNodeVariant *parent,int id,const QCString &key) : + DocCompoundNode(parser,parent), m_id(id), m_key(key), m_relPath(parser->context.relPath) +{ +} + +bool DocXRefItem::parse(DocNodeVariant *thisVariant) +{ + RefList *refList = RefListManager::instance().find(m_key); + if (refList && refList->isEnabled()) + { + RefItem *item = refList->find(m_id); + ASSERT(item!=0); + if (item) + { + if (parser()->context.memberDef && parser()->context.memberDef->name().at(0)=='@') + { + m_file = "@"; // can't cross reference anonymous enum + m_anchor = "@"; + } + else + { + m_file = refList->fileName(); + m_anchor = item->anchor(); + } + m_title = refList->sectionTitle(); + //printf("DocXRefItem: file=%s anchor=%s title=%s\n", + // qPrint(m_file),qPrint(m_anchor),qPrint(m_title)); + + if (!item->text().isEmpty()) + { + parser()->pushContext(); + parser()->internalValidatingParseDoc(thisVariant,children(),item->text()); + parser()->popContext(); + } + } + return TRUE; + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +DocFormula::DocFormula(DocParser *parser,DocNodeVariant *parent,int id) : DocNode(parser,parent), + m_relPath(parser->context.relPath) +{ + QCString text = FormulaManager::instance().findFormula(id); + if (!text.isEmpty()) + { + m_id = id; + m_name.sprintf("form_%d",m_id); + m_text = text; + } + else // wrong \_form#<n> command + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"Wrong formula id %d",id); + m_id = -1; + } +} + +//--------------------------------------------------------------------------- + +DocSecRefItem::DocSecRefItem(DocParser *parser,DocNodeVariant *parent,const QCString &target) : + DocCompoundNode(parser,parent), m_target(target), m_relPath(parser->context.relPath) +{ +} + +void DocSecRefItem::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocSecRefItem::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + parser()->tokenizer.setStateTitle(); + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"\\refitem"); + } + } + parser()->tokenizer.setStatePara(); + parser()->handlePendingStyleCommands(thisVariant,children()); + + if (!m_target.isEmpty()) + { + SrcLangExt lang = getLanguageFromFileName(m_target); + const SectionInfo *sec = SectionManager::instance().find(m_target); + if (sec==0 && lang==SrcLangExt_Markdown) // lookup as markdown file + { + sec = SectionManager::instance().find(markdownFileNameToId(m_target)); + } + if (sec) // ref to section or anchor + { + // set defaults + m_ref = sec->ref(); + m_file = stripKnownExtensions(sec->fileName()); + m_refType = Section; + m_anchor = sec->label(); + m_isSubPage = false; + // adjust if needed + switch (sec->type()) + { + case SectionType::Page: + { + PageDef *pd = Doxygen::pageLinkedMap->find(m_target); + m_isSubPage = pd && pd->hasParentPage(); + if (!m_isSubPage) + { + m_anchor=""; + } + } + break; + case SectionType::Anchor: + m_refType = Anchor; + break; + case SectionType::Table: + m_refType = Table; + break; + default: + break; + } + //printf("m_ref=%s,m_file=%s,type=%d\n", + // qPrint(m_ref),qPrint(m_file),m_refType); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"reference to unknown section %s", + qPrint(m_target)); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"reference to empty target"); + } + + DBG(("DocSecRefItem::parse() end\n")); +} + +//--------------------------------------------------------------------------- + +void DocSecRefList::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocSecRefList::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + int tok=parser()->tokenizer.lex(); + // skip white space + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // handle items + while (tok) + { + if (tok==TK_COMMAND_AT || tok == TK_COMMAND_BS) + { + const char *cmd_start = (tok==TK_COMMAND_AT ? "@" : "\\"); + switch (Mappers::cmdMapper->map(parser()->context.token->name)) + { + case CMD_SECREFITEM: + { + tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\refitem command"); + break; + } + tok=parser()->tokenizer.lex(); + if (tok!=TK_WORD && tok!=TK_LNKWORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of \\refitem", + DocTokenizer::tokToString(tok)); + break; + } + + auto vDocSecRefItem = children().append<DocSecRefItem>(parser(),thisVariant,parser()->context.token->name); + children().get_last<DocSecRefItem>()->parse(vDocSecRefItem); + } + break; + case CMD_ENDSECREFLIST: + goto endsecreflist; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Illegal command %s as part of a \\secreflist", + qPrint(cmd_start + parser()->context.token->name)); + goto endsecreflist; + } + } + else if (tok==TK_WHITESPACE) + { + // ignore whitespace + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected token %s inside section reference list", + DocTokenizer::tokToString(tok)); + goto endsecreflist; + } + tok=parser()->tokenizer.lex(); + } + +endsecreflist: + DBG(("DocSecRefList::parse() end\n")); +} + +//--------------------------------------------------------------------------- + +DocInternalRef::DocInternalRef(DocParser *parser,DocNodeVariant *parent,const QCString &ref) + : DocCompoundNode(parser,parent), m_relPath(parser->context.relPath) +{ + int i=ref.find('#'); + if (i!=-1) + { + m_anchor = ref.right(static_cast<int>(ref.length())-i-1); + m_file = ref.left(i); + } + else + { + m_file = ref; + } +} + +void DocInternalRef::parse(DocNodeVariant *thisVariant) +{ + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocInternalRef::parse() start\n")); + + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"\\ref"); + } + } + + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocInternalRef::parse() end\n")); +} + +//--------------------------------------------------------------------------- + +DocRef::DocRef(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &context) : + DocCompoundNode(parser,parent), m_refType(Unknown), m_isSubPage(FALSE) +{ + const Definition *compound = 0; + QCString anchor; + //printf("DocRef::DocRef(target=%s,context=%s)\n",qPrint(target),qPrint(context)); + ASSERT(!target.isEmpty()); + SrcLangExt lang = getLanguageFromFileName(target); + m_relPath = parser->context.relPath; + const SectionInfo *sec = SectionManager::instance().find(target); + if (sec==0 && lang==SrcLangExt_Markdown) // lookup as markdown file + { + sec = SectionManager::instance().find(markdownFileNameToId(target)); + } + if (sec) // ref to section or anchor + { + PageDef *pd = 0; + if (sec->type()==SectionType::Page) + { + pd = Doxygen::pageLinkedMap->find(target); + } + m_text = sec->title(); + if (m_text.isEmpty()) m_text = sec->label(); + + m_ref = sec->ref(); + m_file = stripKnownExtensions(sec->fileName()); + if (sec->type()==SectionType::Anchor) + { + m_refType = Anchor; + } + else if (sec->type()==SectionType::Table) + { + m_refType = Table; + } + else + { + m_refType = Section; + } + 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,type=%d\n", + // qPrint(m_text),qPrint(m_ref),qPrint(m_file),m_refType); + return; + } + else if (resolveLink(context,target,TRUE,&compound,anchor)) + { + bool isFile = compound ? + (compound->definitionType()==Definition::TypeFile || + compound->definitionType()==Definition::TypePage ? TRUE : FALSE) : + FALSE; + m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile); + m_anchor = anchor; + if (compound && compound->isLinkable()) // ref to compound + { + if (anchor.isEmpty() && /* compound link */ + compound->definitionType()==Definition::TypeGroup && /* is group */ + !toGroupDef(compound)->groupTitle().isEmpty() /* with title */ + ) + { + m_text=(toGroupDef(compound))->groupTitle(); // use group's title as link + } + else if (compound->definitionType()==Definition::TypeMember && + toMemberDef(compound)->isObjCMethod()) + { + // Objective C Method + const MemberDef *member = toMemberDef(compound); + bool localLink = parser->context.memberDef ? member->getClassDef()==parser->context.memberDef->getClassDef() : FALSE; + m_text = member->objCMethodName(localLink,parser->context.inSeeBlock); + } + + m_file = compound->getOutputFileBase(); + m_ref = compound->getReference(); + //printf("isFile=%d compound=%s (%d)\n",isFile,qPrint(compound->name()), + // compound->definitionType()); + return; + } + else if (compound && compound->definitionType()==Definition::TypeFile && + toFileDef(compound)->generateSourceFile() + ) // undocumented file that has source code we can link to + { + m_file = compound->getSourceFileBase(); + m_ref = compound->getReference(); + return; + } + } + m_text = target; + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"unable to resolve reference to '%s' for \\ref command", + qPrint(target)); +} + +static void flattenParagraphs(DocNodeVariant *root,DocNodeList &children) +{ + DocNodeList newChildren; + for (auto &dn : children) + { + DocPara *para = std::get_if<DocPara>(&dn); + if (para) + { + //// move the children of the paragraph to the end of the newChildren list + newChildren.move_append(para->children()); + } + } + + // replace the children list by the newChildren list + children.clear(); + children.move_append(newChildren); + // reparent the children + for (auto &cn : children) + { + setParent(&cn,root); + } +} + +void DocRef::parse(DocNodeVariant *thisVariant) +{ + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocRef::parse() start\n")); + + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + switch (tok) + { + case TK_HTMLTAG: + break; + default: + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"\\ref"); + break; + } + } + } + + if (children().empty() && !m_text.isEmpty()) + { + parser()->context.insideHtmlLink=TRUE; + parser()->pushContext(); + parser()->internalValidatingParseDoc(thisVariant,children(),m_text); + parser()->popContext(); + parser()->context.insideHtmlLink=FALSE; + flattenParagraphs(thisVariant,children()); + } + + parser()->handlePendingStyleCommands(thisVariant,children()); +} + +//--------------------------------------------------------------------------- + +DocCite::DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &) : DocNode(parser,parent) +{ + size_t numBibFiles = Config_getList(CITE_BIB_FILES).size(); + //printf("DocCite::DocCite(target=%s)\n",qPrint(target)); + ASSERT(!target.isEmpty()); + m_relPath = parser->context.relPath; + const CitationManager &ct = CitationManager::instance(); + const CiteInfo *cite = ct.find(target); + //printf("cite=%p text='%s' numBibFiles=%d\n",cite,cite?qPrint(cite->text):"<null>",numBibFiles); + if (numBibFiles>0 && cite && !cite->text().isEmpty()) // ref to citation + { + m_text = cite->text(); + m_ref = ""; + m_anchor = ct.anchorPrefix()+cite->label(); + m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); + //printf("CITE ==> m_text=%s,m_ref=%s,m_file=%s,m_anchor=%s\n", + // qPrint(m_text),qPrint(m_ref),qPrint(m_file),qPrint(m_anchor)); + return; + } + m_text = target; + if (numBibFiles==0) + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"\\cite command found but no bib files specified via CITE_BIB_FILES!"); + } + else if (cite==0) + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"unable to resolve reference to '%s' for \\cite command", + qPrint(target)); + } + else + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"\\cite command to '%s' does not have an associated number", + qPrint(target)); + } +} + +//--------------------------------------------------------------------------- + +DocLink::DocLink(DocParser *parser,DocNodeVariant *parent,const QCString &target) : DocCompoundNode(parser,parent) +{ + const Definition *compound = 0; + QCString anchor; + m_refText = target; + m_relPath = parser->context.relPath; + if (!m_refText.isEmpty() && m_refText.at(0)=='#') + { + m_refText = m_refText.right(m_refText.length()-1); + } + if (resolveLink(parser->context.context,stripKnownExtensions(target),parser->context.inSeeBlock,&compound,anchor)) + { + m_anchor = anchor; + if (compound && compound->isLinkable()) + { + m_file = compound->getOutputFileBase(); + m_ref = compound->getReference(); + } + else if (compound && compound->definitionType()==Definition::TypeFile && + (toFileDef(compound))->generateSourceFile() + ) // undocumented file that has source code we can link to + { + m_file = compound->getSourceFileBase(); + m_ref = compound->getReference(); + } + return; + } + + // bogus link target + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"unable to resolve link to '%s' for \\link command", + qPrint(target)); +} + + +QCString DocLink::parse(DocNodeVariant *thisVariant,bool isJavaLink,bool isXmlLink) +{ + QCString result; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocLink::parse() start\n")); + + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children(),FALSE)) + { + const char *cmd_start = "\\"; + switch (tok) + { + case TK_COMMAND_AT: + cmd_start = "@"; + // fall through + case TK_COMMAND_BS: + switch (Mappers::cmdMapper->map(parser()->context.token->name)) + { + case CMD_ENDLINK: + if (isJavaLink) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"{@link.. ended with @endlink command"); + } + goto endlink; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Illegal command %s as part of a \\link", + qPrint(cmd_start + parser()->context.token->name)); + break; + } + break; + case TK_SYMBOL: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unsupported symbol %s found as part of a \\link", + qPrint(parser()->context.token->name)); + break; + case TK_HTMLTAG: + if (parser()->context.token->name!="see" || !isXmlLink) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected xml/html command %s found as part of a \\link", + qPrint(parser()->context.token->name)); + } + goto endlink; + case TK_LNKWORD: + case TK_WORD: + if (isJavaLink) // special case to detect closing } + { + QCString w = parser()->context.token->name; + int p; + if (w=="}") + { + goto endlink; + } + else if ((p=w.find('}'))!=-1) + { + uint l=w.length(); + children().append<DocWord>(parser(),thisVariant,w.left(p)); + if (static_cast<uint>(p)<l-1) // something left after the } (for instance a .) + { + result=w.right(static_cast<int>(l)-p-1); + } + goto endlink; + } + } + children().append<DocWord>(parser(),thisVariant,parser()->context.token->name); + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected token %s", + DocTokenizer::tokToString(tok)); + break; + } + } + } + if (tok==0) + { + warn_doc_error(parser()->context.fileName, + parser()->tokenizer.getLineNr(), + "Unexpected end of comment while inside link command\n"); + } +endlink: + + if (children().empty()) // no link text + { + children().append<DocWord>(parser(),thisVariant,m_refText); + } + + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocLink::parse() end\n")); + return result; +} + + +//--------------------------------------------------------------------------- + +DocDotFile::DocDotFile(DocParser *parser,DocNodeVariant *parent,const QCString &name,const QCString &context, + const QCString &srcFile,int srcLine) : + DocDiagramFileBase(parser,parent,name,context,srcFile,srcLine) +{ + p->relPath = parser->context.relPath; +} + +bool DocDotFile::parse(DocNodeVariant *thisVariant) +{ + bool ok = false; + parser()->defaultHandleTitleAndSize(CMD_DOTFILE,thisVariant,children(),p->width,p->height); + + bool ambig; + FileDef *fd = findFileDef(Doxygen::dotFileNameLinkedMap,p->name,ambig); + if (fd==0 && p->name.right(4)!=".dot") // try with .dot extension as well + { + fd = findFileDef(Doxygen::dotFileNameLinkedMap,p->name+".dot",ambig); + } + if (fd) + { + p->file = fd->absFilePath(); + ok = true; + if (ambig) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"included dot file name %s is ambiguous.\n" + "Possible candidates:\n%s",qPrint(p->name), + qPrint(showFileDefMatches(Doxygen::dotFileNameLinkedMap,p->name)) + ); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"included dot file %s is not found " + "in any of the paths specified via DOTFILE_DIRS!",qPrint(p->name)); + } + return ok; +} + +DocMscFile::DocMscFile(DocParser *parser,DocNodeVariant *parent,const QCString &name,const QCString &context, + const QCString &srcFile, int srcLine) : + DocDiagramFileBase(parser,parent,name,context,srcFile,srcLine) +{ + p->relPath = parser->context.relPath; +} + +bool DocMscFile::parse(DocNodeVariant *thisVariant) +{ + bool ok = false; + parser()->defaultHandleTitleAndSize(CMD_MSCFILE,thisVariant,children(),p->width,p->height); + + bool ambig; + FileDef *fd = findFileDef(Doxygen::mscFileNameLinkedMap,p->name,ambig); + if (fd==0 && p->name.right(4)!=".msc") // try with .msc extension as well + { + fd = findFileDef(Doxygen::mscFileNameLinkedMap,p->name+".msc",ambig); + } + if (fd) + { + p->file = fd->absFilePath(); + ok = true; + if (ambig) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"included msc file name %s is ambiguous.\n" + "Possible candidates:\n%s",qPrint(p->name), + qPrint(showFileDefMatches(Doxygen::mscFileNameLinkedMap,p->name)) + ); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"included msc file %s is not found " + "in any of the paths specified via MSCFILE_DIRS!",qPrint(p->name)); + } + return ok; +} + +//--------------------------------------------------------------------------- + +DocDiaFile::DocDiaFile(DocParser *parser,DocNodeVariant *parent,const QCString &name,const QCString &context, + const QCString &srcFile,int srcLine) : + DocDiagramFileBase(parser,parent,name,context,srcFile,srcLine) +{ + p->relPath = parser->context.relPath; +} + +bool DocDiaFile::parse(DocNodeVariant *thisVariant) +{ + bool ok = false; + parser()->defaultHandleTitleAndSize(CMD_DIAFILE,thisVariant,children(),p->width,p->height); + + bool ambig; + FileDef *fd = findFileDef(Doxygen::diaFileNameLinkedMap,p->name,ambig); + if (fd==0 && p->name.right(4)!=".dia") // try with .dia extension as well + { + fd = findFileDef(Doxygen::diaFileNameLinkedMap,p->name+".dia",ambig); + } + if (fd) + { + p->file = fd->absFilePath(); + ok = true; + if (ambig) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"included dia file name %s is ambiguous.\n" + "Possible candidates:\n%s",qPrint(p->name), + qPrint(showFileDefMatches(Doxygen::diaFileNameLinkedMap,p->name)) + ); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"included dia file %s is not found " + "in any of the paths specified via DIAFILE_DIRS!",qPrint(p->name)); + } + return ok; +} + +//--------------------------------------------------------------------------- + +DocVhdlFlow::DocVhdlFlow(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) +{ +} + +void DocVhdlFlow::parse(DocNodeVariant *thisVariant) +{ + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocVhdlFlow::parse() start\n")); + + parser()->tokenizer.setStateTitle(); + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"\\vhdlflow"); + } + } + tok=parser()->tokenizer.lex(); + + parser()->tokenizer.setStatePara(); + parser()->handlePendingStyleCommands(thisVariant,children()); + + DBG(("DocVhdlFlow::parse() end\n")); + VhdlDocGen::createFlowChart(parser()->context.memberDef); +} + + +//--------------------------------------------------------------------------- + +DocImage::DocImage(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs,const QCString &name, + Type t,const QCString &url, bool inlineImage) : + DocCompoundNode(parser,parent), p(std::make_unique<Private>(attribs, name, t, parser->context.relPath, url, inlineImage)) +{ +} + +bool DocImage::isSVG() const +{ + QCString locName = p->url.isEmpty() ? p->name : p->url; + int len = static_cast<int>(locName.length()); + int fnd = locName.find('?'); // ignore part from ? until end + if (fnd==-1) fnd=len; + return fnd>=4 && locName.mid(fnd-4,4)==".svg"; +} + +void DocImage::parse(DocNodeVariant *thisVariant) +{ + parser()->defaultHandleTitleAndSize(CMD_IMAGE,thisVariant,children(),p->width,p->height); +} + + +//--------------------------------------------------------------------------- + +int DocHtmlHeader::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlHeader::parse() start\n")); + + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + switch (tok) + { + case TK_HTMLTAG: + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_H1 && parser()->context.token->endTag) // found </h1> tag + { + if (m_level!=1) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"<h%d> ended with </h1>", + m_level); + } + goto endheader; + } + else if (tagId==HTML_H2 && parser()->context.token->endTag) // found </h2> tag + { + if (m_level!=2) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"<h%d> ended with </h2>", + m_level); + } + goto endheader; + } + else if (tagId==HTML_H3 && parser()->context.token->endTag) // found </h3> tag + { + if (m_level!=3) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"<h%d> ended with </h3>", + m_level); + } + goto endheader; + } + else if (tagId==HTML_H4 && parser()->context.token->endTag) // found </h4> tag + { + if (m_level!=4) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"<h%d> ended with </h4>", + m_level); + } + goto endheader; + } + else if (tagId==HTML_H5 && parser()->context.token->endTag) // found </h5> tag + { + if (m_level!=5) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"<h%d> ended with </h5>", + m_level); + } + goto endheader; + } + else if (tagId==HTML_H6 && parser()->context.token->endTag) // found </h6> tag + { + if (m_level!=6) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"<h%d> ended with </h6>", + m_level); + } + goto endheader; + } + else if (tagId==HTML_A) + { + if (!parser()->context.token->endTag) + { + parser()->handleAHref(thisVariant,children(),parser()->context.token->attribs); + } + } + else if (tagId==HTML_BR) + { + children().append<DocLineBreak>(parser(),thisVariant,parser()->context.token->attribs); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <h%d> context", + parser()->context.token->endTag?"/":"",qPrint(parser()->context.token->name),m_level); + } + } + break; + default: + char tmp[20]; + sprintf(tmp,"<h%d>tag",m_level); + parser()->errorHandleDefaultToken(thisVariant,tok,children(),tmp); + } + } + } + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected end of comment while inside" + " <h%d> tag\n",m_level); + } +endheader: + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocHtmlHeader::parse() end\n")); + return retval; +} +//--------------------------------------------------------------------------- + +int DocHRef::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHRef::parse() start\n")); + + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + switch (tok) + { + case TK_HTMLTAG: + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_A && parser()->context.token->endTag) // found </a> tag + { + goto endhref; + } + else if (tagId==HTML_BR) + { + children().append<DocLineBreak>(parser(),thisVariant,parser()->context.token->attribs); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <a href=...> context", + parser()->context.token->endTag?"/":"",qPrint(parser()->context.token->name)); + } + } + break; + default: + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"<a>..</a> block"); + break; + } + } + } + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected end of comment while inside" + " <a href=...> tag"); + } +endhref: + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocHRef::parse() end\n")); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocInternal::parse(DocNodeVariant *thisVariant,int level) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocInternal::parse() start\n")); + + // first parse any number of paragraphs + bool isFirst=TRUE; + DocPara *lastPar=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + DocPara *par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (!par->isEmpty()) + { + if (lastPar) lastPar->markLast(FALSE); + lastPar=par; + } + else + { + children().pop_back(); + } + if (retval==TK_LISTITEM) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid list item found"); + } + } while (retval!=0 && + retval!=RetVal_Section && + retval!=RetVal_Subsection && + retval!=RetVal_Subsubsection && + retval!=RetVal_Paragraph && + retval!=RetVal_EndInternal + ); + if (lastPar) lastPar->markLast(); + + // then parse any number of level-n sections + while ((level==1 && retval==RetVal_Section) || + (level==2 && retval==RetVal_Subsection) || + (level==3 && retval==RetVal_Subsubsection) || + (level==4 && retval==RetVal_Paragraph) + ) + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(level+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + + if (retval==RetVal_Internal) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"\\internal command found inside internal section"); + } + + DBG(("DocInternal::parse() end: retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocIndexEntry::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocIndexEntry::parse() start\n")); + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\addindex command"); + goto endindexentry; + } + parser()->tokenizer.setStateTitle(); + m_entry=""; + while ((tok=parser()->tokenizer.lex())) + { + switch (tok) + { + case TK_WHITESPACE: + m_entry+=" "; + break; + case TK_WORD: + case TK_LNKWORD: + m_entry+=parser()->context.token->name; + break; + case TK_SYMBOL: + { + HtmlEntityMapper::SymType s = DocSymbol::decodeSymbol(parser()->context.token->name); + switch (s) + { + case HtmlEntityMapper::Sym_BSlash: m_entry+='\\'; break; + case HtmlEntityMapper::Sym_At: m_entry+='@'; break; + case HtmlEntityMapper::Sym_Less: m_entry+='<'; break; + case HtmlEntityMapper::Sym_Greater: m_entry+='>'; break; + case HtmlEntityMapper::Sym_Amp: m_entry+='&'; break; + case HtmlEntityMapper::Sym_Dollar: m_entry+='$'; break; + case HtmlEntityMapper::Sym_Hash: m_entry+='#'; break; + case HtmlEntityMapper::Sym_Percent: m_entry+='%'; break; + case HtmlEntityMapper::Sym_apos: m_entry+='\''; break; + case HtmlEntityMapper::Sym_Quot: m_entry+='"'; break; + case HtmlEntityMapper::Sym_lsquo: m_entry+='`'; break; + case HtmlEntityMapper::Sym_rsquo: m_entry+='\''; break; + case HtmlEntityMapper::Sym_ldquo: m_entry+="``"; break; + case HtmlEntityMapper::Sym_rdquo: m_entry+="''"; break; + case HtmlEntityMapper::Sym_ndash: m_entry+="--"; break; + case HtmlEntityMapper::Sym_mdash: m_entry+="---"; break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected symbol found as argument of \\addindex"); + break; + } + } + break; + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + switch (Mappers::cmdMapper->map(parser()->context.token->name)) + { + case CMD_BSLASH: m_entry+='\\'; break; + case CMD_AT: m_entry+='@'; break; + case CMD_LESS: m_entry+='<'; break; + case CMD_GREATER: m_entry+='>'; break; + case CMD_AMP: m_entry+='&'; break; + case CMD_DOLLAR: m_entry+='$'; break; + case CMD_HASH: m_entry+='#'; break; + case CMD_DCOLON: m_entry+="::"; break; + case CMD_PERCENT: m_entry+='%'; break; + case CMD_NDASH: m_entry+="--"; break; + case CMD_MDASH: m_entry+="---"; break; + case CMD_QUOTE: m_entry+='"'; break; + case CMD_PUNT: m_entry+='.'; break; + case CMD_PLUS: m_entry+='+'; break; + case CMD_MINUS: m_entry+='-'; break; + case CMD_EQUAL: m_entry+='='; break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected command %s found as argument of \\addindex", + qPrint(parser()->context.token->name)); + break; + } + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected token %s", + DocTokenizer::tokToString(tok)); + break; + } + } + parser()->tokenizer.setStatePara(); + m_entry = m_entry.stripWhiteSpace(); +endindexentry: + DBG(("DocIndexEntry::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval; +} + +//--------------------------------------------------------------------------- + +DocHtmlCaption::DocHtmlCaption(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) + : DocCompoundNode(parser,parent) +{ + m_hasCaptionId = FALSE; + for (const auto &opt : attribs) + { + if (opt.name=="id" && !opt.value.isEmpty()) // interpret id attribute as an anchor + { + const SectionInfo *sec = SectionManager::instance().find(opt.value); + if (sec) + { + //printf("Found anchor %s\n",qPrint(id)); + m_file = sec->fileName(); + m_anchor = sec->label(); + m_hasCaptionId = TRUE; + } + else + { + warn_doc_error(parser->context.fileName,parser->tokenizer.getLineNr(),"Invalid caption id '%s'",qPrint(opt.value)); + } + } + else // copy attribute + { + m_attribs.push_back(opt); + } + } +} + +int DocHtmlCaption::parse(DocNodeVariant *thisVariant) +{ + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlCaption::parse() start\n")); + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + switch (tok) + { + case TK_HTMLTAG: + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_CAPTION && parser()->context.token->endTag) // found </caption> tag + { + retval = RetVal_OK; + goto endcaption; + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <caption> context", + parser()->context.token->endTag?"/":"",qPrint(parser()->context.token->name)); + } + } + break; + default: + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"<caption> tag"); + break; + } + } + } + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected end of comment while inside" + " <caption> tag"); + } +endcaption: + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocHtmlCaption::parse() end\n")); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlCell::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlCell::parse() start\n")); + + // parse one or more paragraphs + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (retval==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_TD && parser()->context.token->endTag) // found </td> tag + { + retval=TK_NEWPARA; // ignore the tag + } + else if (tagId==HTML_TH && parser()->context.token->endTag) // found </th> tag + { + retval=TK_NEWPARA; // ignore the tag + } + } + } + while ((retval==TK_NEWPARA) || (retval==RetVal_EndParBlock)); + if (par) par->markLast(); + + DBG(("DocHtmlCell::parse() end\n")); + return retval; +} + +int DocHtmlCell::parseXml(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlCell::parseXml() start\n")); + + // parse one or more paragraphs + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (retval==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==XML_ITEM && parser()->context.token->endTag) // found </item> tag + { + retval=TK_NEWPARA; // ignore the tag + } + else if (tagId==XML_DESCRIPTION && parser()->context.token->endTag) // found </description> tag + { + retval=TK_NEWPARA; // ignore the tag + } + } + } + while (retval==TK_NEWPARA); + if (par) par->markLast(); + + DBG(("DocHtmlCell::parseXml() end\n")); + return retval; +} + +uint DocHtmlCell::rowSpan() const +{ + for (const auto &attr : attribs()) + { + if (attr.name.lower()=="rowspan") + { + return attr.value.toUInt(); + } + } + return 0; +} + +uint DocHtmlCell::colSpan() const +{ + for (const auto &attr : attribs()) + { + if (attr.name.lower()=="colspan") + { + return std::max(1u,attr.value.toUInt()); + } + } + return 1; +} + +DocHtmlCell::Alignment DocHtmlCell::alignment() const +{ + for (const auto &attr : attribs()) + { + QCString attrName = attr.name.lower(); + QCString attrValue = attr.value.lower(); + if (attrName=="align") + { + if (attrValue=="center") + return Center; + else if (attrValue=="right") + return Right; + else return Left; + } + else if (attrName=="class" && attrValue.startsWith("markdowntable")) + { + if (attrValue=="markdowntableheadcenter") + return Center; + else if (attrValue=="markdowntableheadright") + return Right; + else if (attrValue=="markdowntableheadleft") + return Left; + else if (attrValue=="markdowntableheadnone") + return Center; + else if (attrValue=="markdowntablebodycenter") + return Center; + else if (attrValue=="markdowntablebodyright") + return Right; + else if (attrValue=="markdowntablebodyleft") + return Left; + else if (attrValue=="markdowntablebodynone") + return Left; + else return Left; + } + } + return Left; +} + +DocHtmlCell::Valignment DocHtmlCell::valignment() const +{ + for (const auto &attr : attribs()) + { + QCString attrName = attr.name.lower(); + QCString attrValue = attr.value.lower(); + if (attrName=="valign") + { + if (attrValue=="top") + return Top; + else if (attrValue=="bottom") + return Bottom; + else if (attrValue=="middle") + return Middle; + else return Middle; + } + } + return Middle; +} + +//--------------------------------------------------------------------------- + +bool DocHtmlRow::isHeading() const +{ // a row is a table heading if all cells are marked as such + bool heading=TRUE; + for (const auto &n : children()) + { + const DocHtmlCell *cell = std::get_if<DocHtmlCell>(&n); + if (cell && !cell->isHeading()) + { + heading = FALSE; + break; + } + } + return !children().empty() && heading; +} + +int DocHtmlRow::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlRow::parse() start\n")); + + bool isHeading=FALSE; + bool isFirst=TRUE; + DocHtmlCell *cell=0; + + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_TD && !parser()->context.token->endTag) // found <td> tag + { + } + else if (tagId==HTML_TH && !parser()->context.token->endTag) // found <th> tag + { + isHeading=TRUE; + } + else // found some other tag + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <td> or <th> tag but " + "found <%s> instead!",qPrint(parser()->context.token->name)); + parser()->tokenizer.pushBackHtmlTag(parser()->context.token->name); + goto endrow; + } + } + else if (tok==0) // premature end of comment + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while looking" + " for a html description title"); + goto endrow; + } + else // token other than html token + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <td> or <th> tag but found %s token instead!", + DocTokenizer::tokToString(tok)); + goto endrow; + } + + // parse one or more cells + do + { + auto vDocHtmlCell = children().append<DocHtmlCell>(parser(),thisVariant, + parser()->context.token->attribs, + isHeading); + cell = children().get_last<DocHtmlCell>(); + cell->markFirst(isFirst); + isFirst=FALSE; + retval=cell->parse(vDocHtmlCell); + isHeading = retval==RetVal_TableHCell; + } + while (retval==RetVal_TableCell || retval==RetVal_TableHCell); + cell->markLast(TRUE); + +endrow: + DBG(("DocHtmlRow::parse() end\n")); + return retval; +} + +int DocHtmlRow::parseXml(DocNodeVariant *thisVariant,bool isHeading) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlRow::parseXml() start\n")); + + bool isFirst=TRUE; + DocHtmlCell *cell=0; + + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==XML_TERM && !parser()->context.token->endTag) // found <term> tag + { + } + else if (tagId==XML_DESCRIPTION && !parser()->context.token->endTag) // found <description> tag + { + } + else // found some other tag + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <term> or <description> tag but " + "found <%s> instead!",qPrint(parser()->context.token->name)); + parser()->tokenizer.pushBackHtmlTag(parser()->context.token->name); + goto endrow; + } + } + else if (tok==0) // premature end of comment + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while looking" + " for a html description title"); + goto endrow; + } + else // token other than html token + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <td> or <th> tag but found %s token instead!", + DocTokenizer::tokToString(tok)); + goto endrow; + } + + do + { + auto vDocHtmlCell = children().append<DocHtmlCell>(parser(),thisVariant,parser()->context.token->attribs,isHeading); + cell = children().get_last<DocHtmlCell>(); + cell->markFirst(isFirst); + isFirst=FALSE; + retval=cell->parseXml(vDocHtmlCell); + } + while (retval==RetVal_TableCell || retval==RetVal_TableHCell); + cell->markLast(TRUE); + +endrow: + DBG(("DocHtmlRow::parseXml() end\n")); + return retval; +} + +//--------------------------------------------------------------------------- + +bool DocHtmlTable::hasCaption() const +{ + return m_caption!=nullptr; +} + +const DocNodeVariant *DocHtmlTable::caption() const +{ + return m_caption.get(); +} + +const DocNodeVariant *DocHtmlTable::firstRow() const +{ + if (!children().empty() && std::holds_alternative<DocHtmlRow>(children().front())) + { + return &children().front(); + } + return 0; +} + +int DocHtmlTable::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlTable::parse() start\n")); + +getrow: + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_TR && !parser()->context.token->endTag) // found <tr> tag + { + // no caption, just rows + retval=RetVal_TableRow; + } + else if (tagId==HTML_CAPTION && !parser()->context.token->endTag) // found <caption> tag + { + if (m_caption) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"table already has a caption, found another one"); + } + else + { + m_caption = std::make_unique<DocNodeVariant>( + DocHtmlCaption(parser(),thisVariant,parser()->context.token->attribs)); + retval=std::get<DocHtmlCaption>(*m_caption).parse(m_caption.get()); + + if (retval==RetVal_OK) // caption was parsed ok + { + goto getrow; + } + } + } + else // found wrong token + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <tr> or <caption> tag but " + "found <%s%s> instead!", parser()->context.token->endTag ? "/" : "", qPrint(parser()->context.token->name)); + } + } + else if (tok==0) // premature end of comment + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while looking" + " for a <tr> or <caption> tag"); + } + else // token other than html token + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <tr> tag but found %s token instead!", + DocTokenizer::tokToString(tok)); + } + + // parse one or more rows + while (retval==RetVal_TableRow) + { + auto vDocHtmlRow = children().append<DocHtmlRow>(parser(),thisVariant,parser()->context.token->attribs); + retval = children().get_last<DocHtmlRow>()->parse(vDocHtmlRow); + } + + computeTableGrid(); + + DBG(("DocHtmlTable::parse() end\n")); + return retval==RetVal_EndTable ? RetVal_OK : retval; +} + +int DocHtmlTable::parseXml(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlTable::parseXml() start\n")); + + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + int tagId=0; + bool isHeader=FALSE; + if (tok==TK_HTMLTAG) + { + tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==XML_ITEM && !parser()->context.token->endTag) // found <item> tag + { + retval=RetVal_TableRow; + } + if (tagId==XML_LISTHEADER && !parser()->context.token->endTag) // found <listheader> tag + { + retval=RetVal_TableRow; + isHeader=TRUE; + } + } + + // parse one or more rows + while (retval==RetVal_TableRow) + { + auto vDocHtmlRow = children().append<DocHtmlRow>(parser(),thisVariant,parser()->context.token->attribs); + DocHtmlRow *tr = children().get_last<DocHtmlRow>(); + retval=tr->parseXml(vDocHtmlRow,isHeader); + isHeader=FALSE; + } + + computeTableGrid(); + + DBG(("DocHtmlTable::parseXml() end\n")); + tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + return tagId==XML_LIST && parser()->context.token->endTag ? RetVal_OK : retval; +} + +/** Helper class to compute the grid for an HTML style table */ +struct ActiveRowSpan +{ + ActiveRowSpan(uint rows,uint col) : rowsLeft(rows), column(col) {} + uint rowsLeft; + uint column; +}; + +/** List of ActiveRowSpan classes. */ +typedef std::vector<ActiveRowSpan> RowSpanList; + +/** determines the location of all cells in a grid, resolving row and + column spans. For each the total number of visible cells is computed, + and the total number of visible columns over all rows is stored. + */ +void DocHtmlTable::computeTableGrid() +{ + //printf("computeTableGrid()\n"); + RowSpanList rowSpans; + uint maxCols=0; + uint rowIdx=1; + for (auto &rowNode : children()) + { + uint colIdx=1; + uint cells=0; + DocHtmlRow *row = std::get_if<DocHtmlRow>(&rowNode); + if (row) + { + size_t i; + for (auto &cellNode : row->children()) + { + DocHtmlCell *cell = std::get_if<DocHtmlCell>(&cellNode); + if (cell) + { + uint rs = cell->rowSpan(); + uint cs = cell->colSpan(); + + for (i=0;i<rowSpans.size();i++) + { + if (rowSpans[i].rowsLeft>0 && + rowSpans[i].column==colIdx) + { + colIdx=rowSpans[i].column+1; + cells++; + } + } + if (rs>0) rowSpans.emplace_back(rs,colIdx); + //printf("found cell at (%d,%d)\n",rowIdx,colIdx); + cell->setRowIndex(rowIdx); + cell->setColumnIndex(colIdx); + colIdx+=cs; + cells++; + } + } + for (i=0;i<rowSpans.size();i++) + { + if (rowSpans[i].rowsLeft>0) rowSpans[i].rowsLeft--; + } + row->setVisibleCells(cells); + row->setRowIndex(rowIdx); + rowIdx++; + } + if (colIdx-1>maxCols) maxCols=colIdx-1; + } + m_numCols = maxCols; +} + +//--------------------------------------------------------------------------- + +int DocHtmlDescTitle::parse(DocNodeVariant *thisVariant) +{ + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlDescTitle::parse() start\n")); + + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + const char *cmd_start = "\\"; + switch (tok) + { + case TK_COMMAND_AT: + cmd_start = "@"; + // fall through + case TK_COMMAND_BS: + { + QCString cmdName=parser()->context.token->name; + bool isJavaLink=FALSE; + switch (Mappers::cmdMapper->map(cmdName)) + { + case CMD_REF: + { + tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(parser()->context.token->name)); + } + else + { + parser()->tokenizer.setStateRef(); + tok=parser()->tokenizer.lex(); // get the reference id + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of \\%s command", + DocTokenizer::tokToString(tok),qPrint(cmdName)); + } + else + { + auto vDocRef = children().append<DocRef>(parser(),thisVariant,parser()->context.token->name,parser()->context.context); + children().get_last<DocRef>()->parse(vDocRef); + } + parser()->tokenizer.setStatePara(); + } + } + break; + case CMD_JAVALINK: + isJavaLink=TRUE; + // fall through + case CMD_LINK: + { + tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(cmdName)); + } + else + { + parser()->tokenizer.setStateLink(); + tok=parser()->tokenizer.lex(); + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of \\%s command", + DocTokenizer::tokToString(tok),qPrint(cmdName)); + } + else + { + parser()->tokenizer.setStatePara(); + auto vDocLink = children().append<DocLink>(parser(),thisVariant,parser()->context.token->name); + DocLink *lnk = children().get_last<DocLink>(); + QCString leftOver = lnk->parse(vDocLink,isJavaLink); + if (!leftOver.isEmpty()) + { + children().append<DocWord>(parser(),thisVariant,leftOver); + } + } + } + } + + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Illegal command %s found as part of a <dt> tag", + qPrint(cmd_start + parser()->context.token->name)); + } + } + break; + case TK_SYMBOL: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unsupported symbol \\%s found as part of a <dt> tag", + qPrint(parser()->context.token->name)); + break; + case TK_HTMLTAG: + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_DD && !parser()->context.token->endTag) // found <dd> tag + { + retval = RetVal_DescData; + goto endtitle; + } + else if (tagId==HTML_DT && parser()->context.token->endTag) + { + // ignore </dt> tag. + } + else if (tagId==HTML_DT) + { + // missing <dt> tag. + retval = RetVal_DescTitle; + goto endtitle; + } + else if (tagId==HTML_DL && parser()->context.token->endTag) + { + retval=RetVal_EndDesc; + goto endtitle; + } + else if (tagId==HTML_A) + { + if (!parser()->context.token->endTag) + { + parser()->handleAHref(thisVariant,children(),parser()->context.token->attribs); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <dt> context", + parser()->context.token->endTag?"/":"",qPrint(parser()->context.token->name)); + } + } + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected token %s found as part of a <dt> tag", + DocTokenizer::tokToString(tok)); + break; + } + } + } + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected end of comment while inside" + " <dt> tag"); + } +endtitle: + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocHtmlDescTitle::parse() end\n")); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlDescData::parse(DocNodeVariant *thisVariant) +{ + m_attribs = parser()->context.token->attribs; + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlDescData::parse() start\n")); + + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + } + while (retval==TK_NEWPARA); + if (par) par->markLast(); + + DBG(("DocHtmlDescData::parse() end\n")); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlDescList::parse(DocNodeVariant *thisVariant) +{ + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + DBG(("DocHtmlDescList::parse() start\n")); + + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_DT && !parser()->context.token->endTag) // found <dt> tag + { + // continue + } + else // found some other tag + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <dt> tag but " + "found <%s> instead!",qPrint(parser()->context.token->name)); + parser()->tokenizer.pushBackHtmlTag(parser()->context.token->name); + goto enddesclist; + } + } + else if (tok==0) // premature end of comment + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while looking" + " for a html description title"); + goto enddesclist; + } + else // token other than html token + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <dt> tag but found %s token instead!", + DocTokenizer::tokToString(tok)); + goto enddesclist; + } + + do + { + auto vDocHtmlDescTitle = children().append<DocHtmlDescTitle>(parser(),thisVariant,parser()->context.token->attribs); + DocHtmlDescTitle *dt = children().get_last<DocHtmlDescTitle>(); + auto vDocHtmlDescData = children().append<DocHtmlDescData>(parser(),thisVariant); + DocHtmlDescData *dd = children().get_last<DocHtmlDescData>(); + retval=dt->parse(vDocHtmlDescTitle); + if (retval==RetVal_DescData) + { + retval=dd->parse(vDocHtmlDescData); + } + else if (retval!=RetVal_DescTitle) + { + // error + break; + } + } while (retval==RetVal_DescTitle); + + if (retval==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while inside <dl> block"); + } + +enddesclist: + + DBG(("DocHtmlDescList::parse() end\n")); + return retval==RetVal_EndDesc ? RetVal_OK : retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlListItem::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocHtmlListItem::parse() start\n")); + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + + // parse one or more paragraphs + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + } + while (retval==TK_NEWPARA); + if (par) par->markLast(); + + DBG(("DocHtmlListItem::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval; +} + +int DocHtmlListItem::parseXml(DocNodeVariant *thisVariant) +{ + DBG(("DocHtmlListItem::parseXml() start\n")); + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + + // parse one or more paragraphs + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (retval==0) break; + + //printf("new item: retval=%x parser()->context.token->name=%s parser()->context.token->endTag=%d\n", + // retval,qPrint(parser()->context.token->name),parser()->context.token->endTag); + if (retval==RetVal_ListItem) + { + break; + } + } + while (retval!=RetVal_CloseXml); + + if (par) par->markLast(); + + DBG(("DocHtmlListItem::parseXml() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlList::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocHtmlList::parse() start\n")); + int retval=RetVal_OK; + int num=1; + auto ns = AutoNodeStack(parser(),thisVariant); + + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace and paragraph breaks + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + if (tagId==HTML_LI && !parser()->context.token->endTag) // found <li> tag + { + // ok, we can go on. + } + else if (((m_type==Unordered && tagId==HTML_UL) || + (m_type==Ordered && tagId==HTML_OL) + ) && parser()->context.token->endTag + ) // found empty list + { + // add dummy item to obtain valid HTML + children().append<DocHtmlListItem>(parser(),thisVariant,HtmlAttribList(),1); + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"empty list!"); + retval = RetVal_EndList; + goto endlist; + } + else // found some other tag + { + // add dummy item to obtain valid HTML + children().append<DocHtmlListItem>(parser(),thisVariant,HtmlAttribList(),1); + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <li> tag but " + "found <%s%s> instead!",parser()->context.token->endTag?"/":"",qPrint(parser()->context.token->name)); + parser()->tokenizer.pushBackHtmlTag(parser()->context.token->name); + goto endlist; + } + } + else if (tok==0) // premature end of comment + { + // add dummy item to obtain valid HTML + children().append<DocHtmlListItem>(parser(),thisVariant,HtmlAttribList(),1); + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while looking" + " for a html list item"); + goto endlist; + } + else // token other than html token + { + // add dummy item to obtain valid HTML + children().append<DocHtmlListItem>(parser(),thisVariant,HtmlAttribList(),1); + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <li> tag but found %s token instead!", + DocTokenizer::tokToString(tok)); + goto endlist; + } + + do + { + auto vDocHtmlListItem = children().append<DocHtmlListItem>(parser(),thisVariant,parser()->context.token->attribs,num++); + DocHtmlListItem *li = children().get_last<DocHtmlListItem>(); + retval=li->parse(vDocHtmlListItem); + } while (retval==RetVal_ListItem); + + if (retval==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while inside <%cl> block", + m_type==Unordered ? 'u' : 'o'); + } + +endlist: + DBG(("DocHtmlList::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval==RetVal_EndList ? RetVal_OK : retval; +} + +int DocHtmlList::parseXml(DocNodeVariant *thisVariant) +{ + DBG(("DocHtmlList::parseXml() start\n")); + int retval=RetVal_OK; + int num=1; + auto ns = AutoNodeStack(parser(),thisVariant); + + // get next token + int tok=parser()->tokenizer.lex(); + // skip whitespace and paragraph breaks + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=parser()->tokenizer.lex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=Mappers::htmlTagMapper->map(parser()->context.token->name); + //printf("parser()->context.token->name=%s parser()->context.token->endTag=%d\n",qPrint(parser()->context.token->name),parser()->context.token->endTag); + if (tagId==XML_ITEM && !parser()->context.token->endTag) // found <item> tag + { + // ok, we can go on. + } + else // found some other tag + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <item> tag but " + "found <%s> instead!",qPrint(parser()->context.token->name)); + parser()->tokenizer.pushBackHtmlTag(parser()->context.token->name); + goto endlist; + } + } + else if (tok==0) // premature end of comment + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while looking" + " for a html list item"); + goto endlist; + } + else // token other than html token + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <item> tag but found %s token instead!", + DocTokenizer::tokToString(tok)); + goto endlist; + } + + do + { + auto vDocHtmlListItem = children().append<DocHtmlListItem>(parser(),thisVariant,parser()->context.token->attribs,num++); + DocHtmlListItem *li = children().get_last<DocHtmlListItem>(); + retval=li->parseXml(vDocHtmlListItem); + if (retval==0) break; + //printf("retval=%x parser()->context.token->name=%s\n",retval,qPrint(parser()->context.token->name)); + } while (retval==RetVal_ListItem); + + if (retval==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while inside <list type=\"%s\"> block", + m_type==Unordered ? "bullet" : "number"); + } + +endlist: + DBG(("DocHtmlList::parseXml() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval==RetVal_EndList || + (retval==RetVal_CloseXml || parser()->context.token->name=="list") ? + RetVal_OK : retval; +} + +//-------------------------------------------------------------------------- + +int DocHtmlBlockQuote::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocHtmlBlockQuote::parse() start\n")); + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + + // parse one or more paragraphs + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + } + while (retval==TK_NEWPARA); + if (par) par->markLast(); + + DBG(("DocHtmlBlockQuote::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval; +} + +//--------------------------------------------------------------------------- + +int DocParBlock::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocParBlock::parse() start\n")); + int retval=0; + auto ns = AutoNodeStack(parser(),thisVariant); + + // parse one or more paragraphs + bool isFirst=TRUE; + DocPara *par=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + } + while (retval==TK_NEWPARA); + if (par) par->markLast(); + + DBG(("DocParBlock::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); + return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval; +} + +//--------------------------------------------------------------------------- + +DocSimpleListItem::DocSimpleListItem(DocParser *parser,DocNodeVariant *parent) + : DocNode(parser,parent) +{ +} + + +int DocSimpleListItem::parse(DocNodeVariant *thisVariant) +{ + auto ns = AutoNodeStack(parser(),thisVariant); + m_paragraph = std::make_unique<DocNodeVariant>(DocPara(parser(),thisVariant)); + DocPara *par = &std::get<DocPara>(*m_paragraph); + int rv=par->parse(m_paragraph.get()); + par->markFirst(); + par->markLast(); + return rv; +} + +//-------------------------------------------------------------------------- + +int DocSimpleList::parse(DocNodeVariant *thisVariant) +{ + auto ns = AutoNodeStack(parser(),thisVariant); + int rv; + do + { + auto vDocSimpleListItem = children().append<DocSimpleListItem>(parser(),thisVariant); + DocSimpleListItem *li = children().get_last<DocSimpleListItem>(); + rv=li->parse(vDocSimpleListItem); + } while (rv==RetVal_ListItem); + return (rv!=TK_NEWPARA) ? rv : RetVal_OK; +} + +//-------------------------------------------------------------------------- + +DocAutoListItem::DocAutoListItem(DocParser *parser,DocNodeVariant *parent,int indent,int num) + : DocCompoundNode(parser,parent), m_indent(indent), m_itemNum(num) +{ +} + +int DocAutoListItem::parse(DocNodeVariant *thisVariant) +{ + int retval = RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + + // first parse any number of paragraphs + bool isFirst=TRUE; + DocPara *lastPar=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + DocPara *par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (!par->isEmpty()) + { + if (lastPar) lastPar->markLast(FALSE); + lastPar=par; + } + else + { + children().pop_back(); + } + // next paragraph should be more indented than the - marker to belong + // to this item + } while (retval==TK_NEWPARA && parser()->context.token->indent>m_indent); + if (lastPar) lastPar->markLast(); + + //printf("DocAutoListItem: retval=%d indent=%d\n",retval,parser()->context.token->indent); + return retval; +} + +//-------------------------------------------------------------------------- + +DocAutoList::DocAutoList(DocParser *parser,DocNodeVariant *parent,int indent,bool isEnumList, + int depth) : + DocCompoundNode(parser,parent), m_indent(indent), m_isEnumList(isEnumList), + m_depth(depth) +{ +} + +int DocAutoList::parse(DocNodeVariant *thisVariant) +{ + int retval = RetVal_OK; + int num=1; + auto ns = AutoNodeStack(parser(),thisVariant); + parser()->tokenizer.startAutoList(); + // first item or sub list => create new list + do + { + if (parser()->context.token->id!=-1) // explicitly numbered list + { + num=parser()->context.token->id; // override num with real number given + } + auto vDocAutoListItem = children().append<DocAutoListItem>(parser(),thisVariant,m_indent,num++); + DocAutoListItem *li = children().get_last<DocAutoListItem>(); + retval=li->parse(vDocAutoListItem); + //printf("DocAutoList::parse(): retval=0x%x parser()->context.token->indent=%d m_indent=%d " + // "m_isEnumList=%d parser()->context.token->isEnumList=%d parser()->context.token->name=%s\n", + // retval,parser()->context.token->indent,m_indent,m_isEnumList,parser()->context.token->isEnumList, + // qPrint(parser()->context.token->name)); + //printf("num=%d parser()->context.token->id=%d\n",num,parser()->context.token->id); + } + while (retval==TK_LISTITEM && // new list item + m_indent==parser()->context.token->indent && // at same indent level + m_isEnumList==parser()->context.token->isEnumList && // of the same kind + (parser()->context.token->id==-1 || parser()->context.token->id>=num) // increasing number (or no number) + ); + + parser()->tokenizer.endAutoList(); + return retval; +} + +//-------------------------------------------------------------------------- + +void DocTitle::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocTitle::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + parser()->tokenizer.setStateTitle(); + int tok; + while ((tok=parser()->tokenizer.lex())) + { + if (!parser()->defaultHandleToken(thisVariant,tok,children())) + { + parser()->errorHandleDefaultToken(thisVariant,tok,children(),"title section"); + } + } + parser()->tokenizer.setStatePara(); + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocTitle::parse() end\n")); +} + +void DocTitle::parseFromString(DocNodeVariant *thisVariant,const QCString &text) +{ + children().append<DocWord>(parser(),thisVariant,text); +} + +//-------------------------------------------------------------------------- + +DocSimpleSect::DocSimpleSect(DocParser *parser,DocNodeVariant *parent,Type t) : + DocCompoundNode(parser,parent), m_type(t) +{ +} + +bool DocSimpleSect::hasTitle() const +{ + return m_title && std::get<DocTitle>(*m_title).hasTitle(); +} + +int DocSimpleSect::parse(DocNodeVariant *thisVariant,bool userTitle,bool needsSeparator) +{ + DBG(("DocSimpleSect::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + // handle case for user defined title + if (userTitle) + { + m_title = std::make_unique<DocNodeVariant>(DocTitle(parser(),thisVariant)); + DocTitle *title = &std::get<DocTitle>(*m_title); + title->parse(m_title.get()); + } + + // add new paragraph as child + if (!children().empty() && std::holds_alternative<DocPara>(children().back())) + { + std::get<DocPara>(children().back()).markLast(FALSE); + } + bool markFirst = children().empty(); + if (needsSeparator) + { + children().append<DocSimpleSectSep>(parser(),thisVariant); + } + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + DocPara *par = children().get_last<DocPara>(); + if (markFirst) + { + par->markFirst(); + } + par->markLast(); + + // parse the contents of the paragraph + int retval = par->parse(vDocPara); + + DBG(("DocSimpleSect::parse() end retval=%d\n",retval)); + return retval; // 0==EOF, TK_NEWPARA, TK_LISTITEM, TK_ENDLIST, RetVal_SimpleSec +} + +int DocSimpleSect::parseRcs(DocNodeVariant *thisVariant) +{ + DBG(("DocSimpleSect::parseRcs() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + m_title = std::make_unique<DocNodeVariant>(DocTitle(parser(),thisVariant)); + DocTitle *title = &std::get<DocTitle>(*m_title); + title->parseFromString(thisVariant,parser()->context.token->name); + + QCString text = parser()->context.token->text; + parser()->pushContext(); // this will create a new parser->context.token + parser()->internalValidatingParseDoc(thisVariant,children(),text); + parser()->popContext(); // this will restore the old parser->context.token + + DBG(("DocSimpleSect::parseRcs()\n")); + return RetVal_OK; +} + +int DocSimpleSect::parseXml(DocNodeVariant *thisVariant) +{ + DBG(("DocSimpleSect::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + int retval = RetVal_OK; + for (;;) + { + // add new paragraph as child + if (!children().empty() && std::holds_alternative<DocPara>(children().back())) + { + std::get<DocPara>(children().back()).markLast(false); + } + bool markFirst = children().empty(); + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + DocPara *par = children().get_last<DocPara>(); + if (markFirst) + { + par->markFirst(); + } + par->markLast(); + + // parse the contents of the paragraph + retval = par->parse(vDocPara); + if (retval == 0) break; + if (retval == RetVal_CloseXml) + { + retval = RetVal_OK; + break; + } + } + + DBG(("DocSimpleSect::parseXml() end retval=%d\n",retval)); + return retval; +} + +void DocSimpleSect::appendLinkWord(DocNodeVariant *thisVariant,const QCString &word) +{ + DocPara *p=0; + if (children().empty() || (p=std::get_if<DocPara>(&children().back()))==0) + { + children().append<DocPara>(parser(),thisVariant); + p = children().get_last<DocPara>(); + } + else + { + // Comma-separate <seealso> links. + p->injectToken(thisVariant,TK_WORD,","); + p->injectToken(thisVariant,TK_WHITESPACE," "); + } + + parser()->context.inSeeBlock=TRUE; + p->injectToken(thisVariant,TK_LNKWORD,word); + parser()->context.inSeeBlock=FALSE; +} + +QCString DocSimpleSect::typeString() const +{ + switch (m_type) + { + case Unknown: break; + case See: return "see"; + case Return: return "return"; + case Author: // fall through + case Authors: return "author"; + case Version: return "version"; + case Since: return "since"; + case Date: return "date"; + case Note: return "note"; + case Warning: return "warning"; + case Pre: return "pre"; + case Post: return "post"; + case Copyright: return "copyright"; + case Invar: return "invariant"; + case Remark: return "remark"; + case Attention: return "attention"; + case User: return "user"; + case Rcs: return "rcs"; + } + return "unknown"; +} + +//-------------------------------------------------------------------------- + +int DocParamList::parse(DocNodeVariant *thisVariant,const QCString &cmdName) +{ + int retval=RetVal_OK; + DBG(("DocParamList::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + DocNodeVariant *vDocPara = 0; + DocPara *par=0; + QCString saveCmdName = cmdName; + + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + retval=RetVal_EndParBlock; + goto endparamlist; + } + parser()->tokenizer.setStateParam(); + tok=parser()->tokenizer.lex(); + while (tok==TK_WORD) /* there is a parameter name */ + { + if (m_type==DocParamSect::Param) + { + int typeSeparator = parser()->context.token->name.find('#'); // explicit type position + if (typeSeparator!=-1) + { + parser()->handleParameterType(thisVariant,m_paramTypes,parser()->context.token->name.left(typeSeparator)); + parser()->context.token->name = parser()->context.token->name.mid(typeSeparator+1); + parser()->context.hasParamCommand=TRUE; + parser()->checkArgumentName(); + if (parent() && std::holds_alternative<DocParamSect>(*parent())) + { + std::get<DocParamSect>(*parent()).m_hasTypeSpecifier=true; + } + } + else + { + parser()->context.hasParamCommand=TRUE; + parser()->checkArgumentName(); + } + } + else if (m_type==DocParamSect::RetVal) + { + parser()->context.hasReturnCommand=TRUE; + parser()->checkRetvalName(); + } + //m_params.append(parser()->context.token->name); + parser()->handleLinkedWord(thisVariant,m_params); + tok=parser()->tokenizer.lex(); + } + parser()->tokenizer.setStatePara(); + if (tok==0) /* premature end of comment block */ + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the " + "argument of command %s",qPrint(saveCmdName)); + retval=RetVal_EndParBlock; + goto endparamlist; + } + if (tok!=TK_WHITESPACE) /* premature end of comment block */ + { + if (tok!=TK_NEWPARA) /* empty param description */ + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s in comment block while parsing the " + "argument of command %s",DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + } + retval=RetVal_EndParBlock; + goto endparamlist; + } + + vDocPara = m_paragraphs.append<DocPara>(parser(),thisVariant); + par = m_paragraphs.get_last<DocPara>(); + retval = par->parse(vDocPara); + par->markFirst(); + par->markLast(); + +endparamlist: + DBG(("DocParamList::parse() end retval=%d\n",retval)); + return retval; +} + +int DocParamList::parseXml(DocNodeVariant *thisVariant,const QCString ¶mName) +{ + int retval=RetVal_OK; + DBG(("DocParamList::parseXml() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + parser()->context.token->name = paramName; + if (m_type==DocParamSect::Param) + { + parser()->context.hasParamCommand=TRUE; + parser()->checkArgumentName(); + } + else if (m_type==DocParamSect::RetVal) + { + parser()->context.hasReturnCommand=TRUE; + parser()->checkRetvalName(); + } + + parser()->handleLinkedWord(thisVariant,m_params); + + do + { + auto vDocPara = m_paragraphs.append<DocPara>(parser(),thisVariant); + DocPara *par = m_paragraphs.get_last<DocPara>(); + retval = par->parse(vDocPara); + if (par->isEmpty()) // avoid adding an empty paragraph for the whitespace + // after </para> and before </param> + { + m_paragraphs.pop_back(); + break; + } + else // append the paragraph to the list + { + if (!m_paragraphs.empty()) + { + m_paragraphs.get_last<DocPara>()->markLast(FALSE); + } + bool markFirst = m_paragraphs.empty(); + par = &std::get<DocPara>(m_paragraphs.back()); + if (markFirst) + { + par->markFirst(); + } + par->markLast(); + } + + if (retval == 0) break; + + } while (retval==RetVal_CloseXml && + Mappers::htmlTagMapper->map(parser()->context.token->name)!=XML_PARAM && + Mappers::htmlTagMapper->map(parser()->context.token->name)!=XML_TYPEPARAM && + Mappers::htmlTagMapper->map(parser()->context.token->name)!=XML_EXCEPTION); + + + if (retval==0) /* premature end of comment block */ + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unterminated param or exception tag"); + } + else + { + retval=RetVal_OK; + } + + DBG(("DocParamList::parse() end retval=%d\n",retval)); + return retval; +} + +//-------------------------------------------------------------------------- + +int DocParamSect::parse(DocNodeVariant *thisVariant,const QCString &cmdName,bool xmlContext, Direction d) +{ + int retval=RetVal_OK; + DBG(("DocParamSect::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + + if (d!=Unspecified) + { + m_hasInOutSpecifier=TRUE; + } + + if (!children().empty() && std::holds_alternative<DocParamList>(children().back())) + { + DocParamList &lastPl = std::get<DocParamList>(children().back()); + lastPl.markLast(false); + } + bool markFirst = children().empty(); + auto vDocParamList = children().append<DocParamList>(parser(),thisVariant,m_type,d); + DocParamList *pl = children().get_last<DocParamList>(); + if (markFirst) + { + pl->markFirst(); + } + pl->markLast(); + if (xmlContext) + { + retval = pl->parseXml(vDocParamList,cmdName); + } + else + { + retval = pl->parse(vDocParamList,cmdName); + } + if (retval==RetVal_EndParBlock) + { + retval = RetVal_OK; + } + + DBG(("DocParamSect::parse() end retval=%d\n",retval)); + return retval; +} + +//-------------------------------------------------------------------------- + +DocPara::DocPara(DocParser *parser,DocNodeVariant *parent) : + DocCompoundNode(parser,parent), + m_isFirst(FALSE), m_isLast(FALSE) +{ +} + +int DocPara::handleSimpleSection(DocNodeVariant *thisVariant, + DocSimpleSect::Type t, bool xmlContext) +{ + DocSimpleSect *ss=0; + DocNodeVariant *vDocSimpleSect = 0; + bool needsSeparator = FALSE; + if (!children().empty() && // has previous element + (ss=children().get_last<DocSimpleSect>()) && // was a simple sect + ss->type()==t && // of same type + t!=DocSimpleSect::User) // but not user defined + { + vDocSimpleSect = &children().back(); + // append to previous section + needsSeparator = TRUE; + } + else // start new section + { + vDocSimpleSect = children().append<DocSimpleSect>(parser(),thisVariant,t); + ss = children().get_last<DocSimpleSect>(); + } + int rv = RetVal_OK; + if (xmlContext) + { + return ss->parseXml(vDocSimpleSect); + } + else + { + rv = ss->parse(vDocSimpleSect,t==DocSimpleSect::User,needsSeparator); + } + return (rv!=TK_NEWPARA) ? rv : RetVal_OK; +} + +int DocPara::handleParamSection(DocNodeVariant *thisVariant, + const QCString &cmdName, + DocParamSect::Type t, + bool xmlContext=FALSE, + int direction=DocParamSect::Unspecified) +{ + DocParamSect *ps = 0; + DocNodeVariant *vDocParamSect = 0; + if (!children().empty() && // previous element + (ps=children().get_last<DocParamSect>()) && // was a param sect + ps->type()==t) // of same type + { + // append to previous section + vDocParamSect = &children().back(); + } + else // start new section + { + vDocParamSect = children().append<DocParamSect>(parser(),thisVariant,t); + ps = children().get_last<DocParamSect>(); + } + int rv=ps->parse(vDocParamSect,cmdName,xmlContext, + static_cast<DocParamSect::Direction>(direction)); + return (rv!=TK_NEWPARA) ? rv : RetVal_OK; +} + +void DocPara::handleCite(DocNodeVariant *thisVariant) +{ + // get the argument of the cite command. + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint("cite")); + return; + } + parser()->tokenizer.setStateCite(); + tok=parser()->tokenizer.lex(); + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the " + "argument of command %s\n", qPrint("cite")); + return; + } + else if (tok!=TK_WORD && tok!=TK_LNKWORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint("cite")); + return; + } + parser()->context.token->sectionId = parser()->context.token->name; + children().append<DocCite>( + parser(),thisVariant,parser()->context.token->name,parser()->context.context); + + parser()->tokenizer.setStatePara(); +} + +void DocPara::handleEmoji(DocNodeVariant *thisVariant) +{ + // get the argument of the emoji command. + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint("emoji")); + return; + } + parser()->tokenizer.setStateEmoji(); + tok=parser()->tokenizer.lex(); + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"no emoji name given or unexpected end of comment block while parsing the " + "argument of command %s", qPrint("emoji")); + parser()->tokenizer.setStatePara(); + return; + } + else if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint("emoji")); + parser()->tokenizer.setStatePara(); + return; + } + children().append<DocEmoji>(parser(),thisVariant,parser()->context.token->name); + parser()->tokenizer.setStatePara(); +} + +int DocPara::handleXRefItem(DocNodeVariant *thisVariant) +{ + int retval=parser()->tokenizer.lex(); + ASSERT(retval==TK_WHITESPACE); + parser()->tokenizer.setStateXRefItem(); + retval=parser()->tokenizer.lex(); + if (retval==RetVal_OK) + { + auto vDocXRefItem = children().append<DocXRefItem>(parser(),thisVariant, + parser()->context.token->id,parser()->context.token->name); + DocXRefItem *ref = children().get_last<DocXRefItem>(); + if (!ref->parse(vDocXRefItem)) + { + children().pop_back(); + } + } + parser()->tokenizer.setStatePara(); + return retval; +} + +void DocPara::handleIline(DocNodeVariant *) +{ + parser()->tokenizer.setStateIline(); + int tok = parser()->tokenizer.lex(); + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"invalid argument for command '\\iline'\n"); + return; + } + parser()->tokenizer.setStatePara(); +} + +void DocPara::handleIncludeOperator(DocNodeVariant *thisVariant,const QCString &cmdName,DocIncOperator::Type t) +{ + QCString saveCmdName = cmdName; + DBG(("handleIncludeOperator(%s)\n",qPrint(saveCmdName))); + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + parser()->tokenizer.setStatePattern(); + tok=parser()->tokenizer.lex(); + parser()->tokenizer.setStatePara(); + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the " + "argument of command %s", qPrint(saveCmdName)); + return; + } + else if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + return; + } + auto it1 = children().size()>=1 ? std::prev(children().end()) : children().end(); + auto it2 = children().size()>=2 ? std::prev(it1) : children().end(); + DocNodeVariant *n1 = it1!=children().end() ? &(*it1) : 0; + DocNodeVariant *n2 = it2!=children().end() ? &(*it2) : 0; + children().append<DocIncOperator>(parser(),thisVariant,t, + parser()->context.token->name, + parser()->context.context, + parser()->context.isExample, + parser()->context.exampleName); + DocIncOperator *op = children().get_last<DocIncOperator>(); + DocIncOperator *n1_docIncOp = std::get_if<DocIncOperator>(n1); + DocWhiteSpace *n1_docWs = std::get_if<DocWhiteSpace >(n1); + DocIncOperator *n2_docIncOp = std::get_if<DocIncOperator>(n2); + bool isFirst = !n1 || // no last node + (!n1_docIncOp && !n1_docWs) || // last node is not operator or whitespace + (n1_docWs && n2 && !n2_docIncOp); // last node is not operator + op->markFirst(isFirst); + op->markLast(true); + if (n1_docIncOp) + { + n1_docIncOp->markLast(false); + } + else if (n1_docWs && n2_docIncOp) + { + n2_docIncOp->markLast(false); + } + op->parse(&children().back()); +} + +template<class T> +void DocPara::handleFile(DocNodeVariant *thisVariant,const QCString &cmdName) +{ + QCString saveCmdName = cmdName; + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + parser()->tokenizer.setStateFile(); + tok=parser()->tokenizer.lex(); + parser()->tokenizer.setStatePara(); + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + return; + } + QCString name = parser()->context.token->name; + auto vT = children().append<T>(parser(),thisVariant,name, + parser()->context.context, + parser()->context.fileName, + parser()->tokenizer.getLineNr()); + auto df = children().get_last<T>(); + if (!df->parse(vT)) + { + children().pop_back(); + } +} + +void DocPara::handleVhdlFlow(DocNodeVariant *thisVariant) +{ + auto vDocVhdlFlow = children().append<DocVhdlFlow>(parser(),thisVariant); + children().get_last<DocVhdlFlow>()->parse(vDocVhdlFlow); +} + +void DocPara::handleLink(DocNodeVariant *thisVariant,const QCString &cmdName,bool isJavaLink) +{ + QCString saveCmdName = cmdName; + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + parser()->tokenizer.setStateLink(); + tok=parser()->tokenizer.lex(); + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"%s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + return; + } + if (saveCmdName == "javalink") + { + children().append<DocStyleChange>(parser(),thisVariant, + parser()->context.nodeStack.size(), + DocStyleChange::Code,cmdName,TRUE); + } + parser()->tokenizer.setStatePara(); + auto vDocLink = children().append<DocLink>(parser(),thisVariant,parser()->context.token->name); + DocLink *lnk = children().get_last<DocLink>(); + if (saveCmdName == "javalink") + { + children().append<DocStyleChange>(parser(),thisVariant, + parser()->context.nodeStack.size(), + DocStyleChange::Code,cmdName,FALSE); + } + QCString leftOver = lnk->parse(vDocLink,isJavaLink); + if (!leftOver.isEmpty()) + { + children().append<DocWord>(parser(),thisVariant,leftOver); + } +} + +void DocPara::handleRef(DocNodeVariant *thisVariant,const QCString &cmdName) +{ + QCString saveCmdName = cmdName; + DBG(("handleRef(%s)\n",qPrint(saveCmdName))); + DocNodeVariant *vDocRef = 0; + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + parser()->tokenizer.setStateRef(); + tok=parser()->tokenizer.lex(); // get the reference id + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + goto endref; + } + vDocRef = children().append<DocRef>(parser(),thisVariant, + parser()->context.token->name, + parser()->context.context); + children().get_last<DocRef>()->parse(vDocRef); +endref: + parser()->tokenizer.setStatePara(); +} + +void DocPara::handleInclude(DocNodeVariant *thisVariant,const QCString &cmdName,DocInclude::Type t) +{ + DBG(("handleInclude(%s)\n",qPrint(cmdName))); + QCString saveCmdName = cmdName; + int tok=parser()->tokenizer.lex(); + bool isBlock = false; + if (tok==TK_WORD && parser()->context.token->name=="{") + { + parser()->tokenizer.setStateOptions(); + tok=parser()->tokenizer.lex(); + parser()->tokenizer.setStatePara(); + StringVector optList=split(parser()->context.token->name.str(),","); + auto contains = [&optList](const char *kw) + { + return std::find(optList.begin(),optList.end(),kw)!=optList.end(); + }; + if (t==DocInclude::Include && contains("lineno")) + { + t = DocInclude::IncWithLines; + } + else if (t==DocInclude::Snippet && contains("lineno")) + { + t = DocInclude::SnipWithLines; + } + else if (t==DocInclude::DontInclude && contains("lineno")) + { + t = DocInclude::DontIncWithLines; + } + else if (t==DocInclude::Include && contains("doc")) + { + t = DocInclude::IncludeDoc; + } + else if (t==DocInclude::Snippet && contains("doc")) + { + t = DocInclude::SnippetDoc; + } + tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + } + else if (tok==TK_WORD && parser()->context.token->name=="[") + { + parser()->tokenizer.setStateBlock(); + tok=parser()->tokenizer.lex(); + isBlock = (parser()->context.token->name.stripWhiteSpace() == "block"); + parser()->tokenizer.setStatePara(); + tok=parser()->tokenizer.lex(); + } + else if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + parser()->tokenizer.setStateFile(); + tok=parser()->tokenizer.lex(); + parser()->tokenizer.setStatePara(); + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the " + "argument of command %s",qPrint(saveCmdName)); + return; + } + else if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + return; + } + QCString fileName = parser()->context.token->name; + QCString blockId; + if (t==DocInclude::Snippet || t==DocInclude::SnipWithLines || t==DocInclude::SnippetDoc) + { + if (fileName == "this") fileName=parser()->context.fileName; + parser()->tokenizer.setStateSnippet(); + tok=parser()->tokenizer.lex(); + parser()->tokenizer.setStatePara(); + if (tok!=TK_WORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected block identifier, but found token %s instead while parsing the %s command", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + return; + } + blockId = "["+parser()->context.token->name+"]"; + } + + // This is the only place to handle the \includedoc and \snippetdoc commands, + // as the content is included here as if it is really here. + if (t==DocInclude::IncludeDoc || t==DocInclude::SnippetDoc) + { + QCString inc_text; + int inc_line = 1; + parser()->readTextFileByName(fileName,inc_text); + if (t==DocInclude::SnippetDoc) + { + int count; + if (!blockId.isEmpty() && (count=inc_text.contains(blockId.data()))!=2) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"block marked with %s for \\snippet should appear twice in file %s, found it %d times\n", + qPrint(blockId),qPrint(fileName),count); + } + inc_line = lineBlock(inc_text, blockId); + inc_text = extractBlock(inc_text, blockId); + } + + Markdown markdown(fileName,inc_line); + QCString strippedDoc = stripIndentation(inc_text); + QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,inc_line) : strippedDoc; + + parser()->pushContext(); + parser()->context.fileName = fileName; + parser()->tokenizer.setLineNr(inc_line); + parser()->internalValidatingParseDoc(thisVariant,children(),processedDoc); + parser()->popContext(); + } + else + { + auto vDocInclude = children().append<DocInclude>(parser(),thisVariant,fileName, + parser()->context.context,t, + parser()->context.isExample, + parser()->context.exampleName, + blockId,isBlock); + children().get_last<DocInclude>()->parse(vDocInclude); + } +} + +void DocPara::handleSection(DocNodeVariant *,const QCString &cmdName) +{ + QCString saveCmdName = cmdName; + // get the argument of the section command. + int tok=parser()->tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after \\%s command", + qPrint(saveCmdName)); + return; + } + tok=parser()->tokenizer.lex(); + if (tok==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the " + "argument of command %s\n", qPrint(saveCmdName)); + return; + } + else if (tok!=TK_WORD && tok!=TK_LNKWORD) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of %s", + DocTokenizer::tokToString(tok),qPrint(saveCmdName)); + return; + } + parser()->context.token->sectionId = parser()->context.token->name; + parser()->tokenizer.setStateSkipTitle(); + parser()->tokenizer.lex(); + parser()->tokenizer.setStatePara(); +} + +int DocPara::handleHtmlHeader(DocNodeVariant *thisVariant, + const HtmlAttribList &tagHtmlAttribs,int level) +{ + auto vDocHtmlHeader = children().append<DocHtmlHeader>(parser(),thisVariant,tagHtmlAttribs,level); + int retval = children().get_last<DocHtmlHeader>()->parse(vDocHtmlHeader); + return (retval==RetVal_OK) ? TK_NEWPARA : retval; +} + +// For XML tags whose content is stored in attributes rather than +// contained within the element, we need a way to inject the attribute +// text into the current paragraph. +bool DocPara::injectToken(DocNodeVariant *thisVariant,int tok,const QCString &tokText) +{ + parser()->context.token->name = tokText; + return parser()->defaultHandleToken(thisVariant,tok,children()); +} + +int DocPara::handleStartCode(DocNodeVariant *thisVariant) +{ + int retval = parser()->tokenizer.lex(); + QCString lang = parser()->context.token->name; + if (!lang.isEmpty() && lang.at(0)!='.') + { + lang="."+lang; + } + if (parser()->context.xmlComment) + { + parser()->context.token->verb = substitute(substitute(parser()->context.token->verb,"<","<"),">",">"); + } + // search for the first non-whitespace line, index is stored in li + int i=0,li=0,l=parser()->context.token->verb.length(); + while (i<l && (parser()->context.token->verb.at(i)==' ' || parser()->context.token->verb.at(i)=='\n')) + { + if (parser()->context.token->verb.at(i)=='\n') li=i+1; + i++; + } + children().append<DocVerbatim>(parser(),thisVariant, + parser()->context.context, + stripIndentation(parser()->context.token->verb.mid(li)), + DocVerbatim::Code, + parser()->context.isExample, + parser()->context.exampleName, + FALSE,lang); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"code section ended without end marker"); + parser()->tokenizer.setStatePara(); + return retval; +} + +void DocPara::handleInheritDoc(DocNodeVariant *thisVariant) +{ + if (parser()->context.memberDef) // inheriting docs from a member + { + const MemberDef *reMd = parser()->context.memberDef->reimplements(); + if (reMd) // member from which was inherited. + { + const MemberDef *thisMd = parser()->context.memberDef; + //printf("{InheritDocs:%s=>%s}\n",qPrint(parser()->context.memberDef->qualifiedName()),qPrint(reMd->qualifiedName())); + parser()->pushContext(); + parser()->context.scope=reMd->getOuterScope(); + if (parser()->context.scope!=Doxygen::globalScope) + { + parser()->context.context=parser()->context.scope->name(); + } + parser()->context.memberDef=reMd; + while (!parser()->context.styleStack.empty()) parser()->context.styleStack.pop(); + while (!parser()->context.nodeStack.empty()) parser()->context.nodeStack.pop(); + parser()->context.copyStack.push_back(reMd); + parser()->internalValidatingParseDoc(thisVariant,children(),reMd->briefDescription()); + parser()->internalValidatingParseDoc(thisVariant,children(),reMd->documentation()); + parser()->context.copyStack.pop_back(); + auto hasParamCommand = parser()->context.hasParamCommand; + auto hasReturnCommand = parser()->context.hasReturnCommand; + auto retvalsFound = parser()->context.retvalsFound; + auto paramsFound = parser()->context.paramsFound; + parser()->popContext(); + parser()->context.hasParamCommand = hasParamCommand; + parser()->context.hasReturnCommand = hasReturnCommand; + parser()->context.retvalsFound = retvalsFound; + parser()->context.paramsFound = paramsFound; + parser()->context.memberDef = thisMd; + } + } +} + + +int DocPara::handleCommand(DocNodeVariant *thisVariant,const QCString &cmdName, const int tok) +{ + DBG(("handleCommand(%s)\n",qPrint(cmdName))); + int retval = RetVal_OK; + int cmdId = Mappers::cmdMapper->map(cmdName); + switch (cmdId) + { + case CMD_UNKNOWN: + children().append<DocWord>(parser(),thisVariant,TK_COMMAND_CHAR(tok) + cmdName); + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Found unknown command '%s%s'",TK_COMMAND_CHAR(tok),qPrint(cmdName)); + break; + case CMD_EMPHASIS: + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Italic,cmdName,TRUE); + retval=parser()->handleStyleArgument(thisVariant,children(),cmdName); + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Italic,cmdName,FALSE); + if (retval!=TK_WORD) children().append<DocWhiteSpace>(parser(),thisVariant," "); + break; + case CMD_BOLD: + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Bold,cmdName,TRUE); + retval=parser()->handleStyleArgument(thisVariant,children(),cmdName); + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Bold,cmdName,FALSE); + if (retval!=TK_WORD) children().append<DocWhiteSpace>(parser(),thisVariant," "); + break; + case CMD_CODE: + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Code,cmdName,TRUE); + retval=parser()->handleStyleArgument(thisVariant,children(),cmdName); + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Code,cmdName,FALSE); + if (retval!=TK_WORD) children().append<DocWhiteSpace>(parser(),thisVariant," "); + break; + case CMD_BSLASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_BSlash); + break; + case CMD_AT: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_At); + break; + case CMD_LESS: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Less); + break; + case CMD_GREATER: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Greater); + break; + case CMD_AMP: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Amp); + break; + case CMD_DOLLAR: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Dollar); + break; + case CMD_HASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Hash); + break; + case CMD_PIPE: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Pipe); + break; + case CMD_DCOLON: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_DoubleColon); + break; + case CMD_PERCENT: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Percent); + break; + case CMD_NDASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + break; + case CMD_MDASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + break; + case CMD_QUOTE: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Quot); + break; + case CMD_PUNT: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Dot); + break; + case CMD_PLUS: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Plus); + break; + case CMD_MINUS: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + break; + case CMD_EQUAL: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Equal); + break; + case CMD_SA: + parser()->context.inSeeBlock=TRUE; + retval = handleSimpleSection(thisVariant,DocSimpleSect::See); + parser()->context.inSeeBlock=FALSE; + break; + case CMD_RETURN: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Return); + parser()->context.hasReturnCommand=TRUE; + break; + case CMD_AUTHOR: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Author); + break; + case CMD_AUTHORS: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Authors); + break; + case CMD_VERSION: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Version); + break; + case CMD_SINCE: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Since); + break; + case CMD_DATE: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Date); + break; + case CMD_NOTE: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Note); + break; + case CMD_WARNING: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Warning); + break; + case CMD_PRE: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Pre); + break; + case CMD_POST: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Post); + break; + case CMD_COPYRIGHT: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Copyright); + break; + case CMD_INVARIANT: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Invar); + break; + case CMD_REMARK: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Remark); + break; + case CMD_ATTENTION: + retval = handleSimpleSection(thisVariant,DocSimpleSect::Attention); + break; + case CMD_PAR: + retval = handleSimpleSection(thisVariant,DocSimpleSect::User); + break; + case CMD_LI: + { + auto vDocSimpleList = children().append<DocSimpleList>(parser(),thisVariant); + retval = children().get_last<DocSimpleList>()->parse(vDocSimpleList); + } + break; + case CMD_SECTION: + { + handleSection(thisVariant,cmdName); + retval = RetVal_Section; + } + break; + case CMD_SUBSECTION: + { + handleSection(thisVariant,cmdName); + retval = RetVal_Subsection; + } + break; + case CMD_SUBSUBSECTION: + { + handleSection(thisVariant,cmdName); + retval = RetVal_Subsubsection; + } + break; + case CMD_PARAGRAPH: + { + handleSection(thisVariant,cmdName); + retval = RetVal_Paragraph; + } + break; + case CMD_STARTCODE: + { + parser()->tokenizer.setStateCode(); + retval = handleStartCode(thisVariant); + } + break; + case CMD_HTMLONLY: + { + parser()->tokenizer.setStateHtmlOnly(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::HtmlOnly,parser()->context.isExample,parser()->context.exampleName,parser()->context.token->name=="block"); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"htmlonly section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_MANONLY: + { + parser()->tokenizer.setStateManOnly(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::ManOnly,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"manonly section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_RTFONLY: + { + parser()->tokenizer.setStateRtfOnly(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::RtfOnly,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"rtfonly section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_LATEXONLY: + { + parser()->tokenizer.setStateLatexOnly(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::LatexOnly,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"latexonly section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_XMLONLY: + { + parser()->tokenizer.setStateXmlOnly(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::XmlOnly,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"xmlonly section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_DBONLY: + { + parser()->tokenizer.setStateDbOnly(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::DocbookOnly,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"docbookonly section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_ILITERAL: + { + DocVerbatim::Type t = DocVerbatim::JavaDocLiteral; + parser()->tokenizer.setStateILiteralOpt(); + retval = parser()->tokenizer.lex(); + + QCString fullMatch = parser()->context.token->verb; + int idx = fullMatch.find('{'); + int idxEnd = fullMatch.find("}",idx+1); + StringVector optList; + if (idx != -1) // options present + { + QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); + optList = split(optStr.str(),","); + for (const auto &opt : optList) + { + if (opt.empty()) continue; + QCString locOpt(opt); + locOpt = locOpt.stripWhiteSpace().lower(); + if (locOpt == "code") + { + t = DocVerbatim::JavaDocCode; + } + else if (!locOpt.isEmpty()) + { + warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Unknown option '%s' for '\\iliteral'",qPrint(opt)); + } + } + } + + parser()->tokenizer.setStateILiteral(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,t,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) + { + if (t == DocVerbatim::JavaDocCode) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"javadoc code section ended without end marker"); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"javadoc literal section ended without end marker"); + } + } + parser()->tokenizer.setStatePara(); + } + break; + case CMD_VERBATIM: + { + parser()->tokenizer.setStateVerbatim(); + retval = parser()->tokenizer.lex(); + children().append<DocVerbatim>(parser(),thisVariant,parser()->context.context,parser()->context.token->verb,DocVerbatim::Verbatim,parser()->context.isExample,parser()->context.exampleName); + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"verbatim section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_DOT: + { + auto vDocVerbatim = children().append<DocVerbatim>(parser(),thisVariant, + parser()->context.context, + parser()->context.token->verb, + DocVerbatim::Dot, + parser()->context.isExample, + parser()->context.exampleName); + DocVerbatim *dv = children().get_last<DocVerbatim>(); + parser()->tokenizer.setStatePara(); + QCString width,height; + parser()->defaultHandleTitleAndSize(CMD_DOT,vDocVerbatim,dv->children(),width,height); + parser()->tokenizer.setStateDot(); + retval = parser()->tokenizer.lex(); + dv->setText(parser()->context.token->verb); + dv->setWidth(width); + dv->setHeight(height); + dv->setLocation(parser()->context.fileName,parser()->tokenizer.getLineNr()); + if (!Config_getBool(HAVE_DOT)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"ignoring \\dot command because HAVE_DOT is not set"); + children().pop_back(); + } + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"dot section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_MSC: + { + auto vDocVerbatim = children().append<DocVerbatim>(parser(),thisVariant, + parser()->context.context, + parser()->context.token->verb, + DocVerbatim::Msc, + parser()->context.isExample, + parser()->context.exampleName); + DocVerbatim *dv = children().get_last<DocVerbatim>(); + parser()->tokenizer.setStatePara(); + QCString width,height; + parser()->defaultHandleTitleAndSize(CMD_MSC,vDocVerbatim,dv->children(),width,height); + parser()->tokenizer.setStateMsc(); + retval = parser()->tokenizer.lex(); + dv->setText(parser()->context.token->verb); + dv->setWidth(width); + dv->setHeight(height); + dv->setLocation(parser()->context.fileName,parser()->tokenizer.getLineNr()); + if (retval==0) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"msc section ended without end marker"); + } + parser()->tokenizer.setStatePara(); + } + break; + case CMD_STARTUML: + { + QCString jarPath = Config_getString(PLANTUML_JAR_PATH); + parser()->tokenizer.setStatePlantUMLOpt(); + retval = parser()->tokenizer.lex(); + QCString fullMatch = parser()->context.token->sectionId; + QCString sectionId = ""; + int idx = fullMatch.find('{'); + int idxEnd = fullMatch.find("}",idx+1); + StringVector optList; + QCString engine; + if (idx != -1) // options present + { + QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); + optList = split(optStr.str(),","); + for (const auto &opt : optList) + { + if (opt.empty()) continue; + bool found = false; + QCString locOpt(opt); + locOpt = locOpt.stripWhiteSpace().lower(); + if (g_plantumlEngine.find(locOpt.str())!=g_plantumlEngine.end()) + { + if (!engine.isEmpty()) + { + warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Multiple definition of engine for '\\startuml'"); + } + engine = locOpt; + found = true; + } + if (!found) + { + if (sectionId.isEmpty()) + { + sectionId = opt; + } + else + { + warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Multiple use of filename for '\\startuml'"); + } + } + } + } + else + { + sectionId = parser()->context.token->sectionId; + } + if (engine.isEmpty()) engine = "uml"; + + if (sectionId.isEmpty()) + { + parser()->tokenizer.setStatePlantUMLOpt(); + retval = parser()->tokenizer.lex(); + assert(retval==RetVal_OK); + + sectionId = parser()->context.token->sectionId; + sectionId = sectionId.stripWhiteSpace(); + } + + QCString plantFile(sectionId); + auto vDocVerbatim = children().append<DocVerbatim>(parser(),thisVariant, + parser()->context.context, + parser()->context.token->verb, + DocVerbatim::PlantUML, + FALSE,plantFile); + DocVerbatim *dv = children().get_last<DocVerbatim>(); + dv->setEngine(engine); + parser()->tokenizer.setStatePara(); + QCString width,height; + parser()->defaultHandleTitleAndSize(CMD_STARTUML,vDocVerbatim,dv->children(),width,height); + parser()->tokenizer.setStatePlantUML(); + retval = parser()->tokenizer.lex(); + int line = 0; + QCString trimmedVerb = stripLeadingAndTrailingEmptyLines(parser()->context.token->verb,line); + if (engine == "ditaa") + { + dv->setUseBitmap(true); + } + else if (engine == "uml") + { + int i = trimmedVerb.find('\n'); + QCString firstLine = i==-1 ? trimmedVerb : trimmedVerb.left(i); + if (firstLine.stripWhiteSpace() == "ditaa") dv->setUseBitmap(true); + } + dv->setText(trimmedVerb); + dv->setWidth(width); + dv->setHeight(height); + dv->setLocation(parser()->context.fileName,parser()->tokenizer.getLineNr()); + if (jarPath.isEmpty()) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"ignoring \\startuml command because PLANTUML_JAR_PATH is not set"); + children().pop_back(); + } + if (retval==0) warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"startuml section ended without end marker"); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_ENDPARBLOCK: + retval=RetVal_EndParBlock; + break; + case CMD_ENDCODE: + case CMD_ENDHTMLONLY: + case CMD_ENDMANONLY: + case CMD_ENDRTFONLY: + case CMD_ENDLATEXONLY: + case CMD_ENDXMLONLY: + case CMD_ENDDBONLY: + case CMD_ENDLINK: + case CMD_ENDVERBATIM: + case CMD_ENDILITERAL: + case CMD_ENDDOT: + case CMD_ENDMSC: + case CMD_ENDUML: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected command %s",qPrint(parser()->context.token->name)); + break; + case CMD_PARAM: + retval = handleParamSection(thisVariant,cmdName,DocParamSect::Param,FALSE,parser()->context.token->paramDir); + break; + case CMD_TPARAM: + retval = handleParamSection(thisVariant,cmdName,DocParamSect::TemplateParam,FALSE,parser()->context.token->paramDir); + break; + case CMD_RETVAL: + retval = handleParamSection(thisVariant,cmdName,DocParamSect::RetVal); + break; + case CMD_EXCEPTION: + retval = handleParamSection(thisVariant,cmdName,DocParamSect::Exception); + break; + case CMD_XREFITEM: + retval = handleXRefItem(thisVariant); + break; + case CMD_LINEBREAK: + { + children().append<DocLineBreak>(parser(),thisVariant); + } + break; + case CMD_ANCHOR: + { + parser()->handleAnchor(thisVariant,children()); + } + break; + case CMD_ADDINDEX: + { + auto vDocIndexEntry = children().append<DocIndexEntry>(parser(),thisVariant, + parser()->context.scope!=Doxygen::globalScope?parser()->context.scope:0, + parser()->context.memberDef); + retval = children().get_last<DocIndexEntry>()->parse(vDocIndexEntry); + } + break; + case CMD_INTERNAL: + retval = RetVal_Internal; + break; + case CMD_ENDINTERNAL: + retval = RetVal_EndInternal; + break; + case CMD_PARBLOCK: + { + auto vDocParBlock = children().append<DocParBlock>(parser(),thisVariant); + retval = children().get_last<DocParBlock>()->parse(vDocParBlock); + } + break; + case CMD_COPYDOC: // fall through + case CMD_COPYBRIEF: // fall through + case CMD_COPYDETAILS: + //retval = RetVal_CopyDoc; + // these commands should already be resolved by processCopyDoc() + break; + case CMD_INCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::Include); + break; + case CMD_INCWITHLINES: + handleInclude(thisVariant,cmdName,DocInclude::IncWithLines); + break; + case CMD_DONTINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::DontInclude); + break; + case CMD_HTMLINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::HtmlInclude); + break; + case CMD_LATEXINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::LatexInclude); + break; + case CMD_RTFINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::RtfInclude); + break; + case CMD_MANINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::ManInclude); + break; + case CMD_XMLINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::XmlInclude); + break; + case CMD_DOCBOOKINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::DocbookInclude); + break; + case CMD_VERBINCLUDE: + handleInclude(thisVariant,cmdName,DocInclude::VerbInclude); + break; + case CMD_SNIPPET: + handleInclude(thisVariant,cmdName,DocInclude::Snippet); + break; + case CMD_SNIPWITHLINES: + handleInclude(thisVariant,cmdName,DocInclude::SnipWithLines); + break; + case CMD_INCLUDEDOC: + handleInclude(thisVariant,cmdName,DocInclude::IncludeDoc); + break; + case CMD_SNIPPETDOC: + handleInclude(thisVariant,cmdName,DocInclude::SnippetDoc); + break; + case CMD_SKIP: + handleIncludeOperator(thisVariant,cmdName,DocIncOperator::Skip); + break; + case CMD_UNTIL: + handleIncludeOperator(thisVariant,cmdName,DocIncOperator::Until); + break; + case CMD_SKIPLINE: + handleIncludeOperator(thisVariant,cmdName,DocIncOperator::SkipLine); + break; + case CMD_LINE: + handleIncludeOperator(thisVariant,cmdName,DocIncOperator::Line); + break; + case CMD_IMAGE: + parser()->handleImage(thisVariant,children()); + break; + case CMD_DOTFILE: + if (!Config_getBool(HAVE_DOT)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(), + "ignoring \\dotfile command because HAVE_DOT is not set"); + } + else + { + handleFile<DocDotFile>(thisVariant,cmdName); + } + break; + case CMD_VHDLFLOW: + handleVhdlFlow(thisVariant); + break; + case CMD_MSCFILE: + handleFile<DocMscFile>(thisVariant,cmdName); + break; + case CMD_DIAFILE: + handleFile<DocDiaFile>(thisVariant,cmdName); + break; + case CMD_LINK: + handleLink(thisVariant,cmdName,FALSE); + break; + case CMD_JAVALINK: + handleLink(thisVariant,cmdName,TRUE); + break; + case CMD_CITE: + handleCite(thisVariant); + break; + case CMD_EMOJI: + handleEmoji(thisVariant); + break; + case CMD_REF: // fall through + case CMD_SUBPAGE: + handleRef(thisVariant,cmdName); + break; + case CMD_SECREFLIST: + { + auto vDocSecRefList = children().append<DocSecRefList>(parser(),thisVariant); + children().get_last<DocSecRefList>()->parse(vDocSecRefList); + } + break; + case CMD_SECREFITEM: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected command %s",qPrint(parser()->context.token->name)); + break; + case CMD_ENDSECREFLIST: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected command %s",qPrint(parser()->context.token->name)); + break; + case CMD_FORMULA: + { + children().append<DocFormula>(parser(),thisVariant,parser()->context.token->id); + } + break; + //case CMD_LANGSWITCH: + // retval = handleLanguageSwitch(); + // break; + case CMD_INTERNALREF: + //warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected command %s",qPrint(parser()->context.token->name)); + { + parser()->handleInternalRef(thisVariant,children()); + parser()->tokenizer.setStatePara(); + } + break; + case CMD_INHERITDOC: + handleInheritDoc(thisVariant); + break; + case CMD_ILINE: + handleIline(thisVariant); + break; + default: + // we should not get here! + ASSERT(0); + break; + } + INTERNAL_ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec || + retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_NEWPARA || + retval==RetVal_Section || retval==RetVal_EndList || + retval==RetVal_Internal || retval==RetVal_SwitchLang || + retval==RetVal_EndInternal + ); + DBG(("handleCommand(%s) end retval=%s\n",qPrint(cmdName),DocTokenizer::retvalToString(retval))); + return retval; +} + +static bool findAttribute(const HtmlAttribList &tagHtmlAttribs, + const char *attrName, + QCString *result) +{ + + for (const auto &opt : tagHtmlAttribs) + { + if (opt.name==attrName) + { + *result = opt.value; + return TRUE; + } + } + return FALSE; +} + +int DocPara::handleHtmlStartTag(DocNodeVariant *thisVariant,const QCString &tagName,const HtmlAttribList &tagHtmlAttribs) +{ + DBG(("handleHtmlStartTag(%s,%d)\n",qPrint(tagName),tagHtmlAttribs.size())); + int retval=RetVal_OK; + int tagId = Mappers::htmlTagMapper->map(tagName); + if (parser()->context.token->emptyTag && !(tagId&XML_CmdMask) && + tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_HR && tagId!=HTML_P) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"HTML tag ('<%s/>') may not use the 'empty tag' XHTML syntax.", + qPrint(tagName)); + } + switch (tagId) + { + case HTML_UL: + if (!parser()->context.token->emptyTag) + { + auto vDocHtmlList = children().append<DocHtmlList>(parser(),thisVariant, + tagHtmlAttribs,DocHtmlList::Unordered); + retval=children().get_last<DocHtmlList>()->parse(vDocHtmlList); + } + break; + case HTML_OL: + if (!parser()->context.token->emptyTag) + { + auto vDocHtmlList = children().append<DocHtmlList>(parser(),thisVariant, + tagHtmlAttribs,DocHtmlList::Ordered); + retval=children().get_last<DocHtmlList>()->parse(vDocHtmlList); + } + break; + case HTML_LI: + if (parser()->context.token->emptyTag) break; + if (!insideUL(thisVariant) && !insideOL(thisVariant)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"lonely <li> tag found"); + } + else + { + retval=RetVal_ListItem; + } + break; + case HTML_BOLD: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Bold,tagName,&parser()->context.token->attribs); + break; + case HTML_S: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::S,tagName,&parser()->context.token->attribs); + break; + case HTML_STRIKE: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Strike,tagName,&parser()->context.token->attribs); + break; + case HTML_DEL: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Del,tagName,&parser()->context.token->attribs); + break; + case HTML_UNDERLINE: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Underline,tagName,&parser()->context.token->attribs); + break; + case HTML_INS: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Ins,tagName,&parser()->context.token->attribs); + break; + case HTML_DETAILS: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Details,tagName,&parser()->context.token->attribs); + break; + case HTML_CODE: + if (parser()->context.token->emptyTag) break; + if (/*getLanguageFromFileName(parser()->context.fileName)==SrcLangExt_CSharp ||*/ parser()->context.xmlComment) + // for C# source or inside a <summary> or <remark> section we + // treat <code> as an XML tag (so similar to @code) + { + parser()->tokenizer.setStateXmlCode(); + retval = handleStartCode(thisVariant); + } + else // normal HTML markup + { + parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Code,tagName,&parser()->context.token->attribs); + } + break; + case HTML_EMPHASIS: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Italic,tagName,&parser()->context.token->attribs); + break; + case HTML_DIV: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Div,tagName,&parser()->context.token->attribs); + break; + case HTML_SPAN: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Span,tagName,&parser()->context.token->attribs); + break; + case HTML_SUB: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Subscript,tagName,&parser()->context.token->attribs); + break; + case HTML_SUP: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Superscript,tagName,&parser()->context.token->attribs); + break; + case HTML_CENTER: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Center,tagName,&parser()->context.token->attribs); + break; + case HTML_SMALL: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Small,tagName,&parser()->context.token->attribs); + break; + case HTML_CITE: + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Cite,tagName,&parser()->context.token->attribs); + break; + case HTML_PRE: + if (parser()->context.token->emptyTag) break; + parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Preformatted,tagName,&parser()->context.token->attribs); + setInsidePreformatted(TRUE); + parser()->tokenizer.setInsidePre(TRUE); + break; + case HTML_P: + retval=TK_NEWPARA; + break; + case HTML_DL: + if (!parser()->context.token->emptyTag) + { + auto vDocHtmlDescList = children().append<DocHtmlDescList>(parser(),thisVariant,tagHtmlAttribs); + retval=children().get_last<DocHtmlDescList>()->parse(vDocHtmlDescList); + } + break; + case HTML_DT: + retval = RetVal_DescTitle; + break; + case HTML_DD: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag <dd> found"); + break; + case HTML_TABLE: + if (!parser()->context.token->emptyTag) + { + auto vDocHtmlTable = children().append<DocHtmlTable>(parser(),thisVariant,tagHtmlAttribs); + retval=children().get_last<DocHtmlTable>()->parse(vDocHtmlTable); + } + break; + case HTML_TR: + retval = RetVal_TableRow; + break; + case HTML_TD: + retval = RetVal_TableCell; + break; + case HTML_TH: + retval = RetVal_TableHCell; + break; + case HTML_CAPTION: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag <caption> found"); + break; + case HTML_BR: + { + children().append<DocLineBreak>(parser(),thisVariant,tagHtmlAttribs); + } + break; + case HTML_HR: + { + children().append<DocHorRuler>(parser(),thisVariant,tagHtmlAttribs); + } + break; + case HTML_A: + retval = parser()->handleAHref(thisVariant,children(),tagHtmlAttribs); + break; + case HTML_H1: + if (!parser()->context.token->emptyTag) retval=handleHtmlHeader(thisVariant,tagHtmlAttribs,1); + break; + case HTML_H2: + if (!parser()->context.token->emptyTag) retval=handleHtmlHeader(thisVariant,tagHtmlAttribs,2); + break; + case HTML_H3: + if (!parser()->context.token->emptyTag) retval=handleHtmlHeader(thisVariant,tagHtmlAttribs,3); + break; + case HTML_H4: + if (!parser()->context.token->emptyTag) retval=handleHtmlHeader(thisVariant,tagHtmlAttribs,4); + break; + case HTML_H5: + if (!parser()->context.token->emptyTag) retval=handleHtmlHeader(thisVariant,tagHtmlAttribs,5); + break; + case HTML_H6: + if (!parser()->context.token->emptyTag) retval=handleHtmlHeader(thisVariant,tagHtmlAttribs,6); + break; + case HTML_IMG: + { + parser()->handleImg(thisVariant,children(),tagHtmlAttribs); + } + break; + case HTML_BLOCKQUOTE: + if (!parser()->context.token->emptyTag) + { + auto vDocHtmlBlockQuote = children().append<DocHtmlBlockQuote>(parser(),thisVariant,tagHtmlAttribs); + retval = children().get_last<DocHtmlBlockQuote>()->parse(vDocHtmlBlockQuote); + } + break; + + case XML_SUMMARY: + if (insideDetails(parser()->context.styleStack)) + { + if (!parser()->context.token->emptyTag) parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Summary,tagName,&parser()->context.token->attribs); + break; + } + case XML_REMARKS: + case XML_EXAMPLE: + parser()->context.xmlComment=TRUE; + // fall through + case XML_VALUE: + case XML_PARA: + if (!children().empty()) + { + retval = TK_NEWPARA; + } + break; + case XML_DESCRIPTION: + if (insideTable(thisVariant)) + { + retval=RetVal_TableCell; + } + break; + case XML_C: + parser()->handleStyleEnter(thisVariant,children(),DocStyleChange::Code,tagName,&parser()->context.token->attribs); + break; + case XML_PARAM: + case XML_TYPEPARAM: + { + parser()->context.xmlComment=TRUE; + QCString paramName; + if (findAttribute(tagHtmlAttribs,"name",¶mName)) + { + if (paramName.isEmpty()) + { + if (Config_getBool(WARN_NO_PARAMDOC)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"empty 'name' attribute for <param%s> tag.",tagId==XML_PARAM?"":"type"); + } + } + else + { + retval = handleParamSection(thisVariant, paramName, + tagId==XML_PARAM ? DocParamSect::Param : DocParamSect::TemplateParam, + TRUE); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing 'name' attribute from <param%s> tag.",tagId==XML_PARAM?"":"type"); + } + } + break; + case XML_PARAMREF: + case XML_TYPEPARAMREF: + { + QCString paramName; + if (findAttribute(tagHtmlAttribs,"name",¶mName)) + { + //printf("paramName=%s\n",qPrint(paramName)); + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Italic,tagName,TRUE); + children().append<DocWord>(parser(),thisVariant,paramName); + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Italic,tagName,FALSE); + if (retval!=TK_WORD) children().append<DocWhiteSpace>(parser(),thisVariant," "); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing 'name' attribute from <param%sref> tag.",tagId==XML_PARAMREF?"":"type"); + } + } + break; + case XML_EXCEPTION: + { + parser()->context.xmlComment=TRUE; + QCString exceptName; + if (findAttribute(tagHtmlAttribs,"cref",&exceptName)) + { + unescapeCRef(exceptName); + retval = handleParamSection(thisVariant,exceptName,DocParamSect::Exception,TRUE); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing 'cref' attribute from <exception> tag."); + } + } + break; + case XML_ITEM: + case XML_LISTHEADER: + if (insideTable(thisVariant)) + { + retval=RetVal_TableRow; + } + else if (insideUL(thisVariant) || insideOL(thisVariant)) + { + retval=RetVal_ListItem; + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"lonely <item> tag found"); + } + break; + case XML_RETURNS: + parser()->context.xmlComment=TRUE; + retval = handleSimpleSection(thisVariant,DocSimpleSect::Return,TRUE); + parser()->context.hasReturnCommand=TRUE; + break; + case XML_TERM: + //children().push_back(std::make_unique<DocStyleChange>(this,parser()->context.nodeStack.size(),DocStyleChange::Bold,TRUE)); + if (insideTable(thisVariant)) + { + retval=RetVal_TableCell; + } + break; + case XML_SEE: + // I'm not sure if <see> is the same as <seealso> or if it + // should you link a member without producing a section. The + // C# specification is extremely vague about this (but what else + // can we expect from Microsoft...) + { + QCString cref; + //printf("XML_SEE: empty tag=%d\n",parser()->context.token->emptyTag); + if (findAttribute(tagHtmlAttribs,"cref",&cref)) + { + unescapeCRef(cref); + if (parser()->context.token->emptyTag) // <see cref="..."/> style + { + bool inSeeBlock = parser()->context.inSeeBlock; + parser()->context.token->name = cref; + parser()->context.inSeeBlock = TRUE; + parser()->handleLinkedWord(thisVariant,children(),TRUE); + parser()->context.inSeeBlock = inSeeBlock; + } + else // <see cref="...">...</see> style + { + //DocRef *ref = new DocRef(this,cref); + //children().append(ref); + //ref->parse(); + parser()->tokenizer.setStatePara(); + auto vDocLink = children().append<DocLink>(parser(),thisVariant,cref); + DocLink *lnk = children().get_last<DocLink>(); + QCString leftOver = lnk->parse(vDocLink,FALSE,TRUE); + if (!leftOver.isEmpty()) + { + children().append<DocWord>(parser(),thisVariant,leftOver); + } + } + } + else if (findAttribute(tagHtmlAttribs,"langword",&cref)) // <see langword="..."/> or <see langword="..."></see> + { + bool inSeeBlock = parser()->context.inSeeBlock; + parser()->context.token->name = cref; + parser()->context.inSeeBlock = TRUE; + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Code,tagName,TRUE); + parser()->handleLinkedWord(thisVariant,children(),TRUE); + children().append<DocStyleChange>(parser(),thisVariant,parser()->context.nodeStack.size(),DocStyleChange::Code,tagName,FALSE); + parser()->context.inSeeBlock = inSeeBlock; + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing 'cref' or 'langword' attribute from <see> tag."); + } + } + break; + case XML_SEEALSO: + { + parser()->context.xmlComment=TRUE; + QCString cref; + if (findAttribute(tagHtmlAttribs,"cref",&cref)) + { + unescapeCRef(cref); + // Look for an existing "see" section + DocNodeVariant *vss=0; + for (auto &n : children()) + { + DocSimpleSect *candidate = std::get_if<DocSimpleSect>(&n); + if (candidate && candidate->type()==DocSimpleSect::See) + { + vss = &n; + } + } + + if (!vss) // start new section + { + vss = children().append<DocSimpleSect>(parser(),thisVariant,DocSimpleSect::See); + } + + std::get<DocSimpleSect>(*vss).appendLinkWord(vss,cref); + retval = RetVal_OK; + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing 'cref' attribute from <seealso> tag."); + } + } + break; + case XML_LIST: + { + QCString type; + findAttribute(tagHtmlAttribs,"type",&type); + DocHtmlList::Type listType = DocHtmlList::Unordered; + HtmlAttribList emptyList; + if (type=="number") + { + listType=DocHtmlList::Ordered; + } + if (type=="table") + { + auto vDocHtmlTable = children().append<DocHtmlTable>(parser(),thisVariant,emptyList); + retval=children().get_last<DocHtmlTable>()->parseXml(vDocHtmlTable); + } + else + { + auto vHtmlList = children().append<DocHtmlList>(parser(),thisVariant,emptyList,listType); + retval=children().get_last<DocHtmlList>()->parseXml(vHtmlList); + } + } + break; + case XML_INCLUDE: + case XML_PERMISSION: + // These tags are defined in .Net but are currently unsupported + parser()->context.xmlComment=TRUE; + break; + case HTML_UNKNOWN: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unsupported xml/html tag <%s> found", qPrint(tagName)); + children().append<DocWord>(parser(),thisVariant, "<"+tagName+parser()->context.token->attribsStr+">"); + break; + case XML_INHERITDOC: + handleInheritDoc(thisVariant); + break; + default: + // we should not get here! + ASSERT(0); + break; + } + return retval; +} + +int DocPara::handleHtmlEndTag(DocNodeVariant *thisVariant,const QCString &tagName) +{ + DBG(("handleHtmlEndTag(%s)\n",qPrint(tagName))); + int tagId = Mappers::htmlTagMapper->map(tagName); + int retval=RetVal_OK; + switch (tagId) + { + case HTML_UL: + if (!insideUL(thisVariant)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"found </ul> tag without matching <ul>"); + } + else + { + retval=RetVal_EndList; + } + break; + case HTML_OL: + if (!insideOL(thisVariant)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"found </ol> tag without matching <ol>"); + } + else + { + retval=RetVal_EndList; + } + break; + case HTML_LI: + if (!insideLI(thisVariant)) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"found </li> tag without matching <li>"); + } + else + { + // ignore </li> tags + } + break; + case HTML_BLOCKQUOTE: + retval=RetVal_EndBlockQuote; + break; + case HTML_BOLD: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Bold,tagName); + break; + case HTML_S: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::S,"s"); + break; + case HTML_STRIKE: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Strike,tagName); + break; + case HTML_DEL: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Del,tagName); + break; + case HTML_UNDERLINE: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Underline,tagName); + break; + case HTML_INS: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Ins,tagName); + break; + case HTML_DETAILS: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Details,tagName); + break; + case HTML_CODE: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Code,tagName); + break; + case HTML_EMPHASIS: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Italic,tagName); + break; + case HTML_DIV: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Div,tagName); + break; + case HTML_SPAN: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Span,tagName); + break; + case HTML_SUB: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Subscript,tagName); + break; + case HTML_SUP: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Superscript,tagName); + break; + case HTML_CENTER: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Center,tagName); + break; + case HTML_SMALL: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Small,tagName); + break; + case HTML_CITE: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Cite,tagName); + break; + case HTML_PRE: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Preformatted,tagName); + setInsidePreformatted(FALSE); + parser()->tokenizer.setInsidePre(FALSE); + break; + case HTML_P: + retval=TK_NEWPARA; + break; + case HTML_DL: + retval=RetVal_EndDesc; + break; + case HTML_DT: + // ignore </dt> tag + break; + case HTML_DD: + // ignore </dd> tag + break; + case HTML_TABLE: + retval=RetVal_EndTable; + break; + case HTML_TR: + // ignore </tr> tag + break; + case HTML_TD: + // ignore </td> tag + break; + case HTML_TH: + // ignore </th> tag + break; + case HTML_CAPTION: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </caption> found"); + break; + case HTML_BR: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Illegal </br> tag found\n"); + break; + case HTML_H1: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </h1> found"); + break; + case HTML_H2: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </h2> found"); + break; + case HTML_H3: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </h3> found"); + break; + case HTML_H4: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </h4> found"); + break; + case HTML_H5: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </h5> found"); + break; + case HTML_H6: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </h6> found"); + break; + case HTML_IMG: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </img> found"); + break; + case HTML_HR: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Illegal </hr> tag found\n"); + break; + case HTML_A: + //warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected tag </a> found"); + // ignore </a> tag (can be part of <a name=...></a> + break; + + case XML_TERM: + //children().push_back(std::make_unique<DocStyleChange>(this,parser()->context.nodeStack.size(),DocStyleChange::Bold,FALSE)); + break; + case XML_SUMMARY: + if (insideDetails(parser()->context.styleStack)) + { + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Summary,tagName); + break; + } + case XML_REMARKS: + case XML_PARA: + case XML_VALUE: + case XML_EXAMPLE: + case XML_PARAM: + case XML_LIST: + case XML_TYPEPARAM: + case XML_RETURNS: + case XML_SEE: + case XML_SEEALSO: + case XML_EXCEPTION: + case XML_INHERITDOC: + retval = RetVal_CloseXml; + break; + case XML_C: + parser()->handleStyleLeave(thisVariant,children(),DocStyleChange::Code,tagName); + break; + case XML_ITEM: + case XML_LISTHEADER: + case XML_INCLUDE: + case XML_PERMISSION: + case XML_DESCRIPTION: + case XML_PARAMREF: + case XML_TYPEPARAMREF: + // These tags are defined in .Net but are currently unsupported + break; + case HTML_UNKNOWN: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unsupported xml/html tag </%s> found", qPrint(tagName)); + children().append<DocWord>(parser(),thisVariant,"</"+tagName+">"); + break; + default: + // we should not get here! + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected end tag %s\n",qPrint(tagName)); + ASSERT(0); + break; + } + return retval; +} + +int DocPara::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocPara::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + // handle style commands "inherited" from the previous paragraph + parser()->handleInitialStyleCommands(thisVariant,children()); + int tok; + int retval=0; + while ((tok=parser()->tokenizer.lex())) // get the next token + { +reparsetoken: + DBG(("token %s at %d",DocTokenizer::tokToString(tok),parser()->tokenizer.getLineNr())); + if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || + tok==TK_COMMAND_AT || tok == TK_COMMAND_BS || tok==TK_HTMLTAG + ) + { + DBG((" name=%s",qPrint(parser()->context.token->name))); + } + DBG(("\n")); + switch(tok) + { + case TK_WORD: + children().append<DocWord>(parser(),thisVariant,parser()->context.token->name); + break; + case TK_LNKWORD: + parser()->handleLinkedWord(thisVariant,children()); + break; + case TK_URL: + children().append<DocURL>(parser(),thisVariant,parser()->context.token->name,parser()->context.token->isEMailAddr); + break; + case TK_WHITESPACE: + { + // prevent leading whitespace and collapse multiple whitespace areas + if (insidePRE(thisVariant) || // all whitespace is relevant + ( + // remove leading whitespace + !children().empty() && + // and whitespace after certain constructs + !holds_one_of_alternatives<DocHtmlDescList, DocHtmlTable, DocHtmlList, DocSimpleSect, + DocAutoList, DocSimpleList, DocHtmlHeader, DocHtmlBlockQuote, + DocParamSect, DocXRefItem>(children().back()) + ) + ) + { + children().append<DocWhiteSpace>(parser(),thisVariant,parser()->context.token->chars); + } + } + break; + case TK_LISTITEM: + { + DBG(("found list item at %d\n",parser()->context.token->indent)); + const DocNodeVariant *n=parent(); + while (n && !std::holds_alternative<DocAutoList>(*n)) n=::parent(n); + const DocAutoList *al = std::get_if<DocAutoList>(n); + if (al) // we found an auto list up in the hierarchy + { + DBG(("previous list item at %d\n",al->indent())); + if (al->indent()>=parser()->context.token->indent) + // new item at the same or lower indent level + { + retval=TK_LISTITEM; + goto endparagraph; + } + } + + // determine list depth + int depth = 0; + n=parent(); + while (n) + { + al = std::get_if<DocAutoList>(n); + if (al && al->isEnumList()) depth++; + n=::parent(n); + } + + // first item or sub list => create new list + do + { + auto vDocAutoList = children().append<DocAutoList>(parser(),thisVariant, + parser()->context.token->indent, + parser()->context.token->isEnumList,depth); + al = children().get_last<DocAutoList>(); + retval = children().get_last<DocAutoList>()->parse(vDocAutoList); + } while (retval==TK_LISTITEM && // new list + al->indent()==parser()->context.token->indent // at same indent level + ); + + // check the return value + if (retval==RetVal_SimpleSec) // auto list ended due to simple section command + { + // Reparse the token that ended the section at this level, + // so a new simple section will be started at this level. + // This is the same as unputting the last read token and continuing. + parser()->context.token->name = parser()->context.token->simpleSectName; + if (parser()->context.token->name.left(4)=="rcs:") // RCS section + { + parser()->context.token->name = parser()->context.token->name.mid(4); + parser()->context.token->text = parser()->context.token->simpleSectText; + tok = TK_RCSTAG; + } + else // other section + { + tok = TK_COMMAND_BS; + } + DBG(("reparsing command %s\n",qPrint(parser()->context.token->name))); + goto reparsetoken; + } + else if (retval==TK_ENDLIST) + { + if (al->indent()>parser()->context.token->indent) // end list + { + goto endparagraph; + } + else // continue with current paragraph + { + } + } + else // paragraph ended due to TK_NEWPARA, TK_LISTITEM, or EOF + { + goto endparagraph; + } + } + break; + case TK_ENDLIST: + DBG(("Found end of list inside of paragraph at line %d\n",parser()->tokenizer.getLineNr())); + if (std::get_if<DocAutoListItem>(parent())) + { + const DocAutoList *al = std::get_if<DocAutoList>(::parent(parent())); + if (al && al->indent()>=parser()->context.token->indent) + { + // end of list marker ends this paragraph + retval=TK_ENDLIST; + goto endparagraph; + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"End of list marker found " + "has invalid indent level"); + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"End of list marker found without any preceding " + "list items"); + } + break; + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + { + // see if we have to start a simple section + int cmd = Mappers::cmdMapper->map(parser()->context.token->name); + const DocNodeVariant *n=parent(); + while (n && !std::holds_alternative<DocSimpleSect>(*n) && + !std::holds_alternative<DocParamSect>(*n)) + { + n=::parent(n); + } + if (cmd&SIMPLESECT_BIT) + { + if (n) // already in a simple section + { + // simple section cannot start in this paragraph, need + // to unwind the stack and remember the command. + parser()->context.token->simpleSectName = parser()->context.token->name; + retval=RetVal_SimpleSec; + goto endparagraph; + } + } + // see if we are in a simple list + n=parent(); + while (n && !std::holds_alternative<DocSimpleListItem>(*n)) n=::parent(n); + if (n) + { + if (cmd==CMD_LI) + { + retval=RetVal_ListItem; + goto endparagraph; + } + } + + // handle the command + retval=handleCommand(thisVariant,parser()->context.token->name,tok); + DBG(("handleCommand returns %s\n",DocTokenizer::retvalToString(retval))); + + // check the return value + if (retval==RetVal_SimpleSec) + { + // Reparse the token that ended the section at this level, + // so a new simple section will be started at this level. + // This is the same as unputting the last read token and continuing. + parser()->context.token->name = parser()->context.token->simpleSectName; + if (parser()->context.token->name.left(4)=="rcs:") // RCS section + { + parser()->context.token->name = parser()->context.token->name.mid(4); + parser()->context.token->text = parser()->context.token->simpleSectText; + tok = TK_RCSTAG; + } + else // other section + { + tok = TK_COMMAND_BS; + } + DBG(("reparsing command %s\n",qPrint(parser()->context.token->name))); + goto reparsetoken; + } + else if (retval>0 && retval<RetVal_OK) + { + // the command ended with a new command, reparse this token + tok = retval; + goto reparsetoken; + } + else if (retval != RetVal_OK) // end of file, end of paragraph, start or end of section + // or some auto list marker + { + goto endparagraph; + } + } + break; + case TK_HTMLTAG: + { + if (!parser()->context.token->endTag) // found a start tag + { + retval = handleHtmlStartTag(thisVariant,parser()->context.token->name,parser()->context.token->attribs); + } + else // found an end tag + { + retval = handleHtmlEndTag(thisVariant,parser()->context.token->name); + } + if (retval!=RetVal_OK) + { + goto endparagraph; + } + } + break; + case TK_SYMBOL: + { + HtmlEntityMapper::SymType s = DocSymbol::decodeSymbol(parser()->context.token->name); + if (s!=HtmlEntityMapper::Sym_Unknown) + { + children().append<DocSymbol>(parser(),thisVariant,s); + } + else + { + children().append<DocWord>(parser(),thisVariant,parser()->context.token->name); + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unsupported symbol %s found", + qPrint(parser()->context.token->name)); + } + break; + } + case TK_NEWPARA: + retval=TK_NEWPARA; + goto endparagraph; + case TK_RCSTAG: + { + const DocNodeVariant *n=parent(); + while (n && !std::holds_alternative<DocSimpleSect>(*n) && + !std::holds_alternative<DocParamSect>(*n)) + { + n=::parent(n); + } + if (n) // already in a simple section + { + // simple section cannot start in this paragraph, need + // to unwind the stack and remember the command. + parser()->context.token->simpleSectName = "rcs:"+parser()->context.token->name; + parser()->context.token->simpleSectText = parser()->context.token->text; + retval=RetVal_SimpleSec; + goto endparagraph; + } + + // see if we are in a simple list + auto vDocSimpleSect = children().append<DocSimpleSect>(parser(),thisVariant,DocSimpleSect::Rcs); + children().get_last<DocSimpleSect>()->parseRcs(vDocSimpleSect); + } + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(), + "Found unexpected token (id=%s)\n",DocTokenizer::tokToString(tok)); + break; + } + } + retval=0; +endparagraph: + parser()->handlePendingStyleCommands(thisVariant,children()); + DBG(("DocPara::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); + DocPara *par = std::get_if<DocPara>(parser()->context.nodeStack.top()); + if (!parser()->context.token->endTag && par && + retval==TK_NEWPARA && parser()->context.token->name.lower() == "p") + { + par->setAttribs(parser()->context.token->attribs); + } + INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || + retval==TK_ENDLIST || retval>RetVal_OK + ); + + return retval; +} + +//-------------------------------------------------------------------------- + +int DocSection::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocSection::parse() start %s level=%d\n",qPrint(parser()->context.token->sectionId),m_level)); + int retval=RetVal_OK; + auto ns = AutoNodeStack(parser(),thisVariant); + + if (!m_id.isEmpty()) + { + const SectionInfo *sec = SectionManager::instance().find(m_id); + if (sec) + { + m_file = sec->fileName(); + m_anchor = sec->label(); + m_title = sec->title(); + if (m_title.isEmpty()) m_title = sec->label(); + } + } + + // first parse any number of paragraphs + bool isFirst=TRUE; + DocPara *lastPar=0; + do + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + DocPara *par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (!par->isEmpty()) + { + if (lastPar) lastPar->markLast(FALSE); + lastPar = par; + } + else + { + children().pop_back(); + } + if (retval==TK_LISTITEM) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid list item found"); + } + if (retval==RetVal_Internal) + { + auto vDocInternal = children().append<DocInternal>(parser(),thisVariant); + retval = children().get_last<DocInternal>()->parse(vDocInternal,m_level+1); + if (retval==RetVal_EndInternal) + { + retval=RetVal_OK; + } + } + } while (retval!=0 && + retval!=RetVal_Section && + retval!=RetVal_Subsection && + retval!=RetVal_Subsubsection && + retval!=RetVal_Paragraph && + retval!=RetVal_EndInternal + ); + + if (lastPar) lastPar->markLast(); + + //printf("m_level=%d <-> %d\n",m_level,Doxygen::subpageNestingLevel); + + while (true) + { + if (retval==RetVal_Subsection && m_level<=Doxygen::subpageNestingLevel+1) + { + // then parse any number of nested sections + while (retval==RetVal_Subsection) // more sections follow + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(2+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + break; + } + else if (retval==RetVal_Subsubsection && m_level<=Doxygen::subpageNestingLevel+2) + { + if ((m_level<=1+Doxygen::subpageNestingLevel) && !parser()->context.token->sectionId.startsWith("autotoc_md")) + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected subsubsection command found inside %s!",g_sectionLevelToName[m_level]); + // then parse any number of nested sections + while (retval==RetVal_Subsubsection) // more sections follow + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(3+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + if (!(m_level<Doxygen::subpageNestingLevel+2 && retval == RetVal_Subsection)) break; + } + else if (retval==RetVal_Paragraph && m_level<=std::min(5,Doxygen::subpageNestingLevel+3)) + { + if ((m_level<=2+Doxygen::subpageNestingLevel) && !parser()->context.token->sectionId.startsWith("autotoc_md")) + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected paragraph command found inside %s!",g_sectionLevelToName[m_level]); + // then parse any number of nested sections + while (retval==RetVal_Paragraph) // more sections follow + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(4+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + if (!(m_level<Doxygen::subpageNestingLevel+3 && (retval == RetVal_Subsection || retval == RetVal_Subsubsection))) break; + } + else + { + break; + } + } + + INTERNAL_ASSERT(retval==0 || + retval==RetVal_Section || + retval==RetVal_Subsection || + retval==RetVal_Subsubsection || + retval==RetVal_Paragraph || + retval==RetVal_Internal || + retval==RetVal_EndInternal + ); + + DBG(("DocSection::parse() end: retval=%s\n",DocTokenizer::retvalToString(retval))); + return retval; +} + +//-------------------------------------------------------------------------- + +void DocText::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocText::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + parser()->tokenizer.setStateText(); + + int tok; + while ((tok=parser()->tokenizer.lex())) // get the next token + { + switch(tok) + { + case TK_WORD: + children().append<DocWord>(parser(),thisVariant,parser()->context.token->name); + break; + case TK_WHITESPACE: + children().append<DocWhiteSpace>(parser(),thisVariant,parser()->context.token->chars); + break; + case TK_SYMBOL: + { + HtmlEntityMapper::SymType s = DocSymbol::decodeSymbol(parser()->context.token->name); + if (s!=HtmlEntityMapper::Sym_Unknown) + { + children().append<DocSymbol>(parser(),thisVariant,s); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unsupported symbol %s found", + qPrint(parser()->context.token->name)); + } + } + break; + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + switch (Mappers::cmdMapper->map(parser()->context.token->name)) + { + case CMD_BSLASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_BSlash); + break; + case CMD_AT: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_At); + break; + case CMD_LESS: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Less); + break; + case CMD_GREATER: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Greater); + break; + case CMD_AMP: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Amp); + break; + case CMD_DOLLAR: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Dollar); + break; + case CMD_HASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Hash); + break; + case CMD_DCOLON: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_DoubleColon); + break; + case CMD_PERCENT: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Percent); + break; + case CMD_NDASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + break; + case CMD_MDASH: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + break; + case CMD_QUOTE: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Quot); + break; + case CMD_PUNT: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Dot); + break; + case CMD_PLUS: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Plus); + break; + case CMD_MINUS: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Minus); + break; + case CMD_EQUAL: + children().append<DocSymbol>(parser(),thisVariant,HtmlEntityMapper::Sym_Equal); + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected command '%s' found", + qPrint(parser()->context.token->name)); + break; + } + break; + default: + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected token %s", + DocTokenizer::tokToString(tok)); + break; + } + } + + parser()->handleUnclosedStyleCommands(); + + DBG(("DocText::parse() end\n")); +} + + +//-------------------------------------------------------------------------- + +void DocRoot::parse(DocNodeVariant *thisVariant) +{ + DBG(("DocRoot::parse() start\n")); + auto ns = AutoNodeStack(parser(),thisVariant); + parser()->tokenizer.setStatePara(); + int retval=0; + + // first parse any number of paragraphs + bool isFirst=TRUE; + DocPara *lastPar=0; + do + { + { + auto vDocPara = children().append<DocPara>(parser(),thisVariant); + DocPara *par = children().get_last<DocPara>(); + if (isFirst) { par->markFirst(); isFirst=FALSE; } + retval=par->parse(vDocPara); + if (par->isEmpty() && par->attribs().empty()) + { + children().pop_back(); + } + else + { + lastPar = par; + } + } + if (retval==RetVal_Paragraph) + { + if (!parser()->context.token->sectionId.startsWith("autotoc_md")) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"found paragraph command (id: '%s') outside of subsubsection context!",qPrint(parser()->context.token->sectionId)); + } + while (retval==RetVal_Paragraph) + { + if (!parser()->context.token->sectionId.isEmpty()) + { + const SectionInfo *sec=SectionManager::instance().find(parser()->context.token->sectionId); + if (sec) + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(4+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid paragraph id '%s'; ignoring paragraph",qPrint(parser()->context.token->sectionId)); + retval = 0; + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing id for paragraph; ignoring paragraph"); + retval = 0; + } + } + } + if (retval==RetVal_Subsubsection) + { + if (!(parser()->context.token->sectionId.startsWith("autotoc_md"))) + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"found subsubsection command (id: '%s') outside of subsection context!",qPrint(parser()->context.token->sectionId)); + while (retval==RetVal_Subsubsection) + { + if (!parser()->context.token->sectionId.isEmpty()) + { + const SectionInfo *sec=SectionManager::instance().find(parser()->context.token->sectionId); + if (sec) + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(3+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid subsubsection id '%s'; ignoring subsubsection",qPrint(parser()->context.token->sectionId)); + retval = 0; + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing id for subsubsection; ignoring subsubsection"); + retval = 0; + } + } + } + if (retval==RetVal_Subsection) + { + if (!parser()->context.token->sectionId.startsWith("autotoc_md")) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"found subsection command (id: '%s') outside of section context!",qPrint(parser()->context.token->sectionId)); + } + while (retval==RetVal_Subsection) + { + if (!parser()->context.token->sectionId.isEmpty()) + { + const SectionInfo *sec=SectionManager::instance().find(parser()->context.token->sectionId); + if (sec) + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(2+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid subsection id '%s'; ignoring subsection",qPrint(parser()->context.token->sectionId)); + retval = 0; + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing id for subsection; ignoring subsection"); + retval = 0; + } + } + } + if (retval==TK_LISTITEM) + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid list item found"); + } + if (retval==RetVal_Internal) + { + auto vDocInternal = children().append<DocInternal>(parser(),thisVariant); + retval = children().get_last<DocInternal>()->parse(vDocInternal,1); + } + } while (retval!=0 && retval!=RetVal_Section); + if (lastPar) lastPar->markLast(); + + //printf("DocRoot::parse() retval=%d %d\n",retval,RetVal_Section); + // then parse any number of level1 sections + while (retval==RetVal_Section) + { + if (!parser()->context.token->sectionId.isEmpty()) + { + const SectionInfo *sec=SectionManager::instance().find(parser()->context.token->sectionId); + if (sec) + { + auto vDocSection = children().append<DocSection>(parser(),thisVariant, + std::min(1+Doxygen::subpageNestingLevel,5), + parser()->context.token->sectionId); + retval = children().get_last<DocSection>()->parse(vDocSection); + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Invalid section id '%s'; ignoring section",qPrint(parser()->context.token->sectionId)); + retval = 0; + } + } + else + { + warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Missing id for section; ignoring section"); + retval = 0; + } + } + + parser()->handleUnclosedStyleCommands(); + + DBG(("DocRoot::parse() end\n")); +} + +static QCString extractCopyDocId(const char *data, uint &j, uint len) +{ + uint s=j; + int round=0; + bool insideDQuote=FALSE; + bool insideSQuote=FALSE; + bool found=FALSE; + while (j<len && !found) + { + if (!insideSQuote && !insideDQuote) + { + switch (data[j]) + { + case '(': round++; break; + case ')': round--; break; + case '"': insideDQuote=TRUE; break; + case '\'': insideSQuote=TRUE; break; + case ' ': // fall through + case '\t': // fall through + case '\n': + found=(round==0); + break; + } + } + else if (insideSQuote) // look for single quote end + { + if (data[j]=='\'' && (j==0 || data[j]!='\\')) + { + insideSQuote=FALSE; + } + } + else if (insideDQuote) // look for double quote end + { + if (data[j]=='"' && (j==0 || data[j]!='\\')) + { + insideDQuote=FALSE; + } + } + if (!found) j++; + } + if (qstrncmp(data+j," const",6)==0) + { + j+=6; + } + else if (qstrncmp(data+j," volatile",9)==0) + { + j+=9; + } + uint e=j; + if (j>0 && data[j-1]=='.') { e--; } // do not include punctuation added by Definition::_setBriefDescription() + QCString id(data+s,e-s); + //printf("extractCopyDocId='%s' input='%s'\n",qPrint(id),&data[s]); + return id; +} + +// macro to check if the input starts with a specific command. +// note that data[i] should point to the start of the command (\ or @ character) +// and the sizeof(str) returns the size of str including the '\0' terminator; +// a fact we abuse to skip over the start of the command character. +#define CHECK_FOR_COMMAND(str,action) \ + do if ((i+sizeof(str)<len) && qstrncmp(data+i+1,str,sizeof(str)-1)==0) \ + { j=i+sizeof(str); action; } while(0) + +static uint isCopyBriefOrDetailsCmd(const char *data, uint i,uint len,bool &brief) +{ + uint j=0; + if (i==0 || (data[i-1]!='@' && data[i-1]!='\\')) // not an escaped command + { + CHECK_FOR_COMMAND("copybrief",brief=TRUE); // @copybrief or \copybrief + CHECK_FOR_COMMAND("copydetails",brief=FALSE); // @copydetails or \copydetails + } + return j; +} + +static uint isVerbatimSection(const char *data,uint i,uint len,QCString &endMarker) +{ + uint j=0; + if (i==0 || (data[i-1]!='@' && data[i-1]!='\\')) // not an escaped command + { + CHECK_FOR_COMMAND("dot",endMarker="enddot"); + CHECK_FOR_COMMAND("code",endMarker="endcode"); + CHECK_FOR_COMMAND("msc",endMarker="endmsc"); + CHECK_FOR_COMMAND("verbatim",endMarker="endverbatim"); + CHECK_FOR_COMMAND("iliteral",endMarker="endiliteral"); + CHECK_FOR_COMMAND("latexonly",endMarker="endlatexonly"); + CHECK_FOR_COMMAND("htmlonly",endMarker="endhtmlonly"); + CHECK_FOR_COMMAND("xmlonly",endMarker="endxmlonly"); + CHECK_FOR_COMMAND("rtfonly",endMarker="endrtfonly"); + CHECK_FOR_COMMAND("manonly",endMarker="endmanonly"); + CHECK_FOR_COMMAND("docbookonly",endMarker="enddocbookonly"); + CHECK_FOR_COMMAND("startuml",endMarker="enduml"); + } + //printf("isVerbatimSection(%s)=%d)\n",qPrint(QCString(&data[i]).left(10)),j); + return j; +} + +static uint skipToEndMarker(const char *data,uint i,uint len,const QCString &endMarker) +{ + while (i<len) + { + if ((data[i]=='@' || data[i]=='\\') && // start of command character + (i==0 || (data[i-1]!='@' && data[i-1]!='\\'))) // that is not escaped + { + if (i+endMarker.length()+1<=len && qstrncmp(data+i+1,endMarker.data(),endMarker.length())==0) + { + return i+endMarker.length()+1; + } + } + i++; + } + // oops no endmarker found... + return i<len ? i+1 : len; +} + +QCString DocParser::processCopyDoc(const char *data,uint &len) +{ + //printf("processCopyDoc start '%s'\n",data); + GrowBuf buf; + uint i=0; + while (i<len) + { + char c = data[i]; + if (c=='@' || c=='\\') // look for a command + { + bool isBrief=TRUE; + uint j=isCopyBriefOrDetailsCmd(data,i,len,isBrief); + if (j>0) + { + // skip whitespace + while (j<len && (data[j]==' ' || data[j]=='\t')) j++; + // extract the argument + QCString id = extractCopyDocId(data,j,len); + const Definition *def = 0; + QCString doc,brief; + //printf("resolving docs='%s'\n",qPrint(id)); + if (findDocsForMemberOrCompound(id,&doc,&brief,&def)) + { + //printf("found it def=%p brief='%s' doc='%s' isBrief=%d\n",def,qPrint(brief),qPrint(doc),isBrief); + auto it = std::find(context.copyStack.begin(),context.copyStack.end(),def); + if (it==context.copyStack.end()) // definition not parsed earlier + { + context.copyStack.push_back(def); + if (isBrief) + { + uint l=static_cast<uint>(brief.length()); + buf.addStr(processCopyDoc(brief.data(),l)); + } + else + { + uint l=static_cast<uint>(doc.length()); + buf.addStr(processCopyDoc(doc.data(),l)); + } + context.copyStack.pop_back(); + } + else + { + warn_doc_error(context.fileName,tokenizer.getLineNr(), + "Found recursive @copy%s or @copydoc relation for argument '%s'.\n", + isBrief?"brief":"details",qPrint(id)); + } + } + else + { + warn_doc_error(context.fileName,tokenizer.getLineNr(), + "@copy%s or @copydoc target '%s' not found", isBrief?"brief":"details", + qPrint(id)); + } + // skip over command + i=j; + } + else + { + QCString endMarker; + uint k = isVerbatimSection(data,i,len,endMarker); + if (k>0) + { + uint orgPos = i; + i=skipToEndMarker(data,k,len,endMarker); + buf.addStr(data+orgPos,i-orgPos); + } + else + { + buf.addChar(c); + i++; + } + } + } + else // not a command, just copy + { + buf.addChar(c); + i++; + } + } + len = static_cast<uint>(buf.getPos()); + buf.addChar(0); + return buf.get(); +} + diff --git a/src/docnode.h b/src/docnode.h new file mode 100644 index 0000000..1db32dc --- /dev/null +++ b/src/docnode.h @@ -0,0 +1,1383 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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 DOCNODE_H +#define DOCNODE_H + +#include <stdio.h> +#include <vector> +#include <memory> +#include <variant> + +#include "qcstring.h" +#include "docvisitor.h" +#include "docparser.h" +#include "htmlattrib.h" +#include "htmlentity.h" +#include "growvector.h" + +class MemberDef; +class Definition; +class DocParser; + +//--------------------------------------------------------------------------- + +#define DOC_NODES \ +/* 0 */ DN(DocWord) DN_SEP DN(DocLinkedWord) DN_SEP DN(DocURL) DN_SEP DN(DocLineBreak) DN_SEP DN(DocHorRuler) DN_SEP \ +/* 5 */ DN(DocAnchor) DN_SEP DN(DocCite) DN_SEP DN(DocStyleChange) DN_SEP DN(DocSymbol) DN_SEP DN(DocEmoji) DN_SEP \ +/* 10 */ DN(DocWhiteSpace) DN_SEP DN(DocSeparator) DN_SEP DN(DocVerbatim) DN_SEP DN(DocInclude) DN_SEP DN(DocIncOperator) DN_SEP \ +/* 15 */ DN(DocFormula) DN_SEP DN(DocIndexEntry) DN_SEP DN(DocAutoList) DN_SEP DN(DocAutoListItem) DN_SEP DN(DocTitle) DN_SEP \ +/* 20 */ DN(DocXRefItem) DN_SEP DN(DocImage) DN_SEP DN(DocDotFile) DN_SEP DN(DocMscFile) DN_SEP DN(DocDiaFile) DN_SEP \ +/* 25 */ DN(DocVhdlFlow) DN_SEP DN(DocLink) DN_SEP DN(DocRef) DN_SEP DN(DocInternalRef) DN_SEP DN(DocHRef) DN_SEP \ +/* 30 */ DN(DocHtmlHeader) DN_SEP DN(DocHtmlDescTitle) DN_SEP DN(DocHtmlDescList) DN_SEP DN(DocSection) DN_SEP DN(DocSecRefItem) DN_SEP \ +/* 35 */ DN(DocSecRefList) DN_SEP DN(DocInternal) DN_SEP DN(DocParBlock) DN_SEP DN(DocSimpleList) DN_SEP DN(DocHtmlList) DN_SEP \ +/* 40 */ DN(DocSimpleSect) DN_SEP DN(DocSimpleSectSep) DN_SEP DN(DocParamSect) DN_SEP DN(DocPara) DN_SEP DN(DocParamList) DN_SEP \ +/* 45 */ DN(DocSimpleListItem) DN_SEP DN(DocHtmlListItem) DN_SEP DN(DocHtmlDescData) DN_SEP DN(DocHtmlCell) DN_SEP DN(DocHtmlCaption) DN_SEP \ +/* 50 */ DN(DocHtmlRow) DN_SEP DN(DocHtmlTable) DN_SEP DN(DocHtmlBlockQuote) DN_SEP DN(DocText) DN_SEP DN(DocRoot) \ + +// forward declarations +#define DN(x) class x; +#define DN_SEP +DOC_NODES +#undef DN +#undef DN_SEP + +// define a variant type +using DocNodeVariant = std::variant< +#define DN(x) x +#define DN_SEP , +DOC_NODES +#undef DN +#undef DN_SEP +>; + +// getter functions to return the name of a doc node type +#define DN(x) constexpr const char *docNodeName(const x &n) { return #x; } +#define DN_SEP +DOC_NODES +#undef DN +#undef DN_SEP + +/** Abstract node interface with type information. */ +class DocNode +{ + public: + /*! Creates a new node */ + DocNode(DocParser *parser,DocNodeVariant *parent) : m_parser(parser), m_parent(parent) {} + + // allow nodes to be moved but not copied + DocNode(const DocNode &) = delete; + DocNode &operator=(const DocNode &) = delete; + DocNode(DocNode &&) = default; + DocNode &operator=(DocNode &&) = default; + ~DocNode() = default; + + /*! Returns the parent of this node or 0 for the root node. */ + DocNodeVariant *parent() { return m_parent; } + const DocNodeVariant *parent() const { return m_parent; } + + DocParser *parser() { return m_parser; } + const DocParser *parser() const { return m_parser; } + + /*! Sets a new parent for this node. */ + void setParent(DocNodeVariant *parent) { m_parent = parent; } + + /*! Returns TRUE iff this node is inside a preformatted section */ + bool isPreformatted() const { return m_insidePre; } + + protected: + /*! Sets whether or not this item is inside a preformatted section */ + void setInsidePreformatted(bool p) { m_insidePre = p; } + enum RefType { Unknown, Anchor, Section, Table }; + private: + bool m_insidePre = false; + DocParser *m_parser; + DocNodeVariant *m_parent; +}; + +struct DocNodeList : public GrowVector<DocNodeVariant> +{ + /** Append a new DocNodeVariant to the list by constructing it with type T and + * parameters Args. + */ + template<class T,class...Args> + [[maybe_unused]] DocNodeVariant *append(Args&&... args); + + /** moves the element of list \a l at the end of this list. + * List \a l will become empty. */ + void move_append(DocNodeList &l); + + /** Returns a pointer to the last element in the list if that element exists and + * holds a T, otherwise nullptr is returned. + */ + template<class T> + T *get_last(); +}; + +/** Base class for nodes with children */ +class DocCompoundNode : public DocNode +{ + public: + DocCompoundNode(DocParser *parser,DocNodeVariant *parent) + : DocNode(parser,parent) {} + DocNodeList &children() { return m_children; } + const DocNodeList &children() const { return m_children; } + + private: + DocNodeList m_children; +}; + +/** Node representing a word + */ +class DocWord : public DocNode +{ + public: + DocWord(DocParser *parser,DocNodeVariant *parent,const QCString &word); + QCString word() const { return m_word; } + + private: + QCString m_word; +}; + +/** Node representing a word that can be linked to something + */ +class DocLinkedWord : public DocNode +{ + public: + DocLinkedWord(DocParser *parser,DocNodeVariant *parent,const QCString &word, + const QCString &ref,const QCString &file, + const QCString &anchor,const QCString &tooltip); + QCString word() const { return m_word; } + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + QCString ref() const { return m_ref; } + QCString anchor() const { return m_anchor; } + QCString tooltip() const { return m_tooltip; } + + private: + QCString m_word; + QCString m_ref; + QCString m_file; + QCString m_relPath; + QCString m_anchor; + QCString m_tooltip; +}; + +/** Node representing a URL (or email address) */ +class DocURL : public DocNode +{ + public: + DocURL(DocParser *parser,DocNodeVariant *parent,const QCString &url,bool isEmail) : + DocNode(parser,parent), m_url(url), m_isEmail(isEmail) {} + QCString url() const { return m_url; } + bool isEmail() const { return m_isEmail; } + + private: + QCString m_url; + bool m_isEmail = false; +}; + +/** Node representing a line break */ +class DocLineBreak : public DocNode +{ + public: + DocLineBreak(DocParser *parser,DocNodeVariant *parent) : DocNode(parser,parent) {} + DocLineBreak(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) + : DocNode(parser,parent), m_attribs(attribs) {} + + const HtmlAttribList &attribs() const { return m_attribs; } + + private: + HtmlAttribList m_attribs; +}; + +/** Node representing a horizontal ruler */ +class DocHorRuler : public DocNode +{ + public: + DocHorRuler(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) + : DocNode(parser,parent), m_attribs(attribs) {} + + const HtmlAttribList &attribs() const { return m_attribs; } + + private: + HtmlAttribList m_attribs; +}; + +/** Node representing an anchor */ +class DocAnchor : public DocNode +{ + public: + DocAnchor(DocParser *parser,DocNodeVariant *parent,const QCString &id,bool newAnchor); + QCString anchor() const { return m_anchor; } + QCString file() const { return m_file; } + + const HtmlAttribList &attribs() const { return m_attribs; } + + private: + QCString m_anchor; + QCString m_file; + HtmlAttribList m_attribs; +}; + +/** Node representing a citation of some bibliographic reference */ +class DocCite : public DocNode +{ + public: + DocCite(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &context); + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + QCString ref() const { return m_ref; } + QCString anchor() const { return m_anchor; } + QCString text() const { return m_text; } + + private: + QCString m_file; + QCString m_relPath; + QCString m_ref; + QCString m_anchor; + QCString m_text; +}; + + +/** Node representing a style change */ +class DocStyleChange : public DocNode +{ + public: + enum Style { Bold = (1<<0), + Italic = (1<<1), + Code = (1<<2), + Center = (1<<3), + Small = (1<<4), + Subscript = (1<<5), + Superscript = (1<<6), + Preformatted = (1<<7), + Span = (1<<8), + Div = (1<<9), + Strike = (1<<10), + Underline = (1<<11), + Del = (1<<12), + Ins = (1<<13), + S = (1<<14), + Details = (1<<15), + Summary = (1<<16), + Cite = (1<<17) + }; + + DocStyleChange(DocParser *parser,DocNodeVariant *parent,size_t position,Style s, + const QCString &tagName,bool enable, const HtmlAttribList *attribs=0) + : DocNode(parser,parent), m_position(position), m_style(s), m_enable(enable) + { + if (attribs) m_attribs=*attribs; + m_tagName = tagName.lower(); + } + Style style() const { return m_style; } + const char *styleString() const; + bool enable() const { return m_enable; } + size_t position() const { return m_position; } + const HtmlAttribList &attribs() const { return m_attribs; } + QCString tagName() const { return m_tagName; } + + private: + size_t m_position = 0; + Style m_style = Bold; + bool m_enable = false; + HtmlAttribList m_attribs; + QCString m_tagName; +}; + +/** Node representing a special symbol */ +class DocSymbol : public DocNode +{ + public: + DocSymbol(DocParser *parser,DocNodeVariant *parent,HtmlEntityMapper::SymType s) + : DocNode(parser,parent), m_symbol(s) {} + HtmlEntityMapper::SymType symbol() const { return m_symbol; } + static HtmlEntityMapper::SymType decodeSymbol(const QCString &symName); + + private: + HtmlEntityMapper::SymType m_symbol = HtmlEntityMapper::Sym_Unknown; +}; + +/** Node representing an emoji */ +class DocEmoji : public DocNode +{ + public: + DocEmoji(DocParser *parser,DocNodeVariant *parent,const QCString &symName); + QCString name() const { return m_symName; } + int index() const { return m_index; } + + private: + QCString m_symName; + int m_index = 0; +}; + +/** Node representing some amount of white space */ +class DocWhiteSpace : public DocNode +{ + public: + DocWhiteSpace(DocParser *parser,DocNodeVariant *parent,const QCString &chars) + : DocNode(parser,parent), m_chars(chars) {} + QCString chars() const { return m_chars; } + private: + QCString m_chars; +}; + +/** Node representing a separator */ +class DocSeparator : public DocNode +{ + public: + DocSeparator(DocParser *parser,DocNodeVariant *parent,const QCString &chars) + : DocNode(parser,parent), m_chars(chars) {} + QCString chars() const { return m_chars; } + private: + QCString m_chars; +}; + +/** Node representing a verbatim, unparsed text fragment */ +class DocVerbatim : public DocNode +{ + public: + enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc, DocbookOnly, PlantUML, JavaDocCode, JavaDocLiteral }; + DocVerbatim(DocParser *parser,DocNodeVariant *parent,const QCString &context, + const QCString &text, Type t,bool isExample, + const QCString &exampleFile,bool isBlock=FALSE,const QCString &lang=QCString()); + Type type() const { return p->type; } + QCString text() const { return p->text; } + QCString context() const { return p->context; } + bool isExample() const { return p->isExample; } + QCString exampleFile() const { return p->exampleFile; } + QCString relPath() const { return p->relPath; } + QCString language() const { return p->lang; } + bool isBlock() const { return p->isBlock; } + bool hasCaption() const { return !p->children.empty(); } + QCString width() const { return p->width; } + QCString height() const { return p->height; } + QCString engine() const { return p->engine; } + bool useBitmap() const { return p->useBitmap; } + const DocNodeList &children() const { return p->children; } + DocNodeList &children() { return p->children; } + QCString srcFile() const { return p->srcFile; } + int srcLine() const { return p->srcLine; } + void setText(const QCString &t) { p->text=t; } + void setWidth(const QCString &w) { p->width=w; } + void setHeight(const QCString &h) { p->height=h; } + void setEngine(const QCString &e) { p->engine=e; } + void setUseBitmap(const bool &u) { p->useBitmap=u; } + void setLocation(const QCString &file,int line) { p->srcFile=file; p->srcLine=line; } + + private: + struct Private + { + Private(const QCString &context_,const QCString &text_, Type type_, bool isExample_, + const QCString &exampleFile_, const QCString &relPath_,const QCString &lang_, bool isBlock_) + : context(context_), text(text_), type(type_), isExample(isExample_), + exampleFile(exampleFile_), relPath(relPath_), lang(lang_), isBlock(isBlock_) {} + QCString context; + QCString text; + Type type = Code; + bool isExample; + QCString exampleFile; + QCString relPath; + QCString lang; + bool isBlock; + QCString width; + QCString height; + QCString engine; + bool useBitmap=false; // some PlantUML engines cannot output data in EPS format so bitmap format is required + DocNodeList children; + QCString srcFile; + int srcLine = -1; + }; + std::unique_ptr<Private> p; +}; + + +/** Node representing an included text block from file */ +class DocInclude : public DocNode +{ + public: + enum Type { Include, DontInclude, VerbInclude, HtmlInclude, LatexInclude, + IncWithLines, Snippet , IncludeDoc, SnippetDoc, SnipWithLines, + DontIncWithLines, RtfInclude, ManInclude, DocbookInclude, XmlInclude}; + DocInclude(DocParser *parser,DocNodeVariant *parent,const QCString &file, + const QCString &context, Type t, + bool isExample,const QCString &exampleFile, + const QCString &blockId, bool isBlock) + : DocNode(parser,parent), m_file(file), m_context(context), m_type(t), + m_isExample(isExample), m_isBlock(isBlock), + m_exampleFile(exampleFile), m_blockId(blockId) {} + QCString file() const { return m_file; } + QCString extension() const { int i=m_file.findRev('.'); + if (i!=-1) + return m_file.right(m_file.length()-static_cast<uint>(i)); + else + return QCString(); + } + Type type() const { return m_type; } + QCString text() const { return m_text; } + QCString context() const { return m_context; } + QCString blockId() const { return m_blockId; } + bool isExample() const { return m_isExample; } + QCString exampleFile() const { return m_exampleFile; } + bool isBlock() const { return m_isBlock; } + void parse(DocNodeVariant *); + + private: + QCString m_file; + QCString m_context; + QCString m_text; + Type m_type; + bool m_isExample; + bool m_isBlock; + QCString m_exampleFile; + QCString m_blockId; +}; + +/** Node representing a include/dontinclude operator block */ +class DocIncOperator : public DocNode +{ + public: + enum Type { Line, SkipLine, Skip, Until }; + DocIncOperator(DocParser *parser,DocNodeVariant *parent,Type t,const QCString &pat, + const QCString &context,bool isExample,const QCString &exampleFile) + : DocNode(parser,parent), m_type(t), m_pattern(pat), m_context(context), + m_isFirst(FALSE), m_isLast(FALSE), + m_isExample(isExample), m_exampleFile(exampleFile) {} + Type type() const { return m_type; } + const char *typeAsString() const + { + switch(m_type) + { + case Line: return "line"; + case SkipLine: return "skipline"; + case Skip: return "skip"; + case Until: return "until"; + } + return ""; + } + int line() const { return m_line; } + bool showLineNo() const { return m_showLineNo; } + QCString text() const { return m_text; } + QCString pattern() const { return m_pattern; } + QCString context() const { return m_context; } + bool isFirst() const { return m_isFirst; } + bool isLast() const { return m_isLast; } + void markFirst(bool v=TRUE) { m_isFirst = v; } + void markLast(bool v=TRUE) { m_isLast = v; } + bool isExample() const { return m_isExample; } + QCString exampleFile() const { return m_exampleFile; } + QCString includeFileName() const { return m_includeFileName; } + void parse(DocNodeVariant *); + + private: + Type m_type = Line; + int m_line = 0; + bool m_showLineNo = false; + QCString m_text; + QCString m_pattern; + QCString m_context; + bool m_isFirst = false; + bool m_isLast = false; + bool m_isExample = false; + QCString m_exampleFile; + QCString m_includeFileName; +}; + +/** Node representing an item of a cross-referenced list */ +class DocFormula : public DocNode +{ + public: + DocFormula(DocParser *parser,DocNodeVariant *parent,int id); + QCString name() const { return m_name; } + QCString text() const { return m_text; } + QCString relPath() const { return m_relPath; } + int id() const { return m_id; } + bool isInline() const + { + if (m_text.length()>1 && m_text.at(0)=='\\' && m_text.at(1)=='[') return false; + if (m_text.startsWith("\\begin{")) return false; + return true; + } + + private: + QCString m_name; + QCString m_text; + QCString m_relPath; + int m_id = 0; +}; + +/** Node representing an entry in the index. */ +class DocIndexEntry : public DocNode +{ + public: + DocIndexEntry(DocParser *parser,DocNodeVariant *parent,const Definition *scope,const MemberDef *md) + : DocNode(parser,parent), m_scope(scope), m_member(md) {} + int parse(DocNodeVariant *); + const Definition *scope() const { return m_scope; } + const MemberDef *member() const { return m_member; } + QCString entry() const { return m_entry; } + + private: + QCString m_entry; + const Definition *m_scope = 0; + const MemberDef *m_member = 0; +}; + +//----------------------------------------------------------------------- + +/** Node representing an auto List */ +class DocAutoList : public DocCompoundNode +{ + public: + DocAutoList(DocParser *parser,DocNodeVariant *parent,int indent,bool isEnumList,int depth); + bool isEnumList() const { return m_isEnumList; } + int indent() const { return m_indent; } + int depth() const { return m_depth; } + int parse(DocNodeVariant *); + + private: + int m_indent = 0; + bool m_isEnumList = false; + int m_depth = 0; +}; + +/** Node representing an item of a auto list */ +class DocAutoListItem : public DocCompoundNode +{ + public: + DocAutoListItem(DocParser *parser,DocNodeVariant *parent,int indent,int num); + int itemNumber() const { return m_itemNum; } + int parse(DocNodeVariant *); + + private: + int m_indent = 0; + int m_itemNum = 0; +}; + + + +/** Node representing a simple section title */ +class DocTitle : public DocCompoundNode +{ + public: + DocTitle(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) {} + void parse(DocNodeVariant *); + void parseFromString(DocNodeVariant *,const QCString &title); + bool hasTitle() const { return !children().empty(); } + + private: +}; + +/** Node representing an item of a cross-referenced list */ +class DocXRefItem : public DocCompoundNode +{ + public: + DocXRefItem(DocParser *parser,DocNodeVariant *parent,int id,const QCString &key); + QCString file() const { return m_file; } + QCString anchor() const { return m_anchor; } + QCString title() const { return m_title; } + QCString relPath() const { return m_relPath; } + QCString key() const { return m_key; } + bool parse(DocNodeVariant *); + + private: + int m_id = 0; + QCString m_key; + QCString m_file; + QCString m_anchor; + QCString m_title; + QCString m_relPath; +}; + +/** Node representing an image */ +class DocImage : public DocCompoundNode +{ + public: + enum Type { Html, Latex, Rtf, DocBook, Xml }; + DocImage(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs, + const QCString &name,Type t,const QCString &url=QCString(), bool inlineImage = TRUE); + Type type() const { return p->type; } + QCString name() const { return p->name; } + bool hasCaption() const { return !children().empty(); } + QCString width() const { return p->width; } + QCString height() const { return p->height; } + QCString relPath() const { return p->relPath; } + QCString url() const { return p->url; } + bool isInlineImage() const { return p->inlineImage; } + bool isSVG() const; + const HtmlAttribList &attribs() const { return p->attribs; } + void parse(DocNodeVariant *); + + private: + struct Private + { + Private(const HtmlAttribList &attribs_,const QCString &name_,Type type_, + const QCString &relPath_, const QCString &url_,bool inlineImage_) + : attribs(attribs_), name(name_), type(type_), + relPath(relPath_), url(url_), inlineImage(inlineImage_) {} + HtmlAttribList attribs; + QCString name; + Type type = Html; + QCString width; + QCString height; + QCString relPath; + QCString url; + bool inlineImage; + }; + std::unique_ptr<Private> p; +}; + +class DocDiagramFileBase : public DocCompoundNode +{ + public: + DocDiagramFileBase(DocParser *parser, DocNodeVariant *parent,const QCString &name, + const QCString &context, const QCString &srcFile,int srcLine) + : DocCompoundNode(parser,parent), p(std::make_unique<Private>(name, context, srcFile, srcLine)) {} + QCString name() const { return p->name; } + QCString file() const { return p->file; } + QCString relPath() const { return p->relPath; } + bool hasCaption() const { return !children().empty(); } + QCString width() const { return p->width; } + QCString height() const { return p->height; } + QCString context() const { return p->context; } + QCString srcFile() const { return p->srcFile; } + int srcLine() const { return p->srcLine; } + + protected: + struct Private + { + Private(const QCString &name_,const QCString &context_,const QCString &srcFile_,int srcLine_) + : name(name_), context(context_), srcFile(srcFile_), srcLine(srcLine_) {} + QCString name; + QCString file; + QCString relPath; + QCString width; + QCString height; + QCString context; + QCString srcFile; + int srcLine; + }; + std::unique_ptr<Private> p; +}; + +/** Node representing a dot file */ +class DocDotFile : public DocDiagramFileBase +{ + public: + DocDotFile(DocParser *parser,DocNodeVariant *parent,const QCString &name,const QCString &context, + const QCString &srcFile,int srcLine); + bool parse(DocNodeVariant *); +}; + +/** Node representing a msc file */ +class DocMscFile : public DocDiagramFileBase +{ + public: + DocMscFile(DocParser *parser,DocNodeVariant *parent,const QCString &name,const QCString &context, + const QCString &srcFile,int srcLine); + bool parse(DocNodeVariant *); +}; + +/** Node representing a dia file */ +class DocDiaFile : public DocDiagramFileBase +{ + public: + DocDiaFile(DocParser *parser,DocNodeVariant *parent,const QCString &name,const QCString &context, + const QCString &srcFile,int srcLine); + bool parse(DocNodeVariant *); +}; + +/** Node representing a VHDL flow chart */ +class DocVhdlFlow : public DocCompoundNode +{ + public: + DocVhdlFlow(DocParser *parser,DocNodeVariant *parent); + void parse(DocNodeVariant *); + bool hasCaption() const { return !children().empty(); } + private: +}; + +/** Node representing a link to some item */ +class DocLink : public DocCompoundNode +{ + public: + DocLink(DocParser *parser,DocNodeVariant *parent,const QCString &target); + QCString parse(DocNodeVariant *,bool,bool isXmlLink=FALSE); + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + QCString ref() const { return m_ref; } + QCString anchor() const { return m_anchor; } + + private: + QCString m_file; + QCString m_relPath; + QCString m_ref; + QCString m_anchor; + QCString m_refText; +}; + +/** Node representing a reference to some item */ +class DocRef : public DocCompoundNode +{ + public: + DocRef(DocParser *parser,DocNodeVariant *parent,const QCString &target,const QCString &context); + void parse(DocNodeVariant *); + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + QCString ref() const { return m_ref; } + QCString anchor() const { return m_anchor; } + QCString targetTitle() const { return m_text; } + bool hasLinkText() const { return !children().empty(); } + bool refToAnchor() const { return m_refType==Anchor; } + bool refToSection() const { return m_refType==Section; } + bool refToTable() const { return m_refType==Table; } + bool isSubPage() const { return m_isSubPage; } + + private: + RefType m_refType = Unknown; + bool m_isSubPage = false; + QCString m_file; + QCString m_relPath; + QCString m_ref; + QCString m_anchor; + QCString m_text; +}; + +/** Node representing an internal reference to some item */ +class DocInternalRef : public DocCompoundNode +{ + public: + DocInternalRef(DocParser *parser,DocNodeVariant *parent,const QCString &target); + void parse(DocNodeVariant*); + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + QCString anchor() const { return m_anchor; } + + private: + QCString m_file; + QCString m_relPath; + QCString m_anchor; +}; + +/** Node representing a Hypertext reference */ +class DocHRef : public DocCompoundNode +{ + public: + DocHRef(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs,const QCString &url, + const QCString &relPath, const QCString &file) + : DocCompoundNode(parser,parent), m_attribs(attribs), m_url(url), + m_relPath(relPath), m_file(file) {} + int parse(DocNodeVariant*); + QCString url() const { return m_url; } + QCString file() const { return m_file; } + QCString relPath() const { return m_relPath; } + const HtmlAttribList &attribs() const { return m_attribs; } + + private: + HtmlAttribList m_attribs; + QCString m_url; + QCString m_relPath; + QCString m_file; +}; + +/** Node Html heading */ +class DocHtmlHeader : public DocCompoundNode +{ + public: + DocHtmlHeader(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs,int level) : + DocCompoundNode(parser,parent), m_level(level), m_attribs(attribs) {} + int level() const { return m_level; } + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant*); + + private: + int m_level = 0; + HtmlAttribList m_attribs; +}; + +/** Node representing a Html description item */ +class DocHtmlDescTitle : public DocCompoundNode +{ + public: + DocHtmlDescTitle(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) : + DocCompoundNode(parser,parent), m_attribs(attribs) {} + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant*); + + private: + HtmlAttribList m_attribs; +}; + +/** Node representing a Html description list */ +class DocHtmlDescList : public DocCompoundNode +{ + public: + DocHtmlDescList(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) : + DocCompoundNode(parser,parent), m_attribs(attribs) {} + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant*); + + private: + HtmlAttribList m_attribs; +}; + +/** Node representing a normal section */ +class DocSection : public DocCompoundNode +{ + public: + DocSection(DocParser *parser,DocNodeVariant *parent,int level,const QCString &id) : + DocCompoundNode(parser,parent), m_level(level), m_id(id) {} + int level() const { return m_level; } + QCString title() const { return m_title; } + QCString anchor() const { return m_anchor; } + QCString id() const { return m_id; } + QCString file() const { return m_file; } + int parse(DocNodeVariant*); + + private: + int m_level = 0; + QCString m_id; + QCString m_title; + QCString m_anchor; + QCString m_file; +}; + +/** Node representing a reference to a section */ +class DocSecRefItem : public DocCompoundNode +{ + public: + DocSecRefItem(DocParser *parser,DocNodeVariant *parent,const QCString &target); + QCString target() const { return m_target; } + QCString file() const { return m_file; } + QCString anchor() const { return m_anchor; } + QCString relPath() const { return m_relPath; } + QCString ref() const { return m_ref; } + bool refToTable() const { return m_refType==Table; } + bool isSubPage() const { return m_isSubPage; } + void parse(DocNodeVariant *); + + private: + QCString m_target; + RefType m_refType = Unknown; + bool m_isSubPage = false; + QCString m_file; + QCString m_relPath; + QCString m_ref; + QCString m_anchor; +}; + +/** Node representing a list of section references */ +class DocSecRefList : public DocCompoundNode +{ + public: + DocSecRefList(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) {} + void parse(DocNodeVariant *); + + private: +}; + +/** Node representing an internal section of documentation */ +class DocInternal : public DocCompoundNode +{ + public: + DocInternal(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) {} + int parse(DocNodeVariant*,int); + + private: +}; + +/** Node representing an block of paragraphs */ +class DocParBlock : public DocCompoundNode +{ + public: + DocParBlock(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) {} + int parse(DocNodeVariant *); + + private: +}; + + +/** Node representing a simple list */ +class DocSimpleList : public DocCompoundNode +{ + public: + DocSimpleList(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) {} + int parse(DocNodeVariant *); + + private: +}; + +/** Node representing a Html list */ +class DocHtmlList : public DocCompoundNode +{ + public: + enum Type { Unordered, Ordered }; + DocHtmlList(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs,Type t) : + DocCompoundNode(parser,parent), m_type(t), m_attribs(attribs) {} + Type type() const { return m_type; } + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + int parseXml(DocNodeVariant *); + + private: + Type m_type = Unordered; + HtmlAttribList m_attribs; +}; + +/** Node representing a simple section */ +class DocSimpleSect : public DocCompoundNode +{ + public: + enum Type + { + Unknown, See, Return, Author, Authors, Version, Since, Date, + Note, Warning, Copyright, Pre, Post, Invar, Remark, Attention, User, Rcs + }; + DocSimpleSect(DocParser *parser,DocNodeVariant *parent,Type t); + Type type() const { return m_type; } + QCString typeString() const; + int parse(DocNodeVariant *,bool userTitle,bool needsSeparator); + int parseRcs(DocNodeVariant *); + int parseXml(DocNodeVariant *); + void appendLinkWord(DocNodeVariant *,const QCString &word); + bool hasTitle() const; + const DocNodeVariant *title() const { return m_title.get(); } + + private: + Type m_type = Unknown; + std::unique_ptr<DocNodeVariant> m_title; +}; + +/** Node representing a separator between two simple sections of the + * same type. + */ +class DocSimpleSectSep : public DocNode +{ + public: + DocSimpleSectSep(DocParser *parser,DocNodeVariant *parent) : DocNode(parser,parent) {} + + private: +}; + +/** Node representing a parameter section */ +class DocParamSect : public DocCompoundNode +{ + friend class DocParamList; + public: + enum Type + { + Unknown, Param, RetVal, Exception, TemplateParam + }; + enum Direction + { + In=1, Out=2, InOut=3, Unspecified=0 + }; + DocParamSect(DocParser *parser,DocNodeVariant *parent,Type t) + : DocCompoundNode(parser,parent), m_type(t), m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE) + {} + int parse(DocNodeVariant *,const QCString &cmdName,bool xmlContext,Direction d); + Type type() const { return m_type; } + bool hasInOutSpecifier() const { return m_hasInOutSpecifier; } + bool hasTypeSpecifier() const { return m_hasTypeSpecifier; } + + private: + Type m_type = Unknown; + bool m_hasInOutSpecifier = false; + bool m_hasTypeSpecifier = false; +}; + +/** Node representing a paragraph in the documentation tree */ +class DocPara : public DocCompoundNode +{ + public: + DocPara(DocParser *parser,DocNodeVariant *parent); + int parse(DocNodeVariant *); + bool isEmpty() const { return children().empty(); } + void markFirst(bool v=TRUE) { m_isFirst=v; } + void markLast(bool v=TRUE) { m_isLast=v; } + bool isFirst() const { return m_isFirst; } + bool isLast() const { return m_isLast; } + + int handleCommand(DocNodeVariant *thisVariant,const QCString &cmdName,const int tok); + int handleHtmlStartTag(DocNodeVariant *thisVariant,const QCString &tagName,const HtmlAttribList &tagHtmlAttribs); + int handleHtmlEndTag(DocNodeVariant *thisVariant,const QCString &tagName); + int handleSimpleSection(DocNodeVariant *thisVariant,DocSimpleSect::Type t,bool xmlContext=FALSE); + int handleXRefItem(DocNodeVariant *thisVariant); + int handleParamSection(DocNodeVariant *thisVariant,const QCString &cmdName,DocParamSect::Type t, + bool xmlContext, + int direction); + void handleIncludeOperator(DocNodeVariant *thisVariant,const QCString &cmdName,DocIncOperator::Type t); + template<class T> void handleFile(DocNodeVariant *thisVariant,const QCString &cmdName); + void handleInclude(DocNodeVariant *thisVariant,const QCString &cmdName,DocInclude::Type t); + void handleLink(DocNodeVariant *thisVariant,const QCString &cmdName,bool isJavaLink); + void handleCite(DocNodeVariant *thisVariant); + void handleEmoji(DocNodeVariant *thisVariant); + void handleRef(DocNodeVariant *thisVariant,const QCString &cmdName); + void handleSection(DocNodeVariant *thisVariant,const QCString &cmdName); + void handleInheritDoc(DocNodeVariant *thisVariant); + void handleVhdlFlow(DocNodeVariant *thisVariant); + void handleIline(DocNodeVariant *thisVariant); + int handleStartCode(DocNodeVariant *thisVariant); + int handleHtmlHeader(DocNodeVariant *thisVariant,const HtmlAttribList &tagHtmlAttribs,int level); + + bool injectToken(DocNodeVariant *thisVariant,int tok,const QCString &tokText); + const HtmlAttribList &attribs() const { return m_attribs; } + void setAttribs(const HtmlAttribList &attribs) { m_attribs = attribs; } + + private: + QCString m_sectionId; + bool m_isFirst = false; + bool m_isLast = false; + HtmlAttribList m_attribs; +}; + +/** Node representing a parameter list. */ +class DocParamList : public DocNode +{ + public: + DocParamList(DocParser *parser,DocNodeVariant *parent,DocParamSect::Type t,DocParamSect::Direction d) + : DocNode(parser,parent), m_type(t), m_dir(d) {} + const DocNodeList ¶meters() const { return m_params; } + const DocNodeList ¶mTypes() const { return m_paramTypes; } + const DocNodeList ¶graphs() const { return m_paragraphs; } + DocParamSect::Type type() const { return m_type; } + DocParamSect::Direction direction() const { return m_dir; } + void markFirst(bool b=TRUE) { m_isFirst=b; } + void markLast(bool b=TRUE) { m_isLast=b; } + bool isFirst() const { return m_isFirst; } + bool isLast() const { return m_isLast; } + int parse(DocNodeVariant *,const QCString &cmdName); + int parseXml(DocNodeVariant *,const QCString ¶mName); + + private: + DocNodeList m_paragraphs; + DocNodeList m_params; + DocNodeList m_paramTypes; + DocParamSect::Type m_type = DocParamSect::Unknown; + DocParamSect::Direction m_dir = DocParamSect::Unspecified; + bool m_isFirst = false; + bool m_isLast = false; +}; + +/** Node representing a simple list item */ +class DocSimpleListItem : public DocNode +{ + public: + DocSimpleListItem(DocParser *parser,DocNodeVariant *parent); + int parse(DocNodeVariant *); + const DocNodeVariant *paragraph() const { return m_paragraph.get(); } + + private: + std::unique_ptr<DocNodeVariant> m_paragraph; +}; + +/** Node representing a HTML list item */ +class DocHtmlListItem : public DocCompoundNode +{ + public: + DocHtmlListItem(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs,int num) + : DocCompoundNode(parser,parent), m_attribs(attribs), m_itemNum(num) {} + int itemNumber() const { return m_itemNum; } + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + int parseXml(DocNodeVariant *); + + private: + HtmlAttribList m_attribs; + int m_itemNum = 0; +}; + +/** Node representing a HTML description data */ +class DocHtmlDescData : public DocCompoundNode +{ + public: + DocHtmlDescData(DocParser *parser,DocNodeVariant *parent) : DocCompoundNode(parser,parent) {} + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + + private: + HtmlAttribList m_attribs; +}; + +/** Node representing a HTML table cell */ +class DocHtmlCell : public DocCompoundNode +{ + friend class DocHtmlTable; + public: + enum Alignment { Left, Right, Center }; + enum Valignment {Top, Middle, Bottom}; + DocHtmlCell(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs,bool isHeading) : + DocCompoundNode(parser,parent), m_isHeading(isHeading), m_attribs(attribs) {} + bool isHeading() const { return m_isHeading; } + bool isFirst() const { return m_isFirst; } + bool isLast() const { return m_isLast; } + void markFirst(bool v=TRUE) { m_isFirst=v; } + void markLast(bool v=TRUE) { m_isLast=v; } + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + int parseXml(DocNodeVariant *); + uint rowIndex() const { return m_rowIdx; } + uint columnIndex() const { return m_colIdx; } + uint rowSpan() const; + uint colSpan() const; + Alignment alignment() const; + Valignment valignment() const; + + private: + void setRowIndex(uint idx) { m_rowIdx = idx; } + void setColumnIndex(uint idx) { m_colIdx = idx; } + bool m_isHeading = false; + bool m_isFirst = false; + bool m_isLast = false; + HtmlAttribList m_attribs; + uint m_rowIdx = static_cast<uint>(-1); + uint m_colIdx = static_cast<uint>(-1); +}; + +/** Node representing a HTML table caption */ +class DocHtmlCaption : public DocCompoundNode +{ + public: + DocHtmlCaption(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs); + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + bool hasCaptionId() const { return m_hasCaptionId; } + QCString file() const { return m_file; } + QCString anchor() const { return m_anchor; } + + private: + HtmlAttribList m_attribs; + bool m_hasCaptionId = false; + QCString m_file; + QCString m_anchor; +}; + +/** Node representing a HTML table row */ +class DocHtmlRow : public DocCompoundNode +{ + friend class DocHtmlTable; + public: + DocHtmlRow(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) + : DocCompoundNode(parser,parent), m_attribs(attribs) {} + size_t numCells() const { return children().size(); } + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + int parseXml(DocNodeVariant *,bool header); + bool isHeading() const; + void setVisibleCells(uint n) { m_visibleCells = n; } + uint visibleCells() const { return m_visibleCells; } + uint rowIndex() const { return m_rowIdx; } + + private: + void setRowIndex(uint idx) { m_rowIdx = idx; } + HtmlAttribList m_attribs; + uint m_visibleCells = 0; + uint m_rowIdx = static_cast<uint>(-1); +}; + +/** Node representing a HTML table */ +class DocHtmlTable : public DocCompoundNode +{ + public: + DocHtmlTable(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) + : DocCompoundNode(parser,parent), m_attribs(attribs) {} + size_t numRows() const { return children().size(); } + bool hasCaption() const; + const HtmlAttribList &attribs() const { return m_attribs; } + int parse(DocNodeVariant *); + int parseXml(DocNodeVariant *); + size_t numColumns() const { return m_numCols; } + const DocNodeVariant *caption() const; + const DocNodeVariant *firstRow() const; + + private: + void computeTableGrid(); + std::unique_ptr<DocNodeVariant> m_caption; + HtmlAttribList m_attribs; + size_t m_numCols = 0; +}; + +/** Node representing an HTML blockquote */ +class DocHtmlBlockQuote : public DocCompoundNode +{ + public: + DocHtmlBlockQuote(DocParser *parser,DocNodeVariant *parent,const HtmlAttribList &attribs) + : DocCompoundNode(parser,parent), m_attribs(attribs) {} + int parse(DocNodeVariant *); + const HtmlAttribList &attribs() const { return m_attribs; } + + private: + HtmlAttribList m_attribs; +}; + +/** Root node of a text fragment */ +class DocText : public DocCompoundNode +{ + public: + DocText(DocParser *parser) : DocCompoundNode(parser,0) {} + void parse(DocNodeVariant *); + bool isEmpty() const { return children().empty(); } +}; + +/** Root node of documentation tree */ +class DocRoot : public DocCompoundNode +{ + public: + DocRoot(DocParser *parser,bool indent,bool sl) + : DocCompoundNode(parser,0), m_indent(indent), m_singleLine(sl) {} + void parse(DocNodeVariant *); + bool indent() const { return m_indent; } + bool singleLine() const { return m_singleLine; } + bool isEmpty() const { return children().empty(); } + + private: + bool m_indent = false; + bool m_singleLine = false; +}; + +//-------------------------------------------------------------------------------------- + +/// returns the parent node of a given node \a n or 0 if the node has no parent. +constexpr const DocNodeVariant *parent(const DocNodeVariant *n) +{ + return n ? std::visit([](auto &&x)->decltype(auto) { return x.parent(); }, *n) : nullptr; +} + +namespace details +{ + +template<class T,class... Ts> +struct Impl +{ + static constexpr bool holds_one_of_alternatives(const DocNodeVariant &v) + { + return std::holds_alternative<T>(v) || Impl<Ts...>::holds_one_of_alternatives(v); + } +}; + +template<class T> +struct Impl<T> +{ + static constexpr bool holds_one_of_alternatives(const DocNodeVariant &v) + { + return std::holds_alternative<T>(v); + } +}; + +} + +/// returns true iff \a v holds one of types passed as template parameters +template<class... Ts> +constexpr bool holds_one_of_alternatives(const DocNodeVariant &v) +{ + return details::Impl<Ts...>::holds_one_of_alternatives(v); +} + +//----------------- DocNodeList --------------------------------------- + +template<class T,class...Args> +inline DocNodeVariant *DocNodeList::append(Args&&... args) +{ + emplace_back(T(std::forward<Args>(args)...)); + return &back(); +} + +inline void DocNodeList::move_append(DocNodeList &elements) +{ + for (auto &&elem : elements) + { + emplace_back(std::move(elem)); + } + elements.clear(); +} + +template<class T> +inline T *DocNodeList::get_last() +{ + return std::get_if<T>(&back()); +} + +/// ---------------- Debug helpers ------------------------------- + +inline const char *docNodeName(const DocNodeVariant &v) +{ +#define DN(x) #x +#define DN_SEP , + static const char *table[] = { DOC_NODES }; +#undef DN +#undef DN_SEP + return table[v.index()]; +} + +inline void dumpDocNodeSizes() +{ +#define DN(x) #x +#define DN_SEP , + static const char *tableWithNames[] = { DOC_NODES }; +#undef DN +#undef DN_SEP + +#define DN(x) sizeof(x) +#define DN_SEP , + static size_t tableWithSizes[] = { DOC_NODES }; +#undef DN +#undef DN_SEP + + size_t maxSize=0; + printf("DocNodeVariant(\n"); + for (size_t i=0;i<sizeof(tableWithNames)/sizeof(tableWithNames[0]);i++) + { + printf(" /* %2zu */ sizeof(%s)=%zu\n",i,tableWithNames[i],tableWithSizes[i]); + if (tableWithSizes[i]>maxSize) maxSize = tableWithSizes[i]; + } + printf(")=%zu\n",maxSize); +} + +inline void dumpDocNodeList(const DocNodeList &children) +{ + printf("children=[\n"); + for (const auto &child : children) + { + const DocWord *w = std::get_if<DocWord>(&child); + printf(" %s (%p) %s\n",docNodeName(child),(void*)&child,qPrint(w?w->word():"")); + } + printf("]\n"); +} + +//---------------------------------------------------------------------------------- + +/** Class representing the abstract syntax tree of a documentation block */ +class DocNodeAST : public IDocNodeAST +{ + public: + template<class DocNode> + DocNodeAST(DocNode &&r) : root(std::move(r)) {} + bool isEmpty() const override + { + if (std::holds_alternative<DocRoot>(root)) + { + return std::get<DocRoot>(root).isEmpty(); + } + else if (std::holds_alternative<DocText>(root)) + { + return std::get<DocText>(root).isEmpty(); + } + return false; + } + DocNodeVariant root; +}; + +#endif diff --git a/src/docparser.cpp b/src/docparser.cpp index b8ffc23..fdb9179 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 1997-2021 by Dimitri van Heesch. + * Copyright (C) 1997-2022 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -19,40 +19,23 @@ #include <ctype.h> -#include "qcstring.h" -#include "regex.h" -#include "doxygen.h" +#include "classlist.h" +#include "cmdmapper.h" +#include "config.h" #include "debug.h" -#include "util.h" -#include "pagedef.h" +#include "dir.h" #include "docparser.h" -#include "doctokenizer.h" -#include "cmdmapper.h" -#include "printdocvisitor.h" -#include "message.h" -#include "section.h" -#include "searchindex.h" -#include "language.h" -#include "portable.h" -#include "cite.h" -#include "arguments.h" -#include "vhdldocgen.h" -#include "groupdef.h" -#include "classlist.h" +#include "docparser_p.h" +#include "doxygen.h" #include "filedef.h" -#include "memberdef.h" -#include "namespacedef.h" -#include "reflist.h" -#include "formula.h" -#include "config.h" -#include "growbuf.h" -#include "markdown.h" -#include "htmlentity.h" -#include "emoji.h" #include "fileinfo.h" -#include "dir.h" - -#define TK_COMMAND_CHAR(token) ((token)==TK_COMMAND_AT ? "@" : "\\") +#include "groupdef.h" +#include "namespacedef.h" +#include "message.h" +#include "pagedef.h" +#include "portable.h" +#include "printdocvisitor.h" +#include "util.h" // debug off #define DBG(x) do {} while(0) @@ -64,164 +47,27 @@ //#define myprintf(...) fprintf(stderr,__VA_ARGS__) //#define DBG(x) myprintf x -#define INTERNAL_ASSERT(x) do {} while(0) -//#define INTERNAL_ASSERT(x) if (!(x)) DBG(("INTERNAL_ASSERT(%s) failed retval=0x%x: file=%s line=%d\n",#x,retval,__FILE__,__LINE__)); - -//--------------------------------------------------------------------------- - -static const char *g_sectionLevelToName[] = -{ - "page", - "section", - "subsection", - "subsubsection", - "paragraph", - "subparagraph" -}; - -static const std::set<std::string> g_plantumlEngine { - "uml", "bpm", "wire", "dot", "ditaa", - "salt", "math", "latex", "gantt", "mindmap", - "wbs", "yaml", "creole", "json", "flow", - "board", "git" -}; - -//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -using DefinitionStack = std::vector<const Definition *>; -using DocNodeStack = std::stack<const DocNode *>; -//using DocStyleChangeStack = std::stack<const DocStyleChange *>; - -template<typename T, typename Container = std::deque<T>> -class iterable_stack -: public std::stack<T, Container> -{ - using std::stack<T, Container>::c; - -public: - - // expose just the iterators of the underlying container - auto begin() { return std::begin(c); } - auto end() { return std::end(c); } - - auto begin() const { return std::begin(c); } - auto end() const { return std::end(c); } -}; -using DocStyleChangeStack = iterable_stack<const DocStyleChange *>; - -/** Parser's context to store all global variables. - */ -struct DocParserContext -{ - const Definition *scope; - QCString context; - bool inSeeBlock; - bool xmlComment; - bool insideHtmlLink; - DocNodeStack nodeStack; - DocStyleChangeStack styleStack; - DocStyleChangeStack initialStyleStack; - DefinitionStack copyStack; - QCString fileName; - QCString relPath; - - bool hasParamCommand; - bool hasReturnCommand; - StringMultiSet retvalsFound; - StringMultiSet paramsFound; - const MemberDef * memberDef; - bool isExample; - QCString exampleName; - QCString searchUrl; - - QCString includeFileName; - QCString includeFileText; - uint includeFileOffset; - uint includeFileLength; - int includeFileLine; - bool includeFileShowLineNo; - - TokenInfo *token; - int lineNo; - bool markdownSupport; -}; - -class DocParser : public IDocParser -{ - public: - void pushContext(); - void popContext(); - void handleImg(DocNode *parent,DocNodeList &children,const HtmlAttribList &tagHtmlAttribs); - int internalValidatingParseDoc(DocNode *parent,DocNodeList &children, - const QCString &doc); - QCString processCopyDoc(const char *data,uint &len); - QCString findAndCopyImage(const QCString &fileName,DocImage::Type type, bool doWarn = true); - void checkArgumentName(); - void checkRetvalName(); - void checkUnOrMultipleDocumentedParams(); - bool findDocsForMemberOrCompound(const QCString &commandName, - QCString *pDoc, - QCString *pBrief, - const Definition **pDef); - bool defaultHandleToken(DocNode *parent,int tok, - DocNodeList &children,bool - handleWord=TRUE); - void errorHandleDefaultToken(DocNode *parent,int tok, - DocNodeList &children,const QCString &txt); - void defaultHandleTitleAndSize(const int cmd, DocNode *parent, - DocNodeList &children, QCString &width,QCString &height); - int handleStyleArgument(DocNode *parent,DocNodeList &children, - const QCString &cmdName); - void handleStyleEnter(DocNode *parent,DocNodeList &children, DocStyleChange::Style s, - const QCString &tagName,const HtmlAttribList *attribs); - void handleStyleLeave(DocNode *parent,DocNodeList &children, DocStyleChange::Style s, - const QCString &tagName); - void handlePendingStyleCommands(DocNode *parent,DocNodeList &children); - void handleInitialStyleCommands(DocPara *parent,DocNodeList &children); - int handleAHref(DocNode *parent,DocNodeList &children,const HtmlAttribList &tagHtmlAttribs); - void handleUnclosedStyleCommands(); - void handleLinkedWord(DocNode *parent,DocNodeList &children,bool ignoreAutoLinkFlag=FALSE); - void handleParameterType(DocNode *parent,DocNodeList &children,const QCString ¶mTypes); - DocInternalRef *handleInternalRef(DocNode *parent); - DocAnchor *handleAnchor(DocNode *parent); - void readTextFileByName(const QCString &file,QCString &text); - - std::stack< DocParserContext > contextStack; - DocParserContext context; - DocTokenizer tokenizer; -}; - -std::unique_ptr<IDocParser> createDocParser() +IDocParserPtr createDocParser() { return std::make_unique<DocParser>(); } //--------------------------------------------------------------------------- - -class AutoNodeStack +DocParser::~DocParser() { - public: - AutoNodeStack(DocParser &parser,const DocNode* node) - : m_parser(parser), m_node(node) { m_parser.context.nodeStack.push(node); } - ~AutoNodeStack() { -#if defined(NDEBUG) - (void)m_node; - if (!m_parser.context.nodeStack.empty()) m_parser.context.nodeStack.pop(); // robust version that does not assert -#else - assert(m_parser.context.nodeStack.top()==m_node); m_parser.context.nodeStack.pop(); // error checking version -#endif - } - - private: - DocParser &m_parser; - const DocNode *m_node; -}; - -//--------------------------------------------------------------------------- + try + { + searchData.transfer(); + } + catch(...) + { + err("Unexpected exception caught in DocParser\n"); + } +} -//--------------------------------------------------------------------------- void DocParser::pushContext() { //QCString indent; @@ -253,29 +99,6 @@ void DocParser::popContext() //--------------------------------------------------------------------------- -// replaces { with < and } with > and also -// replaces > with < and > with > within string s -static void unescapeCRef(QCString &s) -{ - QCString result; - const char *p = s.data(); - if (p) - { - char c; - while ((c=*p++)) - { - if (c=='{') c='<'; else if (c=='}') c='>'; - result+=c; - } - } - - result=substitute(result,"<","<"); - result=substitute(result,">",">"); - s = result; -} - -//--------------------------------------------------------------------------- - /*! search for an image in the imageNameDict and if found * copies the image to the output directory (which depends on the \a type * parameter). @@ -305,7 +128,7 @@ QCString DocParser::findAndCopyImage(const QCString &fileName, DocImage::Type ty int i; if ((i=result.findRev('/'))!=-1 || (i=result.findRev('\\'))!=-1) { - result = result.right((int)result.length()-i-1); + result = result.right(static_cast<int>(result.length())-i-1); } //printf("fileName=%s result=%s\n",fileName,qPrint(result)); QCString outputDir; @@ -550,100 +373,11 @@ void DocParser::checkUnOrMultipleDocumentedParams() } } -//--------------------------------------------------------------------------- - -/*! Strips known html and tex extensions from \a text. */ -static QCString stripKnownExtensions(const QCString &text) -{ - QCString result=text; - if (result.right(4)==".tex") - { - result=result.left(result.length()-4); - } - else if (result.right(Doxygen::htmlFileExtension.length())== - QCString(Doxygen::htmlFileExtension)) - { - result=result.left(result.length()-Doxygen::htmlFileExtension.length()); - } - return result; -} - //--------------------------------------------------------------------------- -/*! Returns TRUE iff node n is a child of a preformatted node */ -static bool insidePRE(DocNode *n) -{ - while (n) - { - if (n->isPreformatted()) return TRUE; - n=n->parent(); - } - return FALSE; -} - //--------------------------------------------------------------------------- -/*! Returns TRUE iff node n is a child of a html list item node */ -static bool insideLI(DocNode *n) -{ - while (n) - { - if (n->kind()==DocNode::Kind_HtmlListItem) return TRUE; - n=n->parent(); - } - return FALSE; -} - -//--------------------------------------------------------------------------- - -/*! Returns TRUE iff node n is a child of a unordered html list node */ -static bool insideUL(DocNode *n) -{ - while (n) - { - if (n->kind()==DocNode::Kind_HtmlList && - ((DocHtmlList *)n)->type()==DocHtmlList::Unordered) return TRUE; - n=n->parent(); - } - return FALSE; -} - -//--------------------------------------------------------------------------- - -/*! Returns TRUE iff node n is a child of a ordered html list node */ -static bool insideOL(DocNode *n) -{ - while (n) - { - if (n->kind()==DocNode::Kind_HtmlList && - ((DocHtmlList *)n)->type()==DocHtmlList::Ordered) return TRUE; - n=n->parent(); - } - return FALSE; -} - -//--------------------------------------------------------------------------- - -static bool insideTable(DocNode *n) -{ - while (n) - { - if (n->kind()==DocNode::Kind_HtmlTable) return TRUE; - n=n->parent(); - } - return FALSE; -} - -static const DocStyleChange *insideDetails(DocStyleChangeStack styleStack) -{ - const DocStyleChange *retItem = NULL; - for (auto i : styleStack) - { - if (i->style() == DocStyleChange::Details) retItem = i; - } - return retItem; -} //--------------------------------------------------------------------------- /*! Looks for a documentation block with name commandName in the current * context (g_parserContext.context). The resulting documentation string is @@ -696,7 +430,7 @@ bool DocParser::findDocsForMemberOrCompound(const QCString &commandName, // for symbols we need to normalize the separator, so A#B, or A\B, or A.B becomes A::B cmdArg = substitute(cmdArg,"#","::"); cmdArg = substitute(cmdArg,"\\","::"); - static bool extractAnonNs = Config_getBool(EXTRACT_ANON_NSPACES); + bool extractAnonNs = Config_getBool(EXTRACT_ANON_NSPACES); if (extractAnonNs && cmdArg.startsWith("anonymous_namespace{") ) @@ -712,7 +446,7 @@ bool DocParser::findDocsForMemberOrCompound(const QCString &commandName, cmdArg = substitute(cmdArg,".","::"); } - int l=(int)cmdArg.length(); + int l=static_cast<int>(cmdArg.length()); int funcStart=cmdArg.find('('); if (funcStart==-1) @@ -755,7 +489,7 @@ bool DocParser::findDocsForMemberOrCompound(const QCString &commandName, } - int scopeOffset=(int)context.context.length(); + int scopeOffset=static_cast<int>(context.context.length()); do // for each scope { QCString fullName=cmdArg; @@ -798,7 +532,7 @@ bool DocParser::findDocsForMemberOrCompound(const QCString &commandName, } //--------------------------------------------------------------------------- -void DocParser::errorHandleDefaultToken(DocNode *parent,int tok, +void DocParser::errorHandleDefaultToken(DocNodeVariant *parent,int tok, DocNodeList &children,const QCString &txt) { const char *cmd_start = "\\"; @@ -808,16 +542,16 @@ void DocParser::errorHandleDefaultToken(DocNode *parent,int tok, cmd_start = "@"; // fall through case TK_COMMAND_BS: - children.push_back(std::make_unique<DocWord>(*this,parent,TK_COMMAND_CHAR(tok) + context.token->name)); - warn_doc_error(context.fileName,tokenizer.getLineNr(),"Illegal command %s as part of a %s", + children.append<DocWord>(this,parent,TK_COMMAND_CHAR(tok) + context.token->name); + warn_doc_error(context.fileName,tokenizer.getLineNr(),"Illegal command %s found as part of a %s", qPrint(cmd_start + context.token->name),qPrint(txt)); break; case TK_SYMBOL: - warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unsupported symbol %s found found as part of a %s", + warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unsupported symbol %s found as part of a %s", qPrint(context.token->name), qPrint(txt)); break; default: - children.push_back(std::make_unique<DocWord>(*this,parent,context.token->name)); + children.append<DocWord>(this,parent,context.token->name); warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unexpected token %s found as part of a %s", DocTokenizer::tokToString(tok), qPrint(txt)); break; @@ -826,7 +560,7 @@ void DocParser::errorHandleDefaultToken(DocNode *parent,int tok, //--------------------------------------------------------------------------- -int DocParser::handleStyleArgument(DocNode *parent,DocNodeList &children,const QCString &cmdName) +int DocParser::handleStyleArgument(DocNodeVariant *parent,DocNodeList &children,const QCString &cmdName) { DBG(("handleStyleArgument(%s)\n",qPrint(cmdName))); QCString saveCmdName = cmdName; @@ -878,27 +612,32 @@ int DocParser::handleStyleArgument(DocNode *parent,DocNodeList &children,const Q /*! Called when a style change starts. For instance a \<b\> command is * encountered. */ -void DocParser::handleStyleEnter(DocNode *parent,DocNodeList &children, +void DocParser::handleStyleEnter(DocNodeVariant *parent,DocNodeList &children, DocStyleChange::Style s,const QCString &tagName,const HtmlAttribList *attribs) { DBG(("HandleStyleEnter\n")); - DocStyleChange *sc= new DocStyleChange(*this,parent,(uint)context.nodeStack.size(),s,tagName,TRUE,attribs); - children.push_back(std::unique_ptr<DocStyleChange>(sc)); - context.styleStack.push(sc); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,TRUE,attribs); + context.styleStack.push(&children.back()); } /*! Called when a style change ends. For instance a \</b\> command is * encountered. */ -void DocParser::handleStyleLeave(DocNode *parent,DocNodeList &children, +void DocParser::handleStyleLeave(DocNodeVariant *parent,DocNodeList &children, DocStyleChange::Style s,const QCString &tagName) { DBG(("HandleStyleLeave\n")); QCString tagNameLower = QCString(tagName).lower(); + + auto topStyleChange = [](const DocStyleChangeStack &stack) -> const DocStyleChange & + { + return std::get<DocStyleChange>(*stack.top()); + }; + if (context.styleStack.empty() || // no style change - context.styleStack.top()->style()!=s || // wrong style change - context.styleStack.top()->tagName()!=tagNameLower || // wrong style change - context.styleStack.top()->position()!=context.nodeStack.size() // wrong position + topStyleChange(context.styleStack).style()!=s || // wrong style change + topStyleChange(context.styleStack).tagName()!=tagNameLower || // wrong style change + topStyleChange(context.styleStack).position()!=context.nodeStack.size() // wrong position ) { if (context.styleStack.empty()) @@ -906,27 +645,27 @@ void DocParser::handleStyleLeave(DocNode *parent,DocNodeList &children, warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </%s> tag without matching <%s>", qPrint(tagName),qPrint(tagName)); } - else if (context.styleStack.top()->tagName()!=tagNameLower) + else if (topStyleChange(context.styleStack).tagName()!=tagNameLower) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </%s> tag while expecting </%s>", - qPrint(tagName),qPrint(context.styleStack.top()->tagName())); + qPrint(tagName),qPrint(topStyleChange(context.styleStack).tagName())); } - else if (context.styleStack.top()->style()!=s) + else if (topStyleChange(context.styleStack).style()!=s) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </%s> tag while expecting </%s>", - qPrint(tagName),qPrint(context.styleStack.top()->tagName())); + qPrint(tagName),qPrint(topStyleChange(context.styleStack).tagName())); } else { - warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </%s> at different nesting level (%zu) than expected (%d)", - qPrint(tagName),context.nodeStack.size(),context.styleStack.top()->position()); + warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </%s> at different nesting level (%zu) than expected (%zu)", + qPrint(tagName),context.nodeStack.size(),topStyleChange(context.styleStack).position()); } } else // end the section { - children.push_back( - std::make_unique<DocStyleChange>( - *this,parent,(uint)context.nodeStack.size(),s,context.styleStack.top()->tagName(),FALSE)); + children.append<DocStyleChange>( + this,parent,context.nodeStack.size(),s, + topStyleChange(context.styleStack).tagName(),FALSE); context.styleStack.pop(); } } @@ -935,32 +674,33 @@ void DocParser::handleStyleLeave(DocNode *parent,DocNodeList &children, * (e.g. a <b> without a </b>). The closed styles are pushed onto a stack * and entered again at the start of a new paragraph. */ -void DocParser::handlePendingStyleCommands(DocNode *parent,DocNodeList &children) +void DocParser::handlePendingStyleCommands(DocNodeVariant *parent,DocNodeList &children) { if (!context.styleStack.empty()) { - const DocStyleChange *sc = context.styleStack.top(); + const DocStyleChange *sc = &std::get<DocStyleChange>(*context.styleStack.top()); while (sc && sc->position()>=context.nodeStack.size()) { // there are unclosed style modifiers in the paragraph - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),sc->style(),sc->tagName(),FALSE)); - context.initialStyleStack.push(sc); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(), + sc->style(),sc->tagName(),FALSE); + context.initialStyleStack.push(context.styleStack.top()); context.styleStack.pop(); - sc = !context.styleStack.empty() ? context.styleStack.top() : 0; + sc = !context.styleStack.empty() ? &std::get<DocStyleChange>(*context.styleStack.top()) : 0; } } } -void DocParser::handleInitialStyleCommands(DocPara *parent,DocNodeList &children) +void DocParser::handleInitialStyleCommands(DocNodeVariant *parent,DocNodeList &children) { while (!context.initialStyleStack.empty()) { - const DocStyleChange *sc = context.initialStyleStack.top(); - handleStyleEnter(parent,children,sc->style(),sc->tagName(),&sc->attribs()); + const DocStyleChange &sc = std::get<DocStyleChange>(*context.initialStyleStack.top()); + handleStyleEnter(parent,children,sc.style(),sc.tagName(),&sc.attribs()); context.initialStyleStack.pop(); } } -int DocParser::handleAHref(DocNode *parent,DocNodeList &children, +int DocParser::handleAHref(DocNodeVariant *parent,DocNodeList &children, const HtmlAttribList &tagHtmlAttribs) { uint index=0; @@ -971,7 +711,7 @@ int DocParser::handleAHref(DocNode *parent,DocNodeList &children, { if (!opt.value.isEmpty()) { - children.push_back(std::make_unique<DocAnchor>(*this,parent,opt.value,TRUE)); + children.append<DocAnchor>(this,parent,opt.value,TRUE); break; // stop looking for other tag attribs } else @@ -987,10 +727,12 @@ int DocParser::handleAHref(DocNode *parent,DocNodeList &children, attrList.erase(attrList.begin()+index); QCString relPath; if (opt.value.at(0) != '#') relPath = context.relPath; - DocHRef *href = new DocHRef(*this,parent,attrList,opt.value,relPath,convertNameToFile(context.fileName,FALSE,TRUE)); - children.push_back(std::unique_ptr<DocHRef>(href)); + auto vDocHRef = children.append<DocHRef>(this, parent, attrList, + opt.value, relPath, + convertNameToFile(context.fileName, FALSE, TRUE)); + DocHRef *href = children.get_last<DocHRef>(); context.insideHtmlLink=TRUE; - retval = href->parse(); + retval = href->parse(vDocHRef); context.insideHtmlLink=FALSE; break; } @@ -1002,52 +744,26 @@ int DocParser::handleAHref(DocNode *parent,DocNodeList &children, return retval; } -const char *DocStyleChange::styleString() const -{ - switch (m_style) - { - case DocStyleChange::Bold: return "b"; - case DocStyleChange::Italic: return "em"; - case DocStyleChange::Code: return "code"; - case DocStyleChange::Center: return "center"; - case DocStyleChange::Small: return "small"; - case DocStyleChange::Cite: return "cite"; - case DocStyleChange::Subscript: return "subscript"; - case DocStyleChange::Superscript: return "superscript"; - case DocStyleChange::Preformatted: return "pre"; - case DocStyleChange::Div: return "div"; - case DocStyleChange::Span: return "span"; - case DocStyleChange::Strike: return "strike"; - case DocStyleChange::S: return "s"; - case DocStyleChange::Del: return "del"; - case DocStyleChange::Underline: return "u"; - case DocStyleChange::Ins: return "ins"; - case DocStyleChange::Details: return "details"; - case DocStyleChange::Summary: return "summary"; - } - return "<invalid>"; -} - void DocParser::handleUnclosedStyleCommands() { if (!context.initialStyleStack.empty()) { - const DocStyleChange *sc = context.initialStyleStack.top(); + QCString tagName = std::get<DocStyleChange>(*context.initialStyleStack.top()).tagName(); context.initialStyleStack.pop(); handleUnclosedStyleCommands(); warn_doc_error(context.fileName,tokenizer.getLineNr(), "end of comment block while expecting " - "command </%s>",qPrint(sc->tagName())); + "command </%s>",qPrint(tagName)); } } -void DocParser::handleLinkedWord(DocNode *parent,DocNodeList &children,bool ignoreAutoLinkFlag) +void DocParser::handleLinkedWord(DocNodeVariant *parent,DocNodeList &children,bool ignoreAutoLinkFlag) { QCString name = linkToText(SrcLangExt_Unknown,context.token->name,TRUE); - static bool autolinkSupport = Config_getBool(AUTOLINK_SUPPORT); + bool autolinkSupport = Config_getBool(AUTOLINK_SUPPORT); if (!autolinkSupport && !ignoreAutoLinkFlag) // no autolinking -> add as normal word { - children.push_back(std::make_unique<DocWord>(*this,parent,name)); + children.append<DocWord>(this,parent,name); return; } @@ -1075,13 +791,12 @@ void DocParser::handleLinkedWord(DocNode *parent,DocNodeList &children,bool igno bool localLink = context.memberDef ? member->getClassDef()==context.memberDef->getClassDef() : FALSE; name = member->objCMethodName(localLink,context.inSeeBlock); } - children.push_back( - std::make_unique<DocLinkedWord>( - *this,parent,name, + children.append<DocLinkedWord>( + this,parent,name, member->getReference(), member->getOutputFileBase(), member->anchor(), - member->briefDescriptionAsTooltip())); + member->briefDescriptionAsTooltip()); } else if (compound->isLinkable()) // compound link { @@ -1094,29 +809,27 @@ void DocParser::handleLinkedWord(DocNode *parent,DocNodeList &children,bool igno { name=toGroupDef(compound)->groupTitle(); } - children.push_back( - std::make_unique<DocLinkedWord>( - *this,parent,name, + children.append<DocLinkedWord>( + this,parent,name, compound->getReference(), compound->getOutputFileBase(), anchor, - compound->briefDescriptionAsTooltip())); + compound->briefDescriptionAsTooltip()); } else if (compound->definitionType()==Definition::TypeFile && (toFileDef(compound))->generateSourceFile() ) // undocumented file that has source code we can link to { - children.push_back( - std::make_unique<DocLinkedWord>( - *this,parent,context.token->name, + children.append<DocLinkedWord>( + this,parent,context.token->name, compound->getReference(), compound->getSourceFileBase(), "", - compound->briefDescriptionAsTooltip())); + compound->briefDescriptionAsTooltip()); } else // not linkable { - children.push_back(std::make_unique<DocWord>(*this,parent,name)); + children.append<DocWord>(this,parent,name); } } else if (!context.insideHtmlLink && len>1 && context.token->name.at(len-1)==':') @@ -1125,35 +838,34 @@ void DocParser::handleLinkedWord(DocNode *parent,DocNodeList &children,bool igno // but Foo itself might be linkable. context.token->name=context.token->name.left(len-1); handleLinkedWord(parent,children,ignoreAutoLinkFlag); - children.push_back(std::make_unique<DocWord>(*this,parent,":")); + children.append<DocWord>(this,parent,":"); } else if (!context.insideHtmlLink && (cd=getClass(context.token->name+"-p"))) { // special case 2, where the token name is not a class, but could // be a Obj-C protocol - children.push_back( - std::make_unique<DocLinkedWord>( - *this,parent,name, + children.append<DocLinkedWord>( + this,parent,name, cd->getReference(), cd->getOutputFileBase(), cd->anchor(), - cd->briefDescriptionAsTooltip())); + cd->briefDescriptionAsTooltip()); } else // normal non-linkable word { if (context.token->name.left(1)=="#" || context.token->name.left(2)=="::") { warn_doc_error(context.fileName,tokenizer.getLineNr(),"explicit link request to '%s' could not be resolved",qPrint(name)); - children.push_back(std::make_unique<DocWord>(*this,parent,context.token->name)); + children.append<DocWord>(this,parent,context.token->name); } else { - children.push_back(std::make_unique<DocWord>(*this,parent,name)); + children.append<DocWord>(this,parent,name); } } } -void DocParser::handleParameterType(DocNode *parent,DocNodeList &children,const QCString ¶mTypes) +void DocParser::handleParameterType(DocNodeVariant *parent,DocNodeList &children,const QCString ¶mTypes) { QCString name = context.token->name; // save token name QCString name1; @@ -1164,19 +876,19 @@ void DocParser::handleParameterType(DocNode *parent,DocNodeList &children,const ii=name1.find('['); context.token->name=ii!=-1 ? name1.mid(0,ii) : name1; // take part without [] handleLinkedWord(parent,children); - if (ii!=-1) children.push_back(std::make_unique<DocWord>(*this,parent,name1.mid(ii))); // add [] part + if (ii!=-1) children.append<DocWord>(this,parent,name1.mid(ii)); // add [] part p=i+1; - children.push_back(std::make_unique<DocSeparator>(*this,parent,"|")); + children.append<DocSeparator>(this,parent,"|"); } name1 = paramTypes.mid(p); ii=name1.find('['); context.token->name=ii!=-1 ? name1.mid(0,ii) : name1; handleLinkedWord(parent,children); - if (ii!=-1) children.push_back(std::make_unique<DocWord>(*this,parent,name1.mid(ii))); + if (ii!=-1) children.append<DocWord>(this,parent,name1.mid(ii)); context.token->name = name; // restore original token name } -DocInternalRef *DocParser::handleInternalRef(DocNode *parent) +void DocParser::handleInternalRef(DocNodeVariant *parent,DocNodeList &children) { //printf("CMD_INTERNALREF\n"); int tok=tokenizer.lex(); @@ -1185,7 +897,7 @@ DocInternalRef *DocParser::handleInternalRef(DocNode *parent) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\%s command", qPrint(tokenName)); - return 0; + return; } tokenizer.setStateInternalRef(); tok=tokenizer.lex(); // get the reference id @@ -1193,19 +905,20 @@ DocInternalRef *DocParser::handleInternalRef(DocNode *parent) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token %s as the argument of %s", DocTokenizer::tokToString(tok),qPrint(tokenName)); - return 0; + return; } - return new DocInternalRef(*this,parent,context.token->name); + auto vDocInternalRef = children.append<DocInternalRef>(this,parent,context.token->name); + children.get_last<DocInternalRef>()->parse(vDocInternalRef); } -DocAnchor *DocParser::handleAnchor(DocNode *parent) +void DocParser::handleAnchor(DocNodeVariant *parent,DocNodeList &children) { int tok=tokenizer.lex(); if (tok!=TK_WHITESPACE) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\%s command", qPrint(context.token->name)); - return 0; + return; } tokenizer.setStateAnchor(); tok=tokenizer.lex(); @@ -1213,16 +926,16 @@ DocAnchor *DocParser::handleAnchor(DocNode *parent) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the " "argument of command %s",qPrint(context.token->name)); - return 0; + return; } else if (tok!=TK_WORD && tok!=TK_LNKWORD) { warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token %s as the argument of %s", DocTokenizer::tokToString(tok),qPrint(context.token->name)); - return 0; + return; } tokenizer.setStatePara(); - return new DocAnchor(*this,parent,context.token->name,FALSE); + children.append<DocAnchor>(this,parent,context.token->name,FALSE); } @@ -1235,9 +948,9 @@ DocAnchor *DocParser::handleAnchor(DocNode *parent) * @param[out] width the extracted width specifier * @param[out] height the extracted height specifier */ -void DocParser::defaultHandleTitleAndSize(const int cmd, DocNode *parent, DocNodeList &children, QCString &width,QCString &height) +void DocParser::defaultHandleTitleAndSize(const int cmd, DocNodeVariant *parent, DocNodeList &children, QCString &width,QCString &height) { - auto ns = AutoNodeStack(*this,parent); + auto ns = AutoNodeStack(this,parent); // parse title tokenizer.setStateTitle(); @@ -1292,6 +1005,114 @@ void DocParser::defaultHandleTitleAndSize(const int cmd, DocNode *parent, DocNod handlePendingStyleCommands(parent,children); } +void DocParser::handleImage(DocNodeVariant *parent, DocNodeList &children) +{ + bool inlineImage = false; + QCString anchorStr; + + int tok=tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + if (tok==TK_WORD) + { + if (context.token->name == "{") + { + tokenizer.setStateOptions(); + tok=tokenizer.lex(); + tokenizer.setStatePara(); + StringVector optList=split(context.token->name.str(),","); + for (const auto &opt : optList) + { + if (opt.empty()) continue; + QCString locOpt(opt); + QCString locOptLow; + locOpt = locOpt.stripWhiteSpace(); + locOptLow = locOpt.lower(); + if (locOptLow == "inline") + { + inlineImage = true; + } + else if (locOptLow.startsWith("anchor:")) + { + if (!anchorStr.isEmpty()) + { + warn_doc_error(context.fileName,tokenizer.getLineNr(), + "multiple use of option 'anchor' for 'image' command, ignoring: '%s'", + qPrint(locOpt.mid(7))); + } + else + { + anchorStr = locOpt.mid(7); + } + } + else + { + warn_doc_error(context.fileName,tokenizer.getLineNr(), + "unknown option '%s' for 'image' command specified", + qPrint(locOpt)); + } + } + tok=tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command"); + return; + } + } + } + else + { + warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command"); + return; + } + } + tok=tokenizer.lex(); + if (tok!=TK_WORD && tok!=TK_LNKWORD) + { + warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token %s as the argument of \\image", + DocTokenizer::tokToString(tok)); + return; + } + tok=tokenizer.lex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command"); + return; + } + DocImage::Type t; + QCString imgType = context.token->name.lower(); + if (imgType=="html") t=DocImage::Html; + else if (imgType=="latex") t=DocImage::Latex; + else if (imgType=="docbook") t=DocImage::DocBook; + else if (imgType=="rtf") t=DocImage::Rtf; + else if (imgType=="xml") t=DocImage::Xml; + else + { + warn_doc_error(context.fileName,tokenizer.getLineNr(),"output format `%s` specified as the first argument of " + "\\image command is not valid", + qPrint(imgType)); + return; + } + tokenizer.setStateFile(); + tok=tokenizer.lex(); + tokenizer.setStatePara(); + if (tok!=TK_WORD) + { + warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token %s as the argument of \\image", + DocTokenizer::tokToString(tok)); + return; + } + if (!anchorStr.isEmpty()) + { + children.append<DocAnchor>(this,parent,anchorStr,true); + } + HtmlAttribList attrList; + auto vDocImage = children.append<DocImage>(this,parent,attrList, + findAndCopyImage(context.token->name,t),t,"",inlineImage); + children.get_last<DocImage>()->parse(vDocImage); +} + + /* Helper function that deals with the most common tokens allowed in * title like sections. * @param parent Parent node, owner of the children list passed as @@ -1303,7 +1124,7 @@ void DocParser::defaultHandleTitleAndSize(const int cmd, DocNode *parent, DocNod * @retval TRUE The token was handled. * @retval FALSE The token was not handled. */ -bool DocParser::defaultHandleToken(DocNode *parent,int tok, DocNodeList &children,bool handleWord) +bool DocParser::defaultHandleToken(DocNodeVariant *parent,int tok, DocNodeList &children,bool handleWord) { DBG(("token %s at %d",DocTokenizer::tokToString(tok),tokenizer.getLineNr())); if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || @@ -1323,62 +1144,62 @@ reparsetoken: switch (Mappers::cmdMapper->map(tokenName)) { case CMD_BSLASH: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_BSlash)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_BSlash); break; case CMD_AT: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_At)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_At); break; case CMD_LESS: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Less)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Less); break; case CMD_GREATER: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Greater)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Greater); break; case CMD_AMP: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Amp)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Amp); break; case CMD_DOLLAR: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Dollar)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dollar); break; case CMD_HASH: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Hash)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Hash); break; case CMD_DCOLON: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_DoubleColon)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_DoubleColon); break; case CMD_PERCENT: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Percent)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Percent); break; case CMD_NDASH: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Minus)); - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Minus)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus); break; case CMD_MDASH: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Minus)); - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Minus)); - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Minus)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus); break; case CMD_QUOTE: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Quot)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quot); break; case CMD_PUNT: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Dot)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dot); break; case CMD_PLUS: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Plus)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Plus); break; case CMD_MINUS: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Minus)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus); break; case CMD_EQUAL: - children.push_back(std::make_unique<DocSymbol>(*this,parent,DocSymbol::Sym_Equal)); + children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Equal); break; case CMD_EMPHASIS: { - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),DocStyleChange::Italic,tokenName,TRUE)); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,TRUE); tok=handleStyleArgument(parent,children,tokenName); - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),DocStyleChange::Italic,tokenName,FALSE)); - if (tok!=TK_WORD) children.push_back(std::make_unique<DocWhiteSpace>(*this,parent," ")); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,FALSE); + if (tok!=TK_WORD) children.append<DocWhiteSpace>(this,parent," "); if (tok==TK_NEWPARA) goto handlepara; else if (tok==TK_WORD || tok==TK_HTMLTAG) { @@ -1389,10 +1210,10 @@ reparsetoken: break; case CMD_BOLD: { - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),DocStyleChange::Bold,tokenName,TRUE)); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,TRUE); tok=handleStyleArgument(parent,children,tokenName); - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),DocStyleChange::Bold,tokenName,FALSE)); - if (tok!=TK_WORD) children.push_back(std::make_unique<DocWhiteSpace>(*this,parent," ")); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,FALSE); + if (tok!=TK_WORD) children.append<DocWhiteSpace>(this,parent," "); if (tok==TK_NEWPARA) goto handlepara; else if (tok==TK_WORD || tok==TK_HTMLTAG) { @@ -1403,10 +1224,10 @@ reparsetoken: break; case CMD_CODE: { - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),DocStyleChange::Code,tokenName,TRUE)); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,TRUE); tok=handleStyleArgument(parent,children,tokenName); - children.push_back(std::make_unique<DocStyleChange>(*this,parent,(uint)context.nodeStack.size(),DocStyleChange::Code,tokenName,FALSE)); - if (tok!=TK_WORD) children.push_back(std::make_unique<DocWhiteSpace>(*this,parent," ")); + children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,FALSE); + if (tok!=TK_WORD) children.append<DocWhiteSpace>(this,parent," "); if (tok==TK_NEWPARA) goto handlepara; else if (tok==TK_WORD || tok==TK_HTMLTAG) { @@ -1419,7 +1240,7 @@ reparsetoken: { tokenizer.setStateHtmlOnly(); tok = tokenizer.lex(); - children.push_back(std::make_unique<DocVerbatim>(*this,parent,context.context,context.token->verb,DocVerbatim::HtmlOnly,context.isExample,context.exampleName,context.token->name=="block")); + children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::HtmlOnly,context.isExample,context.exampleName,context.token->name=="block"); if (tok==0) warn_doc_error(context.fileName,tokenizer.getLineNr(),"htmlonly section ended without end marker"); tokenizer.setStatePara(); } @@ -1428,7 +1249,7 @@ reparsetoken: { tokenizer.setStateManOnly(); tok = tokenizer.lex(); - children.push_back(std::make_unique<DocVerbatim>(*this,parent,context.context,context.token->verb,DocVerbatim::ManOnly,context.isExample,context.exampleName)); + children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::ManOnly,context.isExample,context.exampleName); if (tok==0) warn_doc_error(context.fileName,tokenizer.getLineNr(),"manonly section ended without end marker"); tokenizer.setStatePara(); } @@ -1437,7 +1258,7 @@ reparsetoken: { tokenizer.setStateRtfOnly(); tok = tokenizer.lex(); - children.push_back(std::make_unique<DocVerbatim>(*this,parent,context.context,context.token->verb,DocVerbatim::RtfOnly,context.isExample,context.exampleName)); + children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::RtfOnly,context.isExample,context.exampleName); if (tok==0) warn_doc_error(context.fileName,tokenizer.getLineNr(),"rtfonly section ended without end marker"); tokenizer.setStatePara(); } @@ -1446,7 +1267,7 @@ reparsetoken: { tokenizer.setStateLatexOnly(); tok = tokenizer.lex(); - children.push_back(std::make_unique<DocVerbatim>(*this,parent,context.context,context.token->verb,DocVerbatim::LatexOnly,context.isExample,context.exampleName)); + children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::LatexOnly,context.isExample,context.exampleName); if (tok==0) warn_doc_error(context.fileName,tokenizer.getLineNr(),"latexonly section ended without end marker"); tokenizer.setStatePara(); } @@ -1455,7 +1276,7 @@ reparsetoken: { tokenizer.setStateXmlOnly(); tok = tokenizer.lex(); - children.push_back(std::make_unique<DocVerbatim>(*this,parent,context.context,context.token->verb,DocVerbatim::XmlOnly,context.isExample,context.exampleName)); + children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::XmlOnly,context.isExample,context.exampleName); if (tok==0) warn_doc_error(context.fileName,tokenizer.getLineNr(),"xmlonly section ended without end marker"); tokenizer.setStatePara(); } @@ -1464,33 +1285,24 @@ reparsetoken: { tokenizer.setStateDbOnly(); tok = tokenizer.lex(); - children.push_back(std::make_unique<DocVerbatim>(*this,parent,context.context,context.token->verb,DocVerbatim::DocbookOnly,context.isExample,context.exampleName)); + children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::DocbookOnly,context.isExample,context.exampleName); if (tok==0) warn_doc_error(context.fileName,tokenizer.getLineNr(),"docbookonly section ended without end marker"); tokenizer.setStatePara(); } break; case CMD_FORMULA: { - children.push_back(std::make_unique<DocFormula>(*this,parent,context.token->id)); + children.append<DocFormula>(this,parent,context.token->id); } break; case CMD_ANCHOR: { - DocAnchor *anchor = handleAnchor(parent); - if (anchor) - { - children.push_back(std::unique_ptr<DocAnchor>(anchor)); - } + handleAnchor(parent,children); } break; case CMD_INTERNALREF: { - DocInternalRef *ref = handleInternalRef(parent); - if (ref) - { - children.push_back(std::unique_ptr<DocInternalRef>(ref)); - ref->parse(); - } + handleInternalRef(parent,children); tokenizer.setStatePara(); } break; @@ -1506,7 +1318,7 @@ reparsetoken: } break; case CMD_IMAGE: - ((DocPara *)parent) -> handleImage("image"); + handleImage(parent,children); break; default: return FALSE; @@ -1675,10 +1487,10 @@ reparsetoken: break; case TK_SYMBOL: { - DocSymbol::SymType s = DocSymbol::decodeSymbol(tokenName); - if (s!=DocSymbol::Sym_Unknown) + HtmlEntityMapper::SymType s = DocSymbol::decodeSymbol(tokenName); + if (s!=HtmlEntityMapper::Sym_Unknown) { - children.push_back(std::make_unique<DocSymbol>(*this,parent,s)); + children.append<DocSymbol>(this,parent,s); } else { @@ -1691,7 +1503,7 @@ reparsetoken: handlepara: if (insidePRE(parent) || !children.empty()) { - children.push_back(std::make_unique<DocWhiteSpace>(*this,parent,context.token->chars)); + children.append<DocWhiteSpace>(this,parent,context.token->chars); } break; case TK_LNKWORD: @@ -1705,7 +1517,7 @@ handlepara: case TK_WORD: if (handleWord) { - children.push_back(std::make_unique<DocWord>(*this,parent,context.token->name)); + children.append<DocWord>(this,parent,context.token->name); } else return FALSE; @@ -1713,11 +1525,11 @@ handlepara: case TK_URL: if (context.insideHtmlLink) { - children.push_back(std::make_unique<DocWord>(*this,parent,context.token->name)); + children.append<DocWord>(this,parent,context.token->name); } else { - children.push_back(std::make_unique<DocURL>(*this,parent,context.token->name,context.token->isEMailAddr)); + children.append<DocURL>(this,parent,context.token->name,context.token->isEMailAddr); } break; default: @@ -1728,7 +1540,7 @@ handlepara: //--------------------------------------------------------------------------- -void DocParser::handleImg(DocNode *parent, DocNodeList &children,const HtmlAttribList &tagHtmlAttribs) +void DocParser::handleImg(DocNodeVariant *parent, DocNodeList &children,const HtmlAttribList &tagHtmlAttribs) { bool found=FALSE; uint index=0; @@ -1742,11 +1554,10 @@ void DocParser::handleImg(DocNode *parent, DocNodeList &children,const HtmlAttri // and remove the src attribute attrList.erase(attrList.begin()+index); DocImage::Type t = DocImage::Html; - children.push_back( - std::make_unique<DocImage>( - *this,parent,attrList, + children.append<DocImage>( + this,parent,attrList, findAndCopyImage(opt.value,t,false), - t,opt.value)); + t,opt.value); found = TRUE; } ++index; @@ -1759,36 +1570,7 @@ void DocParser::handleImg(DocNode *parent, DocNodeList &children,const HtmlAttri //--------------------------------------------------------------------------- -DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName) -{ - DBG(("decodeSymbol(%s)\n",qPrint(symName))); - return HtmlEntityMapper::instance()->name2sym(symName); -} - -//--------------------------------------------------------------------------- - -DocEmoji::DocEmoji(DocParser &parser,DocNode *parent,const QCString &symName) : - DocNode(parser), m_symName(symName), m_index(-1) -{ - m_parent = parent; - QCString locSymName = symName; - uint len=locSymName.length(); - if (len>0) - { - if (locSymName.at(len-1)!=':') locSymName.append(":"); - if (locSymName.at(0)!=':') locSymName.prepend(":"); - } - m_symName = locSymName; - m_index = EmojiEntityMapper::instance()->symbol2index(m_symName.str()); - if (m_index==-1) - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"Found unsupported emoji symbol '%s'\n",qPrint(m_symName)); - } -} - -//--------------------------------------------------------------------------- - -int DocParser::internalValidatingParseDoc(DocNode *parent,DocNodeList &children, +int DocParser::internalValidatingParseDoc(DocNodeVariant *parent,DocNodeList &children, const QCString &doc) { int retval = RetVal_OK; @@ -1799,26 +1581,25 @@ int DocParser::internalValidatingParseDoc(DocNode *parent,DocNodeList &children, // first parse any number of paragraphs bool isFirst=TRUE; - DocPara *lastPar=0; - if (!children.empty() && children.back()->kind()==DocNode::Kind_Para) + DocPara *lastPar=!children.empty() ? std::get_if<DocPara>(&children.back()): 0; + if (lastPar) { // last child item was a paragraph - lastPar = (DocPara*)children.back().get(); isFirst=FALSE; } do { - DocPara *par = new DocPara(*this,parent); + auto vDocPara = children.append<DocPara>(this,parent); + DocPara *par = children.get_last<DocPara>(); if (isFirst) { par->markFirst(); isFirst=FALSE; } - retval=par->parse(); + retval=par->parse(vDocPara); if (!par->isEmpty()) { - children.push_back(std::unique_ptr<DocNode>(par)); if (lastPar) lastPar->markLast(FALSE); lastPar=par; } else { - delete par; + children.pop_back(); } } while (retval==TK_NEWPARA); if (lastPar) lastPar->markLast(); @@ -1877,5744 +1658,7 @@ void DocParser::readTextFileByName(const QCString &file,QCString &text) //--------------------------------------------------------------------------- -DocWord::DocWord(DocParser &parser,DocNode *parent,const QCString &word) : - DocNode(parser), m_word(word) -{ - m_parent = parent; - //printf("new word %s url=%s\n",qPrint(word),qPrint(parser.context.searchUrl)); - if (Doxygen::searchIndex && !parser.context.searchUrl.isEmpty()) - { - Doxygen::searchIndex->addWord(word,FALSE); - } -} - -//--------------------------------------------------------------------------- - -DocLinkedWord::DocLinkedWord(DocParser &parser,DocNode *parent,const QCString &word, - const QCString &ref,const QCString &file, - const QCString &anchor,const QCString &tooltip) : - DocNode(parser), m_word(word), m_ref(ref), - m_file(file), m_relPath(parser.context.relPath), m_anchor(anchor), - m_tooltip(tooltip) -{ - m_parent = parent; - //printf("DocLinkedWord: new word %s url=%s tooltip='%s'\n", - // qPrint(word),qPrint(parser.context.searchUrl),qPrint(tooltip)); - if (Doxygen::searchIndex && !parser.context.searchUrl.isEmpty()) - { - Doxygen::searchIndex->addWord(word,FALSE); - } -} - -//--------------------------------------------------------------------------- - -DocAnchor::DocAnchor(DocParser &parser,DocNode *parent,const QCString &id,bool newAnchor) : DocNode(parser) -{ - m_parent = parent; - if (id.isEmpty()) - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"Empty anchor label"); - return; - } - - const CitationManager &ct = CitationManager::instance(); - QCString anchorPrefix = ct.anchorPrefix(); - if (id.left(anchorPrefix.length()) == anchorPrefix) - { - const CiteInfo *cite = ct.find(id.mid(anchorPrefix.length())); - if (cite) - { - m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); - m_anchor = id; - } - else - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"Invalid cite anchor id '%s'",qPrint(id)); - m_anchor = "invalid"; - m_file = "invalid"; - } - } - else if (newAnchor) // found <a name="label"> - { - m_anchor = id; - } - else // found \anchor label - { - const SectionInfo *sec = SectionManager::instance().find(id); - if (sec) - { - //printf("Found anchor %s\n",qPrint(id)); - m_file = sec->fileName(); - m_anchor = sec->label(); - } - else - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"Invalid anchor id '%s'",qPrint(id)); - m_anchor = "invalid"; - m_file = "invalid"; - } - } -} - -//--------------------------------------------------------------------------- - -DocVerbatim::DocVerbatim(DocParser &parser,DocNode *parent,const QCString &context, - const QCString &text, Type t,bool isExample, - const QCString &exampleFile,bool isBlock,const QCString &lang) - : DocNode(parser), m_context(context), m_text(text), m_type(t), - m_isExample(isExample), m_exampleFile(exampleFile), - m_relPath(parser.context.relPath), m_lang(lang), m_isBlock(isBlock) -{ - m_parent = parent; -} - - -//--------------------------------------------------------------------------- - -void DocInclude::parse() -{ - DBG(("DocInclude::parse(file=%s,text=%s)\n",qPrint(m_file),qPrint(m_text))); - switch(m_type) - { - case DontIncWithLines: - // fall through - case IncWithLines: - // fall through - case Include: - // fall through - case DontInclude: - m_parser.readTextFileByName(m_file,m_text); - m_parser.context.includeFileName = m_file; - m_parser.context.includeFileText = m_text; - m_parser.context.includeFileOffset = 0; - m_parser.context.includeFileLength = m_text.length(); - m_parser.context.includeFileLine = 0; - m_parser.context.includeFileShowLineNo = (m_type == DontIncWithLines || m_type == IncWithLines); - //printf("parser.context.includeFile=<<%s>>\n",qPrint(parser.context.includeFileText)); - break; - case VerbInclude: - // fall through - case HtmlInclude: - case LatexInclude: - case DocInclude::RtfInclude: - case DocInclude::ManInclude: - case DocInclude::XmlInclude: - case DocInclude::DocbookInclude: - m_parser.readTextFileByName(m_file,m_text); - break; - case Snippet: - case SnipWithLines: - m_parser.readTextFileByName(m_file,m_text); - // check here for the existence of the blockId inside the file, so we - // only generate the warning once. - int count; - if (!m_blockId.isEmpty() && (count=m_text.contains(m_blockId.data()))!=2) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"block marked with %s for \\snippet should appear twice in file %s, found it %d times\n", - qPrint(m_blockId),qPrint(m_file),count); - } - break; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: - err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" - "Please create a bug report\n",__FILE__); - break; - } -} - -//--------------------------------------------------------------------------- - -void DocIncOperator::parse() -{ - if (m_parser.context.includeFileName.isEmpty()) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), - "No previous '\\include' or '\\dontinclude' command for '\\%s' present", - typeAsString()); - } - - m_includeFileName = m_parser.context.includeFileName; - const char *p = m_parser.context.includeFileText.data(); - uint l = m_parser.context.includeFileLength; - uint o = m_parser.context.includeFileOffset; - int il = m_parser.context.includeFileLine; - DBG(("DocIncOperator::parse() text=%s off=%d len=%d\n",p,o,l)); - uint so = o,bo; - bool nonEmpty = FALSE; - switch(type()) - { - case Line: - while (o<l) - { - char c = p[o]; - if (c=='\n') - { - m_parser.context.includeFileLine++; - if (nonEmpty) break; // we have a pattern to match - so=o+1; // no pattern, skip empty line - } - else if (!isspace((uchar)c)) // no white space char - { - nonEmpty=TRUE; - } - o++; - } - if (m_parser.context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) - { - m_line = il; - m_text = m_parser.context.includeFileText.mid(so,o-so); - DBG(("DocIncOperator::parse() Line: %s\n",qPrint(m_text))); - } - m_parser.context.includeFileOffset = std::min(l,o+1); // set pointer to start of new line - m_showLineNo = m_parser.context.includeFileShowLineNo; - break; - case SkipLine: - while (o<l) - { - so=o; - while (o<l) - { - char c = p[o]; - if (c=='\n') - { - m_parser.context.includeFileLine++; - if (nonEmpty) break; // we have a pattern to match - so=o+1; // no pattern, skip empty line - } - else if (!isspace((uchar)c)) // no white space char - { - nonEmpty=TRUE; - } - o++; - } - if (m_parser.context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) - { - m_line = il; - m_text = m_parser.context.includeFileText.mid(so,o-so); - DBG(("DocIncOperator::parse() SkipLine: %s\n",qPrint(m_text))); - break; - } - o++; // skip new line - } - m_parser.context.includeFileOffset = std::min(l,o+1); // set pointer to start of new line - m_showLineNo = m_parser.context.includeFileShowLineNo; - break; - case Skip: - while (o<l) - { - so=o; - while (o<l) - { - char c = p[o]; - if (c=='\n') - { - m_parser.context.includeFileLine++; - if (nonEmpty) break; // we have a pattern to match - so=o+1; // no pattern, skip empty line - } - else if (!isspace((uchar)c)) // no white space char - { - nonEmpty=TRUE; - } - o++; - } - if (m_parser.context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) - { - break; - } - o++; // skip new line - } - m_parser.context.includeFileOffset = so; // set pointer to start of new line - m_showLineNo = m_parser.context.includeFileShowLineNo; - break; - case Until: - bo=o; - while (o<l) - { - so=o; - while (o<l) - { - char c = p[o]; - if (c=='\n') - { - m_parser.context.includeFileLine++; - if (nonEmpty) break; // we have a pattern to match - so=o+1; // no pattern, skip empty line - } - else if (!isspace((uchar)c)) // no white space char - { - nonEmpty=TRUE; - } - o++; - } - if (m_parser.context.includeFileText.mid(so,o-so).find(m_pattern)!=-1) - { - m_line = il; - m_text = m_parser.context.includeFileText.mid(bo,o-bo); - DBG(("DocIncOperator::parse() Until: %s\n",qPrint(m_text))); - break; - } - o++; // skip new line - } - m_parser.context.includeFileOffset = std::min(l,o+1); // set pointer to start of new line - m_showLineNo = m_parser.context.includeFileShowLineNo; - break; - } -} - -//--------------------------------------------------------------------------- - -DocXRefItem::DocXRefItem(DocParser &parser,DocNode *parent,int id,const QCString &key) : - CompAccept<DocXRefItem>(parser), m_id(id), m_key(key), m_relPath(parser.context.relPath) -{ - m_parent = parent; -} - -bool DocXRefItem::parse() -{ - RefList *refList = RefListManager::instance().find(m_key); - if (refList && refList->isEnabled()) - { - RefItem *item = refList->find(m_id); - ASSERT(item!=0); - if (item) - { - if (m_parser.context.memberDef && m_parser.context.memberDef->name().at(0)=='@') - { - m_file = "@"; // can't cross reference anonymous enum - m_anchor = "@"; - } - else - { - m_file = refList->fileName(); - m_anchor = item->anchor(); - } - m_title = refList->sectionTitle(); - //printf("DocXRefItem: file=%s anchor=%s title=%s\n", - // qPrint(m_file),qPrint(m_anchor),qPrint(m_title)); - - if (!item->text().isEmpty()) - { - m_parser.pushContext(); - m_parser.internalValidatingParseDoc(this,m_children,item->text()); - m_parser.popContext(); - } - } - return TRUE; - } - return FALSE; -} - -//--------------------------------------------------------------------------- - -DocFormula::DocFormula(DocParser &parser,DocNode *parent,int id) : DocNode(parser), - m_relPath(parser.context.relPath) -{ - m_parent = parent; - QCString text = FormulaManager::instance().findFormula(id); - if (!text.isEmpty()) - { - m_id = id; - m_name.sprintf("form_%d",m_id); - m_text = text; - } - else // wrong \_form#<n> command - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"Wrong formula id %d",id); - m_id = -1; - } -} - -//--------------------------------------------------------------------------- - -//int DocLanguage::parse() -//{ -// int retval; -// DBG(("DocLanguage::parse() start\n")); -// auto ns = AutoNodeStack(m_parser,this); -// -// // parse one or more paragraphs -// bool isFirst=TRUE; -// DocPara *par=0; -// do -// { -// par = new DocPara(this); -// if (isFirst) { par->markFirst(); isFirst=FALSE; } -// m_children.push_back(std::unique_ptr<DocPara>(par)); -// retval=par->parse(); -// } -// while (retval==TK_NEWPARA); -// if (par) par->markLast(); -// -// DBG(("DocLanguage::parse() end\n")); -// return retval; -//} - -//--------------------------------------------------------------------------- - -DocSecRefItem::DocSecRefItem(DocParser &parser,DocNode *parent,const QCString &target) : - CompAccept<DocSecRefItem>(parser), m_target(target), m_relPath(parser.context.relPath) -{ - m_parent = parent; -} - -void DocSecRefItem::parse() -{ - DBG(("DocSecRefItem::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - m_parser.tokenizer.setStateTitle(); - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - m_parser.errorHandleDefaultToken(this,tok,m_children,"\\refitem"); - } - } - m_parser.tokenizer.setStatePara(); - m_parser.handlePendingStyleCommands(this,m_children); - - if (!m_target.isEmpty()) - { - SrcLangExt lang = getLanguageFromFileName(m_target); - const SectionInfo *sec = SectionManager::instance().find(m_target); - if (sec==0 && lang==SrcLangExt_Markdown) // lookup as markdown file - { - sec = SectionManager::instance().find(markdownFileNameToId(m_target)); - } - if (sec) // ref to section or anchor - { - // set defaults - m_ref = sec->ref(); - m_file = stripKnownExtensions(sec->fileName()); - m_refType = Section; - m_anchor = sec->label(); - m_isSubPage = false; - // adjust if needed - switch (sec->type()) - { - case SectionType::Page: - { - PageDef *pd = Doxygen::pageLinkedMap->find(m_target); - m_isSubPage = pd && pd->hasParentPage(); - if (!m_isSubPage) - { - m_anchor=""; - } - } - break; - case SectionType::Anchor: - m_refType = Anchor; - break; - case SectionType::Table: - m_refType = Table; - break; - default: - break; - } - //printf("m_ref=%s,m_file=%s,type=%d\n", - // qPrint(m_ref),qPrint(m_file),m_refType); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"reference to unknown section %s", - qPrint(m_target)); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"reference to empty target"); - } - - DBG(("DocSecRefItem::parse() end\n")); -} - -//--------------------------------------------------------------------------- - -void DocSecRefList::parse() -{ - DBG(("DocSecRefList::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - int tok=m_parser.tokenizer.lex(); - // skip white space - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // handle items - while (tok) - { - if (tok==TK_COMMAND_AT || tok == TK_COMMAND_BS) - { - const char *cmd_start = (tok==TK_COMMAND_AT ? "@" : "\\"); - switch (Mappers::cmdMapper->map(m_parser.context.token->name)) - { - case CMD_SECREFITEM: - { - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\refitem command"); - break; - } - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WORD && tok!=TK_LNKWORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of \\refitem", - DocTokenizer::tokToString(tok)); - break; - } - - DocSecRefItem *item = new DocSecRefItem(m_parser,this,m_parser.context.token->name); - m_children.push_back(std::unique_ptr<DocSecRefItem>(item)); - item->parse(); - } - break; - case CMD_ENDSECREFLIST: - goto endsecreflist; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Illegal command %s as part of a \\secreflist", - qPrint(cmd_start + m_parser.context.token->name)); - goto endsecreflist; - } - } - else if (tok==TK_WHITESPACE) - { - // ignore whitespace - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected token %s inside section reference list", - DocTokenizer::tokToString(tok)); - goto endsecreflist; - } - tok=m_parser.tokenizer.lex(); - } - -endsecreflist: - DBG(("DocSecRefList::parse() end\n")); -} - -//--------------------------------------------------------------------------- - -DocInternalRef::DocInternalRef(DocParser &parser,DocNode *parent,const QCString &ref) - : CompAccept<DocInternalRef>(parser), m_relPath(parser.context.relPath) -{ - m_parent = parent; - int i=ref.find('#'); - if (i!=-1) - { - m_anchor = ref.right((int)ref.length()-i-1); - m_file = ref.left(i); - } - else - { - m_file = ref; - } -} - -void DocInternalRef::parse() -{ - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocInternalRef::parse() start\n")); - - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - m_parser.errorHandleDefaultToken(this,tok,m_children,"\\ref"); - } - } - - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocInternalRef::parse() end\n")); -} - -//--------------------------------------------------------------------------- - -DocRef::DocRef(DocParser &parser,DocNode *parent,const QCString &target,const QCString &context) : - CompAccept<DocRef>(parser), m_refType(Unknown), m_isSubPage(FALSE) -{ - m_parent = parent; - const Definition *compound = 0; - QCString anchor; - //printf("DocRef::DocRef(target=%s,context=%s)\n",qPrint(target),qPrint(context)); - ASSERT(!target.isEmpty()); - SrcLangExt lang = getLanguageFromFileName(target); - m_relPath = parser.context.relPath; - const SectionInfo *sec = SectionManager::instance().find(target); - if (sec==0 && lang==SrcLangExt_Markdown) // lookup as markdown file - { - sec = SectionManager::instance().find(markdownFileNameToId(target)); - } - if (sec) // ref to section or anchor - { - PageDef *pd = 0; - if (sec->type()==SectionType::Page) - { - pd = Doxygen::pageLinkedMap->find(target); - } - m_text = sec->title(); - if (m_text.isEmpty()) m_text = sec->label(); - - m_ref = sec->ref(); - m_file = stripKnownExtensions(sec->fileName()); - if (sec->type()==SectionType::Anchor) - { - m_refType = Anchor; - } - else if (sec->type()==SectionType::Table) - { - m_refType = Table; - } - else - { - m_refType = Section; - } - 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,type=%d\n", - // qPrint(m_text),qPrint(m_ref),qPrint(m_file),m_refType); - return; - } - else if (resolveLink(context,target,TRUE,&compound,anchor)) - { - bool isFile = compound ? - (compound->definitionType()==Definition::TypeFile || - compound->definitionType()==Definition::TypePage ? TRUE : FALSE) : - FALSE; - m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile); - m_anchor = anchor; - if (compound && compound->isLinkable()) // ref to compound - { - if (anchor.isEmpty() && /* compound link */ - compound->definitionType()==Definition::TypeGroup && /* is group */ - !toGroupDef(compound)->groupTitle().isEmpty() /* with title */ - ) - { - m_text=(toGroupDef(compound))->groupTitle(); // use group's title as link - } - else if (compound->definitionType()==Definition::TypeMember && - toMemberDef(compound)->isObjCMethod()) - { - // Objective C Method - const MemberDef *member = toMemberDef(compound); - bool localLink = parser.context.memberDef ? member->getClassDef()==parser.context.memberDef->getClassDef() : FALSE; - m_text = member->objCMethodName(localLink,parser.context.inSeeBlock); - } - - m_file = compound->getOutputFileBase(); - m_ref = compound->getReference(); - //printf("isFile=%d compound=%s (%d)\n",isFile,qPrint(compound->name()), - // compound->definitionType()); - return; - } - else if (compound && compound->definitionType()==Definition::TypeFile && - toFileDef(compound)->generateSourceFile() - ) // undocumented file that has source code we can link to - { - m_file = compound->getSourceFileBase(); - m_ref = compound->getReference(); - return; - } - } - m_text = target; - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"unable to resolve reference to '%s' for \\ref command", - qPrint(target)); -} - -static void flattenParagraphs(DocNode *root,DocNodeList &children) -{ - DocNodeList newChildren; - for (const auto &dn : children) - { - if (dn->kind()==DocNode::Kind_Para) - { - DocPara *para = (DocPara*)dn.get(); - // move the children of the paragraph to the end of the newChildren list - newChildren.insert(newChildren.end(), - std::make_move_iterator(para->children().begin()), - std::make_move_iterator(para->children().end())); - } - } - - // replace the children list by the newChildren list - children.clear(); - children.insert(children.end(), - std::make_move_iterator(newChildren.begin()), - std::make_move_iterator(newChildren.end())); - // reparent the children - for (const auto &cn : children) - { - cn->setParent(root); - } -} - -void DocRef::parse() -{ - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocRef::parse() start\n")); - - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - switch (tok) - { - case TK_HTMLTAG: - break; - default: - m_parser.errorHandleDefaultToken(this,tok,m_children,"\\ref"); - break; - } - } - } - - if (m_children.empty() && !m_text.isEmpty()) - { - m_parser.context.insideHtmlLink=TRUE; - m_parser.pushContext(); - m_parser.internalValidatingParseDoc(this,m_children,m_text); - m_parser.popContext(); - m_parser.context.insideHtmlLink=FALSE; - flattenParagraphs(this,m_children); - } - - m_parser.handlePendingStyleCommands(this,m_children); -} - -//--------------------------------------------------------------------------- - -DocCite::DocCite(DocParser &parser,DocNode *parent,const QCString &target,const QCString &) : DocNode(parser) -{ - size_t numBibFiles = Config_getList(CITE_BIB_FILES).size(); - m_parent = parent; - //printf("DocCite::DocCite(target=%s)\n",qPrint(target)); - ASSERT(!target.isEmpty()); - m_relPath = parser.context.relPath; - const CitationManager &ct = CitationManager::instance(); - const CiteInfo *cite = ct.find(target); - //printf("cite=%p text='%s' numBibFiles=%d\n",cite,cite?qPrint(cite->text):"<null>",numBibFiles); - if (numBibFiles>0 && cite && !cite->text().isEmpty()) // ref to citation - { - m_text = cite->text(); - m_ref = ""; - m_anchor = ct.anchorPrefix()+cite->label(); - m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); - //printf("CITE ==> m_text=%s,m_ref=%s,m_file=%s,m_anchor=%s\n", - // qPrint(m_text),qPrint(m_ref),qPrint(m_file),qPrint(m_anchor)); - return; - } - m_text = target; - if (numBibFiles==0) - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"\\cite command found but no bib files specified via CITE_BIB_FILES!"); - } - else if (cite==0) - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"unable to resolve reference to '%s' for \\cite command", - qPrint(target)); - } - else - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"\\cite command to '%s' does not have an associated number", - qPrint(target)); - } -} - -//--------------------------------------------------------------------------- - -DocLink::DocLink(DocParser &parser,DocNode *parent,const QCString &target) : CompAccept<DocLink>(parser) -{ - m_parent = parent; - const Definition *compound = 0; - QCString anchor; - m_refText = target; - m_relPath = parser.context.relPath; - if (!m_refText.isEmpty() && m_refText.at(0)=='#') - { - m_refText = m_refText.right(m_refText.length()-1); - } - if (resolveLink(parser.context.context,stripKnownExtensions(target),parser.context.inSeeBlock,&compound,anchor)) - { - m_anchor = anchor; - if (compound && compound->isLinkable()) - { - m_file = compound->getOutputFileBase(); - m_ref = compound->getReference(); - } - else if (compound && compound->definitionType()==Definition::TypeFile && - (toFileDef(compound))->generateSourceFile() - ) // undocumented file that has source code we can link to - { - m_file = compound->getSourceFileBase(); - m_ref = compound->getReference(); - } - return; - } - - // bogus link target - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"unable to resolve link to '%s' for \\link command", - qPrint(target)); -} - - -QCString DocLink::parse(bool isJavaLink,bool isXmlLink) -{ - QCString result; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocLink::parse() start\n")); - - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children,FALSE)) - { - const char *cmd_start = "\\"; - switch (tok) - { - case TK_COMMAND_AT: - cmd_start = "@"; - // fall through - case TK_COMMAND_BS: - switch (Mappers::cmdMapper->map(m_parser.context.token->name)) - { - case CMD_ENDLINK: - if (isJavaLink) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"{@link.. ended with @endlink command"); - } - goto endlink; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Illegal command %s as part of a \\link", - qPrint(cmd_start + m_parser.context.token->name)); - break; - } - break; - case TK_SYMBOL: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unsupported symbol %s found as part of a \\link", - qPrint(m_parser.context.token->name)); - break; - case TK_HTMLTAG: - if (m_parser.context.token->name!="see" || !isXmlLink) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected xml/html command %s found as part of a \\link", - qPrint(m_parser.context.token->name)); - } - goto endlink; - case TK_LNKWORD: - case TK_WORD: - if (isJavaLink) // special case to detect closing } - { - QCString w = m_parser.context.token->name; - int p; - if (w=="}") - { - goto endlink; - } - else if ((p=w.find('}'))!=-1) - { - uint l=w.length(); - m_children.push_back(std::make_unique<DocWord>(m_parser,this,w.left(p))); - if ((uint)p<l-1) // something left after the } (for instance a .) - { - result=w.right((int)l-p-1); - } - goto endlink; - } - } - m_children.push_back(std::make_unique<DocWord>(m_parser,this,m_parser.context.token->name)); - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected token %s", - DocTokenizer::tokToString(tok)); - break; - } - } - } - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected end of comment while inside" - " link command\n"); - } -endlink: - - if (m_children.empty()) // no link text - { - m_children.push_back(std::make_unique<DocWord>(m_parser,this,m_refText)); - } - - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocLink::parse() end\n")); - return result; -} - - -//--------------------------------------------------------------------------- - -DocDotFile::DocDotFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, - const QCString &srcFile,int srcLine) : - DocDiagramFileBase(parser,name,context,srcFile,srcLine) -{ - m_relPath = parser.context.relPath; - m_parent = parent; -} - -bool DocDotFile::parse() -{ - bool ok = false; - m_parser.defaultHandleTitleAndSize(CMD_DOTFILE,this,m_children,m_width,m_height); - - bool ambig; - FileDef *fd = findFileDef(Doxygen::dotFileNameLinkedMap,m_name,ambig); - if (fd==0 && m_name.right(4)!=".dot") // try with .dot extension as well - { - fd = findFileDef(Doxygen::dotFileNameLinkedMap,m_name+".dot",ambig); - } - if (fd) - { - m_file = fd->absFilePath(); - ok = true; - if (ambig) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"included dot file name %s is ambiguous.\n" - "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::dotFileNameLinkedMap,m_name)) - ); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"included dot file %s is not found " - "in any of the paths specified via DOTFILE_DIRS!",qPrint(m_name)); - } - return ok; -} - -DocMscFile::DocMscFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, - const QCString &srcFile, int srcLine) : - DocDiagramFileBase(parser,name,context,srcFile,srcLine) -{ - m_relPath = parser.context.relPath; - m_parent = parent; -} - -bool DocMscFile::parse() -{ - bool ok = false; - m_parser.defaultHandleTitleAndSize(CMD_MSCFILE,this,m_children,m_width,m_height); - - bool ambig; - FileDef *fd = findFileDef(Doxygen::mscFileNameLinkedMap,m_name,ambig); - if (fd==0 && m_name.right(4)!=".msc") // try with .msc extension as well - { - fd = findFileDef(Doxygen::mscFileNameLinkedMap,m_name+".msc",ambig); - } - if (fd) - { - m_file = fd->absFilePath(); - ok = true; - if (ambig) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"included msc file name %s is ambiguous.\n" - "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::mscFileNameLinkedMap,m_name)) - ); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"included msc file %s is not found " - "in any of the paths specified via MSCFILE_DIRS!",qPrint(m_name)); - } - return ok; -} - -//--------------------------------------------------------------------------- - -DocDiaFile::DocDiaFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, - const QCString &srcFile,int srcLine) : - DocDiagramFileBase(parser,name,context,srcFile,srcLine) -{ - m_relPath = parser.context.relPath; - m_parent = parent; -} - -bool DocDiaFile::parse() -{ - bool ok = false; - m_parser.defaultHandleTitleAndSize(CMD_DIAFILE,this,m_children,m_width,m_height); - - bool ambig; - FileDef *fd = findFileDef(Doxygen::diaFileNameLinkedMap,m_name,ambig); - if (fd==0 && m_name.right(4)!=".dia") // try with .dia extension as well - { - fd = findFileDef(Doxygen::diaFileNameLinkedMap,m_name+".dia",ambig); - } - if (fd) - { - m_file = fd->absFilePath(); - ok = true; - if (ambig) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"included dia file name %s is ambiguous.\n" - "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::diaFileNameLinkedMap,m_name)) - ); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"included dia file %s is not found " - "in any of the paths specified via DIAFILE_DIRS!",qPrint(m_name)); - } - return ok; -} - -//--------------------------------------------------------------------------- - -DocVhdlFlow::DocVhdlFlow(DocParser &parser,DocNode *parent) : CompAccept<DocVhdlFlow>(parser) -{ - m_parent = parent; -} - -void DocVhdlFlow::parse() -{ - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocVhdlFlow::parse() start\n")); - - m_parser.tokenizer.setStateTitle(); - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - m_parser.errorHandleDefaultToken(this,tok,m_children,"\\vhdlflow"); - } - } - tok=m_parser.tokenizer.lex(); - - m_parser.tokenizer.setStatePara(); - m_parser.handlePendingStyleCommands(this,m_children); - - DBG(("DocVhdlFlow::parse() end\n")); - VhdlDocGen::createFlowChart(m_parser.context.memberDef); -} - - -//--------------------------------------------------------------------------- - -DocImage::DocImage(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,const QCString &name, - Type t,const QCString &url, bool inlineImage) : - CompAccept<DocImage>(parser), m_attribs(attribs), m_name(name), - m_type(t), m_relPath(parser.context.relPath), - m_url(url), m_inlineImage(inlineImage) -{ - m_parent = parent; -} - -bool DocImage::isSVG() const -{ - QCString locName = m_url.isEmpty() ? m_name : m_url; - int len = (int)locName.length(); - int fnd = locName.find('?'); // ignore part from ? until end - if (fnd==-1) fnd=len; - return fnd>=4 && locName.mid(fnd-4,4)==".svg"; -} - -void DocImage::parse() -{ - m_parser.defaultHandleTitleAndSize(CMD_IMAGE,this,m_children,m_width,m_height); -} - - -//--------------------------------------------------------------------------- - -int DocHtmlHeader::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlHeader::parse() start\n")); - - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - switch (tok) - { - case TK_HTMLTAG: - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_H1 && m_parser.context.token->endTag) // found </h1> tag - { - if (m_level!=1) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"<h%d> ended with </h1>", - m_level); - } - goto endheader; - } - else if (tagId==HTML_H2 && m_parser.context.token->endTag) // found </h2> tag - { - if (m_level!=2) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"<h%d> ended with </h2>", - m_level); - } - goto endheader; - } - else if (tagId==HTML_H3 && m_parser.context.token->endTag) // found </h3> tag - { - if (m_level!=3) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"<h%d> ended with </h3>", - m_level); - } - goto endheader; - } - else if (tagId==HTML_H4 && m_parser.context.token->endTag) // found </h4> tag - { - if (m_level!=4) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"<h%d> ended with </h4>", - m_level); - } - goto endheader; - } - else if (tagId==HTML_H5 && m_parser.context.token->endTag) // found </h5> tag - { - if (m_level!=5) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"<h%d> ended with </h5>", - m_level); - } - goto endheader; - } - else if (tagId==HTML_H6 && m_parser.context.token->endTag) // found </h6> tag - { - if (m_level!=6) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"<h%d> ended with </h6>", - m_level); - } - goto endheader; - } - else if (tagId==HTML_A) - { - if (!m_parser.context.token->endTag) - { - m_parser.handleAHref(this,m_children,m_parser.context.token->attribs); - } - } - else if (tagId==HTML_BR) - { - m_children.push_back(std::make_unique<DocLineBreak>(m_parser,this,m_parser.context.token->attribs)); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <h%d> context", - m_parser.context.token->endTag?"/":"",qPrint(m_parser.context.token->name),m_level); - } - } - break; - default: - char tmp[20]; - sprintf(tmp,"<h%d>tag",m_level); - m_parser.errorHandleDefaultToken(this,tok,m_children,tmp); - } - } - } - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected end of comment while inside" - " <h%d> tag\n",m_level); - } -endheader: - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocHtmlHeader::parse() end\n")); - return retval; -} -//--------------------------------------------------------------------------- - -int DocHRef::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHRef::parse() start\n")); - - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - switch (tok) - { - case TK_HTMLTAG: - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_A && m_parser.context.token->endTag) // found </a> tag - { - goto endhref; - } - else if (tagId==HTML_BR) - { - m_children.push_back(std::make_unique<DocLineBreak>(m_parser,this,m_parser.context.token->attribs)); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <a href=...> context", - m_parser.context.token->endTag?"/":"",qPrint(m_parser.context.token->name)); - } - } - break; - default: - m_parser.errorHandleDefaultToken(this,tok,m_children,"<a>..</a> block"); - break; - } - } - } - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected end of comment while inside" - " <a href=...> tag"); - } -endhref: - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocHRef::parse() end\n")); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocInternal::parse(int level) -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocInternal::parse() start\n")); - - // first parse any number of paragraphs - bool isFirst=TRUE; - DocPara *lastPar=0; - do - { - DocPara *par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - retval=par->parse(); - if (!par->isEmpty()) - { - m_children.push_back(std::unique_ptr<DocPara>(par)); - lastPar=par; - } - else - { - delete par; - } - if (retval==TK_LISTITEM) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid list item found"); - } - } while (retval!=0 && - retval!=RetVal_Section && - retval!=RetVal_Subsection && - retval!=RetVal_Subsubsection && - retval!=RetVal_Paragraph && - retval!=RetVal_EndInternal - ); - if (lastPar) lastPar->markLast(); - - // then parse any number of level-n sections - while ((level==1 && retval==RetVal_Section) || - (level==2 && retval==RetVal_Subsection) || - (level==3 && retval==RetVal_Subsubsection) || - (level==4 && retval==RetVal_Paragraph) - ) - { - DocSection *s=new DocSection(m_parser,this, - std::min(level+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - - if (retval==RetVal_Internal) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"\\internal command found inside internal section"); - } - - DBG(("DocInternal::parse() end: retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocIndexEntry::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocIndexEntry::parse() start\n")); - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\addindex command"); - goto endindexentry; - } - m_parser.tokenizer.setStateTitle(); - m_entry=""; - while ((tok=m_parser.tokenizer.lex())) - { - switch (tok) - { - case TK_WHITESPACE: - m_entry+=" "; - break; - case TK_WORD: - case TK_LNKWORD: - m_entry+=m_parser.context.token->name; - break; - case TK_SYMBOL: - { - DocSymbol::SymType s = DocSymbol::decodeSymbol(m_parser.context.token->name); - switch (s) - { - case DocSymbol::Sym_BSlash: m_entry+='\\'; break; - case DocSymbol::Sym_At: m_entry+='@'; break; - case DocSymbol::Sym_Less: m_entry+='<'; break; - case DocSymbol::Sym_Greater: m_entry+='>'; break; - case DocSymbol::Sym_Amp: m_entry+='&'; break; - case DocSymbol::Sym_Dollar: m_entry+='$'; break; - case DocSymbol::Sym_Hash: m_entry+='#'; break; - case DocSymbol::Sym_Percent: m_entry+='%'; break; - case DocSymbol::Sym_apos: m_entry+='\''; break; - case DocSymbol::Sym_Quot: m_entry+='"'; break; - case DocSymbol::Sym_lsquo: m_entry+='`'; break; - case DocSymbol::Sym_rsquo: m_entry+='\''; break; - case DocSymbol::Sym_ldquo: m_entry+="``"; break; - case DocSymbol::Sym_rdquo: m_entry+="''"; break; - case DocSymbol::Sym_ndash: m_entry+="--"; break; - case DocSymbol::Sym_mdash: m_entry+="---"; break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected symbol found as argument of \\addindex"); - break; - } - } - break; - case TK_COMMAND_AT: - // fall through - case TK_COMMAND_BS: - switch (Mappers::cmdMapper->map(m_parser.context.token->name)) - { - case CMD_BSLASH: m_entry+='\\'; break; - case CMD_AT: m_entry+='@'; break; - case CMD_LESS: m_entry+='<'; break; - case CMD_GREATER: m_entry+='>'; break; - case CMD_AMP: m_entry+='&'; break; - case CMD_DOLLAR: m_entry+='$'; break; - case CMD_HASH: m_entry+='#'; break; - case CMD_DCOLON: m_entry+="::"; break; - case CMD_PERCENT: m_entry+='%'; break; - case CMD_NDASH: m_entry+="--"; break; - case CMD_MDASH: m_entry+="---"; break; - case CMD_QUOTE: m_entry+='"'; break; - case CMD_PUNT: m_entry+='.'; break; - case CMD_PLUS: m_entry+='+'; break; - case CMD_MINUS: m_entry+='-'; break; - case CMD_EQUAL: m_entry+='='; break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected command %s found as argument of \\addindex", - qPrint(m_parser.context.token->name)); - break; - } - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected token %s", - DocTokenizer::tokToString(tok)); - break; - } - } - m_parser.tokenizer.setStatePara(); - m_entry = m_entry.stripWhiteSpace(); -endindexentry: - DBG(("DocIndexEntry::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval; -} - -//--------------------------------------------------------------------------- - -DocHtmlCaption::DocHtmlCaption(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) - : CompAccept<DocHtmlCaption>(parser) -{ - m_hasCaptionId = FALSE; - for (const auto &opt : attribs) - { - if (opt.name=="id" && !opt.value.isEmpty()) // interpret id attribute as an anchor - { - const SectionInfo *sec = SectionManager::instance().find(opt.value); - if (sec) - { - //printf("Found anchor %s\n",qPrint(id)); - m_file = sec->fileName(); - m_anchor = sec->label(); - m_hasCaptionId = TRUE; - } - else - { - warn_doc_error(parser.context.fileName,parser.tokenizer.getLineNr(),"Invalid caption id '%s'",qPrint(opt.value)); - } - } - else // copy attribute - { - m_attribs.push_back(opt); - } - } - m_parent = parent; -} - -int DocHtmlCaption::parse() -{ - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlCaption::parse() start\n")); - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - switch (tok) - { - case TK_HTMLTAG: - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_CAPTION && m_parser.context.token->endTag) // found </caption> tag - { - retval = RetVal_OK; - goto endcaption; - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <caption> context", - m_parser.context.token->endTag?"/":"",qPrint(m_parser.context.token->name)); - } - } - break; - default: - m_parser.errorHandleDefaultToken(this,tok,m_children,"<caption> tag"); - break; - } - } - } - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected end of comment while inside" - " <caption> tag"); - } -endcaption: - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocHtmlCaption::parse() end\n")); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocHtmlCell::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlCell::parse() start\n")); - - // parse one or more paragraphs - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - if (retval==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_TD && m_parser.context.token->endTag) // found </td> tag - { - retval=TK_NEWPARA; // ignore the tag - } - else if (tagId==HTML_TH && m_parser.context.token->endTag) // found </th> tag - { - retval=TK_NEWPARA; // ignore the tag - } - } - } - while ((retval==TK_NEWPARA) || (retval==RetVal_EndParBlock)); - if (par) par->markLast(); - - DBG(("DocHtmlCell::parse() end\n")); - return retval; -} - -int DocHtmlCell::parseXml() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlCell::parseXml() start\n")); - - // parse one or more paragraphs - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - if (retval==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==XML_ITEM && m_parser.context.token->endTag) // found </item> tag - { - retval=TK_NEWPARA; // ignore the tag - } - else if (tagId==XML_DESCRIPTION && m_parser.context.token->endTag) // found </description> tag - { - retval=TK_NEWPARA; // ignore the tag - } - } - } - while (retval==TK_NEWPARA); - if (par) par->markLast(); - - DBG(("DocHtmlCell::parseXml() end\n")); - return retval; -} - -uint DocHtmlCell::rowSpan() const -{ - for (const auto &attr : attribs()) - { - if (attr.name.lower()=="rowspan") - { - return attr.value.toUInt(); - } - } - return 0; -} - -uint DocHtmlCell::colSpan() const -{ - for (const auto &attr : attribs()) - { - if (attr.name.lower()=="colspan") - { - return std::max(1u,attr.value.toUInt()); - } - } - return 1; -} - -DocHtmlCell::Alignment DocHtmlCell::alignment() const -{ - for (const auto &attr : attribs()) - { - QCString attrName = attr.name.lower(); - QCString attrValue = attr.value.lower(); - if (attrName=="align") - { - if (attrValue=="center") - return Center; - else if (attrValue=="right") - return Right; - else return Left; - } - else if (attrName=="class" && attrValue.startsWith("markdowntable")) - { - if (attrValue=="markdowntableheadcenter") - return Center; - else if (attrValue=="markdowntableheadright") - return Right; - else if (attrValue=="markdowntableheadleft") - return Left; - else if (attrValue=="markdowntableheadnone") - return Center; - else if (attrValue=="markdowntablebodycenter") - return Center; - else if (attrValue=="markdowntablebodyright") - return Right; - else if (attrValue=="markdowntablebodyleft") - return Left; - else if (attrValue=="markdowntablebodynone") - return Left; - else return Left; - } - } - return Left; -} - -DocHtmlCell::Valignment DocHtmlCell::valignment() const -{ - for (const auto &attr : attribs()) - { - QCString attrName = attr.name.lower(); - QCString attrValue = attr.value.lower(); - if (attrName=="valign") - { - if (attrValue=="top") - return Top; - else if (attrValue=="bottom") - return Bottom; - else if (attrValue=="middle") - return Middle; - else return Middle; - } - } - return Middle; -} - -//--------------------------------------------------------------------------- - -int DocHtmlRow::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlRow::parse() start\n")); - - bool isHeading=FALSE; - bool isFirst=TRUE; - DocHtmlCell *cell=0; - - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - if (tok==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_TD && !m_parser.context.token->endTag) // found <td> tag - { - } - else if (tagId==HTML_TH && !m_parser.context.token->endTag) // found <th> tag - { - isHeading=TRUE; - } - else // found some other tag - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <td> or <th> tag but " - "found <%s> instead!",qPrint(m_parser.context.token->name)); - m_parser.tokenizer.pushBackHtmlTag(m_parser.context.token->name); - goto endrow; - } - } - else if (tok==0) // premature end of comment - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while looking" - " for a html description title"); - goto endrow; - } - else // token other than html token - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <td> or <th> tag but found %s token instead!", - DocTokenizer::tokToString(tok)); - goto endrow; - } - - // parse one or more cells - do - { - cell=new DocHtmlCell(m_parser,this,m_parser.context.token->attribs,isHeading); - cell->markFirst(isFirst); - isFirst=FALSE; - m_children.push_back(std::unique_ptr<DocHtmlCell>(cell)); - retval=cell->parse(); - isHeading = retval==RetVal_TableHCell; - } - while (retval==RetVal_TableCell || retval==RetVal_TableHCell); - if (cell) cell->markLast(TRUE); - -endrow: - DBG(("DocHtmlRow::parse() end\n")); - return retval; -} - -int DocHtmlRow::parseXml(bool isHeading) -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlRow::parseXml() start\n")); - - bool isFirst=TRUE; - DocHtmlCell *cell=0; - - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - if (tok==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==XML_TERM && !m_parser.context.token->endTag) // found <term> tag - { - } - else if (tagId==XML_DESCRIPTION && !m_parser.context.token->endTag) // found <description> tag - { - } - else // found some other tag - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <term> or <description> tag but " - "found <%s> instead!",qPrint(m_parser.context.token->name)); - m_parser.tokenizer.pushBackHtmlTag(m_parser.context.token->name); - goto endrow; - } - } - else if (tok==0) // premature end of comment - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while looking" - " for a html description title"); - goto endrow; - } - else // token other than html token - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <td> or <th> tag but found %s token instead!", - DocTokenizer::tokToString(tok)); - goto endrow; - } - - do - { - cell=new DocHtmlCell(m_parser,this,m_parser.context.token->attribs,isHeading); - cell->markFirst(isFirst); - isFirst=FALSE; - m_children.push_back(std::unique_ptr<DocHtmlCell>(cell)); - retval=cell->parseXml(); - } - while (retval==RetVal_TableCell || retval==RetVal_TableHCell); - if (cell) cell->markLast(TRUE); - -endrow: - DBG(("DocHtmlRow::parseXml() end\n")); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocHtmlTable::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlTable::parse() start\n")); - -getrow: - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - if (tok==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_TR && !m_parser.context.token->endTag) // found <tr> tag - { - // no caption, just rows - retval=RetVal_TableRow; - } - else if (tagId==HTML_CAPTION && !m_parser.context.token->endTag) // found <caption> tag - { - if (m_caption) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"table already has a caption, found another one"); - } - else - { - m_caption = new DocHtmlCaption(m_parser,this,m_parser.context.token->attribs); - retval=m_caption->parse(); - - if (retval==RetVal_OK) // caption was parsed ok - { - goto getrow; - } - } - } - else // found wrong token - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <tr> or <caption> tag but " - "found <%s%s> instead!", m_parser.context.token->endTag ? "/" : "", qPrint(m_parser.context.token->name)); - } - } - else if (tok==0) // premature end of comment - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while looking" - " for a <tr> or <caption> tag"); - } - else // token other than html token - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <tr> tag but found %s token instead!", - DocTokenizer::tokToString(tok)); - } - - // parse one or more rows - while (retval==RetVal_TableRow) - { - DocHtmlRow *tr=new DocHtmlRow(m_parser,this,m_parser.context.token->attribs); - m_children.push_back(std::unique_ptr<DocHtmlRow>(tr)); - retval=tr->parse(); - } - - computeTableGrid(); - - DBG(("DocHtmlTable::parse() end\n")); - return retval==RetVal_EndTable ? RetVal_OK : retval; -} - -int DocHtmlTable::parseXml() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlTable::parseXml() start\n")); - - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - int tagId=0; - bool isHeader=FALSE; - if (tok==TK_HTMLTAG) - { - tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==XML_ITEM && !m_parser.context.token->endTag) // found <item> tag - { - retval=RetVal_TableRow; - } - if (tagId==XML_LISTHEADER && !m_parser.context.token->endTag) // found <listheader> tag - { - retval=RetVal_TableRow; - isHeader=TRUE; - } - } - - // parse one or more rows - while (retval==RetVal_TableRow) - { - DocHtmlRow *tr=new DocHtmlRow(m_parser,this,m_parser.context.token->attribs); - m_children.push_back(std::unique_ptr<DocHtmlRow>(tr)); - retval=tr->parseXml(isHeader); - isHeader=FALSE; - } - - computeTableGrid(); - - DBG(("DocHtmlTable::parseXml() end\n")); - tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - return tagId==XML_LIST && m_parser.context.token->endTag ? RetVal_OK : retval; -} - -/** Helper class to compute the grid for an HTML style table */ -struct ActiveRowSpan -{ - ActiveRowSpan(uint rows,uint col) : rowsLeft(rows), column(col) {} - uint rowsLeft; - uint column; -}; - -/** List of ActiveRowSpan classes. */ -typedef std::vector<ActiveRowSpan> RowSpanList; - -/** determines the location of all cells in a grid, resolving row and - column spans. For each the total number of visible cells is computed, - and the total number of visible columns over all rows is stored. - */ -void DocHtmlTable::computeTableGrid() -{ - //printf("computeTableGrid()\n"); - RowSpanList rowSpans; - uint maxCols=0; - uint rowIdx=1; - for (const auto &rowNode : children()) - { - uint colIdx=1; - uint cells=0; - if (rowNode->kind()==DocNode::Kind_HtmlRow) - { - size_t i; - DocHtmlRow *row = (DocHtmlRow*)rowNode.get(); - for (const auto &cellNode : row->children()) - { - if (cellNode->kind()==DocNode::Kind_HtmlCell) - { - DocHtmlCell *cell = (DocHtmlCell*)cellNode.get(); - uint rs = cell->rowSpan(); - uint cs = cell->colSpan(); - - for (i=0;i<rowSpans.size();i++) - { - if (rowSpans[i].rowsLeft>0 && - rowSpans[i].column==colIdx) - { - colIdx=rowSpans[i].column+1; - cells++; - } - } - if (rs>0) rowSpans.emplace_back(rs,colIdx); - //printf("found cell at (%d,%d)\n",rowIdx,colIdx); - cell->setRowIndex(rowIdx); - cell->setColumnIndex(colIdx); - colIdx+=cs; - cells++; - } - } - for (i=0;i<rowSpans.size();i++) - { - if (rowSpans[i].rowsLeft>0) rowSpans[i].rowsLeft--; - } - row->setVisibleCells(cells); - row->setRowIndex(rowIdx); - rowIdx++; - } - if (colIdx-1>maxCols) maxCols=colIdx-1; - } - m_numCols = maxCols; -} - -void DocHtmlTable::accept(DocVisitor *v) -{ - v->visitPre(this); - // for HTML output we put the caption first - //if (m_caption && v->id()==DocVisitor_Html) m_caption->accept(v); - // doxygen 1.8.11: always put the caption first - if (m_caption) m_caption->accept(v); - for (const auto &n : m_children) n->accept(v); - // for other output formats we put the caption last - //if (m_caption && v->id()!=DocVisitor_Html) m_caption->accept(v); - v->visitPost(this); -} - -//--------------------------------------------------------------------------- - -int DocHtmlDescTitle::parse() -{ - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlDescTitle::parse() start\n")); - - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - const char *cmd_start = "\\"; - switch (tok) - { - case TK_COMMAND_AT: - cmd_start = "@"; - // fall through - case TK_COMMAND_BS: - { - QCString cmdName=m_parser.context.token->name; - bool isJavaLink=FALSE; - switch (Mappers::cmdMapper->map(cmdName)) - { - case CMD_REF: - { - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(m_parser.context.token->name)); - } - else - { - m_parser.tokenizer.setStateRef(); - tok=m_parser.tokenizer.lex(); // get the reference id - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of \\%s command", - DocTokenizer::tokToString(tok),qPrint(cmdName)); - } - else - { - DocRef *ref = new DocRef(m_parser,this,m_parser.context.token->name,m_parser.context.context); - m_children.push_back(std::unique_ptr<DocRef>(ref)); - ref->parse(); - } - m_parser.tokenizer.setStatePara(); - } - } - break; - case CMD_JAVALINK: - isJavaLink=TRUE; - // fall through - case CMD_LINK: - { - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(cmdName)); - } - else - { - m_parser.tokenizer.setStateLink(); - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of \\%s command", - DocTokenizer::tokToString(tok),qPrint(cmdName)); - } - else - { - m_parser.tokenizer.setStatePara(); - DocLink *lnk = new DocLink(m_parser,this,m_parser.context.token->name); - m_children.push_back(std::unique_ptr<DocLink>(lnk)); - QCString leftOver = lnk->parse(isJavaLink); - if (!leftOver.isEmpty()) - { - m_children.push_back(std::make_unique<DocWord>(m_parser,this,leftOver)); - } - } - } - } - - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Illegal command %s found as part of a <dt> tag", - qPrint(cmd_start + m_parser.context.token->name)); - } - } - break; - case TK_SYMBOL: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unsupported symbol \\%s found as part of a <dt> tag", - qPrint(m_parser.context.token->name)); - break; - case TK_HTMLTAG: - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_DD && !m_parser.context.token->endTag) // found <dd> tag - { - retval = RetVal_DescData; - goto endtitle; - } - else if (tagId==HTML_DT && m_parser.context.token->endTag) - { - // ignore </dt> tag. - } - else if (tagId==HTML_DT) - { - // missing <dt> tag. - retval = RetVal_DescTitle; - goto endtitle; - } - else if (tagId==HTML_DL && m_parser.context.token->endTag) - { - retval=RetVal_EndDesc; - goto endtitle; - } - else if (tagId==HTML_A) - { - if (!m_parser.context.token->endTag) - { - m_parser.handleAHref(this,m_children,m_parser.context.token->attribs); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected html tag <%s%s> found within <dt> context", - m_parser.context.token->endTag?"/":"",qPrint(m_parser.context.token->name)); - } - } - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected token %s found as part of a <dt> tag", - DocTokenizer::tokToString(tok)); - break; - } - } - } - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected end of comment while inside" - " <dt> tag"); - } -endtitle: - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocHtmlDescTitle::parse() end\n")); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocHtmlDescData::parse() -{ - m_attribs = m_parser.context.token->attribs; - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlDescData::parse() start\n")); - - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - } - while (retval==TK_NEWPARA); - if (par) par->markLast(); - - DBG(("DocHtmlDescData::parse() end\n")); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocHtmlDescList::parse() -{ - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - DBG(("DocHtmlDescList::parse() start\n")); - - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - if (tok==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_DT && !m_parser.context.token->endTag) // found <dt> tag - { - // continue - } - else // found some other tag - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <dt> tag but " - "found <%s> instead!",qPrint(m_parser.context.token->name)); - m_parser.tokenizer.pushBackHtmlTag(m_parser.context.token->name); - goto enddesclist; - } - } - else if (tok==0) // premature end of comment - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while looking" - " for a html description title"); - goto enddesclist; - } - else // token other than html token - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <dt> tag but found %s token instead!", - DocTokenizer::tokToString(tok)); - goto enddesclist; - } - - do - { - DocHtmlDescTitle *dt=new DocHtmlDescTitle(m_parser,this,m_parser.context.token->attribs); - m_children.push_back(std::unique_ptr<DocHtmlDescTitle>(dt)); - DocHtmlDescData *dd=new DocHtmlDescData(m_parser,this); - m_children.push_back(std::unique_ptr<DocHtmlDescData>(dd)); - retval=dt->parse(); - if (retval==RetVal_DescData) - { - retval=dd->parse(); - } - else if (retval!=RetVal_DescTitle) - { - // error - break; - } - } while (retval==RetVal_DescTitle); - - if (retval==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while inside <dl> block"); - } - -enddesclist: - - DBG(("DocHtmlDescList::parse() end\n")); - return retval==RetVal_EndDesc ? RetVal_OK : retval; -} - -//--------------------------------------------------------------------------- - -int DocHtmlListItem::parse() -{ - DBG(("DocHtmlListItem::parse() start\n")); - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - - // parse one or more paragraphs - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - } - while (retval==TK_NEWPARA); - if (par) par->markLast(); - - DBG(("DocHtmlListItem::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval; -} - -int DocHtmlListItem::parseXml() -{ - DBG(("DocHtmlListItem::parseXml() start\n")); - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - - // parse one or more paragraphs - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - if (retval==0) break; - - //printf("new item: retval=%x m_parser.context.token->name=%s m_parser.context.token->endTag=%d\n", - // retval,qPrint(m_parser.context.token->name),m_parser.context.token->endTag); - if (retval==RetVal_ListItem) - { - break; - } - } - while (retval!=RetVal_CloseXml); - - if (par) par->markLast(); - - DBG(("DocHtmlListItem::parseXml() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval; -} - -//--------------------------------------------------------------------------- - -int DocHtmlList::parse() -{ - DBG(("DocHtmlList::parse() start\n")); - int retval=RetVal_OK; - int num=1; - auto ns = AutoNodeStack(m_parser,this); - - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace and paragraph breaks - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - if (tok==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - if (tagId==HTML_LI && !m_parser.context.token->endTag) // found <li> tag - { - // ok, we can go on. - } - else if (((m_type==Unordered && tagId==HTML_UL) || - (m_type==Ordered && tagId==HTML_OL) - ) && m_parser.context.token->endTag - ) // found empty list - { - // add dummy item to obtain valid HTML - m_children.push_back(std::make_unique<DocHtmlListItem>(m_parser,this,HtmlAttribList(),1)); - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"empty list!"); - retval = RetVal_EndList; - goto endlist; - } - else // found some other tag - { - // add dummy item to obtain valid HTML - m_children.push_back(std::make_unique<DocHtmlListItem>(m_parser,this,HtmlAttribList(),1)); - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <li> tag but " - "found <%s%s> instead!",m_parser.context.token->endTag?"/":"",qPrint(m_parser.context.token->name)); - m_parser.tokenizer.pushBackHtmlTag(m_parser.context.token->name); - goto endlist; - } - } - else if (tok==0) // premature end of comment - { - // add dummy item to obtain valid HTML - m_children.push_back(std::make_unique<DocHtmlListItem>(m_parser,this,HtmlAttribList(),1)); - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while looking" - " for a html list item"); - goto endlist; - } - else // token other than html token - { - // add dummy item to obtain valid HTML - m_children.push_back(std::make_unique<DocHtmlListItem>(m_parser,this,HtmlAttribList(),1)); - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <li> tag but found %s token instead!", - DocTokenizer::tokToString(tok)); - goto endlist; - } - - do - { - DocHtmlListItem *li=new DocHtmlListItem(m_parser,this,m_parser.context.token->attribs,num++); - m_children.push_back(std::unique_ptr<DocHtmlListItem>(li)); - retval=li->parse(); - } while (retval==RetVal_ListItem); - - if (retval==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while inside <%cl> block", - m_type==Unordered ? 'u' : 'o'); - } - -endlist: - DBG(("DocHtmlList::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval==RetVal_EndList ? RetVal_OK : retval; -} - -int DocHtmlList::parseXml() -{ - DBG(("DocHtmlList::parseXml() start\n")); - int retval=RetVal_OK; - int num=1; - auto ns = AutoNodeStack(m_parser,this); - - // get next token - int tok=m_parser.tokenizer.lex(); - // skip whitespace and paragraph breaks - while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=m_parser.tokenizer.lex(); - // should find a html tag now - if (tok==TK_HTMLTAG) - { - int tagId=Mappers::htmlTagMapper->map(m_parser.context.token->name); - //printf("m_parser.context.token->name=%s m_parser.context.token->endTag=%d\n",qPrint(m_parser.context.token->name),m_parser.context.token->endTag); - if (tagId==XML_ITEM && !m_parser.context.token->endTag) // found <item> tag - { - // ok, we can go on. - } - else // found some other tag - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <item> tag but " - "found <%s> instead!",qPrint(m_parser.context.token->name)); - m_parser.tokenizer.pushBackHtmlTag(m_parser.context.token->name); - goto endlist; - } - } - else if (tok==0) // premature end of comment - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while looking" - " for a html list item"); - goto endlist; - } - else // token other than html token - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected <item> tag but found %s token instead!", - DocTokenizer::tokToString(tok)); - goto endlist; - } - - do - { - DocHtmlListItem *li=new DocHtmlListItem(m_parser,this,m_parser.context.token->attribs,num++); - m_children.push_back(std::unique_ptr<DocHtmlListItem>(li)); - retval=li->parseXml(); - if (retval==0) break; - //printf("retval=%x m_parser.context.token->name=%s\n",retval,qPrint(m_parser.context.token->name)); - } while (retval==RetVal_ListItem); - - if (retval==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment while inside <list type=\"%s\"> block", - m_type==Unordered ? "bullet" : "number"); - } - -endlist: - DBG(("DocHtmlList::parseXml() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval==RetVal_EndList || - (retval==RetVal_CloseXml || m_parser.context.token->name=="list") ? - RetVal_OK : retval; -} - -//-------------------------------------------------------------------------- - -int DocHtmlBlockQuote::parse() -{ - DBG(("DocHtmlBlockQuote::parse() start\n")); - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - - // parse one or more paragraphs - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - } - while (retval==TK_NEWPARA); - if (par) par->markLast(); - - DBG(("DocHtmlBlockQuote::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval; -} - -//--------------------------------------------------------------------------- - -int DocParBlock::parse() -{ - DBG(("DocParBlock::parse() start\n")); - int retval=0; - auto ns = AutoNodeStack(m_parser,this); - - // parse one or more paragraphs - bool isFirst=TRUE; - DocPara *par=0; - do - { - par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - m_children.push_back(std::unique_ptr<DocPara>(par)); - retval=par->parse(); - } - while (retval==TK_NEWPARA); - if (par) par->markLast(); - - DBG(("DocParBlock::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); - return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval; -} - -//--------------------------------------------------------------------------- - -int DocSimpleListItem::parse() -{ - auto ns = AutoNodeStack(m_parser,this); - int rv=m_paragraph->parse(); - m_paragraph->markFirst(); - m_paragraph->markLast(); - return rv; -} - -//-------------------------------------------------------------------------- - -int DocSimpleList::parse() -{ - auto ns = AutoNodeStack(m_parser,this); - int rv; - do - { - DocSimpleListItem *li=new DocSimpleListItem(m_parser,this); - m_children.push_back(std::unique_ptr<DocSimpleListItem>(li)); - rv=li->parse(); - } while (rv==RetVal_ListItem); - return (rv!=TK_NEWPARA) ? rv : RetVal_OK; -} - -//-------------------------------------------------------------------------- - -DocAutoListItem::DocAutoListItem(DocParser &parser,DocNode *parent,int indent,int num) - : CompAccept<DocAutoListItem>(parser), m_indent(indent), m_itemNum(num) -{ - m_parent = parent; -} - -int DocAutoListItem::parse() -{ - int retval = RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - - // first parse any number of paragraphs - bool isFirst=TRUE; - DocPara *lastPar=0; - do - { - DocPara *par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - retval=par->parse(); - if (!par->isEmpty()) - { - m_children.push_back(std::unique_ptr<DocPara>(par)); - if (lastPar) lastPar->markLast(FALSE); - lastPar=par; - } - else - { - delete par; - } - // next paragraph should be more indented than the - marker to belong - // to this item - } while (retval==TK_NEWPARA && m_parser.context.token->indent>m_indent); - if (lastPar) lastPar->markLast(); - - //printf("DocAutoListItem: retval=%d indent=%d\n",retval,m_parser.context.token->indent); - return retval; -} - -//-------------------------------------------------------------------------- - -DocAutoList::DocAutoList(DocParser &parser,DocNode *parent,int indent,bool isEnumList, - int depth) : - CompAccept<DocAutoList>(parser), m_indent(indent), m_isEnumList(isEnumList), - m_depth(depth) -{ - m_parent = parent; -} - -int DocAutoList::parse() -{ - int retval = RetVal_OK; - int num=1; - auto ns = AutoNodeStack(m_parser,this); - m_parser.tokenizer.startAutoList(); - // first item or sub list => create new list - do - { - if (m_parser.context.token->id!=-1) // explicitly numbered list - { - num=m_parser.context.token->id; // override num with real number given - } - DocAutoListItem *li = new DocAutoListItem(m_parser,this,m_indent,num++); - m_children.push_back(std::unique_ptr<DocAutoListItem>(li)); - retval=li->parse(); - //printf("DocAutoList::parse(): retval=0x%x m_parser.context.token->indent=%d m_indent=%d " - // "m_isEnumList=%d m_parser.context.token->isEnumList=%d m_parser.context.token->name=%s\n", - // retval,m_parser.context.token->indent,m_indent,m_isEnumList,m_parser.context.token->isEnumList, - // qPrint(m_parser.context.token->name)); - //printf("num=%d m_parser.context.token->id=%d\n",num,m_parser.context.token->id); - } - while (retval==TK_LISTITEM && // new list item - m_indent==m_parser.context.token->indent && // at same indent level - m_isEnumList==m_parser.context.token->isEnumList && // of the same kind - (m_parser.context.token->id==-1 || m_parser.context.token->id>=num) // increasing number (or no number) - ); - - m_parser.tokenizer.endAutoList(); - return retval; -} - -//-------------------------------------------------------------------------- - -void DocTitle::parse() -{ - DBG(("DocTitle::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - m_parser.tokenizer.setStateTitle(); - int tok; - while ((tok=m_parser.tokenizer.lex())) - { - if (!m_parser.defaultHandleToken(this,tok,m_children)) - { - m_parser.errorHandleDefaultToken(this,tok,m_children,"title section"); - } - } - m_parser.tokenizer.setStatePara(); - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocTitle::parse() end\n")); -} - -void DocTitle::parseFromString(const QCString &text) -{ - m_children.push_back(std::make_unique<DocWord>(m_parser,this,text)); -} - -//-------------------------------------------------------------------------- - -DocSimpleSect::DocSimpleSect(DocParser &parser,DocNode *parent,Type t) : - CompAccept<DocSimpleSect>(parser), m_type(t) -{ - m_parent = parent; - m_title=0; -} - -DocSimpleSect::~DocSimpleSect() -{ - delete m_title; -} - -void DocSimpleSect::accept(DocVisitor *v) -{ - v->visitPre(this); - if (m_title) m_title->accept(v); - for (const auto &n : m_children) n->accept(v); - v->visitPost(this); -} - -int DocSimpleSect::parse(bool userTitle,bool needsSeparator) -{ - DBG(("DocSimpleSect::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - // handle case for user defined title - if (userTitle) - { - m_title = new DocTitle(m_parser,this); - m_title->parse(); - } - - // add new paragraph as child - DocPara *par = new DocPara(m_parser,this); - if (m_children.empty()) - { - par->markFirst(); - } - else - { - ASSERT(m_children.back()->kind()==DocNode::Kind_Para); - ((DocPara *)m_children.back().get())->markLast(FALSE); - } - par->markLast(); - if (needsSeparator) m_children.push_back(std::make_unique<DocSimpleSectSep>(m_parser,this)); - m_children.push_back(std::unique_ptr<DocPara>(par)); - - // parse the contents of the paragraph - int retval = par->parse(); - - DBG(("DocSimpleSect::parse() end retval=%d\n",retval)); - return retval; // 0==EOF, TK_NEWPARA, TK_LISTITEM, TK_ENDLIST, RetVal_SimpleSec -} - -int DocSimpleSect::parseRcs() -{ - DBG(("DocSimpleSect::parseRcs() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - m_title = new DocTitle(m_parser,this); - m_title->parseFromString(m_parser.context.token->name); - - QCString text = m_parser.context.token->text; - m_parser.pushContext(); // this will create a new parser.context.token - m_parser.internalValidatingParseDoc(this,m_children,text); - m_parser.popContext(); // this will restore the old parser.context.token - - DBG(("DocSimpleSect::parseRcs()\n")); - return RetVal_OK; -} - -int DocSimpleSect::parseXml() -{ - DBG(("DocSimpleSect::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - int retval = RetVal_OK; - for (;;) - { - // add new paragraph as child - DocPara *par = new DocPara(m_parser,this); - if (m_children.empty()) - { - par->markFirst(); - } - else - { - ASSERT(m_children.back()->kind()==DocNode::Kind_Para); - ((DocPara *)m_children.back().get())->markLast(FALSE); - } - par->markLast(); - m_children.push_back(std::unique_ptr<DocPara>(par)); - - // parse the contents of the paragraph - retval = par->parse(); - if (retval == 0) break; - if (retval == RetVal_CloseXml) - { - retval = RetVal_OK; - break; - } - } - - DBG(("DocSimpleSect::parseXml() end retval=%d\n",retval)); - return retval; -} - -void DocSimpleSect::appendLinkWord(const QCString &word) -{ - DocPara *p; - if (m_children.empty() || m_children.back()->kind()!=DocNode::Kind_Para) - { - p = new DocPara(m_parser,this); - m_children.push_back(std::unique_ptr<DocPara>(p)); - } - else - { - p = (DocPara *)m_children.back().get(); - - // Comma-separate <seealso> links. - p->injectToken(TK_WORD,","); - p->injectToken(TK_WHITESPACE," "); - } - - m_parser.context.inSeeBlock=TRUE; - p->injectToken(TK_LNKWORD,word); - m_parser.context.inSeeBlock=FALSE; -} - -QCString DocSimpleSect::typeString() const -{ - switch (m_type) - { - case Unknown: break; - case See: return "see"; - case Return: return "return"; - case Author: // fall through - case Authors: return "author"; - case Version: return "version"; - case Since: return "since"; - case Date: return "date"; - case Note: return "note"; - case Warning: return "warning"; - case Pre: return "pre"; - case Post: return "post"; - case Copyright: return "copyright"; - case Invar: return "invariant"; - case Remark: return "remark"; - case Attention: return "attention"; - case User: return "user"; - case Rcs: return "rcs"; - } - return "unknown"; -} - -//-------------------------------------------------------------------------- - -int DocParamList::parse(const QCString &cmdName) -{ - int retval=RetVal_OK; - DBG(("DocParamList::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - DocPara *par=0; - QCString saveCmdName = cmdName; - - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - retval=RetVal_EndParBlock; - goto endparamlist; - } - m_parser.tokenizer.setStateParam(); - tok=m_parser.tokenizer.lex(); - while (tok==TK_WORD) /* there is a parameter name */ - { - if (m_type==DocParamSect::Param) - { - int typeSeparator = m_parser.context.token->name.find('#'); // explicit type position - if (typeSeparator!=-1) - { - m_parser.handleParameterType(this,m_paramTypes,m_parser.context.token->name.left(typeSeparator)); - m_parser.context.token->name = m_parser.context.token->name.mid(typeSeparator+1); - m_parser.context.hasParamCommand=TRUE; - m_parser.checkArgumentName(); - ((DocParamSect*)parent())->m_hasTypeSpecifier=TRUE; - } - else - { - m_parser.context.hasParamCommand=TRUE; - m_parser.checkArgumentName(); - } - } - else if (m_type==DocParamSect::RetVal) - { - m_parser.context.hasReturnCommand=TRUE; - m_parser.checkRetvalName(); - } - //m_params.append(m_parser.context.token->name); - m_parser.handleLinkedWord(this,m_params); - tok=m_parser.tokenizer.lex(); - } - m_parser.tokenizer.setStatePara(); - if (tok==0) /* premature end of comment block */ - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment block while parsing the " - "argument of command %s",qPrint(saveCmdName)); - retval=RetVal_EndParBlock; - goto endparamlist; - } - if (tok!=TK_WHITESPACE) /* premature end of comment block */ - { - if (tok!=TK_NEWPARA) /* empty param description */ - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s in comment block while parsing the " - "argument of command %s",DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - } - retval=RetVal_EndParBlock; - goto endparamlist; - } - - par = new DocPara(m_parser,this); - m_paragraphs.push_back(std::unique_ptr<DocPara>(par)); - retval = par->parse(); - par->markFirst(); - par->markLast(); - -endparamlist: - DBG(("DocParamList::parse() end retval=%d\n",retval)); - return retval; -} - -int DocParamList::parseXml(const QCString ¶mName) -{ - int retval=RetVal_OK; - DBG(("DocParamList::parseXml() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - m_parser.context.token->name = paramName; - if (m_type==DocParamSect::Param) - { - m_parser.context.hasParamCommand=TRUE; - m_parser.checkArgumentName(); - } - else if (m_type==DocParamSect::RetVal) - { - m_parser.context.hasReturnCommand=TRUE; - m_parser.checkRetvalName(); - } - - m_parser.handleLinkedWord(this,m_params); - - do - { - DocPara *par = new DocPara(m_parser,this); - retval = par->parse(); - if (par->isEmpty()) // avoid adding an empty paragraph for the whitespace - // after </para> and before </param> - { - delete par; - break; - } - else // append the paragraph to the list - { - if (m_paragraphs.empty()) - { - par->markFirst(); - } - else - { - m_paragraphs.back()->markLast(FALSE); - } - par->markLast(); - m_paragraphs.push_back(std::unique_ptr<DocPara>(par)); - } - - if (retval == 0) break; - - } while (retval==RetVal_CloseXml && - Mappers::htmlTagMapper->map(m_parser.context.token->name)!=XML_PARAM && - Mappers::htmlTagMapper->map(m_parser.context.token->name)!=XML_TYPEPARAM && - Mappers::htmlTagMapper->map(m_parser.context.token->name)!=XML_EXCEPTION); - - - if (retval==0) /* premature end of comment block */ - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unterminated param or exception tag"); - } - else - { - retval=RetVal_OK; - } - - - DBG(("DocParamList::parse() end retval=%d\n",retval)); - return retval; -} - -//-------------------------------------------------------------------------- - -int DocParamSect::parse(const QCString &cmdName,bool xmlContext, Direction d) -{ - int retval=RetVal_OK; - DBG(("DocParamSect::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - - if (d!=Unspecified) - { - m_hasInOutSpecifier=TRUE; - } - - DocParamList *pl = new DocParamList(m_parser,this,m_type,d); - if (m_children.empty()) - { - pl->markFirst(); - pl->markLast(); - } - else - { - ASSERT(m_children.back()->kind()==DocNode::Kind_ParamList); - ((DocParamList *)m_children.back().get())->markLast(FALSE); - pl->markLast(); - } - m_children.push_back(std::unique_ptr<DocParamList>(pl)); - if (xmlContext) - { - retval = pl->parseXml(cmdName); - } - else - { - retval = pl->parse(cmdName); - } - if (retval==RetVal_EndParBlock) - { - retval = RetVal_OK; - } - - DBG(("DocParamSect::parse() end retval=%d\n",retval)); - return retval; -} - -//-------------------------------------------------------------------------- - -int DocPara::handleSimpleSection(DocSimpleSect::Type t, bool xmlContext) -{ - DocSimpleSect *ss=0; - bool needsSeparator = FALSE; - if (!m_children.empty() && // previous element - m_children.back()->kind()==Kind_SimpleSect && // was a simple sect - ((DocSimpleSect *)m_children.back().get())->type()==t && // of same type - t!=DocSimpleSect::User) // but not user defined - { - // append to previous section - ss=(DocSimpleSect *)m_children.back().get(); - needsSeparator = TRUE; - } - else // start new section - { - ss=new DocSimpleSect(m_parser,this,t); - m_children.push_back(std::unique_ptr<DocSimpleSect>(ss)); - } - int rv = RetVal_OK; - if (xmlContext) - { - return ss->parseXml(); - } - else - { - rv = ss->parse(t==DocSimpleSect::User,needsSeparator); - } - return (rv!=TK_NEWPARA) ? rv : RetVal_OK; -} - -int DocPara::handleParamSection(const QCString &cmdName, - DocParamSect::Type t, - bool xmlContext=FALSE, - int direction=DocParamSect::Unspecified) -{ - DocParamSect *ps=0; - if (!m_children.empty() && // previous element - m_children.back()->kind()==Kind_ParamSect && // was a param sect - ((DocParamSect *)m_children.back().get())->type()==t) // of same type - { - // append to previous section - ps=(DocParamSect *)m_children.back().get(); - } - else // start new section - { - ps=new DocParamSect(m_parser,this,t); - m_children.push_back(std::unique_ptr<DocParamSect>(ps)); - } - int rv=ps->parse(cmdName,xmlContext,(DocParamSect::Direction)direction); - return (rv!=TK_NEWPARA) ? rv : RetVal_OK; -} - -void DocPara::handleCite() -{ - // get the argument of the cite command. - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint("cite")); - return; - } - m_parser.tokenizer.setStateCite(); - tok=m_parser.tokenizer.lex(); - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment block while parsing the " - "argument of command %s\n", qPrint("cite")); - return; - } - else if (tok!=TK_WORD && tok!=TK_LNKWORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint("cite")); - return; - } - m_parser.context.token->sectionId = m_parser.context.token->name; - m_children.push_back( - std::make_unique<DocCite>( - m_parser,this,m_parser.context.token->name,m_parser.context.context)); - - m_parser.tokenizer.setStatePara(); -} - -void DocPara::handleEmoji() -{ - // get the argument of the emoji command. - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint("emoji")); - return; - } - m_parser.tokenizer.setStateEmoji(); - tok=m_parser.tokenizer.lex(); - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment block while parsing the " - "argument of command %s\n", qPrint("emoji")); - return; - } - else if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint("emoji")); - return; - } - m_children.push_back( - std::make_unique<DocEmoji>( - m_parser,this,m_parser.context.token->name)); - m_parser.tokenizer.setStatePara(); -} - -int DocPara::handleXRefItem() -{ - int retval=m_parser.tokenizer.lex(); - ASSERT(retval==TK_WHITESPACE); - m_parser.tokenizer.setStateXRefItem(); - retval=m_parser.tokenizer.lex(); - if (retval==RetVal_OK) - { - DocXRefItem *ref = new DocXRefItem(m_parser,this,m_parser.context.token->id,m_parser.context.token->name); - if (ref->parse()) - { - m_children.push_back(std::unique_ptr<DocXRefItem>(ref)); - } - else - { - delete ref; - } - } - m_parser.tokenizer.setStatePara(); - return retval; -} - -void DocPara::handleIline() -{ - m_parser.tokenizer.setStateIline(); - int tok = m_parser.tokenizer.lex(); - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"invalid argument for command '\\iline'\n"); - return; - } - m_parser.tokenizer.setStatePara(); -} - -void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t) -{ - QCString saveCmdName = cmdName; - DBG(("handleIncludeOperator(%s)\n",qPrint(saveCmdName))); - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - m_parser.tokenizer.setStatePattern(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment block while parsing the " - "argument of command %s", qPrint(saveCmdName)); - return; - } - else if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - DocIncOperator *op = new DocIncOperator(m_parser,this,t,m_parser.context.token->name,m_parser.context.context,m_parser.context.isExample,m_parser.context.exampleName); - DocNode *n1 = m_children.size()>=1 ? m_children.at(m_children.size()-1).get() : 0; - DocNode *n2 = m_children.size()>=2 ? m_children.at(m_children.size()-2).get() : 0; - bool isFirst = n1==0 || // no last node - (n1->kind()!=DocNode::Kind_IncOperator && - n1->kind()!=DocNode::Kind_WhiteSpace - ) || // last node is not operator or whitespace - (n1->kind()==DocNode::Kind_WhiteSpace && - n2!=0 && n2->kind()!=DocNode::Kind_IncOperator - ); // previous not is not operator - op->markFirst(isFirst); - op->markLast(TRUE); - if (n1!=0 && n1->kind()==DocNode::Kind_IncOperator) - { - ((DocIncOperator *)n1)->markLast(FALSE); - } - else if (n1!=0 && n1->kind()==DocNode::Kind_WhiteSpace && - n2!=0 && n2->kind()==DocNode::Kind_IncOperator - ) - { - ((DocIncOperator *)n2)->markLast(FALSE); - } - m_children.push_back(std::unique_ptr<DocIncOperator>(op)); - op->parse(); -} - -void DocPara::handleImage(const QCString &cmdName) -{ - QCString saveCmdName = cmdName; - bool inlineImage = false; - QCString anchorStr; - - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - if (tok==TK_WORD) - { - if (m_parser.context.token->name == "{") - { - m_parser.tokenizer.setStateOptions(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - StringVector optList=split(m_parser.context.token->name.str(),","); - for (const auto &opt : optList) - { - if (opt.empty()) continue; - QCString locOpt(opt); - QCString locOptLow; - locOpt = locOpt.stripWhiteSpace(); - locOptLow = locOpt.lower(); - if (locOptLow == "inline") - { - inlineImage = true; - } - else if (locOptLow.startsWith("anchor:")) - { - if (!anchorStr.isEmpty()) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), - "multiple use of option 'anchor' for '%s' command, ignoring: '%s'", - qPrint(saveCmdName),qPrint(locOpt.mid(7))); - } - else - { - anchorStr = locOpt.mid(7); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), - "unknown option '%s' for '%s' command specified", - qPrint(locOpt), qPrint(saveCmdName)); - } - } - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - } - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WORD && tok!=TK_LNKWORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - DocImage::Type t; - QCString imgType = m_parser.context.token->name.lower(); - if (imgType=="html") t=DocImage::Html; - else if (imgType=="latex") t=DocImage::Latex; - else if (imgType=="docbook") t=DocImage::DocBook; - else if (imgType=="rtf") t=DocImage::Rtf; - else if (imgType=="xml") t=DocImage::Xml; - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"output format `%s` specified as the first argument of " - "%s command is not valid", - qPrint(imgType),qPrint(saveCmdName)); - return; - } - m_parser.tokenizer.setStateFile(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - if (!anchorStr.isEmpty()) - { - DocAnchor *anchor = new DocAnchor(m_parser,this,anchorStr,true); - m_children.push_back(std::unique_ptr<DocAnchor>(anchor)); - } - HtmlAttribList attrList; - DocImage *img = new DocImage(m_parser,this,attrList, - m_parser.findAndCopyImage(m_parser.context.token->name,t),t,"",inlineImage); - m_children.push_back(std::unique_ptr<DocImage>(img)); - img->parse(); -} - -template<class T> -void DocPara::handleFile(const QCString &cmdName) -{ - QCString saveCmdName = cmdName; - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - m_parser.tokenizer.setStateFile(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - QCString name = m_parser.context.token->name; - auto df = std::make_unique<T>(m_parser,this,name,m_parser.context.context,m_parser.context.fileName,m_parser.tokenizer.getLineNr()); - if (df->parse()) - { - m_children.push_back(std::move(df)); - } -} - -void DocPara::handleVhdlFlow() -{ - DocVhdlFlow *vf = new DocVhdlFlow(m_parser,this); - m_children.push_back(std::unique_ptr<DocVhdlFlow>(vf)); - vf->parse(); -} - -void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) -{ - QCString saveCmdName = cmdName; - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - m_parser.tokenizer.setStateLink(); - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"%s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - if (saveCmdName == "javalink") m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Code,cmdName,TRUE)); - m_parser.tokenizer.setStatePara(); - DocLink *lnk = new DocLink(m_parser,this,m_parser.context.token->name); - m_children.push_back(std::unique_ptr<DocLink>(lnk)); - if (saveCmdName == "javalink") m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Code,cmdName,FALSE)); - QCString leftOver = lnk->parse(isJavaLink); - if (!leftOver.isEmpty()) - { - m_children.push_back(std::make_unique<DocWord>(m_parser,this,leftOver)); - } -} - -void DocPara::handleRef(const QCString &cmdName) -{ - QCString saveCmdName = cmdName; - DBG(("handleRef(%s)\n",qPrint(saveCmdName))); - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - m_parser.tokenizer.setStateRef(); - tok=m_parser.tokenizer.lex(); // get the reference id - DocRef *ref=0; - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - goto endref; - } - ref = new DocRef(m_parser,this,m_parser.context.token->name,m_parser.context.context); - m_children.push_back(std::unique_ptr<DocRef>(ref)); - ref->parse(); -endref: - m_parser.tokenizer.setStatePara(); -} - -void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) -{ - DBG(("handleInclude(%s)\n",qPrint(cmdName))); - QCString saveCmdName = cmdName; - int tok=m_parser.tokenizer.lex(); - bool isBlock = false; - if (tok==TK_WORD && m_parser.context.token->name=="{") - { - m_parser.tokenizer.setStateOptions(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - StringVector optList=split(m_parser.context.token->name.str(),","); - auto contains = [&optList](const char *kw) - { - return std::find(optList.begin(),optList.end(),kw)!=optList.end(); - }; - if (t==DocInclude::Include && contains("lineno")) - { - t = DocInclude::IncWithLines; - } - else if (t==DocInclude::Snippet && contains("lineno")) - { - t = DocInclude::SnipWithLines; - } - else if (t==DocInclude::DontInclude && contains("lineno")) - { - t = DocInclude::DontIncWithLines; - } - else if (t==DocInclude::Include && contains("doc")) - { - t = DocInclude::IncludeDoc; - } - else if (t==DocInclude::Snippet && contains("doc")) - { - t = DocInclude::SnippetDoc; - } - tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - } - else if (tok==TK_WORD && m_parser.context.token->name=="[") - { - m_parser.tokenizer.setStateBlock(); - tok=m_parser.tokenizer.lex(); - isBlock = (m_parser.context.token->name.stripWhiteSpace() == "block"); - m_parser.tokenizer.setStatePara(); - tok=m_parser.tokenizer.lex(); - } - else if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - m_parser.tokenizer.setStateFile(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment block while parsing the " - "argument of command %s",qPrint(saveCmdName)); - return; - } - else if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - QCString fileName = m_parser.context.token->name; - QCString blockId; - if (t==DocInclude::Snippet || t==DocInclude::SnipWithLines || t==DocInclude::SnippetDoc) - { - if (fileName == "this") fileName=m_parser.context.fileName; - m_parser.tokenizer.setStateSnippet(); - tok=m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); - if (tok!=TK_WORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected block identifier, but found token %s instead while parsing the %s command", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - blockId = "["+m_parser.context.token->name+"]"; - } - - // This is the only place to handle the \includedoc and \snippetdoc commands, - // as the content is included here as if it is really here. - if (t==DocInclude::IncludeDoc || t==DocInclude::SnippetDoc) - { - QCString inc_text; - int inc_line = 1; - m_parser.readTextFileByName(fileName,inc_text); - if (t==DocInclude::SnippetDoc) - { - int count; - if (!blockId.isEmpty() && (count=inc_text.contains(blockId.data()))!=2) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"block marked with %s for \\snippet should appear twice in file %s, found it %d times\n", - qPrint(blockId),qPrint(fileName),count); - } - inc_line = lineBlock(inc_text, blockId); - inc_text = extractBlock(inc_text, blockId); - } - - Markdown markdown(fileName,inc_line); - QCString strippedDoc = stripIndentation(inc_text); - QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,inc_line) : strippedDoc; - - m_parser.pushContext(); - m_parser.context.fileName = fileName; - m_parser.tokenizer.setLineNr(inc_line); - m_parser.internalValidatingParseDoc(this,m_children,processedDoc); - m_parser.popContext(); - } - else - { - DocInclude *inc = new DocInclude(m_parser,this,fileName,m_parser.context.context,t,m_parser.context.isExample,m_parser.context.exampleName,blockId,isBlock); - m_children.push_back(std::unique_ptr<DocInclude>(inc)); - inc->parse(); - } -} - -void DocPara::handleSection(const QCString &cmdName) -{ - QCString saveCmdName = cmdName; - // get the argument of the section command. - int tok=m_parser.tokenizer.lex(); - if (tok!=TK_WHITESPACE) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"expected whitespace after \\%s command", - qPrint(saveCmdName)); - return; - } - tok=m_parser.tokenizer.lex(); - if (tok==0) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected end of comment block while parsing the " - "argument of command %s\n", qPrint(saveCmdName)); - return; - } - else if (tok!=TK_WORD && tok!=TK_LNKWORD) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected token %s as the argument of %s", - DocTokenizer::tokToString(tok),qPrint(saveCmdName)); - return; - } - m_parser.context.token->sectionId = m_parser.context.token->name; - m_parser.tokenizer.setStateSkipTitle(); - m_parser.tokenizer.lex(); - m_parser.tokenizer.setStatePara(); -} - -int DocPara::handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level) -{ - DocHtmlHeader *header = new DocHtmlHeader(m_parser,this,tagHtmlAttribs,level); - m_children.push_back(std::unique_ptr<DocHtmlHeader>(header)); - int retval = header->parse(); - return (retval==RetVal_OK) ? TK_NEWPARA : retval; -} - -// For XML tags whose content is stored in attributes rather than -// contained within the element, we need a way to inject the attribute -// text into the current paragraph. -bool DocPara::injectToken(int tok,const QCString &tokText) -{ - m_parser.context.token->name = tokText; - return m_parser.defaultHandleToken(this,tok,m_children); -} - -int DocPara::handleStartCode() -{ - int retval = m_parser.tokenizer.lex(); - QCString lang = m_parser.context.token->name; - if (!lang.isEmpty() && lang.at(0)!='.') - { - lang="."+lang; - } - if (m_parser.context.xmlComment) - { - m_parser.context.token->verb = substitute(substitute(m_parser.context.token->verb,"<","<"),">",">"); - } - // search for the first non-whitespace line, index is stored in li - int i=0,li=0,l=m_parser.context.token->verb.length(); - while (i<l && (m_parser.context.token->verb.at(i)==' ' || m_parser.context.token->verb.at(i)=='\n')) - { - if (m_parser.context.token->verb.at(i)=='\n') li=i+1; - i++; - } - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,stripIndentation(m_parser.context.token->verb.mid(li)),DocVerbatim::Code,m_parser.context.isExample,m_parser.context.exampleName,FALSE,lang)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"code section ended without end marker"); - m_parser.tokenizer.setStatePara(); - return retval; -} - -void DocPara::handleInheritDoc() -{ - if (m_parser.context.memberDef) // inheriting docs from a member - { - const MemberDef *reMd = m_parser.context.memberDef->reimplements(); - if (reMd) // member from which was inherited. - { - const MemberDef *thisMd = m_parser.context.memberDef; - //printf("{InheritDocs:%s=>%s}\n",qPrint(m_parser.context.memberDef->qualifiedName()),qPrint(reMd->qualifiedName())); - m_parser.pushContext(); - m_parser.context.scope=reMd->getOuterScope(); - if (m_parser.context.scope!=Doxygen::globalScope) - { - m_parser.context.context=m_parser.context.scope->name(); - } - m_parser.context.memberDef=reMd; - while (!m_parser.context.styleStack.empty()) m_parser.context.styleStack.pop(); - while (!m_parser.context.nodeStack.empty()) m_parser.context.nodeStack.pop(); - m_parser.context.copyStack.push_back(reMd); - m_parser.internalValidatingParseDoc(this,m_children,reMd->briefDescription()); - m_parser.internalValidatingParseDoc(this,m_children,reMd->documentation()); - m_parser.context.copyStack.pop_back(); - auto hasParamCommand = m_parser.context.hasParamCommand; - auto hasReturnCommand = m_parser.context.hasReturnCommand; - auto retvalsFound = m_parser.context.retvalsFound; - auto paramsFound = m_parser.context.paramsFound; - m_parser.popContext(); - m_parser.context.hasParamCommand = hasParamCommand; - m_parser.context.hasReturnCommand = hasReturnCommand; - m_parser.context.retvalsFound = retvalsFound; - m_parser.context.paramsFound = paramsFound; - m_parser.context.memberDef = thisMd; - } - } -} - - -int DocPara::handleCommand(const QCString &cmdName, const int tok) -{ - DBG(("handleCommand(%s)\n",qPrint(cmdName))); - int retval = RetVal_OK; - int cmdId = Mappers::cmdMapper->map(cmdName); - switch (cmdId) - { - case CMD_UNKNOWN: - m_children.push_back(std::make_unique<DocWord>(m_parser,this,TK_COMMAND_CHAR(tok) + cmdName)); - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Found unknown command '%s%s'",TK_COMMAND_CHAR(tok),qPrint(cmdName)); - break; - case CMD_EMPHASIS: - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Italic,cmdName,TRUE)); - retval=m_parser.handleStyleArgument(this,m_children,cmdName); - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Italic,cmdName,FALSE)); - if (retval!=TK_WORD) m_children.push_back(std::make_unique<DocWhiteSpace>(m_parser,this," ")); - break; - case CMD_BOLD: - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Bold,cmdName,TRUE)); - retval=m_parser.handleStyleArgument(this,m_children,cmdName); - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Bold,cmdName,FALSE)); - if (retval!=TK_WORD) m_children.push_back(std::make_unique<DocWhiteSpace>(m_parser,this," ")); - break; - case CMD_CODE: - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Code,cmdName,TRUE)); - retval=m_parser.handleStyleArgument(this,m_children,cmdName); - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Code,cmdName,FALSE)); - if (retval!=TK_WORD) m_children.push_back(std::make_unique<DocWhiteSpace>(m_parser,this," ")); - break; - case CMD_BSLASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_BSlash)); - break; - case CMD_AT: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_At)); - break; - case CMD_LESS: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Less)); - break; - case CMD_GREATER: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Greater)); - break; - case CMD_AMP: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Amp)); - break; - case CMD_DOLLAR: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Dollar)); - break; - case CMD_HASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Hash)); - break; - case CMD_PIPE: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Pipe)); - break; - case CMD_DCOLON: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_DoubleColon)); - break; - case CMD_PERCENT: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Percent)); - break; - case CMD_NDASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - break; - case CMD_MDASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - break; - case CMD_QUOTE: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Quot)); - break; - case CMD_PUNT: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Dot)); - break; - case CMD_PLUS: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Plus)); - break; - case CMD_MINUS: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - break; - case CMD_EQUAL: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Equal)); - break; - case CMD_SA: - m_parser.context.inSeeBlock=TRUE; - retval = handleSimpleSection(DocSimpleSect::See); - m_parser.context.inSeeBlock=FALSE; - break; - case CMD_RETURN: - retval = handleSimpleSection(DocSimpleSect::Return); - m_parser.context.hasReturnCommand=TRUE; - break; - case CMD_AUTHOR: - retval = handleSimpleSection(DocSimpleSect::Author); - break; - case CMD_AUTHORS: - retval = handleSimpleSection(DocSimpleSect::Authors); - break; - case CMD_VERSION: - retval = handleSimpleSection(DocSimpleSect::Version); - break; - case CMD_SINCE: - retval = handleSimpleSection(DocSimpleSect::Since); - break; - case CMD_DATE: - retval = handleSimpleSection(DocSimpleSect::Date); - break; - case CMD_NOTE: - retval = handleSimpleSection(DocSimpleSect::Note); - break; - case CMD_WARNING: - retval = handleSimpleSection(DocSimpleSect::Warning); - break; - case CMD_PRE: - retval = handleSimpleSection(DocSimpleSect::Pre); - break; - case CMD_POST: - retval = handleSimpleSection(DocSimpleSect::Post); - break; - case CMD_COPYRIGHT: - retval = handleSimpleSection(DocSimpleSect::Copyright); - break; - case CMD_INVARIANT: - retval = handleSimpleSection(DocSimpleSect::Invar); - break; - case CMD_REMARK: - retval = handleSimpleSection(DocSimpleSect::Remark); - break; - case CMD_ATTENTION: - retval = handleSimpleSection(DocSimpleSect::Attention); - break; - case CMD_PAR: - retval = handleSimpleSection(DocSimpleSect::User); - break; - case CMD_LI: - { - DocSimpleList *sl=new DocSimpleList(m_parser,this); - m_children.push_back(std::unique_ptr<DocSimpleList>(sl)); - retval = sl->parse(); - } - break; - case CMD_SECTION: - { - handleSection(cmdName); - retval = RetVal_Section; - } - break; - case CMD_SUBSECTION: - { - handleSection(cmdName); - retval = RetVal_Subsection; - } - break; - case CMD_SUBSUBSECTION: - { - handleSection(cmdName); - retval = RetVal_Subsubsection; - } - break; - case CMD_PARAGRAPH: - { - handleSection(cmdName); - retval = RetVal_Paragraph; - } - break; - case CMD_STARTCODE: - { - m_parser.tokenizer.setStateCode(); - retval = handleStartCode(); - } - break; - case CMD_HTMLONLY: - { - m_parser.tokenizer.setStateHtmlOnly(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::HtmlOnly,m_parser.context.isExample,m_parser.context.exampleName,m_parser.context.token->name=="block")); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"htmlonly section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_MANONLY: - { - m_parser.tokenizer.setStateManOnly(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::ManOnly,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"manonly section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_RTFONLY: - { - m_parser.tokenizer.setStateRtfOnly(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::RtfOnly,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"rtfonly section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_LATEXONLY: - { - m_parser.tokenizer.setStateLatexOnly(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::LatexOnly,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"latexonly section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_XMLONLY: - { - m_parser.tokenizer.setStateXmlOnly(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::XmlOnly,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"xmlonly section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_DBONLY: - { - m_parser.tokenizer.setStateDbOnly(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::DocbookOnly,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"docbookonly section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_ILITERAL: - { - DocVerbatim::Type t = DocVerbatim::JavaDocLiteral; - m_parser.tokenizer.setStateILiteralOpt(); - retval = m_parser.tokenizer.lex(); - - QCString fullMatch = m_parser.context.token->verb; - int idx = fullMatch.find('{'); - int idxEnd = fullMatch.find("}",idx+1); - StringVector optList; - if (idx != -1) // options present - { - QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); - optList = split(optStr.str(),","); - for (const auto &opt : optList) - { - if (opt.empty()) continue; - QCString locOpt(opt); - locOpt = locOpt.stripWhiteSpace().lower(); - if (locOpt == "code") - { - t = DocVerbatim::JavaDocCode; - } - else if (!locOpt.isEmpty()) - { - warn(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), "Unknown option '%s' for '\\iliteral'",qPrint(opt)); - } - } - } - - m_parser.tokenizer.setStateILiteral(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,t,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) - { - if (t == DocVerbatim::JavaDocCode) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"javadoc code section ended without end marker"); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"javadoc literal section ended without end marker"); - } - } - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_VERBATIM: - { - m_parser.tokenizer.setStateVerbatim(); - retval = m_parser.tokenizer.lex(); - m_children.push_back(std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::Verbatim,m_parser.context.isExample,m_parser.context.exampleName)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"verbatim section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_DOT: - { - auto dv = std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::Dot,m_parser.context.isExample,m_parser.context.exampleName); - m_parser.tokenizer.setStatePara(); - QCString width,height; - m_parser.defaultHandleTitleAndSize(CMD_DOT,dv.get(),dv->children(),width,height); - m_parser.tokenizer.setStateDot(); - retval = m_parser.tokenizer.lex(); - dv->setText(m_parser.context.token->verb); - dv->setWidth(width); - dv->setHeight(height); - dv->setLocation(m_parser.context.fileName,m_parser.tokenizer.getLineNr()); - if (!Config_getBool(HAVE_DOT)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"ignoring \\dot command because HAVE_DOT is not set"); - } - else - { - m_children.push_back(std::move(dv)); - } - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"dot section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_MSC: - { - auto dv = std::make_unique<DocVerbatim>(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::Msc,m_parser.context.isExample,m_parser.context.exampleName); - m_parser.tokenizer.setStatePara(); - QCString width,height; - m_parser.defaultHandleTitleAndSize(CMD_MSC,dv.get(),dv->children(),width,height); - m_parser.tokenizer.setStateMsc(); - retval = m_parser.tokenizer.lex(); - dv->setText(m_parser.context.token->verb); - dv->setWidth(width); - dv->setHeight(height); - dv->setLocation(m_parser.context.fileName,m_parser.tokenizer.getLineNr()); - m_children.push_back(std::move(dv)); - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"msc section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_STARTUML: - { - static QCString jarPath = Config_getString(PLANTUML_JAR_PATH); - m_parser.tokenizer.setStatePlantUMLOpt(); - retval = m_parser.tokenizer.lex(); - - QCString fullMatch = m_parser.context.token->sectionId; - QCString sectionId = ""; - int idx = fullMatch.find('{'); - int idxEnd = fullMatch.find("}",idx+1); - StringVector optList; - QCString engine; - if (idx != -1) // options present - { - QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); - optList = split(optStr.str(),","); - for (const auto &opt : optList) - { - if (opt.empty()) continue; - bool found = false; - QCString locOpt(opt); - locOpt = locOpt.stripWhiteSpace().lower(); - if (g_plantumlEngine.find(locOpt.str())!=g_plantumlEngine.end()) - { - if (!engine.isEmpty()) - { - warn(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), "Multiple definition of engine for '\\startuml'"); - } - engine = locOpt; - found = true; - } - if (!found) - { - if (sectionId.isEmpty()) - { - sectionId = opt; - } - else - { - warn(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Multiple use of of filename for '\\startuml'"); - } - } - } - } - else - { - sectionId = m_parser.context.token->sectionId; - } - if (engine.isEmpty()) engine = "uml"; - - if (sectionId.isEmpty()) - { - m_parser.tokenizer.setStatePlantUMLOpt(); - retval = m_parser.tokenizer.lex(); - assert(retval==RetVal_OK); - - sectionId = m_parser.context.token->sectionId; - sectionId = sectionId.stripWhiteSpace(); - } - - QCString plantFile(sectionId); - DocVerbatim *dv = new DocVerbatim(m_parser,this,m_parser.context.context,m_parser.context.token->verb,DocVerbatim::PlantUML,FALSE,plantFile); - dv->setEngine(engine); - m_parser.tokenizer.setStatePara(); - QCString width,height; - m_parser.defaultHandleTitleAndSize(CMD_STARTUML,dv,dv->children(),width,height); - m_parser.tokenizer.setStatePlantUML(); - retval = m_parser.tokenizer.lex(); - int line = 0; - QCString trimmedVerb = stripLeadingAndTrailingEmptyLines(m_parser.context.token->verb,line); - if (engine == "ditaa") - { - dv->setUseBitmap(true); - } - else if (engine == "uml") - { - int i = trimmedVerb.find('\n'); - QCString firstLine = i==-1 ? trimmedVerb : trimmedVerb.left(i); - if (firstLine.stripWhiteSpace() == "ditaa") dv->setUseBitmap(true); - } - dv->setText(trimmedVerb); - dv->setWidth(width); - dv->setHeight(height); - dv->setLocation(m_parser.context.fileName,m_parser.tokenizer.getLineNr()); - if (jarPath.isEmpty()) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"ignoring \\startuml command because PLANTUML_JAR_PATH is not set"); - delete dv; - } - else - { - m_children.push_back(std::unique_ptr<DocVerbatim>(dv)); - } - if (retval==0) warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"startuml section ended without end marker"); - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_ENDPARBLOCK: - retval=RetVal_EndParBlock; - break; - case CMD_ENDCODE: - case CMD_ENDHTMLONLY: - case CMD_ENDMANONLY: - case CMD_ENDRTFONLY: - case CMD_ENDLATEXONLY: - case CMD_ENDXMLONLY: - case CMD_ENDDBONLY: - case CMD_ENDLINK: - case CMD_ENDVERBATIM: - case CMD_ENDILITERAL: - case CMD_ENDDOT: - case CMD_ENDMSC: - case CMD_ENDUML: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected command %s",qPrint(m_parser.context.token->name)); - break; - case CMD_PARAM: - retval = handleParamSection(cmdName,DocParamSect::Param,FALSE,m_parser.context.token->paramDir); - break; - case CMD_TPARAM: - retval = handleParamSection(cmdName,DocParamSect::TemplateParam,FALSE,m_parser.context.token->paramDir); - break; - case CMD_RETVAL: - retval = handleParamSection(cmdName,DocParamSect::RetVal); - break; - case CMD_EXCEPTION: - retval = handleParamSection(cmdName,DocParamSect::Exception); - break; - case CMD_XREFITEM: - retval = handleXRefItem(); - break; - case CMD_LINEBREAK: - { - m_children.push_back(std::make_unique<DocLineBreak>(m_parser,this)); - } - break; - case CMD_ANCHOR: - { - DocAnchor *anchor = m_parser.handleAnchor(this); - if (anchor) - { - m_children.push_back(std::unique_ptr<DocAnchor>(anchor)); - } - } - break; - case CMD_ADDINDEX: - { - DocIndexEntry *ie = new DocIndexEntry(m_parser,this, - m_parser.context.scope!=Doxygen::globalScope?m_parser.context.scope:0, - m_parser.context.memberDef); - m_children.push_back(std::unique_ptr<DocIndexEntry>(ie)); - retval = ie->parse(); - } - break; - case CMD_INTERNAL: - retval = RetVal_Internal; - break; - case CMD_ENDINTERNAL: - retval = RetVal_EndInternal; - break; - case CMD_PARBLOCK: - { - DocParBlock *block = new DocParBlock(m_parser,this); - m_children.push_back(std::unique_ptr<DocParBlock>(block)); - retval = block->parse(); - } - break; - case CMD_COPYDOC: // fall through - case CMD_COPYBRIEF: // fall through - case CMD_COPYDETAILS: - //retval = RetVal_CopyDoc; - // these commands should already be resolved by processCopyDoc() - break; - case CMD_INCLUDE: - handleInclude(cmdName,DocInclude::Include); - break; - case CMD_INCWITHLINES: - handleInclude(cmdName,DocInclude::IncWithLines); - break; - case CMD_DONTINCLUDE: - handleInclude(cmdName,DocInclude::DontInclude); - break; - case CMD_HTMLINCLUDE: - handleInclude(cmdName,DocInclude::HtmlInclude); - break; - case CMD_LATEXINCLUDE: - handleInclude(cmdName,DocInclude::LatexInclude); - break; - case CMD_RTFINCLUDE: - handleInclude(cmdName,DocInclude::RtfInclude); - break; - case CMD_MANINCLUDE: - handleInclude(cmdName,DocInclude::ManInclude); - break; - case CMD_XMLINCLUDE: - handleInclude(cmdName,DocInclude::XmlInclude); - break; - case CMD_DOCBOOKINCLUDE: - handleInclude(cmdName,DocInclude::DocbookInclude); - break; - case CMD_VERBINCLUDE: - handleInclude(cmdName,DocInclude::VerbInclude); - break; - case CMD_SNIPPET: - handleInclude(cmdName,DocInclude::Snippet); - break; - case CMD_SNIPWITHLINES: - handleInclude(cmdName,DocInclude::SnipWithLines); - break; - case CMD_INCLUDEDOC: - handleInclude(cmdName,DocInclude::IncludeDoc); - break; - case CMD_SNIPPETDOC: - handleInclude(cmdName,DocInclude::SnippetDoc); - break; - case CMD_SKIP: - handleIncludeOperator(cmdName,DocIncOperator::Skip); - break; - case CMD_UNTIL: - handleIncludeOperator(cmdName,DocIncOperator::Until); - break; - case CMD_SKIPLINE: - handleIncludeOperator(cmdName,DocIncOperator::SkipLine); - break; - case CMD_LINE: - handleIncludeOperator(cmdName,DocIncOperator::Line); - break; - case CMD_IMAGE: - handleImage(cmdName); - break; - case CMD_DOTFILE: - if (!Config_getBool(HAVE_DOT)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), - "ignoring \\dotfile command because HAVE_DOT is not set"); - } - else - { - handleFile<DocDotFile>(cmdName); - } - break; - case CMD_VHDLFLOW: - handleVhdlFlow(); - break; - case CMD_MSCFILE: - handleFile<DocMscFile>(cmdName); - break; - case CMD_DIAFILE: - handleFile<DocDiaFile>(cmdName); - break; - case CMD_LINK: - handleLink(cmdName,FALSE); - break; - case CMD_JAVALINK: - handleLink(cmdName,TRUE); - break; - case CMD_CITE: - handleCite(); - break; - case CMD_EMOJI: - handleEmoji(); - break; - case CMD_REF: // fall through - case CMD_SUBPAGE: - handleRef(cmdName); - break; - case CMD_SECREFLIST: - { - DocSecRefList *list = new DocSecRefList(m_parser,this); - m_children.push_back(std::unique_ptr<DocSecRefList>(list)); - list->parse(); - } - break; - case CMD_SECREFITEM: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected command %s",qPrint(m_parser.context.token->name)); - break; - case CMD_ENDSECREFLIST: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected command %s",qPrint(m_parser.context.token->name)); - break; - case CMD_FORMULA: - { - m_children.push_back( - std::make_unique<DocFormula>( - m_parser,this,m_parser.context.token->id)); - } - break; - //case CMD_LANGSWITCH: - // retval = handleLanguageSwitch(); - // break; - case CMD_INTERNALREF: - //warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"unexpected command %s",qPrint(m_parser.context.token->name)); - { - DocInternalRef *ref = m_parser.handleInternalRef(this); - if (ref) - { - m_children.push_back(std::unique_ptr<DocInternalRef>(ref)); - ref->parse(); - } - m_parser.tokenizer.setStatePara(); - } - break; - case CMD_INHERITDOC: - handleInheritDoc(); - break; - case CMD_ILINE: - handleIline(); - break; - default: - // we should not get here! - ASSERT(0); - break; - } - INTERNAL_ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec || - retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_NEWPARA || - retval==RetVal_Section || retval==RetVal_EndList || - retval==RetVal_Internal || retval==RetVal_SwitchLang || - retval==RetVal_EndInternal - ); - DBG(("handleCommand(%s) end retval=%s\n",qPrint(cmdName),DocTokenizer::retvalToString(retval))); - return retval; -} - -static bool findAttribute(const HtmlAttribList &tagHtmlAttribs, - const char *attrName, - QCString *result) -{ - - for (const auto &opt : tagHtmlAttribs) - { - if (opt.name==attrName) - { - *result = opt.value; - return TRUE; - } - } - return FALSE; -} - -int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs) -{ - DBG(("handleHtmlStartTag(%s,%d)\n",qPrint(tagName),tagHtmlAttribs.size())); - int retval=RetVal_OK; - int tagId = Mappers::htmlTagMapper->map(tagName); - if (m_parser.context.token->emptyTag && !(tagId&XML_CmdMask) && - tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_HR && tagId!=HTML_P) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"HTML tag ('<%s/>') may not use the 'empty tag' XHTML syntax.", - qPrint(tagName)); - } - switch (tagId) - { - case HTML_UL: - if (!m_parser.context.token->emptyTag) - { - DocHtmlList *list = new DocHtmlList(m_parser,this,tagHtmlAttribs,DocHtmlList::Unordered); - m_children.push_back(std::unique_ptr<DocHtmlList>(list)); - retval=list->parse(); - } - break; - case HTML_OL: - if (!m_parser.context.token->emptyTag) - { - DocHtmlList *list = new DocHtmlList(m_parser,this,tagHtmlAttribs,DocHtmlList::Ordered); - m_children.push_back(std::unique_ptr<DocHtmlList>(list)); - retval=list->parse(); - } - break; - case HTML_LI: - if (m_parser.context.token->emptyTag) break; - if (!insideUL(this) && !insideOL(this)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"lonely <li> tag found"); - } - else - { - retval=RetVal_ListItem; - } - break; - case HTML_BOLD: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Bold,tagName,&m_parser.context.token->attribs); - break; - case HTML_S: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::S,tagName,&m_parser.context.token->attribs); - break; - case HTML_STRIKE: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Strike,tagName,&m_parser.context.token->attribs); - break; - case HTML_DEL: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Del,tagName,&m_parser.context.token->attribs); - break; - case HTML_UNDERLINE: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Underline,tagName,&m_parser.context.token->attribs); - break; - case HTML_INS: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Ins,tagName,&m_parser.context.token->attribs); - break; - case HTML_DETAILS: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Details,tagName,&m_parser.context.token->attribs); - break; - case HTML_CODE: - if (m_parser.context.token->emptyTag) break; - if (/*getLanguageFromFileName(m_parser.context.fileName)==SrcLangExt_CSharp ||*/ m_parser.context.xmlComment) - // for C# source or inside a <summary> or <remark> section we - // treat <code> as an XML tag (so similar to @code) - { - m_parser.tokenizer.setStateXmlCode(); - retval = handleStartCode(); - } - else // normal HTML markup - { - m_parser.handleStyleEnter(this,m_children,DocStyleChange::Code,tagName,&m_parser.context.token->attribs); - } - break; - case HTML_EMPHASIS: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Italic,tagName,&m_parser.context.token->attribs); - break; - case HTML_DIV: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Div,tagName,&m_parser.context.token->attribs); - break; - case HTML_SPAN: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Span,tagName,&m_parser.context.token->attribs); - break; - case HTML_SUB: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Subscript,tagName,&m_parser.context.token->attribs); - break; - case HTML_SUP: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Superscript,tagName,&m_parser.context.token->attribs); - break; - case HTML_CENTER: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Center,tagName,&m_parser.context.token->attribs); - break; - case HTML_SMALL: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Small,tagName,&m_parser.context.token->attribs); - break; - case HTML_CITE: - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Cite,tagName,&m_parser.context.token->attribs); - break; - case HTML_PRE: - if (m_parser.context.token->emptyTag) break; - m_parser.handleStyleEnter(this,m_children,DocStyleChange::Preformatted,tagName,&m_parser.context.token->attribs); - setInsidePreformatted(TRUE); - m_parser.tokenizer.setInsidePre(TRUE); - break; - case HTML_P: - retval=TK_NEWPARA; - break; - case HTML_DL: - if (!m_parser.context.token->emptyTag) - { - DocHtmlDescList *list = new DocHtmlDescList(m_parser,this,tagHtmlAttribs); - m_children.push_back(std::unique_ptr<DocHtmlDescList>(list)); - retval=list->parse(); - } - break; - case HTML_DT: - retval = RetVal_DescTitle; - break; - case HTML_DD: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag <dd> found"); - break; - case HTML_TABLE: - if (!m_parser.context.token->emptyTag) - { - DocHtmlTable *table = new DocHtmlTable(m_parser,this,tagHtmlAttribs); - m_children.push_back(std::unique_ptr<DocHtmlTable>(table)); - retval=table->parse(); - } - break; - case HTML_TR: - retval = RetVal_TableRow; - break; - case HTML_TD: - retval = RetVal_TableCell; - break; - case HTML_TH: - retval = RetVal_TableHCell; - break; - case HTML_CAPTION: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag <caption> found"); - break; - case HTML_BR: - { - m_children.push_back(std::make_unique<DocLineBreak>(m_parser,this,tagHtmlAttribs)); - } - break; - case HTML_HR: - { - m_children.push_back(std::make_unique<DocHorRuler>(m_parser,this,tagHtmlAttribs)); - } - break; - case HTML_A: - retval = m_parser.handleAHref(this,m_children,tagHtmlAttribs); - break; - case HTML_H1: - if (!m_parser.context.token->emptyTag) retval=handleHtmlHeader(tagHtmlAttribs,1); - break; - case HTML_H2: - if (!m_parser.context.token->emptyTag) retval=handleHtmlHeader(tagHtmlAttribs,2); - break; - case HTML_H3: - if (!m_parser.context.token->emptyTag) retval=handleHtmlHeader(tagHtmlAttribs,3); - break; - case HTML_H4: - if (!m_parser.context.token->emptyTag) retval=handleHtmlHeader(tagHtmlAttribs,4); - break; - case HTML_H5: - if (!m_parser.context.token->emptyTag) retval=handleHtmlHeader(tagHtmlAttribs,5); - break; - case HTML_H6: - if (!m_parser.context.token->emptyTag) retval=handleHtmlHeader(tagHtmlAttribs,6); - break; - case HTML_IMG: - { - m_parser.handleImg(this,m_children,tagHtmlAttribs); - } - break; - case HTML_BLOCKQUOTE: - if (!m_parser.context.token->emptyTag) - { - DocHtmlBlockQuote *block = new DocHtmlBlockQuote(m_parser,this,tagHtmlAttribs); - m_children.push_back(std::unique_ptr<DocHtmlBlockQuote>(block)); - retval = block->parse(); - } - break; - - case XML_SUMMARY: - if (insideDetails(m_parser.context.styleStack)) - { - if (!m_parser.context.token->emptyTag) m_parser.handleStyleEnter(this,m_children,DocStyleChange::Summary,tagName,&m_parser.context.token->attribs); - break; - } - case XML_REMARKS: - case XML_EXAMPLE: - m_parser.context.xmlComment=TRUE; - // fall through - case XML_VALUE: - case XML_PARA: - if (!m_children.empty()) - { - retval = TK_NEWPARA; - } - break; - case XML_DESCRIPTION: - if (insideTable(this)) - { - retval=RetVal_TableCell; - } - break; - case XML_C: - m_parser.handleStyleEnter(this,m_children,DocStyleChange::Code,tagName,&m_parser.context.token->attribs); - break; - case XML_PARAM: - case XML_TYPEPARAM: - { - m_parser.context.xmlComment=TRUE; - QCString paramName; - if (findAttribute(tagHtmlAttribs,"name",¶mName)) - { - if (paramName.isEmpty()) - { - if (Config_getBool(WARN_NO_PARAMDOC)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"empty 'name' attribute for <param%s> tag.",tagId==XML_PARAM?"":"type"); - } - } - else - { - retval = handleParamSection(paramName, - tagId==XML_PARAM ? DocParamSect::Param : DocParamSect::TemplateParam, - TRUE); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing 'name' attribute from <param%s> tag.",tagId==XML_PARAM?"":"type"); - } - } - break; - case XML_PARAMREF: - case XML_TYPEPARAMREF: - { - QCString paramName; - if (findAttribute(tagHtmlAttribs,"name",¶mName)) - { - //printf("paramName=%s\n",qPrint(paramName)); - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Italic,tagName,TRUE)); - m_children.push_back(std::make_unique<DocWord>(m_parser,this,paramName)); - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Italic,tagName,FALSE)); - if (retval!=TK_WORD) m_children.push_back(std::make_unique<DocWhiteSpace>(m_parser,this," ")); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing 'name' attribute from <param%sref> tag.",tagId==XML_PARAMREF?"":"type"); - } - } - break; - case XML_EXCEPTION: - { - m_parser.context.xmlComment=TRUE; - QCString exceptName; - if (findAttribute(tagHtmlAttribs,"cref",&exceptName)) - { - unescapeCRef(exceptName); - retval = handleParamSection(exceptName,DocParamSect::Exception,TRUE); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing 'cref' attribute from <exception> tag."); - } - } - break; - case XML_ITEM: - case XML_LISTHEADER: - if (insideTable(this)) - { - retval=RetVal_TableRow; - } - else if (insideUL(this) || insideOL(this)) - { - retval=RetVal_ListItem; - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"lonely <item> tag found"); - } - break; - case XML_RETURNS: - m_parser.context.xmlComment=TRUE; - retval = handleSimpleSection(DocSimpleSect::Return,TRUE); - m_parser.context.hasReturnCommand=TRUE; - break; - case XML_TERM: - //m_children.push_back(std::make_unique<DocStyleChange>(this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Bold,TRUE)); - if (insideTable(this)) - { - retval=RetVal_TableCell; - } - break; - case XML_SEE: - // I'm not sure if <see> is the same as <seealso> or if it - // should you link a member without producing a section. The - // C# specification is extremely vague about this (but what else - // can we expect from Microsoft...) - { - QCString cref; - //printf("XML_SEE: empty tag=%d\n",m_parser.context.token->emptyTag); - if (findAttribute(tagHtmlAttribs,"cref",&cref)) - { - unescapeCRef(cref); - if (m_parser.context.token->emptyTag) // <see cref="..."/> style - { - bool inSeeBlock = m_parser.context.inSeeBlock; - m_parser.context.token->name = cref; - m_parser.context.inSeeBlock = TRUE; - m_parser.handleLinkedWord(this,m_children,TRUE); - m_parser.context.inSeeBlock = inSeeBlock; - } - else // <see cref="...">...</see> style - { - //DocRef *ref = new DocRef(this,cref); - //m_children.append(ref); - //ref->parse(); - m_parser.tokenizer.setStatePara(); - DocLink *lnk = new DocLink(m_parser,this,cref); - m_children.push_back(std::unique_ptr<DocLink>(lnk)); - QCString leftOver = lnk->parse(FALSE,TRUE); - if (!leftOver.isEmpty()) - { - m_children.push_back(std::make_unique<DocWord>(m_parser,this,leftOver)); - } - } - } - else if (findAttribute(tagHtmlAttribs,"langword",&cref)) // <see langword="..."/> or <see langword="..."></see> - { - bool inSeeBlock = m_parser.context.inSeeBlock; - m_parser.context.token->name = cref; - m_parser.context.inSeeBlock = TRUE; - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Code,tagName,TRUE)); - m_parser.handleLinkedWord(this,m_children,TRUE); - m_children.push_back(std::make_unique<DocStyleChange>(m_parser,this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Code,tagName,FALSE)); - m_parser.context.inSeeBlock = inSeeBlock; - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing 'cref' or 'langword' attribute from <see> tag."); - } - } - break; - case XML_SEEALSO: - { - m_parser.context.xmlComment=TRUE; - QCString cref; - if (findAttribute(tagHtmlAttribs,"cref",&cref)) - { - unescapeCRef(cref); - // Look for an existing "see" section - DocSimpleSect *ss=0; - for (const auto &n : m_children) - { - if (n->kind()==Kind_SimpleSect && ((DocSimpleSect *)n.get())->type()==DocSimpleSect::See) - { - ss = (DocSimpleSect *)n.get(); - } - } - - if (!ss) // start new section - { - ss=new DocSimpleSect(m_parser,this,DocSimpleSect::See); - m_children.push_back(std::unique_ptr<DocSimpleSect>(ss)); - } - - ss->appendLinkWord(cref); - retval = RetVal_OK; - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing 'cref' attribute from <seealso> tag."); - } - } - break; - case XML_LIST: - { - QCString type; - findAttribute(tagHtmlAttribs,"type",&type); - DocHtmlList::Type listType = DocHtmlList::Unordered; - HtmlAttribList emptyList; - if (type=="number") - { - listType=DocHtmlList::Ordered; - } - if (type=="table") - { - DocHtmlTable *table = new DocHtmlTable(m_parser,this,emptyList); - m_children.push_back(std::unique_ptr<DocHtmlTable>(table)); - retval=table->parseXml(); - } - else - { - DocHtmlList *list = new DocHtmlList(m_parser,this,emptyList,listType); - m_children.push_back(std::unique_ptr<DocHtmlList>(list)); - retval=list->parseXml(); - } - } - break; - case XML_INCLUDE: - case XML_PERMISSION: - // These tags are defined in .Net but are currently unsupported - m_parser.context.xmlComment=TRUE; - break; - case HTML_UNKNOWN: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unsupported xml/html tag <%s> found", qPrint(tagName)); - m_children.push_back(std::make_unique<DocWord>(m_parser,this, "<"+tagName+m_parser.context.token->attribsStr+">")); - break; - case XML_INHERITDOC: - handleInheritDoc(); - break; - default: - // we should not get here! - ASSERT(0); - break; - } - return retval; -} - -int DocPara::handleHtmlEndTag(const QCString &tagName) -{ - DBG(("handleHtmlEndTag(%s)\n",qPrint(tagName))); - int tagId = Mappers::htmlTagMapper->map(tagName); - int retval=RetVal_OK; - switch (tagId) - { - case HTML_UL: - if (!insideUL(this)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found </ul> tag without matching <ul>"); - } - else - { - retval=RetVal_EndList; - } - break; - case HTML_OL: - if (!insideOL(this)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found </ol> tag without matching <ol>"); - } - else - { - retval=RetVal_EndList; - } - break; - case HTML_LI: - if (!insideLI(this)) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found </li> tag without matching <li>"); - } - else - { - // ignore </li> tags - } - break; - case HTML_BLOCKQUOTE: - retval=RetVal_EndBlockQuote; - break; - //case HTML_PRE: - // if (!insidePRE(this)) - // { - // warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found </pre> tag without matching <pre>"); - // } - // else - // { - // retval=RetVal_EndPre; - // } - // break; - case HTML_BOLD: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Bold,tagName); - break; - case HTML_S: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::S,"s"); - break; - case HTML_STRIKE: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Strike,tagName); - break; - case HTML_DEL: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Del,tagName); - break; - case HTML_UNDERLINE: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Underline,tagName); - break; - case HTML_INS: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Ins,tagName); - break; - case HTML_DETAILS: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Details,tagName); - break; - case HTML_CODE: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Code,tagName); - break; - case HTML_EMPHASIS: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Italic,tagName); - break; - case HTML_DIV: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Div,tagName); - break; - case HTML_SPAN: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Span,tagName); - break; - case HTML_SUB: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Subscript,tagName); - break; - case HTML_SUP: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Superscript,tagName); - break; - case HTML_CENTER: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Center,tagName); - break; - case HTML_SMALL: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Small,tagName); - break; - case HTML_CITE: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Cite,tagName); - break; - case HTML_PRE: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Preformatted,tagName); - setInsidePreformatted(FALSE); - m_parser.tokenizer.setInsidePre(FALSE); - break; - case HTML_P: - retval=TK_NEWPARA; - break; - case HTML_DL: - retval=RetVal_EndDesc; - break; - case HTML_DT: - // ignore </dt> tag - break; - case HTML_DD: - // ignore </dd> tag - break; - case HTML_TABLE: - retval=RetVal_EndTable; - break; - case HTML_TR: - // ignore </tr> tag - break; - case HTML_TD: - // ignore </td> tag - break; - case HTML_TH: - // ignore </th> tag - break; - case HTML_CAPTION: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </caption> found"); - break; - case HTML_BR: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Illegal </br> tag found\n"); - break; - case HTML_H1: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </h1> found"); - break; - case HTML_H2: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </h2> found"); - break; - case HTML_H3: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </h3> found"); - break; - case HTML_H4: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </h4> found"); - break; - case HTML_H5: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </h5> found"); - break; - case HTML_H6: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </h6> found"); - break; - case HTML_IMG: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </img> found"); - break; - case HTML_HR: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Illegal </hr> tag found\n"); - break; - case HTML_A: - //warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected tag </a> found"); - // ignore </a> tag (can be part of <a name=...></a> - break; - - case XML_TERM: - //m_children.push_back(std::make_unique<DocStyleChange>(this,(uint)m_parser.context.nodeStack.size(),DocStyleChange::Bold,FALSE)); - break; - case XML_SUMMARY: - if (insideDetails(m_parser.context.styleStack)) - { - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Summary,tagName); - break; - } - case XML_REMARKS: - case XML_PARA: - case XML_VALUE: - case XML_EXAMPLE: - case XML_PARAM: - case XML_LIST: - case XML_TYPEPARAM: - case XML_RETURNS: - case XML_SEE: - case XML_SEEALSO: - case XML_EXCEPTION: - case XML_INHERITDOC: - retval = RetVal_CloseXml; - break; - case XML_C: - m_parser.handleStyleLeave(this,m_children,DocStyleChange::Code,tagName); - break; - case XML_ITEM: - case XML_LISTHEADER: - case XML_INCLUDE: - case XML_PERMISSION: - case XML_DESCRIPTION: - case XML_PARAMREF: - case XML_TYPEPARAMREF: - // These tags are defined in .Net but are currently unsupported - break; - case HTML_UNKNOWN: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unsupported xml/html tag </%s> found", qPrint(tagName)); - m_children.push_back(std::make_unique<DocWord>(m_parser,this,"</"+tagName+">")); - break; - default: - // we should not get here! - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected end tag %s\n",qPrint(tagName)); - ASSERT(0); - break; - } - return retval; -} - -int DocPara::parse() -{ - DBG(("DocPara::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - // handle style commands "inherited" from the previous paragraph - m_parser.handleInitialStyleCommands(this,m_children); - int tok; - int retval=0; - while ((tok=m_parser.tokenizer.lex())) // get the next token - { -reparsetoken: - DBG(("token %s at %d",DocTokenizer::tokToString(tok),m_parser.tokenizer.getLineNr())); - if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || - tok==TK_COMMAND_AT || tok == TK_COMMAND_BS || tok==TK_HTMLTAG - ) - { - DBG((" name=%s",qPrint(m_parser.context.token->name))); - } - DBG(("\n")); - switch(tok) - { - case TK_WORD: - m_children.push_back(std::make_unique<DocWord>(m_parser,this,m_parser.context.token->name)); - break; - case TK_LNKWORD: - m_parser.handleLinkedWord(this,m_children); - break; - case TK_URL: - m_children.push_back(std::make_unique<DocURL>(m_parser,this,m_parser.context.token->name,m_parser.context.token->isEMailAddr)); - break; - case TK_WHITESPACE: - { - // prevent leading whitespace and collapse multiple whitespace areas - DocNode::Kind k; - if (insidePRE(this) || // all whitespace is relevant - ( - // remove leading whitespace - !m_children.empty() && - // and whitespace after certain constructs - (k=m_children.back()->kind())!=DocNode::Kind_HtmlDescList && - k!=DocNode::Kind_HtmlTable && - k!=DocNode::Kind_HtmlList && - k!=DocNode::Kind_SimpleSect && - k!=DocNode::Kind_AutoList && - k!=DocNode::Kind_SimpleList && - /*k!=DocNode::Kind_Verbatim &&*/ - k!=DocNode::Kind_HtmlHeader && - k!=DocNode::Kind_HtmlBlockQuote && - k!=DocNode::Kind_ParamSect && - k!=DocNode::Kind_XRefItem - ) - ) - { - m_children.push_back(std::make_unique<DocWhiteSpace>(m_parser,this,m_parser.context.token->chars)); - } - } - break; - case TK_LISTITEM: - { - DBG(("found list item at %d parent=%d\n",m_parser.context.token->indent,parent()->kind())); - DocNode *n=parent(); - while (n && n->kind()!=DocNode::Kind_AutoList) n=n->parent(); - if (n) // we found an auto list up in the hierarchy - { - DocAutoList *al = (DocAutoList *)n; - DBG(("previous list item at %d\n",al->indent())); - if (al->indent()>=m_parser.context.token->indent) - // new item at the same or lower indent level - { - retval=TK_LISTITEM; - goto endparagraph; - } - } - - // determine list depth - int depth = 0; - n=parent(); - while(n) - { - if (n->kind() == DocNode::Kind_AutoList && - ((DocAutoList*)n)->isEnumList()) depth++; - n=n->parent(); - } - - // first item or sub list => create new list - DocAutoList *al=0; - do - { - al = new DocAutoList(m_parser,this,m_parser.context.token->indent, - m_parser.context.token->isEnumList,depth); - m_children.push_back(std::unique_ptr<DocAutoList>(al)); - retval = al->parse(); - } while (retval==TK_LISTITEM && // new list - al->indent()==m_parser.context.token->indent // at same indent level - ); - - // check the return value - if (retval==RetVal_SimpleSec) // auto list ended due to simple section command - { - // Reparse the token that ended the section at this level, - // so a new simple section will be started at this level. - // This is the same as unputting the last read token and continuing. - m_parser.context.token->name = m_parser.context.token->simpleSectName; - if (m_parser.context.token->name.left(4)=="rcs:") // RCS section - { - m_parser.context.token->name = m_parser.context.token->name.mid(4); - m_parser.context.token->text = m_parser.context.token->simpleSectText; - tok = TK_RCSTAG; - } - else // other section - { - tok = TK_COMMAND_BS; - } - DBG(("reparsing command %s\n",qPrint(m_parser.context.token->name))); - goto reparsetoken; - } - else if (retval==TK_ENDLIST) - { - if (al->indent()>m_parser.context.token->indent) // end list - { - goto endparagraph; - } - else // continue with current paragraph - { - } - } - else // paragraph ended due to TK_NEWPARA, TK_LISTITEM, or EOF - { - goto endparagraph; - } - } - break; - case TK_ENDLIST: - DBG(("Found end of list inside of paragraph at line %d\n",m_parser.tokenizer.getLineNr())); - if (parent()->kind()==DocNode::Kind_AutoListItem) - { - ASSERT(parent()->parent()->kind()==DocNode::Kind_AutoList); - DocAutoList *al = (DocAutoList *)parent()->parent(); - if (al->indent()>=m_parser.context.token->indent) - { - // end of list marker ends this paragraph - retval=TK_ENDLIST; - goto endparagraph; - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"End of list marker found " - "has invalid indent level"); - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"End of list marker found without any preceding " - "list items"); - } - break; - case TK_COMMAND_AT: - // fall through - case TK_COMMAND_BS: - { - // see if we have to start a simple section - int cmd = Mappers::cmdMapper->map(m_parser.context.token->name); - DocNode *n=parent(); - while (n && - n->kind()!=DocNode::Kind_SimpleSect && - n->kind()!=DocNode::Kind_ParamSect - ) - { - n=n->parent(); - } - if (cmd&SIMPLESECT_BIT) - { - if (n) // already in a simple section - { - // simple section cannot start in this paragraph, need - // to unwind the stack and remember the command. - m_parser.context.token->simpleSectName = m_parser.context.token->name; - retval=RetVal_SimpleSec; - goto endparagraph; - } - } - // see if we are in a simple list - n=parent(); - while (n && n->kind()!=DocNode::Kind_SimpleListItem) n=n->parent(); - if (n) - { - if (cmd==CMD_LI) - { - retval=RetVal_ListItem; - goto endparagraph; - } - } - - // handle the command - retval=handleCommand(m_parser.context.token->name,tok); - DBG(("handleCommand returns %s\n",DocTokenizer::retvalToString(retval))); - - // check the return value - if (retval==RetVal_SimpleSec) - { - // Reparse the token that ended the section at this level, - // so a new simple section will be started at this level. - // This is the same as unputting the last read token and continuing. - m_parser.context.token->name = m_parser.context.token->simpleSectName; - if (m_parser.context.token->name.left(4)=="rcs:") // RCS section - { - m_parser.context.token->name = m_parser.context.token->name.mid(4); - m_parser.context.token->text = m_parser.context.token->simpleSectText; - tok = TK_RCSTAG; - } - else // other section - { - tok = TK_COMMAND_BS; - } - DBG(("reparsing command %s\n",qPrint(m_parser.context.token->name))); - goto reparsetoken; - } - else if (retval==RetVal_OK) - { - // the command ended normally, keep scanning for new tokens. - retval = 0; - } - else if (retval>0 && retval<RetVal_OK) - { - // the command ended with a new command, reparse this token - tok = retval; - goto reparsetoken; - } - else // end of file, end of paragraph, start or end of section - // or some auto list marker - { - goto endparagraph; - } - } - break; - case TK_HTMLTAG: - { - if (!m_parser.context.token->endTag) // found a start tag - { - retval = handleHtmlStartTag(m_parser.context.token->name,m_parser.context.token->attribs); - } - else // found an end tag - { - retval = handleHtmlEndTag(m_parser.context.token->name); - } - if (retval==RetVal_OK) - { - // the command ended normally, keep scanner for new tokens. - retval = 0; - } - else - { - goto endparagraph; - } - } - break; - case TK_SYMBOL: - { - DocSymbol::SymType s = DocSymbol::decodeSymbol(m_parser.context.token->name); - if (s!=DocSymbol::Sym_Unknown) - { - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,s)); - } - else - { - m_children.push_back(std::make_unique<DocWord>(m_parser,this,m_parser.context.token->name)); - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unsupported symbol %s found", - qPrint(m_parser.context.token->name)); - } - break; - } - case TK_NEWPARA: - retval=TK_NEWPARA; - goto endparagraph; - case TK_RCSTAG: - { - DocNode *n=parent(); - while (n && - n->kind()!=DocNode::Kind_SimpleSect && - n->kind()!=DocNode::Kind_ParamSect - ) - { - n=n->parent(); - } - if (n) // already in a simple section - { - // simple section cannot start in this paragraph, need - // to unwind the stack and remember the command. - m_parser.context.token->simpleSectName = "rcs:"+m_parser.context.token->name; - m_parser.context.token->simpleSectText = m_parser.context.token->text; - retval=RetVal_SimpleSec; - goto endparagraph; - } - - // see if we are in a simple list - DocSimpleSect *ss=new DocSimpleSect(m_parser,this,DocSimpleSect::Rcs); - m_children.push_back(std::unique_ptr<DocSimpleSect>(ss)); - ss->parseRcs(); - } - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(), - "Found unexpected token (id=%s)\n",DocTokenizer::tokToString(tok)); - break; - } - } - retval=0; -endparagraph: - m_parser.handlePendingStyleCommands(this,m_children); - DBG(("DocPara::parse() end retval=%s\n",DocTokenizer::retvalToString(retval))); - const DocNode *n = m_parser.context.nodeStack.top(); - if (!m_parser.context.token->endTag && n->kind()==DocNode::Kind_Para && - retval==TK_NEWPARA && m_parser.context.token->name.lower() == "p") - { - ((DocPara *)n)->setAttribs(m_parser.context.token->attribs); - } - INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || - retval==TK_ENDLIST || retval>RetVal_OK - ); - - return retval; -} - -//-------------------------------------------------------------------------- - -int DocSection::parse() -{ - DBG(("DocSection::parse() start %s level=%d\n",qPrint(m_parser.context.token->sectionId),m_level)); - int retval=RetVal_OK; - auto ns = AutoNodeStack(m_parser,this); - - if (!m_id.isEmpty()) - { - const SectionInfo *sec = SectionManager::instance().find(m_id); - if (sec) - { - m_file = sec->fileName(); - m_anchor = sec->label(); - m_title = sec->title(); - if (m_title.isEmpty()) m_title = sec->label(); - } - } - - // first parse any number of paragraphs - bool isFirst=TRUE; - DocPara *lastPar=0; - do - { - DocPara *par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - retval=par->parse(); - if (!par->isEmpty()) - { - m_children.push_back(std::unique_ptr<DocPara>(par)); - lastPar=par; - } - else - { - delete par; - } - if (retval==TK_LISTITEM) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid list item found"); - } - if (retval==RetVal_Internal) - { - DocInternal *in = new DocInternal(m_parser,this); - m_children.push_back(std::unique_ptr<DocInternal>(in)); - retval = in->parse(m_level+1); - if (retval==RetVal_EndInternal) - { - retval=RetVal_OK; - } - } - } while (retval!=0 && - retval!=RetVal_Section && - retval!=RetVal_Subsection && - retval!=RetVal_Subsubsection && - retval!=RetVal_Paragraph && - retval!=RetVal_EndInternal - ); - - if (lastPar) lastPar->markLast(); - - //printf("m_level=%d <-> %d\n",m_level,Doxygen::subpageNestingLevel); - - while (true) - { - if (retval==RetVal_Subsection && m_level<=Doxygen::subpageNestingLevel+1) - { - // then parse any number of nested sections - while (retval==RetVal_Subsection) // more sections follow - { - DocSection *s=new DocSection(m_parser,this, - std::min(2+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - break; - } - else if (retval==RetVal_Subsubsection && m_level<=Doxygen::subpageNestingLevel+2) - { - if ((m_level<=1+Doxygen::subpageNestingLevel) && !m_parser.context.token->sectionId.startsWith("autotoc_md")) - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected subsubsection command found inside %s!",g_sectionLevelToName[m_level]); - // then parse any number of nested sections - while (retval==RetVal_Subsubsection) // more sections follow - { - DocSection *s=new DocSection(m_parser,this, - std::min(3+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - if (!(m_level<Doxygen::subpageNestingLevel+2 && retval == RetVal_Subsection)) break; - } - else if (retval==RetVal_Paragraph && m_level<=std::min(5,Doxygen::subpageNestingLevel+3)) - { - if ((m_level<=2+Doxygen::subpageNestingLevel) && !m_parser.context.token->sectionId.startsWith("autotoc_md")) - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected paragraph command found inside %s!",g_sectionLevelToName[m_level]); - // then parse any number of nested sections - while (retval==RetVal_Paragraph) // more sections follow - { - DocSection *s=new DocSection(m_parser,this, - std::min(4+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - if (!(m_level<Doxygen::subpageNestingLevel+3 && (retval == RetVal_Subsection || retval == RetVal_Subsubsection))) break; - } - else - { - break; - } - } - - INTERNAL_ASSERT(retval==0 || - retval==RetVal_Section || - retval==RetVal_Subsection || - retval==RetVal_Subsubsection || - retval==RetVal_Paragraph || - retval==RetVal_Internal || - retval==RetVal_EndInternal - ); - - DBG(("DocSection::parse() end: retval=%s\n",DocTokenizer::retvalToString(retval))); - return retval; -} - -//-------------------------------------------------------------------------- - -void DocText::parse() -{ - DBG(("DocText::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - m_parser.tokenizer.setStateText(); - - int tok; - while ((tok=m_parser.tokenizer.lex())) // get the next token - { - switch(tok) - { - case TK_WORD: - m_children.push_back(std::make_unique<DocWord>(m_parser,this,m_parser.context.token->name)); - break; - case TK_WHITESPACE: - m_children.push_back(std::make_unique<DocWhiteSpace>(m_parser,this,m_parser.context.token->chars)); - break; - case TK_SYMBOL: - { - DocSymbol::SymType s = DocSymbol::decodeSymbol(m_parser.context.token->name); - if (s!=DocSymbol::Sym_Unknown) - { - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,s)); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unsupported symbol %s found", - qPrint(m_parser.context.token->name)); - } - } - break; - case TK_COMMAND_AT: - // fall through - case TK_COMMAND_BS: - switch (Mappers::cmdMapper->map(m_parser.context.token->name)) - { - case CMD_BSLASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_BSlash)); - break; - case CMD_AT: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_At)); - break; - case CMD_LESS: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Less)); - break; - case CMD_GREATER: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Greater)); - break; - case CMD_AMP: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Amp)); - break; - case CMD_DOLLAR: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Dollar)); - break; - case CMD_HASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Hash)); - break; - case CMD_DCOLON: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_DoubleColon)); - break; - case CMD_PERCENT: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Percent)); - break; - case CMD_NDASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - break; - case CMD_MDASH: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - break; - case CMD_QUOTE: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Quot)); - break; - case CMD_PUNT: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Dot)); - break; - case CMD_PLUS: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Plus)); - break; - case CMD_MINUS: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Minus)); - break; - case CMD_EQUAL: - m_children.push_back(std::make_unique<DocSymbol>(m_parser,this,DocSymbol::Sym_Equal)); - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected command '%s' found", - qPrint(m_parser.context.token->name)); - break; - } - break; - default: - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Unexpected token %s", - DocTokenizer::tokToString(tok)); - break; - } - } - - m_parser.handleUnclosedStyleCommands(); - - DBG(("DocText::parse() end\n")); -} - - -//-------------------------------------------------------------------------- - -void DocRoot::parse() -{ - DBG(("DocRoot::parse() start\n")); - auto ns = AutoNodeStack(m_parser,this); - m_parser.tokenizer.setStatePara(); - int retval=0; - - // first parse any number of paragraphs - bool isFirst=TRUE; - DocPara *lastPar=0; - do - { - DocPara *par = new DocPara(m_parser,this); - if (isFirst) { par->markFirst(); isFirst=FALSE; } - retval=par->parse(); - if (!par->isEmpty() || !par->attribs().empty()) - { - m_children.push_back(std::unique_ptr<DocPara>(par)); - lastPar=par; - } - else - { - delete par; - } - if (retval==RetVal_Paragraph) - { - if (!m_parser.context.token->sectionId.startsWith("autotoc_md")) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found paragraph command (id: '%s') outside of subsubsection context!",qPrint(m_parser.context.token->sectionId)); - } - while (retval==RetVal_Paragraph) - { - if (!m_parser.context.token->sectionId.isEmpty()) - { - const SectionInfo *sec=SectionManager::instance().find(m_parser.context.token->sectionId); - if (sec) - { - DocSection *s=new DocSection(m_parser,this, - std::min(4+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid paragraph id '%s'; ignoring paragraph",qPrint(m_parser.context.token->sectionId)); - retval = 0; - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing id for paragraph; ignoring paragraph"); - retval = 0; - } - } - } - if (retval==RetVal_Subsubsection) - { - if (!(m_parser.context.token->sectionId.startsWith("autotoc_md"))) - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found subsubsection command (id: '%s') outside of subsection context!",qPrint(m_parser.context.token->sectionId)); - while (retval==RetVal_Subsubsection) - { - if (!m_parser.context.token->sectionId.isEmpty()) - { - const SectionInfo *sec=SectionManager::instance().find(m_parser.context.token->sectionId); - if (sec) - { - DocSection *s=new DocSection(m_parser,this, - std::min(3+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid subsubsection id '%s'; ignoring subsubsection",qPrint(m_parser.context.token->sectionId)); - retval = 0; - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing id for subsubsection; ignoring subsubsection"); - retval = 0; - } - } - } - if (retval==RetVal_Subsection) - { - if (!m_parser.context.token->sectionId.startsWith("autotoc_md")) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"found subsection command (id: '%s') outside of section context!",qPrint(m_parser.context.token->sectionId)); - } - while (retval==RetVal_Subsection) - { - if (!m_parser.context.token->sectionId.isEmpty()) - { - const SectionInfo *sec=SectionManager::instance().find(m_parser.context.token->sectionId); - if (sec) - { - DocSection *s=new DocSection(m_parser,this, - std::min(2+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid subsection id '%s'; ignoring subsection",qPrint(m_parser.context.token->sectionId)); - retval = 0; - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing id for subsection; ignoring subsection"); - retval = 0; - } - } - } - if (retval==TK_LISTITEM) - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid list item found"); - } - if (retval==RetVal_Internal) - { - DocInternal *in = new DocInternal(m_parser,this); - m_children.push_back(std::unique_ptr<DocInternal>(in)); - retval = in->parse(1); - } - } while (retval!=0 && retval!=RetVal_Section); - if (lastPar) lastPar->markLast(); - - //printf("DocRoot::parse() retval=%d %d\n",retval,RetVal_Section); - // then parse any number of level1 sections - while (retval==RetVal_Section) - { - if (!m_parser.context.token->sectionId.isEmpty()) - { - const SectionInfo *sec=SectionManager::instance().find(m_parser.context.token->sectionId); - if (sec) - { - DocSection *s=new DocSection(m_parser,this, - std::min(1+Doxygen::subpageNestingLevel,5),m_parser.context.token->sectionId); - m_children.push_back(std::unique_ptr<DocSection>(s)); - retval = s->parse(); - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Invalid section id '%s'; ignoring section",qPrint(m_parser.context.token->sectionId)); - retval = 0; - } - } - else - { - warn_doc_error(m_parser.context.fileName,m_parser.tokenizer.getLineNr(),"Missing id for section; ignoring section"); - retval = 0; - } - } - - m_parser.handleUnclosedStyleCommands(); - - DBG(("DocRoot::parse() end\n")); -} - -static QCString extractCopyDocId(const char *data, uint &j, uint len) -{ - uint s=j; - uint e=j; - int round=0; - bool insideDQuote=FALSE; - bool insideSQuote=FALSE; - bool found=FALSE; - while (j<len && !found) - { - if (!insideSQuote && !insideDQuote) - { - switch (data[j]) - { - case '(': round++; break; - case ')': round--; break; - case '"': insideDQuote=TRUE; break; - case '\'': insideSQuote=TRUE; break; - case ' ': // fall through - case '\t': // fall through - case '\n': - found=(round==0); - break; - } - } - else if (insideSQuote) // look for single quote end - { - if (data[j]=='\'' && (j==0 || data[j]!='\\')) - { - insideSQuote=FALSE; - } - } - else if (insideDQuote) // look for double quote end - { - if (data[j]=='"' && (j==0 || data[j]!='\\')) - { - insideDQuote=FALSE; - } - } - if (!found) j++; - } - if (qstrncmp(data+j," const",6)==0) - { - j+=6; - } - else if (qstrncmp(data+j," volatile",9)==0) - { - j+=9; - } - e=j; - if (j>0 && data[j-1]=='.') { e--; } // do not include punctuation added by Definition::_setBriefDescription() - QCString id(data+s,e-s); - //printf("extractCopyDocId='%s' input='%s'\n",qPrint(id),&data[s]); - return id; -} - -// macro to check if the input starts with a specific command. -// note that data[i] should point to the start of the command (\ or @ character) -// and the sizeof(str) returns the size of str including the '\0' terminator; -// a fact we abuse to skip over the start of the command character. -#define CHECK_FOR_COMMAND(str,action) \ - do if ((i+sizeof(str)<len) && qstrncmp(data+i+1,str,sizeof(str)-1)==0) \ - { j=i+sizeof(str); action; } while(0) - -static uint isCopyBriefOrDetailsCmd(const char *data, uint i,uint len,bool &brief) -{ - int j=0; - if (i==0 || (data[i-1]!='@' && data[i-1]!='\\')) // not an escaped command - { - CHECK_FOR_COMMAND("copybrief",brief=TRUE); // @copybrief or \copybrief - CHECK_FOR_COMMAND("copydetails",brief=FALSE); // @copydetails or \copydetails - } - return j; -} - -static uint isVerbatimSection(const char *data,uint i,uint len,QCString &endMarker) -{ - int j=0; - if (i==0 || (data[i-1]!='@' && data[i-1]!='\\')) // not an escaped command - { - CHECK_FOR_COMMAND("dot",endMarker="enddot"); - CHECK_FOR_COMMAND("code",endMarker="endcode"); - CHECK_FOR_COMMAND("msc",endMarker="endmsc"); - CHECK_FOR_COMMAND("verbatim",endMarker="endverbatim"); - CHECK_FOR_COMMAND("iliteral",endMarker="endiliteral"); - CHECK_FOR_COMMAND("latexonly",endMarker="endlatexonly"); - CHECK_FOR_COMMAND("htmlonly",endMarker="endhtmlonly"); - CHECK_FOR_COMMAND("xmlonly",endMarker="endxmlonly"); - CHECK_FOR_COMMAND("rtfonly",endMarker="endrtfonly"); - CHECK_FOR_COMMAND("manonly",endMarker="endmanonly"); - CHECK_FOR_COMMAND("docbookonly",endMarker="enddocbookonly"); - CHECK_FOR_COMMAND("startuml",endMarker="enduml"); - } - //printf("isVerbatimSection(%s)=%d)\n",qPrint(QCString(&data[i]).left(10)),j); - return j; -} - -static uint skipToEndMarker(const char *data,uint i,uint len,const QCString &endMarker) -{ - while (i<len) - { - if ((data[i]=='@' || data[i]=='\\') && // start of command character - (i==0 || (data[i-1]!='@' && data[i-1]!='\\'))) // that is not escaped - { - if (i+endMarker.length()+1<=len && qstrncmp(data+i+1,endMarker.data(),endMarker.length())==0) - { - return i+endMarker.length()+1; - } - } - i++; - } - // oops no endmarker found... - return i<len ? i+1 : len; -} - -QCString DocParser::processCopyDoc(const char *data,uint &len) -{ - //printf("processCopyDoc start '%s'\n",data); - GrowBuf buf; - uint i=0; - while (i<len) - { - char c = data[i]; - if (c=='@' || c=='\\') // look for a command - { - bool isBrief=TRUE; - uint j=isCopyBriefOrDetailsCmd(data,i,len,isBrief); - if (j>0) - { - // skip whitespace - while (j<len && (data[j]==' ' || data[j]=='\t')) j++; - // extract the argument - QCString id = extractCopyDocId(data,j,len); - const Definition *def = 0; - QCString doc,brief; - //printf("resolving docs='%s'\n",qPrint(id)); - if (findDocsForMemberOrCompound(id,&doc,&brief,&def)) - { - //printf("found it def=%p brief='%s' doc='%s' isBrief=%d\n",def,qPrint(brief),qPrint(doc),isBrief); - auto it = std::find(context.copyStack.begin(),context.copyStack.end(),def); - if (it==context.copyStack.end()) // definition not parsed earlier - { - context.copyStack.push_back(def); - if (isBrief) - { - uint l=brief.length(); - buf.addStr(processCopyDoc(brief.data(),l)); - } - else - { - uint l=doc.length(); - buf.addStr(processCopyDoc(doc.data(),l)); - } - context.copyStack.pop_back(); - } - else - { - warn_doc_error(context.fileName,tokenizer.getLineNr(), - "Found recursive @copy%s or @copydoc relation for argument '%s'.\n", - isBrief?"brief":"details",qPrint(id)); - } - } - else - { - warn_doc_error(context.fileName,tokenizer.getLineNr(), - "@copy%s or @copydoc target '%s' not found", isBrief?"brief":"details", - qPrint(id)); - } - // skip over command - i=j; - } - else - { - QCString endMarker; - uint k = isVerbatimSection(data,i,len,endMarker); - if (k>0) - { - int orgPos = i; - i=skipToEndMarker(data,k,len,endMarker); - buf.addStr(data+orgPos,i-orgPos); - } - else - { - buf.addChar(c); - i++; - } - } - } - else // not a command, just copy - { - buf.addChar(c); - i++; - } - } - len = buf.getPos(); - buf.addChar(0); - return buf.get(); -} - -//--------------------------------------------------------------------------- - -DocRoot *validatingParseDoc(IDocParser &parserIntf, +IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName,int startLine, const Definition *ctx,const MemberDef *md, const QCString &input,bool indexWords, @@ -7622,17 +1666,19 @@ DocRoot *validatingParseDoc(IDocParser &parserIntf, bool singleLine, bool linkFromIndex, bool markdownSupport) { - DocParser &parser = dynamic_cast<DocParser&>(parserIntf); + DocParser *parser = dynamic_cast<DocParser*>(&parserIntf); + assert(parser!=0); + if (parser==0) return 0; //printf("validatingParseDoc(%s,%s)=[%s]\n",ctx?qPrint(ctx->name()):"<none>", // md?qPrint(md->name()):"<none>", // input); //printf("========== validating %s at line %d\n",qPrint(fileName),startLine); //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",qPrint(input)); - //parser.context.token = new TokenInfo; + //parser->context.token = new TokenInfo; // store parser state so we can re-enter this function if needed //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - parser.pushContext(); + parser->pushContext(); if (ctx && ctx!=Doxygen::globalScope && (ctx->definitionType()==Definition::TypeClass || @@ -7640,164 +1686,165 @@ DocRoot *validatingParseDoc(IDocParser &parserIntf, ) ) { - parser.context.context = ctx->name(); + parser->context.context = ctx->name(); } else if (ctx && ctx->definitionType()==Definition::TypePage) { const Definition *scope = (toPageDef(ctx))->getPageScope(); - if (scope && scope!=Doxygen::globalScope) parser.context.context = scope->name(); + if (scope && scope!=Doxygen::globalScope) parser->context.context = scope->name(); } else if (ctx && ctx->definitionType()==Definition::TypeGroup) { const Definition *scope = (toGroupDef(ctx))->getGroupScope(); - if (scope && scope!=Doxygen::globalScope) parser.context.context = scope->name(); + if (scope && scope!=Doxygen::globalScope) parser->context.context = scope->name(); } else { - parser.context.context = ""; + parser->context.context = ""; } - parser.context.scope = ctx; + parser->context.scope = ctx; if (indexWords && Doxygen::searchIndex) { if (md) { - parser.context.searchUrl=md->getOutputFileBase(); - Doxygen::searchIndex->setCurrentDoc(md,md->anchor(),FALSE); + parser->context.searchUrl=md->getOutputFileBase(); + parser->searchData.setCurrentDoc(md,md->anchor(),false); } else if (ctx) { - parser.context.searchUrl=ctx->getOutputFileBase(); - Doxygen::searchIndex->setCurrentDoc(ctx,ctx->anchor(),FALSE); + parser->context.searchUrl=ctx->getOutputFileBase(); + parser->searchData.setCurrentDoc(ctx,ctx->anchor(),false); } } else { - parser.context.searchUrl=""; + parser->context.searchUrl=""; } - parser.context.fileName = fileName; - parser.context.relPath = (!linkFromIndex && ctx) ? + parser->context.fileName = fileName; + parser->context.relPath = (!linkFromIndex && ctx) ? QCString(relativePathToRoot(ctx->getOutputFileBase())) : QCString(""); - //printf("ctx->name=%s relPath=%s\n",qPrint(ctx->name()),qPrint(parser.context.relPath)); - parser.context.memberDef = md; - while (!parser.context.nodeStack.empty()) parser.context.nodeStack.pop(); - while (!parser.context.styleStack.empty()) parser.context.styleStack.pop(); - while (!parser.context.initialStyleStack.empty()) parser.context.initialStyleStack.pop(); - parser.context.inSeeBlock = FALSE; - parser.context.xmlComment = FALSE; - parser.context.insideHtmlLink = FALSE; - parser.context.includeFileText = ""; - parser.context.includeFileOffset = 0; - parser.context.includeFileLength = 0; - parser.context.isExample = isExample; - parser.context.exampleName = exampleName; - parser.context.hasParamCommand = FALSE; - parser.context.hasReturnCommand = FALSE; - parser.context.retvalsFound.clear(); - parser.context.paramsFound.clear(); - parser.context.markdownSupport = markdownSupport; - - //printf("Starting comment block at %s:%d\n",qPrint(parser.context.fileName),startLine); - parser.tokenizer.setLineNr(startLine); - uint ioLen = input.length(); - QCString inpStr = parser.processCopyDoc(input.data(),ioLen); + //printf("ctx->name=%s relPath=%s\n",qPrint(ctx->name()),qPrint(parser->context.relPath)); + parser->context.memberDef = md; + while (!parser->context.nodeStack.empty()) parser->context.nodeStack.pop(); + while (!parser->context.styleStack.empty()) parser->context.styleStack.pop(); + while (!parser->context.initialStyleStack.empty()) parser->context.initialStyleStack.pop(); + parser->context.inSeeBlock = FALSE; + parser->context.xmlComment = FALSE; + parser->context.insideHtmlLink = FALSE; + parser->context.includeFileText = ""; + parser->context.includeFileOffset = 0; + parser->context.includeFileLength = 0; + parser->context.isExample = isExample; + parser->context.exampleName = exampleName; + parser->context.hasParamCommand = FALSE; + parser->context.hasReturnCommand = FALSE; + parser->context.retvalsFound.clear(); + parser->context.paramsFound.clear(); + parser->context.markdownSupport = markdownSupport; + + //printf("Starting comment block at %s:%d\n",qPrint(parser->context.fileName),startLine); + parser->tokenizer.setLineNr(startLine); + uint ioLen = static_cast<uint>(input.length()); + QCString inpStr = parser->processCopyDoc(input.data(),ioLen); if (inpStr.isEmpty() || inpStr.at(inpStr.length()-1)!='\n') { inpStr+='\n'; } //printf("processCopyDoc(in='%s' out='%s')\n",input,qPrint(inpStr)); - parser.tokenizer.init(inpStr.data(),parser.context.fileName,markdownSupport); + parser->tokenizer.init(inpStr.data(),parser->context.fileName,markdownSupport); // build abstract syntax tree - DocRoot *root = new DocRoot(parser,md!=0,singleLine); - root->parse(); - + auto ast = std::make_unique<DocNodeAST>(DocRoot(parser,md!=0,singleLine)); + std::get<DocRoot>(ast->root).parse(&ast->root); if (Debug::isFlagSet(Debug::PrintTree)) { // pretty print the result - PrintDocVisitor *v = new PrintDocVisitor; - root->accept(v); - delete v; + std::visit(PrintDocVisitor{},ast->root); } - parser.checkUnOrMultipleDocumentedParams(); - if (parser.context.memberDef) parser.context.memberDef->detectUndocumentedParams(parser.context.hasParamCommand,parser.context.hasReturnCommand); + parser->checkUnOrMultipleDocumentedParams(); + if (parser->context.memberDef) parser->context.memberDef->detectUndocumentedParams(parser->context.hasParamCommand,parser->context.hasReturnCommand); // TODO: These should be called at the end of the program. - //parser.tokenizer.cleanup(); + //parser->tokenizer.cleanup(); //Mappers::cmdMapper->freeInstance(); //Mappers::htmlTagMapper->freeInstance(); // restore original parser state - parser.popContext(); + parser->popContext(); //printf(">>>>>> end validatingParseDoc(%s,%s)\n",ctx?qPrint(ctx->name()):"<none>", // md?qPrint(md->name()):"<none>"); - return root; + return ast; } -DocText *validatingParseText(IDocParser &parserIntf,const QCString &input) +IDocNodeASTPtr validatingParseText(IDocParser &parserIntf,const QCString &input) { - DocParser &parser = dynamic_cast<DocParser&>(parserIntf); + DocParser *parser = dynamic_cast<DocParser*>(&parserIntf); + assert(parser!=0); + if (parser==0) return 0; + // store parser state so we can re-enter this function if needed - parser.pushContext(); + parser->pushContext(); //printf("------------ input ---------\n%s\n" // "------------ end input -----\n",input); - //parser.context.token = new TokenInfo; - parser.context.context = ""; - parser.context.fileName = "<parseText>"; - parser.context.relPath = ""; - parser.context.memberDef = 0; - while (!parser.context.nodeStack.empty()) parser.context.nodeStack.pop(); - while (!parser.context.styleStack.empty()) parser.context.styleStack.pop(); - while (!parser.context.initialStyleStack.empty()) parser.context.initialStyleStack.pop(); - parser.context.inSeeBlock = FALSE; - parser.context.xmlComment = FALSE; - parser.context.insideHtmlLink = FALSE; - parser.context.includeFileText = ""; - parser.context.includeFileOffset = 0; - parser.context.includeFileLength = 0; - parser.context.isExample = FALSE; - parser.context.exampleName = ""; - parser.context.hasParamCommand = FALSE; - parser.context.hasReturnCommand = FALSE; - parser.context.retvalsFound.clear(); - parser.context.paramsFound.clear(); - parser.context.searchUrl=""; - - DocText *txt = new DocText(parser); + //parser->context.token = new TokenInfo; + parser->context.context = ""; + parser->context.fileName = "<parseText>"; + parser->context.relPath = ""; + parser->context.memberDef = 0; + while (!parser->context.nodeStack.empty()) parser->context.nodeStack.pop(); + while (!parser->context.styleStack.empty()) parser->context.styleStack.pop(); + while (!parser->context.initialStyleStack.empty()) parser->context.initialStyleStack.pop(); + parser->context.inSeeBlock = FALSE; + parser->context.xmlComment = FALSE; + parser->context.insideHtmlLink = FALSE; + parser->context.includeFileText = ""; + parser->context.includeFileOffset = 0; + parser->context.includeFileLength = 0; + parser->context.isExample = FALSE; + parser->context.exampleName = ""; + parser->context.hasParamCommand = FALSE; + parser->context.hasReturnCommand = FALSE; + parser->context.retvalsFound.clear(); + parser->context.paramsFound.clear(); + parser->context.searchUrl=""; + + + auto ast = std::make_unique<DocNodeAST>(DocText(parser)); if (!input.isEmpty()) { - parser.tokenizer.setLineNr(1); - parser.tokenizer.init(input.data(),parser.context.fileName,Config_getBool(MARKDOWN_SUPPORT)); + parser->tokenizer.setLineNr(1); + parser->tokenizer.init(input.data(),parser->context.fileName,Config_getBool(MARKDOWN_SUPPORT)); // build abstract syntax tree - txt->parse(); + std::get<DocText>(ast->root).parse(&ast->root); if (Debug::isFlagSet(Debug::PrintTree)) { // pretty print the result - PrintDocVisitor *v = new PrintDocVisitor; - txt->accept(v); - delete v; + std::visit(PrintDocVisitor{},ast->root); } } // restore original parser state - parser.popContext(); - return txt; + parser->popContext(); + return ast; } -DocRef *createRef(IDocParser &parserIntf,const QCString &target,const QCString &context) +IDocNodeASTPtr createRef(IDocParser &parserIntf,const QCString &target,const QCString &context) { - DocParser &parser = dynamic_cast<DocParser&>(parserIntf); - return new DocRef(parser,0,target,context); + DocParser *parser = dynamic_cast<DocParser*>(&parserIntf); + assert(parser!=0); + if (parser==0) return 0; + return std::make_unique<DocNodeAST>(DocRef(parser,0,target,context)); } void docFindSections(const QCString &input, diff --git a/src/docparser.h b/src/docparser.h index e60b1a1..64db969 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -1,9 +1,6 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2022 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 @@ -20,33 +17,42 @@ #define DOCPARSER_H #include <stdio.h> -#include <vector> #include <memory> #include "qcstring.h" -#include "docvisitor.h" -#include "htmlattrib.h" +#include "growvector.h" -class DocNode; class MemberDef; class Definition; -class MemberGroup; //--------------------------------------------------------------------------- -// forward declared, opaque pointer +//! @brief opaque parser interface class IDocParser { public: - virtual ~IDocParser() {} + virtual ~IDocParser() = default; }; -// factory function -std::unique_ptr<IDocParser> createDocParser(); +//! @brief pointer to parser interface +using IDocParserPtr = std::unique_ptr<IDocParser>; + +//! @brief factory function to create a parser +IDocParserPtr createDocParser(); //--------------------------------------------------------------------------- -/*! Main entry point for the documentation parser. +//! @brief opaque representation of the abstract syntax tree (AST) +class IDocNodeAST +{ + public: + virtual ~IDocNodeAST() = default; + virtual bool isEmpty() const = 0; +}; + +using IDocNodeASTPtr = std::unique_ptr<IDocNodeAST>; + +/*! Main entry point for the comment block parser. * @param parser The parser object created via createDocParser() * @param fileName File in which the documentation block is found (or the * name of the example file in case isExample is TRUE). @@ -66,10 +72,10 @@ std::unique_ptr<IDocParser> createDocParser(); * the relative path when making a link. * @param markdownSupport TRUE if the input needs to take markdown markup into * account. - * @returns Root node of the abstract syntax tree. Ownership of the + * @returns An object representing the abstract syntax tree. Ownership of the * pointer is handed over to the caller. */ -DocRoot *validatingParseDoc(IDocParser &parser,const QCString &fileName,int startLine, +IDocNodeASTPtr validatingParseDoc(IDocParser &parser,const QCString &fileName,int startLine, const Definition *context, const MemberDef *md, const QCString &input,bool indexWords, bool isExample,const QCString &exampleName, @@ -79,1398 +85,18 @@ DocRoot *validatingParseDoc(IDocParser &parser,const QCString &fileName,int star /*! Main entry point for parsing simple text fragments. These * fragments are limited to words, whitespace and symbols. */ -DocText *validatingParseText(IDocParser &parser,const QCString &input); +IDocNodeASTPtr validatingParseText(IDocParser &parser,const QCString &input); -/*! Searches for section and anchor commands in the input */ -void docFindSections(const QCString &input, - const Definition *d, - const QCString &fileName); - -DocRef *createRef(IDocParser &parser,const QCString &target,const QCString &context); +IDocNodeASTPtr createRef(IDocParser &parser,const QCString &target,const QCString &context); //-------------------------------------------------------------------------------- -class DocParser; - -/** Abstract node interface with type information. */ -class DocNode -{ - public: - /*! Available node types. */ - enum Kind { Kind_Root = 0, - Kind_Word = 1, - Kind_WhiteSpace = 2, - Kind_Para = 3, - Kind_AutoList = 4, - Kind_AutoListItem = 5, - Kind_Symbol = 6, - Kind_URL = 7, - Kind_StyleChange = 8, - Kind_SimpleSect = 9, - Kind_Title = 10, - Kind_SimpleList = 11, - Kind_SimpleListItem = 12, - Kind_Section = 13, - Kind_Verbatim = 14, - Kind_XRefItem = 15, - Kind_HtmlList = 16, - Kind_HtmlListItem = 17, - Kind_HtmlDescList = 18, - Kind_HtmlDescData = 19, - Kind_HtmlDescTitle = 20, - Kind_HtmlTable = 21, - Kind_HtmlRow = 22, - Kind_HtmlCell = 23, - Kind_HtmlCaption = 24, - Kind_LineBreak = 25, - Kind_HorRuler = 26, - Kind_Anchor = 27, - Kind_IndexEntry = 28, - Kind_Internal = 29, - Kind_HRef = 30, - Kind_Include = 31, - Kind_IncOperator = 32, - Kind_HtmlHeader = 33, - Kind_Image = 34, - Kind_DotFile = 35, - Kind_Link = 36, - Kind_Ref = 37, - Kind_Formula = 38, - Kind_SecRefItem = 39, - Kind_SecRefList = 40, - Kind_SimpleSectSep = 41, - Kind_LinkedWord = 42, - Kind_ParamSect = 43, - Kind_ParamList = 44, - Kind_InternalRef = 45, - Kind_Copy = 46, - Kind_Text = 47, - Kind_MscFile = 48, - Kind_HtmlBlockQuote = 49, - Kind_VhdlFlow = 50, - Kind_ParBlock = 51, - Kind_DiaFile = 52, - Kind_Emoji = 53, - Kind_Sep = 54 - }; - /*! Creates a new node */ - DocNode(DocParser &parser) : m_parser(parser) {} - - /*! Destroys a node. */ - virtual ~DocNode() {} - - /*! Returns the kind of node. Provides runtime type information */ - virtual Kind kind() const = 0; - - /*! Returns the parent of this node or 0 for the root node. */ - DocNode *parent() const { return m_parent; } - - /*! Sets a new parent for this node. */ - void setParent(DocNode *parent) { m_parent = parent; } - - /*! Acceptor function for node visitors. Part of the visitor pattern. - * @param v Abstract visitor. - */ - virtual void accept(DocVisitor *v) = 0; - - /*! Returns TRUE iff this node is inside a preformatted section */ - bool isPreformatted() const { return m_insidePre; } - - protected: - /*! Sets whether or not this item is inside a preformatted section */ - void setInsidePreformatted(bool p) { m_insidePre = p; } - DocNode *m_parent = 0; - enum RefType { Unknown, Anchor, Section, Table }; - DocParser &m_parser; - private: - - bool m_insidePre = false; -}; - -using DocNodeList = std::vector< std::unique_ptr<DocNode> >; - -/** Default accept implementation for compound nodes in the abstract - * syntax tree. - */ -template<class T> -class CompAccept : public DocNode -{ - public: - CompAccept(DocParser &parser) : DocNode(parser) {} - void accept(DocVisitor *v) override - { - T *obj = dynamic_cast<T *>(this); - v->visitPre(obj); - for (const auto &n : m_children) n->accept(v); - v->visitPost(obj); - } - const DocNodeList &children() const { return m_children; } - DocNodeList &children() { return m_children; } - - protected: - DocNodeList m_children; -}; - - -/** Node representing a word - */ -class DocWord : public DocNode -{ - public: - DocWord(DocParser &parser,DocNode *parent,const QCString &word); - QCString word() const { return m_word; } - Kind kind() const override { return Kind_Word; } - void accept(DocVisitor *v) override { v->visit(this); } - - private: - QCString m_word; -}; - -/** Node representing a word that can be linked to something - */ -class DocLinkedWord : public DocNode -{ - public: - DocLinkedWord(DocParser &parser,DocNode *parent,const QCString &word, - const QCString &ref,const QCString &file, - const QCString &anchor,const QCString &tooltip); - QCString word() const { return m_word; } - Kind kind() const override { return Kind_LinkedWord; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - QCString ref() const { return m_ref; } - QCString anchor() const { return m_anchor; } - QCString tooltip() const { return m_tooltip; } - void accept(DocVisitor *v) override { v->visit(this); } - - private: - QCString m_word; - QCString m_ref; - QCString m_file; - QCString m_relPath; - QCString m_anchor; - QCString m_tooltip; -}; - -/** Node representing a URL (or email address) */ -class DocURL : public DocNode -{ - public: - DocURL(DocParser &parser,DocNode *parent,const QCString &url,bool isEmail) : - DocNode(parser), m_url(url), m_isEmail(isEmail) { m_parent=parent; } - QCString url() const { return m_url; } - Kind kind() const override { return Kind_URL; } - void accept(DocVisitor *v) override { v->visit(this); } - bool isEmail() const { return m_isEmail; } - - private: - QCString m_url; - bool m_isEmail = false; -}; - -/** Node representing a line break */ -class DocLineBreak : public DocNode -{ - public: - DocLineBreak(DocParser &parser,DocNode *parent) : DocNode(parser) { m_parent = parent; } - DocLineBreak(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) - : DocNode(parser), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_LineBreak; } - void accept(DocVisitor *v) override { v->visit(this); } - - const HtmlAttribList &attribs() const { return m_attribs; } - - private: - HtmlAttribList m_attribs; -}; - -/** Node representing a horizontal ruler */ -class DocHorRuler : public DocNode -{ - public: - DocHorRuler(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) - : DocNode(parser), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_HorRuler; } - void accept(DocVisitor *v) override { v->visit(this); } - - const HtmlAttribList &attribs() const { return m_attribs; } - - private: - HtmlAttribList m_attribs; -}; - -/** Node representing an anchor */ -class DocAnchor : public DocNode -{ - public: - DocAnchor(DocParser &parser,DocNode *parent,const QCString &id,bool newAnchor); - Kind kind() const override { return Kind_Anchor; } - QCString anchor() const { return m_anchor; } - QCString file() const { return m_file; } - void accept(DocVisitor *v) override { v->visit(this); } - - const HtmlAttribList &attribs() const { return m_attribs; } - - private: - QCString m_anchor; - QCString m_file; - HtmlAttribList m_attribs; -}; - -/** Node representing a citation of some bibliographic reference */ -class DocCite : public DocNode -{ - public: - DocCite(DocParser &parser,DocNode *parent,const QCString &target,const QCString &context); - Kind kind() const override { return Kind_Ref; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - QCString ref() const { return m_ref; } - QCString anchor() const { return m_anchor; } - QCString text() const { return m_text; } - void accept(DocVisitor *v) override { v->visit(this); } - - private: - QCString m_file; - QCString m_relPath; - QCString m_ref; - QCString m_anchor; - QCString m_text; -}; - - -/** Node representing a style change */ -class DocStyleChange : public DocNode -{ - public: - enum Style { Bold = (1<<0), - Italic = (1<<1), - Code = (1<<2), - Center = (1<<3), - Small = (1<<4), - Subscript = (1<<5), - Superscript = (1<<6), - Preformatted = (1<<7), - Span = (1<<8), - Div = (1<<9), - Strike = (1<<10), - Underline = (1<<11), - Del = (1<<12), - Ins = (1<<13), - S = (1<<14), - Details = (1<<15), - Summary = (1<<16), - Cite = (1<<17) - }; - - DocStyleChange(DocParser &parser,DocNode *parent,uint position,Style s,const QCString &tagName,bool enable, - const HtmlAttribList *attribs=0) : - DocNode(parser), m_position(position), m_style(s), m_enable(enable) - { m_parent = parent; if (attribs) m_attribs=*attribs; m_tagName = tagName.lower();} - Kind kind() const override { return Kind_StyleChange; } - Style style() const { return m_style; } - const char *styleString() const; - bool enable() const { return m_enable; } - uint position() const { return m_position; } - void accept(DocVisitor *v) override { v->visit(this); } - const HtmlAttribList &attribs() const { return m_attribs; } - QCString tagName() const { return m_tagName; } - - private: - uint m_position = 0; - Style m_style = Bold; - bool m_enable = false; - HtmlAttribList m_attribs; - QCString m_tagName; -}; - -/** Node representing a special symbol */ -class DocSymbol : public DocNode -{ - public: - enum SymType { Sym_Unknown = -1, - Sym_nbsp, Sym_iexcl, Sym_cent, Sym_pound, Sym_curren, - Sym_yen, Sym_brvbar, Sym_sect, Sym_uml, Sym_copy, - Sym_ordf, Sym_laquo, Sym_not, Sym_shy, Sym_reg, - Sym_macr, Sym_deg, Sym_plusmn, Sym_sup2, Sym_sup3, - Sym_acute, Sym_micro, Sym_para, Sym_middot, Sym_cedil, - Sym_sup1, Sym_ordm, Sym_raquo, Sym_frac14, Sym_frac12, - Sym_frac34, Sym_iquest, Sym_Agrave, Sym_Aacute, Sym_Acirc, - Sym_Atilde, Sym_Auml, Sym_Aring, Sym_AElig, Sym_Ccedil, - Sym_Egrave, Sym_Eacute, Sym_Ecirc, Sym_Euml, Sym_Igrave, - Sym_Iacute, Sym_Icirc, Sym_Iuml, Sym_ETH, Sym_Ntilde, - Sym_Ograve, Sym_Oacute, Sym_Ocirc, Sym_Otilde, Sym_Ouml, - Sym_times, Sym_Oslash, Sym_Ugrave, Sym_Uacute, Sym_Ucirc, - Sym_Uuml, Sym_Yacute, Sym_THORN, Sym_szlig, Sym_agrave, - Sym_aacute, Sym_acirc, Sym_atilde, Sym_auml, Sym_aring, - Sym_aelig, Sym_ccedil, Sym_egrave, Sym_eacute, Sym_ecirc, - Sym_euml, Sym_igrave, Sym_iacute, Sym_icirc, Sym_iuml, - Sym_eth, Sym_ntilde, Sym_ograve, Sym_oacute, Sym_ocirc, - Sym_otilde, Sym_ouml, Sym_divide, Sym_oslash, Sym_ugrave, - Sym_uacute, Sym_ucirc, Sym_uuml, Sym_yacute, Sym_thorn, - Sym_yuml, Sym_fnof, Sym_Alpha, Sym_Beta, Sym_Gamma, - Sym_Delta, Sym_Epsilon, Sym_Zeta, Sym_Eta, Sym_Theta, - Sym_Iota, Sym_Kappa, Sym_Lambda, Sym_Mu, Sym_Nu, - Sym_Xi, Sym_Omicron, Sym_Pi, Sym_Rho, Sym_Sigma, - Sym_Tau, Sym_Upsilon, Sym_Phi, Sym_Chi, Sym_Psi, - Sym_Omega, Sym_alpha, Sym_beta, Sym_gamma, Sym_delta, - Sym_epsilon, Sym_zeta, Sym_eta, Sym_theta, Sym_iota, - Sym_kappa, Sym_lambda, Sym_mu, Sym_nu, Sym_xi, - Sym_omicron, Sym_pi, Sym_rho, Sym_sigmaf, Sym_sigma, - Sym_tau, Sym_upsilon, Sym_phi, Sym_chi, Sym_psi, - Sym_omega, Sym_thetasym, Sym_upsih, Sym_piv, Sym_bull, - Sym_hellip, Sym_prime, Sym_Prime, Sym_oline, Sym_frasl, - Sym_weierp, Sym_image, Sym_real, Sym_trade, Sym_alefsym, - Sym_larr, Sym_uarr, Sym_rarr, Sym_darr, Sym_harr, - Sym_crarr, Sym_lArr, Sym_uArr, Sym_rArr, Sym_dArr, - Sym_hArr, Sym_forall, Sym_part, Sym_exist, Sym_empty, - Sym_nabla, Sym_isin, Sym_notin, Sym_ni, Sym_prod, - Sym_sum, Sym_minus, Sym_lowast, Sym_radic, Sym_prop, - Sym_infin, Sym_ang, Sym_and, Sym_or, Sym_cap, - Sym_cup, Sym_int, Sym_there4, Sym_sim, Sym_cong, - Sym_asymp, Sym_ne, Sym_equiv, Sym_le, Sym_ge, - Sym_sub, Sym_sup, Sym_nsub, Sym_sube, Sym_supe, - Sym_oplus, Sym_otimes, Sym_perp, Sym_sdot, Sym_lceil, - Sym_rceil, Sym_lfloor, Sym_rfloor, Sym_lang, Sym_rang, - Sym_loz, Sym_spades, Sym_clubs, Sym_hearts, Sym_diams, - Sym_quot, Sym_amp, Sym_lt, Sym_gt, Sym_OElig, - Sym_oelig, Sym_Scaron, Sym_scaron, Sym_Yuml, Sym_circ, - Sym_tilde, Sym_ensp, Sym_emsp, Sym_thinsp, Sym_zwnj, - Sym_zwj, Sym_lrm, Sym_rlm, Sym_ndash, Sym_mdash, - Sym_lsquo, Sym_rsquo, Sym_sbquo, Sym_ldquo, Sym_rdquo, - Sym_bdquo, Sym_dagger, Sym_Dagger, Sym_permil, Sym_lsaquo, - Sym_rsaquo, Sym_euro, - - /* doxygen extensions */ - Sym_tm, Sym_apos, - - /* doxygen commands mapped */ - Sym_BSlash, Sym_At, Sym_Less, Sym_Greater, Sym_Amp, - Sym_Dollar, Sym_Hash, Sym_DoubleColon, Sym_Percent, Sym_Pipe, - Sym_Quot, Sym_Minus, Sym_Plus, Sym_Dot, Sym_Colon, Sym_Equal - }; - enum PerlType { Perl_unknown = 0, Perl_string, Perl_char, Perl_symbol, Perl_umlaut, - Perl_acute, Perl_grave, Perl_circ, Perl_slash, Perl_tilde, - Perl_cedilla, Perl_ring - }; - typedef struct PerlSymb { - const char *symb; - const PerlType type; - }PerlSymb; - DocSymbol(DocParser &parser,DocNode *parent,SymType s) : - DocNode(parser), m_symbol(s) { m_parent = parent; } - SymType symbol() const { return m_symbol; } - Kind kind() const override { return Kind_Symbol; } - void accept(DocVisitor *v) override { v->visit(this); } - static SymType decodeSymbol(const QCString &symName); - - private: - SymType m_symbol = Sym_Unknown; -}; - -/** Node representing a n emoji */ -class DocEmoji : public DocNode -{ - public: - DocEmoji(DocParser &parser,DocNode *parent,const QCString &symName); - QCString name() const { return m_symName; } - int index() const { return m_index; } - Kind kind() const override { return Kind_Emoji; } - void accept(DocVisitor *v) override { v->visit(this); } - - private: - QCString m_symName; - int m_index = 0; -}; - -/** Node representing some amount of white space */ -class DocWhiteSpace : public DocNode -{ - public: - DocWhiteSpace(DocParser &parser,DocNode *parent,const QCString &chars) : - DocNode(parser), m_chars(chars) { m_parent = parent; } - Kind kind() const override { return Kind_WhiteSpace; } - QCString chars() const { return m_chars; } - void accept(DocVisitor *v) override { v->visit(this); } - private: - QCString m_chars; -}; - -/** Node representing a separator */ -class DocSeparator : public DocNode -{ - public: - DocSeparator(DocParser &parser,DocNode *parent,const QCString &chars) : - DocNode(parser), m_chars(chars) { m_parent = parent; } - Kind kind() const override { return Kind_Sep; } - QCString chars() const { return m_chars; } - void accept(DocVisitor *) override { } - private: - QCString m_chars; -}; - -/** Node representing a verbatim, unparsed text fragment */ -class DocVerbatim : public DocNode -{ - public: - enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc, DocbookOnly, PlantUML, JavaDocCode, JavaDocLiteral }; - DocVerbatim(DocParser &parser,DocNode *parent,const QCString &context, - const QCString &text, Type t,bool isExample, - const QCString &exampleFile,bool isBlock=FALSE,const QCString &lang=QCString()); - Kind kind() const override { return Kind_Verbatim; } - Type type() const { return m_type; } - QCString text() const { return m_text; } - QCString context() const { return m_context; } - void accept(DocVisitor *v) override { v->visit(this); } - bool isExample() const { return m_isExample; } - QCString exampleFile() const { return m_exampleFile; } - QCString relPath() const { return m_relPath; } - QCString language() const { return m_lang; } - bool isBlock() const { return m_isBlock; } - bool hasCaption() const { return !m_children.empty(); } - QCString width() const { return m_width; } - QCString height() const { return m_height; } - QCString engine() const { return m_engine; } - bool useBitmap() const { return m_useBitmap; } - const DocNodeList &children() const { return m_children; } - DocNodeList &children() { return m_children; } - QCString srcFile() const { return m_srcFile; } - int srcLine() const { return m_srcLine; } - void setText(const QCString &t) { m_text=t; } - void setWidth(const QCString &w) { m_width=w; } - void setHeight(const QCString &h) { m_height=h; } - void setEngine(const QCString &e) { m_engine=e; } - void setUseBitmap(const bool &u) { m_useBitmap=u; } - void setLocation(const QCString &file,int line) { m_srcFile=file; m_srcLine=line; } - - private: - QCString m_context; - QCString m_text; - Type m_type = Code; - bool m_isExample = false; - QCString m_exampleFile; - QCString m_relPath; - QCString m_lang; - bool m_isBlock = false; - QCString m_width; - QCString m_height; - QCString m_engine; - bool m_useBitmap=false; // some PlantUML engines cannot output data in EPS format so bitmap format is required - DocNodeList m_children; - QCString m_srcFile; - int m_srcLine = -1; -}; - - -/** Node representing an included text block from file */ -class DocInclude : public DocNode -{ - public: - enum Type { Include, DontInclude, VerbInclude, HtmlInclude, LatexInclude, - IncWithLines, Snippet , IncludeDoc, SnippetDoc, SnipWithLines, - DontIncWithLines, RtfInclude, ManInclude, DocbookInclude, XmlInclude}; - DocInclude(DocParser &parser,DocNode *parent,const QCString &file, - const QCString &context, Type t, - bool isExample,const QCString &exampleFile, - const QCString &blockId, bool isBlock) : - DocNode(parser), m_file(file), m_context(context), m_type(t), - m_isExample(isExample), m_isBlock(isBlock), - m_exampleFile(exampleFile), m_blockId(blockId) { m_parent = parent; } - Kind kind() const override { return Kind_Include; } - QCString file() const { return m_file; } - QCString extension() const { int i=m_file.findRev('.'); - if (i!=-1) - return m_file.right(m_file.length()-(uint)i); - else - return QCString(); - } - Type type() const { return m_type; } - QCString text() const { return m_text; } - QCString context() const { return m_context; } - QCString blockId() const { return m_blockId; } - bool isExample() const { return m_isExample; } - QCString exampleFile() const { return m_exampleFile; } - bool isBlock() const { return m_isBlock; } - void accept(DocVisitor *v) override { v->visit(this); } - void parse(); - - private: - QCString m_file; - QCString m_context; - QCString m_text; - Type m_type; - bool m_isExample; - bool m_isBlock; - QCString m_exampleFile; - QCString m_blockId; -}; - -/** Node representing a include/dontinclude operator block */ -class DocIncOperator : public DocNode -{ - public: - enum Type { Line, SkipLine, Skip, Until }; - DocIncOperator(DocParser &parser,DocNode *parent,Type t,const QCString &pat, - const QCString &context,bool isExample,const QCString &exampleFile) : - DocNode(parser), m_type(t), m_pattern(pat), m_context(context), - m_isFirst(FALSE), m_isLast(FALSE), - m_isExample(isExample), m_exampleFile(exampleFile) { m_parent = parent; } - Kind kind() const override { return Kind_IncOperator; } - Type type() const { return m_type; } - const char *typeAsString() const - { - switch(m_type) - { - case Line: return "line"; - case SkipLine: return "skipline"; - case Skip: return "skip"; - case Until: return "until"; - } - return ""; - } - int line() const { return m_line; } - bool showLineNo() const { return m_showLineNo; } - QCString text() const { return m_text; } - QCString pattern() const { return m_pattern; } - QCString context() const { return m_context; } - void accept(DocVisitor *v) override { v->visit(this); } - bool isFirst() const { return m_isFirst; } - bool isLast() const { return m_isLast; } - void markFirst(bool v=TRUE) { m_isFirst = v; } - void markLast(bool v=TRUE) { m_isLast = v; } - bool isExample() const { return m_isExample; } - QCString exampleFile() const { return m_exampleFile; } - QCString includeFileName() const { return m_includeFileName; } - void parse(); - - private: - Type m_type = Line; - int m_line = 0; - bool m_showLineNo = false; - QCString m_text; - QCString m_pattern; - QCString m_context; - bool m_isFirst = false; - bool m_isLast = false; - bool m_isExample = false; - QCString m_exampleFile; - QCString m_includeFileName; -}; - -/** Node representing an item of a cross-referenced list */ -class DocFormula : public DocNode -{ - public: - DocFormula(DocParser &parser,DocNode *parent,int id); - Kind kind() const override { return Kind_Formula; } - QCString name() const { return m_name; } - QCString text() const { return m_text; } - QCString relPath() const { return m_relPath; } - int id() const { return m_id; } - void accept(DocVisitor *v) override { v->visit(this); } - bool isInline() { - if (m_text.length()>1 && m_text.at(0)=='\\' && m_text.at(1)=='[') return false; - if (m_text.length()>7 && m_text.startsWith("\\begin{")) return false; - return true; - } - - private: - QCString m_name; - QCString m_text; - QCString m_relPath; - int m_id = 0; -}; - -/** Node representing an entry in the index. */ -class DocIndexEntry : public DocNode -{ - public: - DocIndexEntry(DocParser &parser,DocNode *parent,const Definition *scope,const MemberDef *md) - : DocNode(parser), m_scope(scope), m_member(md){ m_parent = parent; } - Kind kind() const override { return Kind_IndexEntry; } - int parse(); - const Definition *scope() const { return m_scope; } - const MemberDef *member() const { return m_member; } - QCString entry() const { return m_entry; } - void accept(DocVisitor *v) override { v->visit(this); } - - private: - QCString m_entry; - const Definition *m_scope = 0; - const MemberDef *m_member = 0; -}; - -//----------------------------------------------------------------------- - -/** Node representing an auto List */ -class DocAutoList : public CompAccept<DocAutoList> -{ - public: - DocAutoList(DocParser &parser,DocNode *parent,int indent,bool isEnumList,int depth); - Kind kind() const override { return Kind_AutoList; } - bool isEnumList() const { return m_isEnumList; } - int indent() const { return m_indent; } - int depth() const { return m_depth; } - int parse(); - - private: - int m_indent = 0; - bool m_isEnumList = false; - int m_depth = 0; -}; - -/** Node representing an item of a auto list */ -class DocAutoListItem : public CompAccept<DocAutoListItem> -{ - public: - DocAutoListItem(DocParser &parser,DocNode *parent,int indent,int num); - Kind kind() const override { return Kind_AutoListItem; } - int itemNumber() const { return m_itemNum; } - int parse(); - - private: - int m_indent = 0; - int m_itemNum = 0; -}; - - - -/** Node representing a simple section title */ -class DocTitle : public CompAccept<DocTitle> -{ - public: - DocTitle(DocParser &parser,DocNode *parent) : CompAccept<DocTitle>(parser) { m_parent = parent; } - void parse(); - void parseFromString(const QCString &title); - Kind kind() const override { return Kind_Title; } - bool hasTitle() const { return !m_children.empty(); } - - private: -}; - -/** Node representing an item of a cross-referenced list */ -class DocXRefItem : public CompAccept<DocXRefItem> -{ - public: - DocXRefItem(DocParser &parser,DocNode *parent,int id,const QCString &key); - Kind kind() const override { return Kind_XRefItem; } - QCString file() const { return m_file; } - QCString anchor() const { return m_anchor; } - QCString title() const { return m_title; } - QCString relPath() const { return m_relPath; } - QCString key() const { return m_key; } - bool parse(); - - private: - int m_id = 0; - QCString m_key; - QCString m_file; - QCString m_anchor; - QCString m_title; - QCString m_relPath; -}; - -/** Node representing an image */ -class DocImage : public CompAccept<DocImage> -{ - public: - enum Type { Html, Latex, Rtf, DocBook, Xml }; - DocImage(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs, - const QCString &name,Type t,const QCString &url=QCString(), bool inlineImage = TRUE); - Kind kind() const override { return Kind_Image; } - Type type() const { return m_type; } - QCString name() const { return m_name; } - bool hasCaption() const { return !m_children.empty(); } - QCString width() const { return m_width; } - QCString height() const { return m_height; } - QCString relPath() const { return m_relPath; } - QCString url() const { return m_url; } - bool isInlineImage() const { return m_inlineImage; } - bool isSVG() const; - const HtmlAttribList &attribs() const { return m_attribs; } - void parse(); - - private: - HtmlAttribList m_attribs; - QCString m_name; - Type m_type = Html; - QCString m_width; - QCString m_height; - QCString m_relPath; - QCString m_url; - bool m_inlineImage = false; -}; - -template<class T> -class DocDiagramFileBase : public CompAccept<T> -{ - public: - DocDiagramFileBase(DocParser &parser, const QCString &name,const QCString &context, - const QCString &srcFile,int srcLine) - : CompAccept<T>(parser), m_name(name), m_context(context), m_srcFile(srcFile), m_srcLine(srcLine) {} - QCString name() const { return m_name; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - bool hasCaption() const { return !this->m_children.empty(); } - QCString width() const { return m_width; } - QCString height() const { return m_height; } - QCString context() const { return m_context; } - QCString srcFile() const { return m_srcFile; } - int srcLine() const { return m_srcLine; } - - protected: - QCString m_name; - QCString m_file; - QCString m_relPath; - QCString m_width; - QCString m_height; - QCString m_context; - QCString m_srcFile; - int m_srcLine = -1; -}; - -/** Node representing a dot file */ -class DocDotFile : public DocDiagramFileBase<DocDotFile> -{ - public: - DocDotFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, - const QCString &srcFile,int srcLine); - Kind kind() const override { return Kind_DotFile; } - bool parse(); -}; - -/** Node representing a msc file */ -class DocMscFile : public DocDiagramFileBase<DocMscFile> -{ - public: - DocMscFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, - const QCString &srcFile,int srcLine); - Kind kind() const override { return Kind_MscFile; } - bool parse(); -}; - -/** Node representing a dia file */ -class DocDiaFile : public DocDiagramFileBase<DocDiaFile> -{ - public: - DocDiaFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, - const QCString &srcFile,int srcLine); - Kind kind() const override { return Kind_DiaFile; } - bool parse(); -}; - -/** Node representing a VHDL flow chart */ -class DocVhdlFlow : public CompAccept<DocVhdlFlow> -{ - public: - DocVhdlFlow(DocParser &parser,DocNode *parent); - void parse(); - Kind kind() const override { return Kind_VhdlFlow; } - bool hasCaption() { return !m_children.empty(); } - private: -}; - -/** Node representing a link to some item */ -class DocLink : public CompAccept<DocLink> -{ - public: - DocLink(DocParser &parser,DocNode *parent,const QCString &target); - QCString parse(bool,bool isXmlLink=FALSE); - Kind kind() const override { return Kind_Link; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - QCString ref() const { return m_ref; } - QCString anchor() const { return m_anchor; } - - private: - QCString m_file; - QCString m_relPath; - QCString m_ref; - QCString m_anchor; - QCString m_refText; -}; - -/** Node representing a reference to some item */ -class DocRef : public CompAccept<DocRef> -{ - public: - DocRef(DocParser &parser,DocNode *parent,const QCString &target,const QCString &context); - void parse(); - Kind kind() const override { return Kind_Ref; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - QCString ref() const { return m_ref; } - QCString anchor() const { return m_anchor; } - QCString targetTitle() const { return m_text; } - bool hasLinkText() const { return !m_children.empty(); } - bool refToAnchor() const { return m_refType==Anchor; } - bool refToSection() const { return m_refType==Section; } - bool refToTable() const { return m_refType==Table; } - bool isSubPage() const { return m_isSubPage; } - - private: - RefType m_refType = Unknown; - bool m_isSubPage = false; - QCString m_file; - QCString m_relPath; - QCString m_ref; - QCString m_anchor; - QCString m_text; -}; - -/** Node representing an internal reference to some item */ -class DocInternalRef : public CompAccept<DocInternalRef> -{ - public: - DocInternalRef(DocParser &parser,DocNode *parent,const QCString &target); - void parse(); - Kind kind() const override { return Kind_Ref; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - QCString anchor() const { return m_anchor; } - - private: - QCString m_file; - QCString m_relPath; - QCString m_anchor; -}; - -/** Node representing a Hypertext reference */ -class DocHRef : public CompAccept<DocHRef> -{ - public: - DocHRef(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,const QCString &url, - const QCString &relPath, const QCString &file) : - CompAccept<DocHRef>(parser), m_attribs(attribs), m_url(url), m_relPath(relPath), m_file(file) { m_parent = parent; } - int parse(); - QCString url() const { return m_url; } - QCString file() const { return m_file; } - QCString relPath() const { return m_relPath; } - Kind kind() const override { return Kind_HRef; } - const HtmlAttribList &attribs() const { return m_attribs; } - - private: - HtmlAttribList m_attribs; - QCString m_url; - QCString m_relPath; - QCString m_file; -}; - -/** Node Html heading */ -class DocHtmlHeader : public CompAccept<DocHtmlHeader> -{ - public: - DocHtmlHeader(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,int level) : - CompAccept<DocHtmlHeader>(parser), m_level(level), m_attribs(attribs) { m_parent = parent; } - int level() const { return m_level; } - Kind kind() const override { return Kind_HtmlHeader; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - - private: - int m_level = 0; - HtmlAttribList m_attribs; -}; - -/** Node representing a Html description item */ -class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle> -{ - public: - DocHtmlDescTitle(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) : - CompAccept<DocHtmlDescTitle>(parser), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlDescTitle; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - - private: - HtmlAttribList m_attribs; -}; - -/** Node representing a Html description list */ -class DocHtmlDescList : public CompAccept<DocHtmlDescList> -{ - public: - DocHtmlDescList(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) : - CompAccept<DocHtmlDescList>(parser), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlDescList; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - - private: - HtmlAttribList m_attribs; -}; - -/** Node representing a normal section */ -class DocSection : public CompAccept<DocSection> -{ - public: - DocSection(DocParser &parser,DocNode *parent,int level,const QCString &id) : - CompAccept<DocSection>(parser), m_level(level), m_id(id) { m_parent = parent; } - Kind kind() const override { return Kind_Section; } - int level() const { return m_level; } - QCString title() const { return m_title; } - QCString anchor() const { return m_anchor; } - QCString id() const { return m_id; } - QCString file() const { return m_file; } - int parse(); - - private: - int m_level = 0; - QCString m_id; - QCString m_title; - QCString m_anchor; - QCString m_file; -}; - -/** Node representing a reference to a section */ -class DocSecRefItem : public CompAccept<DocSecRefItem> -{ - public: - DocSecRefItem(DocParser &parser,DocNode *parent,const QCString &target); - Kind kind() const override { return Kind_SecRefItem; } - QCString target() const { return m_target; } - QCString file() const { return m_file; } - QCString anchor() const { return m_anchor; } - QCString relPath() const { return m_relPath; } - QCString ref() const { return m_ref; } - bool refToTable() const { return m_refType==Table; } - bool isSubPage() const { return m_isSubPage; } - void parse(); - - private: - QCString m_target; - RefType m_refType = Unknown; - bool m_isSubPage = false; - QCString m_file; - QCString m_relPath; - QCString m_ref; - QCString m_anchor; -}; - -/** Node representing a list of section references */ -class DocSecRefList : public CompAccept<DocSecRefList> -{ - public: - DocSecRefList(DocParser &parser,DocNode *parent) : CompAccept<DocSecRefList>(parser) { m_parent = parent; } - void parse(); - Kind kind() const override { return Kind_SecRefList; } - - private: -}; - -/** Node representing an internal section of documentation */ -class DocInternal : public CompAccept<DocInternal> -{ - public: - DocInternal(DocParser &parser,DocNode *parent) : CompAccept<DocInternal>(parser) { m_parent = parent; } - int parse(int); - Kind kind() const override { return Kind_Internal; } - - private: -}; - -/** Node representing an block of paragraphs */ -class DocParBlock : public CompAccept<DocParBlock> -{ - public: - DocParBlock(DocParser &parser,DocNode *parent) : CompAccept<DocParBlock>(parser) { m_parent = parent; } - int parse(); - Kind kind() const override { return Kind_ParBlock; } - - private: -}; - - -/** Node representing a simple list */ -class DocSimpleList : public CompAccept<DocSimpleList> -{ - public: - DocSimpleList(DocParser &parser,DocNode *parent) : CompAccept<DocSimpleList>(parser) { m_parent = parent; } - Kind kind() const override { return Kind_SimpleList; } - int parse(); - - private: -}; - -/** Node representing a Html list */ -class DocHtmlList : public CompAccept<DocHtmlList> -{ - public: - enum Type { Unordered, Ordered }; - DocHtmlList(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,Type t) : - CompAccept<DocHtmlList>(parser), m_type(t), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlList; } - Type type() const { return m_type; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - int parseXml(); - - private: - Type m_type = Unordered; - HtmlAttribList m_attribs; -}; - -/** Node representing a simple section */ -class DocSimpleSect : public CompAccept<DocSimpleSect> -{ - public: - enum Type - { - Unknown, See, Return, Author, Authors, Version, Since, Date, - Note, Warning, Copyright, Pre, Post, Invar, Remark, Attention, User, Rcs - }; - DocSimpleSect(DocParser &parser,DocNode *parent,Type t); - virtual ~DocSimpleSect(); - Kind kind() const override { return Kind_SimpleSect; } - Type type() const { return m_type; } - QCString typeString() const; - void accept(DocVisitor *v) override; - int parse(bool userTitle,bool needsSeparator); - int parseRcs(); - int parseXml(); - void appendLinkWord(const QCString &word); - bool hasTitle() const { return m_title->hasTitle(); } - - private: - Type m_type = Unknown; - DocTitle * m_title = 0; -}; - -/** Node representing a separator between two simple sections of the - * same type. +/*! Searches for section and anchor commands in the input + * Sections found will be added to the SectionManager. */ -class DocSimpleSectSep : public DocNode -{ - public: - DocSimpleSectSep(DocParser &parser,DocNode *parent) : DocNode(parser) { m_parent = parent; } - Kind kind() const override { return Kind_SimpleSectSep; } - void accept(DocVisitor *v) override { v->visit(this); } - - private: -}; - -/** Node representing a parameter section */ -class DocParamSect : public CompAccept<DocParamSect> -{ - friend class DocParamList; - public: - enum Type - { - Unknown, Param, RetVal, Exception, TemplateParam - }; - enum Direction - { - In=1, Out=2, InOut=3, Unspecified=0 - }; - DocParamSect(DocParser &parser,DocNode *parent,Type t) - : CompAccept<DocParamSect>(parser), m_type(t), m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE) - { m_parent = parent; } - int parse(const QCString &cmdName,bool xmlContext,Direction d); - Kind kind() const override { return Kind_ParamSect; } - Type type() const { return m_type; } - bool hasInOutSpecifier() const { return m_hasInOutSpecifier; } - bool hasTypeSpecifier() const { return m_hasTypeSpecifier; } - - private: - Type m_type = Unknown; - bool m_hasInOutSpecifier = false; - bool m_hasTypeSpecifier = false; -}; - -/** Node representing a paragraph in the documentation tree */ -class DocPara : public CompAccept<DocPara> -{ - public: - DocPara(DocParser &parser,DocNode *parent) : - CompAccept<DocPara>(parser), m_isFirst(FALSE), m_isLast(FALSE) { m_parent = parent; } - int parse(); - Kind kind() const override { return Kind_Para; } - bool isEmpty() const { return m_children.empty(); } - void markFirst(bool v=TRUE) { m_isFirst=v; } - void markLast(bool v=TRUE) { m_isLast=v; } - bool isFirst() const { return m_isFirst; } - bool isLast() const { return m_isLast; } - - int handleCommand(const QCString &cmdName,const int tok); - int handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs); - int handleHtmlEndTag(const QCString &tagName); - int handleSimpleSection(DocSimpleSect::Type t,bool xmlContext=FALSE); - int handleXRefItem(); - int handleParamSection(const QCString &cmdName,DocParamSect::Type t, - bool xmlContext, - int direction); - void handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t); - void handleImage(const QCString &cmdName); - template<class T> void handleFile(const QCString &cmdName); - void handleInclude(const QCString &cmdName,DocInclude::Type t); - void handleLink(const QCString &cmdName,bool isJavaLink); - void handleCite(); - void handleEmoji(); - void handleRef(const QCString &cmdName); - void handleSection(const QCString &cmdName); - void handleInheritDoc(); - void handleVhdlFlow(); - void handleIline(); - int handleStartCode(); - int handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level); - - bool injectToken(int tok,const QCString &tokText); - const HtmlAttribList &attribs() const { return m_attribs; } - void setAttribs(const HtmlAttribList &attribs) { m_attribs = attribs; } - - private: - QCString m_sectionId; - bool m_isFirst = false; - bool m_isLast = false; - HtmlAttribList m_attribs; -}; - -using DocParaList = std::vector< std::unique_ptr<DocPara> >; - -/** Node representing a parameter list. */ -class DocParamList : public DocNode -{ - public: - DocParamList(DocParser &parser,DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d) - : DocNode(parser), m_type(t), m_dir(d) - { - m_parent = parent; - } - virtual ~DocParamList() { } - Kind kind() const override { return Kind_ParamList; } - DocNodeList ¶meters() { return m_params; } - DocNodeList ¶mTypes() { return m_paramTypes; } - DocParamSect::Type type() const { return m_type; } - DocParamSect::Direction direction() const { return m_dir; } - void markFirst(bool b=TRUE) { m_isFirst=b; } - void markLast(bool b=TRUE) { m_isLast=b; } - bool isFirst() const { return m_isFirst; } - bool isLast() const { return m_isLast; } - void accept(DocVisitor *v) override - { - v->visitPre(this); - for (const auto &n : m_paragraphs) n->accept(v); - v->visitPost(this); - } - int parse(const QCString &cmdName); - int parseXml(const QCString ¶mName); - - private: - DocParaList m_paragraphs; - DocNodeList m_params; - DocNodeList m_paramTypes; - DocParamSect::Type m_type = DocParamSect::Unknown; - DocParamSect::Direction m_dir = DocParamSect::Unspecified; - bool m_isFirst = false; - bool m_isLast = false; -}; - -/** Node representing a simple list item */ -class DocSimpleListItem : public DocNode -{ - public: - DocSimpleListItem(DocParser &parser,DocNode *parent) : - DocNode(parser) { m_paragraph=new DocPara(parser,this); m_parent = parent; } - int parse(); - virtual ~DocSimpleListItem() { delete m_paragraph; } - Kind kind() const override { return Kind_SimpleListItem; } - void accept(DocVisitor *v) override - { - v->visitPre(this); - m_paragraph->accept(v); - v->visitPost(this); - } - - private: - DocPara *m_paragraph = 0; -}; - -/** Node representing a HTML list item */ -class DocHtmlListItem : public CompAccept<DocHtmlListItem> -{ - public: - DocHtmlListItem(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,int num) : - CompAccept<DocHtmlListItem>(parser), m_attribs(attribs), m_itemNum(num) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlListItem; } - int itemNumber() const { return m_itemNum; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - int parseXml(); - - private: - HtmlAttribList m_attribs; - int m_itemNum = 0; -}; - -/** Node representing a HTML description data */ -class DocHtmlDescData : public CompAccept<DocHtmlDescData> -{ - public: - DocHtmlDescData(DocParser &parser,DocNode *parent) : CompAccept<DocHtmlDescData>(parser) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlDescData; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - - private: - HtmlAttribList m_attribs; -}; - -/** Node representing a HTML table cell */ -class DocHtmlCell : public CompAccept<DocHtmlCell> -{ - friend class DocHtmlTable; - public: - enum Alignment { Left, Right, Center }; - enum Valignment {Top, Middle, Bottom}; - DocHtmlCell(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,bool isHeading) : - CompAccept<DocHtmlCell>(parser), m_isHeading(isHeading), m_attribs(attribs) { m_parent = parent; } - bool isHeading() const { return m_isHeading; } - bool isFirst() const { return m_isFirst; } - bool isLast() const { return m_isLast; } - Kind kind() const override { return Kind_HtmlCell; } - void markFirst(bool v=TRUE) { m_isFirst=v; } - void markLast(bool v=TRUE) { m_isLast=v; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - int parseXml(); - uint rowIndex() const { return m_rowIdx; } - uint columnIndex() const { return m_colIdx; } - uint rowSpan() const; - uint colSpan() const; - Alignment alignment() const; - Valignment valignment() const; - - private: - void setRowIndex(uint idx) { m_rowIdx = idx; } - void setColumnIndex(uint idx) { m_colIdx = idx; } - bool m_isHeading = false; - bool m_isFirst = false; - bool m_isLast = false; - HtmlAttribList m_attribs; - uint m_rowIdx = (uint)-1; - uint m_colIdx = (uint)-1; -}; - -/** Node representing a HTML table caption */ -class DocHtmlCaption : public CompAccept<DocHtmlCaption> -{ - public: - DocHtmlCaption(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs); - Kind kind() const override { return Kind_HtmlCaption; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - bool hasCaptionId() const { return m_hasCaptionId; } - QCString file() const { return m_file; } - QCString anchor() const { return m_anchor; } - - private: - HtmlAttribList m_attribs; - bool m_hasCaptionId = false; - QCString m_file; - QCString m_anchor; -}; - -/** Node representing a HTML table row */ -class DocHtmlRow : public CompAccept<DocHtmlRow> -{ - friend class DocHtmlTable; - public: - DocHtmlRow(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) - : CompAccept<DocHtmlRow>(parser), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlRow; } - size_t numCells() const { return m_children.size(); } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - int parseXml(bool header); - bool isHeading() const { // a row is a table heading if all cells are marked as such - bool heading=TRUE; - for (const auto &n : m_children) - { - if (n->kind()==Kind_HtmlCell) - { - heading = heading && ((DocHtmlCell*)n.get())->isHeading(); - } - } - return !m_children.empty() && heading; - } - void setVisibleCells(uint n) { m_visibleCells = n; } - uint visibleCells() const { return m_visibleCells; } - uint rowIndex() const { return m_rowIdx; } - - private: - void setRowIndex(uint idx) { m_rowIdx = idx; } - HtmlAttribList m_attribs; - uint m_visibleCells = 0; - uint m_rowIdx = (uint)-1; -}; - -/** Node representing a HTML table */ -class DocHtmlTable : public CompAccept<DocHtmlTable> -{ - public: - DocHtmlTable(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) - : CompAccept<DocHtmlTable>(parser), m_attribs(attribs) { m_caption=0; m_numCols=0; m_parent = parent; } - ~DocHtmlTable() { delete m_caption; } - Kind kind() const override { return Kind_HtmlTable; } - size_t numRows() const { return m_children.size(); } - bool hasCaption() { return m_caption!=0; } - const HtmlAttribList &attribs() const { return m_attribs; } - int parse(); - int parseXml(); - size_t numColumns() const { return m_numCols; } - void accept(DocVisitor *v) override; - DocHtmlCaption *caption() const { return m_caption; } - DocHtmlRow *firstRow() const { - return (!m_children.empty() && m_children.front()->kind()==Kind_HtmlRow) ? - (DocHtmlRow*)m_children.front().get() : 0; - } - - private: - void computeTableGrid(); - DocHtmlCaption *m_caption = 0; - HtmlAttribList m_attribs; - size_t m_numCols = 0; -}; - -/** Node representing an HTML blockquote */ -class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote> -{ - public: - DocHtmlBlockQuote(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) - : CompAccept<DocHtmlBlockQuote>(parser), m_attribs(attribs) { m_parent = parent; } - Kind kind() const override { return Kind_HtmlBlockQuote; } - int parse(); - const HtmlAttribList &attribs() const { return m_attribs; } - - private: - HtmlAttribList m_attribs; -}; - -/** Root node of a text fragment */ -class DocText : public CompAccept<DocText> -{ - public: - DocText(DocParser &parser) : CompAccept<DocText>(parser) {} - Kind kind() const override { return Kind_Text; } - void parse(); - bool isEmpty() const { return m_children.empty(); } -}; - -/** Root node of documentation tree */ -class DocRoot : public CompAccept<DocRoot> -{ - public: - DocRoot(DocParser &parser,bool indent,bool sl) : CompAccept<DocRoot>(parser), m_indent(indent), m_singleLine(sl) {} - Kind kind() const override { return Kind_Root; } - void parse(); - bool indent() const { return m_indent; } - bool singleLine() const { return m_singleLine; } - bool isEmpty() const { return m_children.empty(); } - - private: - bool m_indent = false; - bool m_singleLine = false; -}; +void docFindSections(const QCString &input, + const Definition *d, + const QCString &fileName); #endif diff --git a/src/docparser_p.h b/src/docparser_p.h new file mode 100644 index 0000000..3eca1ae --- /dev/null +++ b/src/docparser_p.h @@ -0,0 +1,249 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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 DOCPARSER_P_H +#define DOCPARSER_P_H + +/** @file + * @brief Private header shared between docparser.cpp and docnode.cpp + */ + +#include <cassert> +#include <stack> +#include <iterator> +#include <vector> +#include <deque> + +#include "containers.h" +#include "docparser.h" +#include "docnode.h" +#include "doctokenizer.h" +#include "searchindex.h" + +using DefinitionStack = std::vector<const Definition *>; +using DocNodeStack = std::stack<DocNodeVariant *>; + +template<typename T, typename Container = std::deque<T>> +class IterableStack : public std::stack<T, Container> +{ + using std::stack<T, Container>::c; + +public: + + // expose just the iterators of the underlying container + auto begin() { return std::begin(c); } + auto end() { return std::end(c); } + + auto begin() const { return std::begin(c); } + auto end() const { return std::end(c); } +}; +using DocStyleChangeStack = IterableStack<const DocNodeVariant *>; + +/** Parser's context to store all global variables. + */ +struct DocParserContext +{ + const Definition *scope; + QCString context; + bool inSeeBlock; + bool xmlComment; + bool insideHtmlLink; + DocNodeStack nodeStack; + DocStyleChangeStack styleStack; + DocStyleChangeStack initialStyleStack; + DefinitionStack copyStack; + QCString fileName; + QCString relPath; + + bool hasParamCommand; + bool hasReturnCommand; + StringMultiSet retvalsFound; + StringMultiSet paramsFound; + const MemberDef * memberDef; + bool isExample; + QCString exampleName; + QCString searchUrl; + + QCString includeFileName; + QCString includeFileText; + uint includeFileOffset; + uint includeFileLength; + int includeFileLine; + bool includeFileShowLineNo; + + TokenInfo *token; + int lineNo; + bool markdownSupport; +}; + +class DocParser : public IDocParser +{ + public: + ~DocParser(); + void pushContext(); + void popContext(); + void handleImg(DocNodeVariant *parent,DocNodeList &children,const HtmlAttribList &tagHtmlAttribs); + int internalValidatingParseDoc(DocNodeVariant *parent,DocNodeList &children, + const QCString &doc); + QCString processCopyDoc(const char *data,uint &len); + QCString findAndCopyImage(const QCString &fileName,DocImage::Type type, bool doWarn = true); + void checkArgumentName(); + void checkRetvalName(); + void checkUnOrMultipleDocumentedParams(); + bool findDocsForMemberOrCompound(const QCString &commandName, + QCString *pDoc, + QCString *pBrief, + const Definition **pDef); + bool defaultHandleToken(DocNodeVariant *parent,int tok, + DocNodeList &children,bool + handleWord=TRUE); + void errorHandleDefaultToken(DocNodeVariant *parent,int tok, + DocNodeList &children,const QCString &txt); + void defaultHandleTitleAndSize(const int cmd, DocNodeVariant *parent, + DocNodeList &children, QCString &width,QCString &height); + int handleStyleArgument(DocNodeVariant *parent,DocNodeList &children, + const QCString &cmdName); + void handleStyleEnter(DocNodeVariant *parent,DocNodeList &children, DocStyleChange::Style s, + const QCString &tagName,const HtmlAttribList *attribs); + void handleStyleLeave(DocNodeVariant *parent,DocNodeList &children, DocStyleChange::Style s, + const QCString &tagName); + void handlePendingStyleCommands(DocNodeVariant *parent,DocNodeList &children); + void handleInitialStyleCommands(DocNodeVariant *parent,DocNodeList &children); + int handleAHref(DocNodeVariant *parent,DocNodeList &children,const HtmlAttribList &tagHtmlAttribs); + void handleUnclosedStyleCommands(); + void handleLinkedWord(DocNodeVariant *parent,DocNodeList &children,bool ignoreAutoLinkFlag=FALSE); + void handleParameterType(DocNodeVariant *parent,DocNodeList &children,const QCString ¶mTypes); + void handleInternalRef(DocNodeVariant *parent,DocNodeList &children); + void handleAnchor(DocNodeVariant *parent,DocNodeList &children); + void handleImage(DocNodeVariant *parent, DocNodeList &children); + void readTextFileByName(const QCString &file,QCString &text); + + std::stack< DocParserContext > contextStack; + DocParserContext context; + DocTokenizer tokenizer; + SIDataCollection searchData; +}; + +//--------------------------------------------------------------------------- + +class AutoNodeStack +{ + public: + AutoNodeStack(DocParser *parser,DocNodeVariant* node) + : m_parser(parser), m_node(node) { m_parser->context.nodeStack.push(node); } + ~AutoNodeStack() { +#if defined(NDEBUG) + (void)m_node; + if (!m_parser->context.nodeStack.empty()) + { + m_parser->context.nodeStack.pop(); // robust version that does not assert + } +#else + assert(m_parser->context.nodeStack.top()==m_node); + m_parser->context.nodeStack.pop(); // error checking version +#endif + } + + private: + DocParser *m_parser; + const DocNodeVariant *m_node; +}; + +inline bool isPreformatted(const DocNodeVariant *n) +{ + return std::visit([](auto &&x)->decltype(auto) { return x.isPreformatted(); }, *n); +} + +/*! Returns TRUE iff node n is a child of a preformatted node */ +inline bool insidePRE(const DocNodeVariant *n) +{ + while (n) + { + if (isPreformatted(n)) return TRUE; + n=parent(n); + } + return FALSE; +} + +/*! Returns TRUE iff node n is a child of a html list item node */ +inline bool insideLI(const DocNodeVariant *n) +{ + while (n) + { + if (std::holds_alternative<DocHtmlListItem>(*n)) return TRUE; + n=parent(n); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a unordered html list node */ +inline bool insideUL(const DocNodeVariant *n) +{ + while (n) + { + if (std::holds_alternative<DocHtmlList>(*n) && + std::get<DocHtmlList>(*n).type()==DocHtmlList::Unordered) + { + return TRUE; + } + n=parent(n); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a ordered html list node */ +inline bool insideOL(const DocNodeVariant *n) +{ + while (n) + { + if (std::holds_alternative<DocHtmlList>(*n) && + std::get<DocHtmlList>(*n).type()==DocHtmlList::Ordered) + { + return TRUE; + } + n=parent(n); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +inline bool insideTable(const DocNodeVariant *n) +{ + while (n) + { + if (std::holds_alternative<DocHtmlTable>(*n)) return TRUE; + n=parent(n); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +inline bool insideDetails(DocStyleChangeStack styleStack) +{ + for (auto i : styleStack) + { + if (std::get<DocStyleChange>(*i).style() == DocStyleChange::Details) return true; + } + return false; +} + + +#endif diff --git a/src/docsets.cpp b/src/docsets.cpp index a18ac82..bc8f7a9 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -415,14 +415,10 @@ void DocSets::addIndexItem(const Definition *context,const MemberDef *md, { scope = nd->name(); } - const MemberDef *declMd = md->memberDeclaration(); - if (declMd==0) declMd = md; + fd = md->getFileDef(); + if (fd) { - fd = md->getFileDef(); - if (fd) - { - decl = fd->name(); - } + decl = fd->name(); } writeToken(p->tts,md,type,lang,scope,md->anchor(),decl); } diff --git a/src/doctokenizer.h b/src/doctokenizer.h index 43e4092..1c31920 100644 --- a/src/doctokenizer.h +++ b/src/doctokenizer.h @@ -66,6 +66,8 @@ enum Tokens RetVal_EndParBlock = 0x10017 }; +#define TK_COMMAND_CHAR(token) ((token)==TK_COMMAND_AT ? "@" : "\\") + /** @brief Data associated with a token used by the comment block parser. */ struct TokenInfo { diff --git a/src/doctokenizer.l b/src/doctokenizer.l index f5ccc19..976f1dc 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -177,7 +177,7 @@ static int computeIndent(const char *str,size_t length) if (str==0 || length==std::string::npos) return 0; size_t i; int indent=0; - static int tabSize=Config_getInt(TAB_SIZE); + int tabSize=Config_getInt(TAB_SIZE); for (i=0;i<length;i++) { if (str[i]=='\t') @@ -279,8 +279,8 @@ ATTRIB {ATTRNAME}{WS}*("="{WS}*(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'">< URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=\x80-\xFF] URLMASK ({URLCHAR}+([({]{URLCHAR}*[)}])?)+ URLPROTOCOL ("http:"|"https:"|"ftp:"|"ftps:"|"sftp:"|"file:"|"news:"|"irc:"|"ircs:") -FILEICHAR [a-z_A-Z0-9\\:\\\/\-\+&#@] -FILEECHAR [a-z_A-Z0-9\-\+&#@] +FILEICHAR [a-z_A-Z0-9\\:\\\/\-\+=&#@] +FILEECHAR [a-z_A-Z0-9\-\+=&#@] FILECHARS {FILEICHAR}*{FILEECHAR}+ HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}* VFILEMASK {FILECHARS}("."{FILECHARS})* @@ -1234,6 +1234,7 @@ LINENR {BLANK}*[1-9][0-9]* return TK_WORD; } <St_Emoji>. { + unput(*yytext); return 0; } <St_Iline>{LINENR}/[\n\.] | diff --git a/src/docvisitor.cpp b/src/docvisitor.cpp index 506c9f8..58c93b2 100644 --- a/src/docvisitor.cpp +++ b/src/docvisitor.cpp @@ -29,9 +29,8 @@ struct DocVisitor::Private std::stack<bool> hidden; }; -DocVisitor::DocVisitor(int id) : m_p(std::make_unique<Private>()) +DocVisitor::DocVisitor() : m_p(std::make_unique<Private>()) { - m_p->id = id; } DocVisitor::~DocVisitor() @@ -54,11 +53,6 @@ CodeParserInterface &DocVisitor::getCodeParser(const QCString &extension) return *it->second.get(); } -int DocVisitor::id() const -{ - return m_p->id; -} - void DocVisitor::pushHidden(bool hide) { m_p->hidden.push(hide); diff --git a/src/docvisitor.h b/src/docvisitor.h index caf9862..57fc556 100644 --- a/src/docvisitor.h +++ b/src/docvisitor.h @@ -20,187 +20,22 @@ #include "qcstring.h" -// ids -const int DocVisitor_Html = 0; -const int DocVisitor_Latex = 1; -const int DocVisitor_XML = 2; -const int DocVisitor_RTF = 3; -const int DocVisitor_Man = 4; -const int DocVisitor_Text = 5; -const int DocVisitor_Other = 6; -const int DocVisitor_Docbook = 7; - -// forward declarations -class DocWord; -class DocWhiteSpace; -class DocAutoList; -class DocAutoListItem; -class DocPara; -class DocRoot; -class DocSymbol; -class DocEmoji; -class DocURL; -class DocStyleChange; -class DocSimpleSect; -class DocTitle; -class DocSimpleList; -class DocSimpleListItem; -class DocSection; -class DocVerbatim; -class DocXRefItem; -class DocHtmlList; -class DocHtmlListItem; -class DocHtmlDescList; -class DocHtmlDescTitle; -class DocHtmlDescData; -class DocHtmlTable; -class DocHtmlRow; -class DocHtmlCell; -class DocHtmlCaption; -class DocLineBreak; -class DocHorRuler; -class DocAnchor; -class DocIndexEntry; -class DocInternal; -class DocHRef; -class DocInclude; -class DocIncOperator; -class DocHtmlHeader; -class DocImage; -class DocDotFile; -class DocMscFile; -class DocDiaFile; -class DocLink; -class DocCite; -class DocRef; -class DocFormula; -class DocSecRefItem; -class DocSecRefList; -class DocLinkedWord; -class DocParamSect; -class DocParamList; -class DocInternalRef; -class DocText; -class DocSimpleSectSep; -class DocHtmlBlockQuote; -class DocVhdlFlow; -class DocParBlock; class CodeParserInterface; -/*! @brief Abstract visitor that participates in the visitor pattern. +/*! @brief Helper base class for functionality shared by all visitors */ class DocVisitor { struct Private; std::unique_ptr<Private> m_p; public: - DocVisitor(int id); + DocVisitor(); virtual ~DocVisitor(); - int id() const; CodeParserInterface &getCodeParser(const QCString &langExt); void pushHidden(bool hide); bool popHidden(); +}; - /*! @name Visitor functions for leaf nodes - * @{ - */ - virtual void visit(DocWord *) = 0; - virtual void visit(DocWhiteSpace *) = 0; - virtual void visit(DocSymbol *) = 0; - virtual void visit(DocEmoji *) = 0; - virtual void visit(DocURL *) = 0; - virtual void visit(DocStyleChange *) = 0; - virtual void visit(DocVerbatim *) = 0; - virtual void visit(DocLineBreak *) = 0; - virtual void visit(DocHorRuler *) = 0; - virtual void visit(DocAnchor *) = 0; - virtual void visit(DocInclude *) = 0; - virtual void visit(DocIncOperator *) = 0; - virtual void visit(DocFormula *) = 0; - virtual void visit(DocLinkedWord *) = 0; - virtual void visit(DocIndexEntry *) = 0; - virtual void visit(DocSimpleSectSep *) = 0; - virtual void visit(DocCite *) = 0; - /*! @} */ - /*! @name Visitor functions for internal nodes - * @{ - */ - virtual void visitPre(DocAutoList *) = 0; - virtual void visitPost(DocAutoList *) = 0; - virtual void visitPre(DocAutoListItem *) = 0; - virtual void visitPost(DocAutoListItem *) = 0; - virtual void visitPre(DocPara *) = 0; - virtual void visitPost(DocPara *) = 0; - virtual void visitPre(DocRoot *) = 0; - virtual void visitPost(DocRoot *) = 0; - virtual void visitPre(DocSimpleSect *) = 0; - virtual void visitPost(DocSimpleSect *) = 0; - virtual void visitPre(DocTitle *) = 0; - virtual void visitPost(DocTitle *) = 0; - virtual void visitPre(DocSimpleList *) = 0; - virtual void visitPost(DocSimpleList *) = 0; - virtual void visitPre(DocSimpleListItem *) = 0; - virtual void visitPost(DocSimpleListItem *) = 0; - virtual void visitPre(DocSection *) = 0; - virtual void visitPost(DocSection *) = 0; - virtual void visitPre(DocHtmlList *) = 0; - virtual void visitPost(DocHtmlListItem *) = 0; - virtual void visitPre(DocHtmlListItem *) = 0; - virtual void visitPost(DocHtmlList *) = 0; - virtual void visitPre(DocHtmlDescList *) = 0; - virtual void visitPost(DocHtmlDescList *) = 0; - virtual void visitPre(DocHtmlDescTitle *) = 0; - virtual void visitPost(DocHtmlDescTitle *) = 0; - virtual void visitPre(DocHtmlDescData *) = 0; - virtual void visitPost(DocHtmlDescData *) = 0; - virtual void visitPre(DocHtmlTable *) = 0; - virtual void visitPost(DocHtmlRow *) = 0; - virtual void visitPre(DocHtmlCell *) = 0; - virtual void visitPost(DocHtmlCell *) = 0; - virtual void visitPre(DocHtmlRow *) = 0; - virtual void visitPost(DocHtmlTable *) = 0; - virtual void visitPre(DocHtmlCaption *) = 0; - virtual void visitPost(DocHtmlCaption *) = 0; - virtual void visitPre(DocInternal *) = 0; - virtual void visitPost(DocInternal *) = 0; - virtual void visitPre(DocHRef *) = 0; - virtual void visitPost(DocHRef *) = 0; - virtual void visitPre(DocHtmlHeader *) = 0; - virtual void visitPost(DocHtmlHeader *) = 0; - virtual void visitPre(DocImage *) = 0; - virtual void visitPost(DocImage *) = 0; - virtual void visitPre(DocDotFile *) = 0; - virtual void visitPost(DocDotFile *) = 0; - virtual void visitPre(DocMscFile *) = 0; - virtual void visitPost(DocMscFile *) = 0; - virtual void visitPre(DocDiaFile *) = 0; - virtual void visitPost(DocDiaFile *) = 0; - virtual void visitPre(DocLink *) = 0; - virtual void visitPost(DocLink *) = 0; - virtual void visitPre(DocRef *) = 0; - virtual void visitPost(DocRef *) = 0; - virtual void visitPre(DocSecRefItem *) = 0; - virtual void visitPost(DocSecRefItem *) = 0; - virtual void visitPre(DocSecRefList *) = 0; - virtual void visitPost(DocSecRefList *) = 0; - virtual void visitPre(DocParamSect *) = 0; - virtual void visitPost(DocParamSect *) = 0; - virtual void visitPre(DocParamList *) = 0; - virtual void visitPost(DocParamList *) = 0; - virtual void visitPre(DocXRefItem *) = 0; - virtual void visitPost(DocXRefItem *) = 0; - virtual void visitPre(DocInternalRef *) = 0; - virtual void visitPost(DocInternalRef *) = 0; - virtual void visitPre(DocText *) = 0; - virtual void visitPost(DocText *) = 0; - virtual void visitPre(DocHtmlBlockQuote *) = 0; - virtual void visitPost(DocHtmlBlockQuote *) = 0; - virtual void visitPre(DocVhdlFlow *) = 0; - virtual void visitPost(DocVhdlFlow *) = 0; - virtual void visitPre(DocParBlock *) = 0; - virtual void visitPost(DocParBlock *) = 0; - /*! @} */ -}; #endif diff --git a/src/dot.cpp b/src/dot.cpp index e42b73d..1d44dd9 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -17,6 +17,7 @@ #include <cassert> #include <sstream> #include <algorithm> +#include <mutex> #include "config.h" #include "dot.h" @@ -36,6 +37,8 @@ static QCString g_dotFontPath; +static std::mutex g_dotManagerMutex; + static void setDotFontPath(const QCString &path) { ASSERT(g_dotFontPath.isEmpty()); @@ -72,21 +75,10 @@ static void unsetDotFontPath() //-------------------------------------------------------------------- -DotManager *DotManager::m_theInstance = 0; - DotManager *DotManager::instance() { - if (!m_theInstance) - { - m_theInstance = new DotManager; - } - return m_theInstance; -} - -void DotManager::deleteInstance() -{ - delete m_theInstance; - m_theInstance=0; + static DotManager theInstance; + return &theInstance; } DotManager::DotManager() : m_runners(), m_filePatchers() @@ -98,7 +90,7 @@ DotManager::DotManager() : m_runners(), m_filePatchers() { for (i=0;i<dotNumThreads;i++) { - std::unique_ptr<DotWorkerThread> thread = std::make_unique<DotWorkerThread>(m_queue); + DotWorkerThreadPtr thread(new DotWorkerThread(m_queue)); thread->start(); if (thread->isRunning()) { @@ -114,11 +106,12 @@ DotManager::DotManager() : m_runners(), m_filePatchers() DotManager::~DotManager() { - delete m_queue; + if (!Doxygen::terminating) delete m_queue; } DotRunner* DotManager::createRunner(const QCString &absDotName, const QCString& md5Hash) { + std::lock_guard<std::mutex> lock(g_dotManagerMutex); DotRunner* rv = nullptr; auto const runit = m_runners.find(absDotName.str()); if (runit == m_runners.end()) @@ -142,6 +135,7 @@ DotRunner* DotManager::createRunner(const QCString &absDotName, const QCString& DotFilePatcher *DotManager::createFilePatcher(const QCString &fileName) { + std::lock_guard<std::mutex> lock(g_dotManagerMutex); auto patcher = m_filePatchers.find(fileName.str()); if (patcher != m_filePatchers.end()) return &(patcher->second); @@ -280,7 +274,7 @@ void writeDotGraphFromFile(const QCString &inFile,const QCString &outDir, } QCString imgExt = getDotImageExtension(); - QCString imgName = (QCString)outFile+"."+imgExt; + QCString imgName = QCString(outFile)+"."+imgExt; QCString absImgName = QCString(d.absPath())+"/"+imgName; QCString absOutFile = QCString(d.absPath())+"/"+outFile; @@ -22,17 +22,20 @@ #include "dotgraph.h" // only for GraphOutputFormat #include "dotfilepatcher.h" #include "dotrunner.h" +#include "doxygen.h" class DotRunner; class DotRunnerQueue; class TextStream; +using DotWorkerThreadPtr = std::unique_ptr< DotWorkerThread, NonTerminatingDeleter<DotWorkerThread > >; + /** Singleton that manages parallel dot invocations and patching files for embedding image maps */ class DotManager { public: static DotManager *instance(); - static void deleteInstance(); + //static void deleteInstance(); DotRunner* createRunner(const QCString& absDotName, const QCString& md5Hash); DotFilePatcher *createFilePatcher(const QCString &fileName); bool run() const; @@ -41,11 +44,10 @@ class DotManager DotManager(); virtual ~DotManager(); - std::map<std::string, std::unique_ptr<DotRunner>> m_runners; - std::map<std::string, DotFilePatcher> m_filePatchers; - static DotManager *m_theInstance; - DotRunnerQueue *m_queue; - std::vector< std::unique_ptr<DotWorkerThread> > m_workers; + std::map<std::string, std::unique_ptr<DotRunner> > m_runners; + std::map<std::string, DotFilePatcher> m_filePatchers; + DotRunnerQueue *m_queue; + std::vector< DotWorkerThreadPtr > m_workers; }; void writeDotGraphFromFile(const QCString &inFile,const QCString &outDir, diff --git a/src/dotcallgraph.cpp b/src/dotcallgraph.cpp index f18834a..5611551 100644 --- a/src/dotcallgraph.cpp +++ b/src/dotcallgraph.cpp @@ -189,6 +189,8 @@ QCString DotCallGraph::writeGraph( const QCString &relPath,bool generateImageMap, int graphId) { + m_doNotAddImageToIndex = textFormat!=EOF_Html; + return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); } @@ -204,7 +206,7 @@ bool DotCallGraph::isTooBig() const int DotCallGraph::numNodes() const { - return (int)m_startNode->children().size(); + return static_cast<int>(m_startNode->children().size()); } bool DotCallGraph::isTrivial(const MemberDef *md,bool inverse) diff --git a/src/dotclassgraph.cpp b/src/dotclassgraph.cpp index 1bbe4de..e9d0bb8 100644 --- a/src/dotclassgraph.cpp +++ b/src/dotclassgraph.cpp @@ -147,8 +147,8 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, { DotNodeDeque childQueue; DotNodeDeque parentQueue; - IntVector childTreeWidth; - IntVector parentTreeWidth; + std::vector<size_t> childTreeWidth; + std::vector<size_t> parentTreeWidth; childQueue.push_back(rootNode); if (includeParents) parentQueue.push_back(rootNode); bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop @@ -159,16 +159,16 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, { DotNode *n = childQueue.front(); childQueue.pop_front(); - int distance = n->distance(); - if (!n->isVisible() && distance<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed + size_t distance = n->distance(); + if (!n->isVisible() && distance<=static_cast<size_t>(Config_getInt(MAX_DOT_GRAPH_DEPTH))) // not yet processed { if (distance>0) { - int oldSize=(int)childTreeWidth.size(); + size_t oldSize=childTreeWidth.size(); if (distance>oldSize) { - childTreeWidth.resize(std::max(childTreeWidth.size(),(size_t)distance)); - int i; for (i=oldSize;i<distance;i++) childTreeWidth[i]=0; + childTreeWidth.resize(std::max(childTreeWidth.size(),distance)); + for (size_t i=oldSize;i<distance;i++) childTreeWidth[i]=0; } childTreeWidth[distance-1]+=n->label().length(); } @@ -188,14 +188,14 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, if ((!n->isVisible() || firstNode) && n->distance()<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed { firstNode=FALSE; - int distance = n->distance(); + size_t distance = n->distance(); if (distance>0) { - int oldSize = (int)parentTreeWidth.size(); + size_t oldSize = parentTreeWidth.size(); if (distance>oldSize) { - parentTreeWidth.resize(std::max(parentTreeWidth.size(),(size_t)distance)); - int i; for (i=oldSize;i<distance;i++) parentTreeWidth[i]=0; + parentTreeWidth.resize(std::max(parentTreeWidth.size(),distance)); + for (size_t i=oldSize;i<distance;i++) parentTreeWidth[i]=0; } parentTreeWidth[distance-1]+=n->label().length(); } @@ -210,14 +210,13 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, } } if (Config_getBool(UML_LOOK)) return FALSE; // UML graph are always top to bottom - int maxWidth=0; - int maxHeight=(int)std::max(childTreeWidth.size(),parentTreeWidth.size()); - uint i; - for (i=0;i<childTreeWidth.size();i++) + size_t maxWidth=0; + size_t maxHeight=std::max(childTreeWidth.size(),parentTreeWidth.size()); + for (size_t i=0;i<childTreeWidth.size();i++) { if (childTreeWidth.at(i)>maxWidth) maxWidth=childTreeWidth.at(i); } - for (i=0;i<parentTreeWidth.size();i++) + for (size_t i=0;i<parentTreeWidth.size();i++) { if (parentTreeWidth.at(i)>maxWidth) maxWidth=parentTreeWidth.at(i); } @@ -363,13 +362,13 @@ bool DotClassGraph::isTooBig() const int DotClassGraph::numNodes() const { - int numNodes = 0; - numNodes+= (int)m_startNode->children().size(); + size_t numNodes = 0; + numNodes+= m_startNode->children().size(); if (m_graphType==Inheritance) { - numNodes+= (int)m_startNode->parents().size(); + numNodes+= m_startNode->parents().size(); } - return numNodes; + return static_cast<int>(numNodes); } DotClassGraph::~DotClassGraph() diff --git a/src/dotdirdeps.cpp b/src/dotdirdeps.cpp index 27ba67c..4bc48fa 100644 --- a/src/dotdirdeps.cpp +++ b/src/dotdirdeps.cpp @@ -62,20 +62,20 @@ typedef std::vector< std::pair< std::unique_ptr<DirRelation>, bool> > DirRelatio /** Returns a DOT color name according to the directory depth. */ static QCString getDirectoryBackgroundColor(int depthIndex) { - static int hue = Config_getInt(HTML_COLORSTYLE_HUE); - static int sat = Config_getInt(HTML_COLORSTYLE_SAT); - static int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); + int hue = Config_getInt(HTML_COLORSTYLE_HUE); + int sat = Config_getInt(HTML_COLORSTYLE_SAT); + int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); assert(depthIndex>=0 && depthIndex<=Config_getInt(DIR_GRAPH_MAX_DEPTH)); - float fraction = (float)depthIndex/(float)Config_getInt(DIR_GRAPH_MAX_DEPTH); + float fraction = static_cast<float>(depthIndex)/static_cast<float>(Config_getInt(DIR_GRAPH_MAX_DEPTH)); const char hex[] = "0123456789abcdef"; int range = 0x40; // range from darkest color to lightest color - int luma = 0xef-(int)(fraction*range); // interpolation + int luma = 0xef-static_cast<int>(fraction*range); // interpolation double r,g,b; ColoredImage::hsl2rgb(hue/360.0,sat/255.0, pow(luma/255.0,gamma/100.0),&r,&g,&b); - int red = (int)(r*255.0); - int green = (int)(g*255.0); - int blue = (int)(b*255.0); + int red = static_cast<int>(r*255.0); + int green = static_cast<int>(g*255.0); + int blue = static_cast<int>(b*255.0); assert(red>=0 && red<=255); assert(green>=0 && green<=255); assert(blue>=0 && blue<=255); @@ -383,7 +383,7 @@ void writeDotDirDepGraph(TextStream &t,const DirDef *dd,bool linkRelations) size_t nrefs = udir->filePairs().size(); t << " " << dir->getOutputFileBase() << "->" << usedDir->getOutputFileBase(); - t << " [headlabel=\"" << (uint)nrefs << "\", labeldistance=1.5"; + t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5"; if (linkRelations) { t << " headhref=\"" << addHtmlExtensionIfMissing(relationName) << "\""; diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp index dcb3ecb..dc94299 100644 --- a/src/dotfilepatcher.cpp +++ b/src/dotfilepatcher.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "message.h" #include "docparser.h" +#include "docnode.h" #include "doxygen.h" #include "util.h" #include "dot.h" @@ -149,8 +150,10 @@ static QCString replaceRef(const QCString &buf,const QCString &relPath, { result=href+"=\""; // fake ref node to resolve the url - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRef> df { createRef( *parser.get(), link.mid(5), context ) }; + auto parser { createDocParser() }; + auto dfAst { createRef( *parser.get(), link.mid(5), context ) }; + auto dfAstImpl = dynamic_cast<const DocNodeAST*>(dfAst.get()); + const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root); result+=externalRef(relPath,df->ref(),TRUE); if (!df->file().isEmpty()) result += addHtmlExtensionIfMissing(df->file()); @@ -258,35 +261,35 @@ bool DotFilePatcher::isSVGFile() const int DotFilePatcher::addMap(const QCString &mapFile,const QCString &relPath, bool urlOnly,const QCString &context,const QCString &label) { - int id = (int)m_maps.size(); + size_t id = m_maps.size(); m_maps.emplace_back(mapFile,relPath,urlOnly,context,label); - return id; + return static_cast<int>(id); } int DotFilePatcher::addFigure(const QCString &baseName, const QCString &figureName,bool heightCheck) { - int id = (int)m_maps.size(); + size_t id = m_maps.size(); m_maps.emplace_back(figureName,"",heightCheck,"",baseName); - return id; + return static_cast<int>(id); } int DotFilePatcher::addSVGConversion(const QCString &relPath,bool urlOnly, const QCString &context,bool zoomable, int graphId) { - int id = (int)m_maps.size(); + size_t id = m_maps.size(); m_maps.emplace_back("",relPath,urlOnly,context,"",zoomable,graphId); - return id; + return static_cast<int>(id); } int DotFilePatcher::addSVGObject(const QCString &baseName, const QCString &absImgName, const QCString &relPath) { - int id = (int)m_maps.size(); + size_t id = m_maps.size(); m_maps.emplace_back(absImgName,relPath,false,"",baseName); - return id; + return static_cast<int>(id); } bool DotFilePatcher::run() const @@ -391,7 +394,7 @@ bool DotFilePatcher::run() const int mapId=-1; t << line.left(i); int n = sscanf(line.data()+i+1,"!-- SVG %d",&mapId); - if (n==1 && mapId>=0 && mapId<(int)m_maps.size()) + if (n==1 && mapId>=0 && mapId<static_cast<int>(m_maps.size())) { int e = std::max(line.find("--]"),line.find("-->")); const Map &map = m_maps.at(mapId); @@ -414,7 +417,7 @@ bool DotFilePatcher::run() const int mapId=-1; t << line.left(i); int n = sscanf(line.data()+i,"<!-- MAP %d",&mapId); - if (n==1 && mapId>=0 && mapId<(int)m_maps.size()) + if (n==1 && mapId>=0 && mapId<static_cast<int>(m_maps.size())) { TextStream tt; const Map &map = m_maps.at(mapId); @@ -439,7 +442,7 @@ bool DotFilePatcher::run() const int mapId=-1; int n = sscanf(line.data()+i+2,"FIG %d",&mapId); //printf("line='%s' n=%d\n",qPrint(line)+i,n); - if (n==1 && mapId>=0 && mapId<(int)m_maps.size()) + if (n==1 && mapId>=0 && mapId<static_cast<int>(m_maps.size())) { const Map &map = m_maps.at(mapId); //printf("patching FIG %d in file %s with contents of %s\n", diff --git a/src/dotgfxhierarchytable.cpp b/src/dotgfxhierarchytable.cpp index 1668761..ab923e4 100644 --- a/src/dotgfxhierarchytable.cpp +++ b/src/dotgfxhierarchytable.cpp @@ -182,7 +182,7 @@ void DotGfxHierarchyTable::addClassList(const ClassLinkedMap &cl,ClassDefSet &vi { //printf("Trying %s subClasses=%d\n",qPrint(cd->name()),cd->subClasses()->count()); if (cd->getLanguage()==SrcLangExt_VHDL && - (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS + VhdlDocGen::convert(cd->protection())!=VhdlDocGen::ENTITYCLASS ) { continue; diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp index f55a8d9..65ff967 100644 --- a/src/dotgraph.cpp +++ b/src/dotgraph.cpp @@ -14,6 +14,7 @@ */ #include <sstream> +#include <mutex> #include "config.h" #include "doxygen.h" @@ -108,6 +109,8 @@ QCString DotGraph::imgName() const ("." + getDotImageExtension()) : (Config_getBool(USE_PDFLATEX) ? ".pdf" : ".eps")); } +std::mutex g_dotIndexListMutex; + QCString DotGraph::writeGraph( TextStream& t, // output stream for the code file (html, ...) GraphOutputFormat gf, // bitmap(png/svg) or ps(eps/pdf) @@ -133,7 +136,11 @@ QCString DotGraph::writeGraph( m_regenerate = prepareDotFile(); - if (!m_doNotAddImageToIndex) Doxygen::indexList->addImageFile(imgName()); + if (!m_doNotAddImageToIndex) + { + std::lock_guard<std::mutex> lock(g_dotIndexListMutex); + Doxygen::indexList->addImageFile(imgName()); + } generateCode(t); @@ -150,7 +157,7 @@ bool DotGraph::prepareDotFile() char sigStr[33]; uchar md5_sig[16]; // calculate md5 - MD5Buffer((const unsigned char*)m_theGraph.data(), m_theGraph.length(), md5_sig); + MD5Buffer(m_theGraph.data(), m_theGraph.length(), md5_sig); // convert result to a string MD5SigToString(md5_sig, sigStr); diff --git a/src/dotgraph.h b/src/dotgraph.h index 2a77504..87d4165 100644 --- a/src/dotgraph.h +++ b/src/dotgraph.h @@ -34,7 +34,7 @@ class DotGraph public: DotGraph() : m_doNotAddImageToIndex(FALSE), m_noDivTag(FALSE), m_zoomable(TRUE), m_urlOnly(FALSE) {} - virtual ~DotGraph() {} + virtual ~DotGraph() = default; protected: /** returns node numbers. The Counter is reset by the constructor */ diff --git a/src/dotgroupcollaboration.cpp b/src/dotgroupcollaboration.cpp index 58dd75b..b72b525 100644 --- a/src/dotgroupcollaboration.cpp +++ b/src/dotgroupcollaboration.cpp @@ -244,7 +244,7 @@ QCString DotGroupCollaboration::writeGraph( TextStream &t, const QCString &path, const QCString &fileName, const QCString &relPath, bool generateImageMap,int graphId) { - m_doNotAddImageToIndex = TRUE; + m_doNotAddImageToIndex = textFormat!=EOF_Html; return DotGraph::writeGraph(t, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); } @@ -298,12 +298,12 @@ void DotGroupCollaboration::Edge::write( TextStream &t ) const } switch( eType ) { - case thierarchy: - arrowStyle = "dir=\"back\", style=\"solid\""; - break; - default: - t << ", color=\"" << linkTypeColor[(int)eType] << "\""; - break; + case thierarchy: + arrowStyle = "dir=\"back\", style=\"solid\""; + break; + default: + t << ", color=\"" << linkTypeColor[static_cast<int>(eType)] << "\""; + break; } t << ", " << arrowStyle; t << "];\n"; diff --git a/src/dotincldepgraph.cpp b/src/dotincldepgraph.cpp index 5a2f7ca..69aae60 100644 --- a/src/dotincldepgraph.cpp +++ b/src/dotincldepgraph.cpp @@ -205,7 +205,7 @@ bool DotInclDepGraph::isTooBig() const int DotInclDepGraph::numNodes() const { - return (int)m_startNode->children().size(); + return static_cast<int>(m_startNode->children().size()); } void DotInclDepGraph::writeXML(TextStream &t) diff --git a/src/dotnode.cpp b/src/dotnode.cpp index b91f111..beb0dc9 100644 --- a/src/dotnode.cpp +++ b/src/dotnode.cpp @@ -131,7 +131,7 @@ static void writeBoxMemberList(TextStream &t, } int count=0; - static auto dotUmlDetails = Config_getEnum(DOT_UML_DETAILS); + auto dotUmlDetails = Config_getEnum(DOT_UML_DETAILS); for (const auto &mma : *ml) { if (mma->getClassDef() == scope && @@ -392,7 +392,7 @@ void DotNode::writeBox(TextStream &t, { if (!ei.label().isEmpty()) // labels joined by \n { - int i=ei.label().find('\n'); + int i; int p=0; QCString lab; while ((i=ei.label().find('\n',p))!=-1) @@ -408,7 +408,7 @@ void DotNode::writeBox(TextStream &t, //printf("DotNode::writeBox for %s\n",qPrint(m_classDef->name())); t << "{" << convertLabel(m_label) << "\\n"; - static auto dotUmlDetails = Config_getEnum(DOT_UML_DETAILS); + auto dotUmlDetails = Config_getEnum(DOT_UML_DETAILS); if (dotUmlDetails!=DOT_UML_DETAILS_t::NONE) { t << "|"; @@ -471,15 +471,23 @@ void DotNode::writeBox(TextStream &t, } if (!m_url.isEmpty()) { - int anchorPos = m_url.findRev('#'); + int tagPos = m_url.findRev('$'); + t << ",URL=\""; + QCString noTagURL = m_url; + if (tagPos!=-1) + { + t << m_url.left(tagPos); + noTagURL = m_url.mid(tagPos); + } + int anchorPos = noTagURL.findRev('#'); if (anchorPos==-1) { - t << ",URL=\"" << addHtmlExtensionIfMissing(m_url) << "\""; + t << addHtmlExtensionIfMissing(noTagURL) << "\""; } else { - t << ",URL=\"" << addHtmlExtensionIfMissing(m_url.left(anchorPos)) - << m_url.right(m_url.length()-anchorPos) << "\""; + t << addHtmlExtensionIfMissing(noTagURL.left(anchorPos)) + << noTagURL.right(noTagURL.length()-anchorPos) << "\""; } } } diff --git a/src/dotrunner.cpp b/src/dotrunner.cpp index 0597a91..04eb452 100644 --- a/src/dotrunner.cpp +++ b/src/dotrunner.cpp @@ -22,6 +22,7 @@ #include "message.h" #include "config.h" #include "dir.h" +#include "doxygen.h" // the graphicx LaTeX has a limitation of maximum size of 16384 // To be on the save side we take it a little bit smaller i.e. 150 inch * 72 dpi @@ -107,7 +108,7 @@ static bool resetPDFSize(const int width,const int height, const QCString &base) bool DotRunner::readBoundingBox(const QCString &fileName,int *width,int *height,bool isEps) { const char *bb = isEps ? "%%PageBoundingBox:" : "/MediaBox ["; - int bblen = (int)strlen(bb); + size_t bblen = strlen(bb); FILE *f = Portable::fopen(fileName,"rb"); if (!f) { @@ -141,7 +142,7 @@ bool DotRunner::readBoundingBox(const QCString &fileName,int *width,int *height, DotRunner::DotRunner(const QCString& absDotName, const QCString& md5Hash) : m_file(absDotName) , m_md5Hash(md5Hash) - , m_dotExe(Config_getString(DOT_PATH)+"dot") + , m_dotExe(Doxygen::verifiedDotPath) , m_cleanUp(Config_getBool(DOT_CLEANUP)) { } @@ -159,7 +160,7 @@ void DotRunner::addJob(const QCString &format, const QCString &output, return; } auto args = QCString("-T") + format + " -o \"" + output + "\""; - m_jobs.emplace_back(format.str(), output, args, srcFile, srcLine); + m_jobs.emplace_back(format, output, args, srcFile, srcLine); } QCString getBaseNameOfOutput(const QCString &output) diff --git a/src/dotrunner.h b/src/dotrunner.h index 715d06f..035b34d 100644 --- a/src/dotrunner.h +++ b/src/dotrunner.h @@ -90,7 +90,7 @@ class DotWorkerThread ~DotWorkerThread(); void run(); void start(); - bool isRunning() { return m_thread && m_thread->joinable(); } + bool isRunning() const { return m_thread && m_thread->joinable(); } void wait() { m_thread->join(); } private: std::unique_ptr<std::thread> m_thread; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 4686fce..ab76f09 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -63,6 +63,7 @@ #include "commentcnv.h" #include "cmdmapper.h" #include "searchindex.h" +#include "searchindex_js.h" #include "parserintf.h" #include "htags.h" #include "pycode.h" @@ -165,6 +166,8 @@ QCString Doxygen::spaces; bool Doxygen::generatingXmlOutput = FALSE; DefinesPerFileList Doxygen::macroDefinitions; bool Doxygen::clangAssistedParsing = FALSE; +QCString Doxygen::verifiedDotPath; +volatile bool Doxygen::terminating = false; // locally accessible globals static std::multimap< std::string, const Entry* > g_classEntries; @@ -1068,7 +1071,7 @@ static void addClassToContext(const Entry *root) fullName,sec,tagName,refFileName,TRUE,root->spec&Entry::Enum) ))); if (cd) { - Debug::print(Debug::Classes,0," New class '%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p hidden=%d artificial=%d\n", + Debug::print(Debug::Classes,0," New class '%s' (sec=0x%08x)! #tArgLists=%zu tagInfo=%p hidden=%d artificial=%d\n", qPrint(fullName),sec,root->tArgLists.size(), tagInfo,root->hidden,root->artificial); cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -1229,7 +1232,7 @@ static void addConceptToContext(const Entry *root) qualifiedName,tagName,refFileName)))); if (cd) { - Debug::print(Debug::Classes,0," New concept '%s' #tArgLists=%d tagInfo=%p\n", + Debug::print(Debug::Classes,0," New concept '%s' #tArgLists=%zu tagInfo=%p\n", qPrint(qualifiedName),root->tArgLists.size(),tagInfo); cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -1451,7 +1454,7 @@ static void resolveClassNestingRelations() void distributeClassGroupRelations() { - //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); + //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); //if (!inlineGroupedClasses) return; //printf("** distributeClassGroupRelations()\n"); @@ -2058,7 +2061,7 @@ static void findUsingDeclarations(const Entry *root,bool filterPythonPackages) //printf("%s -> %p\n",qPrint(root->name),(void*)usingCd); if (usingCd==0) // definition not in the input => add an artificial class { - Debug::print(Debug::Classes,0," New using class '%s' (sec=0x%08x)! #tArgLists=%d\n", + Debug::print(Debug::Classes,0," New using class '%s' (sec=0x%08x)! #tArgLists=%zu\n", qPrint(name),root->section,root->tArgLists.size()); usingCd = toClassDefMutable( Doxygen::hiddenClassLinkedMap->add(name, @@ -2647,9 +2650,9 @@ static int findFunctionPtr(const std::string &type,SrcLangExt lang, int *pLength !(bb<i && i<be) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer ) { - if (pLength) *pLength=(int)l; + if (pLength) *pLength=static_cast<int>(l); //printf("findFunctionPtr=%d\n",(int)i); - return (int)i; + return static_cast<int>(i); } else { @@ -2789,7 +2792,7 @@ done: static void addVariable(const Entry *root,int isFuncPtr=-1) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); Debug::print(Debug::Variables,0, "VARIABLE_SEC: \n" @@ -2946,7 +2949,7 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) //int anonyScopes = 0; //bool added=FALSE; - static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); if (si!=-1 && !inlineSimpleStructs) // anonymous scope or type { QCString pScope; @@ -3170,7 +3173,7 @@ static void buildInterfaceAndServiceList(const Entry *root) { Debug::print(Debug::Functions,0, "EXPORTED_INTERFACE_SEC:\n" - " '%s' '%s'::'%s' '%s' relates='%s' relatesType='%d' file='%s' line='%d' bodyLine='%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n", + " '%s' '%s'::'%s' '%s' relates='%s' relatesType='%d' file='%s' line='%d' bodyLine='%d' #tArgLists=%zu mGrpId=%d spec=%lld proto=%d docFile=%s\n", qPrint(root->type), qPrint(root->parent()->name), qPrint(root->name), @@ -3429,6 +3432,7 @@ static void addGlobalFunction(const Entry *root,const QCString &rname,const QCSt scope+=sep; } + if (Config_getBool(HIDE_SCOPE_NAMES)) scope = ""; QCString def; //QCString optArgs = root->argList.empty() ? QCString() : root->args; if (!root->type.isEmpty()) @@ -3496,7 +3500,7 @@ static void buildFunctionList(const Entry *root) { Debug::print(Debug::Functions,0, "FUNCTION_SEC:\n" - " '%s' '%s'::'%s' '%s' relates='%s' relatesType='%d' file='%s' line='%d' bodyLine='%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n", + " '%s' '%s'::'%s' '%s' relates='%s' relatesType='%d' file='%s' line='%d' bodyLine='%d' #tArgLists=%zu mGrpId=%d spec=%lld proto=%d docFile=%s\n", qPrint(root->type), qPrint(root->parent()->name), qPrint(root->name), @@ -3648,7 +3652,7 @@ static void buildFunctionList(const Entry *root) if ( matchArguments2(md->getOuterScope(),mfd,&mdAl, rnd ? rnd : Doxygen::globalScope,rfd,&root->argList, - FALSE) && + FALSE,root->lang) && sameNumTemplateArgs && matchingReturnTypes && sameRequiresClause && @@ -3815,7 +3819,7 @@ static void findFriends() (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) && matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), &mmd->argumentList(), fmd->getOuterScope(), fmd->getFileDef(), &fmd->argumentList(), - TRUE + TRUE,mmd->getLanguage() ) ) // if the member is related and the arguments match then the @@ -3945,7 +3949,7 @@ static void transferFunctionReferences() if ( matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),const_cast<ArgumentList*>(&mdefAl), mdec->getOuterScope(),mdec->getFileDef(),const_cast<ArgumentList*>(&mdecAl), - TRUE + TRUE,mdef->getLanguage() ) ) /* match found */ { @@ -3987,7 +3991,7 @@ static void transferRelatedFunctionDocumentation() (rmd->isRelated() || rmd->isForeign()) && // related function matchArguments2( md->getOuterScope(), md->getFileDef(), &md->argumentList(), rmd->getOuterScope(),rmd->getFileDef(),&rmd->argumentList(), - TRUE + TRUE,md->getLanguage() ) ) { @@ -4095,7 +4099,7 @@ static void findUsedClassesForClass(const Entry *root, { //printf(" Found variable %s in class %s\n",qPrint(md->name()),qPrint(masterCd->name())); QCString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs); - QCString typedefValue = resolveTypeDef(masterCd,type); + QCString typedefValue = md->getLanguage()==SrcLangExt_Java ? type : resolveTypeDef(masterCd,type); if (!typedefValue.isEmpty()) { type = typedefValue; @@ -4639,9 +4643,6 @@ static bool findClassRelation( } } bool isATemplateArgument = templateNames.find(biName.str())!=templateNames.end(); - // make templSpec canonical - // warning: the following line doesn't work for Mixin classes (see bug 560623) - // templSpec = getCanonicalTemplateSpec(cd, cd->getFileDef(), templSpec); //printf("4. found=%d\n",found); if (found) @@ -4987,10 +4988,10 @@ static void computeTemplateClassRelations() TemplateNameMap actualTemplateNames; for (const auto &tn_kv : templateNames) { - int templIndex = tn_kv.second; + size_t templIndex = tn_kv.second; Argument actArg; bool hasActArg=FALSE; - if (templIndex<(int)templArgs->size()) + if (templIndex<templArgs->size()) { actArg=templArgs->at(templIndex); hasActArg=TRUE; @@ -5000,7 +5001,7 @@ static void computeTemplateClassRelations() actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end() ) { - actualTemplateNames.insert(std::make_pair(actArg.type.str(),templIndex)); + actualTemplateNames.insert(std::make_pair(actArg.type.str(),static_cast<int>(templIndex))); } } @@ -5179,7 +5180,7 @@ static void addMemberDocs(const Entry *root, if ( matchArguments2( md->getOuterScope(), md->getFileDef(),const_cast<ArgumentList*>(&mdAl), rscope,rfd,&root->argList, - TRUE + TRUE, root->lang ) ) { @@ -5410,7 +5411,7 @@ static bool findGlobalMember(const Entry *root, md->isVariable() || md->isTypedef() || /* in case of function pointers */ matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md.get())->getFileDef(),&mdAl, rnd ? rnd : Doxygen::globalScope,fd,&root->argList, - FALSE); + FALSE,root->lang); // for template members we need to check if the number of // template arguments is the same, otherwise we are dealing with @@ -5475,8 +5476,7 @@ static bool findGlobalMember(const Entry *root, { warnMsg+=" '"; warnMsg+=substitute(md->declaration(),"%","%%"); - warnMsg+="' at line "+QCString().setNum(md->getDefLine())+ - " of file "+md->getDefFileName()+"\n"; + warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine()); } } warn(root->fileName,root->startLine, "%s", qPrint(warnMsg)); @@ -5840,7 +5840,7 @@ static void addMemberFunction(const Entry *root, matchArguments2( md->getClassDef(),md->getFileDef(),&argList, cd,fd,&root->argList, - TRUE); + TRUE,root->lang); if (md->getLanguage()==SrcLangExt_ObjC && md->isVariable() && (root->section&Entry::FUNCTION_SEC)) { @@ -5857,7 +5857,7 @@ static void addMemberFunction(const Entry *root, memType=substitute(stripTemplateSpecifiersFromScope(memType,TRUE), className+"::",""); // see bug758900 Debug::print(Debug::FindMembers,0, - "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n", + "5b. Comparing return types '%s'<->'%s' #args %zu<->%zu\n", qPrint(md->typeString()),qPrint(funcType), md->templateArguments().size(),root->tArgLists.back().size()); if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType) @@ -5953,7 +5953,8 @@ static void addMemberFunction(const Entry *root, root->protection,root->stat,root->virt,spec,relates); return; } - if (md->argsString()==argListToString(root->argList,FALSE,FALSE)) + if (argListToString(md->argumentList(),FALSE,FALSE) == + argListToString(root->argList,FALSE,FALSE)) { // exact argument list match -> remember ucd = ecd = ccd; umd = emd = cmd; @@ -5972,7 +5973,7 @@ static void addMemberFunction(const Entry *root, candidates++; } } - static bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING); + bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING); if (!strictProtoMatching) { if (candidates==1 && ucd && umd) @@ -6010,13 +6011,24 @@ static void addMemberFunction(const Entry *root, warnMsg+=fullFuncDecl; warnMsg+='\n'; - if (candidates>0) + if (candidates>0 || noMatchCount>=1) { warnMsg+="Possible candidates:\n"; + + NamespaceDef *nd=0; + if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); + FileDef *fd=root->fileDef(); + for (const auto &md : *mn) { const ClassDef *cd=md->getClassDef(); - if (cd!=0 && rightScopeMatch(cd->name(),className)) + const ClassDef *tcd=findClassDefinition(fd,nd,scopeName); + if (tcd==0 && cd && stripAnonymousNamespaceScope(cd->name())==scopeName) + { + // don't be fooled by anonymous scopes + tcd=cd; + } + if (cd!=0 && (rightScopeMatch(cd->name(),className) || (cd!=tcd))) { const ArgumentList &templAl = md->templateArguments(); warnMsg+=" '"; @@ -6036,14 +6048,7 @@ static void addMemberFunction(const Entry *root, if (!qScope.isEmpty()) warnMsg+=qScope+"::"+md->name(); warnMsg+=md->argsString(); - if (noMatchCount>1) - { - warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + - " of file "+md->getDefFileName(); - } - else - warnMsg += "'"; - + warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine()); warnMsg+='\n'; } } @@ -6202,7 +6207,7 @@ static void findMember(const Entry *root, { Debug::print(Debug::FindMembers,0, "findMember(root=%p,funcDecl='%s',related='%s',overload=%d," - "isFunc=%d mGrpId=%d #tArgList=%d " + "isFunc=%d mGrpId=%d #tArgList=%zu " "spec=%lld lang=%x\n", root,qPrint(funcDecl),qPrint(relates),overloaded,isFunc,root->mGrpId, root->tArgLists.size(), @@ -6538,7 +6543,7 @@ static void findMember(const Entry *root, if (!isRelated && !strongEnum && mn) // function name already found { Debug::print(Debug::FindMembers,0, - "2. member name exists (%d members with this name)\n",mn->size()); + "2. member name exists (%zu members with this name)\n",mn->size()); if (!className.isEmpty()) // class name is valid { if (funcSpec.isEmpty()) // not a member specialization @@ -6621,7 +6626,7 @@ static void findMember(const Entry *root, className!=rmd->getOuterScope()->name() || !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),&rmdAl, cd,fd,&root->argList, - TRUE); + TRUE,root->lang); if (!newMember) { rmd_found = rmd; @@ -6720,7 +6725,7 @@ static void findMember(const Entry *root, if ( matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),&rmdAl, cd,fd,&root->argList, - TRUE) + TRUE,root->lang) ) { found=TRUE; @@ -7373,20 +7378,26 @@ static void addEnumValuesToEnums(const Entry *root) // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name())); if (nd && !nd->isAnonymous()) { - const NamespaceDef *fnd=fmd->getNamespaceDef(); - if (fnd==nd) // enum value is inside a namespace + if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + const NamespaceDef *fnd=fmd->getNamespaceDef(); + if (fnd==nd) // enum value is inside a namespace + { + md->insertEnumField(fmd); + fmd->setEnumScope(md); + } } } else if (isGlobal) { - const FileDef *ffd=fmd->getFileDef(); - if (ffd==fd) // enum value has file scope + if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + const FileDef *ffd=fmd->getFileDef(); + if (ffd==fd) // enum value has file scope + { + md->insertEnumField(fmd); + fmd->setEnumScope(md); + } } } else if (isRelated && cd) // reparent enum value to @@ -7401,13 +7412,16 @@ static void addEnumValuesToEnums(const Entry *root) } else { - const ClassDef *fcd=fmd->getClassDef(); - if (fcd==cd) // enum value is inside a class + if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added { - //printf("Inserting enum field %s in enum scope %s\n", - // qPrint(fmd->name()),qPrint(md->name())); - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name + const ClassDef *fcd=fmd->getClassDef(); + if (fcd==cd) // enum value is inside a class + { + //printf("Inserting enum field %s in enum scope %s\n", + // qPrint(fmd->name()),qPrint(md->name())); + md->insertEnumField(fmd); // add field def to list + fmd->setEnumScope(md); // cross ref with enum name + } } } } @@ -7713,7 +7727,7 @@ static void addToIndices() { if (pd->isLinkableInProject()) { - Doxygen::indexList->addIndexItem(pd.get(),0,QCString(),filterTitle(pd->title().str())); + Doxygen::indexList->addIndexItem(pd.get(),0,QCString(),filterTitle(pd->title())); } } @@ -7873,7 +7887,7 @@ static void computeMemberRelations() bmd->getLanguage()==SrcLangExt_Python || matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl, md->getOuterScope(), md->getFileDef(), &mdAl, - TRUE + TRUE,bmd->getLanguage() ) ) { @@ -7975,6 +7989,24 @@ static void buildCompleteMemberLists() static void generateFileSources() { + auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser) + { + bool showSources = fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate; // sources need to be shown in the output + bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them + if (showSources) + { + msg("Generating code for file %s...\n",qPrint(fd->docName())); + fd->writeSourceHeader(ol); + fd->writeSourceBody(ol,parser); + fd->writeSourceFooter(ol); + } + else if (parseSources) + { + msg("Parsing code for file %s...\n",qPrint(fd->docName())); + fd->parseSource(parser); + } + ol.indexSearchData(); + }; if (!Doxygen::inputNameLinkedMap->empty()) { #if USE_LIBCLANG @@ -7997,28 +8029,15 @@ static void generateFileSources() { for (const auto &fd : *fn) { - if (fd->isSource() && !fd->isReference() && + if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt_Cpp && ((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",qPrint(fd->docName())); - clangParser->parse(); - 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 - { - msg("Parsing code for file %s...\n",qPrint(fd->docName())); - clangParser->parse(); - fd->parseSource(clangParser.get()); - } + clangParser->parse(); + processSourceFile(fd.get(),*g_outputList,clangParser.get()); for (auto incFile : clangParser->filesInSameTU()) { @@ -8031,19 +8050,7 @@ static void generateFileSources() FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig); if (ifd && !ifd->isReference()) { - if (ifd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output - { - msg(" Generating code for file %s...\n",qPrint(ifd->docName())); - 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 - { - msg(" Parsing code for file %s...\n",qPrint(ifd->docName())); - ifd->parseSource(clangParser.get()); - } + processSourceFile(ifd,*g_outputList,clangParser.get()); processedFiles.insert(incFile); } } @@ -8059,24 +8066,15 @@ static void generateFileSources() { if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed { - if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output + if (fd->getLanguage()==SrcLangExt_Cpp) // C/C++ file, use clang parser { auto clangParser = ClangParser::instance()->createTUParser(fd.get()); - msg("Generating code for file %s...\n",qPrint(fd->docName())); clangParser->parse(); - fd->writeSourceHeader(*g_outputList); - fd->writeSourceBody(*g_outputList,clangParser.get()); - fd->writeSourceFooter(*g_outputList); + processSourceFile(fd.get(),*g_outputList,clangParser.get()); } - else if (!fd->isReference() && Doxygen::parseSourcesNeeded) - // we needed to parse the sources even if we do not show them + else // non C/C++ file, use built-in parser { - auto clangParser = ClangParser::instance()->createTUParser(fd.get()); - msg("Parsing code for file %s...\n",qPrint(fd->docName())); - clangParser->parse(); - fd->writeSourceHeader(*g_outputList); - fd->writeSourceBody(*g_outputList,clangParser.get()); - fd->writeSourceFooter(*g_outputList); + processSourceFile(fd.get(),*g_outputList,nullptr); } } } @@ -8086,10 +8084,6 @@ static void generateFileSources() #endif { std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); - if (numThreads==0) - { - numThreads = std::thread::hardware_concurrency(); - } if (numThreads>1) { msg("Generating code files using %zu threads.\n",numThreads); @@ -8109,11 +8103,8 @@ static void generateFileSources() { bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate; auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList); - if (generateSourceFile) + auto processFile = [ctx]() { - fd->writeSourceHeader(ctx->ol); - } - auto processFile = [ctx]() { if (ctx->generateSourceFile) { msg("Generating code for file %s...\n",qPrint(ctx->fd->docName())); @@ -8126,7 +8117,9 @@ static void generateFileSources() ctx->fd->getAllIncludeFilesRecursively(filesInSameTu); if (ctx->generateSourceFile) // sources need to be shown in the output { + ctx->fd->writeSourceHeader(ctx->ol); ctx->fd->writeSourceBody(ctx->ol,nullptr); + ctx->fd->writeSourceFooter(ctx->ol); } else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded) // we needed to parse the sources even if we do not show them @@ -8141,10 +8134,7 @@ static void generateFileSources() for (auto &f : results) { auto ctx = f.get(); - if (ctx->generateSourceFile) - { - ctx->fd->writeSourceFooter(ctx->ol); - } + ctx->ol.indexSearchData(); } } else // single threaded version @@ -8155,19 +8145,7 @@ static void generateFileSources() { StringVector filesInSameTu; fd->getAllIncludeFilesRecursively(filesInSameTu); - if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output - { - msg("Generating code for file %s...\n",qPrint(fd->docName())); - 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 - { - msg("Parsing code for file %s...\n",qPrint(fd->docName())); - fd->parseSource(nullptr); - } + processSourceFile(fd.get(),*g_outputList,nullptr); } } } @@ -8184,10 +8162,6 @@ static void generateFileDocs() if (!Doxygen::inputNameLinkedMap->empty()) { std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); - if (numThreads==0) - { - numThreads = std::thread::hardware_concurrency(); - } if (numThreads>1) // multi threaded processing { struct DocContext @@ -8405,12 +8379,38 @@ static bool isSymbolHidden(const Definition *d) static void computeTooltipTexts() { - for (const auto &kv : *Doxygen::symbolMap) + std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); + if (numThreads>1) + { + ThreadPool threadPool(numThreads); + std::vector < std::future< void > > results; + // queue the work + for (const auto &kv : *Doxygen::symbolMap) + { + DefinitionMutable *dm = toDefinitionMutable(kv.second); + if (dm && !isSymbolHidden(toDefinition(dm)) && toDefinition(dm)->isLinkableInProject()) + { + auto processTooltip = [dm]() { + dm->computeTooltip(); + }; + results.emplace_back(threadPool.queue(processTooltip)); + } + } + // wait for the results + for (auto &f : results) + { + f.get(); + } + } + else { - DefinitionMutable *dm = toDefinitionMutable(kv.second); - if (dm && !isSymbolHidden(toDefinition(dm)) && toDefinition(dm)->isLinkableInProject()) + for (const auto &kv : *Doxygen::symbolMap) { - dm->computeTooltip(); + DefinitionMutable *dm = toDefinitionMutable(kv.second); + if (dm && !isSymbolHidden(toDefinition(dm)) && toDefinition(dm)->isLinkableInProject()) + { + dm->computeTooltip(); + } } } } @@ -8467,15 +8467,11 @@ static void countMembers() //---------------------------------------------------------------------------- -// generate the documentation of all classes +// generate the documentation for all classes -static void generateClassList(const ClassLinkedMap &classList) +static void generateDocsForClassList(const std::vector<ClassDefMutable*> &classList) { std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); - if (numThreads==0) - { - numThreads = std::thread::hardware_concurrency(); - } if (numThreads>1) // multi threaded processing { struct DocContext @@ -8487,13 +8483,10 @@ static void generateClassList(const ClassLinkedMap &classList) }; ThreadPool threadPool(numThreads); std::vector< std::future< std::shared_ptr<DocContext> > > results; - for (const auto &cdi : classList) + for (const auto &cd : classList) { - ClassDefMutable *cd=toClassDefMutable(cdi.get()); - //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope); - if (cd && - (cd->getOuterScope()==0 || // <-- should not happen, but can if we read an old tag file + if ((cd->getOuterScope()==0 || // <-- should not happen, but can if we read an old tag file cd->getOuterScope()==Doxygen::globalScope // only look at global classes ) && !cd->isHidden() && !cd->isEmbeddedInOuterScope() ) @@ -8525,13 +8518,10 @@ static void generateClassList(const ClassLinkedMap &classList) } else // single threaded processing { - for (const auto &cdi : classList) + for (const auto &cd : classList) { - ClassDefMutable *cd=toClassDefMutable(cdi.get()); - //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope); - if (cd && - (cd->getOuterScope()==0 || // <-- should not happen, but can if we read an old tag file + if ((cd->getOuterScope()==0 || // <-- should not happen, but can if we read an old tag file cd->getOuterScope()==Doxygen::globalScope // only look at global classes ) && !cd->isHidden() && !cd->isEmbeddedInOuterScope() ) @@ -8552,10 +8542,45 @@ static void generateClassList(const ClassLinkedMap &classList) } } +static void addClassAndNestedClasses(std::vector<ClassDefMutable*> &list,ClassDefMutable *cd) +{ + list.push_back(cd); + for (const auto &innerCdi : cd->getClasses()) + { + ClassDefMutable *innerCd = toClassDefMutable(innerCdi); + if (innerCd && innerCd->isLinkableInProject() && innerCd->templateMaster()==0 && + protectionLevelVisible(innerCd->protection()) && + !innerCd->isEmbeddedInOuterScope() + ) + { + list.push_back(innerCd); + addClassAndNestedClasses(list,innerCd); + } + } +} + static void generateClassDocs() { - generateClassList(*Doxygen::classLinkedMap); - generateClassList(*Doxygen::hiddenClassLinkedMap); + std::vector<ClassDefMutable*> classList; + for (const auto &cdi : *Doxygen::classLinkedMap) + { + ClassDefMutable *cd = toClassDefMutable(cdi.get()); + if (cd && (cd->getOuterScope()==0 || + cd->getOuterScope()->definitionType()!=Definition::TypeClass)) + { + addClassAndNestedClasses(classList,cd); + } + } + for (const auto &cdi : *Doxygen::hiddenClassLinkedMap) + { + ClassDefMutable *cd = toClassDefMutable(cdi.get()); + if (cd && (cd->getOuterScope()==0 || + cd->getOuterScope()->definitionType()!=Definition::TypeClass)) + { + addClassAndNestedClasses(classList,cd); + } + } + generateDocsForClassList(classList); } //---------------------------------------------------------------------------- @@ -8977,7 +9002,7 @@ static void findDefineDocumentation(Entry *root) } else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found { - static bool preEnabled = Config_getBool(ENABLE_PREPROCESSING); + bool preEnabled = Config_getBool(ENABLE_PREPROCESSING); if (preEnabled) { warn(root->fileName,root->startLine, @@ -9189,9 +9214,9 @@ static void computePageRelations(Entry *root) PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name); if (pd==subPd) { - term("page defined at line %d of file %s with label %s is a direct " + term("page defined %s with label %s is a direct " "subpage of itself! Please remove this cyclic dependency.\n", - pd->docLine(),qPrint(pd->docFile()),qPrint(pd->name())); + qPrint(warn_line(pd->docFile(),pd->docLine())),qPrint(pd->name())); } else if (subPd) { @@ -9214,9 +9239,9 @@ static void checkPageRelations() { if (ppd==pd.get()) { - term("page defined at line %d of file %s with label %s is a subpage " - "of itself! Please remove this cyclic dependency.\n", - pd->docLine(),qPrint(pd->docFile()),qPrint(pd->name())); + term("page defined %s with label %s is a subpage " + "of itself! Please remove this cyclic dependency.\n", + qPrint(warn_line(pd->docFile(),pd->docLine())),qPrint(pd->name())); } ppd=ppd->getOuterScope(); } @@ -9421,10 +9446,6 @@ static void generateGroupDocs() static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList) { std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); - if (numThreads==0) - { - numThreads = std::thread::hardware_concurrency(); - } if (numThreads>1) // multi threaded processing { struct DocContext @@ -9510,7 +9531,7 @@ static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList) static void generateNamespaceDocs() { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); //writeNamespaceIndex(*g_outputList); @@ -9538,6 +9559,91 @@ static void generateNamespaceDocs() } } +static void runHtmlHelpCompiler() +{ + std::string oldDir = Dir::currentDirPath(); + Dir::setCurrent(Config_getString(HTML_OUTPUT).str()); + Portable::setShortDir(); + Portable::sysTimerStart(); + if (Portable::system(Config_getString(HHC_LOCATION).data(), qPrint(HtmlHelp::hhpFileName), Debug::isFlagSet(Debug::ExtCmd))!=1) + { + err("failed to run html help compiler on %s\n", qPrint(HtmlHelp::hhpFileName)); + } + Portable::sysTimerStop(); + Dir::setCurrent(oldDir); +} + +static void runQHelpGenerator() +{ + QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\""; + std::string oldDir = Dir::currentDirPath(); + Dir::setCurrent(Config_getString(HTML_OUTPUT).str()); + Portable::sysTimerStart(); + + QCString qhgLocation=Config_getString(QHG_LOCATION); + if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging + { + // run qhelpgenerator -v and extract the Qt version used + QCString cmd=qhgLocation+ " -v 2>&1"; + Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd)); + FILE *f=Portable::popen(cmd,"r"); + if (!f) + { + err("could not execute %s\n",qPrint(qhgLocation)); + } + else + { + const size_t bufSize = 1024; + char inBuf[bufSize+1]; + size_t numRead=fread(inBuf,1,bufSize,f); + inBuf[numRead] = '\0'; + Debug::print(Debug::Qhp,0,inBuf); + Portable::pclose(f); + + int qtVersion=0; + static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))"); + reg::Match match; + std::string s = inBuf; + if (reg::search(inBuf,match,versionReg)) + { + qtVersion = 10000*QCString(match[1].str()).toInt() + + 100*QCString(match[2].str()).toInt() + + QCString(match[3].str()).toInt(); + } + if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205)) + { + // dump the output of qhelpgenerator -c file.qhp + // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070 + cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1"; + Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd)); + f=Portable::popen(cmd,"r"); + if (!f) + { + err("could not execute %s\n",qPrint(qhgLocation)); + } + else + { + std::string output; + while ((numRead=fread(inBuf,1,bufSize,f))>0) + { + inBuf[numRead] = '\0'; + output += inBuf; + } + Portable::pclose(f); + Debug::print(Debug::Qhp,0,output.c_str()); + } + } + } + } + + if (Portable::system(qhgLocation, args, FALSE)) + { + err("failed to run qhelpgenerator on %s\n",qPrint(Qhp::qhpFileName)); + } + Portable::sysTimerStop(); + Dir::setCurrent(oldDir); +} + #if defined(_WIN32) static QCString fixSlashes(QCString &s) { @@ -9559,6 +9665,38 @@ static QCString fixSlashes(QCString &s) } #endif +//---------------------------------------------------------------------------- + +static void computeVerifiedDotPath() +{ + // check dot path + QCString dotPath = Config_getString(DOT_PATH); + if (!dotPath.isEmpty()) + { + FileInfo fi(dotPath.str()); + if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec + { + dotPath = dotPath+"/dot"+Portable::commandExtension(); + FileInfo dp(dotPath.str()); + if (!dp.exists() || !dp.isFile()) + { + warn_uncond("the dot tool could not be found as '%s'\n",qPrint(dotPath)); + dotPath = "dot"; + dotPath += Portable::commandExtension(); + } + } +#if defined(_WIN32) // convert slashes + uint i=0,l=dotPath.length(); + for (i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\'; +#endif + } + else + { + dotPath = "dot"; + dotPath += Portable::commandExtension(); + } + Doxygen::verifiedDotPath = dotPath; +} //---------------------------------------------------------------------------- @@ -9600,14 +9738,14 @@ static void generateConfigFile(const QCString &configFile,bool shortList, } } -static void compareDoxyfile() +static void compareDoxyfile(DoxyfileSettings diffList) { std::ofstream f; bool fileOpened=openOutputFile("-",f); if (fileOpened) { TextStream t(&f); - Config::compareDoxyfile(t); + Config::compareDoxyfile(t,diffList); } else { @@ -9878,7 +10016,7 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser, } FileInfo fi(fileName.str()); - BufStr preBuf((uint)fi.size()+4096); + BufStr preBuf(fi.size()+4096); if (Config_getBool(ENABLE_PREPROCESSING) && parser.needsPreprocessing(extension)) @@ -9890,19 +10028,17 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser, std::string absPath = FileInfo(s).absFilePath(); preprocessor.addSearchDir(absPath.c_str()); } - BufStr inBuf((uint)fi.size()+4096); + BufStr inBuf(fi.size()+4096); msg("Preprocessing %s...\n",qPrint(fn)); readInputFile(fileName,inBuf); + inBuf.addTerminalCharIfMissing('\n'); preprocessor.processFile(fileName,inBuf,preBuf); } else // no preprocessing { msg("Reading %s...\n",qPrint(fn)); readInputFile(fileName,preBuf); - } - if (preBuf.data() && preBuf.curPos()>0 && *(preBuf.data()+preBuf.curPos()-1)!='\n') - { - preBuf.addChar('\n'); // add extra newline to help parser + preBuf.addTerminalCharIfMissing('\n'); } BufStr convBuf(preBuf.curPos()+1024); @@ -9942,10 +10078,6 @@ static void parseFilesMultiThreading(const std::shared_ptr<Entry> &root) std::mutex processedFilesLock; // process source files (and their include dependencies) std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); - if (numThreads==0) - { - numThreads = std::thread::hardware_concurrency(); - } msg("Processing input using %zu threads.\n",numThreads); ThreadPool threadPool(numThreads); using FutureType = std::vector< std::shared_ptr<Entry> >; @@ -9955,7 +10087,7 @@ static void parseFilesMultiThreading(const std::shared_ptr<Entry> &root) bool ambig; FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig); ASSERT(fd!=0); - if (fd->isSource() && !fd->isReference()) // this is a source file + if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt_Cpp) // this is a source file { // lambda representing the work to executed by a thread auto processFile = [s,&filesToProcess,&processedFilesLock,&processedFiles]() { @@ -10017,13 +10149,21 @@ static void parseFilesMultiThreading(const std::shared_ptr<Entry> &root) bool ambig; std::vector< std::shared_ptr<Entry> > roots; FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig); - auto clangParser = ClangParser::instance()->createTUParser(fd); auto parser { getParserForFile(s.c_str()) }; - auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true); - roots.push_back(fileRoot); + bool useClang = getLanguageFromFileName(s.c_str())==SrcLangExt_Cpp; + if (useClang) + { + auto clangParser = ClangParser::instance()->createTUParser(fd); + auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true); + roots.push_back(fileRoot); + } + else + { + auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true); + roots.push_back(fileRoot); + } return roots; }; - // dispatch the work and collect the future results results.emplace_back(threadPool.queue(processFile)); } } @@ -10040,7 +10180,7 @@ static void parseFilesMultiThreading(const std::shared_ptr<Entry> &root) else // normal processing #endif { - std::size_t numThreads = std::thread::hardware_concurrency(); + std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS)); msg("Processing input using %zu threads.\n",numThreads); ThreadPool threadPool(numThreads); using FutureType = std::shared_ptr<Entry>; @@ -10087,7 +10227,7 @@ static void parseFilesSingleThreading(const std::shared_ptr<Entry> &root) bool ambig; FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig); ASSERT(fd!=0); - if (fd->isSource() && !fd->isReference()) // this is a source file + if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(s.c_str())==SrcLangExt_Cpp) // this is a source file { auto clangParser = ClangParser::instance()->createTUParser(fd); auto parser { getParserForFile(s.c_str()) }; @@ -10122,10 +10262,19 @@ static void parseFilesSingleThreading(const std::shared_ptr<Entry> &root) { bool ambig; FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig); - auto clangParser = ClangParser::instance()->createTUParser(fd); - auto parser { getParserForFile(s.c_str()) }; - auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true); - root->moveToSubEntryAndKeep(fileRoot); + if (getLanguageFromFileName(s.c_str())==SrcLangExt_Cpp) // not yet processed + { + auto clangParser = ClangParser::instance()->createTUParser(fd); + auto parser { getParserForFile(s.c_str()) }; + auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true); + root->moveToSubEntryAndKeep(fileRoot); + } + else + { + std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) }; + std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true); + root->moveToSubEntryAndKeep(fileRoot); + } processedFiles.insert(s); } } @@ -10157,7 +10306,7 @@ static std::string resolveSymlink(const std::string &path) QCString oldPrefix = "/"; do { -#ifdef WIN32 +#if defined(_WIN32) // UNC path, skip server and share name if (sepPos==0 && (result.left(2)=="//" || result.left(2)=="\\\\")) sepPos = result.find('/',2); @@ -10187,7 +10336,6 @@ static std::string resolveSymlink(const std::string &path) target+=result.mid(sepPos); } result = Dir::cleanDirPath(target.str()); - sepPos = 0; if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink! known.insert(result.str()); if (isRelative) @@ -10575,17 +10723,17 @@ static void usage(const QCString &name,const QCString &versionString) { msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2021\n\n",qPrint(versionString)); msg("You can use doxygen in a number of ways:\n\n"); - msg("1) Use doxygen to generate a template configuration file:\n"); + msg("1) Use doxygen to generate a template configuration file*:\n"); msg(" %s [-s] -g [configName]\n\n",qPrint(name)); - msg("2) Use doxygen to update an old configuration file:\n"); + msg("2) Use doxygen to update an old configuration file*:\n"); msg(" %s [-s] -u [configName]\n\n",qPrint(name)); msg("3) Use doxygen to generate documentation using an existing "); - msg("configuration file:\n"); + msg("configuration file*:\n"); msg(" %s [configName]\n\n",qPrint(name)); msg("4) Use doxygen to generate a template file controlling the layout of the\n"); msg(" generated documentation:\n"); msg(" %s -l [layoutFileName]\n\n",qPrint(name)); - msg(" In case layoutFileName is omitted layoutFileName.xml will be used as filename.\n"); + msg(" In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"); msg(" If - is used for layoutFileName doxygen will write to standard output.\n\n"); msg("5) Use doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"); msg(" RTF: %s -w rtf styleSheetFile\n",qPrint(name)); @@ -10596,14 +10744,19 @@ static void usage(const QCString &name,const QCString &versionString) msg(" If - is used for extensionsFile doxygen will write to standard output.\n\n"); msg("7) Use doxygen to compare the used configuration file with the template configuration file\n"); msg(" %s -x [configFile]\n\n",qPrint(name)); + msg(" Use doxygen to compare the used configuration file with the template configuration file\n"); + msg(" without replacing the environment variables\n"); + msg(" %s -x_noenv [configFile]\n\n",qPrint(name)); msg("8) Use doxygen to show a list of built-in emojis.\n"); msg(" %s -f emoji outputFileName\n\n",qPrint(name)); msg(" If - is used for outputFileName doxygen will write to standard output.\n\n"); - msg("If -s is specified the comments of the configuration items in the config file will be omitted.\n"); - msg("If configName is omitted 'Doxyfile' will be used as a default.\n"); - msg("If - is used for configFile doxygen will write / read the configuration to /from standard output / input.\n\n"); + msg("*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"); + msg(" If configName is omitted 'Doxyfile' will be used as a default.\n"); + msg(" If - is used for configFile doxygen will write / read the configuration to /from standard output / input.\n\n"); msg("If -q is used for a doxygen documentation run, doxygen will see this as if QUIET=YES has been set.\n\n"); msg("-v print version string, -V print extended version information\n"); + msg("-h,-? prints usage help information\n"); + msg("%s -d prints additional usage flags for debugging purposes\n",qPrint(name)); } //---------------------------------------------------------------------------- @@ -10749,8 +10902,6 @@ void cleanUpDoxygen() delete Doxygen::namespaceLinkedMap; delete Doxygen::dirLinkedMap; delete Doxygen::symbolMap; - - DotManager::deleteInstance(); } static int computeIdealCacheParam(size_t v) @@ -10781,7 +10932,7 @@ void readConfiguration(int argc, char **argv) QCString listName; bool genConfig=FALSE; bool shortList=FALSE; - bool diffList=FALSE; + DoxyfileSettings diffList=DoxyfileSettings::Full; bool updateConfig=FALSE; int retVal; bool quiet = false; @@ -10826,7 +10977,14 @@ void readConfiguration(int argc, char **argv) } break; case 'x': - diffList=TRUE; + if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=DoxyfileSettings::CompressedNoEnv; + else if (!strcmp(argv[optInd]+1,"x")) diffList=DoxyfileSettings::Compressed; + else + { + err("option should be \"-x\" or \"-x_noenv\", found: \"%s\".\n",argv[optInd]); + cleanUpDoxygen(); + exit(1); + } break; case 's': shortList=TRUE; @@ -11145,10 +11303,10 @@ void readConfiguration(int argc, char **argv) exit(1); } - if (diffList) + if (diffList!=DoxyfileSettings::Full) { Config::updateObsolete(); - compareDoxyfile(); + compareDoxyfile(diffList); cleanUpDoxygen(); exit(0); } @@ -11267,6 +11425,7 @@ static void stopDoxygen(int) } killpg(0,SIGINT); cleanUpDoxygen(); + Doxygen::terminating=true; exit(1); } #endif @@ -11379,23 +11538,6 @@ static QCString createOutputDirectory(const QCString &baseDirName, return result; } -static QCString getQchFileName() -{ - QCString const & qchFile = Config_getString(QCH_FILE); - if (!qchFile.isEmpty()) - { - return qchFile; - } - - QCString const & projectName = Config_getString(PROJECT_NAME); - QCString const & versionText = Config_getString(PROJECT_NUMBER); - - return QCString("../qch/") - + (projectName.isEmpty() ? QCString("index") : projectName) - + (versionText.isEmpty() ? QCString("") : QCString("-") + versionText) - + QCString(".qch"); -} - void searchInputFiles() { StringUnorderedSet killSet; @@ -11420,7 +11562,7 @@ void searchInputFiles() &exclPatterns, // exclPatList 0, // resultList 0, // resultSet - alwaysRecursive, // recursive + false, // INCLUDE_PATH isn't recursive TRUE, // errorIfNotExist &killSet); // killSet } @@ -11593,6 +11735,8 @@ void parseInput() Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); #endif + computeVerifiedDotPath(); + // we would like to show the versionString earlier, but we first have to handle the configuration file // to know the value of the QUIET setting. QCString versionString = getFullVersion(); @@ -12168,6 +12312,7 @@ void parseInput() combineUsingRelations(); g_s.end(); + initSearchIndexer(); g_s.begin("Adding members to index pages...\n"); addMembersToIndex(); addToIndices(); @@ -12212,8 +12357,6 @@ void generateOutput() exit(0); } - initSearchIndexer(); - bool generateHtml = Config_getBool(GENERATE_HTML); bool generateLatex = Config_getBool(GENERATE_LATEX); bool generateMan = Config_getBool(GENERATE_MAN); @@ -12267,8 +12410,8 @@ void generateOutput() g_outputList->writeStyleInfo(0); // write first part g_s.end(); - static bool searchEngine = Config_getBool(SEARCHENGINE); - static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH); + bool searchEngine = Config_getBool(SEARCHENGINE); + bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH); g_s.begin("Generating search indices...\n"); if (searchEngine && !serverBasedSearch && (generateHtml || g_useOutputTemplate)) @@ -12493,16 +12636,7 @@ void generateOutput() !Config_getString(HHC_LOCATION).isEmpty()) { g_s.begin("Running html help compiler...\n"); - std::string oldDir = Dir::currentDirPath(); - Dir::setCurrent(Config_getString(HTML_OUTPUT).str()); - Portable::setShortDir(); - Portable::sysTimerStart(); - if (Portable::system(Config_getString(HHC_LOCATION).data(), "index.hhp", Debug::isFlagSet(Debug::ExtCmd))!=1) - { - err("failed to run html help compiler on index.hhp\n"); - } - Portable::sysTimerStop(); - Dir::setCurrent(oldDir); + runHtmlHelpCompiler(); g_s.end(); } @@ -12513,19 +12647,7 @@ void generateOutput() !Config_getString(QHG_LOCATION).isEmpty()) { g_s.begin("Running qhelpgenerator...\n"); - QCString qhpFileName = Qhp::getQhpFileName(); - QCString qchFileName = getQchFileName(); - - QCString args = QCString().sprintf("%s -o \"%s\"", qPrint(qhpFileName), qPrint(qchFileName)); - std::string oldDir = Dir::currentDirPath(); - Dir::setCurrent(Config_getString(HTML_OUTPUT).str()); - Portable::sysTimerStart(); - if (Portable::system(Config_getString(QHG_LOCATION).data(), args.data(), FALSE)) - { - err("failed to run qhelpgenerator on index.qhp\n"); - } - Portable::sysTimerStop(); - Dir::setCurrent(oldDir); + runQHelpGenerator(); g_s.end(); } @@ -12546,7 +12668,7 @@ void generateOutput() if (Debug::isFlagSet(Debug::Time)) { msg("Total elapsed time: %.6f seconds\n(of which %.6f seconds waiting for external tools to finish)\n", - ((double)Debug::elapsedTime()), + (static_cast<double>(Debug::elapsedTime())), Portable::getSysElapsedTime() ); g_s.print(); @@ -12570,4 +12692,6 @@ void generateOutput() Config::deinit(); delete Doxygen::clangUsrMap; g_successfulRun=TRUE; + + //dumpDocNodeSizes(); } diff --git a/src/doxygen.h b/src/doxygen.h index 49c530e..d0ecc1b 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -117,8 +117,21 @@ class Doxygen static bool generatingXmlOutput; static DefinesPerFileList macroDefinitions; static bool clangAssistedParsing; + static QCString verifiedDotPath; + static volatile bool terminating; }; +/** Deleter that only deletes an object if doxygen is not already terminating */ +template<class T> +struct NonTerminatingDeleter +{ + void operator()(T *obj) + { + if (!Doxygen::terminating) delete obj; + } +}; + + void initDoxygen(); void readConfiguration(int argc, char **argv); void checkConfiguration(); diff --git a/src/doxygen.md b/src/doxygen.md index e3db534..de38efe 100644 --- a/src/doxygen.md +++ b/src/doxygen.md @@ -155,7 +155,7 @@ easy ways to get debug information. Will print each comment block before and after the comment is interpreted by the comment scanner. - printtree<br> - Give the results in in pretty print way, i.e. in an XML like way with each + Give the results in pretty print way, i.e. in an XML like way with each level indented by a `"."` (dot). - time<br> Provides information of the different stages of the doxygen process. diff --git a/src/doxygen_lex.h b/src/doxygen_lex.h index bb61660..dff85ee 100644 --- a/src/doxygen_lex.h +++ b/src/doxygen_lex.h @@ -23,10 +23,10 @@ QCString msg1 = msg; \ msg1 += "\n lexical analyzer: "; \ msg1 += getLexerFILE(); \ - if (!((struct yyguts_t*)yyscanner)->yyextra_r->fileName.isEmpty()) \ + if (!static_cast<yyguts_t*>(yyscanner)->yyextra_r->fileName.isEmpty()) \ { \ msg1 += " (for: "; \ - msg1 += ((struct yyguts_t*)yyscanner)->yyextra_r->fileName; \ + msg1 += static_cast<yyguts_t*>(yyscanner)->yyextra_r->fileName; \ msg1 += ")"; \ } \ msg1 += "\n"; \ diff --git a/src/emoji.cpp b/src/emoji.cpp index 750ec16..34a6cf0 100644 --- a/src/emoji.cpp +++ b/src/emoji.cpp @@ -1894,18 +1894,18 @@ static struct emojiEntityCompatibility {":person_with_pouting_face:", ":pouting_face:"}, }; -static const int g_numEmojiEntities = (int)(sizeof(g_emojiEntities)/sizeof(*g_emojiEntities)); -static const int g_numEmojiCompatibilityEntities = (int)(sizeof(g_emojiCompatibilityEntities)/sizeof(*g_emojiCompatibilityEntities)); +static const size_t g_numEmojiEntities = sizeof(g_emojiEntities)/sizeof(*g_emojiEntities); +static const size_t g_numEmojiCompatibilityEntities = sizeof(g_emojiCompatibilityEntities)/sizeof(*g_emojiCompatibilityEntities); EmojiEntityMapper *EmojiEntityMapper::s_instance = 0; EmojiEntityMapper::EmojiEntityMapper() { - for (int i = 0; i < g_numEmojiEntities; i++) + for (size_t i = 0; i < g_numEmojiEntities; i++) { - m_name2symGh.insert(std::make_pair(g_emojiEntities[i].name, i)); + m_name2symGh.insert(std::make_pair(g_emojiEntities[i].name, static_cast<int>(i))); } - for (int i = 0; i < g_numEmojiCompatibilityEntities; i++) + for (size_t i = 0; i < g_numEmojiCompatibilityEntities; i++) { int ii = symbol2index(g_emojiCompatibilityEntities[i].newName); if (ii != -1) m_name2symGh.insert(std::make_pair(g_emojiCompatibilityEntities[i].oldName, ii)); @@ -1950,11 +1950,11 @@ int EmojiEntityMapper::symbol2index(const std::string &symName) const */ void EmojiEntityMapper::writeEmojiFile(TextStream &t) { - for (int i = 0; i < g_numEmojiEntities; i++) + for (size_t i = 0; i < g_numEmojiEntities; i++) { t << g_emojiEntities[i].name << "\n"; } - for (int i = 0; i < g_numEmojiCompatibilityEntities; i++) + for (size_t i = 0; i < g_numEmojiCompatibilityEntities; i++) { t << g_emojiCompatibilityEntities[i].oldName << "\n"; } @@ -1967,7 +1967,7 @@ void EmojiEntityMapper::writeEmojiFile(TextStream &t) */ const char *EmojiEntityMapper::unicode(int index) const { - return index>=0 && index<g_numEmojiEntities ? g_emojiEntities[index].unicode : 0; + return index>=0 && static_cast<size_t>(index)<g_numEmojiEntities ? g_emojiEntities[index].unicode : 0; } /*! @brief Access routine to the name of the Emoji entity @@ -1977,5 +1977,5 @@ const char *EmojiEntityMapper::unicode(int index) const */ const char *EmojiEntityMapper::name(int index) const { - return index>=0 && index<g_numEmojiEntities ? g_emojiEntities[index].name : 0; + return index>=0 && static_cast<size_t>(index)<g_numEmojiEntities ? g_emojiEntities[index].name : 0; } diff --git a/src/entry.h b/src/entry.h index cfb5566..d4c835e 100644 --- a/src/entry.h +++ b/src/entry.h @@ -230,7 +230,7 @@ class Entry */ void reset(); - void markAsProcessed() const { ((Entry*)(this))->section = Entry::EMPTY_SEC; } + void markAsProcessed() const { (const_cast<Entry*>(this))->section = Entry::EMPTY_SEC; } void setFileDef(FileDef *fd); FileDef *fileDef() const { return m_fileDef; } diff --git a/src/filedef.cpp b/src/filedef.cpp index 4a86b4d..cb67f00 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -84,8 +84,8 @@ class FileDefImpl : public DefinitionMixin<FileDef> virtual bool isIncluded(const QCString &name) const; virtual PackageDef *packageDef() const { return m_package; } virtual DirDef *getDirDef() const { return m_dir; } - virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const; - virtual LinkedRefMap<const ClassDef> getUsedClasses() const { return m_usingDeclList; } + virtual const LinkedRefMap<const NamespaceDef> &getUsedNamespaces() const; + virtual const LinkedRefMap<const ClassDef> &getUsedClasses() const { return m_usingDeclList; } virtual const IncludeInfoList &includeFileList() const { return m_includeList; } virtual const IncludeInfoList &includedByFileList() const { return m_includedByList; } virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const; @@ -228,7 +228,7 @@ class DevNullCodeDocInterface : public CodeOutputInterface */ FileDefImpl::FileDefImpl(const QCString &p,const QCString &nm, const QCString &lref,const QCString &dn) - : DefinitionMixin((QCString)p+nm,1,1,nm) + : DefinitionMixin(QCString(p)+nm,1,1,nm,0,0,!p.isEmpty()) { m_path=p; m_filePath=m_path+nm; @@ -305,8 +305,8 @@ void FileDefImpl::findSectionsInDocumentation() bool FileDefImpl::hasDetailedDescription() const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); - static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool sourceBrowser = Config_getBool(SOURCE_BROWSER); return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().stripWhiteSpace().isEmpty() || // avail empty section (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()) @@ -386,11 +386,14 @@ void FileDefImpl::writeTagFile(TextStream &tagFile) break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ml->writeTagFile(tagFile); + MemberList * ml = getMemberList(lmd->type); + if (ml) + { + ml->writeTagFile(tagFile); + } } } break; @@ -478,20 +481,19 @@ void FileDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc(*parser.get(), - briefFile(),briefLine(),this,0, - briefDescription(),TRUE,FALSE, - QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - - if (rootNode && !rootNode->isEmpty()) + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + briefFile(),briefLine(),this,0, + briefDescription(),TRUE,FALSE, + QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + if (!ast->isEmpty()) { ol.startParagraph(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); ol.writeString(" - "); ol.popGeneratorState(); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); ol.pushGeneratorState(); ol.disable(OutputGenerator::RTF); ol.writeString(" \n"); @@ -720,8 +722,7 @@ void FileDefImpl::writeMemberGroups(OutputList &ol) /* write user defined member groups */ for (const auto &mg : m_memberGroups) { - if ((!mg->allMembersInSameSection() || !m_subGrouping) - && mg->header()!="[NOHEADER]") + if (!mg->allMembersInSameSection() || !m_subGrouping) { mg->writeDeclarations(ol,0,0,this,0); } @@ -748,56 +749,54 @@ void FileDefImpl::writeSummaryLinks(OutputList &ol) const SrcLangExt lang=getLanguage(); for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::File)) { - if (lde->kind()==LayoutDocEntry::FileClasses && m_classes.declVisible()) + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (lde->kind()==LayoutDocEntry::FileClasses && m_classes.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "nested-classes"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::FileInterfaces && m_interfaces.declVisible()) + else if (lde->kind()==LayoutDocEntry::FileInterfaces && m_interfaces.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "interfaces"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::FileStructs && m_structs.declVisible()) + else if (lde->kind()==LayoutDocEntry::FileStructs && m_structs.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "structs"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::FileExceptions && m_exceptions.declVisible()) + else if (lde->kind()==LayoutDocEntry::FileExceptions && m_exceptions.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "exceptions"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::FileNamespaces && m_namespaces.declVisible(false)) + else if (lde->kind()==LayoutDocEntry::FileNamespaces && m_namespaces.declVisible(false) && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "namespaces"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::FileConcepts && m_concepts.declVisible()) + else if (lde->kind()==LayoutDocEntry::FileConcepts && m_concepts.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "concepts"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } else if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml && ml->declVisible()) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); - first=FALSE; + MemberList * ml = getMemberList(lmd->type); + if (ml && ml->declVisible()) + { + ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); + first=FALSE; + } } } } @@ -813,7 +812,7 @@ void FileDefImpl::writeSummaryLinks(OutputList &ol) const */ void FileDefImpl::writeDocumentation(OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //funcList->countDecMembers(); //QCString fn = name(); @@ -881,6 +880,7 @@ void FileDefImpl::writeDocumentation(OutputList &ol) SrcLangExt lang = getLanguage(); for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::File)) { + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); switch (lde->kind()) { case LayoutDocEntry::BriefDesc: @@ -902,64 +902,40 @@ void FileDefImpl::writeDocumentation(OutputList &ol) writeSourceLink(ol); break; case LayoutDocEntry::FileClasses: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),m_classes); - } + if (ls) writeClassDeclarations(ol,ls->title(lang),m_classes); break; case LayoutDocEntry::FileInterfaces: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),m_interfaces); - } + if (ls) writeClassDeclarations(ol,ls->title(lang),m_interfaces); break; case LayoutDocEntry::FileStructs: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),m_structs); - } + if (ls) writeClassDeclarations(ol,ls->title(lang),m_structs); break; case LayoutDocEntry::FileExceptions: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),m_exceptions); - } + if (ls) writeClassDeclarations(ol,ls->title(lang),m_exceptions); break; case LayoutDocEntry::FileConcepts: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeConcepts(ol,ls->title(lang)); - } + if (ls) writeConcepts(ol,ls->title(lang)); break; case LayoutDocEntry::FileNamespaces: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNamespaceDeclarations(ol,ls->title(lang),false); - } + if (ls) writeNamespaceDeclarations(ol,ls->title(lang),false); break; case LayoutDocEntry::FileConstantGroups: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNamespaceDeclarations(ol,ls->title(lang),true); - } + if (ls) writeNamespaceDeclarations(ol,ls->title(lang),true); break; case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); } break; case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; case LayoutDocEntry::DetailedDesc: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDetailedDescription(ol,ls->title(lang)); - } + if (ls) writeDetailedDescription(ol,ls->title(lang)); break; case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); @@ -969,8 +945,8 @@ void FileDefImpl::writeDocumentation(OutputList &ol) break; case LayoutDocEntry::MemberDef: { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); } break; case LayoutDocEntry::MemberDefEnd: @@ -1045,7 +1021,7 @@ void FileDefImpl::writeMemberPages(OutputList &ol) void FileDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { - static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); + bool createSubDirs=Config_getBool(CREATE_SUBDIRS); ol.writeString(" <div class=\"navtab\">\n"); ol.writeString(" <table>\n"); @@ -1191,7 +1167,7 @@ void FileDefImpl::writeSourceFooter(OutputList &ol) void FileDefImpl::parseSource(ClangTUParser *clangParser) { - static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); + bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); DevNullCodeDocInterface devNullIntf; #if USE_LIBCLANG if (Doxygen::clangAssistedParsing && clangParser && @@ -1377,7 +1353,7 @@ void FileDefImpl::addUsingDirective(const NamespaceDef *nd) //printf("%p: FileDefImpl::addUsingDirective: %s:%d\n",this,qPrint(name()),usingDirList->count()); } -LinkedRefMap<const NamespaceDef> FileDefImpl::getUsedNamespaces() const +const LinkedRefMap<const NamespaceDef> &FileDefImpl::getUsedNamespaces() const { //printf("%p: FileDefImpl::getUsedNamespace: %s:%d\n",this,qPrint(name()),usingDirList?usingDirList->count():0); return m_usingDirList; @@ -1429,6 +1405,7 @@ void FileDefImpl::addIncludedUsingDirectives(FileDefSet &visitedFiles) for (auto it = unl.rbegin(); it!=unl.rend(); ++it) { const auto *nd = *it; + //printf(" adding using directive for %s\n",qPrint(nd->qualifiedName())); m_usingDirList.prepend(nd->qualifiedName(),nd); } // add using declarations @@ -1466,8 +1443,8 @@ bool FileDefImpl::isIncluded(const QCString &name) const bool FileDefImpl::generateSourceFile() const { - static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); - static bool verbatimHeaders = Config_getBool(VERBATIM_HEADERS); + bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + bool verbatimHeaders = Config_getBool(VERBATIM_HEADERS); return !isReference() && (sourceBrowser || (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC) @@ -1558,7 +1535,7 @@ void FileDefImpl::acquireFileVersion() } const int bufSize=1024; char buf[bufSize]; - int numRead = (int)fread(buf,1,bufSize-1,f); + int numRead = static_cast<int>(fread(buf,1,bufSize-1,f)); Portable::pclose(f); if (numRead>0 && numRead<bufSize) { @@ -1600,8 +1577,8 @@ QCString FileDefImpl::includeName() const void FileDefImpl::addMemberToList(MemberListType lt,MemberDef *md) { - static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); - static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); + bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); + bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); const auto &ml = m_memberLists.get(lt,MemberListContainer::File); ml->setNeedsSorting( ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) || @@ -1670,7 +1647,7 @@ MemberList *FileDefImpl::getMemberList(MemberListType lt) const void FileDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) { - static bool optVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool optVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); MemberList * ml = getMemberList(lt); if (ml) { @@ -1694,7 +1671,7 @@ void FileDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,cons bool FileDefImpl::isLinkableInProject() const { - static bool showFiles = Config_getBool(SHOW_FILES); + bool showFiles = Config_getBool(SHOW_FILES); return hasDocumentation() && !isReference() && (showFiles || isLinkableViaGroup()); } diff --git a/src/filedef.h b/src/filedef.h index 7019485..8b90ecd 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -73,8 +73,6 @@ bool compareFileDefs(const FileDef *fd1, const FileDef *fd2); class FileDef : public DefinitionMutable, public Definition { public: - ~FileDef() {} - // ---------------------------------------------------------------------- virtual DefType definitionType() const = 0; @@ -124,8 +122,8 @@ class FileDef : public DefinitionMutable, public Definition virtual PackageDef *packageDef() const = 0; virtual DirDef *getDirDef() const = 0; - virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const = 0; - virtual LinkedRefMap<const ClassDef> getUsedClasses() const = 0; + virtual const LinkedRefMap<const NamespaceDef> &getUsedNamespaces() const = 0; + virtual const LinkedRefMap<const ClassDef> &getUsedClasses() const = 0; virtual const IncludeInfoList &includeFileList() const = 0; virtual const IncludeInfoList &includedByFileList() const = 0; virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const = 0; diff --git a/src/fileinfo.cpp b/src/fileinfo.cpp index 7924642..fdc6b6c 100644 --- a/src/fileinfo.cpp +++ b/src/fileinfo.cpp @@ -103,13 +103,13 @@ std::string FileInfo::absFilePath() const std::string result; std::error_code ec; fs::path path(m_name); - if (fs::exists(path,ec)) + if (!path.is_relative()) { - result = fs::canonical(path,ec).string(); + result = path.lexically_normal().string(); } else { - result = (fs::current_path(ec) / m_name).string(); + result = (fs::current_path(ec) / m_name).lexically_normal().string(); } correctPath(result); return result; diff --git a/src/filename.h b/src/filename.h index f2eb304..aae254f 100644 --- a/src/filename.h +++ b/src/filename.h @@ -21,6 +21,7 @@ #include "linkedmap.h" #include "config.h" +#include "utf8.h" class FileDef; @@ -60,9 +61,7 @@ class FileNameFn std::string key = input; if (!Config_getBool(CASE_SENSE_NAMES)) { - // convert key to lower case - std::transform(key.begin(),key.end(),key.begin(), - [](char c){ return (char)std::tolower(c); }); + key = convertUTF8ToLower(key); } return key; } diff --git a/src/fileparser.h b/src/fileparser.h index e8b358a..c5bad8c 100644 --- a/src/fileparser.h +++ b/src/fileparser.h @@ -22,7 +22,6 @@ class FileCodeParser : public CodeParserInterface { public: - virtual ~FileCodeParser() {} void parseCode(CodeOutputInterface &codeOutIntf, const QCString &scopeName, const QCString &input, diff --git a/src/formula.cpp b/src/formula.cpp index ba64497..3217ae1 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -54,7 +54,7 @@ struct FormulaManager::Private return DisplaySize(-1,-1); } StringVector formulas; - IntMap formulaMap; + std::map<std::string,size_t> formulaMap; std::map<int,DisplaySize> displaySizeMap; }; @@ -75,10 +75,25 @@ void FormulaManager::readFormulas(const QCString &dir,bool doCompare) { uint formulaCount=0; msg("Reading formula repository...\n"); + std::string readLine; std::string line; - int lineNr=1; - while (getline(f,line)) + std::string prefix("\\_form#"); + int lineNr; + int nextLineNr=1; + bool hasNextLine = !getline(f,readLine).fail(); + while (hasNextLine) { + line = readLine; + lineNr = nextLineNr; + + // look ahead a bit because a formula can be spread over several lines + while ((hasNextLine = !getline(f,readLine).fail())) + { + nextLineNr+=1; + if (!readLine.compare(0, prefix.size(), prefix)) break; + line += "\n" + readLine; + } + // format: \_form#<digits>=<digits>x<digits>:formula size_t hi=line.find('#'); size_t ei=line.find('='); @@ -117,7 +132,6 @@ void FormulaManager::readFormulas(const QCString &dir,bool doCompare) p->storeDisplaySize(id,w,h); } } - lineNr++; } if (doCompare && formulaCount!=p->formulas.size()) { @@ -168,17 +182,17 @@ void FormulaManager::generateImages(const QCString &path,Format format,HighDPI h } t << "\\pagestyle{empty}\n"; t << "\\begin{document}\n"; - for (int i=0; i<(int)p->formulas.size(); i++) + for (size_t i=0; i<p->formulas.size(); i++) { QCString resultName; - resultName.sprintf("form_%d.%s",i,format==Format::Vector?"svg":"png"); + resultName.sprintf("form_%d.%s",static_cast<int>(i),format==Format::Vector?"svg":"png"); // only formulas for which no image exists are generated FileInfo fi(resultName.str()); if (!fi.exists()) { // we force a pagebreak after each formula t << p->formulas[i].c_str() << "\n\\pagebreak\n\n"; - formulasToGenerate.push_back(i); + formulasToGenerate.push_back(static_cast<int>(i)); } Doxygen::indexList->addImageFile(resultName); } @@ -272,8 +286,8 @@ void FormulaManager::generateImages(const QCString &path,Format format,HighDPI h if (zoomFactor<8 || zoomFactor>50) zoomFactor=10; scaleFactor *= zoomFactor/10.0; - int width = (int)((x2-x1)*scaleFactor+0.5); - int height = (int)((y2-y1)*scaleFactor+0.5); + int width = static_cast<int>((x2-x1)*scaleFactor+0.5); + int height = static_cast<int>((y2-y1)*scaleFactor+0.5); p->storeDisplaySize(pageNum,width,height); if (format==Format::Vector) @@ -398,7 +412,7 @@ void FormulaManager::generateImages(const QCString &path,Format format,HighDPI h Portable::sysTimerStop(); sprintf(args,"-q -dNOSAFER -dBATCH -dNOPAUSE -dEPSCrop -sDEVICE=pnggray -dGraphicsAlphaBits=4 -dTextAlphaBits=4 " - "-r%d -sOutputFile=form_%d.png %s_tmp_corr.eps",(int)(scaleFactor*72),pageNum,qPrint(formBase)); + "-r%d -sOutputFile=form_%d.png %s_tmp_corr.eps",static_cast<int>(scaleFactor*72),pageNum,qPrint(formBase)); Portable::sysTimerStart(); if (Portable::system(Portable::ghostScriptCommand(),args)!=0) { @@ -443,9 +457,9 @@ void FormulaManager::generateImages(const QCString &path,Format format,HighDPI h if (f.is_open()) { TextStream t(&f); - for (int i=0; i<(int)p->formulas.size(); i++) + for (size_t i=0; i<p->formulas.size(); i++) { - DisplaySize size = p->getDisplaySize(i); + DisplaySize size = p->getDisplaySize(static_cast<int>(i)); t << "\\_form#" << i; if (size.width!=-1 && size.height!=-1) { @@ -469,18 +483,18 @@ int FormulaManager::addFormula(const std::string &formulaText) auto it = p->formulaMap.find(formulaText); if (it!=p->formulaMap.end()) // already stored { - return it->second; + return static_cast<int>(it->second); } // store new formula - int id = (int)p->formulas.size(); - p->formulaMap.insert(std::pair<std::string,int>(formulaText,id)); + size_t id = p->formulas.size(); + p->formulaMap.insert(std::make_pair(formulaText,id)); p->formulas.push_back(formulaText); - return id; + return static_cast<int>(id); } std::string FormulaManager::findFormula(int formulaId) const { - if (formulaId>=0 && formulaId<(int)p->formulas.size()) + if (formulaId>=0 && formulaId<static_cast<int>(p->formulas.size())) { return p->formulas[formulaId]; } diff --git a/src/fortrancode.l b/src/fortrancode.l index 9ddcd17..12ad042 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -695,7 +695,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") yyextra->contLineNr++; if (Config_getBool(STRIP_CODE_COMMENTS)) { - yyextra->yyLineNr+=((QCString)yyextra->docBlock).contains('\n'); + yyextra->yyLineNr+=yyextra->docBlock.contains('\n'); yyextra->yyLineNr+=1; nextCodeLine(yyscanner); yyextra->endComment=TRUE; @@ -1029,7 +1029,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, Definition *d,const QCString &text) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); + bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); yyextra->tooltipManager.addTooltip(ol,d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); @@ -1523,7 +1523,7 @@ void FortranCodeParser::parseCode(CodeOutputInterface & codeOutIntf, { endCodeLine(yyscanner); } - if (isExampleBlock && yyextra->sourceFileDef) + if (!fileDef && isExampleBlock && yyextra->sourceFileDef) { // delete the temporary file definition used for this example delete yyextra->sourceFileDef; diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 20e30b2..04421c5 100755 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -639,6 +639,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* /*------- type definition -------------------------------------------------------------------------------*/ +<ModuleBody>^{BS}type{BS}"=" {} <Start,ModuleBody>^{BS}type/[^a-z0-9_] { if (YY_START == Start) { diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 4e3150e..85291f5 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -350,15 +350,19 @@ static void generateBriefDoc(TextStream &t,const Definition *def) //printf("*** %p: generateBriefDoc(%s)='%s'\n",def,qPrint(def->name()),qPrint(brief)); if (!brief.isEmpty()) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> root { validatingParseDoc(*parser.get(), - def->briefFile(),def->briefLine(), - def,0,brief,FALSE,FALSE, - QCString(),TRUE,TRUE,Config_getBool(MARKDOWN_SUPPORT)) }; - QCString relPath = relativePathToRoot(def->getOutputFileBase()); - HtmlCodeGenerator htmlGen(t,relPath); - auto visitor = std::make_unique<HtmlDocVisitor>(t,htmlGen,def); - root->accept(visitor.get()); + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + def->briefFile(),def->briefLine(), + def,0,brief,FALSE,FALSE, + QCString(),TRUE,TRUE,Config_getBool(MARKDOWN_SUPPORT)) }; + const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast.get()); + if (astImpl) + { + QCString relPath = relativePathToRoot(def->getOutputFileBase()); + HtmlCodeGenerator htmlGen(t,relPath); + HtmlDocVisitor visitor(t,htmlGen,def); + std::visit(visitor,astImpl->root); + } } } @@ -563,7 +567,7 @@ static QCString convertFileId2Var(const QCString &fileId) static bool generateJSTree(NavIndexEntryList &navIndex,TextStream &t, const std::vector<FTVNode*> &nl,int level,bool &first) { - static QCString htmlOutput = Config_getString(HTML_OUTPUT); + QCString htmlOutput = Config_getString(HTML_OUTPUT); QCString indentStr; indentStr.fill(' ',level*2); bool found=FALSE; diff --git a/src/groupdef.cpp b/src/groupdef.cpp index b5cda7b..f9b3c71 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -201,7 +201,7 @@ void GroupDefImpl::setGroupTitle( const QCString &t ) else { m_title = name(); - m_title[0]=(char)toupper(m_title[0]); + m_title[0]=static_cast<char>(toupper(m_title[0])); m_titleSet = FALSE; } } @@ -236,7 +236,7 @@ void GroupDefImpl::findSectionsInDocumentation() void GroupDefImpl::addFile(const FileDef *def) { - static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); + bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); if (def->isHidden()) return; updateLanguage(def); if (sortBriefDocs) @@ -344,7 +344,7 @@ bool GroupDefImpl::insertMember(const MemberDef *md,bool docOnly) (tSrcMdAl.size()==tMdAl.size()) && // same number of template arguments matchArguments2(srcMd->getOuterScope(),srcMd->getFileDef(),&srcMdAl, md->getOuterScope(),md->getFileDef(),&mdAl, - TRUE + TRUE,srcMd->getLanguage() ) && // matching parameters sameScope // both are found in the same scope ) @@ -701,11 +701,14 @@ void GroupDefImpl::writeTagFile(TextStream &tagFile) break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ml->writeTagFile(tagFile); + MemberList * ml = getMemberList(lmd->type); + if (ml) + { + ml->writeTagFile(tagFile); + } } } break; @@ -793,19 +796,19 @@ void GroupDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc(*parser.get(), - briefFile(),briefLine(),this,0, - briefDescription(),TRUE,FALSE, - QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + briefFile(),briefLine(),this,0, + briefDescription(),TRUE,FALSE, + QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + if (!ast->isEmpty()) { ol.startParagraph(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); ol.writeString(" - "); ol.popGeneratorState(); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); ol.pushGeneratorState(); ol.disable(OutputGenerator::RTF); ol.writeString(" \n"); @@ -1061,24 +1064,30 @@ void GroupDefImpl::writeSummaryLinks(OutputList &ol) const (lde->kind()==LayoutDocEntry::GroupDirs && !m_dirList.empty()) ) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - QCString label = lde->kind()==LayoutDocEntry::GroupClasses ? "nested-classes" : - lde->kind()==LayoutDocEntry::GroupConcepts ? "concepts" : - lde->kind()==LayoutDocEntry::GroupNamespaces ? "namespaces" : - lde->kind()==LayoutDocEntry::GroupFiles ? "files" : - lde->kind()==LayoutDocEntry::GroupNestedGroups ? "groups" : - "dirs"; - ol.writeSummaryLink(QCString(),label,ls->title(lang),first); - first=FALSE; + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (ls) + { + QCString label = lde->kind()==LayoutDocEntry::GroupClasses ? "nested-classes" : + lde->kind()==LayoutDocEntry::GroupConcepts ? "concepts" : + lde->kind()==LayoutDocEntry::GroupNamespaces ? "namespaces" : + lde->kind()==LayoutDocEntry::GroupFiles ? "files" : + lde->kind()==LayoutDocEntry::GroupNestedGroups ? "groups" : + "dirs"; + ol.writeSummaryLink(QCString(),label,ls->title(lang),first); + first=FALSE; + } } else if (lde->kind()==LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml && ml->declVisible()) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); - first=FALSE; + MemberList * ml = getMemberList(lmd->type); + if (ml && ml->declVisible()) + { + ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); + first=FALSE; + } } } } @@ -1091,7 +1100,7 @@ void GroupDefImpl::writeSummaryLinks(OutputList &ol) const void GroupDefImpl::writeDocumentation(OutputList &ol) { - //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + //bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); startFile(ol,getOutputFileBase(),name(),m_title,HLI_Modules); @@ -1124,6 +1133,7 @@ void GroupDefImpl::writeDocumentation(OutputList &ol) SrcLangExt lang=getLanguage(); for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group)) { + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); switch (lde->kind()) { case LayoutDocEntry::BriefDesc: @@ -1133,78 +1143,61 @@ void GroupDefImpl::writeDocumentation(OutputList &ol) startMemberDeclarations(ol); break; case LayoutDocEntry::GroupClasses: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClasses(ol,ls->title(lang)); - } + if (ls) writeClasses(ol,ls->title(lang)); break; case LayoutDocEntry::GroupConcepts: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeConcepts(ol,ls->title(lang)); - } + if (ls) writeConcepts(ol,ls->title(lang)); break; case LayoutDocEntry::GroupInlineClasses: - { - writeInlineClasses(ol); - } + writeInlineClasses(ol); break; case LayoutDocEntry::GroupNamespaces: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNamespaces(ol,ls->title(lang)); - } + if (ls) writeNamespaces(ol,ls->title(lang)); break; case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) + { + writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); + } } break; case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; case LayoutDocEntry::DetailedDesc: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDetailedDescription(ol,ls->title(lang)); - } + if (ls) writeDetailedDescription(ol,ls->title(lang)); break; case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); break; case LayoutDocEntry::MemberDef: { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) + { + writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); + } } break; case LayoutDocEntry::MemberDefEnd: endMemberDocumentation(ol); break; case LayoutDocEntry::GroupNestedGroups: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNestedGroups(ol,ls->title(lang)); - } + if (ls) writeNestedGroups(ol,ls->title(lang)); break; case LayoutDocEntry::GroupPageDocs: writePageDocumentation(ol); break; case LayoutDocEntry::GroupDirs: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDirs(ol,ls->title(lang)); - } + if (ls) writeDirs(ol,ls->title(lang)); break; case LayoutDocEntry::GroupFiles: - { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeFiles(ol,ls->title(lang)); - } + if (ls) writeFiles(ol,ls->title(lang)); break; case LayoutDocEntry::GroupGraph: writeGroupGraph(ol); @@ -1281,7 +1274,7 @@ void GroupDefImpl::writeMemberPages(OutputList &ol) void GroupDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { - static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); + bool createSubDirs=Config_getBool(CREATE_SUBDIRS); ol.writeString(" <div class=\"navtab\">\n"); ol.writeString(" <table>\n"); @@ -1583,8 +1576,8 @@ void GroupDefImpl::addListReferences() void GroupDefImpl::addMemberToList(MemberListType lt,const MemberDef *md) { - static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); - static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); + bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); + bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); const auto &ml = m_memberLists.get(lt,MemberListContainer::Group); ml->setNeedsSorting( ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) || @@ -1698,7 +1691,7 @@ MemberList *GroupDefImpl::getMemberList(MemberListType lt) const void GroupDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) { - static bool optimizeVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool optimizeVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); MemberList * ml = getMemberList(lt); if (optimizeVhdl && ml) @@ -1754,7 +1747,7 @@ void GroupDefImpl::updateLanguage(const Definition *d) bool GroupDefImpl::hasDetailedDescription() const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty() || !inbodyDocumentation().isEmpty()) && diff --git a/src/groupdef.h b/src/groupdef.h index 587c709..ba29dc3 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -49,8 +49,6 @@ class MemberDef; class GroupDef : public DefinitionMutable, public Definition { public: - ~GroupDef() {} - virtual DefType definitionType() const = 0; virtual QCString getOutputFileBase() const = 0; virtual QCString anchor() const = 0; diff --git a/src/growbuf.h b/src/growbuf.h index 00bcfec..ba4c5fe 100644 --- a/src/growbuf.h +++ b/src/growbuf.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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 GROWBUF_H #define GROWBUF_H @@ -13,13 +28,13 @@ class GrowBuf { public: GrowBuf() : m_str(0), m_pos(0), m_len(0) {} - GrowBuf(uint initialSize) : m_pos(0), m_len(initialSize) { m_str=(char*)malloc(m_len); } + GrowBuf(size_t initialSize) : m_pos(0), m_len(initialSize) { m_str=static_cast<char*>(malloc(m_len)); } ~GrowBuf() { free(m_str); } GrowBuf(const GrowBuf &other) { m_len = other.m_len; m_pos = other.m_pos; - m_str = (char*)malloc(m_len); + m_str = static_cast<char*>(malloc(m_len)); memcpy(m_str,other.m_str,m_len); } GrowBuf &operator=(const GrowBuf &other) @@ -29,13 +44,13 @@ class GrowBuf free(m_str); m_len = other.m_len; m_pos = other.m_pos; - m_str = (char*)malloc(m_len); + m_str = static_cast<char*>(malloc(m_len)); memcpy(m_str,other.m_str,m_len); } return *this; } GrowBuf(GrowBuf &&other) - : m_str(std::exchange(other.m_str,(char*)0)) + : m_str(std::exchange(other.m_str,static_cast<char*>(0))) , m_pos(std::exchange(other.m_pos,0)) , m_len(std::exchange(other.m_len,0)) { @@ -46,19 +61,19 @@ class GrowBuf return *this; m_len = std::exchange(other.m_len,0); m_pos = std::exchange(other.m_pos,0); - m_str = std::exchange(other.m_str,(char*)0); + m_str = std::exchange(other.m_str,static_cast<char*>(0)); return *this; } - void reserve(uint size) { if (m_len<size) { m_len = size; m_str = (char*)realloc(m_str,m_len); } } + void reserve(size_t size) { if (m_len<size) { m_len = size; m_str = static_cast<char*>(realloc(m_str,m_len)); } } void clear() { m_pos=0; } - void addChar(char c) { if (m_pos>=m_len) { m_len+=GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + void addChar(char c) { if (m_pos>=m_len) { m_len+=GROW_AMOUNT; m_str = static_cast<char*>(realloc(m_str,m_len)); } m_str[m_pos++]=c; } void addStr(const QCString &s) { if (!s.isEmpty()) { - uint l=s.length(); - if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + size_t l=s.length(); + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = static_cast<char*>(realloc(m_str,m_len)); } strcpy(&m_str[m_pos],s.data()); m_pos+=l; } @@ -66,8 +81,8 @@ class GrowBuf void addStr(const std::string &s) { if (!s.empty()) { - uint l=(uint)s.length(); - if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + size_t l=s.length(); + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = static_cast<char*>(realloc(m_str,m_len)); } strcpy(&m_str[m_pos],s.c_str()); m_pos+=l; } @@ -75,32 +90,32 @@ class GrowBuf void addStr(const char *s) { if (s) { - uint l=(uint)strlen(s); - if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + size_t l=strlen(s); + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = static_cast<char*>(realloc(m_str,m_len)); } strcpy(&m_str[m_pos],s); m_pos+=l; } } - void addStr(const char *s,uint n) { + void addStr(const char *s,size_t n) { if (s) { - uint l=(uint)strlen(s); + size_t l=strlen(s); if (n<l) l=n; - if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); } + if (m_pos+l>=m_len) { m_len+=l+GROW_AMOUNT; m_str = static_cast<char*>(realloc(m_str,m_len)); } strncpy(&m_str[m_pos],s,n); m_pos+=l; } } char *get() { return m_str; } const char *get() const { return m_str; } - uint getPos() const { return m_pos; } - void setPos(uint newPos) { m_pos = newPos; } - char at(uint i) const { return m_str[i]; } + size_t getPos() const { return m_pos; } + void setPos(size_t newPos) { m_pos = newPos; } + char at(size_t i) const { return m_str[i]; } bool empty() const { return m_pos==0; } private: char *m_str; - uint m_pos; - uint m_len; + size_t m_pos; + size_t m_len; }; #endif diff --git a/src/growvector.h b/src/growvector.h new file mode 100644 index 0000000..4b5d81a --- /dev/null +++ b/src/growvector.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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 GROWVECTOR_H +#define GROWVECTOR_H + +#include <vector> +#include <memory> +#include <iterator> + +/** @brief std::vector like container optimised for pushing elements to the back. + * + * It differs from std::vector in that it can grow without invalidating + * pointers to its members just like std::deque and std::list. + * + * It differs from std::deque in that the value can be incomplete + * just like std::vector. + * + * It differs from std::list in that it does not need to allocate each node + * separately and provides random access to its members. + * + * It is implemented as a vector of chunks where each chunk is a fixed capacity vector of T. + */ +template<class T> +class GrowVector +{ + private: + static const size_t chunkBits = 4; // a chunk holds 2^bits elements + static const size_t chunkSize = 1 << chunkBits; + static const size_t chunkMask = chunkSize-1; + struct Chunk + { + Chunk() { data.reserve(chunkSize); } + std::vector<T> data; + }; + using ChunkPtr = std::unique_ptr<Chunk>; + + public: + /// @brief bidirectional iterator + template<class C,class I> + class Iterator + { + public: + using iterator_category = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = I; + using pointer = I*; + using reference = I&; + + Iterator(C &vec,size_t pos) : m_vec(&vec), m_pos(pos) {} + Iterator(const Iterator &other) = default; + Iterator &operator=(const Iterator &other) = default; + reference operator*() const { return m_vec->at(m_pos); } + pointer operator->() { return &m_vec->at(m_pos); } + Iterator& operator++() { m_pos++; return *this; } + Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; } + Iterator& operator--() { m_pos--; return *this; } + Iterator operator--(int) { Iterator tmp = *this; --(*this); return tmp; } + friend bool operator== (const Iterator& a, const Iterator& b) { return a.m_pos == b.m_pos; }; + friend bool operator!= (const Iterator& a, const Iterator& b) { return a.m_pos != b.m_pos; }; + + private: + C *m_vec; + size_t m_pos; + }; + using iterator = Iterator<GrowVector,T>; + using const_iterator = Iterator<const GrowVector,const T>; + + /// returns an iterator to the beginning + iterator begin() { return iterator(*this,0); } + /// returns an iterator to the beginning + const_iterator begin() const { return const_iterator(*this,0); } + + /// returns an iterator to the end + iterator end() { return iterator(*this,size()); } + /// returns an iterator to the end + const_iterator end() const { return const_iterator(*this,size()); } + + /// returns the number of elements + size_t size() const + { + return m_chunks.empty() ? 0 : (m_chunks.size()-1)*chunkSize + + m_chunks.back()->data.size(); + } + + /// adds an element to the end + void push_back(T &&t) + { + make_room(); + m_chunks.back()->data.push_back(std::move(t)); + } + + /// constructs an element in-place at the end + template<class...Args> + void emplace_back(Args&&...args) + { + make_room(); + m_chunks.back()->data.emplace_back(std::forward<Args>(args)...); + } + + /// removes the last element + void pop_back() + { + m_chunks.back()->data.pop_back(); + if (m_chunks.back()->data.size()==0) // remove chunk if empty + { + m_chunks.pop_back(); + } + } + + /// access specified element + T &at(size_t i) { return m_chunks.at(i>>chunkBits)->data.at(i&chunkMask); } + /// access specified element + const T &at(size_t i) const { return m_chunks.at(i>>chunkBits)->data.at(i&chunkMask); } + + /// access the first element + T &front() { return m_chunks.front()->data.front(); } + /// access the first element + const T &front() const { return m_chunks.front()->data.front(); } + + /// access the last element + T &back() { return m_chunks.back()->data.back(); } + /// access the last element + const T &back() const { return m_chunks.back()->data.back(); } + + /// checks whether the container is empty + bool empty() const { return m_chunks.empty(); } + + /// clears the contents + void clear() { m_chunks.clear(); } + + private: + void make_room() + { + if (m_chunks.empty() || + m_chunks.back()->data.size()==chunkSize) // add new chuck if needed + { + m_chunks.push_back(std::make_unique<Chunk>()); + } + } + std::vector<ChunkPtr> m_chunks; +}; + +#endif diff --git a/src/htags.cpp b/src/htags.cpp index 03a8686..5cff662 100644 --- a/src/htags.cpp +++ b/src/htags.cpp @@ -160,8 +160,8 @@ QCString Htags::path2URL(const QCString &path) { QCString url,symName=path; QCString dir = g_inputDir.absPath(); - int dl=dir.length(); - if ((int)symName.length()>dl+1) + size_t dl=dir.length(); + if (symName.length()>dl+1) { symName = symName.mid(dl+1); } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index d3f5c95..04598c2 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -102,66 +102,54 @@ static QCString convertIndexWordToAnchor(const QCString &word) return result; } -static bool mustBeOutsideParagraph(const DocNode *n) -{ - switch (n->kind()) - { - /* <ul> */ - case DocNode::Kind_HtmlList: - case DocNode::Kind_SimpleList: - case DocNode::Kind_AutoList: - /* <dl> */ - case DocNode::Kind_SimpleSect: - case DocNode::Kind_ParamSect: - case DocNode::Kind_HtmlDescList: - case DocNode::Kind_XRefItem: - /* <table> */ - case DocNode::Kind_HtmlTable: - /* <h?> */ - case DocNode::Kind_Section: - case DocNode::Kind_HtmlHeader: - /* \internal */ - case DocNode::Kind_Internal: - /* <div> */ - case DocNode::Kind_Include: - case DocNode::Kind_SecRefList: - /* <hr> */ - case DocNode::Kind_HorRuler: - /* CopyDoc gets paragraph markers from the wrapping DocPara node, - * but needs to insert them for all documentation being copied to - * preserve formatting. - */ - case DocNode::Kind_Copy: - /* <blockquote> */ - case DocNode::Kind_HtmlBlockQuote: - /* \parblock */ - case DocNode::Kind_ParBlock: - case DocNode::Kind_IncOperator: - return TRUE; - case DocNode::Kind_Verbatim: - { - DocVerbatim *dv = (DocVerbatim*)n; - DocVerbatim::Type t = dv->type(); - if (t == DocVerbatim::JavaDocCode || t == DocVerbatim::JavaDocLiteral) return FALSE; - return t!=DocVerbatim::HtmlOnly || dv->isBlock(); - } - case DocNode::Kind_StyleChange: - return ((DocStyleChange*)n)->style()==DocStyleChange::Preformatted || - ((DocStyleChange*)n)->style()==DocStyleChange::Div || - ((DocStyleChange*)n)->style()==DocStyleChange::Center; - case DocNode::Kind_Formula: - return !((DocFormula*)n)->isInline(); - case DocNode::Kind_Image: - return !((DocImage*)n)->isInlineImage(); - default: - break; + + +static bool mustBeOutsideParagraph(const DocNodeVariant &n) +{ + //printf("mustBeOutsideParagraph(%s)=",docNodeName(n)); + if (holds_one_of_alternatives< /* <ul> */ DocHtmlList, DocSimpleList, DocAutoList, + /* <dl> */ DocSimpleSect, DocParamSect, DocHtmlDescList, DocXRefItem, + /* <table> */ DocHtmlTable, + /* <h?> */ DocSection, DocHtmlHeader, + /* \internal */ DocInternal, + /* <div> */ DocInclude, DocSecRefList, + /* <hr> */ DocHorRuler, + /* <blockquote> */ DocHtmlBlockQuote, + /* \parblock */ DocParBlock, + DocIncOperator >(n)) + { + return TRUE; + } + const DocVerbatim *dv = std::get_if<DocVerbatim>(&n); + if (dv) + { + DocVerbatim::Type t = dv->type(); + if (t == DocVerbatim::JavaDocCode || t == DocVerbatim::JavaDocLiteral) return FALSE; + return t!=DocVerbatim::HtmlOnly || dv->isBlock(); + } + const DocStyleChange *sc = std::get_if<DocStyleChange>(&n); + if (sc) + { + return sc->style()==DocStyleChange::Preformatted || + sc->style()==DocStyleChange::Div || + sc->style()==DocStyleChange::Center; + } + const DocFormula *df = std::get_if<DocFormula>(&n); + if (df) + { + return !df->isInline(); + } + const DocImage *di = std::get_if<DocImage>(&n); + if (di) + { + return !di->isInlineImage(); } return FALSE; } -static bool isDocVerbatimVisible(const DocVerbatim *s) +static bool isDocVerbatimVisible(const DocVerbatim &s) { - switch(s->type()) + switch (s.type()) { case DocVerbatim::ManOnly: case DocVerbatim::LatexOnly: @@ -174,9 +162,9 @@ static bool isDocVerbatimVisible(const DocVerbatim *s) } } -static bool isDocIncludeVisible(const DocInclude *s) +static bool isDocIncludeVisible(const DocInclude &s) { - switch (s->type()) + switch (s.type()) { case DocInclude::DontInclude: case DocInclude::LatexInclude: @@ -190,9 +178,9 @@ static bool isDocIncludeVisible(const DocInclude *s) } } -static bool isDocIncOperatorVisible(const DocIncOperator *s) +static bool isDocIncOperatorVisible(const DocIncOperator &s) { - switch (s->type()) + switch (s.type()) { case DocIncOperator::Skip: return FALSE; @@ -201,27 +189,34 @@ static bool isDocIncOperatorVisible(const DocIncOperator *s) } } -static bool isInvisibleNode(const DocNode *node) +static bool isInvisibleNode(const DocNodeVariant &node) { - return (node->kind()==DocNode::Kind_WhiteSpace) - || // skip over image nodes that are not for HTML output - (node->kind()==DocNode::Kind_Image && ((DocImage*)node)->type()!=DocImage::Html) - || // skip over verbatim nodes that are not visible in the HTML output - (node->kind()==DocNode::Kind_Verbatim && !isDocVerbatimVisible((DocVerbatim*)node)) - || // skip over include nodes that are not visible in the HTML output - (node->kind()==DocNode::Kind_Include && !isDocIncludeVisible((DocInclude*)node)) - || // skip over include operator nodes that are not visible in the HTML output - (node->kind()==DocNode::Kind_IncOperator && !isDocIncOperatorVisible((DocIncOperator*)node)) - ; + //printf("isInvisibleNode(%s)\n",docNodeName(node)); + // skip over white space + const DocWhiteSpace *ws = std::get_if<DocWhiteSpace>(&node); + if (ws) return true; + // skip over image nodes that are not for HTML output + const DocImage *di = std::get_if<DocImage>(&node); + if (di) return di->type()!=DocImage::Html; + // skip over verbatim nodes that are not visible in the HTML output + const DocVerbatim *dv = std::get_if<DocVerbatim>(&node); + if (dv) return !isDocVerbatimVisible(*dv); + // skip over include nodes that are not visible in the HTML output + const DocInclude *dinc = std::get_if<DocInclude>(&node); + if (dinc) return !isDocIncludeVisible(*dinc); + const DocIncOperator *dio = std::get_if<DocIncOperator>(&node); + // skip over include operator nodes that are not visible in the HTML output + if (dio) return !isDocIncOperatorVisible(*dio); + return false; } static void mergeHtmlAttributes(const HtmlAttribList &attribs, HtmlAttribList &mergeInto) { for (const auto &att : attribs) { - auto it = std::find_if(mergeInto.begin(),mergeInto.end(), + auto it = std::find_if(std::begin(mergeInto),std::end(mergeInto), [&att](const auto &opt) { return opt.name==att.name; }); - if (it!=mergeInto.end()) // attribute name already in mergeInto + if (it!=std::end(mergeInto)) // attribute name already in mergeInto { it->value = it->value + " " + att.value; } @@ -277,37 +272,50 @@ static QCString htmlAttribsToString(const HtmlAttribList &attribs, QCString *pAl HtmlDocVisitor::HtmlDocVisitor(TextStream &t,CodeOutputInterface &ci, const Definition *ctx) - : DocVisitor(DocVisitor_Html), m_t(t), m_ci(ci), m_ctx(ctx) + : m_t(t), m_ci(ci), m_ctx(ctx) { if (ctx) m_langExt=ctx->getDefFileExtension(); } +template<class T> +void HtmlDocVisitor::visitCaption(TextStream &t,const T &n) +{ + if (n.hasCaption()) + { + t << "<div class=\"caption\">\n"; + for (const auto &child : n.children()) + { + std::visit(*this, child); + } + t << "</div>\n"; + } +} + //-------------------------------------- // visitor functions for leaf nodes //-------------------------------------- -void HtmlDocVisitor::visit(DocWord *w) +void HtmlDocVisitor::operator()(const DocWord &w) { - //printf("word: %s\n",qPrint(w->word())); if (m_hide) return; - filter(w->word()); + filter(w.word()); } -void HtmlDocVisitor::visit(DocLinkedWord *w) +void HtmlDocVisitor::operator()(const DocLinkedWord &w) { if (m_hide) return; - //printf("linked word: %s\n",qPrint(w->word())); - startLink(w->ref(),w->file(),w->relPath(),w->anchor(),w->tooltip()); - filter(w->word()); + //printf("linked word: %s\n",qPrint(w.word())); + startLink(w.ref(),w.file(),w.relPath(),w.anchor(),w.tooltip()); + filter(w.word()); endLink(); } -void HtmlDocVisitor::visit(DocWhiteSpace *w) +void HtmlDocVisitor::operator()(const DocWhiteSpace &w) { if (m_hide) return; if (m_insidePre) { - m_t << w->chars(); + m_t << w.chars(); } else { @@ -315,39 +323,40 @@ void HtmlDocVisitor::visit(DocWhiteSpace *w) } } -void HtmlDocVisitor::visit(DocSymbol *s) +void HtmlDocVisitor::operator()(const DocSymbol &s) { if (m_hide) return; if (m_insideTitle && - (s->symbol()==DocSymbol::Sym_Quot || s->symbol()==DocSymbol::Sym_quot)) // escape "'s inside title="..." + (s.symbol()==HtmlEntityMapper::Sym_Quot || s.symbol()==HtmlEntityMapper::Sym_quot)) // escape "'s inside title="..." { m_t << """; } else { - const char *res = HtmlEntityMapper::instance()->html(s->symbol()); + const char *res = HtmlEntityMapper::instance()->html(s.symbol()); if (res) { m_t << res; } else { - err("HTML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + err("HTML: non supported HTML-entity found: %s\n", + HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } } } -void HtmlDocVisitor::visit(DocEmoji *s) +void HtmlDocVisitor::operator()(const DocEmoji &s) { if (m_hide) return; - const char *res = EmojiEntityMapper::instance()->unicode(s->index()); + const char *res = EmojiEntityMapper::instance()->unicode(s.index()); if (res) { - m_t << "<span class=\"emoji\">"<<res<<"</span>"; + m_t << "<span class=\"emoji\">" << res << "</span>"; } else { - m_t << s->name(); + m_t << s.name(); } } @@ -379,12 +388,12 @@ void HtmlDocVisitor::writeObfuscatedMailAddress(const QCString &url) } } -void HtmlDocVisitor::visit(DocURL *u) +void HtmlDocVisitor::operator()(const DocURL &u) { if (m_hide) return; - if (u->isEmail()) // mail address + if (u.isEmail()) // mail address { - QCString url = u->url(); + QCString url = u.url(); // obfuscate the mail address link writeObfuscatedMailAddress(url); if (!Config_getBool(OBFUSCATE_EMAILS)) @@ -411,66 +420,66 @@ void HtmlDocVisitor::visit(DocURL *u) else // web address { m_t << "<a href=\""; - m_t << u->url() << "\">"; - filter(u->url()); + m_t << u.url() << "\">"; + filter(u.url()); m_t << "</a>"; } } -void HtmlDocVisitor::visit(DocLineBreak *br) +void HtmlDocVisitor::operator()(const DocLineBreak &br) { if (m_hide) return; - m_t << "<br "<< htmlAttribsToString(br->attribs()) << " />\n"; + m_t << "<br "<< htmlAttribsToString(br.attribs()) << " />\n"; } -void HtmlDocVisitor::visit(DocHorRuler *hr) +void HtmlDocVisitor::operator()(const DocHorRuler &hr) { if (m_hide) return; forceEndParagraph(hr); - m_t << "<hr "<< htmlAttribsToString(hr->attribs()) << " />\n"; + m_t << "<hr "<< htmlAttribsToString(hr.attribs()) << " />\n"; forceStartParagraph(hr); } -void HtmlDocVisitor::visit(DocStyleChange *s) +void HtmlDocVisitor::operator()(const DocStyleChange &s) { if (m_hide) return; - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) m_t << "<b" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</b>"; + if (s.enable()) m_t << "<b" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</b>"; break; case DocStyleChange::S: - if (s->enable()) m_t << "<s" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</s>"; + if (s.enable()) m_t << "<s" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</s>"; break; case DocStyleChange::Strike: - if (s->enable()) m_t << "<strike" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</strike>"; + if (s.enable()) m_t << "<strike" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</strike>"; break; case DocStyleChange::Del: - if (s->enable()) m_t << "<del" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</del>"; + if (s.enable()) m_t << "<del" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</del>"; break; case DocStyleChange::Underline: - if (s->enable()) m_t << "<u" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</u>"; + if (s.enable()) m_t << "<u" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</u>"; break; case DocStyleChange::Ins: - if (s->enable()) m_t << "<ins" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</ins>"; + if (s.enable()) m_t << "<ins" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</ins>"; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "<em" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</em>"; + if (s.enable()) m_t << "<em" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</em>"; break; case DocStyleChange::Code: - if (s->enable()) m_t << "<code" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</code>"; + if (s.enable()) m_t << "<code" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</code>"; break; case DocStyleChange::Subscript: - if (s->enable()) m_t << "<sub" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</sub>"; + if (s.enable()) m_t << "<sub" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</sub>"; break; case DocStyleChange::Superscript: - if (s->enable()) m_t << "<sup" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</sup>"; + 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 { @@ -479,16 +488,16 @@ void HtmlDocVisitor::visit(DocStyleChange *s) } break; case DocStyleChange::Small: - if (s->enable()) m_t << "<small" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</small>"; + if (s.enable()) m_t << "<small" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</small>"; break; case DocStyleChange::Cite: - if (s->enable()) m_t << "<cite" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</cite>"; + if (s.enable()) m_t << "<cite" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</cite>"; break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s.enable()) { forceEndParagraph(s); - m_t << "<pre" << htmlAttribsToString(s->attribs()) << ">"; + m_t << "<pre" << htmlAttribsToString(s.attribs()) << ">"; m_insidePre=TRUE; } else @@ -499,10 +508,10 @@ 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 { @@ -511,61 +520,39 @@ void HtmlDocVisitor::visit(DocStyleChange *s) } break; case DocStyleChange::Span: - if (s->enable()) m_t << "<span" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</span>"; + if (s.enable()) m_t << "<span" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</span>"; break; case DocStyleChange::Details: - if (s->enable()) m_t << "<details" << htmlAttribsToString(s->attribs()) << ">\n"; else m_t << "</details>\n"; + if (s.enable()) m_t << "<details" << htmlAttribsToString(s.attribs()) << ">\n"; else m_t << "</details>\n"; break; case DocStyleChange::Summary: - if (s->enable()) m_t << "<summary" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</summary>"; + if (s.enable()) m_t << "<summary" << htmlAttribsToString(s.attribs()) << ">"; else m_t << "</summary>"; break; } } +///-------------------------------------------------------------------------------------- -static void visitPreCaption(TextStream &t, DocVerbatim *s) -{ - if (s->hasCaption()) - { - t << "<div class=\"caption\">\n"; - } -} - - -static void visitPostCaption(TextStream &t, DocVerbatim *s) -{ - if (s->hasCaption()) - { - t << "</div>\n"; - } -} - - -static void visitCaption(HtmlDocVisitor *parent, DocNodeList &children) -{ - for (const auto &n : children) n->accept(parent); -} - -void HtmlDocVisitor::visit(DocVerbatim *s) +void HtmlDocVisitor::operator()(const DocVerbatim &s) { if (m_hide) return; QCString lang = m_langExt; - if (!s->language().isEmpty()) // explicit language setting + if (!s.language().isEmpty()) // explicit language setting { - lang = s->language(); + lang = s.language(); } SrcLangExt langExt = getLanguageFromCodeLang(lang); - switch(s->type()) + switch(s.type()) { case DocVerbatim::Code: forceEndParagraph(s); m_ci.startCodeFragment("DoxyCode"); getCodeParser(lang).parseCode(m_ci, - s->context(), - s->text(), + s.context(), + s.text(), langExt, - s->isExample(), - s->exampleFile(), + s.isExample(), + s.exampleFile(), 0, // fileDef -1, // startLine -1, // endLine @@ -580,23 +567,23 @@ void HtmlDocVisitor::visit(DocVerbatim *s) case DocVerbatim::Verbatim: forceEndParagraph(s); m_t << "<pre class=\"fragment\">"; - filter(s->text()); + filter(s.text()); m_t << "</pre>"; forceStartParagraph(s); break; case DocVerbatim::JavaDocLiteral: - filter(s->text(), true); + filter(s.text(), true); break; case DocVerbatim::JavaDocCode: m_t << "<code class=\"JavaDocCode\">"; - filter(s->text(), true); + filter(s.text(), true); m_t << "</code>"; break; case DocVerbatim::HtmlOnly: { - if (s->isBlock()) forceEndParagraph(s); - m_t << s->text(); - if (s->isBlock()) forceStartParagraph(s); + if (s.isBlock()) forceEndParagraph(s); + m_t << s.text(); + if (s.isBlock()) forceStartParagraph(s); } break; case DocVerbatim::ManOnly: @@ -625,15 +612,13 @@ void HtmlDocVisitor::visit(DocVerbatim *s) } else { - QCString stext = s->text(); + QCString stext = s.text(); file.write( stext.data(), stext.length() ); file.close(); m_t << "<div class=\"dotgraph\">\n"; - writeDotFile(fileName,s->relPath(),s->context(),s->srcFile(),s->srcLine()); - visitPreCaption(m_t, s); - visitCaption(this, s->children()); - visitPostCaption(m_t, s); + writeDotFile(fileName,s.relPath(),s.context(),s.srcFile(),s.srcLine()); + visitCaption(m_t, s); m_t << "</div>\n"; if (Config_getBool(DOT_CLEANUP)) Dir().remove(fileName.str()); @@ -660,17 +645,15 @@ void HtmlDocVisitor::visit(DocVerbatim *s) else { QCString text = "msc {"; - text+=s->text(); + text+=s.text(); text+="}"; file.write( text.data(), text.length() ); file.close(); m_t << "<div class=\"mscgraph\">\n"; - writeMscFile(baseName+".msc",s->relPath(),s->context(),s->srcFile(),s->srcLine()); - visitPreCaption(m_t, s); - visitCaption(this, s->children()); - visitPostCaption(m_t, s); + writeMscFile(baseName+".msc",s.relPath(),s.context(),s.srcFile(),s.srcLine()); + visitCaption(m_t, s); m_t << "</div>\n"; if (Config_getBool(DOT_CLEANUP)) Dir().remove(baseName.str()+".msc"); @@ -681,7 +664,7 @@ void HtmlDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: { forceEndParagraph(s); - static QCString htmlOutput = Config_getString(HTML_OUTPUT); + QCString htmlOutput = Config_getString(HTML_OUTPUT); QCString imgExt = getDotImageExtension(); PlantumlManager::OutputFormat format = PlantumlManager::PUML_BITMAP; // default : PUML_BITMAP if (imgExt=="svg") @@ -689,13 +672,11 @@ void HtmlDocVisitor::visit(DocVerbatim *s) format = PlantumlManager::PUML_SVG; } QCString baseName = PlantumlManager::instance().writePlantUMLSource( - htmlOutput,s->exampleFile(), - s->text(),format,s->engine(),s->srcFile(),s->srcLine()); + htmlOutput,s.exampleFile(), + s.text(),format,s.engine(),s.srcFile(),s.srcLine()); m_t << "<div class=\"plantumlgraph\">\n"; - writePlantUMLFile(baseName,s->relPath(),s->context(),s->srcFile(),s->srcLine()); - visitPreCaption(m_t, s); - visitCaption(this, s->children()); - visitPostCaption(m_t, s); + writePlantUMLFile(baseName,s.relPath(),s.context(),s.srcFile(),s.srcLine()); + visitCaption(m_t, s); m_t << "</div>\n"; forceStartParagraph(s); } @@ -703,27 +684,27 @@ void HtmlDocVisitor::visit(DocVerbatim *s) } } -void HtmlDocVisitor::visit(DocAnchor *anc) +void HtmlDocVisitor::operator()(const DocAnchor &anc) { if (m_hide) return; - m_t << "<a class=\"anchor\" id=\"" << anc->anchor() << "\"" << htmlAttribsToString(anc->attribs()) << "></a>"; + m_t << "<a class=\"anchor\" id=\"" << anc.anchor() << "\"" << htmlAttribsToString(anc.attribs()) << "></a>"; } -void HtmlDocVisitor::visit(DocInclude *inc) +void HtmlDocVisitor::operator()(const DocInclude &inc) { if (m_hide) return; - SrcLangExt langExt = getLanguageFromFileName(inc->extension()); - switch(inc->type()) + SrcLangExt langExt = getLanguageFromFileName(inc.extension()); + switch(inc.type()) { case DocInclude::Include: forceEndParagraph(inc); m_ci.startCodeFragment("DoxyCode"); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), 0, // fileDef -1, // startLine -1, // endLine @@ -739,14 +720,14 @@ void HtmlDocVisitor::visit(DocInclude *inc) { forceEndParagraph(inc); m_ci.startCodeFragment("DoxyCode"); - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, // fileDef, -1, // start line -1, // end line @@ -770,15 +751,15 @@ void HtmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::HtmlInclude: { - if (inc->isBlock()) forceEndParagraph(inc); - m_t << inc->text(); - if (inc->isBlock()) forceStartParagraph(inc); + if (inc.isBlock()) forceEndParagraph(inc); + m_t << inc.text(); + if (inc.isBlock()) forceStartParagraph(inc); } break; case DocInclude::VerbInclude: forceEndParagraph(inc); m_t << "<pre class=\"fragment\">"; - filter(inc->text()); + filter(inc.text()); m_t << "</pre>"; forceStartParagraph(inc); break; @@ -786,12 +767,12 @@ void HtmlDocVisitor::visit(DocInclude *inc) { forceEndParagraph(inc); m_ci.startCodeFragment("DoxyCode"); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), 0, -1, // startLine -1, // endLine @@ -808,16 +789,16 @@ void HtmlDocVisitor::visit(DocInclude *inc) { forceEndParagraph(inc); m_ci.startCodeFragment("DoxyCode"); - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, - lineBlock(inc->text(),inc->blockId()), + lineBlock(inc.text(),inc.blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef @@ -837,44 +818,44 @@ void HtmlDocVisitor::visit(DocInclude *inc) } } -void HtmlDocVisitor::visit(DocIncOperator *op) +void HtmlDocVisitor::operator()(const DocIncOperator &op) { //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", - // op->type(),op->isFirst(),op->isLast(),qPrint(op->text())); - if (op->isFirst()) + // op.type(),op.isFirst(),op.isLast(),qPrint(op.text())); + if (op.isFirst()) { forceEndParagraph(op); if (!m_hide) m_ci.startCodeFragment("DoxyCode"); pushHidden(m_hide); m_hide=TRUE; } - QCString locLangExt = getFileNameExtension(op->includeFileName()); + 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) { m_hide = popHidden(); if (!m_hide) { FileDef *fd = 0; - if (!op->includeFileName().isEmpty()) + if (!op.includeFileName().isEmpty()) { - FileInfo cfi( op->includeFileName().str() ); + FileInfo cfi( op.includeFileName().str() ); fd = createFileDef( cfi.dirPath(), cfi.fileName() ); } getCodeParser(locLangExt).parseCode( m_ci, - op->context(), - op->text(), + op.context(), + op.text(), langExt, - op->isExample(), - op->exampleFile(), + op.isExample(), + op.exampleFile(), fd, // fileDef - op->line(), // startLine + op.line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - op->showLineNo(), // show line numbers + op.showLineNo(), // show line numbers m_ctx // search context ); if (fd) delete fd; @@ -882,7 +863,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op) pushHidden(m_hide); m_hide=TRUE; } - if (op->isLast()) + if (op.isLast()) { m_hide = popHidden(); if (!m_hide) m_ci.endCodeFragment("DoxyCode"); @@ -894,10 +875,10 @@ void HtmlDocVisitor::visit(DocIncOperator *op) } } -void HtmlDocVisitor::visit(DocFormula *f) +void HtmlDocVisitor::operator()(const DocFormula &f) { if (m_hide) return; - bool bDisplay = !f->isInline(); + bool bDisplay = !f.isInline(); if (bDisplay) { forceEndParagraph(f); @@ -906,7 +887,7 @@ void HtmlDocVisitor::visit(DocFormula *f) if (Config_getBool(USE_MATHJAX)) { - QCString text = f->text(); + QCString text = f.text(); bool closeInline = FALSE; if (!bDisplay && !text.isEmpty() && text.at(0)=='$' && text.at(text.length()-1)=='$') @@ -931,9 +912,9 @@ void HtmlDocVisitor::visit(DocFormula *f) m_t << "<img class=\"formula" << (bDisplay ? "Dsp" : "Inl"); m_t << "\" alt=\""; - filterQuotedCdataAttr(f->text()); + filterQuotedCdataAttr(f.text()); m_t << "\""; - m_t << " src=\"" << f->relPath() << f->name(); + m_t << " src=\"" << f.relPath() << f.name(); if (Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg) { m_t << ".svg"; @@ -942,7 +923,7 @@ void HtmlDocVisitor::visit(DocFormula *f) { m_t << ".png"; } - FormulaManager::DisplaySize size = FormulaManager::instance().displaySize(f->id()); + FormulaManager::DisplaySize size = FormulaManager::instance().displaySize(f.id()); if (size.width!=-1) { m_t << "\" width=\"" << size.width; @@ -960,41 +941,41 @@ void HtmlDocVisitor::visit(DocFormula *f) } } -void HtmlDocVisitor::visit(DocIndexEntry *e) +void HtmlDocVisitor::operator()(const DocIndexEntry &e) { - QCString anchor = convertIndexWordToAnchor(e->entry()); - if (e->member()) + QCString anchor = convertIndexWordToAnchor(e.entry()); + if (e.member()) { - anchor.prepend(e->member()->anchor()+"_"); + anchor.prepend(e.member()->anchor()+"_"); } m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>"; //printf("*** DocIndexEntry: word='%s' scope='%s' member='%s'\n", - // qPrint(e->entry()), - // e->scope() ? qPrint(e->scope()->name()) : "<null>", - // e->member() ? qPrint(e->member()->name()) : "<null>" + // qPrint(e.entry()), + // e.scope() ? qPrint(e.scope()->name()) : "<null>", + // e.member() ? qPrint(e.member()->name()) : "<null>" // ); - Doxygen::indexList->addIndexItem(e->scope(),e->member(),anchor,e->entry()); + Doxygen::indexList->addIndexItem(e.scope(),e.member(),anchor,e.entry()); } -void HtmlDocVisitor::visit(DocSimpleSectSep *) +void HtmlDocVisitor::operator()(const DocSimpleSectSep &) { m_t << "</dd>\n"; m_t << "<dd>\n"; } -void HtmlDocVisitor::visit(DocCite *cite) +void HtmlDocVisitor::operator()(const DocCite &cite) { if (m_hide) return; - if (!cite->file().isEmpty()) + if (!cite.file().isEmpty()) { - startLink(cite->ref(),cite->file(),cite->relPath(),cite->anchor()); + startLink(cite.ref(),cite.file(),cite.relPath(),cite.anchor()); } else { m_t << "<b>["; } - filter(cite->text()); - if (!cite->file().isEmpty()) + filter(cite.text()); + if (!cite.file().isEmpty()) { endLink(); } @@ -1010,12 +991,12 @@ void HtmlDocVisitor::visit(DocCite *cite) //-------------------------------------- -void HtmlDocVisitor::visitPre(DocAutoList *l) +void HtmlDocVisitor::operator()(const DocAutoList &l) { //printf("DocAutoList::visitPre\n"); if (m_hide) return; forceEndParagraph(l); - if (l->isEnumList()) + if (l.isEnumList()) { // // Do list type based on depth: @@ -1025,20 +1006,15 @@ void HtmlDocVisitor::visitPre(DocAutoList *l) // A. // 1. (repeat)... // - m_t << "<ol type=\"" << types[l->depth() % NUM_HTML_LIST_TYPES] << "\">"; + m_t << "<ol type=\"" << types[l.depth() % NUM_HTML_LIST_TYPES] << "\">"; } else { m_t << "<ul>"; } - if (!l->isPreformatted()) m_t << "\n"; -} - -void HtmlDocVisitor::visitPost(DocAutoList *l) -{ - //printf("DocAutoList::visitPost\n"); - if (m_hide) return; - if (l->isEnumList()) + if (!l.isPreformatted()) m_t << "\n"; + visitChildren(l); + if (l.isEnumList()) { m_t << "</ol>"; } @@ -1046,269 +1022,249 @@ void HtmlDocVisitor::visitPost(DocAutoList *l) { m_t << "</ul>"; } - if (!l->isPreformatted()) m_t << "\n"; + if (!l.isPreformatted()) m_t << "\n"; forceStartParagraph(l); } -void HtmlDocVisitor::visitPre(DocAutoListItem *) +void HtmlDocVisitor::operator()(const DocAutoListItem &li) { if (m_hide) return; m_t << "<li>"; + visitChildren(li); + m_t << "</li>"; + if (!li.isPreformatted()) m_t << "\n"; } -void HtmlDocVisitor::visitPost(DocAutoListItem *li) +template<class Node> +static bool holds_value(const Node *val,const DocNodeVariant &v) { - if (m_hide) return; - m_t << "</li>"; - if (!li->isPreformatted()) m_t << "\n"; + bool b = std::visit([&](auto &&x) { + //printf("holds_value val=%s (%p) v=%s (%p)\n", + // docNodeName(*val),(void*)val,docNodeName(v),(void *)&x); + return val==static_cast<const DocNode*>(&x); + }, v); + return b; } template<class T> -bool isFirstChildNode(T *parent, DocNode *node) +bool isFirstChildNode(const T *parent, const DocPara &node) { - return !parent->children().empty() && parent->children().front().get()==node; + return !parent->children().empty() && holds_value(&node,parent->children().front()); } template<class T> -bool isLastChildNode(T *parent, DocNode *node) +bool isLastChildNode(const T *parent, const DocPara &node) { - return !parent->children().empty() && parent->children().back().get()==node; + return !parent->children().empty() && holds_value(&node,parent->children().back()); } -bool isSeparatedParagraph(DocSimpleSect *parent,DocPara *par) +bool isSeparatedParagraph(const DocSimpleSect &parent,const DocPara &par) { - const DocNodeList &nodes = parent->children(); - auto it = std::find_if(nodes.begin(),nodes.end(),[par](const auto &n) { return n.get()==par; }); - if (it==nodes.end()) return FALSE; - size_t i = it - nodes.begin(); - size_t count = parent->children().size(); - if (count>1 && i==0) // first node + const DocNodeList &nodes = parent.children(); + auto it = std::find_if(std::begin(nodes),std::end(nodes),[&par](const auto &n) { return holds_value(&par,n); }); + if (it==std::end(nodes)) return FALSE; + size_t count = parent.children().size(); + auto isSeparator = [](auto &&it_) { return std::get_if<DocSimpleSectSep>(&(*it_))!=0; }; + if (count>1 && it==std::begin(nodes)) // it points to first node { - if (nodes.at(i+1)->kind()==DocNode::Kind_SimpleSectSep) - { - return TRUE; - } + return isSeparator(std::next(it)); } - else if (count>1 && i==count-1) // last node + else if (count>1 && it==std::prev(std::end(nodes))) // it points to last node { - if (nodes.at(i-1)->kind()==DocNode::Kind_SimpleSectSep) - { - return TRUE; - } + return isSeparator(std::prev(it)); } - else if (count>2 && i>0 && i<count-1) // intermediate node + else if (count>2 && it!=std::begin(nodes) && it!=std::prev(std::end(nodes))) // it points to intermediate node { - if (nodes.at(i-1)->kind()==DocNode::Kind_SimpleSectSep && - nodes.at(i+1)->kind()==DocNode::Kind_SimpleSectSep) - { - return TRUE; - } + return isSeparator(std::prev(it)) && isSeparator(std::next(it)); } - return FALSE; + return false; } -static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) +static int getParagraphContext(const DocPara &p,bool &isFirst,bool &isLast) { int t=0; isFirst=FALSE; isLast=FALSE; - if (p && p->parent()) + if (p.parent()) { - switch (p->parent()->kind()) + const auto parBlock = std::get_if<DocParBlock>(p.parent()); + if (parBlock) { - case DocNode::Kind_ParBlock: - { // hierarchy: node N -> para -> parblock -> para - // adapt return value to kind of N - DocNode::Kind kind = DocNode::Kind_Para; - if ( p->parent()->parent() && p->parent()->parent()->parent() ) - { - kind = p->parent()->parent()->parent()->kind(); - } - isFirst=isFirstChildNode((DocParBlock*)p->parent(),p); - isLast =isLastChildNode ((DocParBlock*)p->parent(),p); - t=NONE; - if (isFirst) - { - if (kind==DocNode::Kind_HtmlListItem || - kind==DocNode::Kind_SecRefItem) - { - t=STARTLI; - } - else if (kind==DocNode::Kind_HtmlDescData || - kind==DocNode::Kind_XRefItem || - kind==DocNode::Kind_SimpleSect) - { - t=STARTDD; - } - else if (kind==DocNode::Kind_HtmlCell || - kind==DocNode::Kind_ParamList) - { - t=STARTTD; - } - } - if (isLast) - { - if (kind==DocNode::Kind_HtmlListItem || - kind==DocNode::Kind_SecRefItem) - { - t=ENDLI; - } - else if (kind==DocNode::Kind_HtmlDescData || - kind==DocNode::Kind_XRefItem || - kind==DocNode::Kind_SimpleSect) - { - t=ENDDD; - } - else if (kind==DocNode::Kind_HtmlCell || - kind==DocNode::Kind_ParamList) - { - t=ENDTD; - } - } - if (!isFirst && !isLast) - { - if (kind==DocNode::Kind_HtmlListItem || - kind==DocNode::Kind_SecRefItem) - { - t=INTERLI; - } - else if (kind==DocNode::Kind_HtmlDescData || - kind==DocNode::Kind_XRefItem || - kind==DocNode::Kind_SimpleSect) - { - t=INTERDD; - } - else if (kind==DocNode::Kind_HtmlCell || - kind==DocNode::Kind_ParamList) - { - t=INTERTD; - } - } - break; - } - case DocNode::Kind_AutoListItem: - isFirst=isFirstChildNode((DocAutoListItem*)p->parent(),p); - isLast =isLastChildNode ((DocAutoListItem*)p->parent(),p); - t=STARTLI; // not used - break; - case DocNode::Kind_SimpleListItem: - isFirst=TRUE; - isLast =TRUE; - t=STARTLI; // not used - break; - case DocNode::Kind_ParamList: - isFirst=TRUE; - isLast =TRUE; - t=STARTLI; // not used - break; - case DocNode::Kind_HtmlListItem: - isFirst=isFirstChildNode((DocHtmlListItem*)p->parent(),p); - isLast =isLastChildNode ((DocHtmlListItem*)p->parent(),p); - if (isFirst) t=STARTLI; - if (isLast) t=ENDLI; - if (!isFirst && !isLast) t = INTERLI; - break; - case DocNode::Kind_SecRefItem: - isFirst=isFirstChildNode((DocSecRefItem*)p->parent(),p); - isLast =isLastChildNode ((DocSecRefItem*)p->parent(),p); - if (isFirst) t=STARTLI; - if (isLast) t=ENDLI; - if (!isFirst && !isLast) t = INTERLI; - break; - case DocNode::Kind_HtmlDescData: - isFirst=isFirstChildNode((DocHtmlDescData*)p->parent(),p); - isLast =isLastChildNode ((DocHtmlDescData*)p->parent(),p); - if (isFirst) t=STARTDD; - if (isLast) t=ENDDD; - if (!isFirst && !isLast) t = INTERDD; - break; - case DocNode::Kind_XRefItem: - isFirst=isFirstChildNode((DocXRefItem*)p->parent(),p); - isLast =isLastChildNode ((DocXRefItem*)p->parent(),p); - if (isFirst) t=STARTDD; - if (isLast) t=ENDDD; - if (!isFirst && !isLast) t = INTERDD; - break; - case DocNode::Kind_SimpleSect: - isFirst=isFirstChildNode((DocSimpleSect*)p->parent(),p); - isLast =isLastChildNode ((DocSimpleSect*)p->parent(),p); - if (isFirst) t=STARTDD; - if (isLast) t=ENDDD; - if (isSeparatedParagraph((DocSimpleSect*)p->parent(),p)) - // if the paragraph is enclosed with separators it will - // be included in <dd>..</dd> so avoid addition paragraph - // markers - { - isFirst=isLast=TRUE; - } - if (!isFirst && !isLast) t = INTERDD; - break; - case DocNode::Kind_HtmlCell: - isFirst=isFirstChildNode((DocHtmlCell*)p->parent(),p); - isLast =isLastChildNode ((DocHtmlCell*)p->parent(),p); - if (isFirst) t=STARTTD; - if (isLast) t=ENDTD; - if (!isFirst && !isLast) t = INTERTD; - break; - default: - break; + // hierarchy: node N -> para -> parblock -> para + // adapt return value to kind of N + const DocNodeVariant *p3 = 0; + if (::parent(p.parent()) && ::parent(::parent(p.parent())) ) + { + p3 = ::parent(::parent(p.parent())); + } + isFirst=isFirstChildNode(parBlock,p); + isLast =isLastChildNode (parBlock,p); + bool isLI = p3!=0 && holds_one_of_alternatives<DocHtmlListItem,DocSecRefItem>(*p3); + bool isDD = p3!=0 && holds_one_of_alternatives<DocHtmlDescData,DocXRefItem,DocSimpleSect>(*p3); + bool isTD = p3!=0 && holds_one_of_alternatives<DocHtmlCell,DocParamList>(*p3); + t=NONE; + if (isFirst) + { + if (isLI) t=STARTLI; else if (isDD) t=STARTDD; else if (isTD) t=STARTTD; + } + if (isLast) + { + if (isLI) t=ENDLI; else if (isDD) t=ENDDD; else if (isTD) t=ENDTD; + } + if (!isFirst && !isLast) + { + if (isLI) t=INTERLI; else if (isDD) t=INTERDD; else if (isTD) t=INTERTD; + } + return t; + } + const auto docAutoListItem = std::get_if<DocAutoListItem>(p.parent()); + if (docAutoListItem) + { + isFirst=isFirstChildNode(docAutoListItem,p); + isLast =isLastChildNode (docAutoListItem,p); + t=STARTLI; // not used + return t; + } + const auto docSimpleListItem = std::get_if<DocSimpleListItem>(p.parent()); + if (docSimpleListItem) + { + isFirst=TRUE; + isLast =TRUE; + t=STARTLI; // not used + return t; + } + const auto docParamList = std::get_if<DocParamList>(p.parent()); + if (docParamList) + { + isFirst=TRUE; + isLast =TRUE; + t=STARTLI; // not used + return t; + } + const auto docHtmlListItem = std::get_if<DocHtmlListItem>(p.parent()); + if (docHtmlListItem) + { + isFirst=isFirstChildNode(docHtmlListItem,p); + isLast =isLastChildNode (docHtmlListItem,p); + if (isFirst) t=STARTLI; + if (isLast) t=ENDLI; + if (!isFirst && !isLast) t = INTERLI; + return t; + } + const auto docSecRefItem = std::get_if<DocSecRefItem>(p.parent()); + if (docSecRefItem) + { + isFirst=isFirstChildNode(docSecRefItem,p); + isLast =isLastChildNode (docSecRefItem,p); + if (isFirst) t=STARTLI; + if (isLast) t=ENDLI; + if (!isFirst && !isLast) t = INTERLI; + return t; + } + const auto docHtmlDescData = std::get_if<DocHtmlDescData>(p.parent()); + if (docHtmlDescData) + { + isFirst=isFirstChildNode(docHtmlDescData,p); + isLast =isLastChildNode (docHtmlDescData,p); + if (isFirst) t=STARTDD; + if (isLast) t=ENDDD; + if (!isFirst && !isLast) t = INTERDD; + return t; + } + const auto docXRefItem = std::get_if<DocXRefItem>(p.parent()); + if (docXRefItem) + { + isFirst=isFirstChildNode(docXRefItem,p); + isLast =isLastChildNode (docXRefItem,p); + if (isFirst) t=STARTDD; + if (isLast) t=ENDDD; + if (!isFirst && !isLast) t = INTERDD; + return t; + } + const auto docSimpleSect = std::get_if<DocSimpleSect>(p.parent()); + if (docSimpleSect) + { + isFirst=isFirstChildNode(docSimpleSect,p); + isLast =isLastChildNode (docSimpleSect,p); + if (isFirst) t=STARTDD; + if (isLast) t=ENDDD; + if (isSeparatedParagraph(*docSimpleSect,p)) + // if the paragraph is enclosed with separators it will + // be included in <dd>..</dd> so avoid addition paragraph + // markers + { + isFirst=isLast=TRUE; + } + if (!isFirst && !isLast) t = INTERDD; + return t; + } + const auto docHtmlCell = std::get_if<DocHtmlCell>(p.parent()); + if (docHtmlCell) + { + isFirst=isFirstChildNode(docHtmlCell,p); + isLast =isLastChildNode (docHtmlCell,p); + if (isFirst) t=STARTTD; + if (isLast) t=ENDTD; + if (!isFirst && !isLast) t = INTERTD; + return t; } - //printf("para=%p parent()->kind=%d isFirst=%d isLast=%d t=%d\n", - // p,p->parent()->kind(),isFirst,isLast,t); } return t; } -void HtmlDocVisitor::visitPre(DocPara *p) +static bool determineIfNeedsTag(const DocPara &p) { - if (m_hide) return; - - //printf("DocPara::visitPre: parent of kind %d ", - // p->parent() ? p->parent()->kind() : -1); - bool needsTag = FALSE; - if (p && p->parent()) - { - switch (p->parent()->kind()) + if (p.parent()) + { + if (holds_one_of_alternatives<DocSection, + DocInternal, + DocHtmlListItem, + DocHtmlDescData, + DocHtmlCell, + DocSimpleListItem, + DocAutoListItem, + DocSimpleSect, + DocXRefItem, + DocHtmlBlockQuote, + DocParBlock + >(*p.parent())) { - case DocNode::Kind_Section: - case DocNode::Kind_Internal: - case DocNode::Kind_HtmlListItem: - case DocNode::Kind_HtmlDescData: - case DocNode::Kind_HtmlCell: - case DocNode::Kind_SimpleListItem: - case DocNode::Kind_AutoListItem: - case DocNode::Kind_SimpleSect: - case DocNode::Kind_XRefItem: - case DocNode::Kind_Copy: - case DocNode::Kind_HtmlBlockQuote: - case DocNode::Kind_ParBlock: - needsTag = TRUE; - break; - case DocNode::Kind_Root: - needsTag = !((DocRoot*)p->parent())->singleLine(); - break; - default: - needsTag = FALSE; + needsTag = TRUE; + } + else if (std::get_if<DocRoot>(p.parent())) + { + needsTag = !std::get<DocRoot>(*p.parent()).singleLine(); } } + return needsTag; +} + +void HtmlDocVisitor::operator()(const DocPara &p) +{ + if (m_hide) return; + + //printf("> DocPara\n"); + //dumpDocNodeList(p.children()); + + bool needsTag = determineIfNeedsTag(p); + //printf(" needsTag=%d\n",needsTag); + bool needsTagBefore = needsTag; + bool needsTagAfter = needsTag; // 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 // paragraph and we don't need to do it here - size_t nodeIndex = 0; - if (p && nodeIndex<p->children().size()) + if (!p.children().empty()) { - while (nodeIndex<p->children().size() && isInvisibleNode(p->children().at(nodeIndex).get())) - { - nodeIndex++; - } - if (nodeIndex<p->children().size()) + auto it = std::find_if(std::begin(p.children()),std::end(p.children()), + [](const auto &node) { return !isInvisibleNode(node); }); + if (it!=std::end(p.children())) { - const DocNode *n = p->children().at(nodeIndex).get(); + const DocNodeVariant &n = *it; if (mustBeOutsideParagraph(n)) { - needsTag = FALSE; + needsTagBefore = FALSE; } } } @@ -1321,98 +1277,72 @@ void HtmlDocVisitor::visitPre(DocPara *p) bool isLast; t = getParagraphContext(p,isFirst,isLast); //printf("startPara first=%d last=%d\n",isFirst,isLast); - if (isFirst && isLast) needsTag=FALSE; + if (isFirst && isLast) needsTagBefore=FALSE; - //printf(" needsTag=%d\n",needsTag); + //printf(" needsTagBefore=%d\n",needsTagBefore); // write the paragraph tag (if needed) - if (needsTag) + if (needsTagBefore) { if (strlen(contexts[t])) - m_t << "<p class=\"" << contexts[t] << "\"" << htmlAttribsToString(p->attribs()) << ">"; + m_t << "<p class=\"" << contexts[t] << "\"" << htmlAttribsToString(p.attribs()) << ">"; else - m_t << "<p " << htmlAttribsToString(p->attribs()) << ">"; + m_t << "<p " << htmlAttribsToString(p.attribs()) << ">"; } -} -void HtmlDocVisitor::visitPost(DocPara *p) -{ - - //printf("DocPara::visitPost: parent of kind %d ", - // p->parent() ? p->parent()->kind() : -1); - - bool needsTag = FALSE; - if (p->parent()) - { - switch (p->parent()->kind()) - { - case DocNode::Kind_Section: - case DocNode::Kind_Internal: - case DocNode::Kind_HtmlListItem: - case DocNode::Kind_HtmlDescData: - case DocNode::Kind_HtmlCell: - case DocNode::Kind_SimpleListItem: - case DocNode::Kind_AutoListItem: - case DocNode::Kind_SimpleSect: - case DocNode::Kind_XRefItem: - case DocNode::Kind_Copy: - case DocNode::Kind_HtmlBlockQuote: - case DocNode::Kind_ParBlock: - needsTag = TRUE; - break; - case DocNode::Kind_Root: - needsTag = !((DocRoot*)p->parent())->singleLine(); - break; - default: - needsTag = FALSE; - } - } + visitChildren(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 // paragraph and we don't need to do it here - if (!p->children().empty()) + if (!p.children().empty()) { - int nodeIndex = static_cast<int>(p->children().size()-1); - while (nodeIndex>=0 && isInvisibleNode(p->children().at(nodeIndex).get())) + auto it = std::prev(std::end(p.children())); + for (;;) { - nodeIndex--; - } - if (nodeIndex>=0) - { - const DocNode *n = p->children().at(nodeIndex).get(); - if (mustBeOutsideParagraph(n)) + const DocNodeVariant &n = *it; + if (!isInvisibleNode(n)) + { + if (mustBeOutsideParagraph(n)) + { + needsTagAfter = FALSE; + } + // stop searching if we found a node that is visible + break; + } + if (it==std::begin(p.children())) + { + // stop searching if we are at the beginning of the list + break; + } + else { - needsTag = FALSE; + --it; } } } - bool isFirst; - bool isLast; - getParagraphContext(p,isFirst,isLast); //printf("endPara first=%d last=%d\n",isFirst,isLast); - if (isFirst && isLast) needsTag=FALSE; - - //printf("DocPara::visitPost needsTag=%d\n",needsTag); - - if (needsTag) m_t << "</p>\n"; + if (isFirst && isLast) needsTagAfter=FALSE; + //printf(" needsTagAfter=%d\n",needsTagAfter); + if (needsTagAfter) m_t << "</p>\n"; + //printf("< DocPara\n"); } -void HtmlDocVisitor::visitPre(DocRoot *) +void HtmlDocVisitor::operator()(const DocRoot &r) { + //printf("> DocRoot\n"); + //dumpDocNodeList(r.children()); + visitChildren(r); + //printf("< DocRoot\n"); } -void HtmlDocVisitor::visitPost(DocRoot *) -{ -} - -void HtmlDocVisitor::visitPre(DocSimpleSect *s) +void HtmlDocVisitor::operator()(const DocSimpleSect &s) { if (m_hide) return; forceEndParagraph(s); - m_t << "<dl class=\"section " << s->typeString() << "\"><dt>"; - switch(s->type()) + m_t << "<dl class=\"section " << s.typeString() << "\"><dt>"; + switch(s.type()) { case DocSimpleSect::See: m_t << theTranslator->trSeeAlso(); break; @@ -1449,95 +1379,74 @@ void HtmlDocVisitor::visitPre(DocSimpleSect *s) case DocSimpleSect::Unknown: break; } - // special case 1: user defined title - if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) + if (s.title()) { - m_t << "</dt><dd>"; + std::visit(*this,*s.title()); } -} - -void HtmlDocVisitor::visitPost(DocSimpleSect *s) -{ - if (m_hide) return; + m_t << "</dt><dd>"; + visitChildren(s); m_t << "</dd></dl>\n"; forceStartParagraph(s); } -void HtmlDocVisitor::visitPre(DocTitle *) -{ -} - -void HtmlDocVisitor::visitPost(DocTitle *) +void HtmlDocVisitor::operator()(const DocTitle &t) { if (m_hide) return; - m_t << "</dt><dd>"; + visitChildren(t); } -void HtmlDocVisitor::visitPre(DocSimpleList *sl) +void HtmlDocVisitor::operator()(const DocSimpleList &sl) { if (m_hide) return; forceEndParagraph(sl); m_t << "<ul>"; - if (!sl->isPreformatted()) m_t << "\n"; - -} - -void HtmlDocVisitor::visitPost(DocSimpleList *sl) -{ - if (m_hide) return; + if (!sl.isPreformatted()) m_t << "\n"; + visitChildren(sl); m_t << "</ul>"; - if (!sl->isPreformatted()) m_t << "\n"; + if (!sl.isPreformatted()) m_t << "\n"; forceStartParagraph(sl); } -void HtmlDocVisitor::visitPre(DocSimpleListItem *) +void HtmlDocVisitor::operator()(const DocSimpleListItem &li) { if (m_hide) return; m_t << "<li>"; -} - -void HtmlDocVisitor::visitPost(DocSimpleListItem *li) -{ - if (m_hide) return; + if (li.paragraph()) + { + visit(*this,*li.paragraph()); + } m_t << "</li>"; - if (!li->isPreformatted()) m_t << "\n"; + if (!li.isPreformatted()) m_t << "\n"; } -void HtmlDocVisitor::visitPre(DocSection *s) +void HtmlDocVisitor::operator()(const DocSection &s) { if (m_hide) return; forceEndParagraph(s); - m_t << "<h" << s->level() << ">"; - m_t << "<a class=\"anchor\" id=\"" << s->anchor(); + m_t << "<h" << s.level() << ">"; + m_t << "<a class=\"anchor\" id=\"" << s.anchor(); m_t << "\"></a>\n"; - filter(convertCharEntitiesToUTF8(s->title())); - m_t << "</h" << s->level() << ">\n"; -} - -void HtmlDocVisitor::visitPost(DocSection *s) -{ + filter(convertCharEntitiesToUTF8(s.title())); + m_t << "</h" << s.level() << ">\n"; + visitChildren(s); forceStartParagraph(s); } -void HtmlDocVisitor::visitPre(DocHtmlList *s) +void HtmlDocVisitor::operator()(const 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 { - m_t << "<ul" << htmlAttribsToString(s->attribs()); + m_t << "<ul" << htmlAttribsToString(s.attribs()); } m_t << ">\n"; -} - -void HtmlDocVisitor::visitPost(DocHtmlList *s) -{ - if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) + visitChildren(s); + if (s.type()==DocHtmlList::Ordered) { m_t << "</ol>"; } @@ -1545,199 +1454,156 @@ void HtmlDocVisitor::visitPost(DocHtmlList *s) { m_t << "</ul>"; } - if (!s->isPreformatted()) m_t << "\n"; + if (!s.isPreformatted()) m_t << "\n"; forceStartParagraph(s); } -void HtmlDocVisitor::visitPre(DocHtmlListItem *i) -{ - if (m_hide) return; - m_t << "<li" << htmlAttribsToString(i->attribs()) << ">"; - if (!i->isPreformatted()) m_t << "\n"; -} - -void HtmlDocVisitor::visitPost(DocHtmlListItem *) +void HtmlDocVisitor::operator()(const DocHtmlListItem &i) { if (m_hide) return; + m_t << "<li" << htmlAttribsToString(i.attribs()) << ">"; + if (!i.isPreformatted()) m_t << "\n"; + visitChildren(i); m_t << "</li>\n"; } -void HtmlDocVisitor::visitPre(DocHtmlDescList *dl) +void HtmlDocVisitor::operator()(const DocHtmlDescList &dl) { if (m_hide) return; forceEndParagraph(dl); - m_t << "<dl" << htmlAttribsToString(dl->attribs()) << ">\n"; -} - -void HtmlDocVisitor::visitPost(DocHtmlDescList *dl) -{ - if (m_hide) return; + m_t << "<dl" << htmlAttribsToString(dl.attribs()) << ">\n"; + visitChildren(dl); m_t << "</dl>\n"; forceStartParagraph(dl); } -void HtmlDocVisitor::visitPre(DocHtmlDescTitle *dt) -{ - if (m_hide) return; - m_t << "<dt" << htmlAttribsToString(dt->attribs()) << ">"; -} - -void HtmlDocVisitor::visitPost(DocHtmlDescTitle *) +void HtmlDocVisitor::operator()(const DocHtmlDescTitle &dt) { if (m_hide) return; + m_t << "<dt" << htmlAttribsToString(dt.attribs()) << ">"; + visitChildren(dt); m_t << "</dt>\n"; } -void HtmlDocVisitor::visitPre(DocHtmlDescData *dd) -{ - if (m_hide) return; - m_t << "<dd" << htmlAttribsToString(dd->attribs()) << ">"; -} - -void HtmlDocVisitor::visitPost(DocHtmlDescData *) +void HtmlDocVisitor::operator()(const DocHtmlDescData &dd) { if (m_hide) return; + m_t << "<dd" << htmlAttribsToString(dd.attribs()) << ">"; + visitChildren(dd); m_t << "</dd>\n"; } -void HtmlDocVisitor::visitPre(DocHtmlTable *t) +void HtmlDocVisitor::operator()(const DocHtmlTable &t) { if (m_hide) return; forceEndParagraph(t); - if (t->hasCaption()) + if (t.caption()) { - QCString anc = t->caption()->anchor(); + QCString anc = std::get<DocHtmlCaption>(*t.caption()).anchor(); if (!anc.isEmpty()) { m_t << "<a class=\"anchor\" id=\"" << anc << "\"></a>\n"; } } - QCString attrs = htmlAttribsToString(t->attribs()); + QCString attrs = htmlAttribsToString(t.attribs()); if (attrs.isEmpty()) { m_t << "<table class=\"doxtable\">\n"; } else { - m_t << "<table" << htmlAttribsToString(t->attribs()) << ">\n"; + m_t << "<table" << htmlAttribsToString(t.attribs()) << ">\n"; } -} - -void HtmlDocVisitor::visitPost(DocHtmlTable *t) -{ - if (m_hide) return; + if (t.caption()) + { + std::visit(*this,*t.caption()); + } + visitChildren(t); m_t << "</table>\n"; forceStartParagraph(t); } -void HtmlDocVisitor::visitPre(DocHtmlRow *tr) -{ - if (m_hide) return; - m_t << "<tr" << htmlAttribsToString(tr->attribs()) << ">\n"; -} - -void HtmlDocVisitor::visitPost(DocHtmlRow *) +void HtmlDocVisitor::operator()(const DocHtmlRow &tr) { if (m_hide) return; + m_t << "<tr" << htmlAttribsToString(tr.attribs()) << ">\n"; + visitChildren(tr); m_t << "</tr>\n"; } -void HtmlDocVisitor::visitPre(DocHtmlCell *c) +void HtmlDocVisitor::operator()(const 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 { - m_t << "<td" << htmlAttribsToString(c->attribs()) << ">"; + m_t << "<td" << htmlAttribsToString(c.attribs()) << ">"; } + visitChildren(c); + if (c.isHeading()) m_t << "</th>"; else m_t << "</td>"; } -void HtmlDocVisitor::visitPost(DocHtmlCell *c) -{ - if (m_hide) return; - if (c->isHeading()) m_t << "</th>"; else m_t << "</td>"; -} - -void HtmlDocVisitor::visitPre(DocHtmlCaption *c) -{ - if (m_hide) return; - m_t << "<caption" << htmlAttribsToString(c->attribs()) << ">"; -} - -void HtmlDocVisitor::visitPost(DocHtmlCaption *) +void HtmlDocVisitor::operator()(const DocHtmlCaption &c) { if (m_hide) return; + m_t << "<caption" << htmlAttribsToString(c.attribs()) << ">"; + visitChildren(c); m_t << "</caption>\n"; } -void HtmlDocVisitor::visitPre(DocInternal *) +void HtmlDocVisitor::operator()(const DocInternal &i) { if (m_hide) return; - //forceEndParagraph(i); - //m_t << "<p><b>" << theTranslator->trForInternalUseOnly() << "</b></p>\n"; + visitChildren(i); } -void HtmlDocVisitor::visitPost(DocInternal *) +void HtmlDocVisitor::operator()(const DocHRef &href) { if (m_hide) return; - //forceStartParagraph(i); -} - -void HtmlDocVisitor::visitPre(DocHRef *href) -{ - if (m_hide) return; - if (href->url().left(7)=="mailto:") + if (href.url().left(7)=="mailto:") { - writeObfuscatedMailAddress(href->url().mid(7)); + writeObfuscatedMailAddress(href.url().mid(7)); } else { - QCString url = correctURL(href->url(),href->relPath()); + QCString url = correctURL(href.url(),href.relPath()); m_t << "<a href=\"" << convertToHtml(url) << "\"" - << htmlAttribsToString(href->attribs()) << ">"; + << htmlAttribsToString(href.attribs()) << ">"; } -} - -void HtmlDocVisitor::visitPost(DocHRef *) -{ - if (m_hide) return; + visitChildren(href); m_t << "</a>"; } -void HtmlDocVisitor::visitPre(DocHtmlHeader *header) +void HtmlDocVisitor::operator()(const DocHtmlHeader &header) { if (m_hide) return; forceEndParagraph(header); - m_t << "<h" << header->level() << htmlAttribsToString(header->attribs()) << ">"; -} - -void HtmlDocVisitor::visitPost(DocHtmlHeader *header) -{ - if (m_hide) return; - m_t << "</h" << header->level() << ">\n"; + m_t << "<h" << header.level() << htmlAttribsToString(header.attribs()) << ">"; + visitChildren(header); + m_t << "</h" << header.level() << ">\n"; forceStartParagraph(header); } -void HtmlDocVisitor::visitPre(DocImage *img) +void HtmlDocVisitor::operator()(const DocImage &img) { - if (img->type()==DocImage::Html) + if (img.type()==DocImage::Html) { - bool inlineImage = img->isInlineImage(); - bool typeSVG = img->isSVG(); - QCString url = img->url(); + bool inlineImage = img.isInlineImage(); + bool typeSVG = img.isSVG(); + QCString url = img.url(); if (!inlineImage) { forceEndParagraph(img); } if (m_hide) return; - QCString baseName=img->name(); + QCString baseName=img.name(); int i; if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) { @@ -1745,15 +1611,15 @@ void HtmlDocVisitor::visitPre(DocImage *img) } if (!inlineImage) m_t << "<div class=\"image\">\n"; QCString sizeAttribs; - if (!img->width().isEmpty()) + if (!img.width().isEmpty()) { - sizeAttribs+=" width=\""+img->width()+"\""; + sizeAttribs+=" width=\""+img.width()+"\""; } - if (!img->height().isEmpty()) // link to local file + if (!img.height().isEmpty()) // link to local file { - sizeAttribs+=" height=\""+img->height()+"\""; + sizeAttribs+=" height=\""+img.height()+"\""; } - // 16 cases: url.isEmpty() | typeSVG | inlineImage | img->hasCaption() + // 16 cases: url.isEmpty() | typeSVG | inlineImage | img.hasCaption() HtmlAttribList extraAttribs; if (typeSVG) @@ -1764,16 +1630,16 @@ void HtmlDocVisitor::visitPre(DocImage *img) extraAttribs.push_back(opt); } QCString alt; - mergeHtmlAttributes(img->attribs(),extraAttribs); + mergeHtmlAttributes(img.attribs(),extraAttribs); QCString attrs = htmlAttribsToString(extraAttribs,&alt); QCString src; if (url.isEmpty()) { - src = img->relPath()+img->name(); + src = img.relPath()+img.name(); } else { - src = correctURL(url,img->relPath()); + src = correctURL(url,img.relPath()); } if (typeSVG && !inlineImage) { @@ -1800,7 +1666,7 @@ void HtmlDocVisitor::visitPre(DocImage *img) m_t << "/>\n"; } } - if (img->hasCaption()) + if (img.hasCaption()) { if (inlineImage) { @@ -1816,21 +1682,10 @@ void HtmlDocVisitor::visitPre(DocImage *img) { m_t << "/>"; } - } - else // other format -> skip - { - pushHidden(m_hide); - m_hide=TRUE; - } -} -void HtmlDocVisitor::visitPost(DocImage *img) -{ - if (img->type()==DocImage::Html) - { - if (m_hide) return; - bool inlineImage = img->isInlineImage(); - if (img->hasCaption()) + visitChildren(img); + + if (img.hasCaption()) { if (inlineImage) { @@ -1848,150 +1703,123 @@ void HtmlDocVisitor::visitPost(DocImage *img) forceStartParagraph(img); } } - else // other format + else // other format -> skip { - m_hide = popHidden(); } } -void HtmlDocVisitor::visitPre(DocDotFile *df) +void HtmlDocVisitor::operator()(const DocDotFile &df) { if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(HTML_OUTPUT)+"/"+stripPath(df->file())); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(HTML_OUTPUT)+"/"+stripPath(df.file())); m_t << "<div class=\"dotgraph\">\n"; - writeDotFile(df->file(),df->relPath(),df->context(),df->srcFile(),df->srcLine()); - if (df->hasCaption()) + writeDotFile(df.file(),df.relPath(),df.context(),df.srcFile(),df.srcLine()); + if (df.hasCaption()) { m_t << "<div class=\"caption\">\n"; } -} - -void HtmlDocVisitor::visitPost(DocDotFile *df) -{ - if (m_hide) return; - if (df->hasCaption()) + visitChildren(df); + if (df.hasCaption()) { m_t << "</div>\n"; } m_t << "</div>\n"; } -void HtmlDocVisitor::visitPre(DocMscFile *df) +void HtmlDocVisitor::operator()(const DocMscFile &df) { if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(HTML_OUTPUT)+"/"+stripPath(df->file())); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(HTML_OUTPUT)+"/"+stripPath(df.file())); m_t << "<div class=\"mscgraph\">\n"; - writeMscFile(df->file(),df->relPath(),df->context(),df->srcFile(),df->srcLine()); - if (df->hasCaption()) + writeMscFile(df.file(),df.relPath(),df.context(),df.srcFile(),df.srcLine()); + if (df.hasCaption()) { m_t << "<div class=\"caption\">\n"; } -} -void HtmlDocVisitor::visitPost(DocMscFile *df) -{ - if (m_hide) return; - if (df->hasCaption()) + visitChildren(df); + if (df.hasCaption()) { m_t << "</div>\n"; } m_t << "</div>\n"; } -void HtmlDocVisitor::visitPre(DocDiaFile *df) +void HtmlDocVisitor::operator()(const DocDiaFile &df) { if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(HTML_OUTPUT)+"/"+stripPath(df->file())); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(HTML_OUTPUT)+"/"+stripPath(df.file())); m_t << "<div class=\"diagraph\">\n"; - writeDiaFile(df->file(),df->relPath(),df->context(),df->srcFile(),df->srcLine()); - if (df->hasCaption()) + writeDiaFile(df.file(),df.relPath(),df.context(),df.srcFile(),df.srcLine()); + if (df.hasCaption()) { m_t << "<div class=\"caption\">\n"; } -} -void HtmlDocVisitor::visitPost(DocDiaFile *df) -{ - if (m_hide) return; - if (df->hasCaption()) + visitChildren(df); + if (df.hasCaption()) { m_t << "</div>\n"; } m_t << "</div>\n"; } -void HtmlDocVisitor::visitPre(DocLink *lnk) -{ - if (m_hide) return; - startLink(lnk->ref(),lnk->file(),lnk->relPath(),lnk->anchor()); -} - -void HtmlDocVisitor::visitPost(DocLink *) +void HtmlDocVisitor::operator()(const DocLink &lnk) { if (m_hide) return; + startLink(lnk.ref(),lnk.file(),lnk.relPath(),lnk.anchor()); + visitChildren(lnk); endLink(); } -void HtmlDocVisitor::visitPre(DocRef *ref) +void HtmlDocVisitor::operator()(const 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 - startLink(ref->ref(),ref->file(),ref->relPath(),ref->isSubPage() ? QCString() : ref->anchor()); + // when ref.isSubPage()==TRUE we use ref.file() for HTML and + // ref.anchor() for LaTeX/RTF + startLink(ref.ref(),ref.file(),ref.relPath(),ref.isSubPage() ? QCString() : ref.anchor()); } - if (!ref->hasLinkText()) filter(ref->targetTitle()); -} - -void HtmlDocVisitor::visitPost(DocRef *ref) -{ - if (m_hide) return; - if (!ref->file().isEmpty()) endLink(); + if (!ref.hasLinkText()) filter(ref.targetTitle()); + visitChildren(ref); + if (!ref.file().isEmpty()) endLink(); //m_t << " "; } -void HtmlDocVisitor::visitPre(DocSecRefItem *ref) +void HtmlDocVisitor::operator()(const DocSecRefItem &ref) { if (m_hide) return; - if (!ref->file().isEmpty()) + if (!ref.file().isEmpty()) { m_t << "<li>"; - startLink(ref->ref(),ref->file(),ref->relPath(),ref->isSubPage() ? QCString() : ref->anchor()); + startLink(ref.ref(),ref.file(),ref.relPath(),ref.isSubPage() ? QCString() : ref.anchor()); } -} - -void HtmlDocVisitor::visitPost(DocSecRefItem *ref) -{ - if (m_hide) return; - if (!ref->file().isEmpty()) + visitChildren(ref); + if (!ref.file().isEmpty()) { endLink(); m_t << "</li>\n"; } } -void HtmlDocVisitor::visitPre(DocSecRefList *s) +void HtmlDocVisitor::operator()(const DocSecRefList &s) { if (m_hide) return; forceEndParagraph(s); m_t << "<div>\n"; m_t << "<ul class=\"multicol\">\n"; -} - -void HtmlDocVisitor::visitPost(DocSecRefList *s) -{ - if (m_hide) return; + visitChildren(s); m_t << "</ul>\n"; m_t << "</div>\n"; forceStartParagraph(s); } -void HtmlDocVisitor::visitPre(DocParamSect *s) +void HtmlDocVisitor::operator()(const DocParamSect &s) { if (m_hide) return; forceEndParagraph(s); QCString className; QCString heading; - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: heading=theTranslator->trParameters(); @@ -2016,42 +1844,40 @@ void HtmlDocVisitor::visitPre(DocParamSect *s) m_t << heading; m_t << "</dt><dd>\n"; m_t << " <table class=\"" << className << "\">\n"; -} - -void HtmlDocVisitor::visitPost(DocParamSect *s) -{ - if (m_hide) return; + visitChildren(s); m_t << " </table>\n"; m_t << " </dd>\n"; m_t << "</dl>\n"; forceStartParagraph(s); } -void HtmlDocVisitor::visitPre(DocParamList *pl) +void HtmlDocVisitor::operator()(const DocSeparator &s) +{ + if (m_hide) return; + m_t << " " << s.chars() << " "; +} + +void HtmlDocVisitor::operator()(const DocParamList &pl) { //printf("DocParamList::visitPre\n"); if (m_hide) return; m_t << " <tr>"; - DocParamSect *sect = 0; - if (pl->parent()->kind()==DocNode::Kind_ParamSect) - { - sect=(DocParamSect*)pl->parent(); - } + const DocParamSect *sect = std::get_if<DocParamSect>(pl.parent()); if (sect && sect->hasInOutSpecifier()) { m_t << "<td class=\"paramdir\">"; - if (pl->direction()!=DocParamSect::Unspecified) + if (pl.direction()!=DocParamSect::Unspecified) { m_t << "["; - if (pl->direction()==DocParamSect::In) + if (pl.direction()==DocParamSect::In) { m_t << "in"; } - else if (pl->direction()==DocParamSect::Out) + else if (pl.direction()==DocParamSect::Out) { m_t << "out"; } - else if (pl->direction()==DocParamSect::InOut) + else if (pl.direction()==DocParamSect::InOut) { m_t << "in,out"; } @@ -2062,115 +1888,80 @@ void HtmlDocVisitor::visitPre(DocParamList *pl) if (sect && sect->hasTypeSpecifier()) { m_t << "<td class=\"paramtype\">"; - for (const auto &type : pl->paramTypes()) + for (const auto &type : pl.paramTypes()) { - if (type->kind()==DocNode::Kind_Word) - { - visit((DocWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_Sep) - { - m_t << " " << ((DocSeparator *)type.get())->chars() << " "; - } + std::visit(*this,type); } m_t << "</td>"; } m_t << "<td class=\"paramname\">"; bool first=TRUE; - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { if (!first) m_t << ","; else first=FALSE; - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } + std::visit(*this,param); } m_t << "</td><td>"; -} - -void HtmlDocVisitor::visitPost(DocParamList *) -{ - //printf("DocParamList::visitPost\n"); - if (m_hide) return; + for (const auto &par : pl.paragraphs()) + { + std::visit(*this,par); + } m_t << "</td></tr>\n"; } -void HtmlDocVisitor::visitPre(DocXRefItem *x) +void HtmlDocVisitor::operator()(const DocXRefItem &x) { if (m_hide) return; - if (x->title().isEmpty()) return; + if (x.title().isEmpty()) return; forceEndParagraph(x); - bool anonymousEnum = x->file()=="@"; + bool anonymousEnum = x.file()=="@"; if (!anonymousEnum) { - m_t << "<dl class=\"" << x->key() << "\"><dt><b><a class=\"el\" href=\"" - << x->relPath() << addHtmlExtensionIfMissing(x->file()) - << "#" << x->anchor() << "\">"; + m_t << "<dl class=\"" << x.key() << "\"><dt><b><a class=\"el\" href=\"" + << x.relPath() << addHtmlExtensionIfMissing(x.file()) + << "#" << x.anchor() << "\">"; } else { - m_t << "<dl class=\"" << x->key() << "\"><dt><b>"; + m_t << "<dl class=\"" << x.key() << "\"><dt><b>"; } - filter(x->title()); + filter(x.title()); m_t << ":"; if (!anonymousEnum) m_t << "</a>"; m_t << "</b></dt><dd>"; -} - -void HtmlDocVisitor::visitPost(DocXRefItem *x) -{ - if (m_hide) return; - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; m_t << "</dd></dl>\n"; forceStartParagraph(x); } -void HtmlDocVisitor::visitPre(DocInternalRef *ref) -{ - if (m_hide) return; - startLink(QCString(),ref->file(),ref->relPath(),ref->anchor()); -} - -void HtmlDocVisitor::visitPost(DocInternalRef *) +void HtmlDocVisitor::operator()(const DocInternalRef &ref) { if (m_hide) return; + startLink(QCString(),ref.file(),ref.relPath(),ref.anchor()); + visitChildren(ref); endLink(); m_t << " "; } -void HtmlDocVisitor::visitPre(DocText *) +void HtmlDocVisitor::operator()(const DocText &t) { + visitChildren(t); } -void HtmlDocVisitor::visitPost(DocText *) -{ -} - -void HtmlDocVisitor::visitPre(DocHtmlBlockQuote *b) +void HtmlDocVisitor::operator()(const DocHtmlBlockQuote &b) { if (m_hide) return; forceEndParagraph(b); - QCString attrs = htmlAttribsToString(b->attribs()); - m_t << "<blockquote class=\"doxtable\"" << htmlAttribsToString(b->attribs()) << ">\n"; -} - -void HtmlDocVisitor::visitPost(DocHtmlBlockQuote *b) -{ - if (m_hide) return; + QCString attrs = htmlAttribsToString(b.attribs()); + m_t << "<blockquote class=\"doxtable\"" << htmlAttribsToString(b.attribs()) << ">\n"; + visitChildren(b); m_t << "</blockquote>\n"; forceStartParagraph(b); } -void HtmlDocVisitor::visitPre(DocVhdlFlow *vf) +void HtmlDocVisitor::operator()(const DocVhdlFlow &vf) { if (m_hide) return; if (VhdlDocGen::getFlowMember()) // use VHDL flow chart creator @@ -2184,16 +1975,12 @@ void HtmlDocVisitor::visitPre(DocVhdlFlow *vf) m_t << ".svg\">"; m_t << VhdlDocGen::getFlowMember()->name(); m_t << "</a>"; - if (vf->hasCaption()) + if (vf.hasCaption()) { m_t << "<br />"; } } -} - -void HtmlDocVisitor::visitPost(DocVhdlFlow *vf) -{ - if (m_hide) return; + visitChildren(vf); if (VhdlDocGen::getFlowMember()) // use VHDL flow chart creator { m_t << "</p>"; @@ -2201,18 +1988,12 @@ void HtmlDocVisitor::visitPost(DocVhdlFlow *vf) } } -void HtmlDocVisitor::visitPre(DocParBlock *) -{ - if (m_hide) return; -} - -void HtmlDocVisitor::visitPost(DocParBlock *) +void HtmlDocVisitor::operator()(const DocParBlock &pb) { if (m_hide) return; + visitChildren(pb); } - - void HtmlDocVisitor::filter(const QCString &str, const bool retainNewline) { if (str.isEmpty()) return; @@ -2393,7 +2174,7 @@ void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName, const QCString { baseName=baseName.left(i); } - static QCString outDir = Config_getString(HTML_OUTPUT); + QCString outDir = Config_getString(HTML_OUTPUT); QCString imgExt = getDotImageExtension(); if (imgExt=="svg") { @@ -2415,33 +2196,41 @@ void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName, const QCString must be located outside of a paragraph, i.e. it is a center, div, or pre tag. See also bug746162. */ -static bool insideStyleChangeThatIsOutsideParagraph(DocPara *para,int nodeIndex) +static bool insideStyleChangeThatIsOutsideParagraph(const DocPara *para, + DocNodeList::const_iterator it) { //printf("insideStyleChangeThatIsOutputParagraph(index=%d)\n",nodeIndex); int styleMask=0; bool styleOutsideParagraph=FALSE; - while (nodeIndex>=0 && !styleOutsideParagraph) + while (!styleOutsideParagraph) { - DocNode *n = para->children().at(nodeIndex).get(); - if (n->kind()==DocNode::Kind_StyleChange) + const DocNodeVariant *n = &(*it); + const DocStyleChange *sc = std::get_if<DocStyleChange>(n); + if (sc) { - DocStyleChange *sc = (DocStyleChange*)n; if (!sc->enable()) // remember styles that has been closed already { - styleMask|=(int)sc->style(); + styleMask|=static_cast<int>(sc->style()); } bool paraStyle = sc->style()==DocStyleChange::Center || sc->style()==DocStyleChange::Div || sc->style()==DocStyleChange::Preformatted; //printf("Found style change %s enabled=%d\n",sc->styleString(),sc->enable()); - if (sc->enable() && (styleMask&(int)sc->style())==0 && // style change that is still active + if (sc->enable() && (styleMask&static_cast<int>(sc->style()))==0 && // style change that is still active paraStyle ) { styleOutsideParagraph=TRUE; } } - nodeIndex--; + if (it!=std::begin(para->children())) + { + --it; + } + else + { + break; + } } return styleOutsideParagraph; } @@ -2450,34 +2239,53 @@ static bool insideStyleChangeThatIsOutsideParagraph(DocPara *para,int nodeIndex) * have to be outside of the paragraph. This method will forcefully end * the current paragraph and forceStartParagraph() will restart it. */ -void HtmlDocVisitor::forceEndParagraph(DocNode *n) +template<class Node> +void HtmlDocVisitor::forceEndParagraph(const Node &n) { - //printf("forceEndParagraph(%p) %d\n",n,n->kind()); - if (n->parent() && n->parent()->kind()==DocNode::Kind_Para) + const DocPara *para=std::get_if<DocPara>(n.parent()); + if (para) { - DocPara *para = (DocPara*)n->parent(); const DocNodeList &children = para->children(); - auto it = std::find_if(children.begin(),children.end(),[n](const auto &np) { return np.get()==n; }); - if (it==children.end()) return; - int nodeIndex = static_cast<int>(it - children.begin()); - nodeIndex--; - if (nodeIndex<0) return; // first node in paragraph - while (nodeIndex>=0 && isInvisibleNode(children.at(nodeIndex).get())) + + //printf("forceEndParagraph\n"); + //dumpDocNodeList(children); + + auto it = std::find_if(std::begin(children),std::end(children), + [&n](const auto &np) { return holds_value(&n,np); }); + if (it==std::end(children)) return; + if (it==std::begin(children)) return; // first node in paragraph + it = std::prev(it); + bool found=false; + while (!found) + { + found = !isInvisibleNode(*it); + if (found) break; + if (it!=std::begin(children)) + { + --it; + } + else + { + break; + } + } + if (!found) return; // first visible node in paragraph + const DocNodeVariant &v = *it; + if (mustBeOutsideParagraph(v)) return; // previous node already outside paragraph context + bool styleOutsideParagraph=false; + if (it!=std::begin(children)) { - nodeIndex--; + it = std::prev(it); + styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,it); } - if (nodeIndex<0) return; // first visible node in paragraph - n = children.at(nodeIndex).get(); - if (mustBeOutsideParagraph(n)) return; // previous node already outside paragraph context - nodeIndex--; - bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex); bool isFirst; bool isLast; - getParagraphContext(para,isFirst,isLast); + getParagraphContext(*para,isFirst,isLast); //printf("forceEnd first=%d last=%d styleOutsideParagraph=%d\n",isFirst,isLast,styleOutsideParagraph); if (isFirst && isLast) return; if (styleOutsideParagraph) return; + //printf("adding </p>\n"); m_t << "</p>"; } } @@ -2486,29 +2294,33 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n) * have to be outside of the paragraph. This method will forcefully start * the paragraph, that was previously ended by forceEndParagraph(). */ -void HtmlDocVisitor::forceStartParagraph(DocNode *n) +template<class Node> +void HtmlDocVisitor::forceStartParagraph(const Node &n) { - //printf("forceStartParagraph(%p) %d\n",n,n->kind()); - if (n->parent() && n->parent()->kind()==DocNode::Kind_Para) // if we are inside a paragraph + //printf("> forceStartParagraph(%s)\n",docNodeName(n)); + const DocPara *para=0; + if (n.parent() && (para = std::get_if<DocPara>(n.parent()))) // if we are inside a paragraph { - DocPara *para = (DocPara*)n->parent(); const DocNodeList &children = para->children(); - auto it = std::find_if(children.begin(),children.end(),[n](const auto &np) { return np.get()==n; }); - if (it==children.end()) return; - int nodeIndex = static_cast<int>(it - children.begin()); - int numNodes = static_cast<int>(para->children().size()); - bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex); + + auto it = std::find_if(std::begin(children), + std::end(children), + [&n](const auto &np) + { return holds_value(&n,np); }); + if (it==std::end(children)) return; + bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,it); + //printf("it=%s (%p) styleOutsideParagraph=%d\n", + // docNodeName(*it), (void *)&*it, styleOutsideParagraph); if (styleOutsideParagraph) return; - nodeIndex++; - if (nodeIndex==numNodes) return; // last node - while (nodeIndex<numNodes && isInvisibleNode(para->children().at(nodeIndex).get())) + it = std::next(it); + while (it!=std::end(children) && isInvisibleNode(*it)) { - nodeIndex++; + ++it; } - if (nodeIndex<numNodes) + if (it!=std::end(children)) { - n = para->children().at(nodeIndex).get(); - if (mustBeOutsideParagraph(n)) return; // next element also outside paragraph + const DocNodeVariant &v = *it; + if (mustBeOutsideParagraph(v)) return; // next element also outside paragraph } else { @@ -2518,7 +2330,7 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n) bool needsTag = TRUE; bool isFirst; bool isLast; - getParagraphContext(para,isFirst,isLast); + getParagraphContext(*para,isFirst,isLast); if (isFirst && isLast) needsTag = FALSE; //printf("forceStart first=%d last=%d needsTag=%d\n",isFirst,isLast,needsTag); diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h index 46bbec7..36fb760 100644 --- a/src/htmldocvisitor.h +++ b/src/htmldocvisitor.h @@ -17,11 +17,11 @@ #define HTMLDOCVISITOR_H #include "docvisitor.h" +#include "docnode.h" #include "qcstring.h" class Definition; class MemberDef; -class DocNode; class CodeOutputInterface; class TextStream; @@ -35,105 +35,80 @@ class HtmlDocVisitor : public DocVisitor // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *) ; - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *); - void visitPost(DocSection *); - void visitPre(DocHtmlList *); - void visitPost(DocHtmlList *) ; - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *); - void visitPost(DocHtmlTable *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *); - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *); - void visitPost(DocLink *); - void visitPre(DocRef *); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &) ; + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &); + void operator()(const DocHtmlList &); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocHtmlCaption &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &); + void operator()(const DocRef &); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); private: + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } + template<class T> + void visitCaption(TextStream &t,const T &n); + //-------------------------------------- // helper functions //-------------------------------------- @@ -154,8 +129,10 @@ class HtmlDocVisitor : public DocVisitor void writePlantUMLFile(const QCString &fileName,const QCString &relPath,const QCString &context, const QCString &srcFile,int srcLine); - void forceEndParagraph(DocNode *n); - void forceStartParagraph(DocNode *n); + template<class DocNode> + void forceEndParagraph(const DocNode &n); + template<class DocNode> + void forceStartParagraph(const DocNode &n); //-------------------------------------- // state variables diff --git a/src/htmlentity.cpp b/src/htmlentity.cpp index 8f2eb78..bcd1b25 100644 --- a/src/htmlentity.cpp +++ b/src/htmlentity.cpp @@ -26,7 +26,7 @@ static const int g_numberHtmlMappedCmds = 11; //! ending ;) static struct htmlEntityInfo { - DocSymbol::SymType symb; + HtmlEntityMapper::SymType symb; const char *item; const char *UTF8; const char *html; @@ -35,291 +35,291 @@ static struct htmlEntityInfo const char *latex; const char *man; const char *rtf; - DocSymbol::PerlSymb perl; + HtmlEntityMapper::PerlSymb perl; } g_htmlEntities[] = { #undef SYM // helper macro to force consistent entries for the symbol and item columns -#define SYM(s) DocSymbol::Sym_##s,"&"#s";" +#define SYM(s) HtmlEntityMapper::Sym_##s,"&"#s";" // HTML4 entities // symb+item UTF-8 html xml docbook latex man rtf perl - { SYM(nbsp), "\xc2\xa0", " ", "<nonbreakablespace/>", " ", "~", " ", "\\~", { " ", DocSymbol::Perl_char }}, - { SYM(iexcl), "\xc2\xa1", "¡", "<iexcl/>", "¡", "!`", NULL, "\\'A1", { NULL, DocSymbol::Perl_unknown }}, - { SYM(cent), "\xc2\xa2", "¢", "<cent/>", "¢", "\\textcent{}", NULL, "\\'A2", { NULL, DocSymbol::Perl_unknown }}, - { SYM(pound), "\xc2\xa3", "£", "<pound/>", "£", "{$\\pounds$}", NULL, "\\'A3", { NULL, DocSymbol::Perl_unknown }}, - { SYM(curren), "\xc2\xa4", "¤", "<curren/>", "¤", "\\textcurrency{}", NULL, "\\'A4", { NULL, DocSymbol::Perl_unknown }}, - { SYM(yen), "\xc2\xa5", "¥", "<yen/>", "¥", "{$\\yen$}", NULL, "\\'A5", { NULL, DocSymbol::Perl_unknown }}, - { SYM(brvbar), "\xc2\xa6", "¦", "<brvbar/>", "¦", "\\textbrokenbar{}", NULL, "\\'A6", { NULL, DocSymbol::Perl_unknown }}, - { SYM(sect), "\xc2\xa7", "§", "<sect/>", "<simplesect/>", "{$\\S$}", NULL, "\\'A7", { "sect", DocSymbol::Perl_symbol }}, - { SYM(uml), "\xc2\xa8", "¨", "<umlaut/>", "¨", "\\textasciidieresis{}", " \\*(4", "\\'A8", { " ", DocSymbol::Perl_umlaut }}, - { SYM(copy), "\xc2\xa9", "©", "<copy/>", "©", "\\copyright{}", "(C)", "\\'A9", { "copyright", DocSymbol::Perl_symbol }}, - { SYM(ordf), "\xc2\xaa", "ª", "<ordf/>", "ª", "\\textordfeminine{}", NULL, "\\'AA", { NULL, DocSymbol::Perl_unknown }}, - { SYM(laquo), "\xc2\xab", "«", "<laquo/>", "«", "\\guillemotleft{}", NULL, "\\'AB", { NULL, DocSymbol::Perl_unknown }}, - { SYM(not), "\xc2\xac", "¬", "<not/>", "¬", "\\textlnot", NULL, "\\'AC", { NULL, DocSymbol::Perl_unknown }}, - { SYM(shy), "\xc2\xad", "­", "<shy/>", "­", "{$\\-$}", NULL, "\\-", { NULL, DocSymbol::Perl_unknown }}, - { SYM(reg), "\xc2\xae", "®", "<registered/>", "®", "\\textregistered{}", "(R)", "\\'AE", { "registered", DocSymbol::Perl_symbol }}, - { SYM(macr), "\xc2\xaf", "¯", "<macr/>", "¯", "\\={}", NULL, "\\'AF", { NULL, DocSymbol::Perl_unknown }}, - { SYM(deg), "\xc2\xb0", "°", "<deg/>", "°", "\\textdegree{}", NULL, "\\'B0", { "deg", DocSymbol::Perl_symbol }}, - { SYM(plusmn), "\xc2\xb1", "±", "<plusmn/>", "±", "{$\\pm$}", NULL, "\\'B1", { "+/-", DocSymbol::Perl_string }}, - { SYM(sup2), "\xc2\xb2", "²", "<sup2/>", "²", "\\texttwosuperior{}", NULL, "\\'B2", { NULL, DocSymbol::Perl_unknown }}, - { SYM(sup3), "\xc2\xb3", "³", "<sup3/>", "³", "\\textthreesuperior{}", NULL, "\\'B3", { NULL, DocSymbol::Perl_unknown }}, - { SYM(acute), "\xc2\xb4", "´", "<acute/>", "´", "\\'{}", NULL, "\\'B4", { " ", DocSymbol::Perl_acute }}, - { SYM(micro), "\xc2\xb5", "µ", "<micro/>", "µ", "{$\\mu$}", NULL, "\\'B5", { NULL, DocSymbol::Perl_unknown }}, - { SYM(para), "\xc2\xb6", "¶", "<para/>", "¶", "{$\\P$}", NULL, "\\'B6", { NULL, DocSymbol::Perl_unknown }}, - { SYM(middot), "\xc2\xb7", "·", "<middot/>", "·", "\\textperiodcentered{}", NULL, "\\'B7", { NULL, DocSymbol::Perl_unknown }}, - { SYM(cedil), "\xc2\xb8", "¸", "<cedil/>", "¸", "\\c{}", " \\*,", "\\'B8", { " ", DocSymbol::Perl_cedilla }}, - { SYM(sup1), "\xc2\xb9", "¹", "<sup1/>", "¹", "\\textonesuperior{}", NULL, "\\'B9", { NULL, DocSymbol::Perl_unknown }}, - { SYM(ordm), "\xc2\xba", "º", "<ordm/>", "º", "\\textordmasculine{}", NULL, "\\'BA", { NULL, DocSymbol::Perl_unknown }}, - { SYM(raquo), "\xc2\xbb", "»", "<raquo/>", "»", "\\guillemotright{}", NULL, "\\'BB", { NULL, DocSymbol::Perl_unknown }}, - { SYM(frac14), "\xc2\xbc", "¼", "<frac14/>", "¼", "{$\\frac14$}", "1/4", "\\'BC", { NULL, DocSymbol::Perl_unknown }}, - { SYM(frac12), "\xc2\xbd", "½", "<frac12/>", "½", "{$\\frac12$}", "1/2", "\\'BD", { NULL, DocSymbol::Perl_unknown }}, - { SYM(frac34), "\xc2\xbe", "¾", "<frac34/>", "¾", "{$\\frac34$}", "3/4", "\\'BE", { NULL, DocSymbol::Perl_unknown }}, - { SYM(iquest), "\xc2\xbf", "¿", "<iquest/>", "¿", "?`", NULL, "\\'BF", { NULL, DocSymbol::Perl_unknown }}, - { SYM(Agrave), "\xc3\x80", "À", "<Agrave/>", "À", "\\`{A}", "A\\*:", "\\'C0", { "A", DocSymbol::Perl_grave }}, - { SYM(Aacute), "\xc3\x81", "Á", "<Aacute/>", "Á", "\\'{A}", "A\\*(`", "\\'C1", { "A", DocSymbol::Perl_acute }}, - { SYM(Acirc), "\xc3\x82", "Â", "<Acirc/>", "Â", "\\^{A}", "A\\*^", "\\'C2", { "A", DocSymbol::Perl_circ }}, - { SYM(Atilde), "\xc3\x83", "Ã", "<Atilde/>", "Ã", "\\~{A}", "A\\*~", "\\'C3", { "A", DocSymbol::Perl_tilde }}, - { SYM(Auml), "\xc3\x84", "Ä", "<Aumlaut/>", "Ä", "\\\"{A}", "A\\*(4", "\\'C4", { "A", DocSymbol::Perl_umlaut }}, - { SYM(Aring), "\xc3\x85", "Å", "<Aring/>", "Å", "\\AA", "A\\*o", "\\'C5", { "A", DocSymbol::Perl_ring }}, - { SYM(AElig), "\xc3\x86", "Æ", "<AElig/>", "Æ", "{\\AE}", NULL, "\\'C6", { "AElig", DocSymbol::Perl_symbol }}, - { SYM(Ccedil), "\xc3\x87", "Ç", "<Ccedil/>", "Ç", "\\c{C}", "C\\*,", "\\'C7", { "C", DocSymbol::Perl_cedilla }}, - { SYM(Egrave), "\xc3\x88", "È", "<Egrave/>", "È", "\\`{E}", "E\\*:", "\\'C8", { "E", DocSymbol::Perl_grave }}, - { SYM(Eacute), "\xc3\x89", "É", "<Eacute/>", "É", "\\'{E}", "E\\*(`", "\\'C9", { "E", DocSymbol::Perl_acute }}, - { SYM(Ecirc), "\xc3\x8a", "Ê", "<Ecirc/>", "Ê", "\\^{E}", "E\\*^", "\\'CA", { "E", DocSymbol::Perl_circ }}, - { SYM(Euml), "\xc3\x8b", "Ë", "<Eumlaut/>", "Ë", "\\\"{E}", "E\\*(4", "\\'CB", { "E", DocSymbol::Perl_umlaut }}, - { SYM(Igrave), "\xc3\x8c", "Ì", "<Igrave/>", "Ì", "\\`{I}", "I\\*:", "\\'CC", { "I", DocSymbol::Perl_grave }}, - { SYM(Iacute), "\xc3\x8d", "Í", "<Iacute/>", "Í", "\\'{I}", "I\\*(`", "\\'CD", { "I", DocSymbol::Perl_acute }}, - { SYM(Icirc), "\xc3\x8e", "Î", "<Icirc/>", "Î", "\\^{I}", "I\\*^", "\\'CE", { "I", DocSymbol::Perl_circ }}, - { SYM(Iuml), "\xc3\x8f", "Ï", "<Iumlaut/>", "Ï", "\\\"{I}", "I\\*(4", "\\'CF", { "I", DocSymbol::Perl_umlaut }}, - { SYM(ETH), "\xc3\x90", "Ð", "<ETH/>", "Ð", "\\DH", NULL, "\\'D0", { NULL, DocSymbol::Perl_unknown }}, - { SYM(Ntilde), "\xc3\x91", "Ñ", "<Ntilde/>", "Ñ", "\\~{N}", "N\\*~", "\\'D1", { "N", DocSymbol::Perl_tilde }}, - { SYM(Ograve), "\xc3\x92", "Ò", "<Ograve/>", "Ò", "\\`{O}", "O\\*:", "\\'D2", { "O", DocSymbol::Perl_grave }}, - { SYM(Oacute), "\xc3\x93", "Ó", "<Oacute/>", "Ó", "\\'{O}", "O\\*(`", "\\'D3", { "O", DocSymbol::Perl_acute }}, - { SYM(Ocirc), "\xc3\x94", "Ô", "<Ocirc/>", "Ô", "\\^{O}", "O\\*^", "\\'D4", { "O", DocSymbol::Perl_circ }}, - { SYM(Otilde), "\xc3\x95", "Õ", "<Otilde/>", "Õ", "\\~{O}", "O\\*~", "\\'D5", { "O", DocSymbol::Perl_tilde }}, - { SYM(Ouml), "\xc3\x96", "Ö", "<Oumlaut/>", "Ö", "\\\"{O}", "O\\*(4", "\\'D6", { "O", DocSymbol::Perl_umlaut }}, - { SYM(times), "\xc3\x97", "×", "<times/>", "×", "{$\\times$}", NULL, "\\'D7", { "*", DocSymbol::Perl_char }}, - { SYM(Oslash), "\xc3\x98", "Ø", "<Oslash/>", "Ø", "{\\O}", "O\x08/", "\\'D8", { "O", DocSymbol::Perl_slash }}, - { SYM(Ugrave), "\xc3\x99", "Ù", "<Ugrave/>", "Ù", "\\`{U}", "U\\*:", "\\'D9", { "U", DocSymbol::Perl_grave }}, - { SYM(Uacute), "\xc3\x9a", "Ú", "<Uacute/>", "Ú", "\\'{U}", "U\\*(`", "\\'DA", { "U", DocSymbol::Perl_acute }}, - { SYM(Ucirc), "\xc3\x9b", "Û", "<Ucirc/>", "Û", "\\^{U}", "U\\*^", "\\'DB", { "U", DocSymbol::Perl_circ }}, - { SYM(Uuml), "\xc3\x9c", "Ü", "<Uumlaut/>", "Ü", "\\\"{U}", "U\\*(4", "\\'DC", { "U", DocSymbol::Perl_umlaut }}, - { SYM(Yacute), "\xc3\x9d", "Ý", "<Yacute/>", "Ý", "\\'{Y}", "Y\\*(`", "\\'DD", { "Y", DocSymbol::Perl_acute }}, - { SYM(THORN), "\xc3\x9e", "Þ", "<THORN/>", "Þ", "\\TH", NULL, "\\'DE", { NULL, DocSymbol::Perl_unknown }}, - { SYM(szlig), "\xc3\x9f", "ß", "<szlig/>", "ß", "{\\ss}", "s\\*:", "\\'DF", { "szlig", DocSymbol::Perl_symbol }}, - { SYM(agrave), "\xc3\xa0", "à", "<agrave/>", "à", "\\`{a}", "a\\*:", "\\'E0", { "a", DocSymbol::Perl_grave }}, - { SYM(aacute), "\xc3\xa1", "á", "<aacute/>", "á", "\\'{a}", "a\\*(`", "\\'E1", { "a", DocSymbol::Perl_acute }}, - { SYM(acirc), "\xc3\xa2", "â", "<acirc/>", "â", "\\^{a}", "a\\*^", "\\'E2", { "a", DocSymbol::Perl_circ }}, - { SYM(atilde), "\xc3\xa3", "ã", "<atilde/>", "ã", "\\~{a}", "a\\*~", "\\'E3", { "a", DocSymbol::Perl_tilde }}, - { SYM(auml), "\xc3\xa4", "ä", "<aumlaut/>", "ä", "\\\"{a}", "a\\*(4", "\\'E4", { "a", DocSymbol::Perl_umlaut }}, - { SYM(aring), "\xc3\xa5", "å", "<aring/>", "å", "\\aa", "a\\*o", "\\'E5", { "a", DocSymbol::Perl_ring }}, - { SYM(aelig), "\xc3\xa6", "æ", "<aelig/>", "æ", "{\\ae}", NULL, "\\'E6", { "aelig", DocSymbol::Perl_symbol }}, - { SYM(ccedil), "\xc3\xa7", "ç", "<ccedil/>", "ç", "\\c{c}", "c\\*,", "\\'E7", { "c", DocSymbol::Perl_cedilla }}, - { SYM(egrave), "\xc3\xa8", "è", "<egrave/>", "è", "\\`{e}", "e\\*:", "\\'E8", { "e", DocSymbol::Perl_grave }}, - { SYM(eacute), "\xc3\xa9", "é", "<eacute/>", "é", "\\'{e}", "e\\*(`", "\\'E9", { "e", DocSymbol::Perl_acute }}, - { SYM(ecirc), "\xc3\xaa", "ê", "<ecirc/>", "ê", "\\^{e}", "e\\*^", "\\'EA", { "e", DocSymbol::Perl_circ }}, - { SYM(euml), "\xc3\xab", "ë", "<eumlaut/>", "ë", "\\\"{e}", "e\\*(4", "\\'EB", { "e", DocSymbol::Perl_umlaut }}, - { SYM(igrave), "\xc3\xac", "ì", "<igrave/>", "ì", "\\`{\\i}", "i\\*:", "\\'EC", { "i", DocSymbol::Perl_grave }}, - { SYM(iacute), "\xc3\xad", "í", "<iacute/>", "í", "\\'{\\i}", "i\\*(`", "\\'ED", { "i", DocSymbol::Perl_acute }}, - { SYM(icirc), "\xc3\xae", "î", "<icirc/>", "î", "\\^{\\i}", "i\\*^", "\\'EE", { "i", DocSymbol::Perl_circ }}, - { SYM(iuml), "\xc3\xaf", "ï", "<iumlaut/>", "ï", "\\\"{\\i}", "i\\*(4", "\\'EF", { "i", DocSymbol::Perl_umlaut }}, - { SYM(eth), "\xc3\xb0", "ð", "<eth/>", "ð", "\\dh", NULL, "\\'F0", { NULL, DocSymbol::Perl_unknown }}, - { SYM(ntilde), "\xc3\xb1", "ñ", "<ntilde/>", "ñ", "\\~{n}", "n\\*~", "\\'F1", { "n", DocSymbol::Perl_tilde }}, - { SYM(ograve), "\xc3\xb2", "ò", "<ograve/>", "ò", "\\`{o}", "o\\*:", "\\'F2", { "o", DocSymbol::Perl_grave }}, - { SYM(oacute), "\xc3\xb3", "ó", "<oacute/>", "ó", "\\'{o}", "o\\*(`", "\\'F3", { "o", DocSymbol::Perl_acute }}, - { SYM(ocirc), "\xc3\xb4", "ô", "<ocirc/>", "ô", "\\^{o}", "o\\*^", "\\'F4", { "o", DocSymbol::Perl_circ }}, - { SYM(otilde), "\xc3\xb5", "õ", "<otilde/>", "õ", "\\~{o}", "o\\*~", "\\'F5", { "o", DocSymbol::Perl_tilde }}, - { SYM(ouml), "\xc3\xb6", "ö", "<oumlaut/>", "ö", "\\\"{o}", "o\\*(4", "\\'F6", { "o", DocSymbol::Perl_umlaut }}, - { SYM(divide), "\xc3\xb7", "÷", "<divide/>", "÷", "{$\\div$}", NULL, "\\'F7", { NULL, DocSymbol::Perl_unknown }}, - { SYM(oslash), "\xc3\xb8", "ø", "<oslash/>", "ø", "{\\o}", "o\x08/", "\\'F8", { "o", DocSymbol::Perl_slash }}, - { SYM(ugrave), "\xc3\xb9", "ù", "<ugrave/>", "ù", "\\`{u}", "u\\*:", "\\'F9", { "u", DocSymbol::Perl_grave }}, - { SYM(uacute), "\xc3\xba", "ú", "<uacute/>", "ú", "\\'{u}", "u\\*(`", "\\'FA", { "u", DocSymbol::Perl_acute }}, - { SYM(ucirc), "\xc3\xbb", "û", "<ucirc/>", "û", "\\^{u}", "u\\*^", "\\'FB", { "u", DocSymbol::Perl_circ }}, - { SYM(uuml), "\xc3\xbc", "ü", "<uumlaut/>", "ü", "\\\"{u}", "u\\*(4", "\\'FC", { "u", DocSymbol::Perl_umlaut }}, - { SYM(yacute), "\xc3\xbd", "ý", "<yacute/>", "ý", "\\'{y}", "y\\*(`", "\\'FD", { "y", DocSymbol::Perl_acute }}, - { SYM(thorn), "\xc3\xbe", "þ", "<thorn/>", "þ", "\\th", NULL, "\\'FE", { NULL, DocSymbol::Perl_unknown }}, - { SYM(yuml), "\xc3\xbf", "ÿ", "<yumlaut/>", "ÿ", "\\\"{y}", "y\\*(4", "\\'FF", { "y", DocSymbol::Perl_umlaut }}, - { SYM(fnof), "\xc6\x92", "ƒ", "<fnof/>", "ƒ", "\\textflorin", NULL, "\\'83", { NULL, DocSymbol::Perl_unknown }}, - { SYM(Alpha), "\xce\x91", "Α", "<Alpha/>", "Α", "A", NULL, "\\u0913?", { "A", DocSymbol::Perl_char }}, - { SYM(Beta), "\xce\x92", "Β", "<Beta/>", "Β", "B", NULL, "\\u0914?", { "B", DocSymbol::Perl_char }}, - { SYM(Gamma), "\xce\x93", "Γ", "<Gamma/>", "Γ", "{$\\Gamma$}", NULL, "\\u0915?", { "Gamma", DocSymbol::Perl_symbol }}, - { SYM(Delta), "\xce\x94", "Δ", "<Delta/>", "Δ", "{$\\Delta$}", NULL, "\\u0916?", { "Delta", DocSymbol::Perl_symbol }}, - { SYM(Epsilon), "\xce\x95", "Ε", "<Epsilon/>", "Ε", "E", NULL, "\\u0917?", { "E", DocSymbol::Perl_char }}, - { SYM(Zeta), "\xce\x96", "Ζ", "<Zeta/>", "Ζ", "Z", NULL, "\\u0918?", { "Z", DocSymbol::Perl_char }}, - { SYM(Eta), "\xce\x97", "Η", "<Eta/>", "Η", "H", NULL, "\\u0919?", { "H", DocSymbol::Perl_char }}, - { SYM(Theta), "\xce\x98", "Θ", "<Theta/>", "Θ", "{$\\Theta$}", NULL, "\\u0920?", { "Theta", DocSymbol::Perl_symbol }}, - { SYM(Iota), "\xce\x99", "Ι", "<Iota/>", "Ι", "I", NULL, "\\u0921?", { "I", DocSymbol::Perl_char }}, - { SYM(Kappa), "\xce\x9a", "Κ", "<Kappa/>", "Κ", "K", NULL, "\\u0922?", { "K", DocSymbol::Perl_char }}, - { SYM(Lambda), "\xce\x9b", "Λ", "<Lambda/>", "Λ", "{$\\Lambda$}", NULL, "\\u0923?", { "Lambda", DocSymbol::Perl_symbol }}, - { SYM(Mu), "\xce\x9c", "Μ", "<Mu/>", "Μ", "M", NULL, "\\u0924?", { "M", DocSymbol::Perl_char }}, - { SYM(Nu), "\xce\x9d", "Ν", "<Nu/>", "Ν", "N", NULL, "\\u0925?", { "N", DocSymbol::Perl_char }}, - { SYM(Xi), "\xce\x9e", "Ξ", "<Xi/>", "Ξ", "{$\\Xi$}", NULL, "\\u0926?", { "Xi", DocSymbol::Perl_symbol }}, - { SYM(Omicron), "\xce\x9f", "Ο", "<Omicron/>", "Ο", "O", NULL, "\\u0927?", { "O", DocSymbol::Perl_char }}, - { SYM(Pi), "\xce\xa0", "Π", "<Pi/>", "Π", "{$\\Pi$}", NULL, "\\u0928?", { "Pi", DocSymbol::Perl_symbol }}, - { SYM(Rho), "\xce\xa1", "Ρ", "<Rho/>", "Ρ", "P", NULL, "\\u0929?", { "P", DocSymbol::Perl_char }}, - { SYM(Sigma), "\xce\xa3", "Σ", "<Sigma/>", "Σ", "{$\\Sigma$}", NULL, "\\u0931?", { "Sigma", DocSymbol::Perl_symbol }}, - { SYM(Tau), "\xce\xa4", "Τ", "<Tau/>", "Τ", "T", NULL, "\\u0932?", { "T", DocSymbol::Perl_char }}, - { SYM(Upsilon), "\xce\xa5", "Υ", "<Upsilon/>", "Υ", "{$\\Upsilon$}", NULL, "\\u0933?", { "Upsilon", DocSymbol::Perl_symbol }}, - { SYM(Phi), "\xce\xa6", "Φ", "<Phi/>", "Φ", "{$\\Phi$}", NULL, "\\u0934?", { "Phi", DocSymbol::Perl_symbol }}, - { SYM(Chi), "\xce\xa7", "Χ", "<Chi/>", "Χ", "X", NULL, "\\u0935?", { "X", DocSymbol::Perl_char }}, - { SYM(Psi), "\xce\xa8", "Ψ", "<Psi/>", "Ψ", "{$\\Psi$}", NULL, "\\u0936?", { "Psi", DocSymbol::Perl_symbol }}, - { SYM(Omega), "\xce\xa9", "Ω", "<Omega/>", "Ω", "{$\\Omega$}", NULL, "\\u0937?", { "Omega", DocSymbol::Perl_symbol }}, - { SYM(alpha), "\xce\xb1", "α", "<alpha/>", "α", "{$\\alpha$}", NULL, "\\u0945?", { "alpha", DocSymbol::Perl_symbol }}, - { SYM(beta), "\xce\xb2", "β", "<beta/>", "β", "{$\\beta$}", NULL, "\\u0946?", { "beta", DocSymbol::Perl_symbol }}, - { SYM(gamma), "\xce\xb3", "γ", "<gamma/>", "γ", "{$\\gamma$}", NULL, "\\u0947?", { "gamma", DocSymbol::Perl_symbol }}, - { SYM(delta), "\xce\xb4", "δ", "<delta/>", "δ", "{$\\delta$}", NULL, "\\u0948?", { "delta", DocSymbol::Perl_symbol }}, - { SYM(epsilon), "\xce\xb5", "ε", "<epsilon/>", "ε", "{$\\varepsilon$}", NULL, "\\u0949?", { "epsilon", DocSymbol::Perl_symbol }}, - { SYM(zeta), "\xce\xb6", "ζ", "<zeta/>", "ζ", "{$\\zeta$}", NULL, "\\u0950?", { "zeta", DocSymbol::Perl_symbol }}, - { SYM(eta), "\xce\xb7", "η", "<eta/>", "η", "{$\\eta$}", NULL, "\\u0951?", { "eta", DocSymbol::Perl_symbol }}, - { SYM(theta), "\xce\xb8", "θ", "<theta/>", "θ", "{$\\theta$}", NULL, "\\u0952?", { "theta", DocSymbol::Perl_symbol }}, - { SYM(iota), "\xce\xb9", "ι", "<iota/>", "ι", "{$\\iota$}", NULL, "\\u0953?", { "iota", DocSymbol::Perl_symbol }}, - { SYM(kappa), "\xce\xba", "κ", "<kappa/>", "κ", "{$\\kappa$}", NULL, "\\u0954?", { "kappa", DocSymbol::Perl_symbol }}, - { SYM(lambda), "\xce\xbb", "λ", "<lambda/>", "λ", "{$\\lambda$}", NULL, "\\u0955?", { "lambda", DocSymbol::Perl_symbol }}, - { SYM(mu), "\xce\xbc", "μ", "<mu/>", "μ", "{$\\mu$}", NULL, "\\u0956?", { "mu", DocSymbol::Perl_symbol }}, - { SYM(nu), "\xce\xbd", "ν", "<nu/>", "ν", "{$\\nu$}", NULL, "\\u0957?", { "nu", DocSymbol::Perl_symbol }}, - { SYM(xi), "\xce\xbe", "ξ", "<xi/>", "ξ", "{$\\xi$}", NULL, "\\u0958?", { "xi", DocSymbol::Perl_symbol }}, - { SYM(omicron), "\xce\xbf", "ο", "<omicron/>", "ο", "{$\\omicron$}", NULL, "\\u0959?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(pi), "\xcf\x80", "π", "<pi/>", "π", "{$\\pi$}", NULL, "\\u0960?", { "pi", DocSymbol::Perl_symbol }}, - { SYM(rho), "\xcf\x81", "ρ", "<rho/>", "ρ", "{$\\rho$}", NULL, "\\u0961?", { "rho", DocSymbol::Perl_symbol }}, - { SYM(sigmaf), "\xcf\x82", "ς", "<sigmaf/>", "ς", "{$\\varsigma$}", NULL, "\\u0962?", { "sigma", DocSymbol::Perl_symbol }}, - { SYM(sigma), "\xcf\x83", "σ", "<sigma/>", "σ", "{$\\sigma$}", NULL, "\\u0963?", { "sigma", DocSymbol::Perl_symbol }}, - { SYM(tau), "\xcf\x84", "τ", "<tau/>", "τ", "{$\\tau$}", NULL, "\\u0964?", { "tau", DocSymbol::Perl_symbol }}, - { SYM(upsilon), "\xcf\x85", "υ", "<upsilon/>", "υ", "{$\\upsilon$}", NULL, "\\u0965?", { "upsilon", DocSymbol::Perl_symbol }}, - { SYM(phi), "\xcf\x86", "φ", "<phi/>", "φ", "{$\\varphi$}", NULL, "\\u0966?", { "phi", DocSymbol::Perl_symbol }}, - { SYM(chi), "\xcf\x87", "χ", "<chi/>", "χ", "{$\\chi$}", NULL, "\\u0967?", { "chi", DocSymbol::Perl_symbol }}, - { SYM(psi), "\xcf\x88", "ψ", "<psi/>", "ψ", "{$\\psi$}", NULL, "\\u0968?", { "psi", DocSymbol::Perl_symbol }}, - { SYM(omega), "\xcf\x89", "ω", "<omega/>", "ω", "{$\\omega$}", NULL, "\\u0969?", { "omega", DocSymbol::Perl_symbol }}, - { SYM(thetasym), "\xcf\x91", "ϑ", "<thetasym/>", "ϑ", "{$\\vartheta$}", NULL, "\\u977?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(upsih), "\xcf\x92", "ϒ", "<upsih/>", "ϒ", "{$\\Upsilon$}", NULL, "\\u978?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(piv), "\xcf\x96", "ϖ", "<piv/>", "ϖ", "{$\\varpi$}", NULL, "\\u982?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(bull), "\xe2\x80\xa2", "•", "<bull/>", "•", "\\textbullet{}", NULL, "\\'95", { NULL, DocSymbol::Perl_unknown }}, - { SYM(hellip), "\xe2\x80\xa6", "…", "<hellip/>", "…", "{$\\dots$}", NULL, "\\'85", { NULL, DocSymbol::Perl_unknown }}, - { SYM(prime), "\xe2\x80\xb2", "′", "<prime/>", "′", "'", NULL, "\\u8242?", { "\\\'", DocSymbol::Perl_string }}, - { SYM(Prime), "\xe2\x80\xb3", "″", "<Prime/>", "″", "''", NULL, "\\u8243?", { "\"", DocSymbol::Perl_char }}, - { SYM(oline), "\xe2\x80\xbe", "‾", "<oline/>", "‾", "{$\\overline{\\,}$}", NULL, "\\u8254?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(frasl), "\xe2\x81\x84", "⁄", "<frasl/>", "⁄", "/", NULL, "\\u8260?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(weierp), "\xe2\x84\x98", "℘", "<weierp/>", "℘", "{$\\wp$}", NULL, "\\u8472?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(image), "\xe2\x84\x91", "ℑ", "<imaginary/>", "ℑ", "{$\\Im$}", NULL, "\\u8465?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(real), "\xe2\x84\x9c", "ℜ", "<real/>", "ℜ", "{$\\Re$}", NULL, "\\u8476?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(trade), "\xe2\x84\xa2", "™", "<trademark/>", "™", "\\texttrademark{}", "(TM)", "\\'99", { "trademark", DocSymbol::Perl_symbol }}, - { SYM(alefsym), "\xe2\x85\xb5", "ℵ", "<alefsym/>", "ℵ", "{$\\aleph$}", NULL, "\\u8501?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(larr), "\xe2\x86\x90", "←", "<larr/>", "←", "{$\\leftarrow$}", NULL, "\\u8592?", { "<-", DocSymbol::Perl_string }}, - { SYM(uarr), "\xe2\x86\x91", "↑", "<uarr/>", "↑", "{$\\uparrow$}", NULL, "\\u8593?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(rarr), "\xe2\x86\x92", "→", "<rarr/>", "→", "{$\\rightarrow$}", NULL, "\\u8594?", { "->", DocSymbol::Perl_string }}, - { SYM(darr), "\xe2\x86\x93", "↓", "<darr/>", "↓", "{$\\downarrow$}", NULL, "\\u8595?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(harr), "\xe2\x86\x94", "↔", "<harr/>", "↔", "{$\\leftrightarrow$}", NULL, "\\u8596?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(crarr), "\xe2\x86\xb5", "↵", "<crarr/>", "↵", "{$\\hookleftarrow$}", NULL, "\\u8629?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(lArr), "\xe2\x87\x90", "⇐", "<lArr/>", "⇐", "{$\\Leftarrow$}", NULL, "\\u8656?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(uArr), "\xe2\x87\x91", "⇑", "<uArr/>", "⇑", "{$\\Uparrow$}", NULL, "\\u8657?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(rArr), "\xe2\x87\x92", "⇒", "<rArr/>", "⇒", "{$\\Rightarrow$}", NULL, "\\u8658?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(dArr), "\xe2\x87\x93", "⇓", "<dArr/>", "⇓", "{$\\Downarrow$}", NULL, "\\u8659?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(hArr), "\xe2\x87\x94", "⇔", "<hArr/>", "⇔", "{$\\Leftrightarrow$}", NULL, "\\u8660?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(forall), "\xe2\x88\x80", "∀", "<forall/>", "∀", "{$\\forall$}", NULL, "\\u8704?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(part), "\xe2\x88\x82", "∂", "<part/>", "∂", "{$\\partial$}", NULL, "\\u8706?", { "partial", DocSymbol::Perl_symbol }}, - { SYM(exist), "\xe2\x88\x83", "∃", "<exist/>", "∃", "{$\\exists$}", NULL, "\\u8707?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(empty), "\xe2\x88\x85", "∅", "<empty/>", "∅", "{$\\emptyset$}", NULL, "\\u8709?", { "empty", DocSymbol::Perl_symbol }}, - { SYM(nabla), "\xe2\x88\x87", "∇", "<nabla/>", "∇", "{$\\nabla$}", NULL, "\\u8711?", { "nabla", DocSymbol::Perl_symbol }}, - { SYM(isin), "\xe2\x88\x88", "∈", "<isin/>", "∈", "{$\\in$}", NULL, "\\u8712?", { "in", DocSymbol::Perl_symbol }}, - { SYM(notin), "\xe2\x88\x89", "∉", "<notin/>", "∉", "{$\\notin$}", NULL, "\\u8713?", { "notin", DocSymbol::Perl_symbol }}, - { SYM(ni), "\xe2\x88\x8b", "∋", "<ni/>", "∋", "{$\\ni$}", NULL, "\\u8715?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(prod), "\xe2\x88\x8f", "∏", "<prod/>", "∏", "{$\\prod$}", NULL, "\\u8719?", { "prod", DocSymbol::Perl_symbol }}, - { SYM(sum), "\xe2\x88\x91", "∑", "<sum/>", "∑", "{$\\sum$}", NULL, "\\u8721?", { "sum", DocSymbol::Perl_symbol }}, - { SYM(minus), "\xe2\x88\x92", "−", "<minus/>", "−", "-", NULL, "\\u8722?", { "-", DocSymbol::Perl_char }}, - { SYM(lowast), "\xe2\x88\x97", "∗", "<lowast/>", "∗", "{$\\ast$}", NULL, "\\u8727?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(radic), "\xe2\x88\x9a", "√", "<radic/>", "√", "{$\\surd$}", NULL, "\\u8730?", { "sqrt", DocSymbol::Perl_symbol }}, - { SYM(prop), "\xe2\x88\x9d", "∝", "<prop/>", "∝", "{$\\propto$}", NULL, "\\u8733?", { "propto", DocSymbol::Perl_symbol }}, - { SYM(infin), "\xe2\x88\x9e", "∞", "<infin/>", "∞", "{$\\infty$}", NULL, "\\u8734?", { "inf", DocSymbol::Perl_symbol }}, - { SYM(ang), "\xe2\x88\xa0", "∠", "<ang/>", "∠", "{$\\angle$}", NULL, "\\u8736?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(and), "\xe2\x88\xa7", "∧", "<and/>", "∧", "{$\\wedge$}", NULL, "\\u8743?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(or), "\xe2\x88\xa8", "∨", "<or/>", "∨", "{$\\vee$}", NULL, "\\u8744?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(cap), "\xe2\x88\xa9", "∩", "<cap/>", "∩", "{$\\cap$}", NULL, "\\u8745?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(cup), "\xe2\x88\xaa", "∪", "<cup/>", "∪", "{$\\cup$}", NULL, "\\u8746?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(int), "\xe2\x88\xab", "∫", "<int/>", "∫", "{$\\int$}", NULL, "\\u8747?", { "int", DocSymbol::Perl_symbol }}, - { SYM(there4), "\xe2\x88\xb4", "∴", "<there4/>", "∴", "{$\\therefore$}", NULL, "\\u8756?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(sim), "\xe2\x88\xbc", "∼", "<sim/>", "∼", "{$\\sim$}", NULL, "\\u8764?", { "~", DocSymbol::Perl_char }}, - { SYM(cong), "\xe2\x89\x85", "≅", "<cong/>", "≅", "{$\\cong$}", NULL, "\\u8773?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(asymp), "\xe2\x89\x88", "≈", "<asymp/>", "≈", "{$\\approx$}", NULL, "\\u8776?", { "approx", DocSymbol::Perl_symbol }}, - { SYM(ne), "\xe2\x89\xa0", "≠", "<ne/>", "≠", "{$\\ne$}", NULL, "\\u8800?", { "!=", DocSymbol::Perl_string }}, - { SYM(equiv), "\xe2\x89\xa1", "≡", "<equiv/>", "≡", "{$\\equiv$}", NULL, "\\u8801?", { "equiv", DocSymbol::Perl_symbol }}, - { SYM(le), "\xe2\x89\xa4", "≤", "<le/>", "≤", "{$\\le$}", NULL, "\\u8804?", { "<=", DocSymbol::Perl_string }}, - { SYM(ge), "\xe2\x89\xa5", "≥", "<ge/>", "≥", "{$\\ge$}", NULL, "\\u8805?", { ">=", DocSymbol::Perl_string }}, - { SYM(sub), "\xe2\x8a\x82", "⊂", "<sub/>", "⊂", "{$\\subset$}", NULL, "\\u8834?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(sup), "\xe2\x8a\x83", "⊃", "<sup/>", "⊃", "{$\\supset$}", NULL, "\\u8835?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(nsub), "\xe2\x8a\x84", "⊄", "<nsub/>", "⊄", "{$\\not\\subset$}", NULL, "\\u8836?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(sube), "\xe2\x8a\x86", "⊆", "<sube/>", "⊆", "{$\\subseteq$}", NULL, "\\u8838?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(supe), "\xe2\x8a\x87", "⊇", "<supe/>", "⊇", "{$\\supseteq$}", NULL, "\\u8839?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(oplus), "\xe2\x8a\x95", "⊕", "<oplus/>", "⊕", "{$\\oplus$}", NULL, "\\u8853?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(otimes), "\xe2\x8a\x97", "⊗", "<otimes/>", "⊗", "{$\\otimes$}", NULL, "\\u8855?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(perp), "\xe2\x8a\xa5", "⊥", "<perp/>", "⊥", "{$\\perp$}", NULL, "\\u8869?", { "perp", DocSymbol::Perl_symbol }}, - { SYM(sdot), "\xe2\x8b\x85", "⋅", "<sdot/>", "⋅", "{$\\cdot$}", NULL, "\\u8901?", { ".", DocSymbol::Perl_char }}, - { SYM(lceil), "\xe2\x8c\x88", "⌈", "<lceil/>", "⌈", "{$\\lceil$}", NULL, "\\u8968?", { "lceil", DocSymbol::Perl_symbol }}, - { SYM(rceil), "\xe2\x8c\x89", "⌉", "<rceil/>", "⌉", "{$\\rceil$}", NULL, "\\u8969?", { "rceil", DocSymbol::Perl_symbol }}, - { SYM(lfloor), "\xe2\x8c\x8a", "⌊", "<lfloor/>", "⌊", "{$\\lfloor$}", NULL, "\\u8970?", { "lfloor", DocSymbol::Perl_symbol }}, - { SYM(rfloor), "\xe2\x8c\x8b", "⌋", "<rfloor/>", "⌋", "{$\\rfloor$}", NULL, "\\u8971?", { "rfloor", DocSymbol::Perl_symbol }}, - { SYM(lang), "\xe2\x8c\xa9", "⟨", "<lang/>", "〈", "{$\\langle$}", NULL, "\\u9001?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(rang), "\xe2\x8c\xaa", "⟩", "<rang/>", "〉", "{$\\rangle$}", NULL, "\\u9002?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(loz), "\xe2\x97\x8a", "◊", "<loz/>", "◊", "{$\\lozenge$}", NULL, "\\u9674?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(spades), "\xe2\x99\xa0", "♠", "<spades/>", "♠", "{$\\spadesuit$}", NULL, "\\u9824?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(clubs), "\xe2\x99\xa3", "♣", "<clubs/>", "♣", "{$\\clubsuit$}", NULL, "\\u9827?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(hearts), "\xe2\x99\xa5", "♥", "<hearts/>", "♥", "{$\\heartsuit$}", NULL, "\\u9829?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(diams), "\xe2\x99\xa6", "♦", "<diams/>", "♦", "{$\\diamondsuit$}", NULL, "\\u9830?", { NULL, DocSymbol::Perl_unknown }}, - { SYM(quot), "\"", """, "\"", """, "\"{}", "\"", "\"", { "\"", DocSymbol::Perl_char }}, - { SYM(amp), "&", "&", "&", "&", "\\&", "&", "&", { "&", DocSymbol::Perl_char }}, - { SYM(lt), "<", "<", "<", "<", "<", "<", "<", { "<", DocSymbol::Perl_char }}, - { SYM(gt), ">", ">", ">", ">", ">", ">", ">", { ">", DocSymbol::Perl_char }}, - { SYM(OElig), "\xc5\x92", "Œ", "<OElig/>", "Œ", "\\OE", NULL, "\\'8C", { NULL, DocSymbol::Perl_unknown }}, - { SYM(oelig), "\xc5\x93", "œ", "<oelig/>", "œ", "\\oe", NULL, "\\'9C", { NULL, DocSymbol::Perl_unknown }}, - { SYM(Scaron), "\xc5\xa0", "Š", "<Scaron/>", "Š", "\\v{S}", NULL, "\\'8A", { NULL, DocSymbol::Perl_unknown }}, - { SYM(scaron), "\xc5\xa1", "š", "<scaron/>", "š", "\\v{s}", NULL, "\\'9A", { NULL, DocSymbol::Perl_unknown }}, - { SYM(Yuml), "\xc5\xb8", "Ÿ", "<Yumlaut/>", "Ÿ", "\\\"{Y}", "Y\\*(4", "\\'9F", { "Y", DocSymbol::Perl_umlaut }}, - { SYM(circ), "\xcb\x86", "ˆ", "<circ/>", "ˆ", "{$\\circ$}", NULL, "\\'88", { " ", DocSymbol::Perl_circ }}, - { SYM(tilde), "\xcb\x9c", "˜", "<tilde/>", "˜", "\\~{}", "~", "\\'98", { " ", DocSymbol::Perl_tilde }}, - { SYM(ensp), "\xe2\x80\x82", " ", "<ensp/>", " ", "\\enskip{}", NULL, "{\\enspace}", { NULL, DocSymbol::Perl_unknown }}, - { SYM(emsp), "\xe2\x80\x83", " ", "<emsp/>", " ", "\\quad{}", NULL, "{\\emspace}", { NULL, DocSymbol::Perl_unknown }}, - { SYM(thinsp), "\xe2\x80\x89", " ", "<thinsp/>", " ", "\\,", NULL, "{\\qmspace}", { NULL, DocSymbol::Perl_unknown }}, - { SYM(zwnj), "\xe2\x80\x8c", "‌", "<zwnj/>", "‌", "{}", NULL, "\\zwnj", { NULL, DocSymbol::Perl_unknown }}, - { SYM(zwj), "\xe2\x80\x8d", "‍", "<zwj/>", "‍", "", NULL, "\\zwj", { NULL, DocSymbol::Perl_unknown }}, - { SYM(lrm), "\xe2\x80\x8e", "‎", "<lrm/>", "‎", "", NULL, "\\ltrmark", { NULL, DocSymbol::Perl_unknown }}, - { SYM(rlm), "\xe2\x80\x8f", "‏", "<rlm/>", "‏", "", NULL, "\\rtlmark", { NULL, DocSymbol::Perl_unknown }}, - { SYM(ndash), "\xe2\x80\x93", "–", "<ndash/>", "–", "--", "--", "\\'96", { "-", DocSymbol::Perl_char }}, - { SYM(mdash), "\xe2\x80\x94", "—", "<mdash/>", "—", "---", "---", "\\'97", { "--", DocSymbol::Perl_string }}, - { SYM(lsquo), "\xe2\x80\x98", "‘", "<lsquo/>", "‘", "`", "`", "\\'91", { "\\\'", DocSymbol::Perl_string }}, - { SYM(rsquo), "\xe2\x80\x99", "’", "<rsquo/>", "’", "'", "'", "\\'92", { "\\\'", DocSymbol::Perl_string }}, - { SYM(sbquo), "\xe2\x80\x9a", "‚", "<sbquo/>", "‚", "\\quotesinglbase{}", NULL, "\\'82", { NULL, DocSymbol::Perl_unknown }}, - { SYM(ldquo), "\xe2\x80\x9c", "“", "<ldquo/>", "“", "``", "``", "\\'93", { "\"", DocSymbol::Perl_char }}, - { SYM(rdquo), "\xe2\x80\x9d", "”", "<rdquo/>", "”", "''", "''", "\\'94", { "\"", DocSymbol::Perl_char }}, - { SYM(bdquo), "\xe2\x80\x9e", "„", "<bdquo/>", "„", "\\quotedblbase{}", NULL, "\\'84", { NULL, DocSymbol::Perl_unknown }}, - { SYM(dagger), "\xe2\x80\xa0", "†", "<dagger/>", "†", "{$\\dagger$}", NULL, "\\'86", { NULL, DocSymbol::Perl_unknown }}, - { SYM(Dagger), "\xe2\x80\xa1", "‡", "<Dagger/>", "‡", "{$\\ddagger$}", NULL, "\\'87", { NULL, DocSymbol::Perl_unknown }}, - { SYM(permil), "\xe2\x80\xb0", "‰", "<permil/>", "‰", "{$\\permil{}$}", NULL, "\\'89", { NULL, DocSymbol::Perl_unknown }}, - { SYM(lsaquo), "\xe2\x80\xb9", "‹", "<lsaquo/>", "‹", "\\guilsinglleft{}", NULL, "\\'8B", { NULL, DocSymbol::Perl_unknown }}, - { SYM(rsaquo), "\xe2\x80\xba", "›", "<rsaquo/>", "›", "\\guilsinglright{}", NULL, "\\'9B", { NULL, DocSymbol::Perl_unknown }}, - { SYM(euro), "\xe2\x82\xac", "€", "<euro/>", "€", "\\texteuro{}", NULL, "\\'80", { NULL, DocSymbol::Perl_unknown }}, + { SYM(nbsp), "\xc2\xa0", " ", "<nonbreakablespace/>", " ", "~", " ", "\\~", { " ", HtmlEntityMapper::Perl_char }}, + { SYM(iexcl), "\xc2\xa1", "¡", "<iexcl/>", "¡", "!`", NULL, "\\'A1", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(cent), "\xc2\xa2", "¢", "<cent/>", "¢", "\\textcent{}", NULL, "\\'A2", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(pound), "\xc2\xa3", "£", "<pound/>", "£", "{$\\pounds$}", NULL, "\\'A3", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(curren), "\xc2\xa4", "¤", "<curren/>", "¤", "\\textcurrency{}", NULL, "\\'A4", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(yen), "\xc2\xa5", "¥", "<yen/>", "¥", "{$\\yen$}", NULL, "\\'A5", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(brvbar), "\xc2\xa6", "¦", "<brvbar/>", "¦", "\\textbrokenbar{}", NULL, "\\'A6", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(sect), "\xc2\xa7", "§", "<sect/>", "<simplesect/>", "{$\\S$}", NULL, "\\'A7", { "sect", HtmlEntityMapper::Perl_symbol }}, + { SYM(uml), "\xc2\xa8", "¨", "<umlaut/>", "¨", "\\textasciidieresis{}", " \\*(4", "\\'A8", { " ", HtmlEntityMapper::Perl_umlaut }}, + { SYM(copy), "\xc2\xa9", "©", "<copy/>", "©", "\\copyright{}", "(C)", "\\'A9", { "copyright", HtmlEntityMapper::Perl_symbol }}, + { SYM(ordf), "\xc2\xaa", "ª", "<ordf/>", "ª", "\\textordfeminine{}", NULL, "\\'AA", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(laquo), "\xc2\xab", "«", "<laquo/>", "«", "\\guillemotleft{}", NULL, "\\'AB", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(not), "\xc2\xac", "¬", "<not/>", "¬", "\\textlnot", NULL, "\\'AC", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(shy), "\xc2\xad", "­", "<shy/>", "­", "{$\\-$}", NULL, "\\-", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(reg), "\xc2\xae", "®", "<registered/>", "®", "\\textregistered{}", "(R)", "\\'AE", { "registered", HtmlEntityMapper::Perl_symbol }}, + { SYM(macr), "\xc2\xaf", "¯", "<macr/>", "¯", "\\={}", NULL, "\\'AF", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(deg), "\xc2\xb0", "°", "<deg/>", "°", "\\textdegree{}", NULL, "\\'B0", { "deg", HtmlEntityMapper::Perl_symbol }}, + { SYM(plusmn), "\xc2\xb1", "±", "<plusmn/>", "±", "{$\\pm$}", NULL, "\\'B1", { "+/-", HtmlEntityMapper::Perl_string }}, + { SYM(sup2), "\xc2\xb2", "²", "<sup2/>", "²", "\\texttwosuperior{}", NULL, "\\'B2", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(sup3), "\xc2\xb3", "³", "<sup3/>", "³", "\\textthreesuperior{}", NULL, "\\'B3", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(acute), "\xc2\xb4", "´", "<acute/>", "´", "\\'{}", NULL, "\\'B4", { " ", HtmlEntityMapper::Perl_acute }}, + { SYM(micro), "\xc2\xb5", "µ", "<micro/>", "µ", "{$\\mu$}", NULL, "\\'B5", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(para), "\xc2\xb6", "¶", "<para/>", "¶", "{$\\P$}", NULL, "\\'B6", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(middot), "\xc2\xb7", "·", "<middot/>", "·", "\\textperiodcentered{}", NULL, "\\'B7", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(cedil), "\xc2\xb8", "¸", "<cedil/>", "¸", "\\c{}", " \\*,", "\\'B8", { " ", HtmlEntityMapper::Perl_cedilla }}, + { SYM(sup1), "\xc2\xb9", "¹", "<sup1/>", "¹", "\\textonesuperior{}", NULL, "\\'B9", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(ordm), "\xc2\xba", "º", "<ordm/>", "º", "\\textordmasculine{}", NULL, "\\'BA", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(raquo), "\xc2\xbb", "»", "<raquo/>", "»", "\\guillemotright{}", NULL, "\\'BB", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(frac14), "\xc2\xbc", "¼", "<frac14/>", "¼", "{$\\frac14$}", "1/4", "\\'BC", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(frac12), "\xc2\xbd", "½", "<frac12/>", "½", "{$\\frac12$}", "1/2", "\\'BD", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(frac34), "\xc2\xbe", "¾", "<frac34/>", "¾", "{$\\frac34$}", "3/4", "\\'BE", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(iquest), "\xc2\xbf", "¿", "<iquest/>", "¿", "?`", NULL, "\\'BF", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(Agrave), "\xc3\x80", "À", "<Agrave/>", "À", "\\`{A}", "A\\*:", "\\'C0", { "A", HtmlEntityMapper::Perl_grave }}, + { SYM(Aacute), "\xc3\x81", "Á", "<Aacute/>", "Á", "\\'{A}", "A\\*(`", "\\'C1", { "A", HtmlEntityMapper::Perl_acute }}, + { SYM(Acirc), "\xc3\x82", "Â", "<Acirc/>", "Â", "\\^{A}", "A\\*^", "\\'C2", { "A", HtmlEntityMapper::Perl_circ }}, + { SYM(Atilde), "\xc3\x83", "Ã", "<Atilde/>", "Ã", "\\~{A}", "A\\*~", "\\'C3", { "A", HtmlEntityMapper::Perl_tilde }}, + { SYM(Auml), "\xc3\x84", "Ä", "<Aumlaut/>", "Ä", "\\\"{A}", "A\\*(4", "\\'C4", { "A", HtmlEntityMapper::Perl_umlaut }}, + { SYM(Aring), "\xc3\x85", "Å", "<Aring/>", "Å", "\\AA", "A\\*o", "\\'C5", { "A", HtmlEntityMapper::Perl_ring }}, + { SYM(AElig), "\xc3\x86", "Æ", "<AElig/>", "Æ", "{\\AE}", NULL, "\\'C6", { "AElig", HtmlEntityMapper::Perl_symbol }}, + { SYM(Ccedil), "\xc3\x87", "Ç", "<Ccedil/>", "Ç", "\\c{C}", "C\\*,", "\\'C7", { "C", HtmlEntityMapper::Perl_cedilla }}, + { SYM(Egrave), "\xc3\x88", "È", "<Egrave/>", "È", "\\`{E}", "E\\*:", "\\'C8", { "E", HtmlEntityMapper::Perl_grave }}, + { SYM(Eacute), "\xc3\x89", "É", "<Eacute/>", "É", "\\'{E}", "E\\*(`", "\\'C9", { "E", HtmlEntityMapper::Perl_acute }}, + { SYM(Ecirc), "\xc3\x8a", "Ê", "<Ecirc/>", "Ê", "\\^{E}", "E\\*^", "\\'CA", { "E", HtmlEntityMapper::Perl_circ }}, + { SYM(Euml), "\xc3\x8b", "Ë", "<Eumlaut/>", "Ë", "\\\"{E}", "E\\*(4", "\\'CB", { "E", HtmlEntityMapper::Perl_umlaut }}, + { SYM(Igrave), "\xc3\x8c", "Ì", "<Igrave/>", "Ì", "\\`{I}", "I\\*:", "\\'CC", { "I", HtmlEntityMapper::Perl_grave }}, + { SYM(Iacute), "\xc3\x8d", "Í", "<Iacute/>", "Í", "\\'{I}", "I\\*(`", "\\'CD", { "I", HtmlEntityMapper::Perl_acute }}, + { SYM(Icirc), "\xc3\x8e", "Î", "<Icirc/>", "Î", "\\^{I}", "I\\*^", "\\'CE", { "I", HtmlEntityMapper::Perl_circ }}, + { SYM(Iuml), "\xc3\x8f", "Ï", "<Iumlaut/>", "Ï", "\\\"{I}", "I\\*(4", "\\'CF", { "I", HtmlEntityMapper::Perl_umlaut }}, + { SYM(ETH), "\xc3\x90", "Ð", "<ETH/>", "Ð", "\\DH", NULL, "\\'D0", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(Ntilde), "\xc3\x91", "Ñ", "<Ntilde/>", "Ñ", "\\~{N}", "N\\*~", "\\'D1", { "N", HtmlEntityMapper::Perl_tilde }}, + { SYM(Ograve), "\xc3\x92", "Ò", "<Ograve/>", "Ò", "\\`{O}", "O\\*:", "\\'D2", { "O", HtmlEntityMapper::Perl_grave }}, + { SYM(Oacute), "\xc3\x93", "Ó", "<Oacute/>", "Ó", "\\'{O}", "O\\*(`", "\\'D3", { "O", HtmlEntityMapper::Perl_acute }}, + { SYM(Ocirc), "\xc3\x94", "Ô", "<Ocirc/>", "Ô", "\\^{O}", "O\\*^", "\\'D4", { "O", HtmlEntityMapper::Perl_circ }}, + { SYM(Otilde), "\xc3\x95", "Õ", "<Otilde/>", "Õ", "\\~{O}", "O\\*~", "\\'D5", { "O", HtmlEntityMapper::Perl_tilde }}, + { SYM(Ouml), "\xc3\x96", "Ö", "<Oumlaut/>", "Ö", "\\\"{O}", "O\\*(4", "\\'D6", { "O", HtmlEntityMapper::Perl_umlaut }}, + { SYM(times), "\xc3\x97", "×", "<times/>", "×", "{$\\times$}", NULL, "\\'D7", { "*", HtmlEntityMapper::Perl_char }}, + { SYM(Oslash), "\xc3\x98", "Ø", "<Oslash/>", "Ø", "{\\O}", "O\x08/", "\\'D8", { "O", HtmlEntityMapper::Perl_slash }}, + { SYM(Ugrave), "\xc3\x99", "Ù", "<Ugrave/>", "Ù", "\\`{U}", "U\\*:", "\\'D9", { "U", HtmlEntityMapper::Perl_grave }}, + { SYM(Uacute), "\xc3\x9a", "Ú", "<Uacute/>", "Ú", "\\'{U}", "U\\*(`", "\\'DA", { "U", HtmlEntityMapper::Perl_acute }}, + { SYM(Ucirc), "\xc3\x9b", "Û", "<Ucirc/>", "Û", "\\^{U}", "U\\*^", "\\'DB", { "U", HtmlEntityMapper::Perl_circ }}, + { SYM(Uuml), "\xc3\x9c", "Ü", "<Uumlaut/>", "Ü", "\\\"{U}", "U\\*(4", "\\'DC", { "U", HtmlEntityMapper::Perl_umlaut }}, + { SYM(Yacute), "\xc3\x9d", "Ý", "<Yacute/>", "Ý", "\\'{Y}", "Y\\*(`", "\\'DD", { "Y", HtmlEntityMapper::Perl_acute }}, + { SYM(THORN), "\xc3\x9e", "Þ", "<THORN/>", "Þ", "\\TH", NULL, "\\'DE", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(szlig), "\xc3\x9f", "ß", "<szlig/>", "ß", "{\\ss}", "s\\*:", "\\'DF", { "szlig", HtmlEntityMapper::Perl_symbol }}, + { SYM(agrave), "\xc3\xa0", "à", "<agrave/>", "à", "\\`{a}", "a\\*:", "\\'E0", { "a", HtmlEntityMapper::Perl_grave }}, + { SYM(aacute), "\xc3\xa1", "á", "<aacute/>", "á", "\\'{a}", "a\\*(`", "\\'E1", { "a", HtmlEntityMapper::Perl_acute }}, + { SYM(acirc), "\xc3\xa2", "â", "<acirc/>", "â", "\\^{a}", "a\\*^", "\\'E2", { "a", HtmlEntityMapper::Perl_circ }}, + { SYM(atilde), "\xc3\xa3", "ã", "<atilde/>", "ã", "\\~{a}", "a\\*~", "\\'E3", { "a", HtmlEntityMapper::Perl_tilde }}, + { SYM(auml), "\xc3\xa4", "ä", "<aumlaut/>", "ä", "\\\"{a}", "a\\*(4", "\\'E4", { "a", HtmlEntityMapper::Perl_umlaut }}, + { SYM(aring), "\xc3\xa5", "å", "<aring/>", "å", "\\aa", "a\\*o", "\\'E5", { "a", HtmlEntityMapper::Perl_ring }}, + { SYM(aelig), "\xc3\xa6", "æ", "<aelig/>", "æ", "{\\ae}", NULL, "\\'E6", { "aelig", HtmlEntityMapper::Perl_symbol }}, + { SYM(ccedil), "\xc3\xa7", "ç", "<ccedil/>", "ç", "\\c{c}", "c\\*,", "\\'E7", { "c", HtmlEntityMapper::Perl_cedilla }}, + { SYM(egrave), "\xc3\xa8", "è", "<egrave/>", "è", "\\`{e}", "e\\*:", "\\'E8", { "e", HtmlEntityMapper::Perl_grave }}, + { SYM(eacute), "\xc3\xa9", "é", "<eacute/>", "é", "\\'{e}", "e\\*(`", "\\'E9", { "e", HtmlEntityMapper::Perl_acute }}, + { SYM(ecirc), "\xc3\xaa", "ê", "<ecirc/>", "ê", "\\^{e}", "e\\*^", "\\'EA", { "e", HtmlEntityMapper::Perl_circ }}, + { SYM(euml), "\xc3\xab", "ë", "<eumlaut/>", "ë", "\\\"{e}", "e\\*(4", "\\'EB", { "e", HtmlEntityMapper::Perl_umlaut }}, + { SYM(igrave), "\xc3\xac", "ì", "<igrave/>", "ì", "\\`{\\i}", "i\\*:", "\\'EC", { "i", HtmlEntityMapper::Perl_grave }}, + { SYM(iacute), "\xc3\xad", "í", "<iacute/>", "í", "\\'{\\i}", "i\\*(`", "\\'ED", { "i", HtmlEntityMapper::Perl_acute }}, + { SYM(icirc), "\xc3\xae", "î", "<icirc/>", "î", "\\^{\\i}", "i\\*^", "\\'EE", { "i", HtmlEntityMapper::Perl_circ }}, + { SYM(iuml), "\xc3\xaf", "ï", "<iumlaut/>", "ï", "\\\"{\\i}", "i\\*(4", "\\'EF", { "i", HtmlEntityMapper::Perl_umlaut }}, + { SYM(eth), "\xc3\xb0", "ð", "<eth/>", "ð", "\\dh", NULL, "\\'F0", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(ntilde), "\xc3\xb1", "ñ", "<ntilde/>", "ñ", "\\~{n}", "n\\*~", "\\'F1", { "n", HtmlEntityMapper::Perl_tilde }}, + { SYM(ograve), "\xc3\xb2", "ò", "<ograve/>", "ò", "\\`{o}", "o\\*:", "\\'F2", { "o", HtmlEntityMapper::Perl_grave }}, + { SYM(oacute), "\xc3\xb3", "ó", "<oacute/>", "ó", "\\'{o}", "o\\*(`", "\\'F3", { "o", HtmlEntityMapper::Perl_acute }}, + { SYM(ocirc), "\xc3\xb4", "ô", "<ocirc/>", "ô", "\\^{o}", "o\\*^", "\\'F4", { "o", HtmlEntityMapper::Perl_circ }}, + { SYM(otilde), "\xc3\xb5", "õ", "<otilde/>", "õ", "\\~{o}", "o\\*~", "\\'F5", { "o", HtmlEntityMapper::Perl_tilde }}, + { SYM(ouml), "\xc3\xb6", "ö", "<oumlaut/>", "ö", "\\\"{o}", "o\\*(4", "\\'F6", { "o", HtmlEntityMapper::Perl_umlaut }}, + { SYM(divide), "\xc3\xb7", "÷", "<divide/>", "÷", "{$\\div$}", NULL, "\\'F7", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(oslash), "\xc3\xb8", "ø", "<oslash/>", "ø", "{\\o}", "o\x08/", "\\'F8", { "o", HtmlEntityMapper::Perl_slash }}, + { SYM(ugrave), "\xc3\xb9", "ù", "<ugrave/>", "ù", "\\`{u}", "u\\*:", "\\'F9", { "u", HtmlEntityMapper::Perl_grave }}, + { SYM(uacute), "\xc3\xba", "ú", "<uacute/>", "ú", "\\'{u}", "u\\*(`", "\\'FA", { "u", HtmlEntityMapper::Perl_acute }}, + { SYM(ucirc), "\xc3\xbb", "û", "<ucirc/>", "û", "\\^{u}", "u\\*^", "\\'FB", { "u", HtmlEntityMapper::Perl_circ }}, + { SYM(uuml), "\xc3\xbc", "ü", "<uumlaut/>", "ü", "\\\"{u}", "u\\*(4", "\\'FC", { "u", HtmlEntityMapper::Perl_umlaut }}, + { SYM(yacute), "\xc3\xbd", "ý", "<yacute/>", "ý", "\\'{y}", "y\\*(`", "\\'FD", { "y", HtmlEntityMapper::Perl_acute }}, + { SYM(thorn), "\xc3\xbe", "þ", "<thorn/>", "þ", "\\th", NULL, "\\'FE", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(yuml), "\xc3\xbf", "ÿ", "<yumlaut/>", "ÿ", "\\\"{y}", "y\\*(4", "\\'FF", { "y", HtmlEntityMapper::Perl_umlaut }}, + { SYM(fnof), "\xc6\x92", "ƒ", "<fnof/>", "ƒ", "\\textflorin", NULL, "\\'83", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(Alpha), "\xce\x91", "Α", "<Alpha/>", "Α", "A", NULL, "\\u0913?", { "A", HtmlEntityMapper::Perl_char }}, + { SYM(Beta), "\xce\x92", "Β", "<Beta/>", "Β", "B", NULL, "\\u0914?", { "B", HtmlEntityMapper::Perl_char }}, + { SYM(Gamma), "\xce\x93", "Γ", "<Gamma/>", "Γ", "{$\\Gamma$}", NULL, "\\u0915?", { "Gamma", HtmlEntityMapper::Perl_symbol }}, + { SYM(Delta), "\xce\x94", "Δ", "<Delta/>", "Δ", "{$\\Delta$}", NULL, "\\u0916?", { "Delta", HtmlEntityMapper::Perl_symbol }}, + { SYM(Epsilon), "\xce\x95", "Ε", "<Epsilon/>", "Ε", "E", NULL, "\\u0917?", { "E", HtmlEntityMapper::Perl_char }}, + { SYM(Zeta), "\xce\x96", "Ζ", "<Zeta/>", "Ζ", "Z", NULL, "\\u0918?", { "Z", HtmlEntityMapper::Perl_char }}, + { SYM(Eta), "\xce\x97", "Η", "<Eta/>", "Η", "H", NULL, "\\u0919?", { "H", HtmlEntityMapper::Perl_char }}, + { SYM(Theta), "\xce\x98", "Θ", "<Theta/>", "Θ", "{$\\Theta$}", NULL, "\\u0920?", { "Theta", HtmlEntityMapper::Perl_symbol }}, + { SYM(Iota), "\xce\x99", "Ι", "<Iota/>", "Ι", "I", NULL, "\\u0921?", { "I", HtmlEntityMapper::Perl_char }}, + { SYM(Kappa), "\xce\x9a", "Κ", "<Kappa/>", "Κ", "K", NULL, "\\u0922?", { "K", HtmlEntityMapper::Perl_char }}, + { SYM(Lambda), "\xce\x9b", "Λ", "<Lambda/>", "Λ", "{$\\Lambda$}", NULL, "\\u0923?", { "Lambda", HtmlEntityMapper::Perl_symbol }}, + { SYM(Mu), "\xce\x9c", "Μ", "<Mu/>", "Μ", "M", NULL, "\\u0924?", { "M", HtmlEntityMapper::Perl_char }}, + { SYM(Nu), "\xce\x9d", "Ν", "<Nu/>", "Ν", "N", NULL, "\\u0925?", { "N", HtmlEntityMapper::Perl_char }}, + { SYM(Xi), "\xce\x9e", "Ξ", "<Xi/>", "Ξ", "{$\\Xi$}", NULL, "\\u0926?", { "Xi", HtmlEntityMapper::Perl_symbol }}, + { SYM(Omicron), "\xce\x9f", "Ο", "<Omicron/>", "Ο", "O", NULL, "\\u0927?", { "O", HtmlEntityMapper::Perl_char }}, + { SYM(Pi), "\xce\xa0", "Π", "<Pi/>", "Π", "{$\\Pi$}", NULL, "\\u0928?", { "Pi", HtmlEntityMapper::Perl_symbol }}, + { SYM(Rho), "\xce\xa1", "Ρ", "<Rho/>", "Ρ", "P", NULL, "\\u0929?", { "P", HtmlEntityMapper::Perl_char }}, + { SYM(Sigma), "\xce\xa3", "Σ", "<Sigma/>", "Σ", "{$\\Sigma$}", NULL, "\\u0931?", { "Sigma", HtmlEntityMapper::Perl_symbol }}, + { SYM(Tau), "\xce\xa4", "Τ", "<Tau/>", "Τ", "T", NULL, "\\u0932?", { "T", HtmlEntityMapper::Perl_char }}, + { SYM(Upsilon), "\xce\xa5", "Υ", "<Upsilon/>", "Υ", "{$\\Upsilon$}", NULL, "\\u0933?", { "Upsilon", HtmlEntityMapper::Perl_symbol }}, + { SYM(Phi), "\xce\xa6", "Φ", "<Phi/>", "Φ", "{$\\Phi$}", NULL, "\\u0934?", { "Phi", HtmlEntityMapper::Perl_symbol }}, + { SYM(Chi), "\xce\xa7", "Χ", "<Chi/>", "Χ", "X", NULL, "\\u0935?", { "X", HtmlEntityMapper::Perl_char }}, + { SYM(Psi), "\xce\xa8", "Ψ", "<Psi/>", "Ψ", "{$\\Psi$}", NULL, "\\u0936?", { "Psi", HtmlEntityMapper::Perl_symbol }}, + { SYM(Omega), "\xce\xa9", "Ω", "<Omega/>", "Ω", "{$\\Omega$}", NULL, "\\u0937?", { "Omega", HtmlEntityMapper::Perl_symbol }}, + { SYM(alpha), "\xce\xb1", "α", "<alpha/>", "α", "{$\\alpha$}", NULL, "\\u0945?", { "alpha", HtmlEntityMapper::Perl_symbol }}, + { SYM(beta), "\xce\xb2", "β", "<beta/>", "β", "{$\\beta$}", NULL, "\\u0946?", { "beta", HtmlEntityMapper::Perl_symbol }}, + { SYM(gamma), "\xce\xb3", "γ", "<gamma/>", "γ", "{$\\gamma$}", NULL, "\\u0947?", { "gamma", HtmlEntityMapper::Perl_symbol }}, + { SYM(delta), "\xce\xb4", "δ", "<delta/>", "δ", "{$\\delta$}", NULL, "\\u0948?", { "delta", HtmlEntityMapper::Perl_symbol }}, + { SYM(epsilon), "\xce\xb5", "ε", "<epsilon/>", "ε", "{$\\varepsilon$}", NULL, "\\u0949?", { "epsilon", HtmlEntityMapper::Perl_symbol }}, + { SYM(zeta), "\xce\xb6", "ζ", "<zeta/>", "ζ", "{$\\zeta$}", NULL, "\\u0950?", { "zeta", HtmlEntityMapper::Perl_symbol }}, + { SYM(eta), "\xce\xb7", "η", "<eta/>", "η", "{$\\eta$}", NULL, "\\u0951?", { "eta", HtmlEntityMapper::Perl_symbol }}, + { SYM(theta), "\xce\xb8", "θ", "<theta/>", "θ", "{$\\theta$}", NULL, "\\u0952?", { "theta", HtmlEntityMapper::Perl_symbol }}, + { SYM(iota), "\xce\xb9", "ι", "<iota/>", "ι", "{$\\iota$}", NULL, "\\u0953?", { "iota", HtmlEntityMapper::Perl_symbol }}, + { SYM(kappa), "\xce\xba", "κ", "<kappa/>", "κ", "{$\\kappa$}", NULL, "\\u0954?", { "kappa", HtmlEntityMapper::Perl_symbol }}, + { SYM(lambda), "\xce\xbb", "λ", "<lambda/>", "λ", "{$\\lambda$}", NULL, "\\u0955?", { "lambda", HtmlEntityMapper::Perl_symbol }}, + { SYM(mu), "\xce\xbc", "μ", "<mu/>", "μ", "{$\\mu$}", NULL, "\\u0956?", { "mu", HtmlEntityMapper::Perl_symbol }}, + { SYM(nu), "\xce\xbd", "ν", "<nu/>", "ν", "{$\\nu$}", NULL, "\\u0957?", { "nu", HtmlEntityMapper::Perl_symbol }}, + { SYM(xi), "\xce\xbe", "ξ", "<xi/>", "ξ", "{$\\xi$}", NULL, "\\u0958?", { "xi", HtmlEntityMapper::Perl_symbol }}, + { SYM(omicron), "\xce\xbf", "ο", "<omicron/>", "ο", "{$\\omicron$}", NULL, "\\u0959?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(pi), "\xcf\x80", "π", "<pi/>", "π", "{$\\pi$}", NULL, "\\u0960?", { "pi", HtmlEntityMapper::Perl_symbol }}, + { SYM(rho), "\xcf\x81", "ρ", "<rho/>", "ρ", "{$\\rho$}", NULL, "\\u0961?", { "rho", HtmlEntityMapper::Perl_symbol }}, + { SYM(sigmaf), "\xcf\x82", "ς", "<sigmaf/>", "ς", "{$\\varsigma$}", NULL, "\\u0962?", { "sigma", HtmlEntityMapper::Perl_symbol }}, + { SYM(sigma), "\xcf\x83", "σ", "<sigma/>", "σ", "{$\\sigma$}", NULL, "\\u0963?", { "sigma", HtmlEntityMapper::Perl_symbol }}, + { SYM(tau), "\xcf\x84", "τ", "<tau/>", "τ", "{$\\tau$}", NULL, "\\u0964?", { "tau", HtmlEntityMapper::Perl_symbol }}, + { SYM(upsilon), "\xcf\x85", "υ", "<upsilon/>", "υ", "{$\\upsilon$}", NULL, "\\u0965?", { "upsilon", HtmlEntityMapper::Perl_symbol }}, + { SYM(phi), "\xcf\x86", "φ", "<phi/>", "φ", "{$\\varphi$}", NULL, "\\u0966?", { "phi", HtmlEntityMapper::Perl_symbol }}, + { SYM(chi), "\xcf\x87", "χ", "<chi/>", "χ", "{$\\chi$}", NULL, "\\u0967?", { "chi", HtmlEntityMapper::Perl_symbol }}, + { SYM(psi), "\xcf\x88", "ψ", "<psi/>", "ψ", "{$\\psi$}", NULL, "\\u0968?", { "psi", HtmlEntityMapper::Perl_symbol }}, + { SYM(omega), "\xcf\x89", "ω", "<omega/>", "ω", "{$\\omega$}", NULL, "\\u0969?", { "omega", HtmlEntityMapper::Perl_symbol }}, + { SYM(thetasym), "\xcf\x91", "ϑ", "<thetasym/>", "ϑ", "{$\\vartheta$}", NULL, "\\u977?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(upsih), "\xcf\x92", "ϒ", "<upsih/>", "ϒ", "{$\\Upsilon$}", NULL, "\\u978?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(piv), "\xcf\x96", "ϖ", "<piv/>", "ϖ", "{$\\varpi$}", NULL, "\\u982?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(bull), "\xe2\x80\xa2", "•", "<bull/>", "•", "\\textbullet{}", NULL, "\\'95", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(hellip), "\xe2\x80\xa6", "…", "<hellip/>", "…", "{$\\dots$}", NULL, "\\'85", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(prime), "\xe2\x80\xb2", "′", "<prime/>", "′", "'", NULL, "\\u8242?", { "\\\'", HtmlEntityMapper::Perl_string }}, + { SYM(Prime), "\xe2\x80\xb3", "″", "<Prime/>", "″", "''", NULL, "\\u8243?", { "\"", HtmlEntityMapper::Perl_char }}, + { SYM(oline), "\xe2\x80\xbe", "‾", "<oline/>", "‾", "{$\\overline{\\,}$}", NULL, "\\u8254?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(frasl), "\xe2\x81\x84", "⁄", "<frasl/>", "⁄", "/", NULL, "\\u8260?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(weierp), "\xe2\x84\x98", "℘", "<weierp/>", "℘", "{$\\wp$}", NULL, "\\u8472?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(image), "\xe2\x84\x91", "ℑ", "<imaginary/>", "ℑ", "{$\\Im$}", NULL, "\\u8465?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(real), "\xe2\x84\x9c", "ℜ", "<real/>", "ℜ", "{$\\Re$}", NULL, "\\u8476?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(trade), "\xe2\x84\xa2", "™", "<trademark/>", "™", "\\texttrademark{}", "(TM)", "\\'99", { "trademark", HtmlEntityMapper::Perl_symbol }}, + { SYM(alefsym), "\xe2\x85\xb5", "ℵ", "<alefsym/>", "ℵ", "{$\\aleph$}", NULL, "\\u8501?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(larr), "\xe2\x86\x90", "←", "<larr/>", "←", "{$\\leftarrow$}", NULL, "\\u8592?", { "<-", HtmlEntityMapper::Perl_string }}, + { SYM(uarr), "\xe2\x86\x91", "↑", "<uarr/>", "↑", "{$\\uparrow$}", NULL, "\\u8593?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(rarr), "\xe2\x86\x92", "→", "<rarr/>", "→", "{$\\rightarrow$}", NULL, "\\u8594?", { "->", HtmlEntityMapper::Perl_string }}, + { SYM(darr), "\xe2\x86\x93", "↓", "<darr/>", "↓", "{$\\downarrow$}", NULL, "\\u8595?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(harr), "\xe2\x86\x94", "↔", "<harr/>", "↔", "{$\\leftrightarrow$}", NULL, "\\u8596?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(crarr), "\xe2\x86\xb5", "↵", "<crarr/>", "↵", "{$\\hookleftarrow$}", NULL, "\\u8629?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(lArr), "\xe2\x87\x90", "⇐", "<lArr/>", "⇐", "{$\\Leftarrow$}", NULL, "\\u8656?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(uArr), "\xe2\x87\x91", "⇑", "<uArr/>", "⇑", "{$\\Uparrow$}", NULL, "\\u8657?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(rArr), "\xe2\x87\x92", "⇒", "<rArr/>", "⇒", "{$\\Rightarrow$}", NULL, "\\u8658?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(dArr), "\xe2\x87\x93", "⇓", "<dArr/>", "⇓", "{$\\Downarrow$}", NULL, "\\u8659?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(hArr), "\xe2\x87\x94", "⇔", "<hArr/>", "⇔", "{$\\Leftrightarrow$}", NULL, "\\u8660?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(forall), "\xe2\x88\x80", "∀", "<forall/>", "∀", "{$\\forall$}", NULL, "\\u8704?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(part), "\xe2\x88\x82", "∂", "<part/>", "∂", "{$\\partial$}", NULL, "\\u8706?", { "partial", HtmlEntityMapper::Perl_symbol }}, + { SYM(exist), "\xe2\x88\x83", "∃", "<exist/>", "∃", "{$\\exists$}", NULL, "\\u8707?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(empty), "\xe2\x88\x85", "∅", "<empty/>", "∅", "{$\\emptyset$}", NULL, "\\u8709?", { "empty", HtmlEntityMapper::Perl_symbol }}, + { SYM(nabla), "\xe2\x88\x87", "∇", "<nabla/>", "∇", "{$\\nabla$}", NULL, "\\u8711?", { "nabla", HtmlEntityMapper::Perl_symbol }}, + { SYM(isin), "\xe2\x88\x88", "∈", "<isin/>", "∈", "{$\\in$}", NULL, "\\u8712?", { "in", HtmlEntityMapper::Perl_symbol }}, + { SYM(notin), "\xe2\x88\x89", "∉", "<notin/>", "∉", "{$\\notin$}", NULL, "\\u8713?", { "notin", HtmlEntityMapper::Perl_symbol }}, + { SYM(ni), "\xe2\x88\x8b", "∋", "<ni/>", "∋", "{$\\ni$}", NULL, "\\u8715?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(prod), "\xe2\x88\x8f", "∏", "<prod/>", "∏", "{$\\prod$}", NULL, "\\u8719?", { "prod", HtmlEntityMapper::Perl_symbol }}, + { SYM(sum), "\xe2\x88\x91", "∑", "<sum/>", "∑", "{$\\sum$}", NULL, "\\u8721?", { "sum", HtmlEntityMapper::Perl_symbol }}, + { SYM(minus), "\xe2\x88\x92", "−", "<minus/>", "−", "-", NULL, "\\u8722?", { "-", HtmlEntityMapper::Perl_char }}, + { SYM(lowast), "\xe2\x88\x97", "∗", "<lowast/>", "∗", "{$\\ast$}", NULL, "\\u8727?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(radic), "\xe2\x88\x9a", "√", "<radic/>", "√", "{$\\surd$}", NULL, "\\u8730?", { "sqrt", HtmlEntityMapper::Perl_symbol }}, + { SYM(prop), "\xe2\x88\x9d", "∝", "<prop/>", "∝", "{$\\propto$}", NULL, "\\u8733?", { "propto", HtmlEntityMapper::Perl_symbol }}, + { SYM(infin), "\xe2\x88\x9e", "∞", "<infin/>", "∞", "{$\\infty$}", NULL, "\\u8734?", { "inf", HtmlEntityMapper::Perl_symbol }}, + { SYM(ang), "\xe2\x88\xa0", "∠", "<ang/>", "∠", "{$\\angle$}", NULL, "\\u8736?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(and), "\xe2\x88\xa7", "∧", "<and/>", "∧", "{$\\wedge$}", NULL, "\\u8743?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(or), "\xe2\x88\xa8", "∨", "<or/>", "∨", "{$\\vee$}", NULL, "\\u8744?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(cap), "\xe2\x88\xa9", "∩", "<cap/>", "∩", "{$\\cap$}", NULL, "\\u8745?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(cup), "\xe2\x88\xaa", "∪", "<cup/>", "∪", "{$\\cup$}", NULL, "\\u8746?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(int), "\xe2\x88\xab", "∫", "<int/>", "∫", "{$\\int$}", NULL, "\\u8747?", { "int", HtmlEntityMapper::Perl_symbol }}, + { SYM(there4), "\xe2\x88\xb4", "∴", "<there4/>", "∴", "{$\\therefore$}", NULL, "\\u8756?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(sim), "\xe2\x88\xbc", "∼", "<sim/>", "∼", "{$\\sim$}", NULL, "\\u8764?", { "~", HtmlEntityMapper::Perl_char }}, + { SYM(cong), "\xe2\x89\x85", "≅", "<cong/>", "≅", "{$\\cong$}", NULL, "\\u8773?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(asymp), "\xe2\x89\x88", "≈", "<asymp/>", "≈", "{$\\approx$}", NULL, "\\u8776?", { "approx", HtmlEntityMapper::Perl_symbol }}, + { SYM(ne), "\xe2\x89\xa0", "≠", "<ne/>", "≠", "{$\\ne$}", NULL, "\\u8800?", { "!=", HtmlEntityMapper::Perl_string }}, + { SYM(equiv), "\xe2\x89\xa1", "≡", "<equiv/>", "≡", "{$\\equiv$}", NULL, "\\u8801?", { "equiv", HtmlEntityMapper::Perl_symbol }}, + { SYM(le), "\xe2\x89\xa4", "≤", "<le/>", "≤", "{$\\le$}", NULL, "\\u8804?", { "<=", HtmlEntityMapper::Perl_string }}, + { SYM(ge), "\xe2\x89\xa5", "≥", "<ge/>", "≥", "{$\\ge$}", NULL, "\\u8805?", { ">=", HtmlEntityMapper::Perl_string }}, + { SYM(sub), "\xe2\x8a\x82", "⊂", "<sub/>", "⊂", "{$\\subset$}", NULL, "\\u8834?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(sup), "\xe2\x8a\x83", "⊃", "<sup/>", "⊃", "{$\\supset$}", NULL, "\\u8835?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(nsub), "\xe2\x8a\x84", "⊄", "<nsub/>", "⊄", "{$\\not\\subset$}", NULL, "\\u8836?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(sube), "\xe2\x8a\x86", "⊆", "<sube/>", "⊆", "{$\\subseteq$}", NULL, "\\u8838?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(supe), "\xe2\x8a\x87", "⊇", "<supe/>", "⊇", "{$\\supseteq$}", NULL, "\\u8839?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(oplus), "\xe2\x8a\x95", "⊕", "<oplus/>", "⊕", "{$\\oplus$}", NULL, "\\u8853?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(otimes), "\xe2\x8a\x97", "⊗", "<otimes/>", "⊗", "{$\\otimes$}", NULL, "\\u8855?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(perp), "\xe2\x8a\xa5", "⊥", "<perp/>", "⊥", "{$\\perp$}", NULL, "\\u8869?", { "perp", HtmlEntityMapper::Perl_symbol }}, + { SYM(sdot), "\xe2\x8b\x85", "⋅", "<sdot/>", "⋅", "{$\\cdot$}", NULL, "\\u8901?", { ".", HtmlEntityMapper::Perl_char }}, + { SYM(lceil), "\xe2\x8c\x88", "⌈", "<lceil/>", "⌈", "{$\\lceil$}", NULL, "\\u8968?", { "lceil", HtmlEntityMapper::Perl_symbol }}, + { SYM(rceil), "\xe2\x8c\x89", "⌉", "<rceil/>", "⌉", "{$\\rceil$}", NULL, "\\u8969?", { "rceil", HtmlEntityMapper::Perl_symbol }}, + { SYM(lfloor), "\xe2\x8c\x8a", "⌊", "<lfloor/>", "⌊", "{$\\lfloor$}", NULL, "\\u8970?", { "lfloor", HtmlEntityMapper::Perl_symbol }}, + { SYM(rfloor), "\xe2\x8c\x8b", "⌋", "<rfloor/>", "⌋", "{$\\rfloor$}", NULL, "\\u8971?", { "rfloor", HtmlEntityMapper::Perl_symbol }}, + { SYM(lang), "\xe2\x8c\xa9", "⟨", "<lang/>", "〈", "{$\\langle$}", NULL, "\\u9001?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(rang), "\xe2\x8c\xaa", "⟩", "<rang/>", "〉", "{$\\rangle$}", NULL, "\\u9002?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(loz), "\xe2\x97\x8a", "◊", "<loz/>", "◊", "{$\\lozenge$}", NULL, "\\u9674?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(spades), "\xe2\x99\xa0", "♠", "<spades/>", "♠", "{$\\spadesuit$}", NULL, "\\u9824?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(clubs), "\xe2\x99\xa3", "♣", "<clubs/>", "♣", "{$\\clubsuit$}", NULL, "\\u9827?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(hearts), "\xe2\x99\xa5", "♥", "<hearts/>", "♥", "{$\\heartsuit$}", NULL, "\\u9829?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(diams), "\xe2\x99\xa6", "♦", "<diams/>", "♦", "{$\\diamondsuit$}", NULL, "\\u9830?", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(quot), "\"", """, "\"", """, "\"{}", "\"", "\"", { "\"", HtmlEntityMapper::Perl_char }}, + { SYM(amp), "&", "&", "&", "&", "\\&", "&", "&", { "&", HtmlEntityMapper::Perl_char }}, + { SYM(lt), "<", "<", "<", "<", "<", "<", "<", { "<", HtmlEntityMapper::Perl_char }}, + { SYM(gt), ">", ">", ">", ">", ">", ">", ">", { ">", HtmlEntityMapper::Perl_char }}, + { SYM(OElig), "\xc5\x92", "Œ", "<OElig/>", "Œ", "\\OE", NULL, "\\'8C", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(oelig), "\xc5\x93", "œ", "<oelig/>", "œ", "\\oe", NULL, "\\'9C", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(Scaron), "\xc5\xa0", "Š", "<Scaron/>", "Š", "\\v{S}", NULL, "\\'8A", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(scaron), "\xc5\xa1", "š", "<scaron/>", "š", "\\v{s}", NULL, "\\'9A", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(Yuml), "\xc5\xb8", "Ÿ", "<Yumlaut/>", "Ÿ", "\\\"{Y}", "Y\\*(4", "\\'9F", { "Y", HtmlEntityMapper::Perl_umlaut }}, + { SYM(circ), "\xcb\x86", "ˆ", "<circ/>", "ˆ", "{$\\circ$}", NULL, "\\'88", { " ", HtmlEntityMapper::Perl_circ }}, + { SYM(tilde), "\xcb\x9c", "˜", "<tilde/>", "˜", "\\~{}", "~", "\\'98", { " ", HtmlEntityMapper::Perl_tilde }}, + { SYM(ensp), "\xe2\x80\x82", " ", "<ensp/>", " ", "\\enskip{}", NULL, "{\\enspace}", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(emsp), "\xe2\x80\x83", " ", "<emsp/>", " ", "\\quad{}", NULL, "{\\emspace}", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(thinsp), "\xe2\x80\x89", " ", "<thinsp/>", " ", "\\,", NULL, "{\\qmspace}", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(zwnj), "\xe2\x80\x8c", "‌", "<zwnj/>", "‌", "{}", NULL, "\\zwnj", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(zwj), "\xe2\x80\x8d", "‍", "<zwj/>", "‍", "", NULL, "\\zwj", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(lrm), "\xe2\x80\x8e", "‎", "<lrm/>", "‎", "", NULL, "\\ltrmark", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(rlm), "\xe2\x80\x8f", "‏", "<rlm/>", "‏", "", NULL, "\\rtlmark", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(ndash), "\xe2\x80\x93", "–", "<ndash/>", "–", "--", "--", "\\'96", { "-", HtmlEntityMapper::Perl_char }}, + { SYM(mdash), "\xe2\x80\x94", "—", "<mdash/>", "—", "---", "---", "\\'97", { "--", HtmlEntityMapper::Perl_string }}, + { SYM(lsquo), "\xe2\x80\x98", "‘", "<lsquo/>", "‘", "`", "`", "\\'91", { "\\\'", HtmlEntityMapper::Perl_string }}, + { SYM(rsquo), "\xe2\x80\x99", "’", "<rsquo/>", "’", "'", "'", "\\'92", { "\\\'", HtmlEntityMapper::Perl_string }}, + { SYM(sbquo), "\xe2\x80\x9a", "‚", "<sbquo/>", "‚", "\\quotesinglbase{}", NULL, "\\'82", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(ldquo), "\xe2\x80\x9c", "“", "<ldquo/>", "“", "``", "``", "\\'93", { "\"", HtmlEntityMapper::Perl_char }}, + { SYM(rdquo), "\xe2\x80\x9d", "”", "<rdquo/>", "”", "''", "''", "\\'94", { "\"", HtmlEntityMapper::Perl_char }}, + { SYM(bdquo), "\xe2\x80\x9e", "„", "<bdquo/>", "„", "\\quotedblbase{}", NULL, "\\'84", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(dagger), "\xe2\x80\xa0", "†", "<dagger/>", "†", "{$\\dagger$}", NULL, "\\'86", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(Dagger), "\xe2\x80\xa1", "‡", "<Dagger/>", "‡", "{$\\ddagger$}", NULL, "\\'87", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(permil), "\xe2\x80\xb0", "‰", "<permil/>", "‰", "{$\\permil{}$}", NULL, "\\'89", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(lsaquo), "\xe2\x80\xb9", "‹", "<lsaquo/>", "‹", "\\guilsinglleft{}", NULL, "\\'8B", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(rsaquo), "\xe2\x80\xba", "›", "<rsaquo/>", "›", "\\guilsinglright{}", NULL, "\\'9B", { NULL, HtmlEntityMapper::Perl_unknown }}, + { SYM(euro), "\xe2\x82\xac", "€", "<euro/>", "€", "\\texteuro{}", NULL, "\\'80", { NULL, HtmlEntityMapper::Perl_unknown }}, // doxygen extension to the HTML4 table of HTML entities - { SYM(tm), "\xe2\x84\xa2", "™", "<tm/>", "™", "\\texttrademark{}", "(TM)", "\\'99", { "trademark", DocSymbol::Perl_symbol }}, - { SYM(apos), "'", "'", "'", "'", "\\textquotesingle{}", "'", "'", { "\\\'", DocSymbol::Perl_string }}, + { SYM(tm), "\xe2\x84\xa2", "™", "<tm/>", "™", "\\texttrademark{}", "(TM)", "\\'99", { "trademark", HtmlEntityMapper::Perl_symbol }}, + { SYM(apos), "'", "'", "'", "'", "\\textquotesingle{}", "'", "'", { "\\\'", HtmlEntityMapper::Perl_string }}, // doxygen commands represented as HTML entities - { SYM(BSlash), "\\", "\\", "\\", "\\", "\\textbackslash{}", "\\\\", "\\\\", { "\\\\", DocSymbol::Perl_string }}, - { SYM(At), "@", "@", "@", "@", "@", "@", "@", { "@", DocSymbol::Perl_char }}, - { SYM(Less), "<", "<", "<", "<", "<", "<", "<", { "<", DocSymbol::Perl_char }}, - { SYM(Greater), ">", ">", ">", ">", ">", ">", ">", { ">", DocSymbol::Perl_char }}, - { SYM(Amp), "&", "&", "&", "&", "\\&", "&", "&", { "&", DocSymbol::Perl_char }}, - { SYM(Dollar), "$", "$", "$", "$", "\\$", "$", "$", { "$", DocSymbol::Perl_char }}, - { SYM(Hash), "#;", "#", "#", "#", "\\#", "#", "#", { "#", DocSymbol::Perl_char }}, - { SYM(DoubleColon), "::", "::", "::", "::", "::", "::", "::", { "::", DocSymbol::Perl_string }}, - { SYM(Percent), "%", "%", "%", "%", "\\%", "%", "%", { "%", DocSymbol::Perl_char }}, - { SYM(Pipe), "|", "|", "|", "|", "$|$", "|", "|", { "|", DocSymbol::Perl_char }}, - { SYM(Quot), "\"", "\"", "\"", """, "\"{}", "\"", "\"", { "\"", DocSymbol::Perl_char }}, - { SYM(Minus), "-", "-", "-", "-", "-\\/", "-", "-", { "-", DocSymbol::Perl_char }}, - { SYM(Plus), "+", "+", "+", "+", "+", "+", "+", { "+", DocSymbol::Perl_char }}, - { SYM(Dot), ".", ".", ".", ".", ".", ".", ".", { ".", DocSymbol::Perl_char }}, - { SYM(Colon), ":", ":", ":", ":", ":", ":", ":", { ":", DocSymbol::Perl_char }}, - { SYM(Equal), "=", "=", "=", "=", "=", "=", "=", { "=", DocSymbol::Perl_char }} + { SYM(BSlash), "\\", "\\", "\\", "\\", "\\textbackslash{}", "\\\\", "\\\\", { "\\\\", HtmlEntityMapper::Perl_string }}, + { SYM(At), "@", "@", "@", "@", "@", "@", "@", { "@", HtmlEntityMapper::Perl_char }}, + { SYM(Less), "<", "<", "<", "<", "<", "<", "<", { "<", HtmlEntityMapper::Perl_char }}, + { SYM(Greater), ">", ">", ">", ">", ">", ">", ">", { ">", HtmlEntityMapper::Perl_char }}, + { SYM(Amp), "&", "&", "&", "&", "\\&", "&", "&", { "&", HtmlEntityMapper::Perl_char }}, + { SYM(Dollar), "$", "$", "$", "$", "\\$", "$", "$", { "$", HtmlEntityMapper::Perl_char }}, + { SYM(Hash), "#;", "#", "#", "#", "\\#", "#", "#", { "#", HtmlEntityMapper::Perl_char }}, + { SYM(DoubleColon), "::", "::", "::", "::", "::", "::", "::", { "::", HtmlEntityMapper::Perl_string }}, + { SYM(Percent), "%", "%", "%", "%", "\\%", "%", "%", { "%", HtmlEntityMapper::Perl_char }}, + { SYM(Pipe), "|", "|", "|", "|", "$|$", "|", "|", { "|", HtmlEntityMapper::Perl_char }}, + { SYM(Quot), "\"", "\"", "\"", """, "\"{}", "\"", "\"", { "\"", HtmlEntityMapper::Perl_char }}, + { SYM(Minus), "-", "-", "-", "-", "-\\/", "-", "-", { "-", HtmlEntityMapper::Perl_char }}, + { SYM(Plus), "+", "+", "+", "+", "+", "+", "+", { "+", HtmlEntityMapper::Perl_char }}, + { SYM(Dot), ".", ".", ".", ".", ".", ".", ".", { ".", HtmlEntityMapper::Perl_char }}, + { SYM(Colon), ":", ":", ":", ":", ":", ":", ":", { ":", HtmlEntityMapper::Perl_char }}, + { SYM(Equal), "=", "=", "=", "=", "=", "=", "=", { "=", HtmlEntityMapper::Perl_char }} }; -static const int g_numHtmlEntities = (int)(sizeof(g_htmlEntities)/ sizeof(*g_htmlEntities)); +static const int g_numHtmlEntities = static_cast<int>(sizeof(g_htmlEntities)/ sizeof(*g_htmlEntities)); HtmlEntityMapper *HtmlEntityMapper::s_instance = 0; @@ -363,9 +363,9 @@ void HtmlEntityMapper::deleteInstance() * @return the UTF8 code of the HTML entity, * in case the UTF code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::utf8(DocSymbol::SymType symb,bool useInPrintf) const +const char *HtmlEntityMapper::utf8(HtmlEntityMapper::SymType symb,bool useInPrintf) const { - if (useInPrintf && symb==DocSymbol::Sym_Percent) + if (useInPrintf && symb==HtmlEntityMapper::Sym_Percent) { return "%%"; // escape for printf } @@ -383,9 +383,9 @@ const char *HtmlEntityMapper::utf8(DocSymbol::SymType symb,bool useInPrintf) con * @return the html representation of the HTML entity, * in case the html code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::html(DocSymbol::SymType symb,bool useInPrintf) const +const char *HtmlEntityMapper::html(HtmlEntityMapper::SymType symb,bool useInPrintf) const { - if (useInPrintf && symb==DocSymbol::Sym_Percent) + if (useInPrintf && symb==HtmlEntityMapper::Sym_Percent) { return "%%"; // escape for printf } @@ -401,7 +401,7 @@ const char *HtmlEntityMapper::html(DocSymbol::SymType symb,bool useInPrintf) con * @return the XML code of the HTML entity, * in case the XML code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::xml(DocSymbol::SymType symb) const +const char *HtmlEntityMapper::xml(HtmlEntityMapper::SymType symb) const { return g_htmlEntities[symb].xml; } @@ -412,7 +412,7 @@ const char *HtmlEntityMapper::xml(DocSymbol::SymType symb) const * @return the docbook code of the HTML entity, * in case the docbook code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::docbook(DocSymbol::SymType symb) const +const char *HtmlEntityMapper::docbook(HtmlEntityMapper::SymType symb) const { return g_htmlEntities[symb].docbook; } @@ -423,7 +423,7 @@ const char *HtmlEntityMapper::docbook(DocSymbol::SymType symb) const * @return the LaTeX code of the HTML entity, * in case the LaTeX code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::latex(DocSymbol::SymType symb) const +const char *HtmlEntityMapper::latex(HtmlEntityMapper::SymType symb) const { return g_htmlEntities[symb].latex; } @@ -434,7 +434,7 @@ const char *HtmlEntityMapper::latex(DocSymbol::SymType symb) const * @return the man of the HTML entity, * in case the man code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::man(DocSymbol::SymType symb) const +const char *HtmlEntityMapper::man(HtmlEntityMapper::SymType symb) const { return g_htmlEntities[symb].man; } @@ -445,7 +445,7 @@ const char *HtmlEntityMapper::man(DocSymbol::SymType symb) const * @return the RTF of the HTML entity, * in case the RTF code is unknown \c NULL is returned. */ -const char *HtmlEntityMapper::rtf(DocSymbol::SymType symb) const +const char *HtmlEntityMapper::rtf(HtmlEntityMapper::SymType symb) const { return g_htmlEntities[symb].rtf; } @@ -455,9 +455,9 @@ const char *HtmlEntityMapper::rtf(DocSymbol::SymType symb) const * @param symb Code of the requested HTML entity * @return the pointer to perl struct with the perl code of the HTML entity, * in case the perl code does not exists the NULL pointer is entered in the - * \c symb field and in the `DocSymbol::Perl_unknown` in the \c type field. + * \c symb field and in the `HtmlEntityMapper::Perl_unknown` in the \c type field. */ -const DocSymbol::PerlSymb *HtmlEntityMapper::perl(DocSymbol::SymType symb) const +const HtmlEntityMapper::PerlSymb *HtmlEntityMapper::perl(HtmlEntityMapper::SymType symb) const { return &g_htmlEntities[symb].perl; } @@ -466,12 +466,12 @@ const DocSymbol::PerlSymb *HtmlEntityMapper::perl(DocSymbol::SymType symb) const * @brief Give code of the requested HTML entity name * @param symName HTML entity name without \c & and \c ; * @return the code for the requested HTML entity name, - * in case the requested HTML item does not exist `DocSymbol::Sym_unknown` is returned. + * in case the requested HTML item does not exist `HtmlEntityMapper::Sym_unknown` is returned. */ -DocSymbol::SymType HtmlEntityMapper::name2sym(const QCString &symName) const +HtmlEntityMapper::SymType HtmlEntityMapper::name2sym(const QCString &symName) const { auto it = m_name2sym.find(symName.str()); - return it!=m_name2sym.end() ? it->second : DocSymbol::Sym_Unknown; + return it!=m_name2sym.end() ? it->second : HtmlEntityMapper::Sym_Unknown; } void HtmlEntityMapper::writeXMLSchema(TextStream &t) diff --git a/src/htmlentity.h b/src/htmlentity.h index cbdc0a1..e249ccd 100644 --- a/src/htmlentity.h +++ b/src/htmlentity.h @@ -18,7 +18,7 @@ #include <unordered_map> #include <string> -#include "docparser.h" +#include "qcstring.h" class TextStream; @@ -26,24 +26,94 @@ class TextStream; class HtmlEntityMapper { public: + enum SymType { Sym_Unknown = -1, + Sym_nbsp, Sym_iexcl, Sym_cent, Sym_pound, Sym_curren, + Sym_yen, Sym_brvbar, Sym_sect, Sym_uml, Sym_copy, + Sym_ordf, Sym_laquo, Sym_not, Sym_shy, Sym_reg, + Sym_macr, Sym_deg, Sym_plusmn, Sym_sup2, Sym_sup3, + Sym_acute, Sym_micro, Sym_para, Sym_middot, Sym_cedil, + Sym_sup1, Sym_ordm, Sym_raquo, Sym_frac14, Sym_frac12, + Sym_frac34, Sym_iquest, Sym_Agrave, Sym_Aacute, Sym_Acirc, + Sym_Atilde, Sym_Auml, Sym_Aring, Sym_AElig, Sym_Ccedil, + Sym_Egrave, Sym_Eacute, Sym_Ecirc, Sym_Euml, Sym_Igrave, + Sym_Iacute, Sym_Icirc, Sym_Iuml, Sym_ETH, Sym_Ntilde, + Sym_Ograve, Sym_Oacute, Sym_Ocirc, Sym_Otilde, Sym_Ouml, + Sym_times, Sym_Oslash, Sym_Ugrave, Sym_Uacute, Sym_Ucirc, + Sym_Uuml, Sym_Yacute, Sym_THORN, Sym_szlig, Sym_agrave, + Sym_aacute, Sym_acirc, Sym_atilde, Sym_auml, Sym_aring, + Sym_aelig, Sym_ccedil, Sym_egrave, Sym_eacute, Sym_ecirc, + Sym_euml, Sym_igrave, Sym_iacute, Sym_icirc, Sym_iuml, + Sym_eth, Sym_ntilde, Sym_ograve, Sym_oacute, Sym_ocirc, + Sym_otilde, Sym_ouml, Sym_divide, Sym_oslash, Sym_ugrave, + Sym_uacute, Sym_ucirc, Sym_uuml, Sym_yacute, Sym_thorn, + Sym_yuml, Sym_fnof, Sym_Alpha, Sym_Beta, Sym_Gamma, + Sym_Delta, Sym_Epsilon, Sym_Zeta, Sym_Eta, Sym_Theta, + Sym_Iota, Sym_Kappa, Sym_Lambda, Sym_Mu, Sym_Nu, + Sym_Xi, Sym_Omicron, Sym_Pi, Sym_Rho, Sym_Sigma, + Sym_Tau, Sym_Upsilon, Sym_Phi, Sym_Chi, Sym_Psi, + Sym_Omega, Sym_alpha, Sym_beta, Sym_gamma, Sym_delta, + Sym_epsilon, Sym_zeta, Sym_eta, Sym_theta, Sym_iota, + Sym_kappa, Sym_lambda, Sym_mu, Sym_nu, Sym_xi, + Sym_omicron, Sym_pi, Sym_rho, Sym_sigmaf, Sym_sigma, + Sym_tau, Sym_upsilon, Sym_phi, Sym_chi, Sym_psi, + Sym_omega, Sym_thetasym, Sym_upsih, Sym_piv, Sym_bull, + Sym_hellip, Sym_prime, Sym_Prime, Sym_oline, Sym_frasl, + Sym_weierp, Sym_image, Sym_real, Sym_trade, Sym_alefsym, + Sym_larr, Sym_uarr, Sym_rarr, Sym_darr, Sym_harr, + Sym_crarr, Sym_lArr, Sym_uArr, Sym_rArr, Sym_dArr, + Sym_hArr, Sym_forall, Sym_part, Sym_exist, Sym_empty, + Sym_nabla, Sym_isin, Sym_notin, Sym_ni, Sym_prod, + Sym_sum, Sym_minus, Sym_lowast, Sym_radic, Sym_prop, + Sym_infin, Sym_ang, Sym_and, Sym_or, Sym_cap, + Sym_cup, Sym_int, Sym_there4, Sym_sim, Sym_cong, + Sym_asymp, Sym_ne, Sym_equiv, Sym_le, Sym_ge, + Sym_sub, Sym_sup, Sym_nsub, Sym_sube, Sym_supe, + Sym_oplus, Sym_otimes, Sym_perp, Sym_sdot, Sym_lceil, + Sym_rceil, Sym_lfloor, Sym_rfloor, Sym_lang, Sym_rang, + Sym_loz, Sym_spades, Sym_clubs, Sym_hearts, Sym_diams, + Sym_quot, Sym_amp, Sym_lt, Sym_gt, Sym_OElig, + Sym_oelig, Sym_Scaron, Sym_scaron, Sym_Yuml, Sym_circ, + Sym_tilde, Sym_ensp, Sym_emsp, Sym_thinsp, Sym_zwnj, + Sym_zwj, Sym_lrm, Sym_rlm, Sym_ndash, Sym_mdash, + Sym_lsquo, Sym_rsquo, Sym_sbquo, Sym_ldquo, Sym_rdquo, + Sym_bdquo, Sym_dagger, Sym_Dagger, Sym_permil, Sym_lsaquo, + Sym_rsaquo, Sym_euro, + + /* doxygen extensions */ + Sym_tm, Sym_apos, + + /* doxygen commands mapped */ + Sym_BSlash, Sym_At, Sym_Less, Sym_Greater, Sym_Amp, + Sym_Dollar, Sym_Hash, Sym_DoubleColon, Sym_Percent, Sym_Pipe, + Sym_Quot, Sym_Minus, Sym_Plus, Sym_Dot, Sym_Colon, Sym_Equal + }; + enum PerlType { Perl_unknown = 0, Perl_string, Perl_char, Perl_symbol, Perl_umlaut, + Perl_acute, Perl_grave, Perl_circ, Perl_slash, Perl_tilde, + Perl_cedilla, Perl_ring + }; static HtmlEntityMapper *instance(); static void deleteInstance(); - DocSymbol::SymType name2sym(const QCString &symName) const; - const char *utf8(DocSymbol::SymType symb,bool useInPrintf=FALSE) const; - const char *html(DocSymbol::SymType symb,bool useInPrintf=FALSE) const; - const char *xml(DocSymbol::SymType symb) const; - const char *docbook(DocSymbol::SymType symb) const; - const char *latex(DocSymbol::SymType symb) const; - const char *man(DocSymbol::SymType symb) const; - const char *rtf(DocSymbol::SymType symb) const; - const DocSymbol::PerlSymb *perl(DocSymbol::SymType symb) const; + SymType name2sym(const QCString &symName) const; + const char *utf8(SymType symb,bool useInPrintf=FALSE) const; + const char *html(SymType symb,bool useInPrintf=FALSE) const; + const char *xml(SymType symb) const; + const char *docbook(SymType symb) const; + const char *latex(SymType symb) const; + const char *man(SymType symb) const; + const char *rtf(SymType symb) const; + struct PerlSymb + { + const char *symb; + const PerlType type; + }; + const PerlSymb *perl(SymType symb) const; void writeXMLSchema(TextStream &t); private: void validate(); HtmlEntityMapper(); ~HtmlEntityMapper(); static HtmlEntityMapper *s_instance; - std::unordered_map<std::string,DocSymbol::SymType> m_name2sym; + std::unordered_map<std::string,SymType> m_name2sym; }; #endif diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index bd7e6a4..ea1f7e6 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -36,6 +36,7 @@ #include "language.h" #include "htmlhelp.h" #include "docparser.h" +#include "docnode.h" #include "htmldocvisitor.h" #include "searchindex.h" #include "pagedef.h" @@ -144,12 +145,12 @@ static QCString getConvertLatexMacro() if (macrofile.isEmpty()) return ""; QCString s = fileToString(macrofile); macrofile = FileInfo(macrofile.str()).absFilePath(); - int size = s.length(); + size_t size = s.length(); GrowBuf out(size); const char *data = s.data(); int line = 1; int cnt = 0; - int i = 0; + size_t i = 0; QCString nr; while (i < size) { @@ -168,13 +169,13 @@ static QCString getConvertLatexMacro() return ""; } i++; - if (!qstrncmp(data + i, "newcommand", (uint)strlen("newcommand"))) + if (!qstrncmp(data + i, "newcommand", strlen("newcommand"))) { - i += (int)strlen("newcommand"); + i += strlen("newcommand"); } - else if (!qstrncmp(data + i, "renewcommand", (uint)strlen("renewcommand"))) + else if (!qstrncmp(data + i, "renewcommand", strlen("renewcommand"))) { - i += (int)strlen("renewcommand"); + i += strlen("renewcommand"); } else { @@ -461,8 +462,22 @@ static QCString substituteHtmlKeywords(const QCString &str, const StringVector &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS); if (!mathJaxExtensions.empty() || !g_latex_macro.isEmpty()) { - mathJaxJs+= ",\n" - " tex: {\n" + mathJaxJs+= ",\n"; + if (!mathJaxExtensions.empty()) + { + bool first = true; + mathJaxJs+= " loader: {\n" + " load: ["; + for (const auto &s : mathJaxExtensions) + { + if (!first) mathJaxJs+= ","; + mathJaxJs+= "'[tex]/"+QCString(s.c_str())+"'"; + first = false; + } + mathJaxJs+= "]\n" + " },\n"; + } + mathJaxJs+= " tex: {\n" " macros: {"; if (!g_latex_macro.isEmpty()) { @@ -1288,11 +1303,19 @@ void HtmlGenerator::writeStyleInfo(int part) } Doxygen::indexList->addStyleSheetFile("jquery.js"); + Doxygen::indexList->addStyleSheetFile("dynsections.js"); + if (Config_getBool(INTERACTIVE_SVG)) { Doxygen::indexList->addStyleSheetFile("svgpan.js"); } + + if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS)) + { + Doxygen::indexList->addStyleSheetFile("menu.js"); + Doxygen::indexList->addStyleSheetFile("menudata.js"); + } } } @@ -2228,12 +2251,15 @@ void HtmlGenerator::endParamList() m_t << "</dl>"; } -void HtmlGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *,int id) +void HtmlGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int id) { - m_codeGen.setId(id); - HtmlDocVisitor *visitor = new HtmlDocVisitor(m_t,m_codeGen,ctx); - n->accept(visitor); - delete visitor; + const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast); + if (astImpl) + { + m_codeGen.setId(id); + HtmlDocVisitor visitor(m_t,m_codeGen,ctx); + std::visit(visitor,astImpl->root); + } } //---------------- helpers for index generation ----------------------------- @@ -2440,8 +2466,8 @@ static void writeDefaultQuickLinks(TextStream &t,bool compact, bool searchEngine = Config_getBool(SEARCHENGINE); bool externalSearch = Config_getBool(EXTERNAL_SEARCH); LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry(); - LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1; - LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file + LayoutNavEntry::Kind kind = LayoutNavEntry::None; + LayoutNavEntry::Kind altKind = LayoutNavEntry::None; // fall back for the old layout file bool highlightParent=FALSE; switch (hli) // map HLI enums to LayoutNavEntry::Kind enums { @@ -2529,7 +2555,7 @@ static void writeDefaultQuickLinks(TextStream &t,bool compact, { // find highlighted index item LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : QCString()); - if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; } + if (!hlEntry && altKind!=LayoutNavEntry::None) { hlEntry=root->find(altKind); kind=altKind; } if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index... { highlightParent=TRUE; @@ -3057,22 +3083,6 @@ void HtmlGenerator::endMemberDeclaration(const QCString &anchor,const QCString & m_t << "\"><td class=\"memSeparator\" colspan=\"2\"> </td></tr>\n"; } -void HtmlGenerator::setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile) -{ - if (Doxygen::searchIndex) - { - Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile); - } -} - -void HtmlGenerator::addWord(const QCString &word,bool hiPriority) -{ - if (Doxygen::searchIndex) - { - Doxygen::searchIndex->addWord(word,hiPriority); - } -} - QCString HtmlGenerator::getMathJaxMacros() { return getConvertLatexMacro(); diff --git a/src/htmlgen.h b/src/htmlgen.h index d5f7904..fc2c8aa 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -44,8 +44,6 @@ class HtmlCodeGenerator : public CodeOutputInterface void startFontClass(const QCString &s); void endFontClass(); void writeCodeAnchor(const QCString &anchor); - void setCurrentDoc(const Definition *,const QCString &,bool) {} - void addWord(const QCString &,bool) {} void startCodeFragment(const QCString &style); void endCodeFragment(const QCString &); @@ -117,9 +115,7 @@ class HtmlGenerator : public OutputGenerator { m_codeGen.endCodeFragment(style); } // --------------------------- - void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile); - void addWord(const QCString &word,bool hiPriority); - void writeDoc(DocNode *,const Definition *,const MemberDef *,int id); + void writeDoc(const IDocNodeAST *node,const Definition *,const MemberDef *,int id); void startFile(const QCString &name,const QCString &manName,const QCString &title,int id); void writeFooter(const QCString &navPath); diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 16bd5c0..51cf757 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -68,8 +68,8 @@ class HtmlHelpRecoder QCString recode(const QCString &s) { - int iSize = s.length(); - int oSize = iSize*4+1; + size_t iSize = s.length(); + size_t oSize = iSize*4+1; QCString output(oSize); size_t iLeft = iSize; size_t oLeft = oSize; @@ -77,7 +77,7 @@ class HtmlHelpRecoder char *oPtr = output.rawData(); if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft)) { - oSize -= (int)oLeft; + oSize -= oLeft; output.resize(oSize+1); output.at(oSize)='\0'; return output; @@ -88,7 +88,7 @@ class HtmlHelpRecoder } } private: - void *m_iconv_null = (void*)(-1); + void *m_iconv_null = reinterpret_cast<void*>(-1); void *m_fromUtf8 = m_iconv_null; }; @@ -320,6 +320,7 @@ class HtmlHelp::Private int dc = 0; StringSet indexFiles; StringSet imageFiles; + StringSet styleFiles; HtmlHelpRecoder recoder; HtmlHelpIndex index; }; @@ -337,104 +338,6 @@ HtmlHelp::~HtmlHelp() { } -/* language codes for Html help - 0x405 Czech - 0x406 Danish - 0x413 Dutch - 0xC09 English (Australia) - 0x809 English (Britain) - 0x1009 English (Canada) - 0x1809 English (Ireland) - 0x1409 English (New Zealand) - 0x1C09 English (South Africa) - 0x409 English (United States) - 0x40B Finnish - 0x40C French - 0x407 German - 0x408 Greece - 0x40E Hungarian - 0x410 Italian - 0x814 Norwegian - 0x415 Polish - 0x816 Portuguese(Portugal) - 0x416 Portuguese(Brazil) - 0x419 Russian - 0x80A Spanish(Mexico) - 0xC0A Spanish(Modern Sort) - 0x40A Spanish(Traditional Sort) - 0x41D Swedish - 0x41F Turkey - 0x411 Japanese - 0x412 Korean - 0x804 Chinese (PRC) - 0x404 Chinese (Taiwan) - - New LCIDs: - 0x421 Indonesian - 0x41A Croatian - 0x418 Romanian - 0x424 Slovenian - 0x41B Slovak - 0x422 Ukrainian - 0x81A Serbian (Serbia, Latin) - 0x403 Catalan - 0x426 Latvian - 0x427 Lithuanian - 0x436 Afrikaans - 0x42A Vietnamese - 0x429 Persian (Iran) - 0xC01 Arabic (Egypt) - I don't know which version of arabic is used inside translator_ar.h , - so I have chosen Egypt at random - -*/ -static StringUnorderedMap s_languageDict = -{ - { "czech", "0x405 Czech" }, - { "danish", "0x406 Danish" }, - { "dutch", "0x413 Dutch" }, - { "finnish", "0x40B Finnish" }, - { "french", "0x40C French" }, - { "german", "0x407 German" }, - { "greek", "0x408 Greece" }, - { "hungarian", "0x40E Hungarian" }, - { "italian", "0x410 Italian" }, - { "norwegian", "0x814 Norwegian" }, - { "polish", "0x415 Polish" }, - { "portuguese", "0x816 Portuguese(Portugal)" }, - { "brazilian", "0x416 Portuguese(Brazil)" }, - { "russian", "0x419 Russian" }, - { "spanish", "0x40A Spanish(Traditional Sort)" }, - { "swedish", "0x41D Swedish" }, - { "turkish", "0x41F Turkey" }, - { "japanese", "0x411 Japanese" }, - { "japanese-en", "0x411 Japanese" }, - { "korean", "0x412 Korean" }, - { "korean-en", "0x412 Korean" }, - { "chinese", "0x804 Chinese (PRC)" }, - { "chinese-traditional", "0x404 Chinese (Taiwan)" }, - { "indonesian", "0x421 Indonesian" }, - { "croatian", "0x41A Croatian" }, - { "romanian", "0x418 Romanian" }, - { "slovene", "0x424 Slovenian" }, - { "slovak", "0x41B Slovak" }, - { "ukrainian", "0x422 Ukrainian" }, - { "serbian", "0x81A Serbian (Serbia, Latin)" }, - { "catalan", "0x403 Catalan" }, - { "lithuanian", "0x427 Lithuanian" }, - { "afrikaans", "0x436 Afrikaans" }, - { "vietnamese", "0x42A Vietnamese" }, - { "persian", "0x429 Persian (Iran)" }, - { "arabic", "0xC01 Arabic (Egypt)" }, - { "latvian", "0x426 Latvian" }, - { "macedonian", "0x042f Macedonian (Former Yugoslav Republic of Macedonia)" }, - { "armenian", "0x42b Armenian" }, - //Code for Esperanto should be as shown below but the htmlhelp compiler 1.3 does not support this - // (and no newer version is available). - //So do a fallback to the default language (see getLanguageString()) - //{ "esperanto", "0x48f Esperanto" }, - { "serbian-cyrillic", "0xC1A Serbian (Serbia, Cyrillic)" } -}; - /*! This will create a contents file (index.hhc) and a index file (index.hhk) * and write the header of those files. * It also creates a project file (index.hhp) @@ -445,7 +348,7 @@ void HtmlHelp::initialize() p->recoder.initialize(); /* open the contents file */ - QCString fName = Config_getString(HTML_OUTPUT) + "/index.hhc"; + QCString fName = Config_getString(HTML_OUTPUT) + "/" + hhcFileName; p->cts.open(fName.str(),std::ofstream::out | std::ofstream::binary); if (!p->cts.is_open()) { @@ -459,8 +362,8 @@ void HtmlHelp::initialize() "</OBJECT>\n" "<UL>\n"; - /* open the contents file */ - fName = Config_getString(HTML_OUTPUT) + "/index.hhk"; + /* open the index file */ + fName = Config_getString(HTML_OUTPUT) + "/" + hhkFileName; p->kts.open(fName.str(),std::ofstream::out | std::ofstream::binary); if (!p->kts.is_open()) { @@ -476,32 +379,15 @@ void HtmlHelp::initialize() } - -QCString HtmlHelp::getLanguageString() -{ - if (!theTranslator->idLanguage().isEmpty()) - { - auto it = s_languageDict.find(theTranslator->idLanguage().str()); - if (it!=s_languageDict.end()) - { - return QCString(it->second); - } - } - // default language - return "0x409 English (United States)"; -} - - - void HtmlHelp::Private::createProjectFile() { /* Write the project file */ - QCString fName = Config_getString(HTML_OUTPUT) + "/index.hhp"; + QCString fName = Config_getString(HTML_OUTPUT) + "/" + hhpFileName; std::ofstream t(fName.str(),std::ofstream::out | std::ofstream::binary); if (t.is_open()) { - const char *hhcFile = "\"index.hhc\""; - const char *hhkFile = "\"index.hhk\""; + QCString hhcFile = "\"" + hhcFileName + "\""; + QCString hhkFile = "\"" + hhkFileName + "\""; bool hhkPresent = index.size()>0; if (!ctsItemPresent) hhcFile = ""; if (!hhkPresent) hhkFile = ""; @@ -514,11 +400,11 @@ void HtmlHelp::Private::createProjectFile() } t << "Compatibility=1.1\n" "Full-text search=Yes\n"; - if (ctsItemPresent) t << "Contents file=index.hhc\n"; + if (ctsItemPresent) t << "Contents file=" + hhcFileName + "\n"; t << "Default Window=main\n" "Default topic=" << indexName << "\n"; - if (hhkPresent) t << "Index file=index.hhk\n"; - t << "Language=" << getLanguageString() << "\n"; + if (hhkPresent) t << "Index file=" + hhkFileName + "\n"; + t << "Language=" << theTranslator->getLanguageString() << "\n"; if (Config_getBool(BINARY_TOC)) t << "Binary TOC=YES\n"; if (Config_getBool(GENERATE_CHI)) t << "Create CHI file=YES\n"; t << "Title=" << recoder.recode(Config_getString(PROJECT_NAME)) << "\n\n"; @@ -557,6 +443,10 @@ void HtmlHelp::Private::createProjectFile() { t << s.c_str() << "\n"; } + for (auto &s : styleFiles) + { + t << s.c_str() << "\n"; + } t.close(); } else @@ -571,7 +461,7 @@ void HtmlHelp::addIndexFile(const QCString &s) } /*! Finalizes the HTML help. This will finish and close the - * contents file (index.hhc) and the index file (index.hhk). + * htmlhelp contents file and the htmlhelp index file. * \sa initialize() */ void HtmlHelp::finalize() @@ -636,7 +526,7 @@ void HtmlHelp::addContentsItem(bool isDir, bool /* addToNavIndex */, const Definition * /* def */) { - static bool binaryTOC = Config_getBool(BINARY_TOC); + bool binaryTOC = Config_getBool(BINARY_TOC); // If we're using a binary toc then folders cannot have links. // Tried this and I didn't see any problems, when not using // the resetting of file and anchor the TOC works better @@ -674,11 +564,11 @@ void HtmlHelp::addContentsItem(bool isDir, p->cts << "<param name=\"ImageNumber\" value=\""; if (isDir) // added - KPW { - p->cts << (int)BOOK_CLOSED ; + p->cts << static_cast<int>(BOOK_CLOSED); } else { - p->cts << (int)TEXT; + p->cts << static_cast<int>(TEXT); } p->cts << "\">"; p->cts << "</OBJECT>\n"; @@ -690,7 +580,7 @@ void HtmlHelp::addIndexItem(const Definition *context,const MemberDef *md, { if (md) { - static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); + bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); if (context==0) // global member { if (md->getGroupDef()) @@ -701,9 +591,10 @@ void HtmlHelp::addIndexItem(const Definition *context,const MemberDef *md, if (context==0) return; // should not happen QCString cfname = md->getOutputFileBase(); + QCString argStr = md->argsString(); QCString cfiname = context->getOutputFileBase(); QCString level1 = context->name(); - QCString level2 = md->name(); + QCString level2 = md->name() + argStr; QCString contRef = separateMemberPages ? cfname : cfiname; QCString memRef = cfname; QCString anchor = !sectionAnchor.isEmpty() ? sectionAnchor : md->anchor(); @@ -717,6 +608,11 @@ void HtmlHelp::addIndexItem(const Definition *context,const MemberDef *md, } } +void HtmlHelp::addStyleSheetFile(const QCString &fileName) +{ + p->styleFiles.insert(fileName.str()); +} + void HtmlHelp::addImageFile(const QCString &fileName) { p->imageFiles.insert(fileName.str()); diff --git a/src/htmlhelp.h b/src/htmlhelp.h index 9d8eea5..a2f3683 100644 --- a/src/htmlhelp.h +++ b/src/htmlhelp.h @@ -77,9 +77,11 @@ class HtmlHelp : public IndexIntf const QCString §ionAnchor, const QCString &title); void addIndexFile(const QCString &name); void addImageFile(const QCString &); - void addStyleSheetFile(const QCString &) {} - static QCString getLanguageString(); + void addStyleSheetFile(const QCString &); + static inline const QCString hhcFileName = "index.hhc"; + static inline const QCString hhkFileName = "index.hhk"; + static inline const QCString hhpFileName = "index.hhp"; private: class Private; std::unique_ptr<Private> p; diff --git a/src/image.cpp b/src/image.cpp index 0b353a9..06985df 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -208,9 +208,9 @@ static Color palette3[] = Image::Image(uint w,uint h) { - static int hue = Config_getInt(HTML_COLORSTYLE_HUE); - static int sat = Config_getInt(HTML_COLORSTYLE_SAT); - static int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); + int hue = Config_getInt(HTML_COLORSTYLE_HUE); + int sat = Config_getInt(HTML_COLORSTYLE_SAT); + int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); double red1,green1,blue1; double red2,green2,blue2; @@ -227,23 +227,21 @@ Image::Image(uint w,uint h) &red2,&green2,&blue2 ); - palette[2].red = (int)(red1 * 255.0); - palette[2].green = (int)(green1 * 255.0); - palette[2].blue = (int)(blue1 * 255.0); + palette[2].red = static_cast<int>(red1 * 255.0); + palette[2].green = static_cast<int>(green1 * 255.0); + palette[2].blue = static_cast<int>(blue1 * 255.0); - palette[3].red = (int)(red2 * 255.0); - palette[3].green = (int)(green2 * 255.0); - palette[3].blue = (int)(blue2 * 255.0); + palette[3].red = static_cast<int>(red2 * 255.0); + palette[3].green = static_cast<int>(green2 * 255.0); + palette[3].blue = static_cast<int>(blue2 * 255.0); - m_data = new uchar[w*h]; - memset(m_data,0,w*h); + m_data.resize(w*h); m_width = w; m_height = h; } Image::~Image() { - delete[] m_data; } void Image::setPixel(uint x,uint y,uchar val) @@ -383,7 +381,7 @@ void Image::fillRect(uint x,uint y,uint width,uint height,uchar colIndex,uint ma bool Image::save(const QCString &fileName,int mode) { - static bool useTransparency = Config_getBool(FORMULA_TRANSPARENT); + bool useTransparency = Config_getBool(FORMULA_TRANSPARENT); uchar* buffer; size_t bufferSize; LodePNG_Encoder encoder; @@ -400,7 +398,7 @@ bool Image::save(const QCString &fileName,int mode) } encoder.infoPng.color.colorType = 3; encoder.infoRaw.color.colorType = 3; - LodePNG_encode(&encoder, &buffer, &bufferSize, m_data, m_width, m_height); + LodePNG_encode(&encoder, &buffer, &bufferSize, &m_data[0], m_width, m_height); LodePNG_saveFile(buffer, bufferSize, fileName.data()); free(buffer); LodePNG_Encoder_cleanup(&encoder); @@ -429,7 +427,7 @@ void ColoredImage::hsl2rgb(double h,double s,double l, m = l + l - v; sv = (v - m ) / v; h *= 6.0; - sextant = (int)h; + sextant = static_cast<int>(h); fract = h - sextant; vsf = v * sv * fract; mid1 = m + vsf; @@ -480,7 +478,7 @@ ColoredImage::ColoredImage(uint width,uint height, m_hasAlpha = alphaLevels!=0; m_width = width; m_height = height; - m_data = (uchar*)malloc(width*height*4); + m_data.resize(width*height*4); uint i; for (i=0;i<width*height;i++) { @@ -490,9 +488,9 @@ ColoredImage::ColoredImage(uint width,uint height, saturation/255.0, // saturation pow(greyLevels[i]/255.0,gamma/100.0), // luma (gamma corrected) &red,&green,&blue); - r = (int)(red *255.0); - g = (int)(green*255.0); - b = (int)(blue *255.0); + r = static_cast<int>(red *255.0); + g = static_cast<int>(green*255.0); + b = static_cast<int>(blue *255.0); a = alphaLevels ? alphaLevels[i] : 255; m_data[i*4+0]=r; m_data[i*4+1]=g; @@ -503,7 +501,6 @@ ColoredImage::ColoredImage(uint width,uint height, ColoredImage::~ColoredImage() { - free(m_data); } bool ColoredImage::save(const QCString &fileName) @@ -514,7 +511,7 @@ bool ColoredImage::save(const QCString &fileName) LodePNG_Encoder_init(&encoder); encoder.infoPng.color.colorType = m_hasAlpha ? 6 : 2; // 2=RGB 24 bit, 6=RGBA 32 bit encoder.infoRaw.color.colorType = 6; // 6=RGBA 32 bit - LodePNG_encode(&encoder, &buffer, &bufferSize, m_data, m_width, m_height); + LodePNG_encode(&encoder, &buffer, &bufferSize, &m_data[0], m_width, m_height); LodePNG_saveFile(buffer, bufferSize, fileName.data()); LodePNG_Encoder_cleanup(&encoder); free(buffer); diff --git a/src/image.h b/src/image.h index 5d19bd2..be523c8 100644 --- a/src/image.h +++ b/src/image.h @@ -19,6 +19,7 @@ #ifndef IMAGE_H #define IMAGE_H +#include <vector> #include "types.h" #include "qcstring.h" @@ -43,13 +44,12 @@ class Image friend uint stringLength(const QCString &s); uint width() const { return m_width; } uint height() const { return m_height; } - uchar *data() const { return m_data; } static uint stringLength(const QCString &s); private: uint m_width; uint m_height; - uchar *m_data; + std::vector<uchar> m_data; }; /** Class representing a bitmap image colored based on hue/sat/gamma settings. */ @@ -66,7 +66,7 @@ class ColoredImage private: uint m_width; uint m_height; - uchar *m_data; + std::vector<uchar> m_data; bool m_hasAlpha; }; diff --git a/src/index.cpp b/src/index.cpp index 8e4fb8a..a0ad1b6 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -86,7 +86,7 @@ static void countRelatedPages(int &docPages,int &indexPages); void countDataStructures() { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted, ClassDef::Class); // "classes" + "annotated" hierarchyClasses = countClassHierarchy(ClassDef::Class); // "hierarchy" // "interfaces" + "annotated" @@ -236,7 +236,7 @@ void startFile(OutputList &ol,const QCString &name,const QCString &manName, const QCString &title,HighlightedItem hli,bool additionalIndices, const QCString &altSidebarName) { - static bool disableIndex = Config_getBool(DISABLE_INDEX); + bool disableIndex = Config_getBool(DISABLE_INDEX); ol.startFile(name,manName,title); ol.startQuickIndices(); if (!disableIndex) @@ -254,7 +254,7 @@ void startFile(OutputList &ol,const QCString &name,const QCString &manName, void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, const QCString &navPath) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); if (!skipNavIndex) @@ -273,7 +273,7 @@ void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, void endFileWithNavPath(const Definition *d,OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); QCString navPath; if (generateTreeView) { @@ -341,12 +341,6 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, const ConceptLinkedRefMap *concepts = nullptr) { - bool hasMembers = !def->getMemberLists().empty() || !def->getMemberGroups().empty(); - Doxygen::indexList->addContentsItem(hasMembers,name, - def->getReference(),def->getOutputFileBase(),anchor, - hasMembers && !preventSeparateIndex, - addToIndex, - def); int numClasses=0; for (const auto &cd : def->getClasses()) { @@ -360,6 +354,12 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, if (cd->isLinkable()) numConcepts++; } } + bool hasMembers = !def->getMemberLists().empty() || !def->getMemberGroups().empty() || (numClasses>0) || (numConcepts>0); + Doxygen::indexList->addContentsItem(hasMembers,name, + def->getReference(),def->getOutputFileBase(),anchor, + hasMembers && !preventSeparateIndex, + addToIndex, + def); //printf("addMembersToIndex(def=%s hasMembers=%d numClasses=%d)\n",qPrint(def->name()),hasMembers,numClasses); if (hasMembers || numClasses>0 || numConcepts>0) { @@ -369,15 +369,18 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, auto kind = lde->kind(); if (kind==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - MemberList *ml = def->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - for (const auto &md : *ml) + MemberList *ml = def->getMemberList(lmd->type); + if (ml) { - if (md->visibleInIndex()) + for (const auto &md : *ml) { - writeMemberToIndex(def,md,addToIndex); + if (md->visibleInIndex()) + { + writeMemberToIndex(def,md,addToIndex); + } } } } @@ -391,7 +394,7 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, { if (cd->isLinkable() && (cd->partOfGroups().empty() || def->definitionType()==Definition::TypeGroup)) { - static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); bool isNestedClass = def->definitionType()==Definition::TypeClass; addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(lde->kind()==LayoutDocEntry::FileClasses),cd->anchor(), addToIndex && (isNestedClass || (cd->isSimple() && inlineSimpleStructs)), @@ -430,7 +433,7 @@ static void writeClassTreeToOutput(OutputList &ol,const BaseClassList &bcl,int l for (const auto &bcd : bcl) { ClassDef *cd=bcd.classDef; - if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) + if (cd->getLanguage()==SrcLangExt_VHDL && VhdlDocGen::convert(cd->protection())!=VhdlDocGen::ENTITYCLASS) { continue; } @@ -583,7 +586,7 @@ static void writeDirTreeNode(OutputList &ol, const DirDef *dd, int level, FTVHel return; } - static bool tocExpand = TRUE; //Config_getBool(TOC_EXPAND); + bool tocExpand = TRUE; //Config_getBool(TOC_EXPAND); bool isDir = !dd->subDirs().empty() || // there are subdirs (tocExpand && // or toc expand and !dd->getFiles().empty() // there are files @@ -628,7 +631,7 @@ static void writeDirTreeNode(OutputList &ol, const DirDef *dd, int level, FTVHel { for (const auto &fd : dd->getFiles()) { - //static bool allExternals = Config_getBool(ALLEXTERNALS); + //bool allExternals = Config_getBool(ALLEXTERNALS); //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject()) //{ // fileCount++; @@ -684,14 +687,12 @@ static void writeDirTreeNode(OutputList &ol, const DirDef *dd, int level, FTVHel { for (const auto &fd : dd->getFiles()) { - //static bool allExternals = Config_getBool(ALLEXTERNALS); - //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject()) bool doc,src; doc = fileVisibleInIndex(fd,src); if (doc) { addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(), - TRUE,FALSE,&fd->getConcepts()); + !fd->isLinkableViaGroup(),FALSE,&fd->getConcepts()); } else if (src) { @@ -781,7 +782,7 @@ static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) static void writeClassTreeForList(OutputList &ol,const ClassLinkedMap &cl,bool &started,FTVHelp* ftv,bool addToIndex, ClassDef::CompoundType ct,ClassDefSet &visitedClasses) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); for (const auto &cd : cl) { //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n", @@ -792,7 +793,7 @@ static void writeClassTreeForList(OutputList &ol,const ClassLinkedMap &cl,bool & bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { - if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) + if (VhdlDocGen::convert(cd->protection())!=VhdlDocGen::ENTITYCLASS) { continue; } @@ -906,7 +907,7 @@ static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex,Cla static int countClassesInTreeList(const ClassLinkedMap &cl, ClassDef::CompoundType ct) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); int count=0; for (const auto &cd : cl) { @@ -1262,22 +1263,19 @@ static void countFiles(int &allFiles,int &docFiles) { allFiles=0; docFiles=0; - if (Config_getBool(SHOW_FILES)) + for (const auto &fn : *Doxygen::inputNameLinkedMap) { - for (const auto &fn : *Doxygen::inputNameLinkedMap) + for (const auto &fd: *fn) { - for (const auto &fd: *fn) + bool doc,src; + doc = fileVisibleInIndex(fd.get(),src); + if (doc || src) { - bool doc,src; - doc = fileVisibleInIndex(fd.get(),src); - if (doc || src) - { - allFiles++; - } - if (doc) - { - docFiles++; - } + allFiles++; + } + if (doc) + { + docFiles++; } } } @@ -1365,7 +1363,7 @@ static void writeSingleFileIndex(OutputList &ol,const FileDef *fd) static void writeFileIndex(OutputList &ol) { - if (documentedFiles==0) return; + if (documentedFiles==0 || !Config_getBool(SHOW_FILES)) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); @@ -1520,20 +1518,20 @@ template<> const ClassDef *get_pointer(const ClassLinkedRefMap::Ptr template<class ListType> static void writeClassTree(const ListType &cl,FTVHelp *ftv,bool addToIndex,bool globalOnly,ClassDef::CompoundType ct) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); for (const auto &cdi : cl) { const ClassDef *cd = get_pointer(cdi); ClassDefMutable *cdm = toClassDefMutable(cd); if (cdm && cd->getLanguage()==SrcLangExt_VHDL) { - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKAGECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS )// no architecture { continue; } - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS) + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::ARCHITECTURECLASS) { QCString n=cd->name(); cdm->setClassName(n); @@ -1591,15 +1589,18 @@ int countVisibleMembers(const NamespaceDef *nd) { if (lde->kind()==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - MemberList *ml = nd->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - for (const auto &md : *ml) + MemberList *ml = nd->getMemberList(lmd->type); + if (ml) { - if (md->visibleInIndex()) + for (const auto &md : *ml) { - count++; + if (md->visibleInIndex()) + { + count++; + } } } } @@ -1614,16 +1615,19 @@ static void writeNamespaceMembers(const NamespaceDef *nd,bool addToIndex) { if (lde->kind()==LayoutDocEntry::MemberDef) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - MemberList *ml = nd->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - for (const auto &md : *ml) + MemberList *ml = nd->getMemberList(lmd->type); + if (ml) { - //printf(" member %s visible=%d\n",qPrint(md->name()),md->visibleInIndex()); - if (md->visibleInIndex()) + for (const auto &md : *ml) { - writeMemberToIndex(nd,md,addToIndex); + //printf(" member %s visible=%d\n",qPrint(md->name()),md->visibleInIndex()); + if (md->visibleInIndex()) + { + writeMemberToIndex(nd,md,addToIndex); + } } } } @@ -1699,7 +1703,10 @@ static void writeNamespaceTree(const NamespaceLinkedRefMap &nsLinkedMap,FTVHelp { for (const auto &nd : nsLinkedMap) { - writeNamespaceTreeElement(nd,ftv,rootOnly,addToIndex); + if (nd->isLinkableInProject()) + { + writeNamespaceTreeElement(nd,ftv,rootOnly,addToIndex); + } } } @@ -1708,7 +1715,10 @@ static void writeNamespaceTree(const NamespaceLinkedMap &nsLinkedMap,FTVHelp *ft { for (const auto &nd : nsLinkedMap) { - writeNamespaceTreeElement(nd.get(),ftv,rootOnly,addToIndex); + if (nd->isLinkableInProject()) + { + writeNamespaceTreeElement(nd.get(),ftv,rootOnly,addToIndex); + } } } @@ -1718,7 +1728,7 @@ static void writeClassTreeInsideNamespace(const NamespaceLinkedRefMap &nsLinkedM static void writeClassTreeInsideNamespaceElement(const NamespaceDef *nd,FTVHelp *ftv, bool rootOnly,bool addToIndex,ClassDef::CompoundType ct) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (!nd->isAnonymous() && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { @@ -1914,7 +1924,7 @@ static void writeNamespaceIndex(OutputList &ol) static int countAnnotatedClasses(int *cp, ClassDef::CompoundType ct) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); int count=0; int countPrinted=0; for (const auto &cd : *Doxygen::classLinkedMap) @@ -1943,13 +1953,13 @@ static void writeAnnotatedClassList(OutputList &ol,ClassDef::CompoundType ct) //bool addToIndex = lne==0 || lne->visible(); bool first=TRUE; - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); for (const auto &cd : *Doxygen::classLinkedMap) { if (cd->getLanguage()==SrcLangExt_VHDL && - ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) + (VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKAGECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; @@ -1977,7 +1987,7 @@ static void writeAnnotatedClassList(OutputList &ol,ClassDef::CompoundType ct) ol.startIndexKey(); if (cd->getLanguage()==SrcLangExt_VHDL) { - QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection()); + QCString prot= VhdlDocGen::getProtectionName(VhdlDocGen::convert(cd->protection())); ol.docify(prot); ol.writeString(" "); } @@ -2032,8 +2042,8 @@ static QCString letterToLabel(const QCString &startLetter) const char hex[]="0123456789abcdef"; while ((c=*p++)) { - result+=hex[((unsigned char)c)>>4]; - result+=hex[((unsigned char)c)&0xf]; + result+=hex[static_cast<unsigned char>(c)>>4]; + result+=hex[static_cast<unsigned char>(c)&0xf]; } } return result; @@ -2067,7 +2077,7 @@ using UsedIndexLetters = std::set<std::string>; // write an alphabetical index of all class with a header for each letter static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct, int annotatedCount) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); // What starting letters are used UsedIndexLetters indexLettersUsed; @@ -2079,7 +2089,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct continue; if (cd->isLinkableInProject() && cd->templateMaster()==0) { - if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture + if (cd->getLanguage()==SrcLangExt_VHDL && !(VhdlDocGen::convert(cd->protection())==VhdlDocGen::ENTITYCLASS ))// no architecture continue; // get the first UTF8 character (after the part that should be ignored) @@ -2116,7 +2126,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct { if (sliceOpt && cd->compoundType() != ct) continue; - if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture + if (cd->getLanguage()==SrcLangExt_VHDL && !(VhdlDocGen::convert(cd->protection())==VhdlDocGen::ENTITYCLASS ))// no architecture continue; if (cd->isLinkableInProject() && cd->templateMaster()==0) @@ -2539,7 +2549,7 @@ static void writeMemberList(OutputList &ol,bool useSections,const std::string &p const MemberIndexMap &memberIndexMap, Definition::DefType type) { - int index = (int)type; + int index = static_cast<int>(type); ASSERT(index<3); typedef void (*writeLinkForMember_t)(OutputList &ol,const MemberDef *md,const QCString &separator, @@ -2592,8 +2602,8 @@ static void writeMemberList(OutputList &ol,bool useSections,const std::string &p if (!firstItem) ol.endItemListItem(); if (!firstSection) ol.endItemList(); QCString cs = letterToLabel(letter.c_str()); - QCString anchor=(QCString)"index_"+convertToId(cs); - QCString title=(QCString)"- "+letter.c_str()+" -"; + QCString anchor=QCString("index_")+convertToId(cs); + QCString title=QCString("- ")+letter.c_str()+" -"; ol.startSection(anchor,title,SectionType::Subsection); ol.docify(title); ol.endSection(anchor,SectionType::Subsection); @@ -2654,7 +2664,7 @@ void initClassMemberIndices() void addClassMemberNameToIndex(const MemberDef *md) { - static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); + bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); const ClassDef *cd=0; if (md->isLinkableInProject() && @@ -2936,8 +2946,8 @@ struct CmhlInfo static const CmhlInfo *getCmhlInfo(size_t hl) { - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static CmhlInfo cmhlInfo[] = { CmhlInfo("functions", theTranslator->trAll()), @@ -2960,7 +2970,7 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h { if (documentedClassMembers[hl]==0) return; - static bool disableIndex = Config_getBool(DISABLE_INDEX); + bool disableIndex = Config_getBool(DISABLE_INDEX); bool multiPageIndex=FALSE; if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) @@ -2974,7 +2984,7 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h QCString extension=Doxygen::htmlFileExtension; LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers); QCString title = lne ? lne->title() : theTranslator->trCompoundMembers(); - if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title; + if (hl!=CMHL_All) title+=QCString(" - ")+getCmhlInfo(hl)->title; bool addToIndex = lne==0 || lne->visible(); if (addToIndex) @@ -3113,9 +3123,9 @@ struct FmhlInfo static const FmhlInfo *getFmhlInfo(size_t hl) { - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); static FmhlInfo fmhlInfo[] = { FmhlInfo("globals", theTranslator->trAll()), @@ -3138,7 +3148,7 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) { if (documentedFileMembers[hl]==0) return; - static bool disableIndex = Config_getBool(DISABLE_INDEX); + bool disableIndex = Config_getBool(DISABLE_INDEX); bool multiPageIndex=FALSE; if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) @@ -3253,7 +3263,7 @@ static void writeFileMemberIndex(OutputList &ol) bool addToIndex = lne==0 || lne->visible(); if (documentedFileMembers[FMHL_All]>0 && addToIndex) { - Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),QCString(),"globals",QCString()); + Doxygen::indexList->addContentsItem(true,lne ? lne->title() : theTranslator->trFileMembers(),QCString(),"globals",QCString()); Doxygen::indexList->incContentsDepth(); } writeFileMemberIndexFiltered(ol,FMHL_All); @@ -3284,9 +3294,9 @@ struct NmhlInfo static const NmhlInfo *getNmhlInfo(size_t hl) { - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); static NmhlInfo nmhlInfo[] = { NmhlInfo("namespacemembers", theTranslator->trAll()), @@ -3311,7 +3321,7 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, { if (documentedNamespaceMembers[hl]==0) return; - static bool disableIndex = Config_getBool(DISABLE_INDEX); + bool disableIndex = Config_getBool(DISABLE_INDEX); bool multiPageIndex=FALSE; @@ -3427,7 +3437,7 @@ static void writeNamespaceMemberIndex(OutputList &ol) bool addToIndex = lne==0 || lne->visible(); if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex) { - Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),QCString(),"namespacemembers",QCString()); + Doxygen::indexList->addContentsItem(true,lne ? lne->title() : theTranslator->trNamespaceMembers(),QCString(),"namespacemembers",QCString()); Doxygen::indexList->incContentsDepth(); } //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); @@ -3488,7 +3498,7 @@ static void writeExampleIndex(OutputList &ol) ol.writeObjectLink(QCString(),n,QCString(),pd->title()); if (addToIndex) { - Doxygen::indexList->addContentsItem(FALSE,filterTitle(pd->title().str()),pd->getReference(),n,QCString(),FALSE,TRUE); + Doxygen::indexList->addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,QCString(),FALSE,TRUE); } } else @@ -3535,11 +3545,11 @@ static void countRelatedPages(int &docPages,int &indexPages) static bool mainPageHasOwnTitle() { - static QCString projectName = Config_getString(PROJECT_NAME); + QCString projectName = Config_getString(PROJECT_NAME); QCString title; if (Doxygen::mainPage) { - title = filterTitle(Doxygen::mainPage->title().str()); + title = filterTitle(Doxygen::mainPage->title()); } return !projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0; } @@ -3561,7 +3571,7 @@ static void writePages(const PageDef *pd,FTVHelp *ftv) if (pd->title().isEmpty()) pageTitle=pd->name(); else - pageTitle=filterTitle(pd->title().str()); + pageTitle=filterTitle(pd->title()); if (ftv) { @@ -3688,14 +3698,12 @@ void writeGraphInfo(OutputList &ol) DotLegendGraph gd; gd.writeGraph(Config_getString(HTML_OUTPUT)); - bool stripCommentsStateRef = Config_getBool(STRIP_CODE_COMMENTS); - bool oldStripCommentsState = stripCommentsStateRef; - bool createSubdirs = Config_getBool(CREATE_SUBDIRS); - bool oldCreateSubdirs = createSubdirs; + bool oldStripCommentsState = Config_getBool(STRIP_CODE_COMMENTS); + bool oldCreateSubdirs = Config_getBool(CREATE_SUBDIRS); // temporarily disable the stripping of comments for our own code example! - stripCommentsStateRef = Config_updateBool(STRIP_CODE_COMMENTS,FALSE); + Config_updateBool(STRIP_CODE_COMMENTS,FALSE); // temporarily disable create subdirs for linking to our example - createSubdirs = Config_updateBool(CREATE_SUBDIRS,FALSE); + Config_updateBool(CREATE_SUBDIRS,FALSE); startFile(ol,"graph_legend",QCString(),theTranslator->trLegendTitle()); startTitle(ol,QCString()); @@ -3806,33 +3814,36 @@ static void writeGroupTreeNode(OutputList &ol, const GroupDef *gd, int level, FT { if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex) { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - MemberList *ml = gd->getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) { - for (const auto &md : *ml) + MemberList *ml = gd->getMemberList(lmd->type); + if (ml) { - const MemberVector &enumList = md->enumFieldList(); - isDir = !enumList.empty() && md->isEnumerate(); - if (md->isVisible() && !md->isAnonymous()) + for (const auto &md : *ml) { - Doxygen::indexList->addContentsItem(isDir, - md->qualifiedName(),md->getReference(), - md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); - } - if (isDir) - { - Doxygen::indexList->incContentsDepth(); - for (const auto &emd : enumList) + const MemberVector &enumList = md->enumFieldList(); + isDir = !enumList.empty() && md->isEnumerate(); + if (md->isVisible() && !md->isAnonymous()) { - if (emd->isVisible()) + Doxygen::indexList->addContentsItem(isDir, + md->qualifiedName(),md->getReference(), + md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); + } + if (isDir) + { + Doxygen::indexList->incContentsDepth(); + for (const auto &emd : enumList) { - Doxygen::indexList->addContentsItem(FALSE, - emd->qualifiedName(),emd->getReference(),emd->getOutputFileBase(), - emd->anchor(),FALSE,addToIndex); + if (emd->isVisible()) + { + Doxygen::indexList->addContentsItem(FALSE, + emd->qualifiedName(),emd->getReference(),emd->getOutputFileBase(), + emd->anchor(),FALSE,addToIndex); + } } + Doxygen::indexList->decContentsDepth(); } - Doxygen::indexList->decContentsDepth(); } } } @@ -3864,7 +3875,7 @@ static void writeGroupTreeNode(OutputList &ol, const GroupDef *gd, int level, FT { Doxygen::indexList->addContentsItem(FALSE, nd->displayName(),nd->getReference(), - nd->getOutputFileBase(),QCString(),FALSE,addToIndex); + nd->getOutputFileBase(),QCString(),FALSE,!Config_getBool(SHOW_NAMESPACES)); } } } @@ -3888,7 +3899,7 @@ static void writeGroupTreeNode(OutputList &ol, const GroupDef *gd, int level, FT { Doxygen::indexList->addContentsItem(FALSE, fd->displayName(),fd->getReference(), - fd->getOutputFileBase(),QCString(),FALSE,FALSE); + fd->getOutputFileBase(),QCString(),FALSE,fd->isLinkableViaGroup()); } } } @@ -4297,9 +4308,9 @@ static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne) static void writeIndex(OutputList &ol) { - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static QCString projectName = Config_getString(PROJECT_NAME); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString projectName = Config_getString(PROJECT_NAME); // save old generator state ol.pushGeneratorState(); @@ -4326,7 +4337,7 @@ static void writeIndex(OutputList &ol) } else if (Doxygen::mainPage) { - title = filterTitle(Doxygen::mainPage->title().str()); + title = filterTitle(Doxygen::mainPage->title()); } QCString indexName="index"; @@ -4338,12 +4349,18 @@ static void writeIndex(OutputList &ol) (!projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0) ) // to avoid duplicate entries in the treeview { - Doxygen::indexList->addContentsItem(Doxygen::mainPage->hasSubPages(),title,QCString(),indexName,QCString(),Doxygen::mainPage->hasSubPages(),TRUE); + Doxygen::indexList->addContentsItem(Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections(),title,QCString(),indexName,QCString(),Doxygen::mainPage->hasSubPages(),TRUE); + if (Doxygen::mainPage->hasSubPages()) Doxygen::indexList->incContentsDepth(); + } if (Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections()) { writePages(Doxygen::mainPage.get(),0); } + if (!projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0 && Doxygen::mainPage->hasSubPages()) + { + if (Doxygen::mainPage->hasSubPages()) Doxygen::indexList->decContentsDepth(); + } } ol.startQuickIndices(); @@ -4473,8 +4490,6 @@ static void writeIndex(OutputList &ol) } if (documentedPages>0) { - //ol.parseText(projPrefix+theTranslator->trPageDocumentation()); - //ol.endIndexSection(isPageDocumentation); bool first=Doxygen::mainPage==0; for (const auto &pd : *Doxygen::pageLinkedMap) { @@ -4596,7 +4611,7 @@ static void writeIndex(OutputList &ol) ol.parseText(/*projPrefix+*/theTranslator->trExceptionIndex()); ol.endIndexSection(isCompoundIndex); } - if (documentedFiles>0) + if (Config_getBool(SHOW_FILES) && documentedFiles>0) { ol.startIndexSection(isFileIndex); ol.parseText(/*projPrefix+*/theTranslator->trFileIndex()); @@ -4647,7 +4662,7 @@ static void writeIndex(OutputList &ol) ol.parseText(/*projPrefix+*/theTranslator->trExceptionDocumentation()); ol.endIndexSection(isClassDocumentation); } - if (documentedFiles>0) + if (Config_getBool(SHOW_FILES) && documentedFiles>0) { ol.startIndexSection(isFileDocumentation); ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation()); @@ -4686,11 +4701,11 @@ static std::vector<bool> indexWritten; static void writeIndexHierarchyEntries(OutputList &ol,const LayoutNavEntryList &entries) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); for (const auto &lne : entries) { LayoutNavEntry::Kind kind = lne->kind(); - uint index = (uint)kind; + size_t index = static_cast<size_t>(kind); if (index>=indexWritten.size()) { size_t i; @@ -4720,7 +4735,7 @@ static void writeIndexHierarchyEntries(OutputList &ol,const LayoutNavEntryList & break; case LayoutNavEntry::Namespaces: { - static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); + bool showNamespaces = Config_getBool(SHOW_NAMESPACES); if (showNamespaces) { if (documentedNamespaces>0 && addToIndex) @@ -4739,7 +4754,7 @@ static void writeIndexHierarchyEntries(OutputList &ol,const LayoutNavEntryList & break; case LayoutNavEntry::NamespaceList: { - static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); + bool showNamespaces = Config_getBool(SHOW_NAMESPACES); if (showNamespaces) { msg("Generating namespace index...\n"); @@ -4884,7 +4899,7 @@ static void writeIndexHierarchyEntries(OutputList &ol,const LayoutNavEntryList & break; case LayoutNavEntry::Files: { - if (documentedFiles>0 && addToIndex) + if (Config_getBool(SHOW_FILES) && documentedFiles>0 && addToIndex) { Doxygen::indexList->addContentsItem(TRUE,lne->title(),QCString(),lne->baseFile(),QCString()); Doxygen::indexList->incContentsDepth(); @@ -4982,8 +4997,9 @@ static void writeIndexHierarchyEntries(OutputList &ol,const LayoutNavEntryList & static bool quickLinkVisible(LayoutNavEntry::Kind kind) { - static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool showNamespaces = Config_getBool(SHOW_NAMESPACES); + bool showFiles = Config_getBool(SHOW_FILES); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); switch (kind) { case LayoutNavEntry::MainPage: return TRUE; @@ -5011,8 +5027,8 @@ static bool quickLinkVisible(LayoutNavEntry::Kind kind) case LayoutNavEntry::ExceptionList: return annotatedExceptions>0; case LayoutNavEntry::ExceptionIndex: return annotatedExceptions>0; case LayoutNavEntry::ExceptionHierarchy: return hierarchyExceptions>0; - case LayoutNavEntry::Files: return documentedFiles>0; - case LayoutNavEntry::FileList: return documentedFiles>0; + case LayoutNavEntry::Files: return documentedFiles>0 && showFiles; + case LayoutNavEntry::FileList: return documentedFiles>0 && showFiles; case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; case LayoutNavEntry::Examples: return !Doxygen::exampleLinkedMap->empty(); case LayoutNavEntry::None: // should never happen, means not properly initialized @@ -5102,6 +5118,7 @@ static bool renderQuickLinksAsJs(std::ostream &t,LayoutNavEntry *root,bool first if (!firstChild) t << ",\n"; firstChild=FALSE; QCString url = entry->url(); + if (isURL(url)) url = "^" + url; t << "{text:\"" << convertToJSString(entry->title()) << "\",url:\"" << convertToJSString(url) << "\""; bool hasChildren=FALSE; diff --git a/src/index.h b/src/index.h index 1244e6d..30d6e5f 100644 --- a/src/index.h +++ b/src/index.h @@ -19,6 +19,7 @@ #include <utility> #include <vector> #include <memory> +#include <mutex> #include "qcstring.h" @@ -32,7 +33,7 @@ class OutputList; class IndexIntf { public: - virtual ~IndexIntf() {} + virtual ~IndexIntf() = default; virtual void initialize() = 0; virtual void finalize() = 0; virtual void incContentsDepth() = 0; @@ -50,7 +51,7 @@ class IndexIntf /** \brief A list of index interfaces. * * This class itself implements all methods of IndexIntf and - * just forwards the calls to all items in the list. + * just forwards the calls to all items in the list (composite design pattern). */ class IndexList : public IndexIntf { @@ -68,6 +69,13 @@ class IndexList : public IndexIntf (intf.get()->*methodPtr)(std::forward<As>(args)...); } } + // For each version with locking + template<class... Ts,class... As> + void foreach_locked(void (IndexIntf::*methodPtr)(Ts...),As&&... args) + { + std::lock_guard<std::mutex> lock(m_mutex); + foreach(methodPtr,std::forward<As>(args)...); + } public: /** Creates a list of indexes */ @@ -91,24 +99,25 @@ class IndexList : public IndexIntf void finalize() { foreach(&IndexIntf::finalize); } void incContentsDepth() - { if (m_enabled) foreach(&IndexIntf::incContentsDepth); } + { if (m_enabled) foreach_locked(&IndexIntf::incContentsDepth); } void decContentsDepth() - { if (m_enabled) foreach(&IndexIntf::decContentsDepth); } + { if (m_enabled) foreach_locked(&IndexIntf::decContentsDepth); } void addContentsItem(bool isDir, const QCString &name, const QCString &ref, const QCString &file, const QCString &anchor,bool separateIndex=FALSE,bool addToNavIndex=FALSE, const Definition *def=0) - { if (m_enabled) foreach(&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); } + { if (m_enabled) foreach_locked(&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); } void addIndexItem(const Definition *context,const MemberDef *md,const QCString §ionAnchor=QCString(),const QCString &title=QCString()) - { if (m_enabled) foreach(&IndexIntf::addIndexItem,context,md,sectionAnchor,title); } + { if (m_enabled) foreach_locked(&IndexIntf::addIndexItem,context,md,sectionAnchor,title); } void addIndexFile(const QCString &name) - { if (m_enabled) foreach(&IndexIntf::addIndexFile,name); } + { if (m_enabled) foreach_locked(&IndexIntf::addIndexFile,name); } void addImageFile(const QCString &name) - { if (m_enabled) foreach(&IndexIntf::addImageFile,name); } + { if (m_enabled) foreach_locked(&IndexIntf::addImageFile,name); } void addStyleSheetFile(const QCString &name) - { if (m_enabled) foreach(&IndexIntf::addStyleSheetFile,name); } + { if (m_enabled) foreach_locked(&IndexIntf::addStyleSheetFile,name); } private: bool m_enabled; + std::mutex m_mutex; }; diff --git a/src/language.cpp b/src/language.cpp index 20259c1..1399df8 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -19,139 +19,53 @@ #include "config.h" #include "util.h" #include "language.h" -#include "lang_cfg.h" #include "vhdldocgen.h" #include "translator.h" #include "translator_en.h" -#if !defined(ENGLISH_ONLY) #include "translator_adapter.h" -#ifdef LANG_NL #include "translator_nl.h" -#endif -#ifdef LANG_AM #include "translator_am.h" -#endif -#ifdef LANG_SV #include "translator_sv.h" -#endif -#ifdef LANG_CZ #include "translator_cz.h" -#endif -#ifdef LANG_FR #include "translator_fr.h" -#endif -#ifdef LANG_ID #include "translator_id.h" -#endif -#ifdef LANG_IT #include "translator_it.h" -#endif -#ifdef LANG_DE #include "translator_de.h" -#endif -#ifdef LANG_JP #include "translator_jp.h" -#endif -#ifdef LANG_JE #include "translator_je.h" -#endif -#ifdef LANG_ES #include "translator_es.h" -#endif -#ifdef LANG_EO #include "translator_eo.h" -#endif -#ifdef LANG_FI #include "translator_fi.h" -#endif -#ifdef LANG_RU #include "translator_ru.h" -#endif -#ifdef LANG_HR #include "translator_hr.h" -#endif -#ifdef LANG_PL #include "translator_pl.h" -#endif -#ifdef LANG_PT #include "translator_pt.h" -#endif -#ifdef LANG_HU +#include "translator_hi.h" #include "translator_hu.h" -#endif -#ifdef LANG_KE #include "translator_ke.h" -#endif -#ifdef LANG_KR #include "translator_kr.h" -#endif -#ifdef LANG_RO #include "translator_ro.h" -#endif -#ifdef LANG_SI #include "translator_si.h" -#endif -#ifdef LANG_CN #include "translator_cn.h" -#endif -#ifdef LANG_TW #include "translator_tw.h" -#endif -#ifdef LANG_NO #include "translator_no.h" -#endif -#ifdef LANG_BR #include "translator_br.h" -#endif -#ifdef LANG_DK #include "translator_dk.h" -#endif -#ifdef LANG_SK #include "translator_sk.h" -#endif -#ifdef LANG_UA #include "translator_ua.h" -#endif -#ifdef LANG_GR #include "translator_gr.h" -#endif -#ifdef LANG_SR #include "translator_sr.h" -#endif -#ifdef LANG_CA #include "translator_ca.h" -#endif -//#ifdef LANG_JS -//#include "translator_js.h" -//#endif -#ifdef LANG_LT #include "translator_lt.h" -#endif -#ifdef LANG_LV #include "translator_lv.h" -#endif -#ifdef LANG_ZA #include "translator_za.h" -#endif -#ifdef LANG_AR #include "translator_ar.h" -#endif -#ifdef LANG_FA #include "translator_fa.h" -#endif -#ifdef LANG_MK #include "translator_mk.h" -#endif -#ifdef LANG_SC #include "translator_sc.h" -#endif -#ifdef LANG_VI #include "translator_vi.h" -#endif -#ifdef LANG_TR #include "translator_tr.h" -#endif -#endif // !ENGLISH_ONLY +#include "translator_bg.h" Translator *theTranslator=0; @@ -160,133 +74,52 @@ void setTranslator(OUTPUT_LANGUAGE_t langName) switch (langName) { case OUTPUT_LANGUAGE_t::English: theTranslator = new TranslatorEnglish; break; -#if !defined(ENGLISH_ONLY) -#ifdef LANG_ZA case OUTPUT_LANGUAGE_t::Afrikaans: theTranslator = new TranslatorAfrikaans; break; -#endif -#ifdef LANG_AR case OUTPUT_LANGUAGE_t::Arabic: theTranslator = new TranslatorArabic; break; -#endif -#ifdef LANG_AM case OUTPUT_LANGUAGE_t::Armenian: theTranslator = new TranslatorArmenian; break; -#endif -#ifdef LANG_BR case OUTPUT_LANGUAGE_t::Brazilian: theTranslator = new TranslatorBrazilian; break; -#endif -#ifdef LANG_CA + case OUTPUT_LANGUAGE_t::Bulgarian: theTranslator = new TranslatorBulgarian; break; case OUTPUT_LANGUAGE_t::Catalan: theTranslator = new TranslatorCatalan; break; -#endif -#ifdef LANG_CN case OUTPUT_LANGUAGE_t::Chinese: theTranslator = new TranslatorChinese; break; -#endif -#ifdef LANG_TW case OUTPUT_LANGUAGE_t::Chinese_Traditional: theTranslator = new TranslatorChinesetraditional; break; -#endif -#ifdef LANG_HR case OUTPUT_LANGUAGE_t::Croatian: theTranslator = new TranslatorCroatian; break; -#endif -#ifdef LANG_CZ case OUTPUT_LANGUAGE_t::Czech: theTranslator = new TranslatorCzech; break; -#endif -#ifdef LANG_DK case OUTPUT_LANGUAGE_t::Danish: theTranslator = new TranslatorDanish; break; -#endif -#ifdef LANG_NL case OUTPUT_LANGUAGE_t::Dutch: theTranslator = new TranslatorDutch; break; -#endif -#ifdef LANG_EO case OUTPUT_LANGUAGE_t::Esperanto: theTranslator = new TranslatorEsperanto; break; -#endif -#ifdef LANG_FA case OUTPUT_LANGUAGE_t::Farsi: theTranslator = new TranslatorPersian; break; -#endif -#ifdef LANG_FI case OUTPUT_LANGUAGE_t::Finnish: theTranslator = new TranslatorFinnish; break; -#endif -#ifdef LANG_FR case OUTPUT_LANGUAGE_t::French: theTranslator = new TranslatorFrench; break; -#endif -#ifdef LANG_DE case OUTPUT_LANGUAGE_t::German: theTranslator = new TranslatorGerman; break; -#endif -#ifdef LANG_GR case OUTPUT_LANGUAGE_t::Greek: theTranslator = new TranslatorGreek; break; -#endif -#ifdef LANG_HU + case OUTPUT_LANGUAGE_t::Hindi: theTranslator = new TranslatorHindi; break; case OUTPUT_LANGUAGE_t::Hungarian: theTranslator = new TranslatorHungarian; break; -#endif -#ifdef LANG_ID case OUTPUT_LANGUAGE_t::Indonesian: theTranslator = new TranslatorIndonesian; break; -#endif -#ifdef LANG_IT case OUTPUT_LANGUAGE_t::Italian: theTranslator = new TranslatorItalian; break; -#endif -#ifdef LANG_JP case OUTPUT_LANGUAGE_t::Japanese: theTranslator = new TranslatorJapanese; break; -#endif -#ifdef LANG_JE case OUTPUT_LANGUAGE_t::Japanese_en: theTranslator = new TranslatorJapaneseEn; break; -#endif -#ifdef LANG_KR case OUTPUT_LANGUAGE_t::Korean: theTranslator = new TranslatorKorean; break; -#endif -#ifdef LANG_KE case OUTPUT_LANGUAGE_t::Korean_en: theTranslator = new TranslatorKoreanEn; break; -#endif -#ifdef LANG_LV case OUTPUT_LANGUAGE_t::Latvian: theTranslator = new TranslatorLatvian; break; -#endif -#ifdef LANG_LT case OUTPUT_LANGUAGE_t::Lithuanian: theTranslator = new TranslatorLithuanian; break; -#endif -#ifdef LANG_MK case OUTPUT_LANGUAGE_t::Macedonian: theTranslator = new TranslatorMacedonian; break; -#endif -#ifdef LANG_NO case OUTPUT_LANGUAGE_t::Norwegian: theTranslator = new TranslatorNorwegian; break; -#endif -#ifdef LANG_FA case OUTPUT_LANGUAGE_t::Persian: theTranslator = new TranslatorPersian; break; -#endif -#ifdef LANG_PL case OUTPUT_LANGUAGE_t::Polish: theTranslator = new TranslatorPolish; break; -#endif -#ifdef LANG_PT case OUTPUT_LANGUAGE_t::Portuguese: theTranslator = new TranslatorPortuguese; break; -#endif -#ifdef LANG_RO case OUTPUT_LANGUAGE_t::Romanian: theTranslator = new TranslatorRomanian; break; -#endif -#ifdef LANG_RU case OUTPUT_LANGUAGE_t::Russian: theTranslator = new TranslatorRussian; break; -#endif -#ifdef LANG_SR case OUTPUT_LANGUAGE_t::Serbian: theTranslator = new TranslatorSerbian; break; -#endif -#ifdef LANG_SC case OUTPUT_LANGUAGE_t::Serbian_Cyrillic: theTranslator = new TranslatorSerbianCyrillic; break; -#endif -#ifdef LANG_SK case OUTPUT_LANGUAGE_t::Slovak: theTranslator = new TranslatorSlovak; break; -#endif -#ifdef LANG_SI case OUTPUT_LANGUAGE_t::Slovene: theTranslator = new TranslatorSlovene; break; -#endif -#ifdef LANG_ES case OUTPUT_LANGUAGE_t::Spanish: theTranslator = new TranslatorSpanish; break; -#endif -#ifdef LANG_SV case OUTPUT_LANGUAGE_t::Swedish: theTranslator = new TranslatorSwedish; break; -#endif -#ifdef LANG_TR case OUTPUT_LANGUAGE_t::Turkish: theTranslator = new TranslatorTurkish; break; -#endif -#ifdef LANG_UA case OUTPUT_LANGUAGE_t::Ukrainian: theTranslator = new TranslatorUkrainian; break; -#endif -#ifdef LANG_VI case OUTPUT_LANGUAGE_t::Vietnamese: theTranslator = new TranslatorVietnamese; break; -#endif -#endif } + + QCString msg = theTranslator->updateNeededMessage(); + if (!msg.isEmpty()) ::msg("%s", qPrint(msg)); } diff --git a/src/languages.py b/src/languages.py deleted file mode 100755 index ea3f348..0000000 --- a/src/languages.py +++ /dev/null @@ -1,106 +0,0 @@ -# -# This file is an aid to generate the Languages rules file. -# usage: -# python languages.py > ..\winbuild\Languages.rules -# -import os -import re - -files = [f for f in os.listdir('.') if re.match(r'translator_[a-z][a-z]\.h', f)] -new_list = [] -for f in files: - new_list.append([f,(os.path.splitext(f)[0]).replace("translator_","").upper()]) - -# -# generating file is lang_cfg.py -# the rules file has to output lang_cfg.h -# -print("""\ -<?xml version="1.0" encoding="utf-8"?> -<VisualStudioToolFile - Name="languages" - Version="8.00" - > - <Rules> - <CustomBuildRule - Name="Languages" - DisplayName="Settings" - CommandLine="python $(InputPath) [AllOptions] [AdditionalOptions] > $(InpDir)/$(InputName).h" - Outputs="$(IntDir)/$(InputName).h" - FileExtensions="*.py" - AdditionalDependencies="" - ExecutionDescription="Executing languages ..." - ShowOnlyRuleProperties="false" - > - <Properties> - <EnumProperty - Name="EnglishOnly" - DisplayName="Use English Only" - Description="Use English Only" - DefaultValue="0" - > - <Values> - <EnumValue - Value="0" - Switch="" - DisplayName="Don't use English Only" - /> - <EnumValue - Value="1" - Switch="ENONLY" - DisplayName="Use English Only" - /> - </Values> - </EnumProperty> -""") -# -# generate loop, English is mandatory (so cannot be chosen) -# -for f in new_list: - if (f[1] != "EN"): - # search for the language description - fil = open(f[0], 'r') - tmp = "" - for line in fil: - if "idLanguage" in line: - tmp = line - if "}" in line: - break - elif (tmp != ""): - tmp += line - if "}" in line: - break - - tmp = tmp.replace("\n","") - l = re.sub('[^"]*"([^"]*)".*','\\1',tmp) - l1 = l.replace("-","") - # capitalize first letter - l = l.title() - print("""\ - <EnumProperty - Name="%s" - DisplayName="Use %s" - Description="Use %s" - DefaultValue="1" - > - <Values> - <EnumValue - Value="0" - Switch="" - DisplayName="Don't use %s" - /> - <EnumValue - Value="1" - Switch="%s" - DisplayName="Use %s" - /> - </Values> - </EnumProperty> - """ % (l1, l, l, l, f[1], l)) - -print("""\ - </Properties> - </CustomBuildRule> - </Rules> -</VisualStudioToolFile> -""") diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 3c5a435..2b48c3c 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -46,7 +46,7 @@ static const char *secLabels[maxLevels] = static const char *getSectionName(int level) { - static bool compactLatex = Config_getBool(COMPACT_LATEX); + bool compactLatex = Config_getBool(COMPACT_LATEX); int l = level; if (compactLatex) l++; if (Doxygen::insideMainPage) l--; @@ -165,10 +165,12 @@ static void visitPostEnd(TextStream &t, bool hasCaption, bool inlineImage = FALS } } - -static void visitCaption(LatexDocVisitor *parent, const DocNodeList &children) +void LatexDocVisitor::visitCaption(const DocNodeList &children) { - for (const auto &n : children) n->accept(parent); + for (const auto &n : children) + { + std::visit(*this,n); + } } QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) @@ -201,8 +203,8 @@ QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) LatexDocVisitor::LatexDocVisitor(TextStream &t,LatexCodeGenerator &ci, const QCString &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_t(t), m_ci(ci), m_insidePre(FALSE), + m_insideItem(FALSE), m_hide(FALSE), m_insideTabbing(insideTabbing), m_langExt(langExt) { } @@ -211,26 +213,26 @@ LatexDocVisitor::LatexDocVisitor(TextStream &t,LatexCodeGenerator &ci, // visitor functions for leaf nodes //-------------------------------------- -void LatexDocVisitor::visit(DocWord *w) +void LatexDocVisitor::operator()(const DocWord &w) { if (m_hide) return; - filter(w->word()); + filter(w.word()); } -void LatexDocVisitor::visit(DocLinkedWord *w) +void LatexDocVisitor::operator()(const DocLinkedWord &w) { if (m_hide) return; - startLink(w->ref(),w->file(),w->anchor()); - filter(w->word()); - endLink(w->ref(),w->file(),w->anchor()); + startLink(w.ref(),w.file(),w.anchor()); + filter(w.word()); + endLink(w.ref(),w.file(),w.anchor()); } -void LatexDocVisitor::visit(DocWhiteSpace *w) +void LatexDocVisitor::operator()(const DocWhiteSpace &w) { if (m_hide) return; if (m_insidePre) { - m_t << w->chars(); + m_t << w.chars(); } else { @@ -238,14 +240,14 @@ void LatexDocVisitor::visit(DocWhiteSpace *w) } } -void LatexDocVisitor::visit(DocSymbol *s) +void LatexDocVisitor::operator()(const DocSymbol &s) { if (m_hide) return; bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - const char *res = HtmlEntityMapper::instance()->latex(s->symbol()); + const char *res = HtmlEntityMapper::instance()->latex(s.symbol()); if (res) { - if (((s->symbol() == DocSymbol::Sym_lt) || (s->symbol() == DocSymbol::Sym_Less))&& (!m_insidePre)) + if (((s.symbol() == HtmlEntityMapper::Sym_lt) || (s.symbol() == HtmlEntityMapper::Sym_Less))&& (!m_insidePre)) { if (pdfHyperlinks) { @@ -256,7 +258,7 @@ void LatexDocVisitor::visit(DocSymbol *s) m_t << "$<$"; } } - else if (((s->symbol() == DocSymbol::Sym_gt) || (s->symbol() == DocSymbol::Sym_Greater)) && (!m_insidePre)) + else if (((s.symbol() == HtmlEntityMapper::Sym_gt) || (s.symbol() == HtmlEntityMapper::Sym_Greater)) && (!m_insidePre)) { if (pdfHyperlinks) { @@ -274,14 +276,14 @@ void LatexDocVisitor::visit(DocSymbol *s) } else { - err("LaTeX: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + err("LaTeX: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } } -void LatexDocVisitor::visit(DocEmoji *s) +void LatexDocVisitor::operator()(const DocEmoji &s) { if (m_hide) return; - QCString emojiName = EmojiEntityMapper::instance()->name(s->index()); + QCString emojiName = EmojiEntityMapper::instance()->name(s.index()); if (!emojiName.isEmpty()) { QCString imageName=emojiName.mid(1,emojiName.length()-2); // strip : at start and end @@ -291,31 +293,31 @@ void LatexDocVisitor::visit(DocEmoji *s) } else { - m_t << s->name(); + m_t << s.name(); } } -void LatexDocVisitor::visit(DocURL *u) +void LatexDocVisitor::operator()(const DocURL &u) { if (m_hide) return; if (Config_getBool(PDF_HYPERLINKS)) { m_t << "\\href{"; - if (u->isEmail()) m_t << "mailto:"; - m_t << latexFilterURL(u->url()) << "}"; + if (u.isEmail()) m_t << "mailto:"; + m_t << latexFilterURL(u.url()) << "}"; } m_t << "{\\texttt{ "; - filter(u->url()); + filter(u.url()); m_t << "}}"; } -void LatexDocVisitor::visit(DocLineBreak *) +void LatexDocVisitor::operator()(const DocLineBreak &) { if (m_hide) return; m_t << "~\\newline\n"; } -void LatexDocVisitor::visit(DocHorRuler *) +void LatexDocVisitor::operator()(const DocHorRuler &) { if (m_hide) return; if (insideTable()) @@ -324,46 +326,46 @@ void LatexDocVisitor::visit(DocHorRuler *) m_t << "\\DoxyHorRuler{0}\n"; } -void LatexDocVisitor::visit(DocStyleChange *s) +void LatexDocVisitor::operator()(const DocStyleChange &s) { if (m_hide) return; - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) m_t << "{\\bfseries{"; else m_t << "}}"; + if (s.enable()) m_t << "{\\bfseries{"; else m_t << "}}"; break; case DocStyleChange::S: case DocStyleChange::Strike: case DocStyleChange::Del: - if (s->enable()) m_t << "\\sout{"; else m_t << "}"; + if (s.enable()) m_t << "\\sout{"; else m_t << "}"; break; case DocStyleChange::Underline: case DocStyleChange::Ins: - if (s->enable()) m_t << "\\uline{"; else m_t << "}"; + if (s.enable()) m_t << "\\uline{"; else m_t << "}"; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "{\\itshape "; else m_t << "}"; + if (s.enable()) m_t << "{\\itshape "; else m_t << "}"; break; case DocStyleChange::Code: - if (s->enable()) m_t << "{\\ttfamily "; else m_t << "}"; + if (s.enable()) m_t << "{\\ttfamily "; else m_t << "}"; break; case DocStyleChange::Subscript: - if (s->enable()) m_t << "\\textsubscript{"; else m_t << "}"; + if (s.enable()) m_t << "\\textsubscript{"; else m_t << "}"; break; case DocStyleChange::Superscript: - if (s->enable()) m_t << "\\textsuperscript{"; else m_t << "}"; + if (s.enable()) m_t << "\\textsuperscript{"; else m_t << "}"; break; case DocStyleChange::Center: - if (s->enable()) m_t << "\\begin{center}"; else m_t << "\\end{center} "; + if (s.enable()) m_t << "\\begin{center}"; else m_t << "\\end{center} "; break; case DocStyleChange::Small: - if (s->enable()) m_t << "\n\\footnotesize "; else m_t << "\n\\normalsize "; + if (s.enable()) m_t << "\n\\footnotesize "; else m_t << "\n\\normalsize "; break; case DocStyleChange::Cite: - if (s->enable()) m_t << "{\\itshape "; else m_t << "}"; + if (s.enable()) m_t << "{\\itshape "; else m_t << "}"; break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s.enable()) { m_t << "\n\\begin{DoxyPre}"; m_insidePre=TRUE; @@ -377,44 +379,44 @@ void LatexDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; case DocStyleChange::Details: /* emulation of the <details> tag */ - if (!s->enable()) m_t << "\n\n"; + if (!s.enable()) m_t << "\n\n"; break; case DocStyleChange::Summary: /* emulation of the <summary> tag inside a <details> tag */ - if (s->enable()) m_t << "{\\bfseries{"; else m_t << "}}"; + if (s.enable()) m_t << "{\\bfseries{"; else m_t << "}}"; break; } } -void LatexDocVisitor::visit(DocVerbatim *s) +void LatexDocVisitor::operator()(const DocVerbatim &s) { if (m_hide) return; QCString lang = m_langExt; - if (!s->language().isEmpty()) // explicit language setting + if (!s.language().isEmpty()) // explicit language setting { - lang = s->language(); + lang = s.language(); } SrcLangExt langExt = getLanguageFromCodeLang(lang); - switch(s->type()) + switch(s.type()) { case DocVerbatim::Code: { m_ci.startCodeFragment("DoxyCode"); - 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_ci.endCodeFragment("DoxyCode"); } break; case DocVerbatim::JavaDocLiteral: - filter(s->text(), true); + filter(s.text(), true); break; case DocVerbatim::JavaDocCode: m_t << "{\\ttfamily "; - filter(s->text(), true); + filter(s.text(), true); m_t << "}"; break; case DocVerbatim::Verbatim: m_t << "\\begin{DoxyVerb}"; - m_t << s->text(); + m_t << s.text(); m_t << "\\end{DoxyVerb}\n"; break; case DocVerbatim::HtmlOnly: @@ -425,7 +427,7 @@ void LatexDocVisitor::visit(DocVerbatim *s) /* nothing */ break; case DocVerbatim::LatexOnly: - m_t << s->text(); + m_t << s.text(); break; case DocVerbatim::Dot: { @@ -444,12 +446,12 @@ void LatexDocVisitor::visit(DocVerbatim *s) } else { - file.write( s->text().data(), s->text().length() ); + file.write( s.text().data(), s.text().length() ); file.close(); - startDotFile(fileName,s->width(),s->height(),s->hasCaption(),s->srcFile(),s->srcLine()); - visitCaption(this, s->children()); - endDotFile(s->hasCaption()); + startDotFile(fileName,s.width(),s.height(),s.hasCaption(),s.srcFile(),s.srcLine()); + visitChildren(s); + endDotFile(s.hasCaption()); if (Config_getBool(DOT_CLEANUP)) Dir().remove(fileName.str()); } @@ -473,7 +475,7 @@ void LatexDocVisitor::visit(DocVerbatim *s) else { QCString text = "msc {"; - text+=s->text(); + text+=s.text(); text+="}"; file.write( text.data(), text.length() ); file.close(); @@ -488,9 +490,9 @@ void LatexDocVisitor::visit(DocVerbatim *s) { QCString latexOutput = Config_getString(LATEX_OUTPUT); QCString baseName = PlantumlManager::instance().writePlantUMLSource( - latexOutput,s->exampleFile(),s->text(), - s->useBitmap() ? PlantumlManager::PUML_BITMAP : PlantumlManager::PUML_EPS, - s->engine(),s->srcFile(),s->srcLine()); + latexOutput,s.exampleFile(),s.text(), + s.useBitmap() ? PlantumlManager::PUML_BITMAP : PlantumlManager::PUML_EPS, + s.engine(),s.srcFile(),s.srcLine()); writePlantUMLFile(baseName, s); } @@ -498,33 +500,33 @@ void LatexDocVisitor::visit(DocVerbatim *s) } } -void LatexDocVisitor::visit(DocAnchor *anc) +void LatexDocVisitor::operator()(const DocAnchor &anc) { if (m_hide) return; - m_t << "\\label{" << stripPath(anc->file()) << "_" << anc->anchor() << "}%\n"; - if (!anc->file().isEmpty() && Config_getBool(PDF_HYPERLINKS)) + m_t << "\\label{" << stripPath(anc.file()) << "_" << anc.anchor() << "}%\n"; + if (!anc.file().isEmpty() && Config_getBool(PDF_HYPERLINKS)) { - m_t << "\\Hypertarget{" << stripPath(anc->file()) << "_" << anc->anchor() + m_t << "\\Hypertarget{" << stripPath(anc.file()) << "_" << anc.anchor() << "}%\n"; } } -void LatexDocVisitor::visit(DocInclude *inc) +void LatexDocVisitor::operator()(const DocInclude &inc) { if (m_hide) return; - SrcLangExt langExt = getLanguageFromFileName(inc->extension()); - switch(inc->type()) + SrcLangExt langExt = getLanguageFromFileName(inc.extension()); + switch(inc.type()) { case DocInclude::IncWithLines: { m_ci.startCodeFragment("DoxyCodeInclude"); - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, // fileDef, -1, // start line -1, // end line @@ -539,9 +541,9 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::Include: { m_ci.startCodeFragment("DoxyCodeInclude"); - 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(), 0, // fileDef -1, // startLine -1, // endLine @@ -561,39 +563,39 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::DocbookInclude: break; case DocInclude::LatexInclude: - m_t << inc->text(); + m_t << inc.text(); break; case DocInclude::VerbInclude: m_t << "\n\\begin{DoxyVerbInclude}\n"; - m_t << inc->text(); + m_t << inc.text(); m_t << "\\end{DoxyVerbInclude}\n"; break; case DocInclude::Snippet: { m_ci.startCodeFragment("DoxyCodeInclude"); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile() + inc.isExample(), + inc.exampleFile() ); m_ci.endCodeFragment("DoxyCodeInclude"); } break; case DocInclude::SnipWithLines: { - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); m_ci.startCodeFragment("DoxyCodeInclude"); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, - lineBlock(inc->text(),inc->blockId()), + lineBlock(inc.text(),inc.blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef @@ -611,46 +613,46 @@ void LatexDocVisitor::visit(DocInclude *inc) } } -void LatexDocVisitor::visit(DocIncOperator *op) +void LatexDocVisitor::operator()(const DocIncOperator &op) { //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", - // op->type(),op->isFirst(),op->isLast(),qPrint(op->text())); - if (op->isFirst()) + // op.type(),op.isFirst(),op.isLast(),qPrint(op.text())); + if (op.isFirst()) { if (!m_hide) m_ci.startCodeFragment("DoxyCodeInclude"); pushHidden(m_hide); m_hide = TRUE; } - QCString locLangExt = getFileNameExtension(op->includeFileName()); + 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) { m_hide = popHidden(); if (!m_hide) { FileDef *fd = 0; - if (!op->includeFileName().isEmpty()) + if (!op.includeFileName().isEmpty()) { - FileInfo cfi( op->includeFileName().str() ); + FileInfo cfi( op.includeFileName().str() ); fd = createFileDef( cfi.dirPath(), cfi.fileName() ); } - getCodeParser(locLangExt).parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile(), + getCodeParser(locLangExt).parseCode(m_ci,op.context(),op.text(),langExt, + op.isExample(),op.exampleFile(), fd, // fileDef - op->line(), // startLine + op.line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - op->showLineNo() // show line numbers + op.showLineNo() // show line numbers ); if (fd) delete fd; } pushHidden(m_hide); m_hide=TRUE; } - if (op->isLast()) + if (op.isLast()) { m_hide=popHidden(); if (!m_hide) m_ci.endCodeFragment("DoxyCodeInclude"); @@ -661,10 +663,10 @@ void LatexDocVisitor::visit(DocIncOperator *op) } } -void LatexDocVisitor::visit(DocFormula *f) +void LatexDocVisitor::operator()(const DocFormula &f) { if (m_hide) return; - QCString s = f->text(); + QCString s = f.text(); const char *p = s.data(); char c; if (p) @@ -680,27 +682,27 @@ void LatexDocVisitor::visit(DocFormula *f) } } -void LatexDocVisitor::visit(DocIndexEntry *i) +void LatexDocVisitor::operator()(const DocIndexEntry &i) { if (m_hide) return; m_t << "\\index{"; - m_t << latexEscapeLabelName(i->entry()); + m_t << latexEscapeLabelName(i.entry()); m_t << "@{"; - m_t << latexEscapeIndexChars(i->entry()); + m_t << latexEscapeIndexChars(i.entry()); m_t << "}}"; } -void LatexDocVisitor::visit(DocSimpleSectSep *) +void LatexDocVisitor::operator()(const DocSimpleSectSep &) { } -void LatexDocVisitor::visit(DocCite *cite) +void LatexDocVisitor::operator()(const DocCite &cite) { if (m_hide) return; - if (!cite->file().isEmpty()) + if (!cite.file().isEmpty()) { - //startLink(cite->ref(),cite->file(),cite->anchor()); - QCString anchor = cite->anchor(); + //startLink(cite.ref(),cite.file(),cite.anchor()); + QCString anchor = cite.anchor(); QCString anchorPrefix = CitationManager::instance().anchorPrefix(); anchor = anchor.mid(anchorPrefix.length()); // strip prefix m_t << "\\cite{" << anchor << "}"; @@ -708,7 +710,7 @@ void LatexDocVisitor::visit(DocCite *cite) else { m_t << "{\\bfseries ["; - filter(cite->text()); + filter(cite.text()); m_t << "]}"; } } @@ -717,11 +719,11 @@ void LatexDocVisitor::visit(DocCite *cite) // visitor functions for compound nodes //-------------------------------------- -void LatexDocVisitor::visitPre(DocAutoList *l) +void LatexDocVisitor::operator()(const DocAutoList &l) { if (m_hide) return; if (m_indentLevel>=maxIndentLevels-1) return; - if (l->isEnumList()) + if (l.isEnumList()) { m_t << "\n\\begin{DoxyEnumerate}"; m_listItemInfo[indentLevel()].isEnum = true; @@ -731,13 +733,8 @@ void LatexDocVisitor::visitPre(DocAutoList *l) m_listItemInfo[indentLevel()].isEnum = false; m_t << "\n\\begin{DoxyItemize}"; } -} - -void LatexDocVisitor::visitPost(DocAutoList *l) -{ - if (m_hide) return; - if (m_indentLevel>=maxIndentLevels-1) return; - if (l->isEnumList()) + visitChildren(l); + if (l.isEnumList()) { m_t << "\n\\end{DoxyEnumerate}"; } @@ -747,46 +744,35 @@ void LatexDocVisitor::visitPost(DocAutoList *l) } } -void LatexDocVisitor::visitPre(DocAutoListItem *) +void LatexDocVisitor::operator()(const DocAutoListItem &li) { if (m_hide) return; m_t << "\n\\item "; incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocAutoListItem *) -{ + visitChildren(li); decIndentLevel(); } -void LatexDocVisitor::visitPre(DocPara *) -{ -} - -void LatexDocVisitor::visitPost(DocPara *p) +void LatexDocVisitor::operator()(const DocPara &p) { if (m_hide) return; - if (!p->isLast() && // omit <p> for last paragraph - !(p->parent() && // and for parameter sections - p->parent()->kind()==DocNode::Kind_ParamSect + visitChildren(p); + if (!p.isLast() && // omit <p> for last paragraph + !(p.parent() && // and for parameter sections + std::get_if<DocParamSect>(p.parent()) ) ) m_t << "\n\n"; } -void LatexDocVisitor::visitPre(DocRoot *r) -{ - //if (r->indent()) incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocRoot *r) +void LatexDocVisitor::operator()(const DocRoot &r) { - //if (r->indent()) decIndentLevel(); + visitChildren(r); } -void LatexDocVisitor::visitPre(DocSimpleSect *s) +void LatexDocVisitor::operator()(const DocSimpleSect &s) { if (m_hide) return; - switch(s->type()) + switch(s.type()) { case DocSimpleSect::See: m_t << "\\begin{DoxySeeAlso}{"; @@ -857,22 +843,16 @@ void LatexDocVisitor::visitPre(DocSimpleSect *s) case DocSimpleSect::Unknown: break; } - // special case 1: user defined title - if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) - { - incIndentLevel(); - m_t << "}\n"; - } - else + if (s.title()) { m_insideItem=TRUE; + std::visit(*this,*s.title()); + m_insideItem=FALSE; } -} - -void LatexDocVisitor::visitPost(DocSimpleSect *s) -{ - if (m_hide) return; - switch(s->type()) + m_t << "}\n"; + incIndentLevel(); + visitChildren(s); + switch(s.type()) { case DocSimpleSect::See: m_t << "\n\\end{DoxySeeAlso}\n"; @@ -931,68 +911,56 @@ void LatexDocVisitor::visitPost(DocSimpleSect *s) decIndentLevel(); } -void LatexDocVisitor::visitPre(DocTitle *) -{ -} - -void LatexDocVisitor::visitPost(DocTitle *) +void LatexDocVisitor::operator()(const DocTitle &t) { if (m_hide) return; - m_insideItem=FALSE; - m_t << "}\n"; + visitChildren(t); } -void LatexDocVisitor::visitPre(DocSimpleList *) +void LatexDocVisitor::operator()(const DocSimpleList &l) { if (m_hide) return; m_t << "\\begin{DoxyItemize}\n"; m_listItemInfo[indentLevel()].isEnum = false; -} - -void LatexDocVisitor::visitPost(DocSimpleList *) -{ - if (m_hide) return; + visitChildren(l); m_t << "\\end{DoxyItemize}\n"; } -void LatexDocVisitor::visitPre(DocSimpleListItem *) +void LatexDocVisitor::operator()(const DocSimpleListItem &li) { if (m_hide) return; m_t << "\\item "; incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocSimpleListItem *) -{ + if (li.paragraph()) + { + visit(*this,*li.paragraph()); + } decIndentLevel(); } -void LatexDocVisitor::visitPre(DocSection *s) +void LatexDocVisitor::operator()(const DocSection &s) { if (m_hide) return; if (Config_getBool(PDF_HYPERLINKS)) { - m_t << "\\hypertarget{" << stripPath(s->file()) << "_" << s->anchor() << "}{}"; + m_t << "\\hypertarget{" << stripPath(s.file()) << "_" << s.anchor() << "}{}"; } - m_t << "\\" << getSectionName(s->level()) << "{"; - filter(convertCharEntitiesToUTF8(s->title())); - m_t << "}\\label{" << stripPath(s->file()) << "_" << s->anchor() << "}\n"; -} - -void LatexDocVisitor::visitPost(DocSection *) -{ + m_t << "\\" << getSectionName(s.level()) << "{"; + filter(convertCharEntitiesToUTF8(s.title())); + m_t << "}\\label{" << stripPath(s.file()) << "_" << s.anchor() << "}\n"; + visitChildren(s); } -void LatexDocVisitor::visitPre(DocHtmlList *s) +void LatexDocVisitor::operator()(const DocHtmlList &s) { if (m_hide) return; if (m_indentLevel>=maxIndentLevels-1) return; - m_listItemInfo[indentLevel()].isEnum = s->type()==DocHtmlList::Ordered; - if (s->type()==DocHtmlList::Ordered) + m_listItemInfo[indentLevel()].isEnum = s.type()==DocHtmlList::Ordered; + if (s.type()==DocHtmlList::Ordered) { bool first = true; m_t << "\n\\begin{DoxyEnumerate}"; - for (const auto &opt : s->attribs()) + for (const auto &opt : s.attribs()) { if (opt.name=="type") { @@ -1039,25 +1007,23 @@ void LatexDocVisitor::visitPre(DocHtmlList *s) if (!first) m_t << "]\n"; } else + { m_t << "\n\\begin{DoxyItemize}"; -} - -void LatexDocVisitor::visitPost(DocHtmlList *s) -{ - if (m_hide) return; + } + visitChildren(s); if (m_indentLevel>=maxIndentLevels-1) return; - if (s->type()==DocHtmlList::Ordered) + if (s.type()==DocHtmlList::Ordered) m_t << "\n\\end{DoxyEnumerate}"; else m_t << "\n\\end{DoxyItemize}"; } -void LatexDocVisitor::visitPre(DocHtmlListItem *l) +void LatexDocVisitor::operator()(const DocHtmlListItem &l) { if (m_hide) return; if (m_listItemInfo[indentLevel()].isEnum) { - for (const auto &opt : l->attribs()) + for (const auto &opt : l.attribs()) { if (opt.name=="value") { @@ -1072,62 +1038,40 @@ void LatexDocVisitor::visitPre(DocHtmlListItem *l) } m_t << "\n\\item "; incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocHtmlListItem *) -{ + visitChildren(l); decIndentLevel(); } -//void LatexDocVisitor::visitPre(DocHtmlPre *) -//{ -// m_t << "\\small\\begin{alltt}"; -// m_insidePre=TRUE; -//} -//void LatexDocVisitor::visitPost(DocHtmlPre *) -//{ -// m_insidePre=FALSE; -// m_t << "\\end{alltt}\\normalsize \n"; -//} - - -static bool classEqualsReflist(const DocNode *n) +static bool classEqualsReflist(const DocHtmlDescList &dl) { - if (n->kind()==DocNode::Kind_HtmlDescList) - { - HtmlAttribList attrs = ((DocHtmlDescList *)n)->attribs(); - auto it = std::find_if(attrs.begin(),attrs.end(), - [](const auto &att) { return att.name=="class"; }); - if (it!=attrs.end() && it->value == "reflist") return true; - } + HtmlAttribList attrs = dl.attribs(); + auto it = std::find_if(attrs.begin(),attrs.end(), + [](const auto &att) { return att.name=="class"; }); + if (it!=attrs.end() && it->value == "reflist") return true; return false; } - -static bool listIsNested(const DocNode *n) +static bool listIsNested(const DocHtmlDescList &dl) { bool isNested=false; - if (n) - { - if (classEqualsReflist(n)) return false; - n = n->parent(); - } + const DocNodeVariant *n = dl.parent(); while (n && !isNested) { - if (n->kind()==DocNode::Kind_HtmlDescList) + if (std::get_if<DocHtmlDescList>(n)) { - isNested = !classEqualsReflist(n); + isNested = !classEqualsReflist(std::get<DocHtmlDescList>(*n)); } - n = n->parent(); + n = ::parent(n); } return isNested; } -void LatexDocVisitor::visitPre(DocHtmlDescList *dl) +void LatexDocVisitor::operator()(const DocHtmlDescList &dl) { if (m_hide) return; - if (classEqualsReflist(dl)) + bool eq = classEqualsReflist(dl); + if (eq) { m_t << "\n\\begin{DoxyRefList}"; } @@ -1136,12 +1080,8 @@ void LatexDocVisitor::visitPre(DocHtmlDescList *dl) if (listIsNested(dl)) m_t << "\n\\hfill"; m_t << "\n\\begin{DoxyDescription}"; } -} - -void LatexDocVisitor::visitPost(DocHtmlDescList *dl) -{ - if (m_hide) return; - if (classEqualsReflist(dl)) + visitChildren(dl); + if (eq) { m_t << "\n\\end{DoxyRefList}"; } @@ -1151,42 +1091,35 @@ void LatexDocVisitor::visitPost(DocHtmlDescList *dl) } } -void LatexDocVisitor::visitPre(DocHtmlDescTitle *) +void LatexDocVisitor::operator()(const DocHtmlDescTitle &dt) { if (m_hide) return; m_t << "\n\\item["; m_insideItem=TRUE; -} - -void LatexDocVisitor::visitPost(DocHtmlDescTitle *) -{ - if (m_hide) return; + visitChildren(dt); m_insideItem=FALSE; m_t << "]"; } -void LatexDocVisitor::visitPre(DocHtmlDescData *) +void LatexDocVisitor::operator()(const DocHtmlDescData &dd) { incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocHtmlDescData *) -{ + visitChildren(dd); decIndentLevel(); } -static bool tableIsNested(const DocNode *n) +static bool tableIsNested(const DocNodeVariant *n) { bool isNested=FALSE; while (n && !isNested) { - isNested = n->kind()==DocNode::Kind_HtmlTable || n->kind()==DocNode::Kind_ParamSect; - n = n->parent(); + isNested = holds_one_of_alternatives<DocHtmlTable,DocParamSect>(*n); + n = ::parent(n); } return isNested; } -static void writeStartTableCommand(TextStream &t,const DocNode *n,int cols) +static void writeStartTableCommand(TextStream &t,const DocNodeVariant *n,size_t cols) { if (tableIsNested(n)) { @@ -1199,7 +1132,7 @@ static void writeStartTableCommand(TextStream &t,const DocNode *n,int cols) //return isNested ? "TabularNC" : "TabularC"; } -static void writeEndTableCommand(TextStream &t,const DocNode *n) +static void writeEndTableCommand(TextStream &t,const DocNodeVariant *n) { if (tableIsNested(n)) { @@ -1212,14 +1145,14 @@ static void writeEndTableCommand(TextStream &t,const DocNode *n) //return isNested ? "TabularNC" : "TabularC"; } -void LatexDocVisitor::visitPre(DocHtmlTable *t) +void LatexDocVisitor::operator()(const DocHtmlTable &t) { if (m_hide) return; pushTableState(); - if (t->hasCaption()) + const DocHtmlCaption *c = t.caption() ? &std::get<DocHtmlCaption>(*t.caption()) : nullptr; + if (c) { - DocHtmlCaption *c = t->caption(); - static bool pdfHyperLinks = Config_getBool(PDF_HYPERLINKS); + bool pdfHyperLinks = Config_getBool(PDF_HYPERLINKS); if (!c->file().isEmpty() && pdfHyperLinks) { m_t << "\\hypertarget{" << stripPath(c->file()) << "_" << c->anchor() @@ -1228,72 +1161,60 @@ void LatexDocVisitor::visitPre(DocHtmlTable *t) m_t << "\n"; } - writeStartTableCommand(m_t,t->parent(),(uint)t->numColumns()); + writeStartTableCommand(m_t,t.parent(),t.numColumns()); - if (t->hasCaption()) + if (c) { - DocHtmlCaption *c = t->caption(); m_t << "\\caption{"; - visitCaption(this, c->children()); + std::visit(*this, *t.caption()); m_t << "}"; m_t << "\\label{" << stripPath(c->file()) << "_" << c->anchor() << "}"; m_t << "\\\\\n"; } - setNumCols((uint)t->numColumns()); + setNumCols(t.numColumns()); m_t << "\\hline\n"; // check if first row is a heading and then render the row already here // and end it with \endfirsthead (triggered via m_firstRow==TRUE) // then repeat the row as normal and end it with \endhead (m_firstRow==FALSE) - DocHtmlRow *firstRow = t->firstRow(); + const DocHtmlRow *firstRow = std::get_if<DocHtmlRow>(t.firstRow()); if (firstRow && firstRow->isHeading()) { setFirstRow(TRUE); - DocNode *n = t->parent(); - if (!tableIsNested(n)) firstRow->accept(this); + if (!tableIsNested(t.parent())) + { + std::visit(*this,*t.firstRow()); + } setFirstRow(FALSE); } -} - -void LatexDocVisitor::visitPost(DocHtmlTable *t) -{ - if (m_hide) return; - writeEndTableCommand(m_t,t->parent()); + visitChildren(t); + writeEndTableCommand(m_t,t.parent()); popTableState(); } -void LatexDocVisitor::visitPre(DocHtmlCaption *c) -{ - m_hideCaption = m_hide; - m_hide = TRUE; -} - -void LatexDocVisitor::visitPost(DocHtmlCaption *c) +void LatexDocVisitor::operator()(const DocHtmlCaption &c) { - m_hide = m_hideCaption; -} - -void LatexDocVisitor::visitPre(DocHtmlRow *r) -{ - setCurrentColumn(0); + if (m_hide) return; + visitChildren(c); } -void LatexDocVisitor::visitPost(DocHtmlRow *row) +void LatexDocVisitor::operator()(const DocHtmlRow &row) { if (m_hide) return; + setCurrentColumn(0); - DocNode *n = row->parent() ->parent(); + visitChildren(row); - int c=currentColumn(); + size_t c=currentColumn(); while (c<=numCols()) // end of row while inside a row span? { for (const auto &span : rowSpans()) { //printf(" found row span: column=%d rs=%d cs=%d rowIdx=%d cell->rowIdx=%d i=%d c=%d\n", - // span->column, span->rowSpan,span->colSpan,row->rowIndex(),span->cell->rowIndex(),i,c); + // span->column, span->rowSpan,span->colSpan,row.rowIndex(),span->cell->rowIndex(),i,c); if (span.rowSpan>0 && span.column==c && // we are at a cell in a row span - row->rowIndex()>span.cell->rowIndex() // but not the row that started the span + row.rowIndex()>span.cell.rowIndex() // but not the row that started the span ) { m_t << "&"; @@ -1313,7 +1234,7 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row) m_t << "\\\\"; - int col = 1; + size_t col = 1; for (auto &span : rowSpans()) { if (span.rowSpan>0) span.rowSpan--; @@ -1339,8 +1260,8 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row) m_t << "\n"; - - if (row->isHeading() && row->rowIndex()==1 && !tableIsNested(n)) + const DocNodeVariant *n = ::parent(row.parent()); + if (row.isHeading() && row.rowIndex()==1 && !tableIsNested(n)) { if (firstRow()) { @@ -1356,15 +1277,11 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row) } } -void LatexDocVisitor::visitPre(DocHtmlCell *c) +void LatexDocVisitor::operator()(const DocHtmlCell &c) { if (m_hide) return; - DocHtmlRow *row = 0; - if (c->parent() && c->parent()->kind()==DocNode::Kind_HtmlRow) - { - row = (DocHtmlRow*)c->parent(); - } + const DocHtmlRow *row = std::get_if<DocHtmlRow>(c.parent()); setCurrentColumn(currentColumn()+1); @@ -1376,11 +1293,11 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) if (row && span.colSpan>1) { m_t << "\\multicolumn{" << span.colSpan << "}{"; - if (currentColumn() /*c->columnIndex()*/==1) // add extra | for first column + if (currentColumn() /*c.columnIndex()*/==1) // add extra | for first column { m_t << "|"; } - m_t << "l|}{" << (c->isHeading()? "\\columncolor{\\tableheadbgcolor}" : "") << "}"; // alignment not relevant, empty column + m_t << "l|}{" << (c.isHeading()? "\\columncolor{\\tableheadbgcolor}" : "") << "}"; // alignment not relevant, empty column setCurrentColumn(currentColumn()+span.colSpan); } else @@ -1391,13 +1308,13 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) } } - int cs = c->colSpan(); - int a = c->alignment(); + int cs = c.colSpan(); + int a = c.alignment(); if (cs>1 && row) { setInColSpan(TRUE); m_t << "\\multicolumn{" << cs << "}{"; - if (c->columnIndex()==1) // add extra | for first column + if (c.columnIndex()==1) // add extra | for first column { m_t << "|"; } @@ -1414,8 +1331,8 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) break; } } - int rs = c->rowSpan(); - int va = c->valignment(); + int rs = c.rowSpan(); + int va = c.valignment(); if (rs>0) { setInRowSpan(TRUE); @@ -1434,7 +1351,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) break; } //printf("adding row span: cell={r=%d c=%d rs=%d cs=%d} curCol=%d\n", - // c->rowIndex(),c->columnIndex(),c->rowSpan(),c->colSpan(), + // c.rowIndex(),c.columnIndex(),c.rowSpan(),c.colSpan(), // currentColumn()); addRowSpan(ActiveRowSpan(c,rs,cs,currentColumn())); m_t << "{" << rs << "}{*}{"; @@ -1447,7 +1364,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) { m_t << "\\PBS\\raggedleft "; } - if (c->isHeading()) + if (c.isHeading()) { m_t << "\\cellcolor{\\tableheadbgcolor}\\textbf{ "; } @@ -1455,12 +1372,10 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) { setCurrentColumn(currentColumn()+cs-1); } -} -void LatexDocVisitor::visitPost(DocHtmlCell *c) -{ - if (m_hide) return; - if (c->isHeading()) + visitChildren(c); + + if (c.isHeading()) { m_t << "}"; } @@ -1474,223 +1389,172 @@ void LatexDocVisitor::visitPost(DocHtmlCell *c) setInColSpan(FALSE); m_t << "}"; } - if (!c->isLast()) m_t << "&"; -} - -void LatexDocVisitor::visitPre(DocInternal *) -{ - if (m_hide) return; - //m_t << "\\begin{DoxyInternal}{"; - //filter(theTranslator->trForInternalUseOnly()); - //m_t << "}\n"; + if (!c.isLast()) m_t << "&"; } -void LatexDocVisitor::visitPost(DocInternal *) +void LatexDocVisitor::operator()(const DocInternal &i) { if (m_hide) return; - //m_t << "\\end{DoxyInternal}\n"; + visitChildren(i); } -void LatexDocVisitor::visitPre(DocHRef *href) +void LatexDocVisitor::operator()(const DocHRef &href) { if (m_hide) return; if (Config_getBool(PDF_HYPERLINKS)) { m_t << "\\href{"; - m_t << latexFilterURL(href->url()); + m_t << latexFilterURL(href.url()); m_t << "}"; } m_t << "{\\texttt{ "; -} - -void LatexDocVisitor::visitPost(DocHRef *) -{ - if (m_hide) return; + visitChildren(href); m_t << "}}"; } -void LatexDocVisitor::visitPre(DocHtmlHeader *header) -{ - if (m_hide) return; - m_t << "\\" << getSectionName(header->level()) << "*{"; -} - -void LatexDocVisitor::visitPost(DocHtmlHeader *) +void LatexDocVisitor::operator()(const DocHtmlHeader &header) { if (m_hide) return; + m_t << "\\" << getSectionName(header.level()) << "*{"; + visitChildren(header); m_t << "}"; } -void LatexDocVisitor::visitPre(DocImage *img) + +void LatexDocVisitor::operator()(const DocImage &img) { - if (img->type()==DocImage::Latex) + if (img.type()==DocImage::Latex) { if (m_hide) return; - QCString gfxName = img->name(); + QCString gfxName = img.name(); if (gfxName.right(4)==".eps" || gfxName.right(4)==".pdf") { gfxName=gfxName.left(gfxName.length()-4); } - visitPreStart(m_t,img->hasCaption(), gfxName, img->width(), img->height(), img->isInlineImage()); + visitPreStart(m_t,img.hasCaption(), gfxName, img.width(), img.height(), img.isInlineImage()); + visitChildren(img); + visitPostEnd(m_t,img.hasCaption(), img.isInlineImage()); } else // other format -> skip { - pushHidden(m_hide); - m_hide=TRUE; } } -void LatexDocVisitor::visitPost(DocImage *img) -{ - if (img->type()==DocImage::Latex) - { - if (m_hide) return; - visitPostEnd(m_t,img->hasCaption(), img->isInlineImage()); - } - else // other format - { - m_hide = popHidden(); - } -} - -void LatexDocVisitor::visitPre(DocDotFile *df) +void LatexDocVisitor::operator()(const DocDotFile &df) { if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(LATEX_OUTPUT)+"/"+stripPath(df->file())); - startDotFile(df->file(),df->width(),df->height(),df->hasCaption(),df->srcFile(),df->srcLine()); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(LATEX_OUTPUT)+"/"+stripPath(df.file())); + startDotFile(df.file(),df.width(),df.height(),df.hasCaption(),df.srcFile(),df.srcLine()); + visitChildren(df); + endDotFile(df.hasCaption()); } -void LatexDocVisitor::visitPost(DocDotFile *df) +void LatexDocVisitor::operator()(const DocMscFile &df) { if (m_hide) return; - endDotFile(df->hasCaption()); -} -void LatexDocVisitor::visitPre(DocMscFile *df) -{ - if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(LATEX_OUTPUT)+"/"+stripPath(df->file())); - startMscFile(df->file(),df->width(),df->height(),df->hasCaption(),df->srcFile(),df->srcLine()); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(LATEX_OUTPUT)+"/"+stripPath(df.file())); + startMscFile(df.file(),df.width(),df.height(),df.hasCaption(),df.srcFile(),df.srcLine()); + visitChildren(df); + endMscFile(df.hasCaption()); } -void LatexDocVisitor::visitPost(DocMscFile *df) +void LatexDocVisitor::operator()(const DocDiaFile &df) { if (m_hide) return; - endMscFile(df->hasCaption()); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(LATEX_OUTPUT)+"/"+stripPath(df.file())); + startDiaFile(df.file(),df.width(),df.height(),df.hasCaption(),df.srcFile(),df.srcLine()); + visitChildren(df); + endDiaFile(df.hasCaption()); } -void LatexDocVisitor::visitPre(DocDiaFile *df) +void LatexDocVisitor::operator()(const DocLink &lnk) { if (m_hide) return; - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(LATEX_OUTPUT)+"/"+stripPath(df->file())); - startDiaFile(df->file(),df->width(),df->height(),df->hasCaption(),df->srcFile(),df->srcLine()); + startLink(lnk.ref(),lnk.file(),lnk.anchor()); + visitChildren(lnk); + endLink(lnk.ref(),lnk.file(),lnk.anchor()); } -void LatexDocVisitor::visitPost(DocDiaFile *df) -{ - if (m_hide) return; - endDiaFile(df->hasCaption()); -} -void LatexDocVisitor::visitPre(DocLink *lnk) +void LatexDocVisitor::operator()(const DocRef &ref) { if (m_hide) return; - startLink(lnk->ref(),lnk->file(),lnk->anchor()); -} - -void LatexDocVisitor::visitPost(DocLink *lnk) -{ - if (m_hide) return; - endLink(lnk->ref(),lnk->file(),lnk->anchor()); -} - -void LatexDocVisitor::visitPre(DocRef *ref) -{ - if (m_hide) return; - // when ref->isSubPage()==TRUE we use ref->file() for HTML and - // ref->anchor() for LaTeX/RTF - if (ref->isSubPage()) + // when ref.isSubPage()==TRUE we use ref.file() for HTML and + // ref.anchor() for LaTeX/RTF + if (ref.isSubPage()) { - startLink(ref->ref(),QCString(),ref->anchor()); + startLink(ref.ref(),QCString(),ref.anchor()); } else { - if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor(),ref->refToTable()); + if (!ref.file().isEmpty()) startLink(ref.ref(),ref.file(),ref.anchor(),ref.refToTable()); } - if (!ref->hasLinkText()) filter(ref->targetTitle()); -} - -void LatexDocVisitor::visitPost(DocRef *ref) -{ - if (m_hide) return; - if (ref->isSubPage()) + if (!ref.hasLinkText()) { - endLink(ref->ref(),QCString(),ref->anchor()); + filter(ref.targetTitle()); + } + visitChildren(ref); + if (ref.isSubPage()) + { + endLink(ref.ref(),QCString(),ref.anchor()); } else { - if (!ref->file().isEmpty()) endLink(ref->ref(),ref->file(),ref->anchor(),ref->refToTable()); + if (!ref.file().isEmpty()) endLink(ref.ref(),ref.file(),ref.anchor(),ref.refToTable()); } } -void LatexDocVisitor::visitPre(DocSecRefItem *ref) +void LatexDocVisitor::operator()(const DocSecRefItem &ref) { if (m_hide) return; m_t << "\\item \\contentsline{section}{"; - if (ref->isSubPage()) + if (ref.isSubPage()) { - startLink(ref->ref(),QCString(),ref->anchor()); + startLink(ref.ref(),QCString(),ref.anchor()); } else { - if (!ref->file().isEmpty()) + if (!ref.file().isEmpty()) { - startLink(ref->ref(),ref->file(),ref->anchor(),ref->refToTable()); + startLink(ref.ref(),ref.file(),ref.anchor(),ref.refToTable()); } } -} - -void LatexDocVisitor::visitPost(DocSecRefItem *ref) -{ - if (m_hide) return; - if (ref->isSubPage()) + visitChildren(ref); + if (ref.isSubPage()) { - endLink(ref->ref(),QCString(),ref->anchor()); + endLink(ref.ref(),QCString(),ref.anchor()); } else { - if (!ref->file().isEmpty()) endLink(ref->ref(),ref->file(),ref->anchor(),ref->refToTable()); + if (!ref.file().isEmpty()) endLink(ref.ref(),ref.file(),ref.anchor(),ref.refToTable()); } m_t << "}{\\ref{"; - if (!ref->file().isEmpty()) m_t << stripPath(ref->file()); - if (!ref->file().isEmpty() && !ref->anchor().isEmpty()) m_t << "_"; - if (!ref->anchor().isEmpty()) m_t << ref->anchor(); + if (!ref.file().isEmpty()) m_t << stripPath(ref.file()); + if (!ref.file().isEmpty() && !ref.anchor().isEmpty()) m_t << "_"; + if (!ref.anchor().isEmpty()) m_t << ref.anchor(); m_t << "}}{}\n"; } -void LatexDocVisitor::visitPre(DocSecRefList *) +void LatexDocVisitor::operator()(const DocSecRefList &l) { if (m_hide) return; m_t << "\\footnotesize\n"; m_t << "\\begin{multicols}{2}\n"; m_t << "\\begin{DoxyCompactList}\n"; incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocSecRefList *) -{ - if (m_hide) return; + visitChildren(l); decIndentLevel(); m_t << "\\end{DoxyCompactList}\n"; m_t << "\\end{multicols}\n"; m_t << "\\normalsize\n"; } -void LatexDocVisitor::visitPre(DocParamSect *s) +void LatexDocVisitor::operator()(const DocParamSect &s) { if (m_hide) return; - bool hasInOutSpecs = s->hasInOutSpecifier(); - bool hasTypeSpecs = s->hasTypeSpecifier(); + bool hasInOutSpecs = s.hasInOutSpecifier(); + bool hasTypeSpecs = s.hasTypeSpecifier(); m_ci.incUsedTableLevel(); - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: m_t << "\n\\begin{DoxyParams}"; @@ -1716,13 +1580,9 @@ void LatexDocVisitor::visitPre(DocParamSect *s) incIndentLevel(); } m_t << "}\n"; -} - -void LatexDocVisitor::visitPost(DocParamSect *s) -{ - if (m_hide) return; + visitChildren(s); m_ci.decUsedTableLevel(); - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: m_t << "\\end{DoxyParams}\n"; @@ -1742,15 +1602,19 @@ void LatexDocVisitor::visitPost(DocParamSect *s) } } -void LatexDocVisitor::visitPre(DocParamList *pl) +void LatexDocVisitor::operator()(const DocSeparator &sep) +{ + m_t << " " << sep.chars() << " "; +} + +void LatexDocVisitor::operator()(const DocParamList &pl) { if (m_hide) return; DocParamSect::Type parentType = DocParamSect::Unknown; - DocParamSect *sect = 0; - if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + const DocParamSect *sect = std::get_if<DocParamSect>(pl.parent()); + if (sect) { - parentType = ((DocParamSect*)pl->parent())->type(); - sect=(DocParamSect*)pl->parent(); + parentType = sect->type(); } bool useTable = parentType==DocParamSect::Param || parentType==DocParamSect::RetVal || @@ -1762,18 +1626,18 @@ void LatexDocVisitor::visitPre(DocParamList *pl) } if (sect && sect->hasInOutSpecifier()) { - if (pl->direction()!=DocParamSect::Unspecified) + if (pl.direction()!=DocParamSect::Unspecified) { m_t << "\\mbox{\\texttt{ "; - if (pl->direction()==DocParamSect::In) + if (pl.direction()==DocParamSect::In) { m_t << "in"; } - else if (pl->direction()==DocParamSect::Out) + else if (pl.direction()==DocParamSect::Out) { m_t << "out"; } - else if (pl->direction()==DocParamSect::InOut) + else if (pl.direction()==DocParamSect::InOut) { m_t << "in,out"; } @@ -1783,37 +1647,19 @@ void LatexDocVisitor::visitPre(DocParamList *pl) } if (sect && sect->hasTypeSpecifier()) { - for (const auto &type : pl->paramTypes()) + for (const auto &type : pl.paramTypes()) { - if (type->kind()==DocNode::Kind_Word) - { - visit((DocWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_Sep) - { - m_t << " " << ((DocSeparator *)type.get())->chars() << " "; - } + std::visit(*this,type); } if (useTable) m_t << " & "; } m_t << "{\\em "; bool first=TRUE; - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { if (!first) m_t << ","; else first=FALSE; m_insideItem=TRUE; - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } + std::visit(*this,param); m_insideItem=FALSE; } m_t << "}"; @@ -1825,20 +1671,10 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { m_t << "]"; } -} - -void LatexDocVisitor::visitPost(DocParamList *pl) -{ - if (m_hide) return; - DocParamSect::Type parentType = DocParamSect::Unknown; - if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + for (const auto &par : pl.paragraphs()) { - parentType = ((DocParamSect*)pl->parent())->type(); + std::visit(*this,par); } - bool useTable = parentType==DocParamSect::Param || - parentType==DocParamSect::RetVal || - parentType==DocParamSect::Exception || - parentType==DocParamSect::TemplateParam; if (useTable) { m_t << "\\\\\n" @@ -1846,95 +1682,71 @@ void LatexDocVisitor::visitPost(DocParamList *pl) } } -void LatexDocVisitor::visitPre(DocXRefItem *x) +void LatexDocVisitor::operator()(const DocXRefItem &x) { - static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); if (m_hide) return; - if (x->title().isEmpty()) return; + if (x.title().isEmpty()) return; incIndentLevel(); m_t << "\\begin{DoxyRefDesc}{"; - filter(x->title()); + filter(x.title()); m_t << "}\n"; - bool anonymousEnum = x->file()=="@"; + bool anonymousEnum = x.file()=="@"; m_t << "\\item["; if (pdfHyperlinks && !anonymousEnum) { - m_t << "\\mbox{\\hyperlink{" << stripPath(x->file()) << "_" << x->anchor() << "}{"; + m_t << "\\mbox{\\hyperlink{" << stripPath(x.file()) << "_" << x.anchor() << "}{"; } else { m_t << "\\textbf{ "; } m_insideItem=TRUE; - filter(x->title()); + filter(x.title()); m_insideItem=FALSE; if (pdfHyperlinks && !anonymousEnum) { m_t << "}"; } m_t << "}]"; -} - -void LatexDocVisitor::visitPost(DocXRefItem *x) -{ - if (m_hide) return; - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; decIndentLevel(); m_t << "\\end{DoxyRefDesc}\n"; } -void LatexDocVisitor::visitPre(DocInternalRef *ref) +void LatexDocVisitor::operator()(const DocInternalRef &ref) { if (m_hide) return; - startLink(QCString(),ref->file(),ref->anchor()); + startLink(QCString(),ref.file(),ref.anchor()); + visitChildren(ref); + endLink(QCString(),ref.file(),ref.anchor()); } -void LatexDocVisitor::visitPost(DocInternalRef *ref) +void LatexDocVisitor::operator()(const DocText &t) { if (m_hide) return; - endLink(QCString(),ref->file(),ref->anchor()); -} - -void LatexDocVisitor::visitPre(DocText *) -{ -} - -void LatexDocVisitor::visitPost(DocText *) -{ + visitChildren(t); } -void LatexDocVisitor::visitPre(DocHtmlBlockQuote *) +void LatexDocVisitor::operator()(const DocHtmlBlockQuote &q) { if (m_hide) return; m_t << "\\begin{quote}\n"; incIndentLevel(); -} - -void LatexDocVisitor::visitPost(DocHtmlBlockQuote *) -{ - if (m_hide) return; + visitChildren(q); m_t << "\\end{quote}\n"; decIndentLevel(); } -void LatexDocVisitor::visitPre(DocVhdlFlow *) -{ - if (m_hide) return; -} - -void LatexDocVisitor::visitPost(DocVhdlFlow *) -{ - if (m_hide) return; -} - -void LatexDocVisitor::visitPre(DocParBlock *) +void LatexDocVisitor::operator()(const DocVhdlFlow &) { - if (m_hide) return; } -void LatexDocVisitor::visitPost(DocParBlock *) +void LatexDocVisitor::operator()(const DocParBlock &pb) { if (m_hide) return; + visitChildren(pb); } void LatexDocVisitor::filter(const QCString &str, const bool retainNewLine) @@ -1951,7 +1763,7 @@ void LatexDocVisitor::filter(const QCString &str, const bool retainNewLine) void LatexDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor,bool refToTable) { - static bool pdfHyperLinks = Config_getBool(PDF_HYPERLINKS); + bool pdfHyperLinks = Config_getBool(PDF_HYPERLINKS); if (ref.isEmpty() && pdfHyperLinks) // internal PDF link { if (refToTable) @@ -1984,7 +1796,7 @@ void LatexDocVisitor::startLink(const QCString &ref,const QCString &file,const Q void LatexDocVisitor::endLink(const QCString &ref,const QCString &file,const QCString &anchor,bool refToTable) { m_t << "}"; - static bool pdfHyperLinks = Config_getBool(PDF_HYPERLINKS); + bool pdfHyperLinks = Config_getBool(PDF_HYPERLINKS); if (ref.isEmpty() && !pdfHyperLinks) { m_t << "{"; @@ -2065,7 +1877,7 @@ void LatexDocVisitor::endMscFile(bool hasCaption) } -void LatexDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s) +void LatexDocVisitor::writeMscFile(const QCString &baseName, const DocVerbatim &s) { QCString shortName = baseName; int i; @@ -2074,10 +1886,10 @@ void LatexDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s) shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(LATEX_OUTPUT); - writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_EPS,s->srcFile(),s->srcLine()); - visitPreStart(m_t, s->hasCaption(), shortName, s->width(),s->height()); - visitCaption(this, s->children()); - visitPostEnd(m_t, s->hasCaption()); + writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_EPS,s.srcFile(),s.srcLine()); + visitPreStart(m_t, s.hasCaption(), shortName, s.width(),s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } @@ -2113,7 +1925,7 @@ void LatexDocVisitor::endDiaFile(bool hasCaption) } -void LatexDocVisitor::writeDiaFile(const QCString &baseName, DocVerbatim *s) +void LatexDocVisitor::writeDiaFile(const QCString &baseName, const DocVerbatim &s) { QCString shortName = baseName; int i; @@ -2122,13 +1934,13 @@ void LatexDocVisitor::writeDiaFile(const QCString &baseName, DocVerbatim *s) shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(LATEX_OUTPUT); - writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_EPS,s->srcFile(),s->srcLine()); - visitPreStart(m_t, s->hasCaption(), shortName, s->width(), s->height()); - visitCaption(this, s->children()); - visitPostEnd(m_t, s->hasCaption()); + writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_EPS,s.srcFile(),s.srcLine()); + visitPreStart(m_t, s.hasCaption(), shortName, s.width(), s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } -void LatexDocVisitor::writePlantUMLFile(const QCString &baseName, DocVerbatim *s) +void LatexDocVisitor::writePlantUMLFile(const QCString &baseName, const DocVerbatim &s) { QCString shortName = baseName; int i; @@ -2136,16 +1948,16 @@ void LatexDocVisitor::writePlantUMLFile(const QCString &baseName, DocVerbatim *s { shortName=shortName.right(shortName.length()-i-1); } - if (s->useBitmap()) + if (s.useBitmap()) { if (shortName.find('.')==-1) shortName += ".png"; } QCString outDir = Config_getString(LATEX_OUTPUT); PlantumlManager::instance().generatePlantUMLOutput(baseName,outDir, - s->useBitmap() ? PlantumlManager::PUML_BITMAP : PlantumlManager::PUML_EPS); - visitPreStart(m_t, s->hasCaption(), shortName, s->width(), s->height()); - visitCaption(this, s->children()); - visitPostEnd(m_t, s->hasCaption()); + s.useBitmap() ? PlantumlManager::PUML_BITMAP : PlantumlManager::PUML_EPS); + visitPreStart(m_t, s.hasCaption(), shortName, s.width(), s.height()); + visitCaption(s.children()); + visitPostEnd(m_t, s.hasCaption()); } int LatexDocVisitor::indentLevel() const diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index 470aaf4..8ce8524 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -20,6 +20,7 @@ #include "qcstring.h" #include "docvisitor.h" +#include "docnode.h" class LatexCodeGenerator; class TextStream; @@ -36,115 +37,85 @@ class LatexDocVisitor : public DocVisitor // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *); - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *s); - void visitPost(DocSection *); - void visitPre(DocHtmlList *s); - void visitPost(DocHtmlList *s); - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - //void visitPre(DocHtmlPre *); - //void visitPost(DocHtmlPre *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *t); - void visitPost(DocHtmlTable *t); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *) ; - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *lnk); - void visitPost(DocLink *); - void visitPre(DocRef *ref); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &); + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &s); + void operator()(const DocHtmlList &s); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &t); + void operator()(const DocHtmlCaption &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &lnk); + void operator()(const DocRef &ref); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); private: + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } struct ActiveRowSpan { - ActiveRowSpan(DocHtmlCell *c,int rs,int cs,int col) + ActiveRowSpan(const DocHtmlCell &c,size_t rs,size_t cs,size_t col) : cell(c), rowSpan(rs), colSpan(cs), column(col) {} - DocHtmlCell *cell; - int rowSpan; - int colSpan; - int column; + const DocHtmlCell &cell; + size_t rowSpan; + size_t colSpan; + size_t column; }; typedef std::vector<ActiveRowSpan> RowSpanList; @@ -168,14 +139,15 @@ class LatexDocVisitor : public DocVisitor const QCString &height, bool hasCaption, const QCString &srcFile,int srcLine); void endMscFile(bool hasCaption); - void writeMscFile(const QCString &fileName, DocVerbatim *s); + void writeMscFile(const QCString &fileName, const DocVerbatim &s); void startDiaFile(const QCString &fileName,const QCString &width, const QCString &height, bool hasCaption, const QCString &srcFile,int srcLine); void endDiaFile(bool hasCaption); - void writeDiaFile(const QCString &fileName, DocVerbatim *s); - void writePlantUMLFile(const QCString &fileName, DocVerbatim *s); + void writeDiaFile(const QCString &fileName, const DocVerbatim &s); + void writePlantUMLFile(const QCString &fileName, const DocVerbatim &s); + void visitCaption(const DocNodeList &children); void incIndentLevel(); void decIndentLevel(); @@ -190,15 +162,14 @@ class LatexDocVisitor : public DocVisitor bool m_insidePre; bool m_insideItem; bool m_hide; - bool m_hideCaption; bool m_insideTabbing; QCString m_langExt; struct TableState { RowSpanList rowSpans; - int numCols = 0; - int currentColumn = 0; + size_t numCols = 0; + size_t currentColumn = 0; bool inRowSpan = false; bool inColSpan = false; bool firstRow = false; @@ -224,19 +195,19 @@ class LatexDocVisitor : public DocVisitor { m_tableStateStack.pop(); } - int currentColumn() const + size_t currentColumn() const { return !m_tableStateStack.empty() ? m_tableStateStack.top().currentColumn : 0; } - void setCurrentColumn(int col) + void setCurrentColumn(size_t col) { if (!m_tableStateStack.empty()) m_tableStateStack.top().currentColumn = col; } - int numCols() const + size_t numCols() const { return !m_tableStateStack.empty() ? m_tableStateStack.top().numCols : 0; } - void setNumCols(int num) + void setNumCols(size_t num) { if (!m_tableStateStack.empty()) m_tableStateStack.top().numCols = num; } diff --git a/src/latexgen.cpp b/src/latexgen.cpp index bc01e01..33087a0 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -32,6 +32,7 @@ #include "dotincldepgraph.h" #include "pagedef.h" #include "docparser.h" +#include "docnode.h" #include "latexdocvisitor.h" #include "dirdef.h" #include "cite.h" @@ -70,12 +71,12 @@ void LatexCodeGenerator::codify(const QCString &str) { if (!str.isEmpty()) { - const signed char *p=(const signed char*)str.data(); - signed char c; + const char *p=str.data(); + char c; //char cs[5]; int spacesToNextTabStop; int tabSize = Config_getInt(TAB_SIZE); - static THREAD_LOCAL signed char *result = NULL; + static THREAD_LOCAL char *result = NULL; static THREAD_LOCAL int lresult = 0; int i; while ((c=*p)) @@ -112,7 +113,7 @@ void LatexCodeGenerator::codify(const QCString &str) if (lresult < (i + bytes + 1)) \ { \ lresult += 512; \ - result = (signed char *)realloc(result, lresult); \ + result = static_cast<char *>(realloc(result, lresult)); \ } \ for (int j=0; j<bytes && *p; j++) \ { \ @@ -130,7 +131,7 @@ void LatexCodeGenerator::codify(const QCString &str) COPYCHAR(); } result[i]=0; // add terminator - filterLatexString(m_t,(const char *)result, + filterLatexString(m_t,result, false, // insideTabbing true, // insidePre false, // insideItem @@ -295,85 +296,90 @@ static void writeLatexMakefile() // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05 QCString latex_command = theTranslator->latexCommandName().quoted(); QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted(); + QCString bibtex_command = "bibtex"; + QCString manual_file = "refman"; + const int latex_count = 8; // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05 + t << "LATEX_CMD?=" << latex_command << "\n" + << "MKIDX_CMD?=" << mkidx_command << "\n" + << "BIBTEX_CMD?=" << bibtex_command << "\n" + << "LATEX_COUNT?=" << latex_count << "\n" + << "MANUAL_FILE?=" << manual_file << "\n" + << "\n"; if (!Config_getBool(USE_PDFLATEX)) // use plain old latex { - t << "LATEX_CMD=" << latex_command << "\n" - << "\n" - << "all: refman.dvi\n" + t << "all: $(MANUAL_FILE).dvi\n" << "\n" - << "ps: refman.ps\n" + << "ps: $(MANUAL_FILE).ps\n" << "\n" - << "pdf: refman.pdf\n" + << "pdf: $(MANUAL_FILE).pdf\n" << "\n" - << "ps_2on1: refman_2on1.ps\n" + << "ps_2on1: $(MANUAL_FILE).ps\n" << "\n" - << "pdf_2on1: refman_2on1.pdf\n" + << "pdf_2on1: $(MANUAL_FILE).pdf\n" << "\n" - << "refman.ps: refman.dvi\n" - << "\tdvips -o refman.ps refman.dvi\n" + << "$(MANUAL_FILE).ps: $(MANUAL_FILE).dvi\n" + << "\tdvips -o $(MANUAL_FILE).ps $(MANUAL_FILE).dvi\n" << "\n"; - t << "refman.pdf: refman.ps\n"; - t << "\tps2pdf refman.ps refman.pdf\n\n"; - t << "refman.dvi: clean refman.tex doxygen.sty\n" + t << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n"; + t << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n\n"; + t << "$(MANUAL_FILE).dvi: clean $(MANUAL_FILE).tex doxygen.sty\n" << "\techo \"Running latex...\"\n" - << "\t$(LATEX_CMD) refman.tex\n" + << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n" << "\techo \"Running makeindex...\"\n" - << "\t" << mkidx_command << " refman.idx\n"; + << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"; if (generateBib) { t << "\techo \"Running bibtex...\"\n"; - t << "\tbibtex refman\n"; + t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n"; t << "\techo \"Rerunning latex....\"\n"; - t << "\t$(LATEX_CMD) refman.tex\n"; + t << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n"; } t << "\techo \"Rerunning latex....\"\n" - << "\t$(LATEX_CMD) refman.tex\n" - << "\tlatex_count=8 ; \\\n" - << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\\n" + << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n" + << "\tlatex_count=%(LATEX_COUNT) ; \\\n" + << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n" << "\t do \\\n" << "\t echo \"Rerunning latex....\" ;\\\n" - << "\t $(LATEX_CMD) refman.tex ; \\\n" + << "\t $(LATEX_CMD) $(MANUAL_FILE).tex ; \\\n" << "\t latex_count=`expr $$latex_count - 1` ;\\\n" << "\t done\n" - << "\t" << mkidx_command << " refman.idx\n" - << "\t$(LATEX_CMD) refman.tex\n\n" - << "refman_2on1.ps: refman.ps\n" - << "\tpsnup -2 refman.ps >refman_2on1.ps\n" + << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n" + << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n\n" + << "$(MANUAL_FILE).ps: $(MANUAL_FILE).ps\n" + << "\tpsnup -2 $(MANUAL_FILE).ps >$(MANUAL_FILE).ps\n" << "\n" - << "refman_2on1.pdf: refman_2on1.ps\n" - << "\tps2pdf refman_2on1.ps refman_2on1.pdf\n"; + << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n" + << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n"; } else // use pdflatex for higher quality output { - t << "LATEX_CMD=" << latex_command << "\n" - << "\n"; - t << "all: refman.pdf\n\n" - << "pdf: refman.pdf\n\n"; - t << "refman.pdf: clean refman.tex\n"; - t << "\t$(LATEX_CMD) refman\n"; - t << "\t" << mkidx_command << " refman.idx\n"; + t << "all: $(MANUAL_FILE).pdf\n\n" + << "pdf: $(MANUAL_FILE).pdf\n\n"; + t << "$(MANUAL_FILE).pdf: clean $(MANUAL_FILE).tex\n"; + t << "\t$(LATEX_CMD) $(MANUAL_FILE)\n"; + t << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"; if (generateBib) { - t << "\tbibtex refman\n"; - t << "\t$(LATEX_CMD) refman\n"; + t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n"; + t << "\t$(LATEX_CMD) $(MANUAL_FILE)\n"; } - t << "\t$(LATEX_CMD) refman\n" - << "\tlatex_count=8 ; \\\n" - << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\\n" + t << "\t$(LATEX_CMD) $(MANUAL_FILE)\n" + << "\tlatex_count=$(LATEX_COUNT) ; \\\n" + << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n" << "\t do \\\n" << "\t echo \"Rerunning latex....\" ;\\\n" - << "\t $(LATEX_CMD) refman ;\\\n" + << "\t $(LATEX_CMD) $(MANUAL_FILE) ;\\\n" << "\t latex_count=`expr $$latex_count - 1` ;\\\n" << "\t done\n" - << "\t" << mkidx_command << " refman.idx\n" - << "\t$(LATEX_CMD) refman\n\n"; + << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n" + << "\t$(LATEX_CMD) $(MANUAL_FILE)\n\n"; } t << "\n" << "clean:\n" << "\trm -f " - << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n"; + << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl $(MANUAL_FILE).pdf\n"; } static void writeMakeBat() @@ -383,6 +389,9 @@ static void writeMakeBat() QCString fileName=dir+"/make.bat"; QCString latex_command = theTranslator->latexCommandName().quoted(); QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted(); + QCString bibtex_command = "bibtex"; + QCString manual_file = "refman"; + const int latex_count = 8; bool generateBib = !CitationManager::instance().isEmpty(); std::ofstream t(fileName.str(),std::ofstream::out | std::ofstream::binary); if (!t.is_open()) @@ -391,72 +400,97 @@ static void writeMakeBat() } t << "set Dir_Old=%cd%\r\n"; t << "cd /D %~dp0\r\n\r\n"; - t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\r\n\r\n"; + t << "\r\n"; + t << "set ORG_LATEX_CMD=%LATEX_CMD%\r\n"; + t << "set ORG_MKIDX_CMD=%MKIDX_CMD%\r\n"; + t << "set ORG_BIBTEX_CMD=%BIBTEX_CMD%\r\n"; + t << "set ORG_LATEX_COUNT=%LATEX_COUNT%\r\n"; + t << "set ORG_MANUAL_FILE=%MANUAL_FILE%\r\n"; + t << "if \"X\"%LATEX_CMD% == \"X\" set LATEX_CMD=" << latex_command << "\r\n"; + t << "if \"X\"%MKIDX_CMD% == \"X\" set MKIDX_CMD=" << mkidx_command << "\r\n"; + t << "if \"X\"%BIBTEX_CMD% == \"X\" set BIBTEX_CMD=" << bibtex_command << "\r\n"; + t << "if \"X\"%LATEX_COUNT% == \"X\" set LATEX_COUNT=" << latex_count << "\r\n"; + t << "if \"X\"%MANUAL_FILE% == \"X\" set MANUAL_FILE=" << manual_file << "\r\n"; + t << "\r\n"; + t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl %MANUAL_FILE%.pdf\r\n\r\n"; + t << "\r\n"; if (!Config_getBool(USE_PDFLATEX)) // use plain old latex { - t << "set LATEX_CMD=" << latex_command << "\r\n"; - t << "%LATEX_CMD% refman.tex\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n"; t << "echo ----\r\n"; - t << mkidx_command << " refman.idx\r\n"; + t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n"; if (generateBib) { - t << "bibtex refman\r\n"; + t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n"; t << "echo ----\r\n"; - t << "\t%LATEX_CMD% refman.tex\r\n"; + t << "\t%LATEX_CMD% %MANUAL_FILE%.tex\r\n"; } t << "setlocal enabledelayedexpansion\r\n"; - t << "set count=8\r\n"; + t << "set count=%LAT#EX_COUNT%\r\n"; t << ":repeat\r\n"; t << "set content=X\r\n"; - t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\r\n"; - t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\r\n"; + t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n"; + t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n"; + t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get bibliographical references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n"; t << "if !content! == X goto :skip\r\n"; t << "set /a count-=1\r\n"; t << "if !count! EQU 0 goto :skip\r\n\r\n"; t << "echo ----\r\n"; - t << "%LATEX_CMD% refman.tex\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n"; t << "goto :repeat\r\n"; t << ":skip\r\n"; t << "endlocal\r\n"; - t << mkidx_command << " refman.idx\r\n"; - t << "%LATEX_CMD% refman.tex\r\n"; - t << "dvips -o refman.ps refman.dvi\r\n"; + t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n"; + t << "dvips -o %MANUAL_FILE%.ps %MANUAL_FILE%.dvi\r\n"; t << Portable::ghostScriptCommand(); t << " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite " - "-sOutputFile=refman.pdf -c save pop -f refman.ps\r\n"; + "-sOutputFile=%MANUAL_FILE%.pdf -c save pop -f %MANUAL_FILE%.ps\r\n"; } else // use pdflatex { - t << "set LATEX_CMD=" << latex_command << "\r\n"; - t << "%LATEX_CMD% refman\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%\r\n"; t << "echo ----\r\n"; - t << mkidx_command << " refman.idx\r\n"; + t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n"; if (generateBib) { - t << "bibtex refman\r\n"; - t << "%LATEX_CMD% refman\r\n"; + t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%\r\n"; } t << "echo ----\r\n"; - t << "%LATEX_CMD% refman\r\n\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%\r\n\r\n"; t << "setlocal enabledelayedexpansion\r\n"; - t << "set count=8\r\n"; + t << "set count=%LATEX_COUNT%\r\n"; t << ":repeat\r\n"; t << "set content=X\r\n"; - t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\r\n"; - t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\r\n"; + t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n"; + t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n"; + t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get bibliographical references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n"; t << "if !content! == X goto :skip\r\n"; t << "set /a count-=1\r\n"; t << "if !count! EQU 0 goto :skip\r\n\r\n"; t << "echo ----\r\n"; - t << "%LATEX_CMD% refman\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%\r\n"; t << "goto :repeat\r\n"; t << ":skip\r\n"; t << "endlocal\r\n"; - t << mkidx_command << " refman.idx\r\n"; - t << "%LATEX_CMD% refman\r\n"; - t << "cd /D %Dir_Old%\r\n"; - t << "set Dir_Old=\r\n"; - } + t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n"; + t << "%LATEX_CMD% %MANUAL_FILE%\r\n"; + } + t<< "\r\n"; + t<< "@REM reset environment\r\n"; + t<< "cd /D %Dir_Old%\r\n"; + t<< "set Dir_Old=\r\n"; + t<< "set LATEX_CMD=%ORG_LATEX_CMD%\r\n"; + t<< "set ORG_LATEX_CMD=\r\n"; + t<< "set MKIDX_CMD=%ORG_MKIDX_CMD%\r\n"; + t<< "set ORG_MKIDX_CMD=\r\n"; + t<< "set BIBTEX_CMD=%ORG_BIBTEX_CMD%\r\n"; + t<< "set ORG_BIBTEX_CMD=\r\n"; + t<< "set MANUAL_FILE=%ORG_MANUAL_FILE%\r\n"; + t<< "set ORG_MANUAL_FILE=\r\n"; + t<< "set LATEX_COUNT=%ORG_LATEX_COUNT%\r\n"; + t<< "set ORG_LATEX_COUNT=\r\n"; #endif } @@ -650,11 +684,12 @@ static QCString substituteLatexKeywords(const QCString &str, QCString latexSpecialFormulaChars = tg2.str(); QCString formulaMacrofile = Config_getString(FORMULA_MACROFILE); + QCString stripMacroFile; if (!formulaMacrofile.isEmpty()) { FileInfo fi(formulaMacrofile.str()); formulaMacrofile=fi.absFilePath(); - QCString stripMacroFile = fi.fileName(); + stripMacroFile = fi.fileName(); copyFile(formulaMacrofile,Config_getString(LATEX_OUTPUT) + "/" + stripMacroFile); } @@ -680,7 +715,7 @@ static QCString substituteLatexKeywords(const QCString &str, result = substitute(result,"$makeindex",makeIndex()); result = substitute(result,"$extralatexpackages",extraLatexPackages); result = substitute(result,"$latexspecialformulachars",latexSpecialFormulaChars); - result = substitute(result,"$formulamacrofile",formulaMacrofile); + result = substitute(result,"$formulamacrofile",stripMacroFile); // additional LaTeX only conditional blocks result = selectBlock(result,"CITATIONS_PRESENT", !CitationManager::instance().isEmpty(),OutputGenerator::Latex); @@ -711,10 +746,6 @@ void LatexGenerator::startIndexSection(IndexSections is) if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter"; m_t << "{"; //Introduction}\n" break; - //case isPackageIndex: - // if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter"; - // m_t << "{"; //Package Index}\n" - // break; case isModuleIndex: if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter"; m_t << "{"; //Module Index}\n" @@ -1941,12 +1972,16 @@ void LatexGenerator::exceptionEntry(const QCString &prefix,bool closeBracket) m_t << " "; } -void LatexGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *,int) +void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int) { - LatexDocVisitor *visitor = - new LatexDocVisitor(m_t,m_codeGen,ctx?ctx->getDefFileExtension():QCString(""),m_insideTabbing); - n->accept(visitor); - delete visitor; + const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast); + if (astImpl) + { + LatexDocVisitor visitor(m_t,m_codeGen, + ctx?ctx->getDefFileExtension():QCString(""), + m_insideTabbing); + std::visit(visitor,astImpl->root); + } } void LatexGenerator::startConstraintList(const QCString &header) diff --git a/src/latexgen.h b/src/latexgen.h index 8c76098..436f5aa 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -50,8 +50,6 @@ class LatexCodeGenerator : public CodeOutputInterface void startFontClass(const QCString &) override; void endFontClass() override; void writeCodeAnchor(const QCString &) override {} - void setCurrentDoc(const Definition *,const QCString &,bool) override {} - void addWord(const QCString &,bool) override {} void startCodeFragment(const QCString &style) override; void endCodeFragment(const QCString &style) override; @@ -124,7 +122,7 @@ class LatexGenerator : public OutputGenerator // --------------------------- - void writeDoc(DocNode *,const Definition *ctx,const MemberDef *,int id); + void writeDoc(const IDocNodeAST *node,const Definition *ctx,const MemberDef *,int id); void startFile(const QCString &name,const QCString &manName,const QCString &title,int id); void writeSearchInfo() {} diff --git a/src/layout.cpp b/src/layout.cpp index f2a8e9d..ce7110b 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -76,7 +76,6 @@ inline QCString compileOptions(const QCString &def,SrcLangExt langId1,const QCSt "|"+QCString().setNum(langId5)+"="+value5; } - static bool elemIsVisible(const XMLHandlers::Attributes &attrib,bool defVal=TRUE) { QCString visible = XMLHandlers::value(attrib,"visible"); @@ -91,15 +90,24 @@ static bool elemIsVisible(const XMLHandlers::Attributes &attrib,bool defVal=TRUE } else if (opt && opt->type==ConfigValues::Info::String) { - return ConfigValues::instance().*(opt->value.s) != "NO"; + return opt->getBooleanRepresentation(); } else if (!opt) { - err("found unsupported value %s for visible attribute in layout file\n", - qPrint(visible)); + err("found unsupported value '%s' for visible attribute in layout file, reverting to '%s'\n", + qPrint(visible),(defVal?"yes":"no")); + return defVal; } } - return visible!="no" && visible!="0"; + QCString visibleLow = visible.lower(); + if (visibleLow=="no" || visibleLow=="false" || visibleLow=="0") return FALSE; + else if (visibleLow=="yes" || visibleLow=="true" || visibleLow=="1") return TRUE; + else + { + err("found unsupported value '%s' for visible attribute in layout file, reverting to '%s'\n", + qPrint(visible),(defVal?"yes":"no")); + return defVal; + } } static bool parentIsVisible(LayoutNavEntry *parent) @@ -187,10 +195,9 @@ class LayoutParser void startSimpleEntry(LayoutDocEntry::Kind k,const XMLHandlers::Attributes &attrib) { bool isVisible = elemIsVisible(attrib) && parentIsVisible(m_rootNav); - if (m_part!=-1 && isVisible) + if (m_part!=LayoutDocManager::Undefined && isVisible) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntrySimple(k)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntrySimple(k)); } } @@ -204,10 +211,9 @@ class LayoutParser //printf("startSectionEntry: title='%s' userTitle='%s'\n", // qPrint(title),qPrint(userTitle)); if (userTitle.isEmpty()) userTitle = title; - if (m_part!=-1 && isVisible) + if (m_part!=LayoutDocManager::Undefined && isVisible) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntrySection(k,userTitle)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntrySection(k,userTitle)); } } @@ -222,10 +228,9 @@ class LayoutParser if (userTitle.isEmpty()) userTitle = title; if (userSubscript.isEmpty()) userSubscript = subscript; //printf("memberdecl: %s\n",qPrint(userTitle)); - if (m_part!=-1 /*&& isVisible*/) + if (m_part!=LayoutDocManager::Undefined) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntryMemberDecl(type,userTitle,userSubscript)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntryMemberDecl(type,userTitle,userSubscript)); } } @@ -235,9 +240,9 @@ class LayoutParser QCString userTitle = XMLHandlers::value(attrib,"title"); if (userTitle.isEmpty()) userTitle = title; //printf("memberdef: %s\n",qPrint(userTitle)); - if (m_part!=-1 /*&& isVisible*/) + if (m_part!=LayoutDocManager::Undefined) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, + LayoutDocManager::instance().addEntry(m_part, new LayoutDocEntryMemberDef(type,userTitle)); } } @@ -270,13 +275,13 @@ class LayoutParser void startNavEntry(const XMLHandlers::Attributes &attrib) { - static bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); - static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); - static bool hasGraphicalHierarchy = Config_getBool(HAVE_DOT) && + bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + bool hasGraphicalHierarchy = Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY); - static bool extractAll = Config_getBool(EXTRACT_ALL); + bool extractAll = Config_getBool(EXTRACT_ALL); static struct NavEntryMap { const char *typeStr; // type attribute name in the XML file @@ -311,13 +316,13 @@ class LayoutParser { "namespaces", LayoutNavEntry::Namespaces, javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt || sliceOpt ? theTranslator->trModules() : theTranslator->trNamespaces(), - javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), + javaOpt || vhdlOpt ? theTranslator->trPackageList() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt || sliceOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll), "namespaces" }, { "namespacelist", LayoutNavEntry::NamespaceList, - javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), + javaOpt || vhdlOpt ? theTranslator->trPackageList() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), QCString(), javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt || sliceOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll), "namespaces" @@ -469,13 +474,6 @@ class LayoutParser theTranslator->trFileMembersDescription(extractAll), "globals" }, - //{ "dirs", - // LayoutNavEntry::Dirs, - // theTranslator->trDirectories(), - // QCString(), - // theTranslator->trDirDescription(), - // "dirs" - //}, { "examples", LayoutNavEntry::Examples, theTranslator->trExamples(), @@ -498,7 +496,7 @@ class LayoutParser "usergroup" }, { 0, // end of list - (LayoutNavEntry::Kind)0, + static_cast<LayoutNavEntry::Kind>(0), QCString(), QCString(), QCString(), @@ -587,87 +585,86 @@ class LayoutParser { LayoutDocManager::instance().clear(LayoutDocManager::Class); m_scope="class/"; - m_part = (int)LayoutDocManager::Class; + m_part = LayoutDocManager::Class; } void endClass() { m_scope=""; - m_part = -1; + m_part = LayoutDocManager::Undefined; } void startNamespace(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Namespace); m_scope="namespace/"; - m_part = (int)LayoutDocManager::Namespace; + m_part = LayoutDocManager::Namespace; } void endNamespace() { m_scope=""; - m_part = -1; + m_part = LayoutDocManager::Undefined; } void startConcept(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Concept); m_scope="concept/"; - m_part = (int)LayoutDocManager::Concept; + m_part = LayoutDocManager::Concept; } void endConcept() { m_scope=""; - m_part = -1; + m_part = LayoutDocManager::Undefined; } void startFile(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::File); m_scope="file/"; - m_part = (int)LayoutDocManager::File; + m_part = LayoutDocManager::File; } void endFile() { m_scope=""; - m_part = -1; + m_part = LayoutDocManager::Undefined; } void startGroup(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Group); m_scope="group/"; - m_part = (int)LayoutDocManager::Group; + m_part = LayoutDocManager::Group; } void endGroup() { m_scope=""; - m_part = -1; + m_part = LayoutDocManager::Undefined; } void startDirectory(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Directory); m_scope="directory/"; - m_part = (int)LayoutDocManager::Directory; + m_part = LayoutDocManager::Directory; } void endDirectory() { m_scope=""; - m_part = -1; + m_part = LayoutDocManager::Undefined; } void startMemberDef(const XMLHandlers::Attributes &) { m_scope+="memberdef/"; - if (m_part!=-1) + if (m_part!=LayoutDocManager::Undefined) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntrySimple(LayoutDocEntry::MemberDefStart)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntrySimple(LayoutDocEntry::MemberDefStart)); } } @@ -677,10 +674,9 @@ class LayoutParser if (i!=-1) { m_scope=m_scope.left(i); - if (m_part!=-1) + if (m_part!=LayoutDocManager::Undefined) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntrySimple(LayoutDocEntry::MemberDefEnd)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntrySimple(LayoutDocEntry::MemberDefEnd)); } } } @@ -688,10 +684,9 @@ class LayoutParser void startMemberDecl(const XMLHandlers::Attributes &) { m_scope+="memberdecl/"; - if (m_part!=-1) + if (m_part!=LayoutDocManager::Undefined) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclStart)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclStart)); } } @@ -701,10 +696,9 @@ class LayoutParser if (i!=-1) { m_scope=m_scope.left(i); - if (m_part!=-1) + if (m_part!=LayoutDocManager::Undefined) { - LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, - new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclEnd)); + LayoutDocManager::instance().addEntry(m_part,new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclEnd)); } } } @@ -715,7 +709,7 @@ class LayoutParser ~LayoutParser() { delete m_rootNav; } QCString m_scope; - int m_part = -1; + LayoutDocManager::LayoutPart m_part = LayoutDocManager::Undefined; LayoutNavEntry *m_rootNav = 0; bool m_invalidEntry = false; static int m_userGroupCount; @@ -904,11 +898,11 @@ static const std::map< std::string, ElementCallbacks > g_elementHandlers = endCb() } }, { "class/memberdecl/packagemethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacMethods, - []() { return compileOptions(theTranslator->trPackageMembers()); }), + []() { return compileOptions(theTranslator->trPackageFunctions()); }), endCb() } }, { "class/memberdecl/packagestaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacStaticMethods, - []() { return compileOptions(theTranslator->trStaticPackageMembers()); }), + []() { return compileOptions(theTranslator->trStaticPackageFunctions()); }), endCb() } }, { "class/memberdecl/packageattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacAttribs, @@ -1597,7 +1591,7 @@ LayoutDocManager & LayoutDocManager::instance() const LayoutDocEntryList &LayoutDocManager::docEntries(LayoutDocManager::LayoutPart part) const { - return d->docEntries[(int)part]; + return d->docEntries[static_cast<int>(part)]; } LayoutNavEntry* LayoutDocManager::rootNavEntry() const @@ -1607,12 +1601,12 @@ LayoutNavEntry* LayoutDocManager::rootNavEntry() const void LayoutDocManager::addEntry(LayoutDocManager::LayoutPart p,LayoutDocEntry *e) { - d->docEntries[(int)p].push_back(std::unique_ptr<LayoutDocEntry>(e)); + d->docEntries[static_cast<int>(p)].push_back(std::unique_ptr<LayoutDocEntry>(e)); } void LayoutDocManager::clear(LayoutDocManager::LayoutPart p) { - d->docEntries[(int)p].clear(); + d->docEntries[static_cast<int>(p)].clear(); } void LayoutDocManager::parse(const QCString &fileName) @@ -1664,8 +1658,8 @@ QCString extractLanguageSpecificTitle(const QCString &input,SrcLangExt lang) e=input.find('|',s); i=input.find('=',s); assert(i>s); - int key=input.mid(s,i-s).toInt(); - if (key==(int)lang) // found matching key + size_t key=input.mid(s,i-s).toUInt(); + if (key==lang) // found matching key { if (e==-1) e=input.length(); return input.mid(i+1,e-i-1); diff --git a/src/layout.h b/src/layout.h index 9b76287..390d393 100644 --- a/src/layout.h +++ b/src/layout.h @@ -30,7 +30,7 @@ class MemberList; /** @brief Base class representing a piece of a documentation page */ struct LayoutDocEntry { - virtual ~LayoutDocEntry() {} + virtual ~LayoutDocEntry() = default; enum Kind { // Generic items for all pages MemberGroups, @@ -200,6 +200,7 @@ class LayoutDocManager public: enum LayoutPart { + Undefined = -1, Class, Concept, Namespace, File, Group, Directory, NrParts }; diff --git a/src/linkedmap.h b/src/linkedmap.h index db3f7b1..26311e9 100644 --- a/src/linkedmap.h +++ b/src/linkedmap.h @@ -87,7 +87,7 @@ class LinkedMap //! Return a non-owning pointer to the newly added object, or to the existing object if //! it was already inserted before under the given key. template<class...Args> - T *add(const char *k, Args&&... args) + [[maybe_unused]] T *add(const char *k, Args&&... args) { T *result = find(k); if (result==nullptr) @@ -102,7 +102,7 @@ class LinkedMap } template<class...Args> - T *add(const QCString &k, Args&&... args) + [[maybe_unused]] T *add(const QCString &k, Args&&... args) { std::string key = k.str(); T *result = find(key); @@ -120,7 +120,7 @@ class LinkedMap //! added under the same key). Ownership is transferred. //! Return a non-owning pointer to the newly added object, or to the existing object if //! it was already inserted before under the given key. - T *add(const char *k, Ptr &&ptr) + [[maybe_unused]] T *add(const char *k, Ptr &&ptr) { T *result = find(k); if (result==nullptr) @@ -133,7 +133,7 @@ class LinkedMap return result; } - T *add(const QCString &k, Ptr &&ptr) + [[maybe_unused]] T *add(const QCString &k, Ptr &&ptr) { std::string key = k.str(); T *result = find(key); diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index bb1169a..3995007 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -32,7 +32,7 @@ ManListItemInfo man_listItemInfo[man_maxIndentLevels]; ManDocVisitor::ManDocVisitor(TextStream &t,CodeOutputInterface &ci, const QCString &langExt) - : DocVisitor(DocVisitor_Man), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(FALSE), + : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(FALSE), m_indent(0), m_langExt(langExt) { } @@ -41,29 +41,29 @@ ManDocVisitor::ManDocVisitor(TextStream &t,CodeOutputInterface &ci, // visitor functions for leaf nodes //-------------------------------------- -void ManDocVisitor::visit(DocWord *w) +void ManDocVisitor::operator()(const DocWord &w) { if (m_hide) return; - filter(w->word()); + filter(w.word()); m_firstCol=FALSE; } -void ManDocVisitor::visit(DocLinkedWord *w) +void ManDocVisitor::operator()(const DocLinkedWord &w) { if (m_hide) return; m_t << "\\fB"; - filter(w->word()); + filter(w.word()); m_t << "\\fP"; m_firstCol=FALSE; } -void ManDocVisitor::visit(DocWhiteSpace *w) +void ManDocVisitor::operator()(const DocWhiteSpace &w) { if (m_hide) return; if (m_insidePre) { - m_t << w->chars(); - m_firstCol=w->chars().at(w->chars().length()-1)=='\n'; + m_t << w.chars(); + m_firstCol=w.chars().at(w.chars().length()-1)=='\n'; } else { @@ -72,10 +72,10 @@ void ManDocVisitor::visit(DocWhiteSpace *w) } } -void ManDocVisitor::visit(DocSymbol *s) +void ManDocVisitor::operator()(const DocSymbol &s) { if (m_hide) return; - const char *res = HtmlEntityMapper::instance()->man(s->symbol()); + const char *res = HtmlEntityMapper::instance()->man(s.symbol()); if (res) { m_t << res; @@ -88,36 +88,36 @@ void ManDocVisitor::visit(DocSymbol *s) m_firstCol=FALSE; } -void ManDocVisitor::visit(DocEmoji *s) +void ManDocVisitor::operator()(const DocEmoji &s) { if (m_hide) return; - const char *res = EmojiEntityMapper::instance()->name(s->index()); + const char *res = EmojiEntityMapper::instance()->name(s.index()); if (res) { m_t << res; } else { - m_t << s->name(); + m_t << s.name(); } m_firstCol=FALSE; } -void ManDocVisitor::visit(DocURL *u) +void ManDocVisitor::operator()(const DocURL &u) { if (m_hide) return; - m_t << u->url(); + m_t << u.url(); m_firstCol=FALSE; } -void ManDocVisitor::visit(DocLineBreak *) +void ManDocVisitor::operator()(const DocLineBreak &) { if (m_hide) return; m_t << "\n.br\n"; m_firstCol=TRUE; } -void ManDocVisitor::visit(DocHorRuler *) +void ManDocVisitor::operator()(const DocHorRuler &) { if (m_hide) return; if (!m_firstCol) m_t << "\n"; @@ -125,13 +125,13 @@ void ManDocVisitor::visit(DocHorRuler *) m_firstCol=TRUE; } -void ManDocVisitor::visit(DocStyleChange *s) +void ManDocVisitor::operator()(const DocStyleChange &s) { if (m_hide) return; - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) m_t << "\\fB"; else m_t << "\\fP"; + if (s.enable()) m_t << "\\fB"; else m_t << "\\fP"; m_firstCol=FALSE; break; case DocStyleChange::S: @@ -141,23 +141,23 @@ void ManDocVisitor::visit(DocStyleChange *s) break; case DocStyleChange::Underline: //underline is shown as emphasis case DocStyleChange::Ins: - if (s->enable()) m_t << "\\fI"; else m_t << "\\fP"; + if (s.enable()) m_t << "\\fI"; else m_t << "\\fP"; m_firstCol=FALSE; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "\\fI"; else m_t << "\\fP"; + if (s.enable()) m_t << "\\fI"; else m_t << "\\fP"; m_firstCol=FALSE; break; case DocStyleChange::Code: - if (s->enable()) m_t << "\\fC"; else m_t << "\\fP"; + if (s.enable()) m_t << "\\fC"; else m_t << "\\fP"; m_firstCol=FALSE; break; case DocStyleChange::Subscript: - if (s->enable()) m_t << "\\*<"; else m_t << "\\*> "; + if (s.enable()) m_t << "\\*<"; else m_t << "\\*> "; m_firstCol=FALSE; break; case DocStyleChange::Superscript: - if (s->enable()) m_t << "\\*{"; else m_t << "\\*} "; + if (s.enable()) m_t << "\\*{"; else m_t << "\\*} "; m_firstCol=FALSE; break; case DocStyleChange::Center: @@ -170,7 +170,7 @@ void ManDocVisitor::visit(DocStyleChange *s) /* not supported */ break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s.enable()) { if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; @@ -189,7 +189,7 @@ void ManDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; case DocStyleChange::Details: /* emulation of the <details> tag */ - if (!s->enable()) + if (!s.enable()) { if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; @@ -197,55 +197,55 @@ void ManDocVisitor::visit(DocStyleChange *s) } break; case DocStyleChange::Summary: /* emulation of the <summary> tag inside a <details> tag */ - if (s->enable()) m_t << "\\fB"; else m_t << "\\fP"; + if (s.enable()) m_t << "\\fB"; else m_t << "\\fP"; m_firstCol=FALSE; break; } } -void ManDocVisitor::visit(DocVerbatim *s) +void ManDocVisitor::operator()(const DocVerbatim &s) { if (m_hide) return; QCString lang = m_langExt; - if (!s->language().isEmpty()) // explicit language setting + if (!s.language().isEmpty()) // explicit language setting { - lang = s->language(); + lang = s.language(); } SrcLangExt langExt = getLanguageFromCodeLang(lang); - switch (s->type()) + switch (s.type()) { case DocVerbatim::Code: if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - getCodeParser(lang).parseCode(m_ci,s->context(),s->text(), + getCodeParser(lang).parseCode(m_ci,s.context(),s.text(), langExt, - s->isExample(),s->exampleFile()); + s.isExample(),s.exampleFile()); if (!m_firstCol) m_t << "\n"; m_t << ".fi\n"; m_t << ".PP\n"; m_firstCol=TRUE; break; case DocVerbatim::JavaDocLiteral: - filter(s->text()); + filter(s.text()); break; case DocVerbatim::JavaDocCode: m_t << "\\fC\n"; - filter(s->text()); + filter(s.text()); m_t << "\\fP\n"; break; case DocVerbatim::Verbatim: if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - filter(s->text()); + filter(s.text()); if (!m_firstCol) m_t << "\n"; m_t << ".fi\n"; m_t << ".PP\n"; m_firstCol=TRUE; break; case DocVerbatim::ManOnly: - m_t << s->text(); + m_t << s.text(); break; case DocVerbatim::HtmlOnly: case DocVerbatim::XmlOnly: @@ -260,29 +260,29 @@ void ManDocVisitor::visit(DocVerbatim *s) } } -void ManDocVisitor::visit(DocAnchor *) +void ManDocVisitor::operator()(const DocAnchor &) { /* no support for anchors in man pages */ } -void ManDocVisitor::visit(DocInclude *inc) +void ManDocVisitor::operator()(const DocInclude &inc) { if (m_hide) return; - SrcLangExt langExt = getLanguageFromFileName(inc->extension()); - switch(inc->type()) + SrcLangExt langExt = getLanguageFromFileName(inc.extension()); + switch(inc.type()) { case DocInclude::IncWithLines: { if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, // fileDef, -1, // start line -1, // end line @@ -301,11 +301,11 @@ void ManDocVisitor::visit(DocInclude *inc) if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), 0, // fileDef -1, // startLine -1, // endLine @@ -327,13 +327,13 @@ void ManDocVisitor::visit(DocInclude *inc) case DocInclude::DocbookInclude: break; case DocInclude::ManInclude: - m_t << inc->text(); + m_t << inc.text(); break; case DocInclude::VerbInclude: if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - m_t << inc->text(); + m_t << inc.text(); if (!m_firstCol) m_t << "\n"; m_t << ".fi\n"; m_t << ".PP\n"; @@ -343,12 +343,12 @@ void ManDocVisitor::visit(DocInclude *inc) if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile() + inc.isExample(), + inc.exampleFile() ); if (!m_firstCol) m_t << "\n"; m_t << ".fi\n"; @@ -360,16 +360,16 @@ void ManDocVisitor::visit(DocInclude *inc) if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_t << ".nf\n"; - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, - lineBlock(inc->text(),inc->blockId()), + lineBlock(inc.text(),inc.blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef @@ -390,14 +390,14 @@ void ManDocVisitor::visit(DocInclude *inc) } } -void ManDocVisitor::visit(DocIncOperator *op) +void ManDocVisitor::operator()(const DocIncOperator &op) { - QCString locLangExt = getFileNameExtension(op->includeFileName()); + QCString locLangExt = getFileNameExtension(op.includeFileName()); if (locLangExt.isEmpty()) locLangExt = m_langExt; SrcLangExt langExt = getLanguageFromFileName(locLangExt); //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", - // op->type(),op->isFirst(),op->isLast(),qPrint(op->text())); - if (op->isFirst()) + // op.type(),op.isFirst(),op.isLast(),qPrint(op.text())); + if (op.isFirst()) { if (!m_hide) { @@ -408,33 +408,33 @@ void ManDocVisitor::visit(DocIncOperator *op) pushHidden(m_hide); m_hide = TRUE; } - if (op->type()!=DocIncOperator::Skip) + if (op.type()!=DocIncOperator::Skip) { m_hide = popHidden(); if (!m_hide) { FileDef *fd = 0; - if (!op->includeFileName().isEmpty()) + if (!op.includeFileName().isEmpty()) { - FileInfo cfi( op->includeFileName().str() ); + FileInfo cfi( op.includeFileName().str() ); fd = createFileDef( cfi.dirPath(), cfi.fileName() ); } - getCodeParser(locLangExt).parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile(), + getCodeParser(locLangExt).parseCode(m_ci,op.context(),op.text(),langExt, + op.isExample(),op.exampleFile(), fd, // fileDef - op->line(), // startLine + op.line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - op->showLineNo() // show line numbers + op.showLineNo() // show line numbers ); if (fd) delete fd; } pushHidden(m_hide); m_hide=TRUE; } - if (op->isLast()) + if (op.isLast()) { m_hide = popHidden(); if (!m_hide) @@ -451,58 +451,61 @@ void ManDocVisitor::visit(DocIncOperator *op) } } -void ManDocVisitor::visit(DocFormula *f) +void ManDocVisitor::operator()(const DocFormula &f) { if (m_hide) return; - m_t << f->text(); + m_t << f.text(); } -void ManDocVisitor::visit(DocIndexEntry *) +void ManDocVisitor::operator()(const DocIndexEntry &) { } -void ManDocVisitor::visit(DocSimpleSectSep *) +void ManDocVisitor::operator()(const DocSimpleSectSep &) { } -void ManDocVisitor::visit(DocCite *cite) +void ManDocVisitor::operator()(const DocCite &cite) { if (m_hide) return; m_t << "\\fB"; - if (cite->file().isEmpty()) m_t << "["; - filter(cite->text()); - if (cite->file().isEmpty()) m_t << "]"; + if (cite.file().isEmpty()) m_t << "["; + filter(cite.text()); + if (cite.file().isEmpty()) m_t << "]"; m_t << "\\fP"; } +void ManDocVisitor::operator()(const DocSeparator &s) +{ + if (m_hide) return; + m_t << s.chars(); +} + //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- -void ManDocVisitor::visitPre(DocAutoList *) +void ManDocVisitor::operator()(const DocAutoList &l) { if (m_hide) return; m_indent+=2; -} - -void ManDocVisitor::visitPost(DocAutoList *) -{ - if (m_hide) return; + visitChildren(l); m_indent-=2; m_t << ".PP\n"; } -void ManDocVisitor::visitPre(DocAutoListItem *li) +void ManDocVisitor::operator()(const DocAutoListItem &li) { if (m_hide) return; QCString ws; ws.fill(' ',m_indent-2); if (!m_firstCol) m_t << "\n"; m_t << ".IP \"" << ws; - if (((DocAutoList *)li->parent())->isEnumList()) + const DocAutoList *list = std::get_if<DocAutoList>(li.parent()); + if (list && list->isEnumList()) { - m_t << li->itemNumber() << ".\" " << m_indent+2; + m_t << li.itemNumber() << ".\" " << m_indent+2; } else // bullet list { @@ -510,25 +513,18 @@ void ManDocVisitor::visitPre(DocAutoListItem *li) } m_t << "\n"; m_firstCol=TRUE; -} - -void ManDocVisitor::visitPost(DocAutoListItem *) -{ - if (m_hide) return; + visitChildren(li); m_t << "\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocPara *) -{ -} - -void ManDocVisitor::visitPost(DocPara *p) +void ManDocVisitor::operator()(const DocPara &p) { if (m_hide) return; - if (!p->isLast() && // omit <p> for last paragraph - !(p->parent() && // and for parameter sections - p->parent()->kind()==DocNode::Kind_ParamSect + visitChildren(p); + if (!p.isLast() && // omit <p> for last paragraph + !(p.parent() && // and for parameter sections + std::get_if<DocParamSect>(p.parent()) ) ) { @@ -538,15 +534,12 @@ void ManDocVisitor::visitPost(DocPara *p) } } -void ManDocVisitor::visitPre(DocRoot *) +void ManDocVisitor::operator()(const DocRoot &r) { + visitChildren(r); } -void ManDocVisitor::visitPost(DocRoot *) -{ -} - -void ManDocVisitor::visitPre(DocSimpleSect *s) +void ManDocVisitor::operator()(const DocSimpleSect &s) { if (m_hide) return; if (!m_firstCol) @@ -555,7 +548,7 @@ void ManDocVisitor::visitPre(DocSimpleSect *s) m_t << ".PP\n"; } m_t << "\\fB"; - switch(s->type()) + switch(s.type()) { case DocSimpleSect::See: m_t << theTranslator->trSeeAlso(); break; @@ -593,49 +586,37 @@ void ManDocVisitor::visitPre(DocSimpleSect *s) } // special case 1: user defined title - if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) + if (s.title()) { - m_t << "\\fP\n"; - m_t << ".RS 4\n"; + std::visit(*this,*s.title()); } -} - -void ManDocVisitor::visitPost(DocSimpleSect *) -{ - if (m_hide) return; + m_t << "\\fP\n"; + m_t << ".RS 4\n"; + visitChildren(s); if (!m_firstCol) m_t << "\n"; m_t << ".RE\n"; m_t << ".PP\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocTitle *) -{ -} - -void ManDocVisitor::visitPost(DocTitle *) +void ManDocVisitor::operator()(const DocTitle &t) { if (m_hide) return; - m_t << "\\fP\n"; - m_t << ".RS 4\n"; + visitChildren(t); } -void ManDocVisitor::visitPre(DocSimpleList *) +void ManDocVisitor::operator()(const DocSimpleList &l) { if (m_hide) return; m_indent+=2; if (!m_firstCol) m_t << "\n"; m_t << ".PD 0\n"; -} - -void ManDocVisitor::visitPost(DocSimpleList *) -{ - if (m_hide) return; + visitChildren(l); m_indent-=2; m_t << ".PP\n"; } -void ManDocVisitor::visitPre(DocSimpleListItem *) +void ManDocVisitor::operator()(const DocSimpleListItem &li) { if (m_hide) return; QCString ws; @@ -643,32 +624,28 @@ void ManDocVisitor::visitPre(DocSimpleListItem *) if (!m_firstCol) m_t << "\n"; m_t << ".IP \"" << ws << "\\(bu\" " << m_indent << "\n"; m_firstCol=TRUE; -} - -void ManDocVisitor::visitPost(DocSimpleListItem *) -{ - if (m_hide) return; + if (li.paragraph()) + { + visit(*this,*li.paragraph()); + } m_t << "\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocSection *s) +void ManDocVisitor::operator()(const DocSection &s) { if (m_hide) return; if (!m_firstCol) m_t << "\n"; - if (s->level()==1) m_t << ".SH"; else m_t << ".SS"; + if (s.level()==1) m_t << ".SH"; else m_t << ".SS"; m_t << " \""; - filter(s->title()); + filter(s.title()); m_t << "\"\n"; - if (s->level()==1) m_t << ".PP\n"; + if (s.level()==1) m_t << ".PP\n"; m_firstCol=TRUE; + visitChildren(s); } -void ManDocVisitor::visitPost(DocSection *) -{ -} - -void ManDocVisitor::visitPre(DocHtmlList *l) +void ManDocVisitor::operator()(const DocHtmlList &l) { if (m_hide) return; m_indent+=2; @@ -676,7 +653,7 @@ void ManDocVisitor::visitPre(DocHtmlList *l) m_t << ".PD 0\n"; man_listItemInfo[m_indent].number = 1; man_listItemInfo[m_indent].type = '1'; - for (const auto &opt : l->attribs()) + for (const auto &opt : l.attribs()) { if (opt.name=="type") { @@ -689,26 +666,23 @@ void ManDocVisitor::visitPre(DocHtmlList *l) if (ok) man_listItemInfo[m_indent].number = val; } } -} - -void ManDocVisitor::visitPost(DocHtmlList *) -{ - if (m_hide) return; + visitChildren(l); m_indent-=2; if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; } -void ManDocVisitor::visitPre(DocHtmlListItem *li) +void ManDocVisitor::operator()(const DocHtmlListItem &li) { if (m_hide) return; QCString ws; ws.fill(' ',m_indent-2); if (!m_firstCol) m_t << "\n"; m_t << ".IP \"" << ws; - if (((DocHtmlList *)li->parent())->type()==DocHtmlList::Ordered) + const DocHtmlList *list = std::get_if<DocHtmlList>(li.parent()); + if (list && list->type()==DocHtmlList::Ordered) { - for (const auto &opt : li->attribs()) + for (const auto &opt : li.attribs()) { if (opt.name=="value") { @@ -747,202 +721,115 @@ void ManDocVisitor::visitPre(DocHtmlListItem *li) } m_t << "\n"; m_firstCol=TRUE; -} - -void ManDocVisitor::visitPost(DocHtmlListItem *) -{ - if (m_hide) return; + visitChildren(li); m_t << "\n"; m_firstCol=TRUE; } -//void ManDocVisitor::visitPre(DocHtmlPre *) -//{ -// if (!m_firstCol) m_t << "\n"; -// m_t << ".PP\n"; -// m_t << ".nf\n"; -// m_insidePre=TRUE; -//} -// -//void ManDocVisitor::visitPost(DocHtmlPre *) -//{ -// m_insidePre=FALSE; -// if (!m_firstCol) m_t << "\n"; -// m_t << ".fi\n"; -// m_t << ".PP\n"; -// m_firstCol=TRUE; -//} - -void ManDocVisitor::visitPre(DocHtmlDescList *) -{ -} - -void ManDocVisitor::visitPost(DocHtmlDescList *) +void ManDocVisitor::operator()(const DocHtmlDescList &dl) { if (m_hide) return; + visitChildren(dl); if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocHtmlDescTitle *) +void ManDocVisitor::operator()(const DocHtmlDescTitle &dt) { if (m_hide) return; if (!m_firstCol) m_t << "\n"; m_t << ".IP \"\\fB"; m_firstCol=FALSE; -} - -void ManDocVisitor::visitPost(DocHtmlDescTitle *) -{ - if (m_hide) return; + visitChildren(dt); m_t << "\\fP\" 1c\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocHtmlDescData *) -{ -} - -void ManDocVisitor::visitPost(DocHtmlDescData *) -{ -} - -void ManDocVisitor::visitPre(DocHtmlTable *) -{ -} - -void ManDocVisitor::visitPost(DocHtmlTable *) -{ -} - -void ManDocVisitor::visitPre(DocHtmlCaption *) -{ -} - -void ManDocVisitor::visitPost(DocHtmlCaption *) -{ -} - -void ManDocVisitor::visitPre(DocHtmlRow *) +void ManDocVisitor::operator()(const DocHtmlDescData &dd) { + visitChildren(dd); } -void ManDocVisitor::visitPost(DocHtmlRow *) +void ManDocVisitor::operator()(const DocHtmlTable &t) { + visitChildren(t); } -void ManDocVisitor::visitPre(DocHtmlCell *) +void ManDocVisitor::operator()(const DocHtmlCaption &c) { + visitChildren(c); } -void ManDocVisitor::visitPost(DocHtmlCell *) +void ManDocVisitor::operator()(const DocHtmlRow &r) { + visitChildren(r); } -void ManDocVisitor::visitPre(DocInternal *) +void ManDocVisitor::operator()(const DocHtmlCell &c) { - if (m_hide) return; - //if (!m_firstCol) m_t << "\n"; - //m_t << ".PP\n"; - //m_t << "\\fB" << theTranslator->trForInternalUseOnly() << "\\fP\n"; - //m_t << ".RS 4\n"; + visitChildren(c); } -void ManDocVisitor::visitPost(DocInternal *) +void ManDocVisitor::operator()(const DocInternal &i) { - if (m_hide) return; - //if (!m_firstCol) m_t << "\n"; - //m_t << ".RE\n"; - //m_t << ".PP\n"; - //m_firstCol=TRUE; + visitChildren(i); } -void ManDocVisitor::visitPre(DocHRef *) +void ManDocVisitor::operator()(const DocHRef &href) { if (m_hide) return; m_t << "\\fC"; -} - -void ManDocVisitor::visitPost(DocHRef *) -{ - if (m_hide) return; + visitChildren(href); m_t << "\\fP"; } -void ManDocVisitor::visitPre(DocHtmlHeader *header) +void ManDocVisitor::operator()(const DocHtmlHeader &header) { if (m_hide) return; if (!m_firstCol) m_t << "\n"; - if (header->level()==1) m_t << ".SH"; else m_t << ".SS"; + if (header.level()==1) m_t << ".SH"; else m_t << ".SS"; m_t << " \""; -} - -void ManDocVisitor::visitPost(DocHtmlHeader *header) -{ - if (m_hide) return; + visitChildren(header); m_t << "\"\n"; - if (header->level()==1) m_t << ".PP\n"; + if (header.level()==1) m_t << ".PP\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocImage *) +void ManDocVisitor::operator()(const DocImage &) { } -void ManDocVisitor::visitPost(DocImage *) -{ -} - -void ManDocVisitor::visitPre(DocDotFile *) -{ -} - -void ManDocVisitor::visitPost(DocDotFile *) -{ -} -void ManDocVisitor::visitPre(DocMscFile *) +void ManDocVisitor::operator()(const DocDotFile &f) { } -void ManDocVisitor::visitPost(DocMscFile *) +void ManDocVisitor::operator()(const DocMscFile &) { } -void ManDocVisitor::visitPre(DocDiaFile *) +void ManDocVisitor::operator()(const DocDiaFile &) { } -void ManDocVisitor::visitPost(DocDiaFile *) -{ -} - -void ManDocVisitor::visitPre(DocLink *) +void ManDocVisitor::operator()(const DocLink &dl) { if (m_hide) return; m_t << "\\fB"; -} - -void ManDocVisitor::visitPost(DocLink *) -{ - if (m_hide) return; + visitChildren(dl); m_t << "\\fP"; } -void ManDocVisitor::visitPre(DocRef *ref) +void ManDocVisitor::operator()(const DocRef &ref) { if (m_hide) return; m_t << "\\fB"; - if (!ref->hasLinkText()) filter(ref->targetTitle()); -} - -void ManDocVisitor::visitPost(DocRef *) -{ - if (m_hide) return; + if (!ref.hasLinkText()) filter(ref.targetTitle()); + visitChildren(ref); m_t << "\\fP"; } -void ManDocVisitor::visitPre(DocSecRefItem *) +void ManDocVisitor::operator()(const DocSecRefItem &ref) { if (m_hide) return; QCString ws; @@ -950,30 +837,22 @@ void ManDocVisitor::visitPre(DocSecRefItem *) if (!m_firstCol) m_t << "\n"; m_t << ".IP \"" << ws << "\\(bu\" " << m_indent << "\n"; m_firstCol=TRUE; -} - -void ManDocVisitor::visitPost(DocSecRefItem *) -{ - if (m_hide) return; + visitChildren(ref); m_t << "\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocSecRefList *) +void ManDocVisitor::operator()(const DocSecRefList &l) { if (m_hide) return; m_indent+=2; -} - -void ManDocVisitor::visitPost(DocSecRefList *) -{ - if (m_hide) return; + visitChildren(l); m_indent-=2; if (!m_firstCol) m_t << "\n"; m_t << ".PP\n"; } -void ManDocVisitor::visitPre(DocParamSect *s) +void ManDocVisitor::operator()(const DocParamSect &s) { if (m_hide) return; if (!m_firstCol) @@ -982,7 +861,7 @@ void ManDocVisitor::visitPre(DocParamSect *s) m_t << ".PP\n"; } m_t << "\\fB"; - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: m_t << theTranslator->trParameters(); break; @@ -997,93 +876,70 @@ void ManDocVisitor::visitPre(DocParamSect *s) } m_t << "\\fP\n"; m_t << ".RS 4\n"; -} - -void ManDocVisitor::visitPost(DocParamSect *) -{ - if (m_hide) return; + visitChildren(s); if (!m_firstCol) m_t << "\n"; m_t << ".RE\n"; m_t << ".PP\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocParamList *pl) +void ManDocVisitor::operator()(const DocParamList &pl) { if (m_hide) return; m_t << "\\fI"; bool first=TRUE; - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { if (!first) m_t << ","; else first=FALSE; - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } + std::visit(*this,param); } m_t << "\\fP "; -} - -void ManDocVisitor::visitPost(DocParamList *pl) -{ - if (m_hide) return; - if (!pl->isLast()) + for (const auto &par : pl.paragraphs()) + { + std::visit(*this,par); + } + if (!pl.isLast()) { if (!m_firstCol) m_t << "\n"; m_t << ".br\n"; } } -void ManDocVisitor::visitPre(DocXRefItem *x) +void ManDocVisitor::operator()(const DocXRefItem &x) { if (m_hide) return; - if (x->title().isEmpty()) return; + if (x.title().isEmpty()) return; if (!m_firstCol) { m_t << "\n"; m_t << ".PP\n"; } m_t << "\\fB"; - filter(x->title()); + filter(x.title()); m_t << "\\fP\n"; m_t << ".RS 4\n"; -} - -void ManDocVisitor::visitPost(DocXRefItem *x) -{ - if (m_hide) return; - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; if (!m_firstCol) m_t << "\n"; m_t << ".RE\n"; m_t << ".PP\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocInternalRef *) +void ManDocVisitor::operator()(const DocInternalRef &ref) { if (m_hide) return; m_t << "\\fB"; -} - -void ManDocVisitor::visitPost(DocInternalRef *) -{ - if (m_hide) return; + visitChildren(ref); m_t << "\\fP"; } -void ManDocVisitor::visitPre(DocText *) +void ManDocVisitor::operator()(const DocText &t) { + visitChildren(t); } -void ManDocVisitor::visitPost(DocText *) -{ -} - -void ManDocVisitor::visitPre(DocHtmlBlockQuote *) +void ManDocVisitor::operator()(const DocHtmlBlockQuote &q) { if (m_hide) return; if (!m_firstCol) @@ -1092,34 +948,22 @@ void ManDocVisitor::visitPre(DocHtmlBlockQuote *) m_t << ".PP\n"; } m_t << ".RS 4\n"; // TODO: add support for nested block quotes -} - -void ManDocVisitor::visitPost(DocHtmlBlockQuote *) -{ - if (m_hide) return; + visitChildren(q); if (!m_firstCol) m_t << "\n"; m_t << ".RE\n"; m_t << ".PP\n"; m_firstCol=TRUE; } -void ManDocVisitor::visitPre(DocVhdlFlow *) -{ -} - -void ManDocVisitor::visitPost(DocVhdlFlow *) +void ManDocVisitor::operator()(const DocVhdlFlow &) { } -void ManDocVisitor::visitPre(DocParBlock *) +void ManDocVisitor::operator()(const DocParBlock &pb) { + visitChildren(pb); } -void ManDocVisitor::visitPost(DocParBlock *) -{ -} - - void ManDocVisitor::filter(const QCString &str) { if (!str.isEmpty()) diff --git a/src/mandocvisitor.h b/src/mandocvisitor.h index a97e556..96910bd 100644 --- a/src/mandocvisitor.h +++ b/src/mandocvisitor.h @@ -23,6 +23,7 @@ #include "qcstring.h" #include "docvisitor.h" +#include "docnode.h" class CodeOutputInterface; class TextStream; @@ -37,108 +38,76 @@ class ManDocVisitor : public DocVisitor // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *); - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *s); - void visitPost(DocSection *); - void visitPre(DocHtmlList *s); - void visitPost(DocHtmlList *s); - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - //void visitPre(DocHtmlPre *); - //void visitPost(DocHtmlPre *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *t); - void visitPost(DocHtmlTable *t); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *) ; - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *lnk); - void visitPost(DocLink *); - void visitPre(DocRef *ref); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - //void visitPre(DocLanguage *); - //void visitPost(DocLanguage *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &); + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &s); + void operator()(const DocHtmlList &s); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &t); + void operator()(const DocHtmlCaption &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &lnk); + void operator()(const DocRef &ref); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); private: + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } //-------------------------------------- // helper functions diff --git a/src/mangen.cpp b/src/mangen.cpp index 256dd67..27484ce 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -690,11 +690,14 @@ void ManGenerator::endParamList() { } -void ManGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *,int) +void ManGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int) { - ManDocVisitor *visitor = new ManDocVisitor(m_t,*this,ctx?ctx->getDefFileExtension():QCString("")); - n->accept(visitor); - delete visitor; + const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST *>(ast); + if (astImpl) + { + auto visitor { ManDocVisitor(m_t,*this,ctx?ctx->getDefFileExtension():QCString("")) }; + std::visit(visitor,astImpl->root); + } m_firstCol=FALSE; m_paragraph = FALSE; } diff --git a/src/mangen.h b/src/mangen.h index 30c3f39..3401038 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -32,7 +32,7 @@ class ManGenerator : public OutputGenerator OutputType type() const { return Man; } - void writeDoc(DocNode *,const Definition *,const MemberDef *,int); + void writeDoc(const IDocNodeAST *ast,const Definition *,const MemberDef *,int); static void init(); void cleanup(); @@ -253,8 +253,6 @@ class ManGenerator : public OutputGenerator void endLabels(); void writeCodeAnchor(const QCString &) {} - void setCurrentDoc(const Definition *,const QCString &,bool) {} - void addWord(const QCString &,bool) {} private: bool m_firstCol = true; diff --git a/src/markdown.cpp b/src/markdown.cpp index c8e6723..350863b 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -105,7 +105,7 @@ class Trace } } data_s[j++]=0; - fprintf(IOSTREAM,"> %s data=[%s…]\n",qPrint(func),data_s); + fprintf(IOSTREAM,"> %s data=[%s...]\n",qPrint(func),data_s); s_indent++; } } @@ -187,7 +187,7 @@ int Trace::s_indent = 0; ((data[i]>='a' && data[i]<='z') || \ (data[i]>='A' && data[i]<='Z') || \ (data[i]>='0' && data[i]<='9') || \ - (((unsigned char)data[i])>=0x80)) // unicode characters + (static_cast<unsigned char>(data[i])>=0x80)) // unicode characters #define extraChar(i) \ (data[i]=='-' || data[i]=='+' || data[i]=='!' || \ @@ -220,17 +220,17 @@ Markdown::Markdown(const QCString &fileName,int lineNr,int indentLevel) { using namespace std::placeholders; // setup callback table for special characters - m_actions[(unsigned int)'_'] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3); - m_actions[(unsigned int)'*'] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3); - m_actions[(unsigned int)'~'] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3); - m_actions[(unsigned int)'`'] = std::bind(&Markdown::processCodeSpan, this,_1,_2,_3); - m_actions[(unsigned int)'\\']= std::bind(&Markdown::processSpecialCommand,this,_1,_2,_3); - m_actions[(unsigned int)'@'] = std::bind(&Markdown::processSpecialCommand,this,_1,_2,_3); - m_actions[(unsigned int)'['] = std::bind(&Markdown::processLink, this,_1,_2,_3); - m_actions[(unsigned int)'!'] = std::bind(&Markdown::processLink, this,_1,_2,_3); - m_actions[(unsigned int)'<'] = std::bind(&Markdown::processHtmlTag, this,_1,_2,_3); - m_actions[(unsigned int)'-'] = std::bind(&Markdown::processNmdash, this,_1,_2,_3); - m_actions[(unsigned int)'"'] = std::bind(&Markdown::processQuoted, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('_')] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('*')] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('~')] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('`')] = std::bind(&Markdown::processCodeSpan, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('\\')]= std::bind(&Markdown::processSpecialCommand,this,_1,_2,_3); + m_actions[static_cast<unsigned int>('@')] = std::bind(&Markdown::processSpecialCommand,this,_1,_2,_3); + m_actions[static_cast<unsigned int>('[')] = std::bind(&Markdown::processLink, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('!')] = std::bind(&Markdown::processLink, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('<')] = std::bind(&Markdown::processHtmlTag, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('-')] = std::bind(&Markdown::processNmdash, this,_1,_2,_3); + m_actions[static_cast<unsigned int>('"')] = std::bind(&Markdown::processQuoted, this,_1,_2,_3); (void)m_lineNr; // not used yet } @@ -239,8 +239,8 @@ enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight }; //---------- constants ------- // -const uchar g_utf8_nbsp[3] = { 0xc2, 0xa0, 0}; // UTF-8 nbsp -const char *g_doxy_nsbp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp +const char *g_utf8_nbsp = "\xc2\xa0"; // UTF-8 nbsp +const char *g_doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp const int codeBlockIndent = 4; //---------- helpers ------- @@ -324,7 +324,7 @@ static void convertStringFragment(QCString &result,const char *data,int size) { TRACE(result); if (size<0) size=0; - result = QCString(data,(uint)size); + result = QCString(data,static_cast<size_t>(size)); TRACE_RESULT(result); } @@ -492,7 +492,7 @@ int Markdown::isSpecialCommand(const char *data,int offset,int size) // skip over spaces while (offset_<size_ && data_[offset_]==' ') offset_++; // skip over label - while (offset_<size_ && (c=data_[offset_])!=' ' && c!='\n') offset_++; + while (offset_<size_ && (c=data_[offset_])!=' ' && c!='\\' && c!='@' && c!='\n') offset_++; return offset_; } return 0; @@ -517,16 +517,22 @@ int Markdown::isSpecialCommand(const char *data,int offset,int size) return endOfLabel(data_,offset_,size_); }; - static const auto endOfFunc = [](const char *data_,int offset_,int size_) -> int + static const auto endOfFuncLike = [](const char *data_,int offset_,int size_,bool allowSpaces) -> int { if (offset_<size_ && data_[offset_]==' ') // we expect a space before the name { char c=0; offset_++; // skip over spaces - while (offset_<size_ && data_[offset_]==' ') offset_++; - // skip over name - while (offset_<size_ && (c=data_[offset_])!=' ' && c!='\n' && c!='(') offset_++; + while (offset_<size_ && data_[offset_]==' ') + { + offset_++; + } + // skip over name (and optionally type) + while (offset_<size_ && (c=data_[offset_])!='\n' && (allowSpaces || c!=' ') && c!='(') + { + offset_++; + } if (c=='(') // find the end of the function { int count=1; @@ -543,9 +549,14 @@ int Markdown::isSpecialCommand(const char *data,int offset,int size) return 0; }; + static const auto endOfFunc = [](const char *data_,int offset_,int size_) -> int + { + return endOfFuncLike(data_,offset_,size_,true); + }; + static const auto endOfGuard = [](const char *data_,int offset_,int size_) -> int { - return endOfFunc(data_,offset_,size_); + return endOfFuncLike(data_,offset_,size_,false); }; static const std::unordered_map<std::string,EndCmdFunc> cmdNames = @@ -609,7 +620,7 @@ int Markdown::isSpecialCommand(const char *data,int offset,int size) { "property", endOfLine }, { "protocol", endOfLine }, { "ref", endOfLabel }, - { "refitem", endOfLabel }, + { "refitem", endOfLine }, { "related", endOfLabel }, { "relatedalso", endOfLabel }, { "relates", endOfLabel }, @@ -1402,7 +1413,6 @@ int Markdown::processLink(const char *data,int offset,int size) return 0; } nlTotal += nl; - nl = 0; // search for optional image attributes QCString attributes; @@ -1441,7 +1451,6 @@ int Markdown::processLink(const char *data,int offset,int size) i++; } nlTotal += nl; - nl = 0; if (i>=size) return 0; // premature end of comment -> no attributes int attributesEnd=i; convertStringFragment(attributes,data+attributesStart,attributesEnd-attributesStart); @@ -1489,6 +1498,7 @@ int Markdown::processLink(const char *data,int offset,int size) writeMarkdownImage("latex", isImageInline, explicitTitle, title, content, link, attributes, fd); writeMarkdownImage("rtf", isImageInline, explicitTitle, title, content, link, attributes, fd); writeMarkdownImage("docbook", isImageInline, explicitTitle, title, content, link, attributes, fd); + writeMarkdownImage("xml", isImageInline, explicitTitle, title, content, link, attributes, fd); } else { @@ -1526,7 +1536,7 @@ int Markdown::processLink(const char *data,int offset,int size) else if (!(forg.exists() && forg.isReadable())) { FileInfo fi(m_fileName.str()); - QCString mdFile = m_fileName.left(m_fileName.length()-(uint)fi.fileName().length()) + link; + QCString mdFile = m_fileName.left(m_fileName.length()-fi.fileName().length()) + link; FileInfo fmd(mdFile.str()); if (fmd.exists() && fmd.isReadable()) { @@ -1671,13 +1681,13 @@ int Markdown::processCodeSpan(const char *data, int /*offset*/, int size) void Markdown::addStrEscapeUtf8Nbsp(const char *s,int len) { TRACE(s); - if (Portable::strnstr(s,g_doxy_nsbp,len)==0) // no escape needed -> fast + if (Portable::strnstr(s,g_doxy_nbsp,len)==0) // no escape needed -> fast { m_out.addStr(s,len); } else // escape needed -> slow { - m_out.addStr(substitute(QCString(s).left(len),g_doxy_nsbp,(const char *)g_utf8_nbsp)); + m_out.addStr(substitute(QCString(s).left(len),g_doxy_nbsp,g_utf8_nbsp)); } } @@ -1746,7 +1756,7 @@ void Markdown::processInline(const char *data,int size) while (i<size) { // skip over character that do not trigger a specific action - while (end<size && ((action=m_actions[(uchar)data[end]])==0)) end++; + while (end<size && ((action=m_actions[static_cast<uchar>(data[end])])==0)) end++; // and add them to the output m_out.addStr(data+i,end-i); if (end>=size) break; @@ -1964,7 +1974,7 @@ static QCString extractTitleId(QCString &title, int level) if (reg::search(ti,match,r2)) { std::string id = match[1].str(); - title = title.left((int)match.position()); + title = title.left(match.position()); //printf("found match id='%s' title=%s\n",id.c_str(),qPrint(title)); TRACE_RESULT(QCString(id)); return QCString(id); @@ -2958,7 +2968,38 @@ QCString Markdown::processQuotations(const QCString &s,int refIndent) { if (isFencedCodeBlock(data+pi,size-pi,currentIndent,lang,blockStart,blockEnd,blockOffset)) { - writeFencedCodeBlock(data+pi,lang.data(),blockStart,blockEnd); + auto addSpecialCommand = [&](const QCString &startCmd,const QCString &endCmd) + { + int cmdPos = pi+blockStart+1; + QCString pl = QCString(data+cmdPos).left(blockEnd-blockStart-1); + uint ii = 0; + // check for absence of start command, either @start<cmd>, or \\start<cmd> + while (ii<pl.length() && qisspace(pl[ii])) ii++; // skip leading whitespace + if (ii+startCmd.length()>=pl.length() || // no room for start command + (pl[ii]!='\\' && pl[ii]!='@') || // no @ or \ after whitespace + qstrncmp(pl.data()+ii+1,startCmd.data(),startCmd.length())!=0) // no start command + { + pl = "@"+startCmd+"\\ilinebr " + pl + " @"+endCmd; + } + processSpecialCommand(pl.data(),0,pl.length()); + }; + + if (!Config_getString(PLANTUML_JAR_PATH).isEmpty() && lang=="plantuml") + { + addSpecialCommand("startuml","enduml"); + } + else if (Config_getBool(HAVE_DOT) && lang=="dot") + { + addSpecialCommand("dot","enddot"); + } + else if (lang=="msc") // msc is built-in + { + addSpecialCommand("msc","endmsc"); + } + else // normal code block + { + writeFencedCodeBlock(data+pi,lang.data(),blockStart,blockEnd); + } i=pi+blockOffset; pi=-1; end=i+1; @@ -3007,7 +3048,6 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) int size = s.length(); int i=0,end=0,pi=-1,ref,level; QCString id,link,title; - int blockIndent = indent; // get indent for the first line end = i+1; @@ -3052,7 +3092,6 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) { //printf("** end of list\n"); currentIndent = indent; - blockIndent = indent; insideList = false; } newBlock = false; @@ -3065,7 +3104,6 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) //printf("** start of list\n"); insideList = true; currentIndent = listIndent; - blockIndent = listIndent; } } else if (isEndOfList(data+i,end-i)) @@ -3073,7 +3111,6 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) //printf("** end of list\n"); insideList = false; currentIndent = listIndent; - blockIndent = listIndent; } else if (isEmptyLine(data+i,end-i)) { @@ -3089,7 +3126,7 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) { int blockStart,blockEnd,blockOffset; QCString lang; - blockIndent = currentIndent; + int blockIndent = currentIndent; //printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level); QCString endBlockName; if (data[i]=='@' || data[i]=='\\') endBlockName = isBlockCommand(data+i,i,size-i); @@ -3116,7 +3153,6 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) { m_out.addChar(data[i]); m_out.addStr(endBlockName); - pi=i; i+=l+1; break; } @@ -3165,7 +3201,6 @@ QCString Markdown::processBlocks(const QCString &s,const int indent) // qPrint(id),qPrint(link),qPrint(title)); m_linkRefs.insert({id.lower().str(),LinkRef(link,title)}); i=ref+pi; - pi=-1; end=i+1; } else if (isFencedCodeBlock(data+pi,size-pi,currentIndent,lang,blockStart,blockEnd,blockOffset)) @@ -3319,7 +3354,7 @@ QCString Markdown::detab(const QCString &s,int &refIndent) int minIndent=maxIndent; while (i<size) { - signed char c = (signed char)data[i++]; + char c = data[i++]; switch(c) { case '\t': // expand tab @@ -3345,7 +3380,7 @@ QCString Markdown::detab(const QCString &s,int &refIndent) int nb = isUTF8NonBreakableSpace(data); if (nb>0) { - m_out.addStr(g_doxy_nsbp); + m_out.addStr(g_doxy_nbsp); i+=nb-1; } else @@ -3408,7 +3443,7 @@ QCString Markdown::process(const QCString &input, int &startNewlines, bool fromP } // post processing - QCString result = substitute(m_out.get(),g_doxy_nsbp," "); + QCString result = substitute(m_out.get(),g_doxy_nbsp," "); const char *p = result.data(); if (p) { @@ -3514,21 +3549,18 @@ void MarkdownOutlineParser::parseInput(const QCString &fileName, break; case ExplicitPageResult::explicitPage: { - // look for `@page label Title\n` and capture `label` - static const reg::Ex re(R"([\\@]page\s+(\a[\w-]*)\s*[^\n]*\n)"); + // look for `@page label My Title\n` and capture `label` (match[1]) and ` My Title` (match[2]) + static const reg::Ex re(R"([\\@]page\s+(\a[\w-]*)(\s*[^\n]*)\n)"); reg::Match match; std::string s = docs.str(); if (reg::search(s,match,re)) { QCString orgLabel = match[1].str(); QCString newLabel = markdownFileNameToId(fileName); - size_t labelStartPos = match[1].position(); - size_t labelEndPos = labelStartPos+match[1].length(); - size_t lineLen = match.length(); - docs = docs.left(labelStartPos)+ // part before label + docs = docs.left(match[1].position())+ // part before label newLabel+ // new label - docs.mid(labelEndPos,lineLen-labelEndPos-1)+ // part between orgLabel and \n - "\\ilinebr @anchor "+orgLabel+"\n"+ // add original anchor + match[2].str()+ // part between orgLabel and \n + "\\ilinebr @anchor "+orgLabel+"\n"+ // add original anchor plus \n of above docs.right(docs.length()-match.length()); // add remainder of docs } } diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 6dd51ea..9e116b9 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -213,7 +213,6 @@ class MemberDefImpl : public DefinitionMixin<MemberDefMutable> virtual MemberDef *fromAnonymousMember() const; virtual bool hasCallGraph() const; virtual bool hasCallerGraph() const; - virtual bool visibleMemberGroup(bool hideNoHeader) const; virtual bool hasReferencesRelation() const; virtual bool hasReferencedByRelation() const; virtual const MemberDef *templateMaster() const; @@ -698,8 +697,6 @@ class MemberDefAliasImpl : public DefinitionAliasMixin<MemberDef> { return getMdAlias()->hasCallGraph(); } virtual bool hasCallerGraph() const { return getMdAlias()->hasCallerGraph(); } - virtual bool visibleMemberGroup(bool hideNoHeader) const - { return getMdAlias()->visibleMemberGroup(hideNoHeader); } virtual bool hasReferencesRelation() const { return getMdAlias()->hasReferencesRelation(); } virtual bool hasReferencedByRelation() const @@ -1519,8 +1516,8 @@ bool MemberDefImpl::hasExamples() const QCString MemberDefImpl::getOutputFileBase() const { - static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); - static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); + bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); QCString baseName; //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n", @@ -1640,8 +1637,8 @@ QCString MemberDefImpl::anchor() const void MemberDefImpl::_computeLinkableInProject() { - static bool extractStatic = Config_getBool(EXTRACT_STATIC); - static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); + bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); m_isLinkableCached = 2; // linkable //printf("MemberDefImpl::isLinkableInProject(name=%s)\n",qPrint(name())); if (isHidden()) @@ -1744,7 +1741,7 @@ bool MemberDefImpl::isLinkableInProject() const { if (m_isLinkableCached==0) { - MemberDefImpl *that = (MemberDefImpl*)this; + MemberDefImpl *that = const_cast<MemberDefImpl*>(this); that->_computeLinkableInProject(); } ASSERT(m_isLinkableCached>0); @@ -1774,7 +1771,7 @@ void MemberDefImpl::writeLink(OutputList &ol, bool onlyText) const { SrcLangExt lang = getLanguage(); - static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); + bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); QCString sep = getLanguageSpecificSeparator(lang,TRUE); QCString n = name(); const ClassDef *classDef = getClassDef(); @@ -1883,12 +1880,12 @@ ClassDef *MemberDefImpl::getClassDefOfAnonymousType() const */ bool MemberDefImpl::isBriefSectionVisible() const { - static bool extractStatic = Config_getBool(EXTRACT_STATIC); - static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); - static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); - static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); + bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); //printf("Member %s grpId=%d docs=%s file=%s args=%s\n", // qPrint(name()), @@ -2161,8 +2158,8 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, bool endAnonScopeNeeded=FALSE; if (reg::search(stype,match,r)) // member has an anonymous type { - int i = (int)match.position(); - int l = (int)match.length(); + int i = static_cast<int>(match.position()); + int l = static_cast<int>(match.length()); //printf("annoClassDef=%p annMemb=%p scopeName='%s' anonymous='%s'\n", // annoClassDef,annMemb,qPrint(cname),qPrint(ltype.mid(i,l))); @@ -2266,9 +2263,9 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, // *** write name if (!isAnonymous()) // hide anonymous stuff { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); + bool extractStatic = Config_getBool(EXTRACT_STATIC); MemberDefMutable *annMemb = toMemberDefMutable(m_impl->annMemb); //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",qPrint(name()),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation()); if (!name().isEmpty() && // name valid @@ -2454,23 +2451,34 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, Config_getBool(BRIEF_MEMBER_DESC) ) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc(*parser.get(), - briefFile(),briefLine(), - getOuterScope()?getOuterScope():d, - this,briefDescription(),TRUE,FALSE, - QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - - if (rootNode && !rootNode->isEmpty()) + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + briefFile(),briefLine(), + getOuterScope()?getOuterScope():d, + this,briefDescription(),TRUE,FALSE, + QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + if (!ast->isEmpty()) { ol.startMemberDescription(anchor(),inheritId); - ol.writeDoc(rootNode.get(),getOuterScope()?getOuterScope():d,this); + ol.writeDoc(ast.get(),getOuterScope()?getOuterScope():d,this); if (detailsVisible) // add More.. link only when both brief and details are visible { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.docify(" "); - ol.startTextLink(getOutputFileBase(),anchor()); + MemberDefMutable *annMemb = NULL; + if (!isAnonymous()) // hide anonymous stuff + { + annMemb = toMemberDefMutable(m_impl->annMemb); + } + if (annMemb) + { + ol.startTextLink(annMemb->getOutputFileBase(),annMemb->anchor()); + } + else + { + ol.startTextLink(getOutputFileBase(),anchor()); + } ol.parseText(theTranslator->trMore()); ol.endTextLink(); ol.popGeneratorState(); @@ -2496,14 +2504,14 @@ bool MemberDefImpl::hasDetailedDescription() const //printf(">hasDetailedDescription(cached=%d)\n",m_impl->hasDetailedDescriptionCached); if (!m_impl->hasDetailedDescriptionCached) { - static bool extractAll = Config_getBool(EXTRACT_ALL); - static bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC); - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); - static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); - static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); - static bool inlineSources = Config_getBool(INLINE_SOURCES); + bool extractAll = Config_getBool(EXTRACT_ALL); + bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); + bool inlineSources = Config_getBool(INLINE_SOURCES); // the member has detailed documentation because the user added some comments bool docFilter = @@ -2597,9 +2605,9 @@ bool MemberDefImpl::hasDetailedDescription() const bool MemberDefImpl::isDetailedSectionVisible(MemberListContainer container) const { - static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES); - static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES); + bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); bool groupFilter = getGroupDef()==0 || container==MemberListContainer::Group || separateMemPages; bool fileFilter = getNamespaceDef()==0 || !getNamespaceDef()->isLinkable() || container!=MemberListContainer::File; bool simpleFilter = (hasBriefDescription() || !hideUndocMembers) && inlineSimpleStructs && @@ -2616,7 +2624,7 @@ bool MemberDefImpl::isDetailedSectionVisible(MemberListContainer container) cons StringVector MemberDefImpl::getLabels(const Definition *container) const { StringVector sl; - static bool inlineInfo = Config_getBool(INLINE_INFO); + bool inlineInfo = Config_getBool(INLINE_INFO); Specifier lvirt=virtualness(); if ((!isObjCMethod() || isOptional() || isRequired()) && @@ -2636,7 +2644,7 @@ StringVector MemberDefImpl::getLabels(const Definition *container) const //ol.docify(" ["); SrcLangExt lang = getLanguage(); bool optVhdl = lang==SrcLangExt_VHDL; - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); if (optVhdl) { sl.push_back(theTranslator->trVhdlType(getMemberSpecifiers(),TRUE).str()); @@ -2911,11 +2919,11 @@ void MemberDefImpl::_writeReimplementedBy(OutputList &ol) const QCString reimplInLine; if (m_impl->virt==Pure || (getClassDef() && getClassDef()->compoundType()==ClassDef::Interface)) { - reimplInLine = theTranslator->trImplementedInList((int)count); + reimplInLine = theTranslator->trImplementedInList(static_cast<int>(count)); } else { - reimplInLine = theTranslator->trReimplementedInList((int)count); + reimplInLine = theTranslator->trReimplementedInList(static_cast<int>(count)); } // write the list of classes that overwrite this member @@ -3134,7 +3142,7 @@ QCString MemberDefImpl::displayDefinition() const //printf("start >%s<\n",qPrint(ldef)); int i=l-1; while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--; - while (i>=0 && isspace((uchar)ldef.at(i))) i--; + while (i>=0 && isspace(static_cast<uchar>(ldef.at(i)))) i--; if (i>0) { // insert braches around the type @@ -3153,7 +3161,7 @@ void MemberDefImpl::_writeGroupInclude(OutputList &ol,bool inGroup) const { // only write out the include file if this is not part of a class or file // definition - static bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC); + bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC); const FileDef *fd = getFileDef(); QCString nm; if (fd) nm = getFileDef()->docName(); @@ -3464,7 +3472,7 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml, //printf("start >%s<\n",qPrint(ldef)); int i=dl-1; while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--; - while (i>=0 && isspace((uchar)ldef.at(i))) i--; + while (i>=0 && isspace(static_cast<uchar>(ldef.at(i)))) i--; if (i>0) { // insert braches around the type @@ -3875,7 +3883,7 @@ void MemberDefImpl::warnIfUndocumented() const t="group", d=gd; else t="file", d=fd; - static bool extractAll = Config_getBool(EXTRACT_ALL); + bool extractAll = Config_getBool(EXTRACT_ALL); //printf("%s:warnIfUndoc: hasUserDocs=%d isFriendClass=%d protection=%d isRef=%d isDel=%d\n", // qPrint(name()), @@ -3920,23 +3928,15 @@ static QCString stripTrailingReturn(const QCString &trailRet) return trailRet; } +static std::mutex g_detectUndocumentedParamsMutex; + void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const { - QCString returnType = typeString(); - bool isPython = getLanguage()==SrcLangExt_Python; - bool isFortran = getLanguage()==SrcLangExt_Fortran; - bool isFortranSubroutine = isFortran && returnType.find("subroutine")!=-1; + // this function is called while parsing the documentation. A member can have multiple + // documentation blocks, which could be handled by multiple threads, hence this guard. + std::lock_guard<std::mutex> lock(g_detectUndocumentedParamsMutex); - bool isVoidReturn = (returnType=="void") || (returnType.right(5)==" void"); - if (!isVoidReturn && returnType == "auto") - { - const ArgumentList &defArgList=isDocsForDefinition() ? argumentList() : declArgumentList(); - if (!defArgList.trailingReturnType().isEmpty()) - { - QCString strippedTrailingReturn = stripTrailingReturn(defArgList.trailingReturnType()); - isVoidReturn = (strippedTrailingReturn=="void") || (strippedTrailingReturn.right(5)==" void"); - } - } + bool isPython = getLanguage()==SrcLangExt_Python; if (!m_impl->hasDocumentedParams && hasParamCommand) { @@ -3995,34 +3995,24 @@ void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturn { m_impl->hasDocumentedReturnType = TRUE; } - else if ( // see if return type is documented in a function w/o return type - hasReturnCommand && - ( - isVoidReturn || // void return type - isFortranSubroutine || // fortran subroutine - isConstructor() || // a constructor - isDestructor() // or destructor - ) - ) - { - - warn_doc_error(docFile(),docLine(),"documented empty return type of %s", - qPrint(qualifiedName())); - } - else if ( // see if return needs to documented - m_impl->hasDocumentedReturnType || - isVoidReturn || // void return type - isFortranSubroutine || // fortran subroutine - isConstructor() || // a constructor - isDestructor() // or destructor - ) - { - m_impl->hasDocumentedReturnType = TRUE; - } } void MemberDefImpl::warnIfUndocumentedParams() const { + QCString returnType = typeString(); + bool isFortran = getLanguage()==SrcLangExt_Fortran; + bool isFortranSubroutine = isFortran && returnType.find("subroutine")!=-1; + + bool isVoidReturn = (returnType=="void") || (returnType.right(5)==" void"); + if (!isVoidReturn && returnType == "auto") + { + const ArgumentList &defArgList=isDocsForDefinition() ? argumentList() : declArgumentList(); + if (!defArgList.trailingReturnType().isEmpty()) + { + QCString strippedTrailingReturn = stripTrailingReturn(defArgList.trailingReturnType()); + isVoidReturn = (strippedTrailingReturn=="void") || (strippedTrailingReturn.right(5)==" void"); + } + } if (!Config_getBool(EXTRACT_ALL) && Config_getBool(WARN_IF_UNDOCUMENTED) && Config_getBool(WARN_NO_PARAMDOC) && @@ -4031,21 +4021,37 @@ void MemberDefImpl::warnIfUndocumentedParams() const !isReference() && !Doxygen::suppressDocWarnings) { - QCString returnType = typeString(); if (!m_impl->hasDocumentedParams) { warn_doc_error(docFile(),docLine(), - "parameters of member %s are not (all) documented", + "parameters of member %s are not documented", qPrint(qualifiedName())); } if (!m_impl->hasDocumentedReturnType && - hasDocumentation() && !returnType.isEmpty()) + hasDocumentation() && !returnType.isEmpty() && + !( // not one of the cases where nothing is returned + isVoidReturn || // void return type + isFortranSubroutine || // fortran subroutine + isConstructor() || // a constructor + isDestructor() // or destructor + ) + ) { warn_doc_error(docFile(),docLine(), "return type of member %s is not documented", qPrint(qualifiedName())); } } + if (Config_getBool(WARN_IF_DOC_ERROR) && + m_impl->hasDocumentedReturnType && + (isVoidReturn || // void return type + isFortranSubroutine || // fortran subroutine + isConstructor() || // a constructor + isDestructor())) // or destructor + { + warn_doc_error(docFile(),docLine(),"found documented return type for %s that does not return anything", + qPrint(qualifiedName())); + } } bool MemberDefImpl::isDocumentedFriendClass() const @@ -4076,12 +4082,6 @@ void MemberDefImpl::setMemberGroup(MemberGroup *grp) m_impl->memberGroup = grp; } -bool MemberDefImpl::visibleMemberGroup(bool hideNoHeader) const -{ - return m_impl->memberGroup!=0 && - (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]"); -} - QCString MemberDefImpl::getScopeString() const { QCString result; @@ -4105,7 +4105,7 @@ void MemberDefImpl::setAnchor() if (m_impl->tArgList.hasParameters()) { char buf[20]; - qsnprintf(buf,20,"%d:",(int)m_impl->tArgList.size()); + qsnprintf(buf,20,"%d:",static_cast<int>(m_impl->tArgList.size())); buf[19]='\0'; memAnchor.prepend(buf); } @@ -4117,7 +4117,7 @@ void MemberDefImpl::setAnchor() // convert to md5 hash uchar md5_sig[16]; char sigStr[33]; - MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig); + MD5Buffer(memAnchor.data(),memAnchor.length(),md5_sig); MD5SigToString(md5_sig,sigStr); m_impl->anc = QCString("a")+sigStr; } @@ -4231,7 +4231,7 @@ void MemberDefImpl::setInitializer(const QCString &initializer) m_impl->initializer=initializer; int l=m_impl->initializer.length(); int p=l-1; - while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--; + while (p>=0 && isspace(static_cast<uchar>(m_impl->initializer.at(p)))) p--; m_impl->initializer=m_impl->initializer.left(p+1); m_impl->initLines=m_impl->initializer.contains('\n'); //printf("%s::setInitializer(%s)\n",qPrint(name()),qPrint(m_impl->initializer)); @@ -4239,10 +4239,10 @@ void MemberDefImpl::setInitializer(const QCString &initializer) void MemberDefImpl::addListReference(Definition *) { - static bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C); - //static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); - //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); - //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C); + //bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); + //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); SrcLangExt lang = getLanguage(); if (!isLinkableInProject()) return; QCString memLabel; @@ -4442,7 +4442,7 @@ bool MemberDefImpl::isConstructor() const { if (m_isConstructorCached==0) { - MemberDefImpl *that = (MemberDefImpl*)this; + MemberDefImpl *that = const_cast<MemberDefImpl*>(this); that->_computeIsConstructor(); } ASSERT(m_isConstructorCached>0); @@ -4479,7 +4479,7 @@ bool MemberDefImpl::isDestructor() const { if (m_isDestructorCached==0) { - MemberDefImpl *that=(MemberDefImpl*)this; + MemberDefImpl *that=const_cast<MemberDefImpl*>(this); that->_computeIsDestructor(); } ASSERT(m_isDestructorCached>0); @@ -4527,7 +4527,7 @@ void MemberDefImpl::writeEnumDeclaration(OutputList &typeDecl, typeDecl.writeChar(' '); } - uint enumValuesPerLine = (uint)Config_getInt(ENUM_VALUES_PER_LINE); + uint enumValuesPerLine = static_cast<uint>(Config_getInt(ENUM_VALUES_PER_LINE)); if (numVisibleEnumValues>0 && enumValuesPerLine>0) { typeDecl.docify("{ "); @@ -5843,7 +5843,7 @@ void combineDeclarationAndDefinition(MemberDefMutable *mdec,MemberDefMutable *md if (sameNumTemplateArgs && matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),&mdefAl, mdec->getOuterScope(),mdec->getFileDef(),&mdecAl, - TRUE + TRUE,mdef->getLanguage() ) ) /* match found */ { @@ -5992,7 +5992,7 @@ const ArgumentList &MemberDefImpl::typeConstraints() const bool MemberDefImpl::isFriendToHide() const { - static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); + bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); bool isFriendToHide = hideFriendCompounds && (m_impl->type=="friend class" || m_impl->type=="friend struct" || diff --git a/src/memberdef.h b/src/memberdef.h index 46c2479..9b6e30d 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -45,7 +45,6 @@ class MemberVector; class MemberDef : public Definition { public: - virtual ~MemberDef() {} virtual DefType definitionType() const = 0; // move this member into a different scope virtual MemberDef *deepCopy() const =0; @@ -236,7 +235,6 @@ class MemberDef : public Definition // callgraph related members virtual bool hasCallGraph() const = 0; virtual bool hasCallerGraph() const = 0; - virtual bool visibleMemberGroup(bool hideNoHeader) const = 0; // referenced related members virtual bool hasReferencesRelation() const = 0; virtual bool hasReferencedByRelation() const = 0; diff --git a/src/membergroup.cpp b/src/membergroup.cpp index 6cfce97..809308a 100644 --- a/src/membergroup.cpp +++ b/src/membergroup.cpp @@ -95,7 +95,6 @@ void MemberGroup::writeDeclarations(OutputList &ol, { //printf("MemberGroup::writeDeclarations() %s\n",qPrint(grpHeader)); QCString ldoc = doc; - if (!ldoc.isEmpty()) ldoc.prepend("<a name=\""+anchor()+"\" id=\""+anchor()+"\"></a>"); memberList->writeDeclarations(ol,cd,nd,fd,gd,grpHeader,ldoc,FALSE,showInline); } @@ -255,29 +254,9 @@ int MemberGroup::numDocEnumValues() const return memberList->numDocEnumValues(); } -QCString MemberGroup::anchor() const -{ - uchar md5_sig[16]; - char sigStr[33]; - QCString locHeader = grpHeader; - if (locHeader.isEmpty()) locHeader="[NOHEADER]"; - MD5Buffer((const unsigned char *)locHeader.data(),locHeader.length(),md5_sig); - MD5SigToString(md5_sig,sigStr); - return QCString("amgrp")+sigStr; -} - void MemberGroup::addListReferences(Definition *def) { memberList->addListReferences(def); - if (def) - { - QCString name = def->getOutputFileBase()+"#"+anchor(); - addRefItem(m_xrefListItems, - name, - theTranslator->trGroup(TRUE,TRUE), - name, - grpHeader,QCString(),def); - } } void MemberGroup::findSectionsInDocumentation(const Definition *d) diff --git a/src/membergroup.h b/src/membergroup.h index 8fbe56c..5d1c78e 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -83,7 +83,6 @@ class MemberGroup void addListReferences(Definition *d); void setRefItems(const RefItemVector &sli); const MemberList &members() const { return *memberList.get(); } - QCString anchor() const; QCString docFile() const { return m_docFile; } int docLine() const { return m_docLine; } diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 23a02df..4a062e5 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -419,18 +419,18 @@ void MemberList::writePlainDeclarations(OutputList &ol, bool inGroup, ol.endMemberItem(); if (!md->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC)) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc(*parser.get(), - md->briefFile(),md->briefLine(), - cd,md, - md->briefDescription(), - TRUE,FALSE, - QCString(),TRUE,FALSE, - Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + md->briefFile(),md->briefLine(), + cd,md, + md->briefDescription(), + TRUE,FALSE, + QCString(),TRUE,FALSE, + Config_getBool(MARKDOWN_SUPPORT)) }; + if (!ast->isEmpty()) { ol.startMemberDescription(md->anchor()); - ol.writeDoc(rootNode.get(),cd,md); + ol.writeDoc(ast.get(),cd,md); if (md->hasDetailedDescription()) { ol.disableAllBut(OutputGenerator::Html); @@ -531,7 +531,7 @@ void MemberList::writeDeclarations(OutputList &ol, (void)showEnumValues; // unused //printf("----- writeDeclaration() this=%p ---- inheritedFrom=%p\n",this,inheritedFrom); - static bool optimizeVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool optimizeVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); QCString inheritId; const Definition *ctx = cd; @@ -614,7 +614,7 @@ void MemberList::writeDeclarations(OutputList &ol, //printf("memberGroupList=%p\n",memberGroupList); for (const auto &mg : m_memberGroupRefList) { - bool hasHeader=!mg->header().isEmpty() && mg->header()!="[NOHEADER]"; + bool hasHeader=!mg->header().isEmpty(); if (inheritId.isEmpty()) { //printf("mg->header=%s hasHeader=%d\n",qPrint(mg->header()),hasHeader); @@ -749,7 +749,7 @@ void MemberList::writeSimpleDocumentation(OutputList &ol, void MemberList::writeDocumentationPage(OutputList &ol, const QCString &scopeName, const DefinitionMutable *container) const { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); struct OverloadInfo { diff --git a/src/membername.h b/src/membername.h index f600c8b..7177d57 100644 --- a/src/membername.h +++ b/src/membername.h @@ -68,7 +68,7 @@ class MemberInfo public: MemberInfo(const MemberDef *md,Protection p,Specifier v,bool inh) : m_memberDef(md), m_prot(p), m_virt(v), m_inherited(inh) {} - ~MemberInfo() {} + ~MemberInfo() = default; // getters const MemberDef *memberDef() { return m_memberDef; } diff --git a/src/message.cpp b/src/message.cpp index ad8076d..8dcca05 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -21,19 +21,22 @@ #include "doxygen.h" #include <mutex> +#include <atomic> // globals static QCString g_warnFormat; +static QCString g_warnLineFormat; static const char * g_warningStr = "warning: "; static const char * g_errorStr = "error: "; static FILE * g_warnFile = stderr; static WARN_AS_ERROR_t g_warnBehavior = WARN_AS_ERROR_t::NO; -static bool g_warnStat = false; +static std::atomic_bool g_warnStat = false; static std::mutex g_mutex; void initWarningFormat() { g_warnFormat = Config_getString(WARN_FORMAT); + g_warnLineFormat = Config_getString(WARN_LINE_FORMAT); QCString logFile = Config_getString(WARN_LOGFILE); if (!logFile.isEmpty()) @@ -68,7 +71,7 @@ void msg(const char *fmt, ...) std::unique_lock<std::mutex> lock(g_mutex); if (Debug::isFlagSet(Debug::Time)) { - printf("%.3f sec: ",((double)Debug::elapsedTime())); + printf("%.3f sec: ",(static_cast<double>(Debug::elapsedTime()))); } va_list args; va_start(args, fmt); @@ -111,6 +114,7 @@ static void format_warn(const QCString &file,int line,const QCString &text) } if (g_warnBehavior == WARN_AS_ERROR_t::YES) { + Doxygen::terminating=true; exit(1); } g_warnStat = true; @@ -125,6 +129,7 @@ static void handle_warn_as_error() QCString msgText = " (warning treated as error, aborting now)\n"; fwrite(msgText.data(),1,msgText.length(),g_warnFile); } + Doxygen::terminating=true; exit(1); } g_warnStat = true; @@ -137,28 +142,40 @@ static void do_warn(bool enabled, const QCString &file, int line, const char *pr va_list argsCopy; va_copy(argsCopy, args); - int l=0; + size_t l=0; if (prefix) { - l=(int)strlen(prefix); + l=strlen(prefix); } // determine needed buffersize based on: // format + arguments // prefix // 1 position for `\0` - int bufSize = vsnprintf(NULL, 0, fmt, args) + l + 1; + size_t bufSize = vsnprintf(NULL, 0, fmt, args) + l + 1; QCString text(bufSize); if (prefix) { qstrncpy(text.rawData(),prefix,bufSize); } vsnprintf(text.rawData()+l, bufSize-l, fmt, argsCopy); - text[bufSize-1]='\0'; + text[static_cast<int>(bufSize)-1]='\0'; format_warn(file,line,text); va_end(argsCopy); } +QCString warn_line(const QCString &file,int line) +{ + QCString fileSubst = file.isEmpty() ? "<unknown>" : file; + QCString lineSubst; lineSubst.setNum(line); + return substitute( + substitute( + g_warnLineFormat, + "$file",fileSubst + ), + "$line",lineSubst + ); +} void warn(const QCString &file,int line,const char *fmt, ...) { va_list args; @@ -238,10 +255,12 @@ void term(const char *fmt, ...) va_end(args); if (g_warnFile != stderr) { - for (int i = 0; i < (int)strlen(g_errorStr); i++) fprintf(g_warnFile, " "); + size_t l = strlen(g_errorStr); + for (size_t i=0; i<l; i++) fprintf(g_warnFile, " "); fprintf(g_warnFile, "%s\n", "Exiting..."); } } + Doxygen::terminating=true; exit(1); } @@ -283,6 +302,7 @@ extern void finishWarnExit() { if (g_warnStat && g_warnBehavior == WARN_AS_ERROR_t::FAIL_ON_WARNINGS) { + Doxygen::terminating=true; exit(1); } } diff --git a/src/message.h b/src/message.h index 3c3ccd9..dc61bbb 100644 --- a/src/message.h +++ b/src/message.h @@ -36,6 +36,7 @@ extern void warn_uncond(const char *fmt, ...) PRINTFLIKE(1, 2); extern void err(const char *fmt, ...) PRINTFLIKE(1, 2); extern void err_full(const QCString &file,int line,const char *fmt, ...) PRINTFLIKE(3, 4); extern void term(const char *fmt, ...) PRINTFLIKE(1, 2); +extern QCString warn_line(const QCString &file,int line); void initWarningFormat(); void warn_flush(); extern void finishWarnExit(); diff --git a/src/msc.cpp b/src/msc.cpp index fff8ad5..b05edfd 100644 --- a/src/msc.cpp +++ b/src/msc.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "message.h" #include "docparser.h" +#include "docnode.h" #include "doxygen.h" #include "index.h" #include "util.h" @@ -70,8 +71,10 @@ static bool convertMapFile(TextStream &t,const QCString &mapName,const QCString { // handle doxygen \ref tag URL reference - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRef> df { createRef( *parser.get(), url, context ) }; + auto parser { createDocParser() }; + auto dfAst { createRef( *parser.get(), url, context ) }; + auto dfAstImpl = dynamic_cast<const DocNodeAST*>(dfAst.get()); + const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root); t << externalRef(relPath,df->ref(),TRUE); if (!df->file().isEmpty()) t << addHtmlExtensionIfMissing(df->file()); if (!df->anchor().isEmpty()) t << "#" << df->anchor(); diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index f8539c0..341e4c7 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -75,9 +75,9 @@ class NamespaceDefImpl : public DefinitionMixin<NamespaceDefMutable> virtual void countMembers(); virtual int numDocMembers() const; virtual void addUsingDirective(const NamespaceDef *nd); - virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const { return m_usingDirList; } + virtual const LinkedRefMap<const NamespaceDef> &getUsedNamespaces() const { return m_usingDirList; } virtual void addUsingDeclaration(const ClassDef *cd); - virtual LinkedRefMap<const ClassDef> getUsedClasses() const { return m_usingDeclList; } + virtual const LinkedRefMap<const ClassDef> &getUsedClasses() const { return m_usingDeclList; } virtual void combineUsingRelations(NamespaceDefSet &visitedNamespace); virtual QCString displayName(bool=TRUE) const; virtual QCString localName() const; @@ -165,6 +165,7 @@ NamespaceDefMutable *createNamespaceDef(const QCString &defFileName,int defLine, const QCString &refFile,const QCString &type, bool isPublished) { + //printf("createNamespaceDef(%s)\n",qPrint(name)); return new NamespaceDefImpl(defFileName,defLine,defColumn,name,ref,refFile,type,isPublished); } @@ -189,9 +190,9 @@ class NamespaceDefAliasImpl : public DefinitionAliasMixin<NamespaceDef> { return getNSAlias()->anchor(); } virtual int numDocMembers() const { return getNSAlias()->numDocMembers(); } - virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const + virtual const LinkedRefMap<const NamespaceDef> &getUsedNamespaces() const { return getNSAlias()->getUsedNamespaces(); } - virtual LinkedRefMap<const ClassDef> getUsedClasses() const + virtual const LinkedRefMap<const ClassDef> &getUsedClasses() const { return getNSAlias()->getUsedClasses(); } virtual QCString displayName(bool b=TRUE) const { return makeDisplayName(this,b); } @@ -468,7 +469,7 @@ void NamespaceDefImpl::insertMember(MemberDef *md) //printf("%s::m_allMembersDict->append(%s)\n",qPrint(name()),qPrint(md->localName())); m_allMembers.add(md->localName(),md); //::addNamespaceMemberNameToIndex(md); - //static bool sortBriefDocs=Config_getBool(SORT_BRIEF_DOCS); + //bool sortBriefDocs=Config_getBool(SORT_BRIEF_DOCS); switch(md->memberType()) { case MemberType_Variable: @@ -549,7 +550,7 @@ void NamespaceDefImpl::computeAnchors() bool NamespaceDefImpl::hasDetailedDescription() const { - static bool repeatBrief = Config_getBool(REPEAT_BRIEF); + bool repeatBrief = Config_getBool(REPEAT_BRIEF); return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty()); } @@ -606,11 +607,14 @@ void NamespaceDefImpl::writeTagFile(TextStream &tagFile) break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ml->writeTagFile(tagFile); + MemberList * ml = getMemberList(lmd->type); + if (ml) + { + ml->writeTagFile(tagFile); + } } } break; @@ -678,19 +682,19 @@ void NamespaceDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> rootNode { validatingParseDoc(*parser.get(), - briefFile(),briefLine(),this,0, - briefDescription(),TRUE,FALSE, - QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - if (rootNode && !rootNode->isEmpty()) + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + briefFile(),briefLine(),this,0, + briefDescription(),TRUE,FALSE, + QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + if (!ast->isEmpty()) { ol.startParagraph(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); ol.writeString(" - "); ol.popGeneratorState(); - ol.writeDoc(rootNode.get(),this,0); + ol.writeDoc(ast.get(),this,0); ol.pushGeneratorState(); ol.disable(OutputGenerator::RTF); ol.writeString(" \n"); @@ -788,8 +792,7 @@ void NamespaceDefImpl::writeMemberGroups(OutputList &ol) /* write user defined member groups */ for (const auto &mg : m_memberGroups) { - if ((!mg->allMembersInSameSection() || !m_subGrouping) - && mg->header()!="[NOHEADER]") + if (!mg->allMembersInSameSection() || !m_subGrouping) { mg->writeDeclarations(ol,0,this,0,0); } @@ -816,63 +819,60 @@ void NamespaceDefImpl::writeSummaryLinks(OutputList &ol) const SrcLangExt lang = getLanguage(); for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)) { - if (lde->kind()==LayoutDocEntry::NamespaceClasses && classes.declVisible()) + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); + if (lde->kind()==LayoutDocEntry::NamespaceClasses && classes.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "nested-classes"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::NamespaceInterfaces && interfaces.declVisible()) + else if (lde->kind()==LayoutDocEntry::NamespaceInterfaces && interfaces.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "interfaces"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::NamespaceStructs && structs.declVisible()) + else if (lde->kind()==LayoutDocEntry::NamespaceStructs && structs.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "structs"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::NamespaceExceptions && exceptions.declVisible()) + else if (lde->kind()==LayoutDocEntry::NamespaceExceptions && exceptions.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "exceptions"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::NamespaceNestedNamespaces && namespaces.declVisible(false)) + else if (lde->kind()==LayoutDocEntry::NamespaceNestedNamespaces && namespaces.declVisible(false) && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "namespaces"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::NamespaceNestedConstantGroups && namespaces.declVisible(true)) + else if (lde->kind()==LayoutDocEntry::NamespaceNestedConstantGroups && namespaces.declVisible(true) && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "constantgroups"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } - else if (lde->kind()==LayoutDocEntry::NamespaceConcepts && m_concepts.declVisible()) + else if (lde->kind()==LayoutDocEntry::NamespaceConcepts && m_concepts.declVisible() && ls) { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); QCString label = "concepts"; ol.writeSummaryLink(QCString(),label,ls->title(lang),first); first=FALSE; } else if (lde->kind()== LayoutDocEntry::MemberDecl) { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - MemberList * ml = getMemberList(lmd->type); - if (ml && ml->declVisible()) + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) { - ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); - first=FALSE; + MemberList * ml = getMemberList(lmd->type); + if (ml && ml->declVisible()) + { + ol.writeSummaryLink(QCString(),MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); + first=FALSE; + } } } } @@ -922,9 +922,9 @@ void NamespaceDefImpl::writeConceptsToTagFile(TextStream &tagFile) void NamespaceDefImpl::writeDocumentation(OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); - //static bool outputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); - //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + //bool outputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); QCString pageTitle = title(); startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_NamespaceVisible,!generateTreeView); @@ -957,6 +957,7 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) SrcLangExt lang = getLanguage(); for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)) { + const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get()); switch (lde->kind()) { case LayoutDocEntry::BriefDesc: @@ -967,44 +968,37 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) break; case LayoutDocEntry::NamespaceClasses: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),classes); + if (ls) writeClassDeclarations(ol,ls->title(lang),classes); } break; case LayoutDocEntry::NamespaceInterfaces: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),interfaces); + if (ls) writeClassDeclarations(ol,ls->title(lang),interfaces); } break; case LayoutDocEntry::NamespaceStructs: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),structs); + if (ls) writeClassDeclarations(ol,ls->title(lang),structs); } break; case LayoutDocEntry::NamespaceExceptions: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeClassDeclarations(ol,ls->title(lang),exceptions); + if (ls) writeClassDeclarations(ol,ls->title(lang),exceptions); } break; case LayoutDocEntry::NamespaceConcepts: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeConcepts(ol,ls->title(lang)); + if (ls) writeConcepts(ol,ls->title(lang)); } break; case LayoutDocEntry::NamespaceNestedNamespaces: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNamespaceDeclarations(ol,ls->title(lang),false); + if (ls) writeNamespaceDeclarations(ol,ls->title(lang),false); } break; case LayoutDocEntry::NamespaceNestedConstantGroups: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeNamespaceDeclarations(ol,ls->title(lang),true); + if (ls) writeNamespaceDeclarations(ol,ls->title(lang),true); } break; case LayoutDocEntry::MemberGroups: @@ -1012,8 +1006,8 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) break; case LayoutDocEntry::MemberDecl: { - const LayoutDocEntryMemberDecl *lmd = (const LayoutDocEntryMemberDecl*)lde.get(); - writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()); + if (lmd) writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); } break; case LayoutDocEntry::MemberDeclEnd: @@ -1021,8 +1015,7 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) break; case LayoutDocEntry::DetailedDesc: { - const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get(); - writeDetailedDescription(ol,ls->title(lang)); + if (ls) writeDetailedDescription(ol,ls->title(lang)); } break; case LayoutDocEntry::MemberDefStart: @@ -1033,8 +1026,8 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) break; case LayoutDocEntry::MemberDef: { - const LayoutDocEntryMemberDef *lmd = (const LayoutDocEntryMemberDef*)lde.get(); - writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); + const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()); + if (lmd) writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); } break; case LayoutDocEntry::MemberDefEnd: @@ -1112,7 +1105,7 @@ void NamespaceDefImpl::writeMemberPages(OutputList &ol) void NamespaceDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { - static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); + bool createSubDirs=Config_getBool(CREATE_SUBDIRS); ol.writeString(" <div class=\"navtab\">\n"); ol.writeString(" <table>\n"); @@ -1168,13 +1161,13 @@ void NamespaceDefImpl::countMembers() int NamespaceDefImpl::numDocMembers() const { MemberList *allMemberList = getMemberList(MemberListType_allMembersList); - return (allMemberList ? allMemberList->numDocMembers() : 0) + (int)m_innerCompounds.size(); + return (allMemberList ? allMemberList->numDocMembers() : 0) + static_cast<int>(m_innerCompounds.size()); } void NamespaceDefImpl::addUsingDirective(const NamespaceDef *nd) { m_usingDirList.add(nd->qualifiedName(),nd); - //printf("%p: NamespaceDefImpl::addUsingDirective: %s:%d\n",this,qPrint(name()),m_usingDirList->count()); + //printf("%s: NamespaceDefImpl::addUsingDirective: %s:%zu\n",qPrint(name()),qPrint(nd->qualifiedName()),m_usingDirList.size()); } void NamespaceDefImpl::addUsingDeclaration(const ClassDef *cd) @@ -1370,8 +1363,8 @@ void NamespaceLinkedRefMap::writeDeclaration(OutputList &ol,const QCString &titl void NamespaceDefImpl::addMemberToList(MemberListType lt,MemberDef *md) { - static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); - static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); + bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); + bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); const auto &ml = m_memberLists.get(lt,MemberListContainer::Namespace); ml->setNeedsSorting( ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) || @@ -1445,7 +1438,7 @@ bool NamespaceDefImpl::isLinkableInProject() const { int i = name().findRev("::"); if (i==-1) i=0; else i+=2; - static bool extractAnonNs = Config_getBool(EXTRACT_ANON_NSPACES); + bool extractAnonNs = Config_getBool(EXTRACT_ANON_NSPACES); if (extractAnonNs && // extract anonymous ns name().mid(i,20)=="anonymous_namespace{" // correct prefix ) // not disabled by config diff --git a/src/namespacedef.h b/src/namespacedef.h index 46d2b1e..bf83039 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -54,15 +54,14 @@ class NamespaceLinkedRefMap : public LinkedRefMap<const NamespaceDef> class NamespaceDef : public Definition { public: - virtual ~NamespaceDef() {} virtual DefType definitionType() const = 0; // ---- getters virtual QCString getOutputFileBase() const = 0; virtual QCString anchor() const = 0; virtual int numDocMembers() const = 0; - virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const = 0; - virtual LinkedRefMap<const ClassDef> getUsedClasses() const = 0; + virtual const LinkedRefMap<const NamespaceDef> &getUsedNamespaces() const = 0; + virtual const LinkedRefMap<const ClassDef> &getUsedClasses() const = 0; virtual QCString displayName(bool=TRUE) const = 0; virtual QCString localName() const = 0; virtual bool isConstantGroup() const = 0; diff --git a/src/outputgen.h b/src/outputgen.h index 1f67a76..89c8a34 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -1,8 +1,6 @@ /****************************************************************************** * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2022 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 @@ -27,6 +25,7 @@ #include "index.h" #include "section.h" #include "textstream.h" +#include "docparser.h" class ClassDiagram; class DotClassGraph; @@ -35,7 +34,6 @@ class DotCallGraph; class DotDirDeps; class DotGfxHierarchyTable; class DotGroupCollaboration; -class DocNode; class MemberDef; class Definition; @@ -61,7 +59,7 @@ struct SourceLinkInfo class CodeOutputInterface { public: - virtual ~CodeOutputInterface() {} + virtual ~CodeOutputInterface() = default; CodeOutputInterface() {} CodeOutputInterface(const CodeOutputInterface &) = delete; CodeOutputInterface &operator=(const CodeOutputInterface &) = delete; @@ -136,8 +134,8 @@ class CodeOutputInterface */ virtual void writeCodeAnchor(const QCString &name) = 0; - virtual void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile) = 0; - virtual void addWord(const QCString &word,bool hiPriority) = 0; + virtual void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile) {} + virtual void addWord(const QCString &word,bool hiPriority) {} /*! Starts a source code fragment. The fragment will be * fed to the code parser (see code.h) for syntax highlighting @@ -161,7 +159,6 @@ class CodeOutputInterface class BaseOutputDocInterface : public CodeOutputInterface { public: - virtual ~BaseOutputDocInterface() {} enum ParamListTypes { Param, RetVal, Exception }; enum SectionTypes { /*See, Return, Author, Version, Since, Date, Bug, Note, @@ -355,14 +352,11 @@ class OutputGenerator : public BaseOutputDocInterface void startPlainFile(const QCString &name); void endPlainFile(); - //QCString getContents() const; bool isEnabled() const { return m_active; } void pushGeneratorState(); void popGeneratorState(); - //void setEncoding(const QCString &enc) { encoding = enc; } - //virtual void postProcess(QByteArray &) { } - virtual void writeDoc(DocNode *,const Definition *ctx,const MemberDef *md,int id) = 0; + virtual void writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *md,int id) = 0; /////////////////////////////////////////////////////////////// // structural output interface @@ -500,7 +494,6 @@ class OutputGenerator : public BaseOutputDocInterface virtual void startInlineMemberDoc() = 0; virtual void endInlineMemberDoc() = 0; - virtual void startLabels() = 0; virtual void writeLabel(const QCString &,bool) = 0; virtual void endLabels() = 0; @@ -517,57 +510,4 @@ class OutputGenerator : public BaseOutputDocInterface std::stack<bool> m_genStack; }; -/** Interface used for generating documentation. - * - * This abstract class is used by several functions - * to generate the output for a specific format. - * This interface contains some state saving and changing - * functions for dealing with format specific output. - */ -class OutputDocInterface : public BaseOutputDocInterface -{ - public: - virtual ~OutputDocInterface() {} - - /*! Disables all output formats except format \a o - * (useful for OutputList only) - */ - virtual void disableAllBut(OutputGenerator::OutputType o) = 0; - - /*! Enables all output formats as far as they have been enabled in - * the config file. (useful for OutputList only) - */ - virtual void enableAll() = 0; - - /*! Disables all output formats (useful for OutputList only) */ - virtual void disableAll()= 0; - - /*! Disables a specific output format (useful for OutputList only) */ - virtual void disable(OutputGenerator::OutputType o) = 0; - - /*! Enables a specific output format (useful for OutputList only) */ - virtual void enable(OutputGenerator::OutputType o) = 0; - - /*! Check whether a specific output format is currently enabled - * (useful for OutputList only) - */ - virtual bool isEnabled(OutputGenerator::OutputType o) = 0; - - /*! Appends the output generated by generator \a g to this - * generator. - */ - //virtual void append(const OutputDocInterface *g) = 0; - - /*! Pushes the state of the current generator (or list of - * generators) on a stack. - */ - virtual void pushGeneratorState() = 0; - - /*! Pops the state of the current generator (or list of - * generators) on a stack. Should be preceded by a call - * the pushGeneratorState(). - */ - virtual void popGeneratorState() = 0; -}; - #endif diff --git a/src/outputlist.cpp b/src/outputlist.cpp index 3175a76..265cb67 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -154,25 +154,28 @@ void OutputList::generateDoc(const QCString &fileName,int startLine, if (og->isEnabled()) count++; } - // we want to validate irrespective of the number of output formats - // specified as: - // - when only XML format there should be warnings as well (XML has its own write routines) - // - no formats there should be warnings as well - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> root { validatingParseDoc(*parser.get(), - fileName,startLine, - ctx,md,docStr,indexWords,isExample,exampleName, - singleLine,linkFromIndex,markdownSupport) }; - if (count>0) writeDoc(root.get(),ctx,md,m_id); + if (count>0) + { + // we want to validate irrespective of the number of output formats + // specified as: + // - when only XML format there should be warnings as well (XML has its own write routines) + // - no formats there should be warnings as well + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + fileName,startLine, + ctx,md,docStr,indexWords,isExample,exampleName, + singleLine,linkFromIndex,markdownSupport) }; + if (ast) writeDoc(ast.get(),ctx,md,m_id); + } } -void OutputList::writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md,int) +void OutputList::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *md,int) { for (const auto &og : m_outputs) { //printf("og->printDoc(extension=%s)\n", // ctx?qPrint(ctx->getDefFileExtension()):"<null>"); - if (og->isEnabled()) og->writeDoc(root,ctx,md,m_id); + if (og->isEnabled()) og->writeDoc(ast,ctx,md,m_id); } } @@ -188,14 +191,14 @@ void OutputList::parseText(const QCString &textStr) // specified as: // - when only XML format there should be warnings as well (XML has its own write routines) // - no formats there should be warnings as well - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocText> root { validatingParseText(*parser.get(), textStr) }; + auto parser { createDocParser() }; + auto textNode { validatingParseText(*parser.get(), textStr) }; - if (count>0) + if (textNode && count>0) { for (const auto &og : m_outputs) { - if (og->isEnabled()) og->writeDoc(root.get(),0,0,m_id); + if (og->isEnabled()) og->writeDoc(textNode.get(),0,0,m_id); } } } diff --git a/src/outputlist.h b/src/outputlist.h index 267a717..ae143f8 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -22,6 +22,8 @@ #include "index.h" // for IndexSections #include "outputgen.h" +#include "searchindex.h" // for SIDataCollection +#include "doxygen.h" class ClassDiagram; class DotClassGraph; @@ -29,12 +31,11 @@ class DotDirDeps; class DotInclDepGraph; class DotGfxHierarchyTable; class DotGroupCollaboration; -class DocRoot; /** Class representing a list of output generators that are written to * in parallel. */ -class OutputList : public OutputDocInterface +class OutputList : public BaseOutputDocInterface { public: OutputList(); @@ -70,7 +71,7 @@ class OutputList : public OutputDocInterface bool indexWords,bool isExample,const QCString &exampleName /*=0*/, bool singleLine /*=FALSE*/,bool linkFromIndex /*=FALSE*/, bool markdownSupport /*=FALSE*/); - void writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md,int id=0); + void writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *md,int id=0); void parseText(const QCString &textStr); void startIndexSection(IndexSections is) @@ -485,10 +486,19 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endFontClass); } void writeCodeAnchor(const QCString &name) { forall(&OutputGenerator::writeCodeAnchor,name); } + void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile) - { forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile); } + { /*forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile);*/ + m_searchData.setCurrentDoc(context,anchor,isSourceFile); + } void addWord(const QCString &word,bool hiPriority) - { forall(&OutputGenerator::addWord,word,hiPriority); } + { /*forall(&OutputGenerator::addWord,word,hiPriority);*/ + m_searchData.addWord(word,hiPriority); + } + void indexSearchData() + { + m_searchData.transfer(); + } void startPlainFile(const QCString &name) { forall(&OutputGenerator::startPlainFile,name); } @@ -515,6 +525,7 @@ class OutputList : public OutputDocInterface std::vector< std::unique_ptr<OutputGenerator> > m_outputs; int m_id; + SIDataCollection m_searchData; }; diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 701b769..9b3d81b 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -170,7 +170,7 @@ void PageDefImpl::writeTagFile(TextStream &tagFile) void PageDefImpl::writeDocumentation(OutputList &ol) { - static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); + bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //outputList->disable(OutputGenerator::Man); QCString pageName,manPageName; @@ -352,7 +352,7 @@ void PageDefImpl::writePageDocumentation(OutputList &ol) const bool PageDefImpl::visibleInIndex() const { - static bool externalPages = Config_getBool(EXTERNAL_PAGES); + bool externalPages = Config_getBool(EXTERNAL_PAGES); return // not part of a group !getGroupDef() && // not an externally defined page diff --git a/src/pagedef.h b/src/pagedef.h index e7f51a4..fa5e400 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -25,8 +25,6 @@ class OutputList; class PageDef : public DefinitionMutable, public Definition { public: - virtual ~PageDef() {} - // setters virtual void setFileName(const QCString &name) = 0; virtual void setLocalToc(const LocalToc &tl) = 0; diff --git a/src/parserintf.h b/src/parserintf.h index a0269b8..b033422 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -42,7 +42,7 @@ class ClangTUParser; class OutlineParserInterface { public: - virtual ~OutlineParserInterface() {} + virtual ~OutlineParserInterface() = default; /** Parses a single input file with the goal to build an Entry tree. * @param[in] fileName The full name of the file. @@ -83,7 +83,7 @@ class OutlineParserInterface class CodeParserInterface { public: - virtual ~CodeParserInterface() {} + virtual ~CodeParserInterface() = default; /** Parses a source file or fragment with the goal to produce * highlighted and cross-referenced output. diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index 5503081..8100d30 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -1,9 +1,6 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2022 by Dimitri van Heesch. * Authors: Dimitri van Heesch, Miguel Lobo. * * Permission to use, copy, modify, and distribute this software and its @@ -25,6 +22,7 @@ #include "perlmodgen.h" #include "docparser.h" +#include "docnode.h" #include "message.h" #include "doxygen.h" #include "pagedef.h" @@ -285,149 +283,115 @@ void PerlModOutput::iclose(char c) /*! @brief Concrete visitor implementation for PerlMod output. */ class PerlModDocVisitor : public DocVisitor { -public: - PerlModDocVisitor(PerlModOutput &); - virtual ~PerlModDocVisitor() { } - - void finish(); - - //-------------------------------------- - // visitor functions for leaf nodes - //-------------------------------------- - - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); - - //-------------------------------------- - // visitor functions for compound nodes - //-------------------------------------- - - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *) ; - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *); - void visitPost(DocSection *); - void visitPre(DocHtmlList *); - void visitPost(DocHtmlList *) ; - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - //void visitPre(DocHtmlPre *); - //void visitPost(DocHtmlPre *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *); - void visitPost(DocHtmlTable *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *); - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *); - void visitPost(DocLink *); - void visitPre(DocRef *); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - //void visitPre(DocLanguage *); - //void visitPost(DocLanguage *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); - -private: + public: + PerlModDocVisitor(PerlModOutput &); + virtual ~PerlModDocVisitor() { } + + void finish(); + + //-------------------------------------- + // visitor functions for leaf nodes + //-------------------------------------- + + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); + + //-------------------------------------- + // visitor functions for compound nodes + //-------------------------------------- + + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &) ; + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &); + void operator()(const DocHtmlList &); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocHtmlCaption &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &); + void operator()(const DocRef &); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); + + private: + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } - //-------------------------------------- - // helper functions - //-------------------------------------- + //-------------------------------------- + // helper functions + //-------------------------------------- - void addLink(const QCString &ref, const QCString &file, - const QCString &anchor); + void addLink(const QCString &ref, const QCString &file, + const QCString &anchor); - void enterText(); - void leaveText(); + void enterText(); + void leaveText(); - void openItem(const QCString &); - void closeItem(); - void singleItem(const QCString &); - void openSubBlock(const QCString & = QCString()); - void closeSubBlock(); - //void openOther(); - //void closeOther(); + void openItem(const QCString &); + void closeItem(); + void singleItem(const QCString &); + void openSubBlock(const QCString & = QCString()); + void closeSubBlock(); - //-------------------------------------- - // state variables - //-------------------------------------- + //-------------------------------------- + // state variables + //-------------------------------------- - PerlModOutput &m_output; - bool m_textmode; - bool m_textblockstart; - QCString m_other; + PerlModOutput &m_output; + bool m_textmode; + bool m_textblockstart; + QCString m_other; }; PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output) - : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false), m_textblockstart(FALSE) + : m_output(output), m_textmode(false), m_textblockstart(FALSE) { m_output.openList("doc"); } @@ -519,43 +483,43 @@ void PerlModDocVisitor::closeSubBlock() */ //} -void PerlModDocVisitor::visit(DocWord *w) +void PerlModDocVisitor::operator()(const DocWord &w) { enterText(); - m_output.addQuoted(w->word()); + m_output.addQuoted(w.word()); } -void PerlModDocVisitor::visit(DocLinkedWord *w) +void PerlModDocVisitor::operator()(const DocLinkedWord &w) { openItem("url"); - addLink(w->ref(), w->file(), w->anchor()); - m_output.addFieldQuotedString("content", w->word()); + addLink(w.ref(), w.file(), w.anchor()); + m_output.addFieldQuotedString("content", w.word()); closeItem(); } -void PerlModDocVisitor::visit(DocWhiteSpace *) +void PerlModDocVisitor::operator()(const DocWhiteSpace &) { enterText(); m_output.add(' '); } -void PerlModDocVisitor::visit(DocSymbol *sy) +void PerlModDocVisitor::operator()(const DocSymbol &sy) { - const DocSymbol::PerlSymb *res = HtmlEntityMapper::instance()->perl(sy->symbol()); + const HtmlEntityMapper::PerlSymb *res = HtmlEntityMapper::instance()->perl(sy.symbol()); const char *accent=0; - if (res-> symb) + if (res->symb) { switch (res->type) { - case DocSymbol::Perl_string: + case HtmlEntityMapper::Perl_string: enterText(); m_output.add(res->symb); break; - case DocSymbol::Perl_char: + case HtmlEntityMapper::Perl_char: enterText(); m_output.add(res->symb[0]); break; - case DocSymbol::Perl_symbol: + case HtmlEntityMapper::Perl_symbol: leaveText(); openItem("symbol"); m_output.addFieldQuotedString("symbol", res->symb); @@ -564,28 +528,28 @@ void PerlModDocVisitor::visit(DocSymbol *sy) default: switch(res->type) { - case DocSymbol::Perl_umlaut: + case HtmlEntityMapper::Perl_umlaut: accent = "umlaut"; break; - case DocSymbol::Perl_acute: + case HtmlEntityMapper::Perl_acute: accent = "acute"; break; - case DocSymbol::Perl_grave: + case HtmlEntityMapper::Perl_grave: accent = "grave"; break; - case DocSymbol::Perl_circ: + case HtmlEntityMapper::Perl_circ: accent = "circ"; break; - case DocSymbol::Perl_slash: + case HtmlEntityMapper::Perl_slash: accent = "slash"; break; - case DocSymbol::Perl_tilde: + case HtmlEntityMapper::Perl_tilde: accent = "tilde"; break; - case DocSymbol::Perl_cedilla: + case HtmlEntityMapper::Perl_cedilla: accent = "cedilla"; break; - case DocSymbol::Perl_ring: + case HtmlEntityMapper::Perl_ring: accent = "ring"; break; default: @@ -605,37 +569,45 @@ void PerlModDocVisitor::visit(DocSymbol *sy) } else { - err("perl: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(sy->symbol(),TRUE)); + err("perl: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(sy.symbol(),TRUE)); } } -void PerlModDocVisitor::visit(DocEmoji *sy) + +void PerlModDocVisitor::operator()(const DocEmoji &sy) { enterText(); - const char *name = EmojiEntityMapper::instance()->name(sy->index()); + const char *name = EmojiEntityMapper::instance()->name(sy.index()); if (name) { m_output.add(name); } else { - m_output.add(sy->name()); + m_output.add(sy.name()); } } -void PerlModDocVisitor::visit(DocURL *u) +void PerlModDocVisitor::operator()(const DocURL &u) { openItem("url"); - m_output.addFieldQuotedString("content", u->url()); + m_output.addFieldQuotedString("content", u.url()); closeItem(); } -void PerlModDocVisitor::visit(DocLineBreak *) { singleItem("linebreak"); } -void PerlModDocVisitor::visit(DocHorRuler *) { singleItem("hruler"); } +void PerlModDocVisitor::operator()(const DocLineBreak &) +{ + singleItem("linebreak"); +} + +void PerlModDocVisitor::operator()(const DocHorRuler &) +{ + singleItem("hruler"); +} -void PerlModDocVisitor::visit(DocStyleChange *s) +void PerlModDocVisitor::operator()(const DocStyleChange &s) { const char *style = 0; - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: style = "bold"; break; case DocStyleChange::S: style = "s"; break; @@ -663,14 +635,14 @@ void PerlModDocVisitor::visit(DocStyleChange *s) } openItem("style"); m_output.addFieldQuotedString("style", style) - .addFieldBoolean("enable", s->enable()); + .addFieldBoolean("enable", s.enable()); closeItem(); } -void PerlModDocVisitor::visit(DocVerbatim *s) +void PerlModDocVisitor::operator()(const DocVerbatim &s) { const char *type = 0; - switch (s->type()) + switch (s.type()) { case DocVerbatim::Code: #if 0 @@ -693,69 +665,69 @@ void PerlModDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: type = "plantuml"; break; } openItem(type); - if (s->hasCaption()) + if (s.hasCaption()) { openSubBlock("caption"); - for (const auto &n : s->children()) n->accept(this); + visitChildren(s); closeSubBlock(); } - m_output.addFieldQuotedString("content", s->text()); + m_output.addFieldQuotedString("content", s.text()); closeItem(); } -void PerlModDocVisitor::visit(DocAnchor *anc) +void PerlModDocVisitor::operator()(const DocAnchor &anc) { - QCString anchor = anc->file() + "_1" + anc->anchor(); + QCString anchor = anc.file() + "_1" + anc.anchor(); openItem("anchor"); m_output.addFieldQuotedString("id", anchor); closeItem(); } -void PerlModDocVisitor::visit(DocInclude *inc) +void PerlModDocVisitor::operator()(const DocInclude &inc) { const char *type = 0; - switch(inc->type()) + switch (inc.type()) { - case DocInclude::IncWithLines: - return; - case DocInclude::Include: - return; - case DocInclude::DontInclude: return; - case DocInclude::DontIncWithLines: return; - case DocInclude::HtmlInclude: type = "htmlonly"; break; - case DocInclude::LatexInclude: type = "latexonly"; break; - case DocInclude::RtfInclude: type = "rtfonly"; break; - case DocInclude::ManInclude: type = "manonly"; break; - case DocInclude::XmlInclude: type = "xmlonly"; break; - case DocInclude::DocbookInclude: type = "docbookonly"; break; - case DocInclude::VerbInclude: type = "preformatted"; break; - case DocInclude::Snippet: return; - case DocInclude::SnipWithLines: return; - case DocInclude::SnippetDoc: - case DocInclude::IncludeDoc: - err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" - "Please create a bug report\n",__FILE__); - break; + case DocInclude::IncWithLines: + return; + case DocInclude::Include: + return; + case DocInclude::DontInclude: return; + case DocInclude::DontIncWithLines: return; + case DocInclude::HtmlInclude: type = "htmlonly"; break; + case DocInclude::LatexInclude: type = "latexonly"; break; + case DocInclude::RtfInclude: type = "rtfonly"; break; + case DocInclude::ManInclude: type = "manonly"; break; + case DocInclude::XmlInclude: type = "xmlonly"; break; + case DocInclude::DocbookInclude: type = "docbookonly"; break; + case DocInclude::VerbInclude: type = "preformatted"; break; + case DocInclude::Snippet: return; + case DocInclude::SnipWithLines: return; + case DocInclude::SnippetDoc: + case DocInclude::IncludeDoc: + err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s" + "Please create a bug report\n",__FILE__); + break; } openItem(type); - m_output.addFieldQuotedString("content", inc->text()); + m_output.addFieldQuotedString("content", inc.text()); closeItem(); } -void PerlModDocVisitor::visit(DocIncOperator *) +void PerlModDocVisitor::operator()(const DocIncOperator &) { #if 0 //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", - // op->type(),op->isFirst(),op->isLast(),op->text().data()); - if (op->isFirst()) + // op.type(),op.isFirst(),op.isLast(),op.text().data()); + if (op.isFirst()) { m_output.add("<programlisting>"); } - if (op->type()!=DocIncOperator::Skip) + if (op.type()!=DocIncOperator::Skip) { - parseCode(m_ci,op->context(),op->text(),FALSE,0); + parseCode(m_ci,op.context(),op.text(),FALSE,0); } - if (op->isLast()) + if (op.isLast()) { m_output.add("</programlisting>"); } @@ -766,16 +738,16 @@ void PerlModDocVisitor::visit(DocIncOperator *) #endif } -void PerlModDocVisitor::visit(DocFormula *f) +void PerlModDocVisitor::operator()(const DocFormula &f) { openItem("formula"); QCString id; - id += QCString().setNum(f->id()); - m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f->text()); + id += QCString().setNum(f.id()); + m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f.text()); closeItem(); } -void PerlModDocVisitor::visit(DocIndexEntry *) +void PerlModDocVisitor::operator()(const DocIndexEntry &) { #if 0 m_output.add("<indexentry>" @@ -787,14 +759,14 @@ void PerlModDocVisitor::visit(DocIndexEntry *) #endif } -void PerlModDocVisitor::visit(DocSimpleSectSep *) +void PerlModDocVisitor::operator()(const DocSimpleSectSep &) { } -void PerlModDocVisitor::visit(DocCite *cite) +void PerlModDocVisitor::operator()(const DocCite &cite) { openItem("cite"); - m_output.addFieldQuotedString("text", cite->text()); + m_output.addFieldQuotedString("text", cite.text()); closeItem(); } @@ -803,30 +775,24 @@ void PerlModDocVisitor::visit(DocCite *cite) // visitor functions for compound nodes //-------------------------------------- -void PerlModDocVisitor::visitPre(DocAutoList *l) +void PerlModDocVisitor::operator()(const DocAutoList &l) { openItem("list"); - m_output.addFieldQuotedString("style", l->isEnumList() ? "ordered" : "itemized"); + m_output.addFieldQuotedString("style", l.isEnumList() ? "ordered" : "itemized"); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocAutoList *) -{ + visitChildren(l); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocAutoListItem *) +void PerlModDocVisitor::operator()(const DocAutoListItem &li) { openSubBlock(); -} - -void PerlModDocVisitor::visitPost(DocAutoListItem *) -{ + visitChildren(li); closeSubBlock(); } -void PerlModDocVisitor::visitPre(DocPara *) +void PerlModDocVisitor::operator()(const DocPara &p) { if (m_textblockstart) m_textblockstart = false; @@ -836,28 +802,22 @@ void PerlModDocVisitor::visitPre(DocPara *) openItem("para"); openSubBlock("content"); */ -} - -void PerlModDocVisitor::visitPost(DocPara *) -{ + visitChildren(p); /* closeSubBlock(); closeItem(); */ } -void PerlModDocVisitor::visitPre(DocRoot *) +void PerlModDocVisitor::operator()(const DocRoot &r) { + visitChildren(r); } -void PerlModDocVisitor::visitPost(DocRoot *) -{ -} - -void PerlModDocVisitor::visitPre(DocSimpleSect *s) +void PerlModDocVisitor::operator()(const DocSimpleSect &s) { const char *type = 0; - switch (s->type()) + switch (s.type()) { case DocSimpleSect::See: type = "see"; break; case DocSimpleSect::Return: type = "return"; break; @@ -884,62 +844,61 @@ void PerlModDocVisitor::visitPre(DocSimpleSect *s) m_output.openHash(); //openOther(); openSubBlock(type); -} - -void PerlModDocVisitor::visitPost(DocSimpleSect *) -{ + if (s.title()) + { + std::visit(*this,*s.title()); + } + visitChildren(s); closeSubBlock(); //closeOther(); m_output.closeHash(); } -void PerlModDocVisitor::visitPre(DocTitle *) +void PerlModDocVisitor::operator()(const DocTitle &t) { openItem("title"); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocTitle *) -{ + visitChildren(t); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocSimpleList *) +void PerlModDocVisitor::operator()(const DocSimpleList &l) { openItem("list"); m_output.addFieldQuotedString("style", "itemized"); openSubBlock("content"); + visitChildren(l); + closeSubBlock(); + closeItem(); } -void PerlModDocVisitor::visitPost(DocSimpleList *) +void PerlModDocVisitor::operator()(const DocSimpleListItem &li) { + openSubBlock(); + if (li.paragraph()) + { + std::visit(*this,*li.paragraph()); + } closeSubBlock(); - closeItem(); } -void PerlModDocVisitor::visitPre(DocSimpleListItem *) { openSubBlock(); } -void PerlModDocVisitor::visitPost(DocSimpleListItem *) { closeSubBlock(); } - -void PerlModDocVisitor::visitPre(DocSection *s) +void PerlModDocVisitor::operator()(const DocSection &s) { - QCString sect = QCString().sprintf("sect%d",s->level()); + QCString sect = QCString().sprintf("sect%d",s.level()); openItem(sect); - m_output.addFieldQuotedString("title", s->title()); + m_output.addFieldQuotedString("title", s.title()); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocSection *) -{ + visitChildren(s); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocHtmlList *l) +void PerlModDocVisitor::operator()(const DocHtmlList &l) { openItem("list"); - m_output.addFieldQuotedString("style", (l->type() == DocHtmlList::Ordered) ? "ordered" : "itemized"); - for (const auto &opt : l->attribs()) + m_output.addFieldQuotedString("style", (l.type() == DocHtmlList::Ordered) ? "ordered" : "itemized"); + for (const auto &opt : l.attribs()) { if (opt.name=="type") { @@ -951,17 +910,14 @@ void PerlModDocVisitor::visitPre(DocHtmlList *l) } } openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocHtmlList *) -{ + visitChildren(l); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocHtmlListItem *l) +void PerlModDocVisitor::operator()(const DocHtmlListItem &l) { - for (const auto &opt : l->attribs()) + for (const auto &opt : l.attribs()) { if (opt.name=="value") { @@ -969,169 +925,130 @@ void PerlModDocVisitor::visitPre(DocHtmlListItem *l) } } openSubBlock(); + visitChildren(l); + closeSubBlock(); } -void PerlModDocVisitor::visitPost(DocHtmlListItem *) { closeSubBlock(); } - -//void PerlModDocVisitor::visitPre(DocHtmlPre *) -//{ -// openItem("preformatted"); -// openSubBlock("content"); -// //m_insidePre=TRUE; -//} - -//void PerlModDocVisitor::visitPost(DocHtmlPre *) -//{ -// //m_insidePre=FALSE; -// closeSubBlock(); -// closeItem(); -//} -void PerlModDocVisitor::visitPre(DocHtmlDescList *) +void PerlModDocVisitor::operator()(const DocHtmlDescList &dl) { #if 0 m_output.add("<variablelist>\n"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlDescList *) -{ + visitChildren(dl); #if 0 m_output.add("</variablelist>\n"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlDescTitle *) +void PerlModDocVisitor::operator()(const DocHtmlDescTitle &dt) { #if 0 m_output.add("<varlistentry><term>"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlDescTitle *) -{ + visitChildren(dt); #if 0 m_output.add("</term></varlistentry>\n"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlDescData *) +void PerlModDocVisitor::operator()(const DocHtmlDescData &dd) { #if 0 m_output.add("<listitem>"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlDescData *) -{ + visitChildren(dd); #if 0 m_output.add("</listitem>\n"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlTable *) +void PerlModDocVisitor::operator()(const DocHtmlTable &t) { #if 0 - m_output.add("<table rows=\""); m_output.add(t->numRows()); - m_output.add("\" cols=\""); m_output.add(t->numCols()); m_output.add("\">"); + m_output.add("<table rows=\""); m_output.add(t.numRows()); + m_output.add("\" cols=\""); m_output.add(t.numCols()); m_output.add("\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlTable *) -{ + if (t.caption()) + { + std::visit(*this,*t.caption()); + } + visitChildren(t); #if 0 m_output.add("</table>\n"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlRow *) +void PerlModDocVisitor::operator()(const DocHtmlRow &r) { #if 0 m_output.add("<row>\n"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlRow *) -{ + visitChildren(r); #if 0 m_output.add("</row>\n"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlCell *) +void PerlModDocVisitor::operator()(const DocHtmlCell &c) { #if 0 - if (c->isHeading()) m_output.add("<entry thead=\"yes\">"); else m_output.add("<entry thead=\"no\">"); + if (c.isHeading()) m_output.add("<entry thead=\"yes\">"); else m_output.add("<entry thead=\"no\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlCell *) -{ + visitChildren(c); #if 0 m_output.add("</entry>"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlCaption *) +void PerlModDocVisitor::operator()(const DocHtmlCaption &c) { #if 0 m_output.add("<caption>"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlCaption *) -{ + visitChildren(c); #if 0 m_output.add("</caption>\n"); #endif } -void PerlModDocVisitor::visitPre(DocInternal *) +void PerlModDocVisitor::operator()(const DocInternal &i) { #if 0 m_output.add("<internal>"); #endif -} - -void PerlModDocVisitor::visitPost(DocInternal *) -{ + visitChildren(i); #if 0 m_output.add("</internal>"); #endif } -void PerlModDocVisitor::visitPre(DocHRef *) +void PerlModDocVisitor::operator()(const DocHRef &href) { #if 0 - m_output.add("<ulink url=\""); m_output.add(href->url()); m_output.add("\">"); + m_output.add("<ulink url=\""); m_output.add(href.url()); m_output.add("\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocHRef *) -{ + visitChildren(href); #if 0 m_output.add("</ulink>"); #endif } -void PerlModDocVisitor::visitPre(DocHtmlHeader *) +void PerlModDocVisitor::operator()(const DocHtmlHeader &header) { #if 0 - m_output.add("<sect"); m_output.add(header->level()); m_output.add(">"); + m_output.add("<sect"); m_output.add(header.level()); m_output.add(">"); #endif -} - -void PerlModDocVisitor::visitPost(DocHtmlHeader *) -{ + visitChildren(header); #if 0 - m_output.add("</sect"); m_output.add(header->level()); m_output.add(">\n"); + m_output.add("</sect"); m_output.add(header.level()); m_output.add(">\n"); #endif } -void PerlModDocVisitor::visitPre(DocImage *) +void PerlModDocVisitor::operator()(const DocImage &img) { #if 0 m_output.add("<image type=\""); - switch(img->type()) + switch(img.type()) { case DocImage::Html: m_output.add("html"); break; case DocImage::Latex: m_output.add("latex"); break; @@ -1139,204 +1056,167 @@ void PerlModDocVisitor::visitPre(DocImage *) } m_output.add("\""); - QCString baseName=img->name(); + QCString baseName=img.name(); int i; if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1) { baseName=baseName.right(baseName.length()-i-1); } m_output.add(" name=\""); m_output.add(baseName); m_output.add("\""); - if (!img->width().isEmpty()) + if (!img.width().isEmpty()) { m_output.add(" width=\""); - m_output.addQuoted(img->width()); + m_output.addQuoted(img.width()); m_output.add("\""); } - else if (!img->height().isEmpty()) + else if (!img.height().isEmpty()) { m_output.add(" height=\""); - m_output.addQuoted(img->height()); + m_output.addQuoted(img.height()); m_output.add("\""); } m_output.add(">"); #endif -} - -void PerlModDocVisitor::visitPost(DocImage *) -{ + visitChildren(img); #if 0 m_output.add("</image>"); #endif } -void PerlModDocVisitor::visitPre(DocDotFile *) +void PerlModDocVisitor::operator()(const DocDotFile &df) { #if 0 m_output.add("<dotfile name=\""); m_output.add(df->file()); m_output.add("\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocDotFile *) -{ + visitChildren(df); #if 0 m_output.add("</dotfile>"); #endif } -void PerlModDocVisitor::visitPre(DocMscFile *) +void PerlModDocVisitor::operator()(const DocMscFile &df) { #if 0 m_output.add("<mscfile name=\""); m_output.add(df->file()); m_output.add("\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocMscFile *) -{ + visitChildren(df); #if 0 m_output.add("<mscfile>"); #endif } -void PerlModDocVisitor::visitPre(DocDiaFile *) +void PerlModDocVisitor::operator()(const DocDiaFile &df) { #if 0 m_output.add("<diafile name=\""); m_output.add(df->file()); m_output.add("\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocDiaFile *) -{ + visitChildren(df); #if 0 m_output.add("</diafile>"); #endif } -void PerlModDocVisitor::visitPre(DocLink *lnk) +void PerlModDocVisitor::operator()(const DocLink &lnk) { openItem("link"); - addLink(lnk->ref(), lnk->file(), lnk->anchor()); -} - -void PerlModDocVisitor::visitPost(DocLink *) -{ + addLink(lnk.ref(), lnk.file(), lnk.anchor()); + visitChildren(lnk); closeItem(); } -void PerlModDocVisitor::visitPre(DocRef *ref) +void PerlModDocVisitor::operator()(const DocRef &ref) { openItem("ref"); - if (!ref->hasLinkText()) - m_output.addFieldQuotedString("text", ref->targetTitle()); + if (!ref.hasLinkText()) + m_output.addFieldQuotedString("text", ref.targetTitle()); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocRef *) -{ + visitChildren(ref); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocSecRefItem *) +void PerlModDocVisitor::operator()(const DocSecRefItem &ref) { #if 0 m_output.add("<tocitem id=\""); m_output.add(ref->file()); m_output.add("_1"); m_output.add(ref->anchor()); m_output.add("\">"); #endif -} - -void PerlModDocVisitor::visitPost(DocSecRefItem *) -{ + visitChildren(ref); #if 0 m_output.add("</tocitem>"); #endif } -void PerlModDocVisitor::visitPre(DocSecRefList *) +void PerlModDocVisitor::operator()(const DocSecRefList &l) { #if 0 m_output.add("<toclist>"); #endif -} - -void PerlModDocVisitor::visitPost(DocSecRefList *) -{ + visitChildren(l); #if 0 m_output.add("</toclist>"); #endif } -//void PerlModDocVisitor::visitPre(DocLanguage *l) -//{ -// openItem("language"); -// m_output.addFieldQuotedString("id", l->id()); -//} -// -//void PerlModDocVisitor::visitPost(DocLanguage *) -//{ -// closeItem(); -//} - -void PerlModDocVisitor::visitPre(DocParamSect *s) +void PerlModDocVisitor::operator()(const DocParamSect &s) { leaveText(); const char *type = 0; - switch(s->type()) - { - case DocParamSect::Param: type = "params"; break; - case DocParamSect::RetVal: type = "retvals"; break; - case DocParamSect::Exception: type = "exceptions"; break; - case DocParamSect::TemplateParam: type = "templateparam"; break; - case DocParamSect::Unknown: - err("unknown parameter section found\n"); - break; + switch(s.type()) + { + case DocParamSect::Param: type = "params"; break; + case DocParamSect::RetVal: type = "retvals"; break; + case DocParamSect::Exception: type = "exceptions"; break; + case DocParamSect::TemplateParam: type = "templateparam"; break; + case DocParamSect::Unknown: + err("unknown parameter section found\n"); + break; } m_output.openHash(); //openOther(); openSubBlock(type); -} - -void PerlModDocVisitor::visitPost(DocParamSect *) -{ + visitChildren(s); closeSubBlock(); //closeOther(); m_output.closeHash(); } -void PerlModDocVisitor::visitPre(DocParamList *pl) +void PerlModDocVisitor::operator()(const DocSeparator &) +{ +} + +void PerlModDocVisitor::operator()(const DocParamList &pl) { leaveText(); - m_output.openHash() - .openList("parameters"); - for (const auto ¶m : pl->parameters()) + m_output.openHash().openList("parameters"); + for (const auto ¶m : pl.parameters()) { QCString name; - if (param->kind()==DocNode::Kind_Word) + const DocWord *word = std::get_if<DocWord>(¶m); + const DocLinkedWord *linkedWord = std::get_if<DocLinkedWord>(¶m); + if (word) { - name = ((DocWord*)param.get())->word(); + name = word->word(); } - else if (param->kind()==DocNode::Kind_LinkedWord) + else if (linkedWord) { - name = ((DocLinkedWord*)param.get())->word(); + name = linkedWord->word(); } QCString dir = ""; - DocParamSect *sect = 0; - if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) - { - sect=(DocParamSect*)pl->parent(); - } + const DocParamSect *sect = std::get_if<DocParamSect>(pl.parent()); if (sect && sect->hasInOutSpecifier()) { - if (pl->direction()!=DocParamSect::Unspecified) + if (pl.direction()!=DocParamSect::Unspecified) { - if (pl->direction()==DocParamSect::In) + if (pl.direction()==DocParamSect::In) { dir = "in"; } - else if (pl->direction()==DocParamSect::Out) + else if (pl.direction()==DocParamSect::Out) { dir = "out"; } - else if (pl->direction()==DocParamSect::InOut) + else if (pl.direction()==DocParamSect::InOut) { dir = "in,out"; } @@ -1349,16 +1229,16 @@ void PerlModDocVisitor::visitPre(DocParamList *pl) } m_output.closeList() .openList("doc"); -} - -void PerlModDocVisitor::visitPost(DocParamList *) -{ + for (const auto &par : pl.paragraphs()) + { + std::visit(*this,par); + } leaveText(); m_output.closeList() .closeHash(); } -void PerlModDocVisitor::visitPre(DocXRefItem *x) +void PerlModDocVisitor::operator()(const DocXRefItem &x) { #if 0 m_output.add("<xrefsect id=\""); @@ -1369,14 +1249,11 @@ void PerlModDocVisitor::visitPre(DocXRefItem *x) m_output.add("</xreftitle>"); m_output.add("<xrefdescription>"); #endif - if (x->title().isEmpty()) return; + if (x.title().isEmpty()) return; openItem("xrefitem"); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocXRefItem *x) -{ - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; closeSubBlock(); closeItem(); #if 0 @@ -1385,53 +1262,37 @@ void PerlModDocVisitor::visitPost(DocXRefItem *x) #endif } -void PerlModDocVisitor::visitPre(DocInternalRef *ref) +void PerlModDocVisitor::operator()(const DocInternalRef &ref) { openItem("ref"); - addLink(QCString(),ref->file(),ref->anchor()); + addLink(QCString(),ref.file(),ref.anchor()); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocInternalRef *) -{ + visitChildren(ref); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocText *) -{ -} - -void PerlModDocVisitor::visitPost(DocText *) +void PerlModDocVisitor::operator()(const DocText &t) { + visitChildren(t); } -void PerlModDocVisitor::visitPre(DocHtmlBlockQuote *) +void PerlModDocVisitor::operator()(const DocHtmlBlockQuote &q) { openItem("blockquote"); openSubBlock("content"); -} - -void PerlModDocVisitor::visitPost(DocHtmlBlockQuote *) -{ + visitChildren(q); closeSubBlock(); closeItem(); } -void PerlModDocVisitor::visitPre(DocVhdlFlow *) -{ -} - -void PerlModDocVisitor::visitPost(DocVhdlFlow *) +void PerlModDocVisitor::operator()(const DocVhdlFlow &) { } -void PerlModDocVisitor::visitPre(DocParBlock *) -{ -} - -void PerlModDocVisitor::visitPost(DocParBlock *) +void PerlModDocVisitor::operator()(const DocParBlock &pb) { + visitChildren(pb); } @@ -1474,16 +1335,23 @@ static void addPerlModDocBlock(PerlModOutput &output, { QCString stext = text.stripWhiteSpace(); if (stext.isEmpty()) + { output.addField(name).add("{}"); - else { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> root { validatingParseDoc(*parser.get(), - fileName,lineNr,scope,md,stext,FALSE,FALSE, - QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + } + else + { + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + fileName,lineNr,scope,md,stext,FALSE,FALSE, + QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; output.openHash(name); - auto visitor = std::make_unique<PerlModDocVisitor>(output); - root->accept(visitor.get()); - visitor->finish(); + auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get()); + if (astImpl) + { + PerlModDocVisitor visitor(output); + std::visit(visitor,astImpl->root); + visitor.finish(); + } output.closeHash(); } } @@ -1768,8 +1636,6 @@ void PerlModGenerator::addListOfAllMembers(const ClassDef *cd) { const MemberDef *md=mi->memberDef(); const ClassDef *mcd=md->getClassDef(); - const Definition *d=md->getGroupDef(); - if (d==0) d = mcd; m_output.openHash() .addFieldQuotedString("name", md->name()) @@ -2183,7 +2049,7 @@ void PerlModGenerator::generatePerlModForPage(PageDef *pd) const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) - m_output.addFieldQuotedString("title4", filterTitle(si->title().str())); + m_output.addFieldQuotedString("title4", filterTitle(si->title())); addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation()); m_output.closeHash(); diff --git a/src/plantuml.cpp b/src/plantuml.cpp index fed8b67..33c7d1e 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -143,7 +143,6 @@ static void runPlantumlContent(const PlantumlManager::FilesMap &plantumlFiles, int exitCode; QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); - QCString dotPath = Config_getString(DOT_PATH); QCString pumlExe = "java"; QCString pumlArgs = ""; @@ -174,12 +173,14 @@ static void runPlantumlContent(const PlantumlManager::FilesMap &plantumlFiles, pumlArgs += plantumlConfigFile; pumlArgs += "\" "; } - if (Config_getBool(HAVE_DOT) && !dotPath.isEmpty()) + // the -graphvizdot option expects a relative or absolute path to the dot executable, so + // we need to use the unverified DOT_PATH option and check if it points to an existing file. + QCString dotPath = Config_getString(DOT_PATH); + FileInfo dp(dotPath.str()); + if (Config_getBool(HAVE_DOT) && dp.exists() && dp.isFile()) { pumlArgs += "-graphvizdot \""; pumlArgs += dotPath; - pumlArgs += "dot"; - pumlArgs += Portable::commandExtension(); pumlArgs += "\" "; } switch (format) diff --git a/src/portable.cpp b/src/portable.cpp index 60c5189..c18011b 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -105,12 +105,8 @@ int Portable::system(const QCString &command,const QCString &args,bool commandHa } if (pid==0) { - const char * argv[4]; - argv[0] = "sh"; - argv[1] = "-c"; - argv[2] = fullCmd.data(); - argv[3] = 0; - execve("/bin/sh",(char * const *)argv,environ); + const char * const argv[4] = { "sh", "-c", fullCmd.data(), 0 }; + execve("/bin/sh",const_cast<char * const*>(argv),environ); exit(127); } for (;;) @@ -208,9 +204,9 @@ unsigned int Portable::pid() { unsigned int pid; #if !defined(_WIN32) || defined(__CYGWIN__) - pid = (unsigned int)getpid(); + pid = static_cast<unsigned int>(getpid()); #else - pid = (unsigned int)GetCurrentProcessId(); + pid = static_cast<unsigned int>(GetCurrentProcessId()); #endif return pid; } @@ -605,14 +601,14 @@ size_t Portable::recodeUtf8StringToW(const QCString &inputStr,uint16_t **outBuf) { if (inputStr.isEmpty() || outBuf==0) return 0; // empty input or invalid output void *handle = portable_iconv_open("UTF-16LE","UTF-8"); - if (handle==(void *)(-1)) return 0; // invalid encoding + if (handle==reinterpret_cast<void *>(-1)) return 0; // invalid encoding size_t len = inputStr.length(); uint16_t *buf = new uint16_t[len+1]; *outBuf = buf; size_t inRemains = len; size_t outRemains = len*sizeof(uint16_t)+2; // chars + \0 const char *p = inputStr.data(); - portable_iconv(handle,&p,&inRemains,(char**)&buf,&outRemains); + portable_iconv(handle,&p,&inRemains,reinterpret_cast<char **>(&buf),&outRemains); *buf=0; portable_iconv_close(handle); return len; @@ -292,6 +292,7 @@ struct preYY_state QCString blockName; int condCtx = 0; bool skip = false; + bool insideIDL = false; bool insideCS = false; // C# has simpler preprocessor bool insideFtn = false; bool isSource = false; @@ -415,6 +416,7 @@ WSopt [ \t\r]* %x CondLineC %x CondLineCpp %x SkipCond +%x IDLquote %% @@ -435,6 +437,32 @@ WSopt [ \t\r]* outputArray(yyscanner,yytext,yyleng); BEGIN(LexCopyLine); } +<Start>^{Bopt}"cpp_quote"{Bopt}"("{Bopt}\" { + if (yyextra->insideIDL) + { + BEGIN(IDLquote); + } + else + { + REJECT; + } + } +<IDLquote>"\\\\" { + outputArray(yyscanner,"\\",1); + } +<IDLquote>"\\\"" { + outputArray(yyscanner,"\"",1); + } +<IDLquote>"\""{Bopt}")" { + BEGIN(Start); + } +<IDLquote>\n { + outputChar(yyscanner,'\n'); + yyextra->yyLineNr++; + } +<IDLquote>. { + outputArray(yyscanner,yytext,yyleng); + } <Start>^{Bopt}/[^#] { outputArray(yyscanner,yytext,yyleng); BEGIN(CopyLine); @@ -1764,7 +1792,7 @@ WSopt [ \t\r]* } <*>{CCS}/{CCE} | <*>{CCS}[*!]? { - if (YY_START==SkipVerbatim || YY_START==SkipCond) + if (YY_START==SkipVerbatim || YY_START==SkipCond || YY_START==IDLquote) { REJECT; } @@ -1786,7 +1814,7 @@ WSopt [ \t\r]* } } <*>{CPPC}[/!]? { - if (YY_START==SkipVerbatim || YY_START==SkipCond || getLanguageFromFileName(yyextra->fileName)==SrcLangExt_Fortran) + if (YY_START==SkipVerbatim || YY_START==SkipCond || getLanguageFromFileName(yyextra->fileName)==SrcLangExt_Fortran || YY_START==IDLquote) { REJECT; } @@ -1844,6 +1872,7 @@ static void setFileName(yyscan_t yyscanner,const QCString &name) //printf("setFileName(%s) state->fileName=%s state->yyFileDef=%p\n", // name,qPrint(state->fileName),state->yyFileDef); if (state->yyFileDef && state->yyFileDef->isReference()) state->yyFileDef=0; + state->insideIDL = getLanguageFromFileName(state->fileName)==SrcLangExt_IDL; state->insideCS = getLanguageFromFileName(state->fileName)==SrcLangExt_CSharp; state->insideFtn = getLanguageFromFileName(state->fileName)==SrcLangExt_Fortran; state->isSource = guessSection(state->fileName); @@ -3559,7 +3588,7 @@ void Preprocessor::processFile(const QCString &fileName,BufStr &input,BufStr &ou #endif printlex(yy_flex_debug, TRUE, __FILE__, qPrint(fileName)); - uint orgOffset=output.curPos(); + size_t orgOffset=output.curPos(); //printf("##########################\n%s\n####################\n", // qPrint(input)); diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index 1424e63..e5e801b 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -19,155 +19,153 @@ #ifndef PRINTDOCVISITOR_H #define PRINTDOCVISITOR_H -#include "docvisitor.h" #include "htmlentity.h" #include "emoji.h" #include "message.h" -/*! Concrete visitor implementation for pretty printing */ -class PrintDocVisitor : public DocVisitor +/*! Visitor implementation for pretty printing */ +class PrintDocVisitor { public: - PrintDocVisitor() : DocVisitor(DocVisitor_Other), m_indent(0), - m_needsEnter(FALSE), m_insidePre(FALSE) {} + PrintDocVisitor() : m_indent(0), m_needsEnter(FALSE), m_insidePre(FALSE) {} //-------------------------------------- - void visit(DocWord *w) + void operator()(const DocWord &w) { indent_leaf(); - printf("%s",qPrint(w->word())); + printf("%s",qPrint(w.word())); } - void visit(DocLinkedWord *w) + void operator()(const DocLinkedWord &w) { indent_leaf(); - printf("%s",qPrint(w->word())); + printf("%s",qPrint(w.word())); } - void visit(DocWhiteSpace *w) + void operator()(const DocWhiteSpace &w) { indent_leaf(); if (m_insidePre) { - printf("%s",qPrint(w->chars())); + printf("%s",qPrint(w.chars())); } else { printf(" "); } } - void visit(DocSymbol *s) + void operator()(const DocSymbol &s) { indent_leaf(); - const char *res = HtmlEntityMapper::instance()->utf8(s->symbol(),TRUE); + const char *res = HtmlEntityMapper::instance()->utf8(s.symbol(),TRUE); if (res) { printf("%s",res); } else { - printf("print: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + printf("print: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } } - void visit(DocEmoji *s) + void operator()(const DocEmoji &s) { indent_leaf(); - const char *res = EmojiEntityMapper::instance()->name(s->index()); + const char *res = EmojiEntityMapper::instance()->name(s.index()); if (res) { printf("%s",res); } else { - printf("print: non supported emoji found: %s\n",qPrint(s->name())); + printf("print: non supported emoji found: %s\n",qPrint(s.name())); } } - void visit(DocURL *u) + void operator()(const DocURL &u) { indent_leaf(); - printf("%s",qPrint(u->url())); + printf("%s",qPrint(u.url())); } - void visit(DocLineBreak *) + void operator()(const DocLineBreak &) { indent_leaf(); printf("<br/>"); } - void visit(DocHorRuler *) + void operator()(const DocHorRuler &) { indent_leaf(); printf("<hr>"); } - void visit(DocStyleChange *s) + void operator()(const DocStyleChange &s) { indent_leaf(); - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) printf("<bold>"); else printf("</bold>"); + if (s.enable()) printf("<bold>"); else printf("</bold>"); break; case DocStyleChange::S: - if (s->enable()) printf("<s>"); else printf("</s>"); + if (s.enable()) printf("<s>"); else printf("</s>"); break; case DocStyleChange::Strike: - if (s->enable()) printf("<strike>"); else printf("</strike>"); + if (s.enable()) printf("<strike>"); else printf("</strike>"); break; case DocStyleChange::Del: - if (s->enable()) printf("<del>"); else printf("</del>"); + if (s.enable()) printf("<del>"); else printf("</del>"); break; case DocStyleChange::Underline: - if (s->enable()) printf("<underline>"); else printf("</underline>"); + if (s.enable()) printf("<underline>"); else printf("</underline>"); break; case DocStyleChange::Ins: - if (s->enable()) printf("<ins>"); else printf("</ins>"); + if (s.enable()) printf("<ins>"); else printf("</ins>"); break; case DocStyleChange::Italic: - if (s->enable()) printf("<italic>"); else printf("</italic>"); + if (s.enable()) printf("<italic>"); else printf("</italic>"); break; case DocStyleChange::Code: - if (s->enable()) printf("<code>"); else printf("</code>"); + if (s.enable()) printf("<code>"); else printf("</code>"); break; case DocStyleChange::Subscript: - if (s->enable()) printf("<sub>"); else printf("</sub>"); + if (s.enable()) printf("<sub>"); else printf("</sub>"); break; case DocStyleChange::Superscript: - if (s->enable()) printf("<sup>"); else printf("</sup>"); + if (s.enable()) printf("<sup>"); else printf("</sup>"); break; case DocStyleChange::Center: - if (s->enable()) printf("<center>"); else printf("</center>"); + if (s.enable()) printf("<center>"); else printf("</center>"); break; case DocStyleChange::Small: - if (s->enable()) printf("<small>"); else printf("</small>"); + if (s.enable()) printf("<small>"); else printf("</small>"); break; case DocStyleChange::Cite: - if (s->enable()) printf("<cite>"); else printf("</cite>"); + if (s.enable()) printf("<cite>"); else printf("</cite>"); break; case DocStyleChange::Preformatted: - if (s->enable()) printf("<pre>"); else printf("</pre>"); + if (s.enable()) printf("<pre>"); else printf("</pre>"); break; case DocStyleChange::Div: - if (s->enable()) printf("<div>"); else printf("</div>"); + if (s.enable()) printf("<div>"); else printf("</div>"); break; case DocStyleChange::Span: - if (s->enable()) printf("<span>"); else printf("</span>"); + if (s.enable()) printf("<span>"); else printf("</span>"); break; case DocStyleChange::Details: - if (s->enable()) + if (s.enable()) { indent_pre(); - printf("<details>\n"); + printf("<details>\n"); } - else + else { indent_post(); printf("</details>\n"); } break; case DocStyleChange::Summary: - if (s->enable()) + if (s.enable()) { indent_pre(); - printf("<summary>\n"); + printf("<summary>\n"); } - else + else { indent_post(); printf("</summary>\n"); @@ -175,10 +173,10 @@ class PrintDocVisitor : public DocVisitor break; } } - void visit(DocVerbatim *s) + void operator()(const DocVerbatim &s) { indent_leaf(); - switch(s->type()) + switch(s.type()) { case DocVerbatim::Code: printf("<code>"); break; case DocVerbatim::Verbatim: printf("<verbatim>"); break; @@ -194,8 +192,8 @@ class PrintDocVisitor : public DocVisitor case DocVerbatim::Msc: printf("<msc>"); break; case DocVerbatim::PlantUML: printf("<plantuml>"); break; } - printf("%s",qPrint(s->text())); - switch(s->type()) + printf("%s",qPrint(s.text())); + switch(s.type()) { case DocVerbatim::Code: printf("</code>"); break; case DocVerbatim::Verbatim: printf("</verbatim>"); break; @@ -212,16 +210,16 @@ class PrintDocVisitor : public DocVisitor case DocVerbatim::PlantUML: printf("</plantuml>"); break; } } - void visit(DocAnchor *a) + void operator()(const DocAnchor &a) { indent_leaf(); - printf("<anchor name=\"%s\"/>",qPrint(a->anchor())); + printf("<anchor name=\"%s\"/>",qPrint(a.anchor())); } - void visit(DocInclude *inc) + void operator()(const DocInclude &inc) { indent_leaf(); - printf("<include file=\"%s\" type=\"",qPrint(inc->file())); - switch(inc->type()) + printf("<include file=\"%s\" type=\"",qPrint(inc.file())); + switch(inc.type()) { case DocInclude::Include: printf("include"); break; case DocInclude::IncWithLines: printf("incwithlines"); break; @@ -229,7 +227,7 @@ class PrintDocVisitor : public DocVisitor case DocInclude::DontIncWithLines: printf("dontinwithlines"); break; case DocInclude::HtmlInclude: printf("htmlinclude"); - if (inc->isBlock()) printf(" block=\"yes\""); + if (inc.isBlock()) printf(" block=\"yes\""); break; case DocInclude::LatexInclude: printf("latexinclude"); break; case DocInclude::RtfInclude: printf("rtfinclude"); break; @@ -247,11 +245,11 @@ class PrintDocVisitor : public DocVisitor } printf("\"/>"); } - void visit(DocIncOperator *op) + void operator()(const DocIncOperator &op) { indent_leaf(); - printf("<incoperator pattern=\"%s\" type=\"",qPrint(op->pattern())); - switch(op->type()) + printf("<incoperator pattern=\"%s\" type=\"",qPrint(op.pattern())); + switch(op.type()) { case DocIncOperator::Line: printf("line"); break; case DocIncOperator::Skip: printf("skip"); break; @@ -260,37 +258,50 @@ class PrintDocVisitor : public DocVisitor } printf("\"/>"); } - void visit(DocFormula *f) + void operator()(const DocFormula &f) { indent_leaf(); - printf("<formula name=%s text=%s/>",qPrint(f->name()),qPrint(f->text())); + printf("<formula name=%s text=%s/>",qPrint(f.name()),qPrint(f.text())); } - void visit(DocIndexEntry *i) + void operator()(const DocIndexEntry &i) { indent_leaf(); - printf("<indexentry>%s</indexentry\n",qPrint(i->entry())); + printf("<indexentry>%s</indexentry\n",qPrint(i.entry())); } - void visit(DocSimpleSectSep *) + void operator()(const DocSimpleSectSep &) { indent_leaf(); printf("<simplesectsep/>"); } - void visit(DocCite *cite) + void operator()(const DocCite &cite) { indent_leaf(); printf("<cite ref=\"%s\" file=\"%s\" " "anchor=\"%s\" text=\"%s\"" "/>\n", - qPrint(cite->ref()),qPrint(cite->file()),qPrint(cite->anchor()), - qPrint(cite->text())); + qPrint(cite.ref()),qPrint(cite.file()),qPrint(cite.anchor()), + qPrint(cite.text())); + } + void operator()(const DocSeparator &) + { + indent_leaf(); + printf("<sep/>"); } //-------------------------------------- + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } - void visitPre(DocAutoList *l) + void operator()(const DocAutoList &l) { indent_pre(); - if (l->isEnumList()) + if (l.isEnumList()) { printf("<ol>\n"); } @@ -298,11 +309,9 @@ class PrintDocVisitor : public DocVisitor { printf("<ul>\n"); } - } - void visitPost(DocAutoList *l) - { + visitChildren(l); indent_post(); - if (l->isEnumList()) + if (l.isEnumList()) { printf("</ol>\n"); } @@ -311,41 +320,35 @@ class PrintDocVisitor : public DocVisitor printf("</ul>\n"); } } - void visitPre(DocAutoListItem *) + void operator()(const DocAutoListItem &li) { indent_pre(); printf("<li>\n"); - } - void visitPost(DocAutoListItem *) - { + visitChildren(li); indent_post(); printf("</li>\n"); } - void visitPre(DocPara *) + void operator()(const DocPara &p) { indent_pre(); printf("<para>\n"); - } - void visitPost(DocPara *) - { + visitChildren(p); indent_post(); printf("</para>\n"); } - void visitPre(DocRoot *) + void operator()(const DocRoot &r) { indent_pre(); printf("<root>\n"); - } - void visitPost(DocRoot *) - { + visitChildren(r); indent_post(); printf("</root>\n"); } - void visitPre(DocSimpleSect *s) + void operator()(const DocSimpleSect &s) { indent_pre(); printf("<simplesect type="); - switch(s->type()) + switch(s.type()) { case DocSimpleSect::See: printf("see"); break; case DocSimpleSect::Return: printf("return"); break; @@ -367,205 +370,179 @@ class PrintDocVisitor : public DocVisitor case DocSimpleSect::Unknown: printf("unknown"); break; } printf(">\n"); - } - void visitPost(DocSimpleSect *) - { + if (s.title()) + { + std::visit(*this, *s.title()); + } + visitChildren(s); indent_post(); printf("</simplesect>\n"); } - void visitPre(DocTitle *) + void operator()(const DocTitle &t) { indent_pre(); printf("<title>\n"); - } - void visitPost(DocTitle *) - { + visitChildren(t); indent_post(); printf("</title>\n"); } - void visitPre(DocSimpleList *) + void operator()(const DocSimpleList &l) { indent_pre(); printf("<ul>\n"); - } - void visitPost(DocSimpleList *) - { + visitChildren(l); indent_post(); printf("</ul>\n"); } - void visitPre(DocSimpleListItem *) + void operator()(const DocSimpleListItem &li) { indent_pre(); printf("<li>\n"); - } - void visitPost(DocSimpleListItem *) - { + if (li.paragraph()) + { + visit(*this,*li.paragraph()); + } indent_post(); printf("</li>\n"); } - void visitPre(DocSection *s) + void operator()(const DocSection &s) { indent_pre(); - printf("<sect%d>\n",s->level()); - } - void visitPost(DocSection *s) - { + printf("<sect%d>\n",s.level()); + visitChildren(s); indent_post(); - printf("</sect%d>\n",s->level()); + printf("</sect%d>\n",s.level()); } - void visitPre(DocHtmlList *s) + void operator()(const DocHtmlList &s) { indent_pre(); - if (s->type()==DocHtmlList::Ordered) + if (s.type()==DocHtmlList::Ordered) { printf("<ol"); - for (const auto &opt : s->attribs()) + for (const auto &opt : s.attribs()) { printf(" %s=\"%s\"",qPrint(opt.name),qPrint(opt.value)); } printf(">\n"); } - else printf("<ul>\n"); - - } - void visitPost(DocHtmlList *s) - { + else + { + printf("<ul>\n"); + } + visitChildren(s); indent_post(); - if (s->type()==DocHtmlList::Ordered) printf("</ol>\n"); else printf("</ul>\n"); + if (s.type()==DocHtmlList::Ordered) + { + printf("</ol>\n"); + } + else + { + printf("</ul>\n"); + } } - void visitPre(DocHtmlListItem *s) + void operator()(const DocHtmlListItem &li) { indent_pre(); printf("<li"); - for (const auto &opt : s->attribs()) + for (const auto &opt : li.attribs()) { printf(" %s=\"%s\"",qPrint(opt.name),qPrint(opt.value)); } printf(">\n"); - } - void visitPost(DocHtmlListItem *) - { + visitChildren(li); indent_post(); printf("</li>\n"); } - //void visitPre(DocHtmlPre *) - //{ - // indent_pre(); - // printf("<pre>\n"); - // m_insidePre=TRUE; - //} - //void visitPost(DocHtmlPre *) - //{ - // m_insidePre=FALSE; - // indent_post(); - // printf("</pre>\n"); - //} - void visitPre(DocHtmlDescList *) + void operator()(const DocHtmlDescList &l) { indent_pre(); printf("<dl>\n"); - } - void visitPost(DocHtmlDescList *) - { + visitChildren(l); indent_post(); printf("</dl>\n"); } - void visitPre(DocHtmlDescTitle *) + void operator()(const DocHtmlDescTitle &dt) { indent_pre(); printf("<dt>\n"); - } - void visitPost(DocHtmlDescTitle *) - { + visitChildren(dt); indent_post(); printf("</dt>\n"); } - void visitPre(DocHtmlDescData *) + void operator()(const DocHtmlDescData &dd) { indent_pre(); printf("<dd>\n"); - } - void visitPost(DocHtmlDescData *) - { + visitChildren(dd); indent_post(); printf("</dd>\n"); } - void visitPre(DocHtmlTable *t) + void operator()(const DocHtmlTable &t) { indent_pre(); printf("<table rows=\"%zu\" cols=\"%zu\">\n", - t->numRows(),t->numColumns()); - } - void visitPost(DocHtmlTable *) - { + t.numRows(),t.numColumns()); + visitChildren(t); + if (t.caption()) + { + std::visit(*this, *t.caption()); + } indent_post(); printf("</table>\n"); } - void visitPre(DocHtmlRow *) + void operator()(const DocHtmlRow &tr) { indent_pre(); printf("<tr>\n"); - } - void visitPost(DocHtmlRow *) - { + visitChildren(tr); indent_post(); printf("</tr>\n"); } - void visitPre(DocHtmlCell *c) + void operator()(const DocHtmlCell &c) { indent_pre(); - printf("<t%c>\n",c->isHeading()?'h':'d'); - } - void visitPost(DocHtmlCell *c) - { + printf("<t%c>\n",c.isHeading()?'h':'d'); + visitChildren(c); indent_post(); - printf("</t%c>\n",c->isHeading()?'h':'d'); + printf("</t%c>\n",c.isHeading()?'h':'d'); } - void visitPre(DocHtmlCaption *) + void operator()(const DocHtmlCaption &c) { indent_pre(); printf("<caption>\n"); - } - void visitPost(DocHtmlCaption *) - { + visitChildren(c); indent_post(); printf("</caption>\n"); } - void visitPre(DocInternal *) + void operator()(const DocInternal &i) { indent_pre(); printf("<internal>\n"); - } - void visitPost(DocInternal *) - { + visitChildren(i); indent_post(); printf("</internal>\n"); } - void visitPre(DocHRef *href) + void operator()(const DocHRef &href) { indent_pre(); - printf("<a url=\"%s\">\n",qPrint(href->url())); - } - void visitPost(DocHRef *) - { + printf("<a url=\"%s\">\n",qPrint(href.url())); + visitChildren(href); indent_post(); printf("</a>\n"); } - void visitPre(DocHtmlHeader *header) + void operator()(const DocHtmlHeader &header) { indent_pre(); - printf("<h%d>\n",header->level()); - } - void visitPost(DocHtmlHeader *header) - { + printf("<h%d>\n",header.level()); + visitChildren(header); indent_post(); - printf("</h%d>\n",header->level()); + printf("</h%d>\n",header.level()); } - void visitPre(DocImage *img) + void operator()(const DocImage &img) { indent_pre(); - printf("<image src=\"%s\" type=\"",qPrint(img->name())); - switch(img->type()) + printf("<image src=\"%s\" type=\"",qPrint(img.name())); + switch(img.type()) { case DocImage::Html: printf("html"); break; case DocImage::Latex: printf("latex"); break; @@ -573,137 +550,96 @@ class PrintDocVisitor : public DocVisitor case DocImage::DocBook: printf("docbook"); break; case DocImage::Xml: printf("xml"); break; } - printf("\" %s %s inline=\"%s\">\n",qPrint(img->width()),qPrint(img->height()),img->isInlineImage() ? "yes" : "no"); - } - void visitPost(DocImage *) - { + printf("\" %s %s inline=\"%s\">\n",qPrint(img.width()),qPrint(img.height()),img.isInlineImage() ? "yes" : "no"); + visitChildren(img); indent_post(); printf("</image>\n"); } - void visitPre(DocDotFile *df) + void operator()(const DocDotFile &df) { indent_pre(); - printf("<dotfile src=\"%s\">\n",qPrint(df->name())); - } - void visitPost(DocDotFile *) - { + printf("<dotfile src=\"%s\">\n",qPrint(df.name())); + visitChildren(df); indent_post(); printf("</dotfile>\n"); } - void visitPre(DocMscFile *df) + void operator()(const DocMscFile &df) { indent_pre(); - printf("<mscfile src=\"%s\">\n",qPrint(df->name())); - } - void visitPost(DocMscFile *) - { + printf("<mscfile src=\"%s\">\n",qPrint(df.name())); + visitChildren(df); indent_post(); printf("</mscfile>\n"); } - void visitPre(DocDiaFile *df) + void operator()(const DocDiaFile &df) { indent_pre(); - printf("<diafile src=\"%s\">\n",qPrint(df->name())); - } - void visitPost(DocDiaFile *) - { + printf("<diafile src=\"%s\">\n",qPrint(df.name())); + visitChildren(df); indent_post(); printf("</diafile>\n"); } - void visitPre(DocLink *lnk) + void operator()(const DocLink &lnk) { indent_pre(); printf("<link ref=\"%s\" file=\"%s\" anchor=\"%s\">\n", - qPrint(lnk->ref()),qPrint(lnk->file()),qPrint(lnk->anchor())); - } - void visitPost(DocLink *) - { + qPrint(lnk.ref()),qPrint(lnk.file()),qPrint(lnk.anchor())); + visitChildren(lnk); indent_post(); printf("</link>\n"); } - void visitPre(DocRef *ref) + void operator()(const DocRef &ref) { indent_pre(); printf("<ref ref=\"%s\" file=\"%s\" " "anchor=\"%s\" targetTitle=\"%s\"" " hasLinkText=\"%s\" refToAnchor=\"%s\" refToSection=\"%s\" refToTable=\"%s\">\n", - qPrint(ref->ref()),qPrint(ref->file()),qPrint(ref->anchor()), - qPrint(ref->targetTitle()),ref->hasLinkText()?"yes":"no", - ref->refToAnchor()?"yes":"no", ref->refToSection()?"yes":"no", - ref->refToTable()?"yes":"no"); - } - void visitPost(DocRef *) - { + qPrint(ref.ref()),qPrint(ref.file()),qPrint(ref.anchor()), + qPrint(ref.targetTitle()),ref.hasLinkText()?"yes":"no", + ref.refToAnchor()?"yes":"no", ref.refToSection()?"yes":"no", + ref.refToTable()?"yes":"no"); + visitChildren(ref); indent_post(); printf("</ref>\n"); } - void visitPre(DocSecRefItem *ref) + void operator()(const DocSecRefItem &ref) { indent_pre(); - printf("<secrefitem target=\"%s\">\n",qPrint(ref->target())); - } - void visitPost(DocSecRefItem *) - { + printf("<secrefitem target=\"%s\">\n",qPrint(ref.target())); + visitChildren(ref); indent_post(); printf("</secrefitem>\n"); } - void visitPre(DocSecRefList *) + void operator()(const DocSecRefList &rl) { indent_pre(); printf("<secreflist>\n"); - } - void visitPost(DocSecRefList *) - { + visitChildren(rl); indent_post(); printf("</secreflist>\n"); } - //void visitPre(DocLanguage *l) - //{ - // indent_pre(); - // printf("<language id=%s>\n",qPrint(l->id())); - //} - //void visitPost(DocLanguage *) - //{ - // indent_post(); - // printf("</language>\n"); - //} - void visitPre(DocParamList *pl) + void operator()(const DocParamList &pl) { indent_pre(); printf("<parameters>"); - if (!pl->parameters().empty()) + if (!pl.parameters().empty()) { printf("<param>"); - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_Sep) - { - printf("</param>"); - printf("<param>"); - } + std::visit(*this,param); } printf("</param>"); } printf("\n"); - } - void visitPost(DocParamList *) - { indent_post(); printf("</parameters>\n"); } - void visitPre(DocParamSect *ps) + void operator()(const DocParamSect &ps) { indent_pre(); printf("<paramsect type="); - switch (ps->type()) + switch (ps.type()) { case DocParamSect::Param: printf("param"); break; case DocParamSect::RetVal: printf("retval"); break; @@ -712,70 +648,56 @@ class PrintDocVisitor : public DocVisitor case DocParamSect::Unknown: printf("unknown"); break; } printf(">\n"); - } - void visitPost(DocParamSect *) - { + visitChildren(ps); indent_post(); printf("</paramsect>\n"); } - void visitPre(DocXRefItem *x) + void operator()(const DocXRefItem &x) { indent_pre(); printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\">\n", - qPrint(x->file()),qPrint(x->anchor()),qPrint(x->title())); - } - void visitPost(DocXRefItem *) - { + qPrint(x.file()),qPrint(x.anchor()),qPrint(x.title())); + visitChildren(x); indent_post(); printf("</xrefitem>\n"); } - void visitPre(DocInternalRef *r) + void operator()(const DocInternalRef &r) { indent_pre(); - printf("<internalref file=%s anchor=%s>\n",qPrint(r->file()),qPrint(r->anchor())); - } - void visitPost(DocInternalRef *) - { + printf("<internalref file=%s anchor=%s>\n",qPrint(r.file()),qPrint(r.anchor())); + visitChildren(r); indent_post(); printf("</internalref>\n"); } - void visitPre(DocText *) + void operator()(const DocText &t) { indent_pre(); printf("<text>\n"); - } - void visitPost(DocText *) - { + visitChildren(t); indent_post(); printf("</text>\n"); } - void visitPre(DocHtmlBlockQuote *) + void operator()(const DocHtmlBlockQuote &q) { indent_pre(); printf("<blockquote>\n"); - } - void visitPost(DocHtmlBlockQuote *) - { + visitChildren(q); indent_post(); printf("</blockquote>\n"); } - void visitPre(DocVhdlFlow *) + void operator()(const DocVhdlFlow &vf) { indent_pre(); printf("<vhdlflow>\n"); - } - void visitPost(DocVhdlFlow *) - { + visitChildren(vf); indent_post(); printf("</vhdlflow>\n"); } - void visitPre(DocParBlock *) + void operator()(const DocParBlock &pb) { indent_pre(); printf("<parblock>\n"); - } - void visitPost(DocParBlock *) - { + visitChildren(pb); indent_post(); printf("</parblock>\n"); } diff --git a/src/pyscanner.l b/src/pyscanner.l index 593db6b..7782125 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -197,7 +197,7 @@ SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ}) SHORTSTRINGCHAR [^\\\n"] STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING}) STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR") -FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally") +FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally") POUNDCOMMENT "#"[^#\n][^\n]* SCRIPTCOMMENT "#!".* @@ -548,7 +548,7 @@ STARTDOCSYMS "##" } <FunctionBody>{ - \n{B}/{IDENTIFIER}{BB} { + \n{B}/{IDENTIFIER}[^{LETTER}{DIGIT}_] { DBG_CTX((stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),yyextra->indent)); if (computeIndent(&yytext[1])<=yyextra->indent) { @@ -1800,6 +1800,7 @@ static void parseCompounds(yyscan_t yyscanner,std::shared_ptr<Entry> rt) pyscannerYYrestart( 0, yyscanner ); if (ce->section&Entry::COMPOUND_MASK) { + yyextra->specialBlock = false; yyextra->current_root = ce; BEGIN( Search ); } diff --git a/src/qcstring.cpp b/src/qcstring.cpp index cdc0207..ab21dc2 100644 --- a/src/qcstring.cpp +++ b/src/qcstring.cpp @@ -21,6 +21,11 @@ #include <stdarg.h> #include <ctype.h> +inline char toLowerChar(char c) +{ + return static_cast<char>(tolower(static_cast<unsigned char>(c))); +} + QCString &QCString::sprintf( const char *format, ... ) { va_list ap; @@ -37,7 +42,7 @@ QCString &QCString::sprintf( const char *format, ... ) int QCString::find( char c, int index, bool cs ) const { - if (index<0 || index>=(int)length()) return -1; // index outside string + if (index<0 || index>=static_cast<int>(length())) return -1; // index outside string const char *pos; if (cs) { @@ -46,11 +51,11 @@ int QCString::find( char c, int index, bool cs ) const else { pos = data()+index; - c = (char)tolower((unsigned char)c); - while (*pos && tolower((unsigned char)*pos)!=c) pos++; + c = toLowerChar(c); + while (*pos && toLowerChar(*pos)!=c) pos++; if (!*pos && c) pos=0; // not found } - return pos ? (int)(pos - data()) : -1; + return pos ? static_cast<int>(pos - data()) : -1; } int QCString::find( const char *str, int index, bool cs ) const @@ -75,7 +80,7 @@ int QCString::find( const char *str, int index, bool cs ) const } if (!*pos) pos = 0; // not found } - return pos ? (int)(pos - data()) : -1; + return pos ? static_cast<int>(pos - data()) : -1; } int QCString::find( const QCString &str, int index, bool cs ) const @@ -94,7 +99,7 @@ int QCString::findRev( char c, int index, bool cs) const if (cs) { pos = strrchr(b,c); - return pos ? (int)(pos - b) : -1; + return pos ? static_cast<int>(pos - b) : -1; } index=len; } @@ -109,10 +114,10 @@ int QCString::findRev( char c, int index, bool cs) const } else { - c = (char)tolower((unsigned char)c); - while ( pos>=b && tolower((unsigned char)*pos)!=c) pos--; + c = toLowerChar(c); + while ( pos>=b && toLowerChar(*pos)!=c) pos--; } - return pos>=b ? (int)(pos - b) : -1; + return pos>=b ? static_cast<int>(pos - b) : -1; } int QCString::findRev( const char *str, int index, bool cs) const @@ -146,10 +151,10 @@ int QCString::contains( char c, bool cs ) const } else { - c = (char)tolower((unsigned char)c); + c = toLowerChar(c); while (*pos) { - if (tolower((unsigned char)*pos)==c) count++; + if (toLowerChar(*pos)==c) count++; pos++; } } @@ -200,7 +205,7 @@ QCString QCString::simplifyWhiteSpace() const if ( to > first && *(to-1) == 0x20 ) to--; *to = '\0'; - result.resize( (int)(to - result.data()) + 1 ); + result.resize( static_cast<int>(to - result.data()) + 1 ); return result; } @@ -228,7 +233,7 @@ short QCString::toShort(bool *ok, int base) const *ok = FALSE; v = 0; } - return (short)v; + return static_cast<short>(v); } ushort QCString::toUShort(bool *ok,int base) const @@ -238,17 +243,17 @@ ushort QCString::toUShort(bool *ok,int base) const *ok = FALSE; v = 0; } - return (ushort)v; + return static_cast<ushort>(v); } int QCString::toInt(bool *ok, int base) const { - return (int)toLong( ok, base ); + return static_cast<int>(toLong( ok, base )); } uint QCString::toUInt(bool *ok,int base) const { - return (uint)toULong( ok, base ); + return static_cast<uint>(toULong( ok, base )); } @@ -397,15 +402,15 @@ bye: void *qmemmove( void *dst, const void *src, size_t len ) { char *d; - char *s; + const char *s; if ( dst > src ) { - d = (char *)dst + len - 1; - s = (char *)src + len - 1; + d = static_cast<char *>(dst) + len - 1; + s = static_cast<const char *>(src) + len - 1; while ( len-- ) *d-- = *s--; } else if ( dst < src ) { - d = (char *)dst; - s = (char *)src; + d = static_cast<char *>(dst); + s = static_cast<const char *>(src); while ( len-- ) *d++ = *s++; } @@ -430,32 +435,35 @@ char *qstrncpy( char *dst, const char *src, size_t len ) return dst; } -int qstricmp( const char *str1, const char *str2 ) +int qstricmp( const char *s1, const char *s2 ) { - const uchar *s1 = (const uchar *)str1; - const uchar *s2 = (const uchar *)str2; + if ( !s1 || !s2 ) + { + return s1 == s2 ? 0 : static_cast<int>(s2 - s1); + } int res; uchar c; - if ( !s1 || !s2 ) - return s1 == s2 ? 0 : (int)(s2 - s1); - for ( ; !(res = (c=(char)tolower(*s1)) - tolower(*s2)); s1++, s2++ ) - if ( !c ) // strings are equal - break; + for ( ; !(res = ((c=toLowerChar(*s1)) - toLowerChar(*s2))); s1++, s2++ ) + { + if ( !c ) // strings are equal + break; + } return res; } -int qstrnicmp( const char *str1, const char *str2, size_t len ) +int qstrnicmp( const char *s1, const char *s2, size_t len ) { - const uchar *s1 = (const uchar *)str1; - const uchar *s2 = (const uchar *)str2; - int res; - uchar c; if ( !s1 || !s2 ) - return (int)(s2 - s1); - for ( ; len--; s1++, s2++ ) { - if ( (res = (c=(char)tolower(*s1)) - tolower(*s2)) ) + { + return static_cast<int>(s2 - s1); + } + for ( ; len--; s1++, s2++ ) + { + char c = toLowerChar(*s1); + int res = c-toLowerChar(*s2); + if ( res!=0 ) // strings are not equal return res; - if ( !c ) // strings are equal + if ( c==0 ) // strings are equal break; } return 0; @@ -483,7 +491,7 @@ QCString substitute(const QCString &s,const QCString &src,const QCString &dst) char *r; for (r=result.rawData(), p=s.data(); (q=strstr(p,src.data()))!=0; p=q+srcLen) { - int l = (int)(q-p); + int l = static_cast<int>(q-p); memcpy(r,p,l); r+=l; @@ -537,7 +545,7 @@ QCString substitute(const QCString &s,const QCString &src,const QCString &dst,in } // skip a consecutive sequence of src when necessary - int l = (int)((q + seq * srcLen)-p); + int l = static_cast<int>((q + seq * srcLen)-p); memcpy(r,p,l); r+=l; @@ -553,7 +561,7 @@ QCString substitute(const QCString &s,const QCString &src,const QCString &dst,in r+=dstLen; } qstrcpy(r,p); - result.resize((int)strlen(result.data())+1); + result.resize(static_cast<int>(strlen(result.data())+1)); //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data()); return result; } diff --git a/src/qcstring.h b/src/qcstring.h index 6d3d198..c62c8a6 100644 --- a/src/qcstring.h +++ b/src/qcstring.h @@ -60,10 +60,10 @@ void *qmemmove( void *dst, const void *src, size_t len ); char *qstrdup( const char * ); inline uint cstrlen( const char *str ) -{ return (uint)strlen(str); } +{ return static_cast<uint>(strlen(str)); } inline uint qstrlen( const char *str ) -{ return str ? (uint)strlen(str) : 0; } +{ return str ? static_cast<uint>(strlen(str)) : 0; } inline char *cstrcpy( char *dst, const char *src ) { return strcpy(dst,src); } @@ -117,7 +117,7 @@ class QCString explicit QCString( const std::string &s ) : m_rep(s) {} - QCString( std::string &&s) { m_rep = std::move(s); } + QCString( std::string &&s) : m_rep(std::move(s)) {} /** creates a string with room for size characters * @param[in] size the number of character to allocate (also counting the 0-terminator!) @@ -144,10 +144,10 @@ class QCString bool isEmpty() const { return m_rep.empty(); } /** Returns the length of the string, not counting the 0-terminator. Equivalent to size(). */ - uint length() const { return (uint)m_rep.size(); } + uint length() const { return static_cast<uint>(m_rep.size()); } /** Returns the length of the string, not counting the 0-terminator. */ - uint size() const { return (uint)m_rep.size(); } + uint size() const { return static_cast<uint>(m_rep.size()); } /** Returns a pointer to the contents of the string in the form of a 0-terminated C string */ const char *data() const { return m_rep.c_str(); } @@ -174,7 +174,7 @@ class QCString */ bool fill( char c, int len = -1 ) { - int l = len==-1 ? (int)m_rep.size() : len; + int l = len==-1 ? static_cast<int>(m_rep.size()) : len; m_rep = std::string(l,c); return TRUE; } @@ -465,7 +465,7 @@ class QCString } #endif - std::string str() const + const std::string &str() const { return m_rep; } @@ -530,7 +530,7 @@ class QCString *****************************************************************************/ inline bool operator==( const QCString &s1, const QCString &s2 ) -{ return qstrcmp(s1.data(),s2.data()) == 0; } +{ return s1.str() == s2.str(); } inline bool operator==( const QCString &s1, const char *s2 ) { return qstrcmp(s1.data(),s2) == 0; } @@ -539,7 +539,7 @@ inline bool operator==( const char *s1, const QCString &s2 ) { return qstrcmp(s1,s2.data()) == 0; } inline bool operator!=( const QCString &s1, const QCString &s2 ) -{ return qstrcmp(s1.data(),s2.data()) != 0; } +{ return s1.str() != s2.str(); } inline bool operator!=( const QCString &s1, const char *s2 ) { return qstrcmp(s1.data(),s2) != 0; } diff --git a/src/qhp.cpp b/src/qhp.cpp index cac54d3..c093adb 100644 --- a/src/qhp.cpp +++ b/src/qhp.cpp @@ -1,6 +1,5 @@ /* - * Copyright (C) 2008 by Sebastian Pipping. - * Copyright (C) 2008 Dimitri van Heesch. + * Copyright (C) 1997-2022 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 @@ -10,22 +9,157 @@ * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. - * - * Sebastian Pipping <sebastian@pipping.org> */ -#include "qhp.h" -#include "qhpxmlwriter.h" -#include "message.h" +#include <algorithm> +#include <fstream> +#include <memory> +#include <string.h> +#include <vector> +#include <cassert> + #include "config.h" -#include "memberdef.h" -#include "groupdef.h" +#include "debug.h" #include "doxygen.h" -#include "filedef.h" +#include "groupdef.h" +#include "memberdef.h" +#include "message.h" +#include "qhp.h" +#include "textstream.h" #include "util.h" -#include <fstream> -#include <string.h> +static inline void writeIndent(TextStream &t,int indent) +{ + if (Debug::isFlagSet(Debug::Qhp)) + { + for (int i=0;i<indent;i++) t << " "; + } +} + +class QhpSectionTree +{ + private: + struct Node + { + enum class Type { Root, Dir, Section }; + // constructor for root node + Node() : type(Type::Root), parent(0) {} + // constructor for dir node + Node(Node *parent_) : type(Type::Dir), parent(parent_) {} + // constructor for section node + Node(Node *parent_, const QCString &title_,const QCString &ref_) + : type(Type::Section), parent(parent_), title(title_), ref(ref_) {} + Type type; + Node *parent = 0; + QCString title; + QCString ref; + std::vector<std::unique_ptr<Node>> children; + }; + + Node m_root; + Node *m_current = &m_root; + + void traverse(const Node &root,TextStream &t,int indent) const + { + /* Input: Output: + * ================================================= + * Section1 <section title=".." ref=".."> + * Dir1 + * Section2 <section title=".." ref=".."> + * Dir2 + * Section3 <section title=".." ref=".."/> + * </section> + * </section> + * Section4 <section title=".." ref="..> + * Dir3 + * Dir4 + * Section5 <section title=.." ref=.."/> + * </section> + * Section6 <section title=".." ref=".."/> + */ + size_t numChildren = root.children.size(); + size_t i=0; + while (i<numChildren) + { + if (root.children[i]->type==Node::Type::Section) + { + i++; + if (i<numChildren && root.children[i]->type==Node::Type::Dir) + { + // we have a dir node + writeIndent(t,indent); + t << "<section title=\"" << convertToXML(root.children[i-1]->title) << "\"" + << " ref=\"" << convertToXML(root.children[i-1]->ref) << "\">\n"; + while (i<numChildren && root.children[i]->type==Node::Type::Dir) + { + traverse(*root.children[i].get(),t,indent+1); + i++; + } + writeIndent(t,indent); + t << "</section>\n"; + } + else // we have a leaf section node + { + writeIndent(t,indent); + t << "<section title=\"" << convertToXML(root.children[i-1]->title) << "\"" + << " ref=\"" << convertToXML(root.children[i-1]->ref) << "\"/>\n"; + } + } + else // dir without preceding section (no extra indent) + { + traverse(*root.children[i].get(),t,indent); + i++; + } + } + } + + public: + void addSection(const QCString &title,const QCString &ref) + { + m_current->children.push_back(std::make_unique<Node>(m_current,title,ref)); + } + void incLevel() + { + auto newNode = new Node(m_current); + m_current->children.push_back(std::unique_ptr<Node>(newNode)); + m_current = newNode; + } + void decLevel() + { + assert(m_current->parent!=0); + if (m_current->parent) + { + m_current = m_current->parent; + } + } + void writeToc(TextStream &t) const + { + writeIndent(t,2); + t << "<toc>\n"; + traverse(m_root,t,3); + writeIndent(t,2); + t << "</toc>\n"; + } +}; + +class Qhp::Private +{ + public: + std::ofstream docFile; + TextStream doc; + TextStream index; + StringSet files; + QhpSectionTree sectionTree; +}; + +static QCString getFullProjectName() +{ + QCString projectName = Config_getString(PROJECT_NAME); + QCString versionText = Config_getString(PROJECT_NUMBER); + if (projectName.isEmpty()) projectName="Root"; + if (!versionText.isEmpty()) projectName+=" "+versionText; + return projectName; +} static QCString makeFileName(const QCString & withoutExtension) { @@ -38,7 +172,7 @@ static QCString makeFileName(const QCString & withoutExtension) } else // add specified HTML extension { - addHtmlExtensionIfMissing(result); + result = addHtmlExtensionIfMissing(result); } } return result; @@ -53,17 +187,12 @@ static QCString makeRef(const QCString & withoutExtension, const QCString & anch return result+"#"+anchor; } -Qhp::Qhp() +Qhp::Qhp() : p(std::make_unique<Private>()) { - m_doc.setIndentLevel(0); - m_toc.setIndentLevel(2); - m_index.setIndentLevel(2); - m_files.setIndentLevel(2); } Qhp::~Qhp() { - clearPrevSection(); } void Qhp::initialize() @@ -81,40 +210,45 @@ void Qhp::initialize() <filterAttribute>1.0</filterAttribute> .. */ - QCString nameSpace = Config_getString(QHP_NAMESPACE); - QCString virtualFolder = Config_getString(QHP_VIRTUAL_FOLDER); - - m_doc.declaration("1.0", "UTF-8"); - - const char * rootAttributes[] = - { "version", "1.0", 0 }; + QCString fileName = Config_getString(HTML_OUTPUT) + "/" + qhpFileName; + p->docFile.open( fileName.str(), std::ofstream::out | std::ofstream::binary); + if (!p->docFile.is_open()) + { + term("Could not open file %s for writing\n", fileName.data()); + } + p->doc.setStream(&p->docFile); - m_doc.open("QtHelpProject", rootAttributes); - m_doc.openCloseContent("namespace", nameSpace); - m_doc.openCloseContent("virtualFolder", virtualFolder); + p->doc << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; + p->doc << "<QtHelpProject version=\"1.0\">\n"; + writeIndent(p->doc,1); + p->doc << "<namespace>" << convertToXML(Config_getString(QHP_NAMESPACE)) << "</namespace>\n"; + writeIndent(p->doc,1); + p->doc << "<virtualFolder>" << convertToXML(Config_getString(QHP_VIRTUAL_FOLDER)) << "</virtualFolder>\n"; // Add custom filter QCString filterName = Config_getString(QHP_CUST_FILTER_NAME); if (!filterName.isEmpty()) { - const char * tagAttributes[] = - { "name", filterName.data(), 0 }; - m_doc.open("customFilter", tagAttributes); + writeIndent(p->doc,1); + p->doc << "<customFilter name=\"" << convertToXML(filterName) << "\">\n"; StringVector customFilterAttributes = split(Config_getString(QHP_CUST_FILTER_ATTRS).str(), " "); for (const auto &attr : customFilterAttributes) { - m_doc.openCloseContent("filterAttribute", attr.c_str()); + writeIndent(p->doc,2); + p->doc << "<filterAttribute>" << convertToXML(QCString(attr)) << "</filterAttribute>\n"; } - m_doc.close("customFilter"); + writeIndent(p->doc,1); + p->doc << "</customFilter>\n"; } - m_doc.open("filterSection"); + writeIndent(p->doc,1); + p->doc << "<filterSection>\n"; // Add section attributes - StringVector sectionFilterAttributes = - split(Config_getString(QHP_SECT_FILTER_ATTRS).str(), " "); + StringVector sectionFilterAttributes = split(Config_getString(QHP_SECT_FILTER_ATTRS).str(), " "); + // always add doxygen as filter attribute if (std::find(sectionFilterAttributes.begin(), sectionFilterAttributes.end(), "doxygen") == sectionFilterAttributes.end()) { @@ -122,102 +256,81 @@ void Qhp::initialize() } for (const auto &attr : sectionFilterAttributes) { - m_doc.openCloseContent("filterAttribute", attr.c_str()); + writeIndent(p->doc,2); + p->doc << "<filterAttribute>" << convertToXML(QCString(attr)) << "</filterAttribute>\n"; } - m_toc.open("toc"); - - // Add extra root node - QCString fullProjectname = getFullProjectName(); - QCString indexFile = "index"+Doxygen::htmlFileExtension; - const char * const attributes[] = - { "title", fullProjectname.data(), - "ref", indexFile.data(), - NULL - }; - m_toc.open("section", attributes); - m_openCount=1; - m_prevSectionTitle = getFullProjectName(); - m_prevSectionLevel = 1; - m_sectionLevel = 1; - - m_index.open("keywords"); - m_files.open("files"); + // Add extra root node to the TOC + p->sectionTree.addSection(getFullProjectName(),"index"+Doxygen::htmlFileExtension); + p->sectionTree.incLevel(); + + writeIndent(p->index,2); + p->index << "<keywords>\n"; } void Qhp::finalize() { + // close root node + p->sectionTree.decLevel(); + // Finish TOC - handlePrevSection(); - while (m_openCount>0) - { - m_toc.close("section"); - m_openCount--; - } - m_toc.close("toc"); - m_doc.insert(m_toc); + p->sectionTree.writeToc(p->doc); // Finish index - m_index.close("keywords"); - m_doc.insert(m_index); + writeIndent(p->index,2); + p->index << "</keywords>\n"; + p->doc << p->index.str(); // Finish files - m_files.close("files"); - m_doc.insert(m_files); - - m_doc.close("filterSection"); - m_doc.close("QtHelpProject"); - - QCString fileName = Config_getString(HTML_OUTPUT) + "/" + getQhpFileName(); - std::ofstream file(fileName.str(),std::ofstream::out | std::ofstream::binary); - if (!file.is_open()) + writeIndent(p->doc,2); + p->doc << "<files>\n"; + for (auto &s : p->files) { - term("Could not open file %s for writing\n", fileName.data()); + writeIndent(p->doc,3); + p->doc << s.c_str() << "\n"; } - TextStream t(&file); - m_doc.dumpTo(t); + writeIndent(p->doc,2); + p->doc << "</files>\n"; + + writeIndent(p->doc,1); + p->doc << "</filterSection>\n"; + p->doc << "</QtHelpProject>\n"; + + p->doc.flush(); + p->docFile.close(); } void Qhp::incContentsDepth() { - m_sectionLevel++; + p->sectionTree.incLevel(); } void Qhp::decContentsDepth() { - if (m_sectionLevel<=0 || (m_sectionLevel==1 && m_skipMainPageSection)) - { - m_skipMainPageSection=FALSE; - return; - } - m_sectionLevel--; + p->sectionTree.decLevel(); } -void Qhp::addContentsItem(bool /*isDir*/, const QCString & name, +void Qhp::addContentsItem(bool isDir, const QCString & name, const QCString & /*ref*/, const QCString & file, const QCString &anchor, bool /* separateIndex */, bool /* addToNavIndex */, const Definition * /*def*/) { - //printf("Qhp::addContentsItem(%s) %d\n",name,m_sectionLevel); - // Backup difference before modification + /* + <toc> + <section title="My Application Manual" ref="index.html"> + <section title="Chapter 1" ref="doc.html#chapter1"/> + <section title="Chapter 2" ref="doc.html#chapter2"/> + <section title="Chapter 3" ref="doc.html#chapter3"/> + </section> + </toc> + */ QCString f = file; if (!f.isEmpty() && f.at(0)=='^') return; // absolute URL not supported - int diff = m_prevSectionLevel - m_sectionLevel; - - handlePrevSection(); - setPrevSection(name, f, anchor, m_sectionLevel); - - // Close sections as needed - //printf("Qhp::addContentsItem() closing %d sections\n",diff); - while (diff>0) - { - m_toc.close("section"); - m_openCount--; - diff--; - } + QCString finalRef = makeRef(f, anchor); + p->sectionTree.addSection(name,finalRef); } void Qhp::addIndexItem(const Definition *context,const MemberDef *md, @@ -231,7 +344,7 @@ void Qhp::addIndexItem(const Definition *context,const MemberDef *md, if (md) // member { - static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); + bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); if (context==0) // global member { if (md->getGroupDef()) @@ -241,25 +354,21 @@ void Qhp::addIndexItem(const Definition *context,const MemberDef *md, } if (context==0) return; // should not happen QCString cfname = md->getOutputFileBase(); + QCString argStr = md->argsString(); QCString cfiname = context->getOutputFileBase(); QCString level1 = context->name(); QCString level2 = !word.isEmpty() ? word : md->name(); QCString contRef = separateMemberPages ? cfname : cfiname; QCString anchor = !sectionAnchor.isEmpty() ? sectionAnchor : md->anchor(); - QCString ref; // <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/> ref = makeRef(contRef, anchor); QCString id = level1+"::"+level2; - const char * attributes[] = - { - "name", level2.data(), - "id", id.data(), - "ref", ref.data(), - 0 - }; - m_index.openClose("keyword", attributes); + writeIndent(p->index,3); + p->index << "<keyword name=\"" << convertToXML(level2 + argStr) << "\"" + " id=\"" << convertToXML(id + "_" + anchor) << "\"" + " ref=\"" << convertToXML(ref) << "\"/>\n"; } else if (context) // container { @@ -267,103 +376,21 @@ void Qhp::addIndexItem(const Definition *context,const MemberDef *md, QCString contRef = context->getOutputFileBase(); QCString level1 = !word.isEmpty() ? word : context->name(); QCString ref = makeRef(contRef,sectionAnchor); - const char * attributes[] = - { - "name", level1.data(), - "id", level1.data(), - "ref", ref.data(), - 0 - }; - m_index.openClose("keyword", attributes); - } -} - -void Qhp::addIndexFile(const QCString & name) -{ - addFile(name); -} - -QCString Qhp::getQhpFileName() -{ - return "index.qhp"; -} - -QCString Qhp::getFullProjectName() -{ - QCString projectName = Config_getString(PROJECT_NAME); - QCString versionText = Config_getString(PROJECT_NUMBER); - if (projectName.isEmpty()) projectName="Root"; - return projectName + (versionText.isEmpty() - ? QCString("") - : QCString(" ") + versionText); -} - -void Qhp::handlePrevSection() -{ - /* - <toc> - <section title="My Application Manual" ref="index.html"> - <section title="Chapter 1" ref="doc.html#chapter1"/> - <section title="Chapter 2" ref="doc.html#chapter2"/> - <section title="Chapter 3" ref="doc.html#chapter3"/> - </section> - </toc> - */ - - if (m_prevSectionTitle.isNull()) - { - m_prevSectionTitle=" "; // should not happen... - } - - // We skip "Main Page" as our extra root is pointing to that - if (!((m_prevSectionLevel==1) && (m_prevSectionTitle==getFullProjectName()))) - { - QCString finalRef = makeRef(m_prevSectionBaseName, m_prevSectionAnchor); - - const char * const attributes[] = - { "title", m_prevSectionTitle.data(), - "ref", finalRef.data(), - NULL - }; - - if (m_prevSectionLevel < m_sectionLevel) - { - // Section with children - m_toc.open("section", attributes); - m_openCount++; - } - else - { - // Section without children - m_toc.openClose("section", attributes); - } - } - else - { - m_skipMainPageSection=TRUE; + writeIndent(p->index,3); + p->index << "<keyword name=\"" << convertToXML(level1) << "\"" + << " id=\"" << convertToXML(level1 +"_" + sectionAnchor) << "\"" + << " ref=\"" << convertToXML(ref) << "\"/>\n"; } - - clearPrevSection(); } -void Qhp::setPrevSection(const QCString & title, const QCString & basename, const QCString & anchor, int level) -{ - m_prevSectionTitle = title; - m_prevSectionBaseName = basename; - m_prevSectionAnchor = anchor; - m_prevSectionLevel = level; -} - -void Qhp::clearPrevSection() +void Qhp::addFile(const QCString & fileName) { - m_prevSectionTitle.resize(0); - m_prevSectionBaseName.resize(0); - m_prevSectionAnchor.resize(0); + p->files.insert(("<file>" + convertToXML(fileName) + "</file>").str()); } -void Qhp::addFile(const QCString & fileName) +void Qhp::addIndexFile(const QCString & fileName) { - m_files.openCloseContent("file", fileName); + addFile(fileName); } void Qhp::addImageFile(const QCString &fileName) @@ -376,3 +403,19 @@ void Qhp::addStyleSheetFile(const QCString &fileName) addFile(fileName); } +QCString Qhp::getQchFileName() +{ + QCString const & qchFile = Config_getString(QCH_FILE); + if (!qchFile.isEmpty()) + { + return qchFile; + } + + QCString const & projectName = Config_getString(PROJECT_NAME); + QCString const & versionText = Config_getString(PROJECT_NUMBER); + + return QCString("../qch/") + + (projectName.isEmpty() ? QCString("index") : projectName) + + (versionText.isEmpty() ? QCString("") : QCString("-") + versionText) + + QCString(".qch"); +} @@ -1,6 +1,5 @@ /* - * Copyright (C) 2008 by Sebastian Pipping. - * Copyright (C) 2008 Dimitri van Heesch. + * Copyright (C) 1997-2022 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 @@ -10,23 +9,21 @@ * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. - * - * Sebastian Pipping <sebastian@pipping.org> */ -#ifndef DOXYGEN_QHP_H -#define DOXYGEN_QHP_H +#ifndef QHP_H +#define QHP_H + +#include <memory> #include "index.h" -#include "qhpxmlwriter.h" class Qhp : public IndexIntf { public: Qhp(); - ~Qhp(); + ~Qhp(); - // BEGIN IndexIntf void initialize(); void finalize(); void incContentsDepth(); @@ -40,32 +37,15 @@ class Qhp : public IndexIntf void addIndexFile(const QCString & name); void addImageFile(const QCString & name); void addStyleSheetFile(const QCString & name); - // END IndexIntf - static QCString getQhpFileName(); + static inline const QCString qhpFileName = "index.qhp"; + static QCString getQchFileName(); private: - void handlePrevSection(); - void clearPrevSection(); - void setPrevSection(const QCString & title, const QCString & basename, const QCString & anchor, int level); - void addFile(const QCString & fileName); - - static QCString getFullProjectName(); - - QhpXmlWriter m_doc; - QhpXmlWriter m_toc; - QhpXmlWriter m_index; - QhpXmlWriter m_files; - - QCString m_prevSectionTitle; - QCString m_prevSectionBaseName; - QCString m_prevSectionAnchor; - - int m_prevSectionLevel = 0; - int m_sectionLevel = 0; - int m_openCount = 0; - bool m_skipMainPageSection = false; + void addFile(const QCString &); + class Private; + std::unique_ptr<Private> p; }; -#endif // DOXYGEN_QHP_H +#endif // QHP_H diff --git a/src/qhpxmlwriter.cpp b/src/qhpxmlwriter.cpp deleted file mode 100644 index b3ab95a..0000000 --- a/src/qhpxmlwriter.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2008 by Sebastian Pipping. - * Copyright (C) 2008 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. - * - * Sebastian Pipping <sebastian@pipping.org> - */ - -#include "qhpxmlwriter.h" -#include "util.h" -#include "qcstring.h" - -QhpXmlWriter::QhpXmlWriter() - : m_indentLevel(0), m_curLineIndented(false), m_compress(false) -{ -} - -QhpXmlWriter::~QhpXmlWriter() -{ -} - -void QhpXmlWriter::setIndentLevel(int level) -{ - m_indentLevel = level; -} - -void QhpXmlWriter::setCompressionEnabled(bool enabled) -{ - m_compress = enabled; -} - -void QhpXmlWriter::insert(QhpXmlWriter const & source) -{ - m_backend << source.m_backend.str(); -} - -void QhpXmlWriter::dumpTo(TextStream & file) -{ - file << m_backend.str(); -} - -void QhpXmlWriter::open(const QCString &elementName, - const char * const attributes[]) -{ - indent(); - openPure(elementName, attributes); - newLine(); - m_indentLevel++; -} - -void QhpXmlWriter::openClose(const QCString &elementName, - const char * const attributes[]) -{ - indent(); - openClosePure(elementName, attributes); - newLine(); -} - -void QhpXmlWriter::openCloseContent(const QCString &elementName, - const QCString &content) -{ - indent(); - openPure(elementName); - m_backend << convertToXML(content); - closePure(elementName); - newLine(); -} - -void QhpXmlWriter::close(const QCString &elementName) -{ - m_indentLevel--; - indent(); - closePure(elementName); - newLine(); -} - -void QhpXmlWriter::declaration(const QCString &version, const QCString &encoding) -{ - m_backend << "<?xml version=\"" << version << "\" encoding=\"" << encoding << "\"?>"; - newLine(); -} - -void QhpXmlWriter::indent() -{ - if (m_curLineIndented) - { - return; - } - for (int i = 0; i < m_indentLevel; i++) - { - m_backend << " "; - } - m_curLineIndented = true; -} - -void QhpXmlWriter::newLine() -{ - if (!m_compress) - { - m_backend << "\n"; - m_curLineIndented = false; - } -} - -void QhpXmlWriter::openPureHelper(const QCString &elementName, - const char * const attributes[], bool close) -{ - m_backend << "<" << elementName; - if (attributes) - { - for (const char * const * walker = attributes; - walker[0]; walker += 2) - { - const char *const key = walker[0]; - const char *const value = walker[1]; - if (!value) - { - continue; - } - m_backend << " " << key << "=\"" << convertToXML(value) << "\""; - } - } - - if (close) - { - m_backend << " /"; - } - m_backend << ">"; -} - -void QhpXmlWriter::openPure(const QCString &elementName, - const char * const attributes[]) -{ - openPureHelper(elementName, attributes, false); -} - -void QhpXmlWriter::openClosePure(const QCString &elementName, - const char * const attributes[]) -{ - openPureHelper(elementName, attributes, true); -} - -void QhpXmlWriter::closePure(const QCString &elementName) -{ - m_backend << "</" << elementName << ">"; -} - diff --git a/src/qhpxmlwriter.h b/src/qhpxmlwriter.h deleted file mode 100644 index 7b591eb..0000000 --- a/src/qhpxmlwriter.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008 by Sebastian Pipping. - * Copyright (C) 2008 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. - * - * Sebastian Pipping <sebastian@pipping.org> - */ - -#ifndef QHPXMLWRITER_H -#define QHPXMLWRITER_H - -#include <sstream> -#include "textstream.h" - -class QhpXmlWriter -{ - public: - QhpXmlWriter(); - ~QhpXmlWriter(); - - void setIndentLevel(int level); - void setCompressionEnabled(bool enabled); - void insert(QhpXmlWriter const & source); - void dumpTo(TextStream & file); - void open(const QCString &elementName, - const char * const attributes[] = 0); - void openClose(const QCString &elementName, - const char * const attributes[] = 0); - void openCloseContent(const QCString &elementName, const QCString &content); - void close(const QCString &elementName); - void declaration(const QCString &version, const QCString &encoding); - - private: - void indent(); - void newLine(); - void openPureHelper(const QCString &elementName, - const char * const attributes[], bool close); - void openPure(const QCString &elementName, - const char * const attributes[] = 0); - void openClosePure(const QCString &elementName, - const char * const attributes[] = 0); - void closePure(const QCString &elementName); - - TextStream m_backend; - int m_indentLevel; - bool m_curLineIndented; - bool m_compress; - -}; - -#endif // QHPXMLWRITER_H diff --git a/src/reflist.cpp b/src/reflist.cpp index ffa6128..bfabeec 100644 --- a/src/reflist.cpp +++ b/src/reflist.cpp @@ -76,7 +76,6 @@ void RefList::generatePage() { doc += "</dd>"; } - first=false; doc += " <dt>"; doc += "\n"; if (item->scope()) diff --git a/src/regex.cpp b/src/regex.cpp index 6286b0b..17c14a1 100644 --- a/src/regex.cpp +++ b/src/regex.cpp @@ -539,7 +539,7 @@ bool Ex::Private::matchAt(size_t tokenPos,size_t tokenLen,const std::string &str tokenPos++; // skip over EndCapture } tokenPos++; // skip over end marker - while ((int)index>=(int)startIndex) + while (index>=startIndex) { // pattern 'x*xy' should match 'xy' and 'xxxxy' bool found = matchAt(tokenPos,tokenLen,str,match,index,level+1); @@ -548,6 +548,7 @@ bool Ex::Private::matchAt(size_t tokenPos,size_t tokenLen,const std::string &str match.setMatch(pos,index-pos+match.length()); return true; } + if (index==0) break; index--; } return false; diff --git a/src/resourcemgr.cpp b/src/resourcemgr.cpp index fb52d99..c6db5d3 100644 --- a/src/resourcemgr.cpp +++ b/src/resourcemgr.cpp @@ -105,7 +105,7 @@ bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir, { QCString n = name; n = n.left(n.length()-4)+".png"; // replace .lum by .png - uchar *data = (uchar*)res->data; + const uchar *data = res->data; ushort width = (data[0]<<8)+data[1]; ushort height = (data[2]<<8)+data[3]; ColoredImgDataItem images[2]; @@ -123,7 +123,7 @@ bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir, { QCString n = name; n = n.left(n.length()-5)+".png"; // replace .luma by .png - uchar *data = (uchar*)res->data; + const uchar *data = res->data; ushort width = (data[0]<<8)+data[1]; ushort height = (data[2]<<8)+data[3]; ColoredImgDataItem images[2]; diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 49a6f33..01a259b 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -41,9 +41,9 @@ //#define DBG_RTF(x) m_t << x #define DBG_RTF(x) do {} while(0) -static QCString align(DocHtmlCell *cell) +static QCString align(const DocHtmlCell &cell) { - for (const auto &attr : cell->attribs()) + for (const auto &attr : cell.attribs()) { if (attr.name.lower()=="align") { @@ -57,7 +57,7 @@ static QCString align(DocHtmlCell *cell) RTFDocVisitor::RTFDocVisitor(TextStream &t,CodeOutputInterface &ci, const QCString &langExt) - : DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_langExt(langExt) + : m_t(t), m_ci(ci), m_langExt(langExt) { } @@ -91,31 +91,31 @@ void RTFDocVisitor::decIndentLevel() // visitor functions for leaf nodes //-------------------------------------- -void RTFDocVisitor::visit(DocWord *w) +void RTFDocVisitor::operator()(const DocWord &w) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocWord)}\n"); - filter(w->word()); + filter(w.word()); m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocLinkedWord *w) +void RTFDocVisitor::operator()(const DocLinkedWord &w) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocLinkedWord)}\n"); - startLink(w->ref(),w->file(),w->anchor()); - filter(w->word()); - endLink(w->ref()); + startLink(w.ref(),w.file(),w.anchor()); + filter(w.word()); + endLink(w.ref()); m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocWhiteSpace *w) +void RTFDocVisitor::operator()(const DocWhiteSpace &w) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocWhiteSpace)}\n"); if (m_insidePre) { - m_t << w->chars(); + m_t << w.chars(); } else { @@ -124,27 +124,27 @@ void RTFDocVisitor::visit(DocWhiteSpace *w) m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocSymbol *s) +void RTFDocVisitor::operator()(const DocSymbol &s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocSymbol)}\n"); - const char *res = HtmlEntityMapper::instance()->rtf(s->symbol()); + const char *res = HtmlEntityMapper::instance()->rtf(s.symbol()); if (res) { m_t << res; } else { - err("RTF: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + err("RTF: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocEmoji *s) +void RTFDocVisitor::operator()(const DocEmoji &s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocEmoji)}\n"); - const char *res = EmojiEntityMapper::instance()->unicode(s->index()); + const char *res = EmojiEntityMapper::instance()->unicode(s.index()); if (res) { const char *p = res; @@ -177,12 +177,12 @@ void RTFDocVisitor::visit(DocEmoji *s) } else { - m_t << s->name(); + m_t << s.name(); } m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocURL *u) +void RTFDocVisitor::operator()(const DocURL &u) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocURL)}\n"); @@ -191,14 +191,14 @@ void RTFDocVisitor::visit(DocURL *u) m_t << "{\\field " "{\\*\\fldinst " "{ HYPERLINK \""; - if (u->isEmail()) m_t << "mailto:"; - m_t << u->url(); + if (u.isEmail()) m_t << "mailto:"; + m_t << u.url(); m_t << "\" }" "{}"; m_t << "}" "{\\fldrslt " "{\\cs37\\ul\\cf2 "; - filter(u->url()); + filter(u.url()); m_t << "}" "}" "}\n"; @@ -206,13 +206,13 @@ void RTFDocVisitor::visit(DocURL *u) else { m_t << "{\\f2 "; - filter(u->url()); + filter(u.url()); m_t << "}"; } m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocLineBreak *) +void RTFDocVisitor::operator()(const DocLineBreak &) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n"); @@ -220,7 +220,7 @@ void RTFDocVisitor::visit(DocLineBreak *) m_lastIsPara=TRUE; } -void RTFDocVisitor::visit(DocHorRuler *) +void RTFDocVisitor::operator()(const DocHorRuler &) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocHorRuler)}\n"); @@ -228,48 +228,48 @@ void RTFDocVisitor::visit(DocHorRuler *) m_lastIsPara=TRUE; } -void RTFDocVisitor::visit(DocStyleChange *s) +void RTFDocVisitor::operator()(const DocStyleChange &s) { if (m_hide) return; m_lastIsPara=FALSE; DBG_RTF("{\\comment RTFDocVisitor::visit(DocStyleChange)}\n"); - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) m_t << "{\\b "; else m_t << "} "; + if (s.enable()) m_t << "{\\b "; else m_t << "} "; break; case DocStyleChange::S: case DocStyleChange::Strike: case DocStyleChange::Del: - if (s->enable()) m_t << "{\\strike "; else m_t << "} "; + if (s.enable()) m_t << "{\\strike "; else m_t << "} "; break; case DocStyleChange::Underline: case DocStyleChange::Ins: - if (s->enable()) m_t << "{\\ul "; else m_t << "} "; + if (s.enable()) m_t << "{\\ul "; else m_t << "} "; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "{\\i "; else m_t << "} "; + if (s.enable()) m_t << "{\\i "; else m_t << "} "; break; case DocStyleChange::Code: - if (s->enable()) m_t << "{\\f2 "; else m_t << "} "; + if (s.enable()) m_t << "{\\f2 "; else m_t << "} "; break; case DocStyleChange::Subscript: - if (s->enable()) m_t << "{\\sub "; else m_t << "} "; + if (s.enable()) m_t << "{\\sub "; else m_t << "} "; break; case DocStyleChange::Superscript: - if (s->enable()) m_t << "{\\super "; else m_t << "} "; + if (s.enable()) m_t << "{\\super "; else m_t << "} "; break; case DocStyleChange::Center: - if (s->enable()) m_t << "{\\qc "; else m_t << "} "; + if (s.enable()) m_t << "{\\qc "; else m_t << "} "; break; case DocStyleChange::Small: - if (s->enable()) m_t << "{\\sub "; else m_t << "} "; + if (s.enable()) m_t << "{\\sub "; else m_t << "} "; break; case DocStyleChange::Cite: - if (s->enable()) m_t << "{\\i "; else m_t << "} "; + if (s.enable()) m_t << "{\\i "; else m_t << "} "; break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s.enable()) { m_t << "{\n"; m_t << "\\par\n"; @@ -287,7 +287,7 @@ void RTFDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; case DocStyleChange::Details: /* emulation of the <details> tag */ - if (s->enable()) + if (s.enable()) { m_t << "{\n"; m_t << "\\par\n"; @@ -300,44 +300,39 @@ void RTFDocVisitor::visit(DocStyleChange *s) m_lastIsPara=TRUE; break; case DocStyleChange::Summary: /* emulation of the <summary> tag inside a <details> tag */ - if (s->enable()) m_t << "{\\b "; else m_t << "} "; + if (s.enable()) m_t << "{\\b "; else m_t << "} "; break; } } -static void visitCaption(RTFDocVisitor *parent, const DocNodeList &children) -{ - for (const auto &n : children) n->accept(parent); -} - -void RTFDocVisitor::visit(DocVerbatim *s) +void RTFDocVisitor::operator()(const DocVerbatim &s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n"); QCString lang = m_langExt; - if (!s->language().isEmpty()) // explicit language setting + if (!s.language().isEmpty()) // explicit language setting { - lang = s->language(); + lang = s.language(); } SrcLangExt langExt = getLanguageFromCodeLang(lang); - switch(s->type()) + switch(s.type()) { case DocVerbatim::Code: m_t << "{\n"; m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - 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\n"; m_t << "}\n"; break; case DocVerbatim::JavaDocLiteral: - filter(s->text(),TRUE); + filter(s.text(),TRUE); break; case DocVerbatim::JavaDocCode: m_t << "{\n"; m_t << "{\\f2 "; - filter(s->text(),TRUE); + filter(s.text(),TRUE); m_t << "}"; m_t << "}\n"; break; @@ -345,12 +340,12 @@ void RTFDocVisitor::visit(DocVerbatim *s) m_t << "{\n"; m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - filter(s->text(),TRUE); + filter(s.text(),TRUE); //m_t << "\\par\n"; m_t << "}\n"; break; case DocVerbatim::RtfOnly: - m_t << s->text(); + m_t << s.text(); break; case DocVerbatim::HtmlOnly: case DocVerbatim::LatexOnly: @@ -376,14 +371,14 @@ void RTFDocVisitor::visit(DocVerbatim *s) } else { - QCString stext = s->text(); + QCString stext = s.text(); file.write( stext.data(), stext.length() ); file.close(); } - writeDotFile(fileName, s->hasCaption(), s->srcFile(), s->srcLine()); - visitCaption(this, s->children()); - includePicturePostRTF(true, s->hasCaption()); + writeDotFile(fileName, s.hasCaption(), s.srcFile(), s.srcLine()); + visitChildren(s); + includePicturePostRTF(true, s.hasCaption()); if (Config_getBool(DOT_CLEANUP)) Dir().remove(fileName.str()); } @@ -404,75 +399,75 @@ void RTFDocVisitor::visit(DocVerbatim *s) err("Could not open file %s for writing\n",qPrint(baseName)); } QCString text = "msc {"; - text+=s->text(); + text+=s.text(); text+="}"; file.write( text.data(), text.length() ); file.close(); - writeMscFile(baseName, s->hasCaption(), s->srcFile(), s->srcLine()); - visitCaption(this, s->children()); - includePicturePostRTF(true, s->hasCaption()); + writeMscFile(baseName, s.hasCaption(), s.srcFile(), s.srcLine()); + visitChildren(s); + includePicturePostRTF(true, s.hasCaption()); if (Config_getBool(DOT_CLEANUP)) Dir().remove(baseName.str()); } break; case DocVerbatim::PlantUML: { - static QCString rtfOutput = Config_getString(RTF_OUTPUT); + QCString rtfOutput = Config_getString(RTF_OUTPUT); QCString baseName = PlantumlManager::instance().writePlantUMLSource( - rtfOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP, - s->engine(),s->srcFile(),s->srcLine()); + rtfOutput,s.exampleFile(),s.text(),PlantumlManager::PUML_BITMAP, + s.engine(),s.srcFile(),s.srcLine()); - writePlantUMLFile(baseName, s->hasCaption()); - visitCaption(this, s->children()); - includePicturePostRTF(true, s->hasCaption()); + writePlantUMLFile(baseName, s.hasCaption()); + visitChildren(s); + includePicturePostRTF(true, s.hasCaption()); } break; } m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocAnchor *anc) +void RTFDocVisitor::operator()(const DocAnchor &anc) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocAnchor)}\n"); QCString anchor; - if (!anc->file().isEmpty()) + if (!anc.file().isEmpty()) { - anchor+=stripPath(anc->file()); + anchor+=stripPath(anc.file()); } - if (!anc->file().isEmpty() && !anc->anchor().isEmpty()) + if (!anc.file().isEmpty() && !anc.anchor().isEmpty()) { anchor+="_"; } - if (!anc->anchor().isEmpty()) + if (!anc.anchor().isEmpty()) { - anchor+=anc->anchor(); + anchor+=anc.anchor(); } m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}\n"; m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}\n"; m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocInclude *inc) +void RTFDocVisitor::operator()(const DocInclude &inc) { if (m_hide) return; - SrcLangExt langExt = getLanguageFromFileName(inc->extension()); + SrcLangExt langExt = getLanguageFromFileName(inc.extension()); DBG_RTF("{\\comment RTFDocVisitor::visit(DocInclude)}\n"); - switch(inc->type()) + switch(inc.type()) { case DocInclude::IncWithLines: { m_t << "{\n"; m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, // fileDef, -1, // start line -1, // end line @@ -489,9 +484,9 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{\n"; m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - 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(), 0, // fileDef -1, // startLine -1, // endLine @@ -511,13 +506,13 @@ void RTFDocVisitor::visit(DocInclude *inc) case DocInclude::DocbookInclude: break; case DocInclude::RtfInclude: - m_t << inc->text(); + m_t << inc.text(); break; case DocInclude::VerbInclude: m_t << "{\n"; m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - filter(inc->text()); + filter(inc.text()); m_t << "\\par"; m_t << "}\n"; break; @@ -525,30 +520,30 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{\n"; if (!m_lastIsPara) m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile() + inc.isExample(), + inc.exampleFile() ); m_t << "}"; break; case DocInclude::SnipWithLines: { - FileInfo cfi( inc->file().str() ); + FileInfo cfi( inc.file().str() ); FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); m_t << "{\n"; if (!m_lastIsPara) m_t << "\\par\n"; m_t << rtf_Style_Reset << getStyle("CodeExample"); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), fd, - lineBlock(inc->text(),inc->blockId()), + lineBlock(inc.text(),inc.blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef @@ -567,15 +562,15 @@ void RTFDocVisitor::visit(DocInclude *inc) m_lastIsPara=TRUE; } -void RTFDocVisitor::visit(DocIncOperator *op) +void RTFDocVisitor::operator()(const DocIncOperator &op) { //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", - // op->type(),op->isFirst(),op->isLast(),qPrint(op->text())); + // op.type(),op.isFirst(),op.isLast(),qPrint(op.text())); DBG_RTF("{\\comment RTFDocVisitor::visit(DocIncOperator)}\n"); - QCString locLangExt = getFileNameExtension(op->includeFileName()); + QCString locLangExt = getFileNameExtension(op.includeFileName()); if (locLangExt.isEmpty()) locLangExt = m_langExt; SrcLangExt langExt = getLanguageFromFileName(locLangExt); - if (op->isFirst()) + if (op.isFirst()) { if (!m_hide) { @@ -586,33 +581,33 @@ void RTFDocVisitor::visit(DocIncOperator *op) pushHidden(m_hide); m_hide = TRUE; } - if (op->type()!=DocIncOperator::Skip) + if (op.type()!=DocIncOperator::Skip) { m_hide = popHidden(); if (!m_hide) { FileDef *fd = 0; - if (!op->includeFileName().isEmpty()) + if (!op.includeFileName().isEmpty()) { - FileInfo cfi( op->includeFileName().str() ); + FileInfo cfi( op.includeFileName().str() ); fd = createFileDef( cfi.dirPath(), cfi.fileName() ); } - getCodeParser(locLangExt).parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile(), + getCodeParser(locLangExt).parseCode(m_ci,op.context(),op.text(),langExt, + op.isExample(),op.exampleFile(), fd, // fileDef - op->line(), // startLine + op.line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - op->showLineNo() // show line numbers + op.showLineNo() // show line numbers ); if (fd) delete fd; } pushHidden(m_hide); m_hide=TRUE; } - if (op->isLast()) + if (op.isLast()) { m_hide = popHidden(); if (!m_hide) @@ -629,11 +624,11 @@ void RTFDocVisitor::visit(DocIncOperator *op) } } -void RTFDocVisitor::visit(DocFormula *f) +void RTFDocVisitor::operator()(const DocFormula &f) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocFormula)}\n"); - bool bDisplay = !f->isInline(); + bool bDisplay = !f.isInline(); if (bDisplay) { m_t << "\\par"; @@ -642,7 +637,7 @@ void RTFDocVisitor::visit(DocFormula *f) m_t << "\\pard"; m_t << "\\qc"; } - m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << f->relPath() << f->name() << ".png\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}"; + m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << f.relPath() << f.name() << ".png\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}"; if (bDisplay) { m_t << "\\par}"; @@ -650,34 +645,34 @@ void RTFDocVisitor::visit(DocFormula *f) m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocIndexEntry *i) +void RTFDocVisitor::operator()(const DocIndexEntry &i) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocIndexEntry)}\n"); - m_t << "{\\xe \\v " << i->entry() << "}\n"; + m_t << "{\\xe \\v " << i.entry() << "}\n"; m_lastIsPara=FALSE; } -void RTFDocVisitor::visit(DocSimpleSectSep *) +void RTFDocVisitor::operator()(const DocSimpleSectSep &) { } -void RTFDocVisitor::visit(DocCite *cite) +void RTFDocVisitor::operator()(const DocCite &cite) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocCite)}\n"); - if (!cite->file().isEmpty()) + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocCite &)}\n"); + if (!cite.file().isEmpty()) { - startLink(cite->ref(),cite->file(),cite->anchor()); + startLink(cite.ref(),cite.file(),cite.anchor()); } else { m_t << "{\\b "; } - filter(cite->text()); - if (!cite->file().isEmpty()) + filter(cite.text()); + if (!cite.file().isEmpty()) { - endLink(cite->ref()); + endLink(cite.ref()); } else { @@ -690,32 +685,27 @@ void RTFDocVisitor::visit(DocCite *cite) // visitor functions for compound nodes //-------------------------------------- -void RTFDocVisitor::visitPre(DocAutoList *l) +void RTFDocVisitor::operator()(const DocAutoList &l) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocAutoList)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocAutoList &)}\n"); m_t << "{\n"; int level = indentLevel(); - m_listItemInfo[level].isEnum = l->isEnumList(); + m_listItemInfo[level].isEnum = l.isEnumList(); m_listItemInfo[level].type = '1'; m_listItemInfo[level].number = 1; m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocAutoList *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoList)}\n"); + visitChildren(l); if (!m_lastIsPara) m_t << "\\par"; m_t << "}\n"; m_lastIsPara=TRUE; if (indentLevel()==0) m_t << "\\par\n"; } -void RTFDocVisitor::visitPre(DocAutoListItem *) +void RTFDocVisitor::operator()(const DocAutoListItem &li) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocAutoListItem)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocAutoListItem &)}\n"); if (!m_lastIsPara) m_t << "\\par\n"; m_t << rtf_Style_Reset; int level = indentLevel(); @@ -731,27 +721,19 @@ void RTFDocVisitor::visitPre(DocAutoListItem *) } incIndentLevel(); m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocAutoListItem *) -{ + visitChildren(li); decIndentLevel(); - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoListItem)}\n"); -} - -void RTFDocVisitor::visitPre(DocPara *) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n"); } -void RTFDocVisitor::visitPost(DocPara *p) +void RTFDocVisitor::operator()(const DocPara &p) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocPara &)}\n"); + visitChildren(p); if (!m_lastIsPara && - !p->isLast() && // omit <p> for last paragraph - !(p->parent() && // and for parameters & sections - p->parent()->kind()==DocNode::Kind_ParamSect + !p.isLast() && // omit <p> for last paragraph + !(p.parent() && // and for parameters & sections + std::get_if<DocParamSect>(p.parent()) ) ) { @@ -760,33 +742,28 @@ void RTFDocVisitor::visitPost(DocPara *p) } } -void RTFDocVisitor::visitPre(DocRoot *r) +void RTFDocVisitor::operator()(const DocRoot &r) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRoot)}\n"); - if (r->indent()) incIndentLevel(); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocRoot &)}\n"); + if (r.indent()) incIndentLevel(); m_t << "{" << rtf_Style["BodyText"].reference() << "\n"; -} - -void RTFDocVisitor::visitPost(DocRoot *r) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRoot)}\n"); - if (!m_lastIsPara && !r->singleLine()) m_t << "\\par\n"; + visitChildren(r); + if (!m_lastIsPara && !r.singleLine()) m_t << "\\par\n"; m_t << "}"; m_lastIsPara=TRUE; - if (r->indent()) decIndentLevel(); + if (r.indent()) decIndentLevel(); } -void RTFDocVisitor::visitPre(DocSimpleSect *s) +void RTFDocVisitor::operator()(const DocSimpleSect &s) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleSect)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSimpleSect &)}\n"); if (!m_lastIsPara) m_t << "\\par\n"; m_t << "{"; // start desc //m_t << "{\\b "; // start bold m_t << "{" << rtf_Style["Heading5"].reference() << "\n"; - switch(s->type()) + switch(s.type()) { case DocSimpleSect::See: m_t << theTranslator->trSeeAlso(); break; @@ -823,119 +800,107 @@ void RTFDocVisitor::visitPre(DocSimpleSect *s) case DocSimpleSect::Unknown: break; } - // special case 1: user defined title - if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) + incIndentLevel(); + if (s.type()!=DocSimpleSect::User && s.type()!=DocSimpleSect::Rcs) { m_t << "\\par"; m_t << "}"; // end bold - incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); m_t << "{\\s17 \\sa60 \\sb30\n"; } + else + { + if (s.title()) + { + std::visit(*this,*s.title()); + } + m_t << "\\par\n"; + m_t << "}"; // end bold + m_t << rtf_Style_Reset << getStyle("DescContinue"); + } m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocSimpleSect *s) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n"); + visitChildren(s); if (!m_lastIsPara) m_t << "\\par\n"; decIndentLevel(); - if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) m_t << "}"; + if (s.type()!=DocSimpleSect::User && s.type()!=DocSimpleSect::Rcs) + { + m_t << "}"; // end DescContinue + } m_t << "}"; // end desc m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocTitle *) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocTitle)}\n"); -} - -void RTFDocVisitor::visitPost(DocTitle *) +void RTFDocVisitor::operator()(const DocTitle &t) { + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocTitle &)}\n"); if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocTitle)}\n"); - m_t << "\\par\n"; - m_t << "}"; // end bold - incIndentLevel(); - m_t << rtf_Style_Reset << getStyle("DescContinue"); - m_lastIsPara=FALSE; + visitChildren(t); } -void RTFDocVisitor::visitPre(DocSimpleList *) +void RTFDocVisitor::operator()(const DocSimpleList &l) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleSect)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSimpleSect &)}\n"); m_t << "{\n"; m_listItemInfo[indentLevel()].isEnum = FALSE; m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocSimpleList *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n"); + visitChildren(l); if (!m_lastIsPara) m_t << "\\par\n"; m_t << "}\n"; m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocSimpleListItem *) +void RTFDocVisitor::operator()(const DocSimpleListItem &li) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleListItem)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSimpleListItem &)}\n"); m_t << "\\par" << rtf_Style_Reset << getStyle("ListBullet") << "\n"; m_lastIsPara=FALSE; incIndentLevel(); -} - -void RTFDocVisitor::visitPost(DocSimpleListItem *) -{ + if (li.paragraph()) + { + std::visit(*this,*li.paragraph()); + } decIndentLevel(); DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleListItem)}\n"); } -void RTFDocVisitor::visitPre(DocSection *s) +void RTFDocVisitor::operator()(const DocSection &s) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSection)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSection &)}\n"); if (!m_lastIsPara) m_t << "\\par\n"; - m_t << "{\\bkmkstart " << rtfFormatBmkStr(stripPath(s->file())+"_"+s->anchor()) << "}\n"; - m_t << "{\\bkmkend " << rtfFormatBmkStr(stripPath(s->file())+"_"+s->anchor()) << "}\n"; + m_t << "{\\bkmkstart " << rtfFormatBmkStr(stripPath(s.file())+"_"+s.anchor()) << "}\n"; + m_t << "{\\bkmkend " << rtfFormatBmkStr(stripPath(s.file())+"_"+s.anchor()) << "}\n"; m_t << "{{" // start section << rtf_Style_Reset; QCString heading; - int level = std::min(s->level()+1,4); + int level = std::min(s.level()+1,4); heading.sprintf("Heading%d",level); // set style m_t << rtf_Style[heading.str()].reference() << "\n"; // make table of contents entry - filter(s->title()); + filter(s.title()); m_t << "\n\\par" << "}\n"; m_t << "{\\tc\\tcl" << level << " \\v "; - filter(s->title()); + filter(s.title()); m_t << "}\n"; m_lastIsPara=TRUE; -} - -void RTFDocVisitor::visitPost(DocSection *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSection)}\n"); + visitChildren(s); m_t << "\\par}\n"; // end section m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocHtmlList *l) +void RTFDocVisitor::operator()(const DocHtmlList &l) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlList)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlList &)}\n"); m_t << "{\n"; int level = indentLevel(); - m_listItemInfo[level].isEnum = l->type()==DocHtmlList::Ordered; + m_listItemInfo[level].isEnum = l.type()==DocHtmlList::Ordered; m_listItemInfo[level].number = 1; m_listItemInfo[level].type = '1'; - for (const auto &opt : l->attribs()) + for (const auto &opt : l.attribs()) { if (opt.name=="type") { @@ -949,26 +914,21 @@ void RTFDocVisitor::visitPre(DocHtmlList *l) } } m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlList *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlList)}\n"); + visitChildren(l); m_t << "\\par" << "}\n"; m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocHtmlListItem *l) +void RTFDocVisitor::operator()(const DocHtmlListItem &l) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlListItem)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlListItem &)}\n"); m_t << "\\par\n"; m_t << rtf_Style_Reset; int level = indentLevel(); if (m_listItemInfo[level].isEnum) { - for (const auto &opt : l->attribs()) + for (const auto &opt : l.attribs()) { if (opt.name=="value") { @@ -1008,114 +968,87 @@ void RTFDocVisitor::visitPre(DocHtmlListItem *l) } incIndentLevel(); m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlListItem *) -{ + visitChildren(l); decIndentLevel(); DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlListItem)}\n"); } -void RTFDocVisitor::visitPre(DocHtmlDescList *) +void RTFDocVisitor::operator()(const DocHtmlDescList &dl) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescList)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDescList &)}\n"); //m_t << "{\n"; //m_t << rtf_Style_Reset << getStyle("ListContinue"); //m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlDescList *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescList)}\n"); + visitChildren(dl); //m_t << "}\n"; //m_t << "\\par\n"; //m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocHtmlDescTitle *) +void RTFDocVisitor::operator()(const DocHtmlDescTitle &dt) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescTitle)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDescTitle &)}\n"); //m_t << "\\par\n"; //m_t << "{\\b "; m_t << "{" << rtf_Style["Heading5"].reference() << "\n"; m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlDescTitle *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescTitle)}\n"); + visitChildren(dt); m_t << "\\par\n"; m_t << "}\n"; m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocHtmlDescData *) +void RTFDocVisitor::operator()(const DocHtmlDescData &dd) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescData)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDescData &)}\n"); incIndentLevel(); m_t << "{" << rtf_Style_Reset << getStyle("DescContinue"); -} - -void RTFDocVisitor::visitPost(DocHtmlDescData *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescData)}\n"); + visitChildren(dd); m_t << "\\par"; m_t << "}\n"; decIndentLevel(); m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocHtmlTable *t) +void RTFDocVisitor::operator()(const DocHtmlTable &t) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlTable)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlTable &)}\n"); if (!m_lastIsPara) m_t << "\\par\n"; m_lastIsPara=TRUE; - if (t->hasCaption()) + if (t.caption()) { - DocHtmlCaption *c = t->caption(); + const DocHtmlCaption &c = std::get<DocHtmlCaption>(*t.caption()); m_t << "\\pard \\qc \\b"; - if (!c->file().isEmpty()) + if (!c.file().isEmpty()) { - m_t << "{\\bkmkstart " << rtfFormatBmkStr(stripPath(c->file())+"_"+c->anchor()) << "}\n"; - m_t << "{\\bkmkend " << rtfFormatBmkStr(stripPath(c->file())+"_"+c->anchor()) << "}\n"; + m_t << "{\\bkmkstart " << rtfFormatBmkStr(stripPath(c.file())+"_"+c.anchor()) << "}\n"; + m_t << "{\\bkmkend " << rtfFormatBmkStr(stripPath(c.file())+"_"+c.anchor()) << "}\n"; } m_t << "{Table \\field\\flddirty{\\*\\fldinst { SEQ Table \\\\*Arabic }}{\\fldrslt {\\noproof 1}} "; + std::visit(*this,*t.caption()); } -} - -void RTFDocVisitor::visitPost(DocHtmlTable *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlTable)}\n"); + visitChildren(t); m_t << "\\pard\\plain\n"; m_t << "\\par\n"; m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocHtmlCaption *) +void RTFDocVisitor::operator()(const DocHtmlCaption &c) { - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlCaption)}\n"); - // start of caption is handled in the RTFDocVisitor::visitPre(DocHtmlTable *t) -} - -void RTFDocVisitor::visitPost(DocHtmlCaption *) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCaption)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlCaption &)}\n"); + visitChildren(c); m_t << "}\n\\par\n"; } -void RTFDocVisitor::visitPre(DocHtmlRow *r) +void RTFDocVisitor::operator()(const DocHtmlRow &r) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlRow)}\n"); - uint i,columnWidth=(uint)r->numCells()>0 ? rtf_pageWidth/(uint)r->numCells() : 10; + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlRow &)}\n"); + size_t i,columnWidth=r.numCells()>0 ? rtf_pageWidth/r.numCells() : 10; m_t << "\\trowd \\trgaph108\\trleft-108" "\\trbrdrt\\brdrs\\brdrw10 " "\\trbrdrl\\brdrs\\brdrw10 " @@ -1123,9 +1056,9 @@ void RTFDocVisitor::visitPre(DocHtmlRow *r) "\\trbrdrr\\brdrs\\brdrw10 " "\\trbrdrh\\brdrs\\brdrw10 " "\\trbrdrv\\brdrs\\brdrw10 \n"; - for (i=0;i<r->numCells();i++) + for (i=0;i<r.numCells();i++) { - if (r->isHeading()) + if (r.isHeading()) { m_t << "\\clcbpat16"; // set cell shading to light grey (color 16 in the clut) } @@ -1138,69 +1071,41 @@ void RTFDocVisitor::visitPre(DocHtmlRow *r) } m_t << "\\pard \\widctlpar\\intbl\\adjustright\n"; m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlRow *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlRow)}\n"); + visitChildren(r); m_t << "\n"; m_t << "\\pard \\widctlpar\\intbl\\adjustright\n"; m_t << "{\\row }\n"; m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPre(DocHtmlCell *c) +void RTFDocVisitor::operator()(const DocHtmlCell &c) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlCell)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlCell &)}\n"); m_t << "{" << align(c); m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlCell *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCell)}\n"); + visitChildren(c); m_t << "\\cell }"; m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPre(DocInternal *) +void RTFDocVisitor::operator()(const DocInternal &i) { if (m_hide) return; - //DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocInternal)}\n"); - //m_t << "{"; // start desc - //m_t << "{\\b "; // start bold - //m_t << theTranslator->trForInternalUseOnly(); - //m_t << "}"; // end bold - //m_t << "\\par\n"; - //incIndentLevel(); - //m_t << rtf_Style_Reset << getStyle("DescContinue"); - //m_lastIsPara=FALSE; + visitChildren(i); } -void RTFDocVisitor::visitPost(DocInternal *) +void RTFDocVisitor::operator()(const DocHRef &href) { if (m_hide) return; - //DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternal)}\n"); - //m_t << "\\par"; - //decIndentLevel(); - //m_t << "}"; // end desc - //m_lastIsPara=TRUE; -} - -void RTFDocVisitor::visitPre(DocHRef *href) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHRef)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHRef &)}\n"); if (Config_getBool(RTF_HYPERLINKS)) { - if (href->url().startsWith("#")) + if (href.url().startsWith("#")) { // when starting with # so a local link QCString cite; - cite = href->file() + "_" + href->url().right(href->url().length()-1); + cite = href.file() + "_" + href.url().right(href.url().length()-1); m_t << "{\\field " "{\\*\\fldinst " "{ HYPERLINK \\\\l \"" << rtfFormatBmkStr(cite) << "\" " @@ -1213,7 +1118,7 @@ void RTFDocVisitor::visitPre(DocHRef *href) { m_t << "{\\field " "{\\*\\fldinst " - "{ HYPERLINK \"" << href->url() << "\" " + "{ HYPERLINK \"" << href.url() << "\" " "}{}" "}" "{\\fldrslt " @@ -1225,12 +1130,7 @@ void RTFDocVisitor::visitPre(DocHRef *href) m_t << "{\\f2 "; } m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHRef *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHRef)}\n"); + visitChildren(href); if (Config_getBool(RTF_HYPERLINKS)) { m_t << "}" @@ -1244,37 +1144,27 @@ void RTFDocVisitor::visitPost(DocHRef *) m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPre(DocHtmlHeader *header) +void RTFDocVisitor::operator()(const DocHtmlHeader &header) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlHeader)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlHeader &)}\n"); m_t << "{" // start section << rtf_Style_Reset; QCString heading; - int level = std::min(header->level(),5); + int level = std::min(header.level(),5); heading.sprintf("Heading%d",level); // set style m_t << rtf_Style[heading.str()].reference(); // make open table of contents entry that will be closed in visitPost method m_t << "{\\tc\\tcl" << level << " "; m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocHtmlHeader *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n"); + visitChildren(header); // close open table of contents entry m_t << "} \\par"; m_t << "}\n"; // end section m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocImage *img) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocImage)}\n"); - includePicturePreRTF(img->name(), img->type()==DocImage::Rtf, img->hasCaption(), img->isInlineImage()); -} void RTFDocVisitor::includePicturePreRTF(const QCString &name, bool isTypeRTF, bool hasCaption, bool inlineImage) { if (isTypeRTF) @@ -1312,12 +1202,6 @@ void RTFDocVisitor::includePicturePreRTF(const QCString &name, bool isTypeRTF, b } } -void RTFDocVisitor::visitPost(DocImage *img) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocImage)}\n"); - includePicturePostRTF(img->type()==DocImage::Rtf, img->hasCaption(), img->isInlineImage()); -} - void RTFDocVisitor::includePicturePostRTF(bool isTypeRTF, bool hasCaption, bool inlineImage) { if (isTypeRTF) @@ -1346,124 +1230,102 @@ void RTFDocVisitor::includePicturePostRTF(bool isTypeRTF, bool hasCaption, bool } } -void RTFDocVisitor::visitPre(DocDotFile *df) +void RTFDocVisitor::operator()(const DocImage &img) { - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocDotFile)}\n"); - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df->file())); - writeDotFile(df); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocImage &)}\n"); + includePicturePreRTF(img.name(), img.type()==DocImage::Rtf, img.hasCaption(), img.isInlineImage()); + visitChildren(img); + includePicturePostRTF(img.type()==DocImage::Rtf, img.hasCaption(), img.isInlineImage()); } -void RTFDocVisitor::visitPost(DocDotFile *df) + +void RTFDocVisitor::operator()(const DocDotFile &df) { - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDotFile)}\n"); - includePicturePostRTF(true, df->hasCaption()); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocDotFile &)}\n"); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file())); + writeDotFile(df); + visitChildren(df); + includePicturePostRTF(true, df.hasCaption()); } -void RTFDocVisitor::visitPre(DocMscFile *df) +void RTFDocVisitor::operator()(const DocMscFile &df) { - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocMscFile)}\n"); - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df->file())); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocMscFile &)}\n"); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file())); writeMscFile(df); + visitChildren(df); + includePicturePostRTF(true, df.hasCaption()); } -void RTFDocVisitor::visitPost(DocMscFile *df) +void RTFDocVisitor::operator()(const DocDiaFile &df) { - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocMscFile)}\n"); - includePicturePostRTF(true, df->hasCaption()); -} - -void RTFDocVisitor::visitPre(DocDiaFile *df) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocDiaFile)}\n"); - if (!Config_getBool(DOT_CLEANUP)) copyFile(df->file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df->file())); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocDiaFile &)}\n"); + if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file())); writeDiaFile(df); + visitChildren(df); + includePicturePostRTF(true, df.hasCaption()); } -void RTFDocVisitor::visitPost(DocDiaFile *df) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDiaFile)}\n"); - includePicturePostRTF(true, df->hasCaption()); -} - -void RTFDocVisitor::visitPre(DocLink *lnk) +void RTFDocVisitor::operator()(const DocLink &lnk) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocLink)}\n"); - startLink(lnk->ref(),lnk->file(),lnk->anchor()); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocLink &)}\n"); + startLink(lnk.ref(),lnk.file(),lnk.anchor()); + visitChildren(lnk); + endLink(lnk.ref()); } -void RTFDocVisitor::visitPost(DocLink *lnk) +void RTFDocVisitor::operator()(const DocRef &ref) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLink)}\n"); - endLink(lnk->ref()); -} - -void RTFDocVisitor::visitPre(DocRef *ref) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRef)}\n"); - // when ref->isSubPage()==TRUE we use ref->file() for HTML and - // ref->anchor() for LaTeX/RTF - if (ref->isSubPage()) + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocRef &)}\n"); + // when ref.isSubPage()==TRUE we use ref.file() for HTML and + // ref.anchor() for LaTeX/RTF + if (ref.isSubPage()) { - startLink(ref->ref(),QCString(),ref->anchor()); + startLink(ref.ref(),QCString(),ref.anchor()); } else { - if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor()); + if (!ref.file().isEmpty()) startLink(ref.ref(),ref.file(),ref.anchor()); } - if (!ref->hasLinkText()) filter(ref->targetTitle()); -} - -void RTFDocVisitor::visitPost(DocRef *ref) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRef)}\n"); - if (!ref->file().isEmpty()) endLink(ref->ref()); + if (!ref.hasLinkText()) filter(ref.targetTitle()); + visitChildren(ref); + if (!ref.file().isEmpty()) endLink(ref.ref()); //m_t << " "; } -void RTFDocVisitor::visitPre(DocSecRefItem *) -{ - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefItem)}\n"); -} - -void RTFDocVisitor::visitPost(DocSecRefItem *) +void RTFDocVisitor::operator()(const DocSecRefItem &ref) { - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefItem)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSecRefItem &)}\n"); + visitChildren(ref); } -void RTFDocVisitor::visitPre(DocSecRefList *) +void RTFDocVisitor::operator()(const DocSecRefList &l) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefList)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSecRefList &)}\n"); m_t << "{\n"; incIndentLevel(); m_t << rtf_Style_Reset << getStyle("LatexTOC") << "\n"; m_t << "\\par\n"; m_lastIsPara=TRUE; -} - -void RTFDocVisitor::visitPost(DocSecRefList *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefList)}\n"); + visitChildren(l); decIndentLevel(); m_t << "\\par"; m_t << "}\n"; m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocParamSect *s) +void RTFDocVisitor::operator()(const DocParamSect &s) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamSect)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocParamSect &)}\n"); m_t << "{"; // start param list if (!m_lastIsPara) m_t << "\\par\n"; //m_t << "{\\b "; // start bold m_t << "{" << rtf_Style["Heading5"].reference() << "\n"; - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: m_t << theTranslator->trParameters(); break; @@ -1478,27 +1340,18 @@ void RTFDocVisitor::visitPre(DocParamSect *s) } m_t << "\\par"; m_t << "}\n"; - bool useTable = s->type()==DocParamSect::Param || - s->type()==DocParamSect::RetVal || - s->type()==DocParamSect::Exception || - s->type()==DocParamSect::TemplateParam; + bool useTable = s.type()==DocParamSect::Param || + s.type()==DocParamSect::RetVal || + s.type()==DocParamSect::Exception || + s.type()==DocParamSect::TemplateParam; if (!useTable) { incIndentLevel(); } m_t << rtf_Style_Reset << getStyle("DescContinue"); m_lastIsPara=TRUE; -} - -void RTFDocVisitor::visitPost(DocParamSect *s) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamSect)}\n"); + visitChildren(s); //m_t << "\\par\n"; - bool useTable = s->type()==DocParamSect::Param || - s->type()==DocParamSect::RetVal || - s->type()==DocParamSect::Exception || - s->type()==DocParamSect::TemplateParam; if (!useTable) { decIndentLevel(); @@ -1506,7 +1359,12 @@ void RTFDocVisitor::visitPost(DocParamSect *s) m_t << "}\n"; } -void RTFDocVisitor::visitPre(DocParamList *pl) +void RTFDocVisitor::operator()(const DocSeparator &sep) +{ + m_t << " " << sep.chars() << " "; +} + +void RTFDocVisitor::operator()(const DocParamList &pl) { static int columnPos[4][5] = { { 2, 25, 100, 100, 100 }, // no inout, no type @@ -1516,14 +1374,13 @@ void RTFDocVisitor::visitPre(DocParamList *pl) }; int config=0; if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamList)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocParamList &)}\n"); DocParamSect::Type parentType = DocParamSect::Unknown; - DocParamSect *sect = 0; - if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + const DocParamSect *sect = std::get_if<DocParamSect>(pl.parent()); + if (sect) { - parentType = ((DocParamSect*)pl->parent())->type(); - sect=(DocParamSect*)pl->parent(); + parentType = sect->type(); } bool useTable = parentType==DocParamSect::Param || parentType==DocParamSect::RetVal || @@ -1561,17 +1418,17 @@ void RTFDocVisitor::visitPre(DocParamList *pl) } // Put in the direction: in/out/in,out if specified. - if (pl->direction()!=DocParamSect::Unspecified) + if (pl.direction()!=DocParamSect::Unspecified) { - if (pl->direction()==DocParamSect::In) + if (pl.direction()==DocParamSect::In) { m_t << "in"; } - else if (pl->direction()==DocParamSect::Out) + else if (pl.direction()==DocParamSect::Out) { m_t << "out"; } - else if (pl->direction()==DocParamSect::InOut) + else if (pl.direction()==DocParamSect::InOut) { m_t << "in,out"; } @@ -1589,20 +1446,9 @@ void RTFDocVisitor::visitPre(DocParamList *pl) { m_t << "{"; } - for (const auto &type : pl->paramTypes()) + for (const auto &type : pl.paramTypes()) { - if (type->kind()==DocNode::Kind_Word) - { - visit((DocWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_Sep) - { - m_t << " " << ((DocSeparator *)type.get())->chars() << " "; - } + std::visit(*this,type); } if (useTable) { @@ -1618,17 +1464,10 @@ void RTFDocVisitor::visitPre(DocParamList *pl) m_t << "{\\i "; bool first=TRUE; - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { if (!first) m_t << ","; else first=FALSE; - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } + std::visit(*this,param); } m_t << "} "; @@ -1637,24 +1476,12 @@ void RTFDocVisitor::visitPre(DocParamList *pl) m_t << "\\cell }{"; } m_lastIsPara=TRUE; -} -void RTFDocVisitor::visitPost(DocParamList *pl) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamList)}\n"); - - DocParamSect::Type parentType = DocParamSect::Unknown; - //DocParamSect *sect = 0; - if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + for (const auto &par : pl.paragraphs()) { - parentType = ((DocParamSect*)pl->parent())->type(); - //sect=(DocParamSect*)pl->parent(); + std::visit(*this,par); } - bool useTable = parentType==DocParamSect::Param || - parentType==DocParamSect::RetVal || - parentType==DocParamSect::Exception || - parentType==DocParamSect::TemplateParam; + if (useTable) { m_t << "\\cell }\n"; @@ -1669,12 +1496,12 @@ void RTFDocVisitor::visitPost(DocParamList *pl) m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocXRefItem *x) +void RTFDocVisitor::operator()(const DocXRefItem &x) { if (m_hide) return; - if (x->title().isEmpty()) return; - bool anonymousEnum = x->file()=="@"; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocXRefItem)}\n"); + if (x.title().isEmpty()) return; + bool anonymousEnum = x.file()=="@"; + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocXRefItem &)}\n"); if (!m_lastIsPara) { m_t << "\\par\n"; @@ -1686,17 +1513,17 @@ void RTFDocVisitor::visitPre(DocXRefItem *x) if (Config_getBool(RTF_HYPERLINKS) && !anonymousEnum) { QCString refName; - if (!x->file().isEmpty()) + if (!x.file().isEmpty()) { - refName+=stripPath(x->file()); + refName+=stripPath(x.file()); } - if (!x->file().isEmpty() && !x->anchor().isEmpty()) + if (!x.file().isEmpty() && !x.anchor().isEmpty()) { refName+="_"; } - if (!x->anchor().isEmpty()) + if (!x.anchor().isEmpty()) { - refName+=x->anchor(); + refName+=x.anchor(); } m_t << "{\\field " @@ -1706,14 +1533,14 @@ void RTFDocVisitor::visitPre(DocXRefItem *x) "}" "{\\fldrslt " "{\\cs37\\ul\\cf2 "; - filter(x->title()); + filter(x.title()); m_t << "}" "}" "}"; } else { - filter(x->title()); + filter(x.title()); } m_t << ":"; m_t << "\\par"; @@ -1721,12 +1548,8 @@ void RTFDocVisitor::visitPre(DocXRefItem *x) incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); m_lastIsPara=FALSE; -} - -void RTFDocVisitor::visitPost(DocXRefItem *x) -{ - if (m_hide) return; - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocXRefItem)}\n"); m_t << "\\par\n"; decIndentLevel(); @@ -1734,71 +1557,46 @@ void RTFDocVisitor::visitPost(DocXRefItem *x) m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocInternalRef *ref) +void RTFDocVisitor::operator()(const DocInternalRef &ref) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocInternalRef)}\n"); - startLink("",ref->file(),ref->anchor()); -} - -void RTFDocVisitor::visitPost(DocInternalRef *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternalRef)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocInternalRef &)}\n"); + startLink("",ref.file(),ref.anchor()); + visitChildren(ref); endLink(""); m_t << " "; } -void RTFDocVisitor::visitPre(DocText *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocText)}\n"); -} - -void RTFDocVisitor::visitPost(DocText *) +void RTFDocVisitor::operator()(const DocText &t) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocText)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocText &)}\n"); + visitChildren(t); } -void RTFDocVisitor::visitPre(DocHtmlBlockQuote *) +void RTFDocVisitor::operator()(const DocHtmlBlockQuote &q) { if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlBlockQuote)}\n"); + DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlBlockQuote &)}\n"); if (!m_lastIsPara) m_t << "\\par\n"; m_t << "{"; // start desc incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); -} - -void RTFDocVisitor::visitPost(DocHtmlBlockQuote *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlBlockQuote)}\n"); + visitChildren(q); if (!m_lastIsPara) m_t << "\\par\n"; decIndentLevel(); m_t << "}"; // end desc m_lastIsPara=TRUE; } -void RTFDocVisitor::visitPre(DocVhdlFlow *) +void RTFDocVisitor::operator()(const DocVhdlFlow &) { - if (m_hide) return; } -void RTFDocVisitor::visitPost(DocVhdlFlow *) -{ - if (m_hide) return; -} - -void RTFDocVisitor::visitPre(DocParBlock *) -{ - if (m_hide) return; -} - -void RTFDocVisitor::visitPost(DocParBlock *) +void RTFDocVisitor::operator()(const DocParBlock &pb) { if (m_hide) return; + visitChildren(pb); } @@ -1813,27 +1611,11 @@ void RTFDocVisitor::filter(const QCString &str,bool verbatim) { if (!str.isEmpty()) { - const unsigned char *p=(const unsigned char *)str.data(); - unsigned char c; - //unsigned char pc='\0'; + const char *p=str.data(); + char c; while (*p) { - //static bool MultiByte = FALSE; c=*p++; - - //if ( MultiByte ) - //{ - // m_t << getMultiByte( c ); - // MultiByte = FALSE; - // continue; - //} - //if ( c >= 0x80 ) - //{ - // MultiByte = TRUE; - // m_t << getMultiByte( c ); - // continue; - //} - switch (c) { case '{': m_t << "\\{"; break; @@ -1848,9 +1630,8 @@ void RTFDocVisitor::filter(const QCString &str,bool verbatim) m_t << '\n'; } break; - default: m_t << (char)c; + default: m_t << c; } - //pc = c; } } } @@ -1898,9 +1679,9 @@ void RTFDocVisitor::endLink(const QCString &ref) m_lastIsPara=FALSE; } -void RTFDocVisitor::writeDotFile(DocDotFile *df) +void RTFDocVisitor::writeDotFile(const DocDotFile &df) { - writeDotFile(df->file(), df->hasCaption(), df->srcFile(), df->srcLine()); + writeDotFile(df.file(), df.hasCaption(), df.srcFile(), df.srcLine()); } void RTFDocVisitor::writeDotFile(const QCString &filename, bool hasCaption, const QCString &srcFile, int srcLine) @@ -1917,9 +1698,9 @@ void RTFDocVisitor::writeDotFile(const QCString &filename, bool hasCaption, includePicturePreRTF(baseName + "." + imgExt, true, hasCaption); } -void RTFDocVisitor::writeMscFile(DocMscFile *df) +void RTFDocVisitor::writeMscFile(const DocMscFile &df) { - writeMscFile(df->file(), df->hasCaption(), df->srcFile(), df->srcLine()); + writeMscFile(df.file(), df.hasCaption(), df.srcFile(), df.srcLine()); } void RTFDocVisitor::writeMscFile(const QCString &fileName, bool hasCaption, const QCString &srcFile, int srcLine) @@ -1935,17 +1716,17 @@ void RTFDocVisitor::writeMscFile(const QCString &fileName, bool hasCaption, includePicturePreRTF(baseName + ".png", true, hasCaption); } -void RTFDocVisitor::writeDiaFile(DocDiaFile *df) +void RTFDocVisitor::writeDiaFile(const DocDiaFile &df) { - QCString baseName=df->file(); + QCString baseName=df.file(); int i; if ((i=baseName.findRev('/'))!=-1) { baseName=baseName.right(baseName.length()-i-1); } QCString outDir = Config_getString(RTF_OUTPUT); - writeDiaGraphFromFile(df->file(),outDir,baseName,DIA_BITMAP,df->srcFile(),df->srcLine()); - includePicturePreRTF(baseName + ".png", true, df->hasCaption()); + writeDiaGraphFromFile(df.file(),outDir,baseName,DIA_BITMAP,df.srcFile(),df.srcLine()); + includePicturePreRTF(baseName + ".png", true, df.hasCaption()); } void RTFDocVisitor::writePlantUMLFile(const QCString &fileName, bool hasCaption) diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h index 9d8a3af..fc3257c 100644 --- a/src/rtfdocvisitor.h +++ b/src/rtfdocvisitor.h @@ -22,7 +22,7 @@ #include <iostream> #include "docvisitor.h" -#include "qcstring.h" +#include "docnode.h" class CodeOutputInterface; class TextStream; @@ -37,106 +37,76 @@ class RTFDocVisitor : public DocVisitor // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *); - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *s); - void visitPost(DocSection *); - void visitPre(DocHtmlList *s); - void visitPost(DocHtmlList *s); - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - //void visitPre(DocHtmlPre *); - //void visitPost(DocHtmlPre *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *t); - void visitPost(DocHtmlTable *t); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *) ; - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *); - void visitPost(DocLink *); - void visitPre(DocRef *ref); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &); + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &s); + void operator()(const DocHtmlList &s); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &t); + void operator()(const DocHtmlCaption &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &); + void operator()(const DocRef &ref); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); private: + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } //-------------------------------------- // helper functions @@ -155,10 +125,10 @@ class RTFDocVisitor : public DocVisitor void includePicturePreRTF(const QCString &name, bool isTypeRTF, bool hasCaption, bool inlineImage = FALSE); void includePicturePostRTF(bool isTypeRTF, bool hasCaption, bool inlineImage = FALSE); void writeDotFile(const QCString &fileName, bool hasCaption,const QCString &srcFile,int srcLine); - void writeDotFile(DocDotFile *); + void writeDotFile(const DocDotFile &); void writeMscFile(const QCString &fileName, bool hasCaption,const QCString &srcFile,int srcLine); - void writeMscFile(DocMscFile *); - void writeDiaFile(DocDiaFile *); + void writeMscFile(const DocMscFile &); + void writeDiaFile(const DocDiaFile &); void writePlantUMLFile(const QCString &fileName, bool hasCaption); //-------------------------------------- diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index e740d1f..a905fc0 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -218,7 +218,7 @@ void RTFGenerator::cleanup() static QCString makeIndexName(const QCString &s,int i) { QCString result=s; - result+=(char)(i+'0'); + result+=static_cast<char>(i+'0'); return result; } @@ -279,7 +279,7 @@ void RTFGenerator::beginRTFDocument() m_t << "{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n"; // set the paper dimensions according to PAPER_TYPE - static auto paperType = Config_getEnum(PAPER_TYPE); + auto paperType = Config_getEnum(PAPER_TYPE); m_t << "{"; switch (paperType) { @@ -431,10 +431,6 @@ void RTFGenerator::startIndexSection(IndexSections is) //Introduction beginRTFChapter(); break; - //case isPackageIndex: - // //Package Index - // beginRTFChapter(); - // break; case isModuleIndex: //Module Index beginRTFChapter(); @@ -601,7 +597,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isTitlePageAuthor: { - m_t << " doxygen" << getDoxygenVersion() << ".}\n"; + m_t << " doxygen " << getDoxygenVersion() << ".}\n"; m_t << "{\\creatim " << dateToRTFDateString() << "}\n}"; DBG_RTF(m_t << "{\\comment end of infoblock}\n"); // setup for this section @@ -633,11 +629,14 @@ void RTFGenerator::endIndexSection(IndexSections is) } else { - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocText> root { validatingParseText(*parser.get(), projectName) }; - m_t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt "; - writeDoc(root.get(),0,0,0); - m_t << "}}\\par\n"; + auto parser { createDocParser() }; + auto ast { validatingParseText(*parser.get(), projectName) }; + if (ast) + { + m_t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt "; + writeDoc(ast.get(),0,0,0); + m_t << "}}\\par\n"; + } } m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to title style @@ -694,11 +693,6 @@ void RTFGenerator::endIndexSection(IndexSections is) m_t << "index"; m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; break; - //case isPackageIndex: - // m_t << "\\par " << rtf_Style_Reset << "\n"; - // m_t << "{\\tc \\v " << theTranslator->trPackageList() << "}\n"; - // m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; - // break; case isModuleIndex: m_t << "\\par " << rtf_Style_Reset << "\n"; m_t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}\n"; @@ -929,23 +923,6 @@ void RTFGenerator::endIndexSection(IndexSections is) } break; case isPageDocumentation: - { -//#error "fix me in the same way as the latex index..." - //m_t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}\n"; - //m_t << "}\n"; - //bool first=TRUE; - //for (const auto *pd : Doxygen::pageLinkedMap) - //{ - // if (!pd->getGroupDef() && !pd->isReference()) - // { - // if (first) m_t << "\\par " << rtf_Style_Reset << "\n"; - // m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \""; - // m_t << pd->getOutputFileBase(); - // m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; - // first=FALSE; - // } - //} - } break; case isPageDocumentation2: { @@ -1615,12 +1592,10 @@ void RTFGenerator::docify(const QCString &str) { if (!str.isEmpty()) { - const unsigned char *p=(const unsigned char *)str.data(); - unsigned char c; - //unsigned char pc='\0'; + const char *p=str.data(); + char c; while (*p) { - //static bool MultiByte = FALSE; c=*p++; switch (c) @@ -1630,12 +1605,9 @@ void RTFGenerator::docify(const QCString &str) case '\\': m_t << "\\\\"; break; default: { - // see if we can insert an hyphenation hint - //if (isupper(c) && islower(pc) && !insideTabbing) m_t << "\\-"; - m_t << (char)c; + m_t << c; } } - //pc = c; m_omitParagraph = FALSE; } } @@ -1648,8 +1620,8 @@ void RTFGenerator::codify(const QCString &str) //static char spaces[]=" "; if (!str.isEmpty()) { - const unsigned char *p=(const unsigned char *)str.data(); - unsigned char c; + const char *p=str.data(); + char c; int spacesToNextTabStop; while (*p) @@ -1670,7 +1642,7 @@ void RTFGenerator::codify(const QCString &str) case '{': m_t << "\\{"; m_col++; break; case '}': m_t << "\\}"; m_col++; break; case '\\': m_t << "\\\\"; m_col++; break; - default: p=(const unsigned char *)writeUTF8Char(m_t,(const char *)p-1); m_col++; break; + default: p=writeUTF8Char(m_t,p-1); m_col++; break; } } } @@ -2021,15 +1993,15 @@ static void encodeForOutput(TextStream &t,const QCString &s) if (s==0) return; QCString encoding; bool converted=FALSE; - int l = (int)s.length(); + size_t l = s.length(); static std::vector<char> enc; - if (l*4>(int)enc.size()) enc.resize(l*4); // worst case + if (l*4>enc.size()) enc.resize(l*4); // worst case encoding.sprintf("CP%s",qPrint(theTranslator->trRTFansicp())); if (!encoding.isEmpty()) { // convert from UTF-8 back to the output encoding void *cd = portable_iconv_open(encoding.data(),"UTF-8"); - if (cd!=(void *)(-1)) + if (cd!=reinterpret_cast<void *>(-1)) { size_t iLeft=l; size_t oLeft=enc.size(); @@ -2037,7 +2009,7 @@ static void encodeForOutput(TextStream &t,const QCString &s) char *outputPtr = &enc[0]; if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft)) { - enc.resize(enc.size()-(unsigned int)oLeft); + enc.resize(enc.size()-oLeft); converted=TRUE; } portable_iconv_close(cd); @@ -2048,12 +2020,11 @@ static void encodeForOutput(TextStream &t,const QCString &s) memcpy(enc.data(),s.data(),l); enc.resize(l); } - uint i; bool multiByte = FALSE; - for (i=0;i<enc.size();i++) + for (size_t i=0;i<enc.size();i++) { - uchar c = (uchar)enc.at(i); + uchar c = static_cast<uchar>(enc.at(i)); if (c>=0x80 || multiByte) { @@ -2072,7 +2043,7 @@ static void encodeForOutput(TextStream &t,const QCString &s) } else { - t << (char)c; + t << c; } } } @@ -2470,11 +2441,14 @@ void RTFGenerator::exceptionEntry(const QCString &prefix,bool closeBracket) m_t << " "; } -void RTFGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *,int) +void RTFGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int) { - RTFDocVisitor *visitor = new RTFDocVisitor(m_t,*this,ctx?ctx->getDefFileExtension():QCString("")); - n->accept(visitor); - delete visitor; + auto astImpl = dynamic_cast<const DocNodeAST*>(ast); + if (astImpl) + { + RTFDocVisitor visitor(m_t,*this,ctx?ctx->getDefFileExtension():QCString("")); + std::visit(visitor,astImpl->root); + } m_omitParagraph = TRUE; } diff --git a/src/rtfgen.h b/src/rtfgen.h index dae336b..376174d 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -40,7 +40,7 @@ class RTFGenerator : public OutputGenerator void setRelativePath(const QCString &path); void setSourceFileName(const QCString &sourceFileName); - void writeDoc(DocNode *,const Definition *,const MemberDef *,int); + void writeDoc(const IDocNodeAST *ast,const Definition *,const MemberDef *,int); void startFile(const QCString &name,const QCString &manName,const QCString &title,int id); void writeSearchInfo() {} @@ -261,8 +261,6 @@ class RTFGenerator : public OutputGenerator void endFontClass(); void writeCodeAnchor(const QCString &) {} - void setCurrentDoc(const Definition *,const QCString &,bool) {} - void addWord(const QCString &,bool) {} static bool preProcessFileInplace(const QCString &path,const QCString &name); diff --git a/src/scanner.l b/src/scanner.l index d7f8b37..92387cc 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -76,6 +76,7 @@ struct scannerYY_state int lastSkipSharpContext = 0; int lastSkipRoundContext = 0; int lastStringContext = 0; + int lastDeprecatedContext = 0; int lastCurlyContext = 0; int lastRoundContext = 0; int lastSharpContext = 0; @@ -458,8 +459,27 @@ NONLopt [^\n]* %x RequiresExpression %x ConceptName + /** Object-C Deprecated */ +%x Deprecated_round + %% +<*>"DEPRECATED_ATTRIBUTE" { // Object-C attribute + if (!yyextra->insideObjC) REJECT; + } +<*>"DEPRECATED_MSG_ATTRIBUTE(\"" { // Object-C attribute + if (!yyextra->insideObjC) REJECT; + yyextra->lastDeprecatedContext=YY_START; + yyextra->lastStringContext=Deprecated_round; + BEGIN(SkipString); + } +<Deprecated_round>")" { + BEGIN(yyextra->lastDeprecatedContext); + } +<Deprecated_round>{BNopt} { + lineCount(yyscanner); + } +<Deprecated_round>. { } <NextSemi>"{" { yyextra->curlyCount=0; yyextra->needsSemi = TRUE; @@ -3489,6 +3509,8 @@ NONLopt [^\n]* { yyextra->mtype = Method; yyextra->virt = Normal; + yyextra->current->bodyLine = -1; + yyextra->current->bodyColumn = 1; yyextra->current->groups.clear(); initEntry(yyscanner); } @@ -5038,6 +5060,16 @@ NONLopt [^\n]* BEGIN(FuncQual); } <OldStyleArgs>. { yyextra->current->args += *yytext; } +<FuncQual,FuncRound,FuncFunc>\" { + if (yyextra->insideIDL && yyextra->insideCppQuote) + { + BEGIN(EndCppQuote); + } + else + { + yyextra->current->args += *yytext; + } + } <FuncQual,FuncRound,FuncFunc>. { yyextra->current->args += *yytext; } <FuncQual>{BN}*"try:" | <FuncQual>{BN}*"try"{BN}+ { /* try-function-block */ @@ -6963,6 +6995,11 @@ NONLopt [^\n]* { BEGIN(EndCppQuote); } + else if (yyextra->insidePHP) + { + yyextra->lastStringContext=YY_START; + BEGIN(SkipString); + } } <*>^{B}*"#" { if (!yyextra->insidePHP) @@ -6989,13 +7026,6 @@ NONLopt [^\n]* BEGIN(SkipPHPString); } } -<*>\" { - if (yyextra->insidePHP) - { - yyextra->lastStringContext=YY_START; - BEGIN(SkipString); - } - } <*>\? { if (yyextra->insideCS && (YY_START != SkipRound) && (YY_START != CSAccessorDecl)) { @@ -7486,12 +7516,16 @@ static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al) yyextra->current->brief.resize(0); //printf("handleParametersCommentBlock [%s]\n",qPrint(doc)); + int lineNr = orgDocLine; + Markdown markdown(yyextra->fileName,lineNr); + QCString strippedDoc = stripIndentation(a.docs); + QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc; while (yyextra->commentScanner.parseCommentBlock( yyextra->thisParser, yyextra->current.get(), - a.docs, // text + processedDoc, // text yyextra->fileName, // file - yyextra->current->docLine, // line of block start + lineNr, FALSE, FALSE, FALSE, diff --git a/src/searchindex.cpp b/src/searchindex.cpp index 55716e0..d0bfd49 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -17,8 +17,12 @@ #include <ctype.h> #include <assert.h> #include <sstream> +#include <mutex> +#include <map> +#include <unordered_map> #include "searchindex.h" + #include "config.h" #include "util.h" #include "doxygen.h" @@ -26,21 +30,9 @@ #include "pagedef.h" #include "growbuf.h" #include "message.h" -#include "version.h" #include "groupdef.h" #include "filedef.h" -#include "memberdef.h" -#include "filename.h" -#include "membername.h" -#include "resourcemgr.h" -#include "namespacedef.h" -#include "classdef.h" -#include "utf8.h" -#include "classlist.h" -//--------------------------------------------------------------------------------------------- -// the following part is for the server based search engine -//--------------------------------------------------------------------------------------------- // file format: (all multi-byte values are stored in big endian format) // 4 byte header @@ -57,6 +49,34 @@ const size_t numIndexEntries = 256*256; //-------------------------------------------------------------------- +struct URL +{ + URL(QCString n,QCString u) : name(n), url(u) {} + QCString name; + QCString url; +}; + +struct URLInfo +{ + URLInfo(int idx,int f) : urlIdx(idx), freq(f) {} + int urlIdx; + int freq; +}; + +class IndexWord +{ + public: + using URLInfoMap = std::unordered_map<int,URLInfo>; + IndexWord(QCString word); + void addUrlIndex(int,bool); + URLInfoMap urls() const { return m_urls; } + QCString word() const { return m_word; } + + private: + QCString m_word; + URLInfoMap m_urls; +}; + IndexWord::IndexWord(QCString word) : m_word(word) { //printf("IndexWord::IndexWord(%s)\n",word); @@ -77,6 +97,22 @@ void IndexWord::addUrlIndex(int idx,bool hiPriority) //-------------------------------------------------------------------- +class SearchIndex : public SearchIndexIntf +{ + public: + SearchIndex(); + void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) override; + void addWord(const QCString &word,bool hiPriority) override; + void write(const QCString &file) override; + private: + void addWord(const QCString &word,bool hiPrio,bool recurse); + 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; +}; + SearchIndex::SearchIndex() : SearchIndexIntf(Internal) { m_index.resize(numIndexEntries); @@ -191,8 +227,8 @@ static int charsToIndex(const QCString &word) //return h; // Simple hashing that allows for substring searching - uint c1=(uchar)word[0]; - uint c2=(uchar)word[1]; + uint c1=static_cast<uchar>(word[0]); + uint c2=static_cast<uchar>(word[1]); return c1*256+c2; } @@ -386,6 +422,30 @@ void SearchIndex::write(const QCString &fileName) } +static std::mutex g_transferSearchIndexMutex; + +void SIDataCollection::transfer() +{ + if (Doxygen::searchIndex) + { + std::lock_guard<std::mutex> lock(g_transferSearchIndexMutex); + for (const auto &v : m_data) + { + if (std::holds_alternative<SIData_Word>(v)) + { + const auto &d = std::get<SIData_Word>(v); + Doxygen::searchIndex->addWord(d.word,d.hiPrio); + } + else if (std::holds_alternative<SIData_CurrentDoc>(v)) + { + const auto &d = std::get<SIData_CurrentDoc>(v); + Doxygen::searchIndex->setCurrentDoc(d.ctx,d.anchor,d.isSourceFile); + } + } + } + m_data.clear(); +} + //--------------------------------------------------------------------------- // the following part is for writing an external search index @@ -401,6 +461,18 @@ struct SearchDocEntry GrowBuf normalText; }; +class SearchIndexExternal : public SearchIndexIntf +{ + struct Private; + public: + SearchIndexExternal(); + void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) override; + void addWord(const QCString &word,bool hiPriority) override; + void write(const QCString &file) override; + private: + std::unique_ptr<Private> p; +}; + struct SearchIndexExternal::Private { std::map<std::string,SearchDocEntry> docEntries; @@ -470,7 +542,7 @@ static QCString definitionToName(const Definition *ctx) void SearchIndexExternal::setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) { - static QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); + QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); QCString baseName = isSourceFile ? (toFileDef(ctx))->getSourceFileBase() : ctx->getOutputFileBase(); QCString url = addHtmlExtensionIfMissing(baseName); if (!anchor.isEmpty()) url+=QCString("#")+anchor; @@ -540,710 +612,12 @@ void SearchIndexExternal::write(const QCString &fileName) } //--------------------------------------------------------------------------------------------- -// the following part is for the javascript based search engine -//--------------------------------------------------------------------------------------------- - -QCString searchName(const Definition *d) -{ - return d->definitionType()==Definition::TypeGroup ? QCString(toGroupDef(d)->groupTitle()) : - d->definitionType()==Definition::TypePage ? toPageDef(d)->title() : - d->localName(); -} - -QCString searchId(const Definition *d) -{ - std::string s = searchName(d).str(); - TextStream t; - for (size_t i=0;i<s.length();i++) - { - if (isIdJS(s[i])) - { - t << s[i]; - } - else // escape non-identifier characters - { - static const char *hex = "0123456789ABCDEF"; - unsigned char uc = static_cast<unsigned char>(s[i]); - t << '_'; - t << hex[uc>>4]; - t << hex[uc&0xF]; - } - } - - return convertUTF8ToLower(t.str()); -} - - -#define SEARCH_INDEX_ALL 0 -#define SEARCH_INDEX_CLASSES 1 -#define SEARCH_INDEX_INTERFACES 2 -#define SEARCH_INDEX_STRUCTS 3 -#define SEARCH_INDEX_EXCEPTIONS 4 -#define SEARCH_INDEX_NAMESPACES 5 -#define SEARCH_INDEX_FILES 6 -#define SEARCH_INDEX_FUNCTIONS 7 -#define SEARCH_INDEX_VARIABLES 8 -#define SEARCH_INDEX_TYPEDEFS 9 -#define SEARCH_INDEX_SEQUENCES 10 -#define SEARCH_INDEX_DICTIONARIES 11 -#define SEARCH_INDEX_ENUMS 12 -#define SEARCH_INDEX_ENUMVALUES 13 -#define SEARCH_INDEX_PROPERTIES 14 -#define SEARCH_INDEX_EVENTS 15 -#define SEARCH_INDEX_RELATED 16 -#define SEARCH_INDEX_DEFINES 17 -#define SEARCH_INDEX_GROUPS 18 -#define SEARCH_INDEX_PAGES 19 -#define SEARCH_INDEX_CONCEPTS 20 - -static std::array<SearchIndexInfo,NUM_SEARCH_INDICES> g_searchIndexInfo = -{ { - // index name getText symbolList - { /* SEARCH_INDEX_ALL */ "all" , []() { return theTranslator->trAll(); }, {} }, - { /* SEARCH_INDEX_CLASSES */ "classes" , []() { return theTranslator->trClasses(); }, {} }, - { /* SEARCH_INDEX_INTERFACES */ "interfaces" , []() { return theTranslator->trSliceInterfaces(); }, {} }, - { /* SEARCH_INDEX_STRUCTS */ "structs" , []() { return theTranslator->trStructs(); }, {} }, - { /* SEARCH_INDEX_EXCEPTIONS */ "exceptions" , []() { return theTranslator->trExceptions(); }, {} }, - { /* SEARCH_INDEX_NAMESPACES */ "namespaces" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? - theTranslator->trModules() : - theTranslator->trNamespace(TRUE,FALSE); }, {} }, - { /* SEARCH_INDEX_FILES */ "files" , []() { return theTranslator->trFile(TRUE,FALSE); }, {} }, - { /* SEARCH_INDEX_FUNCTIONS */ "functions" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? - theTranslator->trOperations() : - theTranslator->trFunctions(); }, {} }, - { /* SEARCH_INDEX_VARIABLES */ "variables" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? - theTranslator->trConstants() : - theTranslator->trVariables(); }, {} }, - { /* SEARCH_INDEX_TYPEDEFS */ "typedefs" , []() { return theTranslator->trTypedefs(); }, {} }, - { /* SEARCH_INDEX_SEQUENCES */ "sequences" , []() { return theTranslator->trSequences(); }, {} }, - { /* SEARCH_INDEX_DICTIONARIES */ "dictionaries", []() { return theTranslator->trDictionaries(); }, {} }, - { /* SEARCH_INDEX_ENUMS */ "enums" , []() { return theTranslator->trEnumerations(); }, {} }, - { /* SEARCH_INDEX_ENUMVALUES */ "enumvalues" , []() { return theTranslator->trEnumerationValues(); }, {} }, - { /* SEARCH_INDEX_PROPERTIES */ "properties" , []() { return theTranslator->trProperties(); }, {} }, - { /* SEARCH_INDEX_EVENTS */ "events" , []() { return theTranslator->trEvents(); }, {} }, - { /* SEARCH_INDEX_RELATED */ "related" , []() { return theTranslator->trFriends(); }, {} }, - { /* SEARCH_INDEX_DEFINES */ "defines" , []() { return theTranslator->trDefines(); }, {} }, - { /* SEARCH_INDEX_GROUPS */ "groups" , []() { return theTranslator->trGroup(TRUE,FALSE); }, {} }, - { /* SEARCH_INDEX_PAGES */ "pages" , []() { return theTranslator->trPage(TRUE,FALSE); }, {} }, - { /* SEARCH_INDEX_CONCEPTS */ "concepts" , []() { return theTranslator->trConcept(true,false); }, {} } -} }; - -static void addMemberToSearchIndex(const MemberDef *md) -{ - static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); - bool isLinkable = md->isLinkable(); - const ClassDef *cd=0; - const NamespaceDef *nd=0; - const FileDef *fd=0; - const GroupDef *gd=0; - if (isLinkable && - ( - ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) || - ((gd=md->getGroupDef()) && gd->isLinkable()) - ) - ) - { - std::string n = md->name().str(); - if (!n.empty()) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(n,0)); - bool isFriendToHide = hideFriendCompounds && - (QCString(md->typeString())=="friend class" || - QCString(md->typeString())=="friend struct" || - QCString(md->typeString())=="friend union"); - if (!(md->isFriend() && isFriendToHide)) - { - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,md); - } - if (md->isFunction() || md->isSlot() || md->isSignal()) - { - g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].add(letter,md); - } - else if (md->isVariable()) - { - g_searchIndexInfo[SEARCH_INDEX_VARIABLES].add(letter,md); - } - else if (md->isSequence()) - { - g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].add(letter,md); - } - else if (md->isDictionary()) - { - g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].add(letter,md); - } - else if (md->isTypedef()) - { - g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].add(letter,md); - } - else if (md->isEnumerate()) - { - g_searchIndexInfo[SEARCH_INDEX_ENUMS].add(letter,md); - } - else if (md->isEnumValue()) - { - g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].add(letter,md); - } - else if (md->isProperty()) - { - g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].add(letter,md); - } - else if (md->isEvent()) - { - g_searchIndexInfo[SEARCH_INDEX_EVENTS].add(letter,md); - } - else if (md->isRelated() || md->isForeign() || - (md->isFriend() && !isFriendToHide)) - { - g_searchIndexInfo[SEARCH_INDEX_RELATED].add(letter,md); - } - } - } - else if (isLinkable && - (((nd=md->getNamespaceDef()) && nd->isLinkable()) || - ((fd=md->getFileDef()) && fd->isLinkable()) - ) - ) - { - std::string n = md->name().str(); - if (!n.empty()) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(n,0)); - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,md); - - if (md->isFunction()) - { - g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].add(letter,md); - } - else if (md->isVariable()) - { - g_searchIndexInfo[SEARCH_INDEX_VARIABLES].add(letter,md); - } - else if (md->isSequence()) - { - g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].add(letter,md); - } - else if (md->isDictionary()) - { - g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].add(letter,md); - } - else if (md->isTypedef()) - { - g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].add(letter,md); - } - else if (md->isEnumerate()) - { - g_searchIndexInfo[SEARCH_INDEX_ENUMS].add(letter,md); - } - else if (md->isEnumValue()) - { - g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].add(letter,md); - } - else if (md->isDefine()) - { - g_searchIndexInfo[SEARCH_INDEX_DEFINES].add(letter,md); - } - } - } -} - -//--------------------------------------------------------------------------------------------- - -void createJavaScriptSearchIndex() -{ - // index classes - for (const auto &cd : *Doxygen::classLinkedMap) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(cd->localName().str(),0)); - if (cd->isLinkable()) - { - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,cd.get()); - if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) - { - if (cd->compoundType()==ClassDef::Interface) - { - g_searchIndexInfo[SEARCH_INDEX_INTERFACES].add(letter,cd.get()); - } - else if (cd->compoundType()==ClassDef::Struct) - { - g_searchIndexInfo[SEARCH_INDEX_STRUCTS].add(letter,cd.get()); - } - else if (cd->compoundType()==ClassDef::Exception) - { - g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].add(letter,cd.get()); - } - else // cd->compoundType()==ClassDef::Class - { - g_searchIndexInfo[SEARCH_INDEX_CLASSES].add(letter,cd.get()); - } - } - else // non slice optimisation: group all types under classes - { - g_searchIndexInfo[SEARCH_INDEX_CLASSES].add(letter,cd.get()); - } - } - } - - // index namespaces - for (const auto &nd : *Doxygen::namespaceLinkedMap) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(nd->name().str(),0)); - if (nd->isLinkable()) - { - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,nd.get()); - g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].add(letter,nd.get()); - } - } - - // index concepts - for (const auto &cd : *Doxygen::conceptLinkedMap) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(cd->name().str(),0)); - if (cd->isLinkable()) - { - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,cd.get()); - g_searchIndexInfo[SEARCH_INDEX_CONCEPTS].add(letter,cd.get()); - } - } - - // index files - for (const auto &fn : *Doxygen::inputNameLinkedMap) - { - for (const auto &fd : *fn) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(fd->name().str(),0)); - if (fd->isLinkable()) - { - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,fd.get()); - g_searchIndexInfo[SEARCH_INDEX_FILES].add(letter,fd.get()); - } - } - } - - // index class members - { - // for each member name - for (const auto &mn : *Doxygen::memberNameLinkedMap) - { - // for each member definition - for (const auto &md : *mn) - { - addMemberToSearchIndex(md.get()); - } - } - } - - // index file/namespace members - { - // for each member name - for (const auto &mn : *Doxygen::functionNameLinkedMap) - { - // for each member definition - for (const auto &md : *mn) - { - addMemberToSearchIndex(md.get()); - } - } - } - - // index groups - for (const auto &gd : *Doxygen::groupLinkedMap) - { - if (gd->isLinkable()) - { - std::string title = gd->groupTitle().str(); - if (!title.empty()) // TODO: able searching for all word in the title - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(title,0)); - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,gd.get()); - g_searchIndexInfo[SEARCH_INDEX_GROUPS].add(letter,gd.get()); - } - } - } - - // index pages - for (const auto &pd : *Doxygen::pageLinkedMap) - { - if (pd->isLinkable()) - { - std::string title = pd->title().str(); - if (!title.empty()) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(title,0)); - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,pd.get()); - g_searchIndexInfo[SEARCH_INDEX_PAGES].add(letter,pd.get()); - } - } - } - if (Doxygen::mainPage) - { - std::string title = Doxygen::mainPage->title().str(); - if (!title.empty()) - { - std::string letter = convertUTF8ToLower(getUTF8CharAt(title,0)); - g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,Doxygen::mainPage.get()); - g_searchIndexInfo[SEARCH_INDEX_PAGES].add(letter,Doxygen::mainPage.get()); - } - } - - // sort all lists - for (auto &sii : g_searchIndexInfo) // for each index - { - for (auto &kv : sii.symbolMap) // for each symbol in the index - { - // sort the symbols (first on "search" name, and then on full name) - std::sort(kv.second.begin(), - kv.second.end(), - [](const Definition *d1,const Definition *d2) - { - int eq = qstricmp(searchName(d1),searchName(d2)); // search name first - return eq==0 ? qstricmp(d1->name(),d2->name())<0 : eq<0; // then full name - }); - } - } -} - -void writeJavaScriptSearchIndex() -{ - // write index files - QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search"; - - for (auto &sii : g_searchIndexInfo) - { - int p=0; - for (const auto &kv : sii.symbolMap) - { - int cnt = 0; - QCString baseName; - baseName.sprintf("%s_%x",sii.name.data(),p); - - QCString fileName = searchDirName + "/"+baseName+Doxygen::htmlFileExtension; - QCString dataFileName = searchDirName + "/"+baseName+".js"; - - std::ofstream t(fileName.str(), std::ofstream::out | std::ofstream::binary); - std::ofstream ti(dataFileName.str(), std::ofstream::out | std::ofstream::binary); - if (t.is_open() && ti.is_open()) - { - { - t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"" - " \"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; - t << "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; - t << "<head><title></title>\n"; - t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n"; - t << "<meta name=\"generator\" content=\"Doxygen " << getDoxygenVersion() << "\"/>\n"; - t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>\n"; - t << "<script type=\"text/javascript\" src=\"" << baseName << ".js\"></script>\n"; - t << "<script type=\"text/javascript\" src=\"search.js\"></script>\n"; - t << "</head>\n"; - t << "<body class=\"SRPage\">\n"; - t << "<div id=\"SRIndex\">\n"; - t << "<div class=\"SRStatus\" id=\"Loading\">" << theTranslator->trLoading() << "</div>\n"; - t << "<div id=\"SRResults\"></div>\n"; // here the results will be inserted - t << "<script type=\"text/javascript\">\n"; - t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */\n"; - t << "createResults();\n"; // this function will insert the results - t << "/* @license-end */\n"; - t << "</script>\n"; - t << "<div class=\"SRStatus\" id=\"Searching\">" - << theTranslator->trSearching() << "</div>\n"; - t << "<div class=\"SRStatus\" id=\"NoMatches\">" - << theTranslator->trNoMatches() << "</div>\n"; - - t << "<script type=\"text/javascript\">\n"; - t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */\n"; - t << "document.getElementById(\"Loading\").style.display=\"none\";\n"; - t << "document.getElementById(\"NoMatches\").style.display=\"none\";\n"; - t << "var searchResults = new SearchResults(\"searchResults\");\n"; - t << "searchResults.Search();\n"; - t << "window.addEventListener(\"message\", function(event) {\n"; - t << " if (event.data == \"take_focus\") {\n"; - t << " var elem = searchResults.NavNext(0);\n"; - t << " if (elem) elem.focus();\n"; - t << " }\n"; - t << "});\n"; - t << "/* @license-end */\n"; - t << "</script>\n"; - t << "</div>\n"; // SRIndex - t << "</body>\n"; - t << "</html>\n"; - } - - ti << "var searchData=\n"; - // format - // searchData[] = array of items - // searchData[x][0] = id - // searchData[x][1] = [ name + child1 + child2 + .. ] - // searchData[x][1][0] = name as shown - // searchData[x][1][y+1] = info for child y - // searchData[x][1][y+1][0] = url - // searchData[x][1][y+1][1] = 1 => target="_parent" - // searchData[x][1][y+1][2] = scope - - ti << "[\n"; - bool firstEntry=TRUE; - - int childCount=0; - QCString lastName; - const Definition *prevScope = 0; - for (auto it = kv.second.begin(); it!=kv.second.end();) - { - const Definition *d = *it; - QCString sname = searchName(d); - QCString id = searchId(d); - - if (sname!=lastName) // this item has a different search word - { - if (!firstEntry) - { - ti << "]]]"; - ti << ",\n"; - } - firstEntry=FALSE; - - ti << " ['" << id << "_" << cnt++ << "',['" << convertToXML(sname) << "',["; - childCount=0; - prevScope=0; - } - - ++it; - const Definition *scope = d->getOuterScope(); - const Definition *next = it!=kv.second.end() ? *it : 0; - const Definition *nextScope = 0; - const MemberDef *md = toMemberDef(d); - if (next) nextScope = next->getOuterScope(); - QCString anchor = d->anchor(); - - if (childCount>0) - { - ti << "],["; - } - ti << "'" << externalRef("../",d->getReference(),TRUE) - << addHtmlExtensionIfMissing(d->getOutputFileBase()); - if (!anchor.isEmpty()) - { - ti << "#" << anchor; - } - ti << "',"; - - static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW); - if (!extLinksInWindow || d->getReference().isEmpty()) - { - ti << "1,"; - } - else - { - ti << "0,"; - } - - if (lastName!=sname && (next==0 || searchName(next)!=sname)) // unique name - { - if (d->getOuterScope()!=Doxygen::globalScope) - { - ti << "'" << convertToXML(d->getOuterScope()->name()) << "'"; - } - else if (md) - { - const FileDef *fd = md->getBodyDef(); - if (fd==0) fd = md->getFileDef(); - if (fd) - { - ti << "'" << convertToXML(fd->localName()) << "'"; - } - } - else - { - ti << "''"; - } - } - else // multiple entries with the same name - { - bool found=FALSE; - bool overloadedFunction = ((prevScope!=0 && scope==prevScope) || - (scope && scope==nextScope)) && md && (md->isFunction() || md->isSlot()); - QCString prefix; - if (md) prefix=convertToXML(md->localName()); - if (overloadedFunction) // overloaded member function - { - prefix+=convertToXML(md->argsString()); - // show argument list to disambiguate overloaded functions - } - else if (md) // unique member function - { - prefix+="()"; // only to show it is a function - } - QCString name; - if (d->definitionType()==Definition::TypeClass) - { - name = convertToXML((toClassDef(d))->displayName()); - found = TRUE; - } - else if (d->definitionType()==Definition::TypeNamespace) - { - name = convertToXML((toNamespaceDef(d))->displayName()); - found = TRUE; - } - else if (scope==0 || scope==Doxygen::globalScope) // in global scope - { - if (md) - { - const FileDef *fd = md->getBodyDef(); - if (fd==0) fd = md->resolveAlias()->getFileDef(); - if (fd) - { - if (!prefix.isEmpty()) prefix+=": "; - name = prefix + convertToXML(fd->localName()); - found = TRUE; - } - } - } - else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef())) - // member in class or namespace scope - { - SrcLangExt lang = md->getLanguage(); - name = convertToXML(d->getOuterScope()->qualifiedName()) - + getLanguageSpecificSeparator(lang) + prefix; - found = TRUE; - } - else if (scope) // some thing else? -> show scope - { - name = prefix + convertToXML(scope->name()); - found = TRUE; - } - if (!found) // fallback - { - name = prefix + "("+theTranslator->trGlobalNamespace()+")"; - } - - ti << "'" << name << "'"; - - prevScope = scope; - childCount++; - } - lastName = sname; - } - if (!firstEntry) - { - ti << "]]]\n"; - } - ti << "];\n"; - } - else - { - err("Failed to open file '%s' for writing...\n",qPrint(fileName)); - } - p++; - } - } - - { - std::ofstream t(searchDirName.str()+"/searchdata.js", - std::ofstream::out | std::ofstream::binary); - if (t.is_open()) - { - t << "var indexSectionsWithContent =\n"; - t << "{\n"; - int j=0; - for (const auto &sii : g_searchIndexInfo) - { - if (!sii.symbolMap.empty()) - { - if (j>0) t << ",\n"; - t << " " << j << ": \""; - - for (const auto &kv : sii.symbolMap) - { - if ( kv.first == "\"" ) t << "\\"; - t << kv.first; - } - t << "\""; - j++; - } - } - if (j>0) t << "\n"; - t << "};\n\n"; - t << "var indexSectionNames =\n"; - t << "{\n"; - j=0; - for (const auto &sii : g_searchIndexInfo) - { - if (!sii.symbolMap.empty()) - { - if (j>0) t << ",\n"; - t << " " << j << ": \"" << sii.name << "\""; - j++; - } - } - if (j>0) t << "\n"; - t << "};\n\n"; - t << "var indexSectionLabels =\n"; - t << "{\n"; - j=0; - for (const auto &sii : g_searchIndexInfo) - { - if (!sii.symbolMap.empty()) - { - if (j>0) t << ",\n"; - t << " " << j << ": \"" << convertToXML(sii.getText()) << "\""; - j++; - } - } - if (j>0) t << "\n"; - t << "};\n\n"; - } - ResourceMgr::instance().copyResource("search.js",searchDirName); - } - - { - QCString noMatchesFileName =searchDirName+"/nomatches"+Doxygen::htmlFileExtension; - std::ofstream t(noMatchesFileName.str(), std::ofstream::out | std::ofstream::binary); - if (t.is_open()) - { - t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " - "\"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; - t << "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; - t << "<head><title></title>\n"; - t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n"; - t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>\n"; - t << "<script type=\"text/javascript\" src=\"search.js\"></script>\n"; - t << "</head>\n"; - t << "<body class=\"SRPage\">\n"; - t << "<div id=\"SRIndex\">\n"; - t << "<div class=\"SRStatus\" id=\"NoMatches\">" - << theTranslator->trNoMatches() << "</div>\n"; - t << "</div>\n"; - t << "</body>\n"; - t << "</html>\n"; - } - } - - Doxygen::indexList->addStyleSheetFile("search/search.js"); -} - -void SearchIndexInfo::add(const std::string &letter,const Definition *def) -{ - //printf("%p: %s->%s (full=%s)\n",this,qPrint(letter),qPrint(searchName(def)),qPrint(def->name())); - auto it = symbolMap.find(letter); - if (it!=symbolMap.end()) - { - it->second.push_back(def); - } - else - { - symbolMap.insert(std::make_pair(letter,std::vector<const Definition*>({def}))); - } -} - -const std::array<SearchIndexInfo,NUM_SEARCH_INDICES> &getSearchIndices() -{ - return g_searchIndexInfo; -} - -//--------------------------------------------------------------------------------------------- void initSearchIndexer() { - static bool searchEngine = Config_getBool(SEARCHENGINE); - static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH); - static bool externalSearch = Config_getBool(EXTERNAL_SEARCH); + bool searchEngine = Config_getBool(SEARCHENGINE); + bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH); + bool externalSearch = Config_getBool(EXTERNAL_SEARCH); if (searchEngine && serverBasedSearch) { if (externalSearch) // external tools produce search index and engine diff --git a/src/searchindex.h b/src/searchindex.h index 893440e..ad79858 100644 --- a/src/searchindex.h +++ b/src/searchindex.h @@ -13,63 +13,80 @@ * */ +/** @file + * @brief Web server based search engine. + * + * Comes in two flavors: internal (via generated index) or external (via doxyindexer + doxysearch) + */ + #ifndef SEARCHINDEX_H #define SEARCHINDEX_H #include <memory> #include <vector> -#include <map> -#include <unordered_map> #include <string> #include <array> -#include <functional> +#include <variant> #include "qcstring.h" class Definition; +class SearchIndexIntf; /*! Initialize the search indexer */ void initSearchIndexer(); /*! Cleanup the search indexer */ void finalizeSearchIndexer(); -//------- server side search index ---------------------- +// --- intermediate data collected by one thread ------ -struct URL +struct SIData_CurrentDoc { - URL(QCString n,QCString u) : name(n), url(u) {} - QCString name; - QCString url; + SIData_CurrentDoc(const Definition *d,const QCString &a,bool b) + : ctx(d), anchor(a), isSourceFile(b) {} + const Definition *ctx = 0; + QCString anchor; + bool isSourceFile; }; - -struct URLInfo +struct SIData_Word { - URLInfo(int idx,int f) : urlIdx(idx), freq(f) {} - int urlIdx; - int freq; + SIData_Word(const QCString &w,bool b) + : word(w), hiPrio(b) {} + QCString word; + bool hiPrio; }; -class IndexWord +// class to aggregate the search data collected on a worker thread +// and later transfer it to the search index on the main thread. +class SIDataCollection { public: - using URLInfoMap = std::unordered_map<int,URLInfo>; - IndexWord(QCString word); - void addUrlIndex(int,bool); - URLInfoMap urls() const { return m_urls; } - QCString word() const { return m_word; } + void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) + { + m_data.emplace_back(SIData_CurrentDoc(ctx,anchor,isSourceFile)); + } + void addWord(const QCString &word,bool hiPriority) + { + m_data.emplace_back(SIData_Word(word,hiPriority)); + } + + // transfer the collected data into the given search index + void transfer(); private: - QCString m_word; - URLInfoMap m_urls; + using SIData = std::variant<SIData_CurrentDoc,SIData_Word>; + std::vector<SIData> m_data; }; +//----------------------------- + class SearchIndexIntf { public: enum Kind { Internal, External }; SearchIndexIntf(Kind k) : m_kind(k) {} - virtual ~SearchIndexIntf() {} + virtual ~SearchIndexIntf() = default; virtual void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) = 0; virtual void addWord(const QCString &word,bool hiPriority) = 0; virtual void write(const QCString &file) = 0; @@ -78,55 +95,5 @@ class SearchIndexIntf Kind m_kind; }; -class SearchIndex : public SearchIndexIntf -{ - public: - SearchIndex(); - void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) override; - void addWord(const QCString &word,bool hiPriority) override; - void write(const QCString &file) override; - private: - void addWord(const QCString &word,bool hiPrio,bool recurse); - 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; -}; - - -class SearchIndexExternal : public SearchIndexIntf -{ - struct Private; - public: - SearchIndexExternal(); - void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile); - void addWord(const QCString &word,bool hiPriority); - void write(const QCString &file); - private: - std::unique_ptr<Private> p; -}; - -//------- client side search index ---------------------- - -#define NUM_SEARCH_INDICES 21 - -QCString searchId(const Definition *d); -QCString searchName(const Definition *d); - -using SearchIndexList = std::vector<const Definition *>; -using SearchIndexMap = std::map<std::string,SearchIndexList>; - -struct SearchIndexInfo -{ - void add(const std::string &letter,const Definition *def); - QCString name; - std::function<QCString()> getText; - SearchIndexMap symbolMap; -}; - -void createJavaScriptSearchIndex(); -void writeJavaScriptSearchIndex(); -const std::array<SearchIndexInfo,NUM_SEARCH_INDICES> &getSearchIndices(); #endif diff --git a/src/searchindex_js.cpp b/src/searchindex_js.cpp new file mode 100644 index 0000000..ad1ef98 --- /dev/null +++ b/src/searchindex_js.cpp @@ -0,0 +1,732 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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 <utility> +#include <algorithm> +#include <fstream> + +#include "searchindex_js.h" +#include "doxygen.h" +#include "groupdef.h" +#include "pagedef.h" +#include "namespacedef.h" +#include "classdef.h" +#include "classlist.h" +#include "membername.h" +#include "filename.h" +#include "language.h" +#include "textstream.h" +#include "util.h" +#include "version.h" +#include "message.h" +#include "resourcemgr.h" + +QCString searchName(const Definition *d) +{ + return d->definitionType()==Definition::TypeGroup ? QCString(toGroupDef(d)->groupTitle()) : + d->definitionType()==Definition::TypePage ? toPageDef(d)->title() : + d->localName(); +} + +QCString searchId(const Definition *d) +{ + std::string s = searchName(d).str(); + TextStream t; + for (size_t i=0;i<s.length();i++) + { + if (isIdJS(s[i])) + { + t << s[i]; + } + else // escape non-identifier characters + { + static const char *hex = "0123456789ABCDEF"; + unsigned char uc = static_cast<unsigned char>(s[i]); + t << '_'; + t << hex[uc>>4]; + t << hex[uc&0xF]; + } + } + + return convertUTF8ToLower(t.str()); +} + + +#define SEARCH_INDEX_ALL 0 +#define SEARCH_INDEX_CLASSES 1 +#define SEARCH_INDEX_INTERFACES 2 +#define SEARCH_INDEX_STRUCTS 3 +#define SEARCH_INDEX_EXCEPTIONS 4 +#define SEARCH_INDEX_NAMESPACES 5 +#define SEARCH_INDEX_FILES 6 +#define SEARCH_INDEX_FUNCTIONS 7 +#define SEARCH_INDEX_VARIABLES 8 +#define SEARCH_INDEX_TYPEDEFS 9 +#define SEARCH_INDEX_SEQUENCES 10 +#define SEARCH_INDEX_DICTIONARIES 11 +#define SEARCH_INDEX_ENUMS 12 +#define SEARCH_INDEX_ENUMVALUES 13 +#define SEARCH_INDEX_PROPERTIES 14 +#define SEARCH_INDEX_EVENTS 15 +#define SEARCH_INDEX_RELATED 16 +#define SEARCH_INDEX_DEFINES 17 +#define SEARCH_INDEX_GROUPS 18 +#define SEARCH_INDEX_PAGES 19 +#define SEARCH_INDEX_CONCEPTS 20 + +static std::array<SearchIndexInfo,NUM_SEARCH_INDICES> g_searchIndexInfo = +{ { + // index name getText symbolList + { /* SEARCH_INDEX_ALL */ "all" , []() { return theTranslator->trAll(); }, {} }, + { /* SEARCH_INDEX_CLASSES */ "classes" , []() { return theTranslator->trClasses(); }, {} }, + { /* SEARCH_INDEX_INTERFACES */ "interfaces" , []() { return theTranslator->trSliceInterfaces(); }, {} }, + { /* SEARCH_INDEX_STRUCTS */ "structs" , []() { return theTranslator->trStructs(); }, {} }, + { /* SEARCH_INDEX_EXCEPTIONS */ "exceptions" , []() { return theTranslator->trExceptions(); }, {} }, + { /* SEARCH_INDEX_NAMESPACES */ "namespaces" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trModules() : + theTranslator->trNamespace(TRUE,FALSE); }, {} }, + { /* SEARCH_INDEX_FILES */ "files" , []() { return theTranslator->trFile(TRUE,FALSE); }, {} }, + { /* SEARCH_INDEX_FUNCTIONS */ "functions" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trOperations() : + theTranslator->trFunctions(); }, {} }, + { /* SEARCH_INDEX_VARIABLES */ "variables" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trConstants() : + theTranslator->trVariables(); }, {} }, + { /* SEARCH_INDEX_TYPEDEFS */ "typedefs" , []() { return theTranslator->trTypedefs(); }, {} }, + { /* SEARCH_INDEX_SEQUENCES */ "sequences" , []() { return theTranslator->trSequences(); }, {} }, + { /* SEARCH_INDEX_DICTIONARIES */ "dictionaries", []() { return theTranslator->trDictionaries(); }, {} }, + { /* SEARCH_INDEX_ENUMS */ "enums" , []() { return theTranslator->trEnumerations(); }, {} }, + { /* SEARCH_INDEX_ENUMVALUES */ "enumvalues" , []() { return theTranslator->trEnumerationValues(); }, {} }, + { /* SEARCH_INDEX_PROPERTIES */ "properties" , []() { return theTranslator->trProperties(); }, {} }, + { /* SEARCH_INDEX_EVENTS */ "events" , []() { return theTranslator->trEvents(); }, {} }, + { /* SEARCH_INDEX_RELATED */ "related" , []() { return theTranslator->trFriends(); }, {} }, + { /* SEARCH_INDEX_DEFINES */ "defines" , []() { return theTranslator->trDefines(); }, {} }, + { /* SEARCH_INDEX_GROUPS */ "groups" , []() { return theTranslator->trGroup(TRUE,FALSE); }, {} }, + { /* SEARCH_INDEX_PAGES */ "pages" , []() { return theTranslator->trPage(TRUE,FALSE); }, {} }, + { /* SEARCH_INDEX_CONCEPTS */ "concepts" , []() { return theTranslator->trConcept(true,false); }, {} } +} }; + +static void addMemberToSearchIndex(const MemberDef *md) +{ + bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); + bool isLinkable = md->isLinkable(); + const ClassDef *cd=0; + const NamespaceDef *nd=0; + const FileDef *fd=0; + const GroupDef *gd=0; + if (isLinkable && + ( + ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) || + ((gd=md->getGroupDef()) && gd->isLinkable()) + ) + ) + { + std::string n = md->name().str(); + if (!n.empty()) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(n,0)); + bool isFriendToHide = hideFriendCompounds && + (QCString(md->typeString())=="friend class" || + QCString(md->typeString())=="friend struct" || + QCString(md->typeString())=="friend union"); + if (!(md->isFriend() && isFriendToHide)) + { + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,md); + } + if (md->isFunction() || md->isSlot() || md->isSignal()) + { + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].add(letter,md); + } + else if (md->isVariable()) + { + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].add(letter,md); + } + else if (md->isSequence()) + { + g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].add(letter,md); + } + else if (md->isDictionary()) + { + g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].add(letter,md); + } + else if (md->isTypedef()) + { + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].add(letter,md); + } + else if (md->isEnumerate()) + { + g_searchIndexInfo[SEARCH_INDEX_ENUMS].add(letter,md); + } + else if (md->isEnumValue()) + { + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].add(letter,md); + } + else if (md->isProperty()) + { + g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].add(letter,md); + } + else if (md->isEvent()) + { + g_searchIndexInfo[SEARCH_INDEX_EVENTS].add(letter,md); + } + else if (md->isRelated() || md->isForeign() || + (md->isFriend() && !isFriendToHide)) + { + g_searchIndexInfo[SEARCH_INDEX_RELATED].add(letter,md); + } + } + } + else if (isLinkable && + (((nd=md->getNamespaceDef()) && nd->isLinkable()) || + ((fd=md->getFileDef()) && fd->isLinkable()) + ) + ) + { + std::string n = md->name().str(); + if (!n.empty()) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(n,0)); + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,md); + + if (md->isFunction()) + { + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].add(letter,md); + } + else if (md->isVariable()) + { + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].add(letter,md); + } + else if (md->isSequence()) + { + g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].add(letter,md); + } + else if (md->isDictionary()) + { + g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].add(letter,md); + } + else if (md->isTypedef()) + { + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].add(letter,md); + } + else if (md->isEnumerate()) + { + g_searchIndexInfo[SEARCH_INDEX_ENUMS].add(letter,md); + } + else if (md->isEnumValue()) + { + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].add(letter,md); + } + else if (md->isDefine()) + { + g_searchIndexInfo[SEARCH_INDEX_DEFINES].add(letter,md); + } + } + } +} + +//--------------------------------------------------------------------------------------------- + +void createJavaScriptSearchIndex() +{ + // index classes + for (const auto &cd : *Doxygen::classLinkedMap) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(cd->localName().str(),0)); + if (cd->isLinkable()) + { + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,cd.get()); + if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + if (cd->compoundType()==ClassDef::Interface) + { + g_searchIndexInfo[SEARCH_INDEX_INTERFACES].add(letter,cd.get()); + } + else if (cd->compoundType()==ClassDef::Struct) + { + g_searchIndexInfo[SEARCH_INDEX_STRUCTS].add(letter,cd.get()); + } + else if (cd->compoundType()==ClassDef::Exception) + { + g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].add(letter,cd.get()); + } + else // cd->compoundType()==ClassDef::Class + { + g_searchIndexInfo[SEARCH_INDEX_CLASSES].add(letter,cd.get()); + } + } + else // non slice optimisation: group all types under classes + { + g_searchIndexInfo[SEARCH_INDEX_CLASSES].add(letter,cd.get()); + } + } + } + + // index namespaces + for (const auto &nd : *Doxygen::namespaceLinkedMap) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(nd->name().str(),0)); + if (nd->isLinkable()) + { + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,nd.get()); + g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].add(letter,nd.get()); + } + } + + // index concepts + for (const auto &cd : *Doxygen::conceptLinkedMap) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(cd->name().str(),0)); + if (cd->isLinkable()) + { + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,cd.get()); + g_searchIndexInfo[SEARCH_INDEX_CONCEPTS].add(letter,cd.get()); + } + } + + // index files + for (const auto &fn : *Doxygen::inputNameLinkedMap) + { + for (const auto &fd : *fn) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(fd->name().str(),0)); + if (fd->isLinkable()) + { + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,fd.get()); + g_searchIndexInfo[SEARCH_INDEX_FILES].add(letter,fd.get()); + } + } + } + + // index class members + { + // for each member name + for (const auto &mn : *Doxygen::memberNameLinkedMap) + { + // for each member definition + for (const auto &md : *mn) + { + addMemberToSearchIndex(md.get()); + } + } + } + + // index file/namespace members + { + // for each member name + for (const auto &mn : *Doxygen::functionNameLinkedMap) + { + // for each member definition + for (const auto &md : *mn) + { + addMemberToSearchIndex(md.get()); + } + } + } + + // index groups + for (const auto &gd : *Doxygen::groupLinkedMap) + { + if (gd->isLinkable()) + { + std::string title = gd->groupTitle().str(); + if (!title.empty()) // TODO: able searching for all word in the title + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(title,0)); + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,gd.get()); + g_searchIndexInfo[SEARCH_INDEX_GROUPS].add(letter,gd.get()); + } + } + } + + // index pages + for (const auto &pd : *Doxygen::pageLinkedMap) + { + if (pd->isLinkable()) + { + std::string title = pd->title().str(); + if (!title.empty()) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(title,0)); + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,pd.get()); + g_searchIndexInfo[SEARCH_INDEX_PAGES].add(letter,pd.get()); + } + } + } + if (Doxygen::mainPage) + { + std::string title = Doxygen::mainPage->title().str(); + if (!title.empty()) + { + std::string letter = convertUTF8ToLower(getUTF8CharAt(title,0)); + g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,Doxygen::mainPage.get()); + g_searchIndexInfo[SEARCH_INDEX_PAGES].add(letter,Doxygen::mainPage.get()); + } + } + + // sort all lists + for (auto &sii : g_searchIndexInfo) // for each index + { + for (auto &kv : sii.symbolMap) // for each symbol in the index + { + // sort the symbols (first on "search" name, and then on full name) + std::sort(kv.second.begin(), + kv.second.end(), + [](const Definition *d1,const Definition *d2) + { + int eq = qstricmp(searchName(d1),searchName(d2)); // search name first + return eq==0 ? qstricmp(d1->name(),d2->name())<0 : eq<0; // then full name + }); + } + } +} + +void writeJavaScriptSearchIndex() +{ + // write index files + QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search"; + + for (auto &sii : g_searchIndexInfo) + { + int p=0; + for (const auto &kv : sii.symbolMap) + { + int cnt = 0; + QCString baseName; + baseName.sprintf("%s_%x",sii.name.data(),p); + + QCString fileName = searchDirName + "/"+baseName+Doxygen::htmlFileExtension; + QCString dataFileName = searchDirName + "/"+baseName+".js"; + + std::ofstream t(fileName.str(), std::ofstream::out | std::ofstream::binary); + std::ofstream ti(dataFileName.str(), std::ofstream::out | std::ofstream::binary); + if (t.is_open() && ti.is_open()) + { + { + t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"" + " \"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; + t << "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; + t << "<head><title></title>\n"; + t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n"; + t << "<meta name=\"generator\" content=\"Doxygen " << getDoxygenVersion() << "\"/>\n"; + t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>\n"; + t << "<script type=\"text/javascript\" src=\"" << baseName << ".js\"></script>\n"; + t << "<script type=\"text/javascript\" src=\"search.js\"></script>\n"; + t << "</head>\n"; + t << "<body class=\"SRPage\">\n"; + t << "<div id=\"SRIndex\">\n"; + t << "<div class=\"SRStatus\" id=\"Loading\">" << theTranslator->trLoading() << "</div>\n"; + t << "<div id=\"SRResults\"></div>\n"; // here the results will be inserted + t << "<script type=\"text/javascript\">\n"; + t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */\n"; + t << "createResults();\n"; // this function will insert the results + t << "/* @license-end */\n"; + t << "</script>\n"; + t << "<div class=\"SRStatus\" id=\"Searching\">" + << theTranslator->trSearching() << "</div>\n"; + t << "<div class=\"SRStatus\" id=\"NoMatches\">" + << theTranslator->trNoMatches() << "</div>\n"; + + t << "<script type=\"text/javascript\">\n"; + t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */\n"; + t << "document.getElementById(\"Loading\").style.display=\"none\";\n"; + t << "document.getElementById(\"NoMatches\").style.display=\"none\";\n"; + t << "var searchResults = new SearchResults(\"searchResults\");\n"; + t << "searchResults.Search();\n"; + t << "window.addEventListener(\"message\", function(event) {\n"; + t << " if (event.data == \"take_focus\") {\n"; + t << " var elem = searchResults.NavNext(0);\n"; + t << " if (elem) elem.focus();\n"; + t << " }\n"; + t << "});\n"; + t << "/* @license-end */\n"; + t << "</script>\n"; + t << "</div>\n"; // SRIndex + t << "</body>\n"; + t << "</html>\n"; + } + + ti << "var searchData=\n"; + // format + // searchData[] = array of items + // searchData[x][0] = id + // searchData[x][1] = [ name + child1 + child2 + .. ] + // searchData[x][1][0] = name as shown + // searchData[x][1][y+1] = info for child y + // searchData[x][1][y+1][0] = url + // searchData[x][1][y+1][1] = 1 => target="_parent" + // searchData[x][1][y+1][1] = 0 => target="_blank" + // searchData[x][1][y+1][2] = scope + + ti << "[\n"; + bool firstEntry=TRUE; + + int childCount=0; + QCString lastName; + const Definition *prevScope = 0; + for (auto it = kv.second.begin(); it!=kv.second.end();) + { + const Definition *d = *it; + QCString sname = searchName(d); + QCString id = searchId(d); + + if (sname!=lastName) // this item has a different search word + { + if (!firstEntry) + { + ti << "]]]"; + ti << ",\n"; + } + firstEntry=FALSE; + + ti << " ['" << id << "_" << cnt++ << "',['" << convertToXML(sname) << "',["; + childCount=0; + prevScope=0; + } + + ++it; + const Definition *scope = d->getOuterScope(); + const Definition *next = it!=kv.second.end() ? *it : 0; + const Definition *nextScope = 0; + const MemberDef *md = toMemberDef(d); + if (next) nextScope = next->getOuterScope(); + QCString anchor = d->anchor(); + + if (childCount>0) + { + ti << "],["; + } + ti << "'" << externalRef("../",d->getReference(),TRUE) + << addHtmlExtensionIfMissing(d->getOutputFileBase()); + if (!anchor.isEmpty()) + { + ti << "#" << anchor; + } + ti << "',"; + + bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW); + if (!extLinksInWindow || d->getReference().isEmpty()) + { + ti << "1,"; + } + else + { + ti << "0,"; + } + + if (lastName!=sname && (next==0 || searchName(next)!=sname)) // unique name + { + if (d->getOuterScope()!=Doxygen::globalScope) + { + ti << "'" << convertToXML(d->getOuterScope()->name()) << "'"; + } + else if (md) + { + const FileDef *fd = md->getBodyDef(); + if (fd==0) fd = md->getFileDef(); + if (fd) + { + ti << "'" << convertToXML(fd->localName()) << "'"; + } + } + else + { + ti << "''"; + } + } + else // multiple entries with the same name + { + bool found=FALSE; + bool overloadedFunction = ((prevScope!=0 && scope==prevScope) || + (scope && scope==nextScope)) && md && (md->isFunction() || md->isSlot()); + QCString prefix; + if (md) prefix=convertToXML(md->localName()); + if (overloadedFunction) // overloaded member function + { + prefix+=convertToXML(md->argsString()); + // show argument list to disambiguate overloaded functions + } + else if (md) // unique member function + { + prefix+="()"; // only to show it is a function + } + QCString name; + if (d->definitionType()==Definition::TypeClass) + { + name = convertToXML((toClassDef(d))->displayName()); + found = TRUE; + } + else if (d->definitionType()==Definition::TypeNamespace) + { + name = convertToXML((toNamespaceDef(d))->displayName()); + found = TRUE; + } + else if (scope==0 || scope==Doxygen::globalScope) // in global scope + { + if (md) + { + const FileDef *fd = md->getBodyDef(); + if (fd==0) fd = md->resolveAlias()->getFileDef(); + if (fd) + { + if (!prefix.isEmpty()) prefix+=": "; + name = prefix + convertToXML(fd->localName()); + found = TRUE; + } + } + } + else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef())) + // member in class or namespace scope + { + SrcLangExt lang = md->getLanguage(); + name = convertToXML(d->getOuterScope()->qualifiedName()) + + getLanguageSpecificSeparator(lang) + prefix; + found = TRUE; + } + else if (scope) // some thing else? -> show scope + { + name = prefix + convertToXML(scope->name()); + found = TRUE; + } + if (!found) // fallback + { + name = prefix + "("+theTranslator->trGlobalNamespace()+")"; + } + + ti << "'" << name << "'"; + + prevScope = scope; + childCount++; + } + lastName = sname; + } + if (!firstEntry) + { + ti << "]]]\n"; + } + ti << "];\n"; + } + else + { + err("Failed to open file '%s' for writing...\n",qPrint(fileName)); + } + p++; + } + } + + { + std::ofstream t(searchDirName.str()+"/searchdata.js", + std::ofstream::out | std::ofstream::binary); + if (t.is_open()) + { + t << "var indexSectionsWithContent =\n"; + t << "{\n"; + int j=0; + for (const auto &sii : g_searchIndexInfo) + { + if (!sii.symbolMap.empty()) + { + if (j>0) t << ",\n"; + t << " " << j << ": \""; + + for (const auto &kv : sii.symbolMap) + { + if ( kv.first == "\"" ) t << "\\"; + t << kv.first; + } + t << "\""; + j++; + } + } + if (j>0) t << "\n"; + t << "};\n\n"; + t << "var indexSectionNames =\n"; + t << "{\n"; + j=0; + for (const auto &sii : g_searchIndexInfo) + { + if (!sii.symbolMap.empty()) + { + if (j>0) t << ",\n"; + t << " " << j << ": \"" << sii.name << "\""; + j++; + } + } + if (j>0) t << "\n"; + t << "};\n\n"; + t << "var indexSectionLabels =\n"; + t << "{\n"; + j=0; + for (const auto &sii : g_searchIndexInfo) + { + if (!sii.symbolMap.empty()) + { + if (j>0) t << ",\n"; + t << " " << j << ": \"" << convertToXML(sii.getText()) << "\""; + j++; + } + } + if (j>0) t << "\n"; + t << "};\n\n"; + } + ResourceMgr::instance().copyResource("search.js",searchDirName); + } + + { + QCString noMatchesFileName =searchDirName+"/nomatches"+Doxygen::htmlFileExtension; + std::ofstream t(noMatchesFileName.str(), std::ofstream::out | std::ofstream::binary); + if (t.is_open()) + { + t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " + "\"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; + t << "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; + t << "<head><title></title>\n"; + t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n"; + t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>\n"; + t << "<script type=\"text/javascript\" src=\"search.js\"></script>\n"; + t << "</head>\n"; + t << "<body class=\"SRPage\">\n"; + t << "<div id=\"SRIndex\">\n"; + t << "<div class=\"SRStatus\" id=\"NoMatches\">" + << theTranslator->trNoMatches() << "</div>\n"; + t << "</div>\n"; + t << "</body>\n"; + t << "</html>\n"; + } + } + + Doxygen::indexList->addStyleSheetFile("search/search.js"); +} + +//-------------------------------------------------------------------------------------- + +void SearchIndexInfo::add(const std::string &letter,const Definition *def) +{ + //printf("%p: %s->%s (full=%s)\n",this,qPrint(letter),qPrint(searchName(def)),qPrint(def->name())); + auto it = symbolMap.find(letter); + if (it!=symbolMap.end()) + { + it->second.push_back(def); + } + else + { + symbolMap.insert(std::make_pair(letter,std::vector<const Definition*>({def}))); + } +} + +const std::array<SearchIndexInfo,NUM_SEARCH_INDICES> &getSearchIndices() +{ + return g_searchIndexInfo; +} + diff --git a/src/searchindex_js.h b/src/searchindex_js.h new file mode 100644 index 0000000..7d3a788 --- /dev/null +++ b/src/searchindex_js.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2022 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. + * + */ + +/** @file + * @brief Javascript based search engine. + */ + +#ifndef SEARCHINDEX_JS_H +#define SEARCHINDEX_JS_H + +#include <array> +#include <vector> +#include <map> +#include <string> +#include <functional> + +#include "qcstring.h" + +#define NUM_SEARCH_INDICES 21 + +class Definition; + +QCString searchId(const Definition *d); +QCString searchName(const Definition *d); + +using SearchIndexList = std::vector<const Definition *>; +using SearchIndexMap = std::map<std::string,SearchIndexList>; + +struct SearchIndexInfo +{ + void add(const std::string &letter,const Definition *def); + QCString name; + std::function<QCString()> getText; + SearchIndexMap symbolMap; +}; + +void createJavaScriptSearchIndex(); +void writeJavaScriptSearchIndex(); +const std::array<SearchIndexInfo,NUM_SEARCH_INDICES> &getSearchIndices(); + +#endif diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index e0514d0..031eca6 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -30,6 +30,7 @@ #include "util.h" #include "outputlist.h" #include "docparser.h" +#include "docnode.h" #include "language.h" #include "version.h" @@ -1394,27 +1395,30 @@ QCString getSQLDocBlock(const Definition *scope, if (doc.isEmpty()) return ""; TextStream t; - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> root { - validatingParseDoc( - *parser.get(), - fileName, - lineNr, - const_cast<Definition*>(scope), - toMemberDef(def), - doc, - FALSE, - FALSE, - 0, - FALSE, - FALSE, - Config_getBool(MARKDOWN_SUPPORT) - ) }; - XMLCodeGenerator codeGen(t); - // create a parse tree visitor for XML - auto visitor = std::make_unique<XmlDocVisitor>(t,codeGen, - scope ? scope->getDefFileExtension() : QCString("")); - root->accept(visitor.get()); + auto parser { createDocParser() }; + auto ast { validatingParseDoc( + *parser.get(), + fileName, + lineNr, + const_cast<Definition*>(scope), + toMemberDef(def), + doc, + FALSE, + FALSE, + 0, + FALSE, + FALSE, + Config_getBool(MARKDOWN_SUPPORT)) + }; + auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get()); + if (astImpl) + { + XMLCodeGenerator codeGen(t); + // create a parse tree visitor for XML + XmlDocVisitor visitor(t,codeGen, + scope ? scope->getDefFileExtension() : QCString("")); + std::visit(visitor,astImpl->root); + } return convertCharEntitiesToUTF8(t.str().c_str()); } @@ -2369,7 +2373,7 @@ static void generateSqlite3ForPage(const PageDef *pd,bool isExample) QCString qrefid = pd->getOutputFileBase(); if (pd->getGroupDef()) { - qrefid+=(QCString)"_"+pd->name(); + qrefid+="_"+pd->name(); } if (qrefid=="index") qrefid="indexpage"; // to prevent overwriting the generated index page. diff --git a/src/symbolmap.h b/src/symbolmap.h index a277846..63e1e3a 100644 --- a/src/symbolmap.h +++ b/src/symbolmap.h @@ -44,7 +44,7 @@ class SymbolMap //! Remove a symbol \a def from the map that was stored under key \a name void remove(const QCString &name,Ptr def) { - auto range = find(name.str()); + auto range = find(name); for (auto it=range.first; it!=range.second; ) { if (it->second==def) it = m_map.erase(it); else ++it; diff --git a/src/symbolresolver.cpp b/src/symbolresolver.cpp index 29b5d6a..cf7fea1 100644 --- a/src/symbolresolver.cpp +++ b/src/symbolresolver.cpp @@ -144,12 +144,13 @@ struct SymbolResolver::Private const Definition *followPath(const Definition *start,const QCString &path); - const Definition *endOfPathIsUsedClass(LinkedRefMap<const ClassDef> cl,const QCString &localName); + const Definition *endOfPathIsUsedClass(const LinkedRefMap<const ClassDef> &cl,const QCString &localName); bool accessibleViaUsingNamespace(StringUnorderedSet &visited, const LinkedRefMap<const NamespaceDef> &nl, const Definition *item, - const QCString &explicitScopePart=""); + const QCString &explicitScopePart="", + int level=0); bool accessibleViaUsingClass(const LinkedRefMap<const ClassDef> &cl, const Definition *item, const QCString &explicitScopePart="" @@ -258,10 +259,9 @@ const ClassDef *SymbolResolver::Private::getResolvedClassRec( } *pk='\0'; - LookupInfo *pval = 0; { std::lock_guard<std::mutex> lock(g_cacheMutex); - pval=Doxygen::lookupCache->find(key.str()); + LookupInfo *pval = Doxygen::lookupCache->find(key.str()); //printf("Searching for %s result=%p\n",qPrint(key),pval); if (pval) { @@ -280,7 +280,7 @@ const ClassDef *SymbolResolver::Private::getResolvedClassRec( else // not found yet; we already add a 0 to avoid the possibility of // endless recursion. { - pval = Doxygen::lookupCache->insert(key.str(),LookupInfo()); + Doxygen::lookupCache->insert(key.str(),LookupInfo()); } } @@ -313,13 +313,11 @@ const ClassDef *SymbolResolver::Private::getResolvedClassRec( //printf("getResolvedClassRec: bestMatch=%p pval->resolvedType=%s\n", // bestMatch,qPrint(bestResolvedType)); - if (pval) { + // we need to insert the item in the cache again, as it could be removed in the meantime std::lock_guard<std::mutex> lock(g_cacheMutex); - pval->classDef = bestMatch; - pval->typeDef = bestTypedef; - pval->templSpec = bestTemplSpec; - pval->resolvedType = bestResolvedType; + Doxygen::lookupCache->insert(key.str(), + LookupInfo(bestMatch,bestTypedef,bestTemplSpec,bestResolvedType)); } //fprintf(stderr,"%d ] bestMatch=%s distance=%d\n",--level, // bestMatch?qPrint(bestMatch->name()):"<none>",minDistance); @@ -820,7 +818,7 @@ const Definition *SymbolResolver::Private::followPath(const Definition *start,co return current; // path could be followed } -const Definition *SymbolResolver::Private::endOfPathIsUsedClass(LinkedRefMap<const ClassDef> cl,const QCString &localName) +const Definition *SymbolResolver::Private::endOfPathIsUsedClass(const LinkedRefMap<const ClassDef> &cl,const QCString &localName) { for (const auto &cd : cl) { @@ -835,35 +833,34 @@ const Definition *SymbolResolver::Private::endOfPathIsUsedClass(LinkedRefMap<con bool SymbolResolver::Private::accessibleViaUsingNamespace(StringUnorderedSet &visited, const LinkedRefMap<const NamespaceDef> &nl, const Definition *item, - const QCString &explicitScopePart) + const QCString &explicitScopePart, + int level) { + //size_t count=0; for (const auto &und : nl) // check used namespaces for the class { - //printf("[Trying via used namespace %s: count=%d/%d\n",qPrint(und->name()), - // count,nl->count()); + //printf("%d [Trying via used namespace %s: count=%zu/%zu\n",level,qPrint(und->name()), + // count++,nl.size()); const Definition *sc = explicitScopePart.isEmpty() ? und : followPath(und,explicitScopePart); if (sc && item->getOuterScope()==sc) { - //printf("] found it\n"); + //printf("%d ] found it\n",level); return true; } if (item->getLanguage()==SrcLangExt_Cpp) { - QCString key=und->name(); - if (!und->getUsedNamespaces().empty() && visited.find(key.str())==visited.end()) + QCString key=und->qualifiedName(); + if (!und->getUsedNamespaces().empty() && visited.insert(key.str()).second) { - visited.insert(key.str()); - - if (accessibleViaUsingNamespace(visited,und->getUsedNamespaces(),item,explicitScopePart)) + if (accessibleViaUsingNamespace(visited,und->getUsedNamespaces(),item,explicitScopePart,level+1)) { - //printf("] found it via recursion\n"); + //printf("%d ] found it via recursion\n",level); return true; } - visited.erase(key.str()); } } - //printf("] Try via used namespace done\n"); + //printf("%d ] Try via used namespace done\n",level); } return false; } @@ -952,7 +949,7 @@ int SymbolResolver::Private::isAccessibleFrom(AccessStack &accessStack, goto done; } StringUnorderedSet visited; - if (accessibleViaUsingNamespace(visited,nscope->getUsedNamespaces(),item)) + if (accessibleViaUsingNamespace(visited,nscope->getUsedNamespaces(),item,0)) { //printf("> found via used namespace\n"); goto done; diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 5ff51ae..e83bcc2 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -22,6 +22,7 @@ #include <functional> #include <utility> #include <algorithm> +#include <variant> #include <assert.h> #include <stdio.h> @@ -40,9 +41,6 @@ #include "containers.h" #include "debug.h" -// set to 1 for debugging -#define DUMP_OUTPUT 0 - // ----------------- private part ----------------------------------------------- namespace { @@ -101,173 +99,209 @@ class TagMemberInfo }; /** Base class for all compound types */ -class TagCompoundInfo +struct TagCompoundInfo { - public: - enum class CompoundType { Class, Concept, Namespace, Package, File, Group, Page, Dir }; - explicit TagCompoundInfo(CompoundType type) : m_type(type) {} - virtual ~TagCompoundInfo() {} - CompoundType compoundType() const { return m_type; } - std::vector<TagMemberInfo> members; - QCString name; - QCString filename; - std::vector<TagAnchorInfo> docAnchors; - int lineNr = 0; - private: - CompoundType m_type; + std::vector<TagMemberInfo> members; + QCString name; + QCString filename; + std::vector<TagAnchorInfo> docAnchors; + int lineNr = 0; }; + /** Container for class specific info that can be read from a tagfile */ -class TagClassInfo : public TagCompoundInfo +struct TagClassInfo : public TagCompoundInfo { - public: - enum class Kind { None=-1, Class, Struct, Union, Interface, Exception, Protocol, Category, Enum, Service, Singleton }; - TagClassInfo(Kind k) : TagCompoundInfo(CompoundType::Class), kind(k) {} - QCString clangId; - QCString anchor; - std::vector<BaseInfo> bases; - StringVector templateArguments; - StringVector classList; - Kind kind; - bool isObjC = false; - static TagClassInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagClassInfo*>(t.get()); - } - static const TagClassInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagClassInfo*>(t.get()); - } + enum class Kind { None=-1, Class, Struct, Union, Interface, Exception, Protocol, Category, Enum, Service, Singleton }; + TagClassInfo(Kind k) : kind(k) {} + QCString clangId; + QCString anchor; + std::vector<BaseInfo> bases; + StringVector templateArguments; + StringVector classList; + Kind kind; + bool isObjC = false; }; +using TagClassInfoPtr = std::unique_ptr<TagClassInfo>; + /** Container for concept specific info that can be read from a tagfile */ -class TagConceptInfo : public TagCompoundInfo +struct TagConceptInfo : public TagCompoundInfo { - public: - TagConceptInfo() :TagCompoundInfo(CompoundType::Concept) {} - QCString clangId; - static TagConceptInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagConceptInfo*>(t.get()); - } - static const TagConceptInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagConceptInfo*>(t.get()); - } + QCString clangId; }; +using TagConceptInfoPtr = std::unique_ptr<TagConceptInfo>; + /** Container for namespace specific info that can be read from a tagfile */ -class TagNamespaceInfo : public TagCompoundInfo +struct TagNamespaceInfo : public TagCompoundInfo { - public: - TagNamespaceInfo() :TagCompoundInfo(CompoundType::Namespace) {} - QCString clangId; - StringVector classList; - StringVector conceptList; - StringVector namespaceList; - static TagNamespaceInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagNamespaceInfo*>(t.get()); - } - static const TagNamespaceInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagNamespaceInfo*>(t.get()); - } + QCString clangId; + StringVector classList; + StringVector conceptList; + StringVector namespaceList; }; +using TagNamespaceInfoPtr = std::unique_ptr<TagNamespaceInfo>; + /** Container for package specific info that can be read from a tagfile */ -class TagPackageInfo : public TagCompoundInfo +struct TagPackageInfo : public TagCompoundInfo { - public: - TagPackageInfo() : TagCompoundInfo(CompoundType::Package) { } - StringVector classList; - static TagPackageInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagPackageInfo*>(t.get()); - } - static const TagPackageInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagPackageInfo*>(t.get()); - } + StringVector classList; }; +using TagPackageInfoPtr = std::unique_ptr<TagPackageInfo>; + /** Container for file specific info that can be read from a tagfile */ -class TagFileInfo : public TagCompoundInfo +struct TagFileInfo : public TagCompoundInfo { - public: - TagFileInfo() : TagCompoundInfo(CompoundType::File) { } - QCString path; - StringVector classList; - StringVector conceptList; - StringVector namespaceList; - std::vector<TagIncludeInfo> includes; - static TagFileInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagFileInfo*>(t.get()); - } - static const TagFileInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagFileInfo*>(t.get()); - } + QCString path; + StringVector classList; + StringVector conceptList; + StringVector namespaceList; + std::vector<TagIncludeInfo> includes; }; +using TagFileInfoPtr = std::unique_ptr<TagFileInfo>; + /** Container for group specific info that can be read from a tagfile */ -class TagGroupInfo : public TagCompoundInfo +struct TagGroupInfo : public TagCompoundInfo { - public: - TagGroupInfo() : TagCompoundInfo(CompoundType::Group) { } - QCString title; - StringVector subgroupList; - StringVector classList; - StringVector conceptList; - StringVector namespaceList; - StringVector fileList; - StringVector pageList; - StringVector dirList; - static TagGroupInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagGroupInfo*>(t.get()); - } - static const TagGroupInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagGroupInfo*>(t.get()); - } + QCString title; + StringVector subgroupList; + StringVector classList; + StringVector conceptList; + StringVector namespaceList; + StringVector fileList; + StringVector pageList; + StringVector dirList; }; +using TagGroupInfoPtr = std::unique_ptr<TagGroupInfo>; + /** Container for page specific info that can be read from a tagfile */ -class TagPageInfo : public TagCompoundInfo +struct TagPageInfo : public TagCompoundInfo { - public: - TagPageInfo() : TagCompoundInfo(CompoundType::Page) {} - QCString title; - static TagPageInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagPageInfo*>(t.get()); - } - static const TagPageInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagPageInfo*>(t.get()); - } + QCString title; }; +using TagPageInfoPtr = std::unique_ptr<TagPageInfo>; + /** Container for directory specific info that can be read from a tagfile */ -class TagDirInfo : public TagCompoundInfo +struct TagDirInfo : public TagCompoundInfo +{ + QCString path; + StringVector subdirList; + StringVector fileList; +}; + +using TagDirInfoPtr = std::unique_ptr<TagDirInfo>; + +/** Variant class that holds a unique pointer to one of the specific container types */ +class TagCompoundVariant { public: - TagDirInfo() : TagCompoundInfo(CompoundType::Dir) {} - QCString path; - StringVector subdirList; - StringVector fileList; - static TagDirInfo *get(std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<TagDirInfo*>(t.get()); - } - static const TagDirInfo *get(const std::unique_ptr<TagCompoundInfo> &t) - { - return dynamic_cast<const TagDirInfo*>(t.get()); + using VariantT = std::variant< std::monostate, // 0 + TagClassInfoPtr, // 1 + TagConceptInfoPtr, // 2 + TagNamespaceInfoPtr, // 3 + TagPackageInfoPtr, // 4 + TagFileInfoPtr, // 5 + TagGroupInfoPtr, // 6 + TagPageInfoPtr, // 7 + TagDirInfoPtr>; // 8 + + enum class Type : uint8_t + { + Uninitialized = 0, + Class = 1, + Concept = 2, + Namespace = 3, + Package = 4, + File = 5, + Group = 6, + Page = 7, + Dir = 8 + }; + + TagCompoundVariant() {} + explicit TagCompoundVariant(VariantT &&v) : m_variant(std::move(v)) {} + TagCompoundVariant(const TagCompoundVariant &) = delete; + TagCompoundVariant &operator=(const TagCompoundVariant &) = delete; + TagCompoundVariant(TagCompoundVariant &&) = default; + TagCompoundVariant &operator=(TagCompoundVariant &&) = default; + ~TagCompoundVariant() = default; + + /** Generic non-const getter */ + template<class R> + R *get() + { + std::unique_ptr<R> *p = std::get_if<std::unique_ptr<R>>(&m_variant); + return p ? p->get() : 0; + } + /** Generic const getter */ + template<class R> + const R *get() const + { + const std::unique_ptr<R> *p = std::get_if<std::unique_ptr<R>>(&m_variant); + return p ? p->get() : 0; + } + + /** Generic factory method to create a variant holding a unique pointer to a given compound type */ + template<class R,typename... Args> + static TagCompoundVariant make(Args&&... args) + { + return TagCompoundVariant(VariantT(std::make_unique<R>(std::forward<Args>(args)...))); + } + + /** @name convenience const and non-const getters for each variant component + * @{ + */ + TagClassInfo *getClassInfo() { return get<TagClassInfo >(); } + const TagClassInfo *getClassInfo() const { return get<TagClassInfo >(); } + TagConceptInfo *getConceptInfo() { return get<TagConceptInfo >(); } + const TagConceptInfo *getConceptInfo() const { return get<TagConceptInfo >(); } + TagNamespaceInfo *getNamespaceInfo() { return get<TagNamespaceInfo>(); } + const TagNamespaceInfo *getNamespaceInfo() const { return get<TagNamespaceInfo>(); } + TagPackageInfo *getPackageInfo() { return get<TagPackageInfo >(); } + const TagPackageInfo *getPackageInfo() const { return get<TagPackageInfo >(); } + TagFileInfo *getFileInfo() { return get<TagFileInfo >(); } + const TagFileInfo *getFileInfo() const { return get<TagFileInfo >(); } + TagGroupInfo *getGroupInfo() { return get<TagGroupInfo >(); } + const TagGroupInfo *getGroupInfo() const { return get<TagGroupInfo >(); } + TagPageInfo *getPageInfo() { return get<TagPageInfo >(); } + const TagPageInfo *getPageInfo() const { return get<TagPageInfo >(); } + TagDirInfo *getDirInfo() { return get<TagDirInfo >(); } + const TagDirInfo *getDirInfo() const { return get<TagDirInfo >(); } + /** @} */ + + /** Convenience method to get the shared compound info */ + TagCompoundInfo *getCompoundInfo() + { + switch(type()) + { + case Type::Uninitialized: return 0; + case Type::Class: return getClassInfo(); + case Type::Concept: return getConceptInfo(); + case Type::Namespace: return getNamespaceInfo(); + case Type::Package: return getPackageInfo(); + case Type::File: return getFileInfo(); + case Type::Group: return getGroupInfo(); + case Type::Page: return getPageInfo(); + case Type::Dir: return getDirInfo(); + } + return 0; + } + Type type() const + { + return static_cast<Type>(m_variant.index()); } + + private: + VariantT m_variant; }; + /** Tag file parser. * * Reads an XML-structured tagfile and builds up the structure in @@ -277,7 +311,7 @@ class TagDirInfo : public TagCompoundInfo class TagFileParser { public: - TagFileParser(const char *tagName) : m_tagName(tagName) {} + explicit TagFileParser(const char *tagName) : m_tagName(tagName) {} void setDocumentLocator ( const XMLLocator * locator ) { @@ -365,7 +399,13 @@ class TagFileParser case InNamespace: case InGroup: case InPackage: - m_curCompound->members.push_back(m_curMember); + { + TagCompoundInfo *info = m_curCompound.getCompoundInfo(); + if (info) + { + info->members.push_back(m_curMember); + } + } break; default: warn("Unexpected tag 'member' found"); @@ -433,7 +473,13 @@ class TagFileParser case InPage: case InPackage: case InDir: - m_curCompound->docAnchors.push_back(TagAnchorInfo(m_fileName,m_curString,m_title)); + { + TagCompoundInfo *info = m_curCompound.getCompoundInfo(); + if (info) + { + info->docAnchors.push_back(TagAnchorInfo(m_fileName,m_curString,m_title)); + } + } break; case InMember: m_curMember.docAnchors.push_back(TagAnchorInfo(m_fileName,m_curString,m_title)); @@ -447,19 +493,34 @@ class TagFileParser switch(m_state) { case InClass: - TagClassInfo::get(m_curCompound)->classList.push_back(m_curString.str()); + { + TagClassInfo *info = m_curCompound.getClassInfo(); + if (info) info->classList.push_back(m_curString.str()); + } break; case InFile: - TagFileInfo::get(m_curCompound)->classList.push_back(m_curString.str()); + { + TagFileInfo *info = m_curCompound.getFileInfo(); + if (info) info->classList.push_back(m_curString.str()); + } break; case InNamespace: - TagNamespaceInfo::get(m_curCompound)->classList.push_back(m_curString.str()); + { + TagNamespaceInfo *info = m_curCompound.getNamespaceInfo(); + if (info) info->classList.push_back(m_curString.str()); + } break; case InGroup: - TagGroupInfo::get(m_curCompound)->classList.push_back(m_curString.str()); + { + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->classList.push_back(m_curString.str()); + } break; case InPackage: - TagPackageInfo::get(m_curCompound)->classList.push_back(m_curString.str()); + { + TagPackageInfo *info = m_curCompound.getPackageInfo(); + if (info) info->classList.push_back(m_curString.str()); + } break; default: warn("Unexpected tag 'class' found"); @@ -472,13 +533,22 @@ class TagFileParser switch(m_state) { case InNamespace: - TagNamespaceInfo::get(m_curCompound)->conceptList.push_back(m_curString.str()); + { + TagNamespaceInfo *info = m_curCompound.getNamespaceInfo(); + if (info) info->conceptList.push_back(m_curString.str()); + } break; case InFile: - TagFileInfo::get(m_curCompound)->conceptList.push_back(m_curString.str()); + { + TagFileInfo *info = m_curCompound.getFileInfo(); + if (info) info->conceptList.push_back(m_curString.str()); + } break; case InGroup: - TagGroupInfo::get(m_curCompound)->conceptList.push_back(m_curString.str()); + { + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->conceptList.push_back(m_curString.str()); + } break; default: warn("Unexpected tag 'concept' found"); @@ -491,13 +561,22 @@ class TagFileParser switch(m_state) { case InNamespace: - TagNamespaceInfo::get(m_curCompound)->namespaceList.push_back(m_curString.str()); + { + TagNamespaceInfo *info = m_curCompound.getNamespaceInfo(); + if (info) info->namespaceList.push_back(m_curString.str()); + } break; case InFile: - TagFileInfo::get(m_curCompound)->namespaceList.push_back(m_curString.str()); + { + TagFileInfo *info = m_curCompound.getFileInfo(); + if (info) info->namespaceList.push_back(m_curString.str()); + } break; case InGroup: - TagGroupInfo::get(m_curCompound)->namespaceList.push_back(m_curString.str()); + { + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->namespaceList.push_back(m_curString.str()); + } break; default: warn("Unexpected tag 'namespace' found"); @@ -510,10 +589,16 @@ class TagFileParser switch(m_state) { case InGroup: - TagGroupInfo::get(m_curCompound)->fileList.push_back(m_curString.str()); + { + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->fileList.push_back(m_curString.str()); + } break; case InDir: - TagDirInfo::get(m_curCompound)->fileList.push_back(m_curString.str()); + { + TagDirInfo *info = m_curCompound.getDirInfo(); + if (info) info->fileList.push_back(m_curString.str()); + } break; default: warn("Unexpected tag 'file' found"); @@ -526,7 +611,10 @@ class TagFileParser switch(m_state) { case InGroup: - TagGroupInfo::get(m_curCompound)->fileList.push_back(m_curString.str()); + { + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->fileList.push_back(m_curString.str()); + } break; default: warn("Unexpected tag 'page' found"); @@ -539,7 +627,10 @@ class TagFileParser switch(m_state) { case InDir: - TagDirInfo::get(m_curCompound)->subdirList.push_back(m_curString.str()); + { + TagDirInfo *info = m_curCompound.getDirInfo(); + if (info) info->subdirList.push_back(m_curString.str()); + } break; default: warn("Unexpected tag 'dir' found"); @@ -583,21 +674,25 @@ class TagFileParser case InPage: case InDir: case InPackage: - m_curCompound->name = m_curString; - break; + { + TagCompoundInfo *info = m_curCompound.getCompoundInfo(); + if (info) info->name = m_curString; + } + break; case InMember: - m_curMember.name = m_curString; - break; + m_curMember.name = m_curString; + break; default: - warn("Unexpected tag 'name' found"); - break; + warn("Unexpected tag 'name' found"); + break; } } void startBase(const XMLHandlers::Attributes& attrib ) { m_curString=""; - if (m_state==InClass && m_curCompound) + TagClassInfo *info = m_curCompound.getClassInfo(); + if (m_state==InClass && info) { QCString protStr = XMLHandlers::value(attrib,"protection"); QCString virtStr = XMLHandlers::value(attrib,"virtualness"); @@ -615,7 +710,7 @@ class TagFileParser { virt = Virtual; } - TagClassInfo::get(m_curCompound)->bases.push_back(BaseInfo(m_curString,prot,virt)); + info->bases.push_back(BaseInfo(m_curString,prot,virt)); } else { @@ -625,9 +720,10 @@ class TagFileParser void endBase() { - if (m_state==InClass && m_curCompound) + TagClassInfo *info = m_curCompound.getClassInfo(); + if (m_state==InClass && info) { - TagClassInfo::get(m_curCompound)->bases.back().name = m_curString; + info->bases.back().name = m_curString; } else { @@ -648,9 +744,10 @@ class TagFileParser void endIncludes() { m_curIncludes.text = m_curString; - if (m_state==InFile && m_curCompound) + TagFileInfo *info = m_curCompound.getFileInfo(); + if (m_state==InFile && info) { - TagFileInfo::get(m_curCompound)->includes.push_back(m_curIncludes); + info->includes.push_back(m_curIncludes); } else { @@ -660,9 +757,10 @@ class TagFileParser void endTemplateArg() { - if (m_state==InClass && m_curCompound) + TagClassInfo *info = m_curCompound.getClassInfo(); + if (m_state==InClass && info) { - TagClassInfo::get(m_curCompound)->templateArguments.push_back(m_curString.str()); + info->templateArguments.push_back(m_curString.str()); } else { @@ -682,7 +780,10 @@ class TagFileParser case InPage: case InPackage: case InDir: - m_curCompound->filename = m_curString; + { + TagCompoundInfo *info = m_curCompound.getCompoundInfo(); + if (info) info->filename = m_curString; + } break; default: warn("Unexpected tag 'filename' found"); @@ -695,10 +796,16 @@ class TagFileParser switch (m_state) { case InFile: - TagFileInfo::get(m_curCompound)->path = m_curString; + { + TagFileInfo *info = m_curCompound.getFileInfo(); + if (info) info->path = m_curString; + } break; case InDir: - TagDirInfo::get(m_curCompound)->path = m_curString; + { + TagDirInfo *info = m_curCompound.getDirInfo(); + if (info) info->path = m_curString; + } break; default: warn("Unexpected tag 'path' found"); @@ -714,7 +821,8 @@ class TagFileParser } else if (m_state==InClass) { - TagClassInfo::get(m_curCompound)->anchor = m_curString; + TagClassInfo *info = m_curCompound.getClassInfo(); + if (info) info->anchor = m_curString; } else { @@ -730,11 +838,13 @@ class TagFileParser } else if (m_state==InClass) { - TagClassInfo::get(m_curCompound)->clangId = m_curString; + TagClassInfo *info = m_curCompound.getClassInfo(); + if (info) info->clangId = m_curString; } else if (m_state==InNamespace) { - TagNamespaceInfo::get(m_curCompound)->clangId = m_curString; + TagNamespaceInfo *info = m_curCompound.getNamespaceInfo(); + if (info) info->clangId = m_curString; } else { @@ -773,10 +883,16 @@ class TagFileParser switch (m_state) { case InGroup: - TagGroupInfo::get(m_curCompound)->title = m_curString; + { + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->title = m_curString; + } break; case InPage: - TagPageInfo::get(m_curCompound)->title = m_curString; + { + TagPageInfo *info = m_curCompound.getPageInfo(); + if (info) info->title = m_curString; + } break; default: warn("Unexpected tag 'title' found"); @@ -788,7 +904,8 @@ class TagFileParser { if (m_state==InGroup) { - TagGroupInfo::get(m_curCompound)->subgroupList.push_back(m_curString.str()); + TagGroupInfo *info = m_curCompound.getGroupInfo(); + if (info) info->subgroupList.push_back(m_curString.str()); } else { @@ -838,17 +955,17 @@ class TagFileParser //------------------------------------ - std::vector< std::unique_ptr<TagCompoundInfo> > m_tagFileCompounds; - std::unique_ptr<TagCompoundInfo> m_curCompound; + std::vector< TagCompoundVariant > m_tagFileCompounds; + TagCompoundVariant m_curCompound; TagMemberInfo m_curMember; TagEnumValueInfo m_curEnumValue; TagIncludeInfo m_curIncludes; - QCString m_curString; - QCString m_tagName; - QCString m_fileName; - QCString m_title; + QCString m_curString; + QCString m_tagName; + QCString m_fileName; + QCString m_title; State m_state = Invalid; std::stack<State> m_stateStack; const XMLLocator *m_locator = nullptr; @@ -908,7 +1025,7 @@ static const std::map< std::string, ElementCallbacks > g_elementHandlers = struct CompoundFactory { - using CreateFunc = std::function<std::unique_ptr<TagCompoundInfo>()>; + using CreateFunc = std::function<TagCompoundVariant()>; CompoundFactory(TagFileParser::State s,CreateFunc f) : state(s), make_instance(f) {} TagFileParser::State state; CreateFunc make_instance; @@ -916,24 +1033,24 @@ struct CompoundFactory static const std::map< std::string, CompoundFactory > g_compoundFactory = { - // kind tag state creation function - { "class", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Class); } } }, - { "struct", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Struct); } } }, - { "union", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Union); } } }, - { "interface", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Interface); } } }, - { "enum", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Enum); } } }, - { "exception", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Exception); } } }, - { "protocol", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Protocol); } } }, - { "category", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Category); } } }, - { "service", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Service); } } }, - { "singleton", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Singleton); } } }, - { "file", { TagFileParser::InFile, []() { return std::make_unique<TagFileInfo>(); } } }, - { "namespace", { TagFileParser::InNamespace, []() { return std::make_unique<TagNamespaceInfo>(); } } }, - { "concept", { TagFileParser::InConcept, []() { return std::make_unique<TagConceptInfo>(); } } }, - { "group", { TagFileParser::InGroup, []() { return std::make_unique<TagGroupInfo>(); } } }, - { "page", { TagFileParser::InPage, []() { return std::make_unique<TagPageInfo>(); } } }, - { "package", { TagFileParser::InPackage, []() { return std::make_unique<TagPackageInfo>(); } } }, - { "dir", { TagFileParser::InDir, []() { return std::make_unique<TagDirInfo>(); } } } + // kind tag state creation function + { "class", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Class); } } }, + { "struct", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Struct); } } }, + { "union", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Union); } } }, + { "interface", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Interface); } } }, + { "enum", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Enum); } } }, + { "exception", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Exception); } } }, + { "protocol", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Protocol); } } }, + { "category", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Category); } } }, + { "service", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Service); } } }, + { "singleton", { TagFileParser::InClass, []() { return TagCompoundVariant::make<TagClassInfo>(TagClassInfo::Kind::Singleton); } } }, + { "file", { TagFileParser::InFile, []() { return TagCompoundVariant::make<TagFileInfo>(); } } }, + { "namespace", { TagFileParser::InNamespace, []() { return TagCompoundVariant::make<TagNamespaceInfo>(); } } }, + { "concept", { TagFileParser::InConcept, []() { return TagCompoundVariant::make<TagConceptInfo>(); } } }, + { "group", { TagFileParser::InGroup, []() { return TagCompoundVariant::make<TagGroupInfo>(); } } }, + { "page", { TagFileParser::InPage, []() { return TagCompoundVariant::make<TagPageInfo>(); } } }, + { "package", { TagFileParser::InPackage, []() { return TagCompoundVariant::make<TagPackageInfo>(); } } }, + { "dir", { TagFileParser::InDir, []() { return TagCompoundVariant::make<TagDirInfo>(); } } } }; //--------------------------------------------------------------------------------------------------------------- @@ -977,7 +1094,8 @@ void TagFileParser::startCompound( const XMLHandlers::Attributes& attrib ) { m_curCompound = it->second.make_instance(); m_state = it->second.state; - m_curCompound->lineNr = m_locator->lineNr(); + TagCompoundInfo *info = m_curCompound.getCompoundInfo(); + if (info) info->lineNr = m_locator->lineNr(); } else { @@ -985,73 +1103,72 @@ void TagFileParser::startCompound( const XMLHandlers::Attributes& attrib ) m_state = Invalid; } - if (isObjC=="yes" && m_curCompound && - m_curCompound->compoundType()==TagCompoundInfo::CompoundType::Class) + TagClassInfo *classInfo = m_curCompound.getClassInfo(); + if (isObjC=="yes" && classInfo) { - TagClassInfo::get(m_curCompound)->isObjC = TRUE; + classInfo->isObjC = TRUE; } } -#if DUMP_OUTPUT /*! Dumps the internal structures. For debugging only! */ void TagFileParser::dump() { - msg("Result:\n"); + Debug::print(Debug::Tag,0,"-------- Results --------\n"); //============== CLASSES for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Class) + if (comp.type()==TagCompoundVariant::Type::Class) { - const TagClassInfo *cd = TagClassInfo::get(comp); - msg("class '%s'\n",qPrint(cd->name)); - msg(" filename '%s'\n",qPrint(cd->filename)); + const TagClassInfo *cd = comp.getClassInfo(); + Debug::print(Debug::Tag,0,"class '%s'\n",qPrint(cd->name)); + Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(cd->filename)); for (const BaseInfo &bi : cd->bases) { - msg( " base: %s \n", bi.name.isEmpty() ? "" : qPrint(bi.name) ); + Debug::print(Debug::Tag,0, " base: %s \n", bi.name.isEmpty() ? "" : qPrint(bi.name) ); } for (const auto &md : cd->members) { - msg(" member:\n"); - msg(" kind: '%s'\n",qPrint(md.kind)); - msg(" name: '%s'\n",qPrint(md.name)); - msg(" anchor: '%s'\n",qPrint(md.anchor)); - msg(" arglist: '%s'\n",qPrint(md.arglist)); + Debug::print(Debug::Tag,0," member:\n"); + Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind)); + Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name)); + Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor)); + Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist)); } } } //============== CONCEPTS for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Concept) + if (comp.type()==TagCompoundVariant::Type::Concept) { - const TagConceptInfo *cd = TagConceptInfo::get(comp); + const TagConceptInfo *cd = comp.getConceptInfo(); - msg("concept '%s'\n",qPrint(cd->name)); - msg(" filename '%s'\n",qPrint(cd->filename)); + Debug::print(Debug::Tag,0,"concept '%s'\n",qPrint(cd->name)); + Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(cd->filename)); } } //============== NAMESPACES for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Namespace) + if (comp.type()==TagCompoundVariant::Type::Namespace) { - const TagNamespaceInfo *nd = TagNamespaceInfo::get(comp); + const TagNamespaceInfo *nd = comp.getNamespaceInfo(); - msg("namespace '%s'\n",qPrint(nd->name)); - msg(" filename '%s'\n",qPrint(nd->filename)); + Debug::print(Debug::Tag,0,"namespace '%s'\n",qPrint(nd->name)); + Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(nd->filename)); for (const auto &cls : nd->classList) { - msg( " class: %s \n", cls.c_str() ); + Debug::print(Debug::Tag,0, " class: %s \n", cls.c_str() ); } for (const auto &md : nd->members) { - msg(" member:\n"); - msg(" kind: '%s'\n",qPrint(md.kind)); - msg(" name: '%s'\n",qPrint(md.name)); - msg(" anchor: '%s'\n",qPrint(md.anchor)); - msg(" arglist: '%s'\n",qPrint(md.arglist)); + Debug::print(Debug::Tag,0," member:\n"); + Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind)); + Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name)); + Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor)); + Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist)); } } } @@ -1059,33 +1176,33 @@ void TagFileParser::dump() //============== FILES for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::File) + if (comp.type()==TagCompoundVariant::Type::File) { - const TagFileInfo *fd = TagFileInfo::get(comp); + const TagFileInfo *fd = comp.getFileInfo(); - msg("file '%s'\n",qPrint(fd->name)); - msg(" filename '%s'\n",qPrint(fd->filename)); + Debug::print(Debug::Tag,0,"file '%s'\n",qPrint(fd->name)); + Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(fd->filename)); for (const auto &ns : fd->namespaceList) { - msg( " namespace: %s \n", ns.c_str() ); + Debug::print(Debug::Tag,0, " namespace: %s \n", ns.c_str() ); } for (const auto &cs : fd->classList) { - msg( " class: %s \n", cs.c_str() ); + Debug::print(Debug::Tag,0, " class: %s \n", cs.c_str() ); } for (const auto &md : fd->members) { - msg(" member:\n"); - msg(" kind: '%s'\n",qPrint(md.kind)); - msg(" name: '%s'\n",qPrint(md.name)); - msg(" anchor: '%s'\n",qPrint(md.anchor)); - msg(" arglist: '%s'\n",qPrint(md.arglist)); + Debug::print(Debug::Tag,0," member:\n"); + Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind)); + Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name)); + Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor)); + Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist)); } for (const auto &ii : fd->includes) { - msg(" includes id: %s name: %s\n",qPrint(ii.id),qPrint(ii.name)); + Debug::print(Debug::Tag,0," includes id: %s name: %s\n",qPrint(ii.id),qPrint(ii.name)); } } } @@ -1093,40 +1210,40 @@ void TagFileParser::dump() //============== GROUPS for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Group) + if (comp.type()==TagCompoundVariant::Type::Group) { - const TagGroupInfo *gd = TagGroupInfo::get(comp); - msg("group '%s'\n",qPrint(gd->name)); - msg(" filename '%s'\n",qPrint(gd->filename)); + const TagGroupInfo *gd = comp.getGroupInfo(); + Debug::print(Debug::Tag,0,"group '%s'\n",qPrint(gd->name)); + Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(gd->filename)); for (const auto &ns : gd->namespaceList) { - msg( " namespace: %s \n", ns.c_str() ); + Debug::print(Debug::Tag,0, " namespace: %s \n", ns.c_str() ); } for (const auto &cs : gd->classList) { - msg( " class: %s \n", cs.c_str() ); + Debug::print(Debug::Tag,0, " class: %s \n", cs.c_str() ); } for (const auto &fi : gd->fileList) { - msg( " file: %s \n", fi.c_str() ); + Debug::print(Debug::Tag,0, " file: %s \n", fi.c_str() ); } for (const auto &sg : gd->subgroupList) { - msg( " subgroup: %s \n", sg.c_str() ); + Debug::print(Debug::Tag,0, " subgroup: %s \n", sg.c_str() ); } for (const auto &pg : gd->pageList) { - msg( " page: %s \n", pg.c_str() ); + Debug::print(Debug::Tag,0, " page: %s \n", pg.c_str() ); } for (const auto &md : gd->members) { - msg(" member:\n"); - msg(" kind: '%s'\n",qPrint(md.kind)); - msg(" name: '%s'\n",qPrint(md.name)); - msg(" anchor: '%s'\n",qPrint(md.anchor)); - msg(" arglist: '%s'\n",qPrint(md.arglist)); + Debug::print(Debug::Tag,0," member:\n"); + Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind)); + Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name)); + Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor)); + Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist)); } } } @@ -1134,37 +1251,37 @@ void TagFileParser::dump() //============== PAGES for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Page) + if (comp.type()==TagCompoundVariant::Type::Page) { - const TagPageInfo *pd = TagPageInfo::get(comp); - msg("page '%s'\n",qPrint(pd->name)); - msg(" title '%s'\n",qPrint(pd->title)); - msg(" filename '%s'\n",qPrint(pd->filename)); + const TagPageInfo *pd = comp.getPageInfo(); + Debug::print(Debug::Tag,0,"page '%s'\n",qPrint(pd->name)); + Debug::print(Debug::Tag,0," title '%s'\n",qPrint(pd->title)); + Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(pd->filename)); } } //============== DIRS for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Dir) + if (comp.type()==TagCompoundVariant::Type::Dir) { - const TagDirInfo *dd = TagDirInfo::get(comp); + const TagDirInfo *dd = comp.getDirInfo(); { - msg("dir '%s'\n",qPrint(dd->name)); - msg(" path '%s'\n",qPrint(dd->path)); + Debug::print(Debug::Tag,0,"dir '%s'\n",qPrint(dd->name)); + Debug::print(Debug::Tag,0," path '%s'\n",qPrint(dd->path)); for (const auto &fi : dd->fileList) { - msg( " file: %s \n", fi.c_str() ); + Debug::print(Debug::Tag,0, " file: %s \n", fi.c_str() ); } for (const auto &sd : dd->subdirList) { - msg( " subdir: %s \n", sd.c_str() ); + Debug::print(Debug::Tag,0, " subdir: %s \n", sd.c_str() ); } } } } + Debug::print(Debug::Tag,0,"-------------------------\n"); } -#endif void TagFileParser::addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l) { @@ -1310,9 +1427,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build class list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Class) + const TagClassInfo *tci = comp.getClassInfo(); + if (tci) { - const TagClassInfo *tci = TagClassInfo::get(comp); std::shared_ptr<Entry> ce = std::make_shared<Entry>(); ce->section = Entry::CLASS_SEC; switch (tci->kind) @@ -1367,10 +1484,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build file list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::File) + const TagFileInfo *tfi = comp.getFileInfo(); + if (tfi) { - const TagFileInfo *tfi = TagFileInfo::get(comp); - std::shared_ptr<Entry> fe = std::make_shared<Entry>(); fe->section = guessSection(tfi->name); fe->name = tfi->name; @@ -1405,10 +1521,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build concept list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Concept) + const TagConceptInfo *tci = comp.getConceptInfo(); + if (tci) { - const TagConceptInfo *tci = TagConceptInfo::get(comp); - std::shared_ptr<Entry> ce = std::make_shared<Entry>(); ce->section = Entry::CONCEPT_SEC; ce->name = tci->name; @@ -1426,10 +1541,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build namespace list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Namespace) + const TagNamespaceInfo *tni = comp.getNamespaceInfo(); + if (tni) { - const TagNamespaceInfo *tni = TagNamespaceInfo::get(comp); - std::shared_ptr<Entry> ne = std::make_shared<Entry>(); ne->section = Entry::NAMESPACE_SEC; ne->name = tni->name; @@ -1448,10 +1562,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build package list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Package) + const TagPackageInfo *tpgi = comp.getPackageInfo(); + if (tpgi) { - const TagPackageInfo *tpgi = TagPackageInfo::get(comp); - std::shared_ptr<Entry> pe = std::make_shared<Entry>(); pe->section = Entry::PACKAGE_SEC; pe->name = tpgi->name; @@ -1469,10 +1582,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build group list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Group) + const TagGroupInfo *tgi = comp.getGroupInfo(); + if (tgi) { - const TagGroupInfo *tgi = TagGroupInfo::get(comp); - std::shared_ptr<Entry> ge = std::make_shared<Entry>(); ge->section = Entry::GROUPDOC_SEC; ge->name = tgi->name; @@ -1490,11 +1602,10 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Group) + const TagGroupInfo *tgi = comp.getGroupInfo(); + if (tgi) { - const TagGroupInfo *tgi = TagGroupInfo::get(comp); // set subgroup relations bug_774118 - for (const auto &sg : tgi->subgroupList) { const auto &children = root->children(); @@ -1511,10 +1622,9 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) // build page list for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::Page) + const TagPageInfo *tpi = comp.getPageInfo(); + if (tpi) { - const TagPageInfo *tpi = TagPageInfo::get(comp); - std::shared_ptr<Entry> pe = std::make_shared<Entry>(); bool isIndex = (stripExtensionGeneral(tpi->filename,getFileNameExtension(tpi->filename))=="index"); pe->section = isIndex ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC; @@ -1534,9 +1644,9 @@ void TagFileParser::addIncludes() { for (const auto &comp : m_tagFileCompounds) { - if (comp->compoundType()==TagCompoundInfo::CompoundType::File) + const TagFileInfo *tfi = comp.getFileInfo(); + if (tfi) { - const TagFileInfo *tfi = TagFileInfo::get(comp); //printf("tag file tagName=%s path=%s name=%s\n",qPrint(m_tagName),qPrint(tfi->path),qPrint(tfi->name)); FileName *fn = Doxygen::inputNameLinkedMap->find(tfi->name); if (fn) @@ -1592,7 +1702,8 @@ void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullName) parser.parse(fullName,inputStr.data(),Debug::isFlagSet(Debug::Lex)); tagFileParser.buildLists(root); tagFileParser.addIncludes(); -#if DUMP_OUTPUT - tagFileParser.dump(); -#endif + if (Debug::isFlagSet(Debug::Tag)) + { + tagFileParser.dump(); + } } diff --git a/src/template.cpp b/src/template.cpp index 7b6954f..1a483d0 100755 --- a/src/template.cpp +++ b/src/template.cpp @@ -231,27 +231,26 @@ class TemplateListGenericConstIterator : public TemplateListIntf::ConstIterator { public: TemplateListGenericConstIterator(const List &l) : m_list(l) { m_index=0; } - virtual ~TemplateListGenericConstIterator() {} virtual void toFirst() { m_index=0; } virtual void toLast() { - uint count = m_list.count(); + int count = static_cast<int>(m_list.count()); m_index = count>0 ? count-1 : 0; } virtual void toNext() { - if (m_index<m_list.count()) { m_index++; } + if (m_index<static_cast<int>(m_list.count())) { m_index++; } } virtual void toPrev() { - if (m_index>0) { --m_index; } + if (m_index>=0) { --m_index; } } virtual bool current(TemplateVariant &v) const { - if (m_index<m_list.count()) + if (m_index>=0 && m_index<static_cast<int>(m_list.count())) { v = m_list.at(m_index); return TRUE; @@ -264,7 +263,7 @@ class TemplateListGenericConstIterator : public TemplateListIntf::ConstIterator } private: const List &m_list; - size_t m_index = 0; + int m_index = 0; }; //------------------------------------------------------------------------------- @@ -274,13 +273,13 @@ class TemplateList : public TemplateListIntf { public: // TemplateListIntf methods - virtual uint count() const + virtual size_t count() const { - return static_cast<uint>(m_elems.size()); + return m_elems.size(); } - virtual TemplateVariant at(uint index) const + virtual TemplateVariant at(size_t index) const { - return index < m_elems.size() ? m_elems[index] : TemplateVariant(); + return index < m_elems.size() ? m_elems[static_cast<int>(index)] : TemplateVariant(); } virtual TemplateListIntf::ConstIteratorPtr createIterator() const { @@ -299,7 +298,7 @@ class TemplateList : public TemplateListIntf m_elems.push_back(v); } - void removeAt(uint index) + void removeAt(size_t index) { if (index<m_elems.size()) { @@ -307,7 +306,7 @@ class TemplateList : public TemplateListIntf } } - void insertAt(uint index,TemplateListPtr list) + void insertAt(size_t index,TemplateListPtr list) { auto it = m_elems.begin()+index; m_elems.insert(it,list->m_elems.begin(),list->m_elems.end()); @@ -328,30 +327,30 @@ TemplateVariant::TemplateVariant(TemplateVariant &&v) { m_raw = std::move(v.m_raw); m_variant = std::move(v.m_variant); - v.m_variant.invalidate(); + v.m_variant = VariantT(); } TemplateVariant &TemplateVariant::operator=(TemplateVariant &&v) { m_raw = std::move(v.m_raw); m_variant = std::move(v.m_variant); - v.m_variant.invalidate(); + v.m_variant = VariantT(); return *this; } bool TemplateVariant::operator==(TemplateVariant &other) const { - if (!m_variant.valid()) + if (!isValid()) { return FALSE; } if (isBool() && other.isBool()) { - return m_variant.get<static_cast<uint8_t>(Type::Bool)>() == other.m_variant.get<static_cast<uint8_t>(Type::Bool)>(); + return std::get<bool>(m_variant) == std::get<bool>(other.m_variant); } else if (isInt() && other.isInt()) { - return m_variant.get<static_cast<uint8_t>(Type::Int)>() == other.m_variant.get<static_cast<uint8_t>(Type::Int)>(); + return std::get<int>(m_variant) == std::get<int>(other.m_variant); } else if (isList() && other.isList()) { @@ -369,11 +368,11 @@ bool TemplateVariant::toBool() const switch (type()) { case Type::None: return false; - case Type::Bool: return m_variant.get<static_cast<uint8_t>(Type::Bool)>(); - case Type::Int: return m_variant.get<static_cast<uint8_t>(Type::Int)>()!=0; - case Type::String: return !m_variant.get<static_cast<uint8_t>(Type::String)>().isEmpty(); + case Type::Bool: return std::get<bool>(m_variant); + case Type::Int: return std::get<int>(m_variant)!=0; + case Type::String: return !std::get<QCString>(m_variant).isEmpty(); case Type::Struct: return true; - case Type::List: return m_variant.get<static_cast<uint8_t>(Type::List)>()->count()!=0; + case Type::List: return std::get<TemplateListIntfPtr>(m_variant)->count()!=0; case Type::Function: return false; case Type::WeakStruct: return true; } @@ -385,11 +384,11 @@ int TemplateVariant::toInt() const switch (type()) { case Type::None: return 0; - case Type::Bool: return m_variant.get<static_cast<uint8_t>(Type::Bool)>() ? 1 : 0; - case Type::Int: return m_variant.get<static_cast<uint8_t>(Type::Int)>(); - case Type::String: return !m_variant.get<static_cast<uint8_t>(Type::String)>().toInt(); + case Type::Bool: return std::get<bool>(m_variant) ? 1 : 0; + case Type::Int: return std::get<int>(m_variant); + case Type::String: return std::get<QCString>(m_variant).toInt(); case Type::Struct: return 0; - case Type::List: return m_variant.get<static_cast<uint8_t>(Type::List)>()->count(); + case Type::List: return static_cast<int>(std::get<TemplateListIntfPtr>(m_variant)->count()); case Type::Function: return 0; case Type::WeakStruct: return 0; } @@ -401,9 +400,9 @@ QCString TemplateVariant::toString() const switch (type()) { case Type::None: return QCString(); - case Type::Bool: return m_variant.get<static_cast<uint8_t>(Type::Bool)>() ? "true" : "false"; - case Type::Int: return QCString().setNum(m_variant.get<static_cast<uint8_t>(Type::Int)>()); - case Type::String: return m_variant.get<static_cast<uint8_t>(Type::String)>(); + case Type::Bool: return std::get<bool>(m_variant) ? "true" : "false"; + case Type::Int: return QCString().setNum(std::get<int>(m_variant)); + case Type::String: return std::get<QCString>(m_variant); case Type::Struct: return structToString(); case Type::List: return listToString(); case Type::Function: return "[function]"; @@ -431,29 +430,29 @@ const char *TemplateVariant::typeAsString() const TemplateListIntfPtr TemplateVariant::toList() { - return isList() ? m_variant.get<static_cast<uint8_t>(Type::List)>() : nullptr; + return isList() ? std::get<TemplateListIntfPtr>(m_variant) : nullptr; } const TemplateListIntfPtr TemplateVariant::toList() const { - return isList() ? m_variant.get<static_cast<uint8_t>(Type::List)>() : nullptr; + return isList() ? std::get<TemplateListIntfPtr>(m_variant) : nullptr; } TemplateStructIntfPtr TemplateVariant::toStruct() { - return isStruct() ? m_variant.get<static_cast<uint8_t>(Type::Struct)>() : - isWeakStruct() ? m_variant.get<static_cast<uint8_t>(Type::WeakStruct)>().lock() : + return isStruct() ? std::get<TemplateStructIntfPtr>(m_variant) : + isWeakStruct() ? std::get<TemplateStructIntfWeakPtr>(m_variant).lock() : nullptr; } const TemplateStructIntfPtr TemplateVariant::toStruct() const { - return isStruct() ? m_variant.get<static_cast<uint8_t>(Type::Struct)>() : - isWeakStruct() ? m_variant.get<static_cast<uint8_t>(Type::WeakStruct)>().lock() : + return isStruct() ? std::get<TemplateStructIntfPtr>(m_variant) : + isWeakStruct() ? std::get<TemplateStructIntfWeakPtr>(m_variant).lock() : nullptr; } TemplateVariant TemplateVariant::call(const std::vector<TemplateVariant> &args) { - return isFunction() ? m_variant.get<static_cast<uint8_t>(Type::Function)>()(args) : TemplateVariant(); + return isFunction() ? std::get<FunctionDelegate>(m_variant)(args) : TemplateVariant(); } //- Template struct implementation -------------------------------------------- @@ -525,19 +524,19 @@ TemplateImmutableList::~TemplateImmutableList() { } -uint TemplateImmutableList::count() const +size_t TemplateImmutableList::count() const { - return static_cast<uint>(p->elems.size()); + return p->elems.size(); } TemplateListIntf::ConstIteratorPtr TemplateImmutableList::createIterator() const - { +{ return std::make_unique< TemplateListGenericConstIterator<TemplateImmutableList> >(*this); - } +} -TemplateVariant TemplateImmutableList::at(uint index) const +TemplateVariant TemplateImmutableList::at(size_t index) const { - return index<p->elems.size() ? p->elems[index] : TemplateVariant(); + return index<p->elems.size() ? p->elems[static_cast<int>(index)] : TemplateVariant(); } TemplateListIntfPtr TemplateImmutableList::alloc(std::initializer_list<TemplateVariant> elements) @@ -744,9 +743,9 @@ class FilterAdd { return arg; } - bool lhsIsInt; + bool lhsIsInt = false; int lhsValue = variantIntValue(v,lhsIsInt); - bool rhsIsInt; + bool rhsIsInt = false; int rhsValue = variantIntValue(arg,rhsIsInt); if (lhsIsInt && rhsIsInt) { @@ -973,11 +972,11 @@ class FilterLength } if (v.isList()) { - return TemplateVariant((int)v.toList()->count()); + return TemplateVariant(v.toList()->count()); } else if (v.isString()) { - return TemplateVariant((int)v.toString().length()); + return TemplateVariant(v.toString().length()); } else { @@ -1303,8 +1302,8 @@ class FilterAlphaIndex const char hex[]="0123456789abcdef"; while ((c=*p++)) { - result+=hex[((unsigned char)c)>>4]; - result+=hex[((unsigned char)c)&0xf]; + result+=hex[static_cast<unsigned char>(c)>>4]; + result+=hex[static_cast<unsigned char>(c)&0xf]; } } //printf("<keyToLabel(%s)\n",qPrint(result)); @@ -1663,7 +1662,7 @@ static TemplateFilterFactory::AutoRegister<FilterIsAbsoluteURL> fIsAbsolute class ExprAst { public: - virtual ~ExprAst() {} + virtual ~ExprAst() = default; virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(); } }; @@ -1934,7 +1933,7 @@ class TemplateNode { public: TemplateNode(TemplateNode *parent) : m_parent(parent) {} - virtual ~TemplateNode() {} + virtual ~TemplateNode() = default; virtual void render(TextStream &ts, TemplateContext *c) = 0; @@ -2575,7 +2574,7 @@ TemplateContextImpl::TemplateContextImpl(const TemplateEngine *e) : m_engine(e), m_indices(TemplateStruct::alloc()) { //printf("%p:TemplateContextImpl::TemplateContextImpl()\n",(void*)this); - m_fromUtf8 = (void*)(-1); + m_fromUtf8 = reinterpret_cast<void*>(-1); push(); set("index",std::static_pointer_cast<TemplateStructIntf>(m_indices)); } @@ -2589,16 +2588,16 @@ TemplateContextImpl::~TemplateContextImpl() void TemplateContextImpl::setEncoding(const QCString &templateName,int line,const QCString &enc) { if (enc==m_encoding) return; // nothing changed - if (m_fromUtf8!=(void *)(-1)) + if (m_fromUtf8!=reinterpret_cast<void *>(-1)) { portable_iconv_close(m_fromUtf8); - m_fromUtf8 = (void*)(-1); + m_fromUtf8 = reinterpret_cast<void*>(-1); } m_encoding=enc; if (!enc.isEmpty()) { m_fromUtf8 = portable_iconv_open(enc.data(),"UTF-8"); - if (m_fromUtf8==(void*)(-1)) + if (m_fromUtf8==reinterpret_cast<void*>(-1)) { warn(templateName,line,"unsupported character conversion: '%s'->'UTF-8'\n", qPrint(enc)); } @@ -2609,8 +2608,8 @@ void TemplateContextImpl::setEncoding(const QCString &templateName,int line,cons QCString TemplateContextImpl::recode(const QCString &s) { //printf("TemplateContextImpl::recode(%s)\n",qPrint(s)); - int iSize = s.length(); - int oSize = iSize*4+1; + size_t iSize = s.length(); + size_t oSize = iSize*4+1; QCString output(oSize); size_t iLeft = iSize; size_t oLeft = oSize; @@ -2618,7 +2617,7 @@ QCString TemplateContextImpl::recode(const QCString &s) char *oPtr = output.rawData(); if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft)) { - oSize -= (int)oLeft; + oSize -= oLeft; output.resize(oSize+1); output.at(oSize)='\0'; return output; @@ -3219,10 +3218,10 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat> for (i=0;i<n;i++) { TemplateStructPtr s = TemplateStruct::alloc(); - s->set("counter0", (int)i); - s->set("counter", (int)(i+1)); - s->set("revcounter", (int)(n-i)); - s->set("revcounter0", (int)(n-i-1)); + s->set("counter0", i); + s->set("counter", i+1); + s->set("revcounter", n-i); + s->set("revcounter0", n-i-1); s->set("first",i==0); s->set("last", i==n-1); c->set("repeatloop",std::static_pointer_cast<TemplateStructIntf>(s)); @@ -3326,27 +3325,27 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange> TemplateVariant ve = m_endExpr->resolve(c); if (vs.isInt() && ve.isInt()) { - int s = vs.toInt(); - int e = ve.toInt(); - int l = m_down ? s-e+1 : e-s+1; + size_t s = vs.toInt(); + size_t e = ve.toInt(); + size_t l = m_down ? s-e+1 : e-s+1; if (l>0) { c->push(); //int index = m_reversed ? list.count() : 0; const TemplateVariant *parentLoop = c->getRef("forloop"); - uint index = 0; - int i = m_down ? e : s; + size_t index = 0; + size_t i = m_down ? e : s; bool done=false; while (!done) { // set the forloop meta-data variable TemplateStructPtr ls = TemplateStruct::alloc(); - ls->set("counter0", (int)index); - ls->set("counter", (int)(index+1)); - ls->set("revcounter", (int)(l-index)); - ls->set("revcounter0", (int)(l-index-1)); - ls->set("first",index==0); - ls->set("last", (int)index==l-1); + ls->set("counter0", index); + ls->set("counter", (index+1)); + ls->set("revcounter", (l-index)); + ls->set("revcounter0", (l-index-1)); + ls->set("first", index==0); + ls->set("last", index==l-1); ls->set("parentloop",parentLoop ? *parentLoop : TemplateVariant()); c->set("forloop",std::static_pointer_cast<TemplateStructIntf>(ls)); @@ -3483,7 +3482,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor> const TemplateListIntfPtr list = v.toList(); if (list) { - uint listSize = list->count(); + size_t listSize = list->count(); if (listSize==0) // empty for loop { m_emptyNodes.render(ts,c); @@ -3493,7 +3492,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor> //int index = m_reversed ? list.count() : 0; //TemplateVariant v; const TemplateVariant *parentLoop = c->getRef("forloop"); - uint index = m_reversed ? listSize-1 : 0; + size_t index = m_reversed ? listSize-1 : 0; TemplateListIntf::ConstIteratorPtr it = list->createIterator(); TemplateVariant ve; for (m_reversed ? it->toLast() : it->toFirst(); @@ -3501,12 +3500,12 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor> m_reversed ? it->toPrev() : it->toNext()) { TemplateStructPtr s = TemplateStruct::alloc(); - s->set("counter0", (int)index); - s->set("counter", (int)(index+1)); - s->set("revcounter", (int)(listSize-index)); - s->set("revcounter0", (int)(listSize-index-1)); - s->set("first",index==0); - s->set("last", index==listSize-1); + s->set("counter0", index); + s->set("counter", index+1); + s->set("revcounter", listSize-index); + s->set("revcounter0", listSize-index-1); + s->set("first", index==0); + s->set("last", index==listSize-1); s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant()); c->set("forloop",std::static_pointer_cast<TemplateStructIntf>(s)); @@ -4461,7 +4460,7 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers> if (i==entryIndex) // found element { TemplateStructPtr s = TemplateStruct::alloc(); - s->set("id",(int)i); + s->set("id",i); c->set("markers",std::static_pointer_cast<TemplateStructIntf>(s)); c->set(m_var,var); // define local variable to hold element of list type bool wasSpaceless = ci->spacelessEnabled(); @@ -5265,7 +5264,7 @@ class TemplateEngine::Private if (f.is_open()) // read template from disk { FileInfo fi(filePath.str()); - int size=(int)fi.size(); + size_t size=fi.size(); QCString data(size+1); f.read(data.rawData(),size); if (!f.fail()) diff --git a/src/template.h b/src/template.h index 4c9f89b..4b0cfe5 100644 --- a/src/template.h +++ b/src/template.h @@ -19,10 +19,10 @@ #include <vector> #include <memory> #include <functional> +#include <variant> #include "qcstring.h" #include "containers.h" -#include "variant.h" class TemplateListIntf; class TemplateStructIntf; @@ -102,59 +102,71 @@ class TemplateVariant using FunctionDelegate = std::function<TemplateVariant(const std::vector<TemplateVariant>&)>; /** Symbolic names for the possible types that this variant can hold. */ - using VariantT = Variant<bool, // index==0: Type::Bool - int, // index==1: Type::Int - QCString, // index==2: Type::String - TemplateStructIntfPtr, // index==3: Type::Struct - TemplateListIntfPtr, // index==4: Type::List - FunctionDelegate, // index==5: Type::Function - TemplateStructIntfWeakPtr // index==6: Type::WeakStruct - >; + using VariantT = std::variant<std::monostate, // index==0, Invalid/default type + bool, // index==1: Type::Bool + int, // index==2: Type::Int + QCString, // index==3: Type::String + TemplateStructIntfPtr, // index==4: Type::Struct + TemplateListIntfPtr, // index==5: Type::List + FunctionDelegate, // index==6: Type::Function + TemplateStructIntfWeakPtr // index==7: Type::WeakStruct + >; enum class Type : uint8_t { - Bool = 0, - Int = 1, - String = 2, - Struct = 3, - List = 4, - Function = 5, - WeakStruct = 6, - None = 255 + None = 0, + Bool = 1, + Int = 2, + String = 3, + Struct = 4, + List = 5, + Function = 6, + WeakStruct = 7 }; /** Constructs an invalid variant. */ TemplateVariant() {} /** Constructs a new variant with a boolean value \a b. */ - explicit TemplateVariant(bool b) { m_variant.set<static_cast<uint8_t>(Type::Bool)>(b); } + explicit TemplateVariant(bool b) { m_variant = b; } /** Constructs a new variant with a integer value \a v. */ - TemplateVariant(int v) { m_variant.set<static_cast<uint8_t>(Type::Int)>(v); } + TemplateVariant(int v) { m_variant = v; } + + /** Constructs a new variant with a integer value \a v. */ + TemplateVariant(unsigned int v) { m_variant = static_cast<int>(v); } + + /** Constructs a new variant with a integer value \a v. + * We use SFINAE to avoid a compiler error in case size_t already matches the 'unsigned int' overload. + */ + template<typename T, + typename std::enable_if<std::is_same<T,size_t>::value,T>::type* = nullptr + > + TemplateVariant(T v) { m_variant = static_cast<int>(v); } /** Constructs a new variant with a string value \a s. */ - TemplateVariant(const char *s,bool raw=FALSE) : m_raw(raw) { m_variant.set<static_cast<uint8_t>(Type::String)>(s); } + TemplateVariant(const char *s,bool raw=FALSE) : m_raw(raw) { m_variant = QCString(s); } /** Constructs a new variant with a string value \a s. */ - TemplateVariant(const QCString &s,bool raw=FALSE) : m_raw(raw) { m_variant.set<static_cast<uint8_t>(Type::String)>(s.str()); } + TemplateVariant(const QCString &s,bool raw=FALSE) : m_raw(raw) { m_variant = s; } /** Constructs a new variant with a string value \a s. */ - TemplateVariant(const std::string &s,bool raw=FALSE) : m_raw(raw) { m_variant.set<static_cast<uint8_t>(Type::String)>(s); } + TemplateVariant(const std::string &s,bool raw=FALSE) : m_raw(raw) { m_variant = QCString(s); } /** Constructs a new variant with a struct value \a s. * @note. The variant will hold a counting reference to the object. */ - TemplateVariant(TemplateStructIntfPtr s) { m_variant.set<static_cast<uint8_t>(Type::Struct)>(s); } + TemplateVariant(TemplateStructIntfPtr s) { m_variant = s; } /** Constructs a new variant with a list value \a l. * @note. The variant will hold a counting reference to the object. */ - TemplateVariant(TemplateListIntfPtr l) { m_variant.set<static_cast<uint8_t>(Type::List)>(l); } + TemplateVariant(TemplateListIntfPtr l) { m_variant = l; } /** Constructs a new variant with a struct value \a s. * @note. The variant will hold a non-counting reference to the object. */ - TemplateVariant(TemplateStructIntfWeakPtr s) { m_variant.set<static_cast<uint8_t>(Type::WeakStruct)>(s); } + TemplateVariant(TemplateStructIntfWeakPtr s) { m_variant = s; } /** Constructs a new variant which represents a method call * @param[in] delegate FunctionDelegate object to invoke when @@ -163,7 +175,7 @@ class TemplateVariant * TemplateVariant::FunctionDelegate::fromFunction() to create * FunctionDelegate objects. */ - TemplateVariant(FunctionDelegate delegate) { m_variant.set<static_cast<uint8_t>(Type::Function)>(delegate); } + TemplateVariant(FunctionDelegate delegate) { m_variant = delegate; } /** Destroys the Variant object */ ~TemplateVariant() = default; @@ -200,21 +212,21 @@ class TemplateVariant int toInt() const; /** Returns TRUE if the variant holds a valid value, or FALSE otherwise */ - constexpr bool isValid() const { return m_variant.valid(); } + constexpr bool isValid() const { return std::holds_alternative<std::monostate>(m_variant); } /** Returns TRUE if the variant holds a boolean value */ - constexpr bool isBool() const { return m_variant.is<static_cast<uint8_t>(Type::Bool)>(); } + constexpr bool isBool() const { return std::holds_alternative<bool>(m_variant); } /** Returns TRUE if the variant holds an integer value */ - constexpr bool isInt() const { return m_variant.is<static_cast<uint8_t>(Type::Int)>(); } + constexpr bool isInt() const { return std::holds_alternative<int>(m_variant); } /** Returns TRUE if the variant holds a string value */ - constexpr bool isString() const { return m_variant.is<static_cast<uint8_t>(Type::String)>(); } + constexpr bool isString() const { return std::holds_alternative<QCString>(m_variant); } /** Returns TRUE if the variant holds a struct value */ - constexpr bool isStruct() const { return m_variant.is<static_cast<uint8_t>(Type::Struct)>(); } + constexpr bool isStruct() const { return std::holds_alternative<TemplateStructIntfPtr>(m_variant); } /** Returns TRUE if the variant holds a list value */ - constexpr bool isList() const { return m_variant.is<static_cast<uint8_t>(Type::List)>(); } + constexpr bool isList() const { return std::holds_alternative<TemplateListIntfPtr>(m_variant); } /** Returns TRUE if the variant holds a function value */ - constexpr bool isFunction() const { return m_variant.is<static_cast<uint8_t>(Type::Function)>(); } + constexpr bool isFunction() const { return std::holds_alternative<FunctionDelegate>(m_variant); } /** Returns TRUE if the variant holds a struct value */ - constexpr bool isWeakStruct() const { return m_variant.is<static_cast<uint8_t>(Type::WeakStruct)>(); } + constexpr bool isWeakStruct() const { return std::holds_alternative<TemplateStructIntfWeakPtr>(m_variant); } /** Returns the pointer to list referenced by this variant * or 0 if this variant does not have list type. @@ -273,7 +285,7 @@ class TemplateListIntf { public: /** Destructor for the iterator */ - virtual ~ConstIterator() {} + virtual ~ConstIterator() = default; /** Moves iterator to the first element in the list */ virtual void toFirst() = 0; /** Moves iterator to the last element in the list */ @@ -292,13 +304,13 @@ class TemplateListIntf using ConstIteratorPtr = std::unique_ptr<ConstIterator>; /** Destroys the list */ - virtual ~TemplateListIntf() {} + virtual ~TemplateListIntf() = default; /** Returns the number of elements in the list */ - virtual uint count() const = 0; + virtual size_t count() const = 0; /** Returns the element at index position \a index. */ - virtual TemplateVariant at(uint index) const = 0; + virtual TemplateVariant at(size_t index) const = 0; /** Creates a new iterator for this list. * @note the user should call delete on the returned pointer. @@ -312,8 +324,8 @@ class TemplateImmutableList : public TemplateListIntf { public: // TemplateListIntf methods - virtual uint count() const; - virtual TemplateVariant at(uint index) const; + virtual size_t count() const; + virtual TemplateVariant at(size_t index) const; virtual TemplateListIntf::ConstIteratorPtr createIterator() const; /** Creates an instance and returns a shared pointer to it */ @@ -338,7 +350,7 @@ class TemplateStructIntf { public: /** Destroys the struct */ - virtual ~TemplateStructIntf() {} + virtual ~TemplateStructIntf() = default; /** Gets the value for a field name. * @param[in] name The name of the field. @@ -384,7 +396,7 @@ class TemplateImmutableStruct : public TemplateStructIntf class TemplateEscapeIntf { public: - virtual ~TemplateEscapeIntf() {} + virtual ~TemplateEscapeIntf() = default; /** Create a copy of the escape filter */ virtual std::unique_ptr<TemplateEscapeIntf> clone() = 0; /** Returns the \a input after escaping certain characters */ @@ -399,7 +411,7 @@ class TemplateEscapeIntf class TemplateSpacelessIntf { public: - virtual ~TemplateSpacelessIntf() {} + virtual ~TemplateSpacelessIntf() = default; /** Create a copy of the spaceless filter */ virtual std::unique_ptr<TemplateSpacelessIntf> clone() = 0; /** Returns the \a input after removing redundant whitespace */ @@ -422,7 +434,7 @@ class TemplateSpacelessIntf class TemplateContext { public: - virtual ~TemplateContext() {} + virtual ~TemplateContext() = default; /** Push a new scope on the stack. */ virtual void push() = 0; @@ -476,7 +488,7 @@ class Template { public: /** Destructor */ - virtual ~Template() {} + virtual ~Template() = default; /** Renders a template instance to a stream. * @param[in] ts The text stream to write the results to. diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp index 47cd56e..bcb1abc 100644 --- a/src/textdocvisitor.cpp +++ b/src/textdocvisitor.cpp @@ -24,29 +24,29 @@ //------------------------------------------------------------------------- -void TextDocVisitor::visit(DocSymbol *s) +void TextDocVisitor::operator()(const DocSymbol &s) { - const char *res = HtmlEntityMapper::instance()->html(s->symbol()); + const char *res = HtmlEntityMapper::instance()->html(s.symbol()); if (res) { m_t << res; } else { - err("text: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + err("text: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } } -void TextDocVisitor::visit(DocEmoji *s) +void TextDocVisitor::operator()(const DocEmoji &s) { - const char *res = EmojiEntityMapper::instance()->name(s->index()); + const char *res = EmojiEntityMapper::instance()->name(s.index()); if (res) { filter(res); } else { - filter(s->name()); + filter(s.name()); } } diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h index 1489018..6cfed63 100644 --- a/src/textdocvisitor.h +++ b/src/textdocvisitor.h @@ -21,116 +21,87 @@ #include "qcstring.h" #include "docvisitor.h" -#include "docparser.h" +#include "docnode.h" #include "textstream.h" /*! @brief Concrete visitor implementation for TEXT output. */ class TextDocVisitor : public DocVisitor { public: - TextDocVisitor(TextStream &t) : DocVisitor(DocVisitor_Text), m_t(t) {} + TextDocVisitor(TextStream &t) : m_t(t) {} //-------------------------------------- // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *w) { filter(w->word()); } - void visit(DocLinkedWord *w) { filter(w->word()); } - void visit(DocWhiteSpace *) { m_t << " "; } - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *u) { filter(u->url()); } - void visit(DocLineBreak *) { m_t << " "; } - void visit(DocHorRuler *) {} - void visit(DocStyleChange *) {} - void visit(DocVerbatim *s) { filter(s->text()); } - void visit(DocAnchor *) {} - void visit(DocInclude *) {} - void visit(DocIncOperator *) {} - void visit(DocFormula *) {} - void visit(DocIndexEntry *) {} - void visit(DocSimpleSectSep *){} - void visit(DocCite *) {} + void operator()(const DocWord &w) { filter(w.word()); } + void operator()(const DocLinkedWord &w) { filter(w.word()); } + void operator()(const DocWhiteSpace &) { m_t << " "; } + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &u) { filter(u.url()); } + void operator()(const DocLineBreak &) { m_t << " "; } + void operator()(const DocHorRuler &) {} + void operator()(const DocStyleChange &) {} + void operator()(const DocVerbatim &s) { filter(s.text()); } + void operator()(const DocAnchor &) {} + void operator()(const DocInclude &) {} + void operator()(const DocIncOperator &) {} + void operator()(const DocFormula &) {} + void operator()(const DocIndexEntry &) {} + void operator()(const DocSimpleSectSep &){} + void operator()(const DocCite &) {} + void operator()(const DocSeparator &) { m_t << " "; } //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *) {} - void visitPost(DocAutoList *) {} - void visitPre(DocAutoListItem *) {} - void visitPost(DocAutoListItem *) {} - void visitPre(DocPara *) {} - void visitPost(DocPara *) {} - void visitPre(DocRoot *) {} - void visitPost(DocRoot *) {} - void visitPre(DocSimpleSect *) {} - void visitPost(DocSimpleSect *) {} - void visitPre(DocTitle *) {} - void visitPost(DocTitle *) {} - void visitPre(DocSimpleList *) {} - void visitPost(DocSimpleList *) {} - void visitPre(DocSimpleListItem *) {} - void visitPost(DocSimpleListItem *) {} - void visitPre(DocSection *) {} - void visitPost(DocSection *) {} - void visitPre(DocHtmlList *) {} - void visitPost(DocHtmlList *) {} - void visitPre(DocHtmlListItem *) {} - void visitPost(DocHtmlListItem *) {} - void visitPre(DocHtmlDescList *) {} - void visitPost(DocHtmlDescList *) {} - void visitPre(DocHtmlDescTitle *) {} - void visitPost(DocHtmlDescTitle *) {} - void visitPre(DocHtmlDescData *) {} - void visitPost(DocHtmlDescData *) {} - void visitPre(DocHtmlTable *) {} - void visitPost(DocHtmlTable *) {} - void visitPre(DocHtmlRow *) {} - void visitPost(DocHtmlRow *) {} - void visitPre(DocHtmlCell *) {} - void visitPost(DocHtmlCell *) {} - void visitPre(DocHtmlCaption *) {} - void visitPost(DocHtmlCaption *) {} - void visitPre(DocInternal *) {} - void visitPost(DocInternal *) {} - void visitPre(DocHRef *) {} - void visitPost(DocHRef *) {} - void visitPre(DocHtmlHeader *) {} - void visitPost(DocHtmlHeader *) {} - void visitPre(DocImage *) {} - void visitPost(DocImage *) {} - void visitPre(DocDotFile *) {} - void visitPost(DocDotFile *) {} - - void visitPre(DocMscFile *) {} - void visitPost(DocMscFile *) {} - void visitPre(DocDiaFile *) {} - void visitPost(DocDiaFile *) {} - void visitPre(DocLink *) {} - void visitPost(DocLink *) {} - void visitPre(DocRef *) {} - void visitPost(DocRef *) {} - void visitPre(DocSecRefItem *) {} - void visitPost(DocSecRefItem *) {} - void visitPre(DocSecRefList *) {} - void visitPost(DocSecRefList *) {} - void visitPre(DocParamSect *) {} - void visitPost(DocParamSect *) {} - void visitPre(DocParamList *) {} - void visitPost(DocParamList *) {} - void visitPre(DocXRefItem *) {} - void visitPost(DocXRefItem *) {} - void visitPre(DocInternalRef *) {} - void visitPost(DocInternalRef *) {} - void visitPre(DocText *) {} - void visitPost(DocText *) {} - void visitPre(DocHtmlBlockQuote *) {} - void visitPost(DocHtmlBlockQuote *) {} - void visitPre(DocVhdlFlow *) {} - void visitPost(DocVhdlFlow *) {} - void visitPre(DocParBlock *) {} - void visitPost(DocParBlock *) {} + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } + void operator()(const DocAutoList &l) { visitChildren(l); } + void operator()(const DocAutoListItem &li) { visitChildren(li); } + void operator()(const DocPara &p) { visitChildren(p); } + void operator()(const DocRoot &r) { visitChildren(r); } + void operator()(const DocSimpleSect &s) { visitChildren(s); } + void operator()(const DocTitle &t) { visitChildren(t); } + void operator()(const DocSimpleList &l) { visitChildren(l); } + void operator()(const DocSimpleListItem &) { } + void operator()(const DocSection &s) { visitChildren(s); } + void operator()(const DocHtmlList &l) { visitChildren(l); } + void operator()(const DocHtmlListItem &li) { visitChildren(li); } + void operator()(const DocHtmlDescList &dl) { visitChildren(dl); } + void operator()(const DocHtmlDescTitle &dt) { visitChildren(dt); } + void operator()(const DocHtmlDescData &dd) { visitChildren(dd); } + void operator()(const DocHtmlTable &t) { visitChildren(t); } + void operator()(const DocHtmlRow &r) { visitChildren(r); } + void operator()(const DocHtmlCell &c) { visitChildren(c); } + void operator()(const DocHtmlCaption &c) { visitChildren(c); } + void operator()(const DocInternal &i) { visitChildren(i); } + void operator()(const DocHRef &h) { visitChildren(h); } + void operator()(const DocHtmlHeader &h) { visitChildren(h); } + void operator()(const DocImage &i) { visitChildren(i); } + void operator()(const DocDotFile &df) { visitChildren(df); } + void operator()(const DocMscFile &df) { visitChildren(df); } + void operator()(const DocDiaFile &df) { visitChildren(df); } + void operator()(const DocLink &l) { visitChildren(l); } + void operator()(const DocRef &r) { visitChildren(r); } + void operator()(const DocSecRefItem &s) { visitChildren(s); } + void operator()(const DocSecRefList &l) { visitChildren(l); } + void operator()(const DocParamSect &s) { visitChildren(s); } + void operator()(const DocParamList &) { } + void operator()(const DocXRefItem &x) { visitChildren(x); } + void operator()(const DocInternalRef &r) { visitChildren(r); } + void operator()(const DocText &t) { visitChildren(t); } + void operator()(const DocHtmlBlockQuote &q) { visitChildren(q); } + void operator()(const DocVhdlFlow &) { } + void operator()(const DocParBlock &pb) { visitChildren(pb); } private: diff --git a/src/textstream.h b/src/textstream.h index 38027ec..d99185c 100644 --- a/src/textstream.h +++ b/src/textstream.h @@ -22,6 +22,7 @@ #include <cstdint> #include <cstdio> #include <fstream> +#include <type_traits> #include "qcstring.h" @@ -96,6 +97,27 @@ class TextStream final m_buffer+=c; return static_cast<TextStream&>(*this); } + /** Adds an unsigned character to the stream */ + TextStream &operator<<( unsigned char c) + { + m_buffer+=c; + return static_cast<TextStream&>(*this); + } + + /** Adds an unsigned character string to the stream */ + TextStream &operator<<( unsigned char *s) + { + if (s) + { + unsigned char *p = s; + while(*p) + { + m_buffer+=*p; + p++; + } + } + return static_cast<TextStream&>(*this); + } /** Adds a C-style string to the stream */ TextStream &operator<<( const char *s) @@ -146,10 +168,22 @@ class TextStream final return static_cast<TextStream&>(*this); } + /** Adds a size_t integer to the stream. + * We use SFINAE to avoid a compiler error in case size_t already matches the 'unsigned int' overload. + */ + template<typename T, + typename std::enable_if<std::is_same<T,size_t>::value,T>::type* = nullptr + > + TextStream &operator<<( T i) + { + output_int32(static_cast<uint>(i),false); + return static_cast<TextStream&>(*this); + } + /** Adds a float to the stream */ TextStream &operator<<( float f) { - output_double((double)f); + output_double(static_cast<double>(f)); return static_cast<TextStream&>(*this); } @@ -233,9 +267,9 @@ class TextStream final *p = '\0'; if ( neg ) { - n = (uint32_t)(-(int32_t)n); + n = static_cast<uint32_t>(-static_cast<int32_t>(n)); } - do { *--p = ((char)(n%10)) + '0'; n /= 10; } while ( n ); + do { *--p = (static_cast<char>(n%10)) + '0'; n /= 10; } while ( n ); if ( neg ) *--p = '-'; m_buffer+=p; } diff --git a/src/translator.h b/src/translator.h index e7372d2..adb552f 100644 --- a/src/translator.h +++ b/src/translator.h @@ -31,7 +31,7 @@ class Translator * It is implemented by the adapter classes. */ virtual QCString updateNeededMessage() { return QCString(); } - virtual ~Translator() {} + virtual ~Translator() = default; // Please, have a look at comments inside the translator_en.h file // to learn the meaning of the following methods. The translator_en.h @@ -79,6 +79,74 @@ class Translator } virtual QCString trISOLang() = 0; + /** language codes for Html help + 0x402 Bulgarian + 0x405 Czech + 0x406 Danish + 0x413 Dutch + 0xC09 English (Australia) + 0x809 English (Britain) + 0x1009 English (Canada) + 0x1809 English (Ireland) + 0x1409 English (New Zealand) + 0x1C09 English (South Africa) + 0x409 English (United States) + 0x40B Finnish + 0x40C French + 0x407 German + 0x408 Greece + 0x439 Hindi + 0x40E Hungarian + 0x410 Italian + 0x814 Norwegian + 0x415 Polish + 0x816 Portuguese(Portugal) + 0x416 Portuguese(Brazil) + 0x419 Russian + 0x80A Spanish(Mexico) + 0xC0A Spanish(Modern Sort) + 0x40A Spanish(Traditional Sort) + 0x41D Swedish + 0x41F Turkey + 0x411 Japanese + 0x412 Korean + 0x804 Chinese (PRC) + 0x404 Chinese (Taiwan) + + New LCIDs: + 0x421 Indonesian + 0x41A Croatian + 0x418 Romanian + 0x424 Slovenian + 0x41B Slovak + 0x422 Ukrainian + 0x81A Serbian (Serbia, Latin) + 0x403 Catalan + 0x426 Latvian + 0x427 Lithuanian + 0x436 Afrikaans + 0x42A Vietnamese + 0x429 Persian (Iran) + 0xC01 Arabic (Egypt) - I don't know which version of arabic is used inside translator_ar.h , + so I have chosen Egypt at random + + Code for Esperanto should be as shown below but the htmlhelp compiler 1.3 does not support this + (and no newer version is available). + 0x48f Esperanto + So do a fallback to the default language + 0x409 English (United States) + + + 0xC1A Serbian (Serbia, Cyrillic) + + */ + virtual QCString getLanguageString() = 0; + + /** + * add punctuation at the end of a brief description when needed and supported by the language + */ + virtual bool needsPunctuation() { return true; } + // --- Language translation methods ------------------- virtual QCString trRelatedFunctions() = 0; @@ -104,7 +172,6 @@ class Translator virtual QCString trClassHierarchy() = 0; virtual QCString trCompoundList() = 0; virtual QCString trFileList() = 0; - //virtual QCString trHeaderFiles() = 0; virtual QCString trCompoundMembers() = 0; virtual QCString trFileMembers() = 0; virtual QCString trRelatedPages() = 0; @@ -115,11 +182,9 @@ class Translator virtual QCString trCompoundListDescription() = 0; virtual QCString trCompoundMembersDescription(bool extractAll) = 0; virtual QCString trFileMembersDescription(bool extractAll) = 0; - //virtual QCString trHeaderFilesDescription() = 0; virtual QCString trExamplesDescription() = 0; virtual QCString trRelatedPagesDescription() = 0; virtual QCString trModulesDescription() = 0; - //virtual QCString trNoDescriptionAvailable() = 0; // index titles (the project name is prepended for these) @@ -132,29 +197,22 @@ class Translator virtual QCString trClassDocumentation() = 0; virtual QCString trFileDocumentation() = 0; virtual QCString trExampleDocumentation() = 0; - virtual QCString trPageDocumentation() = 0; virtual QCString trReferenceManual() = 0; virtual QCString trDefines() = 0; - //virtual QCString trFuncProtos() = 0; virtual QCString trTypedefs() = 0; virtual QCString trEnumerations() = 0; virtual QCString trFunctions() = 0; virtual QCString trVariables() = 0; virtual QCString trEnumerationValues() = 0; virtual QCString trDefineDocumentation() = 0; - //virtual QCString trFunctionPrototypeDocumentation() = 0; virtual QCString trTypedefDocumentation() = 0; virtual QCString trEnumerationTypeDocumentation() = 0; virtual QCString trFunctionDocumentation() = 0; virtual QCString trVariableDocumentation() = 0; virtual QCString trCompounds() = 0; virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) = 0; - //virtual QCString trWrittenBy() = 0; virtual QCString trClassDiagram(const QCString &clName) = 0; - virtual QCString trForInternalUseOnly() = 0; - //virtual QCString trReimplementedForInternalReasons() = 0; virtual QCString trWarning() = 0; - //virtual QCString trBugsAndLimitations() = 0; virtual QCString trVersion() = 0; virtual QCString trDate() = 0; virtual QCString trReturns() = 0; @@ -220,7 +278,6 @@ class Translator virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) = 0; - //virtual QCString trAlphabeticalList() = 0; ////////////////////////////////////////////////////////////////////////// // new since 0.49-990901 @@ -234,7 +291,6 @@ class Translator // new since 0.49-991003 ////////////////////////////////////////////////////////////////////////// - //virtual QCString trSources() = 0; virtual QCString trDefinedAtLineInSourceFile() = 0; virtual QCString trDefinedInSourceFile() = 0; @@ -312,12 +368,6 @@ class Translator virtual QCString trTestList() = 0; ////////////////////////////////////////////////////////////////////////// -// new since 1.2.1 -////////////////////////////////////////////////////////////////////////// - - //virtual QCString trDCOPMethods() = 0; - -////////////////////////////////////////////////////////////////////////// // new since 1.2.2 ////////////////////////////////////////////////////////////////////////// @@ -328,13 +378,10 @@ class Translator // new since 1.2.4 ////////////////////////////////////////////////////////////////////////// - //virtual QCString trInterfaces() = 0; virtual QCString trClasses() = 0; virtual QCString trPackage(const QCString &name) = 0; - virtual QCString trPackageList() = 0; virtual QCString trPackageListDescription() = 0; virtual QCString trPackages() = 0; - //virtual QCString trPackageDocumentation() = 0; virtual QCString trDefineValue() = 0; ////////////////////////////////////////////////////////////////////////// @@ -415,7 +462,6 @@ class Translator virtual QCString trGroup(bool first_capital, bool singular) = 0; virtual QCString trPage(bool first_capital, bool singular) = 0; virtual QCString trMember(bool first_capital, bool singular) = 0; - //virtual QCString trField(bool first_capital, bool singular) = 0; virtual QCString trGlobal(bool first_capital, bool singular) = 0; ////////////////////////////////////////////////////////////////////////// @@ -461,8 +507,9 @@ class Translator ////////////////////////////////////////////////////////////////////////// virtual QCString trPackageTypes() = 0; + virtual QCString trPackageFunctions() = 0; virtual QCString trPackageMembers() = 0; - virtual QCString trStaticPackageMembers() = 0; + virtual QCString trStaticPackageFunctions() = 0; virtual QCString trPackageAttribs() = 0; virtual QCString trStaticPackageAttribs() = 0; @@ -477,7 +524,6 @@ class Translator // new since 1.3.3 ////////////////////////////////////////////////////////////////////////// - //virtual QCString trSearchForIndex() = 0; virtual QCString trSearchResultsTitle() = 0; virtual QCString trSearchResults(int numDocuments) = 0; virtual QCString trSearchMatches() = 0; @@ -495,7 +541,6 @@ class Translator virtual QCString trDirIndex() = 0; virtual QCString trDirDocumentation() = 0; virtual QCString trDirectories() = 0; - virtual QCString trDirDescription() = 0; virtual QCString trDirReference(const QCString &dirName) = 0; virtual QCString trDir(bool first_capital, bool singular) = 0; @@ -556,7 +601,6 @@ class Translator // new since 1.6.3 ////////////////////////////////////////////////////////////////////////// - //virtual QCString trDirDependency(const QCString &name) = 0; virtual QCString trFileIn(const QCString &name) = 0; virtual QCString trIncludesFileIn(const QCString &name) = 0; virtual QCString trDateTime(int year,int month,int day,int dayOfWeek, @@ -668,6 +712,11 @@ class Translator virtual QCString trConceptDocumentation() = 0; virtual QCString trConceptListDescription(bool extractAll) = 0; virtual QCString trConceptDefinition() = 0; + +////////////////////////////////////////////////////////////////////////// +// new since 1.9.4 +////////////////////////////////////////////////////////////////////////// + virtual QCString trPackageList() = 0; }; #endif diff --git a/src/translator_adapter.h b/src/translator_adapter.h index 54a0a35..241b9dd 100644 --- a/src/translator_adapter.h +++ b/src/translator_adapter.h @@ -13,7 +13,6 @@ class TranslatorAdapterBase : public Translator { protected: - virtual ~TranslatorAdapterBase() {} TranslatorEnglish english; /*! An auxiliary inline method used by the updateNeededMessage() @@ -41,7 +40,17 @@ class TranslatorAdapterBase : public Translator }; -class TranslatorAdapter_1_9_2 : public TranslatorAdapterBase +class TranslatorAdapter_1_9_4 : public TranslatorAdapterBase +{ + public: + virtual QCString updateNeededMessage() + { return createUpdateNeededMessage(idLanguage(),"release 1.9.4"); } + + virtual QCString trPackageList() + { return english.trPackageList(); } +}; + +class TranslatorAdapter_1_9_2 : public TranslatorAdapter_1_9_4 { public: virtual QCString updateNeededMessage() diff --git a/src/translator_am.h b/src/translator_am.h index 6e7a9a8..5159493 100644 --- a/src/translator_am.h +++ b/src/translator_am.h @@ -37,6 +37,10 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 }
virtual QCString trISOLang()
{ return "hy"; }
+ virtual QCString getLanguageString()
+ {
+ return "0x42b Armenian";
+ }
// --- Language translation methods -------------------
@@ -110,7 +114,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 */
virtual QCString trGeneratedAutomatically(const QCString &s)
{ QCString result="Ավտոմատ ստեղծված է ելքային կոդից, Doxygen-ի միջոցով, ";
- if (!s.isEmpty()) result+=s+(QCString)" համար:";
+ if (!s.isEmpty()) result+=s+" համար:";
return result;
}
@@ -342,6 +346,10 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 {
return "Տվյալների կառուցվածքներ";
}
+ else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
+ {
+ return trDesignUnitDocumentation();
+ }
else
{
return "Դասեր";
@@ -360,12 +368,6 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 virtual QCString trExampleDocumentation()
{ return "Օրինակներ"; }
- /*! This is used in LaTeX as the title of the chapter containing
- * the documentation of all related pages.
- */
- virtual QCString trPageDocumentation()
- { return "Էջեր"; }
-
/*! This is used in LaTeX as the title of the document */
virtual QCString trReferenceManual()
{ return "Հղումների ձեռնարկ"; }
@@ -459,9 +461,9 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 */
virtual QCString trGeneratedAt(const QCString &date,const QCString &projName)
{
- QCString result=(QCString)"Ստեղծվել է "+date;
- if (!projName.isEmpty()) result+=projName+QCString(" -ի համար,");
- result+=(QCString)" հետևյալ համակարգով.";
+ QCString result=QCString("Ստեղծվել է ")+date;
+ if (!projName.isEmpty()) result+=projName+" -ի համար,";
+ result+=" հետևյալ համակարգով.";
return result;
}
@@ -471,10 +473,6 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 return clName+QCString(" -ի ժառանգման գծագիրը.");
}
- /*! this text is generated when the \\internal command is used. */
- virtual QCString trForInternalUseOnly()
- { return "Միայն ներքին օգտագործման համար"; }
-
/*! this text is generated when the \\warning command is used. */
virtual QCString trWarning()
{ return "Զգուշացում"; }
@@ -549,7 +547,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 ClassDef::CompoundType compType,
bool isTemplate)
{
- QCString result=(QCString)clName;
+ QCString result=clName;
if (isTemplate)
{
switch(compType)
@@ -724,7 +722,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
bool single)
{
- QCString result = (QCString)"Այս ";
+ QCString result = "Այս ";
switch(compType)
{
case ClassDef::Class: result+="դասի"; break;
@@ -789,12 +787,12 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 /*! this text is put before a collaboration diagram */
virtual QCString trCollaborationDiagram(const QCString &clName)
{
- return (QCString)clName+"-ի համագործակցությունների գծագիր.";
+ return clName+"-ի համագործակցությունների գծագիր.";
}
/*! this text is put before an include dependency graph */
virtual QCString trInclDepGraph(const QCString &fName)
{
- return (QCString)fName+"-ի ներառումների կախվածությունների գծագիր.";
+ return fName+"-ի ներառումների կախվածությունների գծագիր.";
}
/*! header that is put before the list of constructor/destructors. */
virtual QCString trConstructorDocumentation()
@@ -1076,12 +1074,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 /*! Used as the title of a Java package */
virtual QCString trPackage(const QCString &name)
{
- return (QCString)"Փաթեթ "+name;
- }
- /*! Title of the package index page */
- virtual QCString trPackageList()
- {
- return "Փաթեթների ցուցակ";
+ return "Փաթեթ "+name;
}
/*! The description of the package index page */
virtual QCString trPackageListDescription()
@@ -1316,14 +1309,18 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 /*! Used as a heading for a list of Java class functions with package
* scope.
*/
- virtual QCString trPackageMembers()
+ virtual QCString trPackageFunctions()
{
return "Փաթեթի ֆունկցիաներ";
}
+ virtual QCString trPackageMembers()
+ {
+ return "Փաթեթի անդամներ";
+ }
/*! Used as a heading for a list of static Java class functions with
* package scope.
*/
- virtual QCString trStaticPackageMembers()
+ virtual QCString trStaticPackageFunctions()
{
return "Փաթեթի ստատիկ ֆունկցիաներ";
}
@@ -1435,14 +1432,6 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 virtual QCString trDirectories()
{ return "Ֆայլադրաններ"; }
- /*! This returns a sentences that introduces the directory hierarchy.
- * and the fact that it is sorted alphabetically per level
- */
- virtual QCString trDirDescription()
- { return "Այս ֆայլադարանների հիերարխիան կարգավորված է կոպտորեն, "
- "բայց ոչ ամբողջապես, այբբենական կարգով.";
- }
-
/*! This returns the title of a directory page. The name of the
* directory is passed via \a dirName.
*/
@@ -1576,7 +1565,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 ClassDef::CompoundType compType,
bool isTemplate)
{
- QCString result=(QCString)clName;
+ QCString result=clName;
if (!isTemplate)
{
switch(compType)
@@ -1658,7 +1647,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 bool single)
{ // here s is one of " Module", " Struct" or " Union"
// single is true implies a single file
- QCString result=(QCString)"Այս ";
+ QCString result="Այս ";
switch(compType)
{
case ClassDef::Class: result+="մոդուլի"; break;
@@ -1744,7 +1733,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 */
virtual QCString trFileIn(const QCString &name)
{
- return (QCString)"Ֆայլը " + name + " ում";
+ return "Ֆայլը " + name + " ում";
}
/*! when clicking a directory dependency label, a page with a
@@ -1753,7 +1742,7 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 */
virtual QCString trIncludesFileIn(const QCString &name)
{
- return (QCString)"Ներառում է ֆայլը " + name + " ում";
+ return "Ներառում է ֆայլը " + name + " ում";
}
/** Compiles a date string.
diff --git a/src/translator_ar.h b/src/translator_ar.h index f847f5b..6b6f1cc 100644 --- a/src/translator_ar.h +++ b/src/translator_ar.h @@ -32,10 +32,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 { - protected: - friend class TranslatorAdapterBase; - virtual ~TranslatorArabic() {} - public: // --- Language control methods ------------------- @@ -70,6 +66,10 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 virtual QCString trISOLang() { return "ar-EG"; } + virtual QCString getLanguageString() + { + return "0xC01 Arabic (Egypt)"; + } // --- Language translation methods ------------------- @@ -135,7 +135,7 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="تم تكوينها آليا بواسطة Doxygen"; - if (!s.isEmpty()) result+=(QCString)" لـ "+s; + if (!s.isEmpty()) result+=" لـ "+s; result+=" من ملفات المصدر."; return result; } @@ -181,10 +181,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 virtual QCString trFileList() { return "قائمة الملفات"; } - /*! This is put above each page as a link to the list of all verbatim headers */ - virtual QCString trHeaderFiles() - { return "الملفات الرأسية"; } - /*! This is put above each page as a link to all members of compounds. */ virtual QCString trCompoundMembers() { @@ -318,10 +314,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 return result; } - /*! This is an introduction to the page with the list of all header files. */ - virtual QCString trHeaderFilesDescription() - { return "Here are the header files that make up the API:"; } - /*! This is an introduction to the page with the list of all examples */ virtual QCString trExamplesDescription() { return "هذه قائمة بكل الأمثلة:"; } @@ -334,14 +326,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 virtual QCString trModulesDescription() { return "هذه قائمة بكل المكونات:"; } - /*! This sentences is used in the annotated class/file lists if no brief - * description is given. - */ - virtual QCString trNoDescriptionAvailable() - { return "لا يوجد وصف متاح"; } - - // index titles (the project name is prepended for these) - /*! This is used in HTML as the title of index.html. */ virtual QCString trDocumentation() @@ -395,6 +379,10 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 { return "فهرس هيكل البيانات"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "فهرس الفئة"; @@ -413,12 +401,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 virtual QCString trExampleDocumentation() { return "توثيق الأمثلة"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "توثيق الصفحات"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "الكتيب المرجعي"; } @@ -515,34 +497,22 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generated on "+date; - if (!projName.isEmpty()) result+=(QCString)" for "+projName; - result+=(QCString)" by"; + QCString result="Generated on "+date; + if (!projName.isEmpty()) result+=" for "+projName; + result+=" by"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Inheritance diagram for "+clName+":"; + return "Inheritance diagram for "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "للاستخدام الداخلي فقط."; } - - /*! this text is generated when the \\reimp command is used. */ - virtual QCString trReimplementedForInternalReasons() - { return "Reimplemented for internal reasons; the API is not affected."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "تنبيه"; } - /*! this text is generated when the \\bug command is used. */ - virtual QCString trBugsAndLimitations() - { return "Bugs and limitations"; } - /*! this text is generated when the \\version command is used. */ virtual QCString trVersion() { return "إصدارة"; } @@ -613,7 +583,7 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Class"; break; @@ -773,7 +743,7 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"توثيق "; + QCString result="توثيق "; switch(compType) { case ClassDef::Class: result+="هذه الفئة"; break; @@ -813,10 +783,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 // new since 0.49-991003 ////////////////////////////////////////////////////////////////////////// - virtual QCString trSources() - { - return "مصادر"; - } virtual QCString trDefinedAtLineInSourceFile() { return "Definition at line @0 of file @1."; @@ -842,12 +808,12 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"رسم التعاون لـ "+clName+":"; + return "رسم التعاون لـ "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"رسم اعتمادية التضمين لـ "+fName+":"; + return "رسم اعتمادية التضمين لـ "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1133,12 +1099,7 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"حزمة "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "قائمة الحزم"; + return "حزمة "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1150,11 +1111,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 { return "حزم"; } - /*! Used as a chapter title for Latex & RTF output */ - virtual QCString trPackageDocumentation() - { - return "توثيق الحزم"; - } /*! Text shown before a multi-line define */ virtual QCString trDefineValue() { @@ -1295,17 +1251,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trField(bool /*first_capital*/, bool singular) - { - QCString result("حقل"); - if (!singular) result="حقول"; - return result; - } - - /*! This is used for translation of the word that will possibly - * be followed by a single name or by a list of names - * of the category. - */ virtual QCString trGlobal(bool /*first_capital*/, bool singular) { QCString result("عام"); @@ -1411,14 +1356,18 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "دوال الحزمة"; } + virtual QCString trPackageMembers() + { + return "أعضاء الحزمة"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "دوال ساكنة للحزمة"; } @@ -1530,14 +1479,6 @@ class TranslatorArabic : public TranslatorAdapter_1_4_6 virtual QCString trDirectories() { return "الأدلة"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "هذا الشكل الهرمي للأدلة تم ترتيبه أبجديا بصورة تقريبية، " - "وليس ترتيبا أبجديا كاملا:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ diff --git a/src/translator_bg.h b/src/translator_bg.h new file mode 100644 index 0000000..b9639b4 --- /dev/null +++ b/src/translator_bg.h @@ -0,0 +1,2304 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2015 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef TRANSLATOR_BG_H +#define TRANSLATOR_BG_H + +/*! + When defining a translator class for the new language, follow + the description in the documentation. One of the steps says + that you should copy the translator_en.h (this) file to your + translator_xx.h new file. Your new language should use the + Translator class as the base class. This means that you need to + implement exactly the same (pure virtual) methods as the + TranslatorEnglish does. Because of this, it is a good idea to + start with the copy of TranslatorEnglish and replace the strings + one by one. + + It is not necessary to include "translator.h" or + "translator_adapter.h" here. The files are included in the + language.cpp correctly. Not including any of the mentioned + files frees the maintainer from thinking about whether the + first, the second, or both files should be included or not, and + why. This holds namely for localized translators because their + base class is changed occasionally to adapter classes when the + Translator class changes the interface, or back to the + Translator class (by the local maintainer) when the localized + translator is made up-to-date again. +*/ + +/* + * Kiril Kirilov released released Feb 28, 2022 + * + */ +class TranslatorBulgarian : public TranslatorAdapter_1_9_4 +{ + public: + + // --- Language control methods ------------------- + + /*! Used for identification of the language. The identification + * should not be translated. It should be replaced by the name + * of the language in English using lower-case characters only + * (e.g. "czech", "japanese", "russian", etc.). It should be equal to + * the identification used in language.cpp. + */ + virtual QCString idLanguage() + { return "bulgarian"; } + + /*! Used to get the LaTeX command(s) for the language support. + * This method should return string with commands that switch + * LaTeX to the desired language. For example + * <pre>"\\usepackage[german]{babel}\n" + * </pre> + * or + * <pre>"\\usepackage{polski}\n" + * "\\usepackage[latin2]{inputenc}\n" + * "\\usepackage[T1]{fontenc}\n" + * </pre> + * + * The English LaTeX does not use such commands. Because of this + * the empty string is returned in this implementation. + */ + virtual QCString latexLanguageSupportCommand() + { + { return "\\usepackage[T2A]{fontenc}\n\\usepackage[bulgarian]{babel}\n"; } + } + + virtual QCString trISOLang() + { + return "bg"; + } + virtual QCString getLanguageString() + { + return "0x402 bulgarian"; + } + + // --- Language translation methods ------------------- + + /*! used in the compound documentation before a list of related functions. */ + virtual QCString trRelatedFunctions() + { return "Функции, свързани с класа"; } + + /*! subscript for the related functions. */ + virtual QCString trRelatedSubscript() + { return "(Имайте предвид, че тези функции не са членове на класа.)"; } + + /*! header that is put before the detailed description of files, classes and namespaces. */ + virtual QCString trDetailedDescription() + { return "Подробно описание"; } + + /*! header that is put before the list of typedefs. */ + virtual QCString trMemberTypedefDocumentation() + { return "Членове Дефинирани типове Документация"; } + + /*! header that is put before the list of enumerations. */ + virtual QCString trMemberEnumerationDocumentation() + { return "Членове Изброявания Документация"; } + + /*! header that is put before the list of member functions. */ + virtual QCString trMemberFunctionDocumentation() + { return "Членове Функции(методи) Документация"; } + + /*! header that is put before the list of member attributes. */ + virtual QCString trMemberDataDocumentation() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Полета Документация"; + } + else + { + return "Член данни Документация"; + } + } + + /*! this is the text of a link put after brief descriptions. */ + virtual QCString trMore() + { return "Допълнително..."; } + + /*! put in the class documentation */ + virtual QCString trListOfAllMembers() + { return "Списък на всички членове"; } + + /*! used as the title of the "list of all members" page of a class */ + virtual QCString trMemberList() + { return "Членове Списък"; } + + /*! this is the first part of a sentence that is followed by a class name */ + virtual QCString trThisIsTheListOfAllMembers() + { return "Това е пълен списък с членове за "; } + + /*! this is the remainder of the sentence after the class name */ + virtual QCString trIncludingInheritedMembers() + { return ", включително всички наследени членове."; } + + /*! this is put at the author sections at the bottom of man pages. + * parameter s is name of the project name. + */ + virtual QCString trGeneratedAutomatically(const QCString &s) + { QCString result="Генерирано автоматично от Doxygen"; + if (!s.isEmpty()) result+=(QCString)" за "+s; + result+=" от изходния код."; + return result; + } + + /*! put after an enum name in the list of all members */ + virtual QCString trEnumName() + { return "изброяване"; } + + /*! put after an enum value in the list of all members */ + virtual QCString trEnumValue() + { return "елементи на изброяване"; } + + /*! put after an undocumented member in the list of all members */ + virtual QCString trDefinedIn() + { return "дефинирани в"; } + + // quick reference sections + + /*! This is put above each page as a link to the list of all groups of + * compounds or files (see the \\group command). + */ + virtual QCString trModules() + { return "Групи"; } + + /*! This is put above each page as a link to the class hierarchy */ + virtual QCString trClassHierarchy() + { return "Класове Йерархия"; } + + /*! This is put above each page as a link to the list of annotated classes */ + virtual QCString trCompoundList() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Структури от данни"; + } + else + { + return "Класове Списък"; + } + } + + /*! This is put above each page as a link to the list of documented files */ + virtual QCString trFileList() + { return "Файлове Списък"; } + + /*! This is put above each page as a link to all members of compounds. */ + virtual QCString trCompoundMembers() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Член Полета с данни"; + } + else + { + return "Членове на класа"; + } + } + + /*! This is put above each page as a link to all members of files. */ + virtual QCString trFileMembers() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Глобални"; + } + else + { + return "Файлове Членове"; + } + } + + /*! This is put above each page as a link to all related pages. */ + virtual QCString trRelatedPages() + { return "Свързани страници"; } + + /*! This is put above each page as a link to all examples. */ + virtual QCString trExamples() + { return "Примери"; } + + /*! This is put above each page as a link to the search engine. */ + virtual QCString trSearch() + { return "Търсене"; } + + /*! This is an introduction to the class hierarchy. */ + virtual QCString trClassHierarchyDescription() + { + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return "Йерархичен списък на всички обекти:"; + } + else + { + return "Този списък с наследявания е сортиран, " + "но не изцяло по азбучен ред:"; + } + } + + /*! This is an introduction to the list with all files. */ + virtual QCString trFileListDescription(bool extractAll) + { + QCString result="Пълен списък с "; + if (!extractAll) result+="документирани "; + result+="файлове с кратко описание:"; + return result; + } + + /*! This is an introduction to the annotated compound list. */ + virtual QCString trCompoundListDescription() + { + + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Структури от данни с кратко описание:"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Класове с кратко описание:"; + } + else + { + return "Класове, структури, " + "обединения и интерфейси с кратко описание:"; + } + } + + /*! This is an introduction to the page with all class members. */ + virtual QCString trCompoundMembersDescription(bool extractAll) + { + QCString result="Списък на всички "; + if (!extractAll) + { + result+="документирани "; + } + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="членове поле, структура и обединение"; + } + else + { + result+="членове на класа"; + } + result+=" с връзки към "; + if (!extractAll) + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="документацията за структура/обединение за всяко поле:"; + } + else + { + result+="документацията на класа за всеки член:"; + } + } + else + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="структурите/обединенията, към които принадлежат:"; + } + else + { + result+="класовете, към които принадлежат:"; + } + } + return result; + } + + /*! This is an introduction to the page with all file members. */ + virtual QCString trFileMembersDescription(bool extractAll) + { + QCString result="Списък на всички "; + if (!extractAll) result+="документирани "; + + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + result+="функции, променливи, макроопределения, изброявания и дефиниции на типове"; + } + else + { + result+="членове на файлове"; + } + result+=" с връзки към "; + if (extractAll) + result+="файловете,към които принадлежат:"; + else + result+="документацията:"; + return result; + } + + /*! This is an introduction to the page with the list of all examples */ + virtual QCString trExamplesDescription() + { return "Списък на всички примери:"; } + + /*! This is an introduction to the page with the list of related pages */ + virtual QCString trRelatedPagesDescription() + { return "Списък на всички свързани страници с документация:"; } + + /*! This is an introduction to the page with the list of class/file groups */ + virtual QCString trModulesDescription() + { return "Списък на всички групи:"; } + + // index titles (the project name is prepended for these) + + /*! This is used in HTML as the title of index.html. */ + virtual QCString trDocumentation() + { return "Документация"; } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all groups. + */ + virtual QCString trModuleIndex() + { return "Групи Указател"; } + + /*! This is used in LaTeX as the title of the chapter with the + * class hierarchy. + */ + virtual QCString trHierarchicalIndex() + { return "Класове Йерархичен указател"; } + + /*! This is used in LaTeX as the title of the chapter with the + * annotated compound index. + */ + virtual QCString trCompoundIndex() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Структури от данни Указател"; + } + else + { + return "Класове Указател"; + } + } + + /*! This is used in LaTeX as the title of the chapter with the + * list of all files. + */ + virtual QCString trFileIndex() + { return "Файлове Списък"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all groups. + */ + virtual QCString trModuleDocumentation() + { return "Групи Документация"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all classes, structs and unions. + */ + virtual QCString trClassDocumentation() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Структури от данни Документация"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } + else + { + return "Класове Документация"; + } + } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all files. + */ + virtual QCString trFileDocumentation() + { return "Файлове Документация"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all examples. + */ + virtual QCString trExampleDocumentation() + { return "Примери Документация"; } + + /*! This is used in LaTeX as the title of the document */ + virtual QCString trReferenceManual() + { return "Помощно ръководство"; } + + /*! This is used in the documentation of a file as a header before the + * list of defines + */ + virtual QCString trDefines() + { return "Макроси"; } + + /*! This is used in the documentation of a file as a header before the + * list of typedefs + */ + virtual QCString trTypedefs() + { return "Дефиниции на типове"; } + + /*! This is used in the documentation of a file as a header before the + * list of enumerations + */ + virtual QCString trEnumerations() + { return "Изброявания"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) functions + */ + virtual QCString trFunctions() + { return "Функции"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) variables + */ + virtual QCString trVariables() + { return "Променливи"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) variables + */ + virtual QCString trEnumerationValues() + { return "Елементи на изброяване"; } + + /*! This is used in the documentation of a file before the list of + * documentation blocks for defines + */ + virtual QCString trDefineDocumentation() + { return "Макро дефиниции Документация"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for typedefs + */ + virtual QCString trTypedefDocumentation() + { return "Дефинирани типове Документация"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration types + */ + virtual QCString trEnumerationTypeDocumentation() + { return "Изброени типове Документация"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for functions + */ + virtual QCString trFunctionDocumentation() + { return "Функции Документация"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for variables + */ + virtual QCString trVariableDocumentation() + { return "Променливи Документация"; } + + /*! This is used in the documentation of a file/namespace/group before + * the list of links to documented compounds + */ + virtual QCString trCompounds() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Структури от данни"; + } + else + { + return "Класове"; + } + } + + /*! This is used in the standard footer of each page and indicates when + * the page was generated + */ + virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) + { + QCString result=(QCString)"Генерирано на "+date; + if (!projName.isEmpty()) result+=(QCString)" за "+projName; + result+=(QCString)" от"; + return result; + } + + /*! this text is put before a class diagram */ + virtual QCString trClassDiagram(const QCString &clName) + { + return (QCString)"Диаграма на наследяване за "+clName+":"; + } + + /*! this text is generated when the \\warning command is used. */ + virtual QCString trWarning() + { return "Предупреждение"; } + + /*! this text is generated when the \\version command is used. */ + virtual QCString trVersion() + { return "Версия"; } + + /*! this text is generated when the \\date command is used. */ + virtual QCString trDate() + { return "Дата"; } + + /*! this text is generated when the \\return command is used. */ + virtual QCString trReturns() + { return "Връща"; } + + /*! this text is generated when the \\sa command is used. */ + virtual QCString trSeeAlso() + { return "Виж също"; } + + /*! this text is generated when the \\param command is used. */ + virtual QCString trParameters() + { return "Аргументи"; } + + /*! this text is generated when the \\exception command is used. */ + virtual QCString trExceptions() + { return "Изключения"; } + + /*! this text is used in the title page of a LaTeX document. */ + virtual QCString trGeneratedBy() + { return "Генериран от"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990307 +////////////////////////////////////////////////////////////////////////// + + /*! used as the title of page containing all the index of all namespaces. */ + virtual QCString trNamespaceList() + { return "Именни пространства Списък "; } + + /*! used as an introduction to the namespace list */ + virtual QCString trNamespaceListDescription(bool extractAll) + { + QCString result="пълен списък с "; + if (!extractAll) result+="документирани "; + result+="именни пространства с кратко описание:"; + return result; + } + + /*! used in the class documentation as a header before the list of all + * friends of a class + */ + virtual QCString trFriends() + { return "Приятели"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990405 +////////////////////////////////////////////////////////////////////////// + + /*! used in the class documentation as a header before the list of all + * related classes + */ + virtual QCString trRelatedFunctionDocumentation() + { return "Приятели и Свързани функции Документация"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990425 +////////////////////////////////////////////////////////////////////////// + + /*! used as the title of the HTML page of a class/struct/union */ + virtual QCString trCompoundReference(const QCString &clName, + ClassDef::CompoundType compType, + bool isTemplate) + { + QCString result=(QCString)clName; + switch(compType) + { + case ClassDef::Class: result+=" Клас"; break; + case ClassDef::Struct: result+=" Структура"; break; + case ClassDef::Union: result+=" Обединение"; break; + case ClassDef::Interface: result+=" Интерфейс"; break; + case ClassDef::Protocol: result+=" Протокол"; break; + case ClassDef::Category: result+=" Категория"; break; + case ClassDef::Exception: result+=" Изключение"; break; + default: break; + } + if (isTemplate) result+=" Шаблон"; + result+=" Препратка"; + return result; + } + + /*! used as the title of the HTML page of a file */ + virtual QCString trFileReference(const QCString &fileName) + { + QCString result=fileName; + result+=" Файл Справка"; + return result; + } + + /*! used as the title of the HTML page of a namespace */ + virtual QCString trNamespaceReference(const QCString &namespaceName) + { + QCString result=namespaceName; + result+=" Именно пространството Справка"; + return result; + } + + virtual QCString trPublicMembers() + { return "Общодостъпни членове функции"; } + virtual QCString trPublicSlots() + { return "Общодостъпни слотове"; } + virtual QCString trSignals() + { return "Сигнали"; } + virtual QCString trStaticPublicMembers() + { return "Статични общодостъпни членове функции"; } + virtual QCString trProtectedMembers() + { return "Защитени членове функции"; } + virtual QCString trProtectedSlots() + { return "Защитени слотове"; } + virtual QCString trStaticProtectedMembers() + { return "Статични защитени членове функции"; } + virtual QCString trPrivateMembers() + { return "Частни членове функции"; } + virtual QCString trPrivateSlots() + { return "Частни слотове"; } + virtual QCString trStaticPrivateMembers() + { return "Статични частни членове функции"; } + + /*! this function is used to produce a comma-separated list of items. + * use generateMarker(i) to indicate where item i should be put. + */ + virtual QCString trWriteList(int numEntries) + { + QCString result; + int i; + // the inherits list contain `numEntries' classes + for (i=0;i<numEntries;i++) + { + // use generateMarker to generate placeholders for the class links! + result+=generateMarker(i); // generate marker for entry i in the list + // (order is left to right) + + if (i!=numEntries-1) // not the last entry, so we need a separator + { + if (i<numEntries-2) // not the fore last entry + result+=", "; + else // the fore last entry + result+=", и "; + } + } + return result; + } + + /*! used in class documentation to produce a list of base classes, + * if class diagrams are disabled. + */ + virtual QCString trInheritsList(int numEntries) + { + return "Базови класове "+trWriteList(numEntries)+"."; + } + + /*! used in class documentation to produce a list of super classes, + * if class diagrams are disabled. + */ + virtual QCString trInheritedByList(int numEntries) + { + return "Производни класове "+trWriteList(numEntries)+"."; + } + + /*! used in member documentation blocks to produce a list of + * members that are hidden by this one. + */ + virtual QCString trReimplementedFromList(int numEntries) + { + return "Заменя наследеният метод "+trWriteList(numEntries)+"."; + } + + /*! used in member documentation blocks to produce a list of + * all member that overwrite the implementation of this member. + */ + virtual QCString trReimplementedInList(int numEntries) + { + return "Заменя в "+trWriteList(numEntries)+"."; + } + + /*! This is put above each page as a link to all members of namespaces. */ + virtual QCString trNamespaceMembers() + { return "Членове Именни пространства"; + } + + /*! This is an introduction to the page with all namespace members */ + virtual QCString trNamespaceMemberDescription(bool extractAll) + { + QCString result="Пълен списък с "; + if (!extractAll) result+="документирани "; + result+="членове именни пространства с връзки към "; + if (extractAll) + result+="документация за именно пространство за всеки член:"; + else + result+="именните пространства към които принадлежат:"; + return result; + } + /*! This is used in LaTeX as the title of the chapter with the + * index of all namespaces. + */ + virtual QCString trNamespaceIndex() + { return "Именни пространства Указател"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all namespaces. + */ + virtual QCString trNamespaceDocumentation() + { return "Именни пространства Документация"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990522 +////////////////////////////////////////////////////////////////////////// + + /*! This is used in the documentation before the list of all + * namespaces in a file. + */ + virtual QCString trNamespaces() + { return "Именни пространства"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990728 +////////////////////////////////////////////////////////////////////////// + + /*! This is put at the bottom of a class documentation page and is + * followed by a list of files that were used to generate the page. + */ + virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, + bool single) + { // single is true implies a single file + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result=(QCString)"Документация за "; + switch(compType) + { + case ClassDef::Class: result+=vhdlOpt?"проектна единица":"клас"; break; + case ClassDef::Struct: result+="структура"; break; + case ClassDef::Union: result+="обединение"; break; + case ClassDef::Interface: result+="интерфейс"; break; + case ClassDef::Protocol: result+="протокол"; break; + case ClassDef::Category: result+="категория"; break; + case ClassDef::Exception: result+="изключение"; break; + default: break; + } + result+=" генериран от "; + if (single) result+="следният файл:"; else result+="следните файлове:"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990901 +////////////////////////////////////////////////////////////////////////// + + /*! This is used as the heading text for the retval command. */ + virtual QCString trReturnValues() + { return "Връщана стойност"; } + + /*! This is in the (quick) index as a link to the main page (index.html) + */ + virtual QCString trMainPage() + { return "Главна страница"; } + + /*! This is used in references to page that are put in the LaTeX + * documentation. It should be an abbreviation of the word page. + */ + virtual QCString trPageAbbreviation() + { return "стр."; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-991003 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trDefinedAtLineInSourceFile() + { + return "Виж дефиницията във файла @1 ред @0."; + } + virtual QCString trDefinedInSourceFile() + { + return "Виж дефиницията във файла @0."; + } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-991205 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trDeprecated() + { + return "Остарело"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.0.0 +////////////////////////////////////////////////////////////////////////// + + /*! this text is put before a collaboration diagram */ + virtual QCString trCollaborationDiagram(const QCString &clName) + { + return (QCString)"Граф на зависимости за класа "+clName+":"; + } + /*! this text is put before an include dependency graph */ + virtual QCString trInclDepGraph(const QCString &fName) + { + return (QCString)"Граф на включените заглавни файлове за "+fName+":"; + } + /*! header that is put before the list of constructor/destructors. */ + virtual QCString trConstructorDocumentation() + { + return "Конструктор & Деструктор Документация"; + } + /*! Used in the file documentation to point to the corresponding sources. */ + virtual QCString trGotoSourceCode() + { + return "Вижте изходният код на този файл."; + } + /*! Used in the file sources to point to the corresponding documentation. */ + virtual QCString trGotoDocumentation() + { + return "Вижте документацията за този файл."; + } + /*! Text for the \\pre command */ + virtual QCString trPrecondition() + { + return "Предпоставка"; + } + /*! Text for the \\post command */ + virtual QCString trPostcondition() + { + return "Следусловие"; + } + /*! Text for the \\invariant command */ + virtual QCString trInvariant() + { + return "Инвариант"; + } + /*! Text shown before a multi-line variable/enum initialization */ + virtual QCString trInitialValue() + { + return "Първоначална стойност:"; + } + /*! Text used the source code in the file index */ + virtual QCString trCode() + { + return "изходен код"; + } + virtual QCString trGraphicalHierarchy() + { + return "Йерархия на класовете Графичен вид"; + } + virtual QCString trGotoGraphicalHierarchy() + { + return "Виж графичен вид на йерархията на класовете"; + } + virtual QCString trGotoTextualHierarchy() + { + return "Виж текстови вид на йерархията на класовете"; + } + virtual QCString trPageIndex() + { + return "Тематични описания Указател"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.0 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trNote() + { + return "Пояснение"; + } + virtual QCString trPublicTypes() + { + return "Общодостъпни типове"; + } + virtual QCString trPublicAttribs() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Полета данни"; + } + else + { + return "Общодостъпни атрибути"; + } + } + virtual QCString trStaticPublicAttribs() + { + return "Статични общодостъпни атрибути"; + } + virtual QCString trProtectedTypes() + { + return "Защитени типове"; + } + virtual QCString trProtectedAttribs() + { + return "Защитени атрибути"; + } + virtual QCString trStaticProtectedAttribs() + { + return "Статични защитени атрибути"; + } + virtual QCString trPrivateTypes() + { + return "Частни типове"; + } + virtual QCString trPrivateAttribs() + { + return "Частни атрибути"; + } + virtual QCString trStaticPrivateAttribs() + { + return "Статични частни атрибути"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.3 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a marker that is put before a \\todo item */ + virtual QCString trTodo() + { + return "Елементи на списъка със задачи"; + } + /*! Used as the header of the todo list */ + virtual QCString trTodoList() + { + return "Списък със задачи за обсъждане свързани с подобренията"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.4 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trReferencedBy() + { + return "Използва се"; + } + virtual QCString trRemarks() + { + return "Забележки"; + } + virtual QCString trAttention() + { + return "Внимание"; + } + virtual QCString trInclByDepGraph() + { + return "Граф на файлове показващ, кой файлове включват " + "явно или косвено този файл:"; + } + virtual QCString trSince() + { + return "От"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.5 +////////////////////////////////////////////////////////////////////////// + + /*! title of the graph legend page */ + virtual QCString trLegendTitle() + { + return "Графична легенда"; + } + /*! page explaining how the dot graph's should be interpreted + * The %A in the text below are to prevent link to classes called "A". + */ + virtual QCString trLegendDocs() + { + return + "Тази страница обяснява как да интерпретирате графиките, генерирани " + "от doxygen.<p>\n" + "Разгледайте следният пример:\n" + "\\code\n" + "/*! Невидим клас поради съкращаване */\n" + "class Invisible { };\n\n" + "/*! Съкратен клас, наследствена връзка е скрита */\n" + "class Truncated : public Invisible { };\n\n" + "/* Класът не е документиран с doxygen коментари */\n" + "class Undocumented { };\n\n" + "/*! Клас, който се наследява чрез публично наследяване */\n" + "class PublicBase : public Truncated { };\n\n" + "/*! Шаблонен клас */\n" + "template<class T> class Templ { };\n\n" + "/*! Клас, който се наследява чрез защитено наследяване */\n" + "class ProtectedBase { };\n\n" + "/*! Клас, който се наследява чрез частно наследяване */\n" + "class PrivateBase { };\n\n" + "/*! Клас, използващ наследеният клас */\n" + "class Used { };\n\n" + "/*! Супер клас, който наследява редица други класове */\n" + "class Inherited : public PublicBase,\n" + " protected ProtectedBase,\n" + " private PrivateBase,\n" + " public Undocumented,\n" + " public Templ<int>\n" + "{\n" + " private:\n" + " Used *m_usedClass;\n" + "};\n" + "\\endcode\n" + "Правоъгълниците в този граф имат следното значение:" + "<p><center><img alt=\"\" src=\"graph_legend."+getDotImageExtension()+"\"></center></p>\n" + "<p>\n" + "Правоъгълниците в този граф имат следното значение:\n" + "</p>\n" + "<ul>\n" + "<li>%Запълненият сиво правоъгълник представлява структурата или клас, " + "за който е създаден графа.</li>\n" + "<li>%Правоъгълника с черна рамка обозначава документирана структура или клас.</li>\n" + "<li>%Правоъгълника със сива рамка обозначава недокументирана структура или клас.</li>\n" + "<li>%Правоъгълника с червена рамка обозначава документирана структура или клас за" + "който не са показани всички отношения наследяване/съдържание. %A Графa e" + "съкратен, ако не се вписва в определените граници.</li>\n" + "</ul>\n" + "<p>\n" + "Стрелките имат следното значение:\n" + "</p>\n" + "<ul>\n" + "<li>%Тъмносиня стрелка се използва за визуализиране на публично наследство " + "между два класа.</li>\n" + "<li>%Тъмнозелена стрелка се използва за защитено наследяване.</li>\n" + "<li>%Тъмночервена стрелка се използва за частно наследяване.</li>\n" + "<li>%Лилава пунктирана стрелка се използва, ако клас се съдържа или използва " + "от друг клас. Стрелката указва променлива(и) " + "чрез който е достъпен посоченият клас или структура.</li>\n" + "<li>%Жълта пунктирана стрелка обозначава връзка между екземпляр на шаблон и " + "класът шаблон, от който е създаден. Стрелката указва " + "параметрите на шаблона на екземпляра.</li>\n" + "</ul>\n"; + } + /*! text for the link to the legend page */ + virtual QCString trLegend() + { + return "легенда"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.0 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a marker that is put before a test item */ + virtual QCString trTest() + { + return "Тест"; + } + /*! Used as the header of the test list */ + virtual QCString trTestList() + { + return "Тестове Списък"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.2 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a section header for IDL properties */ + virtual QCString trProperties() + { + return "Свойства"; + } + /*! Used as a section header for IDL property documentation */ + virtual QCString trPropertyDocumentation() + { + return "Свойство Документация"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.4 +////////////////////////////////////////////////////////////////////////// + + /*! Used for Java classes in the summary section of Java packages */ + virtual QCString trClasses() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Структури от данни"; + } + else + { + return "Класове"; + } + } + /*! Used as the title of a Java package */ + virtual QCString trPackage(const QCString &name) + { + return (QCString)"Пакет "+name; + } + /*! The description of the package index page */ + virtual QCString trPackageListDescription() + { + return "Списък на пакетите с кратки описания(ако има такива):"; + } + /*! The link name in the Quick links header for each page */ + virtual QCString trPackages() + { + return "Пакети"; + } + /*! Text shown before a multi-line define */ + virtual QCString trDefineValue() + { + return "Макроопределение:"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.5 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a marker that is put before a \\bug item */ + virtual QCString trBug() + { + return "Бъг"; + } + /*! Used as the header of the bug list */ + virtual QCString trBugList() + { + return "Бъгове Списък"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.6 +////////////////////////////////////////////////////////////////////////// + + /*! Used as ansicpg for RTF file + * + * The following table shows the correlation of Charset name, Charset Value and + * Codepage number: + * <pre> + * Charset Name Charset Value(hex) Codepage number + * ------------------------------------------------------ + * DEFAULT_CHARSET 1 (x01) + * SYMBOL_CHARSET 2 (x02) + * OEM_CHARSET 255 (xFF) + * ANSI_CHARSET 0 (x00) 1252 + * RUSSIAN_CHARSET 204 (xCC) 1251 + * EE_CHARSET 238 (xEE) 1250 + * GREEK_CHARSET 161 (xA1) 1253 + * TURKISH_CHARSET 162 (xA2) 1254 + * BALTIC_CHARSET 186 (xBA) 1257 + * HEBREW_CHARSET 177 (xB1) 1255 + * ARABIC _CHARSET 178 (xB2) 1256 + * SHIFTJIS_CHARSET 128 (x80) 932 + * HANGEUL_CHARSET 129 (x81) 949 + * GB2313_CHARSET 134 (x86) 936 + * CHINESEBIG5_CHARSET 136 (x88) 950 + * </pre> + * + */ + virtual QCString trRTFansicp() + { + return "1251"; + } + + + /*! Used as ansicpg for RTF fcharset + * \see trRTFansicp() for a table of possible values. + */ + virtual QCString trRTFCharSet() + { + return "204"; + } + + /*! Used as header RTF general index */ + virtual QCString trRTFGeneralIndex() + { + return "Азбучен указател"; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trClass(bool first_capital, bool singular) + { + QCString result((first_capital ? "Клас" : "клас")); + if (!singular) result+="ове"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trFile(bool first_capital, bool singular) + { + QCString result((first_capital ? "Файл" : "файл")); + if (!singular) result+="ове"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trNamespace(bool first_capital, bool singular) + { + QCString result((first_capital ? "Именн" : "именн")); + result+=(singular ? "о пространство" : "и пространства"); + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trGroup(bool first_capital, bool singular) + { + QCString result((first_capital ? "Груп" : "груп")); + result+=(singular ? "а" : "и"); + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trPage(bool first_capital, bool singular) + { + QCString result((first_capital ? "Страниц" : "странц")); + result+=(singular ? "а" : "и"); + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trMember(bool first_capital, bool singular) + { + QCString result((first_capital ? "Член" : "член")); + if (!singular) result+="ове"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trGlobal(bool first_capital, bool singular) + { + QCString result((first_capital ? "Глобалн" : "глобалн")); + result+=(singular ? "а" : "и"); + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.7 +////////////////////////////////////////////////////////////////////////// + + /*! This text is generated when the \\author command is used and + * for the author section in man pages. */ + virtual QCString trAuthor(bool first_capital, bool singular) + { + QCString result((first_capital ? "Автор" : "автор")); + if (!singular) result+="и"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.11 +////////////////////////////////////////////////////////////////////////// + + /*! This text is put before the list of members referenced by a member + */ + virtual QCString trReferences() + { + return "Кръстосани препратки"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.13 +////////////////////////////////////////////////////////////////////////// + + /*! used in member documentation blocks to produce a list of + * members that are implemented by this one. + */ + virtual QCString trImplementedFromList(int numEntries) + { + return "Заменя "+trWriteList(numEntries)+"."; + } + + /*! used in member documentation blocks to produce a list of + * all members that implement this abstract member. + */ + virtual QCString trImplementedInList(int numEntries) + { + return "Заменя в "+trWriteList(numEntries)+"."; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.16 +////////////////////////////////////////////////////////////////////////// + + /*! used in RTF documentation as a heading for the Table + * of Contents. + */ + virtual QCString trRTFTableOfContents() + { + return "Съдържание"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return "Остарели дефиниции и декларации Списък"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.18 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a header for declaration section of the events found in + * a C# program + */ + virtual QCString trEvents() + { + return "Събития"; + } + /*! Header used for the documentation section of a class' events. */ + virtual QCString trEventDocumentation() + { + return "Събития Документация"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a heading for a list of Java class types with package scope. + */ + virtual QCString trPackageTypes() + { + return "Типове с област на видимост пакет"; + } + /*! Used as a heading for a list of Java class functions with package + * scope. + */ + virtual QCString trPackageFunctions() + { + return "Функции с област на видимост пакет"; + } + virtual QCString trPackageMembers() + { + return "Членове с област на видимост пакет"; + } + /*! Used as a heading for a list of static Java class functions with + * package scope. + */ + virtual QCString trStaticPackageFunctions() + { + return "Статични функции с област на видимост пакет"; + } + /*! Used as a heading for a list of Java class variables with package + * scope. + */ + virtual QCString trPackageAttribs() + { + return "Променливи с област на видимост пакет"; + } + /*! Used as a heading for a list of static Java class variables with + * package scope. + */ + virtual QCString trStaticPackageAttribs() + { + return "Статични променливи с област на видимост пакет"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.1 +////////////////////////////////////////////////////////////////////////// + + /*! Used in the quick index of a class/file/namespace member list page + * to link to the unfiltered list of all members. + */ + virtual QCString trAll() + { + return "Указател към не филтриран списък на всички членове"; + } + /*! Put in front of the call graph for a function. */ + virtual QCString trCallGraph() + { + return "Граф с извикванията за тази функция:"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.3 +////////////////////////////////////////////////////////////////////////// + + /*! This string is used as the title for the page listing the search + * results. + */ + virtual QCString trSearchResultsTitle() + { + return "Резултати от търсенето"; + } + /*! This string is put just before listing the search results. The + * text can be different depending on the number of documents found. + * Inside the text you can put the special marker $num to insert + * the number representing the actual number of search results. + * The @a numDocuments parameter can be either 0, 1 or 2, where the + * value 2 represents 2 or more matches. HTML markup is allowed inside + * the returned string. + */ + virtual QCString trSearchResults(int numDocuments) + { + if (numDocuments==0) + { + return "За съжаление няма документи, отговарящи на вашата заявка."; + } + else if (numDocuments==1) + { + return "Намерен е <b>1</b> документ, съответстващ на вашата заявка."; + } + else + { + return "Намерени са <b>$num</b> документи, съответстващи на вашата заявка. " + "Първо се показват най-добрите съвпадения."; + } + } + /*! This string is put before the list of matched words, for each search + * result. What follows is the list of words that matched the query. + */ + virtual QCString trSearchMatches() + { + return "Намерено:"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.8 +////////////////////////////////////////////////////////////////////////// + + /*! This is used in HTML as the title of page with source code for file filename + */ + virtual QCString trSourceFile(QCString& filename) + { + return filename + " Изходен файл"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.9 +////////////////////////////////////////////////////////////////////////// + + /*! This is used as the name of the chapter containing the directory + * hierarchy. + */ + virtual QCString trDirIndex() + { return "Директории Йерархия"; } + + /*! This is used as the name of the chapter containing the documentation + * of the directories. + */ + virtual QCString trDirDocumentation() + { return "Директории Документация"; } + + /*! This is used as the title of the directory index and also in the + * Quick links of an HTML page, to link to the directory hierarchy. + */ + virtual QCString trDirectories() + { return "Директории"; } + + /*! This returns the title of a directory page. The name of the + * directory is passed via \a dirName. + */ + virtual QCString trDirReference(const QCString &dirName) + { QCString result=dirName; result+=" Директория Съдържание"; return result; } + + /*! This returns the word directory with or without starting capital + * (\a first_capital) and in singular or plural form (\a singular). + */ + virtual QCString trDir(bool first_capital, bool singular) + { + QCString result((first_capital ? "Директори" : "директори")); + if (singular) result+="я"; else result+="и"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.1 +////////////////////////////////////////////////////////////////////////// + + /*! This text is added to the documentation when the \\overload command + * is used for a overloaded function. + */ + virtual QCString trOverloadText() + { + return "Това е преопределена член функция, " + "предоставена за удобство. Различава се от спомената по горе " + "функция само по броя на фактическите аргументи."; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.6 +////////////////////////////////////////////////////////////////////////// + + /*! This is used to introduce a caller (or called-by) graph */ + virtual QCString trCallerGraph() + { + return "Граф на извикванията за тази функция:"; + } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration values + */ + virtual QCString trEnumerationValueDocumentation() + { return "Изброяване Документация"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.5.4 (mainly for Fortran) +////////////////////////////////////////////////////////////////////////// + + /*! header that is put before the list of member subprograms (Fortran). */ + virtual QCString trMemberFunctionDocumentationFortran() + { return "Функции/подпрограми Документация"; } + + /*! This is put above each page as a link to the list of annotated data types (Fortran). */ + virtual QCString trCompoundListFortran() + { return "Типове данни Списък"; } + + /*! This is put above each page as a link to all members of compounds (Fortran). */ + virtual QCString trCompoundMembersFortran() + { return "Полета данни"; } + + /*! This is an introduction to the annotated compound list (Fortran). */ + virtual QCString trCompoundListDescriptionFortran() + { return "Анотиран списък от типовете данни с кратки описания:"; } + + /*! This is an introduction to the page with all data types (Fortran). */ + virtual QCString trCompoundMembersDescriptionFortran(bool extractAll) + { + QCString result="Списък на всички "; + if (!extractAll) + { + result+="документирани "; + } + result+="членове типове данни"; + result+=" с препратки към "; + if (!extractAll) + { + result+="документацията за структура от данни за всеки член"; + } + else + { + result+="типовете данни, към които принадлежат:"; + } + return result; + } + + /*! This is used in LaTeX as the title of the chapter with the + * annotated compound index (Fortran). + */ + virtual QCString trCompoundIndexFortran() + { return "Типове данни Указател"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all data types (Fortran). + */ + virtual QCString trTypeDocumentation() + { return "Типове данни Документация"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) subprograms (Fortran). + */ + virtual QCString trSubprograms() + { return "Функции/Подпрограми"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for subprograms (Fortran) + */ + virtual QCString trSubprogramDocumentation() + { return "Функции/Подпрограми Документация"; } + + /*! This is used in the documentation of a file/namespace/group before + * the list of links to documented compounds (Fortran) + */ + virtual QCString trDataTypes() + { return "Типове данни"; } + + /*! used as the title of page containing all the index of all modules (Fortran). */ + virtual QCString trModulesList() + { return "Модули Списък"; } + + /*! used as an introduction to the modules list (Fortran) */ + virtual QCString trModulesListDescription(bool extractAll) + { + QCString result="Списък на всички "; + if (!extractAll) result+="документирани "; + result+="модули с кратко описание:"; + return result; + } + + /*! used as the title of the HTML page of a module/type (Fortran) */ + virtual QCString trCompoundReferenceFortran(const QCString &clName, + ClassDef::CompoundType compType, + bool isTemplate) + { + QCString result=(QCString)clName; + switch(compType) + { + case ClassDef::Class: result+=" Модул"; break; + case ClassDef::Struct: result+=" Тип"; break; + case ClassDef::Union: result+=" Обединение"; break; + case ClassDef::Interface: result+=" Интерфейс"; break; + case ClassDef::Protocol: result+=" Протокол"; break; + case ClassDef::Category: result+=" Категория"; break; + case ClassDef::Exception: result+=" Изключение"; break; + default: break; + } + if (isTemplate) result+=" Шаблон"; + result+=" Отнася се"; + return result; + } + /*! used as the title of the HTML page of a module (Fortran) */ + virtual QCString trModuleReference(const QCString &namespaceName) + { + QCString result=namespaceName; + result+=" Модул Справка"; + return result; + } + + /*! This is put above each page as a link to all members of modules. (Fortran) */ + virtual QCString trModulesMembers() + { return "Модул Членове"; } + + /*! This is an introduction to the page with all modules members (Fortran) */ + virtual QCString trModulesMemberDescription(bool extractAll) + { + QCString result="Списък на всички "; + if (!extractAll) result+="документирани "; + result+="членове на модула с връзки към "; + if (extractAll) + { + result+="документацията на модула за всеки член:"; + } + else + { + result+="модулите, към които принадлежат:"; + } + return result; + } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all modules (Fortran). + */ + virtual QCString trModulesIndex() + { return "Модули Указател"; } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trModule(bool first_capital, bool singular) + { + QCString result((first_capital ? "Модул" : "модул")); + if (!singular) result+="и"; + return result; + } + + /*! This is put at the bottom of a module documentation page and is + * followed by a list of files that were used to generate the page. + */ + virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, + bool single) + { + // single is true implies a single file + QCString result=(QCString)"Документацията за "; + switch(compType) + { + case ClassDef::Class: result+="модул"; break; + case ClassDef::Struct: result+="тип"; break; + case ClassDef::Union: result+="обединение"; break; + case ClassDef::Interface: result+="интерфейс"; break; + case ClassDef::Protocol: result+="протокол"; break; + case ClassDef::Category: result+="категория"; break; + case ClassDef::Exception: result+="изключение"; break; + default: break; + } + result+=" беше генериран "; + if (single) result+="от следният файл:"; else result+="от следните файлове:"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trType(bool first_capital, bool singular) + { + QCString result((first_capital ? "Тип" : "тип")); + if (!singular) result+="ове"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trSubprogram(bool first_capital, bool singular) + { + QCString result((first_capital ? "Подпрограм" : "подпрограм")); + if (singular) result+="а:"; else result+="и:"; + return result; + } + + /*! C# Type Constraint list */ + virtual QCString trTypeConstraints() + { + return "Съвместими типове"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.6.0 (mainly for the new search engine) +////////////////////////////////////////////////////////////////////////// + + /*! directory relation for \a name */ + virtual QCString trDirRelation(const QCString &name) + { + return QCString(name)+" Връзка"; + } + + /*! Loading message shown when loading search results */ + virtual QCString trLoading() + { + return "Зареждане..."; + } + + /*! Label used for search results in the global namespace */ + virtual QCString trGlobalNamespace() + { + return "Глобални именни пространства"; + } + + /*! Message shown while searching */ + virtual QCString trSearching() + { + return "Търсене..."; + } + + /*! Text shown when no search results are found */ + virtual QCString trNoMatches() + { + return "Не намерено"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.6.3 (missing items for the directory pages) +////////////////////////////////////////////////////////////////////////// + + /*! when clicking a directory dependency label, a page with a + * table is shown. The heading for the first column mentions the + * source file that has a relation to another file. + */ + virtual QCString trFileIn(const QCString &name) + { + return (QCString)"Файл в "+name; + } + + /*! when clicking a directory dependency label, a page with a + * table is shown. The heading for the second column mentions the + * destination file that is included. + */ + virtual QCString trIncludesFileIn(const QCString &name) + { + return (QCString)"Включва файла в "+name; + } + + /** Compiles a date string. + * @param year Year in 4 digits + * @param month Month of the year: 1=January + * @param day Day of the Month: 1..31 + * @param dayOfWeek Day of the week: 1=Monday..7=Sunday + * @param hour Hour of the day: 0..23 + * @param minutes Minutes in the hour: 0..59 + * @param seconds Seconds within the minute: 0..59 + * @param includeTime Include time in the result string? + */ + virtual QCString trDateTime(int year,int month,int day,int dayOfWeek, + int hour,int minutes,int seconds, + bool includeTime) + { + static const char *days[] = { "Пн","Вт","Ср","Чт","Пт","Сб","Нд" }; + static const char *months[] = { "Яну","Фев","Мар","Апр","Май","Юни","Юли","Авг","Сеп","Окт","Ное","Дек" }; + QCString sdate; + sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year); + if (includeTime) + { + QCString stime; + stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds); + sdate+=stime; + } + return sdate; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.7.5 +////////////////////////////////////////////////////////////////////////// + + /*! Header for the page with bibliographic citations */ + virtual QCString trCiteReferences() + { return "Библиография"; } + + /*! Text for copyright paragraph */ + virtual QCString trCopyright() + { return "Авторско право"; } + + /*! Header for the graph showing the directory dependencies */ + virtual QCString trDirDepGraph(const QCString &name) + { return QCString("Граф на зависимостта на директория за ")+name+":"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.0 +////////////////////////////////////////////////////////////////////////// + + /*! Detail level selector shown for hierarchical indices */ + virtual QCString trDetailLevel() + { return "ниво на детайлност"; } + + /*! Section header for list of template parameters */ + virtual QCString trTemplateParameters() + { return "Шаблона Параметри"; } + + /*! Used in dot graph when UML_LOOK is enabled and there are many fields */ + virtual QCString trAndMore(const QCString &number) + { return "и "+number+" повече..."; } + + /*! Used file list for a Java enum */ + virtual QCString trEnumGeneratedFromFiles(bool single) + { QCString result = "Документацията за това изброяване е генерирана от "; + if (single) result+="следният файл:"; else result+="следните файлове:"; + result+=":"; + return result; + } + + /*! Header of a Java enum page (Java enums are represented as classes). */ + virtual QCString trEnumReference(const QCString &name) + { return QCString(name)+" Изброяване Справка"; } + + /*! Used for a section containing inherited members */ + virtual QCString trInheritedFrom(const QCString &members,const QCString &what) + { return QCString(members)+" наследен от "+what; } + + /*! Header of the sections with inherited members specific for the + * base class(es) + */ + virtual QCString trAdditionalInheritedMembers() + { return "Допълнителни наследени членове"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.2 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a tooltip for the toggle button that appears in the + * navigation tree in the HTML output when GENERATE_TREEVIEW is + * enabled. This tooltip explains the meaning of the button. + */ + virtual QCString trPanelSynchronisationTooltip(bool enable) + { + QCString opt = enable ? "включване" : "изключване"; + return "натиснете на "+opt+" за синхронизация на панела"; + } + + /*! Used in a method of an Objective-C class that is declared in a + * a category. Note that the @1 marker is required and is replaced + * by a link. + */ + virtual QCString trProvidedByCategory() + { + return "По групи @0."; + } + + /*! Used in a method of an Objective-C category that extends a class. + * Note that the @1 marker is required and is replaced by a link to + * the class method. + */ + virtual QCString trExtendsClass() + { + return "Разширява класа @0."; + } + + /*! Used as the header of a list of class methods in Objective-C. + * These are similar to static public member functions in C++. + */ + virtual QCString trClassMethods() + { + return "Клас Методи"; + } + + /*! Used as the header of a list of instance methods in Objective-C. + * These are similar to public member functions in C++. + */ + virtual QCString trInstanceMethods() + { + return "Общодостъпни Методи"; + } + + /*! Used as the header of the member functions of an Objective-C class. + */ + virtual QCString trMethodDocumentation() + { + return "Метод Документация"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.4 +////////////////////////////////////////////////////////////////////////// + + /** old style UNO IDL services: implemented interfaces */ + virtual QCString trInterfaces() + { return "Експортирани интерфейси"; } + + /** old style UNO IDL services: inherited services */ + virtual QCString trServices() + { return "Включени услуги"; } + + /** UNO IDL constant groups */ + virtual QCString trConstantGroups() + { return "Постоянни групи"; } + + /** UNO IDL constant groups */ + virtual QCString trConstantGroupReference(const QCString &namespaceName) + { + QCString result=namespaceName; + result+=" Постоянни групи Справка"; + return result; + } + /** UNO IDL service page title */ + virtual QCString trServiceReference(const QCString &sName) + { + QCString result=(QCString)sName; + result+=" Сървис Справка"; + return result; + } + /** UNO IDL singleton page title */ + virtual QCString trSingletonReference(const QCString &sName) + { + QCString result=(QCString)sName; + result+=" Конкретика Справка"; + return result; + } + /** UNO IDL service page */ + virtual QCString trServiceGeneratedFromFiles(bool single) + { + // single is true implies a single file + QCString result=(QCString)"Документацията за този сървис " + "беше генерирано от "; + if (single) result+="следният файл:"; else result+="следните файлове:"; + return result; + } + /** UNO IDL singleton page */ + virtual QCString trSingletonGeneratedFromFiles(bool single) + { + // single is true implies a single file + QCString result=(QCString)"Документацията за тази конкретика " + "беше генерирано от "; + if (single) result+="следният файл:"; else result+="следните файлове:"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Проектни единици Йерархия"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Проектни единици Списък"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Проектна единица Членове"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Here is a list of all design unit members with links to " + "the Entities they belong to:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Проектна единица Указател"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Проектни единици"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Функции/Процедури/Процеси"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Библиотека"; + else return "Библиотеки"; + case VhdlDocGen::PACKAGE: + if (single) return "Пакет"; + else return "Пакети"; + case VhdlDocGen::SIGNAL: + if (single) return "Сигнал"; + else return "Сигнали"; + case VhdlDocGen::COMPONENT: + if (single) return "Компонент"; + else return "Компоненти"; + case VhdlDocGen::CONSTANT: + if (single) return "Константа"; + else return "Константи"; + case VhdlDocGen::ENTITY: + if (single) return "Същност"; + else return "Същности"; + case VhdlDocGen::TYPE: + if (single) return "Тип"; + else return "Типове"; + case VhdlDocGen::SUBTYPE: + if (single) return "Подтип"; + else return "Подтипове"; + case VhdlDocGen::FUNCTION: + if (single) return "Функция"; + else return "Функции"; + case VhdlDocGen::RECORD: + if (single) return "Запис"; + else return "Записи"; + case VhdlDocGen::PROCEDURE: + if (single) return "Процедура"; + else return "Процедури"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Архитектура"; + else return "Архитектури"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Атрибут"; + else return "Атрибути"; + case VhdlDocGen::PROCESS: + if (single) return "Процес"; + else return "Процеси"; + case VhdlDocGen::PORT: + if (single) return "Порт"; + else return "Портове"; + case VhdlDocGen::USE: + if (single) return "use клауза"; + else return "Use клаузи"; + case VhdlDocGen::GENERIC: + if (single) return "Роден"; + else return "Родни"; + case VhdlDocGen::PACKAGE_BODY: + return "Тяло на пакета"; + case VhdlDocGen::UNITS: + return "Единици"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Споделена променлива"; + else return "Споделени променливи"; + case VhdlDocGen::VFILE: + if (single) return "Файл"; + else return "Файлове"; + case VhdlDocGen::GROUP: + if (single) return "Група"; + else return "Групи"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Инстанция"; + else return "Инстанции"; + case VhdlDocGen::ALIAS: + if (single) return "Псевдоним"; + else return "Псевдоними"; + case VhdlDocGen::CONFIG: + if (single) return "Конфигурация"; + else return "Конфигурации"; + case VhdlDocGen::MISCELLANEOUS: + return "Други"; + case VhdlDocGen::UCF_CONST: + return "Ограничения"; + default: + return "Клас"; + } + } + virtual QCString trCustomReference(const QCString &name) + { return QCString(name)+" Отнася се"; } + + /* Slice */ + virtual QCString trConstants() + { + return "Константи"; + } + virtual QCString trConstantDocumentation() + { + return "Константи Документация"; + } + virtual QCString trSequences() + { + return "Последователности"; + } + virtual QCString trSequenceDocumentation() + { + return "Последователности Документация"; + } + virtual QCString trDictionaries() + { + return "Речници"; + } + virtual QCString trDictionaryDocumentation() + { + return "Речници Документация"; + } + virtual QCString trSliceInterfaces() + { + return "Интерфейси"; + } + virtual QCString trInterfaceIndex() + { + return "Интерфейси Указател"; + } + virtual QCString trInterfaceList() + { + return "Интерфейси списък"; + } + virtual QCString trInterfaceListDescription() + { + return "Интерфейсите с кратки описания:"; + } + virtual QCString trInterfaceHierarchy() + { + return "Интерфейси Йерархия"; + } + virtual QCString trInterfaceHierarchyDescription() + { + return "Този списък на наследяване е сортиран, но не напълно, по азбучен ред:"; + } + virtual QCString trInterfaceDocumentation() + { + return "Интерфейси Документация"; + } + virtual QCString trStructs() + { + return "Структури"; + } + virtual QCString trStructIndex() + { + return "Структури Указател"; + } + virtual QCString trStructList() + { + return "Структури Списък"; + } + virtual QCString trStructListDescription() + { + return "Структури с кратки описания:"; + } + virtual QCString trStructDocumentation() + { + return "Структури Документация"; + } + virtual QCString trExceptionIndex() + { + return "Изключения Указател"; + } + virtual QCString trExceptionList() + { + return "Изключения Списък"; + } + virtual QCString trExceptionListDescription() + { + return "Изключения с кратки описания:"; + } + virtual QCString trExceptionHierarchy() + { + return "Изключения Йерархия"; + } + virtual QCString trExceptionHierarchyDescription() + { + return "Този списък на наследяване е сортиран, но не напълно, по азбучен ред:"; + } + virtual QCString trExceptionDocumentation() + { + return "Изключения Документация"; + } + virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result=(QCString)clName; + if (isLocal) result+=" Локален"; + switch(compType) + { + case ClassDef::Class: result+=" Клас"; break; + case ClassDef::Struct: result+=" Структура"; break; + case ClassDef::Union: result+=" Обединение"; break; + case ClassDef::Interface: result+=" Интерфейс"; break; + case ClassDef::Protocol: result+=" Протокол"; break; + case ClassDef::Category: result+=" Категория"; break; + case ClassDef::Exception: result+=" Изключение"; break; + default: break; + } + result+=" Отнася се"; + return result; + } + virtual QCString trOperations() + { + return "Операции"; + } + virtual QCString trOperationDocumentation() + { + return "Операции Документация"; + } + virtual QCString trDataMembers() + { + return "Членове Данни"; + } + virtual QCString trDataMemberDocumentation() + { + return "Членове Данни Документация"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.19 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit documentation */ + virtual QCString trDesignUnitDocumentation() + { return "Проектни единици Документация"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.9.2 +////////////////////////////////////////////////////////////////////////// + + /** C++20 concept */ + virtual QCString trConcept(bool first_capital, bool singular) + { + QCString result((first_capital ? "Концепци" : "концепци")); + if (singular) result+="я"; else result+="и"; + return result; + } + /*! used as the title of the HTML page of a C++20 concept page */ + virtual QCString trConceptReference(const QCString &conceptName) + { + QCString result=conceptName; + result+=" Концепции Справка"; + return result; + } + + /*! used as the title of page containing all the index of all concepts. */ + virtual QCString trConceptList() + { return "Концепции Списък"; } + + /*! used as the title of chapter containing the index listing all concepts. */ + virtual QCString trConceptIndex() + { return "Концепции Указател"; } + + /*! used as the title of chapter containing all information about concepts. */ + virtual QCString trConceptDocumentation() + { return "Концепции Документация"; } + + /*! used as an introduction to the concept list */ + virtual QCString trConceptListDescription(bool extractAll) + { + QCString result="Списък на всички "; + if (!extractAll) result+="документирани "; + result+="концепции с кратко описание:"; + return result; + } + + /*! used to introduce the definition of the C++20 concept */ + virtual QCString trConceptDefinition() + { + return "Дефиниция на концепция"; + } +}; + +#endif diff --git a/src/translator_br.h b/src/translator_br.h index 6a86fad..2d7abcb 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -54,7 +54,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian : public Translator +class TranslatorBrazilian : public TranslatorAdapter_1_9_4 { public: @@ -94,6 +94,10 @@ class TranslatorBrazilian : public Translator { return "pt-BR"; } + virtual QCString getLanguageString() + { + return "0x416 Portuguese(Brazil)"; + } // --- Language translation methods ------------------- @@ -168,7 +172,7 @@ class TranslatorBrazilian : public Translator */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Gerado automaticamente por Doxygen"; - if (!s.isEmpty()) result+=(QCString)" para "+s; + if (!s.isEmpty()) result+=" para "+s; result+=" a partir do código-fonte."; return result; } @@ -420,6 +424,10 @@ class TranslatorBrazilian : public Translator { return "Estruturas"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Classes"; @@ -438,12 +446,6 @@ class TranslatorBrazilian : public Translator virtual QCString trExampleDocumentation() { return "Exemplos"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Documentação Relacionada"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Guia de Referência"; } @@ -534,22 +536,18 @@ class TranslatorBrazilian : public Translator */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Gerado em "+date; - if (!projName.isEmpty()) result+=(QCString)" para "+projName; - result+=(QCString)" por"; + QCString result="Gerado em "+date; + if (!projName.isEmpty()) result+=" para "+projName; + result+=" por"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagrama de hierarquia para "+clName+":"; + return "Diagrama de hierarquia para "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Apenas para uso interno."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Aviso"; } @@ -645,7 +643,7 @@ class TranslatorBrazilian : public Translator case ClassDef::Exception: result+="Exceção "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -810,8 +808,8 @@ class TranslatorBrazilian : public Translator bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"A documentação para "; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="A documentação para "; if (compType == ClassDef::Protocol) { result+= "esse "; @@ -887,12 +885,12 @@ class TranslatorBrazilian : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagrama de colaboração para "+clName+":"; + return "Diagrama de colaboração para "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Gráfico de dependência de inclusões para "+fName+":"; + return "Gráfico de dependência de inclusões para "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1175,12 +1173,7 @@ class TranslatorBrazilian : public Translator /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pacote "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista de Pacotes"; + return "Pacote "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1441,14 +1434,18 @@ class TranslatorBrazilian : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funções do Pacote"; } + virtual QCString trPackageMembers() + { + return "Membros do Pacote"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Funções Estáticas do Pacote"; } @@ -1560,12 +1557,6 @@ class TranslatorBrazilian : public Translator virtual QCString trDirectories() { return "Diretórios"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Esta Hierarquia de Diretórios está parcialmente ordenada (ordem alfabética)"; } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1702,7 +1693,7 @@ class TranslatorBrazilian : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result = (QCString)"Referência "; + QCString result = "Referência "; if (isTemplate) result+="do <em>Template</em> "; @@ -1774,7 +1765,7 @@ class TranslatorBrazilian : public Translator bool single) { // single is true implies a single file - QCString result=(QCString)"A documentação para "; + QCString result="A documentação para "; switch(compType) { case ClassDef::Class: result+="esse modulo "; break; @@ -1868,7 +1859,7 @@ class TranslatorBrazilian : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Arquivo em "+name; + return "Arquivo em "+name; } /*! when clicking a directory dependency label, a page with a @@ -1877,7 +1868,7 @@ class TranslatorBrazilian : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inclui arquivo em "+name; + return "Inclui arquivo em "+name; } /** Compiles a date string. @@ -2069,7 +2060,7 @@ class TranslatorBrazilian : public Translator virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"A documentação para esse serviço " + QCString result="A documentação para esse serviço " "foi gerada a partir "; if (single) { result+="do seguinte arquivo:"; @@ -2082,7 +2073,7 @@ class TranslatorBrazilian : public Translator virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"A documentação para esse <em>Singleton</em> " + QCString result="A documentação para esse <em>Singleton</em> " "foi gerada a partir "; if (single) { result+="do seguinte arquivo:"; @@ -2308,7 +2299,7 @@ class TranslatorBrazilian : public Translator } virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result=(QCString)"Referência "; + QCString result="Referência "; switch(compType) { case ClassDef::Class: result+="da Classe "; break; @@ -2349,7 +2340,7 @@ class TranslatorBrazilian : public Translator virtual QCString trDesignUnitDocumentation() { return "Documentação da Unidade de Projeto"; - } + } ////////////////////////////////////////////////////////////////////////// diff --git a/src/translator_ca.h b/src/translator_ca.h index 98f2ece..53dbffb 100644 --- a/src/translator_ca.h +++ b/src/translator_ca.h @@ -35,7 +35,7 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. @@ -79,6 +79,10 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 { return "ca"; } + virtual QCString getLanguageString() + { + return "0x403 Catalan"; + } // --- Language translation methods ------------------- @@ -144,7 +148,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generat automàticament per Doxygen"; - if (!s.isEmpty()) result+=(QCString)" per a "+s; + if (!s.isEmpty()) result+=" per a "+s; result+=" a partir del codi font."; return result; } @@ -392,6 +396,10 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 { return "Documentació de les Estructures de Dades"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Documentació de les Classes"; @@ -410,12 +418,6 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 virtual QCString trExampleDocumentation() { return "Documentació dels Exemples"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Documentació de les Pàgines"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Manual de Referència"; } @@ -506,22 +508,18 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generat a "+date; - if (!projName.isEmpty()) result+=(QCString)" per a "+projName; - result+=(QCString)" per"; + QCString result="Generat a "+date; + if (!projName.isEmpty()) result+=" per a "+projName; + result+=" per"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagrama d'Herència per a "+clName+":"; + return "Diagrama d'Herència per a "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Tan sols per a ús intern."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Atenció"; } @@ -609,7 +607,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 default: break; } if (isTemplate) result+="Template "; - result+=(QCString)clName; + result+=clName; return result; } @@ -756,7 +754,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"La documentació d'aquest"; + QCString result="La documentació d'aquest"; switch(compType) { case ClassDef::Class: result+="a classe"; break; @@ -825,12 +823,12 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagrama de col·laboració per a "+clName+":"; + return "Diagrama de col·laboració per a "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Inclou el graf de dependències per a "+fName+":"; + return "Inclou el graf de dependències per a "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1104,12 +1102,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paquet "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Llista de Paquets"; + return "Paquet "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1366,14 +1359,18 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funcions de Paquet"; } + virtual QCString trPackageMembers() + { + return "Membres de Paquet"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Funcions Estàtiques de Paquet"; } @@ -1485,14 +1482,6 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 virtual QCString trDirectories() { return "Directoris"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Aquesta jerarquia de directoris està ordenada toscament, " - "però no completa, de forma alfabètica:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1640,7 +1629,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 default: break; } if (isTemplate) result+="Template "; - result+=(QCString)clName; + result+=clName; return result; } @@ -1699,7 +1688,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"La documentació d'aquest"; + QCString result="La documentació d'aquest"; switch(compType) { case ClassDef::Class: result+=" mòdul"; break; @@ -1792,7 +1781,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Fitxer a "+name; + return "Fitxer a "+name; } /*! when clicking a directory dependency label, a page with a @@ -1801,7 +1790,7 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inclou fitxer a "+name; + return "Inclou fitxer a "+name; } /** Compiles a date string. diff --git a/src/translator_cn.h b/src/translator_cn.h index 2cc47e4..24aa3a1 100644 --- a/src/translator_cn.h +++ b/src/translator_cn.h @@ -24,7 +24,7 @@ */ #define CN_SPC " " -class TranslatorChinese : public Translator +class TranslatorChinese : public TranslatorAdapter_1_9_4 { public: /*! Used for identification of the language. The identification @@ -59,6 +59,10 @@ class TranslatorChinese : public Translator { return "zh"; } + virtual QCString getLanguageString() + { + return "0x804 Chinese (PRC)"; + } virtual QCString latexFontenc() { return ""; @@ -71,6 +75,10 @@ class TranslatorChinese : public Translator { return "\\end{CJK}\n"; } + virtual bool needsPunctuation() + { + return false; + } /*! used in the compound documentation before a list of related functions. */ @@ -138,7 +146,7 @@ class TranslatorChinese : public Translator virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result; result = "由" CN_SPC "Doyxgen" CN_SPC "通过分析" CN_SPC; - if (!s.isEmpty()) result += ((QCString)s+CN_SPC "的" CN_SPC); + if (!s.isEmpty()) result += (s+CN_SPC "的" CN_SPC); result+= "源代码自动生成."; return result; } @@ -329,6 +337,10 @@ class TranslatorChinese : public Translator { return "结构体说明"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "类说明"; } @@ -340,9 +352,6 @@ class TranslatorChinese : public Translator virtual QCString trExampleDocumentation() { return "示例说明"; } - virtual QCString trPageDocumentation() - { return "页面说明"; } - virtual QCString trReferenceManual() { return "参考手册"; } @@ -392,20 +401,17 @@ class TranslatorChinese : public Translator } virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) - { QCString result=(QCString)"生成于" CN_SPC+date; - if (!projName.isEmpty()) result+=(QCString)CN_SPC ", 为" CN_SPC+projName; - result+=(QCString)"使用" CN_SPC; + { QCString result="生成于" CN_SPC+date; + if (!projName.isEmpty()) result+=CN_SPC ", 为" CN_SPC+projName; + result+="使用" CN_SPC; return result; } virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"类" CN_SPC+clName+CN_SPC "继承关系图:"; + return "类" CN_SPC+clName+CN_SPC "继承关系图:"; } - virtual QCString trForInternalUseOnly() - { return "仅限内部使用."; } - virtual QCString trWarning() { return "警告"; } @@ -464,7 +470,7 @@ class TranslatorChinese : public Translator bool isTemplate) // used as the title of the HTML page of a class/struct/union { - QCString result=(QCString)clName; + QCString result=clName; if (isTemplate) result+=CN_SPC "模板"; switch(compType) { @@ -634,7 +640,7 @@ class TranslatorChinese : public Translator bool) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"该"; + QCString result="该"; switch(compType) { case ClassDef::Class: result+="类"; break; @@ -699,13 +705,13 @@ class TranslatorChinese : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)clName+CN_SPC "的协作图:"; + return clName+CN_SPC "的协作图:"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)fName+CN_SPC "的引用(Include)关系图:"; + return fName+CN_SPC "的引用(Include)关系图:"; } /*! header that is put before the list of constructor/destructors. */ @@ -1007,14 +1013,9 @@ class TranslatorChinese : public Translator /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"包" CN_SPC+name; + return "包" CN_SPC+name; } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "包列表"; - } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1302,15 +1303,19 @@ class TranslatorChinese : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "包函数"; } + virtual QCString trPackageMembers() + { + return "包成员"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "静态包函数"; } @@ -1430,14 +1435,6 @@ class TranslatorChinese : public Translator virtual QCString trDirectories() { return "目录"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { - return "此继承关系列表按字典顺序粗略的排序:" CN_SPC; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1578,7 +1575,7 @@ class TranslatorChinese : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=CN_SPC "模块"; break; @@ -1729,12 +1726,12 @@ class TranslatorChinese : public Translator virtual QCString trFileIn(const QCString &name) { - return (QCString)"文件在"+CN_SPC+name; + return QCString("文件在")+CN_SPC+name; } virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"在" CN_SPC+name+CN_SPC "中引用"; + return "在" CN_SPC+name+CN_SPC "中引用"; } virtual QCString trDateTime(int year,int month,int day,int dayOfWeek, @@ -1892,14 +1889,14 @@ class TranslatorChinese : public Translator /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+= CN_SPC "服务参考"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+= CN_SPC "单例参考"; return result; } @@ -2109,7 +2106,7 @@ class TranslatorChinese : public Translator } virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result=(QCString)clName; + QCString result=clName; if (isLocal) result+=" 局部"; switch(compType) { diff --git a/src/translator_cz.h b/src/translator_cz.h index ba38959..ddd6033 100644 --- a/src/translator_cz.h +++ b/src/translator_cz.h @@ -87,7 +87,7 @@ // something else. It is difficult to find the general translation // for all kinds in the Czech language. -class TranslatorCzech : public Translator +class TranslatorCzech : public TranslatorAdapter_1_9_4 { public: // --- Language control methods ------------------- @@ -111,6 +111,10 @@ class TranslatorCzech : public Translator { return "cs"; } + virtual QCString getLanguageString() + { + return "0x405 Czech"; + } // --- Language translation methods ------------------- @@ -462,12 +466,6 @@ class TranslatorCzech : public Translator virtual QCString trExampleDocumentation() { return "Dokumentace příkladů"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Dokumentace souvisejících stránek"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referenční příručka"; } @@ -558,9 +556,9 @@ class TranslatorCzech : public Translator */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Vygenerováno dne: "+date; + QCString result="Vygenerováno dne: "+date; if (!projName.isEmpty()) result += QCString(", pro projekt: ") + projName; - result+=(QCString)", programem"; + result+=", programem"; return result; } @@ -570,10 +568,6 @@ class TranslatorCzech : public Translator return QCString("Diagram dědičnosti pro třídu ") + clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Pouze pro vnitřní použití."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Pozor"; } @@ -819,7 +813,7 @@ class TranslatorCzech : public Translator virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentace pro "; + QCString result="Dokumentace pro "; switch(compType) { case ClassDef::Class: result+="tuto třídu"; break; @@ -885,12 +879,12 @@ class TranslatorCzech : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagram pro "+clName+":"; + return "Diagram pro "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graf závislostí na vkládaných souborech pro "+fName+":"; + return "Graf závislostí na vkládaných souborech pro "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1185,11 +1179,6 @@ class TranslatorCzech : public Translator { return QCString("Balík ") + name; } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Seznam balíků"; - } /*! The description of the package index page */ virtual QCString trPackageListDescription() { @@ -1451,14 +1440,18 @@ class TranslatorCzech : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funkce v balíku"; } + virtual QCString trPackageMembers() + { + return "Členy v balíku"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statické funkce v balíku"; } @@ -1571,15 +1564,6 @@ class TranslatorCzech : public Translator virtual QCString trDirectories() { return "Adresáře"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { - return "Následující hierarchie adresářů je zhruba, " - "ale ne úplně, řazena podle abecedy:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1790,7 +1774,7 @@ class TranslatorCzech : public Translator bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentace "; + QCString result="Dokumentace "; switch(compType) { case ClassDef::Class: result+="k tomuto modulu"; break; @@ -1880,7 +1864,7 @@ class TranslatorCzech : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Soubor v "+name; + return "Soubor v "+name; } /*! when clicking a directory dependency label, a page with a @@ -1889,7 +1873,7 @@ class TranslatorCzech : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Vkládá (include) soubor z "+name; + return "Vkládá (include) soubor z "+name; } /** Compiles a date string. diff --git a/src/translator_de.h b/src/translator_de.h index d7d2de9..c28385c 100644 --- a/src/translator_de.h +++ b/src/translator_de.h @@ -26,8 +26,6 @@ // // 2001/03/23 Jens Seidel (jensseidel@users.sourceforge.net) // - fixed typos -// - changed trPageDocumentation() "Seitenbeschreibung" to -// "Zusätzliche Informationen" // - removed old trGeneratedFrom() // - changed "/*!" to "/*" (documentation is inherited from translator_en.h // (INHERIT_DOCS = YES), there's no need to make changes twice) @@ -170,6 +168,10 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 { return "de"; } + virtual QCString getLanguageString() + { + return "0x407 German"; + } // --- Language translation methods ------------------- @@ -235,7 +237,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automatisch erzeugt von Doxygen"; - if (!s.isEmpty()) result+=(QCString)" für "+s; + if (!s.isEmpty()) result+=" für "+s; result+=" aus dem Quellcode."; return result; } @@ -509,12 +511,6 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Dokumentation der Beispiele"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Zusätzliche Informationen"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Nachschlagewerk"; } @@ -605,22 +601,18 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Erzeugt am "+date; - if (!projName.isEmpty()) result+=(QCString)" für "+projName; - result+=(QCString)" von"; + QCString result="Erzeugt am "+date; + if (!projName.isEmpty()) result+=" für "+projName; + result+=" von"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Klassendiagramm für "+clName+":"; + return "Klassendiagramm für "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Nur für den internen Gebrauch."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Warnung"; } @@ -695,7 +687,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName+" "; + QCString result=clName+" "; if (isTemplate) result+="Template-"; switch(compType) { @@ -864,11 +856,11 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) { // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"Die Dokumentation für diese"; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="Die Dokumentation für diese"; switch(compType) { - case ClassDef::Class: result+=vhdlOpt?"Entwurfseinheiten":"Klasse"; break; + case ClassDef::Class: result+=vhdlOpt?" Entwurfseinheiten":" Klasse"; break; case ClassDef::Struct: result+=" Struktur"; break; case ClassDef::Union: result+=" Variante"; break; case ClassDef::Interface: result+=" Schnittstelle"; break; @@ -931,13 +923,13 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Zusammengehörigkeiten von "+clName+":"; + return "Zusammengehörigkeiten von "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Include-Abhängigkeitsdiagramm für "+fName+":"; + return "Include-Abhängigkeitsdiagramm für "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ @@ -1256,14 +1248,9 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paket "+name; + return "Paket "+name; } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Paketliste"; - } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1505,15 +1492,19 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Paketfunktionen"; } + virtual QCString trPackageMembers() + { + return "Paketelemente"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statische Paketfunktionen"; } @@ -1627,14 +1618,6 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Verzeichnisse"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Diese Verzeichnishierarchie ist -mit Einschränkungen- " - "alphabetisch sortiert:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1770,7 +1753,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; result += "-"; switch(compType) { @@ -1840,7 +1823,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 bool single) { // single is true implies a single file - QCString result=(QCString)"Die Dokumentation für "; + QCString result="Die Dokumentation für "; switch(compType) { case ClassDef::Class: result+="dieses Modul"; break; @@ -1931,7 +1914,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Datei in "+name; + return "Datei in "+name; } /*! when clicking a directory dependency label, a page with a @@ -1940,7 +1923,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Include-Dateien in "+name; + return "Include-Dateien in "+name; } /** Compiles a date string. @@ -2109,7 +2092,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Dienstreferenz"; return result; } @@ -2117,7 +2100,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Singleton-Referenz"; return result; } @@ -2125,7 +2108,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /** UNO IDL service page */ virtual QCString trServiceGeneratedFromFiles(bool single) { - QCString result=(QCString)"Die Dokumentation für diesen Dienst " + QCString result="Die Dokumentation für diesen Dienst " "wurde generiert aus "; if (single) result+="folgender Datei: "; else result+="folgenden Dateien: "; return result; @@ -2134,7 +2117,7 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 /** UNO IDL singleton page */ virtual QCString trSingletonGeneratedFromFiles(bool single) { - QCString result=(QCString)"Die Dokumentation für diesen Singleton wurde generiert aus "; + QCString result="Die Dokumentation für diesen Singleton wurde generiert aus "; if (single) result+="folgender Datei:"; else result+="folgenden Dateien:"; return result; } diff --git a/src/translator_dk.h b/src/translator_dk.h index 1d01f32..cd348a8 100644 --- a/src/translator_dk.h +++ b/src/translator_dk.h @@ -123,6 +123,10 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 { return "da"; } + virtual QCString getLanguageString() + { + return "0x406 Danish"; + } // --- Language translation methods ------------------- @@ -187,7 +191,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automatisk genereret af Doxygen"; - if (!s.isEmpty()) result+=(QCString)" for "+s; + if (!s.isEmpty()) result+=" for "+s; result+=" ud fra kildekoden."; return result; } @@ -398,9 +402,16 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 */ virtual QCString trClassDocumentation() { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { return "Datastruktur-documentation"; - } else { + } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } + else + { return "Klasse-dokumentation"; } } @@ -417,12 +428,6 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 virtual QCString trExampleDocumentation() { return "Eksempel-dokumentation"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Side-dokumentation"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referencemanual"; } @@ -516,22 +521,18 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Genereret "+date; - if (!projName.isEmpty()) result+=(QCString)" for "+projName; - result+=(QCString)" af"; + QCString result="Genereret "+date; + if (!projName.isEmpty()) result+=" for "+projName; + result+=" af"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Stamtræ for "+clName+":"; + return "Stamtræ for "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Kun til intern brug."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Advarsel"; } @@ -606,7 +607,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName+" "; + QCString result=clName+" "; switch(compType) { case ClassDef::Class: result+=" Klasse-"; break; @@ -764,7 +765,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentationen for denne "; + QCString result="Dokumentationen for denne "; switch(compType) { case ClassDef::Class: result+="klasse"; break; @@ -831,12 +832,12 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Samarbejdsdiagram for "+clName+":"; + return "Samarbejdsdiagram for "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Inklusions-afhængighedsgraf for "+fName+":"; + return "Inklusions-afhængighedsgraf for "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1082,12 +1083,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pakke "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Pakkeoversigt"; + return "Pakke "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1304,9 +1300,11 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 /* Java: Entities with package scope... */ virtual QCString trPackageTypes() { return "Typer med pakke-scope"; } - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Metoder med pakke-scope"; } - virtual QCString trStaticPackageMembers() + virtual QCString trPackageMembers() + { return "Medlemmer med pakke-scope"; } + virtual QCString trStaticPackageFunctions() { return "Statiske metoder med pakke-scope"; } virtual QCString trPackageAttribs() { return "Attributter med pakke-scope"; } @@ -1407,14 +1405,6 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 virtual QCString trDirectories() { return "Kataloger"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Denne katalogstruktur er sorteret næsten - " - "men ikke nødvendigvis helt - alfabetisk:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1555,7 +1545,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Modul"; break; // " Module" @@ -1625,7 +1615,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 bool single) { // single is true implies a single file - QCString result=(QCString)"The documentation for this "; + QCString result="The documentation for this "; switch(compType) { case ClassDef::Class: result+="modul"; break; // "module" @@ -1714,7 +1704,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"File i "+name; // "File in " + return "File i "+name; // "File in " } /*! when clicking a directory dependency label, a page with a @@ -1723,7 +1713,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inkluderer file i "+name; // "Includes file in " + return "Inkluderer file i "+name; // "Includes file in " } /** Compiles a date string. @@ -1783,7 +1773,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 const char* base, const char* plurSuffix) { QCString result(base); - if (first_capital) result[0] = (char)toupper(result[0]); + if (first_capital) result[0] = static_cast<char>(toupper(result[0])); if (!singular) result+=plurSuffix; return result; } diff --git a/src/translator_en.h b/src/translator_en.h index 55d6742..236675b 100644 --- a/src/translator_en.h +++ b/src/translator_en.h @@ -79,6 +79,10 @@ class TranslatorEnglish : public Translator return "en-US"; } + virtual QCString getLanguageString() + { + return "0x409 English (United States)"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -143,7 +147,7 @@ class TranslatorEnglish : public Translator */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generated automatically by Doxygen"; - if (!s.isEmpty()) result+=(QCString)" for "+s; + if (!s.isEmpty()) result+=" for "+s; result+=" from the source code."; return result; } @@ -421,12 +425,6 @@ class TranslatorEnglish : public Translator virtual QCString trExampleDocumentation() { return "Example Documentation"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Page Documentation"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Reference Manual"; } @@ -517,22 +515,18 @@ class TranslatorEnglish : public Translator */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generated on "+date; - if (!projName.isEmpty()) result+=(QCString)" for "+projName; - result+=(QCString)" by"; + QCString result="Generated on "+date; + if (!projName.isEmpty()) result+=" for "+projName; + result+=" by"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Inheritance diagram for "+clName+":"; + return "Inheritance diagram for "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "For internal use only."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Warning"; } @@ -607,7 +601,7 @@ class TranslatorEnglish : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Class"; break; @@ -766,8 +760,8 @@ class TranslatorEnglish : public Translator virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) { // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"The documentation for this "; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="The documentation for this "; switch(compType) { case ClassDef::Class: result+=vhdlOpt?"design unit":"class"; break; @@ -832,12 +826,12 @@ class TranslatorEnglish : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Collaboration diagram for "+clName+":"; + return "Collaboration diagram for "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Include dependency graph for "+fName+":"; + return "Include dependency graph for "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1120,12 +1114,7 @@ class TranslatorEnglish : public Translator /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Package "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Package List"; + return "Package "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1382,14 +1371,18 @@ class TranslatorEnglish : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Package Functions"; } + virtual QCString trPackageMembers() + { + return "Package Members"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Static Package Functions"; } @@ -1501,14 +1494,6 @@ class TranslatorEnglish : public Translator virtual QCString trDirectories() { return "Directories"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "This directory hierarchy is sorted roughly, " - "but not completely, alphabetically:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1644,7 +1629,7 @@ class TranslatorEnglish : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Module"; break; @@ -1713,7 +1698,7 @@ class TranslatorEnglish : public Translator bool single) { // single is true implies a single file - QCString result=(QCString)"The documentation for this "; + QCString result="The documentation for this "; switch(compType) { case ClassDef::Class: result+="module"; break; @@ -1765,7 +1750,7 @@ class TranslatorEnglish : public Translator /*! directory relation for \a name */ virtual QCString trDirRelation(const QCString &name) { - return QCString(name)+" Relation"; + return name+" Relation"; } /*! Loading message shown when loading search results */ @@ -1802,7 +1787,7 @@ class TranslatorEnglish : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"File in "+name; + return "File in "+name; } /*! when clicking a directory dependency label, a page with a @@ -1811,7 +1796,7 @@ class TranslatorEnglish : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Includes file in "+name; + return "Includes file in "+name; } /** Compiles a date string. @@ -1855,7 +1840,7 @@ class TranslatorEnglish : public Translator /*! Header for the graph showing the directory dependencies */ virtual QCString trDirDepGraph(const QCString &name) - { return QCString("Directory dependency graph for ")+name+":"; } + { return "Directory dependency graph for "+name+":"; } ////////////////////////////////////////////////////////////////////////// // new since 1.8.0 @@ -1883,11 +1868,11 @@ class TranslatorEnglish : public Translator /*! Header of a Java enum page (Java enums are represented as classes). */ virtual QCString trEnumReference(const QCString &name) - { return QCString(name)+" Enum Reference"; } + { return name+" Enum Reference"; } /*! Used for a section containing inherited members */ virtual QCString trInheritedFrom(const QCString &members,const QCString &what) - { return QCString(members)+" inherited from "+what; } + { return members+" inherited from "+what; } /*! Header of the sections with inherited members specific for the * base class(es) @@ -1976,14 +1961,14 @@ class TranslatorEnglish : public Translator /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Service Reference"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Singleton Reference"; return result; } @@ -1991,8 +1976,8 @@ class TranslatorEnglish : public Translator virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"The documentation for this service " - "was generated from the following file"; + QCString result="The documentation for this service " + "was generated from the following file"; if (single) result+=":"; else result+="s:"; return result; } @@ -2000,8 +1985,8 @@ class TranslatorEnglish : public Translator virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"The documentation for this singleton " - "was generated from the following file"; + QCString result="The documentation for this singleton " + "was generated from the following file"; if (single) result+=":"; else result+="s:"; return result; } @@ -2121,7 +2106,7 @@ class TranslatorEnglish : public Translator } } virtual QCString trCustomReference(const QCString &name) - { return QCString(name)+" Reference"; } + { return name+" Reference"; } /* Slice */ virtual QCString trConstants() @@ -2222,7 +2207,7 @@ class TranslatorEnglish : public Translator } virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result=(QCString)clName; + QCString result=clName; if (isLocal) result+=" Local"; switch(compType) { @@ -2308,6 +2293,13 @@ class TranslatorEnglish : public Translator { return "Concept definition"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.9.4 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trPackageList() + { return "Package List"; } }; #endif diff --git a/src/translator_eo.h b/src/translator_eo.h index 8482b39..d86ffaf 100644 --- a/src/translator_eo.h +++ b/src/translator_eo.h @@ -37,7 +37,7 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. @@ -81,6 +81,11 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 return "eo"; } + // using fallback see translator.h + virtual QCString getLanguageString() + { + return "0x409 English (United States)"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -145,7 +150,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generita aŭtomate de Doxygen"; - if (!s.isEmpty()) result+=(QCString)" por "+s; + if (!s.isEmpty()) result+=" por "+s; result+=" el la fontkodo."; return result; } @@ -393,6 +398,10 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 { return "Datumstruktura Dokumentado"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Klasa Dokumentado"; @@ -411,12 +420,6 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 virtual QCString trExampleDocumentation() { return "Ekzempla Dokumentado"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Paĝa Dokumentado"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referenca Manlibro"; } @@ -507,22 +510,18 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generita la "+date; - if (!projName.isEmpty()) result+=(QCString)" por "+projName; - result+=(QCString)" de"; + QCString result="Generita la "+date; + if (!projName.isEmpty()) result+=" por "+projName; + result+=" de"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Heredada diagramo por "+clName+":"; + return "Heredada diagramo por "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Nur por ena uzado."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Averto"; } @@ -610,7 +609,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 case ClassDef::Exception: result+="escepto "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -756,7 +755,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) { // single is true implies a single file - QCString result=(QCString)"La dokumentado por tiu ĉi "; + QCString result="La dokumentado por tiu ĉi "; switch(compType) { case ClassDef::Class: result+="klaso"; break; @@ -822,12 +821,12 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Kunlaborada diagramo por "+clName+":"; + return "Kunlaborada diagramo por "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Inkluzivaĵa dependeca diagramo por "+fName+":"; + return "Inkluzivaĵa dependeca diagramo por "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1107,12 +1106,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pakaĵo "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Pakaĵa Listo"; + return "Pakaĵo "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1369,14 +1363,18 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Pakaĵaj Funkcioj"; } + virtual QCString trPackageMembers() + { + return "Pakaĵaj Membroj"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statikaj Pakaĵaj Funkcioj"; } @@ -1488,14 +1486,6 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 virtual QCString trDirectories() { return "Dosierujoj"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Tiu ĉi dosieruja hierarkio estas plimalpli, " - "sed ne tute, ordigita alfabete:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1644,7 +1634,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 case ClassDef::Exception: result+="escepto "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } /*! used as the title of the HTML page of a module (Fortran) */ @@ -1699,7 +1689,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 bool single) { // single is true implies a single file - QCString result=(QCString)"La dokumentado por tiu ĉi "; + QCString result="La dokumentado por tiu ĉi "; switch(compType) { case ClassDef::Class: result+="modulo"; break; @@ -1786,7 +1776,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Dosiero en "+name; + return "Dosiero en "+name; } /*! when clicking a directory dependency label, a page with a @@ -1795,7 +1785,7 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inkluzivas dosieron en "+name; + return "Inkluzivas dosieron en "+name; } /** Compiles a date string. @@ -1941,15 +1931,6 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 { return "Dokumentaro de la Metodo"; } - - /*! Used as the title of the design overview picture created for the - * VHDL output. - */ - virtual QCString trDesignOverview() - { - return "Fasona Superrigardo"; - } - }; #endif diff --git a/src/translator_es.h b/src/translator_es.h index dff426c..f7c22b7 100644 --- a/src/translator_es.h +++ b/src/translator_es.h @@ -72,6 +72,10 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 { return "es"; } + virtual QCString getLanguageString() + { + return "0x40A Spanish(Traditional Sort)"; + } // --- Language translation methods ------------------- @@ -137,7 +141,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generado automáticamente por Doxygen"; - if (!s.isEmpty()) result+=(QCString)" para "+s; + if (!s.isEmpty()) result+=" para "+s; result+=" del código fuente."; return result; } @@ -383,6 +387,10 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 { return "Documentación de las estructuras de datos"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Documentación de las clases"; @@ -401,12 +409,6 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Documentación de ejemplos"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Documentación de páginas"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Manual de referencia"; } @@ -497,22 +499,18 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generado el "+date; - if (!projName.isEmpty()) result+=(QCString)" para "+projName; - result+=(QCString)" por"; + QCString result="Generado el "+date; + if (!projName.isEmpty()) result+=" para "+projName; + result+=" por"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagrama de herencias de "+clName; + return "Diagrama de herencias de "+clName; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Sólo para uso interno."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Atención"; } @@ -600,7 +598,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 case ClassDef::Exception: result+=" la Excepción "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -756,8 +754,8 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"La documentación para est"; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="La documentación para est"; switch(compType) { case ClassDef::Class: result+=vhdlOpt? "a unidades de diseño":"a clase"; break; @@ -823,13 +821,13 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagrama de colaboración para "+clName+":"; + return "Diagrama de colaboración para "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Dependencia gráfica adjunta para "+fName+":"; + return "Dependencia gráfica adjunta para "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ @@ -1142,14 +1140,9 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paquetes "+name; + return "Paquetes "+name; } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista de Paquetes "; - } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1411,15 +1404,19 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funciones del 'package'"; } + virtual QCString trPackageMembers() + { + return "Miembros del 'package'"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Funciones estáticas del 'package'"; } @@ -1536,14 +1533,6 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Directorios"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "La jeraquía de este directorio está ordenada" - " alfabéticamente, de manera aproximada:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1702,7 +1691,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 case ClassDef::Exception: result+=" la excepción"; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -1759,7 +1748,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"La documentación para est"; + QCString result="La documentación para est"; switch(compType) { case ClassDef::Class: result+="e módulo"; break; @@ -1849,7 +1838,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Fichero en "+name; + return "Fichero en "+name; } /*! when clicking a directory dependency label, a page with a @@ -1858,7 +1847,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Incluye ficheros en "+name; + return "Incluye ficheros en "+name; } /** Compiles a date string. @@ -2028,14 +2017,14 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Referencia servicio"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" referencia Singleton"; return result; } @@ -2043,7 +2032,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"La documentacion para este servicio " + QCString result="La documentacion para este servicio " "se ha generado desde "; if (single) result+="el siguiente fichero:"; else result+="los siguientes ficheros:"; return result; @@ -2052,7 +2041,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"La documentación para este singleton " + QCString result="La documentación para este singleton " "se ha generado desde "; if (single) result+="el siguiente fichero:"; else result+="los siguientes ficheros:"; return result; @@ -2286,7 +2275,7 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 default: break; } if (isLocal) result+=" Local"; - result+=(QCString)clName; + result+=clName; return result; } virtual QCString trOperations() diff --git a/src/translator_fa.h b/src/translator_fa.h index cec2da1..b609623 100644 --- a/src/translator_fa.h +++ b/src/translator_fa.h @@ -96,6 +96,10 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 return "fa"; } + virtual QCString getLanguageString() + { + return "0x429 Persian (Iran)"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -160,7 +164,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="تولید شده توسط نرم افزار دی اکسیژن "; - if (!s.isEmpty()) result+=(QCString)" برای "+s; + if (!s.isEmpty()) result+=" برای "+s; result+=" از کد برنامه "; return result; } @@ -384,6 +388,10 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 { return "مستندات ساختار داده ها"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "مستندات کلاس ها"; @@ -402,12 +410,6 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 virtual QCString trExampleDocumentation() { return "مستندات مثال"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "مستندات صفحه"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "راهنمای مرجع"; } @@ -505,21 +507,17 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { QCString result = HtmlDivEnd + HtmlRightToLeft + QCString("توليد شده در ") +date ; - if (!projName.isEmpty()) result+=(QCString)" برای "+projName; - result+=(QCString)" توسط"; + if (!projName.isEmpty()) result+=" برای "+projName; + result+=" توسط"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)""+clName+" نمودار وراثت برای :"; + return ""+clName+" نمودار وراثت برای :"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return ".فقط برای استعمال داخلی"; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "اخطار"; } @@ -751,7 +749,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"مستندات اين "; + QCString result="مستندات اين "; switch(compType) { case ClassDef::Class: result+="کلاس"; break; @@ -816,12 +814,12 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Collaboration diagram for "+clName+":"; + return "Collaboration diagram for "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"نمودار شامل شدن ها برای "+fName+":"; + return "نمودار شامل شدن ها برای "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1101,12 +1099,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Package "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "لیست بسته ها"; + return "Package "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1363,14 +1356,18 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "توابع بسته ها"; } + virtual QCString trPackageMembers() + { + return "عضوها بسته ها"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Static Package Functions"; } @@ -1482,13 +1479,6 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 virtual QCString trDirectories() { return "شاخه ها"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "در ذيل ساختار شاخه ها و دايرکتوری ها را نسبتا مرتب شده می بينيد :"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1600,7 +1590,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Module"; break; @@ -1658,7 +1648,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"The documentation for this "; + QCString result="The documentation for this "; switch(compType) { case ClassDef::Class: result+="module"; break; @@ -1745,7 +1735,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"پرونده ای در "+name; + return "پرونده ای در "+name; } /*! when clicking a directory dependency label, a page with a @@ -1754,7 +1744,7 @@ class TranslatorPersian : public TranslatorAdapter_1_7_5 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Includes file in "+name; + return "Includes file in "+name; } /** Compiles a date string. diff --git a/src/translator_fi.h b/src/translator_fi.h index 1db2372..dd1d418 100644 --- a/src/translator_fi.h +++ b/src/translator_fi.h @@ -89,17 +89,6 @@ positiiviset kommentit otetaan ilolla vastaan. class TranslatorFinnish : public TranslatorAdapter_1_6_0 { public: - /*! This method is used to generate a warning message to signal - * the user that the translation of his/her language of choice - * needs updating. - */ - /*virtual QCString updateNeededMessage() - { - return "The Finnish translator is really obsolete.\n" - "It was not updated since version 1.0.0. As a result,\n" - "some sentences may appear in English.\n\n"; - }*/ - // --- Language control methods ------------------- /*! Used for identification of the language. The identification @@ -134,6 +123,10 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 { return "fi"; } + virtual QCString getLanguageString() + { + return "0x40B Finnish"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -198,9 +191,9 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 * parameter s is name of the project name. */ virtual QCString trGeneratedAutomatically(const QCString &s) - { QCString result=(QCString)"Automaattisesti luotu Doxygenilla " + { QCString result="Automaattisesti luotu Doxygenilla " "lähdekoodista projektille "+s; // "Generated automatically by Doxygen" ... "for" ... "from the sourcecode" - //if (s) result+=(QCString)" voor "+s; + //if (s) result+=" voor "+s; // tässä on ongelma, kuinka taivuttaa parametria, esim. "Jcad"+"in"; "IFC2VRML konversio"+"n" // mutta ratkaistaan ongelma kätevästi kaksoispisteellä -> "Jcad:n" / "IFC2VRML konversio:n" // lopputulos on vähemmän kökkö ja täysin luettava, mutta ei kuitenkaan täydellinen. @@ -453,6 +446,10 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 { return "Tietueiden dokumentaatio"; // "Data Structure Documentation" } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Luokkien dokumentaatio"; // "Class Documentation" @@ -471,12 +468,6 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 virtual QCString trExampleDocumentation() { return "Esimerkkien dokumentaatio"; } // "Example Documentation" - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Sivujen dokumentaatio"; } // "Page Documentation" - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Käsikirja"; } // "Reference Manual" @@ -571,22 +562,18 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 // Muutetaan siis lauserakennetta suomalaisemmaksi // Generated on $date for $project by: // -> Generated for $project on $date by: - QCString result=(QCString)"Generoinut "; - if (!projName.isEmpty()) result+=(QCString)"projektille "+projName+" "; - result+=(QCString)date+" "; + QCString result="Generoinut "; + if (!projName.isEmpty()) result+="projektille "+projName+" "; + result+=date+" "; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return "Luokan "+(QCString)clName+" luokkakaavio"; // "Inheritance diagram for " + return "Luokan "+clName+" luokkakaavio"; // "Inheritance diagram for " } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Vain sisäiseen käyttöön."; } // "For internal use only." - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Varoitus"; } // "Warning" @@ -661,7 +648,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" luokka"; break; // " Class" @@ -745,7 +732,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 */ virtual QCString trInheritsList(int numEntries) { - return (QCString)"Periytyy "+(numEntries > 1 ? "luokista " : "luokasta ")+trWriteList(numEntries)+"."; // "Inherits " + return QCString("Periytyy ")+(numEntries > 1 ? "luokista " : "luokasta ")+trWriteList(numEntries)+"."; // "Inherits " } /*! used in class documentation to produce a list of super classes, @@ -753,7 +740,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 */ virtual QCString trInheritedByList(int numEntries) { - return (QCString)"Periytetään "+(numEntries > 1 ? "luokissa " : "luokassa ")+trWriteList(numEntries)+"."; // "Inherited by " + return QCString("Periytetään ")+(numEntries > 1 ? "luokissa " : "luokassa ")+trWriteList(numEntries)+"."; // "Inherited by " } /*! used in member documentation blocks to produce a list of @@ -761,7 +748,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 */ virtual QCString trReimplementedFromList(int numEntries) { - return (QCString)"Uudelleentoteuttaa "+(numEntries > 1 ? "luokat " : "luokan ")+trWriteList(numEntries)+"."; // "Reimplemented from " + return QCString("Uudelleentoteuttaa ")+(numEntries > 1 ? "luokat " : "luokan ")+trWriteList(numEntries)+"."; // "Reimplemented from " } /*! used in member documentation blocks to produce a list of @@ -769,7 +756,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 */ virtual QCString trReimplementedInList(int numEntries) { - return (QCString)"Uudelleentoteutetaan "+(numEntries > 1 ? "luokissa " : "luokassa ")+trWriteList(numEntries)+"."; // "Reimplemented in " + return QCString("Uudelleentoteutetaan ")+(numEntries > 1 ? "luokissa " : "luokassa ")+trWriteList(numEntries)+"."; // "Reimplemented in " } /*! This is put above each page as a link to all members of namespaces. */ @@ -821,7 +808,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentaatio tälle "; // "The documentation for this " + QCString result="Dokumentaatio tälle "; // "The documentation for this " switch(compType) { case ClassDef::Class: result+="luokalle"; break; // "class" @@ -886,12 +873,12 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Yhteistyökaavio luokalle "+clName+":"; // "Collaboration diagram for "+clName+":" + return "Yhteistyökaavio luokalle "+clName+":"; // "Collaboration diagram for "+clName+":" } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Sisällytysriippuvuuskaavio tiedostolle "+fName+":"; // "Include dependency graph for "+fName+":" + return "Sisällytysriippuvuuskaavio tiedostolle "+fName+":"; // "Include dependency graph for "+fName+":" } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1223,12 +1210,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paketti "+name; // "Package " - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Pakettilista"; // "Package List" + return "Paketti "+name; // "Package " } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1485,14 +1467,18 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Paketin funktiot"; // "Package Functions" } + virtual QCString trPackageMembers() + { + return "Paketin jäsenet"; // "Package Members" + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Paketin staattiset funktiot"; // "Static Package Functions" } @@ -1604,15 +1590,6 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 virtual QCString trDirectories() { return "Hakemistot"; } // "Directories" - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Tämä hakemistohierarkia on järjestetty aakkosellisesti tasoittain:"; - //This directory hierarchy is sorted roughly, " - // "but not completely, alphabetically:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1752,7 +1729,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" moduuli"; break; // " Module" @@ -1820,7 +1797,7 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentaatio tälle "; // "The documentation for this " + QCString result="Dokumentaatio tälle "; // "The documentation for this " switch(compType) { case ClassDef::Class: result+="moduulille"; break; // "module" diff --git a/src/translator_fr.h b/src/translator_fr.h index a612760..f50d5c9 100644 --- a/src/translator_fr.h +++ b/src/translator_fr.h @@ -98,7 +98,7 @@ // files frees the maintainer from thinking about whether the // first, the second, or both files should be included or not, and // why. This holds namely for localized translators because their -// base class is changed occasionaly to adapter classes when the +// base class is changed occasionally to adapter classes when the // Translator class changes the interface, or back to the // Translator class (by the local maintainer) when the localized // translator is made up-to-date again. @@ -139,6 +139,10 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 { return "fr"; } + virtual QCString getLanguageString() + { + return "0x40C French"; + } // --- Language translation methods ------------------- @@ -204,7 +208,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Généré automatiquement par Doxygen"; - if (!s.isEmpty()) result+=(QCString)" pour "+s; + if (!s.isEmpty()) result+=" pour "+s; result+=" à partir du code source."; return result; } @@ -457,6 +461,10 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 { return "Documentation des structures de données"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Documentation des classes"; @@ -475,12 +483,6 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Documentation des exemples"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Documentation des pages associées"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Manuel de référence"; } @@ -571,22 +573,18 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Généré le "+date; - if (!projName.isEmpty()) result+=(QCString)" pour "+projName; - result+=(QCString)" par"; + QCString result="Généré le "+date; + if (!projName.isEmpty()) result+=" pour "+projName; + result+=" par"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Graphe d'héritage de "+clName+":"; + return "Graphe d'héritage de "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Pour un usage interne uniquement."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Avertissement"; } @@ -675,7 +673,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 case ClassDef::Exception: result+="l'exception "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -822,9 +820,9 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); bool feminine = true; - QCString result=(QCString)"La documentation de "; + QCString result="La documentation de "; switch(compType) { case ClassDef::Class: result+=vhdlOpt? "cette unités de conception":"cette classe"; break; @@ -891,12 +889,12 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Graphe de collaboration de "+clName+":"; + return "Graphe de collaboration de "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graphe des dépendances par inclusion de "+fName+":"; + return "Graphe des dépendances par inclusion de "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1176,12 +1174,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paquetage "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Liste des paquetages"; + return "Paquetage "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1439,14 +1432,18 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Fonctions de paquetage"; } + virtual QCString trPackageMembers() + { + return "Membres de paquetage"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Fonctions statiques de paquetage"; } @@ -1558,14 +1555,6 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Répertoires"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Cette hiérarchie de répertoire est triée approximativement, " - "mais pas complètement, par ordre alphabétique :"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1713,7 +1702,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 case ClassDef::Exception: result+="de l'exception "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } /*! used as the title of the HTML page of a module (Fortran) */ @@ -1769,7 +1758,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 bool single) { // single is true implies a single file - QCString result=(QCString)"La documentation de "; + QCString result="La documentation de "; switch(compType) { case ClassDef::Class: result+="ce module"; break; @@ -1858,7 +1847,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Fichier dans "+name; + return "Fichier dans "+name; } /*! when clicking a directory dependency label, a page with a @@ -1867,7 +1856,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inclut le fichier dans "+name; + return "Inclut le fichier dans "+name; } /** Compiles a date string. @@ -2034,21 +2023,21 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 virtual QCString trServiceReference(const QCString &sName) { QCString result="Référence du service "; - result+=(QCString)sName; + result+=sName; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { QCString result="Référence du singleton "; - result+=(QCString)sName; + result+=sName; return result; } /** UNO IDL service page */ virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"La documentation pour ce service " + QCString result="La documentation pour ce service " "a été générée par "; if (single) result+="le fichier suivant :"; else result+="les fichiers suivants :"; return result; @@ -2057,7 +2046,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"La documentation pour ce singleton " + QCString result="La documentation pour ce singleton " "a été générée par "; if (single) result+="le fichier suivant :"; else result+="les fichiers suivants :"; return result; @@ -2297,7 +2286,7 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15 result += (feminine) ? "locale " : "local "; } - result += (QCString)clName; + result += clName; return result; } diff --git a/src/translator_gr.h b/src/translator_gr.h index 41d39f1..4f9e5ee 100644 --- a/src/translator_gr.h +++ b/src/translator_gr.h @@ -48,7 +48,7 @@ #ifndef TRANSLATOR_GR_H #define TRANSLATOR_GR_H -class TranslatorGreek : public Translator +class TranslatorGreek : public TranslatorAdapter_1_9_4 { public: @@ -148,7 +148,7 @@ class TranslatorGreek : public Translator */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Δημιουργήθηκε αυτόματα από το Doxygen"; - if (!s.isEmpty()) result+=(QCString)" για "+s; + if (!s.isEmpty()) result+=" για "+s; result+=" από τον πηγαίο κώδικα."; return result; } @@ -395,6 +395,10 @@ class TranslatorGreek : public Translator { return "Τεκμηρίωση Δομών Δεδομένων"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Τεκμηρίωση Κλάσεων"; @@ -413,12 +417,6 @@ class TranslatorGreek : public Translator virtual QCString trExampleDocumentation() { return "Τεκμηρίωση Παραδειγμάτων"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Τεκμηρίωση Σελίδων"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Εγχειρίδιο Τεκμηρίωσης"; } @@ -509,22 +507,18 @@ class TranslatorGreek : public Translator */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Δημιουργήθηκε στις "+date; - if (!projName.isEmpty()) result+=(QCString)" για "+projName; - result+=(QCString)" από"; + QCString result="Δημιουργήθηκε στις "+date; + if (!projName.isEmpty()) result+=" για "+projName; + result+=" από"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Διάγραμμα κληρονομικότητας για την "+clName+":"; + return "Διάγραμμα κληρονομικότητας για την "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Μόνο για εσωτερική χρήση."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Προειδοποίηση"; } @@ -599,7 +593,7 @@ class TranslatorGreek : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)"Τεκμηρίωση"; + QCString result="Τεκμηρίωση"; if (isTemplate) result+=" Προτύπου"; switch(compType) { @@ -759,7 +753,7 @@ class TranslatorGreek : public Translator bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Η τεκμηρίωση για "; + QCString result="Η τεκμηρίωση για "; switch(compType) { case ClassDef::Class: result+="αυτή την κλάση"; break; @@ -824,12 +818,12 @@ class TranslatorGreek : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Διάγραμμα Συνεργασίας για την κλάση "+clName+":"; + return "Διάγραμμα Συνεργασίας για την κλάση "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Διάγραμμα εξάρτησης αρχείου συμπερίληψης για το "+fName+":"; + return "Διάγραμμα εξάρτησης αρχείου συμπερίληψης για το "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1112,12 +1106,7 @@ class TranslatorGreek : public Translator /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Πακέτο "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Λίστα Πακέτων"; + return "Πακέτο "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1207,6 +1196,10 @@ class TranslatorGreek : public Translator { return "Ευρετήριο"; } + virtual QCString getLanguageString() + { + return "0x408 Greece"; + } /*! This is used for translation of the word that will possibly * be followed by a single name or by a list of names @@ -1384,14 +1377,18 @@ class TranslatorGreek : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Συναρτήσεις Πακέτου"; } + virtual QCString trPackageMembers() + { + return "Μέλη Πακέτου"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Στατικές Συναρτήσεις Πακέτου"; } @@ -1503,14 +1500,6 @@ class TranslatorGreek : public Translator virtual QCString trDirectories() { return "Κατάλογοι"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { - return "Η ιεραρχία καταλόγων ταξινομήθηκε αλφαβητικά, αλλά όχι πολύ αυστηρά:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1646,7 +1635,7 @@ class TranslatorGreek : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Υπομονάδα"; break; @@ -1714,7 +1703,7 @@ class TranslatorGreek : public Translator bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Η τεκμηρίωση για "; + QCString result="Η τεκμηρίωση για "; switch(compType) { case ClassDef::Class: result+="αυτή την υπομονάδα"; break; @@ -1802,7 +1791,7 @@ class TranslatorGreek : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Αρχείο σε "+name; + return "Αρχείο σε "+name; } /*! when clicking a directory dependency label, a page with a @@ -1811,7 +1800,7 @@ class TranslatorGreek : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Εσωκλείει το αρχείο στο "+name; + return "Εσωκλείει το αρχείο στο "+name; } /** Compiles a date string. @@ -1977,14 +1966,14 @@ class TranslatorGreek : public Translator /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Τεκμηρίωση Υπηρεσίας"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Τεκμηρίωση Μονοσύνολου"; return result; } @@ -1992,7 +1981,7 @@ class TranslatorGreek : public Translator virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Η τεκμηρίωση για την υπηρεσία αυτή " + QCString result="Η τεκμηρίωση για την υπηρεσία αυτή " "δημιουργήθηκε από "; if (single) result+="το ακόλουθο αρχείο:"; else result+="τα ακόλουθα αρχεία:"; return result; @@ -2001,7 +1990,7 @@ class TranslatorGreek : public Translator virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Η τεκμηρίωση για αυτό το μονοσύνολο " + QCString result="Η τεκμηρίωση για αυτό το μονοσύνολο " "δημιουργήθηκε από "; if (single) result+="το ακόλουθο αρχείο:"; else result+="τα ακόλουθα αρχεία:"; return result; diff --git a/src/translator_hi.h b/src/translator_hi.h new file mode 100644 index 0000000..fb50015 --- /dev/null +++ b/src/translator_hi.h @@ -0,0 +1,2236 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2015 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +/* English to Hindi keyword dictionary + * alias = उपनाम + * alias = उपनामगण + * architecture = वास्तुकला + * architectures = वास्तुकलाएं + * argument = तर्क + * arguments = तर्कगण + * attribute = गुण + * attrubutes = गुणगण + * category = श्रेणी + * categories = श्रेणीयाँ + * code = संकेत-लिपि + * codes = संकेत-लिपियाॅं + * component = अंग + * components = अंगगण + * concept = संकल्पना + * concepts = संकल्पनाएं + * configuration = विन्यास + * configurations = विन्यासगण + * const/constant = स्थिर + * consts/constants = स्थिरगण + * constructor = निर्माता + * class = वर्ग + * classes = वर्गगण + * datum = आंकड़ा + * data = आंकड़े + * data structure = आंकड़ा संरचना (datum structure) + * data structures = आंकड़े संरचनाएं + * destructor = नाशक + * directory = निर्देशिका + * directories = निर्देशिकाएं + * doxygen = डाॅक्सिजन + * entity = इकाइ + * entities = इकाइयाॅं + * enum/enumerator = परिगणक + * enumeration = परिगणना + * event = घटना + * events = घटनाएं + * example = उदाहरण + * examples = उदाहरणगण + * exception = अपवाद + * exceptions = अपवादगण + * field = भाग + * fields = भागगण + * file = फ़ाइल + * friend = मित्र + * friends = मित्रगण + * function/routine = फलन + * functions/routines = फलनगण + * global = वैश्र्विक + * globals = वैश्र्विकगण + * group = समूह + * groups = समूहगण + * instance = उदाहरण + * instances = उदाहरणगण + * instantiation = उदाहरणीकरण + * instantiations = उदाहरणीकरणगण + * interface = अंतराफलक + * interfaces = अंतराफलकगण + * inherit = + * inheritance = वरासत + * inherited = वरासित + * library = संग्रह + * libraries = संग्रहगण + * member = सदस्य + * members = सदस्यगण + * method = विधि + * methods = विधियाँ + * module = अनुखंड + * modules = अनुखंडगण + * namespace = नाम-स्थान + * operation = कार्यवाही + * operations = कार्यवाहीयाँ + * overload = अधिभार + * overloaded = अधिभारित + * package = संकुल + * packages = संकुलगण + * page = पृष्ठ + * pages = पृष्ठगण + * parameter = मापदंड + * parameters = मापदंडगण + * port = द्वार + * ports = द्वारगण + * private = निजी + * procedure = कार्यविधि + * procedures = कार्यविधियाँ + * process = प्रक्रिया + * processes = प्रक्रियाएं + * property = संपत्ति + * properties = संपत्तियाँ + * protected = संरक्षित + * protocol = प्रोटोकॉल + * public = सार्वजनिक + * record = अभिलेख + * records = अभिलेखगण + * shared = साझाकृत + * search = खोजें + * service = सेवा + * services = सेवाएं + * singleton = एकल + * singletons = एकलगण + * static = अचल + * struct/structure = संरचना + * structs/structures = संरचनाएं + * subfunction/subroutine = उपफलन + * subfunctions/subroutines = उपफलनगण + * subtype = उपप्ररुप + * subtypes = उपप्ररुपगण + * super = उत्तम + * synchronize = सिंक्रनाइज़ + * synchronization = सिंक्रनाइज़ीकरण + * template = टेम्पलेट + * templates = टेम्पलेटगण + * typedef = प्ररुप-परिभाषा + * typedefs = प्ररुप-परिभाषागण + * union = मिलन + * unions = मिलनगण + * variable = परिवर्तनशील + * variables = परिवर्तनशीलगण + */ + +#ifndef TRANSLATOR_HI_H +#define TRANSLATOR_HI_H + +/*! + It is not necessary to include "translator.h" or + "translator_adapter.h" here. The files are included in the + language.cpp correctly. Not including any of the mentioned + files frees the maintainer from thinking about whether the + first, the second, or both files should be included or not, and + why. This holds namely for localized translators because their + base class is changed occasionally to adapter classes when the + Translator class changes the interface, or back to the + Translator class (by the local maintainer) when the localized + translator is made up-to-date again. +*/ +class TranslatorHindi : public TranslatorAdapter_1_9_4 +{ + public: + + // --- Language control methods ------------------- + + /*! Used for identification of the language. The identification + * should not be translated. It should be replaced by the name + * of the language in English using lower-case characters only + * (e.g. "czech", "japanese", "russian", etc.). It should be equal to + * the identification used in language.cpp. + */ + virtual QCString idLanguage() + { return "hindi"; } + + /*! Used to get the LaTeX command(s) for the language support. + * This method should return string with commands that switch + * LaTeX to the desired language. For example + * <pre>"\\usepackage[german]{babel}\n" + * </pre> + * or + * <pre>"\\usepackage{polski}\n" + * "\\usepackage[latin2]{inputenc}\n" + * "\\usepackage[T1]{fontenc}\n" + * </pre> + * + * The English LaTeX does not use such commands. Because of this + * the empty string is returned in this implementation. + */ + virtual QCString latexLanguageSupportCommand() + { return ""; } + + virtual QCString trISOLang() + { return "hi-IN"; } + + virtual QCString getLanguageString() + { return "0x439 Hindi"; } + + // --- Language translation methods ------------------- + + /*! used in the compound documentation before a list of related functions. */ + virtual QCString trRelatedFunctions() + { return "संबंधित फलन"; } + + /*! subscript for the related functions. */ + virtual QCString trRelatedSubscript() + { return "(ध्यान दें कि ये सदस्य फलन नहीं हैं।)"; } + + /*! header that is put before the detailed description of files, classes and namespaces. */ + virtual QCString trDetailedDescription() + { return "विस्तृत विवरण"; } + + /*! header that is put before the list of typedefs. */ + virtual QCString trMemberTypedefDocumentation() + { return "सदस्य प्ररुप-परिभाषा दस्तावेज़ीकरण"; } + + /*! header that is put before the list of enumerations. */ + virtual QCString trMemberEnumerationDocumentation() + { return "सदस्य परिगणना दस्तावेज़ीकरण"; } + + /*! header that is put before the list of member functions. */ + virtual QCString trMemberFunctionDocumentation() + { return "सदस्य फलन दस्तावेज़ीकरण"; } + + /*! header that is put before the list of member attributes. */ + virtual QCString trMemberDataDocumentation() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "भाग दस्तावेज़ीकरण"; + else + return "सदस्य आंकड़े दस्तावेज़ीकरण"; + } + + /*! this is the text of a link put after brief descriptions. */ + virtual QCString trMore() + { return "और..."; } + + /*! put in the class documentation */ + virtual QCString trListOfAllMembers() + { return "सभी सदस्यों की सूची"; } + + /*! used as the title of the "list of all members" page of a class */ + virtual QCString trMemberList() + { return "सदस्य सूची"; } + + /*! this is the first part of a sentence that is followed by a class name */ + virtual QCString trThisIsTheListOfAllMembers() + { return "यह है सदस्यों की पूरी सूची "; } + + /*! this is the remainder of the sentence after the class name */ + virtual QCString trIncludingInheritedMembers() + { return ", सभी विरासत में मिले सदस्यों सहित।"; } + + /*! this is put at the author sections at the bottom of man pages. + * parameter s is name of the project name. + */ + virtual QCString trGeneratedAutomatically(const QCString &s) + { + QCString result = "स्रोत संकेत-लिपि से "; + if (!s.isEmpty()) + result += s + " के लिए "; + result += "डॉक्सिजन द्वारा स्वचालित रूप से उत्पन्न किया गया।"; + return result; + } + + /*! put after an enum name in the list of all members */ + virtual QCString trEnumName() + { return "परिगणक नाम"; } + + /*! put after an enum value in the list of all members */ + virtual QCString trEnumValue() + { return "परिगणक मूल्य"; } + + /*! put after an undocumented member in the list of all members */ + virtual QCString trDefinedIn() + { return "में परिभाषित"; } + + // quick reference sections + + /*! This is put above each page as a link to the list of all groups of + * compounds or files (see the \\group command). + */ + virtual QCString trModules() + { return "अनुखंडगण"; } + + /*! This is put above each page as a link to the class hierarchy */ + virtual QCString trClassHierarchy() + { return "वर्ग पदानुक्रम"; } + + /*! This is put above each page as a link to the list of annotated classes */ + virtual QCString trCompoundList() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े संरचनाएं"; + else + return "वर्ग सूची"; + } + + /*! This is put above each page as a link to the list of documented files */ + virtual QCString trFileList() + { return "फ़ाइल सूची"; } + + /*! This is put above each page as a link to all members of compounds. */ + virtual QCString trCompoundMembers() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े भागगण"; + else + return "वर्ग सदस्यगण"; + } + + /*! This is put above each page as a link to all members of files. */ + virtual QCString trFileMembers() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "वैश्र्विकगण"; + else + return "फ़ाइल सदस्यगण"; + } + + /*! This is put above each page as a link to all related pages. */ + virtual QCString trRelatedPages() + { return "संबंधित पृष्ठगण"; } + + /*! This is put above each page as a link to all examples. */ + virtual QCString trExamples() + { return "उदाहरणगण"; } + + /*! This is put above each page as a link to the search engine. */ + virtual QCString trSearch() + { return "खोजें"; } + + /*! This is an introduction to the class hierarchy. */ + virtual QCString trClassHierarchyDescription() + { + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + return "यहाँ वर्गगण की एक पदानुक्रमनुसार सूची दी गई है:"; + else + return "यह वरासत सूची मोटे तौर पर क्रमबद्ध है, लेकिन पूरी तरह से नहीं, वर्णानुक्रम में:"; + } + + /*! This is an introduction to the list with all files. */ + virtual QCString trFileListDescription(bool extractAll) + { + QCString result = "यहाँ संक्षिप्त विवरण के साथ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "फ़ाइलों की सूची दी गई है:"; + return result; + } + + /*! This is an introduction to the annotated compound list. */ + virtual QCString trCompoundListDescription() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "यहाँ संक्षिप्त विवरण के साथ आंकड़े संरचनाएँ हैं:"; + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + return "यहाँ संक्षिप्त विवरण के साथ वर्गगण दी गई हैं:"; + else + return "यहाँ संक्षिप्त विवरण के साथ सभी वर्गगण, संरचनाएं, मिलनगण और अंतराफलकगण की सूची दी गई हैं:"; + } + + /*! This is an introduction to the page with all class members. */ + virtual QCString trCompoundMembersDescription(bool extractAll) + { + QCString result = "यहाँ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + result += "संरचना और मिलन भागगण"; + else + result += "वर्ग सदस्यगण"; + result += " कि लिंको के साथ "; + if (!extractAll) + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + result += "प्रत्येक भाग के संरचना/मिलन दस्तावेज़ीकरण "; + else + result += "प्रत्येक भाग के वर्ग दस्तावेज़ीकरण "; + } + else + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + result += "संबंधित संरचनाएं/मिलनगण "; + else + result += "संबंधित वर्गगण "; + } + result += "कि सूची दि गई हैं:"; + return result; + } + + /*! This is an introduction to the page with all file members. */ + virtual QCString trFileMembersDescription(bool extractAll) + { + QCString result = "यहाँ सभी "; + if (!extractAll) result += "दस्तावेज़ीकृत "; + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + result += "फलनगण, परिवर्तनशीलगण, मैक्रोगण, परिगणकगण और प्ररुप-परिभाषाएं"; + else + result += "फ़ाइल सदस्यगण"; + result += " कि लिंको के साथ "; + if (extractAll) + result += "संबंधित फाइलों "; + else + result += "दस्तावेज़ीकरण "; + result += "कि सूची दि गई हैं:"; + return result; + } + + /*! This is an introduction to the page with the list of all examples */ + virtual QCString trExamplesDescription() + { return "यहाँ सभी उदाहरणों की एक सूची दी गई है:"; } + + /*! This is an introduction to the page with the list of related pages */ + virtual QCString trRelatedPagesDescription() + { return "यहाँ सभी संबंधित दस्तावेज़ीकरण पृष्ठों की सूची दी गई है:"; } + + /*! This is an introduction to the page with the list of class/file groups */ + virtual QCString trModulesDescription() + { return "यहाँ सभी अनुखंडों की एक सूची है:"; } + + // index titles (the project name is prepended for these) + + /*! This is used in HTML as the title of index.html. */ + virtual QCString trDocumentation() + { return "दस्तावेज़ीकरण"; } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all groups. + */ + virtual QCString trModuleIndex() + { return "अनुखंड अनुक्रमणिका"; } + + /*! This is used in LaTeX as the title of the chapter with the + * class hierarchy. + */ + virtual QCString trHierarchicalIndex() + { return "पदानुक्रमनुसार अनुक्रमणिका"; } + + /*! This is used in LaTeX as the title of the chapter with the + * annotated compound index. + */ + virtual QCString trCompoundIndex() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े संरचना अनुक्रमणिका"; + else + return "वर्ग अनुक्रमणिका"; + } + + /*! This is used in LaTeX as the title of the chapter with the + * list of all files. + */ + virtual QCString trFileIndex() + { return "फ़ाइल अनुक्रमणिका"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all groups. + */ + virtual QCString trModuleDocumentation() + { return "अनुखंड दस्तावेज़ीकरण"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all classes, structs and unions. + */ + virtual QCString trClassDocumentation() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े संरचना दस्तावेज़ीकरण"; + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + return trDesignUnitDocumentation(); + else + return "वर्ग दस्तावेज़ीकरण"; + } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all files. + */ + virtual QCString trFileDocumentation() + { return "फ़ाइल दस्तावेज़ीकरण"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all examples. + */ + virtual QCString trExampleDocumentation() + { return "उदाहरण दस्तावेज़ीकरण"; } + + /*! This is used in LaTeX as the title of the document */ + virtual QCString trReferenceManual() + { return "संदर्भ पुस्तिका"; } + + /*! This is used in the documentation of a file as a header before the + * list of defines + */ + virtual QCString trDefines() + { return "मैक्रोगण"; } + + /*! This is used in the documentation of a file as a header before the + * list of typedefs + */ + virtual QCString trTypedefs() + { return "प्ररुप-परिभाषाएं"; } + + /*! This is used in the documentation of a file as a header before the + * list of enumerations + */ + virtual QCString trEnumerations() + { return "परिगणकगण"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) functions + */ + virtual QCString trFunctions() + { return "फलनगण"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) variables + */ + virtual QCString trVariables() + { return "परिवर्तनशीलगण"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) variables + */ + virtual QCString trEnumerationValues() + { return "परिगणक"; } + + /*! This is used in the documentation of a file before the list of + * documentation blocks for defines + */ + virtual QCString trDefineDocumentation() + { return "मैक्रो परिभाषा दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for typedefs + */ + virtual QCString trTypedefDocumentation() + { return "प्ररुप-परिभाषा दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration types + */ + virtual QCString trEnumerationTypeDocumentation() + { return "परिगणना प्ररूप दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for functions + */ + virtual QCString trFunctionDocumentation() + { return "फलन दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for variables + */ + virtual QCString trVariableDocumentation() + { return "परिवर्तनशील दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file/namespace/group before + * the list of links to documented compounds + */ + virtual QCString trCompounds() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े संरचनाएं"; + else + return "वर्गगण"; + } + + /*! This is used in the standard footer of each page and indicates when + * the page was generated + */ + virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) + { + QCString result; + if (!projName.isEmpty()) + result += projName + " के लिए "; + result += date + " पर उतपन्न किया गया: "; + return result; + } + + /*! this text is put before a class diagram */ + virtual QCString trClassDiagram(const QCString &clName) + { return clName + " के लिए वरासत आरेख:"; } + + /*! this text is generated when the \\warning command is used. */ + virtual QCString trWarning() + { return "चेतावनी"; } + + /*! this text is generated when the \\version command is used. */ + virtual QCString trVersion() + { return "संस्करण"; } + + /*! this text is generated when the \\date command is used. */ + virtual QCString trDate() + { return "दिनांक"; } + + /*! this text is generated when the \\return command is used. */ + virtual QCString trReturns() + { return "वापसी"; } + + /*! this text is generated when the \\sa command is used. */ + virtual QCString trSeeAlso() + { return "यह भी देखें"; } + + /*! this text is generated when the \\param command is used. */ + virtual QCString trParameters() + { return "मापदंडगण"; } + + /*! this text is generated when the \\exception command is used. */ + virtual QCString trExceptions() + { return "अपवादगण"; } + + /*! this text is used in the title page of a LaTeX document. */ + virtual QCString trGeneratedBy() + { return "द्वारा उत्पन्न"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990307 +////////////////////////////////////////////////////////////////////////// + + /*! used as the title of page containing all the index of all namespaces. */ + virtual QCString trNamespaceList() + { return "नाम-स्थान सूची"; } + + /*! used as an introduction to the namespace list */ + virtual QCString trNamespaceListDescription(bool extractAll) + { + QCString result = "यहाँ संक्षिप्त विवरण के साथ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "नाम-स्थानों की सूची दी गई है:"; + return result; + } + + /*! used in the class documentation as a header before the list of all + * friends of a class + */ + virtual QCString trFriends() + { return "मित्रगण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990405 +////////////////////////////////////////////////////////////////////////// + + /*! used in the class documentation as a header before the list of all + * related classes + */ + virtual QCString trRelatedFunctionDocumentation() + { return "मित्रगण और संबंधित फलन दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990425 +////////////////////////////////////////////////////////////////////////// + + /*! used as the title of the HTML page of a class/struct/union */ + virtual QCString trCompoundReference( + const QCString &clName, + ClassDef::CompoundType compType, + bool isTemplate) + { + QCString result=clName; + switch(compType) + { + case ClassDef::Class: result += " वर्ग"; break; + case ClassDef::Struct: result += " संरचना"; break; + case ClassDef::Union: result += " मिलन"; break; + case ClassDef::Interface: result += " अंतराफलक"; break; + case ClassDef::Protocol: result += " प्रोटोकॉल"; break; + case ClassDef::Category: result += " श्रेणी"; break; + case ClassDef::Exception: result += " अपवाद"; break; + default: break; + } + if (isTemplate) + result += " टेम्पलेट"; + result += " संदर्भ"; + return result; + } + + /*! used as the title of the HTML page of a file */ + virtual QCString trFileReference(const QCString &fileName) + { + QCString result = fileName; + result += " फ़ाइल संदर्भ"; + return result; + } + + /*! used as the title of the HTML page of a namespace */ + virtual QCString trNamespaceReference(const QCString &namespaceName) + { + QCString result = namespaceName; + result += " नाम-स्थान संदर्भ"; + return result; + } + + virtual QCString trPublicMembers() + { return "सार्वजनिक सदस्य फलनगण"; } + + virtual QCString trPublicSlots() + { return "सार्वजनिक खांचें"; } + + virtual QCString trSignals() + { return "संकेतगण"; } + + virtual QCString trStaticPublicMembers() + { return "अचल सार्वजनिक सदस्य फलनगण"; } + + virtual QCString trProtectedMembers() + { return "संरक्षित सदस्य फलनगण"; } + + virtual QCString trProtectedSlots() + { return "संरक्षित खांचे"; } + + virtual QCString trStaticProtectedMembers() + { return "अचल संरक्षित सदस्य फलनगण"; } + + virtual QCString trPrivateMembers() + { return "निजी सदस्य फलनगण"; } + + virtual QCString trPrivateSlots() + { return "निजी खांचें"; } + + virtual QCString trStaticPrivateMembers() + { return "अचल निजी सदस्य फलनगण"; } + + /*! this function is used to produce a comma-separated list of items. + * use generateMarker(i) to indicate where item i should be put. + */ + virtual QCString trWriteList(int numEntries) + { + QCString result; + int i; + // the inherits list contain `numEntries' classes + for (i = 0; i < numEntries; ++i) + { + // use generateMarker to generate placeholders for the class links! + result += generateMarker(i); // generate marker for entry i in the list + // (order is left to right) + if (i != numEntries - 1) // not the last entry, so we need a separator + { + if (i < numEntries - 2) // not the fore last entry + result += ", "; + else // the fore last entry + result += ", और "; + } + } + return result; + } + + /*! used in class documentation to produce a list of base classes, + * if class diagrams are disabled. + */ + virtual QCString trInheritsList(int numEntries) + { return trWriteList(numEntries) + " से विरासित।"; } + + /*! used in class documentation to produce a list of super classes, + * if class diagrams are disabled. + */ + virtual QCString trInheritedByList(int numEntries) + { return trWriteList(numEntries) + " द्वारा विरासित।"; } + + /*! used in member documentation blocks to produce a list of + * members that are hidden by this one. + */ + virtual QCString trReimplementedFromList(int numEntries) + { return trWriteList(numEntries) + " से पुन: लागू किया गया।"; } + + /*! used in member documentation blocks to produce a list of + * all member that overwrite the implementation of this member. + */ + virtual QCString trReimplementedInList(int numEntries) + { return trWriteList(numEntries) + " में पुन: लागू किया गया।"; } + + /*! This is put above each page as a link to all members of namespaces. */ + virtual QCString trNamespaceMembers() + { return "नाम-स्थान सदस्यगण"; } + + /*! This is an introduction to the page with all namespace members */ + virtual QCString trNamespaceMemberDescription(bool extractAll) + { + QCString result = "यहाँ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "नाम-स्थान सदस्यगण कि लिंको के साथ "; + if (extractAll) + result += "प्रत्येक सदस्य के नाम-स्थान दस्तावेज़ीकरण "; + else + result += "उनसे संबंधित नाम-स्थानों "; + result += "कि सूची दि गई हैं:"; + return result; + } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all namespaces. + */ + virtual QCString trNamespaceIndex() + { return "नाम-स्थान अनुक्रमणिका"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all namespaces. + */ + virtual QCString trNamespaceDocumentation() + { return "नाम-स्थान दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990522 +////////////////////////////////////////////////////////////////////////// + + /*! This is used in the documentation before the list of all + * namespaces in a file. + */ + virtual QCString trNamespaces() + { return "नाम-स्थानगण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990728 +////////////////////////////////////////////////////////////////////////// + + /*! This is put at the bottom of a class documentation page and is + * followed by a list of files that were used to generate the page. + */ + virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, + bool single) + { + // single is true implies a single file + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result; + switch (compType) + { + case ClassDef::Class: result += vhdlOpt ? "डिज़ाइन इकाई" : "वर्ग"; break; + case ClassDef::Struct: result += "संस्करण"; break; + case ClassDef::Union: result += "मिलन"; break; + case ClassDef::Interface: result += "अंतराफलक"; break; + case ClassDef::Protocol: result += "प्रोटोकॉल"; break; + case ClassDef::Category: result += "श्रेणी"; break; + case ClassDef::Exception: result += "अपवाद"; break; + default: break; + } + result += " के लिए दस्तावेज़ीकरण "; + if (single) + result += " फ़ाइल से उत्पन्न किया गया था:"; + else + result += " निम्न फ़ाइलों से उत्पन्न किया गया था:"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990901 +////////////////////////////////////////////////////////////////////////// + + /*! This is used as the heading text for the retval command. */ + virtual QCString trReturnValues() + { return "वापसी मान"; } + + /*! This is in the (quick) index as a link to the main page (index.html) + */ + virtual QCString trMainPage() + { return "मुख्य पृष्ठ"; } + + /*! This is used in references to page that are put in the LaTeX + * documentation. It should be an abbreviation of the word page. + */ + virtual QCString trPageAbbreviation() + { return "पृ."; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-991003 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trDefinedAtLineInSourceFile() + { return "फ़ाइल @1 की लाइन @0 पर परिभाषित।"; } + + virtual QCString trDefinedInSourceFile() + { return "फ़ाइल @0 में परिभाषित।"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-991205 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trDeprecated() + { return "पदावनत"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.0.0 +////////////////////////////////////////////////////////////////////////// + + /*! this text is put before a collaboration diagram */ + virtual QCString trCollaborationDiagram(const QCString &clName) + { return clName + " के लिए सहयोगीकरण आरेख:"; } + + /*! this text is put before an include dependency graph */ + virtual QCString trInclDepGraph(const QCString &fName) + { return fName + " के लिए निर्भरता लेखाचित्र शामिल करें:"; } + + /*! header that is put before the list of constructor/destructors. */ + virtual QCString trConstructorDocumentation() + { return "निर्माता और नाशक दस्तावेज़ीकरण"; } + + /*! Used in the file documentation to point to the corresponding sources. */ + virtual QCString trGotoSourceCode() + { return "इस फाइल कि स्त्रोत संकेत-लिपि को देखें।"; } + + /*! Used in the file sources to point to the corresponding documentation. */ + virtual QCString trGotoDocumentation() + { return "इस फ़ाइल के दस्तावेज़ीकरण पर जाएं।"; } + + /*! Text for the \\pre command */ + virtual QCString trPrecondition() + { return "पूर्वशर्त"; } + + /*! Text for the \\post command */ + virtual QCString trPostcondition() + { return "शर्तपश्चात्"; } + + /*! Text for the \\invariant command */ + virtual QCString trInvariant() + { return "अपरिवर्तनीय"; } + + /*! Text shown before a multi-line variable/enum initialization */ + virtual QCString trInitialValue() + { return "प्रारंभिक मूल्य:"; } + + /*! Text used the source code in the file index */ + virtual QCString trCode() + { return "संकेत-लिपि"; } + + virtual QCString trGraphicalHierarchy() + { return "चित्रात्मक वर्ग पदानुक्रम"; } + + virtual QCString trGotoGraphicalHierarchy() + { return "चित्रात्मक वर्ग पदानुक्रम पर जाएँ"; } + + virtual QCString trGotoTextualHierarchy() + { return "पाठ्य वर्ग पदानुक्रम पर जाएँ"; } + + virtual QCString trPageIndex() + { return "पृष्ठ अनुक्रमणिका"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.0 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trNote() + { return "ध्यान दें"; } + + virtual QCString trPublicTypes() + { return "सार्वजनिक प्ररुपगण"; } + + virtual QCString trPublicAttribs() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े भागगण"; + else + return "सार्वजनिक गुणगण"; + } + + virtual QCString trStaticPublicAttribs() + { return "अचल सार्वजनिक गुणगण"; } + + virtual QCString trProtectedTypes() + { return "संरक्षित प्ररुपगण"; } + + virtual QCString trProtectedAttribs() + { return "संरक्षित गुणगण"; } + + virtual QCString trStaticProtectedAttribs() + { return "अचल संरक्षित गुणगण"; } + + virtual QCString trPrivateTypes() + { return "निजी प्ररुपगण"; } + + virtual QCString trPrivateAttribs() + { return "निजी गुणगण"; } + + virtual QCString trStaticPrivateAttribs() + { return "अचल निजी गुणगण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.3 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a marker that is put before a \\todo item */ + virtual QCString trTodo() + { return "करने के लिए"; } + + /*! Used as the header of the todo list */ + virtual QCString trTodoList() + { return "करने के लिए सूची"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.4 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trReferencedBy() + { return "द्वारा संदर्भित"; } + + virtual QCString trRemarks() + { return "टिप्पणियाँ"; } + + virtual QCString trAttention() + { return "ध्यान"; } + + virtual QCString trInclByDepGraph() + { return "यह लेखाचित्र दिखाता है कि कौन सी फ़ाइलें प्रत्यक्ष या परोक्ष रूप से इस फ़ाइल को शामिल करती हैं:"; } + + virtual QCString trSince() + { return "जबसे"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.1.5 +////////////////////////////////////////////////////////////////////////// + + /*! title of the graph legend page */ + virtual QCString trLegendTitle() + { return "लेखाचित्र किंवदंती"; } + + /*! page explaining how the dot graph's should be interpreted + * The %A in the text below are to prevent link to classes called "A". + */ + virtual QCString trLegendDocs() + { + return + "यह पृष्ठ बताता है कि डॉक्सिजन द्वारा उत्पन्न लेखाचित्र की व्याख्या कैसे करें।\n" + "<p>\n" + "निम्नलिखित उदाहरण पर विचार करें:\n" + "\\code\n" + "/*! काट-छाँट के कारण अदृश्य वर्ग */\n" + "class Invisible { };\n\n" + "/*! वरासत संबंध छिपा हुआ है, वर्ग काट-छाँट दिया गया */\n" + "class Truncated : public Invisible { };\n\n" + "/* वर्ग को डॉक्सिजन टिप्पणियों के साथ दस्तावेज़ीकृत नहीं किया गया */\n" + "class Undocumented { };\n\n" + "/*! वह वर्ग जो सार्वजनिक वरासत का उपयोग करके विरासित की गई */\n" + "class PublicBase : public Truncated { };\n\n" + "/*! एक टेम्पलेट वर्ग */\n" + "template<class T> class Templ { };\n\n" + "/*! वह वर्ग जो संरक्षित वरासत का उपयोग करके विरासित की गई */\n" + "class ProtectedBase { };\n\n" + "/*! वह वर्ग जो निजी वरासत का उपयोग करके विरासित की गई */\n" + "class PrivateBase { };\n\n" + "/*! वह वर्ग जिसका उपयोग विरासित वर्ग द्वारा किया जाता हैं */\n" + "class Used { };\n\n" + "/*! उत्तम वर्ग जो कई अन्य वर्गों से वरासित हैं */\n" + "class Inherited : public PublicBase,\n" + " protected ProtectedBase,\n" + " private PrivateBase,\n" + " public Undocumented,\n" + " public Templ<int>\n" + "{\n" + " private:\n" + " Used *m_usedClass;\n" + "};\n" + "\\endcode\n" + "इसका परिणाम निम्नलिखित लेखाचित्र में होगा:" + "<p><center><img alt=\"\" src=\"graph_legend." + getDotImageExtension() + "\"></center></p>\n" + "<p>\n" + "उपरोक्त लेखाचित्र के डिब्बों के निम्नलिखित अर्थ हैं:\n" + "</p>\n" + "<ul>\n" + "<li>%A भरा ग्रे डिब्बा उस संरचना या वर्ग को दर्शाता है जिसके लिए लेखाचित्र बनाया गया हैं।</li>\n" + "<li>%A डिब्बा, काली बॉर्डर वाला, एक दस्तावेज़ीकृत संरचना या वर्ग को निरूपित करता हैं।</li>\n" + "<li>%A डिब्बा, ग्रे बॉर्डर वाला, एक निरदस्तावेज़ीकृत संरचना या वर्ग को निरूपित है।</li>\n" + "<li>%A डिब्बा, लाल बॉर्डर वाला, एक दस्तावेज़ीकृत संरचना या वर्ग को निरूपित है जिसके लिए " + "सभी वरासत संबंध नहीं दिखाए गए हैं। %A लेखाचित्र को काट-छाँट दिया जाता है यदि वह निर्दिष्ट " + "सीमाओं के भीतर नहीं समा पाता हैं।</li>\n" + "</ul>\n" + "<p>\n" + "तीर के निम्नलिखित अर्थ हैं:\n" + "</p>\n" + "<ul>\n" + "<li>%A गहरे नीले तीर का उपयोग दो वर्गों के बीच सार्वजनिक वरासत संबंध की कल्पना करने " + "के लिए किया जाता हैं।</li>\n" + "<li>%A गहरे हरे तीर का उपयोग संरक्षित वरासत के लिए किया जाता हैं।</li>\n" + "<li>%A गहरे लाल तीर का उपयोग निजी वरासत के लिए किया जाता हैं।</li>\n" + "<li>%A बैंगनी धराशायी तीर का उपयोग किया जाता है यदि कोई वर्ग समाहित है या किसी अन्य " + "वर्ग द्वारा उपयोग किया जाता है। तीर को परिवर्तनशील(गण) के साथ लेबल किया गया है जिसके " + "माध्यम से वर्ग या संरचना पहुंचने योग्य हैं।</li>\n" + "<li>%A पीला धराशायी तीर एक टेम्पलेट उदाहरण और उस टेम्पलेट वर्ग के बीच संबंध को दर्शाता " + "है जिससे इसे उदाहरणीत किया गया था। तीर को उदाहरण के टेम्पलेट मापदंड के साथ लेबल किया गया है।</li>\n" + "</ul>\n"; + } + + /*! text for the link to the legend page */ + virtual QCString trLegend() + { return "किंवदंती"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.0 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a marker that is put before a test item */ + virtual QCString trTest() + { return "परीक्षा"; } + /*! Used as the header of the test list */ + virtual QCString trTestList() + { return "परीक्षा सूची"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.2 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a section header for IDL properties */ + virtual QCString trProperties() + { return "संपत्तियाँ"; } + + /*! Used as a section header for IDL property documentation */ + virtual QCString trPropertyDocumentation() + { return "संपत्ति दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.4 +////////////////////////////////////////////////////////////////////////// + + /*! Used for Java classes in the summary section of Java packages */ + virtual QCString trClasses() + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + return "आंकड़े संरचनाएं"; + else + return "वर्गगण"; + } + + /*! Used as the title of a Java package */ + virtual QCString trPackage(const QCString &name) + { return "संकुल " + name; } + + /*! The description of the package index page */ + virtual QCString trPackageListDescription() + { return "यहाँ संक्षिप्त विवरण के साथ संकुल दिए गए हैं (यदि उपलब्ध हो):"; } + + /*! The link name in the Quick links header for each page */ + virtual QCString trPackages() + { return "संकुलगण"; } + + /*! Text shown before a multi-line define */ + virtual QCString trDefineValue() + { return "मूल्य:"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.5 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a marker that is put before a \\bug item */ + virtual QCString trBug() + { return "त्रुटि"; } + + /*! Used as the header of the bug list */ + virtual QCString trBugList() + { return "त्रुटि सूची"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.6 +////////////////////////////////////////////////////////////////////////// + + /*! Used as ansicpg for RTF file + * + * The following table shows the correlation of Charset name, Charset Value and + * <pre> + * Codepage number: + * Charset Name Charset Value(hex) Codepage number + * ------------------------------------------------------ + * DEFAULT_CHARSET 1 (x01) + * SYMBOL_CHARSET 2 (x02) + * OEM_CHARSET 255 (xFF) + * ANSI_CHARSET 0 (x00) 1252 + * RUSSIAN_CHARSET 204 (xCC) 1251 + * EE_CHARSET 238 (xEE) 1250 + * GREEK_CHARSET 161 (xA1) 1253 + * TURKISH_CHARSET 162 (xA2) 1254 + * BALTIC_CHARSET 186 (xBA) 1257 + * HEBREW_CHARSET 177 (xB1) 1255 + * ARABIC _CHARSET 178 (xB2) 1256 + * SHIFTJIS_CHARSET 128 (x80) 932 + * HANGEUL_CHARSET 129 (x81) 949 + * GB2313_CHARSET 134 (x86) 936 + * CHINESEBIG5_CHARSET 136 (x88) 950 + * </pre> + * + */ + virtual QCString trRTFansicp() + { return "65001"; } + + /*! Used as ansicpg for RTF fcharset + * \see trRTFansicp() for a table of possible values. + */ + virtual QCString trRTFCharSet() + { return "1252"; } + + /*! Used as header RTF general index */ + virtual QCString trRTFGeneralIndex() + { return "अनुक्रमणिका"; } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trClass(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "वर्ग"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trFile(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "फ़ाइल"; + if (!singular) + result += "ें"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trNamespace(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "नाम-स्थान"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trGroup(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "अनुखंड"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trPage(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "पृष्ठ"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trMember(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "सदस्य"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trGlobal(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "वैश्र्विक"; + if (!singular) + result += "गण"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.7 +////////////////////////////////////////////////////////////////////////// + + /*! This text is generated when the \\author command is used and + * for the author section in man pages. */ + virtual QCString trAuthor(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "लेखक"; + if (!singular) + result += "गण"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.11 +////////////////////////////////////////////////////////////////////////// + + /*! This text is put before the list of members referenced by a member + */ + virtual QCString trReferences() + { return "संदर्भ"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.13 +////////////////////////////////////////////////////////////////////////// + + /*! used in member documentation blocks to produce a list of + * members that are implemented by this one. + */ + virtual QCString trImplementedFromList(int numEntries) + { return trWriteList(numEntries) + " लागू करता है।"; } + + /*! used in member documentation blocks to produce a list of + * all members that implement this abstract member. + */ + virtual QCString trImplementedInList(int numEntries) + { return trWriteList(numEntries) + " में लागू करता है।"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.16 +////////////////////////////////////////////////////////////////////////// + + /*! used in RTF documentation as a heading for the Table + * of Contents. + */ + virtual QCString trRTFTableOfContents() + { return "विषय-सूची"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { return "पदावनत सूची"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.18 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a header for declaration section of the events found in + * a C# program + */ + virtual QCString trEvents() + { return "घटनाएं"; } + + /*! Header used for the documentation section of a class' events. */ + virtual QCString trEventDocumentation() + { return "घटना दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a heading for a list of Java class types with package scope. + */ + virtual QCString trPackageTypes() + { return "संकुल प्ररूपगण"; } + + /*! Used as a heading for a list of Java class functions with package + * scope. + */ + virtual QCString trPackageFunctions() + { return "संकुल फलनगण"; } + virtual QCString trPackageMembers() + { return "संकुल सदस्यगण"; } + + /*! Used as a heading for a list of static Java class functions with + * package scope. + */ + virtual QCString trStaticPackageFunctions() + { return "अचल संकुल फलनगण"; } + + /*! Used as a heading for a list of Java class variables with package + * scope. + */ + virtual QCString trPackageAttribs() + { return "संकुल गुणगण"; } + + /*! Used as a heading for a list of static Java class variables with + * package scope. + */ + virtual QCString trStaticPackageAttribs() + { return "अचल संकुल गुणगण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.1 +////////////////////////////////////////////////////////////////////////// + + /*! Used in the quick index of a class/file/namespace member list page + * to link to the unfiltered list of all members. + */ + virtual QCString trAll() + { return "सभी"; } + + /*! Put in front of the call graph for a function. */ + virtual QCString trCallGraph() + { return "इस फलन के लिए बुलावा लेखाचित्र यहां दिया गया है:"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.3 +////////////////////////////////////////////////////////////////////////// + + /*! This string is used as the title for the page listing the search + * results. + */ + virtual QCString trSearchResultsTitle() + { return "खोज के परिणामगण"; } + + /*! This string is put just before listing the search results. The + * text can be different depending on the number of documents found. + * Inside the text you can put the special marker $num to insert + * the number representing the actual number of search results. + * The @a numDocuments parameter can be either 0, 1 or 2, where the + * value 2 represents 2 or more matches. HTML markup is allowed inside + * the returned string. + */ + virtual QCString trSearchResults(int numDocuments) + { + if (numDocuments == 0) + return "क्षमा करें, आपकी जिज्ञासा से मेल खाने वाला कोई दस्तावेज़ नहीं है।"; + else if (numDocuments == 1) + return "आपकी जिज्ञासा से मेल खाने वाला <b>1</b> दस्तावेज़ मिला।"; + else + return "आपकी जिज्ञासा से मेल खाने वाले <b>$num</b> दस्तावेज़ मिले। सर्वश्रेष्ठ मिलान पहले दिखा रहे हैं।"; + } + + /*! This string is put before the list of matched words, for each search + * result. What follows is the list of words that matched the query. + */ + virtual QCString trSearchMatches() + { return "मिलानगण:"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.8 +////////////////////////////////////////////////////////////////////////// + + /*! This is used in HTML as the title of page with source code for file filename + */ + virtual QCString trSourceFile(QCString& filename) + { return filename + " स्त्रोत फ़ाइल"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.3.9 +////////////////////////////////////////////////////////////////////////// + + /*! This is used as the name of the chapter containing the directory + * hierarchy. + */ + virtual QCString trDirIndex() + { return "निर्देशिकाएं पदानुक्रम"; } + + /*! This is used as the name of the chapter containing the documentation + * of the directories. + */ + virtual QCString trDirDocumentation() + { return "निर्देशिका दस्तावेज़ीकरण"; } + + /*! This is used as the title of the directory index and also in the + * Quick links of an HTML page, to link to the directory hierarchy. + */ + virtual QCString trDirectories() + { return "निर्देशिकाएं"; } + + /*! This returns the title of a directory page. The name of the + * directory is passed via \a dirName. + */ + virtual QCString trDirReference(const QCString &dirName) + { + QCString result = dirName; + result += " निर्देशिका संदर्भ"; + return result; + } + + /*! This returns the word directory with or without starting capital + * (\a first_capital) and in singular or plural form (\a singular). + */ + virtual QCString trDir(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "निर्देशिका"; + if (!singular) + result += "एं"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.1 +////////////////////////////////////////////////////////////////////////// + + /*! This text is added to the documentation when the \\overload command + * is used for a overloaded function. + */ + virtual QCString trOverloadText() + { + return "यह अतिभारित सदस्य फलन सुविधा के लिए प्रदान किया गया है। यह उपरोक्त" + " फलन से केवल इस बात में भिन्न है कि यह किस तर्क को स्वीकार करता है।"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.6 +////////////////////////////////////////////////////////////////////////// + + /*! This is used to introduce a caller (or called-by) graph */ + virtual QCString trCallerGraph() + { + return "इस फलन के लिए बुलावा लेखाचित्र यहाँ दिया गया है:"; + } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration values + */ + virtual QCString trEnumerationValueDocumentation() + { return "परिगणक दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.5.4 (mainly for Fortran) +////////////////////////////////////////////////////////////////////////// + + /*! header that is put before the list of member subprograms (Fortran). */ + virtual QCString trMemberFunctionDocumentationFortran() + { return "सदस्य फलन/उपफलन दस्तावेज़ीकरण"; } + + /*! This is put above each page as a link to the list of annotated data types (Fortran). */ + virtual QCString trCompoundListFortran() + { return "आंकड़े प्ररुपगण सूची"; } + + /*! This is put above each page as a link to all members of compounds (Fortran). */ + virtual QCString trCompoundMembersFortran() + { return "आंकड़े भागगण"; } + + /*! This is an introduction to the annotated compound list (Fortran). */ + virtual QCString trCompoundListDescriptionFortran() + { return "यहाँ संक्षिप्त विवरण के साथ आँकड़े प्ररूपगण हैं:"; } + + /*! This is an introduction to the page with all data types (Fortran). */ + virtual QCString trCompoundMembersDescriptionFortran(bool extractAll) + { + QCString result = "यहाँ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "आंकड़े प्ररूपगण कि लिंको के साथ "; + if (!extractAll) + result += "प्रत्येक सदस्य के आंकड़े संरचना दस्तावेज़ीकरण "; + else + result += "उनसे संबंधित आंकड़े प्ररूपगण "; + result += "कि सूची दि गई हैं:"; + return result; + } + + /*! This is used in LaTeX as the title of the chapter with the + * annotated compound index (Fortran). + */ + virtual QCString trCompoundIndexFortran() + { return "आंकड़े प्ररुप अनुक्रमणिका"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all data types (Fortran). + */ + virtual QCString trTypeDocumentation() + { return "आंकड़े प्ररुप दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) subprograms (Fortran). + */ + virtual QCString trSubprograms() + { return "फलनगण/उपफलनगण"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for subprograms (Fortran) + */ + virtual QCString trSubprogramDocumentation() + { return "फलन/उपफलन दस्तावेज़ीकरण"; } + + /*! This is used in the documentation of a file/namespace/group before + * the list of links to documented compounds (Fortran) + */ + virtual QCString trDataTypes() + { return "आंकड़े प्ररुपगण"; } + + /*! used as the title of page containing all the index of all modules (Fortran). */ + virtual QCString trModulesList() + { return "अनुखंडगण सूची"; } + + /*! used as an introduction to the modules list (Fortran) */ + virtual QCString trModulesListDescription(bool extractAll) + { + QCString result = "यहाँ संक्षिप्त विवरण के साथ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "अनुखंडगण की सूची दी गई है:"; + return result; + } + + /*! used as the title of the HTML page of a module/type (Fortran) */ + virtual QCString trCompoundReferenceFortran( + const QCString &clName, + ClassDef::CompoundType compType, + bool isTemplate) + { + QCString result = clName; + switch (compType) + { + case ClassDef::Class: result+=" अनुखंड"; break; + case ClassDef::Struct: result+=" प्ररुप"; break; + case ClassDef::Union: result+=" मिलन"; break; + case ClassDef::Interface: result+=" अंतराफलक"; break; + case ClassDef::Protocol: result+=" प्रोटोकॉल"; break; + case ClassDef::Category: result+=" श्रेणी"; break; + case ClassDef::Exception: result+=" अपवाद"; break; + default: break; + } + if (isTemplate) + result += " टेम्पलेट"; + result += " संदर्भ"; + return result; + } + + /*! used as the title of the HTML page of a module (Fortran) */ + virtual QCString trModuleReference(const QCString &namespaceName) + { + QCString result = namespaceName; + result += " अनुखंड संदर्भ"; + return result; + } + + /*! This is put above each page as a link to all members of modules. (Fortran) */ + virtual QCString trModulesMembers() + { return "अनुखंडगण सदस्यगण"; } + + /*! This is an introduction to the page with all modules members (Fortran) */ + virtual QCString trModulesMemberDescription(bool extractAll) + { + QCString result = "यहाँ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "अनुखंड सदस्यगण कि लिंको के साथ "; + if (extractAll) + result += "प्रत्येक सदस्य के दस्तावेज़ीकरण "; + else + result += "उनसे संबंधित अनुखंडगण "; + result += "कि सूची दि गई हैं:"; + return result; + } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all modules (Fortran). + */ + virtual QCString trModulesIndex() + { return "अनुखंडगण अनुक्रमणिका"; } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trModule(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "अनुखंड"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is put at the bottom of a module documentation page and is + * followed by a list of files that were used to generate the page. + */ + virtual QCString trGeneratedFromFilesFortran( + ClassDef::CompoundType compType, + bool single) + { + // single is true implies a single file + QCString result; + switch(compType) + { + case ClassDef::Class: result += "अनुखंड"; break; + case ClassDef::Struct: result += "प्ररुप"; break; + case ClassDef::Union: result += "मिलन"; break; + case ClassDef::Interface: result += "अंतराफलक"; break; + case ClassDef::Protocol: result += "प्रोटोकॉल"; break; + case ClassDef::Category: result += "श्रेणी"; break; + case ClassDef::Exception: result += "अपवाद"; break; + default: break; + } + result += " के लिए दस्तावेज़ीकरण "; + if (single) + result += " फ़ाइल से उत्पन्न किया गया था:"; + else + result += " निम्न फ़ाइलों से उत्पन्न किया गया था:"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trType(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "प्ररुप"; + if (!singular) + result += "गण"; + return result; + } + + /*! This is used for translation of the word that will possibly + * be followed by a single name or by a list of names + * of the category. + */ + virtual QCString trSubprogram(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "उपप्रोग्राम"; + if (!singular) + result += "गण"; + return result; + } + + /*! C# Type Constraint list */ + virtual QCString trTypeConstraints() + { return "प्ररुप बाध्यताएं"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.6.0 (mainly for the new search engine) +////////////////////////////////////////////////////////////////////////// + + /*! directory relation for \a name */ + virtual QCString trDirRelation(const QCString &name) + { return name + " रिश्ता"; } + + /*! Loading message shown when loading search results */ + virtual QCString trLoading() + { return "लादा जा रहा..."; } + + /*! Label used for search results in the global namespace */ + virtual QCString trGlobalNamespace() + { return "वैश्र्विक नाम-स्थान"; } + + /*! Message shown while searching */ + virtual QCString trSearching() + { return "खोजां जा रहा..."; } + + /*! Text shown when no search results are found */ + virtual QCString trNoMatches() + { return "कोई समानता नहीं"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.6.3 (missing items for the directory pages) +////////////////////////////////////////////////////////////////////////// + + /*! when clicking a directory dependency label, a page with a + * table is shown. The heading for the first column mentions the + * source file that has a relation to another file. + */ + virtual QCString trFileIn(const QCString &name) + { return name + " में फ़ाइल"; } + + /*! when clicking a directory dependency label, a page with a + * table is shown. The heading for the second column mentions the + * destination file that is included. + */ + virtual QCString trIncludesFileIn(const QCString &name) + { return name + " में फ़ाइल शामिल है"; } + + /** Compiles a date string. + * @param year Year in 4 digits + * @param month Month of the year: 1=January + * @param day Day of the Month: 1..31 + * @param dayOfWeek Day of the week: 1=Monday..7=Sunday + * @param hour Hour of the day: 0..23 + * @param minutes Minutes in the hour: 0..59 + * @param seconds Seconds within the minute: 0..59 + * @param includeTime Include time in the result string? + */ + virtual QCString trDateTime( + int year, int month, int day, int dayOfWeek, + int hour, int minutes, int seconds, bool includeTime) + { + static const char *days[] = { "सोमवार", "मंगलवार", "बुधवार", "गुरुवार", + "शुक्रवार", "शनिवार", "रविवार" }; + static const char *months[] = { "जनवरी", "फरवरी", "मार्च", "अप्रैल", "मई", "जून", + "जुलाई", "अगस्त", "सितम्बर", "अक्टूबर", "नवम्बर", "दिसम्बर" }; + QCString sdate; + sdate.sprintf("%s %s %d %d", days[dayOfWeek - 1], months[month - 1], day, year); + if (includeTime) + { + QCString stime; + stime.sprintf(" %.2d:%.2d:%.2d", hour, minutes, seconds); + sdate += stime; + } + return sdate; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.7.5 +////////////////////////////////////////////////////////////////////////// + + /*! Header for the page with bibliographic citations */ + virtual QCString trCiteReferences() + { return "ग्रन्थसूची"; } + + /*! Text for copyright paragraph */ + virtual QCString trCopyright() + { return "कॉपीराइट"; } + + /*! Header for the graph showing the directory dependencies */ + virtual QCString trDirDepGraph(const QCString &name) + { return name + " के लिए निर्देशिका निर्भरता लेखाचित्र:"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.0 +////////////////////////////////////////////////////////////////////////// + + /*! Detail level selector shown for hierarchical indices */ + virtual QCString trDetailLevel() + { return "विस्तार स्तर"; } + + /*! Section header for list of template parameters */ + virtual QCString trTemplateParameters() + { return "टेम्पलेट मापदंड"; } + + /*! Used in dot graph when UML_LOOK is enabled and there are many fields */ + virtual QCString trAndMore(const QCString &number) + { return "और " + number + " अधिक..."; } + + /*! Used file list for a Java enum */ + virtual QCString trEnumGeneratedFromFiles(bool single) + { + QCString result = "इस परिगणक के लिए दस्तावेज़ीकरण निम्न फ़ाइल"; + if (!single) + result += "ों"; + result += " से उत्पन्न किया गया था:"; + return result; + } + + /*! Header of a Java enum page (Java enums are represented as classes). */ + virtual QCString trEnumReference(const QCString &name) + { return name + " परिगणक संदर्भ"; } + + /*! Used for a section containing inherited members */ + virtual QCString trInheritedFrom(const QCString &members,const QCString &what) + { return what + " से विरासत में मिले " + members; } + + /*! Header of the sections with inherited members specific for the + * base class(es) + */ + virtual QCString trAdditionalInheritedMembers() + { return "अतिरिक्त विरासत में मिले सदस्य"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.2 +////////////////////////////////////////////////////////////////////////// + + /*! Used as a tooltip for the toggle button that appears in the + * navigation tree in the HTML output when GENERATE_TREEVIEW is + * enabled. This tooltip explains the meaning of the button. + */ + virtual QCString trPanelSynchronisationTooltip(bool enable) + { + QCString opt = enable ? "चालू" : "बंद"; + return "पैनल सिंक्रनाइज़ीकरण " + opt + " करने के लिए क्लिक करें"; + } + + /*! Used in a method of an Objective-C class that is declared in a + * a category. Note that the @1 marker is required and is replaced + * by a link. + */ + virtual QCString trProvidedByCategory() + { return "श्रेणी @0 द्वारा प्रदान किया गया।"; } + + /*! Used in a method of an Objective-C category that extends a class. + * Note that the @1 marker is required and is replaced by a link to + * the class method. + */ + virtual QCString trExtendsClass() + { return "वर्ग @0 को विस्तार करता है।"; } + + /*! Used as the header of a list of class methods in Objective-C. + * These are similar to static public member functions in C++. + */ + virtual QCString trClassMethods() + { return "वर्ग विधियाँ"; } + + /*! Used as the header of a list of instance methods in Objective-C. + * These are similar to public member functions in C++. + */ + virtual QCString trInstanceMethods() + { return "उदाहरण विधियाँ"; } + + /*! Used as the header of the member functions of an Objective-C class. + */ + virtual QCString trMethodDocumentation() + { return "विधि दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.4 +////////////////////////////////////////////////////////////////////////// + + /** old style UNO IDL services: implemented interfaces */ + virtual QCString trInterfaces() + { return "निर्यातीत अंतराफलकगण"; } + + /** old style UNO IDL services: inherited services */ + virtual QCString trServices() + { return "शामिलीत सेवाएं"; } + + /** UNO IDL constant groups */ + virtual QCString trConstantGroups() + { return "स्थिर समूहगण"; } + + /** UNO IDL constant groups */ + virtual QCString trConstantGroupReference(const QCString &namespaceName) + { + QCString result = namespaceName; + result += " स्थिर समूह संदर्भ"; + return result; + } + + /** UNO IDL service page title */ + virtual QCString trServiceReference(const QCString &sName) + { + QCString result = sName; + result += " सेवा संदर्भ"; + return result; + } + + /** UNO IDL singleton page title */ + virtual QCString trSingletonReference(const QCString &sName) + { + QCString result = sName; + result += " एकल संदर्भ"; + return result; + } + + /** UNO IDL service page */ + virtual QCString trServiceGeneratedFromFiles(bool single) + { + // single is true implies a single file + QCString result = "इस सेवा के लिए दस्तावेज़ीकरण निम्न फ़ाइल"; + if (!single) + result += "ों"; + result += " से उत्पन्न किया गया था:"; + return result; + } + + /** UNO IDL singleton page */ + virtual QCString trSingletonGeneratedFromFiles(bool single) + { + // single is true implies a single file + QCString result = "इस एकल के लिए दस्तावेज़ीकरण निम्न फ़ाइल"; + if (!single) + result += "ों"; + result += " से उत्पन्न किया गया था:"; + return result; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "डिज़ाइन इकाई पदानुक्रम"; } + + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "डिज़ाइन इकाई सूची"; } + + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "डिज़ाइन इकाई सदस्यगण"; } + + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { return "यहाँ उन सभी डिज़ाइन इकाई सदस्यों की सूची उनसे संबंधित इकाईयों की लिंक के साथ दी गई हैं:"; } + + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "डिज़ाइन इकाई अनुक्रमणिका"; } + + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "डिज़ाइन इकाईयाँ"; } + + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "फलनगण/कार्यविधियाँ/प्रक्रियाएं"; } + + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch (type) + { + case VhdlDocGen::LIBRARY: + if (single) return "संग्रह"; + else return "संग्रहगण"; + case VhdlDocGen::PACKAGE: + if (single) return "संकुल"; + else return "संकुलगण"; + case VhdlDocGen::SIGNAL: + if (single) return "संकेत"; + else return "संकेतगण"; + case VhdlDocGen::COMPONENT: + if (single) return "अंग"; + else return "अंगगण"; + case VhdlDocGen::CONSTANT: + if (single) return "स्थिर"; + else return "स्थिरगण"; + case VhdlDocGen::ENTITY: + if (single) return "इकाई"; + else return "इकाईयाँ"; + case VhdlDocGen::TYPE: + if (single) return "प्ररूप"; + else return "प्ररूपगण"; + case VhdlDocGen::SUBTYPE: + if (single) return "उपप्ररूप"; + else return "उपप्ररूपगण"; + case VhdlDocGen::FUNCTION: + if (single) return "फलन"; + else return "फलनगण"; + case VhdlDocGen::RECORD: + if (single) return "अभिलेख"; + else return "अभिलेखगण"; + case VhdlDocGen::PROCEDURE: + if (single) return "कार्यविधि"; + else return "कार्यविधियाँ"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "वास्तुकला"; + else return "वास्तुकलाएं"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "तर्क"; + else return "तर्कगण"; + case VhdlDocGen::PROCESS: + if (single) return "प्रक्रिया"; + else return "प्रक्रियाएं"; + case VhdlDocGen::PORT: + if (single) return "द्वार"; + else return "द्वारगण"; + case VhdlDocGen::USE: + if (single) return "प्रयोग खंड"; + else return "प्रयोग खंडगण"; + case VhdlDocGen::GENERIC: + if (single) return "सामान्य"; + else return "सामान्यगण"; + case VhdlDocGen::PACKAGE_BODY: + return "संकुल शरीर"; + case VhdlDocGen::UNITS: + return "इकाईयाँ"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "साझाकृत परिवर्तनशील"; + else return "साझाकृत परिवर्तनशीलगण"; + case VhdlDocGen::VFILE: + if (single) return "फ़ाइल"; + else return "फ़ाइलगण"; + case VhdlDocGen::GROUP: + if (single) return "समूह"; + else return "समूहगण"; + case VhdlDocGen::INSTANTIATION: + if (single) return "उदाहरणीकरण"; + else return "उदाहरणीकरणगण"; + case VhdlDocGen::ALIAS: + if (single) return "उपनाम"; + else return "उपनामगण"; + case VhdlDocGen::CONFIG: + if (single) return "विन्यास"; + else return "विन्यासगण"; + case VhdlDocGen::MISCELLANEOUS: + return "विविध"; + case VhdlDocGen::UCF_CONST: + return "बाध्यताएं"; + default: + return "वर्ग"; + } + } + + virtual QCString trCustomReference(const QCString &name) + { return name + " संदर्भ"; } + + virtual QCString trConstants() + { return "स्थिरगण"; } + + virtual QCString trConstantDocumentation() + { return "स्थिर दस्तावेज़ीकरण"; } + + virtual QCString trSequences() + { return "अनुक्रमगण"; } + + virtual QCString trSequenceDocumentation() + { return "अनुक्रम दस्तावेज़ीकरण"; } + + virtual QCString trDictionaries() + { return "शब्दकोशगण"; } + + virtual QCString trDictionaryDocumentation() + { return "शब्दकोश दस्तावेज़ीकरण"; } + + virtual QCString trSliceInterfaces() + { return "अंतराफलकगण"; } + + virtual QCString trInterfaceIndex() + { return "अंतराफलक अनुक्रमणिका"; } + + virtual QCString trInterfaceList() + { return "अंतराफलक सूची"; } + + virtual QCString trInterfaceListDescription() + { return "यहाँ संक्षिप्त विवरण के साथ अंतराफलकगण हैं:"; } + + virtual QCString trInterfaceHierarchy() + { return "अंतराफलक पदानुक्रम"; } + + virtual QCString trInterfaceHierarchyDescription() + { return "यह अंतराफलक विरासत सूची मोटे तौर पर क्रमबद्ध है, लेकिन पूरी तरह से नहीं, वर्णानुक्रम में:"; } + + virtual QCString trInterfaceDocumentation() + { return "अंतराफलक दस्तावेज़ीकरण"; } + + virtual QCString trStructs() + { return "संरचनाएं"; } + + virtual QCString trStructIndex() + { return "संरचना अनुक्रमणिका"; } + + virtual QCString trStructList() + { return "संरचना सूची"; } + + virtual QCString trStructListDescription() + { return "यहाँ संक्षिप्त विवरण के साथ संरचनाएं हैं:"; } + + virtual QCString trStructDocumentation() + { return "संरचना दस्तावेज़ीकरण"; } + + virtual QCString trExceptionIndex() + { return "अपवाद अनुक्रमणिका"; } + + virtual QCString trExceptionList() + { return "अपवाद सूची"; } + + virtual QCString trExceptionListDescription() + { return "यहाँ संक्षिप्त विवरण के साथ अपवादगण हैं:"; } + + virtual QCString trExceptionHierarchy() + { return "अपवाद पदानुक्रम"; } + + virtual QCString trExceptionHierarchyDescription() + { return "यह अपवाद विरासत सूची मोटे तौर पर क्रमबद्ध है, लेकिन पूरी तरह से नहीं, वर्णानुक्रम में:"; } + + virtual QCString trExceptionDocumentation() + { return "अपवाद दस्तावेज़ीकरण"; } + + virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result = clName; + if (isLocal) result += " स्थानीय"; + switch (compType) + { + case ClassDef::Class: result+=" वर्ग"; break; + case ClassDef::Struct: result+=" संरचना"; break; + case ClassDef::Union: result+=" मिलन"; break; + case ClassDef::Interface: result+=" अंतराफलक"; break; + case ClassDef::Protocol: result+=" प्रोटोकॉल"; break; + case ClassDef::Category: result+=" श्रेणी"; break; + case ClassDef::Exception: result+=" अपवाद"; break; + default: break; + } + result += " संदर्भ"; + return result; + } + + virtual QCString trOperations() + { return "कार्यवाहीयाँ"; } + + virtual QCString trOperationDocumentation() + { return "कार्यवाही दस्तावेज़ीकरण"; } + + virtual QCString trDataMembers() + { return "आंकड़े सदस्यगण"; } + + virtual QCString trDataMemberDocumentation() + { return "आंकड़े सदस्य दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.19 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit documentation */ + virtual QCString trDesignUnitDocumentation() + { return "डिज़ाइन इकाई दस्तावेज़ीकरण"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.9.2 +////////////////////////////////////////////////////////////////////////// + + /** C++20 concept */ + virtual QCString trConcept(bool first_capital, bool singular) + { + // There is no first-letter capitalization notion in Hindi. + QCString result = "संकल्पना"; + if (!singular) result += "एं"; + return result; + } + /*! used as the title of the HTML page of a C++20 concept page */ + virtual QCString trConceptReference(const QCString &conceptName) + { + QCString result = conceptName; + result += " संकल्पना संदर्भ"; + return result; + } + + /*! used as the title of page containing all the index of all concepts. */ + virtual QCString trConceptList() + { return "संकल्पना सूची"; } + + /*! used as the title of chapter containing the index listing all concepts. */ + virtual QCString trConceptIndex() + { return "संकल्पना अनुक्रमणिका"; } + + /*! used as the title of chapter containing all information about concepts. */ + virtual QCString trConceptDocumentation() + { return "संकल्पना दस्तावेज़ीकरण"; } + + /*! used as an introduction to the concept list */ + virtual QCString trConceptListDescription(bool extractAll) + { + QCString result = "यहाँ संक्षिप्त विवरण के साथ सभी "; + if (!extractAll) + result += "दस्तावेज़ीकृत "; + result += "संकल्पनाएं की सूची दी गई है:"; + return result; + } + + /*! used to introduce the definition of the C++20 concept */ + virtual QCString trConceptDefinition() + { return "संकल्पना परिभाषा"; } +}; + +#endif diff --git a/src/translator_hr.h b/src/translator_hr.h index 9f9f841..1329f1c 100644 --- a/src/translator_hr.h +++ b/src/translator_hr.h @@ -94,6 +94,10 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 { return "\\usepackage[croatian]{babel}\n"; } QCString trISOLang() { return "hr"; } + virtual QCString getLanguageString() + { + return "0x41A Croatian"; + } QCString trRelatedFunctions() { return "Povezane funkcije"; } QCString trRelatedSubscript() @@ -120,7 +124,7 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 { return ", uključujući naslijeđene članove."; } QCString trGeneratedAutomatically(const QCString &s) { QCString result="napravljeno automatski Doxygen-om"; - if (!s.isEmpty()) result+=(QCString)" za "+s; + if (!s.isEmpty()) result+=" za "+s; result+=" iz programskog koda."; return result; } @@ -234,30 +238,32 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 } else { - return "Skupno kazalo "; + return "Skupno kazalo "; } - } + } QCString trFileIndex() { return "Kazalo datoteka"; } QCString trModuleDocumentation() { return "Dokumentacija modula"; } QCString trClassDocumentation() { - if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) - { - return "Dokumentacija struktura podataka"; - } - else - { - return "Dokumentacija klasa"; - } - } + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Dokumentacija struktura podataka"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } + else + { + return "Dokumentacija klasa"; + } + } QCString trFileDocumentation() { return "Dokumentacija datoteka"; } QCString trExampleDocumentation() { return "Dokumentacija primjera"; } - QCString trPageDocumentation() - { return "Dokumentacija vezane stranice"; } QCString trReferenceManual() { return "Priručnik"; } @@ -287,8 +293,8 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 { return "Strukture"; } QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Napravljeno "+date; - if (!projName.isEmpty()) result+=(QCString)" projekt: "+projName; + QCString result="Napravljeno "+date; + if (!projName.isEmpty()) result+=" projekt: "+projName; result+=" generator: "; return result; } @@ -296,8 +302,6 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 { return QCString("Dijagram klasa za ")+clName; } - QCString trForInternalUseOnly() - { return "Isključivo za internu uporabu."; } QCString trWarning() { return "Upozorenje"; } QCString trVersion() @@ -561,12 +565,12 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 /*! this text is put before a collaboration diagram */ QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Kolaboracijski dijagram za "+clName+ ":"; + return "Kolaboracijski dijagram za "+clName+ ":"; } /*! this text is put before an include dependency graph */ QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graf include međuovisnosti za "+fName+":"; + return "Graf include međuovisnosti za "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ QCString trConstructorDocumentation() @@ -826,12 +830,7 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista paketa"; + return "Paket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1060,14 +1059,18 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funkcije u paketu"; } + virtual QCString trPackageMembers() + { + return "članovi u paketu"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statičke funkcije u paketu"; } @@ -1185,12 +1188,6 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 virtual QCString trDirectories() { return "Direktoriji"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Stablo direktorija sortirano abecednim redom:"; } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1324,7 +1321,7 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Modul"; break; @@ -1392,7 +1389,7 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 bool) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentacija ovog "; + QCString result="Dokumentacija ovog "; switch(compType) { case ClassDef::Class: result+="modula"; break; @@ -1477,7 +1474,7 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Datoteka u "+name; + return "Datoteka u "+name; } /*! when clicking a directory dependency label, a page with a @@ -1486,7 +1483,7 @@ class TranslatorCroatian : public TranslatorAdapter_1_8_2 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Uključuje datotake u "+name; + return "Uključuje datotake u "+name; } /** Compiles a date string. diff --git a/src/translator_hu.h b/src/translator_hu.h index 67f3570..ccf35db 100644 --- a/src/translator_hu.h +++ b/src/translator_hu.h @@ -104,6 +104,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 { return "hu"; } + virtual QCString getLanguageString() + { + return "0x40E Hungarian"; + } // --- Language translation methods ------------------- @@ -169,7 +173,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Ezt a dokumentációt a Doxygen készítette "; - if (!s.isEmpty()) result+=(QCString)" a" + zed(s[0])+s+(QCString)" projekthez"; + if (!s.isEmpty()) result+=QCString(" a") + zed(s[0])+s+" projekthez"; result+=" a forráskódból."; return result; } @@ -418,6 +422,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 { return "Adatszerkezetek dokumentációja"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Osztályok dokumentációja"; @@ -436,12 +444,6 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Példák dokumentációja"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Kapcsolódó dokumentációk"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referencia kézikönyv"; } @@ -532,22 +534,18 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)""; - if (!projName.isEmpty()) result+=(QCString)"Projekt: "+projName; - result+=(QCString)" Készült: "+date+" Készítette: "; + QCString result=""; + if (!projName.isEmpty()) result+="Projekt: "+projName; + result+=" Készült: "+date+" Készítette: "; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"A"+zed(clName[0])+clName+" osztály származási diagramja:"; + return QCString("A")+zed(clName[0])+clName+" osztály származási diagramja:"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "CSAK BELSŐ HASZNÁLATRA!"; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Figyelmeztetés"; } @@ -622,7 +620,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" osztály"; break; @@ -781,7 +779,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) { // single is true implies a single file - QCString result=(QCString)"Ez a dokumentáció "; + QCString result="Ez a dokumentáció "; switch(compType) { case ClassDef::Class: result+="az osztályról"; break; @@ -847,12 +845,12 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"A"+zed(clName[0])+clName+" osztály együttműködési diagramja:"; + return QCString("A")+zed(clName[0])+clName+" osztály együttműködési diagramja:"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"A"+zed(fName[0])+fName+" definíciós fájl függési gráfja:"; + return QCString("A")+zed(fName[0])+fName+" definíciós fájl függési gráfja:"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1133,12 +1131,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return name+(QCString)" csomag"; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Csomaglista"; + return name+" csomag"; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1396,14 +1389,18 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Csomag függvények"; } + virtual QCString trPackageMembers() + { + return "Csomag tagok"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statikus csomag függvények"; } @@ -1515,14 +1512,6 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Könyvtárak"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Majdnem (de nem teljesen) betűrendbe szedett " - "könyvtárhierarchia:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1657,7 +1646,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" modul"; break; @@ -1726,7 +1715,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 bool single) { // single is true implies a single file - QCString result=(QCString)"Ez a dokumentáció "; + QCString result="Ez a dokumentáció "; switch(compType) { case ClassDef::Class: result+="a modulról"; break; @@ -1816,7 +1805,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Fájl a(z) "+name+" könyvtárban"; + return "Fájl a(z) "+name+" könyvtárban"; } /*! when clicking a directory dependency label, a page with a @@ -1825,7 +1814,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Tartalmazott fájl a(z) "+name+" könyvtárban"; + return "Tartalmazott fájl a(z) "+name+" könyvtárban"; } /** Compiles a date string. @@ -1990,14 +1979,14 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" szolgáltatás referencia"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" egyke példány referencia"; return result; } @@ -2005,7 +1994,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"A szolgáltatás dokumentációja " + QCString result="A szolgáltatás dokumentációja " "a következő fájl"; if (single) result+="ból"; else result+="okból"; result+="lett létrehozva:"; @@ -2015,7 +2004,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Az egyke példány dokomentációja " + QCString result="Az egyke példány dokomentációja " "a következő fájl"; if (single) result+="ból"; else result+="okból"; result+="lett létrehozva:"; diff --git a/src/translator_id.h b/src/translator_id.h index cb7ae2e..1e4052f 100644 --- a/src/translator_id.h +++ b/src/translator_id.h @@ -62,6 +62,10 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 { return "id"; } + virtual QCString getLanguageString() + { + return "0x421 Indonesian"; + } // --- Language translation methods ------------------- @@ -127,7 +131,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Dibangkitkan secara otomatis oleh Doxygen"; - if (!s.isEmpty()) result+=(QCString)" untuk "+s; + if (!s.isEmpty()) result+=" untuk "+s; result+=" dari kode sumber."; return result; } @@ -374,6 +378,10 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 { return "Dokumentasi Struktur Data"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Dokumentasi Kelas"; @@ -392,12 +400,6 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 virtual QCString trExampleDocumentation() { return "Dokumentasi Contoh"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Dokumentasi Halaman"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Dokumen Referensi"; } @@ -488,22 +490,18 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Dibangkitkan pada tanggal "+date; - if (!projName.isEmpty()) result+=(QCString)" untuk "+projName; - result+=(QCString)" oleh"; + QCString result="Dibangkitkan pada tanggal "+date; + if (!projName.isEmpty()) result+=" untuk "+projName; + result+=" oleh"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagram hierarki kelas untuk "+clName+":"; + return "Diagram hierarki kelas untuk "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Hanya untuk digunakan secara internal."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Peringatan"; } @@ -591,7 +589,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 default: break; } if (isTemplate) result+=" Template "; - result+=(QCString)clName; + result+=clName; return result; } @@ -738,7 +736,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentasi untuk "; + QCString result="Dokumentasi untuk "; switch(compType) { case ClassDef::Class: result+="kelas"; break; @@ -804,12 +802,12 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagram kolaborasi untuk "+clName+":"; + return "Diagram kolaborasi untuk "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Bagan kebergantungan pemuatan untuk "+fName+":"; + return "Bagan kebergantungan pemuatan untuk "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1088,12 +1086,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Daftar Paket"; + return "Paket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1350,14 +1343,18 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Daftar Fungsi Paket"; } + virtual QCString trPackageMembers() + { + return "Anggota-anggota Paket"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Daftar Fungsi Statis Paket"; } @@ -1469,13 +1466,6 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 virtual QCString trDirectories() { return "Daftar Direktori"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Struktur direktori ini diurutkan hampir berdasarkan abjad:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1623,7 +1613,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 case ClassDef::Exception: result+="Eksepsi "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } /*! used as the title of the HTML page of a module (Fortran) */ @@ -1678,7 +1668,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentasi untuk "; + QCString result="Dokumentasi untuk "; switch(compType) { case ClassDef::Class: result+="module"; break; @@ -1766,7 +1756,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"File dimuat dalam "+name; + return "File dimuat dalam "+name; } /*! when clicking a directory dependency label, a page with a @@ -1775,7 +1765,7 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Memuat file dalam "+name; + return "Memuat file dalam "+name; } /** Compiles a date string. diff --git a/src/translator_it.h b/src/translator_it.h index 87361d3..04ebbf5 100644 --- a/src/translator_it.h +++ b/src/translator_it.h @@ -33,7 +33,7 @@ * 2006/10: made class to derive directly from Translator class (reported in Petr Prikryl October 9 translator report) * 2006/06: updated translation of new items used since version 1.4.6 * 2006/05: translated new items used since version 1.4.6 - * corrected typo in trPackageMembers method + * corrected typo in trPackageFunction method * 2005/03: translated new items used since version 1.4.1 * removed unused methods listed in Petr Prikryl February 28 translator report * 2004/09: translated new items used since version 1.3.9 @@ -116,6 +116,10 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 { return "it"; } + virtual QCString getLanguageString() + { + return "0x410 Italian"; + } // --- Language translation methods ------------------- @@ -182,7 +186,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generato automaticamente da Doxygen"; - if (!s.isEmpty()) result+=(QCString)" per "+s; + if (!s.isEmpty()) result+=" per "+s; result+=" a partire dal codice sorgente."; return result; } @@ -424,12 +428,6 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 QCString trExampleDocumentation() { return "Documentazione degli esempi"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - QCString trPageDocumentation() - { return "Documentazione delle pagine tra loro collegate "; } - /*! This is used in LaTeX as the title of the document */ QCString trReferenceManual() { return "Manuale di riferimento"; } @@ -520,22 +518,18 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 */ QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generato "+date; - if (!projName.isEmpty()) result+=(QCString)" per "+projName; - result+=(QCString)" da"; + QCString result="Generato "+date; + if (!projName.isEmpty()) result+=" per "+projName; + result+=" da"; return result; } /*! this text is put before a class diagram */ QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagramma delle classi per "+clName; + return "Diagramma delle classi per "+clName; } - /*! this text is generated when the \\internal command is used. */ - QCString trForInternalUseOnly() - { return "Solo per uso interno."; } - /*! this text is generated when the \\warning command is used. */ QCString trWarning() { return "Avvertimento"; } @@ -624,7 +618,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 case ClassDef::Exception: result+="l'eccezione "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -633,7 +627,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 QCString trFileReference(const QCString &fileName) { QCString result="Riferimenti per il file "; - result+=(QCString)fileName; + result+=fileName; return result; } @@ -641,7 +635,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 QCString trNamespaceReference(const QCString &namespaceName) { QCString result="Riferimenti per il namespace "; - result+=(QCString)namespaceName; + result+=namespaceName; return result; } @@ -774,7 +768,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"La documentazione per quest"; + QCString result="La documentazione per quest"; switch(compType) { case ClassDef::Class: result+="a classe"; break; @@ -840,12 +834,12 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagramma di collaborazione per "+clName+":"; + return "Diagramma di collaborazione per "+clName+":"; } /*! this text is put before an include dependency graph */ QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Grafo delle dipendenze di inclusione per "+fName+":"; + return "Grafo delle dipendenze di inclusione per "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ QCString trConstructorDocumentation() @@ -1119,12 +1113,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Package "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista dei package"; + return "Package "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1353,14 +1342,18 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funzioni con visibilità di package"; } + virtual QCString trPackageMembers() + { + return "Membri con visibilità di package"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Funzioni statiche con visibilità di package"; } @@ -1472,14 +1465,6 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Directory"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Questa gerarchia di directory è approssimativamente, " - "ma non completamente, ordinata in ordine alfabetico:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1626,7 +1611,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 case ClassDef::Exception: result+=" l'eccezione"; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -1683,7 +1668,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"La documentazione per quest"; + QCString result="La documentazione per quest"; switch(compType) { case ClassDef::Class: result+="o modulo"; break; @@ -1772,7 +1757,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"File in "+name; + return "File in "+name; } /*! when clicking a directory dependency label, a page with a @@ -1781,7 +1766,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Include il file in "+name; + return "Include il file in "+name; } /** Compiles a date string. @@ -1947,14 +1932,14 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)"Riferimenti per il servizio "; + QCString result="Riferimenti per il servizio "; result+=sName; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)"Riferimenti per il singleton "; + QCString result="Riferimenti per il singleton "; result+=sName; return result; } @@ -1962,7 +1947,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"La documentazione per questo servizio " + QCString result="La documentazione per questo servizio " "è stata generata a partire "; if (single) result+="dal seguente file:"; else result+="dai seguenti file:"; return result; @@ -1971,7 +1956,7 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"La documentazione per questo singleton " + QCString result="La documentazione per questo singleton " "è stata generata a partire "; if (single) result+="dal seguente file:"; else result+="dai seguenti file:"; return result; diff --git a/src/translator_je.h b/src/translator_je.h index 66ee178..6504b92 100644 --- a/src/translator_je.h +++ b/src/translator_je.h @@ -67,6 +67,10 @@ class TranslatorJapaneseEn : public TranslatorEnglish { return "ja"; } + virtual QCString getLanguageString() + { + return "0x411 Japanese"; + } }; #endif diff --git a/src/translator_jp.h b/src/translator_jp.h index 0f9cdf7..4d5d1dd 100644 --- a/src/translator_jp.h +++ b/src/translator_jp.h @@ -83,6 +83,10 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 { return "ja"; } + virtual QCString getLanguageString() + { + return "0x411 Japanese"; + } virtual QCString latexFontenc() { return ""; @@ -95,6 +99,10 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 { return "\\end{CJK}\n"; } + virtual bool needsPunctuation() + { + return false; + } /*! used in the compound documentation before a list of related functions. */ virtual QCString trRelatedFunctions() @@ -169,7 +177,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result = "Doxygen により"; - if (!s.isEmpty()) result=(QCString)" "+s+"の"; + if (!s.isEmpty()) result=" "+s+"の"; result+="ソースコードから抽出しました。"; return result; } @@ -424,6 +432,10 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 { return "データ構造詳解"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "クラス詳解"; @@ -442,12 +454,6 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "各例詳解"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "ページ詳解"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "リファレンスマニュアル"; } @@ -536,8 +542,8 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result = (QCString)date+"作成"; - if (!projName.isEmpty()) result+=(QCString)" - " + projName; + QCString result = date+"作成"; + if (!projName.isEmpty()) result+=" - " + projName; result+=" / 構成: "; return result; } @@ -545,13 +551,9 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)clName+" の継承関係図"; + return clName+" の継承関係図"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "内部処理用です。"; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "警告"; } @@ -627,7 +629,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName+" "; + QCString result=clName+" "; switch(compType) { case ClassDef::Class: result+="クラス"; break; @@ -646,14 +648,14 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 /*! used as the title of the HTML page of a file */ virtual QCString trFileReference(const QCString &fileName) { - QCString result=(QCString)fileName+" ファイル"; + QCString result=fileName+" ファイル"; return result; } /*! used as the title of the HTML page of a namespace */ virtual QCString trNamespaceReference(const QCString &namespaceName) { - QCString result=(QCString)namespaceName+" 名前空間"; + QCString result=namespaceName+" 名前空間"; return result; } @@ -792,7 +794,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 bool /*single*/) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"この"; + QCString result="この"; switch(compType) { case ClassDef::Class: result+="クラス"; break; @@ -852,12 +854,12 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)clName+" 連携図"; + return clName+" 連携図"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)fName+" の依存先関係図:"; + return fName+" の依存先関係図:"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1130,12 +1132,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)name+" パッケージ"; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "パッケージ一覧"; + return name+" パッケージ"; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1377,14 +1374,19 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "関数"; } + virtual QCString trPackageMembers() + { + return "パッケージ内のメンバ"; + } + /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "静的関数"; } @@ -1496,14 +1498,6 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "ディレクトリ"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "このディレクトリ一覧はおおまかにはソートされていますが、" - "完全にアルファベット順でソートされてはいません。"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1651,7 +1645,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 default: break; } if (isTemplate) result += "テンプレート "; - result+=(QCString)clName; + result+=clName; return result; } /*! used as the title of the HTML page of a module (Fortran) */ @@ -1783,7 +1777,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)name+"にあるファイル"; + return name+"にあるファイル"; } /*! when clicking a directory dependency label, a page with a @@ -1792,7 +1786,7 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)name+"にあるファイルを include している"; + return name+"にあるファイルを include している"; } /** Compiles a date string. @@ -1955,14 +1949,14 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" サービス詳解"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Singleton 詳解"; return result; } diff --git a/src/translator_ke.h b/src/translator_ke.h index 2dda941..ffa10a5 100644 --- a/src/translator_ke.h +++ b/src/translator_ke.h @@ -64,6 +64,10 @@ class TranslatorKoreanEn : public TranslatorEnglish { return "ko"; } + virtual QCString getLanguageString() + { + return "0x412 Korean"; + } }; #endif diff --git a/src/translator_kr.h b/src/translator_kr.h index c0ae658..43a2fbe 100644 --- a/src/translator_kr.h +++ b/src/translator_kr.h @@ -43,17 +43,13 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. */ class TranslatorKorean : public TranslatorAdapter_1_8_15 { - protected: - friend class TranslatorAdapterBase; - virtual ~TranslatorKorean() {} - public: // --- Language control methods ------------------- @@ -102,7 +98,14 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 { return "ko"; } - + virtual QCString getLanguageString() + { + return "0x412 Korean"; + } + virtual bool needsPunctuation() + { + return false; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -167,7 +170,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="소스 코드로부터 "; - if (!s.isEmpty()) result+=s+(QCString)"를 위해 "; + if (!s.isEmpty()) result+=s+"를 위해 "; result+="Doxygen에 의해 자동으로 생성됨."; return result; } @@ -417,6 +420,10 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 { return "데이터 구조 문서화"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "클래스 문서화"; @@ -435,12 +442,6 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "예제 문서화"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "페이지 문서화"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "참조 매뉴얼"; } @@ -531,22 +532,18 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"생성시간 : "+date; - if (!projName.isEmpty()) result+=(QCString)", 프로젝트명 : "+projName; - result+=(QCString)", 생성자 : "; + QCString result="생성시간 : "+date; + if (!projName.isEmpty()) result+=", 프로젝트명 : "+projName; + result+=", 생성자 : "; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)clName+"에 대한 상속 다이어그램 : "; + return clName+"에 대한 상속 다이어그램 : "; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "내부적적으로만 사용하기 위해."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "경고"; } @@ -621,7 +618,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" 클래스"; break; @@ -781,7 +778,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"이 "; + QCString result="이 "; switch(compType) { case ClassDef::Class: result+="클래스"; break; @@ -847,12 +844,12 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)clName+"에 대한 협력 다이어그램:"; + return clName+"에 대한 협력 다이어그램:"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)fName+"에 대한 include 의존 그래프"; + return fName+"에 대한 include 의존 그래프"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1126,12 +1123,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return name+(QCString)" 패키지"; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "패키지 목록"; + return name+" 패키지"; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1388,14 +1380,18 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "패키지 함수"; } + virtual QCString trPackageMembers() + { + return "패키지 멤버들"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "정적 패키지 함수"; } @@ -1507,13 +1503,6 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "디렉토리"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "이 디렉토리 목록은 완전하진 않지만, (대략적으로) 알파벳순으로 정렬되어있습니다.:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1649,7 +1638,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" 모듈"; break; @@ -1717,7 +1706,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"다음 파일"; + QCString result="다음 파일"; if (single) result+=""; else result+="들"; result+="로부터 생성된 "; result+="이 "; @@ -1978,14 +1967,14 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" 서비스 레퍼런스"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" 싱글톤 레퍼런스"; return result; } @@ -1993,7 +1982,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"이 서비스에 대한 문서화는 다음의 파일"; + QCString result="이 서비스에 대한 문서화는 다음의 파일"; if (!single) result+="들"; result+="로부터 생성되었습니다.:"; return result; @@ -2002,7 +1991,7 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"이 싱글톤에 대한 문서화는 다음의 파일"; + QCString result="이 싱글톤에 대한 문서화는 다음의 파일"; if (!single) result+="들"; result+="로부터 생성되었습니다.:"; return result; diff --git a/src/translator_lt.h b/src/translator_lt.h index ad88331..9f16716 100644 --- a/src/translator_lt.h +++ b/src/translator_lt.h @@ -69,6 +69,10 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 { return "lt"; } + virtual QCString getLanguageString() + { + return "0x427 Lithuanian"; + } // --- Language translation methods ------------------- @@ -134,7 +138,7 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automatiškai sugeneruota Doxygen įrankiu"; - if (!s.isEmpty()) result+=(QCString)" "+s; + if (!s.isEmpty()) result+=" "+s; result+=" iš programos kodo."; return result; } @@ -382,6 +386,10 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 { return "Duomenų Struktūros Dokumentacija"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Klasės Dokumentacija"; @@ -400,12 +408,6 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 virtual QCString trExampleDocumentation() { return "Pavyzdžio Dokumentacija"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Puslapio Dokumentacija"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Informacinis Vadovas"; } @@ -496,22 +498,18 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Sugeneruota "+date;/*FIXME*/ - if (!projName.isEmpty()) result+=(QCString)" "+projName;/*FIXME*/ - result+=(QCString)" ";/*FIXME*/ + QCString result="Sugeneruota "+date;/*FIXME*/ + if (!projName.isEmpty()) result+=" "+projName;/*FIXME*/ + result+=" ";/*FIXME*/ return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Paveldimumo diagrama "+clName+":"; /*FIXME*/ + return "Paveldimumo diagrama "+clName+":"; /*FIXME*/ } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Tiktai vidiniam naudojimui."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Įspėjimas"; } @@ -586,7 +584,7 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Klasė"; break; @@ -745,7 +743,7 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentacija "; + QCString result="Dokumentacija "; switch(compType) { case ClassDef::Class: result+="šiai klasei"; break; @@ -810,12 +808,12 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Bendradarbiavimo diagrama "+clName+":";/*FIXME*/ + return "Bendradarbiavimo diagrama "+clName+":";/*FIXME*/ } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Įtraukimo priklausomybių diagrama "+fName+":";/*FIXME*/ + return "Įtraukimo priklausomybių diagrama "+fName+":";/*FIXME*/ } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1096,12 +1094,7 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paketas "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Paketo Sąrašas"; + return "Paketas "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1364,14 +1357,18 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Paketo Funkcijos"; } + virtual QCString trPackageMembers() + { + return "Paketo Nariai"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statinės Paketo Funkcijos"; } @@ -1482,13 +1479,6 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 virtual QCString trDirectories() { return "Direktorijos"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Ši direktorjų strūktūra grubiai surikiuota abėcėlės tvarka:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ diff --git a/src/translator_lv.h b/src/translator_lv.h index 7367502..c54fe7e 100644 --- a/src/translator_lv.h +++ b/src/translator_lv.h @@ -35,7 +35,7 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. @@ -84,6 +84,10 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 { return "lv"; } + virtual QCString getLanguageString() + { + return "0x426 Latvian"; + } // --- Language translation methods ------------------- @@ -149,7 +153,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automātiski ģenerēts izmantojot Doxygen"; - if (!s.isEmpty()) result+=(QCString)" priekš "+s; + if (!s.isEmpty()) result+=" priekš "+s; result+=" no pirmkoda."; return result; } @@ -397,6 +401,10 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 { return "Datu struktūras dokomentācija"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Klases dokumentācija"; @@ -415,12 +423,6 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 virtual QCString trExampleDocumentation() { return "Piemēri"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Lapas dokumentācija"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Rokasgrāmata"; } @@ -511,22 +513,18 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Ģenerēts "+date; - if (!projName.isEmpty()) result+=(QCString)" projektam "+projName; - result+=(QCString)" ar"; + QCString result="Ģenerēts "+date; + if (!projName.isEmpty()) result+=" projektam "+projName; + result+=" ar"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Mantojamības diagramma klasei "+clName+":"; + return "Mantojamības diagramma klasei "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Tikai iekšējai lietošanai."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Brīdinājums"; } @@ -601,7 +599,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" klases"; break; @@ -760,7 +758,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) { // single is true implies a single file - QCString result=(QCString)"Šī"; + QCString result="Šī"; switch(compType) { case ClassDef::Class: result+="s klases"; break; @@ -825,12 +823,12 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Sadarbības diagramma klasei "+clName+":"; + return "Sadarbības diagramma klasei "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Include dependency graph for "+fName+":"; + return "Include dependency graph for "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1113,12 +1111,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pakotne "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Pakotņu saraksts"; + return "Pakotne "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1375,14 +1368,18 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Pakas funkcijas"; } + virtual QCString trPackageMembers() + { + return "Pakas elementi"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statiskās pakas funkcijas"; } @@ -1494,14 +1491,6 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 virtual QCString trDirectories() { return "Direktorijas"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Šī direktoriju hierarhija ir aptuveni, " - "bet ne pilnībā, alfabēta secībā:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1637,7 +1626,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" moduļa"; break; @@ -1706,7 +1695,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentācija š"; + QCString result="Dokumentācija š"; switch(compType) { case ClassDef::Class: result+="im modulim"; break; @@ -1795,7 +1784,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"File in "+name; + return "File in "+name; } /*! when clicking a directory dependency label, a page with a @@ -1804,7 +1793,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Includes file in "+name; + return "Includes file in "+name; } /** Compiles a date string. @@ -1944,15 +1933,6 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 { return "Metožu dokumentācija"; } - - /*! Used as the title of the design overview picture created for the - * VHDL output. - */ - virtual QCString trDesignOverview() - { - return "Dizaina pārskats"; - } - }; #endif diff --git a/src/translator_mk.h b/src/translator_mk.h index 6db452e..0be70fc 100644 --- a/src/translator_mk.h +++ b/src/translator_mk.h @@ -69,6 +69,10 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 { return "mk"; } + virtual QCString getLanguageString() + { + return "0x042f Macedonian (Former Yugoslav Republic of Macedonia)"; + } // --- Language translation methods ------------------- @@ -130,7 +134,7 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Автоматски создадено од Doxygen"; - if (!s.isEmpty()) result+=(QCString)" за "+s; + if (!s.isEmpty()) result+=" за "+s; result+=" изворниот код."; return result; } @@ -377,6 +381,10 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 { return "Документација на Структури"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Документација на Класи"; @@ -395,12 +403,6 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 virtual QCString trExampleDocumentation() { return "Документаија на Примери"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Документација на Страници"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Прирачник"; } @@ -491,22 +493,18 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Создадено на "+date; - if (!projName.isEmpty()) result+=(QCString)" за "+projName; - result+=(QCString)" од"; + QCString result="Создадено на "+date; + if (!projName.isEmpty()) result+=" за "+projName; + result+=" од"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Диаграм на наследување за "+clName+":"; + return "Диаграм на наследување за "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Само за интерна употреба."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Предупредување"; } @@ -581,7 +579,7 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Класа"; break; @@ -741,7 +739,7 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Документацијата за "; + QCString result="Документацијата за "; switch(compType) { case ClassDef::Class: result+="оваа класа"; break; @@ -806,12 +804,12 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Диаграм на соработка за "+clName+":"; + return "Диаграм на соработка за "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Вклучен дијаграм на зависност за "+fName+":"; + return "Вклучен дијаграм на зависност за "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1091,12 +1089,7 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Пакет "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Список на Пакети"; + return "Пакет "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1353,14 +1346,18 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Функции во Пакетот"; } + virtual QCString trPackageMembers() + { + return "Членови во Пакетот"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Статични Функции во Пакетот"; } @@ -1472,12 +1469,6 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 virtual QCString trDirectories() { return "Именици"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Ова стебло на именици е приближно азбучно подреден:";} - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1612,7 +1603,7 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName + " - Повикување на"; + QCString result=clName + " - Повикување на"; switch(compType) { case ClassDef::Class: result+=" Класа"; break; @@ -1679,7 +1670,7 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Документацијата за "; + QCString result="Документацијата за "; switch(compType) { case ClassDef::Class: result+="оваа класа"; break; diff --git a/src/translator_nl.h b/src/translator_nl.h index 0e4171b..8b95637 100644 --- a/src/translator_nl.h +++ b/src/translator_nl.h @@ -38,6 +38,10 @@ class TranslatorDutch : public Translator { return "\\usepackage[dutch]{babel}\n"; } QCString trISOLang() { return "nl"; } + virtual QCString getLanguageString() + { + return "0x413 Dutch"; + } QCString trRelatedFunctions() { return "Gerelateerde functies"; } QCString trRelatedSubscript() @@ -64,7 +68,7 @@ class TranslatorDutch : public Translator { return ", inclusief alle overgeërfde members."; } QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automatisch gegenereerd door Doxygen"; - if (!s.isEmpty()) result+=(QCString)" voor "+s; + if (!s.isEmpty()) result+=" voor "+s; result+=" uit de programmatekst."; return result; } @@ -166,13 +170,24 @@ class TranslatorDutch : public Translator QCString trModuleDocumentation() { return "Module Documentatie"; } QCString trClassDocumentation() - { return "Klassen Documentatie"; } + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Klassen Documentatie"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } + else + { + return "Klassen Documentatie"; + } + } QCString trFileDocumentation() { return "Bestand Documentatie"; } QCString trExampleDocumentation() { return "Documentatie van voorbeelden"; } - QCString trPageDocumentation() - { return "Documentatie van gerelateerde pagina's"; } QCString trReferenceManual() { return "Naslagwerk"; } @@ -204,17 +219,15 @@ class TranslatorDutch : public Translator { return "Klassen"; } QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Gegenereerd op "+date; - if (!projName.isEmpty()) result+=(QCString)" voor "+projName; - result+=(QCString)" door"; + QCString result="Gegenereerd op "+date; + if (!projName.isEmpty()) result+=" voor "+projName; + result+=" door"; return result; } QCString trClassDiagram(const QCString &clName) { - return (QCString)"Klasse diagram voor "+clName; + return "Klasse diagram voor "+clName; } - QCString trForInternalUseOnly() - { return "Alleen voor intern gebruik."; } QCString trWarning() { return "Waarschuwing"; } QCString trVersion() @@ -264,7 +277,7 @@ class TranslatorDutch : public Translator bool isTemplate) // used as the title of the HTML page of a class/struct/union { - QCString result=(QCString)clName; + QCString result=clName; if (isTemplate) result+=" Template"; switch(compType) { @@ -414,8 +427,8 @@ class TranslatorDutch : public Translator bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"De documentatie voor "; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="De documentatie voor "; switch(compType) { case ClassDef::Class: result+=vhdlOpt?"deze ontwerp eenheid":"deze klasse"; break; @@ -482,12 +495,12 @@ class TranslatorDutch : public Translator /*! this text is put before a collaboration diagram */ QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Collaboratie diagram voor "+clName+":"; + return "Collaboratie diagram voor "+clName+":"; } /*! this text is put before an include dependency graph */ QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Include afhankelijkheidsgraaf voor "+fName+":"; + return "Include afhankelijkheidsgraaf voor "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ QCString trConstructorDocumentation() @@ -752,12 +765,7 @@ class TranslatorDutch : public Translator /*! Used as the title of a Java package */ QCString trPackage(const QCString &name) { - return (QCString)"Package "+name; - } - /*! Title of the package index page */ - QCString trPackageList() - { - return "Package Lijst"; + return "Package "+name; } /*! The description of the package index page */ QCString trPackageListDescription() @@ -845,7 +853,7 @@ class TranslatorDutch : public Translator */ virtual QCString trClass(bool first_capital, bool singular) { - QCString result((first_capital ? "Klasse" : "klass")); + QCString result((first_capital ? "Klasse" : "klasse")); if (!singular) result+="n"; return result; } @@ -1008,14 +1016,18 @@ class TranslatorDutch : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Package Functies"; } + virtual QCString trPackageMembers() + { + return "Package Members"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statische Package Functies"; } @@ -1127,14 +1139,6 @@ class TranslatorDutch : public Translator virtual QCString trDirectories() { return "Folders"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Deze folder hiërarchie is min of meer alfabetisch " - "gesorteerd:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1254,7 +1258,7 @@ class TranslatorDutch : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Module"; break; @@ -1318,7 +1322,7 @@ class TranslatorDutch : public Translator bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"De documentatie voor "; + QCString result="De documentatie voor "; switch(compType) { case ClassDef::Class: result+="deze module"; break; @@ -1370,7 +1374,7 @@ class TranslatorDutch : public Translator /*! directory relation for \a name */ virtual QCString trDirRelation(const QCString &name) { - return QCString(name)+" Relatie"; + return name+" Relatie"; } /*! Loading message shown when loading search results */ @@ -1407,7 +1411,7 @@ class TranslatorDutch : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Bestand in "+name; + return "Bestand in "+name; } /*! when clicking a directory dependency label, a page with a @@ -1416,7 +1420,7 @@ class TranslatorDutch : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Includeert bestand in "+name; + return "Includeert bestand in "+name; } virtual QCString trDateTime(int year,int month,int day,int dayOfWeek, int hour,int minutes,int seconds, @@ -1449,7 +1453,7 @@ class TranslatorDutch : public Translator /*! Header for the graph showing the directory dependencies */ virtual QCString trDirDepGraph(const QCString &name) - { return QCString("Folder afhankelijkheidsgraaf voor ")+name+":"; } + { return "Folder afhankelijkheidsgraaf voor "+name+":"; } ////////////////////////////////////////////////////////////////////////// // new since 1.8.0 @@ -1478,11 +1482,11 @@ class TranslatorDutch : public Translator /*! Header of a Java enum page (Java enums are represented as classes). */ virtual QCString trEnumReference(const QCString &name) - { return QCString(name)+" Enum Referentie"; } + { return name+" Enum Referentie"; } /*! Used for a section containing inherited members */ virtual QCString trInheritedFrom(const QCString &members,const QCString &what) - { return QCString(members)+" overgeërfd van "+what; } + { return members+" overgeërfd van "+what; } /*! Header of the sections with inherited members specific for the * base class(es) @@ -1571,14 +1575,14 @@ class TranslatorDutch : public Translator /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Service Referentie"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Singleton Referentie"; return result; } @@ -1714,7 +1718,7 @@ class TranslatorDutch : public Translator } } virtual QCString trCustomReference(const QCString &name) - { return QCString(name)+" Referentie"; } + { return name+" Referentie"; } /* Slice */ virtual QCString trConstants() @@ -1767,7 +1771,7 @@ class TranslatorDutch : public Translator { return "Documentatie van exceptions"; } virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result=(QCString)clName; + QCString result=clName; if (isLocal) result+=" Lokale"; switch(compType) { @@ -1837,6 +1841,12 @@ class TranslatorDutch : public Translator return "Concept definitie"; } +////////////////////////////////////////////////////////////////////////// +// new since 1.9.4 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trPackageList() + { return "Package Lijst"; } }; #endif diff --git a/src/translator_no.h b/src/translator_no.h index 0444047..916ba89 100755 --- a/src/translator_no.h +++ b/src/translator_no.h @@ -79,6 +79,10 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 { return "nn"; } + virtual QCString getLanguageString() + { + return "0x814 Norwegian"; + } // --- Language translation methods ------------------- @@ -144,7 +148,7 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generert automatisk av Doxygen"; - if (!s.isEmpty()) result+=(QCString)" for "+s; + if (!s.isEmpty()) result+=" for "+s; result+=" fra kildekoden."; return result; } @@ -190,10 +194,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 virtual QCString trFileList() { return "Fil-liste"; } - /*! This is put above each page as a link to the list of all verbatim headers */ - virtual QCString trHeaderFiles() - { return "Header-filer"; } - /*! This is put above each page as a link to all members of compounds. */ virtual QCString trCompoundMembers() { @@ -329,10 +329,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 return result; } - /*! This is an introduction to the page with the list of all header files. */ - virtual QCString trHeaderFilesDescription() - { return "Her er alle header-filene som utgjør API'et:"; } - /*! This is an introduction to the page with the list of all examples */ virtual QCString trExamplesDescription() { return "Her er en liste over alle eksemplene:"; } @@ -345,12 +341,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 virtual QCString trModulesDescription() { return "Her er en liste over alle moduler:"; } - /*! This sentences is used in the annotated class/file lists if no brief - * description is given. - */ - virtual QCString trNoDescriptionAvailable() - { return "Ingen beskrivelse tilgjengelig"; } - // index titles (the project name is prepended for these) @@ -406,6 +396,10 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 { return "Datastrukturdokumentasjon"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Klassedokumentasjon"; @@ -424,12 +418,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 virtual QCString trExampleDocumentation() { return "Eksempeldokumentasjon"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Sidedokumentasjon"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referansemanual"; } @@ -526,34 +514,22 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generert "+date; - if (!projName.isEmpty()) result+=(QCString)" for "+projName; - result+=(QCString)" av"; + QCString result="Generert "+date; + if (!projName.isEmpty()) result+=" for "+projName; + result+=" av"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Arvediagram for "+clName+":"; + return "Arvediagram for "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Kun for intern bruk."; } - - /*! this text is generated when the \\reimp command is used. */ - virtual QCString trReimplementedForInternalReasons() - { return "Reimplementert av interne grunner; API er ikke påvirket."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Advarsel"; } - /*! this text is generated when the \\bug command is used. */ - virtual QCString trBugsAndLimitations() - { return "Feil og begrensninger"; } - /*! this text is generated when the \\version command is used. */ virtual QCString trVersion() { return "Versjon"; } @@ -624,7 +600,7 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Klasse"; break; @@ -784,7 +760,7 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentasjonen for "; + QCString result="Dokumentasjonen for "; switch(compType) { case ClassDef::Class: result+="denne klasse"; break; @@ -824,10 +800,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 // new since 0.49-991003 ////////////////////////////////////////////////////////////////////////// - virtual QCString trSources() - { - return "Kilder"; - } virtual QCString trDefinedAtLineInSourceFile() { return "Definisjon på linje @0 i filen @1."; @@ -853,12 +825,12 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Samarbeidsdiagram for "+clName+":"; + return "Samarbeidsdiagram for "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Avhengighetsgraf for "+fName+":"; + return "Avhengighetsgraf for "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ @@ -1138,12 +1110,7 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Package "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Pakke-liste"; + return "Package "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1155,11 +1122,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 { return "Pakker"; } - /*! Used as a chapter title for Latex & RTF output */ - virtual QCString trPackageDocumentation() - { - return "Pakke-dokumentasjon"; - } /*! Text shown before a multi-line define */ virtual QCString trDefineValue() { @@ -1300,17 +1262,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trField(bool first_capital, bool singular) - { - QCString result((first_capital ? "Felt" : "felt")); - if (!singular) result+=""; - return result; - } - - /*! This is used for translation of the word that will possibly - * be followed by a single name or by a list of names - * of the category. - */ virtual QCString trGlobal(bool first_capital, bool singular) { QCString result((first_capital ? "Global" : "global")); @@ -1416,14 +1367,18 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Pakkefunksjoner"; } + virtual QCString trPackageMembers() + { + return "Pakkemedlemmer"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statiske Pakkefunksjoner"; } @@ -1535,14 +1490,6 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 virtual QCString trDirectories() { return "Kataloger"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Denne katalogen er grovsortert alfabetisk " - "(ikke nødvendigvis korrekt)."; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ diff --git a/src/translator_pl.h b/src/translator_pl.h index 1a094d6..c8a215f 100644 --- a/src/translator_pl.h +++ b/src/translator_pl.h @@ -58,6 +58,10 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 { return "pl"; } + virtual QCString getLanguageString() + { + return "0x415 Polish"; + } // --- Language translation methods ------------------- @@ -123,7 +127,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 */ QCString trGeneratedAutomatically(const QCString &s) { QCString result="Wygenerowano automatycznie z kodu źródłowego programem Doxygen"; - if (!s.isEmpty()) result+=(QCString)" dla "+s; + if (!s.isEmpty()) result+=" dla "+s; result+="."; return result; } @@ -169,10 +173,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 QCString trFileList() { return "Lista plików"; } - /*! This is put above each page as a link to the list of all verbatim headers */ - QCString trHeaderFiles() - { return "Pliki nagłówkowe"; } - /*! This is put above each page as a link to all members of compounds. */ QCString trCompoundMembers() { @@ -308,10 +308,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 return result; } - /*! This is an introduction to the page with the list of all header files. */ - QCString trHeaderFilesDescription() - { return "Tutaj znajdują się pliki nagłówkowe tworzące API:"; } - /*! This is an introduction to the page with the list of all examples */ QCString trExamplesDescription() { return "Tutaj znajduje się lista wszystkich przykładów:"; } @@ -324,12 +320,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 QCString trModulesDescription() { return "Tutaj znajduje się lista wszystkich grup:"; } - /*! This sentences is used in the annotated class/file lists if no brief - * description is given. - */ - QCString trNoDescriptionAvailable() - { return "Brak opisu"; } - // index titles (the project name is prepended for these) @@ -385,6 +375,10 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 { return "Dokumentacja struktur danych"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Dokumentacja klas"; @@ -403,12 +397,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 QCString trExampleDocumentation() { return "Dokumentacja przykładów"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - QCString trPageDocumentation() - { return "Dokumentacja stron"; } - /*! This is used in LaTeX as the title of the document */ QCString trReferenceManual() { return "Podręcznik"; } @@ -499,34 +487,22 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 */ QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Wygenerowano "+date; - if (!projName.isEmpty()) result+=(QCString)" dla "+projName; - result+=(QCString)" programem"; + QCString result="Wygenerowano "+date; + if (!projName.isEmpty()) result+=" dla "+projName; + result+=" programem"; return result; } /*! this text is put before a class diagram */ QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagram dziedziczenia dla "+clName; + return "Diagram dziedziczenia dla "+clName; } - /*! this text is generated when the \\internal command is used. */ - QCString trForInternalUseOnly() - { return "Tylko do użytku wewnętrznego."; } - - /*! this text is generated when the \\reimp command is used. */ - QCString trReimplementedForInternalReasons() - { return "Reimplementowana z wewnętrzych przyczyn; nie dotyczy API."; } - /*! this text is generated when the \\warning command is used. */ QCString trWarning() { return "Ostrzeżenie"; } - /*! this text is generated when the \\bug command is used. */ - QCString trBugsAndLimitations() - { return "Błędy i ograniczenia"; } - /*! this text is generated when the \\version command is used. */ QCString trVersion() { return "Wersja"; } @@ -608,7 +584,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 case ClassDef::Exception: result+=" wyjątku "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } @@ -756,7 +732,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentacja dla te"; + QCString result="Dokumentacja dla te"; switch(compType) { case ClassDef::Class: result+="j klasy"; break; @@ -796,10 +772,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 // new since 0.49-991003 ////////////////////////////////////////////////////////////////////////// - QCString trSources() - { - return "Źródła"; - } QCString trDefinedAtLineInSourceFile() { return "Definicja w linii @0 pliku @1."; @@ -825,12 +797,12 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 /*! this text is put before a collaboration diagram */ QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagram współpracy dla "+clName+":"; + return "Diagram współpracy dla "+clName+":"; } /*! this text is put before an include dependency graph */ QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Wykres zależności załączania dla "+fName+":"; + return "Wykres zależności załączania dla "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ QCString trConstructorDocumentation() @@ -1112,12 +1084,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pakiet "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista Pakietów"; + return "Pakiet "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1129,11 +1096,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 { return "Pakiety"; } - /*! Used as a chapter title for Latex & RTF output */ - virtual QCString trPackageDocumentation() - { - return "Dokumentacja Pakietu"; - } /*! Text shown before a multi-line define */ virtual QCString trDefineValue() { @@ -1248,17 +1210,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trField(bool first_capital, bool singular) - { - QCString result((first_capital ? "Pol" : "pol")); - result+=(singular ? "e" : "a"); - return result; - } - - /*! This is used for translation of the word that will possibly - * be followed by a single name or by a list of names - * of the category. - */ virtual QCString trGlobal(bool first_capital, bool singular) { QCString result((first_capital ? "Global" : "global")); @@ -1360,14 +1311,18 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funkcje pakietu"; } + virtual QCString trPackageMembers() + { + return "Składowe pakietu"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statyczne funkcje pakietu"; } @@ -1485,14 +1440,6 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 virtual QCString trDirectories() { return "Katalogi"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { - return "Ta struktura katalogów posortowana jest z grubsza, " - "choć nie całkowicie, alfabetycznie:"; - } /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. @@ -1641,7 +1588,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 case ClassDef::Exception: result+=" wyjątku "; break; default: break; } - result+=(QCString)clName; + result+=clName; return result; } /*! used as the title of the HTML page of a module (Fortran) */ @@ -1696,7 +1643,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentacja dla te"; + QCString result="Dokumentacja dla te"; switch(compType) { case ClassDef::Class: result+="go modułu"; break; @@ -1783,7 +1730,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Plik w "+name; + return "Plik w "+name; } /*! when clicking a directory dependency label, a page with a @@ -1792,7 +1739,7 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Zawiera plik w "+name; + return "Zawiera plik w "+name; } /** Compiles a date string. diff --git a/src/translator_pt.h b/src/translator_pt.h index 8bfbf96..cad2a06 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -19,7 +19,7 @@ * Ulisses Guedes <uli1958 at hotmail dot com> * * Notes about this translation: - * Since I'm Brazilian, this translation may be odd or even incorect for + * Since I'm Brazilian, this translation may be odd or even incorrect for * Portuguese (from Portugal) speakers. If you find any errors, feel free * to contact me. * @@ -65,7 +65,7 @@ #define TRANSLATOR_PT_H -class TranslatorPortuguese : public Translator +class TranslatorPortuguese : public TranslatorAdapter_1_9_4 { public: @@ -104,6 +104,10 @@ class TranslatorPortuguese : public Translator { return "pt"; } + virtual QCString getLanguageString() + { + return "0x816 Portuguese(Portugal)"; + } // --- Language translation methods ------------------- @@ -169,7 +173,7 @@ class TranslatorPortuguese : public Translator */ QCString trGeneratedAutomatically(const QCString &s) { QCString result="Gerado automaticamente por Doxygen"; - if (!s.isEmpty()) result+=(QCString)" para "+s; + if (!s.isEmpty()) result+=" para "+s; result+=" a partir do código fonte."; return result; } @@ -409,7 +413,20 @@ class TranslatorPortuguese : public Translator * the documentation of all classes, structs and unions. */ QCString trClassDocumentation() - { return "Documentação da classe"; } + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Documentação da estruturas de dados"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } + else + { + return "Documentação da classe"; + } + } /*! This is used in LaTeX as the title of the chapter containing * the documentation of all files. @@ -423,12 +440,6 @@ class TranslatorPortuguese : public Translator QCString trExampleDocumentation() { return "Documentação do exemplo"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - QCString trPageDocumentation() - { return "Documentação da página"; } - /*! This is used in LaTeX as the title of the document */ QCString trReferenceManual() { return "Manual de referência"; } @@ -519,22 +530,18 @@ class TranslatorPortuguese : public Translator */ QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Gerado em "+date; - if (!projName.isEmpty()) result+=(QCString)" para "+projName; - result+=(QCString)" por"; + QCString result="Gerado em "+date; + if (!projName.isEmpty()) result+=" para "+projName; + result+=" por"; return result; } /*! this text is put before a class diagram */ QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagrama de heranças da classe "+clName; + return "Diagrama de heranças da classe "+clName; } - /*! this text is generated when the \\internal command is used. */ - QCString trForInternalUseOnly() - { return "Apenas para uso interno."; } - /*! this text is generated when the \\warning command is used. */ QCString trWarning() { return "Aviso"; } @@ -622,7 +629,7 @@ class TranslatorPortuguese : public Translator default: break; } if (isTemplate) result+="Template "; - result+=(QCString)clName; + result+=clName; return result; } @@ -772,8 +779,8 @@ class TranslatorPortuguese : public Translator bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"A documentação para "; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="A documentação para "; switch(compType) { case ClassDef::Class: result+=vhdlOpt?"esta Unidade de Design":"esta classe"; break; @@ -839,12 +846,12 @@ class TranslatorPortuguese : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagrama de colaboração para "+clName+":"; + return "Diagrama de colaboração para "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Diagrama de dependências de inclusão para "+fName+":"; + return "Diagrama de dependências de inclusão para "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1117,12 +1124,7 @@ class TranslatorPortuguese : public Translator /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pacote "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista de pacotes"; + return "Pacote "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1379,14 +1381,18 @@ class TranslatorPortuguese : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funções do Pacote"; } + virtual QCString trPackageMembers() + { + return "Membros do Pacote"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Funções Estáticas do Pacote"; } @@ -1498,12 +1504,6 @@ class TranslatorPortuguese : public Translator virtual QCString trDirectories() { return "Diretórios"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Esta Hierarquia de Diretórios está parcialmente ordenada (ordem alfabética)"; } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1639,7 +1639,7 @@ class TranslatorPortuguese : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result = (QCString)"Referência "; + QCString result = "Referência "; if (isTemplate) result+="da Template "; @@ -1710,7 +1710,7 @@ class TranslatorPortuguese : public Translator bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"A documentação para "; + QCString result="A documentação para "; switch(compType) { case ClassDef::Class: result+="este modulo "; break; @@ -1803,7 +1803,7 @@ class TranslatorPortuguese : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Ficheiro em "+name; + return "Ficheiro em "+name; } /*! when clicking a directory dependency label, a page with a @@ -1812,7 +1812,7 @@ class TranslatorPortuguese : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inclui ficheiro em "+name; + return "Inclui ficheiro em "+name; } /** Compiles a date string. @@ -2005,7 +2005,7 @@ class TranslatorPortuguese : public Translator virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"A documentação para este serviço " + QCString result="A documentação para este serviço " "foi gerada a partir "; if (single) { result+="do seguinte ficheiro:"; @@ -2019,7 +2019,7 @@ class TranslatorPortuguese : public Translator virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"A documentação para este singleton " + QCString result="A documentação para este singleton " "foi gerada a partir "; if (single) { result+="do seguinte ficheiro:"; @@ -2246,7 +2246,7 @@ class TranslatorPortuguese : public Translator } virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result=(QCString)"Referência "; + QCString result="Referência "; switch(compType) { case ClassDef::Class: result+="da Classe "; break; diff --git a/src/translator_ro.h b/src/translator_ro.h index 6536009..011bc29 100644 --- a/src/translator_ro.h +++ b/src/translator_ro.h @@ -78,6 +78,10 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 { return "ro"; } + virtual QCString getLanguageString() + { + return "0x418 Romanian"; + } // --- Language translation methods ------------------- @@ -144,7 +148,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Generat automat de Doxygen"; - if (!s.isEmpty()) result+=(QCString)" pentru "+s; + if (!s.isEmpty()) result+=" pentru "+s; result+=" din codul sursă."; return result; } @@ -402,6 +406,10 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 { return "Documentaţia Structurilor de Date"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Documentaţia Claselor"; @@ -421,12 +429,6 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Documentaţia Exemplelor"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Documentaţii înrudite"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Manual de utilizare"; } @@ -518,22 +520,18 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generat "+date; - if (!projName.isEmpty()) result+=(QCString)" pentru "+projName; - result+=(QCString)" de către"; + QCString result="Generat "+date; + if (!projName.isEmpty()) result+=" pentru "+projName; + result+=" de către"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagrama de relaţii pentru "+clName; + return "Diagrama de relaţii pentru "+clName; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Doar pentru uz intern."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Atenţie"; } @@ -620,7 +618,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 default: break; } if (isTemplate) result+=" (Template) "; - result+=(QCString)clName; + result+=clName; return result; } @@ -770,7 +768,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Documentaţia pentru această "; + QCString result="Documentaţia pentru această "; switch(compType) { case ClassDef::Class: result+="clasă"; break; @@ -835,12 +833,12 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagrama de relaţii pentru "+clName+":"; + return "Diagrama de relaţii pentru "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graful dependenţelor prin incluziune pentru "+fName+":"; + return "Graful dependenţelor prin incluziune pentru "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1117,12 +1115,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pachet "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Lista Pachetelor"; + return "Pachet "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1379,14 +1372,18 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funcţii în pachet"; } + virtual QCString trPackageMembers() + { + return "Membrii în pachet"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Funcţii statice în pachet"; } @@ -1498,14 +1495,6 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Directoare"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Această ierarhie de directoare este sortată în general, " - "dar nu complet, în ordine alfabetică:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1656,7 +1645,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 default: break; } if (isTemplate) result+="(Template) "; - result+=(QCString)clName; + result+=clName; return result; } /*! used as the title of the HTML page of a module (Fortran) */ @@ -1712,7 +1701,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Documentaţia "; + QCString result="Documentaţia "; switch(compType) { case ClassDef::Class: result+="modulului"; break; @@ -1801,7 +1790,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Fișierul din "+name; + return "Fișierul din "+name; } /*! when clicking a directory dependency label, a page with a @@ -1810,7 +1799,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Include fișierul din "+name; + return "Include fișierul din "+name; } /** Compiles a date string. @@ -1977,14 +1966,14 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Referință Serviciu"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Referință Singleton"; return result; } @@ -1992,7 +1981,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Documentația pentru acest serviciu " + QCString result="Documentația pentru acest serviciu " "a fost generată din "; if (single) result += "următorul fișier:"; @@ -2004,7 +1993,7 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Documentația pentru acest singleton " + QCString result="Documentația pentru acest singleton " "a fost generată din "; if (single) result += "următorul fișier:"; diff --git a/src/translator_ru.h b/src/translator_ru.h index 6a699d4..0ae718c 100644 --- a/src/translator_ru.h +++ b/src/translator_ru.h @@ -39,6 +39,10 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 virtual QCString trISOLang() { return "ru"; } + virtual QCString getLanguageString() + { + return "0x419 Russian"; + } // --- Language translation methods ------------------- @@ -339,6 +343,10 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 { return "Структуры данных"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Классы"; @@ -357,12 +365,6 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Примеры"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Тематические описания"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Оглавление"; } @@ -470,10 +472,6 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 return QCString("Граф наследования:")+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Только для внутреннего использования"; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Предупреждения"; } @@ -804,12 +802,12 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Граф связей класса "+clName+":"; + return "Граф связей класса "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Граф включаемых заголовочных файлов для "+fName+":"; + return "Граф включаемых заголовочных файлов для "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1093,11 +1091,6 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 { return QCString("Пакет ")+name; } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Полный список пакетов "; - } /*! The description of the package index page */ virtual QCString trPackageListDescription() { @@ -1331,14 +1324,18 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Функции с областью видимости пакета"; } + virtual QCString trPackageMembers() + { + return "Члены с областью видимости пакета"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Статические функции с областью видимости пакета"; } @@ -1450,12 +1447,6 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Алфавитный указатель директорий"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Дерево директорий"; } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1593,7 +1584,7 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; if (isTemplate) { switch(compType) @@ -1675,7 +1666,7 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Документация по "; + QCString result="Документация по "; switch(compType) { case ClassDef::Class: result+="модулю"; break; @@ -1761,7 +1752,7 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Файл в "+name; + return "Файл в "+name; } /*! when clicking a directory dependency label, a page with a @@ -1770,7 +1761,7 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Включает файл в "+name; + return "Включает файл в "+name; } /** Compiles a date string. @@ -1935,14 +1926,14 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Ссылка на сервис"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Ссылка на одиночку"; return result; } @@ -1950,7 +1941,7 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Документация для этого сервиса " + QCString result="Документация для этого сервиса " "сгенерирована из следующего файл"; if (single) result+="а:"; else result+="ов:"; return result; @@ -1959,7 +1950,7 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Документация по этому одиночке " + QCString result="Документация по этому одиночке " "сгенерирована из следующего файл"; if (single) result+="а:"; else result+="ов:"; return result; diff --git a/src/translator_sc.h b/src/translator_sc.h index c5924b8..90eff44 100644 --- a/src/translator_sc.h +++ b/src/translator_sc.h @@ -35,7 +35,7 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. @@ -82,6 +82,10 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 { return "sr-Cyrl"; } + virtual QCString getLanguageString() + { + return "0xC1A Serbian (Serbia, Cyrillic)"; + } // --- Language translation methods ------------------- @@ -147,7 +151,7 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Аутоматски направљено помоћу Doxygen-а"; - if (!s.isEmpty()) result+=(QCString)" за "+s; + if (!s.isEmpty()) result+=" за "+s; result+=" из изворног кода."; return result; } @@ -395,6 +399,10 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 { return "Документација структуре"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Документација класе"; @@ -413,12 +421,6 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 virtual QCString trExampleDocumentation() { return "Документација примера"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Документација странице"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Приручник"; } @@ -509,22 +511,18 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Направљено "+date; - if (!projName.isEmpty()) result+=(QCString)" за "+projName; - result+=(QCString)" помоћу"; + QCString result="Направљено "+date; + if (!projName.isEmpty()) result+=" за "+projName; + result+=" помоћу"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Дијаграм наслеђивања за "+clName+":"; + return "Дијаграм наслеђивања за "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Само за унутрашњу употребу."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Упозорење"; } @@ -599,7 +597,7 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; if (isTemplate) { result+=" Шаблон"; @@ -776,7 +774,7 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Документација за "; + QCString result="Документација за "; switch(compType) { case ClassDef::Class: result+="ову класу"; break; @@ -841,12 +839,12 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Дијаграм сарадње за "+clName+":"; + return "Дијаграм сарадње за "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Дијаграм зависности укључивања за "+fName+":"; + return "Дијаграм зависности укључивања за "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1127,12 +1125,7 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Пакет "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Списак пакета"; + return "Пакет "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1389,14 +1382,18 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Функције пакета"; } + virtual QCString trPackageMembers() + { + return "Чланови пакета"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Статичке функције пакета"; } @@ -1520,14 +1517,6 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 virtual QCString trDirectories() { return "Директоријуми"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Ова хијерархија директоријума је уређена " - "приближно по абецеди:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1662,7 +1651,7 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; if (isTemplate) result+=" Шаблон"; result+=" Референца"; switch(compType) @@ -1730,7 +1719,7 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Документација за "; + QCString result="Документација за "; switch(compType) { case ClassDef::Class: result+="овај модул"; break; diff --git a/src/translator_si.h b/src/translator_si.h index c199ef6..2440c1b 100644 --- a/src/translator_si.h +++ b/src/translator_si.h @@ -23,9 +23,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { - protected: - friend class TranslatorAdapterBase; - virtual ~TranslatorSlovene() {} public: QCString idLanguage() { return "slovene"; } @@ -38,6 +35,10 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { return "\\usepackage[slovene]{babel}\n"; } QCString trISOLang() { return "sl"; } + virtual QCString getLanguageString() + { + return "0x424 Slovenian"; + } QCString trRelatedFunctions() { return "Povezane funkcije"; } QCString trRelatedSubscript() @@ -66,7 +67,7 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { return ", vključujoč dedovane metode in atribute."; } QCString trGeneratedAutomatically(const QCString &s) { QCString result="zgenerirano z Doxygen-om"; - if (!s.isEmpty()) result+=(QCString)" za "+s; + if (!s.isEmpty()) result+=" za "+s; result+=" iz izvorne kode."; return result; } @@ -84,8 +85,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { return "kratek opis razredov"; } QCString trFileList() { return "seznam datotek"; } -/* QCString trHeaderFiles() */ -/* { return "'Header' datoteka"; } */ QCString trCompoundMembers() { return "metode in atributi"; } QCString trFileMembers() @@ -128,17 +127,12 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 else result+="s povezavami na datoteke v katerih se nahajajo:"; return result; } -/* QCString trHeaderFilesDescription() */ -/* { return "Seznam header datotek, ki tvorijo aplikacijski vmesnik (API) :"; } */ QCString trExamplesDescription() { return "Seznam primerov :"; } QCString trRelatedPagesDescription() { return "Seznam strani z dodatnimi opisi:"; } QCString trModulesDescription() { return "Seznam modulov:"; } -/* QCString trNoDescriptionAvailable() */ -/* { return "Opis ni dostopen"; } */ - QCString trDocumentation() { return "Dokumentacija"; } QCString trModuleIndex() @@ -157,8 +151,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { return "Opis datoteke"; } QCString trExampleDocumentation() { return "Opis primera"; } - QCString trPageDocumentation() - { return "Opis povezanih strani"; } QCString trReferenceManual() { return "Priročnik"; } @@ -188,25 +180,17 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { return "Strukture"; } QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generirano "+date; - if (!projName.isEmpty()) result+=(QCString)" projekt: "+projName; - result+=(QCString)" generator: "; + QCString result="Generirano "+date; + if (!projName.isEmpty()) result+=" projekt: "+projName; + result+=" generator: "; return result; } QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagram razredov za "+clName; + return "Diagram razredov za "+clName; } - QCString trForInternalUseOnly() - { return "Samo za interno uporabo."; } -/* QCString trReimplementedForInternalReasons() */ -/* { return "Ponovno implementirano zaradi internih razlogov. " */ -/* "Nima vpliva na API."; */ -/* } */ QCString trWarning() { return "Opozorilo"; } -/* QCString trBugsAndLimitations() */ -/* { return "Napake in omejtive"; } */ QCString trVersion() { return "Verzija"; } QCString trDate() @@ -266,7 +250,7 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 case ClassDef::Exception: result+=" IDL prekinitev "; break; default: break; } - result += (QCString)clName; + result += clName; return result; } @@ -403,7 +387,7 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Opis "; + QCString result="Opis "; switch(compType) { case ClassDef::Class: result+="razreda"; break; @@ -445,10 +429,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 // new since 0.49-991106 ////////////////////////////////////////////////////////////////////////// -/* QCString trSources() */ -/* { */ -/* return "Izvorne datoteke"; */ -/* } */ QCString trDefinedAtLineInSourceFile() { return "Definirano v @0 vrstici datoteke @1."; @@ -474,12 +454,12 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 /*! this text is put before a collaboration diagram */ QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Kolaboracijski diagram razreda "+clName+":"; + return "Kolaboracijski diagram razreda "+clName+":"; } /*! this text is put before an include dependency graph */ QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graf prikazuje seznam datotek, " + return "Graf prikazuje seznam datotek, " "ki jih datoteka \""+fName+"\" " "direktno ali indirektno vključuje. Pravokotniki ponazarjajo datoteke, puščice " "predstavljajo relacije med njimi. " @@ -767,12 +747,7 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"JAVA paket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Seznam JAVA paketov"; + return "JAVA paket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -784,11 +759,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 { return "JAVA paketi"; } - /*! Used as a chapter title for Latex & RTF output */ -/* virtual QCString trPackageDocumentation() */ -/* { */ -/* return "Opisi JAVA paketov"; */ -/* } */ /*! Text shown before a multi-line define */ virtual QCString trDefineValue() { @@ -930,18 +900,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ -/* virtual QCString trField(bool first_capital, bool singular) */ -/* { */ -/* QCString result((first_capital ? "Polj" : "polj")); */ -/* if (!singular) result+="a"; */ -/* else result += "e"; */ -/* return result; */ -/* } */ - - /*! This is used for translation of the word that will possibly - * be followed by a single name or by a list of names - * of the category. - */ virtual QCString trGlobal(bool first_capital, bool singular) { QCString result((first_capital ? "Global" : "global")); @@ -1045,14 +1003,18 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funkcije paketa"; /* don't know the context */ } + virtual QCString trPackageMembers() + { + return "Elemente paketa"; /* don't know the context */ + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statične funkcije paketa"; } @@ -1168,13 +1130,6 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 virtual QCString trDirectories() { return "Imeniki"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Imeniška hierarhija je urejena v glavnem, toda ne popolnoma, po abecedi, "; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ diff --git a/src/translator_sk.h b/src/translator_sk.h index 1691ff5..a7a44b3 100644 --- a/src/translator_sk.h +++ b/src/translator_sk.h @@ -53,6 +53,10 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 { return "sk"; } + virtual QCString getLanguageString() + { + return "0x41B Slovak"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -119,7 +123,7 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 { QCString result("Generované automaticky programom Doxygen " "zo zdrojových textov"); if (!s.isEmpty()) - result+=(QCString)" projektu "+s; + result+=" projektu "+s; result+="."; return result; } @@ -384,12 +388,6 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "Dokumentácia príkladov"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Dokumentácia súvisiacich stránok"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referenčná príručka"; } @@ -480,22 +478,18 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Generované "+date; - if (!projName.isEmpty()) result+=(QCString)" pre projekt "+projName; - result+=(QCString)" programom"; + QCString result="Generované "+date; + if (!projName.isEmpty()) result+=" pre projekt "+projName; + result+=" programom"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Diagram dedičnosti pre triedu "+clName; + return "Diagram dedičnosti pre triedu "+clName; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Iba pre interné použitie."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Pozor"; } @@ -742,7 +736,7 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentácia pre "; + QCString result="Dokumentácia pre "; switch(compType) { case ClassDef::Class: result+="túto triedu"; break; @@ -808,12 +802,12 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Diagram tried pre "+clName+":"; + return "Diagram tried pre "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graf závislostí na vkladaných súboroch " + return "Graf závislostí na vkladaných súboroch " "pre "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ @@ -1092,12 +1086,7 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Balík "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Zoznam balíkov"; + return "Balík "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1329,14 +1318,18 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funkcie v balíku"; } + virtual QCString trPackageMembers() + { + return "Členy v balíku"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statické funkcie v balíku"; } @@ -1450,15 +1443,6 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "Adresáre"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { - return "Následujúca hierarchia adresárov je zhruba, " - "ale nie úplne, zoradená podľa abecedy:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1668,7 +1652,7 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentácia "; + QCString result="Dokumentácia "; switch(compType) { case ClassDef::Class: result+="k tomuto modulu"; break; @@ -1756,7 +1740,7 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Súbor v "+name; + return "Súbor v "+name; } /*! when clicking a directory dependency label, a page with a @@ -1765,7 +1749,7 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Vkladá (include) súbor z "+name; + return "Vkladá (include) súbor z "+name; } /** Compiles a date string. diff --git a/src/translator_sr.h b/src/translator_sr.h index e5a6cf7..2ef83c2 100644 --- a/src/translator_sr.h +++ b/src/translator_sr.h @@ -62,6 +62,10 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 { return "sr-Latn"; } + virtual QCString getLanguageString() + { + return "0x81A Serbian (Serbia, Latin)"; + } // --- Language translation methods ------------------- @@ -130,7 +134,7 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Napravljeno automatski korišćenjem alata Doxygen"; - if (!s.isEmpty()) result+=(QCString)" za projekat " + s; + if (!s.isEmpty()) result+=" za projekat " + s; result+=" od izvornog koda."; return result; } @@ -375,6 +379,10 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 { return "Dokumentacija stuktura/unija"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Dokumentacija klasa"; @@ -393,12 +401,6 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 virtual QCString trExampleDocumentation() { return "Dokumentacija primera"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Dokumentacija stranice"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Priručnik"; } @@ -489,9 +491,9 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"[" + date + "] Napravljeno automatski "; - if (!projName.isEmpty()) result+=(QCString)" za projekat " + projName; - result+=(QCString)" upotrebom "; + QCString result="[" + date + "] Napravljeno automatski "; + if (!projName.isEmpty()) result+=" za projekat " + projName; + result+=" upotrebom "; return result; } @@ -501,10 +503,6 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 return QCString("Dijagram nasleđivanja za klasu ") + clName + ":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Samo za unutrašnju upotrebu."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Upozorenje"; } @@ -739,7 +737,7 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentacija "; + QCString result="Dokumentacija "; switch(compType) { case ClassDef::Class: result+="ove klase"; break; @@ -804,12 +802,12 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Klasni dijagram za "+clName+":"; + return "Klasni dijagram za "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Graf zavisnosti datoteka za "+fName+":"; + return "Graf zavisnosti datoteka za "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1089,12 +1087,7 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Spisak paketa"; + return "Paket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1352,14 +1345,18 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Funkcije u paketu"; } + virtual QCString trPackageMembers() + { + return "Članovi u paketu"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statičke funkcije u paketu"; // Zajednicke funkcije u paketu } @@ -1471,12 +1468,6 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 virtual QCString trDirectories() { return "Direktorijumi"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Hijerarhija direktorijuma uređena približno po abecedi:"; } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1612,7 +1603,7 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Modul"; break; @@ -1680,7 +1671,7 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Dokumentacija za ovaj "; + QCString result="Dokumentacija za ovaj "; switch(compType) { case ClassDef::Class: result+="modul"; break; @@ -1723,59 +1714,11 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 return "Ograničenja tipova"; } -////////////////////////////////////////////////////////////////////////// -// following methods have no corresponding entry in translator_en.h -////////////////////////////////////////////////////////////////////////// - -// /*! This is put above each page as a link to the list of all verbatim headers */ -// virtual QCString trHeaderFiles() -// { return "Zaglavlja"; } -// -// /*! This is an introduction to the page with the list of all header files. */ -// virtual QCString trHeaderFilesDescription() -// { return "Zaglavlja koje izgraduju API:"; } -// -// /*! This sentences is used in the annotated class/file lists if no brief -// * description is given. -// */ -// virtual QCString trNoDescriptionAvailable() -// { return "Opis nije dostupan"; } -// -// /*! this text is generated when the \\reimp command is used. */ -// virtual QCString trReimplementedForInternalReasons() -// { return decode("Preuradeno zbog unutrasnjih razloga; Nema uticaja na API." ); } -// -// /*! this text is generated when the \\bug command is used. */ -// virtual QCString trBugsAndLimitations() -// { return "Greske i ogranicenja"; } -// -// virtual QCString trSources() -// { -// return decode("Izvorne datoteke" ); -// } -// -// /*! Used for Java interfaces in the summary section of Java packages */ -// virtual QCString trInterfaces() -// { -// return "Interfejsi"; //!< Radna okruzenja. Ali to je dve reci. -// } -// -// /*! Used as a chapter title for Latex & RTF output */ -// virtual QCString trPackageDocumentation() -// { -// return "Dokumentacija paketa"; -// } -// -// /*! This is used for translation of the word that will possibly -// * be followed by a single name or by a list of names -// * of the category. -// */ -// virtual QCString trField(bool first_capital, bool singular) -// { -// QCString result((first_capital ? "Polj" : "polj")); -// result+= (singular ? "e" : "a"); -// return result; -// } + /*! Used for Java interfaces in the summary section of Java packages */ + virtual QCString trInterfaces() + { + return "Interfejsi"; //!< Radna okruzenja. Ali to je dve reci. + } }; diff --git a/src/translator_sv.h b/src/translator_sv.h index 31f764f..f7a788c 100644 --- a/src/translator_sv.h +++ b/src/translator_sv.h @@ -156,7 +156,7 @@ English: #ifndef TRANSLATOR_SE_H #define TRANSLATOR_SE_H -class TranslatorSwedish : public Translator +class TranslatorSwedish : public TranslatorAdapter_1_9_4 { public: @@ -186,6 +186,10 @@ class TranslatorSwedish : public Translator { return "sv"; } + virtual QCString getLanguageString() + { + return "0x41D Swedish"; + } // --- Language translation methods ------------------- @@ -251,7 +255,7 @@ class TranslatorSwedish : public Translator */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automatiskt skapad av Doxygen"; - if (!s.isEmpty()) result+=(QCString)" för "+s; + if (!s.isEmpty()) result+=" för "+s; result+=" från källkoden."; return result; } @@ -500,6 +504,10 @@ class TranslatorSwedish : public Translator { return "Dokumentation över datastrukturer"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Klassdokumentation"; @@ -518,12 +526,6 @@ class TranslatorSwedish : public Translator virtual QCString trExampleDocumentation() { return "Exempeldokumentation"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Sid-dokumentation"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referensmanual"; } @@ -614,22 +616,18 @@ class TranslatorSwedish : public Translator */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Skapad "+date; - if (!projName.isEmpty()) result+=(QCString)" för "+projName; - result+=(QCString)" av"; + QCString result="Skapad "+date; + if (!projName.isEmpty()) result+=" för "+projName; + result+=" av"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Klassdiagram för "+clName; + return "Klassdiagram för "+clName; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Endast för internt bruk."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Varning"; } @@ -701,7 +699,7 @@ class TranslatorSwedish : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" klass"; break; @@ -871,8 +869,8 @@ class TranslatorSwedish : public Translator bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - QCString result=(QCString)"Dokumentationen för "; + bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + QCString result="Dokumentationen för "; switch(compType) { case ClassDef::Class: result+=vhdlOpt? "denna designenhets":"denna klass"; break; @@ -937,12 +935,12 @@ class TranslatorSwedish : public Translator /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Samarbetsdiagram för "+clName+":"; + return "Samarbetsdiagram för "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Include-beroendediagram för "+fName+":"; + return "Include-beroendediagram för "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1225,12 +1223,7 @@ class TranslatorSwedish : public Translator /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Paketlista"; + return "Paket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1475,14 +1468,18 @@ class TranslatorSwedish : public Translator /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Paketfunktioner"; } + virtual QCString trPackageMembers() + { + return "Paketmedlemmar"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statiska paketfunktioner"; } @@ -1594,14 +1591,6 @@ class TranslatorSwedish : public Translator virtual QCString trDirectories() { return "Kataloger"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Den här katalogen är grovt sorterad, " - "men inte helt, i alfabetisk ordning:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1738,7 +1727,7 @@ class TranslatorSwedish : public Translator ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Modul"; break; @@ -1807,7 +1796,7 @@ class TranslatorSwedish : public Translator bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentationen för "; + QCString result="Dokumentationen för "; switch(compType) { case ClassDef::Class: result+="denna modul"; break; @@ -1895,7 +1884,7 @@ class TranslatorSwedish : public Translator */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Fil i "+name; + return "Fil i "+name; } /*! when clicking a directory dependency label, a page with a @@ -1904,7 +1893,7 @@ class TranslatorSwedish : public Translator */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Inkluderar fil i "+name; + return "Inkluderar fil i "+name; } /** Compiles a date string. @@ -2069,14 +2058,14 @@ class TranslatorSwedish : public Translator /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Tjänstereferens"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+=" Singleton-referens"; return result; } @@ -2084,7 +2073,7 @@ class TranslatorSwedish : public Translator virtual QCString trServiceGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentationen för denna tjänst " + QCString result="Dokumentationen för denna tjänst " "genererades från följande fil"; if (single) result+=":"; else result+="er:"; return result; @@ -2093,7 +2082,7 @@ class TranslatorSwedish : public Translator virtual QCString trSingletonGeneratedFromFiles(bool single) { // single is true implies a single file - QCString result=(QCString)"Dokumentationen för denna singleton " + QCString result="Dokumentationen för denna singleton " "genererades från följande fil"; if (single) result+=":"; else result+="er:"; return result; @@ -2319,7 +2308,7 @@ class TranslatorSwedish : public Translator } virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal) { - QCString result=(QCString)clName; + QCString result=clName; if (isLocal) result+=" Lokal"; switch(compType) { diff --git a/src/translator_tr.h b/src/translator_tr.h index ef8c5a3..20a1eec 100644 --- a/src/translator_tr.h +++ b/src/translator_tr.h @@ -35,7 +35,7 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. @@ -77,6 +77,10 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 { return "tr"; } + virtual QCString getLanguageString() + { + return "0x41F Turkey"; + } // --- Language translation methods ------------------- @@ -142,7 +146,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Doxygen tarafından"; - if (!s.isEmpty()) result+=s+(QCString)" için "; + if (!s.isEmpty()) result+=s+" için "; result+=" kaynak koddan otomatik üretilmiştir."; return result; } @@ -386,6 +390,10 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 { return "Veri Yapıları Dokümantasyonu"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Sınıf Dokümantasyonu"; @@ -404,12 +412,6 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 virtual QCString trExampleDocumentation() { return "Örnek Dokümantasyonu"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Sayfa Dokümantasyonu"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Referans Kitabı"; } @@ -500,22 +502,18 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=projName+(QCString)" için "+date; - if (!projName.isEmpty()) result+=(QCString)" tarihinde "; - result+=(QCString)" üreten: "; + QCString result=projName+" için "+date; + if (!projName.isEmpty()) result+=" tarihinde "; + result+=" üreten: "; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return clName+(QCString)" için kalıtım şeması:"; + return clName+" için kalıtım şeması:"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "İç kullanıma ayrılmıştır."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Uyarı"; } @@ -590,7 +588,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Sınıf"; break; @@ -750,7 +748,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Bu "; + QCString result="Bu "; switch(compType) { case ClassDef::Class: result+="sınıf"; break; @@ -816,12 +814,12 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return clName+(QCString)" için işbirliği (collaboration) şeması:"; + return clName+" için işbirliği (collaboration) şeması:"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return fName+(QCString)" için içerme bağımlılık grafiği:"; + return fName+" için içerme bağımlılık grafiği:"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1101,12 +1099,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Paket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Paket Listesi"; + return "Paket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1363,14 +1356,18 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 /*! Used as a heading for a list of Java class fonksiyonlar with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Paket Fonksiyonlar"; } + virtual QCString trPackageMembers() + { + return "Paket Üyeler"; + } /*! Used as a heading for a list of static Java class fonksiyonlar with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Static Pakat Fonksiyonları"; } @@ -1482,14 +1479,6 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 virtual QCString trDirectories() { return "Dizinler"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Bu dizin hiyerarşisi tamamen olmasa da yaklaşık " - "olarak alfabetik sıraya konulmuştur:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1624,7 +1613,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Modül"; break; @@ -1692,7 +1681,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Bu "; + QCString result="Bu "; switch(compType) { case ClassDef::Class: result+="modül"; break; @@ -1737,43 +1726,43 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 } - ////////////////////////////////////////////////////////////////////////// - // new since 1.6.0 (mainly for the new search engine) - ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// + // new since 1.6.0 (mainly for the new search engine) + ////////////////////////////////////////////////////////////////////////// /*! directory relation for \a name */ virtual QCString trDirRelation(const QCString &name) { - return QCString(name)+" İlişkisi"; + return QCString(name)+" İlişkisi"; } /*! Loading message shown when loading search results */ virtual QCString trLoading() { - return "Yüklüyor..."; + return "Yüklüyor..."; } /*! Label used for search results in the global namespace */ virtual QCString trGlobalNamespace() { - return "En Üst Seviye"; + return "En Üst Seviye"; } /*! Message shown while searching */ virtual QCString trSearching() { - return "Arıyor..."; + return "Arıyor..."; } /*! Text shown when no search results are found */ virtual QCString trNoMatches() { - return "Eşleşme Yok"; + return "Eşleşme Yok"; } - ////////////////////////////////////////////////////////////////////////// - // new since 1.6.3 (missing items for the directory pages) - ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// + // new since 1.6.3 (missing items for the directory pages) + ////////////////////////////////////////////////////////////////////////// /*! when clicking a directory dependency label, a page with a * table is shown. The heading for the first column mentions the @@ -1781,7 +1770,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)(name) + (QCString)" dizinindeki dosya"; + return name+" dizinindeki dosya"; } /*! when clicking a directory dependency label, a page with a @@ -1790,7 +1779,7 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)(name) + (QCString)" dizinindeki dosyayı kapsıyor"; + return name + " dizinindeki dosyayı kapsıyor"; } /** Compiles a date string. @@ -1807,17 +1796,17 @@ class TranslatorTurkish : public TranslatorAdapter_1_7_5 int hour,int minutes,int seconds, bool includeTime) { - static const char *days[] = { "Pzt","Sal","Çar","Per","Cma","Cmt","Pzr" }; - static const char *months[] = { "Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Ekm","Kas","Ara" }; - QCString sdate; - sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year); - if (includeTime) - { - QCString stime; - stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds); - sdate+=stime; - } - return sdate; + static const char *days[] = { "Pzt","Sal","Çar","Per","Cma","Cmt","Pzr" }; + static const char *months[] = { "Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Ekm","Kas","Ara" }; + QCString sdate; + sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year); + if (includeTime) + { + QCString stime; + stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds); + sdate+=stime; + } + return sdate; } }; diff --git a/src/translator_tw.h b/src/translator_tw.h index 24ad7ed..0fb7b11 100644 --- a/src/translator_tw.h +++ b/src/translator_tw.h @@ -36,7 +36,7 @@ // files frees the maintainer from thinking about whether the // first, the second, or both files should be included or not, and // why. This holds namely for localized translators because their -// base class is changed occasionaly to adapter classes when the +// base class is changed occasionally to adapter classes when the // Translator class changes the interface, or back to the // Translator class (by the local maintainer) when the localized // translator is made up-to-date again. @@ -90,6 +90,10 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 { return "zh-Hant"; } + virtual QCString getLanguageString() + { + return "0x404 Chinese (Taiwan)"; + } // --- Language translation methods ------------------- @@ -155,7 +159,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="本文件由Doxygen"; - if (!s.isEmpty()) result+=(QCString)" 自 "+s; + if (!s.isEmpty()) result+=" 自 "+s; result+=" 的原始碼中自動產生."; return result; } @@ -399,6 +403,10 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 { return "資料結構說明文件"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "類別說明文件"; @@ -417,12 +425,6 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 virtual QCString trExampleDocumentation() { return "範例說明文件"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "頁面說明文件"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "參考手冊"; } @@ -519,22 +521,18 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"產生日期:"+date; - if (!projName.isEmpty()) result+=(QCString)", 專案:"+projName; - result+=(QCString)", 產生器:"; + QCString result="產生日期:"+date; + if (!projName.isEmpty()) result+=", 專案:"+projName; + result+=", 產生器:"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"類別"+clName+"的繼承圖:"; + return "類別"+clName+"的繼承圖:"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "僅供內部使用."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "警告"; } @@ -609,7 +607,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName+" "; + QCString result=clName+" "; switch(compType) { case ClassDef::Class: result+=" 類別"; break; @@ -768,7 +766,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,bool) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"此"; + QCString result="此"; switch(compType) { case ClassDef::Class: result+="類別(class)"; break; @@ -833,12 +831,12 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)""+clName+"的合作圖:"; + return ""+clName+"的合作圖:"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)""+fName+"的包含相依圖:"; + return ""+fName+"的包含相依圖:"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1119,12 +1117,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Package "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Package列表"; + return "Package "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1366,14 +1359,18 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Package 函數列表"; } + virtual QCString trPackageMembers() + { + return "Package 成員列表"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "靜態 Package 函數列表"; } @@ -1485,13 +1482,6 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 virtual QCString trDirectories() { return "目錄"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "這個目錄階層經過簡略的字母排序: "; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1618,7 +1608,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+="模組"; break; @@ -1685,7 +1675,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 bool /* single */) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"這個"; + QCString result="這個"; switch(compType) { case ClassDef::Class: result+="模組"; break; @@ -1769,7 +1759,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"檔案在"+name; + return "檔案在"+name; } /*! when clicking a directory dependency label, a page with a @@ -1778,7 +1768,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"含入檔案在"+name; + return "含入檔案在"+name; } /** Compiles a date string. @@ -1943,14 +1933,14 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 /** UNO IDL service page title */ virtual QCString trServiceReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+="服務參考"; return result; } /** UNO IDL singleton page title */ virtual QCString trSingletonReference(const QCString &sName) { - QCString result=(QCString)sName; + QCString result=sName; result+="Singleton參考"; return result; } @@ -1958,7 +1948,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 virtual QCString trServiceGeneratedFromFiles(bool) { // single is true implies a single file - QCString result=(QCString)"本服務的文件由以下的檔案" + QCString result="本服務的文件由以下的檔案" "所產生"; result+=":"; return result; @@ -1967,7 +1957,7 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 virtual QCString trSingletonGeneratedFromFiles(bool) { // single is true implies a single file - QCString result=(QCString)"本singleton的文件由下面的檔案" + QCString result="本singleton的文件由下面的檔案" "所產生"; result+=":"; return result; diff --git a/src/translator_ua.h b/src/translator_ua.h index 02f9eab..746616a 100644 --- a/src/translator_ua.h +++ b/src/translator_ua.h @@ -35,6 +35,10 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 { return "uk"; } + virtual QCString getLanguageString() + { + return "0x422 Ukrainian"; + } // --- Language translation methods ------------------- @@ -334,6 +338,10 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 { return "Структури даних" ; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Класи" ; @@ -352,12 +360,6 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 virtual QCString trExampleDocumentation() { return "Приклади"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Документація по темі"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Довідковий посібник"; } @@ -465,10 +467,6 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 return QCString("Схема успадкувань для ")+clName; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Тільки для внутрішнього користування"; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Застереження"; } @@ -717,7 +715,7 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Документація "; + QCString result="Документація "; switch(compType) { case ClassDef::Class: @@ -797,7 +795,7 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Діаграма зв'язків класу "+clName+":"; + return "Діаграма зв'язків класу "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) @@ -1082,11 +1080,6 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 { return QCString("Пакет ")+name; } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Повний список пакетів"; - } /*! The description of the package index page */ virtual QCString trPackageListDescription() { @@ -1322,15 +1315,19 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Функції пакетів"; } + virtual QCString trPackageMembers() + { + return "Елементи пакетів"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Статичні функцію пакетів"; } @@ -1444,14 +1441,6 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 virtual QCString trDirectories() { return "Каталоги"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Дерево каталогів впорядковано наближено " - "до алфавіту:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1587,7 +1576,7 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; if (isTemplate) { switch(compType) @@ -1672,7 +1661,7 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 bool single) { // single is true implies a single file - QCString result=(QCString)"Документацію для "; + QCString result="Документацію для "; switch(compType) { case ClassDef::Class: result+="цього модуля"; break; @@ -1761,7 +1750,7 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 */ virtual QCString trFileIn(const QCString &name) { - return (QCString)"Файл у "+name; + return "Файл у "+name; } /*! when clicking a directory dependency label, a page with a @@ -1770,7 +1759,7 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 */ virtual QCString trIncludesFileIn(const QCString &name) { - return (QCString)"Включає файли в "+name; + return "Включає файли в "+name; } /** Compiles a date string. @@ -1908,15 +1897,6 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 { return "Документація метода"; } - - /*! Used as the title of the design overview picture created for the - * VHDL output. - */ - virtual QCString trDesignOverview() - { - return "Огляд дизайну проекту"; - } - }; #endif diff --git a/src/translator_vi.h b/src/translator_vi.h index a36dee4..7b3b5d8 100644 --- a/src/translator_vi.h +++ b/src/translator_vi.h @@ -42,7 +42,7 @@ files frees the maintainer from thinking about whether the first, the second, or both files should be included or not, and why. This holds namely for localized translators because their - base class is changed occasionaly to adapter classes when the + base class is changed occasionally to adapter classes when the Translator class changes the interface, or back to the Translator class (by the local maintainer) when the localized translator is made up-to-date again. @@ -99,6 +99,10 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 { return "vi"; } + virtual QCString getLanguageString() + { + return "0x42A Vietnamese"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ @@ -163,7 +167,7 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Được tạo ra bởi Doxygen"; - if (!s.isEmpty()) result+=(QCString)" cho "+s; + if (!s.isEmpty()) result+=" cho "+s; result+=" từ mã nguồn."; return result; } @@ -411,6 +415,10 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 { return "Thông tin về cấu trúc cơ sở dữ liệu"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Thông tin về Class"; @@ -429,12 +437,6 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 virtual QCString trExampleDocumentation() { return "Thông tin về các ví dụ"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Trang Thông tin"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Thông tin tham chiếu"; } @@ -525,22 +527,18 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Được biên soạn vào "+date; - if (!projName.isEmpty()) result+=(QCString)" cho mã nguồn dự án "+projName; - result+=(QCString)" bởi"; + QCString result="Được biên soạn vào "+date; + if (!projName.isEmpty()) result+=" cho mã nguồn dự án "+projName; + result+=" bởi"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Sơ đồ kế thừa cho "+clName+":"; + return "Sơ đồ kế thừa cho "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Chỉ cho sử dụng nội bộ."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Lưu ý"; } @@ -615,7 +613,7 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Class"; break; @@ -774,7 +772,7 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,bool) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Thông tin cho "; + QCString result="Thông tin cho "; switch(compType) { case ClassDef::Class: result+="class"; break; @@ -839,12 +837,12 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Sơ đồ liên kết cho "+clName+":"; + return "Sơ đồ liên kết cho "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Kèm theo graph phụ thuộc cho "+fName+":"; + return "Kèm theo graph phụ thuộc cho "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1124,12 +1122,7 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Gói "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Danh sách gói"; + return "Gói "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1386,14 +1379,18 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Các hàm Package"; } + virtual QCString trPackageMembers() + { + return "Members Package"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Các hàm Static Package"; } @@ -1505,14 +1502,6 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 virtual QCString trDirectories() { return "Các thư mục"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Thư mục đã được sắp xếp theo al-pha-bê, " - "nhưng chưa đầy đủ:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1647,7 +1636,7 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Module"; break; @@ -1715,7 +1704,7 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Module", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Thông tin cho "; + QCString result="Thông tin cho "; switch(compType) { case ClassDef::Class: result+="module"; break; diff --git a/src/translator_za.h b/src/translator_za.h index 362adfb..ad5bc3c 100644 --- a/src/translator_za.h +++ b/src/translator_za.h @@ -63,6 +63,10 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 { return "af"; } + virtual QCString getLanguageString() + { + return "0x436 Afrikaans"; + } // --- Language translation methods ------------------- @@ -128,7 +132,7 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAutomatically(const QCString &s) { QCString result="Automaties gegenereer deur Doxygen"; - if (!s.isEmpty()) result+=(QCString)" vir "+s; + if (!s.isEmpty()) result+=" vir "+s; result+=" van die bron kode af."; return result; } @@ -374,6 +378,10 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 { return "Data Strukture Dokumentasie"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return trDesignUnitDocumentation(); + } else { return "Klas Dokumentasie"; @@ -392,12 +400,6 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 virtual QCString trExampleDocumentation() { return "Voorbeeld Dokumentasie"; } - /*! This is used in LaTeX as the title of the chapter containing - * the documentation of all related pages. - */ - virtual QCString trPageDocumentation() - { return "Bladsy Dokumentasie"; } - /*! This is used in LaTeX as the title of the document */ virtual QCString trReferenceManual() { return "Verwysings Handleiding"; } @@ -488,22 +490,18 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 */ virtual QCString trGeneratedAt(const QCString &date,const QCString &projName) { - QCString result=(QCString)"Gegenereer op "+date; - if (!projName.isEmpty()) result+=(QCString)" vir "+projName; - result+=(QCString)" deur"; + QCString result="Gegenereer op "+date; + if (!projName.isEmpty()) result+=" vir "+projName; + result+=" deur"; return result; } /*! this text is put before a class diagram */ virtual QCString trClassDiagram(const QCString &clName) { - return (QCString)"Afleidings diagram vir "+clName+":"; + return "Afleidings diagram vir "+clName+":"; } - /*! this text is generated when the \\internal command is used. */ - virtual QCString trForInternalUseOnly() - { return "Slegs vir interne gebruik."; } - /*! this text is generated when the \\warning command is used. */ virtual QCString trWarning() { return "Waarskuwing"; } @@ -578,7 +576,7 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" klas"; break; @@ -738,7 +736,7 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 bool single) { // here s is one of " Class", " Struct" or " Union" // single is true implies a single file - QCString result=(QCString)"Die dokumentasie vir hierdie "; + QCString result="Die dokumentasie vir hierdie "; switch(compType) { case ClassDef::Class: result+="klas"; break; @@ -803,12 +801,12 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 /*! this text is put before a collaboration diagram */ virtual QCString trCollaborationDiagram(const QCString &clName) { - return (QCString)"Samewerkings diagram vir "+clName+":"; + return "Samewerkings diagram vir "+clName+":"; } /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const QCString &fName) { - return (QCString)"Insluitings afhanklikheid diagram vir "+fName+":"; + return "Insluitings afhanklikheid diagram vir "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1089,12 +1087,7 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 /*! Used as the title of a Java package */ virtual QCString trPackage(const QCString &name) { - return (QCString)"Pakket "+name; - } - /*! Title of the package index page */ - virtual QCString trPackageList() - { - return "Pakket Lys"; + return "Pakket "+name; } /*! The description of the package index page */ virtual QCString trPackageListDescription() @@ -1351,14 +1344,18 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 /*! Used as a heading for a list of Java class functions with package * scope. */ - virtual QCString trPackageMembers() + virtual QCString trPackageFunctions() { return "Pakket Funksies"; } + virtual QCString trPackageMembers() + { + return "Pakket Lede"; + } /*! Used as a heading for a list of static Java class functions with * package scope. */ - virtual QCString trStaticPackageMembers() + virtual QCString trStaticPackageFunctions() { return "Statiese Pakket Funksies"; } @@ -1470,14 +1467,6 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 virtual QCString trDirectories() { return "Directories"; } - /*! This returns a sentences that introduces the directory hierarchy. - * and the fact that it is sorted alphabetically per level - */ - virtual QCString trDirDescription() - { return "Hierdie directory hiërargie is min of meer alfabeties " - "gesorteer:"; - } - /*! This returns the title of a directory page. The name of the * directory is passed via \a dirName. */ @@ -1613,7 +1602,7 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 ClassDef::CompoundType compType, bool isTemplate) { - QCString result=(QCString)clName; + QCString result=clName; switch(compType) { case ClassDef::Class: result+=" Module"; break; @@ -1681,7 +1670,7 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 bool single) { // single is true implies a single file - QCString result=(QCString)"The documentation for this "; + QCString result="The documentation for this "; switch(compType) { case ClassDef::Class: result+="module"; break; diff --git a/src/utf8.cpp b/src/utf8.cpp index e7108f4..ac11995 100644 --- a/src/utf8.cpp +++ b/src/utf8.cpp @@ -54,13 +54,13 @@ uint8_t getUTF8CharNumBytes(char c) //! given the number of bytes it's made of static inline uint32_t decode_utf8( const char* data , int numBytes ) noexcept { - uint32_t cp = (unsigned char)*data; + uint32_t cp = static_cast<unsigned char>(*data); if (numBytes>1) { cp &= 0x7F >> numBytes; // Mask out the header bits for (int i=1 ; i<numBytes ; i++) { - cp = (cp<<6) | ((unsigned char)data[i]&0x3F); + cp = (cp<<6) | (static_cast<unsigned char>(data[i])&0x3F); } } return cp; @@ -141,12 +141,12 @@ uint32_t getUnicodeForUTF8CharAt(const std::string &input,size_t pos) static inline char asciiToLower(uint32_t code) { - return code>='A' && code<='Z' ? (char)(code+'a'-'A') : (char)code; + return code>='A' && code<='Z' ? static_cast<char>(code+'a'-'A') : static_cast<char>(code); } static inline char asciiToUpper(uint32_t code) { - return code>='a' && code<='z' ? (char)(code+'A'-'a') : (char)code; + return code>='a' && code<='z' ? static_cast<char>(code+'A'-'a') : static_cast<char>(code); } static inline std::string caseConvert(const std::string &input, @@ -212,7 +212,7 @@ const char *writeUTF8Char(TextStream &t,const char *s) bool lastUTF8CharIsMultibyte(const std::string &input) { // last byte is part of a multibyte UTF8 char if bit 8 is set and bit 7 is not - return !input.empty() && (((unsigned char)input[input.length()-1])&0xC0)==0x80; + return !input.empty() && (static_cast<unsigned char>(input[input.length()-1])&0xC0)==0x80; } bool isUTF8CharUpperCase(const std::string &input,size_t pos) diff --git a/src/util.cpp b/src/util.cpp index 9d9cc41..f957181 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -96,7 +96,7 @@ static const char *hex = "0123456789ABCDEF"; // TextGeneratorOLImpl implementation //------------------------------------------------------------------------ -TextGeneratorOLImpl::TextGeneratorOLImpl(OutputDocInterface &od) : m_od(od) +TextGeneratorOLImpl::TextGeneratorOLImpl(BaseOutputDocInterface &od) : m_od(od) { } @@ -182,7 +182,7 @@ QCString removeAnonymousScopes(const QCString &str) // helper to check if the found delimiter ends with a colon auto endsWithColon = [](const std::string &del) { - for (int i=(int)del.size()-1;i>=0;i--) + for (int i=static_cast<int>(del.size())-1;i>=0;i--) { if (del[i]=='@') return false; else if (del[i]==':') return true; @@ -261,20 +261,20 @@ done: return newScope; } -void writePageRef(OutputDocInterface &od,const QCString &cn,const QCString &mn) +void writePageRef(OutputList &ol,const QCString &cn,const QCString &mn) { - od.pushGeneratorState(); + ol.pushGeneratorState(); - od.disable(OutputGenerator::Html); - od.disable(OutputGenerator::Man); - od.disable(OutputGenerator::Docbook); - if (Config_getBool(PDF_HYPERLINKS)) od.disable(OutputGenerator::Latex); - if (Config_getBool(RTF_HYPERLINKS)) od.disable(OutputGenerator::RTF); - od.startPageRef(); - od.docify(theTranslator->trPageAbbreviation()); - od.endPageRef(cn,mn); + ol.disable(OutputGenerator::Html); + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); + if (Config_getBool(PDF_HYPERLINKS)) ol.disable(OutputGenerator::Latex); + if (Config_getBool(RTF_HYPERLINKS)) ol.disable(OutputGenerator::RTF); + ol.startPageRef(); + ol.docify(theTranslator->trPageAbbreviation()); + ol.endPageRef(cn,mn); - od.popGeneratorState(); + ol.popGeneratorState(); } /*! Generate a place holder for a position in a list. Used for @@ -377,6 +377,11 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, if (typedefContext) *typedefContext=context; // see if the qualified name has a scope part + if (qualifiedName.find('<')!=-1) + { + //printf(" templates cannot be typedefs!\n"); + return result; + } int scopeIndex = qualifiedName.findRev("::"); QCString resName=qualifiedName; if (scopeIndex!=-1) // strip scope part for the name @@ -460,7 +465,7 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, if (md) { //printf(">>resolveTypeDef: Found typedef name '%s' in scope '%s' value='%s' args='%s'\n", - // qPrint(qualifiedName),qPrint(context->name()),md->typeString(),md->argsString() + // qPrint(qualifiedName),qPrint(context->name()),qPrint(md->typeString()),qPrint(md->argsString()) // ); result=md->typeString(); QCString args = md->argsString(); @@ -552,11 +557,11 @@ QCString removeRedundantWhiteSpace(const QCString &s) // improve the performance of this function // and thread_local is needed to make it multi-thread safe static THREAD_LOCAL char *growBuf = 0; - static THREAD_LOCAL int growBufLen = 0; - if ((int)s.length()*3>growBufLen) // For input character we produce at most 3 output characters, + static THREAD_LOCAL size_t growBufLen = 0; + if (s.length()*3>growBufLen) // For input character we produce at most 3 output characters, { growBufLen = s.length()*3; - growBuf = (char *)realloc(growBuf,growBufLen+1); // add 1 for 0-terminator + growBuf = static_cast<char *>(realloc(growBuf,growBufLen+1)); // add 1 for 0-terminator } if (growBuf==0) return s; // should not happen, only we run out of memory @@ -572,7 +577,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) char c; char pc=0; // skip leading whitespace - while (i<l && isspace((uchar)src[i])) + while (i<l && isspace(static_cast<uchar>(src[i]))) { i++; } @@ -629,7 +634,6 @@ QCString removeRedundantWhiteSpace(const QCString &s) case '"': // quoted string { *dst++=c; - pc = c; i++; for (;i<l;i++) // find end of string { @@ -637,7 +641,6 @@ QCString removeRedundantWhiteSpace(const QCString &s) *dst++=c; if (c=='\\' && i+1<l) { - pc = c; i++; c = src[i]; *dst++=c; @@ -646,7 +649,6 @@ QCString removeRedundantWhiteSpace(const QCString &s) { break; } - pc = c; } } break; @@ -661,7 +663,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) } break; case '>': // current char is a > - if (i>0 && !isspace((uchar)pc) && + if (i>0 && !isspace(static_cast<uchar>(pc)) && (isId(pc) || pc=='*' || pc=='&' || pc=='.' || pc=='>') && // prev char is an id char or space or *&. (osp<8 || (osp==8 && pc!='-')) // string in front is not "operator>" or "operator->" ) @@ -676,7 +678,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) break; case ',': // current char is a , *dst++=c; - if (i>0 && !isspace((uchar)pc) && + if (i>0 && !isspace(static_cast<uchar>(pc)) && ((i<l-1 && (isId(nc) || nc=='[')) || // the [ is for attributes (see bug702170) (i<l-2 && nc=='$' && isId(src[i+2])) || // for PHP: ',$name' -> ', $name' (i<l-3 && nc=='&' && src[i+2]=='$' && isId(src[i+3])) // for PHP: ',&$name' -> ', &$name' @@ -733,7 +735,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) // else fallthrough case '@': // '@name' -> ' @name' case '\'': // ''name' -> '' name' - if (i>0 && i<l-1 && pc!='=' && pc!=':' && !isspace((uchar)pc) && + if (i>0 && i<l-1 && pc!='=' && pc!=':' && !isspace(static_cast<uchar>(pc)) && isId(nc) && osp<8) // ")id" -> ") id" { *dst++=' '; @@ -762,8 +764,8 @@ QCString removeRedundantWhiteSpace(const QCString &s) case '\n': // fallthrough case '\t': { - if (g_charAroundSpace.charMap[(uchar)pc].before && - g_charAroundSpace.charMap[(uchar)nc].after && + if (g_charAroundSpace.charMap[static_cast<uchar>(pc)].before && + g_charAroundSpace.charMap[static_cast<uchar>(nc)].after && !(pc==',' && nc=='.') && (osp<8 || (osp>=8 && isId(pc) && isId(nc))) // e.g. 'operator >>' -> 'operator>>', @@ -782,21 +784,21 @@ QCString removeRedundantWhiteSpace(const QCString &s) default: *dst++=c; if (c=='t' && csp==5 && i<l-1 && // found 't' in 'const' - !(isId(nc) || nc==')' || nc==',' || isspace((uchar)nc)) + !(isId(nc) || nc==')' || nc==',' || isspace(static_cast<uchar>(nc))) ) // prevent const ::A from being converted to const::A { *dst++=' '; csp=0; } else if (c=='e' && vosp==8 && i<l-1 && // found 'e' in 'volatile' - !(isId(nc) || nc==')' || nc==',' || isspace((uchar)nc)) + !(isId(nc) || nc==')' || nc==',' || isspace(static_cast<uchar>(nc))) ) // prevent volatile ::A from being converted to volatile::A { *dst++=' '; vosp=0; } else if (c=='l' && vsp==7 && i<l-1 && // found 'l' in 'virtual' - !(isId(nc) || nc==')' || nc==',' || isspace((uchar)nc)) + !(isId(nc) || nc==')' || nc==',' || isspace(static_cast<uchar>(nc))) ) // prevent virtual ::A from being converted to virtual::A { *dst++=' '; @@ -1108,7 +1110,7 @@ void writeMarkerList(OutputList &ol,const std::string &markerText,size_t numMark size_t matchLen = match.length(); ol.parseText(markerText.substr(index,newIndex-index)); unsigned long entryIndex = std::stoul(match[1].str()); - if (entryIndex<(unsigned long)numMarkers) + if (entryIndex<static_cast<unsigned long>(numMarkers)) { replaceFunc(entryIndex); } @@ -1140,7 +1142,7 @@ void writeExamples(OutputList &ol,const ExampleList &list) ol.popGeneratorState(); }; - writeMarkerList(ol, theTranslator->trWriteList((int)list.size()).str(), list.size(), replaceFunc); + writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc); ol.writeString("."); } @@ -1247,10 +1249,10 @@ QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool include * converted content (i.e. the same as \a len (Unix, MAC) or * smaller (DOS). */ -static int filterCRLF(char *buf,int len) +static size_t filterCRLF(char *buf,size_t len) { - int src = 0; // source index - int dest = 0; // destination index + size_t src = 0; // source index + size_t dest = 0; // destination index char c; // current character while (src<len) @@ -1350,14 +1352,14 @@ QCString getFileFilter(const QCString &name,bool isSourceCode) QCString transcodeCharacterStringToUTF8(const QCString &input) { bool error=FALSE; - static QCString inputEncoding = Config_getString(INPUT_ENCODING); + QCString inputEncoding = Config_getString(INPUT_ENCODING); const char *outputEncoding = "UTF-8"; if (inputEncoding.isEmpty() || qstricmp(inputEncoding,outputEncoding)==0) return input; int inputSize=input.length(); int outputSize=inputSize*4+1; QCString output(outputSize); void *cd = portable_iconv_open(outputEncoding,inputEncoding.data()); - if (cd==(void *)(-1)) + if (cd==reinterpret_cast<void *>(-1)) { err("unsupported character conversion: '%s'->'%s'\n", qPrint(inputEncoding),outputEncoding); @@ -1371,7 +1373,7 @@ QCString transcodeCharacterStringToUTF8(const QCString &input) char *outputPtr = output.rawData(); if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft)) { - outputSize-=(int)oLeft; + outputSize-=static_cast<int>(oLeft); output.resize(outputSize+1); output.at(outputSize)='\0'; //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf)); @@ -1397,7 +1399,6 @@ QCString fileToString(const QCString &name,bool filter,bool isSourceCode) bool fileOpened=false; if (name[0]=='-' && name[1]==0) // read from stdin { - fileOpened=true; std::string contents; std::string line; while (getline(std::cin,line)) @@ -1414,11 +1415,11 @@ QCString fileToString(const QCString &name,bool filter,bool isSourceCode) err("file '%s' not found\n",qPrint(name)); return ""; } - BufStr buf((uint)fi.size()); + BufStr buf(fi.size()); fileOpened=readInputFile(name,buf,filter,isSourceCode); if (fileOpened) { - int s = buf.size(); + size_t s = buf.size(); if (s>1 && buf.at(s-2)!='\n') { buf.at(s-1)='\n'; @@ -1517,7 +1518,7 @@ static void stripIrrelevantString(QCString &target,const QCString &str) while ((i=target.find(str,p))!=-1) { bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str - (i+l==(int)target.length() || !isId(target.at(i+l))); // not a character after str + (i+l==static_cast<int>(target.length()) || !isId(target.at(i+l))); // not a character after str if (isMatch) { int i1=target.find('*',i+l); @@ -1589,9 +1590,9 @@ static QCString stripDeclKeywords(const QCString &s) } // forward decl for circular dependencies -static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCString type); +static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCString type,SrcLangExt lang); -QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec) +static QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec,SrcLangExt lang) { QCString templSpec = spec.stripWhiteSpace(); @@ -1599,9 +1600,9 @@ QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QC // std::list<std::string> against list<string> so it is now back again! if (!templSpec.isEmpty() && templSpec.at(0) == '<') { - templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace()); + templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace(),lang); } - QCString resolvedType = resolveTypeDef(d,templSpec); + QCString resolvedType = lang==SrcLangExt_Java ? templSpec : resolveTypeDef(d,templSpec); if (!resolvedType.isEmpty()) // not known as a typedef either { templSpec = resolvedType; @@ -1612,14 +1613,14 @@ QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QC static QCString getCanonicalTypeForIdentifier( - const Definition *d,const FileDef *fs,const QCString &word, + const Definition *d,const FileDef *fs,const QCString &word,SrcLangExt lang, QCString *tSpec,int count=0) { if (count>10) return word; // oops recursion QCString symName,result,templSpec,tmpName; if (tSpec && !tSpec->isEmpty()) - templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec)); + templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec,lang)); if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty()) { @@ -1691,7 +1692,7 @@ static QCString getCanonicalTypeForIdentifier( else if (!ts.isEmpty() && templSpec.isEmpty()) { // use formal template args for spec - templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,ts)); + templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,ts,lang)); } result = removeRedundantWhiteSpace(cd->qualifiedName() + templSpec); @@ -1734,7 +1735,7 @@ static QCString getCanonicalTypeForIdentifier( type.stripPrefix("typename "); type = stripTemplateSpecifiersFromScope(type,FALSE); } - result = getCanonicalTypeForIdentifier(d,fs,type,tSpec,count+1); + result = getCanonicalTypeForIdentifier(d,fs,type,mType->getLanguage(),tSpec,count+1); } else { @@ -1743,7 +1744,7 @@ static QCString getCanonicalTypeForIdentifier( } else // fallback { - resolvedType = resolveTypeDef(d,word); + resolvedType = lang==SrcLangExt_Java ? word : resolveTypeDef(d,word); //printf("typedef [%s]->[%s]\n",qPrint(word),qPrint(resolvedType)); if (resolvedType.isEmpty()) // not known as a typedef either { @@ -1758,7 +1759,7 @@ static QCString getCanonicalTypeForIdentifier( return result; } -static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCString type) +static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCString type,SrcLangExt lang) { type = type.stripWhiteSpace(); @@ -1785,7 +1786,7 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr //printf(" i=%d p=%d\n",i,p); if (i>pp) canType += type.mid(pp,i-pp); - QCString ct = getCanonicalTypeForIdentifier(d,fs,word,&templSpec); + QCString ct = getCanonicalTypeForIdentifier(d,fs,word,lang,&templSpec); // in case the ct is empty it means that "word" represents scope "d" // and this does not need to be added to the canonical @@ -1819,7 +1820,7 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr size_t tl = match.length(); std::string matchStr = match.str(); canType += ts.substr(tp,ti-tp); - canType += getCanonicalTypeForIdentifier(d,fs,matchStr.c_str(),0); + canType += getCanonicalTypeForIdentifier(d,fs,matchStr.c_str(),lang,0); tp=ti+tl; } canType+=ts.substr(tp); @@ -1833,7 +1834,7 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr return removeRedundantWhiteSpace(canType); } -static QCString extractCanonicalArgType(const Definition *d,const FileDef *fs,const Argument &arg) +static QCString extractCanonicalArgType(const Definition *d,const FileDef *fs,const Argument &arg,SrcLangExt lang) { QCString type = arg.type.stripWhiteSpace(); QCString name = arg.name; @@ -1853,12 +1854,13 @@ static QCString extractCanonicalArgType(const Definition *d,const FileDef *fs,co type+=arg.array; } - return extractCanonicalType(d,fs,type); + return extractCanonicalType(d,fs,type,lang); } static bool matchArgument2( const Definition *srcScope,const FileDef *srcFileScope,Argument &srcA, - const Definition *dstScope,const FileDef *dstFileScope,Argument &dstA + const Definition *dstScope,const FileDef *dstFileScope,Argument &dstA, + SrcLangExt lang ) { //printf(">> match argument: %s::'%s|%s' (%s) <-> %s::'%s|%s' (%s)\n", @@ -1896,8 +1898,8 @@ static bool matchArgument2( if (srcA.canType.isEmpty() || dstA.canType.isEmpty()) { // need to re-evaluate both see issue #8370 - srcA.canType = extractCanonicalArgType(srcScope,srcFileScope,srcA); - dstA.canType = extractCanonicalArgType(dstScope,dstFileScope,dstA); + srcA.canType = extractCanonicalArgType(srcScope,srcFileScope,srcA,lang); + dstA.canType = extractCanonicalArgType(dstScope,dstFileScope,dstA,lang); } if (srcA.canType==dstA.canType) @@ -1917,8 +1919,8 @@ static bool matchArgument2( // new algorithm for argument matching bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,const ArgumentList *srcAl, - const Definition *dstScope,const FileDef *dstFileScope,const ArgumentList *dstAl, - bool checkCV) + const Definition *dstScope,const FileDef *dstFileScope,const ArgumentList *dstAl, + bool checkCV,SrcLangExt lang) { ASSERT(srcScope!=0 && dstScope!=0); @@ -1990,7 +1992,8 @@ bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,cons Argument &srcA = const_cast<Argument&>(*srcIt); Argument &dstA = const_cast<Argument&>(*dstIt); if (!matchArgument2(srcScope,srcFileScope,srcA, - dstScope,dstFileScope,dstA) + dstScope,dstFileScope,dstA, + lang) ) { NOMATCH @@ -2002,7 +2005,6 @@ bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,cons } - // merges the initializer of two argument lists // pre: the types of the arguments in the list should match. void mergeArguments(ArgumentList &srcAl,ArgumentList &dstAl,bool forceNameOverwrite) @@ -2172,7 +2174,7 @@ static void findMembersWithSpecificName(const MemberName *mn, match=matchArguments2( md->getOuterScope(),fd,&mdAl, Doxygen::globalScope,fd,argList_p.get(), - checkCV); + checkCV,md->getLanguage()); } if (match) { @@ -2246,7 +2248,7 @@ bool getDefs(const QCString &scName, if (memberName.left(9)!="operator " && // treat operator conversion methods // as a special case (im=memberName.findRev("::"))!=-1 && - im<(int)memberName.length()-2 // not A:: + im<static_cast<int>(memberName.length())-2 // not A:: ) { mScope=memberName.left(im); @@ -2310,7 +2312,7 @@ bool getDefs(const QCString &scName, bool match = args.isEmpty() || matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),&mmdAl, fcd, fcd->getFileDef(),argList.get(), - checkCV); + checkCV,mmd->getLanguage()); //printf("match=%d\n",match); if (match) { @@ -2433,9 +2435,8 @@ bool getDefs(const QCString &scName, const ArgumentList &mmdAl = mmd->argumentList(); if (matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),&mmdAl, - Doxygen::globalScope,mmd->getFileDef(),argList.get(), - checkCV - ) + Doxygen::globalScope,mmd->getFileDef(),argList.get(), + checkCV,mmd->getLanguage()) ) { fuzzy_mmd = mmd; @@ -2520,7 +2521,7 @@ bool getDefs(const QCString &scName, match=matchArguments2( mmd->getOuterScope(),mmd->getFileDef(),&mmdAl, fnd,mmd->getFileDef(),argList_p.get(), - checkCV); + checkCV,mmd->getLanguage()); } if (match) { @@ -2696,7 +2697,7 @@ static bool getScopeDefs(const QCString &docScope,const QCString &scope, cd=0;nd=0; QCString scopeName=scope; - //printf("getScopeDefs: docScope='%s' scope='%s'\n",docScope,scope); + //printf("getScopeDefs: docScope='%s' scope='%s'\n",qPrint(docScope),qPrint(scope)); if (scopeName.isEmpty()) return FALSE; bool explicitGlobalScope=FALSE; @@ -2719,8 +2720,7 @@ static bool getScopeDefs(const QCString &docScope,const QCString &scope, if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::"); if (((cd=getClass(fullName)) || // normal class - (cd=getClass(fullName+"-p")) //|| // ObjC protocol - //(cd=getClass(fullName+"-g")) // C# generic + (cd=getClass(fullName+"-p")) // ObjC protocol ) && cd->isLinkable()) { return TRUE; // class link written => quit @@ -2745,9 +2745,9 @@ static bool getScopeDefs(const QCString &docScope,const QCString &scope, static bool isLowerCase(QCString &s) { if (s.isEmpty()) return true; - uchar *p=(uchar*)s.data(); + const char *p=s.data(); int c; - while ((c=*p++)) if (!islower(c)) return false; + while ((c=static_cast<uchar>(*p++))) if (!islower(c)) return false; return true; } @@ -2802,11 +2802,12 @@ bool resolveRef(/* in */ const QCString &scName, return FALSE; } - //printf("scName=%s fullName=%s\n",scName,qPrint(fullName)); + //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName)); // check if this is a class or namespace reference if (scName!=fullName && getScopeDefs(scName,fullName,cd,nd)) { + //printf("found scopeDef\n"); if (cd) // scope matches that of a class { *resContext = cd; @@ -2823,7 +2824,7 @@ bool resolveRef(/* in */ const QCString &scName, { //printf("found scName=%s fullName=%s scName==fullName=%d " // "inSeeBlock=%d scopePos=%d!\n", - // scName,qPrint(fullName),scName==fullName,inSeeBlock,scopePos); + // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos); return FALSE; } // continue search... @@ -2942,7 +2943,7 @@ bool resolveRef(/* in */ const QCString &scName, QCString linkToText(SrcLangExt lang,const QCString &link,bool isFileName) { - //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); QCString result=link; if (!result.isEmpty()) { @@ -2984,7 +2985,7 @@ QCString linkToText(SrcLangExt lang,const QCString &link,bool isFileName) * instead of :: the \# symbol may also be used. */ -bool generateRef(OutputDocInterface &od,const char *scName, +bool generateRef(BaseOutputDocInterface &od,const char *scName, const char *name,bool inSeeBlock,const char *rt) { //printf("generateRef(scName=%s,name=%s,inSee=%d,rt=%s)\n",scName,name,inSeeBlock,rt); @@ -3148,7 +3149,7 @@ bool resolveLink(/* in */ const QCString &scName, // basis for the link's text. // returns TRUE if a link could be generated. -bool generateLink(OutputDocInterface &od,const QCString &clName, +bool generateLink(OutputList &ol,const QCString &clName, const QCString &lr,bool inSeeBlock,const QCString <) { //printf("generateLink(clName=%s,lr=%s,lr=%s)\n",clName,lr,lt); @@ -3170,11 +3171,11 @@ bool generateLink(OutputDocInterface &od,const QCString &clName, { linkText=linkToText(compound->getLanguage(),lt,TRUE); } - od.writeObjectLink(compound->getReference(), + ol.writeObjectLink(compound->getReference(), compound->getOutputFileBase(),anchor,linkText); if (!compound->isReference()) { - writePageRef(od,compound->getOutputFileBase(),anchor); + writePageRef(ol,compound->getOutputFileBase(),anchor); } } else @@ -3185,12 +3186,12 @@ bool generateLink(OutputDocInterface &od,const QCString &clName, } else // link could not be found { - od.docify(linkText); + ol.docify(linkText); return FALSE; } } -void generateFileRef(OutputDocInterface &od,const QCString &name,const QCString &text) +void generateFileRef(OutputList &ol,const QCString &name,const QCString &text) { //printf("generateFileRef(%s,%s)\n",name,text); QCString linkText = text.isEmpty() ? text : name; @@ -3200,9 +3201,9 @@ void generateFileRef(OutputDocInterface &od,const QCString &name,const QCString if ((fd=findFileDef(Doxygen::inputNameLinkedMap,name,ambig)) && fd->isLinkable()) // link to documented input file - od.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText); + ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText); else - od.docify(linkText); + ol.docify(linkText); } //---------------------------------------------------------------------- @@ -3228,7 +3229,7 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const QCString &n,bool &ambi const int maxAddrSize = 20; char addr[maxAddrSize]; - qsnprintf(addr,maxAddrSize,"%p:",(void*)fnMap); + qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap)); QCString key = addr; key+=n; @@ -3496,7 +3497,7 @@ QCString escapeCharsInString(const QCString &name,bool allowDots,bool allowUnder if (doEscape) // not a valid unicode char or escaping needed { char ids[5]; - unsigned char id = (unsigned char)c; + unsigned char id = static_cast<unsigned char>(c); ids[0]='_'; ids[1]='x'; ids[2]=hex[id>>4]; @@ -3512,7 +3513,7 @@ QCString escapeCharsInString(const QCString &name,bool allowDots,bool allowUnder else { growBuf.addChar('_'); - growBuf.addChar((char)tolower(c)); + growBuf.addChar(static_cast<char>(tolower(c))); } break; } @@ -3574,7 +3575,7 @@ QCString unescapeCharsInString(const QCString &s) default: if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A' { - result+=(char)toupper(*p); + result+=static_cast<char>(toupper(*p)); p++; } else // unknown escape, pass underscore character as-is @@ -3597,6 +3598,8 @@ static std::unordered_map<std::string,int> g_usedNames; static std::mutex g_usedNamesMutex; static int g_usedNamesCount=1; + + /*! This function determines the file name on disk of an item * given its name, which could be a class name with template * arguments, so special characters need to be escaped. @@ -3604,8 +3607,8 @@ static int g_usedNamesCount=1; QCString convertNameToFile(const QCString &name,bool allowDots,bool allowUnderscore) { if (name.isEmpty()) return name; - static bool shortNames = Config_getBool(SHORT_NAMES); - static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); + bool shortNames = Config_getBool(SHORT_NAMES); + bool createSubdirs = Config_getBool(CREATE_SUBDIRS); QCString result; if (shortNames) // use short names only { @@ -3632,7 +3635,7 @@ QCString convertNameToFile(const QCString &name,bool allowDots,bool allowUndersc // third algorithm based on MD5 hash uchar md5_sig[16]; char sigStr[33]; - MD5Buffer((const unsigned char *)result.data(),resultLen,md5_sig); + MD5Buffer(result.data(),resultLen,md5_sig); MD5SigToString(md5_sig,sigStr); result=result.left(128-32)+sigStr; } @@ -3640,12 +3643,14 @@ QCString convertNameToFile(const QCString &name,bool allowDots,bool allowUndersc if (createSubdirs) { int l1Dir=0,l2Dir=0; + int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL); + int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1; // compute md5 hash to determine sub directory to use uchar md5_sig[16]; - MD5Buffer((const unsigned char *)result.data(),result.length(),md5_sig); - l1Dir = md5_sig[14]&0xf; - l2Dir = md5_sig[15]; + MD5Buffer(result.data(),result.length(),md5_sig); + l1Dir = md5_sig[14] & 0xf; + l2Dir = md5_sig[15] & createSubdirsBitmaskL2; result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir)); } @@ -3678,7 +3683,8 @@ void createSubDirs(const Dir &d) { if (Config_getBool(CREATE_SUBDIRS)) { - // create 4096 subdirectories + // create up to 4096 subdirectories + int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL); int l1,l2; for (l1=0;l1<16;l1++) { @@ -3688,7 +3694,7 @@ void createSubDirs(const Dir &d) { term("Failed to create output directory '%s'\n",qPrint(subdir)); } - for (l2=0;l2<256;l2++) + for (l2=0; l2 < createSubdirsLevelPow2; l2++) { QCString subsubdir; subsubdir.sprintf("d%x/d%02x",l1,l2); @@ -3706,11 +3712,12 @@ void clearSubDirs(const Dir &d) if (Config_getBool(CREATE_SUBDIRS)) { // remove empty subdirectories + int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL); for (int l1=0;l1<16;l1++) { QCString subdir; subdir.sprintf("d%x",l1); - for (int l2=0;l2<256;l2++) + for (int l2=0; l2 < createSubdirsLevelPow2; l2++) { QCString subsubdir; subsubdir.sprintf("d%x/d%02x",l1,l2); @@ -3923,8 +3930,8 @@ QCString convertToId(const QCString &s) else { encChar[0]='_'; - encChar[1]=hex[((unsigned char)c)>>4]; - encChar[2]=hex[((unsigned char)c)&0xF]; + encChar[1]=hex[static_cast<unsigned char>(c)>>4]; + encChar[2]=hex[static_cast<unsigned char>(c)&0xF]; encChar[3]=0; growBuf.addStr(encChar); } @@ -4000,9 +4007,9 @@ QCString convertToDocBook(const QCString &s, const bool retainNewline) { if (s.isEmpty()) return s; GrowBuf growBuf; - const unsigned char *q; + const char *q; int cnt; - const unsigned char *p=(const unsigned char *)s.data(); + const char *p=s.data(); char c; while ((c=*p++)) { @@ -4022,8 +4029,8 @@ QCString convertToDocBook(const QCString &s, const bool retainNewline) if (*q == ';') { --p; // we need & as well - DocSymbol::SymType res = HtmlEntityMapper::instance()->name2sym(QCString((char *)p).left(cnt)); - if (res == DocSymbol::Sym_Unknown) + HtmlEntityMapper::SymType res = HtmlEntityMapper::instance()->name2sym(QCString(p).left(cnt)); + if (res == HtmlEntityMapper::Sym_Unknown) { p++; growBuf.addStr("&"); @@ -4189,9 +4196,9 @@ QCString convertCharEntitiesToUTF8(const QCString &str) growBuf.addStr(s.substr(i,p-i)); } QCString entity(match.str()); - DocSymbol::SymType symType = HtmlEntityMapper::instance()->name2sym(entity); + HtmlEntityMapper::SymType symType = HtmlEntityMapper::instance()->name2sym(entity); const char *code=0; - if (symType!=DocSymbol::Sym_Unknown && (code=HtmlEntityMapper::instance()->utf8(symType))) + if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance()->utf8(symType))) { growBuf.addStr(code); } @@ -4338,14 +4345,14 @@ void addMembersToMemberGroup(MemberList *ml, */ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCString &templSpec,SrcLangExt lang) { - static reg::Ex re_norm(R"(\a[\w:]*)"); - static reg::Ex re_fortran(R"(\a[\w:()=]*)"); + static const reg::Ex re_norm(R"(\a[\w:]*)"); + static const reg::Ex re_fortran(R"(\a[\w:()=]*)"); static const reg::Ex *re = &re_norm; name.resize(0); templSpec.resize(0); if (type.isEmpty()) return -1; - int typeLen=(int)type.length(); + size_t typeLen=type.length(); if (typeLen>0) { if (lang == SrcLangExt_Fortran) @@ -4357,33 +4364,33 @@ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStri } } std::string s = type.str(); - reg::Iterator it(s,*re,(int)pos); + reg::Iterator it(s,*re,static_cast<int>(pos)); reg::Iterator end; if (it!=end) { const auto &match = *it; - int i = (int)match.position(); - int l = (int)match.length(); - int ts = i+l; - int te = ts; - int tl = 0; + size_t i = match.position(); + size_t l = match.length(); + size_t ts = i+l; + size_t te = ts; + size_t tl = 0; - while (ts<typeLen && type[ts]==' ') ts++,tl++; // skip any whitespace - if (ts<typeLen && type[ts]=='<') // assume template instance + while (ts<typeLen && type[static_cast<uint>(ts)]==' ') ts++,tl++; // skip any whitespace + if (ts<typeLen && type[static_cast<uint>(ts)]=='<') // assume template instance { // locate end of template te=ts+1; int brCount=1; while (te<typeLen && brCount!=0) { - if (type[te]=='<') + if (type[static_cast<uint>(te)]=='<') { - if (te<typeLen-1 && type[te+1]=='<') te++; else brCount++; + if (te<typeLen-1 && type[static_cast<uint>(te)+1]=='<') te++; else brCount++; } - if (type[te]=='>') + if (type[static_cast<uint>(te)]=='>') { - if (te<typeLen-1 && type[te+1]=='>') te++; else brCount--; + if (te<typeLen-1 && type[static_cast<uint>(te)+1]=='>') te++; else brCount--; } te++; } @@ -4393,18 +4400,18 @@ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStri { templSpec = QCString(type).mid(ts,te-ts); tl+=te-ts; - pos=i+l+tl; + pos=static_cast<int>(i+l+tl); } else // no template part { - pos=i+l; + pos=static_cast<int>(i+l); } //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n", // qPrint(type),pos,qPrint(name),qPrint(templSpec),i); - return i; + return static_cast<int>(i); } } - pos = typeLen; + pos = static_cast<int>(typeLen); //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n", // qPrint(type),pos,qPrint(name),qPrint(templSpec)); return -1; @@ -4937,14 +4944,14 @@ void filterLatexString(TextStream &t,const QCString &str, { if (str.isEmpty()) return; //if (strlen(str)<2) stackTrace(); - const unsigned char *p=(const unsigned char *)str.data(); - const unsigned char *q; + const char *p=str.data(); + const char *q; int cnt; unsigned char c; unsigned char pc='\0'; while (*p) { - c=*p++; + c=static_cast<unsigned char>(*p++); if (insidePre) { @@ -4952,13 +4959,13 @@ void filterLatexString(TextStream &t,const QCString &str, { case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd // the LaTeX command \ucr has been defined in doxygen.sty - if ((unsigned char)*(p) == 0xbf && (unsigned char)*(p+1) == 0xbd) + if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd) { t << "{\\ucr}"; p += 2; } else - t << (char)c; + t << static_cast<char>(c); break; case '\\': t << "\\(\\backslash\\)"; break; case '{': t << "\\{"; break; @@ -4970,7 +4977,7 @@ void filterLatexString(TextStream &t,const QCString &str, case '$': t << "\\$"; break; case '"': t << "\"{}"; break; case '-': t << "-\\/"; break; - case '^': insideTable ? t << "\\string^" : t << (char)c; break; + case '^': insideTable ? t << "\\string^" : t << static_cast<char>(c); break; case '~': t << "\\string~"; break; case '\n': if (retainNewline) t << "\\newline"; else t << ' '; break; @@ -4978,7 +4985,7 @@ void filterLatexString(TextStream &t,const QCString &str, break; default: if (c<32) t << ' '; // non printable control character - else t << (char)c; + else t << static_cast<char>(c); break; } } @@ -4988,13 +4995,13 @@ void filterLatexString(TextStream &t,const QCString &str, { case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd // the LaTeX command \ucr has been defined in doxygen.sty - if ((unsigned char)*(p) == 0xbf && (unsigned char)*(p+1) == 0xbd) + if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd) { t << "{\\ucr}"; p += 2; } else - t << (char)c; + t << static_cast<char>(c); break; case '#': t << "\\#"; break; case '$': t << "\\$"; break; @@ -5011,8 +5018,8 @@ void filterLatexString(TextStream &t,const QCString &str, if (*q == ';') { --p; // we need & as well - DocSymbol::SymType res = HtmlEntityMapper::instance()->name2sym(QCString((char *)p).left(cnt)); - if (res == DocSymbol::Sym_Unknown) + HtmlEntityMapper::SymType res = HtmlEntityMapper::instance()->name2sym(QCString(p).left(cnt)); + if (res == HtmlEntityMapper::Sym_Unknown) { p++; t << "\\&"; @@ -5080,7 +5087,7 @@ void filterLatexString(TextStream &t,const QCString &str, } else { - t << (char)c; + t << static_cast<char>(c); } } } @@ -5203,7 +5210,7 @@ QCString latexFilterURL(const QCString &s) { if (s.isEmpty()) return s; TextStream t; - const signed char *p=(const signed char*)s.data(); + const char *p=s.data(); char c; while ((c=*p++)) { @@ -5215,7 +5222,7 @@ QCString latexFilterURL(const QCString &s) default: if (c<0) { - unsigned char id = (unsigned char)c; + unsigned char id = static_cast<unsigned char>(c); t << "\\%" << hex[id>>4] << hex[id&0xF]; } else @@ -5280,7 +5287,7 @@ bool checkExtension(const QCString &fName, const QCString &ext) QCString addHtmlExtensionIfMissing(const QCString &fName) { if (fName.isEmpty()) return fName; - if (fName.find('.')==-1) // no extension + if (stripPath(fName).find('.')==-1) // no extension { return QCString(fName)+Doxygen::htmlFileExtension; } @@ -5468,7 +5475,7 @@ g_lang2extMap[] = { "sql", "sql", SrcLangExt_SQL, ".sql" }, { "md", "md", SrcLangExt_Markdown, ".md" }, { "lex", "lex", SrcLangExt_Lex, ".l" }, - { 0, 0, (SrcLangExt)0, 0 } + { 0, 0, static_cast<SrcLangExt>(0),0} }; bool updateLanguageMapping(const QCString &extension,const QCString &language) @@ -5587,7 +5594,7 @@ SrcLangExt getLanguageFromFileName(const QCString& fileName, SrcLangExt defLang) if (it!=g_extLookup.end()) // listed extension { //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal); - return (SrcLangExt)it->second; + return static_cast<SrcLangExt>(it->second); } //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName)); return defLang; // not listed => assume C-ish language. @@ -5699,17 +5706,17 @@ bool checkIfTypedef(const Definition *scope,const FileDef *fileScope,const QCStr static int nextUTF8CharPosition(const QCString &utf8Str,uint len,uint startPos) { if (startPos>=len) return len; - uchar c = (uchar)utf8Str[startPos]; + uchar c = static_cast<uchar>(utf8Str[startPos]); int bytes=getUTF8CharNumBytes(c); if (c=='&') // skip over character entities { bytes=1; int (*matcher)(int) = 0; - c = (uchar)utf8Str[startPos+bytes]; + c = static_cast<uchar>(utf8Str[startPos+bytes]); if (c=='#') // numerical entity? { bytes++; - c = (uchar)utf8Str[startPos+bytes]; + c = static_cast<uchar>(utf8Str[startPos+bytes]); if (c=='x') // hexadecimal entity? { bytes++; @@ -5727,7 +5734,7 @@ static int nextUTF8CharPosition(const QCString &utf8Str,uint len,uint startPos) } if (matcher) { - while ((c = (uchar)utf8Str[startPos+bytes])!=0 && matcher(c)) + while ((c = static_cast<uchar>(utf8Str[startPos+bytes]))!=0 && matcher(c)) { bytes++; } @@ -5746,13 +5753,17 @@ QCString parseCommentAsText(const Definition *scope,const MemberDef *md, if (doc.isEmpty()) return ""; //printf("parseCommentAsText(%s)\n",qPrint(doc)); TextStream t; - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocRoot> root { validatingParseDoc(*parser.get(), - fileName,lineNr, - (Definition*)scope,(MemberDef*)md,doc,FALSE,FALSE, - QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - auto visitor = std::make_unique<TextDocVisitor>(t); - root->accept(visitor.get()); + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + fileName,lineNr, + const_cast<Definition*>(scope),const_cast<MemberDef*>(md),doc,FALSE,FALSE, + QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get()); + if (astImpl) + { + TextDocVisitor visitor(t); + std::visit(visitor,astImpl->root); + } QCString result = convertCharEntitiesToUTF8(t.str().c_str()).stripWhiteSpace(); int i=0; int charCnt=0; @@ -5788,10 +5799,10 @@ static QCString expandAliasRec(StringUnorderedSet &aliasesProcessed, struct Marker { - Marker(int p, int n,int s) : pos(p),number(n),size(s) {} - int pos; // position in the string + Marker(size_t p, int n,size_t s) : pos(p),number(n),size(s) {} + size_t pos; // position in the string int number; // argument number - int size; // size of the marker + size_t size; // size of the marker }; /** For a string \a s that starts with a command name, returns the character @@ -5817,7 +5828,7 @@ static int findEndOfCommand(const char *s) QCString args = extractAliasArgs(p,0); i+=args.length(); } - i+=(int)(p-s); + i+=static_cast<int>(p-s); } return i; } @@ -5833,8 +5844,8 @@ static QCString replaceAliasArguments(StringUnorderedSet &aliasesProcessed, // first make a list of arguments from the comma separated argument list std::vector<QCString> args; - int i,l=(int)argList.length(); - int s=0; + size_t i,l=argList.length(); + size_t s=0; for (i=0;i<l;i++) { char c = argList.at(i); @@ -5857,7 +5868,7 @@ static QCString replaceAliasArguments(StringUnorderedSet &aliasesProcessed, l = aliasValue.length(); char pc='\0'; bool insideMarkerId=false; - int markerStart=0; + size_t markerStart=0; auto isDigit = [](char c) { return c>='0' && c<='9'; }; for (i=0;i<=l;i++) { @@ -5865,7 +5876,7 @@ static QCString replaceAliasArguments(StringUnorderedSet &aliasesProcessed, if (insideMarkerId && !isDigit(c)) // found end of a markerId { insideMarkerId = false; - int markerLen = i-markerStart; + size_t markerLen = i-markerStart; markerList.push_back(Marker(markerStart-1, aliasValue.mid(markerStart,markerLen).toInt(), markerLen+1)); @@ -5888,13 +5899,13 @@ static QCString replaceAliasArguments(StringUnorderedSet &aliasesProcessed, // then we replace the markers with the corresponding arguments in one pass QCString result; - int p=0; - for (i=0;i<(int)markerList.size();i++) + size_t p=0; + for (i=0;i<markerList.size();i++) { const Marker &m = markerList.at(i); result+=aliasValue.mid(p,m.pos-p); //printf("part before marker %d: '%s'\n",i,qPrint(aliasValue.mid(p,m->pos-p))); - if (m.number>0 && m.number<=(int)args.size()) // valid number + if (m.number>0 && m.number<=static_cast<int>(args.size())) // valid number { result+=expandAliasRec(aliasesProcessed,args.at(m.number-1),TRUE); //printf("marker index=%d pos=%d number=%d size=%d replacement %s\n",i,m->pos,m->number,m->size, @@ -6124,28 +6135,28 @@ void stackTrace() #endif } -static int transcodeCharacterBuffer(const QCString &fileName,BufStr &srcBuf,int size, +static size_t transcodeCharacterBuffer(const QCString &fileName,BufStr &srcBuf,size_t size, const QCString &inputEncoding,const QCString &outputEncoding) { if (inputEncoding.isEmpty() || outputEncoding.isEmpty()) return size; if (qstricmp(inputEncoding,outputEncoding)==0) return size; void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data()); - if (cd==(void *)(-1)) + if (cd==reinterpret_cast<void *>(-1)) { term("unsupported character conversion: '%s'->'%s': %s\n" "Check the INPUT_ENCODING setting in the config file!\n", qPrint(inputEncoding),qPrint(outputEncoding),strerror(errno)); } - int tmpBufSize=size*4+1; + size_t tmpBufSize=size*4+1; BufStr tmpBuf(tmpBufSize); size_t iLeft=size; size_t oLeft=tmpBufSize; const char *srcPtr = srcBuf.data(); char *dstPtr = tmpBuf.data(); - uint newSize=0; + size_t newSize=0; if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft)) { - newSize = tmpBufSize-(int)oLeft; + newSize = tmpBufSize-oLeft; srcBuf.shrink(newSize); strncpy(srcBuf.data(),tmpBuf.data(),newSize); //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf)); @@ -6163,7 +6174,7 @@ static int transcodeCharacterBuffer(const QCString &fileName,BufStr &srcBuf,int bool readInputFile(const QCString &fileName,BufStr &inBuf,bool filter,bool isSourceCode) { // try to open file - int size=0; + size_t size=0; FileInfo fi(fileName.str()); if (!fi.exists()) return FALSE; @@ -6176,7 +6187,7 @@ bool readInputFile(const QCString &fileName,BufStr &inBuf,bool filter,bool isSou err("could not open file %s\n",qPrint(fileName)); return FALSE; } - size=(int)fi.size(); + size=fi.size(); // read the file inBuf.skip(size); f.read(inBuf.data(),size); @@ -6199,7 +6210,7 @@ bool readInputFile(const QCString &fileName,BufStr &inBuf,bool filter,bool isSou const int bufSize=1024; char buf[bufSize]; int numRead; - while ((numRead=(int)fread(buf,1,bufSize,f))>0) + while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0) { //printf(">>>>>>>>Reading %d bytes\n",numRead); inBuf.addArray(buf,numRead),size+=numRead; @@ -6212,23 +6223,25 @@ bool readInputFile(const QCString &fileName,BufStr &inBuf,bool filter,bool isSou int start=0; if (size>=2 && - ((uchar)inBuf.at(0)==0xFF && (uchar)inBuf.at(1)==0xFE) // Little endian BOM + static_cast<uchar>(inBuf.at(0))==0xFF && + static_cast<uchar>(inBuf.at(1))==0xFE // Little endian BOM ) // UCS-2LE encoded file { transcodeCharacterBuffer(fileName,inBuf,inBuf.curPos(), "UCS-2LE","UTF-8"); } else if (size>=2 && - ((uchar)inBuf.at(0)==0xFE && (uchar)inBuf.at(1)==0xFF) // big endian BOM + static_cast<uchar>(inBuf.at(0))==0xFE && + static_cast<uchar>(inBuf.at(1))==0xFF // big endian BOM ) // UCS-2BE encoded file { transcodeCharacterBuffer(fileName,inBuf,inBuf.curPos(), "UCS-2BE","UTF-8"); } else if (size>=3 && - (uchar)inBuf.at(0)==0xEF && - (uchar)inBuf.at(1)==0xBB && - (uchar)inBuf.at(2)==0xBF + static_cast<uchar>(inBuf.at(0))==0xEF && + static_cast<uchar>(inBuf.at(1))==0xBB && + static_cast<uchar>(inBuf.at(2))==0xBF ) // UTF-8 encoded file { inBuf.dropFromStart(3); // remove UTF-8 BOM: no translation needed @@ -6244,7 +6257,7 @@ bool readInputFile(const QCString &fileName,BufStr &inBuf,bool filter,bool isSou // and translate CR's size=inBuf.curPos()-start; - int newSize=filterCRLF(inBuf.data()+start,size); + size_t newSize=filterCRLF(inBuf.data()+start,size); //printf("filter char at %p size=%d newSize=%d\n",qPrint(dest)+oldPos,size,newSize); if (newSize!=size) // we removed chars { @@ -6327,7 +6340,7 @@ bool patternMatch(const FileInfo &fi,const StringVector &patList) QCString externalLinkTarget(const bool parent) { - static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW); + bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW); if (extLinksInWindow) return "target=\"_blank\" "; else if (parent) @@ -6367,9 +6380,9 @@ QCString externalRef(const QCString &relPath,const QCString &ref,bool href) */ void writeColoredImgData(const QCString &dir,ColoredImgDataItem data[]) { - static int hue = Config_getInt(HTML_COLORSTYLE_HUE); - static int sat = Config_getInt(HTML_COLORSTYLE_SAT); - static int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); + int hue = Config_getInt(HTML_COLORSTYLE_HUE); + int sat = Config_getInt(HTML_COLORSTYLE_SAT); + int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); while (data->name) { QCString fileName = dir+"/"+data->name; @@ -6397,9 +6410,9 @@ QCString replaceColorMarkers(const QCString &str) static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])"); reg::Iterator it(s,re); reg::Iterator end; - static int hue = Config_getInt(HTML_COLORSTYLE_HUE); - static int sat = Config_getInt(HTML_COLORSTYLE_SAT); - static int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); + int hue = Config_getInt(HTML_COLORSTYLE_HUE); + int sat = Config_getInt(HTML_COLORSTYLE_SAT); + int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); size_t sl=s.length(); size_t p=0; for (; it!=end ; ++it) @@ -6418,9 +6431,9 @@ QCString replaceColorMarkers(const QCString &str) int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]); ColoredImage::hsl2rgb(hue/360.0,sat/255.0, pow(level/255.0,gamma/100.0),&r,&g,&b); - red = (int)(r*255.0); - green = (int)(g*255.0); - blue = (int)(b*255.0); + red = static_cast<int>(r*255.0); + green = static_cast<int>(g*255.0); + blue = static_cast<int>(b*255.0); char colStr[8]; colStr[0]='#'; colStr[1]=hex[red>>4]; @@ -6589,8 +6602,8 @@ QCString correctURL(const QCString &url,const QCString &relPath) bool protectionLevelVisible(Protection prot) { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - static bool extractPackage = Config_getBool(EXTRACT_PACKAGE); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool extractPackage = Config_getBool(EXTRACT_PACKAGE); return (prot!=Private && prot!=Package) || (prot==Private && extractPrivate) || @@ -6610,7 +6623,7 @@ QCString stripIndentation(const QCString &s) int indent=0; int minIndent=1000000; // "infinite" bool searchIndent=TRUE; - static int tabSize=Config_getInt(TAB_SIZE); + int tabSize=Config_getInt(TAB_SIZE); while ((c=*p++)) { if (c=='\t') indent+=tabSize - (indent%tabSize); @@ -6716,7 +6729,7 @@ void stripIndentation(QCString &doc,const int indentationLevel) bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile) { - static bool allExternals = Config_getBool(ALLEXTERNALS); + bool allExternals = Config_getBool(ALLEXTERNALS); bool isDocFile = fd->isDocumentationFile(); genSourceFile = !isDocFile && fd->generateSourceFile(); return ( ((allExternals && fd->isLinkable()) || @@ -6860,7 +6873,7 @@ void convertProtectionLevel( int *outListType2 ) { - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); // default representing 1-1 mapping *outListType1=inListType; *outListType2=-1; @@ -7089,11 +7102,8 @@ void writeExtraLatexPackages(TextStream &t) void writeLatexSpecialFormulaChars(TextStream &t) { unsigned char minus[4]; // Superscript minus - char *pminus = (char *)minus; unsigned char sup2[3]; // Superscript two - char *psup2 = (char *)sup2; unsigned char sup3[3]; - char *psup3 = (char *)sup3; // Superscript three minus[0]= 0xE2; minus[1]= 0x81; minus[2]= 0xBB; @@ -7106,9 +7116,9 @@ void writeLatexSpecialFormulaChars(TextStream &t) sup3[2]= 0; t << "\\usepackage{newunicodechar}\n" - " \\newunicodechar{" << pminus << "}{${}^{-}$}% Superscript minus\n" - " \\newunicodechar{" << psup2 << "}{${}^{2}$}% Superscript two\n" - " \\newunicodechar{" << psup3 << "}{${}^{3}$}% Superscript three\n" + " \\newunicodechar{" << minus << "}{${}^{-}$}% Superscript minus\n" + " \\newunicodechar{" << sup2 << "}{${}^{2}$}% Superscript two\n" + " \\newunicodechar{" << sup3 << "}{${}^{3}$}% Superscript three\n" "\n"; } @@ -7121,6 +7131,7 @@ bool recognizeFixedForm(const QCString &contents, FortranFormat format) if (format == FortranFormat_Fixed) return TRUE; if (format == FortranFormat_Free) return FALSE; + int tabSize=Config_getInt(TAB_SIZE); for (int i=0;;i++) { @@ -7132,6 +7143,9 @@ bool recognizeFixedForm(const QCString &contents, FortranFormat format) column=0; skipLine=FALSE; break; + case '\t': + column += tabSize-1; + break; case ' ': break; case '\000': @@ -7146,8 +7160,7 @@ bool recognizeFixedForm(const QCString &contents, FortranFormat format) if (skipLine) break; return FALSE; case '!': - if (column>1 && column<7) return FALSE; - skipLine=TRUE; + if (column!=6) skipLine=TRUE; break; default: if (skipLine) break; @@ -7175,13 +7188,13 @@ QCString clearBlock(const QCString &s,const QCString &begin,const QCString &end) { if (s.isEmpty() || begin.isEmpty() || end.isEmpty()) return s; const char *p, *q; - int beginLen = (int)begin.length(); - int endLen = (int)end.length(); - int resLen = 0; + size_t beginLen = begin.length(); + size_t endLen = end.length(); + size_t resLen = 0; for (p=s.data(); (q=strstr(p,begin.data()))!=0; p=q+endLen) { - resLen+=(int)(q-p); - p=q+beginLen; + resLen += q-p; + p = q+beginLen; if ((q=strstr(p,end.data()))==0) { resLen+=beginLen; @@ -7195,7 +7208,7 @@ QCString clearBlock(const QCString &s,const QCString &begin,const QCString &end) char *r; for (r=result.rawData(), p=s.data(); (q=strstr(p,begin.data()))!=0; p=q+endLen) { - int l = (int)(q-p); + size_t l = q-p; memcpy(r,p,l); r+=l; p=q+beginLen; @@ -7324,7 +7337,7 @@ StringVector split(const std::string &s,const reg::Ex &delimiter) int findIndex(const StringVector &sv,const std::string &s) { auto it = std::find(sv.begin(),sv.end(),s); - return it!=sv.end() ? (int)(it-sv.begin()) : -1; + return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1; } /// find the index of the first occurrence of pattern \a re in a string \a s @@ -7332,7 +7345,7 @@ int findIndex(const StringVector &sv,const std::string &s) int findIndex(const std::string &s,const reg::Ex &re) { reg::Match match; - return reg::search(s,match,re) ? (int)match.position() : -1; + return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1; } /// create a string where the string in the vector are joined by the given delimiter @@ -60,7 +60,7 @@ class Dir; class TextGeneratorIntf { public: - virtual ~TextGeneratorIntf() {} + virtual ~TextGeneratorIntf() = default; virtual void writeString(const QCString &,bool) const = 0; virtual void writeBreak(int indent) const = 0; virtual void writeLink(const QCString &extRef,const QCString &file, @@ -72,15 +72,14 @@ class TextGeneratorIntf class TextGeneratorOLImpl : public TextGeneratorIntf { public: - virtual ~TextGeneratorOLImpl() {} - TextGeneratorOLImpl(OutputDocInterface &od); + TextGeneratorOLImpl(BaseOutputDocInterface &od); void writeString(const QCString &s,bool keepSpaces) const; void writeBreak(int indent) const; void writeLink(const QCString &extRef,const QCString &file, const QCString &anchor,const QCString &text ) const; private: - OutputDocInterface &m_od; + BaseOutputDocInterface &m_od; }; //-------------------------------------------------------------------- @@ -137,19 +136,19 @@ bool resolveLink(/* in */ const QCString &scName, /* out */ QCString &resAnchor ); -bool generateLink(OutputDocInterface &od,const QCString &, +bool generateLink(OutputList &ol,const QCString &, const QCString &,bool inSeeBlock,const QCString &); -void generateFileRef(OutputDocInterface &od,const QCString &, +void generateFileRef(OutputList &ol,const QCString &, const QCString &linkTxt=QCString()); -void writePageRef(OutputDocInterface &od,const QCString &cn,const QCString &mn); +void writePageRef(OutputList &ol,const QCString &cn,const QCString &mn); -QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec); +//QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec); bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,const ArgumentList *srcAl, const Definition *dstScope,const FileDef *dstFileScope,const ArgumentList *dstAl, - bool checkCV + bool checkCV,SrcLangExt lang ); void mergeArguments(ArgumentList &,ArgumentList &,bool forceNameOverwrite=FALSE); @@ -379,8 +378,8 @@ struct ColoredImgDataItem const char *name; unsigned short width; unsigned short height; - unsigned char *content; - unsigned char *alpha; + const unsigned char *content; + const unsigned char *alpha; }; void writeColoredImgData(const QCString &dir,ColoredImgDataItem data[]); diff --git a/src/variant.h b/src/variant.h deleted file mode 100644 index 7f0407e..0000000 --- a/src/variant.h +++ /dev/null @@ -1,303 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1997-2021 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 VARIANT_H -#define VARIANT_H - -#include <string> -#include <utility> - -namespace details -{ - -//----- template helper class to compute the maximum over a set of template arguments - -//! generic declaration of a template to compute the maximum size of a set of template parameters. -template <size_t arg1, size_t ... others> -struct TMax; - -//! specialization to stop the recursion when arrived at a single argument. -template <size_t arg> -struct TMax<arg> -{ - //! the compile time computed maximum value - static const size_t value = arg; -}; - -//! recursive definition for multiple arguments -template <size_t arg1, size_t arg2, size_t ... others> -struct TMax<arg1, arg2, others...> -{ - //! the compile time computed maximum value - static const size_t value = arg1 >= arg2 ? - TMax<arg1, others...>::value : - TMax<arg2, others...>::value ; -}; - -//------ helper class to deal with memory management of an array of template types - -//! generic declaration of a template to handle copying, moving, and deleting -//! type that matches a given index in the list of variant parameters. -template<uint8_t n,typename... Ts> -struct HelperRecT; - -//! Recursive template definition for multiple arguments. -//! Each function checks for a matching index, and if found does the action. -//! If not, the same function is called with the next index and one less type argument. -template<uint8_t n, typename F, typename... Ts> -struct HelperRecT<n, F, Ts...> -{ - //! Helper function to copy an instance of a type by performing a placement new. - //! @param id The id if the type to search for in the template parameter list - //! @param src_v A pointer to the value of the type to copy from. - //! @param dst_v A pointer to the variable to copy to. - inline static void copy(uint8_t id, const void * src_v, void * dst_v) - { - if (n==id) // found it - { - new (dst_v) F(*reinterpret_cast<const F*>(src_v)); - } - else // continue searching - { - HelperRecT<n+1,Ts...>::copy(id, src_v, dst_v); - } - } - - //! Helper function to move an instance of a type by calling the move constructor on it. - //! @param id The id if the type to search for in the template parameter list - //! @param src_v A pointer to the value of the type to copy from. - //! @param dst_v A pointer to the variable to copy to. - inline static void move(uint8_t id, void * src_v, void * dst_v) - { - if (n==id) // found it - { - new (dst_v) F(std::move(*reinterpret_cast<F*>(src_v))); - } - else // continue searching - { - HelperRecT<n+1,Ts...>::move(id, src_v, dst_v); - } - } - - //! Helper function to destroy an object of a given type by calling its destructor. - //! @param id The id if the type to search for in the template parameter list - //! @param data A pointer to the object to destroy - inline static void destroy(uint8_t id, void * data) - { - if (n==id) // found it - { - reinterpret_cast<F*>(data)->~F(); - } - else // continue searching - { - HelperRecT<n+1,Ts...>::destroy(id, data); - } - } - -}; - -//! Specialization to stop the recursion when the end of the list has reached -template<uint8_t n> -struct HelperRecT<n> -{ - inline static void copy(uint8_t id, const void * src_v, void * dst_v) { } - inline static void move(uint8_t id, void * src_v, void * dst_v) { } - inline static void destroy(uint8_t id, void * data) { } -}; - -//! Helper to kickstart the recursive search -template<typename ...Ts> -struct HelperT -{ - inline static void copy(uint8_t id, const void *src_v, void *dst_v) - { HelperRecT<0, Ts...>::copy(id, src_v, dst_v); } - inline static void move(uint8_t id, void *src_v, void *dst_v) - { HelperRecT<0, Ts...>::move(id, src_v, dst_v); } - inline static void destroy(uint8_t id,void *data) - { HelperRecT<0, Ts...>::destroy(id, data); } -}; - -//! Specialization to end the recursion -template<> -struct HelperT<> -{ - inline static void copy(uint8_t id, const void * src_v, void * dst_v) { } - inline static void move(uint8_t id, void * src_v, void * dst_v) { } - inline static void destroy(uint8_t id, void * data) { } -}; - -} // namespace details - -//! Generic declaration of a template type wrapper where VariantType<index,...>::type -//! represents the type of the variant at the given index. -//! The first type of the variant has index 0, the second has -//! index 1, etc. -template<uint8_t index, typename... Items> -struct VariantType; - -//! specialization to stop the recursion when arrived at index 0 and type F -template<typename F,typename...Ts> -struct VariantType<0, F, Ts...> -{ - using type = F; -}; - -//! recursive definition of the type wrapper -template<uint8_t index, typename F, typename... Ts> -struct VariantType<index, F, Ts...> -{ - using type = typename VariantType<index-1,Ts...>::type; -}; - -//------------------------------------------------------------------ - -//! Implementation of a variant container (similar to C++17's std::variant). -//! It can hold either no instances (e.g. initially or after calling invalidate()), -//! or hold exactly one instance of an object (after calling set()) -//! whose type is one of the variant's template parameters. -//! Each parameter has an index, the first parameter has index 0. -//! It behaves similar to a C union, in that the memory of all -//! possible object types is shared, but unlike a C union -//! it does allow C++ objects with constructors and destructors to be stored and -//! knows what type is stored. -template<typename... Ts> -struct Variant { - private: - //! constant respresenting the maximum size that can hold all types in the template list - static const size_t data_size = details::TMax<sizeof(Ts)...>::value; - //! constant respresenting the maximum alignment requirement for all types in the template list - static const size_t data_align = details::TMax<alignof(Ts)...>::value; - - //! the data type for the Variant's internal memory - using Data = typename std::aligned_storage<data_size, data_align>::type; - - //! a short hand name for the helper class - using HelperT = details::HelperT<Ts...>; - - template<uint8_t index> - using Type = typename VariantType<index,Ts...>::type; - - //! The id that represents an invalid type - static inline uint8_t invalid_id() { return 255; } - - //! the actual data - Data m_data; - //! a unique identifier for the type held by this variant - uint8_t m_id; - - public: - //! The default constructor - Variant() : m_id(invalid_id()) - { - } - - //! The copy constructor - Variant(const Variant<Ts...>& src) : m_id(src.m_id) - { - HelperT::copy(src.m_id, &src.m_data, &m_data); - } - - //! The move constructor - Variant(Variant<Ts...>&& src) : m_id(src.m_id) - { - HelperT::move(src.m_id, &src.m_data, &m_data); - } - - //! The copy assignment operator - Variant<Ts...>& operator= (const Variant<Ts...> &src) - { - if (this!=&src) // prevent self assignment - { - // destroy the old value - if (valid()) HelperT::destroy(m_id,&m_data); - // and copy over the new one - m_id = src.m_id; - HelperT::copy(src.m_id, &src.m_data, &m_data); - } - return *this; - } - - //! The move assignment operator - Variant<Ts...>& operator= (Variant<Ts...> &&src) - { - // destroy the old value - if (valid()) HelperT::destroy(m_id,&m_data); - // and move in the new one - m_id = src.m_id; - HelperT::move(src.m_id, &src.m_data, &m_data); - return *this; - } - - //! The destructor - ~Variant() - { - HelperT::destroy(m_id, &m_data); - } - - //! Returns true iff the variant container holds a specific type. - //! @tparam T the type to search for. - template<uint8_t index> - constexpr bool is() const { return m_id==index; } - - //! Returns true iff the Variant holds a valid type. - constexpr bool valid() const { return m_id!=invalid_id(); } - - //! Invalidate the variant. Will destroy any object that is held. - void invalidate() - { - HelperT::destroy(m_id,&m_data); - m_id = invalid_id(); - } - - //! Returns the index of the type held by this variant, or invalid_id() if the - //! variant does not hold any type (i.e. valid() returns false). - constexpr uint8_t index() const { return m_id; } - - //! Replaces the contents of the variant container by constructing a type T calling - //! the constructor with Args - //! @tparam index the type to make the variant hold an instance of. - //! @tparam Args The arguments types to pass to the constructor of T. - //! @param args The argument values - template<uint8_t index, typename... Args> - void set(Args&&... args) - { - HelperT::destroy(m_id, &m_data); - m_id = index; - new (&m_data) Type<index>(std::forward<Args>(args)...); - } - - //! Return a non-constant reference to the value held by the variant container. - //! @throw std::bad_cast() if called on a variant container that does not hold - //! an instance of the type of the variant at index. - template<uint8_t index> - Type<index>& get() - { - if (m_id != index) throw std::bad_cast(); - return *reinterpret_cast<Type<index>*>(&m_data); - } - - //! Returns a constant reference to the value held by the variant container. - //! @throw std::bad_cast() if called on a variant container that does not hold - //! an instance of the type of the variant at index. - template<uint8_t index> - const Type<index>& get() const - { - if (m_id != index) throw std::bad_cast(); - return *reinterpret_cast<const Type<index>*>(&m_data); - } - -}; - -#endif diff --git a/src/vhdlcode.l b/src/vhdlcode.l index 2e11f9e..f0a9883 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -1237,7 +1237,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (text.isEmpty()) return; - static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); + bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); yyextra->tooltipManager.addTooltip(ol,d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 8793e58..59a24a7 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -165,7 +165,7 @@ static void createSVG() QCString vlargs="-Tsvg \""+ov+"\" "+dir ; - if (Portable::system(Config_getString(DOT_PATH) + "dot",vlargs)!=0) + if (Portable::system(Doxygen::verifiedDotPath,vlargs)!=0) { err("could not create dot file"); } @@ -178,7 +178,7 @@ void VhdlDocGen::writeOverview() bool found=FALSE; for (const auto &cd : *Doxygen::classLinkedMap) { - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ) + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::ENTITYCLASS ) { found=TRUE; break; @@ -201,7 +201,7 @@ void VhdlDocGen::writeOverview() for (const auto &cd : *Doxygen::classLinkedMap) { - if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS ) + if (VhdlDocGen::convert(cd->protection())!=VhdlDocGen::ENTITYCLASS ) { continue; } @@ -612,8 +612,8 @@ const MemberDef* VhdlDocGen::findMember(const QCString& className, const QCStrin // nothing found so far // if we are an architecture or package body search in entity - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::ARCHITECTURECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS) { Definition *d = cd->getOuterScope(); // searching upper/lower case names @@ -642,8 +642,8 @@ const MemberDef* VhdlDocGen::findMember(const QCString& className, const QCStrin } - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS || - (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::ARCHITECTURECLASS || + VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS) { Definition *d = cd->getOuterScope(); @@ -812,7 +812,7 @@ QCString VhdlDocGen::getClassName(const ClassDef* cd) QCString temp; if (cd==0) return ""; - if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) + if (VhdlDocGen::convert(cd->protection())==VhdlDocGen::PACKBODYCLASS) { temp=cd->name(); temp.stripPrefix("_"); @@ -830,17 +830,17 @@ void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol) { std::vector<QCString> ql; QCString nn=cd->className(); - int ii=(int)cd->protection()+2; + VhdlClasses ii=convert(cd->protection()); QCString type; - if (ii==VhdlDocGen::ENTITY) - type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE); - else if (ii==VhdlDocGen::ARCHITECTURE) + if (ii==VhdlDocGen::ENTITYCLASS) type+=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE); - else if (ii==VhdlDocGen::PACKAGE_BODY) - type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE); - else if (ii==VhdlDocGen::PACKAGE) + else if (ii==VhdlDocGen::ARCHITECTURECLASS) + type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE); + else if (ii==VhdlDocGen::PACKBODYCLASS) type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE_BODY,TRUE); + else if (ii==VhdlDocGen::PACKAGECLASS) + type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE); else type+=""; @@ -849,17 +849,17 @@ void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol) ol.disable(OutputGenerator::RTF); ol.disable(OutputGenerator::Man); - if (ii==VhdlDocGen::PACKAGE_BODY) + if (ii==VhdlDocGen::PACKBODYCLASS) { nn.stripPrefix("_"); cd=getClass(nn); } - else if (ii==VhdlDocGen::PACKAGE) + else if (ii==VhdlDocGen::PACKAGECLASS) { nn.prepend("_"); cd=getClass(nn); } - else if (ii==VhdlDocGen::ARCHITECTURE) + else if (ii==VhdlDocGen::ARCHITECTURECLASS) { StringVector qlist=split(nn.str(),"-"); if (qlist.size()>1) @@ -870,7 +870,7 @@ void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol) } QCString opp; - if (ii==VhdlDocGen::ENTITY) + if (ii==VhdlDocGen::ENTITYCLASS) { VhdlDocGen::findAllArchitectures(ql,cd); for (const auto &s : ql) @@ -1040,10 +1040,10 @@ void VhdlDocGen::parseFuncProto(const QCString &text,QCString& name,QCString& re QCString VhdlDocGen::getIndexWord(const QCString &c,int index) { - static const reg::Ex reg(R"([\s|])"); + static const reg::Ex reg(R"([\s:|])"); auto ql=split(c.str(),reg); - if ((size_t)index < ql.size()) + if (index < static_cast<int>(ql.size())) { return QCString(ql[index]); } @@ -1757,7 +1757,7 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDefMutable* mdef,OutputList &o else if (nd) d=nd; else if (fd) d=fd; else if (gd) d=gd; - else d=(Definition*)mdef; + else d=mdef; // write search index info if (Doxygen::searchIndex) @@ -1778,7 +1778,7 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDefMutable* mdef,OutputList &o ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType(); // start a new member declaration - uint isAnonymous = (bool)(annoClassDef); // || m_impl->annMemb || m_impl->annEnumType; + uint isAnonymous = annoClassDef!=0; // || m_impl->annMemb || m_impl->annEnumType; ///printf("startMemberItem for %s\n",qPrint(name())); uint64_t mm=mdef->getMemberSpecifiers(); if (mm==VhdlDocGen::MISCELLANEOUS) @@ -1836,7 +1836,7 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDefMutable* mdef,OutputList &o break; case VhdlDocGen::USE: kl=VhdlDocGen::getClass(mdef->name()); - if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break; + if (kl && (VhdlDocGen::convert(kl->protection())==VhdlDocGen::ENTITYCLASS)) break; writeLink(mdef,ol); ol.insertMemberAlign(); ol.docify(" "); @@ -2123,7 +2123,7 @@ void VhdlDocGen::writeVHDLDeclarations(const MemberList* ml,OutputList &ol, if (membersHaveSpecificType(&mg->members(),type)) { //printf("mg->header=%s\n",qPrint(mg->header())); - bool hasHeader=mg->header()!="[NOHEADER]"; + bool hasHeader=!mg->header().isEmpty(); ol.startMemberGroupHeader(hasHeader); if (hasHeader) { @@ -3398,7 +3398,7 @@ void FlowChart::createSVG() QCString vlargs="-Tsvg \""+ov+"\" "+dir ; - if (Portable::system(Config_getString(DOT_PATH) + "dot",vlargs)!=0) + if (Portable::system(Doxygen::verifiedDotPath,vlargs)!=0) { err("could not create dot file"); } @@ -3544,7 +3544,7 @@ void FlowChart::writeShape(TextStream &t,const FlowChart &fl) int z=q.findRev("\n"); - if (z==(int)q.length()-1) + if (z==static_cast<int>(q.length())-1) { q=q.remove(z,2); } diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index 207e449..abc47f1 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -76,6 +76,17 @@ class VhdlDocGen ARCHITECTURECLASS, // Overlays: Private PACKAGECLASS // Overlays: Package }; + static VhdlClasses convert(Protection prot) + { + switch (prot) + { + case Public: return ENTITYCLASS; + case Protected: return PACKBODYCLASS; + case Private: return ARCHITECTURECLASS; + case Package: return PACKAGECLASS; + } + return ENTITYCLASS; + } enum VhdlKeyWords { diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index 963f3ec..bea252f 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -707,7 +707,7 @@ void VHDLOutlineParser::mapLibPackage( Entry* root) bool VHDLOutlineParser::addLibUseClause(const QCString &type) { - static bool showIEEESTD=Config_getBool(FORCE_LOCAL_INCLUDES); + bool showIEEESTD=Config_getBool(FORCE_LOCAL_INCLUDES); if (showIEEESTD) // all standard packages and libraries will not be shown { @@ -878,7 +878,7 @@ QCString filter2008VhdlComment(const char *s) } } // special attention in case */ at end of last line - int len = growBuf.getPos(); + size_t len = growBuf.getPos(); if (growBuf.at(len-1) == '/' && growBuf.at(len-2) == '*') { len -= 2; diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index c0e0271..d3395db 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -30,13 +30,65 @@ #include "filedef.h" #include "fileinfo.h" -static void visitCaption(XmlDocVisitor *parent, const DocNodeList &children) +static void startSimpleSect(TextStream &t,const DocSimpleSect &s) { - for (const auto &n : children) n->accept(parent); + t << "<simplesect kind=\""; + switch(s.type()) + { + case DocSimpleSect::See: + t << "see"; break; + case DocSimpleSect::Return: + t << "return"; break; + case DocSimpleSect::Author: + t << "author"; break; + case DocSimpleSect::Authors: + t << "authors"; break; + case DocSimpleSect::Version: + t << "version"; break; + case DocSimpleSect::Since: + t << "since"; break; + case DocSimpleSect::Date: + t << "date"; break; + case DocSimpleSect::Note: + t << "note"; break; + case DocSimpleSect::Warning: + t << "warning"; break; + case DocSimpleSect::Pre: + t << "pre"; break; + case DocSimpleSect::Post: + t << "post"; break; + case DocSimpleSect::Copyright: + t << "copyright"; break; + case DocSimpleSect::Invar: + t << "invariant"; break; + case DocSimpleSect::Remark: + t << "remark"; break; + case DocSimpleSect::Attention: + t << "attention"; break; + case DocSimpleSect::User: + t << "par"; break; + case DocSimpleSect::Rcs: + t << "rcs"; break; + case DocSimpleSect::Unknown: break; + } + t << "\">"; +} + +static void endSimpleSect(TextStream &t,const DocSimpleSect &) +{ + t << "</simplesect>\n"; +} + +static void visitCaption(XmlDocVisitor &visitor, const DocNodeList &children) +{ + for (const auto &n : children) + { + std::visit(visitor,n); + } } static void visitPreStart(TextStream &t, const char *cmd, bool doCaption, - XmlDocVisitor *parent, const DocNodeList &children, + XmlDocVisitor &visitor, const DocNodeList &children, const QCString &name, bool writeType, DocImage::Type type, const QCString &width, const QCString &height, const QCString engine = QCString(), const QCString &alt = QCString(), bool inlineImage = FALSE) { @@ -81,7 +133,7 @@ static void visitPreStart(TextStream &t, const char *cmd, bool doCaption, if (doCaption) { t << " caption=\""; - visitCaption(parent, children); + visitCaption(visitor, children); t << "\""; } t << ">"; @@ -93,7 +145,7 @@ static void visitPostEnd(TextStream &t, const char *cmd) } XmlDocVisitor::XmlDocVisitor(TextStream &t,CodeOutputInterface &ci,const QCString &langExt) - : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), + : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_langExt(langExt) { } @@ -102,26 +154,26 @@ XmlDocVisitor::XmlDocVisitor(TextStream &t,CodeOutputInterface &ci,const QCStrin // visitor functions for leaf nodes //-------------------------------------- -void XmlDocVisitor::visit(DocWord *w) +void XmlDocVisitor::operator()(const DocWord &w) { if (m_hide) return; - filter(w->word()); + filter(w.word()); } -void XmlDocVisitor::visit(DocLinkedWord *w) +void XmlDocVisitor::operator()(const DocLinkedWord &w) { if (m_hide) return; - startLink(w->ref(),w->file(),w->anchor()); - filter(w->word()); + startLink(w.ref(),w.file(),w.anchor()); + filter(w.word()); endLink(); } -void XmlDocVisitor::visit(DocWhiteSpace *w) +void XmlDocVisitor::operator()(const DocWhiteSpace &w) { if (m_hide) return; if (m_insidePre) { - m_t << w->chars(); + m_t << w.chars(); } else { @@ -129,107 +181,107 @@ void XmlDocVisitor::visit(DocWhiteSpace *w) } } -void XmlDocVisitor::visit(DocSymbol *s) +void XmlDocVisitor::operator()(const DocSymbol &s) { if (m_hide) return; - const char *res = HtmlEntityMapper::instance()->xml(s->symbol()); + const char *res = HtmlEntityMapper::instance()->xml(s.symbol()); if (res) { m_t << res; } else { - err("XML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); + err("XML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s.symbol(),TRUE)); } } -void XmlDocVisitor::visit(DocEmoji *s) +void XmlDocVisitor::operator()(const DocEmoji &s) { if (m_hide) return; - const char *res = EmojiEntityMapper::instance()->name(s->index()); + const char *res = EmojiEntityMapper::instance()->name(s.index()); if (res) { QCString name=res; name = name.mid(1,name.length()-2); m_t << "<emoji name=\"" << name << "\" unicode=\""; - filter(EmojiEntityMapper::instance()->unicode(s->index())); + filter(EmojiEntityMapper::instance()->unicode(s.index())); m_t << "\"/>"; } else { - m_t << s->name(); + m_t << s.name(); } } -void XmlDocVisitor::visit(DocURL *u) +void XmlDocVisitor::operator()(const DocURL &u) { if (m_hide) return; m_t << "<ulink url=\""; - if (u->isEmail()) m_t << "mailto:"; - filter(u->url()); + if (u.isEmail()) m_t << "mailto:"; + filter(u.url()); m_t << "\">"; - filter(u->url()); + filter(u.url()); m_t << "</ulink>"; } -void XmlDocVisitor::visit(DocLineBreak *) +void XmlDocVisitor::operator()(const DocLineBreak &) { if (m_hide) return; m_t << "<linebreak/>\n"; } -void XmlDocVisitor::visit(DocHorRuler *) +void XmlDocVisitor::operator()(const DocHorRuler &) { if (m_hide) return; m_t << "<hruler/>\n"; } -void XmlDocVisitor::visit(DocStyleChange *s) +void XmlDocVisitor::operator()(const DocStyleChange &s) { if (m_hide) return; - switch (s->style()) + switch (s.style()) { case DocStyleChange::Bold: - if (s->enable()) m_t << "<bold>"; else m_t << "</bold>"; + if (s.enable()) m_t << "<bold>"; else m_t << "</bold>"; break; case DocStyleChange::S: - if (s->enable()) m_t << "<s>"; else m_t << "</s>"; + if (s.enable()) m_t << "<s>"; else m_t << "</s>"; break; case DocStyleChange::Strike: - if (s->enable()) m_t << "<strike>"; else m_t << "</strike>"; + if (s.enable()) m_t << "<strike>"; else m_t << "</strike>"; break; case DocStyleChange::Del: - if (s->enable()) m_t << "<del>"; else m_t << "</del>"; + if (s.enable()) m_t << "<del>"; else m_t << "</del>"; break; case DocStyleChange::Underline: - if (s->enable()) m_t << "<underline>"; else m_t << "</underline>"; + if (s.enable()) m_t << "<underline>"; else m_t << "</underline>"; break; case DocStyleChange::Ins: - if (s->enable()) m_t << "<ins>"; else m_t << "</ins>"; + if (s.enable()) m_t << "<ins>"; else m_t << "</ins>"; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>"; + if (s.enable()) m_t << "<emphasis>"; else m_t << "</emphasis>"; break; case DocStyleChange::Code: - if (s->enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>"; + if (s.enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>"; break; case DocStyleChange::Subscript: - if (s->enable()) m_t << "<subscript>"; else m_t << "</subscript>"; + if (s.enable()) m_t << "<subscript>"; else m_t << "</subscript>"; break; case DocStyleChange::Superscript: - if (s->enable()) m_t << "<superscript>"; else m_t << "</superscript>"; + if (s.enable()) m_t << "<superscript>"; else m_t << "</superscript>"; break; case DocStyleChange::Center: - if (s->enable()) m_t << "<center>"; else m_t << "</center>"; + if (s.enable()) m_t << "<center>"; else m_t << "</center>"; break; case DocStyleChange::Small: - if (s->enable()) m_t << "<small>"; else m_t << "</small>"; + if (s.enable()) m_t << "<small>"; else m_t << "</small>"; break; case DocStyleChange::Cite: - if (s->enable()) m_t << "<cite>"; else m_t << "</cite>"; + if (s.enable()) m_t << "<cite>"; else m_t << "</cite>"; break; case DocStyleChange::Preformatted: - if (s->enable()) + if (s.enable()) { m_t << "<preformatted>"; m_insidePre=TRUE; @@ -243,52 +295,52 @@ void XmlDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; case DocStyleChange::Details: - if (s->enable()) m_t << "<details>"; else m_t << "</details>"; + if (s.enable()) m_t << "<details>"; else m_t << "</details>"; break; case DocStyleChange::Summary: - if (s->enable()) m_t << "<summary>"; else m_t << "</summary>"; + if (s.enable()) m_t << "<summary>"; else m_t << "</summary>"; break; } } -void XmlDocVisitor::visit(DocVerbatim *s) +void XmlDocVisitor::operator()(const DocVerbatim &s) { if (m_hide) return; QCString lang = m_langExt; - if (!s->language().isEmpty()) // explicit language setting + if (!s.language().isEmpty()) // explicit language setting { - lang = s->language(); + lang = s.language(); } SrcLangExt langExt = getLanguageFromCodeLang(lang); - switch(s->type()) + switch(s.type()) { case DocVerbatim::Code: m_t << "<programlisting"; - if (!s->language().isEmpty()) + if (!s.language().isEmpty()) m_t << " filename=\"" << lang << "\">"; else m_t << ">"; - 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::JavaDocLiteral: m_t << "<javadocliteral>"; - filter(s->text()); + filter(s.text()); m_t << "</javadocliteral>"; break; case DocVerbatim::JavaDocCode: m_t << "<javadoccode>"; - filter(s->text()); + filter(s.text()); m_t << "</javadoccode>"; break; case DocVerbatim::Verbatim: m_t << "<verbatim>"; - filter(s->text()); + filter(s.text()); m_t << "</verbatim>"; break; case DocVerbatim::HtmlOnly: - if (s->isBlock()) + if (s.isBlock()) { m_t << "<htmlonly block=\"yes\">"; } @@ -296,90 +348,89 @@ void XmlDocVisitor::visit(DocVerbatim *s) { m_t << "<htmlonly>"; } - filter(s->text()); + filter(s.text()); m_t << "</htmlonly>"; break; case DocVerbatim::RtfOnly: m_t << "<rtfonly>"; - filter(s->text()); + filter(s.text()); m_t << "</rtfonly>"; break; case DocVerbatim::ManOnly: m_t << "<manonly>"; - filter(s->text()); + filter(s.text()); m_t << "</manonly>"; break; case DocVerbatim::LatexOnly: m_t << "<latexonly>"; - filter(s->text()); + filter(s.text()); m_t << "</latexonly>"; break; case DocVerbatim::DocbookOnly: m_t << "<docbookonly>"; - filter(s->text()); + filter(s.text()); m_t << "</docbookonly>"; break; case DocVerbatim::XmlOnly: - m_t << s->text(); + m_t << s.text(); break; case DocVerbatim::Dot: - visitPreStart(m_t, "dot", s->hasCaption(), this, s->children(), QCString(""), FALSE, DocImage::Html, s->width(), s->height()); - filter(s->text()); + visitPreStart(m_t, "dot", s.hasCaption(), *this, s.children(), QCString(""), FALSE, DocImage::Html, s.width(), s.height()); + filter(s.text()); visitPostEnd(m_t, "dot"); break; case DocVerbatim::Msc: - visitPreStart(m_t, "msc", s->hasCaption(), this, s->children(), QCString(""), FALSE, DocImage::Html, s->width(), s->height()); - filter(s->text()); + visitPreStart(m_t, "msc", s.hasCaption(), *this, s.children(), QCString(""), FALSE, DocImage::Html, s.width(), s.height()); + filter(s.text()); visitPostEnd(m_t, "msc"); break; case DocVerbatim::PlantUML: - visitPreStart(m_t, "plantuml", s->hasCaption(), this, s->children(), QCString(""), FALSE, DocImage::Html, s->width(), s->height(), s->engine()); - filter(s->text()); + visitPreStart(m_t, "plantuml", s.hasCaption(), *this, s.children(), QCString(""), FALSE, DocImage::Html, s.width(), s.height(), s.engine()); + filter(s.text()); visitPostEnd(m_t, "plantuml"); break; } } -void XmlDocVisitor::visit(DocAnchor *anc) +void XmlDocVisitor::operator()(const DocAnchor &anc) { if (m_hide) return; - m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>"; + m_t << "<anchor id=\"" << anc.file() << "_1" << anc.anchor() << "\"/>"; } -void XmlDocVisitor::visit(DocInclude *inc) +void XmlDocVisitor::operator()(const DocInclude &inc) { if (m_hide) return; - SrcLangExt langExt = getLanguageFromFileName(inc->extension()); - switch(inc->type()) + SrcLangExt langExt = getLanguageFromFileName(inc.extension()); + switch(inc.type()) { case DocInclude::IncWithLines: { - m_t << "<programlisting filename=\"" << inc->file() << "\">"; - FileInfo cfi( inc->file().str() ); - FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + m_t << "<programlisting filename=\"" << inc.file() << "\">"; + FileInfo cfi( inc.file().str() ); + std::unique_ptr<FileDef> fd { createFileDef( cfi.dirPath(), cfi.fileName() ) }; + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), - fd, // fileDef, + inc.isExample(), + inc.exampleFile(), + fd.get(), // fileDef, -1, // start line -1, // end line FALSE, // inline fragment 0, // memberDef TRUE // show line numbers ); - delete fd; m_t << "</programlisting>"; } break; case DocInclude::Include: - m_t << "<programlisting filename=\"" << inc->file() << "\">"; - getCodeParser(inc->extension()).parseCode(m_ci,inc->context(), - inc->text(), + m_t << "<programlisting filename=\"" << inc.file() << "\">"; + getCodeParser(inc.extension()).parseCode(m_ci,inc.context(), + inc.text(), langExt, - inc->isExample(), - inc->exampleFile(), + inc.isExample(), + inc.exampleFile(), 0, // fileDef -1, // startLine -1, // endLine @@ -393,7 +444,7 @@ void XmlDocVisitor::visit(DocInclude *inc) case DocInclude::DontIncWithLines: break; case DocInclude::HtmlInclude: - if (inc->isBlock()) + if (inc.isBlock()) { m_t << "<htmlonly block=\"yes\">"; } @@ -401,67 +452,66 @@ void XmlDocVisitor::visit(DocInclude *inc) { m_t << "<htmlonly>"; } - filter(inc->text()); + filter(inc.text()); m_t << "</htmlonly>"; break; case DocInclude::LatexInclude: m_t << "<latexonly>"; - filter(inc->text()); + filter(inc.text()); m_t << "</latexonly>"; break; case DocInclude::RtfInclude: m_t << "<rtfonly>"; - filter(inc->text()); + filter(inc.text()); m_t << "</rtfonly>"; break; case DocInclude::ManInclude: m_t << "<manonly>"; - filter(inc->text()); + filter(inc.text()); m_t << "</manonly>"; break; case DocInclude::XmlInclude: - filter(inc->text()); + filter(inc.text()); break; case DocInclude::DocbookInclude: m_t << "<docbookonly>"; - filter(inc->text()); + filter(inc.text()); m_t << "</docbookonly>"; break; case DocInclude::VerbInclude: m_t << "<verbatim>"; - filter(inc->text()); + filter(inc.text()); m_t << "</verbatim>"; break; case DocInclude::Snippet: - m_t << "<programlisting filename=\"" << inc->file() << "\">"; - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + m_t << "<programlisting filename=\"" << inc.file() << "\">"; + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile() + inc.isExample(), + inc.exampleFile() ); m_t << "</programlisting>"; break; case DocInclude::SnipWithLines: { - m_t << "<programlisting filename=\"" << inc->file() << "\">"; - FileInfo cfi( inc->file().str() ); - FileDef *fd = createFileDef( cfi.dirPath(), cfi.fileName() ); - getCodeParser(inc->extension()).parseCode(m_ci, - inc->context(), - extractBlock(inc->text(),inc->blockId()), + m_t << "<programlisting filename=\"" << inc.file() << "\">"; + FileInfo cfi( inc.file().str() ); + std::unique_ptr<FileDef> fd { createFileDef( cfi.dirPath(), cfi.fileName() ) }; + getCodeParser(inc.extension()).parseCode(m_ci, + inc.context(), + extractBlock(inc.text(),inc.blockId()), langExt, - inc->isExample(), - inc->exampleFile(), - fd, - lineBlock(inc->text(),inc->blockId()), + inc.isExample(), + inc.exampleFile(), + fd.get(), + lineBlock(inc.text(),inc.blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE // show line number ); - delete fd; m_t << "</programlisting>"; } break; @@ -473,50 +523,49 @@ void XmlDocVisitor::visit(DocInclude *inc) } } -void XmlDocVisitor::visit(DocIncOperator *op) +void XmlDocVisitor::operator()(const DocIncOperator &op) { //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", - // op->type(),op->isFirst(),op->isLast(),qPrint(op->text())); - if (op->isFirst()) + // op.type(),op.isFirst(),op.isLast(),qPrint(op.text())); + if (op.isFirst()) { if (!m_hide) { - m_t << "<programlisting filename=\"" << op->includeFileName() << "\">"; + m_t << "<programlisting filename=\"" << op.includeFileName() << "\">"; } pushHidden(m_hide); m_hide = TRUE; } - QCString locLangExt = getFileNameExtension(op->includeFileName()); + 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) { m_hide = popHidden(); if (!m_hide) { - FileDef *fd = 0; - if (!op->includeFileName().isEmpty()) + std::unique_ptr<FileDef> fd; + if (!op.includeFileName().isEmpty()) { - FileInfo cfi( op->includeFileName().str() ); - fd = createFileDef( cfi.dirPath(), cfi.fileName() ); + FileInfo cfi( op.includeFileName().str() ); + fd.reset(createFileDef( cfi.dirPath(), cfi.fileName() )); } - getCodeParser(locLangExt).parseCode(m_ci,op->context(), - op->text(),langExt,op->isExample(), - op->exampleFile(), - fd, // fileDef - op->line(), // startLine + getCodeParser(locLangExt).parseCode(m_ci,op.context(), + op.text(),langExt,op.isExample(), + op.exampleFile(), + fd.get(), // fileDef + op.line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - op->showLineNo() // show line numbers + op.showLineNo() // show line numbers ); - if (fd) delete fd; } pushHidden(m_hide); m_hide=TRUE; } - if (op->isLast()) + if (op.isLast()) { m_hide = popHidden(); if (!m_hide) m_t << "</programlisting>"; @@ -527,50 +576,51 @@ void XmlDocVisitor::visit(DocIncOperator *op) } } -void XmlDocVisitor::visit(DocFormula *f) +void XmlDocVisitor::operator()(const DocFormula &f) { if (m_hide) return; - m_t << "<formula id=\"" << f->id() << "\">"; - filter(f->text()); + m_t << "<formula id=\"" << f.id() << "\">"; + filter(f.text()); m_t << "</formula>"; } -void XmlDocVisitor::visit(DocIndexEntry *ie) +void XmlDocVisitor::operator()(const DocIndexEntry &ie) { if (m_hide) return; m_t << "<indexentry>" "<primaryie>"; - filter(ie->entry()); + filter(ie.entry()); m_t << "</primaryie>" "<secondaryie></secondaryie>" "</indexentry>"; } -void XmlDocVisitor::visit(DocSimpleSectSep *sep) +void XmlDocVisitor::operator()(const DocSimpleSectSep &sep) { - if (sep->parent() && sep->parent()->kind()==DocNode::Kind_SimpleSect) + const DocSimpleSect *sect = std::get_if<DocSimpleSect>(sep.parent()); + if (sect) { - visitPost((DocSimpleSect*)sep->parent()); // end current section - visitPre((DocSimpleSect*)sep->parent()); // start new section + endSimpleSect(m_t,*sect); + startSimpleSect(m_t,*sect); } } -void XmlDocVisitor::visit(DocCite *cite) +void XmlDocVisitor::operator()(const DocCite &cite) { if (m_hide) return; - if (!cite->file().isEmpty()) startLink(cite->ref(),cite->file(),cite->anchor()); - filter(cite->text()); - if (!cite->file().isEmpty()) endLink(); + if (!cite.file().isEmpty()) startLink(cite.ref(),cite.file(),cite.anchor()); + filter(cite.text()); + if (!cite.file().isEmpty()) endLink(); } //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- -void XmlDocVisitor::visitPre(DocAutoList *l) +void XmlDocVisitor::operator()(const DocAutoList &l) { if (m_hide) return; - if (l->isEnumList()) + if (l.isEnumList()) { m_t << "<orderedlist>\n"; } @@ -578,12 +628,8 @@ void XmlDocVisitor::visitPre(DocAutoList *l) { m_t << "<itemizedlist>\n"; } -} - -void XmlDocVisitor::visitPost(DocAutoList *l) -{ - if (m_hide) return; - if (l->isEnumList()) + visitChildren(l); + if (l.isEnumList()) { m_t << "</orderedlist>\n"; } @@ -593,173 +639,111 @@ void XmlDocVisitor::visitPost(DocAutoList *l) } } -void XmlDocVisitor::visitPre(DocAutoListItem *) +void XmlDocVisitor::operator()(const DocAutoListItem &li) { if (m_hide) return; m_t << "<listitem>"; -} - -void XmlDocVisitor::visitPost(DocAutoListItem *) -{ - if (m_hide) return; + visitChildren(li); m_t << "</listitem>"; } -void XmlDocVisitor::visitPre(DocPara *) +void XmlDocVisitor::operator()(const DocPara &p) { if (m_hide) return; m_t << "<para>"; -} - -void XmlDocVisitor::visitPost(DocPara *) -{ - if (m_hide) return; + visitChildren(p); m_t << "</para>\n"; } -void XmlDocVisitor::visitPre(DocRoot *) +void XmlDocVisitor::operator()(const DocRoot &r) { - //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n"; + visitChildren(r); } -void XmlDocVisitor::visitPost(DocRoot *) -{ - //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n"; -} - -void XmlDocVisitor::visitPre(DocSimpleSect *s) +void XmlDocVisitor::operator()(const DocSimpleSect &s) { if (m_hide) return; - m_t << "<simplesect kind=\""; - switch(s->type()) + startSimpleSect(m_t,s); + if (s.title()) { - case DocSimpleSect::See: - m_t << "see"; break; - case DocSimpleSect::Return: - m_t << "return"; break; - case DocSimpleSect::Author: - m_t << "author"; break; - case DocSimpleSect::Authors: - m_t << "authors"; break; - case DocSimpleSect::Version: - m_t << "version"; break; - case DocSimpleSect::Since: - m_t << "since"; break; - case DocSimpleSect::Date: - m_t << "date"; break; - case DocSimpleSect::Note: - m_t << "note"; break; - case DocSimpleSect::Warning: - m_t << "warning"; break; - case DocSimpleSect::Pre: - m_t << "pre"; break; - case DocSimpleSect::Post: - m_t << "post"; break; - case DocSimpleSect::Copyright: - m_t << "copyright"; break; - case DocSimpleSect::Invar: - m_t << "invariant"; break; - case DocSimpleSect::Remark: - m_t << "remark"; break; - case DocSimpleSect::Attention: - m_t << "attention"; break; - case DocSimpleSect::User: - m_t << "par"; break; - case DocSimpleSect::Rcs: - m_t << "rcs"; break; - case DocSimpleSect::Unknown: break; + std::visit(*this,*s.title()); } - m_t << "\">"; + visitChildren(s); + endSimpleSect(m_t,s); } -void XmlDocVisitor::visitPost(DocSimpleSect *) -{ - if (m_hide) return; - m_t << "</simplesect>\n"; -} - -void XmlDocVisitor::visitPre(DocTitle *) +void XmlDocVisitor::operator()(const DocTitle &t) { if (m_hide) return; m_t << "<title>"; -} - -void XmlDocVisitor::visitPost(DocTitle *) -{ - if (m_hide) return; + visitChildren(t); m_t << "</title>"; } -void XmlDocVisitor::visitPre(DocSimpleList *) +void XmlDocVisitor::operator()(const DocSimpleList &l) { if (m_hide) return; m_t << "<itemizedlist>\n"; -} - -void XmlDocVisitor::visitPost(DocSimpleList *) -{ - if (m_hide) return; + visitChildren(l); m_t << "</itemizedlist>\n"; } -void XmlDocVisitor::visitPre(DocSimpleListItem *) +void XmlDocVisitor::operator()(const DocSimpleListItem &li) { if (m_hide) return; m_t << "<listitem>"; -} - -void XmlDocVisitor::visitPost(DocSimpleListItem *) -{ - if (m_hide) return; + if (li.paragraph()) + { + std::visit(*this,*li.paragraph()); + } m_t << "</listitem>\n"; } -void XmlDocVisitor::visitPre(DocSection *s) +void XmlDocVisitor::operator()(const DocSection &s) { if (m_hide) return; - m_t << "<sect" << s->level() << " id=\"" << s->file(); - if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor(); + m_t << "<sect" << s.level() << " id=\"" << s.file(); + if (!s.anchor().isEmpty()) m_t << "_1" << s.anchor(); m_t << "\">\n"; m_t << "<title>"; - filter(convertCharEntitiesToUTF8(s->title())); + filter(convertCharEntitiesToUTF8(s.title())); m_t << "</title>\n"; + visitChildren(s); + m_t << "</sect" << s.level() << ">\n"; } -void XmlDocVisitor::visitPost(DocSection *s) -{ - m_t << "</sect" << s->level() << ">\n"; -} - -void XmlDocVisitor::visitPre(DocHtmlList *s) +void XmlDocVisitor::operator()(const DocHtmlList &s) { if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) + if (s.type()==DocHtmlList::Ordered) { m_t << "<orderedlist"; - for (const auto &opt : s->attribs()) + for (const auto &opt : s.attribs()) { m_t << " " << opt.name << "=\"" << opt.value << "\""; } m_t << ">\n"; } else + { m_t << "<itemizedlist>\n"; -} - -void XmlDocVisitor::visitPost(DocHtmlList *s) -{ - if (m_hide) return; - if (s->type()==DocHtmlList::Ordered) + } + visitChildren(s); + if (s.type()==DocHtmlList::Ordered) + { m_t << "</orderedlist>\n"; + } else + { m_t << "</itemizedlist>\n"; + } } -void XmlDocVisitor::visitPre(DocHtmlListItem *l) +void XmlDocVisitor::operator()(const DocHtmlListItem &l) { if (m_hide) return; m_t << "<listitem"; - for (const auto &opt : l->attribs()) + for (const auto &opt : l.attribs()) { if (opt.name=="value") { @@ -767,56 +751,40 @@ void XmlDocVisitor::visitPre(DocHtmlListItem *l) } } m_t << ">\n"; -} - -void XmlDocVisitor::visitPost(DocHtmlListItem *) -{ - if (m_hide) return; + visitChildren(l); m_t << "</listitem>\n"; } -void XmlDocVisitor::visitPre(DocHtmlDescList *) +void XmlDocVisitor::operator()(const DocHtmlDescList &dl) { if (m_hide) return; m_t << "<variablelist>\n"; -} - -void XmlDocVisitor::visitPost(DocHtmlDescList *) -{ - if (m_hide) return; + visitChildren(dl); m_t << "</variablelist>\n"; } -void XmlDocVisitor::visitPre(DocHtmlDescTitle *) +void XmlDocVisitor::operator()(const DocHtmlDescTitle &dt) { if (m_hide) return; m_t << "<varlistentry><term>"; -} - -void XmlDocVisitor::visitPost(DocHtmlDescTitle *) -{ - if (m_hide) return; + visitChildren(dt); m_t << "</term></varlistentry>\n"; } -void XmlDocVisitor::visitPre(DocHtmlDescData *) +void XmlDocVisitor::operator()(const DocHtmlDescData &dd) { if (m_hide) return; m_t << "<listitem>"; -} - -void XmlDocVisitor::visitPost(DocHtmlDescData *) -{ - if (m_hide) return; + visitChildren(dd); m_t << "</listitem>\n"; } -void XmlDocVisitor::visitPre(DocHtmlTable *t) +void XmlDocVisitor::operator()(const DocHtmlTable &t) { if (m_hide) return; - m_t << "<table rows=\"" << (uint)t->numRows() - << "\" cols=\"" << (uint)t->numColumns() << "\"" ; - for (const auto &opt : t->attribs()) + m_t << "<table rows=\"" << t.numRows() + << "\" cols=\"" << t.numColumns() << "\"" ; + for (const auto &opt : t.attribs()) { if (opt.name=="width") { @@ -824,41 +792,27 @@ void XmlDocVisitor::visitPre(DocHtmlTable *t) } } m_t << ">"; - if (t->hasCaption()) + if (t.caption()) { - DocHtmlCaption *c = t->caption(); - m_t << "<caption"; - if (!c->file().isEmpty()) - { - m_t << " id=\"" << stripPath(c->file()) << "_1" << c->anchor() << "\""; - } - m_t << ">"; + std::visit(*this,*t.caption()); } -} - -void XmlDocVisitor::visitPost(DocHtmlTable *) -{ - if (m_hide) return; + visitChildren(t); m_t << "</table>\n"; } -void XmlDocVisitor::visitPre(DocHtmlRow *) +void XmlDocVisitor::operator()(const DocHtmlRow &r) { if (m_hide) return; m_t << "<row>\n"; -} - -void XmlDocVisitor::visitPost(DocHtmlRow *) -{ - if (m_hide) return; + visitChildren(r); m_t << "</row>\n"; } -void XmlDocVisitor::visitPre(DocHtmlCell *c) +void XmlDocVisitor::operator()(const DocHtmlCell &c) { if (m_hide) return; - if (c->isHeading()) m_t << "<entry thead=\"yes\""; else m_t << "<entry thead=\"no\""; - for (const auto &opt : c->attribs()) + if (c.isHeading()) m_t << "<entry thead=\"yes\""; else m_t << "<entry thead=\"no\""; + for (const auto &opt : c.attribs()) { if (opt.name=="colspan" || opt.name=="rowspan") { @@ -903,211 +857,151 @@ void XmlDocVisitor::visitPre(DocHtmlCell *c) } } m_t << ">"; -} - -void XmlDocVisitor::visitPost(DocHtmlCell *) -{ - if (m_hide) return; + visitChildren(c); m_t << "</entry>"; } -void XmlDocVisitor::visitPre(DocHtmlCaption *) -{ - if (m_hide) return; - // start of caption is handled in the XmlDocVisitor::visitPre(DocHtmlTable *t) -} - -void XmlDocVisitor::visitPost(DocHtmlCaption *) +void XmlDocVisitor::operator()(const DocHtmlCaption &c) { if (m_hide) return; + m_t << "<caption"; + if (!c.file().isEmpty()) + { + m_t << " id=\"" << stripPath(c.file()) << "_1" << c.anchor() << "\""; + } + m_t << ">"; + visitChildren(c); m_t << "</caption>\n"; } -void XmlDocVisitor::visitPre(DocInternal *) +void XmlDocVisitor::operator()(const DocInternal &i) { if (m_hide) return; m_t << "<internal>"; -} - -void XmlDocVisitor::visitPost(DocInternal *) -{ - if (m_hide) return; + visitChildren(i); m_t << "</internal>\n"; } -void XmlDocVisitor::visitPre(DocHRef *href) -{ - if (m_hide) return; - m_t << "<ulink url=\"" << convertToXML(href->url(), TRUE) << "\">"; -} - -void XmlDocVisitor::visitPost(DocHRef *) +void XmlDocVisitor::operator()(const DocHRef &href) { if (m_hide) return; + m_t << "<ulink url=\"" << convertToXML(href.url(), TRUE) << "\">"; + visitChildren(href); m_t << "</ulink>"; } -void XmlDocVisitor::visitPre(DocHtmlHeader *header) -{ - if (m_hide) return; - m_t << "<heading level=\"" << header->level() << "\">"; -} - -void XmlDocVisitor::visitPost(DocHtmlHeader *) +void XmlDocVisitor::operator()(const DocHtmlHeader &header) { if (m_hide) return; + m_t << "<heading level=\"" << header.level() << "\">"; + visitChildren(header); m_t << "</heading>\n"; } -void XmlDocVisitor::visitPre(DocImage *img) +void XmlDocVisitor::operator()(const DocImage &img) { if (m_hide) return; - QCString url = img->url(); + QCString url = img.url(); QCString baseName; if (url.isEmpty()) { - baseName = img->relPath()+img->name(); + baseName = img.relPath()+img.name(); } else { - baseName = correctURL(url,img->relPath()); + baseName = correctURL(url,img.relPath()); } - HtmlAttribList attribs = img->attribs(); + HtmlAttribList attribs = img.attribs(); auto it = std::find_if(attribs.begin(),attribs.end(), [](const auto &att) { return att.name=="alt"; }); QCString altValue = it!=attribs.end() ? it->value : ""; - visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, - img->type(), img->width(), img->height(), QCString(), - altValue, img->isInlineImage()); + visitPreStart(m_t, "image", FALSE, *this, img.children(), baseName, TRUE, + img.type(), img.width(), img.height(), QCString(), + altValue, img.isInlineImage()); // copy the image to the output dir FileDef *fd; bool ambig; - if (url.isEmpty() && (fd=findFileDef(Doxygen::imageNameLinkedMap,img->name(),ambig))) + if (url.isEmpty() && (fd=findFileDef(Doxygen::imageNameLinkedMap,img.name(),ambig))) { copyFile(fd->absFilePath(),Config_getString(XML_OUTPUT)+"/"+baseName); } -} - -void XmlDocVisitor::visitPost(DocImage *) -{ - if (m_hide) return; + visitChildren(img); visitPostEnd(m_t, "image"); } -void XmlDocVisitor::visitPre(DocDotFile *df) -{ - if (m_hide) return; - copyFile(df->file(),Config_getString(XML_OUTPUT)+"/"+stripPath(df->file())); - visitPreStart(m_t, "dotfile", FALSE, this, df->children(), stripPath(df->file()), FALSE, DocImage::Html, df->width(), df->height()); -} - -void XmlDocVisitor::visitPost(DocDotFile *) +void XmlDocVisitor::operator()(const DocDotFile &df) { if (m_hide) return; + copyFile(df.file(),Config_getString(XML_OUTPUT)+"/"+stripPath(df.file())); + visitPreStart(m_t, "dotfile", FALSE, *this, df.children(), stripPath(df.file()), FALSE, DocImage::Html, df.width(), df.height()); + visitChildren(df); visitPostEnd(m_t, "dotfile"); } -void XmlDocVisitor::visitPre(DocMscFile *df) -{ - if (m_hide) return; - copyFile(df->file(),Config_getString(XML_OUTPUT)+"/"+stripPath(df->file())); - visitPreStart(m_t, "mscfile", FALSE, this, df->children(), stripPath(df->file()), FALSE, DocImage::Html, df->width(), df->height()); -} - -void XmlDocVisitor::visitPost(DocMscFile *) +void XmlDocVisitor::operator()(const DocMscFile &df) { if (m_hide) return; + copyFile(df.file(),Config_getString(XML_OUTPUT)+"/"+stripPath(df.file())); + visitPreStart(m_t, "mscfile", FALSE, *this, df.children(), stripPath(df.file()), FALSE, DocImage::Html, df.width(), df.height()); + visitChildren(df); visitPostEnd(m_t, "mscfile"); } -void XmlDocVisitor::visitPre(DocDiaFile *df) -{ - if (m_hide) return; - copyFile(df->file(),Config_getString(XML_OUTPUT)+"/"+stripPath(df->file())); - visitPreStart(m_t, "diafile", FALSE, this, df->children(), stripPath(df->file()), FALSE, DocImage::Html, df->width(), df->height()); -} - -void XmlDocVisitor::visitPost(DocDiaFile *) +void XmlDocVisitor::operator()(const DocDiaFile &df) { if (m_hide) return; + copyFile(df.file(),Config_getString(XML_OUTPUT)+"/"+stripPath(df.file())); + visitPreStart(m_t, "diafile", FALSE, *this, df.children(), stripPath(df.file()), FALSE, DocImage::Html, df.width(), df.height()); + visitChildren(df); visitPostEnd(m_t, "diafile"); } -void XmlDocVisitor::visitPre(DocLink *lnk) -{ - if (m_hide) return; - startLink(lnk->ref(),lnk->file(),lnk->anchor()); -} - -void XmlDocVisitor::visitPost(DocLink *) +void XmlDocVisitor::operator()(const DocLink &lnk) { if (m_hide) return; + startLink(lnk.ref(),lnk.file(),lnk.anchor()); + visitChildren(lnk); endLink(); } -void XmlDocVisitor::visitPre(DocRef *ref) +void XmlDocVisitor::operator()(const DocRef &ref) { if (m_hide) return; - if (!ref->file().isEmpty()) + if (!ref.file().isEmpty()) { - startLink(ref->ref(),ref->file(),ref->isSubPage() ? QCString() : ref->anchor()); + startLink(ref.ref(),ref.file(),ref.isSubPage() ? QCString() : ref.anchor()); } - if (!ref->hasLinkText()) filter(ref->targetTitle()); + if (!ref.hasLinkText()) filter(ref.targetTitle()); + visitChildren(ref); + if (!ref.file().isEmpty()) endLink(); } -void XmlDocVisitor::visitPost(DocRef *ref) +void XmlDocVisitor::operator()(const DocSecRefItem &ref) { if (m_hide) return; - if (!ref->file().isEmpty()) endLink(); - //m_t << " "; -} - -void XmlDocVisitor::visitPre(DocSecRefItem *ref) -{ - if (m_hide) return; - m_t << "<tocitem id=\"" << ref->file(); - if (!ref->anchor().isEmpty()) m_t << "_1" << ref->anchor(); + m_t << "<tocitem id=\"" << ref.file(); + if (!ref.anchor().isEmpty()) m_t << "_1" << ref.anchor(); m_t << "\""; m_t << ">"; -} - -void XmlDocVisitor::visitPost(DocSecRefItem *) -{ - if (m_hide) return; + visitChildren(ref); m_t << "</tocitem>\n"; } -void XmlDocVisitor::visitPre(DocSecRefList *) +void XmlDocVisitor::operator()(const DocSecRefList &l) { if (m_hide) return; m_t << "<toclist>\n"; -} - -void XmlDocVisitor::visitPost(DocSecRefList *) -{ - if (m_hide) return; + visitChildren(l); m_t << "</toclist>\n"; } -//void XmlDocVisitor::visitPre(DocLanguage *l) -//{ -// if (m_hide) return; -// m_t << "<language langid=\"" << l->id() << "\">"; -//} -// -//void XmlDocVisitor::visitPost(DocLanguage *) -//{ -// if (m_hide) return; -// m_t << "</language>\n"; -//} - -void XmlDocVisitor::visitPre(DocParamSect *s) +void XmlDocVisitor::operator()(const DocParamSect &s) { if (m_hide) return; m_t << "<parameterlist kind=\""; - switch(s->type()) + switch(s.type()) { case DocParamSect::Param: m_t << "param"; break; @@ -1121,153 +1015,112 @@ void XmlDocVisitor::visitPre(DocParamSect *s) ASSERT(0); } m_t << "\">"; + visitChildren(s); + m_t << "</parameterlist>\n"; } -void XmlDocVisitor::visitPost(DocParamSect *) +void XmlDocVisitor::operator()(const DocSeparator &) { - if (m_hide) return; - m_t << "</parameterlist>\n"; + m_t << "</parametertype>\n"; + m_t << "<parametertype>"; } -void XmlDocVisitor::visitPre(DocParamList *pl) +void XmlDocVisitor::operator()(const DocParamList &pl) { if (m_hide) return; m_t << "<parameteritem>\n"; m_t << "<parameternamelist>\n"; - for (const auto ¶m : pl->parameters()) + for (const auto ¶m : pl.parameters()) { - if (!pl->paramTypes().empty()) + if (!pl.paramTypes().empty()) { m_t << "<parametertype>"; - for (const auto &type : pl->paramTypes()) + for (const auto &type : pl.paramTypes()) { - if (type->kind()==DocNode::Kind_Word) - { - visit((DocWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)type.get()); - } - else if (type->kind()==DocNode::Kind_Sep) - { - m_t << "</parametertype>\n"; - m_t << "<parametertype>"; - } + std::visit(*this,type); } m_t << "</parametertype>\n"; } m_t << "<parametername"; - if (pl->direction()!=DocParamSect::Unspecified) + if (pl.direction()!=DocParamSect::Unspecified) { m_t << " direction=\""; - if (pl->direction()==DocParamSect::In) + if (pl.direction()==DocParamSect::In) { m_t << "in"; } - else if (pl->direction()==DocParamSect::Out) + else if (pl.direction()==DocParamSect::Out) { m_t << "out"; } - else if (pl->direction()==DocParamSect::InOut) + else if (pl.direction()==DocParamSect::InOut) { m_t << "inout"; } m_t << "\""; } m_t << ">"; - if (param->kind()==DocNode::Kind_Word) - { - visit((DocWord*)param.get()); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param.get()); - } + std::visit(*this,param); m_t << "</parametername>\n"; } m_t << "</parameternamelist>\n"; m_t << "<parameterdescription>\n"; -} - -void XmlDocVisitor::visitPost(DocParamList *) -{ - if (m_hide) return; + for (const auto &par : pl.paragraphs()) + { + std::visit(*this,par); + } m_t << "</parameterdescription>\n"; m_t << "</parameteritem>\n"; } -void XmlDocVisitor::visitPre(DocXRefItem *x) +void XmlDocVisitor::operator()(const DocXRefItem &x) { if (m_hide) return; - if (x->title().isEmpty()) return; + if (x.title().isEmpty()) return; m_t << "<xrefsect id=\""; - m_t << x->file() << "_1" << x->anchor(); + m_t << x.file() << "_1" << x.anchor(); m_t << "\">"; m_t << "<xreftitle>"; - filter(x->title()); + filter(x.title()); m_t << "</xreftitle>"; m_t << "<xrefdescription>"; -} - -void XmlDocVisitor::visitPost(DocXRefItem *x) -{ - if (m_hide) return; - if (x->title().isEmpty()) return; + visitChildren(x); + if (x.title().isEmpty()) return; m_t << "</xrefdescription>"; m_t << "</xrefsect>"; } -void XmlDocVisitor::visitPre(DocInternalRef *ref) -{ - if (m_hide) return; - startLink(QCString(),ref->file(),ref->anchor()); -} - -void XmlDocVisitor::visitPost(DocInternalRef *) +void XmlDocVisitor::operator()(const DocInternalRef &ref) { if (m_hide) return; + startLink(QCString(),ref.file(),ref.anchor()); + visitChildren(ref); endLink(); m_t << " "; } -void XmlDocVisitor::visitPre(DocText *) +void XmlDocVisitor::operator()(const DocText &t) { + visitChildren(t); } -void XmlDocVisitor::visitPost(DocText *) -{ -} - -void XmlDocVisitor::visitPre(DocHtmlBlockQuote *) +void XmlDocVisitor::operator()(const DocHtmlBlockQuote &q) { if (m_hide) return; m_t << "<blockquote>"; -} - -void XmlDocVisitor::visitPost(DocHtmlBlockQuote *) -{ - if (m_hide) return; + visitChildren(q); m_t << "</blockquote>"; } -void XmlDocVisitor::visitPre(DocVhdlFlow *) +void XmlDocVisitor::operator()(const DocVhdlFlow &) { } -void XmlDocVisitor::visitPost(DocVhdlFlow *) -{ -} - -void XmlDocVisitor::visitPre(DocParBlock *) +void XmlDocVisitor::operator()(const DocParBlock &pb) { if (m_hide) return; m_t << "<parblock>"; -} - -void XmlDocVisitor::visitPost(DocParBlock *) -{ - if (m_hide) return; + visitChildren(pb); m_t << "</parblock>"; } diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h index 9f88056..ce3b657 100644 --- a/src/xmldocvisitor.h +++ b/src/xmldocvisitor.h @@ -23,6 +23,7 @@ #include "qcstring.h" #include "docvisitor.h" +#include "docnode.h" #include "textstream.h" class CodeOutputInterface; @@ -38,109 +39,76 @@ class XmlDocVisitor : public DocVisitor // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *); - void visit(DocLinkedWord *); - void visit(DocWhiteSpace *); - void visit(DocSymbol *); - void visit(DocEmoji *); - void visit(DocURL *); - void visit(DocLineBreak *); - void visit(DocHorRuler *); - void visit(DocStyleChange *); - void visit(DocVerbatim *); - void visit(DocAnchor *); - void visit(DocInclude *); - void visit(DocIncOperator *); - void visit(DocFormula *); - void visit(DocIndexEntry *); - void visit(DocSimpleSectSep *); - void visit(DocCite *); + void operator()(const DocWord &); + void operator()(const DocLinkedWord &); + void operator()(const DocWhiteSpace &); + void operator()(const DocSymbol &); + void operator()(const DocEmoji &); + void operator()(const DocURL &); + void operator()(const DocLineBreak &); + void operator()(const DocHorRuler &); + void operator()(const DocStyleChange &); + void operator()(const DocVerbatim &); + void operator()(const DocAnchor &); + void operator()(const DocInclude &); + void operator()(const DocIncOperator &); + void operator()(const DocFormula &); + void operator()(const DocIndexEntry &); + void operator()(const DocSimpleSectSep &); + void operator()(const DocCite &); + void operator()(const DocSeparator &); //-------------------------------------- // visitor functions for compound nodes //-------------------------------------- - void visitPre(DocAutoList *); - void visitPost(DocAutoList *); - void visitPre(DocAutoListItem *); - void visitPost(DocAutoListItem *); - void visitPre(DocPara *) ; - void visitPost(DocPara *); - void visitPre(DocRoot *); - void visitPost(DocRoot *); - void visitPre(DocSimpleSect *); - void visitPost(DocSimpleSect *); - void visitPre(DocTitle *); - void visitPost(DocTitle *); - void visitPre(DocSimpleList *); - void visitPost(DocSimpleList *); - void visitPre(DocSimpleListItem *); - void visitPost(DocSimpleListItem *); - void visitPre(DocSection *); - void visitPost(DocSection *); - void visitPre(DocHtmlList *); - void visitPost(DocHtmlList *) ; - void visitPre(DocHtmlListItem *); - void visitPost(DocHtmlListItem *); - //void visitPre(DocHtmlPre *); - //void visitPost(DocHtmlPre *); - void visitPre(DocHtmlDescList *); - void visitPost(DocHtmlDescList *); - void visitPre(DocHtmlDescTitle *); - void visitPost(DocHtmlDescTitle *); - void visitPre(DocHtmlDescData *); - void visitPost(DocHtmlDescData *); - void visitPre(DocHtmlTable *); - void visitPost(DocHtmlTable *); - void visitPre(DocHtmlRow *); - void visitPost(DocHtmlRow *) ; - void visitPre(DocHtmlCell *); - void visitPost(DocHtmlCell *); - void visitPre(DocHtmlCaption *); - void visitPost(DocHtmlCaption *); - void visitPre(DocInternal *); - void visitPost(DocInternal *); - void visitPre(DocHRef *); - void visitPost(DocHRef *); - void visitPre(DocHtmlHeader *); - void visitPost(DocHtmlHeader *); - void visitPre(DocImage *); - void visitPost(DocImage *); - void visitPre(DocDotFile *); - void visitPost(DocDotFile *); - - void visitPre(DocMscFile *); - void visitPost(DocMscFile *); - void visitPre(DocDiaFile *); - void visitPost(DocDiaFile *); - void visitPre(DocLink *); - void visitPost(DocLink *); - void visitPre(DocRef *); - void visitPost(DocRef *); - void visitPre(DocSecRefItem *); - void visitPost(DocSecRefItem *); - void visitPre(DocSecRefList *); - void visitPost(DocSecRefList *); - //void visitPre(DocLanguage *); - //void visitPost(DocLanguage *); - void visitPre(DocParamSect *); - void visitPost(DocParamSect *); - void visitPre(DocParamList *); - void visitPost(DocParamList *); - void visitPre(DocXRefItem *); - void visitPost(DocXRefItem *); - void visitPre(DocInternalRef *); - void visitPost(DocInternalRef *); - void visitPre(DocText *); - void visitPost(DocText *); - void visitPre(DocHtmlBlockQuote *); - void visitPost(DocHtmlBlockQuote *); - void visitPre(DocVhdlFlow *); - void visitPost(DocVhdlFlow *); - void visitPre(DocParBlock *); - void visitPost(DocParBlock *); + void operator()(const DocAutoList &); + void operator()(const DocAutoListItem &); + void operator()(const DocPara &) ; + void operator()(const DocRoot &); + void operator()(const DocSimpleSect &); + void operator()(const DocTitle &); + void operator()(const DocSimpleList &); + void operator()(const DocSimpleListItem &); + void operator()(const DocSection &); + void operator()(const DocHtmlList &); + void operator()(const DocHtmlListItem &); + void operator()(const DocHtmlDescList &); + void operator()(const DocHtmlDescTitle &); + void operator()(const DocHtmlDescData &); + void operator()(const DocHtmlTable &); + void operator()(const DocHtmlRow &); + void operator()(const DocHtmlCell &); + void operator()(const DocHtmlCaption &); + void operator()(const DocInternal &); + void operator()(const DocHRef &); + void operator()(const DocHtmlHeader &); + void operator()(const DocImage &); + void operator()(const DocDotFile &); + void operator()(const DocMscFile &); + void operator()(const DocDiaFile &); + void operator()(const DocLink &); + void operator()(const DocRef &); + void operator()(const DocSecRefItem &); + void operator()(const DocSecRefList &); + void operator()(const DocParamSect &); + void operator()(const DocParamList &); + void operator()(const DocXRefItem &); + void operator()(const DocInternalRef &); + void operator()(const DocText &); + void operator()(const DocHtmlBlockQuote &); + void operator()(const DocVhdlFlow &); + void operator()(const DocParBlock &); private: + template<class T> + void visitChildren(const T &t) + { + for (const auto &child : t.children()) + { + std::visit(*this, child); + } + } //-------------------------------------- // helper functions diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 14797b5..07b0d83 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -123,7 +123,7 @@ inline void writeXMLCodeString(TextStream &t,const QCString &str, int &col) { case '\t': { - static int tabSize = Config_getInt(TAB_SIZE); + int tabSize = Config_getInt(TAB_SIZE); int spacesToNextTabStop = tabSize - (col%tabSize); col+=spacesToNextTabStop; while (spacesToNextTabStop--) t << "<sp/>"; @@ -334,7 +334,7 @@ void XMLCodeGenerator::writeLineNumber(const QCString &extRef,const QCString &co if (!compId.isEmpty()) { m_refId=compId; - if (!anchorId.isEmpty()) m_refId+=(QCString)"_1"+anchorId; + if (!anchorId.isEmpty()) m_refId+=QCString("_1")+anchorId; m_isMemberRef = anchorId!=0; if (!extRef.isEmpty()) m_external=extRef; } @@ -424,17 +424,21 @@ static void writeXMLDocBlock(TextStream &t, QCString stext = text.stripWhiteSpace(); if (stext.isEmpty()) return; // convert the documentation string into an abstract syntax tree - std::unique_ptr<IDocParser> parser { createDocParser() }; - std::unique_ptr<DocNode> root { validatingParseDoc(*parser.get(), - fileName,lineNr,scope,md,text,FALSE,FALSE, - QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; - // create a code generator - auto xmlCodeGen = std::make_unique<XMLCodeGenerator>(t); - // create a parse tree visitor for XML - auto visitor = std::make_unique<XmlDocVisitor>(t,*xmlCodeGen,scope?scope->getDefFileExtension():QCString("")); - // visit all nodes - root->accept(visitor.get()); - // clean up + auto parser { createDocParser() }; + auto ast { validatingParseDoc(*parser.get(), + fileName,lineNr,scope,md,text,FALSE,FALSE, + QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) }; + auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get()); + if (astImpl) + { + // create a code generator + auto xmlCodeGen = std::make_unique<XMLCodeGenerator>(t); + // create a parse tree visitor for XML + XmlDocVisitor visitor(t,*xmlCodeGen,scope?scope->getDefFileExtension():QCString("")); + // visit all nodes + std::visit(visitor,astImpl->root); + // clean up + } } void writeXMLCodeBlock(TextStream &t,FileDef *fd) @@ -500,7 +504,7 @@ static void stripQualifiers(QCString &typeStr) static QCString classOutputFileBase(const ClassDef *cd) { - //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); + //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); //if (inlineGroupedClasses && cd->partOfGroups()!=0) return cd->getOutputFileBase(); //else @@ -509,7 +513,7 @@ static QCString classOutputFileBase(const ClassDef *cd) static QCString memberOutputFileBase(const MemberDef *md) { - //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); + //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0) // return md->getClassDef()->getXmlOutputFileBase(); //else @@ -1761,7 +1765,7 @@ static void generateXMLForPage(PageDef *pd,TextStream &ti,bool isExample) QCString pageName = pd->getOutputFileBase(); if (pd->getGroupDef()) { - pageName+=(QCString)"_"+pd->name(); + pageName+=QCString("_")+pd->name(); } if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page. @@ -1790,7 +1794,7 @@ static void generateXMLForPage(PageDef *pd,TextStream &ti,bool isExample) QCString title; if (mainPageHasTitle()) { - title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()).str()); + title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title())); } else { @@ -1804,7 +1808,7 @@ static void generateXMLForPage(PageDef *pd,TextStream &ti,bool isExample) const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) { - t << " <title>" << convertToXML(filterTitle(convertCharEntitiesToUTF8(si->title()).str())) + t << " <title>" << convertToXML(filterTitle(convertCharEntitiesToUTF8(si->title()))) << "</title>\n"; } } @@ -1821,7 +1825,7 @@ static void generateXMLForPage(PageDef *pd,TextStream &ti,bool isExample) if (isSection(si->type())) { //printf(" level=%d title=%s\n",level,qPrint(si->title)); - int nextLevel = (int)si->type(); + int nextLevel = static_cast<int>(si->type()); if (nextLevel>level) { for (l=level;l<nextLevel;l++) diff --git a/src/xmlgen.h b/src/xmlgen.h index 7adda71..41104f6 100644 --- a/src/xmlgen.h +++ b/src/xmlgen.h @@ -39,8 +39,6 @@ class XMLCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const QCString &) override; void writeLineNumber(const QCString &extRef,const QCString &compId, const QCString &anchorId,int l,bool writeLineAnchor) override; - void setCurrentDoc(const Definition *,const QCString &,bool) override {} - void addWord(const QCString &,bool) override {} void startCodeFragment(const QCString &) override; void endCodeFragment(const QCString &) override; |