diff options
Diffstat (limited to 'src')
154 files changed, 15631 insertions, 6164 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5c55efa..4dc31fa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,7 +119,7 @@ FLEX_TARGET(xmlcode xmlcode.l ${GENERATED_SRC}/xmlcode.cpp FLEX_TARGET(sqlcode sqlcode.l ${GENERATED_SRC}/sqlcode.cpp COMPILE_FLAGS "${LEX_FLAGS}") FLEX_TARGET(configimpl configimpl.l ${GENERATED_SRC}/configimpl.cpp COMPILE_FLAGS "${LEX_FLAGS}") -BISON_TARGET(constexp constexp.y ${GENERATED_SRC}/ce_parse.cpp COMPILE_FLAGS ${YACC_FLAGS}) +BISON_TARGET(constexp constexp.y ${GENERATED_SRC}/ce_parse.cpp COMPILE_FLAGS "${YACC_FLAGS}") add_library(doxycfg STATIC ${GENERATED_SRC}/lang_cfg.h @@ -183,6 +183,7 @@ add_library(_doxygen STATIC dot.cpp doxygen.cpp eclipsehelp.cpp + emoji.cpp entry.cpp filedef.cpp filename.cpp diff --git a/src/cite.cpp b/src/cite.cpp index f86350b..4f88611 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -223,7 +223,6 @@ void CiteDict::generatePage() const if (line.find("<!-- BEGIN BIBLIOGRAPHY")!=-1) insideBib=TRUE; else if (line.find("<!-- END BIBLIOGRAPH")!=-1) insideBib=FALSE; - else if (insideBib) doc+=line+"\n"; int i; // determine text to use at the location of the @cite command if (insideBib && (i=line.find("name=\"CITEREF_"))!=-1) @@ -234,14 +233,17 @@ void CiteDict::generatePage() const { QCString label = line.mid(i+14,j-i-14); QCString number = line.mid(j+2,k-j-1); + label = substitute(substitute(label,"–","--"),"—","---"); CiteInfo *ci = m_entries.find(label); //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),ci); + line = line.left(i+14) + label + line.right(line.length()-j); if (ci) { ci->text = number; } } } + if (insideBib) doc+=line+"\n"; } //printf("doc=[%s]\n",doc.data()); @@ -268,7 +270,7 @@ void CiteDict::generatePage() const { if (!bibFile.isEmpty()) { - // bug_700510, multile times the same name were overwriting; creating new names + // bug_700510, multiple times the same name were overwriting; creating new names // also for names with spaces ++i; copyFile(bibFile,latexOutputDir + bibTmpFile + QCString().setNum(i) + ".bib"); diff --git a/src/clangparser.cpp b/src/clangparser.cpp index 77151d6..18dd404 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -4,6 +4,7 @@ #if USE_LIBCLANG #include <clang-c/Index.h> +#include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/Tooling.h" #include <qfileinfo.h> #include <stdlib.h> @@ -196,32 +197,32 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) std::vector<std::string> options = command[command.size()-1].CommandLine; // copy each compiler option used from the database. Skip the first which is compiler exe. for (auto option = options.begin()+1; option != options.end(); option++) { - argv[argc++] = strdup(option->c_str()); + argv[argc++] = qstrdup(option->c_str()); } // this extra addition to argv is accounted for as we are skipping the first entry in - argv[argc++]=strdup("-w"); // finally, turn off warnings. + argv[argc++]=qstrdup("-w"); // finally, turn off warnings. } else { // add include paths for input files for (di.toFirst();di.current();++di,++argc) { QCString inc = QCString("-I")+di.currentKey(); - argv[argc]=strdup(inc.data()); + argv[argc]=qstrdup(inc.data()); //printf("argv[%d]=%s\n",argc,argv[argc]); } // add external include paths for (uint i=0;i<includePath.count();i++) { QCString inc = QCString("-I")+includePath.at(i); - argv[argc++]=strdup(inc.data()); + argv[argc++]=qstrdup(inc.data()); } // user specified options for (uint i=0;i<clangOptions.count();i++) { - argv[argc++]=strdup(clangOptions.at(i)); + argv[argc++]=qstrdup(clangOptions.at(i)); } // extra options - argv[argc++]=strdup("-ferror-limit=0"); - argv[argc++]=strdup("-x"); + argv[argc++]=qstrdup("-ferror-limit=0"); + argv[argc++]=qstrdup("-x"); // Since we can be presented with a .h file that can contain C/C++ or // Objective C code and we need to configure the parser before knowing this, @@ -249,19 +250,19 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) switch(p->detectedLang) { case ClangParser::Private::Detected_Cpp: - argv[argc++]=strdup("c++"); + argv[argc++]=qstrdup("c++"); break; case ClangParser::Private::Detected_ObjC: - argv[argc++]=strdup("objective-c"); + argv[argc++]=qstrdup("objective-c"); break; case ClangParser::Private::Detected_ObjCpp: - argv[argc++]=strdup("objective-c++"); + argv[argc++]=qstrdup("objective-c++"); break; } // provide the input and and its dependencies as unsaved files so we can // pass the filtered versions - argv[argc++]=strdup(fileName); + argv[argc++]=qstrdup(fileName); } static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); //printf("source %s ----------\n%s\n-------------\n\n", @@ -271,7 +272,7 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) p->sources = new QCString[numUnsavedFiles]; p->ufs = new CXUnsavedFile[numUnsavedFiles]; p->sources[0] = detab(fileToString(fileName,filterSourceFiles,TRUE)); - p->ufs[0].Filename = strdup(fileName); + p->ufs[0].Filename = qstrdup(fileName); p->ufs[0].Contents = p->sources[0].data(); p->ufs[0].Length = p->sources[0].length(); QStrListIterator it(filesInTranslationUnit); @@ -280,7 +281,7 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) { p->fileMapping.insert(it.current(),new uint(i)); p->sources[i] = detab(fileToString(it.current(),filterSourceFiles,TRUE)); - p->ufs[i].Filename = strdup(it.current()); + p->ufs[i].Filename = qstrdup(it.current()); p->ufs[i].Contents = p->sources[i].data(); p->ufs[i].Length = p->sources[i].length(); } @@ -963,6 +964,7 @@ void ClangParser::writeSources(CodeOutputInterface &,FileDef *) ClangParser::ClangParser() { + p = NULL; } ClangParser::~ClangParser() diff --git a/src/clangparser.h b/src/clangparser.h index 6072208..8bb9aba 100644 --- a/src/clangparser.h +++ b/src/clangparser.h @@ -19,7 +19,7 @@ class ClangParser * @param[in,out] filesInTranslationUnit Other files that are * part of the input and included by the file. * The function will return a subset of the files, - * only including the onces that were actually found + * only including the ones that were actually found * during parsing. */ void start(const char *fileName,QStrList &filesInTranslationUnit); diff --git a/src/classdef.cpp b/src/classdef.cpp index e1a80ce..e9d39d5 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -17,6 +17,7 @@ #include <stdio.h> #include <qfile.h> +#include <qfileinfo.h> #include <qregexp.h> #include "classdef.h" #include "classlist.h" @@ -201,6 +202,8 @@ class ClassDefImpl bool isAnonymous; uint64 spec; + + QCString metaData; }; void ClassDefImpl::init(const char *defFileName, const char *name, @@ -440,7 +443,7 @@ void ClassDef::internalInsertMember(MemberDef *md, if (getLanguage()==SrcLangExt_VHDL) { - QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE); + QCString title=theTranslator->trVhdlType(md->getMemberSpecifiers(),FALSE); if (!m_impl->vhdlSummaryTitles.find(title)) { m_impl->vhdlSummaryTitles.append(title,new QCString(title)); @@ -671,6 +674,10 @@ void ClassDef::internalInsertMember(MemberDef *md, case MemberType_Variable: addMemberToList(MemberListType_variableMembers,md,FALSE); break; + case MemberType_Define: + warn(md->getDefFileName(),md->getDefLine()-1,"A define (%s) cannot be made a member of %s", + md->name().data(), this->name().data()); + break; default: err("Unexpected member type %d found!\n",md->memberType()); } @@ -1013,13 +1020,13 @@ void ClassDef::writeDetailedDocumentationBody(OutputList &ol) // write examples if (hasExamples() && m_impl->exampleSDict) { - ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": "); + ol.startExamples(); ol.startDescForItem(); //ol.startParagraph(); writeExample(ol,m_impl->exampleSDict); //ol.endParagraph(); ol.endDescForItem(); - ol.endSimpleSect(); + ol.endExamples(); } //ol.newParagraph(); writeSourceDef(ol,name()); @@ -1110,7 +1117,15 @@ void ClassDef::showUsedFiles(OutputList &ol) ol.writeRuler(); - ol.parseText(generatedFromFiles()); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Docbook); + ol.startParagraph(); + ol.parseText(generatedFromFiles()); + ol.endParagraph(); + ol.popGeneratorState(); + ol.disable(OutputGenerator::Docbook); + ol.parseText(generatedFromFiles()); + ol.enable(OutputGenerator::Docbook); bool first=TRUE; QListIterator<FileDef> li(m_impl->files); @@ -1223,7 +1238,7 @@ void ClassDef::writeInheritanceGraph(OutputList &ol) } } else if (Config_getBool(CLASS_DIAGRAMS) && count>0) - // write class diagram using build-in generator + // write class diagram using built-in generator { ClassDiagram diagram(this); // create a diagram of this class. ol.startClassDiagram(); @@ -1360,10 +1375,165 @@ QCString ClassDef::includeStatement() const } } +void ClassDef::writeIncludeFilesForSlice(OutputList &ol) +{ + if (m_impl->incInfo) + { + QCString nm; + QStrList paths = Config_getList(STRIP_FROM_PATH); + if (!paths.isEmpty() && m_impl->incInfo->fileDef) + { + QCString abs = m_impl->incInfo->fileDef->absFilePath(); + const char *s = paths.first(); + QCString potential; + unsigned int length = 0; + while (s) + { + QFileInfo info(s); + if (info.exists()) + { + QString prefix = info.absFilePath(); + if (prefix.at(prefix.length() - 1) != '/') + { + prefix += '/'; + } + + if (prefix.length() > length && + qstricmp(abs.left(prefix.length()).data(), prefix.data()) == 0) // case insensitive compare + { + length = prefix.length(); + potential = abs.right(abs.length() - prefix.length()); + } + s = paths.next(); + } + } + + if (length > 0) + { + nm = potential; + } + } + + if (nm.isEmpty()) + { + nm = m_impl->incInfo->includeName.data(); + } + + ol.startParagraph(); + ol.docify(theTranslator->trDefinedIn()+" "); + ol.startTypewriter(); + ol.docify("<"); + if (m_impl->incInfo->fileDef) + { + ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm); + } + else + { + ol.docify(nm); + } + ol.docify(">"); + ol.endTypewriter(); + ol.endParagraph(); + } + + // Write a summary of the Slice definition including metadata. + ol.startParagraph(); + ol.startTypewriter(); + if (!m_impl->metaData.isEmpty()) + { + ol.docify(m_impl->metaData); + ol.lineBreak(); + } + if (m_impl->spec & Entry::Local) + { + ol.docify("local "); + } + if (m_impl->spec & Entry::Interface) + { + ol.docify("interface "); + } + else if (m_impl->spec & Entry::Struct) + { + ol.docify("struct "); + } + else if (m_impl->spec & Entry::Exception) + { + ol.docify("exception "); + } + else + { + ol.docify("class "); + } + ol.docify(stripScope(name())); + if (m_impl->inherits) + { + if (m_impl->spec & (Entry::Interface|Entry::Exception)) + { + ol.docify(" extends "); + BaseClassListIterator it(*m_impl->inherits); + BaseClassDef *ibcd; + for (;(ibcd=it.current());++it) + { + ClassDef *icd = ibcd->classDef; + ol.docify(icd->name()); + if (!it.atLast()) + { + ol.docify(", "); + } + } + } + else + { + // Must be a class. + bool implements = false; + BaseClassListIterator it(*m_impl->inherits); + BaseClassDef *ibcd; + for (;(ibcd=it.current());++it) + { + ClassDef *icd = ibcd->classDef; + if (icd->m_impl->spec & Entry::Interface) + { + implements = true; + } + else + { + ol.docify(" extends "); + ol.docify(icd->name()); + } + } + if (implements) + { + ol.docify(" implements "); + bool first = true; + for (ibcd=it.toFirst();(ibcd=it.current());++it) + { + ClassDef *icd = ibcd->classDef; + if (icd->m_impl->spec & Entry::Interface) + { + if (!first) + { + ol.docify(", "); + } + else + { + first = false; + } + ol.docify(icd->name()); + } + } + } + } + } + ol.docify(" { ... }"); + ol.endTypewriter(); + ol.endParagraph(); +} + void ClassDef::writeIncludeFiles(OutputList &ol) { if (m_impl->incInfo /*&& Config_getBool(SHOW_INCLUDE_FILES)*/) { + SrcLangExt lang = getLanguage(); QCString nm=m_impl->incInfo->includeName.isEmpty() ? (m_impl->incInfo->fileDef ? m_impl->incInfo->fileDef->docName().data() : "" @@ -1374,7 +1544,6 @@ void ClassDef::writeIncludeFiles(OutputList &ol) ol.startParagraph(); ol.startTypewriter(); ol.docify(includeStatement()); - SrcLangExt lang = getLanguage(); bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; if (m_impl->incInfo->local || isIDLorJava) ol.docify("\""); @@ -1568,7 +1737,7 @@ void ClassDef::writeSummaryLinks(OutputList &ol) SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles); for (li.toFirst();li.current();++li) { - ol.writeSummaryLink(0,li.current()->data(),li.current()->data(),first); + ol.writeSummaryLink(0,convertToId(li.current()->data()),li.current()->data(),first); first=FALSE; } } @@ -1582,7 +1751,11 @@ void ClassDef::writeSummaryLinks(OutputList &ol) void ClassDef::writeTagFile(FTextStream &tagFile) { if (!isLinkableInProject()) return; - tagFile << " <compound kind=\"" << compoundTypeString(); + tagFile << " <compound kind=\""; + if (isFortran() && (compoundTypeString() == "type")) + tagFile << "struct"; + else + tagFile << compoundTypeString(); tagFile << "\""; if (isObjectiveC()) { tagFile << " objc=\"yes\""; } tagFile << ">" << endl; @@ -1835,6 +2008,7 @@ void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor) // LaTeX + RTF ol.disable(OutputGenerator::Html); ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); if (!(usePDFLatex && pdfHyperlinks)) { ol.disable(OutputGenerator::Latex); @@ -1870,19 +2044,42 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade { //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); SrcLangExt lang = getLanguage(); if (visibleInParentsDeclList()) { if (!found) // first class { - ol.startMemberHeader("nested-classes"); + if (sliceOpt) + { + if (compoundType()==Interface) + { + ol.startMemberHeader("interfaces"); + } + else if (compoundType()==Struct) + { + ol.startMemberHeader("structs"); + } + else if (compoundType()==Exception) + { + ol.startMemberHeader("exceptions"); + } + else // compoundType==Class + { + ol.startMemberHeader("nested-classes"); + } + } + else // non-Slice optimization: single header for class/struct/.. + { + ol.startMemberHeader("nested-classes"); + } if (header) { ol.parseText(header); } else if (lang==SrcLangExt_VHDL) { - ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE)); + ol.parseText(theTranslator->trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE)); } else { @@ -1901,6 +2098,10 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type { + if (isSliceLocal()) + { + ol.writeString("local "); + } ol.writeString(ctype); ol.writeString(" "); ol.insertMemberAlign(); @@ -1935,21 +2136,7 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade if (rootNode && !rootNode->isEmpty()) { ol.startMemberDescription(anchor()); - - ol.pushGeneratorState(); - ol.disableAll(); - ol.enable(OutputGenerator::RTF); - ol.writeString("{"); - ol.popGeneratorState(); - ol.writeDoc(rootNode,this,0); - - ol.pushGeneratorState(); - ol.disableAll(); - ol.enable(OutputGenerator::RTF); - ol.writeString("\\par}"); - ol.popGeneratorState(); - if (isLinkableInProject()) { writeMoreLink(ol,anchor()); @@ -2018,7 +2205,14 @@ void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*page writeBriefDescription(ol,exampleFlag); break; case LayoutDocEntry::ClassIncludes: - writeIncludeFiles(ol); + if (lang==SrcLangExt_Slice) + { + writeIncludeFilesForSlice(ol); + } + else + { + writeIncludeFiles(ol); + } break; case LayoutDocEntry::ClassInheritanceGraph: writeInheritanceGraph(ol); @@ -2080,8 +2274,14 @@ void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*page case LayoutDocEntry::NamespaceNestedNamespaces: case LayoutDocEntry::NamespaceNestedConstantGroups: case LayoutDocEntry::NamespaceClasses: + case LayoutDocEntry::NamespaceInterfaces: + case LayoutDocEntry::NamespaceStructs: + case LayoutDocEntry::NamespaceExceptions: case LayoutDocEntry::NamespaceInlineClasses: case LayoutDocEntry::FileClasses: + case LayoutDocEntry::FileInterfaces: + case LayoutDocEntry::FileStructs: + case LayoutDocEntry::FileExceptions: case LayoutDocEntry::FileNamespaces: case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: @@ -2120,9 +2320,15 @@ QCString ClassDef::title() const m_impl->compType, m_impl->tempArgs != 0); } + else if (lang==SrcLangExt_Slice) + { + pageTitle = theTranslator->trCompoundReferenceSlice(displayName(), + m_impl->compType, + isSliceLocal()); + } else if (lang==SrcLangExt_VHDL) { - pageTitle = VhdlDocGen::getClassTitle(this)+" Reference"; + pageTitle = theTranslator->trCustomReference(VhdlDocGen::getClassTitle(this)); } else if (isJavaEnum()) { @@ -2158,9 +2364,35 @@ void ClassDef::writeDocumentation(OutputList &ol) 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); QCString pageTitle = title(); - startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView); + HighlightedItem hli; + if (sliceOpt) + { + if (compoundType()==Interface) + { + hli = HLI_InterfaceVisible; + } + else if (compoundType()==Struct) + { + hli = HLI_StructVisible; + } + else if (compoundType()==Exception) + { + hli = HLI_ExceptionVisible; + } + else + { + hli = HLI_ClassVisible; + } + } + else + { + hli = HLI_ClassVisible; + } + + startFile(ol,getOutputFileBase(),name(),pageTitle,hli,!generateTreeView); if (!generateTreeView) { if (getOuterScope()!=Doxygen::globalScope) @@ -2287,15 +2519,40 @@ void ClassDef::writeMemberList(OutputList &ol) { 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); if (m_impl->allMemberNameInfoSDict==0 || cOpt) return; // only for HTML ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); + HighlightedItem hli; + if (sliceOpt) + { + if (compoundType()==Interface) + { + hli = HLI_InterfaceVisible; + } + else if (compoundType()==Struct) + { + hli = HLI_StructVisible; + } + else if (compoundType()==Exception) + { + hli = HLI_ExceptionVisible; + } + else + { + hli = HLI_ClassVisible; + } + } + else + { + hli = HLI_ClassVisible; + } + QCString memListFile = getMemberListFileName(); - startFile(ol,memListFile,memListFile,theTranslator->trMemberList(), - HLI_ClassVisible,!generateTreeView,getOutputFileBase()); + startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),hli,!generateTreeView,getOutputFileBase()); if (!generateTreeView) { if (getOuterScope()!=Doxygen::globalScope) @@ -2315,8 +2572,8 @@ void ClassDef::writeMemberList(OutputList &ol) ol.endParagraph(); //ol.startItemList(); - ol.writeString("<table class=\"directory\">\n"); + bool first = true; // to prevent empty table int idx=0; //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first(); MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict); @@ -2343,6 +2600,11 @@ void ClassDef::writeMemberList(OutputList &ol) { QCString name=mi->ambiguityResolutionScope+md->name(); //ol.writeListItem(); + if (first) + { + ol.writeString("<table class=\"directory\">\n"); + first = false; + } ol.writeString(" <tr"); if ((idx&1)==0) ol.writeString(" class=\"even\""); idx++; @@ -2396,6 +2658,11 @@ void ClassDef::writeMemberList(OutputList &ol) // generate link to the class instead. { //ol.writeListItem(); + if (first) + { + ol.writeString("<table class=\"directory\">\n"); + first = false; + } ol.writeString(" <tr bgcolor=\"#f0f0f0\""); if ((idx&1)==0) ol.writeString(" class=\"even\""); idx++; @@ -2474,7 +2741,7 @@ void ClassDef::writeMemberList(OutputList &ol) QStrList sl; if (lang==SrcLangExt_VHDL) { - sl.append(VhdlDocGen::trVhdlType(md->getMemberSpecifiers())); //append vhdl type + sl.append(theTranslator->trVhdlType(md->getMemberSpecifiers(),TRUE)); //append vhdl type } else if (md->isFriend()) sl.append("friend"); else if (md->isRelated()) sl.append("related"); @@ -2525,7 +2792,7 @@ void ClassDef::writeMemberList(OutputList &ol) } //ol.endItemList(); - ol.writeString("</table>"); + if (!first) ol.writeString("</table>"); endFile(ol); ol.popGeneratorState(); @@ -2687,7 +2954,7 @@ bool ClassDef::hasNonReferenceSuperClass() return found; } -/*! called from MemberDef::writeDeclaration() to (recusively) write the +/*! called from MemberDef::writeDeclaration() to (recursively) write the * definition of an anonymous struct, union or class. */ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup, @@ -2873,7 +3140,7 @@ static bool isStandardFunc(MemberDef *md) } /*! - * recusively merges the `all members' lists of a class base + * recursively merges the `all members' lists of a class base * with that of this class. Must only be called for classes without * subclasses! */ @@ -4514,6 +4781,11 @@ bool ClassDef::isObjectiveC() const return getLanguage()==SrcLangExt_ObjC; } +bool ClassDef::isFortran() const +{ + return getLanguage()==SrcLangExt_Fortran; +} + bool ClassDef::isCSharp() const { return getLanguage()==SrcLangExt_CSharp; @@ -4742,12 +5014,22 @@ bool ClassDef::subGrouping() const return m_impl->subGrouping; } +bool ClassDef::isSliceLocal() const +{ + return m_impl->spec&Entry::Local; +} + void ClassDef::setName(const char *name) { m_impl->isAnonymous = QCString(name).find('@')!=-1; Definition::setName(name); } +void ClassDef::setMetaData(const char *md) +{ + m_impl->metaData = md; +} + bool ClassDef::isAnonymous() const { return m_impl->isAnonymous; diff --git a/src/classdef.h b/src/classdef.h index 23c5c5c..14f9fc8 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -200,7 +200,7 @@ class ClassDef : public Definition MemberDef *getMemberByName(const QCString &) const; /** Returns TRUE iff \a bcd is a direct or indirect base class of this - * class. This function will recusively traverse all branches of the + * class. This function will recursively traverse all branches of the * inheritance tree. */ bool isBaseClass(ClassDef *bcd,bool followInstances,int level=0); @@ -266,6 +266,9 @@ class ClassDef : public Definition /** Returns TRUE if this class is implemented in Objective-C */ bool isObjectiveC() const; + /** Returns TRUE if this class is implemented in Fortran */ + bool isFortran() const; + /** Returns TRUE if this class is implemented in C# */ bool isCSharp() const; @@ -333,6 +336,7 @@ class ClassDef : public Definition QCString getMemberListFileName() const; bool subGrouping() const; + bool isSliceLocal() const; //----------------------------------------------------------------------------------- // --- setters ---- @@ -373,6 +377,8 @@ class ClassDef : public Definition void setTagLessReference(ClassDef *cd); void setName(const char *name); + void setMetaData(const char *md); + //----------------------------------------------------------------------------------- // --- actions ---- //----------------------------------------------------------------------------------- @@ -426,6 +432,7 @@ class ClassDef : public Definition void writeDetailedDescription(OutputList &ol,const QCString &pageType,bool exampleFlag, const QCString &title,const QCString &anchor=QCString()); void writeIncludeFiles(OutputList &ol); + void writeIncludeFilesForSlice(OutputList &ol); //void writeAllMembersLink(OutputList &ol); void writeInheritanceGraph(OutputList &ol); void writeCollaborationGraph(OutputList &ol); diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp index 2c8effc..55f8214 100644 --- a/src/cmdmapper.cpp +++ b/src/cmdmapper.cpp @@ -111,6 +111,7 @@ CommandMap cmdMap[] = { "\\", CMD_BSLASH }, { "@", CMD_AT }, { "<", CMD_LESS }, + { "=", CMD_EQUAL }, { ">", CMD_GREATER }, { "&", CMD_AMP }, { "$", CMD_DOLLAR }, @@ -147,6 +148,7 @@ CommandMap cmdMap[] = { "--", CMD_NDASH }, { "---", CMD_MDASH }, { "_setscope", CMD_SETSCOPE }, + { "emoji", CMD_EMOJI }, { 0, 0 }, }; @@ -193,6 +195,8 @@ CommandMap htmlTagMap[] = { "span", HTML_SPAN }, { "div", HTML_DIV }, { "blockquote", HTML_BLOCKQUOTE }, + { "strike", HTML_STRIKE }, + { "u", HTML_UNDERLINE }, { "c", XML_C }, // { "code", XML_CODE }, <= ambiguous <code> is also a HTML tag diff --git a/src/cmdmapper.h b/src/cmdmapper.h index 8cb529d..8c49b3f 100644 --- a/src/cmdmapper.h +++ b/src/cmdmapper.h @@ -136,7 +136,9 @@ enum CommandType CMD_MINUS = 106, CMD_INCLUDEDOC = 107, CMD_SNIPPETDOC = 108, - CMD_SNIPWITHLINES= 109 + CMD_SNIPWITHLINES= 109, + CMD_EMOJI = 110, + CMD_EQUAL = 111 }; enum HtmlTagType @@ -175,6 +177,8 @@ enum HtmlTagType HTML_SPAN = 31, HTML_DIV = 32, HTML_BLOCKQUOTE= 33, + HTML_STRIKE = 34, + HTML_UNDERLINE = 35, XML_CmdMask = 0x100, @@ -116,11 +116,13 @@ static int g_memCallContext; static int g_lastCContext; static int g_skipInlineInitContext; +static bool g_insideCpp; static bool g_insideObjC; static bool g_insideJava; static bool g_insideCS; static bool g_insidePHP; static bool g_insideProtocolList; +static bool g_insideSlice; static bool g_lexInit = FALSE; @@ -982,7 +984,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName } } NamespaceDef *nd = getResolvedNamespace(className); - if (nd) + if (nd && nd->isLinkableInProject()) { g_theCallContext.setScope(nd); addToSearchIndex(className); @@ -1323,7 +1325,9 @@ static void generateFunctionLink(CodeOutputInterface &ol,const char *funcName) //CodeClassDef *ccd=0; ClassDef *ccd=0; QCString locScope=g_classScope; - QCString locFunc=removeRedundantWhiteSpace(funcName); + QString qq=removeRedundantWhiteSpace(funcName); + if (g_insidePHP && qq.startsWith("self::")) qq=qq.mid(4); + QCString locFunc(qq.data()); QCString funcScope; QCString funcWithScope=locFunc; QCString funcWithFullScope=locFunc; @@ -1796,6 +1800,11 @@ static QCString escapeComment(const char *s) return result; } +static bool skipLanguageSpecificKeyword(const QCString &kw) +{ + return g_insideCpp && (kw == "remove" || kw == "set" || kw == "get"); +} + /* ----------------------------------------------------------------- */ #undef YY_INPUT @@ -1823,10 +1832,11 @@ TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" SCOPETNAME (((({ID}{TEMPLIST}?){BN}*)?{SEP}{BN}*)*)((~{BN}*)?{ID}) SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*{SEP}{BN}*)+ KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw"|"@synthesize"|"@property") -KEYWORD ("asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"set"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"sizeof"|"static"|"struct"|"__super"|"function"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|"alignas"|"alignof"|{KEYWORD_OBJC}) +KEYWORD ("asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"set"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"null"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"sizeof"|"static"|"struct"|"__super"|"function"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|"alignas"|"alignof"|{KEYWORD_OBJC}) FLOWKW ("break"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"return"|"switch"|"throw"|"throws"|"@catch"|"@finally") FLOWCONDITION ("case"|"for"|"foreach"|"for each"|"goto"|"if"|"try"|"while"|"@try") -TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string"|"nullptr") +TYPEKW ("bool"|"byte"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string"|"nullptr") +TYPEKWSL ("LocalObject"|"Object"|"Value") CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast") CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++" @@ -2164,8 +2174,12 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_code->codify(yytext); endFontClass(); } +<ClassName>{ID}("."{ID})* | <ClassName>{ID}("::"{ID})* { - g_curClassName=yytext; + if(g_insideCS) + g_curClassName=substitute(yytext,".","::"); + else + g_curClassName=yytext; addType(); if (g_curClassName=="alignas") { @@ -2229,7 +2243,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" unput(*yytext); BEGIN( Body ); } -<ClassVar>("extends"|"implements") { // Java +<ClassVar>("extends"|"implements") { // Java, Slice startFontClass("keyword"); codifyLines(yytext); endFontClass(); @@ -2415,6 +2429,8 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_prefixed_with_this_keyword = TRUE; } <Body>{KEYWORD}/([^a-z_A-Z0-9]) { + if (g_insideJava && qstrcmp("internal",yytext) ==0) REJECT; + if (skipLanguageSpecificKeyword(yytext)) REJECT; startFontClass("keyword"); codifyLines(yytext); if (QCString(yytext)=="typedef") @@ -2425,11 +2441,13 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" endFontClass(); } <Body>{KEYWORD}/{B}* { + if (skipLanguageSpecificKeyword(yytext)) REJECT; startFontClass("keyword"); codifyLines(yytext); endFontClass(); } <Body>{KEYWORD}/{BN}*"(" { + if (skipLanguageSpecificKeyword(yytext)) REJECT; startFontClass("keyword"); codifyLines(yytext); endFontClass(); @@ -2526,6 +2544,20 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" addType(); g_name+=yytext; } +<Body,TemplDecl,ObjCMethod>{TYPEKWSL}/{B}* { + if (!g_insideSlice) + { + REJECT; + } + else + { + startFontClass("keywordtype"); + g_code->codify(yytext); + endFontClass(); + addType(); + g_name+=yytext; + } + } <Body>"generic"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { startFontClass("keyword"); g_code->codify(yytext); @@ -2586,7 +2618,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" generatePHPVariableLink(*g_code,yytext); g_name+=yytext+7; } -<Body,TemplCast>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"("::"{ID})*/{B}* { // A<T> *pt; +<Body,TemplCast>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>\(]*">"("::"{ID})*/{B}* { // A<T> *pt; int i=QCString(yytext).find('<'); QCString kw = QCString(yytext).left(i).stripWhiteSpace(); if (kw.right(5)=="_cast" && YY_START==Body) @@ -2617,6 +2649,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" addType(); g_name=varname; } +<Body>{SCOPETNAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{BN}*"(" | <Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() or A\B\foo() addType(); generateFunctionLink(*g_code,yytext); @@ -2984,6 +3017,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) { //addParmType(); //g_parmName=yytext; + if (skipLanguageSpecificKeyword(yytext)) REJECT; startFontClass("keyword"); g_code->codify(yytext); endFontClass(); @@ -2995,6 +3029,20 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_code->codify(yytext); endFontClass(); } +<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKWSL}/([^a-z_A-Z0-9]) { + if (!g_insideSlice) + { + REJECT; + } + else + { + addParmType(); + g_parmName=yytext; + startFontClass("keywordtype"); + g_code->codify(yytext); + endFontClass(); + } + } <MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) { addParmType(); g_parmName=yytext; @@ -3567,6 +3615,9 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" endFontClass(); } } +<SkipComment>[^\*\n]+ { + g_code->codify(yytext); + } <*>"/*" { startFontClass("comment"); g_code->codify(yytext); @@ -3738,10 +3789,12 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, g_sourceFileDef = new FileDef("",(exName?exName:"generated")); cleanupSourceDef = TRUE; } - g_insideObjC = lang==SrcLangExt_ObjC; - g_insideJava = lang==SrcLangExt_Java; - g_insideCS = lang==SrcLangExt_CSharp; - g_insidePHP = lang==SrcLangExt_PHP; + g_insideObjC = lang==SrcLangExt_ObjC; + g_insideJava = lang==SrcLangExt_Java; + g_insideCS = lang==SrcLangExt_CSharp; + g_insidePHP = lang==SrcLangExt_PHP; + g_insideCpp = lang==SrcLangExt_Cpp; + g_insideSlice = lang==SrcLangExt_Slice; if (g_sourceFileDef) { setCurrentDoc("l00001"); diff --git a/src/commentcnv.l b/src/commentcnv.l index 44e2543..88236ed 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -294,12 +294,12 @@ void replaceComment(int offset); } else { - /* check for fixed format; we might have some conditional as part of multilene if like C<5 .and. & */ + /* check for fixed format; we might have some conditional as part of multiline if like C<5 .and. & */ if (isFixedForm && (g_col == 0)) { copyToOutput(yytext,(int)yyleng); g_nestingCount=0; - g_commentStack.clear(); /* to be on the save side */ + g_commentStack.clear(); /* to be on the safe side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); } @@ -591,7 +591,15 @@ void replaceComment(int offset); copyToOutput(yytext,(int)yyleng); } <SkipString>\\. { /* escaped character in string */ - copyToOutput(yytext,(int)yyleng); + if (g_lang==SrcLangExt_Fortran) + { + unput(yytext[1]); + copyToOutput(yytext,1); + } + else + { + copyToOutput(yytext,(int)yyleng); + } } <SkipString>"\"" { /* end of string */ copyToOutput(yytext,(int)yyleng); @@ -604,7 +612,15 @@ void replaceComment(int offset); copyToOutput(yytext,(int)yyleng); } <SkipChar>\\. { /* escaped character */ - copyToOutput(yytext,(int)yyleng); + if (g_lang==SrcLangExt_Fortran) + { + unput(yytext[1]); + copyToOutput(yytext,1); + } + else + { + copyToOutput(yytext,(int)yyleng); + } } <SkipChar>' { /* end of character literal */ copyToOutput(yytext,(int)yyleng); @@ -1068,7 +1084,7 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) { CondCtx *ctx = g_condStack.pop(); QCString sectionInfo = " "; - if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label %s ",ctx->sectionId.data()); + if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label '%s' ",ctx->sectionId.stripWhiteSpace().data()); warn(g_fileName,ctx->lineNr,"Conditional section%sdoes not have " "a corresponding \\endcond command within this file.",sectionInfo.data()); } @@ -1093,7 +1109,9 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) if (Debug::isFlagSet(Debug::CommentCnv)) { g_outBuf->at(g_outBuf->curPos())='\0'; - msg("-------------\n%s\n-------------\n",g_outBuf->data()); + Debug::print(Debug::CommentCnv,0,"-----------\nCommentCnv: %s\n" + "output=[\n%s]\n-----------\n",fileName,g_outBuf->data() + ); } printlex(yy_flex_debug, FALSE, __FILE__, fileName); } diff --git a/src/commentscan.h b/src/commentscan.h index e202f0a..d324969 100644 --- a/src/commentscan.h +++ b/src/commentscan.h @@ -40,7 +40,7 @@ class ParserInterface; * @param[in,out] lineNr The line number at which the comment block was found. * When the function returns it will be set to the last line parsed. * @param[in] isBrief TRUE iff this comment block represents a brief description. - * @param[in] isJavaDocStyle TRUE iff this comment block is in "JavaDoc" style. + * @param[in] isJavadocStyle TRUE iff this comment block is in "Javadoc" style. * This means that it starts as a brief description until the end of * the sentences is found and then proceeds as a detailed description. * @param[in] isInbody TRUE iff this comment block is located in the body of @@ -65,7 +65,7 @@ bool parseCommentBlock(ParserInterface *parser, const QCString &fileName, int &lineNr, bool isBrief, - bool isJavaDocStyle, + bool isJavadocStyle, bool isInbody, Protection &prot, int &position, diff --git a/src/commentscan.l b/src/commentscan.l index 588d40a..90e7ac3 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -30,7 +30,7 @@ #include <qstack.h> #include <qregexp.h> #include <qfile.h> - +#include <qcstringlist.h> #include "scanner.h" #include "entry.h" #include "doxygen.h" @@ -54,81 +54,85 @@ #define YY_NO_UNISTD_H 1 // forward declarations -static bool handleBrief(const QCString &); -static bool handleFn(const QCString &); -static bool handleDef(const QCString &); -static bool handleOverload(const QCString &); -static bool handleEnum(const QCString &); -static bool handleDefGroup(const QCString &); -static bool handleAddToGroup(const QCString &); -static bool handleWeakGroup(const QCString &); -static bool handleNamespace(const QCString &); -static bool handlePackage(const QCString &); -static bool handleClass(const QCString &); -static bool handleHeaderFile(const QCString &); -static bool handleProtocol(const QCString &); -static bool handleCategory(const QCString &); -static bool handleUnion(const QCString &); -static bool handleStruct(const QCString &); -static bool handleInterface(const QCString &); -static bool handleIdlException(const QCString &); -static bool handlePage(const QCString &); -static bool handleMainpage(const QCString &); -static bool handleFile(const QCString &); -static bool handleDir(const QCString &); -static bool handleExample(const QCString &); -static bool handleDetails(const QCString &); -static bool handleName(const QCString &); -static bool handleTodo(const QCString &); -static bool handleTest(const QCString &); -static bool handleBug(const QCString &); -static bool handleSubpage(const QCString &s); -static bool handleDeprecated(const QCString &); -static bool handleXRefItem(const QCString &); -static bool handleRelated(const QCString &); -static bool handleRelatedAlso(const QCString &); -static bool handleMemberOf(const QCString &); -static bool handleRefItem(const QCString &); -static bool handleSection(const QCString &); -static bool handleAnchor(const QCString &); -static bool handleCite(const QCString &); -static bool handleFormatBlock(const QCString &); -static bool handleAddIndex(const QCString &); -static bool handleIf(const QCString &); -static bool handleIfNot(const QCString &); -static bool handleElseIf(const QCString &); -static bool handleElse(const QCString &); -static bool handleEndIf(const QCString &); -static bool handleIngroup(const QCString &); -static bool handleNoSubGrouping(const QCString &); -static bool handleShowInitializer(const QCString &); -static bool handleHideInitializer(const QCString &); -static bool handleCallgraph(const QCString &); -static bool handleHideCallgraph(const QCString &); -static bool handleCallergraph(const QCString &); -static bool handleHideCallergraph(const QCString &); -static bool handleInternal(const QCString &); -static bool handleLineBr(const QCString &); -static bool handleStatic(const QCString &); -static bool handlePure(const QCString &); -static bool handlePrivate(const QCString &); -static bool handlePrivateSection(const QCString &); -static bool handleProtected(const QCString &); -static bool handleProtectedSection(const QCString &); -static bool handlePublic(const QCString &s); -static bool handlePublicSection(const QCString &s); -static bool handleToc(const QCString &s); -static bool handleInherit(const QCString &); -static bool handleExtends(const QCString &); -static bool handleCopyDoc(const QCString &); -static bool handleCopyBrief(const QCString &); -static bool handleCopyDetails(const QCString &); -static bool handleParBlock(const QCString &); -static bool handleEndParBlock(const QCString &); -static bool handleParam(const QCString &); -static bool handleRetval(const QCString &); - -typedef bool (*DocCmdFunc)(const QCString &name); +static bool handleBrief(const QCString &, const QCStringList &); +static bool handleFn(const QCString &, const QCStringList &); +static bool handleDef(const QCString &, const QCStringList &); +static bool handleOverload(const QCString &, const QCStringList &); +static bool handleEnum(const QCString &, const QCStringList &); +static bool handleDefGroup(const QCString &, const QCStringList &); +static bool handleAddToGroup(const QCString &, const QCStringList &); +static bool handleWeakGroup(const QCString &, const QCStringList &); +static bool handleNamespace(const QCString &, const QCStringList &); +static bool handlePackage(const QCString &, const QCStringList &); +static bool handleClass(const QCString &, const QCStringList &); +static bool handleHeaderFile(const QCString &, const QCStringList &); +static bool handleProtocol(const QCString &, const QCStringList &); +static bool handleCategory(const QCString &, const QCStringList &); +static bool handleUnion(const QCString &, const QCStringList &); +static bool handleStruct(const QCString &, const QCStringList &); +static bool handleInterface(const QCString &, const QCStringList &); +static bool handleIdlException(const QCString &, const QCStringList &); +static bool handlePage(const QCString &, const QCStringList &); +static bool handleMainpage(const QCString &, const QCStringList &); +static bool handleFile(const QCString &, const QCStringList &); +static bool handleDir(const QCString &, const QCStringList &); +static bool handleExample(const QCString &, const QCStringList &); +static bool handleDetails(const QCString &, const QCStringList &); +static bool handleName(const QCString &, const QCStringList &); +static bool handleTodo(const QCString &, const QCStringList &); +static bool handleTest(const QCString &, const QCStringList &); +static bool handleBug(const QCString &, const QCStringList &); +static bool handleSubpage(const QCString &s, const QCStringList &); +static bool handleDeprecated(const QCString &, const QCStringList &); +static bool handleXRefItem(const QCString &, const QCStringList &); +static bool handleRelated(const QCString &, const QCStringList &); +static bool handleRelatedAlso(const QCString &, const QCStringList &); +static bool handleMemberOf(const QCString &, const QCStringList &); +static bool handleRefItem(const QCString &, const QCStringList &); +static bool handleSection(const QCString &, const QCStringList &); +static bool handleAnchor(const QCString &, const QCStringList &); +static bool handleCite(const QCString &, const QCStringList &); +static bool handleFormatBlock(const QCString &, const QCStringList &); +static bool handleAddIndex(const QCString &, const QCStringList &); +static bool handleIf(const QCString &, const QCStringList &); +static bool handleIfNot(const QCString &, const QCStringList &); +static bool handleElseIf(const QCString &, const QCStringList &); +static bool handleElse(const QCString &, const QCStringList &); +static bool handleEndIf(const QCString &, const QCStringList &); +static bool handleIngroup(const QCString &, const QCStringList &); +static bool handleNoSubGrouping(const QCString &, const QCStringList &); +static bool handleShowInitializer(const QCString &, const QCStringList &); +static bool handleHideInitializer(const QCString &, const QCStringList &); +static bool handleCallgraph(const QCString &, const QCStringList &); +static bool handleHideCallgraph(const QCString &, const QCStringList &); +static bool handleCallergraph(const QCString &, const QCStringList &); +static bool handleHideCallergraph(const QCString &, const QCStringList &); +static bool handleReferencedByRelation(const QCString &, const QCStringList &); +static bool handleHideReferencedByRelation(const QCString &, const QCStringList &); +static bool handleReferencesRelation(const QCString &, const QCStringList &); +static bool handleHideReferencesRelation(const QCString &, const QCStringList &); +static bool handleInternal(const QCString &, const QCStringList &); +static bool handleLineBr(const QCString &, const QCStringList &); +static bool handleStatic(const QCString &, const QCStringList &); +static bool handlePure(const QCString &, const QCStringList &); +static bool handlePrivate(const QCString &, const QCStringList &); +static bool handlePrivateSection(const QCString &, const QCStringList &); +static bool handleProtected(const QCString &, const QCStringList &); +static bool handleProtectedSection(const QCString &, const QCStringList &); +static bool handlePublic(const QCString &s, const QCStringList &); +static bool handlePublicSection(const QCString &s, const QCStringList &); +static bool handleToc(const QCString &s, const QCStringList &); +static bool handleInherit(const QCString &, const QCStringList &); +static bool handleExtends(const QCString &, const QCStringList &); +static bool handleCopyDoc(const QCString &, const QCStringList &); +static bool handleCopyBrief(const QCString &, const QCStringList &); +static bool handleCopyDetails(const QCString &, const QCStringList &); +static bool handleParBlock(const QCString &, const QCStringList &); +static bool handleEndParBlock(const QCString &, const QCStringList &); +static bool handleParam(const QCString &, const QCStringList &); +static bool handleRetval(const QCString &, const QCStringList &); + +typedef bool (*DocCmdFunc)(const QCString &name, const QCStringList &optList); struct DocCmdMap { @@ -214,6 +218,10 @@ static DocCmdMap docCmdMap[] = { "hidecallgraph", &handleHideCallgraph, FALSE }, { "callergraph", &handleCallergraph, FALSE }, { "hidecallergraph", &handleHideCallergraph, FALSE }, + { "showrefby", &handleReferencedByRelation, FALSE }, + { "hiderefby", &handleHideReferencedByRelation, FALSE }, + { "showrefs", &handleReferencesRelation, FALSE }, + { "hiderefs", &handleHideReferencesRelation, FALSE }, { "internal", &handleInternal, TRUE }, { "_linebr", &handleLineBr, FALSE }, { "static", &handleStatic, FALSE }, @@ -548,7 +556,7 @@ static void addXRefItem(const char *listName,const char *itemTitle, if (docEntry->sli) { QListIterator<ListItemInfo> slii(*docEntry->sli); - for (slii.toFirst();(lii=slii.current());++slii) + for (slii.toLast();(lii=slii.current());--slii) { if (qstrcmp(lii->type,listName)==0) { @@ -563,14 +571,7 @@ static void addXRefItem(const char *listName,const char *itemTitle, RefItem *item = refList->getRefItem(lii->itemId); ASSERT(item!=0); item->text += " <p>"; - if (Doxygen::markdownSupport) - { - item->text += processMarkdown(yyFileName,yyLineNr,current,outputXRef); - } - else - { - item->text += outputXRef; - } + item->text += outputXRef; //printf("%s: text +=%s\n",listName,item->text.data()); } else // new item @@ -585,18 +586,11 @@ static void addXRefItem(const char *listName,const char *itemTitle, sprintf(anchorLabel,"_%s%06d",listName,itemId); RefItem *item = refList->getRefItem(itemId); ASSERT(item!=0); - if (Doxygen::markdownSupport) - { - item->text = processMarkdown(yyFileName,yyLineNr,current,outputXRef); - } - else - { - item->text = outputXRef; - } + item->text = outputXRef; item->listAnchor = anchorLabel; docEntry->addSpecialListItem(listName,itemId); QCString cmdString; - cmdString.sprintf("\\xrefitem %s %d.",listName,itemId); + cmdString.sprintf(" \\xrefitem %s %d.",listName,itemId); if (inBody) { docEntry->inbodyDocs += cmdString; @@ -702,7 +696,13 @@ static void addSection() static void addCite() { - Doxygen::citeDict->insert(yytext); + QCString name=yytext; + if (yytext[0] =='"') + { + name=yytext+1; + name=name.left(yyleng-2); + } + Doxygen::citeDict->insert(name.data()); } //----------------------------------------------------------------------------- @@ -934,7 +934,9 @@ HR [hH][rR] PARA [pP][aA][rR][aA] CODE [cC][oO][dD][eE] CAPTION [cC][aA][pP][tT][iI][oO][nN] -DETAILEDHTML {PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA} +CENTER [cC][eE][nN][tT][eE][rR] +DIV [dD][iI][vV] +DETAILEDHTML {CENTER}|{DIV}|{PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA} DETAILEDHTMLOPT {CODE} BN [ \t\n\r] BL [ \t\r]*"\n" @@ -949,9 +951,9 @@ 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\-]* -CITESCHAR [a-z_A-Z0-9\x80-\xFF] -CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/]* -CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)* +CITESCHAR [a-z_A-Z0-9\x80-\xFF\-\?] +CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/\?]* +CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*|"\""{CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*"\"" SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME "$"?(({ID}?{BN}*("::"|"."){BN}*)*)((~{BN}*)?{ID}) TMPLSPEC "<"{BN}*[^>]+{BN}*">" @@ -1003,6 +1005,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" %x CiteLabel %x CopyDoc %x GuardExpr +%x CdataSection %% @@ -1018,7 +1021,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" * words and whitespace and other characters (#,?!, etc). * grouping commands (e.g. @{ and @}) * language switch (e.g. \~english or \~). - * mail address (e.g. dimitri@stack.nl). + * mail address (e.g. doxygen@gmail.com). * quoted text, such as "foo@bar" * XML commands, <summary></summary><remarks></remarks> */ @@ -1060,10 +1063,13 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(yytext); } <Comment>"</summary>" { // start of a .NET XML style detailed description + setOutput(OutputBrief); addOutput(yytext); setOutput(OutputDoc); } <Comment>"</remarks>" { // end of a brief or detailed description + + setOutput(OutputDoc); addOutput(yytext); } <Comment>"<"{CAPTION}{ATTR}">" { @@ -1092,24 +1098,42 @@ RCSTAG "$"{ID}":"[^\n$]+"$" insidePre=FALSE; addOutput(yytext); } -<Comment>{RCSTAG} { // RCS tag which end a brief description - setOutput(OutputDoc); - REJECT; - } -<Comment>"<!--" { - BEGIN(HtmlComment); - } +<Comment>{RCSTAG} { // RCS tag which end a brief description + setOutput(OutputDoc); + REJECT; + } +<Comment>"<!--" { + BEGIN(HtmlComment); + } +<Comment>"<!\[CDATA\[" { + BEGIN(CdataSection); + } <Comment>{B}*{CMD}"endinternal"{B}* { - addOutput("\\endinternal "); + addOutput(" \\endinternal "); if (!inInternalDocs) warn(yyFileName,yyLineNr, "found \\endinternal without matching \\internal" ); inInternalDocs = FALSE; } +<Comment>{B}*{CMD}[a-z_A-Z]+"{"[a-zA-Z_,:0-9\. ]*"}"{B}* | <Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command // the {B}* in the front was added for bug620924 - QCString cmdName = QCString(yytext).stripWhiteSpace().data()+1; + QCString fullMatch = QCString(yytext); + int idx = fullMatch.find('{'); + int idxEnd = fullMatch.find("}",idx+1); + QCString cmdName; + QCStringList optList; + if (idx == -1) // no options + { + cmdName = QCString(yytext).stripWhiteSpace().data()+1; // to remove {CMD} + } + else // options present + { + cmdName = fullMatch.left(idx).stripWhiteSpace().data()+1; // to remove {CMD} + QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); + optList = QCStringList::split(',',optStr); + } DocCmdMapper::Cmd *cmdPtr = DocCmdMapper::map(cmdName); if (cmdPtr) // special action is required { @@ -1123,7 +1147,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" setOutput(OutputDoc); } //if (i>0) addOutput(QCString(yytext).left(i)); // removed for bug 689341 - if (cmdPtr->func && cmdPtr->func(cmdName)) + if (cmdPtr->func && cmdPtr->func(cmdName, optList)) { // implicit split of the comment block into two // entries. Restart the next block at the start @@ -1329,6 +1353,24 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <HtmlComment>. { // ignore every else } +<CdataSection>"\]\]>" { + BEGIN( Comment ); + } +<CdataSection>{DOCNL} { + addOutput('\n'); + if (*yytext=='\n') yyLineNr++; + } +<CdataSection>[<>&] { // the special XML characters for iwhich the CDATA section is especially used + addOutput('\\'); + addOutput(*yytext); + } +<CdataSection>[^\\\n\]<>&]+ { + addOutput(yytext); + } +<CdataSection>. { + addOutput(*yytext); + } + /* -------------- Rules for handling formulas ---------------- */ <ReadFormulaShort>{CMD}"f$" { // end of inline formula @@ -1355,7 +1397,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" formulaText+=*yytext; yyLineNr++; } -<ReadFormulaLong,ReadFormulaShort>. { // any othe character +<ReadFormulaLong,ReadFormulaShort>. { // any other character formulaText+=*yytext; } @@ -1517,14 +1559,16 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (*yytext=='\n') yyLineNr++; BEGIN( Comment ); } +<GroupDocArg1>. { // ignore other stuff + } <GroupDocArg2>"\\"{B}*"\n" { // line continuation yyLineNr++; addOutput('\n'); } -<GroupDocArg2>[^\n\\\*]+ { // title (stored in type) +<GroupDocArg2>[^\n\*]+ { // title (stored in type) current->type += yytext; current->type = current->type.stripWhiteSpace(); - } + } <GroupDocArg2>{DOCNL} { if ( current->groupDocType==Entry::GROUPDOC_NORMAL && current->type.isEmpty() @@ -1561,28 +1605,24 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <PageDocArg1>. { // ignore other stuff } <PageDocArg2>.*"\n" { // second argument; page title - yyLineNr++; - current->args = yytext; + yyLineNr++; + // bug 748927 + QCString tmp = yytext; + tmp = substitute(substitute(tmp,"@<","<"),"@>",">"); + tmp = substitute(substitute(tmp,"\\<","<"),"\\>",">"); + current->args = tmp; addOutput('\n'); BEGIN( Comment ); } /* --------- handle arguments of the param command ------------ */ <ParamArg1>{ID}/{B}*"," { - if (yytext[0]=='_' && Config_getBool(MARKDOWN_SUPPORT)) - { - addOutput('\\'); - } addOutput(yytext); } <ParamArg1>"," { addOutput(" , "); } <ParamArg1>{ID} { - if (yytext[0]=='_' && Config_getBool(MARKDOWN_SUPPORT)) - { - addOutput('\\'); - } addOutput(yytext); BEGIN( Comment ); } @@ -1716,7 +1756,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the section/subsection/.. commands ------- */ -<SectionLabel>{LABELID} { // first argyment +<SectionLabel>{LABELID} { // first argument g_sectionLabel=yytext; addOutput(yytext); g_sectionTitle.resize(0); @@ -1860,10 +1900,10 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(*yytext); } <FormatBlock><<EOF>> { - QCString endTag = "@end"+blockName; + QCString endTag = "end"+blockName; if (blockName=="startuml") endTag="enduml"; warn(yyFileName,yyLineNr, - "reached end of comment while inside a @%s block; check for missing @%s tag!", + "reached end of comment while inside a \\%s block; check for missing \\%s tag!", blockName.data(),endTag.data() ); yyterminate(); @@ -1944,7 +1984,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (guards.isEmpty()) { warn(yyFileName,yyLineNr, - "found @endif without matching start command"); + "found \\endif without matching start command"); } else { @@ -1962,7 +2002,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (guards.isEmpty()) { warn(yyFileName,yyLineNr, - "found @else without matching start command"); + "found \\else without matching start command"); } else { @@ -1979,7 +2019,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (guards.isEmpty()) { warn(yyFileName,yyLineNr, - "found @elseif without matching start command"); + "found \\elseif without matching start command"); } else { @@ -2050,7 +2090,6 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } } <SkipInternal>[@\\]"endinternal"[ \t]* { - addOutput("\\endinternal "); BEGIN(Comment); } <SkipInternal>[^ \\@\n]+ { // skip non-special characters @@ -2221,7 +2260,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of the cite command ------- */ -<CiteLabel>{CITEID} { // found argyment +<CiteLabel>{CITEID} { // found argument addCite(); addOutput(yytext); BEGIN(Comment); @@ -2267,14 +2306,14 @@ RCSTAG "$"{ID}":"[^\n$]+"$" //---------------------------------------------------------------------------- -static bool handleBrief(const QCString &) +static bool handleBrief(const QCString &, const QCStringList &) { //printf("handleBrief\n"); setOutput(OutputBrief); return FALSE; } -static bool handleFn(const QCString &) +static bool handleFn(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::MEMBERDOC_SEC); functionProto.resize(0); @@ -2283,7 +2322,7 @@ static bool handleFn(const QCString &) return stop; } -static bool handleDef(const QCString &) +static bool handleDef(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::DEFINEDOC_SEC); functionProto.resize(0); @@ -2291,21 +2330,21 @@ static bool handleDef(const QCString &) return stop; } -static bool handleOverload(const QCString &) +static bool handleOverload(const QCString &, const QCStringList &) { functionProto.resize(0); BEGIN(OverloadParam); return FALSE; } -static bool handleEnum(const QCString &) +static bool handleEnum(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::ENUMDOC_SEC); BEGIN(EnumDocArg1); return stop; } -static bool handleDefGroup(const QCString &) +static bool handleDefGroup(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_NORMAL; @@ -2313,7 +2352,7 @@ static bool handleDefGroup(const QCString &) return stop; } -static bool handleAddToGroup(const QCString &) +static bool handleAddToGroup(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_ADD; @@ -2321,7 +2360,7 @@ static bool handleAddToGroup(const QCString &) return stop; } -static bool handleWeakGroup(const QCString &) +static bool handleWeakGroup(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_WEAK; @@ -2329,83 +2368,83 @@ static bool handleWeakGroup(const QCString &) return stop; } -static bool handleNamespace(const QCString &) +static bool handleNamespace(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::NAMESPACEDOC_SEC); BEGIN( NameSpaceDocArg1 ); return stop; } -static bool handlePackage(const QCString &) +static bool handlePackage(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::PACKAGEDOC_SEC); BEGIN( PackageDocArg1 ); return stop; } -static bool handleClass(const QCString &) +static bool handleClass(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::CLASSDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleHeaderFile(const QCString &) +static bool handleHeaderFile(const QCString &, const QCStringList &) { BEGIN( ClassDocArg2 ); return FALSE; } -static bool handleProtocol(const QCString &) +static bool handleProtocol(const QCString &, const QCStringList &) { // Obj-C protocol bool stop=makeStructuralIndicator(Entry::PROTOCOLDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleCategory(const QCString &) +static bool handleCategory(const QCString &, const QCStringList &) { // Obj-C category bool stop=makeStructuralIndicator(Entry::CATEGORYDOC_SEC); BEGIN( CategoryDocArg1 ); return stop; } -static bool handleUnion(const QCString &) +static bool handleUnion(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::UNIONDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleStruct(const QCString &) +static bool handleStruct(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::STRUCTDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleInterface(const QCString &) +static bool handleInterface(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::INTERFACEDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handleIdlException(const QCString &) +static bool handleIdlException(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::EXCEPTIONDOC_SEC); BEGIN( ClassDocArg1 ); return stop; } -static bool handlePage(const QCString &) +static bool handlePage(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::PAGEDOC_SEC); BEGIN( PageDocArg1 ); return stop; } -static bool handleMainpage(const QCString &) +static bool handleMainpage(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::MAINPAGEDOC_SEC); if (!stop) @@ -2416,7 +2455,7 @@ static bool handleMainpage(const QCString &) return stop; } -static bool handleFile(const QCString &) +static bool handleFile(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::FILEDOC_SEC); if (!stop) @@ -2427,7 +2466,7 @@ static bool handleFile(const QCString &) return stop; } -static bool handleParam(const QCString &) +static bool handleParam(const QCString &, const QCStringList &) { // we need process param and retval arguments to escape leading underscores in case of // markdown processing, see bug775493 @@ -2436,14 +2475,14 @@ static bool handleParam(const QCString &) return FALSE; } -static bool handleRetval(const QCString &) +static bool handleRetval(const QCString &, const QCStringList &) { addOutput("@retval "); BEGIN( ParamArg1 ); return FALSE; } -static bool handleDir(const QCString &) +static bool handleDir(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::DIRDOC_SEC); if (!stop) current->name = yyFileName; @@ -2451,15 +2490,30 @@ static bool handleDir(const QCString &) return stop; } -static bool handleExample(const QCString &) +static bool handleExample(const QCString &cmd, const QCStringList &optList) { - bool stop=makeStructuralIndicator(Entry::EXAMPLE_SEC); + Entry::Sections section=Entry::EXAMPLE_SEC; + QCStringList::ConstIterator it; + for ( it = optList.begin(); it != optList.end(); ++it ) + { + QCString opt = (*it).stripWhiteSpace().lower(); + if (opt=="lineno") + { + section=Entry::EXAMPLE_LINENO_SEC; + } + else + { + warn(yyFileName,yyLineNr, + "unsupported option '%s' for command '\\%s'",qPrint(opt),qPrint(cmd)); + } + } + bool stop=makeStructuralIndicator(section); if (!stop) current->name = yyFileName; BEGIN( FileDocArg1 ); return stop; } -static bool handleDetails(const QCString &) +static bool handleDetails(const QCString &, const QCStringList &) { if (inContext!=OutputBrief) { @@ -2470,7 +2524,7 @@ static bool handleDetails(const QCString &) return FALSE; } -static bool handleName(const QCString &) +static bool handleName(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::MEMBERGRP_SEC); if (!stop) @@ -2485,7 +2539,7 @@ static bool handleName(const QCString &) return stop; } -static bool handleTodo(const QCString &) +static bool handleTodo(const QCString &, const QCStringList &) { newXRefKind = XRef_Todo; setOutput(OutputXRef); @@ -2493,7 +2547,7 @@ static bool handleTodo(const QCString &) return FALSE; } -static bool handleTest(const QCString &) +static bool handleTest(const QCString &, const QCStringList &) { newXRefKind = XRef_Test; setOutput(OutputXRef); @@ -2501,7 +2555,7 @@ static bool handleTest(const QCString &) return FALSE; } -static bool handleBug(const QCString &) +static bool handleBug(const QCString &, const QCStringList &) { newXRefKind = XRef_Bug; setOutput(OutputXRef); @@ -2509,7 +2563,7 @@ static bool handleBug(const QCString &) return FALSE; } -static bool handleDeprecated(const QCString &) +static bool handleDeprecated(const QCString &, const QCStringList &) { newXRefKind = XRef_Deprecated; setOutput(OutputXRef); @@ -2517,14 +2571,14 @@ static bool handleDeprecated(const QCString &) return FALSE; } -static bool handleXRefItem(const QCString &) +static bool handleXRefItem(const QCString &, const QCStringList &) { newXRefKind = XRef_Item; BEGIN(XRefItemParam1); return FALSE; } -static bool handleParBlock(const QCString &) +static bool handleParBlock(const QCString &, const QCStringList &) { if (g_insideParBlock) { @@ -2541,7 +2595,7 @@ static bool handleParBlock(const QCString &) return FALSE; } -static bool handleEndParBlock(const QCString &) +static bool handleEndParBlock(const QCString &, const QCStringList &) { if (!g_insideParBlock) { @@ -2554,34 +2608,50 @@ static bool handleEndParBlock(const QCString &) return FALSE; } -static bool handleRelated(const QCString &) +static bool handleRelated(const QCString &, const QCStringList &) { + if (!current->relates.isEmpty()) + { + warn(yyFileName,yyLineNr, + "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition"); + } + current->relatesType = Simple; BEGIN(RelatesParam1); return FALSE; } -static bool handleRelatedAlso(const QCString &) +static bool handleRelatedAlso(const QCString &, const QCStringList &) { + if (!current->relates.isEmpty()) + { + warn(yyFileName,yyLineNr, + "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition"); + } current->relatesType = Duplicate; BEGIN(RelatesParam1); return FALSE; } -static bool handleMemberOf(const QCString &) +static bool handleMemberOf(const QCString &, const QCStringList &) { + if (!current->relates.isEmpty()) + { + warn(yyFileName,yyLineNr, + "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition"); + } current->relatesType = MemberOf; BEGIN(RelatesParam1); return FALSE; } -static bool handleRefItem(const QCString &) +static bool handleRefItem(const QCString &, const QCStringList &) { addOutput("@refitem "); BEGIN(LineParam); return FALSE; } -static bool handleSection(const QCString &s) +static bool handleSection(const QCString &s, const QCStringList &) { setOutput(OutputDoc); addOutput("@"+s+" "); @@ -2593,7 +2663,7 @@ static bool handleSection(const QCString &s) return FALSE; } -static bool handleSubpage(const QCString &s) +static bool handleSubpage(const QCString &s, const QCStringList &) { if (current->section!=Entry::EMPTY_SEC && current->section!=Entry::PAGEDOC_SEC && @@ -2613,14 +2683,14 @@ static bool handleSubpage(const QCString &s) return FALSE; } -static bool handleAnchor(const QCString &s) +static bool handleAnchor(const QCString &s, const QCStringList &) { addOutput("@"+s+" "); BEGIN(AnchorLabel); return FALSE; } -static bool handleCite(const QCString &s) +static bool handleCite(const QCString &s, const QCStringList &) { if (!g_spaceBeforeCmd.isEmpty()) { @@ -2632,24 +2702,31 @@ static bool handleCite(const QCString &s) return FALSE; } -static bool handleFormatBlock(const QCString &s) +static bool handleFormatBlock(const QCString &s, const QCStringList &optList) { - addOutput("@"+s+" "); - //printf("handleFormatBlock(%s)\n",s.data()); + if (optList.isEmpty()) + { + addOutput("@"+s+" "); + } + else + { + addOutput("@"+s+"{"+optList.join(",")+"} "); + } + //printf("handleFormatBlock(%s) with option(%s)\n",s.data(),opt.data()); blockName=s; g_commentCount=0; BEGIN(FormatBlock); return FALSE; } -static bool handleAddIndex(const QCString &) +static bool handleAddIndex(const QCString &, const QCStringList &) { addOutput("@addindex "); BEGIN(LineParam); return FALSE; } -static bool handleIf(const QCString &) +static bool handleIf(const QCString &, const QCStringList &) { enabledSectionFound=FALSE; guardType = Guard_If; @@ -2658,7 +2735,7 @@ static bool handleIf(const QCString &) return FALSE; } -static bool handleIfNot(const QCString &) +static bool handleIfNot(const QCString &, const QCStringList &) { enabledSectionFound=FALSE; guardType = Guard_IfNot; @@ -2667,7 +2744,7 @@ static bool handleIfNot(const QCString &) return FALSE; } -static bool handleElseIf(const QCString &) +static bool handleElseIf(const QCString &, const QCStringList &) { if (guards.isEmpty()) { @@ -2682,7 +2759,7 @@ static bool handleElseIf(const QCString &) return FALSE; } -static bool handleElse(const QCString &) +static bool handleElse(const QCString &, const QCStringList &) { if (guards.isEmpty()) { @@ -2696,7 +2773,7 @@ static bool handleElse(const QCString &) return FALSE; } -static bool handleEndIf(const QCString &) +static bool handleEndIf(const QCString &, const QCStringList &) { if (guards.isEmpty()) { @@ -2717,56 +2794,80 @@ static bool handleEndIf(const QCString &) return FALSE; } -static bool handleIngroup(const QCString &) +static bool handleIngroup(const QCString &, const QCStringList &) { inGroupParamFound=FALSE; BEGIN( InGroupParam ); return FALSE; } -static bool handleNoSubGrouping(const QCString &) +static bool handleNoSubGrouping(const QCString &, const QCStringList &) { current->subGrouping = FALSE; return FALSE; } -static bool handleShowInitializer(const QCString &) +static bool handleShowInitializer(const QCString &, const QCStringList &) { current->initLines = 100000; // ON return FALSE; } -static bool handleHideInitializer(const QCString &) +static bool handleHideInitializer(const QCString &, const QCStringList &) { current->initLines = 0; // OFF return FALSE; } -static bool handleCallgraph(const QCString &) +static bool handleCallgraph(const QCString &, const QCStringList &) { current->callGraph = TRUE; // ON return FALSE; } -static bool handleHideCallgraph(const QCString &) +static bool handleHideCallgraph(const QCString &, const QCStringList &) { current->callGraph = FALSE; // OFF return FALSE; } -static bool handleCallergraph(const QCString &) +static bool handleCallergraph(const QCString &, const QCStringList &) { current->callerGraph = TRUE; // ON return FALSE; } -static bool handleHideCallergraph(const QCString &) +static bool handleHideCallergraph(const QCString &, const QCStringList &) { current->callerGraph = FALSE; // OFF return FALSE; } -static bool handleInternal(const QCString &) +static bool handleReferencedByRelation(const QCString &, const QCStringList &) +{ + current->referencedByRelation = TRUE; // ON + return FALSE; +} + +static bool handleHideReferencedByRelation(const QCString &, const QCStringList &) +{ + current->referencedByRelation = FALSE; // OFF + return FALSE; +} + +static bool handleReferencesRelation(const QCString &, const QCStringList &) +{ + current->referencesRelation = TRUE; // ON + return FALSE; +} + +static bool handleHideReferencesRelation(const QCString &, const QCStringList &) +{ + current->referencesRelation = FALSE; // OFF + return FALSE; +} + +static bool handleInternal(const QCString &, const QCStringList &) { if (!Config_getBool(INTERNAL_DOCS)) { @@ -2782,91 +2883,141 @@ static bool handleInternal(const QCString &) else { // re-enabled for bug640828 - addOutput("\\internal "); + addOutput(" \\internal "); inInternalDocs = TRUE; } return FALSE; } -static bool handleLineBr(const QCString &) +static bool handleLineBr(const QCString &, const QCStringList &) { addOutput('\n'); return FALSE; } -static bool handleStatic(const QCString &) +static bool handleStatic(const QCString &, const QCStringList &) { endBrief(); current->stat = TRUE; return FALSE; } -static bool handlePure(const QCString &) +static bool handlePure(const QCString &, const QCStringList &) { endBrief(); current->virt = Pure; return FALSE; } -static bool handlePrivate(const QCString &) +static bool handlePrivate(const QCString &, const QCStringList &) { current->protection = Private; return FALSE; } -static bool handlePrivateSection(const QCString &) +static bool handlePrivateSection(const QCString &, const QCStringList &) { current->protection = protection = Private; return FALSE; } -static bool handleProtected(const QCString &) +static bool handleProtected(const QCString &, const QCStringList &) { current->protection = Protected; return FALSE; } -static bool handleProtectedSection(const QCString &) +static bool handleProtectedSection(const QCString &, const QCStringList &) { current->protection = protection = Protected ; return FALSE; } -static bool handlePublic(const QCString &) +static bool handlePublic(const QCString &, const QCStringList &) { current->protection = Public; return FALSE; } -static bool handlePublicSection(const QCString &) +static bool handlePublicSection(const QCString &, const QCStringList &) { current->protection = protection = Public; return FALSE; } -static bool handleToc(const QCString &) +static bool handleToc(const QCString &, const QCStringList &optList) { if (current->section==Entry::PAGEDOC_SEC || current->section==Entry::MAINPAGEDOC_SEC) { - current->stat=TRUE; // we 'abuse' stat to pass whether or the TOC is enabled + QCStringList::ConstIterator it; + for ( it = optList.begin(); it != optList.end(); ++it ) + { + QCString opt = (*it).stripWhiteSpace().lower(); + char dum; + int level = 5; + int i = opt.find(':'); + if (i>0) // found ':' but not on position 0 what would mean just a level + { + if (sscanf(opt.right(opt.length() - i - 1).data(),"%d%c",&level,&dum) != 1) + { + warn(yyFileName,yyLineNr,"Unknown option:level specified with \\tableofcontents: `%s'", (*it).stripWhiteSpace().data()); + opt = ""; + } + else + { + level = (level > 5 ? 5 : level); + level = (level <= 0 ? 5 : level); + opt = opt.left(i).stripWhiteSpace(); + } + } + if (!opt.isEmpty()) + { + if (opt == "html") + { + current->localToc.enableHtml(level); + } + else if (opt == "latex") + { + current->localToc.enableLatex(level); + } + else if (opt == "xml") + { + current->localToc.enableXml(level); + } + else if (opt == "docbook") + { + current->localToc.enableDocbook(level); + } + else + { + warn(yyFileName,yyLineNr,"Unknown option specified with \\tableofcontents: `%s'", (*it).stripWhiteSpace().data()); + } + } + } + if (current->localToc.nothingEnabled()) + { + // for backward compatibility + current->localToc.enableHtml(5); + current->localToc.enableXml(5); + } } return FALSE; } -static bool handleInherit(const QCString &) +static bool handleInherit(const QCString &, const QCStringList &) { BEGIN(InheritParam); return FALSE; } -static bool handleExtends(const QCString &) +static bool handleExtends(const QCString &, const QCStringList &) { BEGIN(ExtendsParam); return FALSE; } -static bool handleCopyBrief(const QCString &) +static bool handleCopyBrief(const QCString &, const QCStringList &) { if (current->brief.isEmpty() && current->doc.isEmpty()) { // if we don't have a brief or detailed description yet, @@ -2883,7 +3034,7 @@ static bool handleCopyBrief(const QCString &) return FALSE; } -static bool handleCopyDetails(const QCString &) +static bool handleCopyDetails(const QCString &, const QCStringList &) { setOutput(OutputDoc); if (!g_spaceBeforeCmd.isEmpty()) @@ -2895,7 +3046,7 @@ static bool handleCopyDetails(const QCString &) return FALSE; } -static bool handleCopyDoc(const QCString &) +static bool handleCopyDoc(const QCString &, const QCStringList &) { setOutput(OutputBrief); if (!g_spaceBeforeCmd.isEmpty()) @@ -2943,7 +3094,26 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, langParser = parser; current = curEntry; if (comment.isEmpty()) return FALSE; // avoid empty strings - inputString = comment; + if (Doxygen::markdownSupport) + { + inputString = processMarkdown(fileName,lineNr,NULL,comment); + const char *p = inputString.data(); + if (p) + { + while (*p==' ') p++; // skip over spaces + while (*p=='\n') p++; // skip over newlines + if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br> + } + if (p>inputString.data()) + { + // strip part of the input + inputString = inputString.mid(p-inputString.data()); + } + } + else + { + inputString = comment; + } inputString.append(" "); inputPosition = position; yyLineNr = lineNr; @@ -2970,7 +3140,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, } Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\n" - "input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(comment) + "input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(inputString) ); commentscanYYrestart( commentscanYYin ); @@ -3008,15 +3178,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, openGroup(current,yyFileName,yyLineNr); } - if (Doxygen::markdownSupport) - { - current->brief = processMarkdown(fileName,lineNr,current,current->brief); - current->doc = processMarkdown(fileName,lineNr,current,current->doc); - current->inbodyDocs = processMarkdown(fileName,lineNr,current,current->inbodyDocs); - } - - Debug::print(Debug::CommentScan,0, - "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n===========\n", + Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\noutput=[\n" + "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n]\n===========\n", + qPrint(fileName),lineNr, current->briefLine,qPrint(current->brief), current->docLine,qPrint(current->doc), current->inbodyLine,qPrint(current->inbodyDocs) diff --git a/src/condparser.cpp b/src/condparser.cpp index 6c5d787..74e26bc 100644 --- a/src/condparser.cpp +++ b/src/condparser.cpp @@ -100,9 +100,10 @@ static bool isAlpha(const char c) return (c>='A' && c<='Z') || (c>='a' && c<='z') || c=='_'; } -static bool isAlphaNum(const char c) +static bool isAlphaNumSpec(const char c) { - return isAlpha(c) || (c>='0' && c<='9'); + return isAlpha(c) || (c>='0' && c<='9') || c=='-' || c=='.' || + (((unsigned char)c)>=0x80 && ((unsigned char)c)<=0xFF); } /** @@ -170,7 +171,7 @@ void CondParser::getToken() if (isAlpha(*m_e)) { m_tokenType = VARIABLE; - while (isAlphaNum(*m_e)) + while (isAlphaNumSpec(*m_e)) { m_token += *m_e++; } @@ -283,7 +284,7 @@ bool CondParser::parseVar() } /** - * evaluate an operator for given valuess + * evaluate an operator for given values */ bool CondParser::evalOperator(int opId, bool lhs, bool rhs) { diff --git a/src/config.h b/src/config.h index e86e950..102774e 100644 --- a/src/config.h +++ b/src/config.h @@ -51,6 +51,11 @@ namespace Config */ void writeTemplate(FTextStream &t,bool shortList,bool updateOnly=FALSE); + /*! Writes a the differences between the current configuration and the + * template configuration to stream \a t. + */ + void compareDoxyfile(FTextStream &t); + /*! Parses a configuration file with name \a fn. * \returns TRUE if successful, FALSE if the file could not be * opened or read. @@ -61,7 +66,7 @@ namespace Config * and replaces environment variables. * \param clearHeaderAndFooter set to TRUE when writing header and footer templates. */ - void postProcess(bool clearHeaderAndFooter); + void postProcess(bool clearHeaderAndFooter, bool compare = FALSE); /*! Check the validity of the parsed options and correct or warn the user where needed. */ void checkAndCorrect(); diff --git a/src/config.xml b/src/config.xml index 2c9212a..13ae663 100644 --- a/src/config.xml +++ b/src/config.xml @@ -4,13 +4,13 @@ <![CDATA[ /* * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -41,28 +41,28 @@ Each statement consists of a \c TAG_NAME written in capitals, followed by the equal sign (<code>=</code>) and one or more values. If the same tag is assigned more than once, the last assignment overwrites any earlier assignment. For tags that take a list as their argument, -the <code>+=</code> operator can be used instead of <code>=</code> to append -new values to the list. Values are sequences of non-blanks. If the value should +the <code>+=</code> operator can be used instead of <code>=</code> to append +new values to the list. Values are sequences of non-blanks. If the value should contain one or more blanks it must be surrounded by quotes (<code>"..."</code>). Multiple lines can be concatenated by inserting a backslash (\c \\) -as the last character of a line. Environment variables can be expanded +as the last character of a line. Environment variables can be expanded using the pattern <code>\$(ENV_VARIABLE_NAME)</code>. You can also include part of a configuration file from another configuration file using a <code>\@INCLUDE</code> tag as follows: \verbatim @INCLUDE = config_file_name -\endverbatim -The include file is searched in the current working directory. You can +\endverbatim +The include file is searched in the current working directory. You can also specify a list of directories that should be searched before looking -in the current working directory. Do this by putting a <code>\@INCLUDE_PATH</code> tag +in the current working directory. Do this by putting a <code>\@INCLUDE_PATH</code> tag with these paths before the <code>\@INCLUDE</code> tag, e.g.: \verbatim @INCLUDE_PATH = my_config_dir \endverbatim The configuration options can be divided into several categories. -Below is an alphabetical index of the tags that are recognized +Below is an alphabetical index of the tags that are recognized followed by the descriptions of the tags grouped by category. ]]> </docs> @@ -91,14 +91,14 @@ Values that contain spaces should be placed between quotes (\" \"). <![CDATA[ \section config_examples Examples -Suppose you have a simple project consisting of two files: a source file +Suppose you have a simple project consisting of two files: a source file \c example.cc and a header file \c example.h. Then a minimal configuration file is as simple as: \verbatim INPUT = example.cc example.h \endverbatim -Assuming the example makes use of Qt classes and \c perl is located +Assuming the example makes use of Qt classes and \c perl is located in <code>/usr/bin</code>, a more realistic configuration file would be: \verbatim PROJECT_NAME = Example @@ -109,8 +109,8 @@ PERL_PATH = /usr/local/bin/perl SEARCHENGINE = NO \endverbatim -To generate the documentation for the -<a href="http://www.stack.nl/~dimitri/qdbttabular/index.html">QdbtTabular</a> package +To generate the documentation for the +<a href="https://sourceforge.net/projects/qdbttabular/">QdbtTabular</a> package I have used the following configuration file: \verbatim PROJECT_NAME = QdbtTabular @@ -125,7 +125,7 @@ SEARCHENGINE = YES \endverbatim To regenerate the Qt-1.44 documentation from the sources, you could use the -following config file: +following configuration file: \verbatim PROJECT_NAME = Qt OUTPUT_DIRECTORY = qt_docs @@ -160,7 +160,7 @@ INPUT = $(QTDIR)/doc \ $(QTDIR)/src/dialogs \ $(QTDIR)/src/tools FILE_PATTERNS = *.cpp *.h q*.doc -INCLUDE_PATH = $(QTDIR)/include +INCLUDE_PATH = $(QTDIR)/include RECURSIVE = YES \endverbatim @@ -212,7 +212,7 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='string' id='DOXYFILE_ENCODING' format='string' defval='UTF-8'> <docs> <![CDATA[ - This tag specifies the encoding used for all characters in the config file that + This tag specifies the encoding used for all characters in the configuration file that follow. The default is UTF-8 which is also the encoding used for all text before the first occurrence of this tag. Doxygen uses \c libiconv (or the iconv built into \c libc) for the transcoding. See https://www.gnu.org/software/libiconv/ for the list of @@ -224,8 +224,8 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ The \c PROJECT_NAME tag is a single word (or a sequence of words - surrounded by double-quotes, unless you are using Doxywizard) that should identify the project for which the - documentation is generated. This name is used in the title of most + surrounded by double-quotes, unless you are using Doxywizard) that should identify the project for which the + documentation is generated. This name is used in the title of most generated pages and in a few other places. ]]> </docs> @@ -242,9 +242,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='string' id='PROJECT_BRIEF' format='string' defval=''> <docs> <![CDATA[ - Using the \c PROJECT_BRIEF tag one can provide an optional one line description - for a project that appears at the top of each page and should give viewer - a quick idea about the purpose of the project. Keep the description short. + Using the \c PROJECT_BRIEF tag one can provide an optional one line description + for a project that appears at the top of each page and should give viewer + a quick idea about the purpose of the project. Keep the description short. ]]> </docs> </option> @@ -252,9 +252,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='string' id='PROJECT_LOGO' format='image' defval=''> <docs> <![CDATA[ - With the \c PROJECT_LOGO tag one can specify a logo or an icon that is - included in the documentation. The maximum height of the logo should not - exceed 55 pixels and the maximum width should not exceed 200 pixels. + With the \c PROJECT_LOGO tag one can specify a logo or an icon that is + included in the documentation. The maximum height of the logo should not + exceed 55 pixels and the maximum width should not exceed 200 pixels. Doxygen will copy the logo to the output directory. ]]> </docs> @@ -262,9 +262,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='string' id='OUTPUT_DIRECTORY' format='dir' defval=''> <docs> <![CDATA[ - The \c OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) - path into which the generated documentation will be written. - If a relative path is entered, it will be relative to the location + The \c OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) + path into which the generated documentation will be written. + If a relative path is entered, it will be relative to the location where doxygen was started. If left blank the current directory will be used. ]]> </docs> @@ -273,11 +273,11 @@ 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 - format and will distribute the generated files over these directories. + 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. + causes performance problems for the file system. ]]> </docs> </option> @@ -285,8 +285,8 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ If the \c ALLOW_UNICODE_NAMES tag is set to \c YES, - doxygen will allow non-ASCII characters to appear in the names of generated files. - If set to \c NO, non-ASCII characters will be escaped, for example _xE3_x81_x84 + doxygen will allow non-ASCII characters to appear in the names of generated files. + If set to \c NO, non-ASCII characters will be escaped, for example _xE3_x81_x84 will be used for Unicode U+3044. ]]> </docs> @@ -369,12 +369,12 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='REPEAT_BRIEF' defval='1'> <docs> <![CDATA[ - If the \c REPEAT_BRIEF tag is set to \c YES, doxygen will - prepend the brief description of a member or function before the detailed - description - <br>Note: + If the \c REPEAT_BRIEF tag is set to \c YES, doxygen will + prepend the brief description of a member or function before the detailed + description + <br>Note: If both \ref cfg_hide_undoc_members "HIDE_UNDOC_MEMBERS" and - \ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" are set to \c NO, the + \ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" are set to \c NO, the brief descriptions will be completely suppressed. ]]> </docs> @@ -388,7 +388,7 @@ Go to the <a href="commands.html">next</a> section or return to the stripped from the text and the result, after processing the whole list, is used as the annotated text. Otherwise, the brief description is used as-is. If left blank, the following values are used (`$name` is automatically replaced with the - name of the entity): + name of the entity): ]]> </docs> <value name='The $name class'/> @@ -406,7 +406,7 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='ALWAYS_DETAILED_SEC' defval='0'> <docs> <![CDATA[ - If the \c ALWAYS_DETAILED_SEC and \ref cfg_repeat_brief "REPEAT_BRIEF" tags + If the \c ALWAYS_DETAILED_SEC and \ref cfg_repeat_brief "REPEAT_BRIEF" tags are both set to \c YES then doxygen will generate a detailed section even if there is only a brief description. @@ -437,12 +437,12 @@ Go to the <a href="commands.html">next</a> section or return to the <![CDATA[ The \c STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. Stripping is - only done if one of the specified strings matches the left-hand part of the + only done if one of the specified strings matches the left-hand part of the path. The tag can be used to show relative paths in the file list. If left blank the directory from which doxygen is run is used as the path to strip. - <br>Note that you can specify absolute paths here, but also - relative paths, which will be relative from the directory where doxygen is + <br>Note that you can specify absolute paths here, but also + relative paths, which will be relative from the directory where doxygen is started. ]]> </docs> @@ -451,11 +451,11 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='list' id='STRIP_FROM_INC_PATH' format='string'> <docs> <![CDATA[ - The \c STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of + The \c STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the path mentioned in the documentation of a class, which tells - the reader which header file to include in order to use a class. + the reader which header file to include in order to use a class. If left blank only the name of the header file containing the class - definition is used. Otherwise one should specify the list of include paths that + definition is used. Otherwise one should specify the list of include paths that are normally passed to the compiler using the `-I` flag. ]]> </docs> @@ -474,7 +474,7 @@ Go to the <a href="commands.html">next</a> section or return to the <![CDATA[ If the \c JAVADOC_AUTOBRIEF tag is set to \c YES then doxygen will interpret the first line (until the first dot) of a Javadoc-style - comment as the brief description. If set to \c NO, the + comment as the brief description. If set to \c NO, the Javadoc-style will behave just like regular Qt-style comments (thus requiring an explicit \ref cmdbrief "\@brief" command for a brief description.) ]]> @@ -534,30 +534,54 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ This tag can be used to specify a number of aliases that act - as commands in the documentation. An alias has the form: + as commands in the documentation. An alias has the form: \verbatim name=value \endverbatim - For example adding + For example adding \verbatim - "sideeffect=@par Side Effects:\n" + "sideeffect=@par Side Effects:\n" \endverbatim will allow you to - put the command \c \\sideeffect (or \c \@sideeffect) in the documentation, which + put the command \c \\sideeffect (or \c \@sideeffect) in the documentation, which will result in a user-defined paragraph with heading "Side Effects:". You can put \ref cmdn "\\n"'s in the value part of an alias to insert newlines (in the resulting output). - You can put `^^` in the value part of an alias to insert a newline as if + You can put `^^` in the value part of an alias to insert a newline as if a physical newline was in the original file. ]]> </docs> + <docs doxyfile='0' documentation='0'> +<![CDATA[ + When you need a literal `{` or `}` or `,` in the value part of an alias you have to + escape them by means of a backslash, this can lead to conflicts with the + commands \c \\{ and \c \\} for these it is advised to use the version \c @{ and \c @} or + use a double escape (\c \\\\{ and \c \\\\}) +]]> + </docs> + <docs doxywizard='0' documentation='0'> +<![CDATA[ + When you need a literal `{` or `}` or `,` in the value part of an alias you have to + escape them by means of a backslash (\c \\), this can lead to conflicts with the + commands \c \\{ and \c \\} for these it is advised to use the version \c @{ and \c @} or + use a double escape (\c \\\\{ and \c \\\\}) +]]> + </docs> + <docs doxyfile='0' doxywizard='0'> +<![CDATA[ + When you need a literal `{` or `}` or `,` in the value part of an alias you have to + escape them by means of a backslash (`\`), this can lead to conflicts with the + commands \c \\{ and \c \\} for these it is advised to use the version \c @@{ and \c @@} or + use a double escape (\c \\\\{ and \c \\\\}) +]]> + </docs> </option> <option type='list' id='TCL_SUBST' format='string'> <docs> <![CDATA[ - This tag can be used to specify a number of word-keyword mappings (TCL only). - A mapping has the form <code>"name=value"</code>. For example adding - <code>"class=itcl::class"</code> will allow you to use the command class in the + This tag can be used to specify a number of word-keyword mappings (TCL only). + A mapping has the form <code>"name=value"</code>. For example adding + <code>"class=itcl::class"</code> will allow you to use the command class in the <code>itcl::class</code> meaning. ]]> </docs> @@ -565,10 +589,10 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='OPTIMIZE_OUTPUT_FOR_C' defval='0'> <docs> <![CDATA[ - Set the \c OPTIMIZE_OUTPUT_FOR_C tag to \c YES if your project consists - of C sources only. Doxygen will then generate output that is more tailored - for C. For instance, some of the names that are used will be different. - The list of all members will be omitted, etc. + Set the \c OPTIMIZE_OUTPUT_FOR_C tag to \c YES if your project consists + of C sources only. Doxygen will then generate output that is more tailored + for C. For instance, some of the names that are used will be different. + The list of all members will be omitted, etc. ]]> </docs> </option> @@ -576,16 +600,16 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ Set the \c OPTIMIZE_OUTPUT_JAVA tag to \c YES if your project consists of Java or - Python sources only. Doxygen will then generate output that is more tailored - for that language. For instance, namespaces will be presented as packages, - qualified scopes will look different, etc. + Python sources only. Doxygen will then generate output that is more tailored + for that language. For instance, namespaces will be presented as packages, + qualified scopes will look different, etc. ]]> </docs> </option> <option type='bool' id='OPTIMIZE_FOR_FORTRAN' defval='0'> <docs> <![CDATA[ - Set the \c OPTIMIZE_FOR_FORTRAN tag to \c YES if your project consists of Fortran + Set the \c OPTIMIZE_FOR_FORTRAN tag to \c YES if your project consists of Fortran sources. Doxygen will then generate output that is tailored for Fortran. ]]> </docs> @@ -593,11 +617,21 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='OPTIMIZE_OUTPUT_VHDL' defval='0'> <docs> <![CDATA[ - Set the \c OPTIMIZE_OUTPUT_VHDL tag to \c YES if your project consists of VHDL + Set the \c OPTIMIZE_OUTPUT_VHDL tag to \c YES if your project consists of VHDL sources. Doxygen will then generate output that is tailored for VHDL. ]]> </docs> </option> + <option type='bool' id='OPTIMIZE_OUTPUT_SLICE' defval='0'> + <docs> +<![CDATA[ + Set the \c OPTIMIZE_OUTPUT_SLICE tag to \c YES if your project consists of Slice + sources only. Doxygen will then generate output that is more tailored + for that language. For instance, namespaces will be presented as modules, + types will be separated into more groups, etc. +]]> + </docs> + </option> <option type='list' id='EXTENSION_MAPPING' format='string'> <docs> <![CDATA[ @@ -605,18 +639,18 @@ Go to the <a href="commands.html">next</a> section or return to the With this tag you can assign which parser to use for a given extension. Doxygen has a built-in mapping, but you can override or extend it using this tag. The format is <code>ext=language</code>, where \c ext is a file extension, and language is one of - the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, - Objective-C, Python, Fortran (fixed format Fortran: FortranFixed, + the parsers supported by doxygen: IDL, Java, Javascript, Csharp (C#), C, C++, D, PHP, + md (Markdown), Objective-C, Python, Slice, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In the later case the parser tries to guess whether the code is fixed or free - formatted code, this is the default for Fortran type files), VHDL. + formatted code, this is the default for Fortran type files), VHDL, tcl. For instance to make doxygen treat <code>.inc</code> files as Fortran files (default is PHP), and <code>.f</code> files as C (default is Fortran), use: `inc=Fortran f=C`. <br>Note: For files without extension you can use `no_extension` as a placeholder. - <br>Note that for custom extensions you also need to set \ref cfg_file_patterns "FILE_PATTERNS" otherwise the + <br>Note that for custom extensions you also need to set \ref cfg_file_patterns "FILE_PATTERNS" otherwise the files are not read by doxygen. ]]> </docs> @@ -624,12 +658,12 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='MARKDOWN_SUPPORT' defval='1'> <docs> <![CDATA[ - If the \c MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all - comments according to the Markdown format, which allows for more readable - documentation. See http://daringfireball.net/projects/markdown/ for details. - The output of markdown processing is further processed by doxygen, so you - can mix doxygen, HTML, and XML commands with Markdown formatting. - Disable only in case of backward compatibilities issues. + If the \c MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all + comments according to the Markdown format, which allows for more readable + documentation. See https://daringfireball.net/projects/markdown/ for details. + The output of markdown processing is further processed by doxygen, so you + can mix doxygen, HTML, and XML commands with Markdown formatting. + Disable only in case of backward compatibilities issues. ]]> </docs> </option> @@ -646,9 +680,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='AUTOLINK_SUPPORT' defval='1'> <docs> <![CDATA[ - When enabled doxygen tries to link words that correspond to documented classes, - or namespaces to their corresponding documentation. Such a link can be - prevented in individual cases by putting a \c % sign in front of the word or + When enabled doxygen tries to link words that correspond to documented classes, + or namespaces to their corresponding documentation. Such a link can be + prevented in individual cases by putting a \c % sign in front of the word or globally by setting \c AUTOLINK_SUPPORT to \c NO. ]]> </docs> @@ -676,10 +710,10 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='SIP_SUPPORT' defval='0'> <docs> <![CDATA[ - Set the \c SIP_SUPPORT tag to \c YES if your project consists - of <a href="https://www.riverbankcomputing.com/software/sip/intro">sip</a> sources only. - Doxygen will parse them like normal C++ but will assume all classes use public - instead of private inheritance when no explicit protection keyword is present. + Set the \c SIP_SUPPORT tag to \c YES if your project consists + of <a href="https://www.riverbankcomputing.com/software/sip/intro">sip</a> sources only. + Doxygen will parse them like normal C++ but will assume all classes use public + instead of private inheritance when no explicit protection keyword is present. ]]> </docs> </option> @@ -689,8 +723,8 @@ Go to the <a href="commands.html">next</a> section or return to the For Microsoft's IDL there are \c propget and \c propput attributes to indicate getter and setter methods for a property. Setting this option to \c YES will make doxygen to replace the get and set methods by a property in the - documentation. This will only work if the methods are indeed getting or - setting a simple type. If this is not the case, or you want to show the + documentation. This will only work if the methods are indeed getting or + setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to \c NO. ]]> </docs> @@ -721,16 +755,16 @@ Go to the <a href="commands.html">next</a> section or return to the the same type (for instance a group of public functions) to be put as a subgroup of that type (e.g. under the Public Functions section). Set it to \c NO to prevent subgrouping. Alternatively, this can be done per class using - the \ref cmdnosubgrouping "\\nosubgrouping" command. + the \ref cmdnosubgrouping "\\nosubgrouping" command. ]]> </docs> </option> <option type='bool' id='INLINE_GROUPED_CLASSES' defval='0'> <docs> <![CDATA[ - When the \c INLINE_GROUPED_CLASSES tag is set to \c YES, classes, structs and - unions are shown inside the group in which they are included - (e.g. using \ref cmdingroup "\\ingroup") instead of on a separate page (for HTML and Man pages) + When the \c INLINE_GROUPED_CLASSES tag is set to \c YES, classes, structs and + unions are shown inside the group in which they are included + (e.g. using \ref cmdingroup "\\ingroup") instead of on a separate page (for HTML and Man pages) or section (for \f$\mbox{\LaTeX}\f$ and RTF). <br>Note that this feature does not work in combination with \ref cfg_separate_member_pages "SEPARATE_MEMBER_PAGES". @@ -740,11 +774,11 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='INLINE_SIMPLE_STRUCTS' defval='0'> <docs> <![CDATA[ - When the \c INLINE_SIMPLE_STRUCTS tag is set to \c YES, structs, classes, and - unions with only public data fields or simple typedef fields will be shown - inline in the documentation of the scope in which they are defined (i.e. file, - namespace, or group documentation), provided this scope is documented. If set - to \c NO, structs, classes, and unions are shown on a separate + When the \c INLINE_SIMPLE_STRUCTS tag is set to \c YES, structs, classes, and + unions with only public data fields or simple typedef fields will be shown + inline in the documentation of the scope in which they are defined (i.e. file, + namespace, or group documentation), provided this scope is documented. If set + to \c NO, structs, classes, and unions are shown on a separate page (for HTML and Man pages) or section (for \f$\mbox{\LaTeX}\f$ and RTF). ]]> </docs> @@ -753,11 +787,11 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ When \c TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or enum - is documented as struct, union, or enum with the name of the typedef. So - <code>typedef struct TypeS {} TypeT</code>, will appear in the documentation as a struct - with name \c TypeT. When disabled the typedef will appear as a member of a file, - namespace, or class. And the struct will be named \c TypeS. This can typically - be useful for C code in case the coding convention dictates that all compound + is documented as struct, union, or enum with the name of the typedef. So + <code>typedef struct TypeS {} TypeT</code>, will appear in the documentation as a struct + with name \c TypeT. When disabled the typedef will appear as a member of a file, + namespace, or class. And the struct will be named \c TypeS. This can typically + be useful for C code in case the coding convention dictates that all compound types are typedef'ed and only the typedef is referenced, never the tag name. ]]> </docs> @@ -766,14 +800,14 @@ Go to the <a href="commands.html">next</a> section or return to the <!-- be careful when changing these formulas as they are hard coded in the conversion script --> <docs> <![CDATA[ - The size of the symbol lookup cache can be - set using \c LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given - their name and scope. Since this can be an expensive process and often the - same symbol appears multiple times in the code, doxygen keeps a cache of - pre-resolved symbols. If the cache is too small doxygen will become slower. - If the cache is too large, memory is wasted. The cache size is given by this - formula: \f$2^{(16+\mbox{LOOKUP\_CACHE\_SIZE})}\f$. The valid range is 0..9, the default is 0, - corresponding to a cache size of \f$2^{16} = 65536\f$ symbols. + The size of the symbol lookup cache can be + set using \c LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given + their name and scope. Since this can be an expensive process and often the + same symbol appears multiple times in the code, doxygen keeps a cache of + pre-resolved symbols. If the cache is too small doxygen will become slower. + If the cache is too large, memory is wasted. The cache size is given by this + formula: \f$2^{(16+\mbox{LOOKUP\_CACHE\_SIZE})}\f$. The valid range is 0..9, the default is 0, + corresponding to a cache size of \f$2^{16} = 65536\f$ symbols. At the end of a run doxygen will report the cache usage and suggest the optimal cache size from a speed point of view. ]]> @@ -784,14 +818,14 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='EXTRACT_ALL' defval='0'> <docs> <![CDATA[ - If the \c EXTRACT_ALL tag is set to \c YES, doxygen will assume all - entities in documentation are documented, even if no documentation was - available. Private class members and static file members will be hidden - unless the \ref cfg_extract_private "EXTRACT_PRIVATE" respectively + If the \c EXTRACT_ALL tag is set to \c YES, doxygen will assume all + entities in documentation are documented, even if no documentation was + available. Private class members and static file members will be hidden + unless the \ref cfg_extract_private "EXTRACT_PRIVATE" respectively \ref cfg_extract_static "EXTRACT_STATIC" tags are set to \c YES. - \note This will also disable the warnings about undocumented members - that are normally produced when \ref cfg_warnings "WARNINGS" is + \note This will also disable the warnings about undocumented members + that are normally produced when \ref cfg_warnings "WARNINGS" is set to \c YES. ]]> </docs> @@ -799,7 +833,7 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='EXTRACT_PRIVATE' defval='0'> <docs> <![CDATA[ - If the \c EXTRACT_PRIVATE tag is set to \c YES, all private members of a + If the \c EXTRACT_PRIVATE tag is set to \c YES, all private members of a class will be included in the documentation. ]]> </docs> @@ -807,8 +841,8 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='EXTRACT_PACKAGE' defval='0'> <docs> <![CDATA[ - If the \c EXTRACT_PACKAGE tag is set to \c YES, all members with package - or internal scope will be included in the documentation. + If the \c EXTRACT_PACKAGE tag is set to \c YES, all members with package + or internal scope will be included in the documentation. ]]> </docs> </option> @@ -823,8 +857,8 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='EXTRACT_LOCAL_CLASSES' defval='1'> <docs> <![CDATA[ - If the \c EXTRACT_LOCAL_CLASSES tag is set to \c YES, classes (and structs) - defined locally in source files will be included in the documentation. + If the \c EXTRACT_LOCAL_CLASSES tag is set to \c YES, classes (and structs) + defined locally in source files will be included in the documentation. If set to \c NO, only classes defined in header files are included. Does not have any effect for Java sources. ]]> @@ -833,7 +867,7 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='EXTRACT_LOCAL_METHODS' defval='0'> <docs> <![CDATA[ - This flag is only useful for Objective-C code. If set to \c YES, local + This flag is only useful for Objective-C code. If set to \c YES, local methods, which are defined in the implementation section but not in the interface are included in the documentation. If set to \c NO, only methods in the interface are included. @@ -854,7 +888,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ If the \c HIDE_UNDOC_MEMBERS tag is set to \c YES, doxygen will hide all - undocumented members inside documented classes or files. + undocumented members inside documented classes or files. If set to \c NO these members will be included in the various overviews, but no documentation section is generated. This option has no effect if \ref cfg_extract_all "EXTRACT_ALL" is enabled. @@ -865,7 +899,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ If the \c HIDE_UNDOC_CLASSES tag is set to \c YES, doxygen will hide all - undocumented classes that are normally visible in the class hierarchy. + undocumented classes that are normally visible in the class hierarchy. If set to \c NO, these classes will be included in the various overviews. This option has no effect if \ref cfg_extract_all "EXTRACT_ALL" is enabled. @@ -885,9 +919,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='HIDE_IN_BODY_DOCS' defval='0'> <docs> <![CDATA[ - If the \c HIDE_IN_BODY_DOCS tag is set to \c YES, doxygen will hide any + If the \c HIDE_IN_BODY_DOCS tag is set to \c YES, doxygen will hide any documentation blocks found inside the body of a function. - If set to \c NO, these blocks will be appended to the + If set to \c NO, these blocks will be appended to the function's detailed documentation block. ]]> </docs> @@ -917,9 +951,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='HIDE_SCOPE_NAMES' defval='0'> <docs> <![CDATA[ - If the \c HIDE_SCOPE_NAMES tag is set to \c NO then doxygen + If the \c HIDE_SCOPE_NAMES tag is set to \c NO then doxygen will show members with their full class and namespace scopes in the - documentation. If set to \c YES, the scope will be hidden. + documentation. If set to \c YES, the scope will be hidden. ]]> </docs> </option> @@ -928,7 +962,7 @@ Go to the <a href="commands.html">next</a> section or return to the <![CDATA[ If the \c HIDE_COMPOUND_REFERENCE tag is set to \c NO (default) then doxygen will append additional text to a page's title, such as Class Reference. - If set to \c YES the compound reference will be hidden. + If set to \c YES the compound reference will be hidden. ]]> </docs> </option> @@ -936,7 +970,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ If the \c SHOW_INCLUDE_FILES tag is set to \c YES then doxygen - will put a list of the files that are included by a file in the documentation + will put a list of the files that are included by a file in the documentation of that file. ]]> </docs> @@ -944,7 +978,7 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='SHOW_GROUPED_MEMB_INC' defval='0'> <docs> <![CDATA[ - If the SHOW_GROUPED_MEMB_INC tag is set to \c YES then Doxygen + If the SHOW_GROUPED_MEMB_INC tag is set to \c YES then Doxygen will add for each grouped member an include statement to the documentation, telling the reader which file to include in order to use the member. ]]> @@ -953,8 +987,8 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='FORCE_LOCAL_INCLUDES' defval='0'> <docs> <![CDATA[ - If the \c FORCE_LOCAL_INCLUDES tag is set to \c YES then doxygen - will list include files with double quotes in the documentation + If the \c FORCE_LOCAL_INCLUDES tag is set to \c YES then doxygen + will list include files with double quotes in the documentation rather than with sharp brackets. ]]> </docs> @@ -1006,9 +1040,9 @@ Go to the <a href="commands.html">next</a> section or return to the <option type='bool' id='SORT_GROUP_NAMES' defval='0'> <docs> <![CDATA[ - If the \c SORT_GROUP_NAMES tag is set to \c YES then doxygen will sort the + If the \c SORT_GROUP_NAMES tag is set to \c YES then doxygen will sort the hierarchy of group names into alphabetical order. If set to \c NO - the group names will appear in their defined order. + the group names will appear in their defined order. ]]> </docs> </option> @@ -1020,7 +1054,7 @@ Go to the <a href="commands.html">next</a> section or return to the \c NO, the class list will be sorted only by class name, not including the namespace part. \note This option is not very useful if \ref cfg_hide_scope_names "HIDE_SCOPE_NAMES" is set to \c YES. - \note This option applies only to the class list, not to the + \note This option applies only to the class list, not to the alphabetical list. ]]> </docs> @@ -1029,10 +1063,10 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ If the \c STRICT_PROTO_MATCHING option is enabled and doxygen fails to - do proper type resolution of all parameters of a function it will reject a + do proper type resolution of all parameters of a function it will reject a match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose - by doing a simple string match. By disabling \c STRICT_PROTO_MATCHING doxygen + by doing a simple string match. By disabling \c STRICT_PROTO_MATCHING doxygen will still accept a match between prototype and implementation in such cases. ]]> </docs> @@ -1041,7 +1075,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ The \c GENERATE_TODOLIST tag can be used to enable (\c YES) or - disable (\c NO) the todo list. This list is created by + disable (\c NO) the todo list. This list is created by putting \ref cmdtodo "\\todo" commands in the documentation. ]]> </docs> @@ -1050,7 +1084,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ The \c GENERATE_TESTLIST tag can be used to enable (\c YES) or - disable (\c NO) the test list. This list is created by + disable (\c NO) the test list. This list is created by putting \ref cmdtest "\\test" commands in the documentation. ]]> </docs> @@ -1059,7 +1093,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ The \c GENERATE_BUGLIST tag can be used to enable (\c YES) or - disable (\c NO) the bug list. This list is created by + disable (\c NO) the bug list. This list is created by putting \ref cmdbug "\\bug" commands in the documentation. ]]> </docs> @@ -1068,7 +1102,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ The \c GENERATE_DEPRECATEDLIST tag can be used to enable (\c YES) or - disable (\c NO) the deprecated list. This list is created by + disable (\c NO) the deprecated list. This list is created by putting \ref cmddeprecated "\\deprecated" commands in the documentation. ]]> @@ -1078,7 +1112,7 @@ Go to the <a href="commands.html">next</a> section or return to the <docs> <![CDATA[ The \c ENABLED_SECTIONS tag can be used to enable conditional - documentation sections, marked by \ref cmdif "\\if" \<section_label\> ... + documentation sections, marked by \ref cmdif "\\if" \<section_label\> ... \ref cmdendif "\\endif" and \ref cmdcond "\\cond" \<section_label\> ... \ref cmdendcond "\\endcond" blocks. ]]> @@ -1130,14 +1164,16 @@ Go to the <a href="commands.html">next</a> section or return to the The \c FILE_VERSION_FILTER tag can be used to specify a program or script that doxygen should invoke to get the current version for each file (typically from the version control system). Doxygen will invoke the program by executing (via - <code>popen()</code>) the command <code>command input-file</code>, where \c command is - the value of the \c FILE_VERSION_FILTER tag, and \c input-file is the name - of an input file provided by doxygen. + <code>popen()</code>) the command <code>command input-file</code>, where \c command is + the value of the \c FILE_VERSION_FILTER tag, and \c input-file is the name + of an input file provided by doxygen. Whatever the program writes to standard output is used as the file version. ]]> </docs> <docs doxywizard='0' doxyfile='0'> <![CDATA[ +<br> +<br> Example of using a shell script as a filter for Unix: \verbatim FILE_VERSION_FILTER = "/bin/sh versionfilter.sh" @@ -1147,8 +1183,8 @@ Example shell script for CVS: \verbatim #!/bin/sh cvs status $1 | sed -n 's/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p' -\endverbatim -<br> +\endverbatim +<br> Example shell script for Subversion: \verbatim #!/bin/sh @@ -1157,7 +1193,7 @@ svn stat -v $1 | sed -n 's/^[ A-Z?\*|!]\{1,15\}/r/;s/ \{1,15\}/\/r/;s/ .*//p' <br> Example filter for ClearCase: \verbatim -FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" +FILE_VERSION_FILTER = "cleartool desc -fmt \%Vn" \endverbatim ]]> </docs> @@ -1176,8 +1212,8 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" doxygen's defaults, run doxygen with the `-l` option. You can optionally specify a file name after the option, if omitted \c DoxygenLayout.xml will be used as the name of the layout file. - <br>Note that if you run doxygen from a directory containing - a file called \c DoxygenLayout.xml, doxygen will parse it automatically even if + <br>Note that if you run doxygen from a directory containing + a file called \c DoxygenLayout.xml, doxygen will parse it automatically even if the \c LAYOUT_FILE tag is left empty. ]]> </docs> @@ -1185,11 +1221,11 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='list' id='CITE_BIB_FILES' format='file'> <docs> <![CDATA[ - The \c CITE_BIB_FILES tag can be used to specify one or more \c bib files - containing the reference definitions. This must be a list of <code>.bib</code> files. The - <code>.bib</code> extension is automatically appended if omitted. This requires the + The \c CITE_BIB_FILES tag can be used to specify one or more \c bib files + containing the reference definitions. This must be a list of <code>.bib</code> files. The + <code>.bib</code> extension is automatically appended if omitted. This requires the \c bibtex tool to be installed. See also https://en.wikipedia.org/wiki/BibTeX for - more info. For \f$\mbox{\LaTeX}\f$ the style of the bibliography can be controlled + more info. For \f$\mbox{\LaTeX}\f$ the style of the bibliography can be controlled using \ref cfg_latex_bib_style "LATEX_BIB_STYLE". To use this feature you need \c bibtex and \c perl available in the search path. See also \ref cmdcite "\\cite" for info how to create references. @@ -1210,7 +1246,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <docs> <![CDATA[ The \c WARNINGS tag can be used to turn on/off the warning messages that are - generated to standard error (\c stderr) by doxygen. If \c WARNINGS is set to + generated to standard error (\c stderr) by doxygen. If \c WARNINGS is set to \c YES this implies that the warnings are on. <br> \b Tip: Turn warnings on while writing the documentation. @@ -1232,18 +1268,20 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" If the \c WARN_IF_DOC_ERROR tag is set to \c YES, doxygen will generate warnings for potential errors in the documentation, such as not documenting some parameters in a documented function, or documenting parameters that - don't exist or using markup commands wrongly. + don't exist or using markup commands wrongly. ]]> </docs> </option> <option type='bool' id='WARN_NO_PARAMDOC' defval='0'> <docs> <![CDATA[ - This \c WARN_NO_PARAMDOC option can be enabled to get warnings for + This \c WARN_NO_PARAMDOC option can be enabled to get warnings for functions that are documented, but have no documentation for their parameters or return value. If set to \c NO, doxygen will only warn about wrong or incomplete parameter documentation, but not about the absence of documentation. + If \ref cfg_extract_all "EXTRACT_ALL" is set to \c YES then this flag will + automatically be disabled. ]]> </docs> </option> @@ -1259,13 +1297,13 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <docs> <![CDATA[ The \c WARN_FORMAT tag determines the format of the warning messages that - doxygen can produce. The string should contain the <code>\$file</code>, - <code>\$line</code>, and <code>\$text</code> + doxygen can produce. The string should contain the <code>\$file</code>, + <code>\$line</code>, and <code>\$text</code> tags, which will be replaced by the file and line number from which the warning originated and the warning text. - 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") + 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") ]]> </docs> </option> @@ -1273,7 +1311,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <docs> <![CDATA[ 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 + and error messages should be written. If left blank the output is written to standard error (`stderr`). ]]> </docs> @@ -1283,9 +1321,9 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='list' id='INPUT' format='filedir'> <docs> <![CDATA[ - The \c INPUT tag is used to specify the files and/or directories that contain - documented source files. You may enter file names like - \c myfile.cpp or directories like \c /usr/src/myproject. + The \c INPUT tag is used to specify the files and/or directories that contain + documented source files. You may enter file names like + \c myfile.cpp or directories like \c /usr/src/myproject. Separate the files or directories with spaces. See also \ref cfg_file_patterns "FILE_PATTERNS" and \ref cfg_extension_mapping "EXTENSION_MAPPING" @@ -1298,10 +1336,10 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='string' id='INPUT_ENCODING' format='string' defval='UTF-8'> <docs> <![CDATA[ - This tag can be used to specify the character encoding of the source files that + This tag can be used to specify the character encoding of the source files that doxygen parses. Internally doxygen uses the UTF-8 encoding. - Doxygen uses `libiconv` (or the `iconv` built into `libc`) for the transcoding. - See <a href="https://www.gnu.org/software/libiconv/">the libiconv documentation</a> for + Doxygen uses `libiconv` (or the `iconv` built into `libc`) for the transcoding. + See <a href="https://www.gnu.org/software/libiconv/">the libiconv documentation</a> for the list of possible encodings. ]]> </docs> @@ -1309,9 +1347,9 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='list' id='FILE_PATTERNS' format='string'> <docs> <![CDATA[ - If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the - \c FILE_PATTERNS tag to specify one or more wildcard patterns - (like `*.cpp` and `*.h`) to filter out the source-files + If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the + \c FILE_PATTERNS tag to specify one or more wildcard patterns + (like `*.cpp` and `*.h`) to filter out the source-files in the directories.<br> Note that for custom extensions or not directly supported extensions you also need to set \ref cfg_extension_mapping "EXTENSION_MAPPING" for the extension @@ -1363,6 +1401,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <value name='*.vhdl'/> <value name='*.ucf'/> <value name='*.qsf'/> + <value name='*.ice'/> </option> <option type='bool' id='RECURSIVE' defval='0'> <docs> @@ -1385,7 +1424,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='bool' id='EXCLUDE_SYMLINKS' defval='0'> <docs> <![CDATA[ - The \c EXCLUDE_SYMLINKS tag can be used to select whether or not files or directories + The \c EXCLUDE_SYMLINKS tag can be used to select whether or not files or directories that are symbolic links (a Unix file system feature) are excluded from the input. ]]> </docs> @@ -1396,8 +1435,8 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the \c EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude certain files from those directories. - <br>Note that the wildcards are matched - against the file with absolute path, so to exclude all test directories + <br>Note that the wildcards are matched + against the file with absolute path, so to exclude all test directories for example use the pattern `*``/test/``*` ]]> </docs> @@ -1405,13 +1444,13 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='list' id='EXCLUDE_SYMBOLS' format='string'> <docs> <![CDATA[ - The \c EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names - (namespaces, classes, functions, etc.) that should be excluded from the - output. The symbol name can be a fully qualified name, a word, or if the - wildcard `*` is used, a substring. Examples: `ANamespace`, `AClass`, - `AClass::ANamespace`, `ANamespace::*Test` - <br>Note that the wildcards are matched against the file with absolute path, - so to exclude all test directories use the pattern + The \c EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names + (namespaces, classes, functions, etc.) that should be excluded from the + output. The symbol name can be a fully qualified name, a word, or if the + wildcard `*` is used, a substring. Examples: `ANamespace`, `AClass`, + `AClass::ANamespace`, `ANamespace::*Test` + <br>Note that the wildcards are matched against the file with absolute path, + so to exclude all test directories use the pattern `*``/test/``*` ]]> </docs> @@ -1428,7 +1467,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='list' id='EXAMPLE_PATTERNS' format='string'> <docs> <![CDATA[ - If the value of the \ref cfg_example_path "EXAMPLE_PATH" tag contains directories, + If the value of the \ref cfg_example_path "EXAMPLE_PATH" tag contains directories, you can use the \c EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like `*.cpp` and `*.h`) to filter out the source-files in the directories. If left @@ -1442,8 +1481,8 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <![CDATA[ If the \c EXAMPLE_RECURSIVE tag is set to \c YES then subdirectories will be searched for input files to be used with the \ref cmdinclude "\\include" or - \ref cmddontinclude "\\dontinclude" - commands irrespective of the value of the \ref cfg_recursive "RECURSIVE" tag. + \ref cmddontinclude "\\dontinclude" + commands irrespective of the value of the \ref cfg_recursive "RECURSIVE" tag. ]]> </docs> </option> @@ -1451,7 +1490,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <docs> <![CDATA[ The \c IMAGE_PATH tag can be used to specify one or more files or - directories that contain images that are to be included in the + directories that contain images that are to be included in the documentation (see the \ref cmdimage "\\image" command). ]]> </docs> @@ -1468,9 +1507,9 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" where <code>\<filter\></code> is the value of the \c INPUT_FILTER tag, and <code>\<input-file\></code> is the name of an input file. Doxygen will then use the output that the filter program writes - to standard output. If \ref cfg_filter_patterns "FILTER_PATTERNS" is specified, this tag will be ignored. - <br>Note that the filter must not add or remove lines; it is applied before the - code is scanned, but not when the output code is generated. If lines are added + to standard output. If \ref cfg_filter_patterns "FILTER_PATTERNS" is specified, this tag will be ignored. + <br>Note that the filter must not add or remove lines; it is applied before the + code is scanned, but not when the output code is generated. If lines are added or removed, the anchors will not be placed correctly. <br>Note that for custom extensions or not directly supported extensions you also need to set \ref cfg_extension_mapping "EXTENSION_MAPPING" for the extension @@ -1487,7 +1526,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" filter if there is a match. The filters are a list of the form: pattern=filter (like `*.cpp=my_cpp_filter`). See \ref cfg_input_filter "INPUT_FILTER" for further information on how filters are used. If the \c FILTER_PATTERNS tag is empty or if - none of the patterns match the file name, \ref cfg_input_filter "INPUT_FILTER" is + none of the patterns match the file name, \ref cfg_input_filter "INPUT_FILTER" is applied. <br>Note that for custom extensions or not directly supported extensions you also need to set \ref cfg_extension_mapping "EXTENSION_MAPPING" for the extension @@ -1500,7 +1539,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <![CDATA[ If the \c FILTER_SOURCE_FILES tag is set to \c YES, the input filter (if set using \ref cfg_input_filter "INPUT_FILTER") will also be used to filter the input - files that are used for producing the source files to browse + files that are used for producing the source files to browse (i.e. when \ref cfg_source_browser "SOURCE_BROWSER" is set to \c YES). ]]> </docs> @@ -1508,10 +1547,10 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='list' id='FILTER_SOURCE_PATTERNS' format='string' depends='FILTER_SOURCE_FILES'> <docs> <![CDATA[ - The \c FILTER_SOURCE_PATTERNS tag can be used to specify source filters per - file pattern. A pattern will override the setting - for \ref cfg_filter_patterns "FILTER_PATTERN" (if any) - and it is also possible to disable source filtering for a specific pattern + The \c FILTER_SOURCE_PATTERNS tag can be used to specify source filters per + file pattern. A pattern will override the setting + for \ref cfg_filter_patterns "FILTER_PATTERN" (if any) + and it is also possible to disable source filtering for a specific pattern using `*.ext=` (so without naming a filter). ]]> </docs> @@ -1519,9 +1558,9 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='string' id='USE_MDFILE_AS_MAINPAGE' format='string' defval=''> <docs> <![CDATA[ - If the \c USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that - is part of the input, its contents will be placed on the main page (`index.html`). - This can be useful if you have a project on for instance GitHub and want to reuse + If the \c USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that + is part of the input, its contents will be placed on the main page (`index.html`). + This can be useful if you have a project on for instance GitHub and want to reuse the introduction page also for the doxygen output. ]]> </docs> @@ -1560,7 +1599,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <![CDATA[ If the \c REFERENCED_BY_RELATION tag is set to \c YES then for each documented entity all documented - functions referencing it will be listed. + functions referencing it will be listed. ]]> </docs> </option> @@ -1569,7 +1608,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <![CDATA[ If the \c REFERENCES_RELATION tag is set to \c YES then for each documented function all documented entities - called/used by that function will be listed. + called/used by that function will be listed. ]]> </docs> </option> @@ -1577,9 +1616,9 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <docs> <![CDATA[ If the \c REFERENCES_LINK_SOURCE tag is set to \c YES - and \ref cfg_source_browser "SOURCE_BROWSER" tag is set to \c YES then the hyperlinks from + and \ref cfg_source_browser "SOURCE_BROWSER" tag is set to \c YES then the hyperlinks from functions in \ref cfg_references_relation "REFERENCES_RELATION" and - \ref cfg_referenced_by_relation "REFERENCED_BY_RELATION" lists will + \ref cfg_referenced_by_relation "REFERENCED_BY_RELATION" lists will link to the source code. Otherwise they will link to the documentation. ]]> </docs> @@ -1587,11 +1626,11 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" <option type='bool' id='SOURCE_TOOLTIPS' defval='1' depends='SOURCE_BROWSER'> <docs> <![CDATA[ -If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -source code will show a tooltip with additional information such as prototype, -brief description and links to the definition and documentation. Since this will -make the HTML file larger and loading of large files a bit slower, you can opt -to disable this feature. +If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +source code will show a tooltip with additional information such as prototype, +brief description and links to the definition and documentation. Since this will +make the HTML file larger and loading of large files a bit slower, you can opt +to disable this feature. ]]> </docs> </option> @@ -1601,12 +1640,12 @@ to disable this feature. If the \c USE_HTAGS tag is set to \c YES then the references to source code will point to the HTML generated by the \c htags(1) tool instead of doxygen built-in source browser. The \c htags tool is part of GNU's global source - tagging system (see https://www.gnu.org/software/global/global.html). You - will need version 4.8.6 or higher. + tagging system (see https://www.gnu.org/software/global/global.html). You + will need version 4.8.6 or higher. <br> To use it do the following: -# Install the latest version of \c global - -# Enable \ref cfg_source_browser "SOURCE_BROWSER" and \c USE_HTAGS in the config file + -# Enable \ref cfg_source_browser "SOURCE_BROWSER" and \c USE_HTAGS in the configuration file -# Make sure the \ref cfg_input "INPUT" points to the root of the source tree -# Run \c doxygen as normal <br> @@ -1632,23 +1671,23 @@ to disable this feature. <option type='bool' id='CLANG_ASSISTED_PARSING' setting='USE_LIBCLANG' defval='0'> <docs> <![CDATA[ - If the \c CLANG_ASSISTED_PARSING tag is set to \c YES then doxygen will use the - <a href="http://clang.llvm.org/">clang parser</a> for more accurate parsing - at the cost of reduced performance. This can be particularly helpful with - template rich C++ code for which doxygen's built-in parser lacks the + If the \c CLANG_ASSISTED_PARSING tag is set to \c YES then doxygen will use the + <a href="http://clang.llvm.org/">clang parser</a> for more accurate parsing + at the cost of reduced performance. This can be particularly helpful with + template rich C++ code for which doxygen's built-in parser lacks the necessary type information. @note The availability of this option depends on whether or not doxygen - was generated with the `-Duse-libclang=ON` option for CMake. + was generated with the `-Duse_libclang=ON` option for CMake. ]]> </docs> </option> <option type='list' id='CLANG_OPTIONS' format='string' setting='USE_LIBCLANG' depends='CLANG_ASSISTED_PARSING'> <docs> <![CDATA[ - If clang assisted parsing is enabled you can provide the compiler with command - line options that you would normally use when invoking the compiler. Note that - the include paths will already be set by doxygen for the files and directories + If clang assisted parsing is enabled you can provide the compiler with command + line options that you would normally use when invoking the compiler. Note that + the include paths will already be set by doxygen for the files and directories specified with \ref cfg_input "INPUT" and \ref cfg_include_path "INCLUDE_PATH". ]]> </docs> @@ -1663,7 +1702,7 @@ to disable this feature. will then be passed to the parser. @note The availability of this option depends on whether or not doxygen - was generated with the `-Duse-libclang=ON` option for CMake. + was generated with the `-Duse_libclang=ON` option for CMake. ]]> </docs> </option> @@ -1673,7 +1712,7 @@ to disable this feature. <docs> <![CDATA[ If the \c ALPHABETICAL_INDEX tag is set to \c YES, an alphabetical index - of all compounds will be generated. Enable this if the project contains + of all compounds will be generated. Enable this if the project contains a lot of classes, structs, unions or interfaces. ]]> </docs> @@ -1681,7 +1720,7 @@ to disable this feature. <option type='int' id='COLS_IN_ALPHA_INDEX' minval='1' maxval='20' defval='5' depends='ALPHABETICAL_INDEX'> <docs> <![CDATA[ - The \c COLS_IN_ALPHA_INDEX tag can be + The \c COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in which the alphabetical index list will be split. ]]> </docs> @@ -1689,9 +1728,9 @@ to disable this feature. <option type='list' id='IGNORE_PREFIX' format='string' depends='ALPHABETICAL_INDEX'> <docs> <![CDATA[ - In case all classes in a project start with a common prefix, all classes will + In case all classes in a project start with a common prefix, all classes will be put under the same header in the alphabetical index. - The \c IGNORE_PREFIX tag can be used to specify a prefix + The \c IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) that should be ignored while generating the index headers. ]]> </docs> @@ -1718,7 +1757,7 @@ to disable this feature. <option type='string' id='HTML_FILE_EXTENSION' format='string' defval='.html' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_FILE_EXTENSION tag can be used to specify the file extension for + The \c HTML_FILE_EXTENSION tag can be used to specify the file extension for each generated HTML page (for example: <code>.htm, .php, .asp</code>). ]]> </docs> @@ -1726,10 +1765,10 @@ to disable this feature. <option type='string' id='HTML_HEADER' format='file' defval='' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_HEADER tag can be used to specify a user-defined HTML - header file for each generated HTML page. - If the tag is left blank doxygen will generate a - standard header. + The \c HTML_HEADER tag can be used to specify a user-defined HTML + header file for each generated HTML page. + If the tag is left blank doxygen will generate a + standard header. <br> To get valid HTML the header file that includes any scripts and style sheets that doxygen @@ -1745,7 +1784,7 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil the default header that doxygen normally uses. @note The header is subject to change so you typically - have to regenerate the default header when upgrading to a newer version of + have to regenerate the default header when upgrading to a newer version of doxygen. ]]> </docs> @@ -1758,7 +1797,7 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil <dt><code>\$date</code><dd>will be replaced with the current date. <dt><code>\$year</code><dd>will be replaces with the current year. <dt><code>\$doxygenversion</code><dd>will be replaced with the version of doxygen - <dt><code>\$projectname</code><dd>will be replaced with the name of + <dt><code>\$projectname</code><dd>will be replaced with the name of the project (see \ref cfg_project_name "PROJECT_NAME") <dt><code>\$projectnumber</code><dd>will be replaced with the project number (see \ref cfg_project_number "PROJECT_NUMBER") @@ -1766,25 +1805,25 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil description (see \ref cfg_project_brief "PROJECT_BRIEF") <dt><code>\$projectlogo</code><dd>will be replaced with the project logo (see \ref cfg_project_logo "PROJECT_LOGO") - <dt><code>\$treeview</code><dd>will be replaced with links to - the javascript and style sheets needed for the navigation tree - (or an empty string when \ref cfg_generate_treeview "GENERATE_TREEVIEW" + <dt><code>\$treeview</code><dd>will be replaced with links to + the javascript and style sheets needed for the navigation tree + (or an empty string when \ref cfg_generate_treeview "GENERATE_TREEVIEW" is disabled). - <dt><code>\$search</code><dd>will be replaced with a links to - the javascript and style sheets needed for the search engine - (or an empty string when \ref cfg_searchengine "SEARCHENGINE" + <dt><code>\$search</code><dd>will be replaced with a links to + the javascript and style sheets needed for the search engine + (or an empty string when \ref cfg_searchengine "SEARCHENGINE" is disabled). - <dt><code>\$mathjax</code><dd>will be replaced with a links to - the javascript and style sheets needed for the MathJax feature + <dt><code>\$mathjax</code><dd>will be replaced with a links to + the javascript and style sheets needed for the MathJax feature (or an empty string when \ref cfg_use_mathjax "USE_MATHJAX" is disabled). <dt><code>\$relpath^</code><dd> - If \ref cfg_create_subdirs "CREATE_SUBDIRS" is enabled, the command <code>\$relpath^</code> can be + If \ref cfg_create_subdirs "CREATE_SUBDIRS" is enabled, the command <code>\$relpath^</code> can be used to produce a relative path to the root of the HTML output directory, e.g. use <code>\$relpath^doxygen.css</code>, to refer to the standard style sheet. </dl> - To cope with differences in the layout of the header and footer that depend on - configuration settings, the header can also contain special blocks that + To cope with differences in the layout of the header and footer that depend on + configuration settings, the header can also contain special blocks that will be copied to the output or skipped depending on the configuration. Such blocks have the following form: \verbatim @@ -1813,9 +1852,9 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil when the \ref cfg_project_logo "PROJECT_LOGO" option is not empty. <dt><code>TITLEAREA</code><dd>Content within this block is copied to the output when a title is visible at the top of each page. This is the case - if either \ref cfg_project_name "PROJECT_NAME", - \ref cfg_project_brief "PROJECT_BRIEF", \ref cfg_project_logo "PROJECT_LOGO" - is filled in or if both \ref cfg_disable_index "DISABLE_INDEX" and + if either \ref cfg_project_name "PROJECT_NAME", + \ref cfg_project_brief "PROJECT_BRIEF", \ref cfg_project_logo "PROJECT_LOGO" + is filled in or if both \ref cfg_disable_index "DISABLE_INDEX" and \ref cfg_searchengine "SEARCHENGINE" are enabled. </dl> ]]> @@ -1830,12 +1869,12 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil <option type='string' id='HTML_FOOTER' format='file' defval='' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_FOOTER tag can be used to specify a user-defined HTML footer for - each generated HTML page. + The \c HTML_FOOTER tag can be used to specify a user-defined HTML footer for + each generated HTML page. If the tag is left blank doxygen will generate a standard footer. - See \ref cfg_html_header "HTML_HEADER" for more information on - how to generate a default footer and what special commands can be + See \ref cfg_html_header "HTML_HEADER" for more information on + how to generate a default footer and what special commands can be used inside the footer. See also section \ref doxygen_usage for information on how to generate @@ -1846,17 +1885,17 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil <option type='string' id='HTML_STYLESHEET' format='file' defval='' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_STYLESHEET tag can be used to specify a user-defined cascading - style sheet that is used by each HTML page. It can be used to - fine-tune the look of the HTML output. If left blank doxygen - will generate a default style sheet. - + The \c HTML_STYLESHEET tag can be used to specify a user-defined cascading + style sheet that is used by each HTML page. It can be used to + fine-tune the look of the HTML output. If left blank doxygen + will generate a default style sheet. + See also section \ref doxygen_usage for information on how to generate the style sheet that doxygen normally uses. - \note It is recommended to use + \note It is recommended to use \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET" instead of this tag, - as it is more robust and + as it is more robust and this tag (<code>HTML_STYLESHEET</code>) will in the future become obsolete. ]]> </docs> @@ -1864,12 +1903,12 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil <option type='list' id='HTML_EXTRA_STYLESHEET' format='file' defval='' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_EXTRA_STYLESHEET tag can be used to specify additional - user-defined cascading style sheets that are included after the standard - style sheets created by doxygen. Using this option one can overrule - certain style aspects. This is preferred over using \ref cfg_html_stylesheet "HTML_STYLESHEET" - since it does not replace the standard style sheet and is therefore more - robust against future updates. Doxygen will copy the style sheet files to + The \c HTML_EXTRA_STYLESHEET tag can be used to specify additional + user-defined cascading style sheets that are included after the standard + style sheets created by doxygen. Using this option one can overrule + certain style aspects. This is preferred over using \ref cfg_html_stylesheet "HTML_STYLESHEET" + since it does not replace the standard style sheet and is therefore more + robust against future updates. Doxygen will copy the style sheet files to the output directory. \note The order of the extra style sheet files is of importance (e.g. the last style sheet in the list overrules the setting of the previous ones in the list). @@ -1918,12 +1957,12 @@ hr.footer { <option type='list' id='HTML_EXTRA_FILES' format='file' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_EXTRA_FILES tag can be used to specify one or more extra images or - other source files which should be copied to the HTML output directory. Note - that these files will be copied to the base HTML output directory. Use the + The \c HTML_EXTRA_FILES tag can be used to specify one or more extra images or + other source files which should be copied to the HTML output directory. Note + that these files will be copied to the base HTML output directory. Use the <code>$relpath^</code> marker in the \ref cfg_html_header "HTML_HEADER" and/or - \ref cfg_html_footer "HTML_FOOTER" files to load these - files. In the \ref cfg_html_stylesheet "HTML_STYLESHEET" file, use the file name only. Also note that + \ref cfg_html_footer "HTML_FOOTER" files to load these + files. In the \ref cfg_html_stylesheet "HTML_STYLESHEET" file, use the file name only. Also note that the files will be copied as-is; there are no commands or markers available. ]]> </docs> @@ -1931,32 +1970,32 @@ hr.footer { <option type='int' id='HTML_COLORSTYLE_HUE' minval='0' maxval='359' defval='220' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_COLORSTYLE_HUE tag controls the color of the HTML output. - Doxygen will adjust the colors in the style sheet and background images - according to this color. Hue is specified as an angle on a colorwheel, - see https://en.wikipedia.org/wiki/Hue for more information. - For instance the value 0 represents red, 60 is yellow, 120 is green, - 180 is cyan, 240 is blue, 300 purple, and 360 is red again. + The \c HTML_COLORSTYLE_HUE tag controls the color of the HTML output. + Doxygen will adjust the colors in the style sheet and background images + according to this color. Hue is specified as an angle on a colorwheel, + see https://en.wikipedia.org/wiki/Hue for more information. + For instance the value 0 represents red, 60 is yellow, 120 is green, + 180 is cyan, 240 is blue, 300 purple, and 360 is red again. ]]> </docs> </option> <option type='int' id='HTML_COLORSTYLE_SAT' minval='0' maxval='255' defval='100' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of - the colors in the HTML output. For a value of 0 the output will use - grayscales only. A value of 255 will produce the most vivid colors. + The \c HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of + the colors in the HTML output. For a value of 0 the output will use + grayscales only. A value of 255 will produce the most vivid colors. ]]> </docs> </option> <option type='int' id='HTML_COLORSTYLE_GAMMA' minval='40' maxval='240' defval='80' depends='GENERATE_HTML'> <docs> <![CDATA[ - The \c HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to - the luminance component of the colors in the HTML output. Values below - 100 gradually make the output lighter, whereas values above 100 make - the output darker. The value divided by 100 is the actual gamma applied, - so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, + The \c HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to + the luminance component of the colors in the HTML output. Values below + 100 gradually make the output lighter, whereas values above 100 make + the output darker. The value divided by 100 is the actual gamma applied, + so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not change the gamma. ]]> </docs> @@ -1964,9 +2003,9 @@ hr.footer { <option type='bool' id='HTML_TIMESTAMP' defval='0' depends='GENERATE_HTML'> <docs> <![CDATA[ - If the \c HTML_TIMESTAMP tag is set to \c YES then the footer of - each generated HTML page will contain the date and time when the page - was generated. Setting this to \c YES can help to show when doxygen was last run + If the \c HTML_TIMESTAMP tag is set to \c YES then the footer of + each generated HTML page will contain the date and time when the page + was generated. Setting this to \c YES can help to show when doxygen was last run and thus if the documentation is up to date. ]]> </docs> @@ -1974,11 +2013,11 @@ hr.footer { <option type='bool' id='HTML_DYNAMIC_MENUS' defval='1' depends='GENERATE_HTML'> <docs> <![CDATA[ - If the \c HTML_DYNAMIC_MENUS tag is set to \c YES then the generated HTML - documentation will contain a main index with vertical navigation menus that - are dynamically created via Javascript. If disabled, the navigation index will consists of - multiple levels of tabs that are statically embedded in every HTML page. - Disable this option to support browsers that do not have Javascript, like + If the \c HTML_DYNAMIC_MENUS tag is set to \c YES then the generated HTML + documentation will contain a main index with vertical navigation menus that + are dynamically created via Javascript. If disabled, the navigation index will consists of + multiple levels of tabs that are statically embedded in every HTML page. + Disable this option to support browsers that do not have Javascript, like the Qt help browser. ]]> </docs> @@ -1988,20 +2027,20 @@ hr.footer { <![CDATA[ If the \c HTML_DYNAMIC_SECTIONS tag is set to \c YES then the generated HTML documentation will contain sections that can be hidden and shown after the - page has loaded. + page has loaded. ]]> </docs> </option> <option type='int' id='HTML_INDEX_NUM_ENTRIES' minval='0' maxval='9999' defval='100' depends='GENERATE_HTML'> <docs> <![CDATA[ - With \c HTML_INDEX_NUM_ENTRIES one can control the preferred number of - entries shown in the various tree structured indices initially; the user - can expand and collapse entries dynamically later on. Doxygen will expand - the tree to such a level that at most the specified number of entries are - visible (unless a fully collapsed tree already exceeds this amount). - So setting the number of entries 1 will produce a full collapsed tree by - default. 0 is a special value representing an infinite number of entries + With \c HTML_INDEX_NUM_ENTRIES one can control the preferred number of + entries shown in the various tree structured indices initially; the user + can expand and collapse entries dynamically later on. Doxygen will expand + the tree to such a level that at most the specified number of entries are + visible (unless a fully collapsed tree already exceeds this amount). + So setting the number of entries 1 will produce a full collapsed tree by + default. 0 is a special value representing an infinite number of entries and will result in a full expanded tree by default. ]]> </docs> @@ -2010,16 +2049,16 @@ hr.footer { <docs> <![CDATA[ If the \c GENERATE_DOCSET tag is set to \c YES, additional index files - will be generated that can be used as input for - <a href="https://developer.apple.com/tools/xcode/">Apple's Xcode 3 + will be generated that can be used as input for + <a href="https://developer.apple.com/xcode/">Apple's Xcode 3 integrated development environment</a>, introduced with OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a Makefile in the HTML output directory. Running \c make will produce the docset in that - directory and running <code>make install</code> will install the docset in - <code>~/Library/Developer/Shared/Documentation/DocSets</code> + directory and running <code>make install</code> will install the docset in + <code>~/Library/Developer/Shared/Documentation/DocSets</code> so that Xcode will find it at startup. See - https://developer.apple.com/tools/creatingdocsetswithdoxygen.html for - more information. + https://developer.apple.com/library/archive/featuredarticles/DoxygenXcode/_index.html + for more information. ]]> </docs> </option> @@ -2028,7 +2067,7 @@ hr.footer { <![CDATA[ This tag determines the name of the docset feed. A documentation feed provides an umbrella under which multiple - documentation sets from a single provider (such as a company or product suite) + documentation sets from a single provider (such as a company or product suite) can be grouped. ]]> </docs> @@ -2038,7 +2077,7 @@ hr.footer { <![CDATA[ This tag specifies a string that should uniquely identify the documentation set bundle. This should be a - reverse domain-name style string, e.g. <code>com.mycompany.MyDocSet</code>. + reverse domain-name style string, e.g. <code>com.mycompany.MyDocSet</code>. Doxygen will append <code>.docset</code> to the name. ]]> </docs> @@ -2047,8 +2086,8 @@ hr.footer { <docs> <![CDATA[ The \c DOCSET_PUBLISHER_ID -tag specifies a string that should uniquely identify -the documentation publisher. This should be a reverse domain-name style +tag specifies a string that should uniquely identify +the documentation publisher. This should be a reverse domain-name style string, e.g. <code>com.mycompany.MyDocSet.documentation</code>. ]]> </docs> @@ -2064,14 +2103,14 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ If the \c GENERATE_HTMLHELP tag is set to \c YES then - doxygen generates three additional HTML index files: - \c index.hhp, \c index.hhc, and \c index.hhk. The \c index.hhp is a - project file that can be read by - <a href="http://www.microsoft.com/en-us/download/details.aspx?id=21138"> + doxygen generates three additional HTML index files: + \c index.hhp, \c index.hhc, and \c index.hhk. The \c index.hhp is a + project file that can be read by + <a href="https://www.microsoft.com/en-us/download/details.aspx?id=21138"> Microsoft's HTML Help Workshop</a> on Windows. <br> - The HTML Help Workshop contains a compiler that can convert all HTML output + The HTML Help Workshop contains a compiler that can convert all HTML output generated by doxygen into a single compiled HTML file (`.chm`). Compiled HTML files are now used as the Windows 98 help format, and will replace the old Windows help format (`.hlp`) on all Windows platforms in the future. @@ -2095,7 +2134,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ The \c HHC_LOCATION tag can - be used to specify the location (absolute path including file name) of + be used to specify the location (absolute path including file name) of the HTML help compiler (\c hhc.exe). If non-empty, doxygen will try to run the HTML help compiler on the generated \c index.hhp. ]]> @@ -2113,9 +2152,9 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='string' id='CHM_INDEX_ENCODING' format='string' defval='' depends='GENERATE_HTMLHELP'> <docs> <![CDATA[ - The \c CHM_INDEX_ENCODING - is used to encode HtmlHelp index (\c hhk), content (\c hhc) and project file - content. + The \c CHM_INDEX_ENCODING + is used to encode HtmlHelp index (\c hhk), content (\c hhc) and project file + content. ]]> </docs> </option> @@ -2132,8 +2171,8 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='bool' id='TOC_EXPAND' defval='0' depends='GENERATE_HTMLHELP'> <docs> <![CDATA[ - The \c TOC_EXPAND flag can be set to \c YES to add extra items for - group members to the table of contents of the HTML help documentation + The \c TOC_EXPAND flag can be set to \c YES to add extra items for + group members to the table of contents of the HTML help documentation and to the tree view. ]]> </docs> @@ -2163,7 +2202,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <![CDATA[ The \c QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help Project output. For more information please see - <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>. + <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>. ]]> </docs> </option> @@ -2172,7 +2211,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <![CDATA[ The \c QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt Help Project output. For more information please see - <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>. + <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>. ]]> </docs> </option> @@ -2180,7 +2219,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ If the \c QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom filter to add. For more information please see - <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. + <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. ]]> </docs> </option> @@ -2189,7 +2228,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <![CDATA[ The \c QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the custom filter to add. For more information please see - <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. + <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. ]]> </docs> </option> @@ -2197,7 +2236,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ The \c QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's filter section matches. - <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. + <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. ]]> </docs> </option> @@ -2212,15 +2251,15 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='bool' id='GENERATE_ECLIPSEHELP' defval='0' depends='GENERATE_HTML'> <docs> <![CDATA[ - If the \c GENERATE_ECLIPSEHELP tag is set to \c YES, additional index files - will be generated, together with the HTML files, they form an `Eclipse` help - plugin. + If the \c GENERATE_ECLIPSEHELP tag is set to \c YES, additional index files + will be generated, together with the HTML files, they form an `Eclipse` help + plugin. - To install this plugin and make it available under the help contents - menu in `Eclipse`, the contents of the directory containing the HTML and XML - files needs to be copied into the plugins directory of eclipse. The name of - the directory within the plugins directory should be the same as - the \ref cfg_eclipse_doc_id "ECLIPSE_DOC_ID" value. + To install this plugin and make it available under the help contents + menu in `Eclipse`, the contents of the directory containing the HTML and XML + files needs to be copied into the plugins directory of eclipse. The name of + the directory within the plugins directory should be the same as + the \ref cfg_eclipse_doc_id "ECLIPSE_DOC_ID" value. After copying `Eclipse` needs to be restarted before the help appears. ]]> @@ -2229,8 +2268,8 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='string' id='ECLIPSE_DOC_ID' format='string' defval='org.doxygen.Project' depends='GENERATE_ECLIPSEHELP'> <docs> <![CDATA[ - A unique identifier for the `Eclipse` help plugin. When installing the plugin - the directory name containing the HTML and XML files should also have + A unique identifier for the `Eclipse` help plugin. When installing the plugin + the directory name containing the HTML and XML files should also have this name. Each documentation set should have its own identifier. ]]> </docs> @@ -2242,8 +2281,8 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. might be necessary to disable the index and replace it with your own. The \c DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top of each HTML page. A value of \c NO enables the index and the - value \c YES disables it. Since the tabs in the index contain the same - information as the navigation tree, you can set this option to \c YES if + value \c YES disables it. Since the tabs in the index contain the same + information as the navigation tree, you can set this option to \c YES if you also set \ref cfg_generate_treeview "GENERATE_TREEVIEW" to \c YES. ]]> </docs> @@ -2266,7 +2305,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. the \ref cfg_project_name "PROJECT_NAME". Since the tree basically has the same information as the tab index, you could - consider setting \ref cfg_disable_index "DISABLE_INDEX" to \c YES when + consider setting \ref cfg_disable_index "DISABLE_INDEX" to \c YES when enabling this option. ]]> </docs> @@ -2276,7 +2315,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ The \c ENUM_VALUES_PER_LINE tag can be used to set the number of enum values - that doxygen will group on one line in the generated HTML documentation. + that doxygen will group on one line in the generated HTML documentation. <br>Note that a value of 0 will completely suppress the enum values from appearing in the overview section. ]]> @@ -2294,8 +2333,8 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='bool' id='EXT_LINKS_IN_WINDOW' defval='0' depends='GENERATE_HTML'> <docs> <![CDATA[ - If the \c EXT_LINKS_IN_WINDOW option is set to \c YES, doxygen will open - links to external symbols imported via tag files in a separate window. + If the \c EXT_LINKS_IN_WINDOW option is set to \c YES, doxygen will open + links to external symbols imported via tag files in a separate window. ]]> </docs> </option> @@ -2305,7 +2344,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. Use this tag to change the font size of \f$\mbox{\LaTeX}\f$ formulas included as images in the HTML documentation. When you change the font size after a successful doxygen run you need - to manually remove any `form_*.png` images from the HTML + to manually remove any `form_*.png` images from the HTML output directory to force them to be regenerated. ]]> </docs> @@ -2313,23 +2352,23 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='bool' id='FORMULA_TRANSPARENT' defval='1' depends='GENERATE_HTML'> <docs> <![CDATA[ - Use the \c FORMULA_TRANSPARENT tag to determine whether or not the images - generated for formulas are transparent PNGs. Transparent PNGs are - not supported properly for IE 6.0, but are supported on all modern browsers. - <br>Note that when changing this option you need to delete any `form_*.png` files - in the HTML output directory before the changes have effect. + Use the \c FORMULA_TRANSPARENT tag to determine whether or not the images + generated for formulas are transparent PNGs. Transparent PNGs are + not supported properly for IE 6.0, but are supported on all modern browsers. + <br>Note that when changing this option you need to delete any `form_*.png` files + in the HTML output directory before the changes have effect. ]]> </docs> </option> <option type='bool' id='USE_MATHJAX' defval='0' depends='GENERATE_HTML'> <docs> <![CDATA[ - Enable the \c USE_MATHJAX option to render \f$\mbox{\LaTeX}\f$ formulas using MathJax - (see https://www.mathjax.org) which uses client side Javascript for the - rendering instead of using pre-rendered bitmaps. Use this if you do not - have \f$\mbox{\LaTeX}\f$ installed or if you want to formulas look prettier in the HTML - output. When enabled you may also need to install MathJax separately and - configure the path to it using the \ref cfg_mathjax_relpath "MATHJAX_RELPATH" + Enable the \c USE_MATHJAX option to render \f$\mbox{\LaTeX}\f$ formulas using MathJax + (see https://www.mathjax.org) which uses client side Javascript for the + rendering instead of using pre-rendered bitmaps. Use this if you do not + have \f$\mbox{\LaTeX}\f$ installed or if you want to formulas look prettier in the HTML + output. When enabled you may also need to install MathJax separately and + configure the path to it using the \ref cfg_mathjax_relpath "MATHJAX_RELPATH" option. ]]> </docs> @@ -2337,7 +2376,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='enum' id='MATHJAX_FORMAT' defval='HTML-CSS' depends='USE_MATHJAX'> <docs> <![CDATA[ - When MathJax is enabled you can set the default output format to be used for + When MathJax is enabled you can set the default output format to be used for the MathJax output. See <a href="http://docs.mathjax.org/en/latest/output.html">the MathJax site</a> for more details. @@ -2347,16 +2386,16 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <value name="NativeMML" desc="(i.e. MathML)"/> <value name="SVG"/> </option> - <option type='string' id='MATHJAX_RELPATH' format='string' defval='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/' depends='USE_MATHJAX'> + <option type='string' id='MATHJAX_RELPATH' format='string' defval='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/' depends='USE_MATHJAX'> <docs> <![CDATA[ - When MathJax is enabled you need to specify the location relative to the - HTML output directory using the \c MATHJAX_RELPATH option. The destination - directory should contain the `MathJax.js` script. For instance, if the \c mathjax - directory is located at the same level as the HTML output directory, then - \c MATHJAX_RELPATH should be <code>../mathjax</code>. The default value points to - the MathJax Content Delivery Network so you can quickly see the result without - installing MathJax. However, it is strongly recommended to install a local + When MathJax is enabled you need to specify the location relative to the + HTML output directory using the \c MATHJAX_RELPATH option. The destination + directory should contain the `MathJax.js` script. For instance, if the \c mathjax + directory is located at the same level as the HTML output directory, then + \c MATHJAX_RELPATH should be <code>../mathjax</code>. The default value points to + the MathJax Content Delivery Network so you can quickly see the result without + installing MathJax. However, it is strongly recommended to install a local copy of MathJax from https://www.mathjax.org before deployment. ]]> </docs> @@ -2364,7 +2403,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <option type='list' id='MATHJAX_EXTENSIONS' format='string' depends='USE_MATHJAX'> <docs> <![CDATA[ - The \c MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax extension + The \c MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax extension names that should be enabled during MathJax rendering. For example \verbatim MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols @@ -2375,9 +2414,9 @@ MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols <option type='string' id='MATHJAX_CODEFILE' format='string' depends='USE_MATHJAX'> <docs> <![CDATA[ - The \c MATHJAX_CODEFILE tag can be used to specify a file with javascript - pieces of code that will be used on startup of the MathJax code. - See + The \c MATHJAX_CODEFILE tag can be used to specify a file with javascript + pieces of code that will be used on startup of the MathJax code. + See <a href="http://docs.mathjax.org/en/latest/output.html">the MathJax site</a> for more details. ]]> @@ -2394,7 +2433,7 @@ MATHJAX_CODEFILE = disableRenderer.js MathJax.Hub.Config({ menuSettings: { showRenderer: false, - } + } }); \endverbatim ]]> @@ -2409,24 +2448,24 @@ MATHJAX_CODEFILE = disableRenderer.js <docs> <![CDATA[ When the \c SEARCHENGINE tag is enabled doxygen will generate a search box - for the HTML output. The underlying search engine uses javascript + for the HTML output. The underlying search engine uses javascript and DHTML and should work on any modern browser. Note that when using - HTML help (\ref cfg_generate_htmlhelp "GENERATE_HTMLHELP"), + HTML help (\ref cfg_generate_htmlhelp "GENERATE_HTMLHELP"), Qt help (\ref cfg_generate_qhp "GENERATE_QHP"), or docsets - (\ref cfg_generate_docset "GENERATE_DOCSET") there is already a search - function so this one should typically be disabled. For large projects - the javascript based search engine can be slow, then enabling - \ref cfg_server_based_search "SERVER_BASED_SEARCH" may provide a - better solution. + (\ref cfg_generate_docset "GENERATE_DOCSET") there is already a search + function so this one should typically be disabled. For large projects + the javascript based search engine can be slow, then enabling + \ref cfg_server_based_search "SERVER_BASED_SEARCH" may provide a + better solution. It is possible to search using the keyboard; to jump to the search box use <code>\<access key\> + S</code> (what the <code>\<access key\></code> is depends on the OS and browser, but it is typically <code>\<CTRL\></code>, <code>\<ALT\></code>/<code>\<option\></code>, or both). - Inside the search box use the <code>\<cursor down key\></code> to jump into the search + Inside the search box use the <code>\<cursor down key\></code> to jump into the search results window, the results can be navigated using the <code>\<cursor keys\></code>. Press <code>\<Enter\></code> to select an item or <code>\<escape\></code> to cancel the search. The filter options can be selected when the cursor is inside the search box - by pressing <code>\<Shift\>+\<cursor down\></code>. Also here use the <code>\<cursor keys\></code> to + by pressing <code>\<Shift\>+\<cursor down\></code>. Also here use the <code>\<cursor keys\></code> to select a filter and <code>\<Enter\></code> or <code>\<escape\></code> to activate or cancel the filter option. ]]> </docs> @@ -2434,14 +2473,14 @@ MATHJAX_CODEFILE = disableRenderer.js <option type='bool' id='SERVER_BASED_SEARCH' defval='0' depends='SEARCHENGINE'> <docs> <![CDATA[ -When the \c SERVER_BASED_SEARCH tag is enabled the search engine will be -implemented using a web server instead of a web client using Javascript. +When the \c SERVER_BASED_SEARCH tag is enabled the search engine will be +implemented using a web server instead of a web client using Javascript. -There are two flavors of web server based searching depending on the -\ref cfg_external_search "EXTERNAL_SEARCH" setting. When disabled, -doxygen will generate a PHP script for searching and an index file used -by the script. When \ref cfg_external_search "EXTERNAL_SEARCH" is -enabled the indexing and searching needs to be provided by external tools. +There are two flavors of web server based searching depending on the +\ref cfg_external_search "EXTERNAL_SEARCH" setting. When disabled, +doxygen will generate a PHP script for searching and an index file used +by the script. When \ref cfg_external_search "EXTERNAL_SEARCH" is +enabled the indexing and searching needs to be provided by external tools. See the section \ref extsearch for details. ]]> </docs> @@ -2449,14 +2488,14 @@ See the section \ref extsearch for details. <option type='bool' id='EXTERNAL_SEARCH' defval='0' depends='SEARCHENGINE'> <docs> <![CDATA[ - When \c EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP - script for searching. Instead the search results are written to an XML file - which needs to be processed by an external indexer. Doxygen will invoke an - external search engine pointed to by the - \ref cfg_searchengine_url "SEARCHENGINE_URL" option to obtain + When \c EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP + script for searching. Instead the search results are written to an XML file + which needs to be processed by an external indexer. Doxygen will invoke an + external search engine pointed to by the + \ref cfg_searchengine_url "SEARCHENGINE_URL" option to obtain the search results. - <br>Doxygen ships with an example indexer (\c doxyindexer) and - search engine (<code>doxysearch.cgi</code>) which are based on the open source search + <br>Doxygen ships with an example indexer (\c doxyindexer) and + search engine (<code>doxysearch.cgi</code>) which are based on the open source search engine library <a href="https://xapian.org/">Xapian</a>. <br>See the section \ref extsearch for details. ]]> @@ -2465,11 +2504,11 @@ See the section \ref extsearch for details. <option type='string' id='SEARCHENGINE_URL' format='string' defval='' depends='SEARCHENGINE'> <docs> <![CDATA[ - The \c SEARCHENGINE_URL should point to a search engine hosted by a web server - which will return the search results when \ref cfg_external_search "EXTERNAL_SEARCH" + The \c SEARCHENGINE_URL should point to a search engine hosted by a web server + which will return the search results when \ref cfg_external_search "EXTERNAL_SEARCH" is enabled. - <br>Doxygen ships with an example indexer (\c doxyindexer) and - search engine (<code>doxysearch.cgi</code>) which are based on the open source search + <br>Doxygen ships with an example indexer (\c doxyindexer) and + search engine (<code>doxysearch.cgi</code>) which are based on the open source search engine library <a href="https://xapian.org/">Xapian</a>. See the section \ref extsearch for details. ]]> @@ -2478,9 +2517,9 @@ See the section \ref extsearch for details. <option type='string' id='SEARCHDATA_FILE' format='file' defval='searchdata.xml' depends='SEARCHENGINE'> <docs> <![CDATA[ -When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and -\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the unindexed -search data is written to a file for indexing by an external tool. With the +When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and +\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the unindexed +search data is written to a file for indexing by an external tool. With the \c SEARCHDATA_FILE tag the name of this file can be specified. ]]> </docs> @@ -2488,10 +2527,10 @@ search data is written to a file for indexing by an external tool. With the <option type='string' id='EXTERNAL_SEARCH_ID' format='string' defval='' depends='SEARCHENGINE'> <docs> <![CDATA[ -When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and -\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the -\c EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -useful in combination with \ref cfg_extra_search_mappings "EXTRA_SEARCH_MAPPINGS" +When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and +\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the +\c EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +useful in combination with \ref cfg_extra_search_mappings "EXTRA_SEARCH_MAPPINGS" to search through multiple projects and redirect the results back to the right project. ]]> </docs> @@ -2499,16 +2538,16 @@ to search through multiple projects and redirect the results back to the right p <option type='list' id='EXTRA_SEARCH_MAPPINGS' format='string' depends='SEARCHENGINE'> <docs> <![CDATA[ - The \c EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen - projects other than the one defined by this configuration file, but that are - all added to the same external search index. Each project needs to have a - unique id set via \ref cfg_external_search_id "EXTERNAL_SEARCH_ID". - The search mapping then maps the id of to a relative location where the - documentation can be found. + The \c EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen + projects other than the one defined by this configuration file, but that are + all added to the same external search index. Each project needs to have a + unique id set via \ref cfg_external_search_id "EXTERNAL_SEARCH_ID". + The search mapping then maps the id of to a relative location where the + documentation can be found. - The format is: + The format is: \verbatim -EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... \endverbatim ]]> </docs> @@ -2526,28 +2565,43 @@ EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... <option type='string' id='LATEX_OUTPUT' format='dir' defval='latex' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c LATEX_OUTPUT tag is used to specify where the \f$\mbox{\LaTeX}\f$ + The \c LATEX_OUTPUT tag is used to specify where the \f$\mbox{\LaTeX}\f$ docs will be put. If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in front of it. ]]> </docs> </option> - <option type='string' id='LATEX_CMD_NAME' format='file' defval='latex' depends='GENERATE_LATEX'> + <option type='string' id='LATEX_CMD_NAME' format='file' defval='' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c LATEX_CMD_NAME tag can be used to specify the \f$\mbox{\LaTeX}\f$ command name to be invoked. - <br>Note that when enabling \ref cfg_use_pdflatex "USE_PDFLATEX" this option is only used for - generating bitmaps for formulas in the HTML output, but not in the - \c Makefile that is written to the output directory. + The \c LATEX_CMD_NAME tag can be used to specify the \f$\mbox{\LaTeX}\f$ command name to be invoked. + <br>Note that when not enabling \ref cfg_use_pdflatex "USE_PDFLATEX" the default is \c latex when + enabling \ref cfg_use_pdflatex "USE_PDFLATEX" the default is \c pdflatex and when in the later case + \c latex is chosen this is overwritten by \c pdflatex. For specific output languages the default can + have been set differently, this depends on the implementation of the output language. ]]> </docs> </option> <option type='string' id='MAKEINDEX_CMD_NAME' format='file' defval='makeindex' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c MAKEINDEX_CMD_NAME tag can be used to specify the command name to + The \c MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate index for \f$\mbox{\LaTeX}\f$. + + @note This tag is used in the `Makefile` / `make.bat`. + \sa \ref cfg_latex_makeindex_cmd "LATEX_MAKEINDEX_CMD" for the part in the generated output file (`.tex`). +]]> + </docs> + </option> + <option type='string' id='LATEX_MAKEINDEX_CMD' defval='\makeindex' depends='GENERATE_LATEX'> + <docs> +<![CDATA[ + The \c LATEX_MAKEINDEX_CMD tag can be used to specify the command name to + generate index for \f$\mbox{\LaTeX}\f$. + + @note This tag is used in the generated output file (`.tex`). + \sa \ref cfg_makeindex_cmd_name "MAKEINDEX_CMD_NAME" for the part in the `Makefile` / `make.bat`. ]]> </docs> </option> @@ -2575,7 +2629,7 @@ EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... <option type='list' id='EXTRA_PACKAGES' format='string' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c EXTRA_PACKAGES tag can be used to specify one or more \f$\mbox{\LaTeX}\f$ + The \c EXTRA_PACKAGES tag can be used to specify one or more \f$\mbox{\LaTeX}\f$ package names that should be included in the \f$\mbox{\LaTeX}\f$ output. The package can be specified just by its name or with the correct syntax as to be used with the \f$\mbox{\LaTeX}\f$ `\usepackage` command. @@ -2583,7 +2637,7 @@ EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... To get the `times` font for instance you can specify : \verbatim EXTRA_PACKAGES=times -or +or EXTRA_PACKAGES={times} \endverbatim To use the option `intlimits` with the `amsmath` package you can specify: @@ -2597,21 +2651,21 @@ or <option type='string' id='LATEX_HEADER' format='file' defval='' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c LATEX_HEADER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$ - header for the generated \f$\mbox{\LaTeX}\f$ document. - The header should contain everything until the first chapter. + The \c LATEX_HEADER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$ + header for the generated \f$\mbox{\LaTeX}\f$ document. + The header should contain everything until the first chapter. - If it is left blank doxygen will generate a - standard header. See section \ref doxygen_usage for information on how to + If it is left blank doxygen will generate a + standard header. See section \ref doxygen_usage for information on how to let doxygen write the default header to a separate file. - + <br>Note: Only use a user-defined header if you know what you are doing! The following commands have a special meaning inside the header: <code>\$title</code>, <code>\$datetime</code>, <code>\$date</code>, - <code>\$doxygenversion</code>, <code>\$projectname</code>, - <code>\$projectnumber</code>, <code>\$projectbrief</code>, - <code>\$projectlogo</code>. + <code>\$doxygenversion</code>, <code>\$projectname</code>, + <code>\$projectnumber</code>, <code>\$projectbrief</code>, + <code>\$projectlogo</code>. Doxygen will replace <code>\$title</code> with the empty string, for the replacement values of the other commands the user is referred to \ref cfg_html_header "HTML_HEADER". ]]> @@ -2620,14 +2674,14 @@ or <option type='string' id='LATEX_FOOTER' format='file' defval='' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c LATEX_FOOTER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$ footer for - the generated \f$\mbox{\LaTeX}\f$ document. The footer should contain everything after - the last chapter. If it is left blank doxygen will generate a + The \c LATEX_FOOTER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$ footer for + the generated \f$\mbox{\LaTeX}\f$ document. The footer should contain everything after + the last chapter. If it is left blank doxygen will generate a standard footer. - See \ref cfg_latex_header "LATEX_HEADER" for more information on - how to generate a default footer and what special commands can be + See \ref cfg_latex_header "LATEX_HEADER" for more information on + how to generate a default footer and what special commands can be used inside the footer. - + <br>Note: Only use a user-defined footer if you know what you are doing! ]]> </docs> @@ -2635,10 +2689,10 @@ or <option type='list' id='LATEX_EXTRA_STYLESHEET' format='file' defval='' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c LATEX_EXTRA_STYLESHEET tag can be used to specify additional - user-defined \f$\mbox{\LaTeX}\f$ style sheets that are included after the standard - style sheets created by doxygen. Using this option one can overrule - certain style aspects. Doxygen will copy the style sheet files to + The \c LATEX_EXTRA_STYLESHEET tag can be used to specify additional + user-defined \f$\mbox{\LaTeX}\f$ style sheets that are included after the standard + style sheets created by doxygen. Using this option one can overrule + certain style aspects. Doxygen will copy the style sheet files to the output directory. \note The order of the extra style sheet files is of importance (e.g. the last style sheet in the list overrules the setting of the previous ones in the list). @@ -2659,8 +2713,8 @@ or <option type='bool' id='PDF_HYPERLINKS' defval='1' depends='GENERATE_LATEX'> <docs> <![CDATA[ - If the \c PDF_HYPERLINKS tag is set to \c YES, the \f$\mbox{\LaTeX}\f$ that - is generated is prepared for conversion to PDF (using \c ps2pdf or \c pdflatex). + If the \c PDF_HYPERLINKS tag is set to \c YES, the \f$\mbox{\LaTeX}\f$ that + is generated is prepared for conversion to PDF (using \c ps2pdf or \c pdflatex). The PDF file will contain links (just like the HTML output) instead of page references. This makes the output suitable for online browsing using a PDF viewer. @@ -2672,7 +2726,7 @@ or <![CDATA[ If the \c USE_PDFLATEX tag is set to \c YES, doxygen will use \c pdflatex to generate the PDF file directly from the \f$\mbox{\LaTeX}\f$ - files. Set this option to \c YES, to get a higher quality PDF documentation. + files. Set this option to \c YES, to get a higher quality PDF documentation. ]]> </docs> </option> @@ -2680,9 +2734,9 @@ or <docs> <![CDATA[ If the \c LATEX_BATCHMODE tag is set to \c YES, doxygen will add the \c \\batchmode - command to the generated \f$\mbox{\LaTeX}\f$ files. This will - instruct \f$\mbox{\LaTeX}\f$ to keep running if errors occur, instead of - asking the user for help. This option is also used when generating formulas + command to the generated \f$\mbox{\LaTeX}\f$ files. This will + instruct \f$\mbox{\LaTeX}\f$ to keep running if errors occur, instead of + asking the user for help. This option is also used when generating formulas in HTML. ]]> </docs> @@ -2691,17 +2745,17 @@ or <docs> <![CDATA[ If the \c LATEX_HIDE_INDICES tag is set to \c YES then doxygen will not - include the index chapters (such as File Index, Compound Index, etc.) - in the output. + include the index chapters (such as File Index, Compound Index, etc.) + in the output. ]]> </docs> </option> <option type='bool' id='LATEX_SOURCE_CODE' defval='0' depends='GENERATE_LATEX'> <docs> <![CDATA[ - If the \c LATEX_SOURCE_CODE tag is set to \c YES then doxygen will include - source code with syntax highlighting in the \f$\mbox{\LaTeX}\f$ output. - <br>Note that which sources are shown also depends on other settings + If the \c LATEX_SOURCE_CODE tag is set to \c YES then doxygen will include + source code with syntax highlighting in the \f$\mbox{\LaTeX}\f$ output. + <br>Note that which sources are shown also depends on other settings such as \ref cfg_source_browser "SOURCE_BROWSER". ]]> </docs> @@ -2709,8 +2763,8 @@ or <option type='string' id='LATEX_BIB_STYLE' format='string' defval='plain' depends='GENERATE_LATEX'> <docs> <![CDATA[ - The \c LATEX_BIB_STYLE tag can be used to specify the style to use for the - bibliography, e.g. \c plainnat, or \c ieeetr. + The \c LATEX_BIB_STYLE tag can be used to specify the style to use for the + bibliography, e.g. \c plainnat, or \c ieeetr. See https://en.wikipedia.org/wiki/BibTeX and \ref cmdcite "\\cite" for more info. ]]> @@ -2726,6 +2780,16 @@ or ]]> </docs> </option> + <option type='string' id='LATEX_EMOJI_DIRECTORY' format='dir' defval='' depends='GENERATE_LATEX'> + <docs> +<![CDATA[ + The \c LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) + path from which the emoji images will be read. + If a relative path is entered, it will be relative to the \ref cfg_latex_output "LATEX_OUTPUT" + directory. If left blank the \ref cfg_latex_output "LATEX_OUTPUT" directory will be used. +]]> + </docs> + </option> </group> <group name='RTF' docs='Configuration options related to the RTF output'> <option type='bool' id='GENERATE_RTF' defval='0'> @@ -2772,7 +2836,7 @@ or <docs> <![CDATA[ Load stylesheet definitions from file. Syntax is similar to doxygen's - config file, i.e. a series of assignments. You only have to provide + configuration file, i.e. a series of assignments. You only have to provide replacements, missing definitions are set to their default value. <br> See also section \ref doxygen_usage for information on how to generate @@ -2785,8 +2849,8 @@ or <docs> <![CDATA[ Set optional variables used in the generation of an RTF document. - Syntax is similar to doxygen's config file. - A template extensions file can be generated using + Syntax is similar to doxygen's configuration file. + A template extensions file can be generated using <code>doxygen -e rtf extensionFile</code>. ]]> </docs> @@ -2816,8 +2880,8 @@ or <![CDATA[ The \c MAN_OUTPUT tag is used to specify where the man pages will be put. If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be - put in front of it. - A directory \c man3 will be created inside the directory specified by + put in front of it. + A directory \c man3 will be created inside the directory specified by \c MAN_OUTPUT. ]]> </docs> @@ -2844,10 +2908,10 @@ or <option type='bool' id='MAN_LINKS' defval='0' depends='GENERATE_MAN'> <docs> <![CDATA[ - If the \c MAN_LINKS tag is set to \c YES and doxygen generates man output, - then it will generate one additional man file for each entity documented in - the real man page(s). These additional files only source the real man page, - but without them the \c man command would be unable to find the correct page. + If the \c MAN_LINKS tag is set to \c YES and doxygen generates man output, + then it will generate one additional man file for each entity documented in + the real man page(s). These additional files only source the real man page, + but without them the \c man command would be unable to find the correct page. ]]> </docs> </option> @@ -2858,15 +2922,15 @@ or <![CDATA[ If the \c GENERATE_XML tag is set to \c YES, doxygen will generate an XML file that captures the structure of - the code including all documentation. + the code including all documentation. ]]> </docs> </option> <option type='string' id='XML_OUTPUT' format='dir' defval='xml' depends='GENERATE_XML'> <docs> <![CDATA[ - The \c XML_OUTPUT tag is used to specify where the XML pages will be put. - If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be + The \c XML_OUTPUT tag is used to specify where the XML pages will be put. + If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in front of it. ]]> </docs> @@ -2895,7 +2959,7 @@ or <option type='bool' id='GENERATE_DOCBOOK' defval='0'> <docs> <![CDATA[ -If the \c GENERATE_DOCBOOK tag is set to \c YES, doxygen will generate Docbook files +If the \c GENERATE_DOCBOOK tag is set to \c YES, doxygen will generate Docbook files that can be used to generate PDF. ]]> </docs> @@ -2903,8 +2967,8 @@ that can be used to generate PDF. <option type='string' id='DOCBOOK_OUTPUT' format='dir' defval='docbook' depends='GENERATE_DOCBOOK'> <docs> <![CDATA[ -The \c DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. -If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in +The \c DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in front of it. ]]> </docs> @@ -2927,8 +2991,8 @@ front of it. If the \c GENERATE_AUTOGEN_DEF tag is set to \c YES, doxygen will generate an AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures the structure of the code including all - documentation. Note that this feature is still experimental - and incomplete at the moment. + documentation. Note that this feature is still experimental + and incomplete at the moment. ]]> </docs> </option> @@ -2946,8 +3010,8 @@ If the \c GENERATE_SQLITE3 tag is set to \c YES doxygen will generate a <option type='string' id='SQLITE3_OUTPUT' format='dir' defval='sqlite3' depends='GENERATE_SQLITE3'> <docs> <![CDATA[ -The \c SQLITE3_OUTPUT tag is used to specify where the \c Sqlite3 database will be put. -If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be +The \c SQLITE3_OUTPUT tag is used to specify where the \c Sqlite3 database will be put. +If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in front of it. ]]> </docs> @@ -2962,7 +3026,7 @@ put in front of it. If the \c GENERATE_PERLMOD tag is set to \c YES, doxygen will generate a Perl module file that captures the structure of the code including all documentation. - <br>Note that this + <br>Note that this feature is still experimental and incomplete at the moment. ]]> @@ -2971,28 +3035,28 @@ put in front of it. <option type='bool' id='PERLMOD_LATEX' defval='0' depends='GENERATE_PERLMOD'> <docs> <![CDATA[ - If the \c PERLMOD_LATEX tag is set to \c YES, doxygen will generate - the necessary \c Makefile rules, \c Perl scripts and \f$\mbox{\LaTeX}\f$ code to be able - to generate PDF and DVI output from the Perl module output. + If the \c PERLMOD_LATEX tag is set to \c YES, doxygen will generate + the necessary \c Makefile rules, \c Perl scripts and \f$\mbox{\LaTeX}\f$ code to be able + to generate PDF and DVI output from the Perl module output. ]]> </docs> </option> <option type='bool' id='PERLMOD_PRETTY' defval='1' depends='GENERATE_PERLMOD'> <docs> <![CDATA[ - If the \c PERLMOD_PRETTY tag is set to \c YES, the Perl module output will be - nicely formatted so it can be parsed by a human reader. This is useful + If the \c PERLMOD_PRETTY tag is set to \c YES, the Perl module output will be + nicely formatted so it can be parsed by a human reader. This is useful if you want to understand what is going on. On the other hand, if this tag is set to \c NO, the size of the Perl module output will be much smaller - and Perl will parse it just the same. + and Perl will parse it just the same. ]]> </docs> </option> <option type='string' id='PERLMOD_MAKEVAR_PREFIX' format='string' defval='' depends='GENERATE_PERLMOD'> <docs> <![CDATA[ - The names of the make variables in the generated `doxyrules.make` file - are prefixed with the string contained in \c PERLMOD_MAKEVAR_PREFIX. + The names of the make variables in the generated `doxyrules.make` file + are prefixed with the string contained in \c PERLMOD_MAKEVAR_PREFIX. This is useful so different `doxyrules.make` files included by the same `Makefile` don't overwrite each other's variables. ]]> @@ -3005,7 +3069,7 @@ put in front of it. <![CDATA[ If the \c ENABLE_PREPROCESSING tag is set to \c YES, doxygen will evaluate all C-preprocessor directives found in the sources and include - files. + files. ]]> </docs> </option> @@ -3013,7 +3077,7 @@ put in front of it. <docs> <![CDATA[ If the \c MACRO_EXPANSION tag is set to \c YES, doxygen will expand all macro - names in the source code. If set to \c NO, only conditional + names in the source code. If set to \c NO, only conditional compilation will be performed. Macro expansion can be done in a controlled way by setting \ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" to \c YES. ]]> @@ -3048,10 +3112,10 @@ put in front of it. <option type='list' id='INCLUDE_FILE_PATTERNS' format='string' depends='ENABLE_PREPROCESSING'> <docs> <![CDATA[ - You can use the \c INCLUDE_FILE_PATTERNS tag to specify one or more wildcard - patterns (like `*.h` and `*.hpp`) to filter out the header-files in the - directories. If left blank, the patterns specified with \ref cfg_file_patterns "FILE_PATTERNS" will - be used. + You can use the \c INCLUDE_FILE_PATTERNS tag to specify one or more wildcard + patterns (like `*.h` and `*.hpp`) to filter out the header-files in the + directories. If left blank, the patterns specified with \ref cfg_file_patterns "FILE_PATTERNS" will + be used. ]]> </docs> </option> @@ -3061,7 +3125,7 @@ put in front of it. The \c PREDEFINED tag can be used to specify one or more macro names that are defined before the preprocessor is started (similar to the `-D` option of e.g. \c gcc). The argument of the tag is a list of macros of the form: - <code>name</code> or <code>name=definition</code> (no spaces). + <code>name</code> or <code>name=definition</code> (no spaces). If the definition and the \c "=" are omitted, \c "=1" is assumed. To prevent a macro definition from being undefined via \c \#undef or recursively expanded use the <code>:=</code> operator instead of the \c = operator. @@ -3076,18 +3140,18 @@ put in front of it. this tag can be used to specify a list of macro names that should be expanded. The macro definition that is found in the sources will be used. Use the \ref cfg_predefined "PREDEFINED" tag if you want to use a different macro definition that - overrules the definition found in the source code. + overrules the definition found in the source code. ]]> </docs> </option> <option type='bool' id='SKIP_FUNCTION_MACROS' defval='1' depends='ENABLE_PREPROCESSING'> <docs> <![CDATA[ - If the \c SKIP_FUNCTION_MACROS tag is set to \c YES then - doxygen's preprocessor will remove all references to function-like macros that are alone - on a line, have an all uppercase name, and do not end with a semicolon. - Such function macros are typically - used for boiler-plate code, and will confuse the parser if not removed. + If the \c SKIP_FUNCTION_MACROS tag is set to \c YES then + doxygen's preprocessor will remove all references to function-like macros that are alone + on a line, have an all uppercase name, and do not end with a semicolon. + Such function macros are typically + used for boiler-plate code, and will confuse the parser if not removed. ]]> </docs> </option> @@ -3096,25 +3160,25 @@ put in front of it. <option type='list' id='TAGFILES' format='file'> <docs> <![CDATA[ - The \c TAGFILES tag can be used to specify one or more tag files. + The \c TAGFILES tag can be used to specify one or more tag files. -For each -tag file the location of the external documentation should be added. The -format of a tag file without this location is as follows: +For each +tag file the location of the external documentation should be added. The +format of a tag file without this location is as follows: \verbatim - TAGFILES = file1 file2 ... + TAGFILES = file1 file2 ... \endverbatim -Adding location for the tag files is done as follows: +Adding location for the tag files is done as follows: \verbatim - TAGFILES = file1=loc1 "file2 = loc2" ... + TAGFILES = file1=loc1 "file2 = loc2" ... \endverbatim where `loc1` and `loc2` can be relative or absolute paths or URLs. See the section \ref external for more information about the use of tag files. \note - Each tag file must have a unique name + Each tag file must have a unique name (where the name does \e NOT include the path). - If a tag file is not located in the directory in which doxygen + If a tag file is not located in the directory in which doxygen is run, you must also specify the path to the tagfile here. ]]> </docs> @@ -3124,7 +3188,7 @@ where `loc1` and `loc2` can be relative or absolute paths or URLs. <![CDATA[ When a file name is specified after \c GENERATE_TAGFILE, doxygen will create a tag file that is based on the input files it reads. - See section \ref external for more information about the usage of + See section \ref external for more information about the usage of tag files. ]]> </docs> @@ -3150,9 +3214,9 @@ where `loc1` and `loc2` can be relative or absolute paths or URLs. <option type='bool' id='EXTERNAL_PAGES' defval='1'> <docs> <![CDATA[ - If the \c EXTERNAL_PAGES tag is set to \c YES, all external pages will be listed - in the related pages index. If set to \c NO, only the current project's - pages will be listed. + If the \c EXTERNAL_PAGES tag is set to \c YES, all external pages will be listed + in the related pages index. If set to \c NO, only the current project's + pages will be listed. ]]> </docs> </option> @@ -3171,19 +3235,19 @@ where `loc1` and `loc2` can be relative or absolute paths or URLs. <![CDATA[ If the \c CLASS_DIAGRAMS tag is set to \c YES, doxygen will generate a class diagram (in HTML and \f$\mbox{\LaTeX}\f$) for classes with base or - super classes. Setting the tag to \c NO turns the diagrams off. Note that - this option also works with \ref cfg_have_dot "HAVE_DOT" disabled, but it is recommended to - install and use \c dot, since it yields more powerful graphs. + super classes. Setting the tag to \c NO turns the diagrams off. Note that + this option also works with \ref cfg_have_dot "HAVE_DOT" disabled, but it is recommended to + install and use \c dot, since it yields more powerful graphs. ]]> </docs> </option> <option type='string' id='MSCGEN_PATH' format='dir' defval=''> <docs> <![CDATA[ - You can define message sequence charts within doxygen comments using the \ref cmdmsc "\\msc" - command. Doxygen will then run the <a href="http://www.mcternan.me.uk/mscgen/">mscgen tool</a>) to - produce the chart and insert it in the documentation. The <code>MSCGEN_PATH</code> tag allows you to - specify the directory where the \c mscgen tool resides. If left empty the tool is assumed to + You can define message sequence charts within doxygen comments using the \ref cmdmsc "\\msc" + command. Doxygen will then run the <a href="http://www.mcternan.me.uk/mscgen/">mscgen tool</a>) to + produce the chart and insert it in the documentation. The <code>MSCGEN_PATH</code> tag allows you to + specify the directory where the \c mscgen tool resides. If left empty the tool is assumed to be found in the default search path. ]]> </docs> @@ -3191,9 +3255,9 @@ where `loc1` and `loc2` can be relative or absolute paths or URLs. <option type='string' id='DIA_PATH' format='dir' defval=''> <docs> <![CDATA[ -You can include diagrams made with dia in doxygen documentation. Doxygen will then run -dia to produce the diagram and insert it in the documentation. The DIA_PATH tag allows -you to specify the directory where the dia binary resides. If left empty dia is assumed +You can include diagrams made with dia in doxygen documentation. Doxygen will then run +dia to produce the diagram and insert it in the documentation. The DIA_PATH tag allows +you to specify the directory where the dia binary resides. If left empty dia is assumed to be found in the default search path. ]]> </docs> @@ -3211,9 +3275,9 @@ to be found in the default search path. <docs> <![CDATA[ If you set the \c HAVE_DOT tag to \c YES then doxygen will assume the \c dot tool is - available from the \c path. This tool is part of - <a href="http://www.graphviz.org/">Graphviz</a>, a graph - visualization toolkit from AT\&T and Lucent Bell Labs. The other options in + available from the \c path. This tool is part of + <a href="http://www.graphviz.org/">Graphviz</a>, a graph + visualization toolkit from AT\&T and Lucent Bell Labs. The other options in this section have no effect if this option is set to \c NO ]]> </docs> @@ -3221,11 +3285,11 @@ to be found in the default search path. <option type='int' id='DOT_NUM_THREADS' defval='0' minval='0' maxval='32' depends='HAVE_DOT'> <docs> <![CDATA[ - The \c DOT_NUM_THREADS specifies the number of \c dot invocations doxygen is - allowed to run in parallel. When set to \c 0 doxygen will - base this on the number of processors available in the system. You can set it - explicitly to a value larger than 0 to get control over the balance - between CPU load and processing speed. + The \c DOT_NUM_THREADS specifies the number of \c dot invocations doxygen is + allowed to run in parallel. When set to \c 0 doxygen will + base this on the number of processors available in the system. You can set it + explicitly to a value larger than 0 to get control over the balance + between CPU load and processing speed. ]]> </docs> </option> @@ -3233,11 +3297,11 @@ to be found in the default search path. <docs> <![CDATA[ When you want a differently looking font in the dot files that doxygen generates - you can specify the font name - using \c DOT_FONTNAME. You need to make sure dot is able to find the font, - which can be done by putting it in a standard location or by setting the - \c DOTFONTPATH environment variable or by setting \ref cfg_dot_fontpath "DOT_FONTPATH" to the - directory containing the font. + you can specify the font name + using \c DOT_FONTNAME. You need to make sure dot is able to find the font, + which can be done by putting it in a standard location or by setting the + \c DOTFONTPATH environment variable or by setting \ref cfg_dot_fontpath "DOT_FONTPATH" to the + directory containing the font. ]]> </docs> </option> @@ -3252,8 +3316,8 @@ to be found in the default search path. <docs> <![CDATA[ By default doxygen will tell \c dot to use the default font as specified with \ref cfg_dot_fontname "DOT_FONTNAME". - If you specify a - different font using \ref cfg_dot_fontname "DOT_FONTNAME" you can set the path where \c dot + If you specify a + different font using \ref cfg_dot_fontname "DOT_FONTNAME" you can set the path where \c dot can find it using this tag. ]]> </docs> @@ -3263,7 +3327,7 @@ to be found in the default search path. <![CDATA[ If the \c CLASS_GRAPH tag is set to \c YES then doxygen will generate a graph for each documented class showing the direct and - indirect inheritance relations. Setting this tag to \c YES will force + indirect inheritance relations. Setting this tag to \c YES will force the \ref cfg_class_diagrams "CLASS_DIAGRAMS" tag to \c NO. ]]> </docs> @@ -3298,10 +3362,10 @@ to be found in the default search path. <option type='int' id='UML_LIMIT_NUM_FIELDS' defval='10' minval='0' maxval='100' depends='HAVE_DOT'> <docs> <![CDATA[ - If the \ref cfg_uml_look "UML_LOOK" tag is enabled, the fields and methods are shown inside - the class node. If there are many fields or methods and many nodes the - graph may become too big to be useful. The \c UML_LIMIT_NUM_FIELDS - threshold limits the number of items for each type to make the size more + If the \ref cfg_uml_look "UML_LOOK" tag is enabled, the fields and methods are shown inside + the class node. If there are many fields or methods and many nodes the + graph may become too big to be useful. The \c UML_LIMIT_NUM_FIELDS + threshold limits the number of items for each type to make the size more manageable. Set this to 0 for no limit. Note that the threshold may be exceeded by 50% before the limit is enforced. So when you set the threshold to 10, up to 15 fields may appear, but if the number exceeds 15, the @@ -3312,7 +3376,7 @@ to be found in the default search path. <option type='bool' id='TEMPLATE_RELATIONS' defval='0' depends='HAVE_DOT'> <docs> <![CDATA[ - If the \c TEMPLATE_RELATIONS tag is set to \c YES then + If the \c TEMPLATE_RELATIONS tag is set to \c YES then the inheritance and collaboration graphs will show the relations between templates and their instances. ]]> </docs> @@ -3321,7 +3385,7 @@ to be found in the default search path. <docs> <![CDATA[ If the \c INCLUDE_GRAPH, \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" and - \ref cfg_search_includes "SEARCH_INCLUDES" + \ref cfg_search_includes "SEARCH_INCLUDES" tags are set to \c YES then doxygen will generate a graph for each documented file showing the direct and indirect include dependencies of the file with other documented files. @@ -3342,12 +3406,12 @@ to be found in the default search path. <option type='bool' id='CALL_GRAPH' defval='0' depends='HAVE_DOT'> <docs> <![CDATA[ - If the \c CALL_GRAPH tag is set to \c YES then doxygen will - generate a call dependency graph for every global function or class method. + If the \c CALL_GRAPH tag is set to \c YES then doxygen will + generate a call dependency graph for every global function or class method. <br>Note that enabling this option will significantly increase the time of a run. - So in most cases it will be better to enable call graphs for selected - functions only using the \ref cmdcallgraph "\\callgraph" command. - Disabling a call graph can be accomplished by means of the command + So in most cases it will be better to enable call graphs for selected + functions only using the \ref cmdcallgraph "\\callgraph" command. + Disabling a call graph can be accomplished by means of the command \ref cmdhidecallgraph "\\hidecallgraph". ]]> </docs> @@ -3355,12 +3419,12 @@ to be found in the default search path. <option type='bool' id='CALLER_GRAPH' defval='0' depends='HAVE_DOT'> <docs> <![CDATA[ - If the \c CALLER_GRAPH tag is set to \c YES then doxygen will - generate a caller dependency graph for every global function or class method. + If the \c CALLER_GRAPH tag is set to \c YES then doxygen will + generate a caller dependency graph for every global function or class method. <br>Note that enabling this option will significantly increase the time of a run. - So in most cases it will be better to enable caller graphs for selected - functions only using the \ref cmdcallergraph "\\callergraph" command. - Disabling a caller graph can be accomplished by means of the command + So in most cases it will be better to enable caller graphs for selected + functions only using the \ref cmdcallergraph "\\callergraph" command. + Disabling a caller graph can be accomplished by means of the command \ref cmdhidecallergraph "\\hidecallergraph". ]]> </docs> @@ -3368,7 +3432,7 @@ to be found in the default search path. <option type='bool' id='GRAPHICAL_HIERARCHY' defval='1' depends='HAVE_DOT'> <docs> <![CDATA[ - If the \c GRAPHICAL_HIERARCHY tag is set to \c YES then + If the \c GRAPHICAL_HIERARCHY tag is set to \c YES then doxygen will graphical hierarchy of all classes instead of a textual one. ]]> </docs> @@ -3376,7 +3440,7 @@ to be found in the default search path. <option type='bool' id='DIRECTORY_GRAPH' defval='1' depends='HAVE_DOT'> <docs> <![CDATA[ - If the \c DIRECTORY_GRAPH tag is set + If the \c DIRECTORY_GRAPH tag is set to \c YES then doxygen will show the dependencies a directory has on other directories in a graphical way. The dependency relations are determined by the \c \#include relations between the files in the directories. @@ -3390,7 +3454,7 @@ to be found in the default search path. generated by \c dot. For an explanation of the image formats see the section output formats in the documentation of the \c dot tool (<a href="http://www.graphviz.org/">Graphviz</a>). - \note If you choose \c svg you need to set + \note If you choose \c svg you need to set \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order to make the SVG files visible in IE 9+ (other browsers do not have this requirement). ]]> @@ -3412,10 +3476,10 @@ to be found in the default search path. <docs> <![CDATA[ If \ref cfg_dot_image_format "DOT_IMAGE_FORMAT" is set to \c svg, then this option can be set to \c YES to - enable generation of interactive SVG images that allow zooming and panning. - <br>Note that this requires a modern browser other than Internet Explorer. + enable generation of interactive SVG images that allow zooming and panning. + <br>Note that this requires a modern browser other than Internet Explorer. Tested and working are Firefox, Chrome, Safari, and Opera. - \note For IE 9+ you need to set \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order + \note For IE 9+ you need to set \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order to make the SVG files visible. Older versions of IE do not have SVG support. ]]> </docs> @@ -3423,15 +3487,15 @@ to be found in the default search path. <option type='string' id='DOT_PATH' format='dir' 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. - If left blank, it is assumed the \c dot tool can be found in the \c path. + The \c DOT_PATH tag can be used to specify the path where the \c dot tool can be found. + If left blank, it is assumed the \c dot tool can be found in the \c path. ]]> </docs> </option> <option type='list' id='DOTFILE_DIRS' format='dir' depends='HAVE_DOT'> <docs> <![CDATA[ - The \c DOTFILE_DIRS tag can be used to specify one or more directories that + The \c DOTFILE_DIRS tag can be used to specify one or more directories that contain dot files that are included in the documentation (see the \ref cmddotfile "\\dotfile" command). ]]> @@ -3440,7 +3504,7 @@ to be found in the default search path. <option type='list' id='MSCFILE_DIRS' format='dir'> <docs> <![CDATA[ - The \c MSCFILE_DIRS tag can be used to specify one or more directories that + The \c MSCFILE_DIRS tag can be used to specify one or more directories that contain msc files that are included in the documentation (see the \ref cmdmscfile "\\mscfile" command). ]]> @@ -3449,7 +3513,7 @@ to be found in the default search path. <option type='list' id='DIAFILE_DIRS' format='dir'> <docs> <![CDATA[ - The \c DIAFILE_DIRS tag can be used to specify one or more directories that + The \c DIAFILE_DIRS tag can be used to specify one or more directories that contain dia files that are included in the documentation (see the \ref cmddiafile "\\diafile" command). ]]> @@ -3458,9 +3522,9 @@ to be found in the default search path. <option type='string' id='PLANTUML_JAR_PATH' format='dir' defval=''> <docs> <![CDATA[ - When using plantuml, the \c PLANTUML_JAR_PATH tag should be used to specify the path where - java can find the \c plantuml.jar file. If left blank, it is assumed PlantUML is not used or - called during a preprocessing step. Doxygen will generate a warning when it encounters a + When using plantuml, the \c PLANTUML_JAR_PATH tag should be used to specify the path where + java can find the \c plantuml.jar file. If left blank, it is assumed PlantUML is not used or + called during a preprocessing step. Doxygen will generate a warning when it encounters a \ref cmdstartuml "\\startuml" command in this case and will not generate output for the diagram. ]]> </docs> @@ -3468,7 +3532,7 @@ to be found in the default search path. <option type='string' id='PLANTUML_CFG_FILE' format='file' defval=''> <docs> <![CDATA[ - When using plantuml, the \c PLANTUML_CFG_FILE tag can be used to specify a configuration + When using plantuml, the \c PLANTUML_CFG_FILE tag can be used to specify a configuration file for plantuml. ]]> </docs> @@ -3477,16 +3541,16 @@ to be found in the default search path. <docs> <![CDATA[ When using plantuml, the specified paths are searched for files specified by the \c !include - statement in a plantuml block. + statement in a plantuml block. ]]> </docs> </option> <option type='int' id='DOT_GRAPH_MAX_NODES' minval='0' maxval='10000' defval='50' depends='HAVE_DOT'> <docs> <![CDATA[ - The \c DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of + The \c DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes that will be shown in the graph. If the number of nodes in a graph - becomes larger than this value, doxygen will truncate the graph, which is + becomes larger than this value, doxygen will truncate the graph, which is visualized by representing a node as a red box. Note that doxygen if the number of direct children of the root node in a graph is already larger than \c DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note @@ -3497,7 +3561,7 @@ to be found in the default search path. <option type='int' id='MAX_DOT_GRAPH_DEPTH' minval='0' maxval='1000' defval='0' depends='HAVE_DOT'> <docs> <![CDATA[ - The \c MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the + The \c MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs generated by \c dot. A depth value of 3 means that only nodes reachable from the root by following a path via at most 3 edges will be shown. Nodes that lay further from the root node will be omitted. Note that setting this @@ -3511,12 +3575,12 @@ to be found in the default search path. <docs> <![CDATA[ Set the \c DOT_TRANSPARENT tag to \c YES to generate images with a transparent - background. This is disabled by default, because dot on Windows does not + background. This is disabled by default, because dot on Windows does not seem to support this out of the box. <br> - Warning: Depending on the platform used, - enabling this option may lead to badly anti-aliased labels on the edges of - a graph (i.e. they become hard to read). + Warning: Depending on the platform used, + enabling this option may lead to badly anti-aliased labels on the edges of + a graph (i.e. they become hard to read). ]]> </docs> </option> diff --git a/src/configgen.py b/src/configgen.py index 33857b7..ca2a5d1 100755 --- a/src/configgen.py +++ b/src/configgen.py @@ -272,7 +272,7 @@ def parseOption(node): print(" \"%s\"" % (line)) print(" );") if defval != '': - print(" cs->setDefaultValue(\"%s\");" % (defval)) + print(" cs->setDefaultValue(\"%s\");" % (defval.replace('\\','\\\\'))) if format == 'file': print(" cs->setWidgetType(ConfigString::File);") elif format == 'image': @@ -529,7 +529,7 @@ def parseOptionDoc(node, first): if defval != '': print("") print("The default value is: <code>%s</code>." % ( - defval)) + defval.replace('\\','\\\\'))) print("") # depends handling if (node.hasAttribute('depends')): diff --git a/src/configimpl.h b/src/configimpl.h index c901198..1594d47 100644 --- a/src/configimpl.h +++ b/src/configimpl.h @@ -73,7 +73,9 @@ class ConfigOption protected: virtual void writeTemplate(FTextStream &t,bool sl,bool upd) = 0; + virtual void compareDoxyfile(FTextStream &t) = 0; virtual void convertStrToVal() {} + virtual void emptyValueToDefault() {} virtual void substEnvVars() = 0; virtual void init() {} @@ -103,6 +105,7 @@ class ConfigInfo : public ConfigOption m_doc = doc; } void writeTemplate(FTextStream &t, bool sl,bool); + void compareDoxyfile(FTextStream &){}; void substEnvVars() {} }; @@ -124,6 +127,7 @@ class ConfigList : public ConfigOption WidgetType widgetType() const { return m_widgetType; } QStrList *valueRef() { return &m_value; } void writeTemplate(FTextStream &t,bool sl,bool); + void compareDoxyfile(FTextStream &t); void substEnvVars(); void init() { m_value = m_defaultValue; } private: @@ -153,6 +157,7 @@ class ConfigEnum : public ConfigOption QCString *valueRef() { return &m_value; } void substEnvVars(); void writeTemplate(FTextStream &t,bool sl,bool); + void compareDoxyfile(FTextStream &t); void init() { m_value = m_defValue.copy(); } private: @@ -182,8 +187,10 @@ class ConfigString : public ConfigOption void setDefaultValue(const char *v) { m_defValue = v; } QCString *valueRef() { return &m_value; } void writeTemplate(FTextStream &t,bool sl,bool); + void compareDoxyfile(FTextStream &t); void substEnvVars(); void init() { m_value = m_defValue.copy(); } + void emptyValueToDefault() { if(m_value.isEmpty()) m_value=m_defValue; }; private: QCString m_value; @@ -213,6 +220,7 @@ class ConfigInt : public ConfigOption void convertStrToVal(); void substEnvVars(); void writeTemplate(FTextStream &t,bool sl,bool upd); + void compareDoxyfile(FTextStream &t); void init() { m_value = m_defValue; } private: int m_value; @@ -241,6 +249,7 @@ class ConfigBool : public ConfigOption void substEnvVars(); void setValueString(const QCString &v) { m_valueString = v; } void writeTemplate(FTextStream &t,bool sl,bool upd); + void compareDoxyfile(FTextStream &t); void init() { m_value = m_defValue; } private: bool m_value; @@ -256,6 +265,7 @@ class ConfigObsolete : public ConfigOption ConfigObsolete(const char *name) : ConfigOption(O_Obsolete) { m_name = name; } void writeTemplate(FTextStream &,bool,bool); + void compareDoxyfile(FTextStream &) {} void substEnvVars() {} }; @@ -267,6 +277,7 @@ class ConfigDisabled : public ConfigOption ConfigDisabled(const char *name) : ConfigOption(O_Disabled) { m_name = name; } void writeTemplate(FTextStream &,bool,bool); + void compareDoxyfile(FTextStream &) {} void substEnvVars() {} }; @@ -466,6 +477,11 @@ class ConfigImpl */ void writeTemplate(FTextStream &t,bool shortIndex,bool updateOnly); + /*! Writes a the differences between the current configuration and the + * template configuration to stream \a t. + */ + void compareDoxyfile(FTextStream &t); + void setHeader(const char *header) { m_header = header; } ///////////////////////////// @@ -477,6 +493,10 @@ class ConfigImpl */ void convertStrToVal(); + /*! Sets default value in case value is empty + */ + void emptyValueToDefault(); + /*! Replaces references to environment variable by the actual value * of the environment variable. */ diff --git a/src/configimpl.l b/src/configimpl.l index df032a6..b533910 100644 --- a/src/configimpl.l +++ b/src/configimpl.l @@ -315,6 +315,77 @@ void ConfigList::writeTemplate(FTextStream &t,bool sl,bool) t << "\n"; } +void ConfigList::compareDoxyfile(FTextStream &t) +{ + const char *p = m_value.first(); + const char *q = m_defaultValue.first(); + int defCnt = 0; + int valCnt = 0; + + // count non empty elements + while (p) + { + QCString s=p; + if (!s.stripWhiteSpace().isEmpty()) valCnt += 1; + p = m_value.next(); + } + + while (q) + { + QCString s=q; + if (!s.stripWhiteSpace().isEmpty()) defCnt += 1; + q = m_defaultValue.next(); + } + if ( valCnt != defCnt) + { + writeTemplate(t,TRUE,TRUE); + return; + } + + // get first non empry element + q = m_defaultValue.first(); + p = m_value.first(); + QCString sp = p; + while (p && sp.stripWhiteSpace().isEmpty()) + { + p = m_value.next(); + sp = p; + } + QCString sq = q; + while (q && sq.stripWhiteSpace().isEmpty()) + { + q = m_value.next(); + sq = q; + } + while (p) + { + // skip empty elements + sp = p; + while (p && sp.stripWhiteSpace().isEmpty()) + { + p = m_value.next(); + sp = p; + } + sq = q; + while (q && sq.stripWhiteSpace().isEmpty()) + { + q = m_value.next(); + sq = q; + } + // be sure we have still an element (p and q have same number of 'filled' elements) + if (p) + { + if (sp.stripWhiteSpace() != sq.stripWhiteSpace()) + { + writeTemplate(t,TRUE,TRUE); + return; + } + p = m_value.next(); + q = m_defaultValue.next(); + } + } +} + void ConfigEnum::writeTemplate(FTextStream &t,bool sl,bool) { if (!sl) @@ -332,6 +403,11 @@ void ConfigEnum::writeTemplate(FTextStream &t,bool sl,bool) t << "\n"; } +void ConfigEnum::compareDoxyfile(FTextStream &t) +{ + if (m_value != m_defValue) writeTemplate(t,TRUE,TRUE); +} + void ConfigString::writeTemplate(FTextStream &t,bool sl,bool) { if (!sl) @@ -349,6 +425,11 @@ void ConfigString::writeTemplate(FTextStream &t,bool sl,bool) t << "\n"; } +void ConfigString::compareDoxyfile(FTextStream &t) +{ + if (m_value.stripWhiteSpace() != m_defValue.stripWhiteSpace()) writeTemplate(t,TRUE,TRUE); +} + void ConfigInt::writeTemplate(FTextStream &t,bool sl,bool upd) { if (!sl) @@ -373,6 +454,11 @@ void ConfigInt::writeTemplate(FTextStream &t,bool sl,bool upd) t << "\n"; } +void ConfigInt::compareDoxyfile(FTextStream &t) +{ + if (m_value != m_defValue) writeTemplate(t,TRUE,TRUE); +} + void ConfigBool::writeTemplate(FTextStream &t,bool sl,bool upd) { if (!sl) @@ -397,6 +483,11 @@ void ConfigBool::writeTemplate(FTextStream &t,bool sl,bool upd) t << "\n"; } +void ConfigBool::compareDoxyfile(FTextStream &t) +{ + if (m_value != m_defValue) writeTemplate(t,TRUE,TRUE); +} + void ConfigObsolete::writeTemplate(FTextStream &,bool,bool) {} void ConfigDisabled::writeTemplate(FTextStream &,bool,bool) {} @@ -777,7 +868,7 @@ static void readIncludeFile(const char *incName) } BEGIN(Start); } -<GetStrList>[ \t]+ { +<GetStrList>[ \t,]+ { if (!elemStr.isEmpty()) { //printf("elemStr2=`%s'\n",elemStr.data()); @@ -831,7 +922,7 @@ static void readIncludeFile(const char *incName) bs.data(),yyLineNr,yyFileName.data()); } } -<GetStrList>[^ \#\"\t\r\n]+ { +<GetStrList>[^ \#\"\t\r\n,]+ { elemStr+=configStringRecode(yytext,encoding,"UTF-8"); } <SkipComment>\n { yyLineNr++; BEGIN(Start); } @@ -871,6 +962,18 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd) } } +void ConfigImpl::compareDoxyfile(FTextStream &t) +{ + t << "# Difference with default Doxyfile " << versionString << endl; + QListIterator<ConfigOption> it = iterator(); + ConfigOption *option; + for (;(option=it.current());++it) + { + option->m_userComment = ""; + option->compareDoxyfile(t); + } +} + void ConfigImpl::convertStrToVal() { QListIterator<ConfigOption> it = iterator(); @@ -880,6 +983,15 @@ void ConfigImpl::convertStrToVal() option->convertStrToVal(); } } +void ConfigImpl::emptyValueToDefault() +{ + QListIterator<ConfigOption> it = iterator(); + ConfigOption *option; + for (;(option=it.current());++it) + { + option->emptyValueToDefault(); + } +} static void substEnvVarsInString(QCString &s) { @@ -1151,7 +1263,7 @@ static void cleanUpPaths(QStrList &str) char *sfp = str.first(); while (sfp) { - register char *p = sfp; + char *p = sfp; if (p) { char c; @@ -1749,14 +1861,21 @@ void Config::writeTemplate(FTextStream &t,bool shortList,bool update) ConfigImpl::instance()->writeTemplate(t,shortList,update); } +void Config::compareDoxyfile(FTextStream &t) +{ + postProcess(FALSE, TRUE); + ConfigImpl::instance()->compareDoxyfile(t); +} + bool Config::parse(const char *fileName,bool update) { return ConfigImpl::instance()->parse(fileName,update); } -void Config::postProcess(bool clearHeaderAndFooter) +void Config::postProcess(bool clearHeaderAndFooter, bool compare) { ConfigImpl::instance()->substituteEnvironmentVars(); + if (!compare)ConfigImpl::instance()->emptyValueToDefault(); ConfigImpl::instance()->convertStrToVal(); // avoid bootstrapping issues when the config file already diff --git a/src/context.cpp b/src/context.cpp index 896c4e0..6b5d2ac 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -246,7 +246,6 @@ class PropertyMapper /** Add a property to the map * @param[in] name The name of the property to add. - * @param[in] obj The object handling access to the property. * @param[in] handle The method to call when the property is accessed. */ void addProperty(const char *name,typename PropertyFunc::Handler handle) @@ -262,6 +261,7 @@ class PropertyMapper } /** Gets the value of a property. + * @param[in] obj The object handling access to the property. * @param[in] name The name of the property. * @returns A variant representing the properties value or an * invalid variant if it was not found. @@ -617,7 +617,7 @@ class TranslateContext::Private TemplateVariant classes() const { return theTranslator->trClasses(); - // TODO: VHDL: trVhdlType(VhdlDocGen::ENTITY,FALSE) + // TODO: VHDL: theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE) // TODO: Fortran: trDataTypes() } TemplateVariant classList() const @@ -658,7 +658,7 @@ class TranslateContext::Private { return theTranslator->trPackages(); } - else if (m_fortranOpt) + else if (m_fortranOpt || m_sliceOpt) { return theTranslator->trModules(); } @@ -689,7 +689,7 @@ class TranslateContext::Private { return theTranslator->trPackages(); } - else if (m_fortranOpt) + else if (m_fortranOpt || m_sliceOpt) { return theTranslator->trModulesList(); } @@ -704,7 +704,7 @@ class TranslateContext::Private { return theTranslator->trPackageMembers(); } - else if (m_fortranOpt) + else if (m_fortranOpt || m_sliceOpt) { return theTranslator->trModulesMembers(); } @@ -856,6 +856,14 @@ class TranslateContext::Private { return theTranslator->trCallerGraph(); } + TemplateVariant referencedByRelation() const + { + return theTranslator->trReferencedBy(); + } + TemplateVariant referencesRelation() const + { + return theTranslator->trReferences(); + } TemplateVariant inheritedFrom() const { return theTranslator->trInheritedFrom("@0","@1"); @@ -927,13 +935,14 @@ class TranslateContext::Private { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - return fortranOpt ? theTranslator->trSubprograms() : - vhdlOpt ? VhdlDocGen::trFunctionAndProc() : + return fortranOpt ? theTranslator->trSubprograms() : + vhdlOpt ? theTranslator->trFunctionAndProc() : theTranslator->trFunctions(); } TemplateVariant variables() const { - return theTranslator->trVariables(); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + return sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables(); } TemplateVariant typedefs() const { @@ -1112,6 +1121,10 @@ class TranslateContext::Private s_inst.addProperty("callGraph", &Private::callGraph); //%% string callerGraph s_inst.addProperty("callerGraph", &Private::callerGraph); + //%% string referencedByRelation + s_inst.addProperty("referencedByRelation", &Private::referencedByRelation); + //%% string referencesRelation + s_inst.addProperty("referencesRelation", &Private::referencesRelation); //%% markerstring inheritedFrom s_inst.addProperty("inheritedFrom", &Private::inheritedFrom); //%% string addtionalInheritedMembers @@ -1209,6 +1222,7 @@ class TranslateContext::Private m_javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); m_fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); m_vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); + m_sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); } TemplateVariant get(const char *n) const { @@ -1218,6 +1232,7 @@ class TranslateContext::Private bool m_javaOpt; bool m_fortranOpt; bool m_vhdlOpt; + bool m_sliceOpt; static PropertyMapper<TranslateContext::Private> s_inst; }; //%% } @@ -1525,6 +1540,7 @@ class DefinitionContext case SrcLangExt_SQL: result="sql"; break; case SrcLangExt_Tcl: result="tcl"; break; case SrcLangExt_Markdown: result="markdown"; break; + case SrcLangExt_Slice: result="slice"; break; } return result; } @@ -1985,16 +2001,32 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> { case ContextOutputFormat_Html: { + QGString result; + FTextStream tt(&result); + QCString name = convertToHtml(m_classDef->displayName()); - t << "<div class=\"center\">" << endl; - t << "<img src=\""; - t << relPathAsString() << m_classDef->getOutputFileBase(); - t << ".png\" usemap=\"#" << convertToId(name) << "_map\" alt=\"\"/>" << endl; - t << "<map id=\"" << convertToId(name) << "_map\" name=\"" << convertToId(name) << "_map\">" << endl; - d.writeImage(t,g_globals.outputDir, + d.writeImage(tt,g_globals.outputDir, relPathAsString(), m_classDef->getOutputFileBase()); - t << "</div>"; + if (!result.isEmpty()) + { + t << "<div class=\"center\">" << endl; + t << " <img src=\""; + t << relPathAsString() << m_classDef->getOutputFileBase(); + t << ".png\" usemap=\"#" << convertToId(name) << "_map\" alt=\"\"/>" << endl; + t << " <map id=\"" << convertToId(name) << "_map\" name=\"" << convertToId(name) << "_map\">" << endl; + t << result; + t << " </map>" << endl; + t << "</div>"; + } + else + { + t << "<div class=\"center\">" << endl; + t << " <img src=\""; + t << relPathAsString() << m_classDef->getOutputFileBase(); + t << ".png\" alt=\"\"/>" << endl; + t << "</div>"; + } } break; case ContextOutputFormat_Latex: @@ -2670,24 +2702,29 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri if (!init) { addBaseProperties(s_inst); - s_inst.addProperty("title", &Private::title); - s_inst.addProperty("highlight", &Private::highlight); - s_inst.addProperty("subhighlight", &Private::subHighlight); - s_inst.addProperty("compoundType", &Private::compoundType); - s_inst.addProperty("hasDetails", &Private::hasDetails); - s_inst.addProperty("classes", &Private::classes); - s_inst.addProperty("namespaces", &Private::namespaces); - s_inst.addProperty("constantgroups", &Private::constantgroups); - s_inst.addProperty("typedefs", &Private::typedefs); - s_inst.addProperty("enums", &Private::enums); - s_inst.addProperty("functions", &Private::functions); - s_inst.addProperty("variables", &Private::variables); - s_inst.addProperty("memberGroups", &Private::memberGroups); - s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); - s_inst.addProperty("detailedEnums", &Private::detailedEnums); - s_inst.addProperty("detailedFunctions", &Private::detailedFunctions); - s_inst.addProperty("detailedVariables", &Private::detailedVariables); - s_inst.addProperty("inlineClasses", &Private::inlineClasses); + s_inst.addProperty("title", &Private::title); + s_inst.addProperty("highlight", &Private::highlight); + s_inst.addProperty("subhighlight", &Private::subHighlight); + s_inst.addProperty("compoundType", &Private::compoundType); + s_inst.addProperty("hasDetails", &Private::hasDetails); + s_inst.addProperty("classes", &Private::classes); + //s_inst.addProperty("interfaces", &Private::interfaces); + s_inst.addProperty("namespaces", &Private::namespaces); + s_inst.addProperty("constantgroups", &Private::constantgroups); + s_inst.addProperty("typedefs", &Private::typedefs); + s_inst.addProperty("sequences", &Private::sequences); + s_inst.addProperty("dictionaries", &Private::dictionaries); + s_inst.addProperty("enums", &Private::enums); + s_inst.addProperty("functions", &Private::functions); + s_inst.addProperty("variables", &Private::variables); + s_inst.addProperty("memberGroups", &Private::memberGroups); + s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); + s_inst.addProperty("detailedSequences", &Private::detailedSequences); + s_inst.addProperty("detailedDictionaries", &Private::detailedDictionaries); + s_inst.addProperty("detailedEnums", &Private::detailedEnums); + s_inst.addProperty("detailedFunctions", &Private::detailedFunctions); + s_inst.addProperty("detailedVariables", &Private::detailedVariables); + s_inst.addProperty("inlineClasses", &Private::inlineClasses); init=TRUE; } if (!nd->cookie()) { nd->setCookie(new NamespaceContext::Private::Cachable(nd)); } @@ -2722,6 +2759,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri Cachable &cache = getCache(); if (!cache.classes) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); TemplateList *classList = TemplateList::alloc(); if (m_namespaceDef->getClassSDict()) { @@ -2729,6 +2767,12 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { + if (sliceOpt && (cd->compoundType()==ClassDef::Struct || + cd->compoundType()==ClassDef::Interface || + cd->compoundType()==ClassDef::Exception)) + { + continue; // These types appear in their own sections. + } if (cd->visibleInParentsDeclList()) { classList->append(ClassContext::alloc(cd)); @@ -2807,6 +2851,14 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri { return getMemberList(getCache().typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs()); } + TemplateVariant sequences() const + { + return getMemberList(getCache().sequences,MemberListType_decSequenceMembers,theTranslator->trSequences()); + } + TemplateVariant dictionaries() const + { + return getMemberList(getCache().dictionaries,MemberListType_decDictionaryMembers,theTranslator->trDictionaries()); + } TemplateVariant enums() const { return getMemberList(getCache().enums,MemberListType_decEnumMembers,theTranslator->trEnumerations()); @@ -2816,12 +2868,14 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri QCString title = theTranslator->trFunctions(); SrcLangExt lang = m_namespaceDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms(); - else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc(); + else if (lang==SrcLangExt_VHDL) title=theTranslator->trFunctionAndProc(); return getMemberList(getCache().functions,MemberListType_decFuncMembers,title); } TemplateVariant variables() const { - return getMemberList(getCache().variables,MemberListType_decVarMembers,theTranslator->trVariables()); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + return getMemberList(getCache().variables,MemberListType_decVarMembers, + sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } TemplateVariant memberGroups() const { @@ -2843,6 +2897,14 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri { return getMemberList(getCache().detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()); } + TemplateVariant detailedSequences() const + { + return getMemberList(getCache().detailedSequences,MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()); + } + TemplateVariant detailedDictionaries() const + { + return getMemberList(getCache().detailedDictionaries,MemberListType_docDictionaryMembers,theTranslator->trDictionaryDocumentation()); + } TemplateVariant detailedEnums() const { return getMemberList(getCache().detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); @@ -2856,7 +2918,10 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri } TemplateVariant detailedVariables() const { - return getMemberList(getCache().detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation()); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + return getMemberList(getCache().detailedVariables,MemberListType_docVarMembers, + sliceOpt ? theTranslator->trConstantDocumentation() : + theTranslator->trVariableDocumentation()); } TemplateVariant inlineClasses() const { @@ -2889,14 +2954,19 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri { Cachable(NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>::Cachable(nd) {} SharedPtr<TemplateList> classes; + SharedPtr<TemplateList> interfaces; SharedPtr<TemplateList> namespaces; SharedPtr<TemplateList> constantgroups; SharedPtr<MemberListInfoContext> typedefs; + SharedPtr<MemberListInfoContext> sequences; + SharedPtr<MemberListInfoContext> dictionaries; SharedPtr<MemberListInfoContext> enums; SharedPtr<MemberListInfoContext> functions; SharedPtr<MemberListInfoContext> variables; SharedPtr<MemberGroupListContext> memberGroups; SharedPtr<MemberListInfoContext> detailedTypedefs; + SharedPtr<MemberListInfoContext> detailedSequences; + SharedPtr<MemberListInfoContext> detailedDictionaries; SharedPtr<MemberListInfoContext> detailedEnums; SharedPtr<MemberListInfoContext> detailedFunctions; SharedPtr<MemberListInfoContext> detailedVariables; @@ -2961,12 +3031,16 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> s_inst.addProperty("constantgroups", &Private::constantgroups); s_inst.addProperty("macros", &Private::macros); s_inst.addProperty("typedefs", &Private::typedefs); + s_inst.addProperty("sequences", &Private::sequences); + s_inst.addProperty("dictionaries", &Private::dictionaries); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("detailedMacros", &Private::detailedMacros); s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); + s_inst.addProperty("detailedSequences", &Private::detailedSequences); + s_inst.addProperty("detailedDictionaries", &Private::detailedDictionaries); s_inst.addProperty("detailedEnums", &Private::detailedEnums); s_inst.addProperty("detailedFunctions", &Private::detailedFunctions); s_inst.addProperty("detailedVariables", &Private::detailedVariables); @@ -3240,6 +3314,14 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> { return getMemberList(getCache().typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs()); } + TemplateVariant sequences() const + { + return getMemberList(getCache().sequences,MemberListType_decSequenceMembers,theTranslator->trSequences()); + } + TemplateVariant dictionaries() const + { + return getMemberList(getCache().dictionaries,MemberListType_decDictionaryMembers,theTranslator->trDictionaries()); + } TemplateVariant enums() const { return getMemberList(getCache().enums,MemberListType_decEnumMembers,theTranslator->trEnumerations()); @@ -3249,12 +3331,14 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> QCString title = theTranslator->trFunctions(); SrcLangExt lang = m_fileDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms(); - else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc(); + else if (lang==SrcLangExt_VHDL) title=theTranslator->trFunctionAndProc(); return getMemberList(getCache().functions,MemberListType_decFuncMembers,title); } TemplateVariant variables() const { - return getMemberList(getCache().variables,MemberListType_decVarMembers,theTranslator->trVariables()); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + return getMemberList(getCache().variables,MemberListType_decVarMembers, + sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } TemplateVariant memberGroups() const { @@ -3280,6 +3364,14 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> { return getMemberList(getCache().detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()); } + TemplateVariant detailedSequences() const + { + return getMemberList(getCache().detailedSequences,MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()); + } + TemplateVariant detailedDictionaries() const + { + return getMemberList(getCache().detailedDictionaries,MemberListType_docDictionaryMembers,theTranslator->trDictionaryDocumentation()); + } TemplateVariant detailedEnums() const { return getMemberList(getCache().detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); @@ -3339,12 +3431,16 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> SharedPtr<TemplateList> constantgroups; SharedPtr<MemberListInfoContext> macros; SharedPtr<MemberListInfoContext> typedefs; + SharedPtr<MemberListInfoContext> sequences; + SharedPtr<MemberListInfoContext> dictionaries; SharedPtr<MemberListInfoContext> enums; SharedPtr<MemberListInfoContext> functions; SharedPtr<MemberListInfoContext> variables; SharedPtr<MemberGroupListContext> memberGroups; SharedPtr<MemberListInfoContext> detailedMacros; SharedPtr<MemberListInfoContext> detailedTypedefs; + SharedPtr<MemberListInfoContext> detailedSequences; + SharedPtr<MemberListInfoContext> detailedDictionaries; SharedPtr<MemberListInfoContext> detailedEnums; SharedPtr<MemberListInfoContext> detailedFunctions; SharedPtr<MemberListInfoContext> detailedVariables; @@ -3994,6 +4090,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> s_inst.addProperty("callGraph", &Private::callGraph); s_inst.addProperty("hasCallerGraph", &Private::hasCallerGraph); s_inst.addProperty("callerGraph", &Private::callerGraph); + s_inst.addProperty("hasReferencedByRelation", &Private::hasReferencedByRelation); + s_inst.addProperty("referencedByRelation", &Private::referencedByRelation); + s_inst.addProperty("hasReferencesRelation", &Private::hasReferencesRelation); + s_inst.addProperty("referencesRelation", &Private::referencesRelation); s_inst.addProperty("fieldType", &Private::fieldType); s_inst.addProperty("type", &Private::type); s_inst.addProperty("detailsVisibleFor", &Private::detailsVisibleFor); @@ -4918,6 +5018,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } return TemplateVariant(FALSE); } + TemplateVariant hasReferencedByRelation() const + { + return TemplateVariant(m_memberDef->hasReferencedByRelation()); + } TemplateVariant callGraph() const { if (hasCallGraph().toBool()) @@ -4958,6 +5062,14 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> return TemplateVariant(""); } } + TemplateVariant referencedByRelation() const + { + if (hasReferencedByRelation().toBool()) + { + err("context.cpp: output format not yet supported"); + } + return TemplateVariant(""); + } DotCallGraph *getCallerGraph() const { Cachable &cache = getCache(); @@ -4978,6 +5090,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } return TemplateVariant(FALSE); } + TemplateVariant hasReferencesRelation() const + { + return TemplateVariant(m_memberDef->hasReferencesRelation()); + } TemplateVariant callerGraph() const { if (hasCallerGraph().toBool()) @@ -5018,6 +5134,14 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> return TemplateVariant(""); } } + TemplateVariant referencesRelation() const + { + if (hasReferencesRelation().toBool()) + { + err("context.cpp: output format not yet supported"); + } + return TemplateVariant(""); + } TemplateVariant type() const { return m_memberDef->typeString(); @@ -5489,12 +5613,14 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> QCString title = theTranslator->trFunctions(); SrcLangExt lang = m_groupDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms(); - else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc(); + else if (lang==SrcLangExt_VHDL) title=theTranslator->trFunctionAndProc(); return getMemberList(getCache().functions,MemberListType_decFuncMembers,title); } TemplateVariant variables() const { - return getMemberList(getCache().variables,MemberListType_decVarMembers,theTranslator->trVariables()); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + return getMemberList(getCache().variables,MemberListType_decVarMembers, + sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } TemplateVariant signals() const { @@ -5828,7 +5954,7 @@ class ClassIndexContext::Private } else if (vhdlOpt) { - return VhdlDocGen::trDesignUnits(); + return theTranslator->trDesignUnits(); } else { @@ -6022,7 +6148,7 @@ class ClassHierarchyContext::Private static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); if (vhdlOpt) { - return VhdlDocGen::trDesignUnitHierarchy(); + return theTranslator->trDesignUnitHierarchy(); } else { @@ -6428,7 +6554,7 @@ class NestingContext::Private : public GenericNodeListContext if (nd->localName().find('@')==-1 && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { - bool hasChildren = namespaceHasVisibleChild(nd,addClasses); + bool hasChildren = namespaceHasVisibleChild(nd,addClasses,false,ClassDef::Class); bool isLinkable = nd->isLinkableInProject(); if (isLinkable || hasChildren) { @@ -6780,7 +6906,7 @@ class ClassTreeContext::Private } else if (vhdlOpt) { - return VhdlDocGen::trDesignUnitList(); + return theTranslator->trDesignUnitList(); } else { @@ -6943,11 +7069,12 @@ class NamespaceTreeContext::Private 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); if (javaOpt || vhdlOpt) { return theTranslator->trPackages(); } - else if (fortranOpt) + else if (fortranOpt || sliceOpt) { return theTranslator->trModulesList(); } @@ -6978,7 +7105,8 @@ class NamespaceTreeContext::Private SharedPtr<NestingContext> m_namespaceTree; struct Cachable { - Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {} + Cachable() : maxDepth(0), maxDepthComputed(FALSE), + preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; @@ -7352,7 +7480,8 @@ class PageTreeContext::Private SharedPtr<NestingContext> m_pageTree; struct Cachable { - Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {} + Cachable() : maxDepth(0), maxDepthComputed(FALSE), + preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; @@ -7604,7 +7733,8 @@ class ModuleTreeContext::Private SharedPtr<NestingContext> m_moduleTree; struct Cachable { - Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {} + Cachable() : maxDepth(0), maxDepthComputed(FALSE), + preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; @@ -7807,7 +7937,8 @@ class ExampleTreeContext::Private SharedPtr<NestingContext> m_exampleTree; struct Cachable { - Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {} + Cachable() : maxDepth(0), maxDepthComputed(FALSE), + preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; diff --git a/src/defargs.l b/src/defargs.l index 7f1e1bb..7e9ccca 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -52,6 +52,7 @@ #include <assert.h> #include <ctype.h> #include <qregexp.h> +#include <qcstringlist.h> #include "defargs.h" #include "entry.h" @@ -102,6 +103,38 @@ static int yyread(char *buf,int max_size) return c; } +/* bug_520975 */ +static bool nameIsActuallyPartOfType(QCString &name) +{ + static bool first=TRUE; + static QDict<void> keywords(17); + if (first) // fill keyword dict first time + { + #define DUMMY_ADDR (void*)0x8 + keywords.insert("unsigned", DUMMY_ADDR); // foo(... unsigned) + keywords.insert("signed", DUMMY_ADDR); // foo(... signed) + keywords.insert("bool", DUMMY_ADDR); // foo(... bool) + keywords.insert("char", DUMMY_ADDR); // foo(... char) + keywords.insert("char8_t", DUMMY_ADDR); // foo(... char8_t) + keywords.insert("char16_t", DUMMY_ADDR); // foo(... char16_t) + keywords.insert("char32_t", DUMMY_ADDR); // foo(... char32_t) + keywords.insert("int", DUMMY_ADDR); // foo(... int) + keywords.insert("short", DUMMY_ADDR); // foo(... short) + keywords.insert("long", DUMMY_ADDR); // foo(... long) + keywords.insert("float", DUMMY_ADDR); // foo(... float) + keywords.insert("double", DUMMY_ADDR); // foo(... double) + keywords.insert("int8_t", DUMMY_ADDR); // foo(... int8_t) + keywords.insert("uint8_t", DUMMY_ADDR); // foo(... uint8_t) + keywords.insert("int16_t", DUMMY_ADDR); // foo(... int16_t) + keywords.insert("uint16_t", DUMMY_ADDR); // foo(... uint16_t) + keywords.insert("int32_t", DUMMY_ADDR); // foo(... int32_t) + keywords.insert("uint32_t", DUMMY_ADDR); // foo(... uint32_t) + keywords.insert("const", DUMMY_ADDR); // foo(... const) + keywords.insert("volatile", DUMMY_ADDR); // foo(... volatile) + first=FALSE; + } + return name.length()>0 && keywords.find(name)!=0; +} %} B [ \t] @@ -384,10 +417,9 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" a->type.mid(sv)=="union" || a->type.mid(sv)=="class" || a->type.mid(sv)=="typename" || - a->type=="const" || - a->type=="volatile" + nameIsActuallyPartOfType(a->name) ) - { + { a->type = a->type + " " + a->name; a->name.resize(0); } diff --git a/src/defgen.cpp b/src/defgen.cpp index cd69ab2..a8f89c5 100644 --- a/src/defgen.cpp +++ b/src/defgen.cpp @@ -89,20 +89,22 @@ void generateDEFForMember(MemberDef *md, bool isFunc=FALSE; switch (md->memberType()) { - case MemberType_Define: memType="define"; break; - case MemberType_EnumValue: ASSERT(0); break; - case MemberType_Property: memType="property"; break; - case MemberType_Event: memType="event"; break; - case MemberType_Variable: memType="variable"; break; - case MemberType_Typedef: memType="typedef"; break; - case MemberType_Enumeration: memType="enum"; break; - case MemberType_Interface: memType="interface"; break; - case MemberType_Service: memType="service"; break; - case MemberType_Function: memType="function"; isFunc=TRUE; break; - case MemberType_Signal: memType="signal"; isFunc=TRUE; break; - case MemberType_Friend: memType="friend"; isFunc=TRUE; break; - case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break; - case MemberType_Slot: memType="slot"; isFunc=TRUE; break; + case MemberType_Define: memType="define"; break; + case MemberType_EnumValue: ASSERT(0); break; + case MemberType_Property: memType="property"; break; + case MemberType_Event: memType="event"; break; + case MemberType_Variable: memType="variable"; break; + case MemberType_Typedef: memType="typedef"; break; + case MemberType_Enumeration: memType="enum"; break; + case MemberType_Interface: memType="interface"; break; + case MemberType_Service: memType="service"; break; + case MemberType_Sequence: memType="sequence"; break; + case MemberType_Dictionary: memType="dictionary"; break; + case MemberType_Function: memType="function"; isFunc=TRUE; break; + case MemberType_Signal: memType="signal"; isFunc=TRUE; break; + case MemberType_Friend: memType="friend"; isFunc=TRUE; break; + case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break; + case MemberType_Slot: memType="slot"; isFunc=TRUE; break; } t << memPrefix << "kind = '" << memType << "';" << endl; @@ -146,7 +148,7 @@ void generateDEFForMember(MemberDef *md, stringToArgumentList(md->argsString(),declAl); QCString fcnPrefix = " " + memPrefix + "param-"; - if (declAl->count()>0) + if (defAl && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); @@ -511,6 +513,8 @@ void generateDEFForNamespace(NamespaceDef *nd,FTextStream &t) generateDEFSection(nd,t,nd->getMemberList(MemberListType_decDefineMembers),"define"); generateDEFSection(nd,t,nd->getMemberList(MemberListType_decProtoMembers),"prototype"); generateDEFSection(nd,t,nd->getMemberList(MemberListType_decTypedefMembers),"typedef"); + generateDEFSection(nd,t,nd->getMemberList(MemberListType_decSequenceMembers),"sequence"); + generateDEFSection(nd,t,nd->getMemberList(MemberListType_decDictionaryMembers),"dictionary"); generateDEFSection(nd,t,nd->getMemberList(MemberListType_decEnumMembers),"enum"); generateDEFSection(nd,t,nd->getMemberList(MemberListType_decFuncMembers),"func"); generateDEFSection(nd,t,nd->getMemberList(MemberListType_decVarMembers),"var"); @@ -538,6 +542,8 @@ void generateDEFForFile(FileDef *fd,FTextStream &t) generateDEFSection(fd,t,fd->getMemberList(MemberListType_decDefineMembers),"define"); generateDEFSection(fd,t,fd->getMemberList(MemberListType_decProtoMembers),"prototype"); generateDEFSection(fd,t,fd->getMemberList(MemberListType_decTypedefMembers),"typedef"); + generateDEFSection(fd,t,fd->getMemberList(MemberListType_decSequenceMembers),"sequence"); + generateDEFSection(fd,t,fd->getMemberList(MemberListType_decDictionaryMembers),"dictionary"); generateDEFSection(fd,t,fd->getMemberList(MemberListType_decEnumMembers),"enum"); generateDEFSection(fd,t,fd->getMemberList(MemberListType_decFuncMembers),"func"); generateDEFSection(fd,t,fd->getMemberList(MemberListType_decVarMembers),"var"); diff --git a/src/definition.cpp b/src/definition.cpp index ff30429..fbf5be8 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -41,6 +41,8 @@ #include "namespacedef.h" #include "filedef.h" #include "dirdef.h" +#include "pagedef.h" +#include "bufstr.h" #define START_MARKER 0x4445465B // DEF[ #define END_MARKER 0x4445465D // DEF] @@ -269,6 +271,7 @@ void Definition::removeFromMap(Definition *d) if (dl->isEmpty()) { Doxygen::symbolMap->take(symbolName); + delete dl; } } else // symbolName unique @@ -303,6 +306,7 @@ Definition::Definition(const Definition &d) : DefinitionIntf(), m_cookie(0) { m_name = d.m_name; m_defLine = d.m_defLine; + m_defColumn = d.m_defColumn; m_impl = new DefinitionImpl; *m_impl = *d.m_impl; m_impl->sectionDict = 0; @@ -714,6 +718,139 @@ void Definition::setInbodyDocumentation(const char *d,const char *inbodyFile,int _setInbodyDocumentation(d,inbodyFile,inbodyLine); } +//--------------------------------------- + +struct FilterCacheItem +{ + portable_off_t filePos; + uint fileSize; +}; + +/*! Cache for storing the result of filtering a file */ +class FilterCache +{ + public: + FilterCache() : m_endPos(0) { m_cache.setAutoDelete(TRUE); } + bool getFileContents(const QCString &fileName,BufStr &str) + { + static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); + QCString filter = getFileFilter(fileName,TRUE); + bool usePipe = !filter.isEmpty() && filterSourceFiles; + FILE *f=0; + const int blockSize = 4096; + char buf[blockSize]; + FilterCacheItem *item=0; + if (usePipe && (item = m_cache.find(fileName))) // cache hit: reuse stored result + { + //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); + f = portable_fopen(Doxygen::filterDBFileName,"rb"); + if (f) + { + bool success=TRUE; + str.resize(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)); + success=FALSE; + } + if (success) + { + int numBytes = fread(str.data(),1,item->fileSize,f); + if (numBytes!=item->fileSize) + { + err("Failed to read %d bytes from position %d in filter database file %s: got %d bytes\n", + (int)item->fileSize,(int)item->filePos,qPrint(Doxygen::filterDBFileName),numBytes); + success=FALSE; + } + } + str.addChar('\0'); + fclose(f); + return success; + } + else + { + err("Failed to open filter database file %s\n",qPrint(Doxygen::filterDBFileName)); + return FALSE; + } + } + else if (usePipe) // cache miss: filter active but file not previously processed + { + //printf("getFileContents(%s): cache miss\n",qPrint(fileName)); + // filter file + QCString cmd=filter+" \""+fileName+"\""; + Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd)); + f = portable_popen(cmd,"r"); + FILE *bf = portable_fopen(Doxygen::filterDBFileName,"a+b"); + FilterCacheItem *item = new FilterCacheItem; + item->filePos = m_endPos; + if (bf==0) + { + // handle error + err("Error opening filter database file %s\n",qPrint(Doxygen::filterDBFileName)); + str.addChar('\0'); + delete item; + portable_pclose(f); + return FALSE; + } + // append the filtered output to the database file + int size=0; + while (!feof(f)) + { + int bytesRead = fread(buf,1,blockSize,f); + int bytesWritten = fwrite(buf,1,bytesRead,bf); + if (bytesRead!=bytesWritten) + { + // handle error + err("Failed to write to filter database %s. Wrote %d out of %d bytes\n", + qPrint(Doxygen::filterDBFileName),bytesWritten,bytesRead); + str.addChar('\0'); + delete item; + portable_pclose(f); + fclose(bf); + return FALSE; + } + size+=bytesWritten; + str.addArray(buf,bytesWritten); + } + str.addChar('\0'); + item->fileSize = size; + // add location entry to the dictionary + m_cache.append(fileName,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); + // update end of file position + m_endPos += size; + portable_pclose(f); + fclose(bf); + } + else // no filtering + { + // normal file + //printf("getFileContents(%s): no filter\n",qPrint(fileName)); + f = portable_fopen(fileName,"r"); + while (!feof(f)) + { + int bytesRead = fread(buf,1,blockSize,f); + str.addArray(buf,bytesRead); + } + str.addChar('\0'); + fclose(f); + } + return TRUE; + } + private: + SDict<FilterCacheItem> m_cache; + portable_off_t m_endPos; +}; + +static FilterCache g_filterCache; + +//----------------------------------------- + + /*! Reads a fragment of code from file \a fileName starting at * line \a startLine and ending at line \a endLine (inclusive). The fragment is * stored in \a result. If FALSE is returned the code fragment could not be @@ -728,67 +865,60 @@ void Definition::setInbodyDocumentation(const char *d,const char *inbodyFile,int bool readCodeFragment(const char *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); - static int tabSize = Config_getInt(TAB_SIZE); - //printf("readCodeFragment(%s,%d,%d)\n",fileName,startLine,endLine); - if (fileName==0 || fileName[0]==0) return FALSE; // not a valid file name QCString filter = getFileFilter(fileName,TRUE); - FILE *f=0; bool usePipe = !filter.isEmpty() && filterSourceFiles; + int tabSize = Config_getInt(TAB_SIZE); SrcLangExt lang = getLanguageFromFileName(fileName); - if (!usePipe) // no filter given or wanted - { - f = portable_fopen(fileName,"r"); - } - else // use filter - { - QCString cmd=filter+" \""+fileName+"\""; - Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd)); - f = portable_popen(cmd,"r"); - } - bool found = lang==SrcLangExt_VHDL || - lang==SrcLangExt_Tcl || - lang==SrcLangExt_Python || - lang==SrcLangExt_Fortran; + const int blockSize = 4096; + BufStr str(blockSize); + g_filterCache.getFileContents(fileName,str); + + bool found = lang==SrcLangExt_VHDL || + lang==SrcLangExt_Tcl || + lang==SrcLangExt_Python || + lang==SrcLangExt_Fortran; // for VHDL, TCL, Python, and Fortran no bracket search is possible - if (f) + char *p=str.data(); + if (p) { int c=0; int col=0; int lineNr=1; // skip until the startLine has reached - while (lineNr<startLine && !feof(f)) + while (lineNr<startLine && *p) { - while ((c=fgetc(f))!='\n' && c!=EOF) /* skip */; - lineNr++; + while ((c=*p++)!='\n' && c!=0) /* skip */; + lineNr++; if (found && c == '\n') c = '\0'; } - if (!feof(f)) + if (*p) { // skip until the opening bracket or lonely : is found char cn=0; - while (lineNr<=endLine && !feof(f) && !found) + while (lineNr<=endLine && *p && !found) { int pc=0; - while ((c=fgetc(f))!='{' && c!=':' && c!=EOF) // } so vi matching brackets has no problem + while ((c=*p++)!='{' && c!=':' && c!=0) { //printf("parsing char `%c'\n",c); - if (c=='\n') + if (c=='\n') { - lineNr++,col=0; + lineNr++,col=0; } - else if (c=='\t') + else if (c=='\t') { col+=tabSize - (col%tabSize); } else if (pc=='/' && c=='/') // skip single line comment { - while ((c=fgetc(f))!='\n' && c!=EOF) pc=c; + while ((c=*p++)!='\n' && c!=0) pc=c; if (c=='\n') lineNr++,col=0; } else if (pc=='/' && c=='*') // skip C style comment { - while (((c=fgetc(f))!='/' || pc!='*') && c!=EOF) + while (((c=*p++)!='/' || pc!='*') && c!=0) { if (c=='\n') lineNr++,col=0; pc=c; @@ -802,16 +932,16 @@ bool readCodeFragment(const char *fileName, } if (c==':') { - cn=fgetc(f); + cn=*p++; if (cn!=':') found=TRUE; } - else if (c=='{') // } so vi matching brackets has no problem + else if (c=='{') { found=TRUE; } } //printf(" -> readCodeFragment(%s,%d,%d) lineNr=%d\n",fileName,startLine,endLine,lineNr); - if (found) + if (found) { // For code with more than one line, // fill the line with spaces until we are at the right column @@ -825,57 +955,47 @@ bool readCodeFragment(const char *fileName, // copy until end of line if (c) result+=c; startLine=lineNr; - if (c==':') + if (c==':') { result+=cn; if (cn=='\n') lineNr++; } - const int maxLineLength=4096; - char lineStr[maxLineLength]; - do + char lineStr[blockSize]; + do { //printf("reading line %d in range %d-%d\n",lineNr,startLine,endLine); int size_read; - do + do { // read up to maxLineLength-1 bytes, the last byte being zero - char *p = fgets(lineStr, maxLineLength,f); - //printf(" read %s",p); - if (p) - { - size_read=qstrlen(p); - } - else // nothing read + int i=0; + while ((c=*p++) && i<blockSize-1) { - size_read=-1; - lineStr[0]='\0'; + lineStr[i++]=c; + if (c=='\n') break; // stop at end of the line } - result+=lineStr; - } while (size_read == (maxLineLength-1)); - - lineNr++; - } while (lineNr<=endLine && !feof(f)); + lineStr[i]=0; + size_read=i; + result+=lineStr; // append line to the output + } while (size_read == (blockSize-1)); // append more if line does not fit in buffer + lineNr++; + } while (lineNr<=endLine && *p); // strip stuff after closing bracket int newLineIndex = result.findRev('\n'); int braceIndex = result.findRev('}'); - if (braceIndex > newLineIndex) + if (braceIndex > newLineIndex) { result.truncate(braceIndex+1); } endLine=lineNr-1; } } - if (usePipe) + if (usePipe) { - portable_pclose(f); Debug::print(Debug::FilterOutput, 0, "Filter output\n"); Debug::print(Debug::FilterOutput,0,"-------------\n%s\n-------------\n",qPrint(result)); } - else - { - fclose(f); - } } result = transcodeCharacterStringToUTF8(result); if (!result.isEmpty() && result.at(result.length()-1)!='\n') result += "\n"; @@ -920,6 +1040,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); static bool rtfSourceCode = Config_getBool(RTF_SOURCE_CODE); + static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); ol.pushGeneratorState(); //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef); QCString fn = getSourceFileBase(); @@ -944,11 +1065,15 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (!docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (!rtfSourceCode) { ol.disable(OutputGenerator::RTF); } - // write line link (HTML, LaTeX optionally, RTF optionally) + // write line link (HTML and optionally LaTeX, Docbook, RTF) ol.writeObjectLink(0,fn,anchorStr,lineStr); ol.enableAll(); ol.disable(OutputGenerator::Html); @@ -956,6 +1081,10 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -974,6 +1103,10 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (!docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (!rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -986,6 +1119,10 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1008,6 +1145,10 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (!docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (!rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1020,6 +1161,10 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1034,15 +1179,19 @@ void Definition::writeSourceDef(OutputList &ol,const char *) ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); - if (!latexSourceCode) + ol.disableAllBut(OutputGenerator::Html); + if (latexSourceCode) { - ol.disable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Latex); } - if (!rtfSourceCode) + if (docbookSourceCode) { - ol.disable(OutputGenerator::RTF); + ol.enable(OutputGenerator::Docbook); + } + if (rtfSourceCode) + { + ol.enable(OutputGenerator::RTF); } - ol.disableAllBut(OutputGenerator::Html); // write line link (HTML only) ol.writeObjectLink(0,fn,anchorStr,lineStr); ol.enableAll(); @@ -1051,6 +1200,10 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.disable(OutputGenerator::Latex); } + if (docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1144,6 +1297,7 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, const QCString &text,MemberSDict *members,bool /*funcOnly*/) { static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); + static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); static bool rtfSourceCode = Config_getBool(RTF_SOURCE_CODE); static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE); @@ -1202,6 +1356,10 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, { ol.disable(OutputGenerator::Latex); } + if (!docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (!rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1220,6 +1378,10 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, { ol.disable(OutputGenerator::Latex); } + if (docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1237,6 +1399,10 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, { ol.disable(OutputGenerator::Latex); } + if (!docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (!rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1254,6 +1420,10 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, { ol.disable(OutputGenerator::Latex); } + if (docbookSourceCode) + { + ol.disable(OutputGenerator::Docbook); + } if (rtfSourceCode) { ol.disable(OutputGenerator::RTF); @@ -1277,18 +1447,12 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName) { - if (Config_getBool(REFERENCED_BY_RELATION)) - { - _writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_impl->sourceRefByDict,FALSE); - } + _writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_impl->sourceRefByDict,FALSE); } void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) { - if (Config_getBool(REFERENCES_RELATION)) - { - _writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_impl->sourceRefsDict,TRUE); - } + _writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_impl->sourceRefsDict,TRUE); } bool Definition::hasDocumentation() const @@ -1475,13 +1639,21 @@ void Definition::mergeRefItems(Definition *d) m_impl->xrefListItems->setAutoDelete(TRUE); } QListIterator<ListItemInfo> slii(*xrefList); + QListIterator<ListItemInfo> mlii(*m_impl->xrefListItems); ListItemInfo *lii; + ListItemInfo *mii; for (slii.toFirst();(lii=slii.current());++slii) { - if (_getXRefListId(lii->type)==-1) + bool found = false; + for (mlii.toFirst();(mii=mlii.current());++mlii) { - m_impl->xrefListItems->append(new ListItemInfo(*lii)); + if ((qstrcmp(lii->type,mii->type)==0) && (lii->itemId == mii->itemId)) + { + found = true; + break; + } } + if (!found) m_impl->xrefListItems->append(new ListItemInfo(*lii)); } } } @@ -1613,72 +1785,150 @@ void Definition::writeNavigationPath(OutputList &ol) const } // TODO: move to htmlgen -void Definition::writeToc(OutputList &ol) +void Definition::writeToc(OutputList &ol, const LocalToc &localToc) { SectionDict *sectionDict = m_impl->sectionDict; if (sectionDict==0) return; - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - ol.writeString("<div class=\"toc\">"); - ol.writeString("<h3>"); - ol.writeString(theTranslator->trRTFTableOfContents()); - ol.writeString("</h3>\n"); - ol.writeString("<ul>"); - SDict<SectionInfo>::Iterator li(*sectionDict); - SectionInfo *si; - int level=1,l; - char cs[2]; - cs[1]='\0'; - bool inLi[5]={ FALSE, FALSE, FALSE, FALSE }; - for (li.toFirst();(si=li.current());++li) - { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + if (localToc.isHtmlEnabled()) + { + int maxLevel = localToc.htmlLevel(); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + ol.writeString("<div class=\"toc\">"); + ol.writeString("<h3>"); + ol.writeString(theTranslator->trRTFTableOfContents()); + ol.writeString("</h3>\n"); + ol.writeString("<ul>"); + SDict<SectionInfo>::Iterator li(*sectionDict); + SectionInfo *si; + int level=1,l; + char cs[2]; + cs[1]='\0'; + bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; + for (li.toFirst();(si=li.current());++li) { - //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; - if (nextLevel>level) + if (si->type==SectionInfo::Section || + si->type==SectionInfo::Subsection || + si->type==SectionInfo::Subsubsection || + si->type==SectionInfo::Paragraph) { - for (l=level;l<nextLevel;l++) + //printf(" level=%d title=%s\n",level,si->title.data()); + int nextLevel = (int)si->type; + if (nextLevel>level) { - ol.writeString("<ul>"); + for (l=level;l<nextLevel;l++) + { + if (l < maxLevel) ol.writeString("<ul>"); + } } + else if (nextLevel<level) + { + for (l=level;l>nextLevel;l--) + { + if (l <= maxLevel && inLi[l]) ol.writeString("</li>\n"); + inLi[l]=FALSE; + if (l <= maxLevel) ol.writeString("</ul>\n"); + } + } + cs[0]='0'+nextLevel; + if (nextLevel <= maxLevel && inLi[nextLevel]) ol.writeString("</li>\n"); + QCString titleDoc = convertToHtml(si->title); + if (nextLevel <= maxLevel) ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>"); + inLi[nextLevel]=TRUE; + level = nextLevel; } - else if (nextLevel<level) + } + if (level > maxLevel) level = maxLevel; + while (level>1 && level <= maxLevel) + { + if (inLi[level]) ol.writeString("</li>\n"); + inLi[level]=FALSE; + ol.writeString("</ul>\n"); + level--; + } + if (level <= maxLevel && inLi[level]) ol.writeString("</li>\n"); + inLi[level]=FALSE; + ol.writeString("</ul>\n"); + ol.writeString("</div>\n"); + ol.popGeneratorState(); + } + + if (localToc.isDocbookEnabled()) + { + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Docbook); + ol.writeString(" <toc>\n"); + ol.writeString(" <title>" + theTranslator->trRTFTableOfContents() + "</title>\n"); + SectionDict *sectionDict = getSectionDict(); + SDict<SectionInfo>::Iterator li(*sectionDict); + SectionInfo *si; + int level=1,l; + bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; + int maxLevel = localToc.docbookLevel(); + for (li.toFirst();(si=li.current());++li) + { + if (si->type==SectionInfo::Section || + si->type==SectionInfo::Subsection || + si->type==SectionInfo::Subsubsection || + si->type==SectionInfo::Paragraph) { - for (l=level;l>nextLevel;l--) + //printf(" level=%d title=%s\n",level,si->title.data()); + int nextLevel = (int)si->type; + if (nextLevel>level) + { + for (l=level;l<nextLevel;l++) + { + if (l < maxLevel) ol.writeString(" <tocdiv>\n"); + } + } + else if (nextLevel<level) + { + for (l=level;l>nextLevel;l--) + { + inLi[l]=FALSE; + if (l <= maxLevel) ol.writeString(" </tocdiv>\n"); + } + } + if (nextLevel <= maxLevel) { - if (inLi[l]) ol.writeString("</li>\n"); - inLi[l]=FALSE; - ol.writeString("</ul>\n"); + QCString titleDoc = convertToDocBook(si->title); + ol.writeString(" <tocentry>" + (si->title.isEmpty()?si->label:titleDoc) + "</tocentry>\n"); } + inLi[nextLevel]=TRUE; + level = nextLevel; } - cs[0]='0'+nextLevel; - if (inLi[nextLevel]) ol.writeString("</li>\n"); - QCString titleDoc = convertToHtml(si->title); - ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>"); - inLi[nextLevel]=TRUE; - level = nextLevel; } + if (level > maxLevel) level = maxLevel; + while (level>1 && level <= maxLevel) + { + inLi[level]=FALSE; + ol.writeString("</tocdiv>\n"); + level--; + } + inLi[level]=FALSE; + ol.writeString(" </toc>\n"); + ol.popGeneratorState(); } - while (level>1) + + if (localToc.isLatexEnabled()) { - if (inLi[level]) ol.writeString("</li>\n"); - inLi[level]=FALSE; - ol.writeString("</ul>\n"); - level--; + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Latex); + int maxLevel = localToc.latexLevel(); + + ol.writeString("\\etocsetnexttocdepth{"+QCString().setNum(maxLevel)+"}\n"); + + ol.writeString("\\localtableofcontents\n"); + ol.popGeneratorState(); } - if (inLi[level]) ol.writeString("</li>\n"); - inLi[level]=FALSE; - ol.writeString("</ul>\n"); - ol.writeString("</div>\n"); - ol.popGeneratorState(); } //---------------------------------------------------------------------------------------- +SectionDict * Definition::getSectionDict(void) +{ + return m_impl->sectionDict; +} QCString Definition::symbolName() const { diff --git a/src/definition.h b/src/definition.h index d16c6b9..c0428a0 100644 --- a/src/definition.h +++ b/src/definition.h @@ -275,6 +275,9 @@ class Definition : public DefinitionIntf QCString id() const; + /** returns the section dictionary, only of importance for pagedef */ + SectionDict * getSectionDict(void); + //----------------------------------------------------------------------------------- // ---- setters ----- //----------------------------------------------------------------------------------- @@ -346,7 +349,7 @@ class Definition : public DefinitionIntf void setLocalName(const QCString name); void addSectionsToIndex(); - void writeToc(OutputList &ol); + void writeToc(OutputList &ol, const LocalToc <); void setCookie(Cookie *cookie) { delete m_cookie; m_cookie = cookie; } Cookie *cookie() const { return m_cookie; } diff --git a/src/diagram.cpp b/src/diagram.cpp index 42792ad..83e42b3 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -833,7 +833,7 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, } ++rit; di=rit.current(); } - // add last horizonal line and a vertical connection line + // add last horizontal line and a vertical connection line if (bitmap) { if (doBase) // base classes @@ -1380,7 +1380,5 @@ void ClassDiagram::writeImage(FTextStream &t,const char *path, #define IMAGE_EXT ".png" image.save((QCString)path+"/"+fileName+IMAGE_EXT); Doxygen::indexList->addImageFile(QCString(fileName)+IMAGE_EXT); - - if (generateMap) t << "</map>" << endl; } diff --git a/src/dirdef.cpp b/src/dirdef.cpp index b247ba7..7294e4f 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -485,8 +485,14 @@ void DirDef::writeDocumentation(OutputList &ol) case LayoutDocEntry::NamespaceNestedNamespaces: case LayoutDocEntry::NamespaceNestedConstantGroups: case LayoutDocEntry::NamespaceClasses: + case LayoutDocEntry::NamespaceInterfaces: + case LayoutDocEntry::NamespaceStructs: + case LayoutDocEntry::NamespaceExceptions: case LayoutDocEntry::NamespaceInlineClasses: case LayoutDocEntry::FileClasses: + case LayoutDocEntry::FileInterfaces: + case LayoutDocEntry::FileStructs: + case LayoutDocEntry::FileExceptions: case LayoutDocEntry::FileNamespaces: case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: @@ -930,14 +936,14 @@ void buildDirectories() for (;(fd=fni.current());++fni) { //printf("buildDirectories %s\n",fd->name().data()); - if (fd->getReference().isEmpty() && !fd->isDocumentationFile()) + if (fd->getReference().isEmpty()) { DirDef *dir; if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory { dir = DirDef::mergeDirectoryInTree(fd->getPath()); } - if (dir) dir->addFile(fd); + if (dir && !fd->isDocumentationFile()) dir->addFile(fd); } else { diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index 345629e..97c602d 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * -* +* * * Copyright (C) 1997-2015 by Dimitri van Heesch. * @@ -21,11 +21,14 @@ #include <qfile.h> #include <qtextstream.h> #include <qintdict.h> +#include <qregexp.h> #include "docbookgen.h" #include "doxygen.h" #include "message.h" #include "config.h" #include "classlist.h" +#include "classdef.h" +#include "diagram.h" #include "util.h" #include "defargs.h" #include "outputgen.h" @@ -54,57 +57,22 @@ // debug inside output //#define Docbook_DB(x) QCString __t;__t.sprintf x;m_t << __t +#if 0 +#define DB_GEN_C DB_GEN_C1(t) +#define DB_GEN_C1(x) x << "<!-- DB_GEN_C " << __LINE__ << " -->\n"; +#define DB_GEN_C2(y) DB_GEN_C2a(t,y) +#define DB_GEN_C2a(x,y) x << "<!-- DB_GEN_C " << __LINE__ << " " << y << " -->\n"; +#else +#define DB_GEN_C +#define DB_GEN_C1(x) +#define DB_GEN_C2(y) +#define DB_GEN_C2a(x,y) +#endif //------------------ -class DocbookSectionMapper : public QIntDict<char> -{ - public: - DocbookSectionMapper() : QIntDict<char>(47) - { - insert(MemberListType_pubTypes,"public-type"); - insert(MemberListType_pubMethods,"public-func"); - insert(MemberListType_pubAttribs,"public-attrib"); - insert(MemberListType_pubSlots,"public-slot"); - insert(MemberListType_signals,"signal"); - insert(MemberListType_dcopMethods,"dcop-func"); - insert(MemberListType_properties,"property"); - insert(MemberListType_events,"event"); - insert(MemberListType_pubStaticMethods,"public-static-func"); - insert(MemberListType_pubStaticAttribs,"public-static-attrib"); - insert(MemberListType_proTypes,"protected-type"); - insert(MemberListType_proMethods,"protected-func"); - insert(MemberListType_proAttribs,"protected-attrib"); - insert(MemberListType_proSlots,"protected-slot"); - insert(MemberListType_proStaticMethods,"protected-static-func"); - insert(MemberListType_proStaticAttribs,"protected-static-attrib"); - insert(MemberListType_pacTypes,"package-type"); - insert(MemberListType_pacMethods,"package-func"); - insert(MemberListType_pacAttribs,"package-attrib"); - insert(MemberListType_pacStaticMethods,"package-static-func"); - insert(MemberListType_pacStaticAttribs,"package-static-attrib"); - insert(MemberListType_priTypes,"private-type"); - insert(MemberListType_priMethods,"private-func"); - insert(MemberListType_priAttribs,"private-attrib"); - insert(MemberListType_priSlots,"private-slot"); - insert(MemberListType_priStaticMethods,"private-static-func"); - insert(MemberListType_priStaticAttribs,"private-static-attrib"); - insert(MemberListType_friends,"friend"); - insert(MemberListType_related,"related"); - insert(MemberListType_decDefineMembers,"define"); - insert(MemberListType_decProtoMembers,"prototype"); - insert(MemberListType_decTypedefMembers,"typedef"); - insert(MemberListType_decEnumMembers,"enum"); - insert(MemberListType_decFuncMembers,"func"); - insert(MemberListType_decVarMembers,"var"); - } -}; - -static DocbookSectionMapper g_docbookSectionMapper; - - inline void writeDocbookString(FTextStream &t,const char *s) { - t << convertToXML(s); + t << convertToDocBook(s); } inline void writeDocbookCodeString(FTextStream &t,const char *s, int &col) @@ -128,27 +96,30 @@ inline void writeDocbookCodeString(FTextStream &t,const char *s, int &col) case '&': t << "&"; col++; break; case '\'': t << "'"; col++; break; case '"': t << """; col++; break; + case '\007': t << "^G"; col++; break; // bell + case '\014': t << "^L"; col++; break; // form feed default: t << c; col++; break; } } } -static void writeDocbookHeaderMainpage(FTextStream &t) +static void addIndexTerm(FTextStream &t, QCString prim, QCString sec = "") { - t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; - t << "<chapter xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" << endl; -} - -static void writeDocbookHeader_ID(FTextStream &t, QCString id) -{ - t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; - t << "<section xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:id=\"" << id << "\">" << endl; + t << "<indexterm><primary>"; + t << convertToDocBook(prim); + t << "</primary>"; + if (!sec.isEmpty()) + { + t << "<secondary>"; + t << convertToDocBook(sec); + t << "</secondary>"; + } + t << "</indexterm>" << endl; } - void writeDocbookLink(FTextStream &t,const char * /*extRef*/,const char *compoundId, const char *anchorId,const char * text,const char * /*tooltip*/) { - t << "<link linkend=\"" << compoundId; + t << "<link linkend=\"_" << stripPath(compoundId); if (anchorId) t << "_1" << anchorId; t << "\""; t << ">"; @@ -156,1856 +127,1060 @@ void writeDocbookLink(FTextStream &t,const char * /*extRef*/,const char *compoun t << "</link>"; } -class TextGeneratorDocbookImpl : public TextGeneratorIntf +DocbookCodeGenerator::DocbookCodeGenerator(FTextStream &t) : m_lineNumber(-1), m_col(0), + m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE) { - public: - TextGeneratorDocbookImpl(FTextStream &t): m_t(t) {} - void writeString(const char *s,bool /*keepSpaces*/) const - { - writeDocbookString(m_t,s); - } - void writeBreak(int) const {} - void writeLink(const char *extRef,const char *file, - const char *anchor,const char *text - ) const - { - writeDocbookLink(m_t,extRef,file,anchor,text,0); - } - private: - FTextStream &m_t; -}; + m_prettyCode=Config_getBool(DOCBOOK_PROGRAMLISTING); + setTextStream(t); +} -class DocbookCodeGenerator : public CodeOutputInterface +DocbookCodeGenerator::DocbookCodeGenerator() : m_lineNumber(-1), m_col(0), + m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE), m_streamSet(FALSE) { - public: - DocbookCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1), m_col(0), - m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE) {} - virtual ~DocbookCodeGenerator() {} + m_prettyCode=Config_getBool(DOCBOOK_PROGRAMLISTING); +} - void codify(const char *text) - { - Docbook_DB(("(codify \"%s\")\n",text)); - writeDocbookCodeString(m_t,text,m_col); - } - void writeCodeLink(const char *ref,const char *file, - const char *anchor,const char *name, - const char *tooltip) - { - Docbook_DB(("(writeCodeLink)\n")); - writeDocbookLink(m_t,ref,file,anchor,name,tooltip); - m_col+=strlen(name); - } - void writeTooltip(const char *, const DocLinkInfo &, const char *, - const char *, const SourceLinkInfo &, const SourceLinkInfo & - ) - { - Docbook_DB(("(writeToolTip)\n")); - } - void startCodeLine(bool) - { - Docbook_DB(("(startCodeLine)\n")); - if (m_lineNumber!=-1) - { - if (!m_refId.isEmpty()) - { - m_t << "<link linkend=\"" << m_refId << "\">"; - } - m_t << m_lineNumber << " "; - if (!m_refId.isEmpty()) - { - m_t << "</link>"; - } - } - m_insideCodeLine=TRUE; - m_col=0; - } - void endCodeLine() - { - m_t << endl; - Docbook_DB(("(endCodeLine)\n")); - m_lineNumber = -1; - m_refId.resize(0); - m_external.resize(0); - m_insideCodeLine=FALSE; - } - void startFontClass(const char *colorClass) - { - Docbook_DB(("(startFontClass)\n")); - m_t << "<emphasis class=\"" << colorClass << "\">"; - m_insideSpecialHL=TRUE; - } - void endFontClass() - { - Docbook_DB(("(endFontClass)\n")); - m_t << "</emphasis>"; // non DocBook - m_insideSpecialHL=FALSE; - } - void writeCodeAnchor(const char *) - { - Docbook_DB(("(writeCodeAnchor)\n")); - } - void writeLineNumber(const char *extRef,const char *compId, - const char *anchorId,int l) - { - Docbook_DB(("(writeLineNumber)\n")); - // we remember the information provided here to use it - // at the <codeline> start tag. - m_lineNumber = l; - if (compId) - { - m_refId=compId; - if (anchorId) m_refId+=(QCString)"_1"+anchorId; - if (extRef) m_external=extRef; - } - } - void setCurrentDoc(Definition *,const char *,bool) - { - } - void addWord(const char *,bool) +DocbookCodeGenerator::~DocbookCodeGenerator() {} + +void DocbookCodeGenerator::codify(const char *text) +{ + Docbook_DB(("(codify \"%s\")\n",text)); + writeDocbookCodeString(m_t,text,m_col); +} +void DocbookCodeGenerator::writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip) +{ + Docbook_DB(("(writeCodeLink)\n")); + writeDocbookLink(m_t,ref,file,anchor,name,tooltip); + m_col+=strlen(name); +} +void DocbookCodeGenerator::writeCodeLinkLine(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip) +{ + Docbook_DB(("(writeCodeLinkLine)\n")); + m_t << "<anchor xml:id=\"_" << stripExtensionGeneral(stripPath(file),".xml"); + m_t << "_1l"; + writeDocbookString(m_t,name); + m_t << "\"/>"; + m_col+=strlen(name); +} +void DocbookCodeGenerator::writeTooltip(const char *, const DocLinkInfo &, const char *, + const char *, const SourceLinkInfo &, const SourceLinkInfo & + ) +{ + Docbook_DB(("(writeToolTip)\n")); +} +void DocbookCodeGenerator::startCodeLine(bool) +{ + Docbook_DB(("(startCodeLine)\n")); + m_insideCodeLine=TRUE; + m_col=0; +} +void DocbookCodeGenerator::endCodeLine() +{ + m_t << endl; + Docbook_DB(("(endCodeLine)\n")); + m_lineNumber = -1; + m_refId.resize(0); + m_external.resize(0); + m_insideCodeLine=FALSE; +} +void DocbookCodeGenerator::startFontClass(const char *colorClass) +{ + Docbook_DB(("(startFontClass)\n")); + m_t << "<emphasis role=\"" << colorClass << "\">"; + m_insideSpecialHL=TRUE; +} +void DocbookCodeGenerator::endFontClass() +{ + Docbook_DB(("(endFontClass)\n")); + m_t << "</emphasis>"; // non DocBook + m_insideSpecialHL=FALSE; +} +void DocbookCodeGenerator::writeCodeAnchor(const char *) +{ + Docbook_DB(("(writeCodeAnchor)\n")); +} +void DocbookCodeGenerator::writeLineNumber(const char *ref,const char *fileName, + const char *anchor,int l) +{ + Docbook_DB(("(writeLineNumber)\n")); + m_insideCodeLine = TRUE; + if (m_prettyCode) + { + QCString lineNumber; + lineNumber.sprintf("%05d",l); + + if (fileName && !m_sourceFileName.isEmpty()) { + writeCodeLinkLine(ref,m_sourceFileName,anchor,lineNumber,0); + writeCodeLink(ref,fileName,anchor,lineNumber,0); } - void finish() + else { - if (m_insideCodeLine) endCodeLine(); + codify(lineNumber); } - - private: - FTextStream &m_t; - QCString m_refId; - QCString m_external; - int m_lineNumber; - int m_col; - bool m_insideCodeLine; - bool m_insideSpecialHL; -}; - - -static void writeTemplateArgumentList(ArgumentList *al, - FTextStream &t, - Definition *scope, - FileDef *fileScope, - int indent) -{ - QCString indentStr; - indentStr.fill(' ',indent); - if (al) + m_t << " "; + } + else { - t << indentStr << "<templateparamlist>" << endl; - ArgumentListIterator ali(*al); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) - { - t << indentStr << " <param>" << endl; - if (!a->type.isEmpty()) - { - t << indentStr << " <type>"; - linkifyText(TextGeneratorDocbookImpl(t),scope,fileScope,0,a->type); - t << "</type>" << endl; - } - if (!a->name.isEmpty()) - { - t << indentStr << " <declname>" << a->name << "</declname>" << endl; - t << indentStr << " <defname>" << a->name << "</defname>" << endl; - } - if (!a->defval.isEmpty()) - { - t << indentStr << " <defval>"; - linkifyText(TextGeneratorDocbookImpl(t),scope,fileScope,0,a->defval); - t << "</defval>" << endl; - } - t << indentStr << " </param>" << endl; - } - t << indentStr << "</templateparamlist>" << endl; + m_t << l << " "; } -} -static void writeTemplateList(ClassDef *cd,FTextStream &t) +} +void DocbookCodeGenerator::setCurrentDoc(Definition *,const char *,bool) { - writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4); } - -static void writeDocbookDocBlock(FTextStream &t, - const QCString &fileName, - int lineNr, - Definition *scope, - MemberDef * md, - const QCString &text) -{ - QCString stext = text.stripWhiteSpace(); - if (stext.isEmpty()) return; - // convert the documentation string into an abstract syntax tree - DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE); - // create a code generator - DocbookCodeGenerator *docbookCodeGen = new DocbookCodeGenerator(t); - // create a parse tree visitor for Docbook - DocbookDocVisitor *visitor = new DocbookDocVisitor(t,*docbookCodeGen); - // visit all nodes - root->accept(visitor); - // clean up - delete visitor; - delete docbookCodeGen; - delete root; +void DocbookCodeGenerator::addWord(const char *,bool) +{ } - -void writeDocbookCodeBlock(FTextStream &t,FileDef *fd) -{ - ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension()); - SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension()); - pIntf->resetCodeParserState(); - DocbookCodeGenerator *docbookGen = new DocbookCodeGenerator(t); - pIntf->parseCode(*docbookGen, // codeOutIntf - 0, // scopeName - fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)), - langExt, // lang - FALSE, // isExampleBlock - 0, // exampleName - fd, // fileDef - -1, // startLine - -1, // endLine - FALSE, // inlineFragement - 0, // memberDef - TRUE // showLineNumbers - ); - docbookGen->finish(); - delete docbookGen; +void DocbookCodeGenerator::finish() +{ + if (m_insideCodeLine) endCodeLine(); } - -static QCString classOutputFileBase(ClassDef *cd) +void DocbookCodeGenerator::startCodeFragment() +{ + m_t << "<literallayout><computeroutput>" << endl; +} +void DocbookCodeGenerator::endCodeFragment() { - //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - //if (inlineGroupedClasses && cd->partOfGroups()!=0) - return cd->getOutputFileBase(); - //else - // return cd->getOutputFileBase(); + m_t << "</computeroutput></literallayout>" << endl; } -static QCString memberOutputFileBase(MemberDef *md) +DocbookGenerator::DocbookGenerator() : OutputGenerator() { - //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); - //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0) - // return md->getClassDef()->getDocbookOutputFileBase(); - //else - // return md->getOutputFileBase(); - return md->getOutputFileBase(); +DB_GEN_C + dir=Config_getString(DOCBOOK_OUTPUT); + //insideTabbing=FALSE; + //firstDescItem=TRUE; + //disableLinks=FALSE; + //m_indent=0; + //templateMemberItem = FALSE; + m_prettyCode=Config_getBool(DOCBOOK_PROGRAMLISTING); + m_denseText = FALSE; + m_inGroup = FALSE; + m_inDetail = FALSE; + m_levelListItem = 0; + m_descTable = FALSE; + m_inLevel = -1; + m_firstMember = FALSE; + for (int i = 0 ; i < sizeof(m_inListItem) / sizeof(*m_inListItem) ; i++) m_inListItem[i] = FALSE; + for (int i = 0 ; i < sizeof(m_inSimpleSect) / sizeof(*m_inSimpleSect) ; i++) m_inSimpleSect[i] = FALSE; } +DocbookGenerator::~DocbookGenerator() +{ +DB_GEN_C +} -static void generateDocbookForMember(MemberDef *md,FTextStream &t,Definition *def, bool detailed=0) +void DocbookGenerator::init() { + QCString dir=Config_getString(DOCBOOK_OUTPUT); + QDir d(dir); + if (!d.exists() && !d.mkdir(dir)) + { + err("Could not create output directory %s\n",dir.data()); + exit(1); + } - // + declaration/definition arg lists - // + reimplements - // + reimplementedBy - // + exceptions - // + const/volatile specifiers - // - examples - // + source definition - // + source references - // + source referenced by - // - body code - // + template arguments - // (templateArguments(), definitionTemplateParameterLists()) - // - call graph + createSubDirs(d); +} - // enum values are written as part of the enum - if (md->memberType()==MemberType_EnumValue) return; - if (md->isHidden()) return; - //if (md->name().at(0)=='@') return; // anonymous member +void DocbookGenerator::startFile(const char *name,const char *,const char *) +{ +DB_GEN_C + QCString fileName=name; + QCString pageName; + QCString fileType="section"; + if (fileName == "refman") + { + fileName="index"; + fileType="book"; + } + else if (fileName == "index") + { + fileName="mainpage"; + fileType="chapter"; + } + pageName = fileName; + relPath = relativePathToRoot(fileName); + if (fileName.right(4)!=".xml") fileName+=".xml"; + startPlainFile(fileName); + m_codeGen.setTextStream(t); + m_codeGen.setRelativePath(relPath); + m_codeGen.setSourceFileName(stripPath(fileName)); + + t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; + t << "<" << fileType << " xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\""; + if (!pageName.isEmpty()) t << " xml:id=\"_" << stripPath(pageName) << "\""; + t << ">" << endl; +} - // group members are only visible in their group - //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return; - QCString memType; - switch (md->memberType()) +void DocbookGenerator::endFile() +{ +DB_GEN_C + if (m_inDetail) t << "</section>" << endl; + m_inDetail = FALSE; + while (m_inLevel != -1) { - case MemberType_Define: memType="define"; break; - case MemberType_Function: memType="function"; break; - case MemberType_Variable: memType="variable"; break; - case MemberType_Typedef: memType="typedef"; break; - case MemberType_Enumeration: memType="enum"; break; - case MemberType_EnumValue: ASSERT(0); break; - case MemberType_Signal: memType="signal"; break; - case MemberType_Slot: memType="slot"; break; - case MemberType_Friend: memType="friend"; break; - case MemberType_DCOP: memType="dcop"; break; - case MemberType_Property: memType="property"; break; - case MemberType_Event: memType="event"; break; - case MemberType_Interface: memType="interface"; break; - case MemberType_Service: memType="service"; break; + t << "</section>" << endl; + m_inLevel--; } - QCString scopeName; - if (md->getClassDef()) + if (m_inGroup) t << "</section>" << endl; + m_inGroup = FALSE; + + QCString fileType="section"; + QCString fileName= m_codeGen.sourceFileName(); + if (fileName == "index.xml") { - scopeName=md->getClassDef()->name(); + fileType="book"; } - else if (md->getNamespaceDef()) + else if (fileName == "mainpage.xml") { - scopeName=md->getNamespaceDef()->name(); + fileType="chapter"; } - if (detailed==0) + t << "</" << fileType << ">" << endl; + endPlainFile(); + m_codeGen.setSourceFileName(""); +} + +void DocbookGenerator::startIndexSection(IndexSections is) +{ +DB_GEN_C2("IndexSections " << is) + switch (is) { - t << " <para>" << endl; - t << " <itemizedlist>" << endl; - t << " <listitem>" << endl; - //enum - bool closePara=TRUE; - if (md->memberType()==MemberType_Enumeration) - { - MemberList *enumFields = md->enumFieldList(); - t << " <para><literallayout>" << memType << " <link linkend=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) + case isTitlePageStart: { - t << md->getGroupDef()->getOutputFileBase(); + QCString dbk_projectName = Config_getString(PROJECT_NAME); + t << " <info>" << endl; + t << " <title>" << convertToDocBook(dbk_projectName) << "</title>" << endl; + t << " </info>" << endl; } - else - { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>"; - if (enumFields!=0) + break; + case isTitlePageAuthor: + break; + case isMainPage: + t << "<chapter>" << endl; + t << " <title>"; + break; + case isModuleIndex: + //Module Index}\n" + break; + case isDirIndex: + //Directory Index}\n" + break; + case isNamespaceIndex: + //Namespace Index}\n" + break; + case isClassHierarchyIndex: + //Hierarchical Index}\n" + break; + case isCompoundIndex: + //t << "{"; //Class Index}\n" + break; + case isFileIndex: + //Annotated File Index}\n" + break; + case isPageIndex: + //Annotated Page Index}\n" + break; + case isModuleDocumentation: + t << "<chapter>\n"; + t << " <title>"; + break; + case isDirDocumentation: + t << "<chapter>\n"; + t << " <title>"; + break; + case isNamespaceDocumentation: + t << "<chapter>\n"; + t << " <title>"; + break; + case isClassDocumentation: + t << "<chapter>\n"; + t << " <title>"; + break; + case isFileDocumentation: + t << "<chapter>\n"; + t << " <title>"; + break; + case isExampleDocumentation: + t << "<chapter>\n"; + t << " <title>"; + break; + case isPageDocumentation: + break; + case isPageDocumentation2: + break; + case isEndIndex: + break; + } +} + +void DocbookGenerator::endIndexSection(IndexSections is) +{ +DB_GEN_C2("IndexSections " << is) + static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); + switch (is) + { + case isTitlePageStart: + break; + case isTitlePageAuthor: + break; + case isMainPage: + t << "</title>" << endl; + t << " <xi:include href=\"mainpage.xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + t << "</chapter>" << endl; + break; + case isModuleIndex: + //t << "</chapter>" << endl; + break; + case isDirIndex: + //t << "<xi:include href=\"dirs.xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>"; + //t << "</chapter>" << endl; + break; + case isNamespaceIndex: + //t << "<xi:include href=\"namespaces.xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>"; + //t << "</chapter>" << endl; + break; + case isClassHierarchyIndex: + //t << "<xi:include href=\"hierarchy.xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>"; + //t << "</chapter>" << endl; + break; + case isCompoundIndex: + //t << "</chapter>" << endl; + break; + case isFileIndex: + //t << "<xi:include href=\"files.xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>"; + //t << "</chapter>" << endl; + break; + case isPageIndex: + //t << "<xi:include href=\"pages.xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>"; + //t << "</chapter>" << endl; + break; + case isModuleDocumentation: { - MemberListIterator emli(*enumFields); - MemberDef *emd; - t << " {" << endl; - int cnt=0; - for (emli.toFirst();(emd=emli.current());++emli) + t << "</title>" << endl; + GroupSDict::Iterator gli(*Doxygen::groupSDict); + GroupDef *gd; + bool found=FALSE; + for (gli.toFirst();(gd=gli.current()) && !found;++gli) { - if (cnt!=0) - { - t << "," << endl; - } - t << "<link linkend=\"" << memberOutputFileBase(emd) << "_1" << emd->anchor() << "\">"; - writeDocbookString(t,emd->name()); - t << "</link>"; - if (!emd->initializer().isEmpty()) + if (!gd->isReference()) { - writeDocbookString(t,emd->initializer()); + t << " <xi:include href=\"" << gd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + found=TRUE; } - cnt++; - } - t << endl << "}"; - } - t << "</literallayout>" << endl; - if (md->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis></para>" << endl; - } - } - else if (md->memberType()==MemberType_Define) - { - t << " <para>" << "#" << memType << " <link linkend=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else - { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>"; - if (!md->initializer().isEmpty() && md->initializer().length()<2000) - { - t << " "; - linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->initializer()); - } - if (md->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis></para>" << endl; - } - } - else if (md->memberType()==MemberType_Variable) - { - if (md->getClassDef()) - { - t << " <para>" << convertToXML(md->declaration()); - if (md->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis></para>"; - } - } - else - { - t << " <para>"; - linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString()); - t << " <link linkend=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); } - else + for (;(gd=gli.current());++gli) { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>"; - if (md->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis></para>" << endl; + if (!gd->isReference()) + { + t << " <xi:include href=\"" << gd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + } } } - } - else if (md->memberType()==MemberType_Typedef) - { - t << " <para>" << memType; - t << " "; - linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString()); - t << " "; - t << " <link linkend=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else + t << "</chapter>\n"; + break; + case isDirDocumentation: { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>"; - if (md->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis></para>" << endl; - } - } - else if (md->memberType()==MemberType_Function) - { - t << " <para>"; - linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString()); - t << " <link linkend=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else - { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>"; - t << " (" << endl; - ArgumentList *declAl = md->declArgumentList(); - if (declAl && declAl->count()>0) - { - ArgumentListIterator declAli(*declAl); - Argument *a; - int cnt=0; - for (declAli.toFirst();(a=declAli.current());++declAli) + t << "</title>" << endl; + SDict<DirDef>::Iterator dli(*Doxygen::directories); + DirDef *dd; + bool found=FALSE; + for (dli.toFirst();(dd=dli.current()) && !found;++dli) { - if (cnt!=0) - { - t << ", "; - } - if (!a->type.isEmpty()) + if (dd->isLinkableInProject()) { - linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,a->type); + t << "< xi:include href=\"" << dd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + found=TRUE; } - t << " "; - if (!a->name.isEmpty()) + } + for (;(dd=dli.current());++dli) + { + if (dd->isLinkableInProject()) { - writeDocbookString(t,a->name); + t << " <xi:include href=\"" << dd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; } - cnt++; } } - t << ")"; - if (md->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis></para>" << endl; - } - } - else - { - closePara = FALSE; - } - if (closePara) t << "</para>" << endl; - t << " </listitem>" << endl; - t << " </itemizedlist>" << endl; - t << " </para>" << endl; - } - else - { - if (md->memberType()==MemberType_Enumeration) - { - MemberList *enumFields = md->enumFieldList(); - t << " <section xml:id=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else + t << "</chapter>\n"; + break; + case isNamespaceDocumentation: { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << endl; - t << " <title>" << memType << " " << convertToXML(md->name()) << " " << "</title>" << endl; - t << " "; - writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation()); - t << endl; - if (enumFields!=0) - { - MemberListIterator emli(*enumFields); - MemberDef *emd; - t << " <formalpara>" << endl; - t << " <title>" << theTranslator->trEnumerationValues() << ":</title>" << endl; - t << " <variablelist>" << endl; - for (emli.toFirst();(emd=emli.current());++emli) + t << "</title>" << endl; + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); + NamespaceDef *nd; + bool found=FALSE; + for (nli.toFirst();(nd=nli.current()) && !found;++nli) { - t << " <varlistentry xml:id=\""; - t << memberOutputFileBase(emd) << "_1" << emd->anchor() << "\">" << endl; - t << " <term>"; - writeDocbookString(t,emd->name()); - t << "</term>" << endl; - t << " <listitem>" << endl; - if(Config_getBool(REPEAT_BRIEF)) + if (nd->isLinkableInProject()) { - t << " <para>"; - writeDocbookString(t,emd->briefDescription()); - t << "</para>" << endl; + t << "<xi:include href=\"" << nd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + found=TRUE; } - t << " </listitem>" << endl; - t << " </varlistentry>" << endl; } - t << " </variablelist>" << endl; - t << " </formalpara>" << endl; - t << " <para>"; - t << "Definition at line " << md->getDefLine() << " of file " << stripPath(md->getDefFileName()) << endl; - t << " <computeroutput><literallayout>" << endl; - t << "{" << endl; - for (emli.toFirst();(emd=emli.current());++emli) + while ((nd=nli.current())) { - writeDocbookString(t,emd->name()); - if (!emd->initializer().isEmpty()) + if (nd->isLinkableInProject()) { - writeDocbookString(t,emd->initializer()); + t << "<xi:include href=\"" << nd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; } - t << ", " << endl; + ++nli; } - t << "}" << convertToXML(md->name()) << ";" << endl; - t << " </literallayout></computeroutput>" << endl; - t << " </para>" << endl; - t << " </section>" << endl; - } - } - else if (md->memberType()==MemberType_Typedef) - { - t << " <section xml:id=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else - { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << endl; - t << " <title>" << convertToXML(md->definition()) << "</title>"; - if(Config_getBool(REPEAT_BRIEF)) - { - t << " <emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis>" << endl; - } - t << " "; - writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation()); - t << endl; - t << " </section>" << endl; - } - else if (md->memberType()==MemberType_Function) - { - t << " <section xml:id=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else - { - t << memberOutputFileBase(md); - } - t << "_1" << md->anchor() << "\">" << endl; - t << " <title>" << convertToXML(md->definition()) << " " << convertToXML(md->argsString()) << "</title>"; - if(Config_getBool(REPEAT_BRIEF)) - { - t << " <emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis>" << endl; } - t << " "; - writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation()); - t << endl; - t << " </section>" << endl; - } - else if (md->memberType()==MemberType_Define) - { - if (md->documentation()) + t << "</chapter>\n"; + break; + case isClassDocumentation: { - t << " <section xml:id=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) + t << "</title>" << endl; + ClassSDict::Iterator cli(*Doxygen::classSDict); + ClassDef *cd=0; + bool found=FALSE; + for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - t << md->getGroupDef()->getOutputFileBase(); + if (cd->isLinkableInProject() && + cd->templateMaster()==0 && + !cd->isEmbeddedInOuterScope() + ) + { + t << " <xi:include href=\"" << cd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + found=TRUE; + } } - else + for (;(cd=cli.current());++cli) { - t << memberOutputFileBase(md); + if (cd->isLinkableInProject() && + cd->templateMaster()==0 && + !cd->isEmbeddedInOuterScope() + ) + { + t << " <xi:include href=\"" << cd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + } } - t << "_1" << md->anchor() << "\">" << endl; - t << " <title>" << convertToXML(md->definition()) << "</title>"; - t << " "; - writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation()); - t << endl; - t << " <para>Definition at line " << md->getDefLine() << " of file " << stripPath(md->getDefFileName()) << "</para>" << endl; - t << " <para>The Documentation for this define was generated from the following file: </para>" << endl; - t << " <para><itemizedlist><listitem><para>" << stripPath(md->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl; - t << " </section>" << endl; } - } - else if (md->memberType()==MemberType_Variable) - { - if (md->getClassDef()) + t << "</chapter>\n"; + break; + case isFileDocumentation: { - if (md->documentation()) + t << "</title>" << endl; + bool isFirst=TRUE; + FileNameListIterator fnli(*Doxygen::inputNameList); + FileName *fn; + for (fnli.toFirst();(fn=fnli.current());++fnli) { - t << " <simplesect>" << endl; - t << " <title>" << convertToXML(md->definition()) << "</title>"; - t << " "; - writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation()); - t << endl; - t << " <para>Definition at line " << md->getDefLine() << " of file " << stripPath(md->getDefFileName()) << "</para>" << endl; - t << " <para>The Documentation for this struct was generated from the following file: </para>" << endl; - t << " <para><itemizedlist><listitem><para>" << stripPath(md->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl; - t << " </simplesect>" << endl; + FileNameIterator fni(*fn); + FileDef *fd; + for (;(fd=fni.current());++fni) + { + if (fd->isLinkableInProject()) + { + if (isFirst) + { + t << " <xi:include href=\"" << fd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + if (sourceBrowser && m_prettyCode && fd->generateSourceFile()) + { + t << " <xi:include href=\"" << fd->getSourceFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + } + isFirst=FALSE; + } + else + { + t << " <xi:include href=\"" << fd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + if (sourceBrowser && m_prettyCode && fd->generateSourceFile()) + { + t << " <xi:include href=\"" << fd->getSourceFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + } + } + } + } } } - else + t << "</chapter>\n"; + break; + case isExampleDocumentation: { - t << " <section xml:id=\""; - if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup) - { - t << md->getGroupDef()->getOutputFileBase(); - } - else + t << "</title>" << endl; + PageSDict::Iterator pdi(*Doxygen::exampleSDict); + PageDef *pd=pdi.toFirst(); + if (pd) { - t << memberOutputFileBase(md); + t << " <xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; } - t << "_1" << md->anchor() << "\">" << endl; - t << " <title>" << convertToXML(md->definition()) << "</title>"; - if(Config_getBool(REPEAT_BRIEF)) + for (++pdi;(pd=pdi.current());++pdi) { - t << " <emphasis>"; - writeDocbookString(t,md->briefDescription()); - t << "</emphasis>" << endl; + t << " <xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; } - t << " "; - writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation()); - t << endl; - t << " </section>" << endl; } - } + t << "</chapter>\n"; + break; + case isPageDocumentation: + break; + case isPageDocumentation2: + break; + case isEndIndex: + t << "<index/>" << endl; + break; } } - -static void generateDocbookSection(Definition *d,FTextStream &t,MemberList *ml,const char *, - bool detailed=0, const char *header=0,const char *documentation=0) -{ - if (ml==0) return; - MemberListIterator mli(*ml); - MemberDef *md; - int count=0; - int doc_count=0; - QCString title, desctitle; - - for (mli.toFirst();(md=mli.current());++mli) - { - // namespace members are also inserted in the file scope, but - // to prevent this duplication in the Docbook output, we filter those here. - if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0) - { - count++; - } - } - - if (count==0) return; // empty list - - switch (ml->listType()) - { - case MemberListType_decDefineMembers: title=theTranslator->trDefines(); desctitle=theTranslator->trDefineDocumentation(); break; - case MemberListType_decTypedefMembers: title=theTranslator->trTypedefs(); desctitle=theTranslator->trTypedefDocumentation(); break; - case MemberListType_decEnumMembers: title=theTranslator->trEnumerations(); desctitle=theTranslator->trEnumerationTypeDocumentation(); break; - case MemberListType_decFuncMembers: title=theTranslator->trFunctions(); desctitle=theTranslator->trFunctionDocumentation(); break; - case MemberListType_decVarMembers: title=theTranslator->trVariables(); desctitle=theTranslator->trVariableDocumentation(); break; - case MemberListType_pubAttribs: title=theTranslator->trPublicAttribs(); desctitle=theTranslator->trMemberDataDocumentation(); break; - case MemberListType_priAttribs: title=theTranslator->trPrivateAttribs(); desctitle=theTranslator->trMemberDataDocumentation(); break; - case MemberListType_proAttribs: title=theTranslator->trProtectedAttribs(); desctitle=theTranslator->trMemberDataDocumentation(); break; - default: title=""; desctitle=""; break; - } - - if (detailed) - { - for (mli.toFirst();(md=mli.current());++mli) - { - if (md->documentation().isEmpty() && !Config_getBool(REPEAT_BRIEF)) - { - continue; - } - doc_count = 1; - break; - } - - if(doc_count == 0) - { - return; - } - - if (desctitle) - { - t << " <section>" << endl; - t << " <title>" << desctitle << "</title>" << endl; - } - } else - { - t << " <section>" << endl; - if (header) - { - t << " <title>" << convertToXML(header) << "</title>" << endl; - } - else - { - t << " <title>" << title << "</title>" << endl; - } - } - - if (documentation) - { - t << " <description>"; - writeDocbookDocBlock(t,d->docFile(),d->docLine(),d,0,documentation); - t << "</description>" << endl; - } - for (mli.toFirst();(md=mli.current());++mli) - { - // namespace members are also inserted in the file scope, but - // to prevent this duplication in the Docbook output, we filter those here. - if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0) - { - if (detailed && md->documentation().isEmpty() && !Config_getBool(REPEAT_BRIEF)) - { - continue; - } - - generateDocbookForMember(md,t,d,detailed); - } - } - if (detailed) - { - if (desctitle) - { - t << " </section>" << endl; - } - } - else - { - t << " </section>" << endl; - } -} - -static void writeInnerClasses(const ClassSDict *cl,FTextStream &t) +void DocbookGenerator::writePageLink(const char *name, bool /*first*/) { - if (cl) +DB_GEN_C + PageSDict::Iterator pdi(*Doxygen::pageSDict); + PageDef *pd = pdi.toFirst(); + for (pd = pdi.toFirst();(pd=pdi.current());++pdi) { - ClassSDict::Iterator cli(*cl); - ClassDef *cd; - QCString title = theTranslator->trClasses(); - - if (cli.toFirst()) + if (!pd->getGroupDef() && !pd->isReference() && pd->name() == stripPath(name)) { - t << " <section>" << endl; - t << " <title> " << title << " </title>" << endl; - } - for (cli.toFirst();(cd=cli.current());++cli) - { - if (!cd->isHidden() && cd->name().find('@')==-1) + t << "<chapter>\n"; + if (!pd->title().isEmpty()) { - t << " <para>" << endl; - t << " <itemizedlist>" << endl; - t << " <listitem>" << endl; - t << " <para>" << "struct <link linkend=\"" << classOutputFileBase(cd) << "\">" << convertToXML(cd->name()) << "</link>"; - t << "</para>" << endl; - if (cd->briefDescription()) - { - t << "<para><emphasis>"; - writeDocbookString(t,cd->briefDescription()); - t << "</emphasis></para>" << endl; - } - t << " </listitem>" << endl; - t << " </itemizedlist>" << endl; - t << " </para>" << endl; + t << " <title>" << convertToDocBook(pd->title()) << "</title>" << endl; } - } - if (cli.toFirst()) - { - t << " </section>" << endl; - } - } -} - -static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t) -{ - if (nl) - { - NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; - QCString title = theTranslator->trNamespaces(); - - if (nli.toFirst()) - { - t << " <simplesect>" << endl; - t << " <title> " << title << " </title>" << endl; - } - for (nli.toFirst();(nd=nli.current());++nli) - { - if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes + else { - t << " <para>" << endl; - t << " <itemizedlist>" << endl; - t << " <listitem>" << endl; - t << " <para>" << "struct <link linkend=\"" << nd->getOutputFileBase() << "\">" << convertToXML(nd->name()) << "</link>"; - t << "</para>" << endl; - t << " </listitem>" << endl; - t << " </itemizedlist>" << endl; - t << " </para>" << endl; + t << " <title>" << convertToDocBook(pd->name()) << "</title>" << endl; } - } - if (nli.toFirst()) - { - t << " </simplesect>" << endl; + t << " <xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; + t << "</chapter>\n"; } } } - -static void writeInnerFiles(const FileList *fl,FTextStream &t) +void DocbookGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) { - if (fl) - { - QListIterator<FileDef> fli(*fl); - FileDef *fd; - QCString title = theTranslator->trFile(TRUE,TRUE); - - if (fli.toFirst()) - { - t << " <simplesect>" << endl; - t << " <title> " << title << " </title>" << endl; - } - for (fli.toFirst();(fd=fli.current());++fli) - { - t << " <para>" << endl; - t << " <itemizedlist>" << endl; - t << " <listitem>" << endl; - t << " <para>" << "file <link linkend=\"" << fd->getOutputFileBase() << "\">" << convertToXML(fd->name()) << "</link>"; - t << "</para>" << endl; - t << " </listitem>" << endl; - t << " </itemizedlist>" << endl; - t << " </para>" << endl; - } - if (fli.toFirst()) - { - t << " </simplesect>" << endl; - } - } +DB_GEN_C + DocbookDocVisitor *visitor = + new DocbookDocVisitor(t,*this); + n->accept(visitor); + delete visitor; } -static void writeInnerPages(const PageSDict *pl,FTextStream &t) +void DocbookGenerator::startParagraph(const char *) { - if (pl) - { - PageSDict::Iterator pli(*pl); - PageDef *pd; - - for (pli.toFirst();(pd=pli.current());++pli) - { - t << "<xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - } - } +DB_GEN_C + t << "<para>" << endl; } -static void writeInnerGroups(const GroupList *gl,FTextStream &t) +void DocbookGenerator::endParagraph() { - if (gl) - { - GroupListIterator gli(*gl); - GroupDef *sgd; - - //Docbook header tags for inner groups - if (gli.toFirst()) - { - t << " <simplesect>" << endl; - t << " <title>" << theTranslator->trModules() << "</title>" << endl; - t << " </simplesect>" << endl; - t << " <para>" << endl; - t << " <itemizedlist>" << endl; - } - - for (gli.toFirst();(sgd=gli.current());++gli) - { - t << " <listitem><para><link linkend=\"" << sgd->getOutputFileBase() << "\">" << convertToXML(sgd->groupTitle()) << "</link></para></listitem>" << endl; - } - - //Docbook footer tags for inner groups - if (gli.toFirst()) - { - t << " </itemizedlist>" << endl; - t << " </para>" << endl; - } - - } +DB_GEN_C + t << "</para>" << endl; } - -static void writeInnerDirs(const DirList *dl,FTextStream &t) +void DocbookGenerator::writeString(const char *text) { - if (dl) - { - QListIterator<DirDef> subdirs(*dl); - DirDef *subdir; - QCString title = theTranslator->trDirectories(); - if (subdirs.toFirst()) - { - t << " <simplesect>" << endl; - t << " <title> " << title << " </title>" << endl; - } - for (subdirs.toFirst();(subdir=subdirs.current());++subdirs) - { - t << " <para>" << endl; - t << " <itemizedlist>" << endl; - t << " <listitem>" << endl; - t << " <para>" << "dir <link linkend=\"" << subdir->getOutputFileBase() << "\">" << convertToXML(subdir->displayName()) << "</link>"; - t << "</para>" << endl; - t << " </listitem>" << endl; - t << " </itemizedlist>" << endl; - t << " </para>" << endl; - } - if (subdirs.toFirst()) - { - t << " </simplesect>" << endl; - } - } +DB_GEN_C + t << text; } - -static void writeInnerGroupFiles(const GroupList *gl,FTextStream &t) +void DocbookGenerator::startMemberHeader(const char *name,int) { - if (gl) - { - GroupListIterator gli(*gl); - GroupDef *sgd; - - for (gli.toFirst();(sgd=gli.current());++gli) - { - t << "<xi:include href=\"" << sgd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - } - } +DB_GEN_C + t << "<simplesect>" << endl; + m_inSimpleSect[m_levelListItem] = TRUE; + t << " <title>"; } -static void generateDocbookForClass(ClassDef *cd,FTextStream &ti) -{ - // + brief description - // + detailed description - // + template argument list(s) - // - include file - // + member groups - // + inheritance diagram - // + list of direct super classes - // + list of direct sub classes - // + list of inner classes - // + collaboration diagram - // + list of all members - // + user defined member sections - // + standard member sections - // + detailed member documentation - // - examples using the class - - if (cd->isReference()) return; // skip external references. - if (cd->isHidden()) return; // skip hidden classes. - if (cd->name().find('@')!=-1) return; // skip anonymous compounds. - if (cd->templateMaster()!=0) return; // skip generated template instances. - - msg("Generating Docbook output for class %s\n",cd->name().data()); - - QCString fileDocbook=cd->getOutputFileBase()+".xml"; - //Add the file Documentation info to index file - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml"; - QCString relPath = relativePathToRoot(fileName); - QFile f(fileName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - - writeDocbookHeader_ID(t, classOutputFileBase(cd)); +void DocbookGenerator::endMemberHeader() +{ +DB_GEN_C + t << " </title>" << endl; +} +void DocbookGenerator::docify(const char *str) +{ +DB_GEN_C + t << convertToDocBook(str); +} +void DocbookGenerator::writeObjectLink(const char *ref, const char *f, + const char *anchor, const char *text) +{ +DB_GEN_C + if (anchor) + if (f) t << "<link linkend=\"_" << stripPath(f) << "_1" << anchor << "\">"; + else t << "<link linkend=\"_" << anchor << "\">"; + else + t << "<link linkend=\"_" << stripPath(f) << "\">"; + docify(text); + t << "</link>"; +} +void DocbookGenerator::startMemberList() +{ +DB_GEN_C + t << " <itemizedlist>" << endl; + m_levelListItem++; +} +void DocbookGenerator::endMemberList() +{ +DB_GEN_C + if (m_inListItem[m_levelListItem]) t << "</listitem>" << endl; + m_inListItem[m_levelListItem] = FALSE; + t << " </itemizedlist>" << endl; + m_levelListItem = (m_levelListItem> 0 ? m_levelListItem - 1 : 0); + if (m_inSimpleSect[m_levelListItem]) t << "</simplesect>" << endl; + m_inSimpleSect[m_levelListItem] = FALSE; +} +void DocbookGenerator::startMemberItem(const char *,int,const char *) +{ +DB_GEN_C + if (m_inListItem[m_levelListItem]) t << "</listitem>" << endl; + t << " <listitem><para>"; + m_inListItem[m_levelListItem] = TRUE; +} +void DocbookGenerator::endMemberItem() +{ +DB_GEN_C + t << "</para>" << endl; +} +void DocbookGenerator::startBold(void) +{ +DB_GEN_C + t << "<emphasis role=\"strong\">"; +} +void DocbookGenerator::endBold(void) +{ +DB_GEN_C + t << "</emphasis>"; +} +void DocbookGenerator::startGroupHeader(int extraIndentLevel) +{ +DB_GEN_C2("m_inLevel " << m_inLevel) +DB_GEN_C2("extraIndentLevel " << extraIndentLevel) + m_firstMember = TRUE; + if (m_inSimpleSect[m_levelListItem]) t << "</simplesect>" << endl; + m_inSimpleSect[m_levelListItem] = FALSE; + if (m_inLevel != -1) m_inGroup = TRUE; + if (m_inLevel == extraIndentLevel) t << "</section>" << endl; + m_inLevel = extraIndentLevel; + t << "<section>" << endl; t << "<title>"; - writeDocbookString(t,cd->name()); - t << " " << cd->compoundTypeString() << " Reference"; - t << "</title>" << endl; - - IncludeInfo *ii=cd->includeInfo(); - if (ii) - { - QCString nm = ii->includeName; - if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName(); - if (!nm.isEmpty()) - { - t << "<para>" << endl; - t << " <programlisting>#include "; - if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references - { - t << "<link linkend=\"" << ii->fileDef->getOutputFileBase() << "\">"; - } - if (ii->local) - { - t << """; - } - else - { - t << "<"; - } - t << convertToXML(nm); - if (ii->local) - { - t << """; - } - else - { - t << ">"; - } - if (ii->fileDef && !ii->fileDef->isReference()) - { - t << "</link>"; - } - t << "</programlisting>" << endl; - t << "</para>" << endl; - } - } - - if (Config_getBool(HAVE_DOT) && (Config_getBool(CLASS_DIAGRAMS) || Config_getBool(CLASS_GRAPH))) - { - t << "<para>Inheritance diagram for " << convertToXML(cd->name()) << "</para>" << endl; - DotClassGraph inheritanceGraph(cd,DotNode::Inheritance); - inheritanceGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,TRUE,FALSE); - } - - if (Config_getBool(HAVE_DOT) && Config_getBool(COLLABORATION_GRAPH)) - { - t << "<para>Collaboration diagram for " << convertToXML(cd->name()) << "</para>" << endl; - DotClassGraph collaborationGraph(cd,DotNode::Collaboration); - collaborationGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,TRUE,FALSE); - } +} +void DocbookGenerator::writeRuler(void) +{ +DB_GEN_C2("m_inLevel " << m_inLevel) +DB_GEN_C2("m_inGroup " << m_inGroup) + if (m_inGroup) t << "</section>" << endl; + m_inGroup = FALSE; +} - writeInnerClasses(cd->getClassSDict(),t); +void DocbookGenerator::endGroupHeader(int) +{ +DB_GEN_C + t << "</title>" << endl; +} - writeTemplateList(cd,t); - if (cd->getMemberGroupSDict()) +void DocbookGenerator::startParameterList(bool openBracket) +{ +DB_GEN_C + if (openBracket) t << "("; +} +void DocbookGenerator::endParameterList() +{ +DB_GEN_C +} +void DocbookGenerator::writeNonBreakableSpace(int n) +{ +DB_GEN_C + for (int i=0;i<n;i++) t << " "; +} +void DocbookGenerator::lineBreak(const char *) +{ +DB_GEN_C + t << endl; +} +void DocbookGenerator::startTypewriter() +{ +DB_GEN_C + if (!m_denseText) t << "<computeroutput>"; +} +void DocbookGenerator::endTypewriter() +{ +DB_GEN_C + if (!m_denseText) t << "</computeroutput>" << endl; +} +void DocbookGenerator::startTextBlock(bool dense) +{ +DB_GEN_C + if (dense) { - MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict()); - MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - { - generateDocbookSection(cd,t,mg->members(),"user-defined",0,mg->header(), - mg->documentation()); - } + m_denseText = TRUE; + t << "<programlisting>"; } - - - QListIterator<MemberList> mli(cd->getMemberLists()); - MemberList *ml; - for (mli.toFirst();(ml=mli.current());++mli) - { - if ((ml->listType()&MemberListType_detailedLists)==0) - { - generateDocbookSection(cd,t,ml,g_docbookSectionMapper.find(ml->listType())); - } - } - - if(Config_getBool(REPEAT_BRIEF)) +} +void DocbookGenerator::endTextBlock(bool dense) +{ +DB_GEN_C + if (m_denseText) { - if (cd->briefDescription()) - { - t << " <simplesect>" << endl; - // A title as 'Brief Description' may not be necessary. - //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl; - writeDocbookDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription()); - t << " </simplesect>" << endl; - } + m_denseText = FALSE; + t << "</programlisting>"; } - - if (cd->documentation()) +} +void DocbookGenerator::startMemberDoc(const char *clname, const char *memname, const char *anchor, const char *title, + int memCount, int memTotal, bool showInline) +{ +DB_GEN_C2("m_inLevel " << m_inLevel) + t << " <section>" << endl; + t << " <title>" << convertToDocBook(title); + if (memTotal>1) { - t << " <simplesect>" << endl; - t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl; - writeDocbookDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation()); - t << " <para>Definition at line " << cd->getDefLine() << " of file " << stripPath(cd->getDefFileName()) << "</para>" << endl; - t << " <para>The Documentation for this struct was generated from the following file: </para>" << endl; - t << " <para><itemizedlist><listitem><para>" << stripPath(cd->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl; - t << " </simplesect>" << endl; + t << "<computeroutput>[" << memCount << "/" << memTotal << "]</computeroutput>"; } - for (mli.toFirst();(ml=mli.current());++mli) + t << "</title>" << endl; + if (memname && memname[0]!='@') { - if ((ml->listType()&MemberListType_detailedLists)==0) - { - generateDocbookSection(cd,t,ml,g_docbookSectionMapper.find(ml->listType()),1); - } + addIndexTerm(t,memname,clname); + addIndexTerm(t,clname,memname); } - - /*// TODO: Handling of Inheritance and Colloboration graph for Docbook to be implemented - DotClassGraph inheritanceGraph(cd,DotNode::Inheritance); - if (!inheritanceGraph.isTrivial()) - { - t << " <inheritancegraph>" << endl; - inheritanceGraph.writeDocbook(t); - t << " </inheritancegraph>" << endl; - } - DotClassGraph collaborationGraph(cd,DotNode::Collaboration); - if (!collaborationGraph.isTrivial()) - { - t << " <collaborationgraph>" << endl; - collaborationGraph.writeDocbook(t); - t << " </collaborationgraph>" << endl; - } - t << " <location file=\"" - << cd->getDefFileName() << "\" line=\"" - << cd->getDefLine() << "\""; - if (cd->getStartBodyLine()!=-1) - { - FileDef *bodyDef = cd->getBodyDef(); - if (bodyDef) - { - t << " bodyfile=\"" << bodyDef->absFilePath() << "\""; - } - t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" - << cd->getEndBodyLine() << "\""; - } - t << "/>" << endl; - writeListOfAllMembers(cd,t); - */ - - t << "</section>" << endl; - } - -static void generateDocbookForNamespace(NamespaceDef *nd,FTextStream &ti) -{ - // + contained class definitions - // + contained namespace definitions - // + member groups - // + normal members - // + brief desc - // + detailed desc - // + location - // - files containing (parts of) the namespace definition - - if (nd->isReference() || nd->isHidden()) return; // skip external references - - QCString fileDocbook=nd->getOutputFileBase()+".xml"; - //Add the file Documentation info to index file - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml"; - QFile f(fileName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - - writeDocbookHeader_ID(t, nd->getOutputFileBase()); +void DocbookGenerator::endMemberDoc(bool) +{ +DB_GEN_C + t << "</computeroutput></para>"; +} +void DocbookGenerator::startTitleHead(const char *) +{ +DB_GEN_C t << "<title>"; - writeDocbookString(t,nd->name()); +} +void DocbookGenerator::endTitleHead(const char *fileName,const char *name) +{ +DB_GEN_C t << "</title>" << endl; - - writeInnerClasses(nd->getClassSDict(),t); - writeInnerNamespaces(nd->getNamespaceSDict(),t); - - if (nd->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict()); - MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - { - generateDocbookSection(nd,t,mg->members(),"user-defined",0,mg->header(), - mg->documentation()); - } - } - - QListIterator<MemberList> mli(nd->getMemberLists()); - MemberList *ml; - for (mli.toFirst();(ml=mli.current());++mli) + if (name) addIndexTerm(t, name); +} +void DocbookGenerator::startDoxyAnchor(const char *fName,const char *manName, + const char *anchor,const char *name, + const char *args) +{ +DB_GEN_C + if (!m_inListItem[m_levelListItem] && !m_descTable) { - if ((ml->listType()&MemberListType_declarationLists)!=0) - { - generateDocbookSection(nd,t,ml,g_docbookSectionMapper.find(ml->listType())); - } + if (!m_firstMember) t << " </section>"; + m_firstMember = FALSE; } - - if(Config_getBool(REPEAT_BRIEF)) + if (anchor) { - if (nd->briefDescription()) - { - t << " <simplesect>" << endl; - //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl; - writeDocbookDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription()); - t << " </simplesect>" << endl; - } + t << "<anchor xml:id=\"_" << stripPath(fName) << "_1" << anchor << "\"/>"; } - - if (nd->documentation()) - { - t << " <simplesect>" << endl; - t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl; - writeDocbookDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation()); - t << " <para>Definition at line " << nd->getDefLine() << " of file " << stripPath(nd->getDefFileName()) << "</para>" << endl; - t << " <para>The Documentation for this struct was generated from the following file: </para>" << endl; - t << " <para><itemizedlist><listitem><para>" << stripPath(nd->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl; - t << " </simplesect>" << endl; - } - t << "</section>" << endl; } - -static void generateDocbookForFile(FileDef *fd,FTextStream &ti) -{ - // + includes files - // + includedby files - // + include graph - // + included by graph - // + contained class definitions - // + contained namespace definitions - // + member groups - // + normal members - // + brief desc - // + detailed desc - // + source code - // + location - // - number of lines - - if (fd->isReference()) return; // skip external references - - QCString fileDocbook=fd->getOutputFileBase()+".xml"; - //Add the file Documentation info to index file - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml"; - QCString relPath = relativePathToRoot(fileName); - - QFile f(fileName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - writeDocbookHeader_ID(t, fd->getOutputFileBase()); - - t << " <title>"; - writeDocbookString(t,fd->name()); - t << " File Reference"; +void DocbookGenerator::endDoxyAnchor(const char *fileName,const char *anchor) +{ +DB_GEN_C +} +void DocbookGenerator::startMemberDocName(bool) +{ +DB_GEN_C + t << "<para><computeroutput>"; +} +void DocbookGenerator::endMemberDocName() +{ +DB_GEN_C +} +void DocbookGenerator::startMemberGroupHeader(bool hasHeader) +{ +DB_GEN_C + t << "<simplesect><title>"; +} +void DocbookGenerator::endMemberGroupHeader() +{ +DB_GEN_C t << "</title>" << endl; - - IncludeInfo *inc; - - if (fd->includeFileList()) - { - QListIterator<IncludeInfo> ili1(*fd->includeFileList()); - for (ili1.toFirst();(inc=ili1.current());++ili1) - { - t << " <programlisting>#include "; - if (inc->local) - { - t << """; - } - else - { - t << "<"; - } - t << convertToXML(inc->includeName); - if (inc->local) - { - t << """; - } - else - { - t << ">"; - } - t << "</programlisting>" << endl; - } - } - if (Config_getBool(HAVE_DOT)) - { - if (Config_getBool(INCLUDE_GRAPH)) - { - t << "<para>Include dependency diagram for " << convertToXML(fd->name()) << "</para>" << endl; - DotInclDepGraph idepGraph(fd, FALSE); - idepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE); - } - if (Config_getBool(INCLUDED_BY_GRAPH)) - { - t << "<para>Included by dependency diagram for " << convertToXML(fd->name()) << "</para>" << endl; - DotInclDepGraph ibdepGraph(fd, TRUE); - ibdepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE); - } - } - - if (fd->getClassSDict()) - { - writeInnerClasses(fd->getClassSDict(),t); - } - if (fd->getNamespaceSDict()) - { - writeInnerNamespaces(fd->getNamespaceSDict(),t); - } - - if (fd->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict()); - MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - { - generateDocbookSection(fd,t,mg->members(),"user-defined",0,mg->header(), - mg->documentation()); - } - } - - QListIterator<MemberList> mli(fd->getMemberLists()); - MemberList *ml; - for (mli.toFirst();(ml=mli.current());++mli) - { - if ((ml->listType()&MemberListType_declarationLists)!=0) - { - generateDocbookSection(fd,t,ml,g_docbookSectionMapper.find(ml->listType())); - } - } - - t << " <simplesect>" << endl; - t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl; - writeDocbookDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription()); - writeDocbookDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation()); - if (Config_getBool(FULL_PATH_NAMES)) - { - t << " <para>Definition in file " << fd->getDefFileName() << "</para>" << endl; - } - else - { - t << " <para>Definition in file " << stripPath(fd->getDefFileName()) << "</para>" << endl; - } - t << " </simplesect>" << endl; - - if (Config_getBool(DOCBOOK_PROGRAMLISTING)) - { - t << " <literallayout><computeroutput>" << endl; - writeDocbookCodeBlock(t,fd); - t << " </computeroutput></literallayout>" << endl; - } - - t << "</section>" << endl; +} +void DocbookGenerator::startMemberGroup() +{ +DB_GEN_C +} +void DocbookGenerator::endMemberGroup(bool) +{ +DB_GEN_C + t << "</simplesect>" << endl; +} +void DocbookGenerator::startClassDiagram() +{ +DB_GEN_C + t << "<para>"; } -static void generateDocbookForGroup(GroupDef *gd,FTextStream &ti) -{ - // + members - // + member groups - // + files - // + classes - // + namespaces - // - packages - // + pages - // + child groups - // - examples - // + brief description - // + detailed description - - if (gd->isReference()) return; // skip external references - - if (!gd->isASubGroup()) - { - QCString fileDocbook=gd->getOutputFileBase()+".xml"; - //Add the file Documentation info to index file - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - } - - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml"; - QCString relPath = relativePathToRoot(fileName); - - QFile f(fileName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } - - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - writeDocbookHeader_ID(t, gd->getOutputFileBase()); - - t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl; +void DocbookGenerator::endClassDiagram(const ClassDiagram &d, const char *fileName,const char *) +{ +DB_GEN_C + t << " <informalfigure>" << endl; + t << " <mediaobject>" << endl; + t << " <imageobject>" << endl; + t << " <imagedata width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" + << relPath << fileName << ".png\">" << "</imagedata>" << endl; + t << " </imageobject>" << endl; + d.writeImage(t,dir,relPath,fileName,FALSE); + t << " </mediaobject>" << endl; + t << " </informalfigure>" << endl; + t << "</para>" << endl; +} +void DocbookGenerator::startLabels() +{ +DB_GEN_C +} - if (Config_getBool(GROUP_GRAPHS) && Config_getBool(HAVE_DOT)) - { - t << "<para>Collaboration diagram for " << convertToXML(gd->groupTitle()) << "</para>" << endl; - DotGroupCollaboration collaborationGraph(gd); - collaborationGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE); - } +void DocbookGenerator::writeLabel(const char *l,bool isLast) +{ +DB_GEN_C + t << "<computeroutput>[" << l << "]</computeroutput>"; + if (!isLast) t << ", "; +} - if (gd->briefDescription()) - { - //t << " <section>" << endl; - //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl; - writeDocbookDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription()); - //t << " </section>" << endl; - } +void DocbookGenerator::endLabels() +{ +DB_GEN_C +} +void DocbookGenerator::startExamples() +{ +DB_GEN_C + t << "<simplesect><title>"; + docify(theTranslator->trExamples()); + t << "</title>"; +} - if (gd->documentation()) +void DocbookGenerator::endExamples() +{ +DB_GEN_C + t << "</simplesect>" << endl; +} +void DocbookGenerator::startSubsubsection(void) +{ +DB_GEN_C + t << "<simplesect><title>"; +} +void DocbookGenerator::endSubsubsection(void) +{ +DB_GEN_C + t << "</title></simplesect>" << endl; +} +void DocbookGenerator::writeChar(char c) +{ +DB_GEN_C + char cs[2]; + cs[0]=c; + cs[1]=0; + docify(cs); +} +void DocbookGenerator::startMemberDocPrefixItem() +{ +DB_GEN_C + t << "<computeroutput>"; +} +void DocbookGenerator::endMemberDocPrefixItem() +{ +DB_GEN_C + t << "</computeroutput>"; +} +void DocbookGenerator::exceptionEntry(const char* prefix,bool closeBracket) +{ +DB_GEN_C + if (prefix) + t << " " << prefix << "("; + else if (closeBracket) + t << ")"; + t << " "; +} +void DocbookGenerator::startParameterName(bool) +{ +DB_GEN_C + t << " "; +} +void DocbookGenerator::endParameterName(bool last,bool /*emptyList*/,bool closeBracket) +{ +DB_GEN_C + if (last) { - t << " <section>" << endl; - t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl; - writeDocbookDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation()); - t << " </section>" << endl; + if (closeBracket) t << ")"; } +} +void DocbookGenerator::startCodeFragment() +{ +DB_GEN_C + t << "<programlisting>"; +} +void DocbookGenerator::endCodeFragment() +{ +DB_GEN_C + t << "</programlisting>"; +} +void DocbookGenerator::startMemberTemplateParams() +{ +DB_GEN_C +} - writeInnerFiles(gd->getFiles(),t); - writeInnerClasses(gd->getClasses(),t); - writeInnerNamespaces(gd->getNamespaces(),t); - writeInnerPages(gd->getPages(),t); - writeInnerGroups(gd->getSubGroups(),t); - - if (gd->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict()); - MemberGroup *mg; - for (;(mg=mgli.current());++mgli) - { - generateDocbookSection(gd,t,mg->members(),"user-defined",0,mg->header(), - mg->documentation()); - } - } +void DocbookGenerator::endMemberTemplateParams(const char *,const char *) +{ +DB_GEN_C + t << "</para>"; + t << "<para>"; +} +void DocbookGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) +{ +DB_GEN_C + t << " <section xml:id=\"_" << stripPath(lab) << "\">"; + t << "<title>"; +} +void DocbookGenerator::endSection(const char *lab,SectionInfo::SectionType) +{ +DB_GEN_C + t << "</title>"; + t << " </section>"; +} +void DocbookGenerator::addIndexItem(const char *prim,const char *sec) +{ +DB_GEN_C + addIndexTerm(t, prim, sec); +} - QListIterator<MemberList> mli(gd->getMemberLists()); - MemberList *ml; - for (mli.toFirst();(ml=mli.current());++mli) - { - if ((ml->listType()&MemberListType_declarationLists)!=0) - { - generateDocbookSection(gd,t,ml,g_docbookSectionMapper.find(ml->listType())); - } - } - for (mli.toFirst();(ml=mli.current());++mli) +void DocbookGenerator::startDescTable(const char *title) +{ +DB_GEN_C + int ncols = 2; + t << "<informaltable frame=\"all\">" << endl; + if (title)t << "<title>" << convertToDocBook(title) << "</title>" << endl; + t << " <tgroup cols=\"" << ncols << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl; + for (int i = 0; i < ncols; i++) { - if ((ml->listType()&MemberListType_declarationLists)!=0) - { - generateDocbookSection(gd,t,ml,g_docbookSectionMapper.find(ml->listType()),1); - } + t << " <colspec colname='c" << i+1 << "'/>\n"; } + t << "<tbody>\n"; + m_descTable = TRUE; +} - writeInnerGroupFiles(gd->getSubGroups(),t); - - t << "</section>" << endl; - +void DocbookGenerator::endDescTable() +{ +DB_GEN_C + t << " </tbody>" << endl; + t << " </tgroup>" << endl; + t << "</informaltable>" << endl; + m_descTable = FALSE; } -static void generateDocbookForDir(DirDef *dd,FTextStream &ti) +void DocbookGenerator::startDescTableRow() { - if (dd->isReference()) return; // skip external references +DB_GEN_C + t << "<row>"; + t << "<entry>"; +} - QCString fileDocbook=dd->getOutputFileBase()+".xml"; - //Add the file Documentation info to index file - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; +void DocbookGenerator::endDescTableRow() +{ +DB_GEN_C + t << "</row>"; +} - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml"; - QFile f(fileName); - QCString relPath = relativePathToRoot(fileName); +void DocbookGenerator::startDescTableTitle() +{ +DB_GEN_C +} - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } +void DocbookGenerator::endDescTableTitle() +{ +DB_GEN_C +} - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - writeDocbookHeader_ID(t, dd->getOutputFileBase()); +void DocbookGenerator::startDescTableData() +{ +DB_GEN_C + t << "</entry><entry>"; +} - t << " <title>"; - t << theTranslator->trDirReference(dd->displayName()); +void DocbookGenerator::endDescTableData() +{ +DB_GEN_C + t << "</entry>"; +} +void DocbookGenerator::startGroupCollaboration() +{ +DB_GEN_C +} +void DocbookGenerator::endGroupCollaboration(const DotGroupCollaboration &g) +{ +DB_GEN_C + g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE); +} +void DocbookGenerator::startDotGraph() +{ +DB_GEN_C +} +void DocbookGenerator::endDotGraph(const DotClassGraph &g) +{ +DB_GEN_C + g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,TRUE,FALSE); +} +void DocbookGenerator::startInclDepGraph() +{ +DB_GEN_C +} +void DocbookGenerator::endInclDepGraph(const DotInclDepGraph &g) +{ +DB_GEN_C + QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT), fileName,relPath,FALSE); +} +void DocbookGenerator::startCallGraph() +{ +DB_GEN_C +} +void DocbookGenerator::endCallGraph(const DotCallGraph &g) +{ +DB_GEN_C + QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT), fileName,relPath,FALSE); +} +void DocbookGenerator::startDirDepGraph() +{ +DB_GEN_C +} +void DocbookGenerator::endDirDepGraph(const DotDirDeps &g) +{ +DB_GEN_C + QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT), fileName,relPath,FALSE); +} +void DocbookGenerator::startMemberDocList() +{ +DB_GEN_C +} +void DocbookGenerator::endMemberDocList() +{ +DB_GEN_C + m_inGroup = TRUE; +} +void DocbookGenerator::startConstraintList(const char *header) +{ +DB_GEN_C + t << "<simplesect><title>"; + docify(header); t << "</title>" << endl; - if (Config_getBool(DIRECTORY_GRAPH) && Config_getBool(HAVE_DOT)) - { - t << "<para>Directory dependency diagram for " << convertToXML(dd->displayName()) << "</para>" << endl; - DotDirDeps dirdepGraph(dd); - dirdepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE); - } - - writeInnerDirs(&dd->subDirs(),t); - writeInnerFiles(dd->getFiles(),t); - - t << " <simplesect>" << endl; - t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl; - writeDocbookDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription()); - writeDocbookDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation()); - t << " <para>Directory location is " << dd->name() << "</para>" << endl; - t << " </simplesect>" << endl; - - t << "</section>" << endl; } - -static void generateDocbookForPage(PageDef *pd,FTextStream &ti,bool isExample) +void DocbookGenerator::startConstraintParam() { - // + name - // + title - // + documentation - - if (pd->isReference()) return; - - QCString pageName = pd->getOutputFileBase(); - if (pd->getGroupDef()) - { - pageName+=(QCString)"_"+pd->name(); - } - if (pageName=="index") - { - pageName="mainpage"; // to prevent overwriting the generated index page. - } - - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - QCString fileName=outputDirectory+"/"+pageName+".xml"; - QFile f(fileName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } - - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - - if(isExample) - { - QCString fileDocbook=pageName+".xml"; - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - } - - if (!pd->hasParentPage() && !isExample) - { - QCString fileDocbook=pageName+".xml"; - //Add the file Documentation info to index file - ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl; - writeDocbookHeaderMainpage(t); - } - else - { - QCString pid; - if(isExample) - { - pid = pageName; - } - else - { - pid = pageName+"_1"+pageName; - } - writeDocbookHeader_ID(t, pid); - } - - SectionInfo *si = Doxygen::sectionDict->find(pd->name()); - if (si) - { - t << " <title>" << convertToXML(si->title) << "</title>" << endl; - } - else - { - t << " <title>" << convertToXML(pd->name()) << "</title>" << endl; - } - - if (isExample) - { - writeDocbookDocBlock(t,pd->docFile(),pd->docLine(),pd,0, - pd->documentation()+"\n\\include "+pd->name()); - } - else - { - writeDocbookDocBlock(t,pd->docFile(),pd->docLine(),pd,0, - pd->documentation()); - } - writeInnerPages(pd->getSubPages(),t); - - if (!pd->hasParentPage() && !isExample) - { - t << endl << "</chapter>" << endl; - } - else - { - t << endl << "</section>" << endl; - } +DB_GEN_C + t << "<para><emphasis role=\"strong\">"; } - -void generateDocbook() +void DocbookGenerator::endConstraintParam() { - - // + classes - // + namespaces - // + files - // + groups - // + related pages - // - examples - - QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT); - if (outputDirectory.isEmpty()) - { - outputDirectory=QDir::currentDirPath().utf8(); - } - else - { - QDir dir(outputDirectory); - if (!dir.exists()) - { - dir.setPath(QDir::currentDirPath()); - if (!dir.mkdir(outputDirectory)) - { - err("tag DOCBOOK_OUTPUT: Output directory `%s' does not " - "exist and cannot be created\n",outputDirectory.data()); - exit(1); - } - else - { - msg("Notice: Output directory `%s' does not exist. " - "I have created it for you.\n", outputDirectory.data()); - } - dir.cd(outputDirectory); - } - outputDirectory=dir.absPath().utf8(); - } - - QDir dir(outputDirectory); - if (!dir.exists()) - { - dir.setPath(QDir::currentDirPath()); - if (!dir.mkdir(outputDirectory)) - { - err("Cannot create directory %s\n",outputDirectory.data()); - return; - } - } - QDir docbookDir(outputDirectory); - createSubDirs(docbookDir); - - QCString fileName=outputDirectory+"/index.xml"; - QCString dbk_projectName = Config_getString(PROJECT_NAME); - QFile f(fileName); - - f.setName(fileName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot open file %s for writing!\n",fileName.data()); - return; - } - FTextStream t(&f); - //t.setEncoding(FTextStream::UnicodeUTF8); - - // write index header for Docbook which calls the structure file - t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; - t << "<book xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" << endl; - t << " <info>" << endl; - t << " <title>" << dbk_projectName << "</title>" << endl; - t << " </info>" << endl; - - // NAMESPACE DOCUMENTATION - NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); - NamespaceDef *nd; - - //Namespace Documentation index header - if (nli.toFirst()) - { - t << " <chapter>" << endl; - t << " <title>Namespace Documentation</title>" << endl; - } - - for (nli.toFirst();(nd=nli.current());++nli) - { - msg("Generating Docbook output for namespace %s\n",nd->name().data()); - generateDocbookForNamespace(nd,t); - } - - //Namespace Documentation index footer - if (nli.toFirst()) - { - t << " </chapter>" << endl; - } - - /** MAINPAGE DOCUMENTATION **/ - - if (Doxygen::mainPage) - { - msg("Generating Docbook output for the main page\n"); - generateDocbookForPage(Doxygen::mainPage,t,FALSE); - } - - // PAGE DOCUMENTATION - { - PageSDict::Iterator pdi(*Doxygen::pageSDict); - PageDef *pd=0; - - for (pdi.toFirst();(pd=pdi.current());++pdi) - { - msg("Generating Docbook output for page %s\n",pd->name().data()); - generateDocbookForPage(pd,t,FALSE); - } - } - - /** MODULE GROUP DOCUMENTATION **/ - - GroupSDict::Iterator gli(*Doxygen::groupSDict); - GroupDef *gd; - - //Module group Documentation index header - if (gli.toFirst()) - { - t << " <chapter>" << endl; - t << " <title>" << theTranslator->trModuleDocumentation() << "</title>" << endl; - } - - for (;(gd=gli.current());++gli) - { - msg("Generating Docbook output for group %s\n",gd->name().data()); - generateDocbookForGroup(gd,t); - } - - //Module group Documentation index footer - if (gli.toFirst()) - { - t << " </chapter>" << endl; - } - - //CLASS DOCUMENTATION - - { - ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd; - - //Class Documentation index header - if (cli.toFirst()) - { - t << " <chapter>" << endl; - t << " <title>" << theTranslator->trClassDocumentation() << "</title>" << endl; - } - - for (cli.toFirst();(cd=cli.current());++cli) - { - generateDocbookForClass(cd,t); - } - - //Class Documentation index footer - if (cli.toFirst()) - { - t << " </chapter>" << endl; - } - } - - // FILE DOCUMENTATION - - static bool showFiles = Config_getBool(SHOW_FILES); - if (showFiles) - { - FileNameListIterator fnli(*Doxygen::inputNameList); - FileName *fn; - - //File Documentation index header - if (fnli.toFirst()) - { - t << " <chapter>" << endl; - t << " <title>" << theTranslator->trFileDocumentation() << "</title>" << endl; - } - - for (;(fn=fnli.current());++fnli) - { - FileNameIterator fni(*fn); - FileDef *fd; - for (;(fd=fni.current());++fni) - { - msg("Generating Docbook output for file %s\n",fd->name().data()); - generateDocbookForFile(fd,t); - } - } - - //File Documentation index footer - if (fnli.toFirst()) - { - t << " </chapter>" << endl; - } - } - - // DIRECTORY DOCUMENTATION - if (Config_getBool(DIRECTORY_GRAPH) && Config_getBool(HAVE_DOT)) - { - DirDef *dir; - DirSDict::Iterator sdi(*Doxygen::directories); - - //Directory Documentation index header - if (sdi.toFirst()) - { - t << " <chapter>" << endl; - t << " <title>" << theTranslator->trDirDocumentation() << "</title>" << endl; - } - - for (sdi.toFirst();(dir=sdi.current());++sdi) - { - msg("Generate Docbook output for dir %s\n",dir->name().data()); - generateDocbookForDir(dir,t); - } - - //Module group Documentation index footer - if (sdi.toFirst()) - { - t << " </chapter>" << endl; - } - } - - // EXAMPLE PAGE DOCUMENTATION - - { - PageSDict::Iterator pdi(*Doxygen::exampleSDict); - PageDef *pd=0; - - //Example Page Documentation index header - if (pdi.toFirst()) - { - t << " <chapter>" << endl; - t << " <title>" << theTranslator->trExampleDocumentation() << "</title>" << endl; - } - - for (pdi.toFirst();(pd=pdi.current());++pdi) - { - msg("Generating Docbook output for example %s\n",pd->name().data()); - generateDocbookForPage(pd,t,TRUE); - } - - //Example Page Documentation index footer - if (pdi.toFirst()) - { - t << " </chapter>" << endl; - } - } - - t << "</book>" << endl; - +DB_GEN_C +} +void DocbookGenerator::startConstraintType() +{ +DB_GEN_C + t << ":"; +} +void DocbookGenerator::endConstraintType() +{ +DB_GEN_C + t << "</emphasis></para>" << endl; +} +void DocbookGenerator::startConstraintDocs() +{ +DB_GEN_C +} +void DocbookGenerator::endConstraintDocs() +{ +DB_GEN_C +} +void DocbookGenerator::endConstraintList() +{ +DB_GEN_C + t << "</simplesect>" << endl; } - - diff --git a/src/docbookgen.h b/src/docbookgen.h index 866d056..08255a1 100644 --- a/src/docbookgen.h +++ b/src/docbookgen.h @@ -15,6 +15,349 @@ #ifndef DOCBOOKGEN_H #define DOCBOOKGEN_H -void generateDocbook(); +#include "outputgen.h" + +class DocbookCodeGenerator : public CodeOutputInterface +{ + public: + DocbookCodeGenerator(FTextStream &t); + DocbookCodeGenerator(); + virtual ~DocbookCodeGenerator(); + void setTextStream(FTextStream &t) + { + m_streamSet = t.device()!=0; + m_t.setDevice(t.device()); + } + void setRelativePath(const QCString &path) { m_relPath = path; } + void setSourceFileName(const QCString &sourceFileName) { m_sourceFileName = sourceFileName; } + QCString sourceFileName() { return m_sourceFileName; } + + void codify(const char *text); + void writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip); + void writeCodeLinkLine(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip); + void writeTooltip(const char *, const DocLinkInfo &, const char *, + const char *, const SourceLinkInfo &, const SourceLinkInfo & + ); + void startCodeLine(bool); + void endCodeLine(); + void startFontClass(const char *colorClass); + void endFontClass(); + void writeCodeAnchor(const char *); + void writeLineNumber(const char *extRef,const char *compId, + const char *anchorId,int l); + void setCurrentDoc(Definition *,const char *,bool); + void addWord(const char *,bool); + void finish(); + void startCodeFragment(); + void endCodeFragment(); + + private: + FTextStream m_t; + bool m_streamSet; + QCString m_refId; + QCString m_external; + int m_lineNumber; + int m_col; + bool m_insideCodeLine; + bool m_insideSpecialHL; + QCString m_relPath; + QCString m_sourceFileName; + bool m_prettyCode; +}; + + +#if 0 +// define for cases that have been implemented with an empty body +#define DB_GEN_EMPTY t << "<!-- DBG_GEN_head_check " << __LINE__ << " -->\n"; +#else +#define DB_GEN_EMPTY +#endif + +#if 0 +// Generic debug statements +#define DB_GEN_H DB_GEN_H1(t) +#define DB_GEN_H1(x) x << "<!-- DBG_GEN_head " << __LINE__ << " -->\n"; +#define DB_GEN_H2(y) DB_GEN_H2a(t,y) +#define DB_GEN_H2a(x,y) x << "<!-- DBG_GEN_head " << __LINE__ << " " << y << " -->\n"; +// define for cases that have NOT yet been implemented / considered +#define DB_GEN_NEW fprintf(stderr,"DBG_GEN_head %d\n",__LINE__); DB_GEN_H +#else +#define DB_GEN_H +#define DB_GEN_H1(x) +#define DB_GEN_H2(y) +#define DB_GEN_H2a(x,y) +#define DB_GEN_NEW +#endif + +class DocbookGenerator : public OutputGenerator +{ + public: + DocbookGenerator(); + ~DocbookGenerator(); + static void init(); + + /////////////////////////////////////////////////////////////// + // generic generator methods + /////////////////////////////////////////////////////////////// + void enable() + { if (genStack->top()) active=*genStack->top(); else active=TRUE; } + void disable() { active=FALSE; } + void enableIf(OutputType o) { if (o==Docbook) enable(); } + void disableIf(OutputType o) { if (o==Docbook) disable(); } + void disableIfNot(OutputType o) { if (o!=Docbook) disable(); } + bool isEnabled(OutputType o) { return (o==Docbook && active); } + OutputGenerator *get(OutputType o) { return (o==Docbook) ? this : 0; } + + // --- CodeOutputInterface + void codify(const char *text) + { m_codeGen.codify(text); } + void writeCodeLink(const char *ref, const char *file, + const char *anchor,const char *name, + const char *tooltip) + { m_codeGen.writeCodeLink(ref,file,anchor,name,tooltip); } + void writeLineNumber(const char *ref,const char *file,const char *anchor,int lineNumber) + { m_codeGen.writeLineNumber(ref,file,anchor,lineNumber); } + void writeTooltip(const char *id, const DocLinkInfo &docInfo, const char *decl, + const char *desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo + ) + { m_codeGen.writeTooltip(id,docInfo,decl,desc,defInfo,declInfo); } + void startCodeLine(bool hasLineNumbers) + { m_codeGen.startCodeLine(hasLineNumbers); } + void endCodeLine() + { m_codeGen.endCodeLine(); } + void startFontClass(const char *s) + { m_codeGen.startFontClass(s); } + void endFontClass() + { m_codeGen.endFontClass(); } + void writeCodeAnchor(const char *anchor) + { m_codeGen.writeCodeAnchor(anchor); } + // --------------------------- + + void writeDoc(DocNode *,Definition *ctx,MemberDef *md); + + /////////////////////////////////////////////////////////////// + // structural output interface + /////////////////////////////////////////////////////////////// + void startFile(const char *name,const char *manName, + const char *title); + void writeSearchInfo(){DB_GEN_EMPTY}; + void writeFooter(const char *navPath){DB_GEN_NEW}; + void endFile(); + void startIndexSection(IndexSections); + void endIndexSection(IndexSections); + void writePageLink(const char *,bool); + void startProjectNumber(){DB_GEN_NEW}; + void endProjectNumber(){DB_GEN_NEW}; + void writeStyleInfo(int part){DB_GEN_EMPTY}; + void startTitleHead(const char *); + void endTitleHead(const char *fileName,const char *name); + void startIndexListItem(){DB_GEN_NEW}; + void endIndexListItem(){DB_GEN_NEW}; + void startIndexList(){DB_GEN_NEW}; + void endIndexList(){DB_GEN_NEW}; + void startIndexKey(){DB_GEN_NEW}; + void endIndexKey(){DB_GEN_NEW}; + void startIndexValue(bool){DB_GEN_NEW}; + void endIndexValue(const char *,bool){DB_GEN_NEW}; + void startItemList() {DB_GEN_EMPTY}; + void endItemList() {DB_GEN_EMPTY}; + + void startIndexItem(const char *ref,const char *file){DB_GEN_NEW}; + void endIndexItem(const char *ref,const char *file){DB_GEN_NEW}; + void startItemListItem() {DB_GEN_EMPTY}; + void endItemListItem() {DB_GEN_EMPTY}; + void docify(const char *text); + void writeChar(char); + void writeString(const char *); + void startParagraph(const char *); + void endParagraph(void); + void writeObjectLink(const char *,const char *,const char *,const char *); + void startHtmlLink(const char *){DB_GEN_NEW}; + void endHtmlLink(void){DB_GEN_NEW}; + void startBold(void); + void endBold(void); + void startTypewriter(void); + void endTypewriter(void); + void startEmphasis(void){DB_GEN_NEW}; + void endEmphasis(void){DB_GEN_NEW}; + void startCodeFragment(void); + void endCodeFragment(void); + void writeRuler(void); + void startDescription(void){DB_GEN_NEW}; + void endDescription(void){DB_GEN_NEW}; + void startDescItem(void){DB_GEN_NEW}; + void startDescForItem(void){DB_GEN_EMPTY}; + void endDescForItem(void){DB_GEN_EMPTY}; + void endDescItem(void){DB_GEN_NEW}; + void startCenter(void){DB_GEN_NEW}; + void endCenter(void){DB_GEN_NEW}; + void startSmall(void){DB_GEN_NEW}; + void endSmall(void){DB_GEN_NEW}; + void startExamples(void); + void endExamples(void); + void startParamList(BaseOutputDocInterface::ParamListTypes,const char *){DB_GEN_NEW}; + void endParamList(void){DB_GEN_NEW}; + void startTitle(void){DB_GEN_NEW}; + void endTitle(void){DB_GEN_NEW}; + void writeAnchor(const char *,const char *){DB_GEN_EMPTY}; + void startSection(const char *,const char *,SectionInfo::SectionType); + void endSection(const char *,SectionInfo::SectionType); + void lineBreak(const char *); + void addIndexItem(const char *,const char *); + void writeNonBreakableSpace(int); + void startDescTable(const char *); + void endDescTable(void); + void startDescTableRow(void); + void endDescTableRow(void); + void startDescTableTitle(void); + void endDescTableTitle(void); + void startDescTableData(void); + void endDescTableData(void); + void startTextLink(const char *,const char *){DB_GEN_NEW}; + void endTextLink(void){DB_GEN_NEW}; + void startPageRef(void){DB_GEN_NEW}; + void endPageRef(const char *,const char *){DB_GEN_NEW}; + void startSubsection(void){DB_GEN_NEW}; + void endSubsection(void){DB_GEN_NEW}; + void startSubsubsection(void); + void endSubsubsection(void); + + + void startGroupHeader(int); + void endGroupHeader(int); + void startMemberSections(){DB_GEN_EMPTY}; + void endMemberSections(){DB_GEN_EMPTY}; + void startHeaderSection(){DB_GEN_EMPTY}; + void endHeaderSection(){DB_GEN_EMPTY}; + void startMemberHeader(const char *anchor, int typ); + void endMemberHeader(); + void startMemberSubtitle(){DB_GEN_EMPTY}; + void endMemberSubtitle(){DB_GEN_EMPTY}; + void startMemberDocList(); + void endMemberDocList(); + void startMemberList(); + void endMemberList(); + void startInlineHeader(){DB_GEN_NEW}; + void endInlineHeader(){DB_GEN_NEW}; + void startAnonTypeScope(int){DB_GEN_EMPTY}; + void endAnonTypeScope(int){DB_GEN_EMPTY}; + void startMemberItem(const char *,int,const char *); + void endMemberItem(); + void startMemberTemplateParams(); + void endMemberTemplateParams(const char *,const char *); + void startMemberGroupHeader(bool); + void endMemberGroupHeader(); + void startMemberGroupDocs(){DB_GEN_EMPTY}; + void endMemberGroupDocs(){DB_GEN_EMPTY}; + void startMemberGroup(); + void endMemberGroup(bool); + void insertMemberAlign(bool){DB_GEN_EMPTY}; + void insertMemberAlignLeft(int,bool){DB_GEN_EMPTY}; + void startMemberDoc(const char *,const char *, + const char *,const char *,int,int,bool); + void endMemberDoc(bool); + void startDoxyAnchor(const char *fName,const char *manName, + const char *anchor,const char *name, + const char *args); + void endDoxyAnchor(const char *fileName,const char *anchor); + void writeLatexSpacing(){DB_GEN_EMPTY} + void writeStartAnnoItem(const char *type,const char *file, + const char *path,const char *name){DB_GEN_NEW}; + void writeEndAnnoItem(const char *name){DB_GEN_NEW}; + void startMemberDescription(const char *anchor,const char *inheritId, bool typ){DB_GEN_EMPTY}; + void endMemberDescription(){DB_GEN_EMPTY}; + void startMemberDeclaration(){DB_GEN_EMPTY}; + void endMemberDeclaration(const char *anchor,const char *inheritId){DB_GEN_EMPTY}; + void writeInheritedSectionTitle(const char *id,const char *ref, + const char *file,const char *anchor, + const char *title,const char *name){DB_GEN_NEW}; + void startIndent(){DB_GEN_EMPTY}; + void endIndent(){DB_GEN_EMPTY}; + void writeSynopsis(){DB_GEN_EMPTY}; + void startClassDiagram(); + void endClassDiagram(const ClassDiagram &,const char *,const char *); + void startDotGraph(); + void endDotGraph(const DotClassGraph &g); + void startInclDepGraph(); + void endInclDepGraph(const DotInclDepGraph &g); + void startGroupCollaboration(); + void endGroupCollaboration(const DotGroupCollaboration &g); + void startCallGraph(); + void endCallGraph(const DotCallGraph &g); + void startDirDepGraph(); + void endDirDepGraph(const DotDirDeps &g); + void writeGraphicalHierarchy(const DotGfxHierarchyTable &g){DB_GEN_NEW}; + void startQuickIndices(){DB_GEN_EMPTY}; + void endQuickIndices(){DB_GEN_EMPTY}; + void writeSplitBar(const char *){DB_GEN_EMPTY}; + void writeNavigationPath(const char *){DB_GEN_NEW}; + void writeLogo(){DB_GEN_NEW}; + void writeQuickLinks(bool compact,HighlightedItem hli,const char *file){DB_GEN_EMPTY}; + void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first){DB_GEN_EMPTY}; + void startContents(){DB_GEN_EMPTY}; + void endContents(){DB_GEN_EMPTY}; + void startPageDoc(const char *pageTitle){DB_GEN_EMPTY} + void endPageDoc() {DB_GEN_EMPTY} + void startTextBlock(bool); + void endTextBlock(bool); + void lastIndexPage(){DB_GEN_EMPTY}; + void startMemberDocPrefixItem(); + void endMemberDocPrefixItem(); + void startMemberDocName(bool); + void endMemberDocName(); + void startParameterType(bool,const char *key){DB_GEN_EMPTY}; + void endParameterType(){DB_GEN_EMPTY}; + void startParameterName(bool); + void endParameterName(bool,bool,bool); + void startParameterList(bool); + void endParameterList(); + void exceptionEntry(const char*,bool); + + void startConstraintList(const char *); + void startConstraintParam(); + void endConstraintParam(); + void startConstraintType(); + void endConstraintType(); + void startConstraintDocs(); + void endConstraintDocs(); + void endConstraintList(); + + void startMemberDocSimple(bool){DB_GEN_NEW}; + void endMemberDocSimple(bool){DB_GEN_NEW}; + void startInlineMemberType(){DB_GEN_NEW}; + void endInlineMemberType(){DB_GEN_NEW}; + void startInlineMemberName(){DB_GEN_NEW}; + void endInlineMemberName(){DB_GEN_NEW}; + void startInlineMemberDoc(){DB_GEN_NEW}; + void endInlineMemberDoc(){DB_GEN_NEW}; + + void startLabels(); + void writeLabel(const char *,bool); + void endLabels(); + + void setCurrentDoc(Definition *,const char *,bool) {DB_GEN_EMPTY} + void addWord(const char *,bool) {DB_GEN_EMPTY} + +private: + DocbookGenerator(const DocbookGenerator &o); + DocbookGenerator &operator=(const DocbookGenerator &o); + + QCString relPath; + DocbookCodeGenerator m_codeGen; + bool m_prettyCode; + bool m_denseText; + bool m_inGroup; + bool m_inDetail; + int m_levelListItem; + bool m_inListItem[20]; + bool m_inSimpleSect[20]; + bool m_descTable; + int m_inLevel; + bool m_firstMember; +}; #endif diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index ab10da0..99df99c 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -34,58 +34,99 @@ #include "msc.h" #include "dia.h" #include "htmlentity.h" +#include "emoji.h" #include "plantuml.h" -static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, QCString width, QCString height) +#if 0 +#define DB_VIS_C DB_VIS_C1(m_t) +#define DB_VIS_C1(x) x << "<!-- DB_VIS_C " << __LINE__ << " -->\n"; +#define DB_VIS_C2(y) DB_VIS_C2a(m_t,y) +#define DB_VIS_C2a(x,y) x << "<!-- DB_VIS_C " << __LINE__ << " " << y << " -->\n"; +#else +#define DB_VIS_C +#define DB_VIS_C1(x) +#define DB_VIS_C2(y) +#define DB_VIS_C2a(x,y) +#endif + +void DocbookDocVisitor::visitCaption(const QList<DocNode> &children) +{ + QListIterator<DocNode> cli(children); + DocNode *n; + for (cli.toFirst();(n=cli.current());++cli) n->accept(this); +} + +void DocbookDocVisitor::visitPreStart(FTextStream &t, + const QList<DocNode> &children, + bool hasCaption, + const QCString &name, + const QCString &width, + const QCString &height, + bool inlineImage) { - QCString tmpStr; - t << " <figure>" << endl; - t << " <title></title>" << endl; + if (hasCaption && !inlineImage) + { + t << " <figure>" << endl; + t << " <title>" << endl; + visitCaption(children); + t << " </title>" << endl; + } + else + { + t << " <informalfigure>" << endl; + } t << " <mediaobject>" << endl; t << " <imageobject>" << endl; t << " <imagedata"; if (!width.isEmpty()) { - t << " width=\"" << convertToXML(width) << "\""; + t << " width=\"" << convertToDocBook(width) << "\""; } else { - t << " width=\"50%\""; + if (!height.isEmpty() && !inlineImage) t << " width=\"50%\""; } if (!height.isEmpty()) { - t << " depth=\"" << convertToXML(tmpStr) << "\""; + t << " depth=\"" << convertToDocBook(height) << "\""; } - t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << name << "\">"; + t << " align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << name << "\">"; t << "</imagedata>" << endl; t << " </imageobject>" << endl; - if (hasCaption) + if (hasCaption && !inlineImage) { - t << " <caption>" << endl; + t << " <!--" << endl; // Needed for general formatting with title for other formats } } -static void visitPostEnd(FTextStream &t, const bool hasCaption) +void DocbookDocVisitor::visitPostEnd(FTextStream &t, bool hasCaption, bool inlineImage) { t << endl; - if (hasCaption) + if (hasCaption && !inlineImage) { - t << " </caption>" << endl; + t << " -->" << endl; // Needed for general formatting with title for other formats } t << " </mediaobject>" << endl; - t << " </figure>" << endl; -} - -static void visitCaption(DocbookDocVisitor *parent, QList<DocNode> children) -{ - QListIterator<DocNode> cli(children); - DocNode *n; - for (cli.toFirst();(n=cli.current());++cli) n->accept(parent); + if (hasCaption && !inlineImage) + { + t << " </figure>" << endl; + } + else + { + t << " </informalfigure>" << endl; + } } DocbookDocVisitor::DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci) : DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) { +DB_VIS_C + // m_t << "<section>" << endl; +} +DocbookDocVisitor::~DocbookDocVisitor() +{ +DB_VIS_C + // m_t << "</section>" << endl; } //-------------------------------------- @@ -94,12 +135,14 @@ DocbookDocVisitor::DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci) void DocbookDocVisitor::visit(DocWord *w) { +DB_VIS_C if (m_hide) return; filter(w->word()); } void DocbookDocVisitor::visit(DocLinkedWord *w) { +DB_VIS_C if (m_hide) return; startLink(w->file(),w->anchor()); filter(w->word()); @@ -108,6 +151,7 @@ void DocbookDocVisitor::visit(DocLinkedWord *w) void DocbookDocVisitor::visit(DocWhiteSpace *w) { +DB_VIS_C if (m_hide) return; if (m_insidePre) { @@ -121,6 +165,7 @@ void DocbookDocVisitor::visit(DocWhiteSpace *w) void DocbookDocVisitor::visit(DocSymbol *s) { +DB_VIS_C if (m_hide) return; const char *res = HtmlEntityMapper::instance()->docbook(s->symbol()); if (res) @@ -133,8 +178,24 @@ void DocbookDocVisitor::visit(DocSymbol *s) } } +void DocbookDocVisitor::visit(DocEmoji *s) +{ +DB_VIS_C + if (m_hide) return; + const char *res = EmojiEntityMapper::instance()->unicode(s->index()); + if (res) + { + m_t << res; + } + else + { + m_t << s->name(); + } +} + void DocbookDocVisitor::visit(DocURL *u) { +DB_VIS_C if (m_hide) return; m_t << "<link xlink:href=\""; if (u->isEmail()) m_t << "mailto:"; @@ -146,12 +207,16 @@ void DocbookDocVisitor::visit(DocURL *u) void DocbookDocVisitor::visit(DocLineBreak *) { +DB_VIS_C if (m_hide) return; - m_t << endl << "<literallayout>\n</literallayout>" << endl; + m_t << endl << "<literallayout> 
</literallayout>" << endl; + // gives nicer results but gives problems as it is not allowed in <pare> and also problems with dblatex + // m_t << endl << "<sbr/>" << endl; } void DocbookDocVisitor::visit(DocHorRuler *) { +DB_VIS_C if (m_hide) return; m_t << "<informaltable frame='bottom'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>\n"; m_t << "</entry></row></tbody></tgroup></informaltable>\n"; @@ -159,6 +224,7 @@ void DocbookDocVisitor::visit(DocHorRuler *) void DocbookDocVisitor::visit(DocStyleChange *s) { +DB_VIS_C if (m_hide) return; switch (s->style()) { @@ -196,6 +262,8 @@ void DocbookDocVisitor::visit(DocStyleChange *s) /* There is no equivalent Docbook tag for rendering Small text */ case DocStyleChange::Small: /* XSLT Stylesheets can be used */ break; /* HTML only */ + case DocStyleChange::Strike: break; + case DocStyleChange::Underline: break; case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; } @@ -203,6 +271,7 @@ void DocbookDocVisitor::visit(DocStyleChange *s) void DocbookDocVisitor::visit(DocVerbatim *s) { +DB_VIS_C if (m_hide) return; SrcLangExt langExt = getLanguageFromFileName(m_langExt); switch(s->type()) @@ -215,9 +284,9 @@ void DocbookDocVisitor::visit(DocVerbatim *s) m_t << "</computeroutput></literallayout>"; break; case DocVerbatim::Verbatim: - m_t << "<literallayout>"; + m_t << "<literallayout><computeroutput>"; filter(s->text()); - m_t << "</literallayout>"; + m_t << "</computeroutput></literallayout>"; break; case DocVerbatim::HtmlOnly: break; @@ -230,7 +299,6 @@ void DocbookDocVisitor::visit(DocVerbatim *s) case DocVerbatim::XmlOnly: break; case DocVerbatim::DocbookOnly: - break; m_t << s->text(); break; case DocVerbatim::Dot: @@ -302,12 +370,14 @@ void DocbookDocVisitor::visit(DocVerbatim *s) void DocbookDocVisitor::visit(DocAnchor *anc) { +DB_VIS_C if (m_hide) return; - m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>"; + m_t << "<anchor xml:id=\"_" << stripPath(anc->file()) << "_1" << anc->anchor() << "\"/>"; } void DocbookDocVisitor::visit(DocInclude *inc) { +DB_VIS_C if (m_hide) return; SrcLangExt langExt = getLanguageFromFileName(inc->extension()); switch(inc->type()) @@ -343,9 +413,9 @@ void DocbookDocVisitor::visit(DocInclude *inc) case DocInclude::LatexInclude: break; case DocInclude::VerbInclude: - m_t << "<verbatim>"; + m_t << "<literallayout>"; filter(inc->text()); - m_t << "</verbatim>"; + m_t << "</literallayout>"; break; case DocInclude::Snippet: m_t << "<literallayout><computeroutput>"; @@ -391,6 +461,7 @@ void DocbookDocVisitor::visit(DocInclude *inc) void DocbookDocVisitor::visit(DocIncOperator *op) { +DB_VIS_C if (op->isFirst()) { if (!m_hide) @@ -427,27 +498,37 @@ void DocbookDocVisitor::visit(DocIncOperator *op) void DocbookDocVisitor::visit(DocFormula *f) { +DB_VIS_C if (m_hide) return; - m_t << "<equation><title>" << f->name() << "</title>"; - filter(f->text()); - m_t << "</equation>"; + + if (f->isInline()) m_t << "<inlinemediaobject>" << endl; + else m_t << " <mediaobject>" << endl; + m_t << " <imageobject>" << endl; + m_t << " <imagedata "; + m_t << "align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << f->relPath() << f->name() << ".png\"/>" << endl; + m_t << " </imageobject>" << endl; + if (f->isInline()) m_t << "</inlinemediaobject>" << endl; + else m_t << " </mediaobject>" << endl; } void DocbookDocVisitor::visit(DocIndexEntry *ie) { +DB_VIS_C if (m_hide) return; - m_t << "<indexentry><primaryie>" << endl; + m_t << "<indexterm><primary>"; filter(ie->entry()); - m_t << "</primaryie><secondaryie></secondaryie></indexentry>" << endl; + m_t << "</primary></indexterm>" << endl; } void DocbookDocVisitor::visit(DocSimpleSectSep *) { - m_t << "<simplesect/>"; +DB_VIS_C + // m_t << "<simplesect/>"; } void DocbookDocVisitor::visit(DocCite *cite) { +DB_VIS_C if (m_hide) return; if (!cite->file().isEmpty()) startLink(cite->file(),cite->anchor()); filter(cite->text()); @@ -460,6 +541,7 @@ void DocbookDocVisitor::visit(DocCite *cite) void DocbookDocVisitor::visitPre(DocAutoList *l) { +DB_VIS_C if (m_hide) return; if (l->isEnumList()) { @@ -473,6 +555,7 @@ void DocbookDocVisitor::visitPre(DocAutoList *l) void DocbookDocVisitor::visitPost(DocAutoList *l) { +DB_VIS_C if (m_hide) return; if (l->isEnumList()) { @@ -486,18 +569,21 @@ void DocbookDocVisitor::visitPost(DocAutoList *l) void DocbookDocVisitor::visitPre(DocAutoListItem *) { +DB_VIS_C if (m_hide) return; m_t << "<listitem>"; } void DocbookDocVisitor::visitPost(DocAutoListItem *) { +DB_VIS_C if (m_hide) return; m_t << "</listitem>"; } void DocbookDocVisitor::visitPre(DocPara *) { +DB_VIS_C if (m_hide) return; m_t << endl; m_t << "<para>"; @@ -505,6 +591,7 @@ void DocbookDocVisitor::visitPre(DocPara *) void DocbookDocVisitor::visitPost(DocPara *) { +DB_VIS_C if (m_hide) return; m_t << "</para>"; m_t << endl; @@ -512,16 +599,19 @@ void DocbookDocVisitor::visitPost(DocPara *) void DocbookDocVisitor::visitPre(DocRoot *) { +DB_VIS_C //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n"; } void DocbookDocVisitor::visitPost(DocRoot *) { +DB_VIS_C //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n"; } void DocbookDocVisitor::visitPre(DocSimpleSect *s) { +DB_VIS_C if (m_hide) return; switch(s->type()) { @@ -532,7 +622,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trSeeAlso()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSeeAlso()) << ": </title>" << endl; } break; case DocSimpleSect::Return: @@ -542,7 +632,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trReturns()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trReturns()) << ": </title>" << endl; } break; case DocSimpleSect::Author: @@ -552,7 +642,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trAuthor(TRUE, TRUE)) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, TRUE)) << ": </title>" << endl; } break; case DocSimpleSect::Authors: @@ -562,7 +652,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trAuthor(TRUE, FALSE)) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, FALSE)) << ": </title>" << endl; } break; case DocSimpleSect::Version: @@ -572,7 +662,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trVersion()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trVersion()) << ": </title>" << endl; } break; case DocSimpleSect::Since: @@ -582,7 +672,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trSince()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSince()) << ": </title>" << endl; } break; case DocSimpleSect::Date: @@ -592,27 +682,27 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trDate()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trDate()) << ": </title>" << endl; } break; case DocSimpleSect::Note: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trNote() << ": </title>" << endl; + m_t << "<note><title>" << theTranslator->trNote() << ": </title>" << endl; } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trNote()) << ": </title>" << endl; + m_t << "<note><title>" << convertToDocBook(theTranslator->trNote()) << ": </title>" << endl; } break; case DocSimpleSect::Warning: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trWarning() << ": </title>" << endl; + m_t << "<warning><title>" << theTranslator->trWarning() << ": </title>" << endl; } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trWarning()) << ": </title>" << endl; + m_t << "<warning><title>" << convertToDocBook(theTranslator->trWarning()) << ": </title>" << endl; } break; case DocSimpleSect::Pre: @@ -622,7 +712,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trPrecondition()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPrecondition()) << ": </title>" << endl; } break; case DocSimpleSect::Post: @@ -632,7 +722,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trPostcondition()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPostcondition()) << ": </title>" << endl; } break; case DocSimpleSect::Copyright: @@ -642,7 +732,7 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trCopyright()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trCopyright()) << ": </title>" << endl; } break; case DocSimpleSect::Invar: @@ -652,85 +742,121 @@ void DocbookDocVisitor::visitPre(DocSimpleSect *s) } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trInvariant()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trInvariant()) << ": </title>" << endl; } break; case DocSimpleSect::Remark: + // <remark> is miising the <title> possibility if (m_insidePre) { m_t << "<formalpara><title>" << theTranslator->trRemarks() << ": </title>" << endl; } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trRemarks()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trRemarks()) << ": </title>" << endl; } break; case DocSimpleSect::Attention: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trAttention() << ": </title>" << endl; + m_t << "<caution><title>" << theTranslator->trAttention() << ": </title>" << endl; } else { - m_t << "<formalpara><title>" << convertToXML(theTranslator->trAttention()) << ": </title>" << endl; + m_t << "<caution><title>" << convertToDocBook(theTranslator->trAttention()) << ": </title>" << endl; } break; case DocSimpleSect::User: - m_t << "<formalpara><title></title>" << endl; + if (s->hasTitle()) + m_t << "<formalpara>" << endl; + else + m_t << "<para>" << endl; break; case DocSimpleSect::Rcs: - m_t << "<formalpara><title></title>" << endl; + case DocSimpleSect::Unknown: + m_t << "<para>" << endl; break; - case DocSimpleSect::Unknown: m_t << "<formalpara><title></title>" << endl; break; } } -void DocbookDocVisitor::visitPost(DocSimpleSect *) +void DocbookDocVisitor::visitPost(DocSimpleSect *s) { +DB_VIS_C if (m_hide) return; - m_t << "</formalpara>" << endl; + switch(s->type()) + { + case DocSimpleSect::Rcs: + case DocSimpleSect::Unknown: + m_t << "</para>" << endl; + break; + case DocSimpleSect::User: + if (s->hasTitle()) + m_t << "</formalpara>" << endl; + else + m_t << "</para>" << endl; + break; + case DocSimpleSect::Note: + m_t << "</note>" << endl; + break; + case DocSimpleSect::Attention: + m_t << "</caution>" << endl; + break; + case DocSimpleSect::Warning: + m_t << "</warning>" << endl; + break; + default: + m_t << "</formalpara>" << endl; + break; + } } -void DocbookDocVisitor::visitPre(DocTitle *) +void DocbookDocVisitor::visitPre(DocTitle *t) { +DB_VIS_C if (m_hide) return; - m_t << "<title>"; + if (t->hasTitle()) m_t << "<title>"; } -void DocbookDocVisitor::visitPost(DocTitle *) +void DocbookDocVisitor::visitPost(DocTitle *t) { +DB_VIS_C if (m_hide) return; - m_t << "</title>"; + if (t->hasTitle()) m_t << "</title>"; } void DocbookDocVisitor::visitPre(DocSimpleList *) { +DB_VIS_C if (m_hide) return; m_t << "<itemizedlist>\n"; } void DocbookDocVisitor::visitPost(DocSimpleList *) { +DB_VIS_C if (m_hide) return; m_t << "</itemizedlist>\n"; } void DocbookDocVisitor::visitPre(DocSimpleListItem *) { +DB_VIS_C if (m_hide) return; m_t << "<listitem>"; } void DocbookDocVisitor::visitPost(DocSimpleListItem *) { +DB_VIS_C if (m_hide) return; m_t << "</listitem>\n"; } void DocbookDocVisitor::visitPre(DocSection *s) { +DB_VIS_C if (m_hide) return; - m_t << "<section xml:id=\"" << s->file(); + m_t << "<section xml:id=\"_" << stripPath(s->file()); if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor(); m_t << "\">" << endl; m_t << "<title>"; @@ -740,11 +866,13 @@ void DocbookDocVisitor::visitPre(DocSection *s) void DocbookDocVisitor::visitPost(DocSection *) { +DB_VIS_C m_t << "</section>\n"; } void DocbookDocVisitor::visitPre(DocHtmlList *s) { +DB_VIS_C if (m_hide) return; if (s->type()==DocHtmlList::Ordered) m_t << "<orderedlist>\n"; @@ -754,6 +882,7 @@ void DocbookDocVisitor::visitPre(DocHtmlList *s) void DocbookDocVisitor::visitPost(DocHtmlList *s) { +DB_VIS_C if (m_hide) return; if (s->type()==DocHtmlList::Ordered) m_t << "</orderedlist>\n"; @@ -763,143 +892,277 @@ void DocbookDocVisitor::visitPost(DocHtmlList *s) void DocbookDocVisitor::visitPre(DocHtmlListItem *) { +DB_VIS_C if (m_hide) return; m_t << "<listitem>\n"; } void DocbookDocVisitor::visitPost(DocHtmlListItem *) { +DB_VIS_C if (m_hide) return; m_t << "</listitem>\n"; } void DocbookDocVisitor::visitPre(DocHtmlDescList *) { +DB_VIS_C if (m_hide) return; m_t << "<variablelist>\n"; } void DocbookDocVisitor::visitPost(DocHtmlDescList *) { +DB_VIS_C if (m_hide) return; m_t << "</variablelist>\n"; } void DocbookDocVisitor::visitPre(DocHtmlDescTitle *) { +DB_VIS_C if (m_hide) return; m_t << "<varlistentry><term>"; } void DocbookDocVisitor::visitPost(DocHtmlDescTitle *) { +DB_VIS_C if (m_hide) return; m_t << "</term>\n"; } void DocbookDocVisitor::visitPre(DocHtmlDescData *) { +DB_VIS_C if (m_hide) return; m_t << "<listitem>"; } void DocbookDocVisitor::visitPost(DocHtmlDescData *) { +DB_VIS_C if (m_hide) return; m_t << "</listitem></varlistentry>\n"; } +static int colCnt = 0; +static bool bodySet = FALSE; // it is possible to have tables without a header void DocbookDocVisitor::visitPre(DocHtmlTable *t) { +DB_VIS_C + bodySet = FALSE; if (m_hide) return; - m_t << "<table frame=\"all\">" << endl; - m_t << " <title></title>" << endl; + m_t << "<informaltable frame=\"all\">" << endl; m_t << " <tgroup cols=\"" << t->numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl; - m_t << " <tbody>" << endl; + for (int 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"; + } } void DocbookDocVisitor::visitPost(DocHtmlTable *) { +DB_VIS_C if (m_hide) return; - m_t << " </tbody>" << endl; + if (bodySet) m_t << " </tbody>" << endl; + bodySet = FALSE; m_t << " </tgroup>" << endl; - m_t << "</table>" << endl; + m_t << "</informaltable>" << endl; } -void DocbookDocVisitor::visitPre(DocHtmlRow *) +void DocbookDocVisitor::visitPre(DocHtmlRow *tr) { +DB_VIS_C + colCnt = 0; if (m_hide) return; - m_t << "<row>\n"; + + if (tr->isHeading()) m_t << "<thead>\n"; + else if (!bodySet) + { + bodySet = TRUE; + m_t << "<tbody>\n"; + } + + m_t << " <row "; + + HtmlAttribListIterator li(tr->attribs()); + HtmlAttrib *opt; + for (li.toFirst();(opt=li.current());++li) + { + if (opt->name=="class") + { + // just skip it + } + else if (opt->name=="style") + { + // just skip it + } + else if (opt->name=="height") + { + // just skip it + } + else if (opt->name=="filter") + { + // just skip it + } + else + { + m_t << " " << opt->name << "='" << opt->value << "'"; + } + } + m_t << ">\n"; } -void DocbookDocVisitor::visitPost(DocHtmlRow *) +void DocbookDocVisitor::visitPost(DocHtmlRow *tr) { +DB_VIS_C if (m_hide) return; m_t << "</row>\n"; + if (tr->isHeading()) + { + bodySet = TRUE; + m_t << "</thead><tbody>\n"; + } } -void DocbookDocVisitor::visitPre(DocHtmlCell *) +void DocbookDocVisitor::visitPre(DocHtmlCell *c) { +DB_VIS_C + colCnt++; if (m_hide) return; - m_t << "<entry>"; + m_t << "<entry"; + + HtmlAttribListIterator li(c->attribs()); + HtmlAttrib *opt; + for (li.toFirst();(opt=li.current());++li) + { + if (opt->name=="colspan") + { + m_t << " namest='c" << colCnt << "'"; + int cols = opt->value.toInt(); + colCnt += (cols - 1); + m_t << " nameend='c" << colCnt << "'"; + } + else if (opt->name=="rowspan") + { + int extraRows = opt->value.toInt() - 1; + m_t << " morerows='" << extraRows << "'"; + } + else if (opt->name=="class") + { + if (opt->value == "markdownTableBodyRight") + { + m_t << " align='right'"; + } + else if (opt->value == "markdownTableBodyLeftt") + { + m_t << " align='left'"; + } + else if (opt->value == "markdownTableBodyCenter") + { + m_t << " align='center'"; + } + else if (opt->value == "markdownTableHeadRight") + { + m_t << " align='right'"; + } + else if (opt->value == "markdownTableHeadLeftt") + { + m_t << " align='left'"; + } + else if (opt->value == "markdownTableHeadCenter") + { + m_t << " align='center'"; + } + } + else if (opt->name=="style") + { + // just skip it + } + else if (opt->name=="width") + { + // just skip it + } + else if (opt->name=="height") + { + // just skip it + } + else + { + m_t << " " << opt->name << "='" << opt->value << "'"; + } + } + m_t << ">"; } -void DocbookDocVisitor::visitPost(DocHtmlCell *) +void DocbookDocVisitor::visitPost(DocHtmlCell *c) { +DB_VIS_C if (m_hide) return; m_t << "</entry>"; } -void DocbookDocVisitor::visitPre(DocHtmlCaption *) +void DocbookDocVisitor::visitPre(DocHtmlCaption *c) { +DB_VIS_C if (m_hide) return; - m_t << "<caption>"; + m_t << "<caption>"; } void DocbookDocVisitor::visitPost(DocHtmlCaption *) { +DB_VIS_C if (m_hide) return; m_t << "</caption>\n"; } void DocbookDocVisitor::visitPre(DocInternal *) { +DB_VIS_C if (m_hide) return; // TODO: to be implemented } void DocbookDocVisitor::visitPost(DocInternal *) { +DB_VIS_C if (m_hide) return; // TODO: to be implemented } void DocbookDocVisitor::visitPre(DocHRef *href) { +DB_VIS_C if (m_hide) return; - m_t << "<link xlink:href=\"" << href->url() << "\">"; + m_t << "<link xlink:href=\"" << convertToDocBook(href->url()) << "\">"; } void DocbookDocVisitor::visitPost(DocHRef *) { +DB_VIS_C if (m_hide) return; m_t << "</link>"; } void DocbookDocVisitor::visitPre(DocHtmlHeader *) { +DB_VIS_C if (m_hide) return; m_t << "<formalpara><title>"; } void DocbookDocVisitor::visitPost(DocHtmlHeader *) { +DB_VIS_C if (m_hide) return; m_t << "</title></formalpara>\n"; } void DocbookDocVisitor::visitPre(DocImage *img) { +DB_VIS_C if (img->type()==DocImage::DocBook) { if (m_hide) return; @@ -910,7 +1173,7 @@ void DocbookDocVisitor::visitPre(DocImage *img) { baseName=baseName.right(baseName.length()-i-1); } - visitPreStart(m_t, img -> hasCaption(), baseName, img -> width(), img -> height()); + visitPreStart(m_t, img->children(), img->hasCaption(), img->relPath() + baseName, img->width(), img->height(), img->isInlineImage()); } else { @@ -921,10 +1184,11 @@ void DocbookDocVisitor::visitPre(DocImage *img) void DocbookDocVisitor::visitPost(DocImage *img) { +DB_VIS_C if (img->type()==DocImage::DocBook) { if (m_hide) return; - visitPostEnd(m_t, img -> hasCaption()); + visitPostEnd(m_t, img -> hasCaption(),img -> isInlineImage()); // copy the image to the output dir QCString baseName=img->name(); int i; @@ -961,96 +1225,118 @@ void DocbookDocVisitor::visitPost(DocImage *img) void DocbookDocVisitor::visitPre(DocDotFile *df) { +DB_VIS_C if (m_hide) return; - startDotFile(df->file(),df->width(),df->height(),df->hasCaption()); + startDotFile(df->file(),df->width(),df->height(),df->hasCaption(),df->children()); } 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; - startMscFile(df->file(),df->width(),df->height(),df->hasCaption()); + startMscFile(df->file(),df->width(),df->height(),df->hasCaption(),df->children()); } void DocbookDocVisitor::visitPost(DocMscFile *df) { +DB_VIS_C if (m_hide) return; endMscFile(df->hasCaption()); } void DocbookDocVisitor::visitPre(DocDiaFile *df) { +DB_VIS_C if (m_hide) return; - startDiaFile(df->file(),df->width(),df->height(),df->hasCaption()); + startDiaFile(df->file(),df->width(),df->height(),df->hasCaption(),df->children()); } void DocbookDocVisitor::visitPost(DocDiaFile *df) { +DB_VIS_C if (m_hide) return; endDiaFile(df->hasCaption()); } void DocbookDocVisitor::visitPre(DocLink *lnk) { +DB_VIS_C if (m_hide) return; startLink(lnk->file(),lnk->anchor()); } void DocbookDocVisitor::visitPost(DocLink *) { +DB_VIS_C if (m_hide) return; endLink(); } void DocbookDocVisitor::visitPre(DocRef *ref) { +DB_VIS_C if (m_hide) return; - if (!ref->file().isEmpty()) startLink(ref->file(),ref->anchor()); + if (ref->isSubPage()) + { + startLink(0,ref->anchor()); + } + else + { + if (!ref->file().isEmpty()) startLink(ref->file(),ref->anchor()); + } + if (!ref->hasLinkText()) filter(ref->targetTitle()); } void DocbookDocVisitor::visitPost(DocRef *ref) { +DB_VIS_C if (m_hide) return; if (!ref->file().isEmpty()) endLink(); } void DocbookDocVisitor::visitPre(DocSecRefItem *ref) { +DB_VIS_C if (m_hide) return; - m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">"; + //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; - m_t << "</tocitem>" << endl; + m_t << "</tocentry>" << endl; } void DocbookDocVisitor::visitPre(DocSecRefList *) { +DB_VIS_C if (m_hide) return; - m_t << "<toclist>" << endl; + m_t << "<toc>" << endl; } void DocbookDocVisitor::visitPost(DocSecRefList *) { +DB_VIS_C if (m_hide) return; - m_t << "</toclist>" << endl; + m_t << "</toc>" << endl; } void DocbookDocVisitor::visitPre(DocParamSect *s) { +DB_VIS_C if (m_hide) return; m_t << endl; m_t << " <formalpara>" << endl; - m_t << " <title/>" << endl; - m_t << " <table frame=\"all\">" << endl; - m_t << " <title>"; + m_t << " <title>" << endl; switch(s->type()) { case DocParamSect::Param: m_t << theTranslator->trParameters(); break; @@ -1060,29 +1346,96 @@ void DocbookDocVisitor::visitPre(DocParamSect *s) default: ASSERT(0); } - m_t << " </title>" << endl; - m_t << " <tgroup cols=\"2\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl; - m_t << " <colspec colwidth=\"1*\"/>" << endl; - m_t << " <colspec colwidth=\"4*\"/>" << endl; + m_t << " </title>" << endl; + m_t << " <para>" << endl; + m_t << " <table frame=\"all\">" << endl; + int ncols = 2; + if (s->type() == DocParamSect::Param) + { + bool hasInOutSpecs = s->hasInOutSpecifier(); + bool hasTypeSpecs = s->hasTypeSpecifier(); + if (hasInOutSpecs && hasTypeSpecs) ncols += 2; + else if (hasInOutSpecs || hasTypeSpecs) ncols += 1; + } + m_t << " <tgroup cols=\"" << ncols << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl; + for (int i = 1; i <= ncols; i++) + { + if (i == ncols) m_t << " <colspec colwidth=\"4*\"/>" << endl; + else m_t << " <colspec colwidth=\"1*\"/>" << endl; + } m_t << " <tbody>" << endl; } void DocbookDocVisitor::visitPost(DocParamSect *) { +DB_VIS_C if (m_hide) return; m_t << " </tbody>" << endl; m_t << " </tgroup>" << endl; m_t << " </table>" << endl; + m_t << " </para>" << endl; m_t << " </formalpara>" << endl; m_t << " "; } void DocbookDocVisitor::visitPre(DocParamList *pl) { +DB_VIS_C if (m_hide) return; + m_t << " <row>" << endl; + + DocParamSect::Type parentType = DocParamSect::Unknown; + DocParamSect *sect = 0; + if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect) + { + parentType = ((DocParamSect*)pl->parent())->type(); + sect=(DocParamSect*)pl->parent(); + } + + if (sect && sect->hasInOutSpecifier()) + { + m_t << " <entry>"; + if (pl->direction()!=DocParamSect::Unspecified) + { + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "in,out"; + } + } + m_t << " </entry>"; + } + + if (sect && sect->hasTypeSpecifier()) + { + QListIterator<DocNode> li(pl->paramTypes()); + DocNode *type; + bool first=TRUE; + m_t << " <entry>"; + for (li.toFirst();(type=li.current());++li) + { + if (!first) m_t << " | "; else first=FALSE; + if (type->kind()==DocNode::Kind_Word) + { + visit((DocWord*)type); + } + else if (type->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)type); + } + } + m_t << " </entry>"; + } + QListIterator<DocNode> li(pl->parameters()); DocNode *param; - m_t << " <row>" << endl; if (!li.toFirst()) { m_t << " <entry></entry>" << endl; @@ -1114,6 +1467,7 @@ void DocbookDocVisitor::visitPre(DocParamList *pl) void DocbookDocVisitor::visitPost(DocParamList *) { +DB_VIS_C if (m_hide) return; m_t << "</entry>" << endl; m_t << " </row>" << endl; @@ -1121,10 +1475,11 @@ void DocbookDocVisitor::visitPost(DocParamList *) void DocbookDocVisitor::visitPre(DocXRefItem *x) { +DB_VIS_C if (m_hide) return; if (x->title().isEmpty()) return; - m_t << "<para><link linkend=\""; - m_t << x->file() << "_1" << x->anchor(); + m_t << "<para><link linkend=\"_"; + m_t << stripPath(x->file()) << "_1" << x->anchor(); m_t << "\">"; filter(x->title()); m_t << "</link>"; @@ -1133,6 +1488,7 @@ void DocbookDocVisitor::visitPre(DocXRefItem *x) void DocbookDocVisitor::visitPost(DocXRefItem *x) { +DB_VIS_C if (m_hide) return; if (x->title().isEmpty()) return; m_t << "</para>"; @@ -1140,12 +1496,14 @@ void DocbookDocVisitor::visitPost(DocXRefItem *x) void DocbookDocVisitor::visitPre(DocInternalRef *ref) { +DB_VIS_C if (m_hide) return; startLink(ref->file(),ref->anchor()); } void DocbookDocVisitor::visitPost(DocInternalRef *) { +DB_VIS_C if (m_hide) return; endLink(); m_t << " "; @@ -1153,6 +1511,7 @@ void DocbookDocVisitor::visitPost(DocInternalRef *) void DocbookDocVisitor::visitPre(DocCopy *) { +DB_VIS_C if (m_hide) return; // TODO: to be implemented } @@ -1160,6 +1519,7 @@ void DocbookDocVisitor::visitPre(DocCopy *) void DocbookDocVisitor::visitPost(DocCopy *) { +DB_VIS_C if (m_hide) return; // TODO: to be implemented } @@ -1167,72 +1527,89 @@ void DocbookDocVisitor::visitPost(DocCopy *) void DocbookDocVisitor::visitPre(DocText *) { +DB_VIS_C // TODO: to be implemented } void DocbookDocVisitor::visitPost(DocText *) { +DB_VIS_C // TODO: to be implemented } void DocbookDocVisitor::visitPre(DocHtmlBlockQuote *) { +DB_VIS_C if (m_hide) return; m_t << "<blockquote>"; } void DocbookDocVisitor::visitPost(DocHtmlBlockQuote *) { +DB_VIS_C if (m_hide) return; m_t << "</blockquote>"; } void DocbookDocVisitor::visitPre(DocVhdlFlow *) { +DB_VIS_C // TODO: to be implemented } void DocbookDocVisitor::visitPost(DocVhdlFlow *) { +DB_VIS_C // TODO: to be implemented } void DocbookDocVisitor::visitPre(DocParBlock *) { +DB_VIS_C } void DocbookDocVisitor::visitPost(DocParBlock *) { +DB_VIS_C } void DocbookDocVisitor::filter(const char *str) { - m_t << convertToXML(str); +DB_VIS_C + m_t << convertToDocBook(str); } void DocbookDocVisitor::startLink(const QCString &file,const QCString &anchor) { - m_t << "<link linkend=\"" << file; - if (!anchor.isEmpty()) m_t << "_1" << anchor; +DB_VIS_C + m_t << "<link linkend=\"_" << stripPath(file); + if (!anchor.isEmpty()) + { + if (file) m_t << "_1"; + m_t << anchor; + } m_t << "\">"; } void DocbookDocVisitor::endLink() { +DB_VIS_C m_t << "</link>"; } void DocbookDocVisitor::pushEnabled() { +DB_VIS_C m_enabled.push(new bool(m_hide)); } void DocbookDocVisitor::popEnabled() { +DB_VIS_C bool *v=m_enabled.pop(); ASSERT(v!=0); m_hide = *v; @@ -1241,6 +1618,7 @@ void DocbookDocVisitor::popEnabled() void DocbookDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s) { +DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) @@ -1249,13 +1627,14 @@ void DocbookDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s) } QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_BITMAP); - visitPreStart(m_t, s->hasCaption(), shortName, s->width(),s->height()); - visitCaption(this, s->children()); + 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) { +DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) @@ -1264,17 +1643,19 @@ void DocbookDocVisitor::writePlantUMLFile(const QCString &baseName, DocVerbatim } QCString outDir = Config_getString(DOCBOOK_OUTPUT); generatePlantUMLOutput(baseName,outDir,PUML_BITMAP); - visitPreStart(m_t, s->hasCaption(), shortName, s->width(),s->height()); - visitCaption(this, s->children()); + 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, const QCString &width, const QCString &height, - bool hasCaption + bool hasCaption, + const QList<DocNode> &children ) { +DB_VIS_C QCString baseName=fileName; int i; if ((i=baseName.findRev('/'))!=-1) @@ -1289,11 +1670,12 @@ void DocbookDocVisitor::startMscFile(const QCString &fileName, QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeMscGraphFromFile(fileName,outDir,baseName,MSC_BITMAP); m_t << "<para>" << endl; - visitPreStart(m_t, hasCaption, baseName + ".png", width, height); + visitPreStart(m_t, children, hasCaption, baseName + ".png", width, height); } void DocbookDocVisitor::endMscFile(bool hasCaption) { +DB_VIS_C if (m_hide) return; visitPostEnd(m_t, hasCaption); m_t << "</para>" << endl; @@ -1301,6 +1683,7 @@ void DocbookDocVisitor::endMscFile(bool hasCaption) void DocbookDocVisitor::writeDiaFile(const QCString &baseName, DocVerbatim *s) { +DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) @@ -1309,17 +1692,19 @@ void DocbookDocVisitor::writeDiaFile(const QCString &baseName, DocVerbatim *s) } QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_BITMAP); - visitPreStart(m_t, s->hasCaption(), shortName, s->width(),s->height()); - visitCaption(this, s->children()); + 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, const QCString &width, const QCString &height, - bool hasCaption + bool hasCaption, + const QList<DocNode> &children ) { +DB_VIS_C QCString baseName=fileName; int i; if ((i=baseName.findRev('/'))!=-1) @@ -1334,11 +1719,12 @@ void DocbookDocVisitor::startDiaFile(const QCString &fileName, QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeDiaGraphFromFile(fileName,outDir,baseName,DIA_BITMAP); m_t << "<para>" << endl; - visitPreStart(m_t, hasCaption, baseName + ".png", width, height); + visitPreStart(m_t, children, hasCaption, baseName + ".png", width, height); } void DocbookDocVisitor::endDiaFile(bool hasCaption) { +DB_VIS_C if (m_hide) return; visitPostEnd(m_t, hasCaption); m_t << "</para>" << endl; @@ -1346,6 +1732,7 @@ void DocbookDocVisitor::endDiaFile(bool hasCaption) void DocbookDocVisitor::writeDotFile(const QCString &baseName, DocVerbatim *s) { +DB_VIS_C QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) @@ -1354,17 +1741,19 @@ void DocbookDocVisitor::writeDotFile(const QCString &baseName, DocVerbatim *s) } QCString outDir = Config_getString(DOCBOOK_OUTPUT); writeDotGraphFromFile(baseName+".dot",outDir,shortName,GOF_BITMAP); - visitPreStart(m_t, s->hasCaption(), baseName + ".dot", s->width(),s->height()); - visitCaption(this, s->children()); + 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, const QCString &width, const QCString &height, - bool hasCaption + bool hasCaption, + const QList<DocNode> &children ) { +DB_VIS_C QCString baseName=fileName; int i; if ((i=baseName.findRev('/'))!=-1) @@ -1380,11 +1769,12 @@ void DocbookDocVisitor::startDotFile(const QCString &fileName, QCString imgExt = getDotImageExtension(); writeDotGraphFromFile(fileName,outDir,baseName,GOF_BITMAP); m_t << "<para>" << endl; - visitPreStart(m_t, hasCaption, baseName + "." + imgExt, width, height); + visitPreStart(m_t, children, hasCaption, baseName + "." + imgExt, width, height); } void DocbookDocVisitor::endDotFile(bool hasCaption) { +DB_VIS_C if (m_hide) return; m_t << endl; visitPostEnd(m_t, hasCaption); diff --git a/src/docbookvisitor.h b/src/docbookvisitor.h index 6c7976c..24b1fbb 100644 --- a/src/docbookvisitor.h +++ b/src/docbookvisitor.h @@ -20,7 +20,9 @@ #include "docvisitor.h" #include <qstack.h> +#include <qlist.h> #include <qcstring.h> +#include <docparser.h> class FTextStream; class CodeOutputInterface; @@ -31,6 +33,7 @@ class DocbookDocVisitor : public DocVisitor { public: DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci); + ~DocbookDocVisitor(); //-------------------------------------- // visitor functions for leaf nodes //-------------------------------------- @@ -38,6 +41,7 @@ class DocbookDocVisitor : public DocVisitor void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); @@ -145,18 +149,27 @@ class DocbookDocVisitor : public DocVisitor void pushEnabled(); void popEnabled(); void startMscFile(const QCString &fileName,const QCString &width, - const QCString &height, bool hasCaption); + const QCString &height, bool hasCaption,const QList<DocNode> &children); void endMscFile(bool hasCaption); void writeMscFile(const QCString &fileName, DocVerbatim *s); void startDiaFile(const QCString &fileName,const QCString &width, - const QCString &height, bool hasCaption); + const QCString &height, bool hasCaption,const QList<DocNode> &children); void endDiaFile(bool hasCaption); void writeDiaFile(const QCString &fileName, DocVerbatim *s); void startDotFile(const QCString &fileName,const QCString &width, - const QCString &height, bool hasCaption); + const QCString &height, bool hasCaption,const QList<DocNode> &children); void endDotFile(bool hasCaption); void writeDotFile(const QCString &fileName, DocVerbatim *s); void writePlantUMLFile(const QCString &fileName, DocVerbatim *s); + void visitPreStart(FTextStream &t, + const QList<DocNode> &children, + bool hasCaption, + const QCString &name, + const QCString &width, + const QCString &height, + bool inlineImage = FALSE); + void visitPostEnd(FTextStream &t, bool hasCaption, bool inlineImage = FALSE); + void visitCaption(const QList<DocNode> &children); //-------------------------------------- // state variables //-------------------------------------- diff --git a/src/docparser.cpp b/src/docparser.cpp index 3d57c2e..a5c0cc7 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -26,6 +26,7 @@ #include <qdict.h> #include <qregexp.h> #include <ctype.h> +#include <qcstringlist.h> #include "doxygen.h" #include "debug.h" @@ -54,6 +55,9 @@ #include "growbuf.h" #include "markdown.h" #include "htmlentity.h" +#include "emoji.h" + +#define TK_COMMAND_CHAR(token) ((token)==TK_COMMAND_AT ? '@' : '\\') // debug off #define DBG(x) do {} while(0) @@ -146,6 +150,9 @@ struct DocParserContext static QStack<DocParserContext> g_parserStack; //--------------------------------------------------------------------------- +static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribList &tagHtmlAttribs); + +//--------------------------------------------------------------------------- static void docParserPushContext(bool saveParamInfo=TRUE) { //QCString indent; @@ -262,7 +269,7 @@ static void unescapeCRef(QCString &s) * copies the image to the output directory (which depends on the \a type * parameter). */ -static QCString findAndCopyImage(const char *fileName,DocImage::Type type) +static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool dowarn = true) { QCString result; bool ambig; @@ -330,7 +337,8 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type) } else { - printf("Source & Destination are the same!\n"); + warn(g_fileName,doctokenizerYYlineno, + "Prevented to copy file %s onto itself!\n",qPrint(inputFile)); } } else @@ -358,7 +366,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type) return baseName; } } - else if (ambig) + else if (ambig && dowarn) { QCString text; text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName)); @@ -369,7 +377,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type) else { result=fileName; - if (result.left(5)!="http:" && result.left(6)!="https:") + if (result.left(5)!="http:" && result.left(6)!="https:" && dowarn) { warn_doc_error(g_fileName,doctokenizerYYlineno, "image file %s is not found in IMAGE_PATH: " @@ -423,7 +431,7 @@ static void checkArgumentName(const QCString &name,bool isParam) } if (!found && isParam) { - //printf("member type=%d\n",memberDef->memberType()); + //printf("member type=%d\n",g_memberDef->memberType()); QCString scope=g_memberDef->getScopeString(); if (!scope.isEmpty()) scope+="::"; else scope=""; QCString inheritedFrom = ""; @@ -451,11 +459,12 @@ static void checkArgumentName(const QCString &name,bool isParam) } /*! Checks if the parameters that have been specified using \@param are - * indeed all parameters. + * indeed all parameters and that a parameter does not have multiple + * \@param blocks. * Must be called after checkArgumentName() has been called for each * argument. */ -static void checkUndocumentedParams() +static void checkUnOrMultipleDocumentedParams() { if (g_memberDef && g_hasParamCommand && Config_getBool(WARN_IF_DOC_ERROR)) { @@ -470,18 +479,37 @@ static void checkUndocumentedParams() bool found=FALSE; for (ali.toFirst();(a=ali.current());++ali) { + int count = 0; QCString argName = g_memberDef->isDefine() ? a->type : a->name; if (lang==SrcLangExt_Fortran) argName = argName.lower(); argName=argName.stripWhiteSpace(); + QCString aName = argName; if (argName.right(3)=="...") argName=argName.left(argName.length()-3); - if (g_memberDef->getLanguage()==SrcLangExt_Python && (argName=="self" || argName=="cls")) + if (lang==SrcLangExt_Python && (argName=="self" || argName=="cls")) { // allow undocumented self / cls parameter for Python } else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a->docs.isEmpty()) { found = TRUE; - break; + } + else + { + QDictIterator<void> it1(g_paramsFound); + void *item1; + for (;(item1=it1.current());++it1) + { + if (argName == it1.currentKey()) count++; + } + } + if (count > 1) + { + warn_doc_error(g_memberDef->getDefFileName(), + g_memberDef->getDefLine(), + "argument '" + aName + + "' from the argument list of " + + QCString(g_memberDef->qualifiedName()) + + " has muliple @param documentation sections"); } } if (found) @@ -497,7 +525,7 @@ static void checkUndocumentedParams() QCString argName = g_memberDef->isDefine() ? a->type : a->name; if (lang==SrcLangExt_Fortran) argName = argName.lower(); argName=argName.stripWhiteSpace(); - if (g_memberDef->getLanguage()==SrcLangExt_Python && (argName=="self" || argName=="cls")) + if (lang==SrcLangExt_Python && (argName=="self" || argName=="cls")) { // allow undocumented self / cls parameter for Python } @@ -842,7 +870,31 @@ static bool findDocsForMemberOrCompound(const char *commandName, return FALSE; } //--------------------------------------------------------------------------- +inline void errorHandleDefaultToken(DocNode *parent,int tok, + QList<DocNode> &children,const char *txt) +{ + switch (tok) + { + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + children.append(new DocWord(parent,TK_COMMAND_CHAR(tok) + g_token->name)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a %s", + qPrint(TK_COMMAND_CHAR(tok) + g_token->name), txt); + break; + case TK_SYMBOL: + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found found as part of a %s", + qPrint(g_token->name), txt); + break; + default: + children.append(new DocWord(parent,g_token->name)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a %s", + tokToString(tok), txt); + break; + } +} +//--------------------------------------------------------------------------- // forward declaration static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool @@ -852,6 +904,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, const QCString &cmdName) { DBG(("handleStyleArgument(%s)\n",qPrint(cmdName))); + QCString saveCmdName = cmdName; int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { @@ -877,14 +930,6 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s as the argument of a \\%s command", - qPrint(g_token->name),qPrint(cmdName)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found while handling command %s", - qPrint(g_token->name),qPrint(cmdName)); - break; case TK_HTMLTAG: if (insideLI(parent) && Mappers::htmlTagMapper->map(g_token->name) && g_token->endTag) { // ignore </li> as the end of a style command @@ -893,8 +938,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, return tok; break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s while handling command %s", - tokToString(tok),qPrint(cmdName)); + errorHandleDefaultToken(parent,tok,children,"\\" + saveCmdName + " command"); break; } break; @@ -1027,16 +1071,18 @@ 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::Subscript: return "subscript"; - case DocStyleChange::Superscript: return "superscript"; - case DocStyleChange::Preformatted: return "pre"; + 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::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::Underline: return "u"; } return "<invalid>"; } @@ -1271,21 +1317,7 @@ static void defaultHandleTitleAndSize(const int cmd, DocNode *parent, QList<DocN } if (!defaultHandleToken(parent,tok,children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\%s", - qPrint(g_token->name), Mappers::cmdMapper->find(cmd).data()); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(parent,tok,children,Mappers::cmdMapper->find(cmd).data()); } } // parse size attributes @@ -1343,8 +1375,8 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children handleWord) { DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); - if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || - tok==TK_COMMAND || tok==TK_HTMLTAG + 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(g_token->name))); @@ -1354,7 +1386,9 @@ reparsetoken: QCString tokenName = g_token->name; switch (tok) { - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: switch (Mappers::cmdMapper->map(tokenName)) { case CMD_BSLASH: @@ -1405,6 +1439,9 @@ reparsetoken: case CMD_MINUS: children.append(new DocSymbol(parent,DocSymbol::Sym_Minus)); break; + case CMD_EQUAL: + children.append(new DocSymbol(parent,DocSymbol::Sym_Equal)); + break; case CMD_EMPHASIS: { children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,TRUE)); @@ -1538,6 +1575,9 @@ reparsetoken: doctokenizerYYsetStatePara(); } break; + case CMD_IMAGE: + ((DocPara *)parent) -> handleImage("image"); + break; default: return FALSE; } @@ -1562,6 +1602,26 @@ reparsetoken: handleStyleLeave(parent,children,DocStyleChange::Bold,tokenName); } break; + case HTML_STRIKE: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Strike,&g_token->attribs); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Strike,tokenName); + } + break; + case HTML_UNDERLINE: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Underline,&g_token->attribs); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Underline,tokenName); + } + break; case HTML_CODE: case XML_C: if (!g_token->endTag) @@ -1623,6 +1683,10 @@ reparsetoken: handleStyleLeave(parent,children,DocStyleChange::Small,tokenName); } break; + case HTML_IMG: + if (!g_token->endTag) + handleImg(parent,children,g_token->attribs); + break; default: return FALSE; break; @@ -1700,7 +1764,8 @@ static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribL // and remove the src attribute bool result = attrList.remove(index); ASSERT(result); - DocImage *img = new DocImage(parent,attrList,opt->value,DocImage::Html,opt->value); + DocImage::Type t = DocImage::Html; + DocImage *img = new DocImage(parent,attrList,findAndCopyImage(opt->value,t,false),t,opt->value); children.append(img); found = TRUE; } @@ -1721,6 +1786,27 @@ DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName) //--------------------------------------------------------------------------- +DocEmoji::DocEmoji(DocNode *parent,const QCString &symName) : + m_symName(symName), m_index(-1) +{ + m_parent = parent; + QCString locSymName = symName; + int 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); + if (m_index==-1) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unsupported emoji symbol '%s'\n",qPrint(m_symName)); + } +} + +//--------------------------------------------------------------------------- + static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children, const QCString &doc) { @@ -1850,11 +1936,8 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label"); } - if (newAnchor) // found <a name="label"> - { - m_anchor = id; - } - else if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) + + if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) { CiteInfo *cite = Doxygen::citeDict->find(id.mid(CiteConsts::anchorPrefix.length())); if (cite) @@ -1869,6 +1952,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) m_file = "invalid"; } } + else if (newAnchor) // found <a name="label"> + { + m_anchor = id; + } else // found \anchor label { SectionInfo *sec = Doxygen::sectionDict->find(id); @@ -2280,21 +2367,7 @@ void DocSecRefItem::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\refitem", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"\\refitem"); } } doctokenizerYYsetStatePara(); @@ -2342,7 +2415,7 @@ void DocSecRefList::parse() // handle items while (tok) { - if (tok==TK_COMMAND) + if (tok==TK_COMMAND_AT || tok == TK_COMMAND_BS) { switch (Mappers::cmdMapper->map(g_token->name)) { @@ -2422,21 +2495,7 @@ void DocInternalRef::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"\\ref"); } } @@ -2580,19 +2639,10 @@ void DocRef::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; case TK_HTMLTAG: break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); + errorHandleDefaultToken(this,tok,m_children,"\\ref"); break; } } @@ -2703,7 +2753,9 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) { switch (tok) { - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: switch (Mappers::cmdMapper->map(g_token->name)) { case CMD_ENDLINK: @@ -2719,13 +2771,13 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) } break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found as part of a \\link", qPrint(g_token->name)); break; case TK_HTMLTAG: if (g_token->name!="see" || !isXmlLink) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found as part of a \\link", qPrint(g_token->name)); } goto endlink; @@ -2903,21 +2955,7 @@ void DocVhdlFlow::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\vhdlflow", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"\\vhdlflow"); } } tok=doctokenizerYYlex(); @@ -2935,10 +2973,10 @@ void DocVhdlFlow::parse() //--------------------------------------------------------------------------- DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString &name, - Type t,const QCString &url) : - m_attribs(attribs), m_name(name), + Type t,const QCString &url, bool inlineImage) : + m_attribs(attribs), m_name(name), m_type(t), m_relPath(g_relPath), - m_url(url) + m_url(url), m_inlineImage(inlineImage) { m_parent = parent; } @@ -2964,10 +3002,6 @@ int DocHtmlHeader::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <h%d> tag", - qPrint(g_token->name),m_level); - break; case TK_HTMLTAG: { int tagId=Mappers::htmlTagMapper->map(g_token->name); @@ -3042,17 +3076,12 @@ int DocHtmlHeader::parse() warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <h%d> context", g_token->endTag?"/":"",qPrint(g_token->name),m_level); } - } break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; + char tmp[20]; + sprintf(tmp,"<h%d>tag",m_level); + errorHandleDefaultToken(this,tok,m_children,tmp); } } } @@ -3084,16 +3113,7 @@ int DocHRef::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <a>..</a> block", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; case TK_HTMLTAG: - { int tagId=Mappers::htmlTagMapper->map(g_token->name); if (tagId==HTML_A && g_token->endTag) // found </a> tag @@ -3108,8 +3128,7 @@ int DocHRef::parse() } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok),doctokenizerYYlineno); + errorHandleDefaultToken(this,tok,m_children,"<a>..</a> block"); break; } } @@ -3242,29 +3261,32 @@ int DocIndexEntry::parse() } } break; - case TK_COMMAND: - switch (Mappers::cmdMapper->map(g_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; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command %s found as argument of \\addindex", - qPrint(g_token->name)); - break; - } + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + switch (Mappers::cmdMapper->map(g_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(g_fileName,doctokenizerYYlineno,"Unexpected command %s found as argument of \\addindex", + qPrint(g_token->name)); + break; + } break; default: warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", @@ -3330,14 +3352,6 @@ int DocHtmlCaption::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <caption> tag", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; case TK_HTMLTAG: { int tagId=Mappers::htmlTagMapper->map(g_token->name); @@ -3354,8 +3368,7 @@ int DocHtmlCaption::parse() } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); + errorHandleDefaultToken(this,tok,m_children,"<caption> tag"); break; } } @@ -3485,14 +3498,34 @@ DocHtmlCell::Alignment DocHtmlCell::alignment() const { HtmlAttribList attrs = attribs(); uint i; - for (i=0; i<attrs.count(); ++i) + for (i=0; i<attrs.count(); ++i) { if (attrs.at(i)->name.lower()=="align") { - if (attrs.at(i)->value.lower()=="center") + if (attrs.at(i)->value.lower()=="center") + return Center; + else if (attrs.at(i)->value.lower()=="right") + return Right; + else return Left; + } + else if (attrs.at(i)->name.lower()=="class") + { + if (attrs.at(i)->value.lower()=="markdowntableheadcenter") return Center; - else if (attrs.at(i)->value.lower()=="right") + else if (attrs.at(i)->value.lower()=="markdowntableheadright") return Right; + else if (attrs.at(i)->value.lower()=="markdowntableheadleft") + return Left; + else if (attrs.at(i)->value.lower()=="markdowntableheadnone") + return Center; + else if (attrs.at(i)->value.lower()=="markdowntablebodycenter") + return Center; + else if (attrs.at(i)->value.lower()=="markdowntablebodyright") + return Right; + else if (attrs.at(i)->value.lower()=="markdowntablebodyleft") + return Left; + else if (attrs.at(i)->value.lower()=="markdowntablebodynone") + return Left; else return Left; } } @@ -3849,7 +3882,9 @@ int DocHtmlDescTitle::parse() { switch (tok) { - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: { QCString cmdName=g_token->name; bool isJavaLink=FALSE; @@ -3860,7 +3895,7 @@ int DocHtmlDescTitle::parse() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(g_token->name)); } else @@ -3869,7 +3904,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); // get the reference id if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command", tokToString(tok),qPrint(cmdName)); } else @@ -3890,7 +3925,7 @@ int DocHtmlDescTitle::parse() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(cmdName)); } else @@ -3899,7 +3934,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command", tokToString(tok),qPrint(cmdName)); } else @@ -3918,13 +3953,13 @@ int DocHtmlDescTitle::parse() break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <dt> tag", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s found as part of a <dt> tag", qPrint(g_token->name)); } } break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol \\%s found as part of a <dt> tag", qPrint(g_token->name)); break; case TK_HTMLTAG: @@ -3965,7 +4000,7 @@ int DocHtmlDescTitle::parse() } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a <dt> tag", tokToString(tok)); break; } @@ -4470,21 +4505,7 @@ void DocTitle::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a title section", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"title section"); } } doctokenizerYYsetStatePara(); @@ -4940,6 +4961,35 @@ void DocPara::handleCite() doctokenizerYYsetStatePara(); } +void DocPara::handleEmoji() +{ + // get the argument of the emoji command. + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + qPrint("emoji")); + return; + } + doctokenizerYYsetStateEmoji(); + tok=doctokenizerYYlex(); + if (tok==0) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + "argument of command %s\n", qPrint("emoji")); + return; + } + else if (tok!=TK_WORD) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + tokToString(tok),qPrint("emoji")); + return; + } + DocEmoji *emoji = new DocEmoji(this,g_token->name); + m_children.append(emoji); + doctokenizerYYsetStatePara(); +} + int DocPara::handleXRefItem() { int retval=doctokenizerYYlex(); @@ -5017,25 +5067,64 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type void DocPara::handleImage(const QCString &cmdName) { + QCString saveCmdName = cmdName; + bool inlineImage = FALSE; + int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); - return; + if (tok==TK_WORD) + { + if (g_token->name == "{") + { + while ((tok=doctokenizerYYlex())==TK_WHITESPACE); + if (g_token->name != "}") // non-empty option string + { + if (g_token->name.lower() != "inline") + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"currently only 'inline' suported as option of %s command", + qPrint(saveCmdName)); + } + else + { + inlineImage = TRUE; + } + while ((tok=doctokenizerYYlex())==TK_WHITESPACE); + } + if (!((tok==TK_WORD) && (g_token->name == "}"))) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected closing '}' at option of %s command", + qPrint(saveCmdName)); + return; + } + tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command with option", + qPrint(saveCmdName)); + return; + } + } + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + qPrint(saveCmdName)); + return; + } } tok=doctokenizerYYlex(); if (tok!=TK_WORD && tok!=TK_LNKWORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + qPrint(saveCmdName)); return; } DocImage::Type t; @@ -5046,9 +5135,9 @@ void DocPara::handleImage(const QCString &cmdName) else if (imgType=="rtf") t=DocImage::Rtf; else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"image type %s specified as the first argument of " - "%s is not valid", - qPrint(imgType),qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"output format %s specified as the first argument of " + "%s command is not valid", + qPrint(imgType),qPrint(saveCmdName)); return; } doctokenizerYYsetStateFile(); @@ -5057,11 +5146,11 @@ void DocPara::handleImage(const QCString &cmdName) if (tok!=TK_WORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } HtmlAttribList attrList; - DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t); + DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t,"",inlineImage); m_children.append(img); img->parse(); } @@ -5155,7 +5244,40 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) { DBG(("handleInclude(%s)\n",qPrint(cmdName))); int tok=doctokenizerYYlex(); - if (tok!=TK_WHITESPACE) + bool isBlock = false; + if (tok==TK_WORD && g_token->name=="{") + { + doctokenizerYYsetStateOptions(); + tok=doctokenizerYYlex(); + doctokenizerYYsetStatePara(); + QCStringList optList=QCStringList::split(",",g_token->name); + if (t==DocInclude::Include && optList.contains("lineno")) + { + t = DocInclude::IncWithLines; + } + else if (t==DocInclude::Snippet && optList.contains("lineno")) + { + t = DocInclude::SnipWithLines; + } + else if (t==DocInclude::Include && optList.contains("doc")) + { + t = DocInclude::IncludeDoc; + } + else if (t==DocInclude::Snippet && optList.contains("doc")) + { + t = DocInclude::SnippetDoc; + } + tok=doctokenizerYYlex(); + } + else if (tok==TK_WORD && g_token->name=="[") + { + doctokenizerYYsetStateBlock(); + tok=doctokenizerYYlex(); + isBlock = (g_token->name.stripWhiteSpace() == "block"); + doctokenizerYYsetStatePara(); + tok=doctokenizerYYlex(); + } + else if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", qPrint(cmdName)); @@ -5213,7 +5335,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) } else { - DocInclude *inc = new DocInclude(this,fileName,g_context,t,g_isExample,g_exampleName,blockId); + DocInclude *inc = new DocInclude(this,fileName,g_context,t,g_isExample,g_exampleName,blockId,isBlock); m_children.append(inc); inc->parse(); } @@ -5319,7 +5441,7 @@ void DocPara::handleInheritDoc() } -int DocPara::handleCommand(const QCString &cmdName) +int DocPara::handleCommand(const QCString &cmdName, const int tok) { DBG(("handleCommand(%s)\n",qPrint(cmdName))); int retval = RetVal_OK; @@ -5327,6 +5449,7 @@ int DocPara::handleCommand(const QCString &cmdName) switch (cmdId) { case CMD_UNKNOWN: + m_children.append(new DocWord(this,TK_COMMAND_CHAR(tok) + cmdName)); warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command `\\%s'",qPrint(cmdName)); break; case CMD_EMPHASIS: @@ -5398,6 +5521,9 @@ int DocPara::handleCommand(const QCString &cmdName) case CMD_MINUS: m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus)); break; + case CMD_EQUAL: + m_children.append(new DocSymbol(this,DocSymbol::Sym_Equal)); + break; case CMD_SA: g_inSeeBlock=TRUE; retval = handleSimpleSection(DocSimpleSect::See); @@ -5593,7 +5719,8 @@ int DocPara::handleCommand(const QCString &cmdName) defaultHandleTitleAndSize(CMD_STARTUML,dv,dv->children(),width,height); doctokenizerYYsetStatePlantUML(); retval = doctokenizerYYlex(); - dv->setText(g_token->verb); + int line=0; + dv->setText(stripLeadingAndTrailingEmptyLines(g_token->verb,line)); dv->setWidth(width); dv->setHeight(height); if (jarPath.isEmpty()) @@ -5750,6 +5877,9 @@ int DocPara::handleCommand(const QCString &cmdName) case CMD_CITE: handleCite(); break; + case CMD_EMOJI: + handleEmoji(); + break; case CMD_REF: // fall through case CMD_SUBPAGE: handleRef(cmdName); @@ -5863,6 +5993,12 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta case HTML_BOLD: handleStyleEnter(this,m_children,DocStyleChange::Bold,&g_token->attribs); break; + case HTML_STRIKE: + handleStyleEnter(this,m_children,DocStyleChange::Strike,&g_token->attribs); + break; + case HTML_UNDERLINE: + handleStyleEnter(this,m_children,DocStyleChange::Underline,&g_token->attribs); + break; case HTML_CODE: if (/*getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp ||*/ g_xmlComment) // for C# source or inside a <summary> or <remark> section we @@ -6125,16 +6261,15 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } } } - else if (findAttribute(tagHtmlAttribs,"langword",&cref)) // <see langword="..."/> or <see langworld="..."></see> + else if (findAttribute(tagHtmlAttribs,"langword",&cref)) // <see langword="..."/> or <see langword="..."></see> { - doctokenizerYYsetStatePara(); - DocLink *lnk = new DocLink(this,cref); - m_children.append(lnk); - QCString leftOver = lnk->parse(FALSE,TRUE); - if (!leftOver.isEmpty()) - { - m_children.append(new DocWord(this,leftOver)); - } + bool inSeeBlock = g_inSeeBlock; + g_token->name = cref; + g_inSeeBlock = TRUE; + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,TRUE)); + handleLinkedWord(this,m_children,TRUE); + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,FALSE)); + g_inSeeBlock = inSeeBlock; } else { @@ -6273,6 +6408,12 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case HTML_BOLD: handleStyleLeave(this,m_children,DocStyleChange::Bold,"b"); break; + case HTML_STRIKE: + handleStyleLeave(this,m_children,DocStyleChange::Strike,"strike"); + break; + case HTML_UNDERLINE: + handleStyleLeave(this,m_children,DocStyleChange::Underline,"u"); + break; case HTML_CODE: handleStyleLeave(this,m_children,DocStyleChange::Code,"code"); break; @@ -6416,8 +6557,8 @@ int DocPara::parse() { reparsetoken: DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); - if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || - tok==TK_COMMAND || tok==TK_HTMLTAG + 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(g_token->name))); @@ -6515,7 +6656,7 @@ reparsetoken: } else // other section { - tok = TK_COMMAND; + tok = TK_COMMAND_BS; } DBG(("reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -6560,7 +6701,9 @@ reparsetoken: "list items"); } break; - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: { // see if we have to start a simple section int cmd = Mappers::cmdMapper->map(g_token->name); @@ -6596,7 +6739,7 @@ reparsetoken: } // handle the command - retval=handleCommand(g_token->name); + retval=handleCommand(g_token->name,tok); DBG(("handleCommand returns %x\n",retval)); // check the return value @@ -6614,7 +6757,7 @@ reparsetoken: } else // other section { - tok = TK_COMMAND; + tok = TK_COMMAND_BS; } DBG(("reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -6886,7 +7029,9 @@ void DocText::parse() } } break; - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: switch (Mappers::cmdMapper->map(g_token->name)) { case CMD_BSLASH: @@ -6937,6 +7082,9 @@ void DocText::parse() case CMD_MINUS: m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus)); break; + case CMD_EQUAL: + m_children.append(new DocSymbol(this,DocSymbol::Sym_Equal)); + break; default: warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command `%s' found", qPrint(g_token->name)); @@ -7305,7 +7453,7 @@ QString::Direction getTextDirByConfig(const DocPara *para, int nodeIndex) return QString::DirNeutral; } -QCString getDirHtmlClassOfNode(QString::Direction textDir, const char *initValue) +QCString getDirHtmlClassOfNode(QString::Direction textDir, const QCString &initValue) { QCString classFromDir; if (textDir == QString::DirLTR) @@ -7315,9 +7463,9 @@ QCString getDirHtmlClassOfNode(QString::Direction textDir, const char *initValue else classFromDir = ""; - if (initValue != NULL && !classFromDir.isEmpty()) + if (initValue && !classFromDir.isEmpty()) return QCString(" class=\"") + initValue + " " + classFromDir + "\""; - if (initValue != NULL) + if (initValue) return QCString(" class=\"") + initValue + "\""; if (!classFromDir.isEmpty()) return QCString(" class=\"") + classFromDir + "\""; @@ -7541,7 +7689,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, delete v; } - checkUndocumentedParams(); + checkUnOrMultipleDocumentedParams(); detectNoDocumentedParams(); // TODO: These should be called at the end of the program. diff --git a/src/docparser.h b/src/docparser.h index 8fcbed6..ca32b20 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -37,7 +37,7 @@ class SectionDict; QString::Direction getTextDirByConfig(const QString &text); QString::Direction getTextDirByConfig(const DocNode *node); QString::Direction getTextDirByConfig(const DocPara *para, int nodeIndex); -QCString getDirHtmlClassOfNode(QString::Direction textDir, const char *initValue = NULL); +QCString getDirHtmlClassOfNode(QString::Direction textDir, const QCString &initValue=""); QCString getDirHtmlClassOfPage(QCString pageTitle); QCString getHtmlDirEmbedingChar(QString::Direction textDir); QCString getJsDirEmbedingChar(QString::Direction textDir); @@ -140,7 +140,8 @@ class DocNode Kind_HtmlBlockQuote = 49, Kind_VhdlFlow = 50, Kind_ParBlock = 51, - Kind_DiaFile = 52 + Kind_DiaFile = 52, + Kind_Emoji = 53 }; /*! Creates a new node */ DocNode() : m_parent(0), m_insidePre(FALSE) {} @@ -277,7 +278,7 @@ class DocLinkedWord : public DocNode QCString m_tooltip; }; -/** Node representing an URL (or email address) */ +/** Node representing a URL (or email address) */ class DocURL : public DocNode { public: @@ -306,7 +307,7 @@ class DocLineBreak : public DocNode private: }; -/** Node representing a horizonal ruler */ +/** Node representing a horizontal ruler */ class DocHorRuler : public DocNode { public: @@ -367,7 +368,9 @@ class DocStyleChange : public DocNode Superscript = (1<<6), Preformatted = (1<<7), Span = (1<<8), - Div = (1<<9) + Div = (1<<9), + Strike = (1<<10), + Underline = (1<<11) }; DocStyleChange(DocNode *parent,uint position,Style s,bool enable, @@ -452,7 +455,7 @@ class DocSymbol : public DocNode /* 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_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, @@ -473,6 +476,21 @@ class DocSymbol : public DocNode SymType m_symbol; }; +/** Node representing a n emoji */ +class DocEmoji : public DocNode +{ + public: + DocEmoji(DocNode *parent,const QCString &symName); + QCString name() const { return m_symName; } + int index() const { return m_index; } + Kind kind() const { return Kind_Emoji; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + QCString m_symName; + int m_index; +}; + /** Node representing some amount of white space */ class DocWhiteSpace : public DocNode { @@ -480,7 +498,7 @@ class DocWhiteSpace : public DocNode DocWhiteSpace(DocNode *parent,const QCString &chars) : m_chars(chars) { m_parent = parent; } Kind kind() const { return Kind_WhiteSpace; } - QCString chars() const { return m_chars; } + QCString chars() const { return m_chars; } void accept(DocVisitor *v) { v->visit(this); } private: QCString m_chars; @@ -537,10 +555,10 @@ class DocInclude : public DocNode DocInclude(DocNode *parent,const QCString &file, const QCString context, Type t, bool isExample,const QCString exampleFile, - const QCString blockId) : + const QCString blockId, bool isBlock) : m_file(file), m_context(context), m_type(t), m_isExample(isExample), m_exampleFile(exampleFile), - m_blockId(blockId) { m_parent = parent; } + m_blockId(blockId), m_isBlock(isBlock) { m_parent = parent; } Kind kind() const { return Kind_Include; } QCString file() const { return m_file; } QCString extension() const { int i=m_file.findRev('.'); @@ -555,6 +573,7 @@ class DocInclude : public DocNode 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) { v->visit(this); } void parse(); @@ -564,6 +583,7 @@ class DocInclude : public DocNode QCString m_text; Type m_type; bool m_isExample; + bool m_isBlock; QCString m_exampleFile; QCString m_blockId; }; @@ -705,6 +725,7 @@ class DocTitle : public CompAccept<DocTitle> void parse(); void parseFromString(const QCString &title); Kind kind() const { return Kind_Title; } + bool hasTitle() const { return !m_children.isEmpty(); } private: }; @@ -737,7 +758,7 @@ class DocImage : public CompAccept<DocImage> public: enum Type { Html, Latex, Rtf, DocBook }; DocImage(DocNode *parent,const HtmlAttribList &attribs, - const QCString &name,Type t,const QCString &url=QCString()); + const QCString &name,Type t,const QCString &url=QCString(), bool inlineImage = TRUE); Kind kind() const { return Kind_Image; } Type type() const { return m_type; } QCString name() const { return m_name; } @@ -746,6 +767,7 @@ class DocImage : public CompAccept<DocImage> QCString height() const { return m_height; } QCString relPath() const { return m_relPath; } QCString url() const { return m_url; } + bool isInlineImage() const { return m_inlineImage; } const HtmlAttribList &attribs() const { return m_attribs; } void parse(); @@ -757,6 +779,7 @@ class DocImage : public CompAccept<DocImage> QCString m_height; QCString m_relPath; QCString m_url; + bool m_inlineImage; }; /** Node representing a dot file */ @@ -1090,6 +1113,7 @@ class DocSimpleSect : public CompAccept<DocSimpleSect> int parseRcs(); int parseXml(); void appendLinkWord(const QCString &word); + bool hasTitle() const { return m_title->hasTitle(); } private: Type m_type; @@ -1151,7 +1175,7 @@ class DocPara : public CompAccept<DocPara> bool isFirst() const { return m_isFirst; } bool isLast() const { return m_isLast; } - int handleCommand(const QCString &cmdName); + 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); @@ -1165,6 +1189,7 @@ class DocPara : public CompAccept<DocPara> 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(); @@ -1368,7 +1393,7 @@ class DocHtmlTable : public CompAccept<DocHtmlTable> { public: DocHtmlTable(DocNode *parent,const HtmlAttribList &attribs) - : m_attribs(attribs) { m_caption=0; m_parent = parent; } + : m_attribs(attribs) { m_caption=0; m_numCols=0; m_parent = parent; } ~DocHtmlTable() { delete m_caption; } Kind kind() const { return Kind_HtmlTable; } uint numRows() const { return m_children.count(); } diff --git a/src/docsets.cpp b/src/docsets.cpp index 29b7616..1327d80 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -334,6 +334,7 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md, case SrcLangExt_SQL: lang="sql"; break; // Sql case SrcLangExt_Tcl: lang="tcl"; break; // Tcl case SrcLangExt_Markdown:lang="markdown"; break; // Markdown + case SrcLangExt_Slice: lang="slice"; break; // Slice case SrcLangExt_Unknown: lang="unknown"; break; // should not happen! } @@ -401,6 +402,10 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md, type="ifc"; break; case MemberType_Service: type="svc"; break; + case MemberType_Sequence: + type="sequence"; break; + case MemberType_Dictionary: + type="dictionary"; break; } cd = md->getClassDef(); nd = md->getNamespaceDef(); diff --git a/src/doctokenizer.h b/src/doctokenizer.h index eb39906..8b8ca97 100644 --- a/src/doctokenizer.h +++ b/src/doctokenizer.h @@ -34,12 +34,13 @@ enum Tokens TK_WHITESPACE = 3, TK_LISTITEM = 4, TK_ENDLIST = 5, - TK_COMMAND = 6, + TK_COMMAND_AT = 6, //! Command starting with `@` TK_HTMLTAG = 7, TK_SYMBOL = 8, TK_NEWPARA = 9, TK_RCSTAG = 10, TK_URL = 11, + TK_COMMAND_BS = 12, //! Command starting with `\` RetVal_OK = 0x10000, RetVal_SimpleSec = 0x10001, @@ -163,5 +164,8 @@ void doctokenizerYYendAutoList(); void doctokenizerYYsetStatePlantUML(); void doctokenizerYYsetStateSetScope(); void doctokenizerYYsetStatePlantUMLOpt(); +void doctokenizerYYsetStateOptions(); +void doctokenizerYYsetStateBlock(); +void doctokenizerYYsetStateEmoji(); #endif diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 90a8c55..eb14470 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -38,9 +38,12 @@ #include "definition.h" #include "doxygen.h" #include "portable.h" +#include "cite.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 + +#define TK_COMMAND_SEL() (yytext[0] == '@' ? TK_COMMAND_AT : TK_COMMAND_BS) //-------------------------------------------------------------------------- @@ -116,12 +119,13 @@ const char *tokToString(int token) case TK_WHITESPACE: return "TK_WHITESPACE"; case TK_LISTITEM: return "TK_LISTITEM"; case TK_ENDLIST: return "TK_ENDLIST"; - case TK_COMMAND: return "TK_COMMAND"; + case TK_COMMAND_AT: return "TK_COMMAND_AT"; case TK_HTMLTAG: return "TK_HTMLTAG"; case TK_SYMBOL: return "TK_SYMBOL"; case TK_NEWPARA: return "TK_NEWPARA"; case TK_RCSTAG: return "TK_RCSTAG"; case TK_URL: return "TK_URL"; + case TK_COMMAND_BS: return "TK_COMMAND_BS"; } return "ERROR"; } @@ -257,6 +261,12 @@ static void handleHtmlTag() if (i<(int)yyleng) c=tagText.at(++i); } opt.value = tagText.mid(startAttrib,endAttrib-startAttrib); + if (opt.name == "align") opt.value = opt.value.lower(); + else if (opt.name == "valign") + { + opt.value = opt.value.lower(); + if (opt.value == "center") opt.value="middle"; + } } else // start next option { @@ -335,9 +345,9 @@ BLANK [ \t\r] 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\-]* PHPTYPE [\\:a-z_A-Z0-9\x80-\xFF\-]+ -CITESCHAR [a-z_A-Z0-9\x80-\xFF] -CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/]* -CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)* +CITESCHAR [a-z_A-Z0-9\x80-\xFF\-\?] +CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/\?] +CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*|"\""{CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*"\"" MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+ OPTSTARS ("//"{BLANK}*)?"*"*{BLANK}* LISTITEM {BLANK}*[-]("#")?{WS} @@ -350,14 +360,15 @@ URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=] URLMASK ({URLCHAR}+([({]{URLCHAR}*[)}])?)+ FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+@&#] FILEECHAR [a-z_A-Z0-9\-\+@&#] -HFILEMASK ("."{FILESCHAR}*{FILEECHAR}+)* +HFILEMASK ("."{FILESCHAR}*{FILEECHAR}+)+ FILEMASK ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|{HFILEMASK} LINKMASK [^ \t\n\r\\@<&${}]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"){BLANK}+)? VERBATIM "verbatim"{BLANK}* SPCMD1 {CMD}([a-z_A-Z][a-z_A-Z0-9]*|{VERBATIM}|"--"|"---") -SPCMD2 {CMD}[\\@<>&$#%~".+|-] +SPCMD2 {CMD}[\\@<>&$#%~".+=|-] SPCMD3 {CMD}form#[0-9]+ SPCMD4 {CMD}"::" +SPCMD5 {CMD}":" INOUT "inout"|"in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in") PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]" VARARGS "..." @@ -387,14 +398,15 @@ LNKWORD2 (({SCOPEPRE}*"operator"{OPMASK})|({SCOPEPRE}"operator"{OPMASKOPT})|((" LNKWORD3 ([0-9a-z_A-Z\-]+("/"|"\\"))*[0-9a-z_A-Z\-]+("."[0-9a-z_A-Z]+)+ CHARWORDQ [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,."='] ESCWORD ("%"{ID}(("::"|"."){ID})*)|("%'") -WORD1 {ESCWORD}|{CHARWORDQ}+|"{"|"}"|"'\"'"|("\""[^"\n]*\n?[^"\n]*"\"") -WORD2 "."|","|"("|")"|"["|"]"|":"|";"|"\?"|"="|"'" +CHARWORDQ1 [^ \-+0-9\t\n\r\\@<>()\[\]:;\?{}&%$#,."='] +WORD1 {ESCWORD}|{CHARWORDQ1}{CHARWORDQ}*|"{"|"}"|"'\"'"|("\""[^"\n]*\n?[^"\n]*"\"") +WORD2 "."|","|"("|")"|"["|"]"|"::"|":"|";"|"\?"|"="|"'" WORD1NQ {ESCWORD}|{CHARWORDQ}+|"{"|"}" -WORD2NQ "."|","|"("|")"|"["|"]"|":"|";"|"\?"|"="|"'" +WORD2NQ "."|","|"("|")"|"["|"]"|"::"|":"|";"|"\?"|"="|"'" CAPTION [cC][aA][pP][tT][iI][oO][nN] HTMLTAG "<"(("/")?){ID}({WS}+{ATTRIB})*{WS}*(("/")?)">" -HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p" -HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P" +HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p"|"strike"|"u" +HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P"|"STRIKE"|"U" HTMLKEYW {HTMLKEYL}|{HTMLKEYU} REFWORD2_PRE ("#"|"::")?((({ID}{TEMPLPART}?)|{ANONNS})("."|"#"|"::"|"-"|"/"))*({ID}{TEMPLPART}?(":")?) REFWORD2 {REFWORD2_PRE}{FUNCARG2}? @@ -402,8 +414,8 @@ REFWORD2_NOCV {REFWORD2_PRE}("("{FUNCPART}")")? REFWORD3 ({ID}":")*{ID}":"? REFWORD4_NOCV (({SCOPEPRE}*"operator"{OPMASKOP2})|(("::"|"#"){SCOPEPRE}*"operator"{OPMASKOP2})) REFWORD4 {REFWORD4_NOCV}{CVSPEC}? -REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4} -REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} +REFWORD {FILEMASK}|{LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4} +REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} %option noyywrap %option yylineno @@ -446,6 +458,9 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} %x St_Snippet %x St_SetScope %x St_SetScopeEnd +%x St_Options +%x St_Block +%x St_Emoji %x St_Sections %s St_SecLabel1 @@ -554,13 +569,13 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->indent = computeIndent(text,dotPos); return TK_ENDLIST; } -<St_Para>"{"{BLANK}*"@link" { +<St_Para>"{"{BLANK}*"@link"/{BLANK}+ { g_token->name = "javalink"; - return TK_COMMAND; + return TK_COMMAND_AT; } <St_Para>"{"{BLANK}*"@inheritDoc"{BLANK}*"}" { g_token->name = "inheritdoc"; - return TK_COMMAND; + return TK_COMMAND_AT; } <St_Para>"@_fakenl" { // artificial new line yylineno++; @@ -570,22 +585,23 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} bool ok; g_token->id = QCString(yytext).right((int)yyleng-6).toInt(&ok); ASSERT(ok); - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_Para>{CMD}"n"\n { /* \n followed by real newline */ yylineno++; g_token->name = yytext+1; g_token->name = g_token->name.stripWhiteSpace(); g_token->paramDir=TokenInfo::Unspecified; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_Para>{SPCMD1} | <St_Para>{SPCMD2} | +<St_Para>{SPCMD5} | <St_Para>{SPCMD4} { /* special command */ g_token->name = yytext+1; g_token->name = g_token->name.stripWhiteSpace(); g_token->paramDir=TokenInfo::Unspecified; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_Para>{PARAMIO} { /* param [in,out] command */ g_token->name = "param"; @@ -611,7 +627,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} { g_token->paramDir=TokenInfo::Unspecified; } - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK}/\. { // URL. g_token->name=yytext; @@ -657,7 +673,8 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->text = tagName.mid(text_begin,text_end-text_begin); return TK_RCSTAG; } -<St_Para,St_HtmlOnly>"$("{ID}")" { /* environment variable */ +<St_Para,St_HtmlOnly,St_ManOnly,St_LatexOnly,St_RtfOnly,St_XmlOnly,St_DbOnly>"$("{ID}")" | /* environment variable */ +<St_Para,St_HtmlOnly,St_ManOnly,St_LatexOnly,St_RtfOnly,St_XmlOnly,St_DbOnly>"$("{ID}"("{ID}"))" { /* environment variable */ QCString name = &yytext[2]; name = name.left(name.length()-1); QCString value = portable_getenv(name); @@ -696,6 +713,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } /********* patterns for normal words ******************/ +<St_Para,St_Text>[\-+0-9] | <St_Para,St_Text>{WORD1} | <St_Para,St_Text>{WORD2} { /* function call */ if (yytext[0]=='%') // strip % if present @@ -729,7 +747,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } <St_Text>[\\@<>&$#%~] { g_token->name = yytext; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_Para>({BLANK}*\n)+{BLANK}*\n/{LISTITEM} { /* skip trailing paragraph followed by new list item */ if (g_insidePre || g_autoListLevel==0) @@ -922,7 +940,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_TitleN>{SPCMD2} { /* special command */ g_token->name = yytext+1; g_token->paramDir=TokenInfo::Unspecified; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_TitleN>{ID}"=" { /* attribute */ if (yytext[0]=='%') // strip % if present @@ -931,6 +949,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name = yytext; return TK_WORD; } +<St_TitleN>[\-+0-9] | <St_TitleN>{WORD1} | <St_TitleN>{WORD2} { /* word */ if (yytext[0]=='%') // strip % if present @@ -955,7 +974,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_TitleQ>{SPCMD2} { /* special command */ g_token->name = yytext+1; g_token->paramDir=TokenInfo::Unspecified; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_TitleQ>{WORD1NQ} | <St_TitleQ>{WORD2NQ} { /* word */ @@ -1001,7 +1020,15 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return 0; } <St_Cite>{CITEID} { // label to cite - g_token->name=yytext; + if (yytext[0] =='"') + { + g_token->name=yytext+1; + g_token->name=g_token->name.left(yyleng-2); + } + else + { + g_token->name=yytext; + } return TK_WORD; } <St_Cite>{BLANK} { // white space @@ -1050,7 +1077,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_IntRef>{BLANK}+"\"" { BEGIN(St_Ref2); } -<St_SetScope>({SCOPEMASK}|{ANONNS}){BLANK} { +<St_SetScope>({SCOPEMASK}|{ANONNS}){BLANK}|{FILEMASK} { g_token->name = yytext; g_token->name = g_token->name.stripWhiteSpace(); return TK_WORD; @@ -1086,7 +1113,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Ref2>{SPCMD2} { /* special command */ g_token->name = yytext+1; g_token->paramDir=TokenInfo::Unspecified; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <St_Ref2>{WORD1NQ} | <St_Ref2>{WORD2NQ} { @@ -1144,6 +1171,29 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->chars=yytext; return TK_WHITESPACE; } +<St_Options>{ID} { + g_token->name+=yytext; + } +<St_Options>{WS}*","{WS}* +<St_Options>{WS} { /* option separator */ + g_token->name+=","; + } +<St_Options>"}" { + return TK_WORD; + } +<St_Block>{ID} { + g_token->name+=yytext; + } +<St_Block>"]" { + return TK_WORD; + } +<St_Emoji>[:0-9_a-z+-]+ { + g_token->name=yytext; + return TK_WORD; + } +<St_Emoji>. { + return 0; + } <St_File>{FILEMASK} { g_token->name = yytext; return TK_WORD; @@ -1308,7 +1358,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <*>[\\@<>&$#%~"=] { /* unescaped special character */ //warn(g_fileName,yylineno,"Unexpected character `%s', assuming command \\%s was meant.",yytext,yytext); g_token->name = yytext; - return TK_COMMAND; + return TK_COMMAND_SEL(); } <*>. { warn(g_fileName,yylineno,"Unexpected character `%s'",yytext); @@ -1506,6 +1556,24 @@ void doctokenizerYYsetStateSetScope() BEGIN(St_SetScope); } +void doctokenizerYYsetStateOptions() +{ + g_token->name=""; + BEGIN(St_Options); +} + +void doctokenizerYYsetStateBlock() +{ + g_token->name=""; + BEGIN(St_Block); +} + +void doctokenizerYYsetStateEmoji() +{ + g_token->name=""; + BEGIN(St_Emoji); +} + void doctokenizerYYcleanup() { yy_delete_buffer( YY_CURRENT_BUFFER ); diff --git a/src/docvisitor.h b/src/docvisitor.h index 18fb743..d2318c9 100644 --- a/src/docvisitor.h +++ b/src/docvisitor.h @@ -37,6 +37,7 @@ class DocAutoListItem; class DocPara; class DocRoot; class DocSymbol; +class DocEmoji; class DocURL; class DocStyleChange; class DocSimpleSect; @@ -101,6 +102,7 @@ class DocVisitor 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; diff --git a/src/dot.cpp b/src/dot.cpp index 80703b9..0944a02 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -24,6 +24,7 @@ #include <qthread.h> #include <qmutex.h> #include <qwaitcondition.h> +#include <qregexp.h> #include "dot.h" #include "doxygen.h" @@ -139,7 +140,7 @@ static const char svgZoomFooter[] = " <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" " </g>\n" " </g>\n" -// link to orginial SVG +// link to original SVG " <svg viewBox=\"0 0 15 15\" width=\"100%\" height=\"30px\" preserveAspectRatio=\"xMaxYMin meet\">\n" " <g id=\"arrow_out\" transform=\"scale(0.3 0.3)\">\n" " <a xlink:href=\"$orgname\" target=\"_base\">\n" @@ -266,6 +267,7 @@ static void writeGraphHeader(FTextStream &t,const QCString &title=QCString()) { t << " // INTERACTIVE_SVG=YES\n"; } + t << " // LATEX_PDF_SIZE\n"; // write placeholder for LaTeX PDF bounding box size repacement if (Config_getBool(DOT_TRANSPARENT)) { t << " bgcolor=\"transparent\";" << endl; @@ -375,6 +377,7 @@ static bool convertMapFile(FTextStream &t,const char *mapName, const QCString &context=QCString()) { QFile f(mapName); + static QRegExp re("id=\"node[0-9]*\""); if (!f.open(IO_ReadOnly)) { err("problems opening map file %s for inclusion in the docs!\n" @@ -393,7 +396,7 @@ static bool convertMapFile(FTextStream &t,const char *mapName, if (buf.left(5)=="<area") { - t << replaceRef(buf,relPath,urlOnly,context); + t << replaceRef(buf,relPath,urlOnly,context).replace(re,""); } } } @@ -437,6 +440,55 @@ static void unsetDotFontPath() g_dotFontPath=""; } +static bool resetPDFSize(const int width,const int height, const char *base) +{ + QString tmpName = QString::fromUtf8(QCString(base)+".tmp"); + QString patchFile = QString::fromUtf8(QCString(base)+".dot"); + if (!QDir::current().rename(patchFile,tmpName)) + { + err("Failed to rename file %s to %s!\n",patchFile.data(),tmpName.data()); + return FALSE; + } + QFile fi(tmpName); + QFile fo(patchFile); + if (!fi.open(IO_ReadOnly)) + { + err("problem opening file %s for patching!\n",tmpName.data()); + QDir::current().rename(tmpName,patchFile); + return FALSE; + } + if (!fo.open(IO_WriteOnly)) + { + err("problem opening file %s for patching!\n",patchFile.data()); + QDir::current().rename(tmpName,patchFile); + fi.close(); + return FALSE; + } + FTextStream t(&fo); + const int maxLineLen=100*1024; + while (!fi.atEnd()) // foreach line + { + QCString line(maxLineLen); + int numBytes = fi.readLine(line.rawData(),maxLineLen); + if (numBytes<=0) + { + break; + } + line.resize(numBytes+1); + if (line.find("LATEX_PDF_SIZE") != -1) + { + double scale = (width > height ? width : height)/double(MAX_LATEX_GRAPH_INCH); + t << " size=\""<<width/scale << "," <<height/scale <<"\";\n"; + } + else + t << line; + } + fi.close(); + fo.close(); + // remove temporary file + QDir::current().remove(tmpName); + return TRUE; +} static bool readBoundingBox(const char *fileName,int *width,int *height,bool isEps) { QCString bb = isEps ? QCString("%%PageBoundingBox:") : QCString("/MediaBox ["); @@ -765,10 +817,10 @@ DotRunner::DotRunner(const QCString &file,const QCString &path, m_jobs.setAutoDelete(TRUE); } -void DotRunner::addJob(const char *format,const char *output) +void DotRunner::addJob(const char *format,const char *output, const char *base) { QCString args = QCString("-T")+format+" -o \""+output+"\""; - m_jobs.append(new DotConstString(args)); + m_jobs.append(new DotConstString(args, base)); } void DotRunner::addPostProcessing(const char *cmd,const char *args) @@ -780,6 +832,7 @@ void DotRunner::addPostProcessing(const char *cmd,const char *args) bool DotRunner::run() { int exitCode=0; + int width=0,height=0; QCString dotArgs; QListIterator<DotConstString> li(m_jobs); @@ -792,9 +845,26 @@ bool DotRunner::run() dotArgs+=' '; dotArgs+=s->data(); } - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; + dotArgs=QCString("\"")+m_file.data()+"\""; + bool redo = FALSE; + for (li.toFirst();(s=li.current());++li) + { + if (s->pdfData()) + { + if (!readBoundingBox(QCString(s->pdfData())+".pdf",&width,&height,FALSE)) goto error; + if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) + { + if (!resetPDFSize(width,height,s->pdfData())) goto error; + dotArgs+=' '; + dotArgs+=s->data(); + redo = TRUE; + } + } + } + if (redo) { - goto error; + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; } } else @@ -802,9 +872,15 @@ bool DotRunner::run() for (li.toFirst();(s=li.current());++li) { dotArgs=QCString("\"")+m_file.data()+"\" "+s->data(); - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; + if (s->pdfData()) { - goto error; + if (!readBoundingBox(QCString(s->pdfData())+".pdf",&width,&height,FALSE)) goto error; + if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) + { + if (!resetPDFSize(width,height,s->pdfData())) goto error; + if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; + } } } } @@ -1034,12 +1110,18 @@ bool DotFilePatcher::run() int n = sscanf(line.data()+i,"<!-- MAP %d",&mapId); if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) { + QGString result; + FTextStream tt(&result); Map *map = m_maps.at(mapId); //printf("patching MAP %d in file %s with contents of %s\n", // mapId,m_patchFile.data(),map->mapFile.data()); - t << "<map name=\"" << map->label << "\" id=\"" << map->label << "\">" << endl; - convertMapFile(t,map->mapFile,map->relPath,map->urlOnly,map->context); - t << "</map>" << endl; + convertMapFile(tt,map->mapFile,map->relPath,map->urlOnly,map->context); + if (!result.isEmpty()) + { + t << "<map name=\"" << map->label << "\" id=\"" << map->label << "\">" << endl; + t << result; + t << "</map>" << endl; + } } else // error invalid map id! { @@ -1309,6 +1391,11 @@ bool DotManager::run() setDotFontPath(Config_getString(RTF_OUTPUT)); setPath=TRUE; } + else if (Config_getBool(GENERATE_DOCBOOK)) + { + setDotFontPath(Config_getString(DOCBOOK_OUTPUT)); + setPath=TRUE; + } portable_sysTimerStart(); // fill work queue with dot operations DotRunner *dr; @@ -1428,6 +1515,7 @@ DotNode::DotNode(int n,const char *lab,const char *tip, const char *url, , m_visible(FALSE) , m_truncated(Unknown) , m_distance(1000) + , m_renumbered(false) { } @@ -1804,10 +1892,14 @@ void DotNode::writeBox(FTextStream &t, << m_url.right(m_url.length()-anchorPos) << "\""; } } - if (!m_tooltip.isEmpty()) - { - t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\""; - } + } + if (!m_tooltip.isEmpty()) + { + t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\""; + } + else + { + t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0' is used } t << "];" << endl; } @@ -2196,7 +2288,11 @@ void DotNode::renumberNodes(int &number) DotNode *cn; for (dnlic.toFirst();(cn=dnlic.current());++dnlic) { - cn->renumberNodes(number); + if (!cn->m_renumbered) + { + cn->m_renumbered = true; + cn->renumberNodes(number); + } } } } @@ -2245,7 +2341,10 @@ void DotGfxHierarchyTable::createGraph(DotNode *n,FTextStream &out, QCString baseName; QCString imgExt = getDotImageExtension(); QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - baseName.sprintf("inherit_graph_%d",id); + if (m_prefix.isEmpty()) + baseName.sprintf("inherit_graph_%d",id); + else + baseName.sprintf("%sinherit_graph_%d",m_prefix.data(),id); QCString imgName = baseName+"."+ imgExt; QCString mapName = baseName+".map"; QCString absImgName = QCString(d.absPath().data())+"/"+imgName; @@ -2437,6 +2536,7 @@ void DotGfxHierarchyTable::addHierarchy(DotNode *n,ClassDef *cd,bool hideSuper) void DotGfxHierarchyTable::addClassList(ClassSDict *cl) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); ClassSDict::Iterator cli(*cl); ClassDef *cd; for (cli.toLast();(cd=cli.current());--cli) @@ -2448,6 +2548,10 @@ void DotGfxHierarchyTable::addClassList(ClassSDict *cl) { continue; } + if (sliceOpt && cd->compoundType() != m_classType) + { + continue; + } if (!hasVisibleRoot(cd->baseClasses()) && cd->isVisibleInHierarchy() ) // root node in the forest @@ -2480,7 +2584,10 @@ void DotGfxHierarchyTable::addClassList(ClassSDict *cl) } } -DotGfxHierarchyTable::DotGfxHierarchyTable() : m_curNodeNumber(1) +DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::CompoundType ct) + : m_prefix(prefix) + , m_classType(ct) + , m_curNodeNumber(1) { m_rootNodes = new QList<DotNode>; m_usedNodes = new QDict<DotNode>(1009); @@ -2993,7 +3100,7 @@ DotClassGraph::~DotClassGraph() QCString computeMd5Signature(DotNode *root, DotNode::GraphType gt, GraphOutputFormat format, - bool lrRank, + const QCString &rank, // either "LR", "RL", or "" bool renderParents, bool backArrows, const QCString &title, @@ -3004,9 +3111,9 @@ QCString computeMd5Signature(DotNode *root, QGString buf; FTextStream md5stream(&buf); writeGraphHeader(md5stream,title); - if (lrRank) + if (!rank.isEmpty()) { - md5stream << " rankdir=\"LR\";" << endl; + md5stream << " rankdir=\"" << rank << "\";" << endl; } root->clearWriteFlag(); root->write(md5stream, @@ -3055,7 +3162,7 @@ static bool updateDotGraph(DotNode *root, DotNode::GraphType gt, const QCString &baseName, GraphOutputFormat format, - bool lrRank, + const QCString &rank, bool renderParents, bool backArrows, const QCString &title=QCString() @@ -3064,7 +3171,7 @@ static bool updateDotGraph(DotNode *root, QCString theGraph; // TODO: write graph to theGraph, then compute md5 checksum QCString md5 = computeMd5Signature( - root,gt,format,lrRank,renderParents, + root,gt,format,rank,renderParents, backArrows,title,theGraph); QFile f(baseName+".dot"); if (f.open(IO_WriteOnly)) @@ -3125,7 +3232,7 @@ QCString DotClassGraph::writeGraph(FTextStream &out, m_graphType, absBaseName, graphFormat, - m_lrRank, + m_lrRank ? "LR" : "", m_graphType==DotNode::Inheritance, TRUE, m_startNode->label() @@ -3150,7 +3257,7 @@ QCString DotClassGraph::writeGraph(FTextStream &out, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -3164,29 +3271,15 @@ QCString DotClassGraph::writeGraph(FTextStream &out, if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) { out << "<para>" << endl; - out << " <figure>" << endl; - out << " <title>"; - switch (m_graphType) - { - case DotNode::Collaboration: - out << "Collaboration graph"; - break; - case DotNode::Inheritance: - out << "Inheritance graph"; - break; - default: - ASSERT(0); - break; - } - out << "</title>" << endl; + out << " <informalfigure>" << endl; out << " <mediaobject>" << endl; out << " <imageobject>" << endl; out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; + out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; out << "</imagedata>" << endl; out << " </imageobject>" << endl; out << " </mediaobject>" << endl; - out << " </figure>" << endl; + out << " </informalfigure>" << endl; out << "</para>" << endl; } else if (graphFormat==GOF_BITMAP && generateImageMap) // produce HTML to include the image @@ -3409,9 +3502,10 @@ DotInclDepGraph::DotInclDepGraph(FileDef *fd,bool inverse) m_inclDepFileName = fd->includeDependencyGraphFileName(); m_inclByDepFileName = fd->includedByDependencyGraphFileName(); QCString tmp_url=fd->getReference()+"$"+fd->getOutputFileBase(); + QCString tooltip = fd->briefDescriptionAsTooltip(); m_startNode = new DotNode(m_curNodeNumber++, fd->docName(), - "", + tooltip, tmp_url.data(), TRUE // root node ); @@ -3484,7 +3578,7 @@ QCString DotInclDepGraph::writeGraph(FTextStream &out, DotNode::Dependency, absBaseName, graphFormat, - FALSE, // lrRank + "", // lrRank FALSE, // renderParents m_inverse, // backArrows m_startNode->label() @@ -3508,7 +3602,7 @@ QCString DotInclDepGraph::writeGraph(FTextStream &out, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -3522,17 +3616,15 @@ QCString DotInclDepGraph::writeGraph(FTextStream &out, if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) { out << "<para>" << endl; - out << " <figure>" << endl; - out << " <title>Dependency diagram"; - out << "</title>" << endl; + out << " <informalfigure>" << endl; out << " <mediaobject>" << endl; out << " <imageobject>" << endl; out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; + out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; out << "</imagedata>" << endl; out << " </imageobject>" << endl; out << " </mediaobject>" << endl; - out << " </figure>" << endl; + out << " </informalfigure>" << endl; out << "</para>" << endl; } else if (graphFormat==GOF_BITMAP && generateImageMap) @@ -3738,9 +3830,10 @@ DotCallGraph::DotCallGraph(MemberDef *md,bool inverse) { name = md->qualifiedName(); } + QCString tooltip = md->briefDescriptionAsTooltip(); m_startNode = new DotNode(m_curNodeNumber++, linkToText(md->getLanguage(),name,FALSE), - "", + tooltip, uniqueId.data(), TRUE // root node ); @@ -3796,11 +3889,12 @@ QCString DotCallGraph::writeGraph(FTextStream &out, GraphOutputFormat graphForma QCString absImgName = absBaseName+"."+imgExt; bool regenerate = FALSE; + if (updateDotGraph(m_startNode, DotNode::CallGraph, absBaseName, graphFormat, - TRUE, // lrRank + m_inverse ? "RL" : "LR", // lrRank FALSE, // renderParents m_inverse, // backArrows m_startNode->label() @@ -3826,7 +3920,7 @@ QCString DotCallGraph::writeGraph(FTextStream &out, GraphOutputFormat graphForma DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -3841,17 +3935,15 @@ QCString DotCallGraph::writeGraph(FTextStream &out, GraphOutputFormat graphForma if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) { out << "<para>" << endl; - out << " <figure>" << endl; - out << " <title>Call diagram"; - out << "</title>" << endl; + out << " <informalfigure>" << endl; out << " <mediaobject>" << endl; out << " <imageobject>" << endl; out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; + out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; out << "</imagedata>" << endl; out << " </imageobject>" << endl; out << " </mediaobject>" << endl; - out << " </figure>" << endl; + out << " </informalfigure>" << endl; out << "</para>" << endl; } else if (graphFormat==GOF_BITMAP && generateImageMap) @@ -3992,7 +4084,7 @@ QCString DotDirDeps::writeGraph(FTextStream &out, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -4006,17 +4098,15 @@ QCString DotDirDeps::writeGraph(FTextStream &out, if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) { out << "<para>" << endl; - out << " <figure>" << endl; - out << " <title>Directory Dependency diagram"; - out << "</title>" << endl; + out << " <informalfigure>" << endl; out << " <mediaobject>" << endl; out << " <imageobject>" << endl; out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; + out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; out << "</imagedata>" << endl; out << " </imageobject>" << endl; out << " </mediaobject>" << endl; - out << " </figure>" << endl; + out << " </informalfigure>" << endl; out << "</para>" << endl; } else if (graphFormat==GOF_BITMAP && generateImageMap) @@ -4170,7 +4260,7 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir, { if (Config_getBool(USE_PDFLATEX)) { - dotRun.addJob("pdf",absOutFile+".pdf"); + dotRun.addJob("pdf",absOutFile+".pdf",absOutFile); } else { @@ -4238,13 +4328,18 @@ void writeDotImageMapFromFile(FTextStream &t, } else // bitmap graphics { - t << "<img src=\"" << relPath << imgName << "\" alt=\"" - << imgName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl - << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">"; + QGString result; + FTextStream tt(&result); - convertMapFile(t, absOutFile, relPath ,TRUE, context); - - t << "</map>" << endl; + t << "<img src=\"" << relPath << imgName << "\" alt=\"" + << imgName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl; + convertMapFile(tt, absOutFile, relPath ,TRUE, context); + if (!result.isEmpty()) + { + t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">"; + t << result; + t << "</map>" << endl; + } } d.remove(absOutFile); } @@ -4262,7 +4357,8 @@ DotGroupCollaboration::DotGroupCollaboration(GroupDef* gd) { QCString tmp_url = gd->getReference()+"$"+gd->getOutputFileBase(); m_usedNodes = new QDict<DotNode>(1009); - m_rootNode = new DotNode(m_curNodeNumber++, gd->groupTitle(), "", tmp_url, TRUE ); + QCString tooltip = gd->briefDescriptionAsTooltip(); + m_rootNode = new DotNode(m_curNodeNumber++, gd->groupTitle(), tooltip, tmp_url, TRUE ); m_rootNode->markAsVisible(); m_usedNodes->insert(gd->name(), m_rootNode ); m_edges.setAutoDelete(TRUE); @@ -4555,7 +4651,7 @@ QCString DotGroupCollaboration::writeGraph( FTextStream &t, DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); if (usePDFLatex) { - dotRun->addJob("pdf",absPdfName); + dotRun->addJob("pdf",absPdfName,absBaseName); } else { @@ -4568,17 +4664,15 @@ QCString DotGroupCollaboration::writeGraph( FTextStream &t, if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) { t << "<para>" << endl; - t << " <figure>" << endl; - t << " <title>Group Collaboration diagram"; - t << "</title>" << endl; + t << " <informalfigure>" << endl; t << " <mediaobject>" << endl; t << " <imageobject>" << endl; t << " <imagedata"; - t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; + t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; t << "</imagedata>" << endl; t << " </imageobject>" << endl; t << " </mediaobject>" << endl; - t << " </figure>" << endl; + t << " </informalfigure>" << endl; t << "</para>" << endl; } else if (graphFormat==GOF_BITMAP && writeImageMap) @@ -26,8 +26,8 @@ #include <qqueue.h> #include <qthread.h> #include "sortdict.h" +#include "classdef.h" -class ClassDef; class FileDef; class FTextStream; class DotNodeList; @@ -42,6 +42,12 @@ class DotRunnerQueue; enum GraphOutputFormat { GOF_BITMAP, GOF_EPS }; enum EmbeddedOutputFormat { EOF_Html, EOF_LaTeX, EOF_Rtf, EOF_DocBook }; +// 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 +// It is anyway hard to view these size of images +#define MAX_LATEX_GRAPH_INCH 150 +#define MAX_LATEX_GRAPH_SIZE (MAX_LATEX_GRAPH_INCH * 72) + /** Attributes of an edge of a dot graph */ struct EdgeInfo { @@ -116,6 +122,7 @@ class DotNode bool m_visible; //!< is the node visible in the output TruncState m_truncated; //!< does the node have non-visible children/parents int m_distance; //!< shortest path to the root node + bool m_renumbered;//!< indicates if the node has been renumbered (to prevent endless loops) friend class DotGfxHierarchyTable; friend class DotClassGraph; @@ -127,8 +134,9 @@ class DotNode friend QCString computeMd5Signature( DotNode *root, GraphType gt, - GraphOutputFormat f, - bool lrRank, bool renderParents, + GraphOutputFormat f, + const QCString &rank, + bool renderParents, bool backArrows, const QCString &title, QCString &graphStr @@ -149,7 +157,7 @@ class DotNodeList : public QList<DotNode> class DotGfxHierarchyTable { public: - DotGfxHierarchyTable(); + DotGfxHierarchyTable(const char *prefix="",ClassDef::CompoundType ct=ClassDef::Class); ~DotGfxHierarchyTable(); void writeGraph(FTextStream &t,const char *path, const char *fileName) const; void createGraph(DotNode *rootNode,FTextStream &t,const char *path,const char *fileName,int id) const; @@ -159,10 +167,12 @@ class DotGfxHierarchyTable void addHierarchy(DotNode *n,ClassDef *cd,bool hide); void addClassList(ClassSDict *cl); - QList<DotNode> *m_rootNodes; - QDict<DotNode> *m_usedNodes; - int m_curNodeNumber; - DotNodeList *m_rootSubgraphs; + QCString m_prefix; + ClassDef::CompoundType m_classType; + QList<DotNode> *m_rootNodes; + QDict<DotNode> *m_usedNodes; + int m_curNodeNumber; + DotNodeList *m_rootSubgraphs; }; /** Representation of a class inheritance or dependency graph */ @@ -338,11 +348,12 @@ class DotGroupCollaboration class DotConstString { public: - DotConstString() { m_str=0; } - ~DotConstString() { delete[] m_str; } - DotConstString(const QCString &s) : m_str(0) { set(s); } - DotConstString(const DotConstString &s) : m_str(0) { set(s.data()); } + DotConstString() { m_str=0; m_pdfstr=0;} + ~DotConstString() { delete[] m_str; delete[] m_pdfstr;} + DotConstString(const QCString &s, const QCString &p = NULL) : m_str(0), m_pdfstr(0) { set(s); setpdf(p);} + DotConstString(const DotConstString &s) : m_str(0), m_pdfstr(0) { set(s.data()); } const char *data() const { return m_str; } + const char *pdfData() const { return m_pdfstr; } bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; } void set(const QCString &s) { @@ -354,9 +365,20 @@ class DotConstString qstrcpy(m_str,s.data()); } } + void setpdf(const QCString &p) + { + delete[] m_pdfstr; + m_pdfstr=0; + if (!p.isEmpty()) + { + m_pdfstr=new char[p.length()+1]; + qstrcpy(m_pdfstr,p.data()); + } + } private: DotConstString &operator=(const DotConstString &); char *m_str; + char *m_pdfstr; }; /** Helper class to run dot from doxygen. @@ -377,7 +399,7 @@ class DotRunner /** Adds an additional job to the run. * Performing multiple jobs one file can be faster. */ - void addJob(const char *format,const char *output); + void addJob(const char *format,const char *output, const char *base = NULL); void addPostProcessing(const char *cmd,const char *args); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 00826d6..2d55ae6 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -13,6 +13,10 @@ * */ +#if !defined(_WIN32) || defined(__CYGWIN__) +#define _DEFAULT_SOURCE 1 +#endif + #include <locale.h> #include <qfileinfo.h> @@ -99,6 +103,7 @@ #include "settings.h" #include "context.h" #include "fileparser.h" +#include "emoji.h" // provided by the generated file resources.cpp extern void initResources(); @@ -163,6 +168,7 @@ bool Doxygen::suppressDocWarnings = FALSE; Store *Doxygen::symbolStorage; QCString Doxygen::objDBFileName; QCString Doxygen::entryDBFileName; +QCString Doxygen::filterDBFileName; bool Doxygen::gatherDefines = TRUE; IndexList *Doxygen::indexList; int Doxygen::subpageNestingLevel = 0; @@ -342,6 +348,7 @@ static STLInfo g_stlinfo[] = { "auto_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // deprecated { "smart_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11 { "unique_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11 + { "shared_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++14 { "weak_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11 { "ios_base", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 { "error_code", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 @@ -515,7 +522,7 @@ static void addSTLClasses(EntryNav *rootNav) { addSTLMember(classEntryNav,info->templType2,info->templName2); } - if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || + if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" || fullName=="std::unique_ptr" || fullName=="std::weak_ptr") { Entry *memEntry = new Entry; @@ -605,7 +612,7 @@ static void addRelatedPage(EntryNav *rootNav) { pd->setBriefDescription(root->brief,root->briefFile,root->briefLine); pd->addSectionsToDefinition(root->anchors); - pd->setShowToc(root->stat); + pd->setLocalToc(root->localToc); addPageToContext(pd,rootNav); } } @@ -1298,6 +1305,8 @@ static void addClassToContext(EntryNav *rootNav) } cd->setCompoundType(convertToCompoundType(root->section,root->spec)); + + cd->setMetaData(root->metaData); } else // new class { @@ -1362,6 +1371,8 @@ static void addClassToContext(EntryNav *rootNav) cd->setBodySegment(root->bodyLine,root->endBodyLine); cd->setBodyDef(fd); + cd->setMetaData(root->metaData); + // see if the class is found inside a namespace //bool found=addNamespace(root,cd); @@ -1581,7 +1592,7 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC md->typeString(),md->name(),md->argsString(),md->excpString(), md->protection(),md->virtualness(),md->isStatic(),Member, md->memberType(), - 0,0); + 0,0,""); imd->setMemberClass(cd); imd->setDocumentation(md->documentation(),md->docFile(),md->docLine()); imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine()); @@ -1753,6 +1764,7 @@ static void buildNamespaceList(EntryNav *rootNav) nd->setReference(""); nd->setFileName(fullName); } + nd->setMetaData(root->metaData); // file definition containing the namespace nd FileDef *fd=rootNav->fileDef(); @@ -1782,6 +1794,7 @@ static void buildNamespaceList(EntryNav *rootNav) nd->setArtificial(root->artificial); nd->setLanguage(root->lang); nd->setId(root->id); + nd->setMetaData(root->metaData); //printf("Adding namespace to group\n"); addNamespaceToGroups(root,nd); @@ -1957,6 +1970,7 @@ static void findUsingDirectives(EntryNav *rootNav) nd->setArtificial(TRUE); nd->setLanguage(root->lang); nd->setId(root->id); + nd->setMetaData(root->metaData); QListIterator<Grouping> gli(*root->groups); Grouping *g; @@ -2162,7 +2176,7 @@ static void findUsingDeclImports(EntryNav *rootNav) md->typeString(),memName,md->argsString(), md->excpString(),root->protection,root->virt, md->isStatic(),Member,md->memberType(), - templAl,al + templAl,al,root->metaData ); } newMd->setMemberClass(cd); @@ -2182,6 +2196,8 @@ static void findUsingDeclImports(EntryNav *rootNav) newMd->setDefinition(md->definition()); newMd->enableCallGraph(root->callGraph); newMd->enableCallerGraph(root->callerGraph); + newMd->enableReferencedByRelation(root->referencedByRelation); + newMd->enableReferencesRelation(root->referencesRelation); newMd->setBitfields(md->bitfieldString()); newMd->addSectionsToDefinition(root->anchors); newMd->setBodySegment(md->getStartBodyLine(),md->getEndBodyLine()); @@ -2355,7 +2371,7 @@ static MemberDef *addVariableToClass( fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, prot,Normal,root->stat,related, - mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0); + mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope()) //md->setDefFile(root->fileName); @@ -2378,6 +2394,8 @@ static MemberDef *addVariableToClass( md->setWriteAccessor(root->write); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); md->setHidden(root->hidden); md->setArtificial(root->artificial); md->setLanguage(root->lang); @@ -2598,7 +2616,7 @@ static MemberDef *addVariableToFile( fileName,root->startLine,root->startColumn, root->type,name,root->args,0, root->protection, Normal,root->stat,Member, - mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0); + mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setMemberSpecifiers(root->spec); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -2615,6 +2633,8 @@ static MemberDef *addVariableToFile( md->setId(root->id); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); md->setExplicitExternal(root->explicitExternal); //md->setOuterScope(fd); if (!root->explicitExternal) @@ -2816,6 +2836,8 @@ done: static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + rootNav->loadEntry(g_storage); Entry *root = rootNav->entry(); @@ -2935,6 +2957,10 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) mtype=MemberType_Property; else if (root->mtype==Event) mtype=MemberType_Event; + else if (type.find("sequence<") != -1) + mtype=sliceOpt ? MemberType_Sequence : MemberType_Typedef; + else if (type.find("dictionary<") != -1) + mtype=sliceOpt ? MemberType_Dictionary : MemberType_Typedef; else mtype=MemberType_Variable; @@ -3049,6 +3075,58 @@ static void buildTypedefList(EntryNav *rootNav) } //---------------------------------------------------------------------- +// Searches the Entry tree for sequence documentation sections. +// If found they are stored in the global list. +static void buildSequenceList(EntryNav *rootNav) +{ + if (!rootNav->name().isEmpty() && + rootNav->section()==Entry::VARIABLE_SEC && + rootNav->type().find("sequence<")!=-1 // it's a sequence + ) + { + addVariable(rootNav); + } + if (rootNav->children()) + { + EntryNavListIterator eli(*rootNav->children()); + EntryNav *e; + for (;(e=eli.current());++eli) + { + if (e->section()!=Entry::ENUM_SEC) + { + buildSequenceList(e); + } + } + } +} + +//---------------------------------------------------------------------- +// Searches the Entry tree for dictionary documentation sections. +// If found they are stored in the global list. +static void buildDictionaryList(EntryNav *rootNav) +{ + if (!rootNav->name().isEmpty() && + rootNav->section()==Entry::VARIABLE_SEC && + rootNav->type().find("dictionary<")!=-1 // it's a dictionary + ) + { + addVariable(rootNav); + } + if (rootNav->children()) + { + EntryNavListIterator eli(*rootNav->children()); + EntryNav *e; + for (;(e=eli.current());++eli) + { + if (e->section()!=Entry::ENUM_SEC) + { + buildDictionaryList(e); + } + } + } +} + +//---------------------------------------------------------------------- // Searches the Entry tree for Variable documentation sections. // If found they are stored in their class or in the global list. @@ -3109,7 +3187,7 @@ static void addInterfaceOrServiceToServiceOrSingleton( MemberDef *const md = new MemberDef( fileName, root->startLine, root->startColumn, root->type, rname, "", "", root->protection, root->virt, root->stat, Member, - type, 0, root->argList); + type, 0, root->argList, root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -3128,6 +3206,8 @@ static void addInterfaceOrServiceToServiceOrSingleton( md->setDefinition(def); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); Debug::print(Debug::Functions,0, " Interface Member:\n" @@ -3296,7 +3376,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, root->stat && root->relatesType != MemberOf, root->relates.isEmpty() ? Member : root->relatesType == MemberOf ? Foreign : Related, - mtype,root->tArgLists ? root->tArgLists->getLast() : 0,root->argList); + mtype,root->tArgLists ? root->tArgLists->getLast() : 0,root->argList, root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -3380,6 +3460,8 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, md->setDefinition(def); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); Debug::print(Debug::Functions,0, " Func Member:\n" @@ -3647,6 +3729,8 @@ static void buildFunctionList(EntryNav *rootNav) md->enableCallGraph(md->hasCallGraph() || root->callGraph); md->enableCallerGraph(md->hasCallerGraph() || root->callerGraph); + md->enableReferencedByRelation(md->hasReferencedByRelation() || root->referencedByRelation); + md->enableReferencesRelation(md->hasReferencesRelation() || root->referencesRelation); // merge ingroup specifiers if (md->getGroupDef()==0 && root->groups->getFirst()!=0) @@ -3686,7 +3770,7 @@ static void buildFunctionList(EntryNav *rootNav) root->fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,Member, - MemberType_Function,tArgList,root->argList); + MemberType_Function,tArgList,root->argList,root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setLanguage(root->lang); @@ -3766,6 +3850,8 @@ static void buildFunctionList(EntryNav *rootNav) md->setDefinition(def); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); //if (root->mGrpId!=-1) //{ // md->setMemberGroup(memberGroupDict[root->mGrpId]); @@ -3917,8 +4003,13 @@ static void findFriends() mmd->enableCallGraph(mmd->hasCallGraph() || fmd->hasCallGraph()); mmd->enableCallerGraph(mmd->hasCallerGraph() || fmd->hasCallerGraph()); + mmd->enableReferencedByRelation(mmd->hasReferencedByRelation() || fmd->hasReferencedByRelation()); + mmd->enableReferencesRelation(mmd->hasReferencesRelation() || fmd->hasReferencesRelation()); + fmd->enableCallGraph(mmd->hasCallGraph() || fmd->hasCallGraph()); fmd->enableCallerGraph(mmd->hasCallerGraph() || fmd->hasCallerGraph()); + fmd->enableReferencedByRelation(mmd->hasReferencedByRelation() || fmd->hasReferencedByRelation()); + fmd->enableReferencesRelation(mmd->hasReferencesRelation() || fmd->hasReferencesRelation()); } } } @@ -5318,6 +5409,8 @@ static void addMemberDocs(EntryNav *rootNav, md->setDefinition(fDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); ClassDef *cd=md->getClassDef(); NamespaceDef *nd=md->getNamespaceDef(); QCString fullName; @@ -5410,6 +5503,8 @@ static void addMemberDocs(EntryNav *rootNav, md->enableCallGraph(md->hasCallGraph() || root->callGraph); md->enableCallerGraph(md->hasCallerGraph() || root->callerGraph); + md->enableReferencedByRelation(md->hasReferencedByRelation() || root->referencedByRelation); + md->enableReferencesRelation(md->hasReferencesRelation() || root->referencesRelation); md->mergeMemberSpecifiers(root->spec); md->addSectionsToDefinition(root->anchors); @@ -6431,7 +6526,7 @@ static void findMember(EntryNav *rootNav, funcType,funcName,funcArgs,exceptions, declMd ? declMd->protection() : root->protection, root->virt,root->stat,Member, - mtype,tArgList,root->argList); + mtype,tArgList,root->argList,root->metaData); //printf("new specialized member %s args=`%s'\n",md->name().data(),funcArgs.data()); md->setTagInfo(rootNav->tagInfo()); md->setLanguage(root->lang); @@ -6442,6 +6537,8 @@ static void findMember(EntryNav *rootNav, md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); @@ -6498,7 +6595,7 @@ static void findMember(EntryNav *rootNav, root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Related, - mtype,tArgList,root->argList); + mtype,tArgList,root->argList,root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); @@ -6507,6 +6604,8 @@ static void findMember(EntryNav *rootNav, md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); QCString doc=getOverloadDocs(); doc+="<p>"; doc+=root->doc; @@ -6636,7 +6735,7 @@ static void findMember(EntryNav *rootNav, isMemberOf ? Foreign : Related, mtype, (root->tArgLists ? root->tArgLists->getLast() : 0), - funcArgs.isEmpty() ? 0 : root->argList); + funcArgs.isEmpty() ? 0 : root->argList,root->metaData); if (isDefine && mdDefine) { @@ -6711,6 +6810,8 @@ static void findMember(EntryNav *rootNav, md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setDocsForDefinition(!root->proto); @@ -6774,7 +6875,7 @@ localObjCMethod: root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Member, - MemberType_Function,0,root->argList); + MemberType_Function,0,root->argList,root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); @@ -6783,6 +6884,8 @@ localObjCMethod: md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); @@ -7110,7 +7213,7 @@ static void findEnums(EntryNav *rootNav) root->protection,Normal,FALSE, isMemberOf ? Foreign : isRelated ? Related : Member, MemberType_Enumeration, - 0,0); + 0,0,root->metaData); md->setTagInfo(rootNav->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); @@ -7125,6 +7228,8 @@ static void findEnums(EntryNav *rootNav) md->setMemberGroupId(root->mGrpId); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); //printf("%s::setRefItems(%d)\n",md->name().data(),root->sli?root->sli->count():-1); md->setRefItems(root->sli); //printf("found enum %s nd=%p\n",md->name().data(),nd); @@ -7332,7 +7437,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav) fileName,root->startLine,root->startColumn, root->type,root->name,root->args,0, root->protection, Normal,root->stat,Member, - MemberType_EnumValue,0,0); + MemberType_EnumValue,0,0,root->metaData); if (md->getClassDef()) fmd->setMemberClass(md->getClassDef()); else if (md->getNamespaceDef()) fmd->setNamespace(md->getNamespaceDef()); else if (md->getFileDef()) fmd->setFileDef(md->getFileDef()); @@ -7692,7 +7797,7 @@ static void computeMemberRelations() // bmcd->name().data(),bmd->name().data(),bmd // ); if (md!=bmd && bmcd && mcd && bmcd!=mcd && - (bmd->virtualness()!=Normal || + (bmd->virtualness()!=Normal || bmd->getLanguage()==SrcLangExt_Python || bmcd->compoundType()==ClassDef::Interface || bmcd->compoundType()==ClassDef::Protocol ) && @@ -8462,7 +8567,7 @@ static void findDefineDocumentation(EntryNav *rootNav) { MemberDef *md=new MemberDef(rootNav->tagInfo()->tagName,1,1, "#define",root->name,root->args,0, - Public,Normal,FALSE,Member,MemberType_Define,0,0); + Public,Normal,FALSE,Member,MemberType_Define,0,0,""); md->setTagInfo(rootNav->tagInfo()); md->setLanguage(root->lang); //printf("Searching for `%s' fd=%p\n",filePathName.data(),fd); @@ -8712,7 +8817,7 @@ static void findMainPage(EntryNav *rootNav) //setFileNameForSections(root->anchors,"index",Doxygen::mainPage); Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine); Doxygen::mainPage->setFileName(indexName); - Doxygen::mainPage->setShowToc(root->stat); + Doxygen::mainPage->setLocalToc(root->localToc); addPageToContext(Doxygen::mainPage,rootNav); SectionInfo *si = Doxygen::sectionDict->find(Doxygen::mainPage->name()); @@ -8922,7 +9027,7 @@ static void generatePageDocs() static void buildExampleList(EntryNav *rootNav) { - if (rootNav->section()==Entry::EXAMPLE_SEC && !rootNav->name().isEmpty()) + if ((rootNav->section()==Entry::EXAMPLE_SEC || rootNav->section()==Entry::EXAMPLE_LINENO_SEC) && !rootNav->name().isEmpty()) { rootNav->loadEntry(g_storage); Entry *root = rootNav->entry(); @@ -8943,7 +9048,7 @@ static void buildExampleList(EntryNav *rootNav) pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE)); pd->addSectionsToDefinition(root->anchors); pd->setLanguage(root->lang); - //pi->addSections(root->anchors); + pd->setShowLineNo(rootNav->section()==Entry::EXAMPLE_LINENO_SEC); Doxygen::exampleSDict->inSort(root->name,pd); //we don't add example to groups @@ -8992,11 +9097,16 @@ static void generateExampleDocs() g_outputList->docify(pd->name()); endTitle(*g_outputList,n,0); g_outputList->startContents(); + QCString lineNoOptStr; + if (pd->showLineNo()) + { + lineNoOptStr="{lineno}"; + } g_outputList->generateDoc(pd->docFile(), // file pd->docLine(), // startLine pd, // context 0, // memberDef - pd->documentation()+"\n\n\\include "+pd->name(), // docs + pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs TRUE, // index words TRUE, // is example pd->name() @@ -9042,8 +9152,33 @@ static void generateGroupDocs() //---------------------------------------------------------------------------- // generate module pages +static void generateNamespaceClassDocs(ClassSDict *d) +{ + // for each class in the namespace... + ClassSDict::Iterator cli(*d); + ClassDef *cd; + for ( ; (cd=cli.current()) ; ++cli ) + { + if ( ( cd->isLinkableInProject() && + cd->templateMaster()==0 + ) // skip external references, anonymous compounds and + // template instances and nested classes + && !cd->isHidden() && !cd->isEmbeddedInOuterScope() + ) + { + msg("Generating docs for compound %s...\n",cd->name().data()); + + cd->writeDocumentation(*g_outputList); + cd->writeMemberList(*g_outputList); + } + cd->writeDocumentationForInnerClasses(*g_outputList); + } +} + static void generateNamespaceDocs() { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + //writeNamespaceIndex(*g_outputList); NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); @@ -9058,24 +9193,12 @@ static void generateNamespaceDocs() nd->writeDocumentation(*g_outputList); } - // for each class in the namespace... - ClassSDict::Iterator cli(*nd->getClassSDict()); - ClassDef *cd; - for ( ; (cd=cli.current()) ; ++cli ) + generateNamespaceClassDocs(nd->getClassSDict()); + if (sliceOpt) { - if ( ( cd->isLinkableInProject() && - cd->templateMaster()==0 - ) // skip external references, anonymous compounds and - // template instances and nested classes - && !cd->isHidden() && !cd->isEmbeddedInOuterScope() - ) - { - msg("Generating docs for compound %s...\n",cd->name().data()); - - cd->writeDocumentation(*g_outputList); - cd->writeMemberList(*g_outputList); - } - cd->writeDocumentationForInnerClasses(*g_outputList); + generateNamespaceClassDocs(nd->getInterfaceSDict()); + generateNamespaceClassDocs(nd->getStructSDict()); + generateNamespaceClassDocs(nd->getExceptionSDict()); } } } @@ -9142,7 +9265,24 @@ static void generateConfigFile(const char *configFile,bool shortList, exit(1); } } - +static void compareDoxyfile() +{ + QFile f; + char configFile[2]; + configFile[0] = '-'; + configFile[1] = '\0'; + bool fileOpened=openOutputFile(configFile,f); + if (fileOpened) + { + FTextStream t(&f); + Config::compareDoxyfile(t); + } + else + { + err("Cannot open file %s for writing\n",configFile); + exit(1); + } +} //---------------------------------------------------------------------------- // read and parse a tag file @@ -9574,7 +9714,7 @@ int readDir(QFileInfo *fi, if (fi->isSymLink()) { dirName = resolveSymlink(dirName.data()); - if (dirName.isEmpty()) return 0; // recusive symlink + if (dirName.isEmpty()) return 0; // recursive symlink if (g_pathsVisited.find(dirName)) return 0; // already visited path g_pathsVisited.insert(dirName,(void*)0x8); } @@ -9624,7 +9764,7 @@ int readDir(QFileInfo *fi, { fn = new FileName(cfi->absFilePath().utf8(),name); fn->append(fd); - if (fnList) fnList->inSort(fn); + if (fnList) fnList->append(fn); fnDict->insert(name,fn); } } @@ -9723,7 +9863,7 @@ int readFileOrDirectory(const char *s, { fn = new FileName(filePath,name); fn->append(fd); - if (fnList) fnList->inSort(fn); + if (fnList) fnList->append(fn); fnDict->insert(name,fn); } } @@ -9752,14 +9892,17 @@ int readFileOrDirectory(const char *s, //---------------------------------------------------------------------------- -void readFormulaRepository() +void readFormulaRepository(QCString dir, bool cmp) { - QFile f(Config_getString(HTML_OUTPUT)+"/formula.repository"); + static int current_repository = 0; + int new_repository = 0; + QFile f(dir+"/formula.repository"); if (f.open(IO_ReadOnly)) // open repository { msg("Reading formula repository...\n"); QTextStream t(&f); QCString line; + Formula *f; while (!t.eof()) { line=t.readLine().utf8(); @@ -9773,14 +9916,41 @@ void readFormulaRepository() { QCString formName = line.left(se); QCString formText = line.right(line.length()-se-1); - Formula *f=new Formula(formText); - Doxygen::formulaList->setAutoDelete(TRUE); - Doxygen::formulaList->append(f); - Doxygen::formulaDict->insert(formText,f); - Doxygen::formulaNameDict->insert(formName,f); + if (cmp) + { + if ((f=Doxygen::formulaDict->find(formText))==0) + { + err("discrepancy between formula repositories! Remove " + "formula.repository and from_* files from output directories."); + exit(1); + } + QCString formLabel; + formLabel.sprintf("\\form#%d",f->getId()); + if (formLabel != formName) + { + err("discrepancy between formula repositories! Remove " + "formula.repository and from_* files from output directories."); + exit(1); + } + new_repository++; + } + else + { + f=new Formula(formText); + Doxygen::formulaList->append(f); + Doxygen::formulaDict->insert(formText,f); + Doxygen::formulaNameDict->insert(formName,f); + current_repository++; + } } } } + if (cmp && (current_repository != new_repository)) + { + err("size discrepancy between formula repositories! Remove " + "formula.repository and from_* files from output directories."); + exit(1); + } } //---------------------------------------------------------------------------- @@ -9831,7 +10001,7 @@ static void escapeAliases() while ((in=value.find("^^",p))!=-1) { newValue+=value.mid(p,in-p); - newValue+="\n"; + newValue+="@_linebr"; p=in+2; } newValue+=value.mid(p,value.length()-p); @@ -9969,6 +10139,11 @@ static void usage(const char *name) msg(" LaTeX: %s -w latex headerFile footerFile styleSheetFile [configFile]\n\n",name); msg("6) Use doxygen to generate a rtf extensions file\n"); msg(" RTF: %s -e rtf extensionsFile\n\n",name); + msg("7) Use doxygen to compare the used configuration file with the template configuration file\n"); + msg(" %s -x [configFile]\n\n",name); + msg("8) Use doxygen to show a list of build in emoji.\n"); + msg(" %s -f emoji outputFileName\n\n",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\n"); msg("-v print version string\n"); @@ -10055,6 +10230,7 @@ void initDoxygen() Doxygen::genericsDict = new GenericsSDict; Doxygen::indexList = new IndexList; Doxygen::formulaList = new FormulaList; + Doxygen::formulaList->setAutoDelete(TRUE); Doxygen::formulaDict = new FormulaDict(1009); Doxygen::formulaNameDict = new FormulaDict(1009); Doxygen::sectionDict = new SectionDict(257); @@ -10169,10 +10345,11 @@ void readConfiguration(int argc, char **argv) const char *layoutName=0; const char *debugLabel; const char *formatName; + const char *listName; bool genConfig=FALSE; bool shortList=FALSE; + bool diffList=FALSE; bool updateConfig=FALSE; - bool genLayout=FALSE; int retVal; while (optind<argc && argv[optind][0]=='-' && (isalpha(argv[optind][1]) || argv[optind][1]=='?' || @@ -10183,17 +10360,14 @@ void readConfiguration(int argc, char **argv) { case 'g': genConfig=TRUE; - configName=getArg(argc,argv,optind); - if (optind+1<argc && qstrcmp(argv[optind+1],"-")==0) - { configName="-"; optind++; } - if (!configName) - { configName="Doxyfile"; } break; case 'l': - genLayout=TRUE; layoutName=getArg(argc,argv,optind); if (!layoutName) { layoutName="DoxygenLayout.xml"; } + writeDefaultLayoutFile(layoutName); + cleanUpDoxygen(); + exit(0); break; case 'd': debugLabel=getArg(argc,argv,optind); @@ -10212,6 +10386,9 @@ void readConfiguration(int argc, char **argv) exit(1); } break; + case 'x': + diffList=TRUE; + break; case 's': shortList=TRUE; break; @@ -10246,6 +10423,34 @@ void readConfiguration(int argc, char **argv) cleanUpDoxygen(); exit(1); break; + case 'f': + listName=getArg(argc,argv,optind); + if (!listName) + { + err("option \"-f\" is missing list specifier.\n"); + cleanUpDoxygen(); + exit(1); + } + if (qstricmp(listName,"emoji")==0) + { + if (optind+1>=argc) + { + err("option \"-f emoji\" is missing an output file name\n"); + cleanUpDoxygen(); + exit(1); + } + QFile f; + if (openOutputFile(argv[optind+1],f)) + { + EmojiEntityMapper::instance()->writeEmojiFile(f); + } + cleanUpDoxygen(); + exit(0); + } + err("option \"-f\" has invalid list specifier.\n"); + cleanUpDoxygen(); + exit(1); + break; case 'w': formatName=getArg(argc,argv,optind); if (!formatName) @@ -10426,26 +10631,6 @@ void readConfiguration(int argc, char **argv) Config::init(); - if (genConfig && g_useOutputTemplate) - { - generateTemplateFiles("templates"); - cleanUpDoxygen(); - exit(0); - } - - if (genConfig) - { - generateConfigFile(configName,shortList); - cleanUpDoxygen(); - exit(0); - } - if (genLayout) - { - writeDefaultLayoutFile(layoutName); - cleanUpDoxygen(); - exit(0); - } - QFileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile"); if (optind>=argc) { @@ -10457,6 +10642,10 @@ void readConfiguration(int argc, char **argv) { configName="doxyfile"; } + else if (genConfig) + { + configName="Doxyfile"; + } else { err("Doxyfile not found and no input file specified!\n"); @@ -10467,7 +10656,7 @@ void readConfiguration(int argc, char **argv) else { QFileInfo fi(argv[optind]); - if (fi.exists() || qstrcmp(argv[optind],"-")==0) + if (fi.exists() || qstrcmp(argv[optind],"-")==0 || genConfig) { configName=argv[optind]; } @@ -10479,6 +10668,19 @@ void readConfiguration(int argc, char **argv) } } + if (genConfig && g_useOutputTemplate) + { + generateTemplateFiles("templates"); + cleanUpDoxygen(); + exit(0); + } + + if (genConfig) + { + generateConfigFile(configName,shortList); + cleanUpDoxygen(); + exit(0); + } if (!Config::parse(configName,updateConfig)) { @@ -10487,6 +10689,13 @@ void readConfiguration(int argc, char **argv) exit(1); } + if (diffList) + { + compareDoxyfile(); + cleanUpDoxygen(); + exit(0); + } + if (updateConfig) { generateConfigFile(configName,shortList,TRUE); @@ -10520,8 +10729,11 @@ void adjustConfiguration() Doxygen::imageNameDict = new FileNameDict(257); Doxygen::imageNameDict->setAutoDelete(TRUE); Doxygen::dotFileNameDict = new FileNameDict(257); + Doxygen::dotFileNameDict->setAutoDelete(TRUE); Doxygen::mscFileNameDict = new FileNameDict(257); + Doxygen::mscFileNameDict->setAutoDelete(TRUE); Doxygen::diaFileNameDict = new FileNameDict(257); + Doxygen::diaFileNameDict->setAutoDelete(TRUE); QCString outputLanguage=Config_getEnum(OUTPUT_LANGUAGE); if (!setTranslator(outputLanguage)) @@ -10616,6 +10828,10 @@ static void stopDoxygen(int) { thisDir.remove(Doxygen::objDBFileName); } + if (!Doxygen::filterDBFileName.isEmpty()) + { + thisDir.remove(Doxygen::filterDBFileName); + } killpg(0,SIGINT); exit(1); } @@ -10716,6 +10932,10 @@ static void exitDoxygen() { thisDir.remove(Doxygen::objDBFileName); } + if (!Doxygen::filterDBFileName.isEmpty()) + { + thisDir.remove(Doxygen::filterDBFileName); + } } } @@ -10891,6 +11111,7 @@ void searchInputFiles() } s=inputList.next(); } + Doxygen::inputNameList->sort(); delete killDict; g_s.end(); } @@ -10955,6 +11176,8 @@ void parseInput() Doxygen::objDBFileName.prepend(outputDirectory+"/"); Doxygen::entryDBFileName.sprintf("doxygen_entrydb_%d.tmp",pid); Doxygen::entryDBFileName.prepend(outputDirectory+"/"); + Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid); + Doxygen::filterDBFileName.prepend(outputDirectory+"/"); if (Doxygen::symbolStorage->open(Doxygen::objDBFileName)==-1) { @@ -10965,7 +11188,7 @@ void parseInput() /************************************************************************** - * Check/create output directorties * + * Check/create output directories * **************************************************************************/ QCString htmlOutput; @@ -11068,9 +11291,20 @@ void parseInput() // Notice: the order of the function calls below is very important! - if (Config_getBool(GENERATE_HTML)) + if (Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX)) + { + readFormulaRepository(Config_getString(HTML_OUTPUT)); + } + if (Config_getBool(GENERATE_RTF)) + { + // in case GENERRATE_HTML is set we just have to compare, both repositories should be identical + readFormulaRepository(Config_getString(RTF_OUTPUT),Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX)); + } + if (Config_getBool(GENERATE_DOCBOOK)) { - readFormulaRepository(); + // in case GENERRATE_HTML is set we just have to compare, both repositories should be identical + readFormulaRepository(Config_getString(DOCBOOK_OUTPUT), + (Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX)) || Config_getBool(GENERATE_RTF)); } /************************************************************************** @@ -11190,6 +11424,17 @@ void parseInput() buildTypedefList(rootNav); g_s.end(); + if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + g_s.begin("Searching for documented sequences...\n"); + buildSequenceList(rootNav); + g_s.end(); + + g_s.begin("Searching for documented dictionaries...\n"); + buildDictionaryList(rootNav); + g_s.end(); + } + g_s.begin("Searching for members imported via using declarations...\n"); // this should be after buildTypedefList in order to properly import // used typedefs @@ -11419,6 +11664,7 @@ void generateOutput() bool generateLatex = Config_getBool(GENERATE_LATEX); bool generateMan = Config_getBool(GENERATE_MAN); bool generateRtf = Config_getBool(GENERATE_RTF); + bool generateDocbook = Config_getBool(GENERATE_DOCBOOK); g_outputList = new OutputList(TRUE); @@ -11446,6 +11692,11 @@ void generateOutput() g_outputList->add(new LatexGenerator); LatexGenerator::init(); } + if (generateDocbook) + { + g_outputList->add(new DocbookGenerator); + DocbookGenerator::init(); + } if (generateMan) { g_outputList->add(new ManGenerator); @@ -11472,6 +11723,7 @@ void generateOutput() if (generateHtml) writeDoxFont(Config_getString(HTML_OUTPUT)); if (generateLatex) writeDoxFont(Config_getString(LATEX_OUTPUT)); + if (generateDocbook) writeDoxFont(Config_getString(DOCBOOK_OUTPUT)); if (generateRtf) writeDoxFont(Config_getString(RTF_OUTPUT)); g_s.begin("Generating style sheet...\n"); @@ -11558,6 +11810,19 @@ void generateOutput() Doxygen::formulaList->generateBitmaps(Config_getString(HTML_OUTPUT)); g_s.end(); } + if (Doxygen::formulaList->count()>0 && generateRtf) + { + g_s.begin("Generating bitmaps for formulas in RTF...\n"); + Doxygen::formulaList->generateBitmaps(Config_getString(RTF_OUTPUT)); + g_s.end(); + } + + if (Doxygen::formulaList->count()>0 && generateDocbook) + { + g_s.begin("Generating bitmaps for formulas in Docbook...\n"); + Doxygen::formulaList->generateBitmaps(Config_getString(DOCBOOK_OUTPUT)); + g_s.end(); + } if (Config_getBool(SORT_GROUP_NAMES)) { @@ -11591,6 +11856,8 @@ void generateOutput() removeDoxFont(Config_getString(RTF_OUTPUT)); if (generateLatex) removeDoxFont(Config_getString(LATEX_OUTPUT)); + if (generateDocbook) + removeDoxFont(Config_getString(DOCBOOK_OUTPUT)); } if (Config_getBool(GENERATE_XML)) @@ -11608,13 +11875,6 @@ void generateOutput() g_s.end(); } - if (Config_getBool(GENERATE_DOCBOOK)) - { - g_s.begin("Generating Docbook output...\n"); - generateDocbook(); - g_s.end(); - } - if (Config_getBool(GENERATE_AUTOGEN_DEF)) { g_s.begin("Generating AutoGen DEF output...\n"); @@ -11685,6 +11945,10 @@ void generateOutput() copyLogo(Config_getString(LATEX_OUTPUT)); copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT)); } + if (generateDocbook) + { + copyLogo(Config_getString(DOCBOOK_OUTPUT)); + } if (generateRtf) { copyLogo(Config_getString(RTF_OUTPUT)); @@ -11763,6 +12027,7 @@ void generateOutput() Doxygen::symbolStorage->close(); QDir thisDir; thisDir.remove(Doxygen::objDBFileName); + thisDir.remove(Doxygen::filterDBFileName); Config::deinit(); QTextCodec::deleteAllCodecs(); delete Doxygen::symbolMap; diff --git a/src/doxygen.h b/src/doxygen.h index b3467c1..4ff8a56 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -140,6 +140,7 @@ class Doxygen static Store *symbolStorage; static QCString objDBFileName; static QCString entryDBFileName; + static QCString filterDBFileName; static CiteDict *citeDict; static bool gatherDefines; static bool userComments; @@ -159,7 +160,7 @@ void searchInputFiles(StringList &inputFiles); void parseInput(); void generateOutput(); void readAliases(); -void readFormulaRepository(); +void readFormulaRepository(QCString dir, bool cmp = FALSE); void cleanUpDoxygen(); int readFileOrDirectory(const char *s, FileNameList *fnList, diff --git a/src/doxygen.md b/src/doxygen.md index ccb47b9..17144ec 100644 --- a/src/doxygen.md +++ b/src/doxygen.md @@ -9,7 +9,7 @@ links to the relevant parts of the code. This document is intended for developers who want to work on doxygen. Users of doxygen are referred to the [User Manual](http://www.doxygen.org/manual.html). -The generic starting point of the application is of cource the main() function. +The generic starting point of the application is of course the main() function. Configuration options --------------------- diff --git a/src/emoji.cpp b/src/emoji.cpp new file mode 100644 index 0000000..c332083 --- /dev/null +++ b/src/emoji.cpp @@ -0,0 +1,1599 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2018 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 "emoji.h" +#include "message.h" +#include "ftextstream.h" +#include "util.h" + +static struct emojiEntityInfo +{ + const char *name; + const char *unicode; +} g_emojiEntities[] = +/* generated using the download_github_emojis.py script */ +{ + { ":+1:", "👍" }, + { ":-1:", "👎" }, + { ":100:", "💯" }, + { ":1234:", "🔢" }, + { ":1st_place_medal:", "🥇" }, + { ":2nd_place_medal:", "🥈" }, + { ":3rd_place_medal:", "🥉" }, + { ":8ball:", "🎱" }, + { ":a:", "🅰" }, + { ":ab:", "🆎" }, + { ":abc:", "🔤" }, + { ":abcd:", "🔡" }, + { ":accept:", "🉑" }, + { ":aerial_tramway:", "🚡" }, + { ":afghanistan:", "🇦🇫" }, + { ":airplane:", "✈" }, + { ":aland_islands:", "🇦🇽" }, + { ":alarm_clock:", "⏰" }, + { ":albania:", "🇦🇱" }, + { ":alembic:", "⚗" }, + { ":algeria:", "🇩🇿" }, + { ":alien:", "👽" }, + { ":ambulance:", "🚑" }, + { ":american_samoa:", "🇦🇸" }, + { ":amphora:", "🏺" }, + { ":anchor:", "⚓" }, + { ":andorra:", "🇦🇩" }, + { ":angel:", "👼" }, + { ":anger:", "💢" }, + { ":angola:", "🇦🇴" }, + { ":angry:", "😠" }, + { ":anguilla:", "🇦🇮" }, + { ":anguished:", "😧" }, + { ":ant:", "🐜" }, + { ":antarctica:", "🇦🇶" }, + { ":antigua_barbuda:", "🇦🇬" }, + { ":apple:", "🍎" }, + { ":aquarius:", "♒" }, + { ":argentina:", "🇦🇷" }, + { ":aries:", "♈" }, + { ":armenia:", "🇦🇲" }, + { ":arrow_backward:", "◀" }, + { ":arrow_double_down:", "⏬" }, + { ":arrow_double_up:", "⏫" }, + { ":arrow_down:", "⬇" }, + { ":arrow_down_small:", "🔽" }, + { ":arrow_forward:", "▶" }, + { ":arrow_heading_down:", "⤵" }, + { ":arrow_heading_up:", "⤴" }, + { ":arrow_left:", "⬅" }, + { ":arrow_lower_left:", "↙" }, + { ":arrow_lower_right:", "↘" }, + { ":arrow_right:", "➡" }, + { ":arrow_right_hook:", "↪" }, + { ":arrow_up:", "⬆" }, + { ":arrow_up_down:", "↕" }, + { ":arrow_up_small:", "🔼" }, + { ":arrow_upper_left:", "↖" }, + { ":arrow_upper_right:", "↗" }, + { ":arrows_clockwise:", "🔃" }, + { ":arrows_counterclockwise:", "🔄" }, + { ":art:", "🎨" }, + { ":articulated_lorry:", "🚛" }, + { ":artificial_satellite:", "🛰" }, + { ":aruba:", "🇦🇼" }, + { ":asterisk:", "*⃣" }, + { ":astonished:", "😲" }, + { ":athletic_shoe:", "👟" }, + { ":atm:", "🏧" }, + { ":atom_symbol:", "⚛" }, + { ":australia:", "🇦🇺" }, + { ":austria:", "🇦🇹" }, + { ":avocado:", "🥑" }, + { ":azerbaijan:", "🇦🇿" }, + { ":b:", "🅱" }, + { ":baby:", "👶" }, + { ":baby_bottle:", "🍼" }, + { ":baby_chick:", "🐤" }, + { ":baby_symbol:", "🚼" }, + { ":back:", "🔙" }, + { ":bacon:", "🥓" }, + { ":badminton:", "🏸" }, + { ":baggage_claim:", "🛄" }, + { ":baguette_bread:", "🥖" }, + { ":bahamas:", "🇧🇸" }, + { ":bahrain:", "🇧🇭" }, + { ":balance_scale:", "⚖" }, + { ":balloon:", "🎈" }, + { ":ballot_box:", "🗳" }, + { ":ballot_box_with_check:", "☑" }, + { ":bamboo:", "🎍" }, + { ":banana:", "🍌" }, + { ":bangbang:", "‼" }, + { ":bangladesh:", "🇧🇩" }, + { ":bank:", "🏦" }, + { ":bar_chart:", "📊" }, + { ":barbados:", "🇧🇧" }, + { ":barber:", "💈" }, + { ":baseball:", "⚾" }, + { ":basketball:", "🏀" }, + { ":basketball_man:", "⛹" }, + { ":basketball_woman:", "⛹♀" }, + { ":bat:", "🦇" }, + { ":bath:", "🛀" }, + { ":bathtub:", "🛁" }, + { ":battery:", "🔋" }, + { ":beach_umbrella:", "🏖" }, + { ":bear:", "🐻" }, + { ":bed:", "🛏" }, + { ":bee:", "🐝" }, + { ":beer:", "🍺" }, + { ":beers:", "🍻" }, + { ":beetle:", "🐞" }, + { ":beginner:", "🔰" }, + { ":belarus:", "🇧🇾" }, + { ":belgium:", "🇧🇪" }, + { ":belize:", "🇧🇿" }, + { ":bell:", "🔔" }, + { ":bellhop_bell:", "🛎" }, + { ":benin:", "🇧🇯" }, + { ":bento:", "🍱" }, + { ":bermuda:", "🇧🇲" }, + { ":bhutan:", "🇧🇹" }, + { ":bicyclist:", "🚴" }, + { ":bike:", "🚲" }, + { ":biking_man:", "🚴" }, + { ":biking_woman:", "🚴♀" }, + { ":bikini:", "👙" }, + { ":biohazard:", "☣" }, + { ":bird:", "🐦" }, + { ":birthday:", "🎂" }, + { ":black_circle:", "⚫" }, + { ":black_flag:", "🏴" }, + { ":black_heart:", "🖤" }, + { ":black_joker:", "🃏" }, + { ":black_large_square:", "⬛" }, + { ":black_medium_small_square:", "◾" }, + { ":black_medium_square:", "◼" }, + { ":black_nib:", "✒" }, + { ":black_small_square:", "▪" }, + { ":black_square_button:", "🔲" }, + { ":blonde_man:", "👱" }, + { ":blonde_woman:", "👱♀" }, + { ":blossom:", "🌼" }, + { ":blowfish:", "🐡" }, + { ":blue_book:", "📘" }, + { ":blue_car:", "🚙" }, + { ":blue_heart:", "💙" }, + { ":blush:", "😊" }, + { ":boar:", "🐗" }, + { ":boat:", "⛵" }, + { ":bolivia:", "🇧🇴" }, + { ":bomb:", "💣" }, + { ":book:", "📖" }, + { ":bookmark:", "🔖" }, + { ":bookmark_tabs:", "📑" }, + { ":books:", "📚" }, + { ":boom:", "💥" }, + { ":boot:", "👢" }, + { ":bosnia_herzegovina:", "🇧🇦" }, + { ":botswana:", "🇧🇼" }, + { ":bouquet:", "💐" }, + { ":bow:", "🙇" }, + { ":bow_and_arrow:", "🏹" }, + { ":bowing_man:", "🙇" }, + { ":bowing_woman:", "🙇♀" }, + { ":bowling:", "🎳" }, + { ":boxing_glove:", "🥊" }, + { ":boy:", "👦" }, + { ":brazil:", "🇧🇷" }, + { ":bread:", "🍞" }, + { ":bride_with_veil:", "👰" }, + { ":bridge_at_night:", "🌉" }, + { ":briefcase:", "💼" }, + { ":british_indian_ocean_territory:", "🇮🇴" }, + { ":british_virgin_islands:", "🇻🇬" }, + { ":broken_heart:", "💔" }, + { ":brunei:", "🇧🇳" }, + { ":bug:", "🐛" }, + { ":building_construction:", "🏗" }, + { ":bulb:", "💡" }, + { ":bulgaria:", "🇧🇬" }, + { ":bullettrain_front:", "🚅" }, + { ":bullettrain_side:", "🚄" }, + { ":burkina_faso:", "🇧🇫" }, + { ":burrito:", "🌯" }, + { ":burundi:", "🇧🇮" }, + { ":bus:", "🚌" }, + { ":business_suit_levitating:", "🕴" }, + { ":busstop:", "🚏" }, + { ":bust_in_silhouette:", "👤" }, + { ":busts_in_silhouette:", "👥" }, + { ":butterfly:", "🦋" }, + { ":cactus:", "🌵" }, + { ":cake:", "🍰" }, + { ":calendar:", "📆" }, + { ":call_me_hand:", "🤙" }, + { ":calling:", "📲" }, + { ":cambodia:", "🇰🇭" }, + { ":camel:", "🐫" }, + { ":camera:", "📷" }, + { ":camera_flash:", "📸" }, + { ":cameroon:", "🇨🇲" }, + { ":camping:", "🏕" }, + { ":canada:", "🇨🇦" }, + { ":canary_islands:", "🇮🇨" }, + { ":cancer:", "♋" }, + { ":candle:", "🕯" }, + { ":candy:", "🍬" }, + { ":canoe:", "🛶" }, + { ":cape_verde:", "🇨🇻" }, + { ":capital_abcd:", "🔠" }, + { ":capricorn:", "♑" }, + { ":car:", "🚗" }, + { ":card_file_box:", "🗃" }, + { ":card_index:", "📇" }, + { ":card_index_dividers:", "🗂" }, + { ":caribbean_netherlands:", "🇧🇶" }, + { ":carousel_horse:", "🎠" }, + { ":carrot:", "🥕" }, + { ":cat:", "🐱" }, + { ":cat2:", "🐈" }, + { ":cayman_islands:", "🇰🇾" }, + { ":cd:", "💿" }, + { ":central_african_republic:", "🇨🇫" }, + { ":chad:", "🇹🇩" }, + { ":chains:", "⛓" }, + { ":champagne:", "🍾" }, + { ":chart:", "💹" }, + { ":chart_with_downwards_trend:", "📉" }, + { ":chart_with_upwards_trend:", "📈" }, + { ":checkered_flag:", "🏁" }, + { ":cheese:", "🧀" }, + { ":cherries:", "🍒" }, + { ":cherry_blossom:", "🌸" }, + { ":chestnut:", "🌰" }, + { ":chicken:", "🐔" }, + { ":children_crossing:", "🚸" }, + { ":chile:", "🇨🇱" }, + { ":chipmunk:", "🐿" }, + { ":chocolate_bar:", "🍫" }, + { ":christmas_island:", "🇨🇽" }, + { ":christmas_tree:", "🎄" }, + { ":church:", "⛪" }, + { ":cinema:", "🎦" }, + { ":circus_tent:", "🎪" }, + { ":city_sunrise:", "🌇" }, + { ":city_sunset:", "🌆" }, + { ":cityscape:", "🏙" }, + { ":cl:", "🆑" }, + { ":clamp:", "🗜" }, + { ":clap:", "👏" }, + { ":clapper:", "🎬" }, + { ":classical_building:", "🏛" }, + { ":clinking_glasses:", "🥂" }, + { ":clipboard:", "📋" }, + { ":clock1:", "🕐" }, + { ":clock10:", "🕙" }, + { ":clock1030:", "🕥" }, + { ":clock11:", "🕚" }, + { ":clock1130:", "🕦" }, + { ":clock12:", "🕛" }, + { ":clock1230:", "🕧" }, + { ":clock130:", "🕜" }, + { ":clock2:", "🕑" }, + { ":clock230:", "🕝" }, + { ":clock3:", "🕒" }, + { ":clock330:", "🕞" }, + { ":clock4:", "🕓" }, + { ":clock430:", "🕟" }, + { ":clock5:", "🕔" }, + { ":clock530:", "🕠" }, + { ":clock6:", "🕕" }, + { ":clock630:", "🕡" }, + { ":clock7:", "🕖" }, + { ":clock730:", "🕢" }, + { ":clock8:", "🕗" }, + { ":clock830:", "🕣" }, + { ":clock9:", "🕘" }, + { ":clock930:", "🕤" }, + { ":closed_book:", "📕" }, + { ":closed_lock_with_key:", "🔐" }, + { ":closed_umbrella:", "🌂" }, + { ":cloud:", "☁" }, + { ":cloud_with_lightning:", "🌩" }, + { ":cloud_with_lightning_and_rain:", "⛈" }, + { ":cloud_with_rain:", "🌧" }, + { ":cloud_with_snow:", "🌨" }, + { ":clown_face:", "🤡" }, + { ":clubs:", "♣" }, + { ":cn:", "🇨🇳" }, + { ":cocktail:", "🍸" }, + { ":cocos_islands:", "🇨🇨" }, + { ":coffee:", "☕" }, + { ":coffin:", "⚰" }, + { ":cold_sweat:", "😰" }, + { ":collision:", "💥" }, + { ":colombia:", "🇨🇴" }, + { ":comet:", "☄" }, + { ":comoros:", "🇰🇲" }, + { ":computer:", "💻" }, + { ":computer_mouse:", "🖱" }, + { ":confetti_ball:", "🎊" }, + { ":confounded:", "😖" }, + { ":confused:", "😕" }, + { ":congo_brazzaville:", "🇨🇬" }, + { ":congo_kinshasa:", "🇨🇩" }, + { ":congratulations:", "㊗" }, + { ":construction:", "🚧" }, + { ":construction_worker:", "👷" }, + { ":construction_worker_man:", "👷" }, + { ":construction_worker_woman:", "👷♀" }, + { ":control_knobs:", "🎛" }, + { ":convenience_store:", "🏪" }, + { ":cook_islands:", "🇨🇰" }, + { ":cookie:", "🍪" }, + { ":cool:", "🆒" }, + { ":cop:", "👮" }, + { ":copyright:", "©" }, + { ":corn:", "🌽" }, + { ":costa_rica:", "🇨🇷" }, + { ":cote_divoire:", "🇨🇮" }, + { ":couch_and_lamp:", "🛋" }, + { ":couple:", "👫" }, + { ":couple_with_heart:", "💑" }, + { ":couple_with_heart_man_man:", "👨❤👨" }, + { ":couple_with_heart_woman_man:", "💑" }, + { ":couple_with_heart_woman_woman:", "👩❤👩" }, + { ":couplekiss_man_man:", "👨❤💋👨" }, + { ":couplekiss_man_woman:", "💏" }, + { ":couplekiss_woman_woman:", "👩❤💋👩" }, + { ":cow:", "🐮" }, + { ":cow2:", "🐄" }, + { ":cowboy_hat_face:", "🤠" }, + { ":crab:", "🦀" }, + { ":crayon:", "🖍" }, + { ":credit_card:", "💳" }, + { ":crescent_moon:", "🌙" }, + { ":cricket:", "🏏" }, + { ":croatia:", "🇭🇷" }, + { ":crocodile:", "🐊" }, + { ":croissant:", "🥐" }, + { ":crossed_fingers:", "🤞" }, + { ":crossed_flags:", "🎌" }, + { ":crossed_swords:", "⚔" }, + { ":crown:", "👑" }, + { ":cry:", "😢" }, + { ":crying_cat_face:", "😿" }, + { ":crystal_ball:", "🔮" }, + { ":cuba:", "🇨🇺" }, + { ":cucumber:", "🥒" }, + { ":cupid:", "💘" }, + { ":curacao:", "🇨🇼" }, + { ":curly_loop:", "➰" }, + { ":currency_exchange:", "💱" }, + { ":curry:", "🍛" }, + { ":custard:", "🍮" }, + { ":customs:", "🛃" }, + { ":cyclone:", "🌀" }, + { ":cyprus:", "🇨🇾" }, + { ":czech_republic:", "🇨🇿" }, + { ":dagger:", "🗡" }, + { ":dancer:", "💃" }, + { ":dancers:", "👯" }, + { ":dancing_men:", "👯♂" }, + { ":dancing_women:", "👯" }, + { ":dango:", "🍡" }, + { ":dark_sunglasses:", "🕶" }, + { ":dart:", "🎯" }, + { ":dash:", "💨" }, + { ":date:", "📅" }, + { ":de:", "🇩🇪" }, + { ":deciduous_tree:", "🌳" }, + { ":deer:", "🦌" }, + { ":denmark:", "🇩🇰" }, + { ":department_store:", "🏬" }, + { ":derelict_house:", "🏚" }, + { ":desert:", "🏜" }, + { ":desert_island:", "🏝" }, + { ":desktop_computer:", "🖥" }, + { ":detective:", "🕵" }, + { ":diamond_shape_with_a_dot_inside:", "💠" }, + { ":diamonds:", "♦" }, + { ":disappointed:", "😞" }, + { ":disappointed_relieved:", "😥" }, + { ":dizzy:", "💫" }, + { ":dizzy_face:", "😵" }, + { ":djibouti:", "🇩🇯" }, + { ":do_not_litter:", "🚯" }, + { ":dog:", "🐶" }, + { ":dog2:", "🐕" }, + { ":dollar:", "💵" }, + { ":dolls:", "🎎" }, + { ":dolphin:", "🐬" }, + { ":dominica:", "🇩🇲" }, + { ":dominican_republic:", "🇩🇴" }, + { ":door:", "🚪" }, + { ":doughnut:", "🍩" }, + { ":dove:", "🕊" }, + { ":dragon:", "🐉" }, + { ":dragon_face:", "🐲" }, + { ":dress:", "👗" }, + { ":dromedary_camel:", "🐪" }, + { ":drooling_face:", "🤤" }, + { ":droplet:", "💧" }, + { ":drum:", "🥁" }, + { ":duck:", "🦆" }, + { ":dvd:", "📀" }, + { ":e-mail:", "📧" }, + { ":eagle:", "🦅" }, + { ":ear:", "👂" }, + { ":ear_of_rice:", "🌾" }, + { ":earth_africa:", "🌍" }, + { ":earth_americas:", "🌎" }, + { ":earth_asia:", "🌏" }, + { ":ecuador:", "🇪🇨" }, + { ":egg:", "🥚" }, + { ":eggplant:", "🍆" }, + { ":egypt:", "🇪🇬" }, + { ":eight:", "8⃣" }, + { ":eight_pointed_black_star:", "✴" }, + { ":eight_spoked_asterisk:", "✳" }, + { ":el_salvador:", "🇸🇻" }, + { ":electric_plug:", "🔌" }, + { ":elephant:", "🐘" }, + { ":email:", "✉" }, + { ":end:", "🔚" }, + { ":envelope:", "✉" }, + { ":envelope_with_arrow:", "📩" }, + { ":equatorial_guinea:", "🇬🇶" }, + { ":eritrea:", "🇪🇷" }, + { ":es:", "🇪🇸" }, + { ":estonia:", "🇪🇪" }, + { ":ethiopia:", "🇪🇹" }, + { ":eu:", "🇪🇺" }, + { ":euro:", "💶" }, + { ":european_castle:", "🏰" }, + { ":european_post_office:", "🏤" }, + { ":european_union:", "🇪🇺" }, + { ":evergreen_tree:", "🌲" }, + { ":exclamation:", "❗" }, + { ":expressionless:", "😑" }, + { ":eye:", "👁" }, + { ":eye_speech_bubble:", "👁🗨" }, + { ":eyeglasses:", "👓" }, + { ":eyes:", "👀" }, + { ":face_with_head_bandage:", "🤕" }, + { ":face_with_thermometer:", "🤒" }, + { ":facepunch:", "👊" }, + { ":factory:", "🏭" }, + { ":falkland_islands:", "🇫🇰" }, + { ":fallen_leaf:", "🍂" }, + { ":family:", "👪" }, + { ":family_man_boy:", "👨👦" }, + { ":family_man_boy_boy:", "👨👦👦" }, + { ":family_man_girl:", "👨👧" }, + { ":family_man_girl_boy:", "👨👧👦" }, + { ":family_man_girl_girl:", "👨👧👧" }, + { ":family_man_man_boy:", "👨👨👦" }, + { ":family_man_man_boy_boy:", "👨👨👦👦" }, + { ":family_man_man_girl:", "👨👨👧" }, + { ":family_man_man_girl_boy:", "👨👨👧👦" }, + { ":family_man_man_girl_girl:", "👨👨👧👧" }, + { ":family_man_woman_boy:", "👪" }, + { ":family_man_woman_boy_boy:", "👨👩👦👦" }, + { ":family_man_woman_girl:", "👨👩👧" }, + { ":family_man_woman_girl_boy:", "👨👩👧👦" }, + { ":family_man_woman_girl_girl:", "👨👩👧👧" }, + { ":family_woman_boy:", "👩👦" }, + { ":family_woman_boy_boy:", "👩👦👦" }, + { ":family_woman_girl:", "👩👧" }, + { ":family_woman_girl_boy:", "👩👧👦" }, + { ":family_woman_girl_girl:", "👩👧👧" }, + { ":family_woman_woman_boy:", "👩👩👦" }, + { ":family_woman_woman_boy_boy:", "👩👩👦👦" }, + { ":family_woman_woman_girl:", "👩👩👧" }, + { ":family_woman_woman_girl_boy:", "👩👩👧👦" }, + { ":family_woman_woman_girl_girl:", "👩👩👧👧" }, + { ":faroe_islands:", "🇫🇴" }, + { ":fast_forward:", "⏩" }, + { ":fax:", "📠" }, + { ":fearful:", "😨" }, + { ":feet:", "🐾" }, + { ":female_detective:", "🕵♀" }, + { ":ferris_wheel:", "🎡" }, + { ":ferry:", "⛴" }, + { ":field_hockey:", "🏑" }, + { ":fiji:", "🇫🇯" }, + { ":file_cabinet:", "🗄" }, + { ":file_folder:", "📁" }, + { ":film_projector:", "📽" }, + { ":film_strip:", "🎞" }, + { ":finland:", "🇫🇮" }, + { ":fire:", "🔥" }, + { ":fire_engine:", "🚒" }, + { ":fireworks:", "🎆" }, + { ":first_quarter_moon:", "🌓" }, + { ":first_quarter_moon_with_face:", "🌛" }, + { ":fish:", "🐟" }, + { ":fish_cake:", "🍥" }, + { ":fishing_pole_and_fish:", "🎣" }, + { ":fist:", "✊" }, + { ":fist_left:", "🤛" }, + { ":fist_oncoming:", "👊" }, + { ":fist_raised:", "✊" }, + { ":fist_right:", "🤜" }, + { ":five:", "5⃣" }, + { ":flags:", "🎏" }, + { ":flashlight:", "🔦" }, + { ":fleur_de_lis:", "⚜" }, + { ":flight_arrival:", "🛬" }, + { ":flight_departure:", "🛫" }, + { ":flipper:", "🐬" }, + { ":floppy_disk:", "💾" }, + { ":flower_playing_cards:", "🎴" }, + { ":flushed:", "😳" }, + { ":fog:", "🌫" }, + { ":foggy:", "🌁" }, + { ":football:", "🏈" }, + { ":footprints:", "👣" }, + { ":fork_and_knife:", "🍴" }, + { ":fountain:", "⛲" }, + { ":fountain_pen:", "🖋" }, + { ":four:", "4⃣" }, + { ":four_leaf_clover:", "🍀" }, + { ":fox_face:", "🦊" }, + { ":fr:", "🇫🇷" }, + { ":framed_picture:", "🖼" }, + { ":free:", "🆓" }, + { ":french_guiana:", "🇬🇫" }, + { ":french_polynesia:", "🇵🇫" }, + { ":french_southern_territories:", "🇹🇫" }, + { ":fried_egg:", "🍳" }, + { ":fried_shrimp:", "🍤" }, + { ":fries:", "🍟" }, + { ":frog:", "🐸" }, + { ":frowning:", "😦" }, + { ":frowning_face:", "☹" }, + { ":frowning_man:", "🙍♂" }, + { ":frowning_woman:", "🙍" }, + { ":fu:", "🖕" }, + { ":fuelpump:", "⛽" }, + { ":full_moon:", "🌕" }, + { ":full_moon_with_face:", "🌝" }, + { ":funeral_urn:", "⚱" }, + { ":gabon:", "🇬🇦" }, + { ":gambia:", "🇬🇲" }, + { ":game_die:", "🎲" }, + { ":gb:", "🇬🇧" }, + { ":gear:", "⚙" }, + { ":gem:", "💎" }, + { ":gemini:", "♊" }, + { ":georgia:", "🇬🇪" }, + { ":ghana:", "🇬🇭" }, + { ":ghost:", "👻" }, + { ":gibraltar:", "🇬🇮" }, + { ":gift:", "🎁" }, + { ":gift_heart:", "💝" }, + { ":girl:", "👧" }, + { ":globe_with_meridians:", "🌐" }, + { ":goal_net:", "🥅" }, + { ":goat:", "🐐" }, + { ":golf:", "⛳" }, + { ":golfing_man:", "🏌" }, + { ":golfing_woman:", "🏌♀" }, + { ":gorilla:", "🦍" }, + { ":grapes:", "🍇" }, + { ":greece:", "🇬🇷" }, + { ":green_apple:", "🍏" }, + { ":green_book:", "📗" }, + { ":green_heart:", "💚" }, + { ":green_salad:", "🥗" }, + { ":greenland:", "🇬🇱" }, + { ":grenada:", "🇬🇩" }, + { ":grey_exclamation:", "❕" }, + { ":grey_question:", "❔" }, + { ":grimacing:", "😬" }, + { ":grin:", "😁" }, + { ":grinning:", "😀" }, + { ":guadeloupe:", "🇬🇵" }, + { ":guam:", "🇬🇺" }, + { ":guardsman:", "💂" }, + { ":guardswoman:", "💂♀" }, + { ":guatemala:", "🇬🇹" }, + { ":guernsey:", "🇬🇬" }, + { ":guinea:", "🇬🇳" }, + { ":guinea_bissau:", "🇬🇼" }, + { ":guitar:", "🎸" }, + { ":gun:", "🔫" }, + { ":guyana:", "🇬🇾" }, + { ":haircut:", "💇" }, + { ":haircut_man:", "💇♂" }, + { ":haircut_woman:", "💇" }, + { ":haiti:", "🇭🇹" }, + { ":hamburger:", "🍔" }, + { ":hammer:", "🔨" }, + { ":hammer_and_pick:", "⚒" }, + { ":hammer_and_wrench:", "🛠" }, + { ":hamster:", "🐹" }, + { ":hand:", "✋" }, + { ":handbag:", "👜" }, + { ":handshake:", "🤝" }, + { ":hankey:", "💩" }, + { ":hash:", "#⃣" }, + { ":hatched_chick:", "🐥" }, + { ":hatching_chick:", "🐣" }, + { ":headphones:", "🎧" }, + { ":hear_no_evil:", "🙉" }, + { ":heart:", "❤" }, + { ":heart_decoration:", "💟" }, + { ":heart_eyes:", "😍" }, + { ":heart_eyes_cat:", "😻" }, + { ":heartbeat:", "💓" }, + { ":heartpulse:", "💗" }, + { ":hearts:", "♥" }, + { ":heavy_check_mark:", "✔" }, + { ":heavy_division_sign:", "➗" }, + { ":heavy_dollar_sign:", "💲" }, + { ":heavy_exclamation_mark:", "❗" }, + { ":heavy_heart_exclamation:", "❣" }, + { ":heavy_minus_sign:", "➖" }, + { ":heavy_multiplication_x:", "✖" }, + { ":heavy_plus_sign:", "➕" }, + { ":helicopter:", "🚁" }, + { ":herb:", "🌿" }, + { ":hibiscus:", "🌺" }, + { ":high_brightness:", "🔆" }, + { ":high_heel:", "👠" }, + { ":hocho:", "🔪" }, + { ":hole:", "🕳" }, + { ":honduras:", "🇭🇳" }, + { ":honey_pot:", "🍯" }, + { ":honeybee:", "🐝" }, + { ":hong_kong:", "🇭🇰" }, + { ":horse:", "🐴" }, + { ":horse_racing:", "🏇" }, + { ":hospital:", "🏥" }, + { ":hot_pepper:", "🌶" }, + { ":hotdog:", "🌭" }, + { ":hotel:", "🏨" }, + { ":hotsprings:", "♨" }, + { ":hourglass:", "⌛" }, + { ":hourglass_flowing_sand:", "⏳" }, + { ":house:", "🏠" }, + { ":house_with_garden:", "🏡" }, + { ":houses:", "🏘" }, + { ":hugs:", "🤗" }, + { ":hungary:", "🇭🇺" }, + { ":hushed:", "😯" }, + { ":ice_cream:", "🍨" }, + { ":ice_hockey:", "🏒" }, + { ":ice_skate:", "⛸" }, + { ":icecream:", "🍦" }, + { ":iceland:", "🇮🇸" }, + { ":id:", "🆔" }, + { ":ideograph_advantage:", "🉐" }, + { ":imp:", "👿" }, + { ":inbox_tray:", "📥" }, + { ":incoming_envelope:", "📨" }, + { ":india:", "🇮🇳" }, + { ":indonesia:", "🇮🇩" }, + { ":information_desk_person:", "💁" }, + { ":information_source:", "ℹ" }, + { ":innocent:", "😇" }, + { ":interrobang:", "⁉" }, + { ":iphone:", "📱" }, + { ":iran:", "🇮🇷" }, + { ":iraq:", "🇮🇶" }, + { ":ireland:", "🇮🇪" }, + { ":isle_of_man:", "🇮🇲" }, + { ":israel:", "🇮🇱" }, + { ":it:", "🇮🇹" }, + { ":izakaya_lantern:", "🏮" }, + { ":jack_o_lantern:", "🎃" }, + { ":jamaica:", "🇯🇲" }, + { ":japan:", "🗾" }, + { ":japanese_castle:", "🏯" }, + { ":japanese_goblin:", "👺" }, + { ":japanese_ogre:", "👹" }, + { ":jeans:", "👖" }, + { ":jersey:", "🇯🇪" }, + { ":jordan:", "🇯🇴" }, + { ":joy:", "😂" }, + { ":joy_cat:", "😹" }, + { ":joystick:", "🕹" }, + { ":jp:", "🇯🇵" }, + { ":kaaba:", "🕋" }, + { ":kazakhstan:", "🇰🇿" }, + { ":kenya:", "🇰🇪" }, + { ":key:", "🔑" }, + { ":keyboard:", "⌨" }, + { ":keycap_ten:", "🔟" }, + { ":kick_scooter:", "🛴" }, + { ":kimono:", "👘" }, + { ":kiribati:", "🇰🇮" }, + { ":kiss:", "💋" }, + { ":kissing:", "😗" }, + { ":kissing_cat:", "😽" }, + { ":kissing_closed_eyes:", "😚" }, + { ":kissing_heart:", "😘" }, + { ":kissing_smiling_eyes:", "😙" }, + { ":kiwi_fruit:", "🥝" }, + { ":knife:", "🔪" }, + { ":koala:", "🐨" }, + { ":koko:", "🈁" }, + { ":kosovo:", "🇽🇰" }, + { ":kr:", "🇰🇷" }, + { ":kuwait:", "🇰🇼" }, + { ":kyrgyzstan:", "🇰🇬" }, + { ":label:", "🏷" }, + { ":lantern:", "🏮" }, + { ":laos:", "🇱🇦" }, + { ":large_blue_circle:", "🔵" }, + { ":large_blue_diamond:", "🔷" }, + { ":large_orange_diamond:", "🔶" }, + { ":last_quarter_moon:", "🌗" }, + { ":last_quarter_moon_with_face:", "🌜" }, + { ":latin_cross:", "✝" }, + { ":latvia:", "🇱🇻" }, + { ":laughing:", "😆" }, + { ":leaves:", "🍃" }, + { ":lebanon:", "🇱🇧" }, + { ":ledger:", "📒" }, + { ":left_luggage:", "🛅" }, + { ":left_right_arrow:", "↔" }, + { ":leftwards_arrow_with_hook:", "↩" }, + { ":lemon:", "🍋" }, + { ":leo:", "♌" }, + { ":leopard:", "🐆" }, + { ":lesotho:", "🇱🇸" }, + { ":level_slider:", "🎚" }, + { ":liberia:", "🇱🇷" }, + { ":libra:", "♎" }, + { ":libya:", "🇱🇾" }, + { ":liechtenstein:", "🇱🇮" }, + { ":light_rail:", "🚈" }, + { ":link:", "🔗" }, + { ":lion:", "🦁" }, + { ":lips:", "👄" }, + { ":lipstick:", "💄" }, + { ":lithuania:", "🇱🇹" }, + { ":lizard:", "🦎" }, + { ":lock:", "🔒" }, + { ":lock_with_ink_pen:", "🔏" }, + { ":lollipop:", "🍭" }, + { ":loop:", "➿" }, + { ":loud_sound:", "🔊" }, + { ":loudspeaker:", "📢" }, + { ":love_hotel:", "🏩" }, + { ":love_letter:", "💌" }, + { ":low_brightness:", "🔅" }, + { ":luxembourg:", "🇱🇺" }, + { ":lying_face:", "🤥" }, + { ":m:", "Ⓜ" }, + { ":macau:", "🇲🇴" }, + { ":macedonia:", "🇲🇰" }, + { ":madagascar:", "🇲🇬" }, + { ":mag:", "🔍" }, + { ":mag_right:", "🔎" }, + { ":mahjong:", "🀄" }, + { ":mailbox:", "📫" }, + { ":mailbox_closed:", "📪" }, + { ":mailbox_with_mail:", "📬" }, + { ":mailbox_with_no_mail:", "📭" }, + { ":malawi:", "🇲🇼" }, + { ":malaysia:", "🇲🇾" }, + { ":maldives:", "🇲🇻" }, + { ":male_detective:", "🕵" }, + { ":mali:", "🇲🇱" }, + { ":malta:", "🇲🇹" }, + { ":man:", "👨" }, + { ":man_artist:", "👨🎨" }, + { ":man_astronaut:", "👨🚀" }, + { ":man_cartwheeling:", "🤸♂" }, + { ":man_cook:", "👨🍳" }, + { ":man_dancing:", "🕺" }, + { ":man_facepalming:", "🤦♂" }, + { ":man_factory_worker:", "👨🏭" }, + { ":man_farmer:", "👨🌾" }, + { ":man_firefighter:", "👨🚒" }, + { ":man_health_worker:", "👨⚕" }, + { ":man_in_tuxedo:", "🤵" }, + { ":man_judge:", "👨⚖" }, + { ":man_juggling:", "🤹♂" }, + { ":man_mechanic:", "👨🔧" }, + { ":man_office_worker:", "👨💼" }, + { ":man_pilot:", "👨✈" }, + { ":man_playing_handball:", "🤾♂" }, + { ":man_playing_water_polo:", "🤽♂" }, + { ":man_scientist:", "👨🔬" }, + { ":man_shrugging:", "🤷♂" }, + { ":man_singer:", "👨🎤" }, + { ":man_student:", "👨🎓" }, + { ":man_teacher:", "👨🏫" }, + { ":man_technologist:", "👨💻" }, + { ":man_with_gua_pi_mao:", "👲" }, + { ":man_with_turban:", "👳" }, + { ":mandarin:", "🍊" }, + { ":mans_shoe:", "👞" }, + { ":mantelpiece_clock:", "🕰" }, + { ":maple_leaf:", "🍁" }, + { ":marshall_islands:", "🇲🇭" }, + { ":martial_arts_uniform:", "🥋" }, + { ":martinique:", "🇲🇶" }, + { ":mask:", "😷" }, + { ":massage:", "💆" }, + { ":massage_man:", "💆♂" }, + { ":massage_woman:", "💆" }, + { ":mauritania:", "🇲🇷" }, + { ":mauritius:", "🇲🇺" }, + { ":mayotte:", "🇾🇹" }, + { ":meat_on_bone:", "🍖" }, + { ":medal_military:", "🎖" }, + { ":medal_sports:", "🏅" }, + { ":mega:", "📣" }, + { ":melon:", "🍈" }, + { ":memo:", "📝" }, + { ":men_wrestling:", "🤼♂" }, + { ":menorah:", "🕎" }, + { ":mens:", "🚹" }, + { ":metal:", "🤘" }, + { ":metro:", "🚇" }, + { ":mexico:", "🇲🇽" }, + { ":micronesia:", "🇫🇲" }, + { ":microphone:", "🎤" }, + { ":microscope:", "🔬" }, + { ":middle_finger:", "🖕" }, + { ":milk_glass:", "🥛" }, + { ":milky_way:", "🌌" }, + { ":minibus:", "🚐" }, + { ":minidisc:", "💽" }, + { ":mobile_phone_off:", "📴" }, + { ":moldova:", "🇲🇩" }, + { ":monaco:", "🇲🇨" }, + { ":money_mouth_face:", "🤑" }, + { ":money_with_wings:", "💸" }, + { ":moneybag:", "💰" }, + { ":mongolia:", "🇲🇳" }, + { ":monkey:", "🐒" }, + { ":monkey_face:", "🐵" }, + { ":monorail:", "🚝" }, + { ":montenegro:", "🇲🇪" }, + { ":montserrat:", "🇲🇸" }, + { ":moon:", "🌔" }, + { ":morocco:", "🇲🇦" }, + { ":mortar_board:", "🎓" }, + { ":mosque:", "🕌" }, + { ":motor_boat:", "🛥" }, + { ":motor_scooter:", "🛵" }, + { ":motorcycle:", "🏍" }, + { ":motorway:", "🛣" }, + { ":mount_fuji:", "🗻" }, + { ":mountain:", "⛰" }, + { ":mountain_bicyclist:", "🚵" }, + { ":mountain_biking_man:", "🚵" }, + { ":mountain_biking_woman:", "🚵♀" }, + { ":mountain_cableway:", "🚠" }, + { ":mountain_railway:", "🚞" }, + { ":mountain_snow:", "🏔" }, + { ":mouse:", "🐭" }, + { ":mouse2:", "🐁" }, + { ":movie_camera:", "🎥" }, + { ":moyai:", "🗿" }, + { ":mozambique:", "🇲🇿" }, + { ":mrs_claus:", "🤶" }, + { ":muscle:", "💪" }, + { ":mushroom:", "🍄" }, + { ":musical_keyboard:", "🎹" }, + { ":musical_note:", "🎵" }, + { ":musical_score:", "🎼" }, + { ":mute:", "🔇" }, + { ":myanmar:", "🇲🇲" }, + { ":nail_care:", "💅" }, + { ":name_badge:", "📛" }, + { ":namibia:", "🇳🇦" }, + { ":national_park:", "🏞" }, + { ":nauru:", "🇳🇷" }, + { ":nauseated_face:", "🤢" }, + { ":necktie:", "👔" }, + { ":negative_squared_cross_mark:", "❎" }, + { ":nepal:", "🇳🇵" }, + { ":nerd_face:", "🤓" }, + { ":netherlands:", "🇳🇱" }, + { ":neutral_face:", "😐" }, + { ":new:", "🆕" }, + { ":new_caledonia:", "🇳🇨" }, + { ":new_moon:", "🌑" }, + { ":new_moon_with_face:", "🌚" }, + { ":new_zealand:", "🇳🇿" }, + { ":newspaper:", "📰" }, + { ":newspaper_roll:", "🗞" }, + { ":next_track_button:", "⏭" }, + { ":ng:", "🆖" }, + { ":ng_man:", "🙅♂" }, + { ":ng_woman:", "🙅" }, + { ":nicaragua:", "🇳🇮" }, + { ":niger:", "🇳🇪" }, + { ":nigeria:", "🇳🇬" }, + { ":night_with_stars:", "🌃" }, + { ":nine:", "9⃣" }, + { ":niue:", "🇳🇺" }, + { ":no_bell:", "🔕" }, + { ":no_bicycles:", "🚳" }, + { ":no_entry:", "⛔" }, + { ":no_entry_sign:", "🚫" }, + { ":no_good:", "🙅" }, + { ":no_good_man:", "🙅♂" }, + { ":no_good_woman:", "🙅" }, + { ":no_mobile_phones:", "📵" }, + { ":no_mouth:", "😶" }, + { ":no_pedestrians:", "🚷" }, + { ":no_smoking:", "🚭" }, + { ":non-potable_water:", "🚱" }, + { ":norfolk_island:", "🇳🇫" }, + { ":north_korea:", "🇰🇵" }, + { ":northern_mariana_islands:", "🇲🇵" }, + { ":norway:", "🇳🇴" }, + { ":nose:", "👃" }, + { ":notebook:", "📓" }, + { ":notebook_with_decorative_cover:", "📔" }, + { ":notes:", "🎶" }, + { ":nut_and_bolt:", "🔩" }, + { ":o:", "⭕" }, + { ":o2:", "🅾" }, + { ":ocean:", "🌊" }, + { ":octopus:", "🐙" }, + { ":oden:", "🍢" }, + { ":office:", "🏢" }, + { ":oil_drum:", "🛢" }, + { ":ok:", "🆗" }, + { ":ok_hand:", "👌" }, + { ":ok_man:", "🙆♂" }, + { ":ok_woman:", "🙆" }, + { ":old_key:", "🗝" }, + { ":older_man:", "👴" }, + { ":older_woman:", "👵" }, + { ":om:", "🕉" }, + { ":oman:", "🇴🇲" }, + { ":on:", "🔛" }, + { ":oncoming_automobile:", "🚘" }, + { ":oncoming_bus:", "🚍" }, + { ":oncoming_police_car:", "🚔" }, + { ":oncoming_taxi:", "🚖" }, + { ":one:", "1⃣" }, + { ":open_book:", "📖" }, + { ":open_file_folder:", "📂" }, + { ":open_hands:", "👐" }, + { ":open_mouth:", "😮" }, + { ":open_umbrella:", "☂" }, + { ":ophiuchus:", "⛎" }, + { ":orange:", "🍊" }, + { ":orange_book:", "📙" }, + { ":orthodox_cross:", "☦" }, + { ":outbox_tray:", "📤" }, + { ":owl:", "🦉" }, + { ":ox:", "🐂" }, + { ":package:", "📦" }, + { ":page_facing_up:", "📄" }, + { ":page_with_curl:", "📃" }, + { ":pager:", "📟" }, + { ":paintbrush:", "🖌" }, + { ":pakistan:", "🇵🇰" }, + { ":palau:", "🇵🇼" }, + { ":palestinian_territories:", "🇵🇸" }, + { ":palm_tree:", "🌴" }, + { ":panama:", "🇵🇦" }, + { ":pancakes:", "🥞" }, + { ":panda_face:", "🐼" }, + { ":paperclip:", "📎" }, + { ":paperclips:", "🖇" }, + { ":papua_new_guinea:", "🇵🇬" }, + { ":paraguay:", "🇵🇾" }, + { ":parasol_on_ground:", "⛱" }, + { ":parking:", "🅿" }, + { ":part_alternation_mark:", "〽" }, + { ":partly_sunny:", "⛅" }, + { ":passenger_ship:", "🛳" }, + { ":passport_control:", "🛂" }, + { ":pause_button:", "⏸" }, + { ":paw_prints:", "🐾" }, + { ":peace_symbol:", "☮" }, + { ":peach:", "🍑" }, + { ":peanuts:", "🥜" }, + { ":pear:", "🍐" }, + { ":pen:", "🖊" }, + { ":pencil:", "📝" }, + { ":pencil2:", "✏" }, + { ":penguin:", "🐧" }, + { ":pensive:", "😔" }, + { ":performing_arts:", "🎭" }, + { ":persevere:", "😣" }, + { ":person_fencing:", "🤺" }, + { ":person_frowning:", "🙍" }, + { ":person_with_blond_hair:", "👱" }, + { ":person_with_pouting_face:", "🙎" }, + { ":peru:", "🇵🇪" }, + { ":philippines:", "🇵🇭" }, + { ":phone:", "☎" }, + { ":pick:", "⛏" }, + { ":pig:", "🐷" }, + { ":pig2:", "🐖" }, + { ":pig_nose:", "🐽" }, + { ":pill:", "💊" }, + { ":pineapple:", "🍍" }, + { ":ping_pong:", "🏓" }, + { ":pisces:", "♓" }, + { ":pitcairn_islands:", "🇵🇳" }, + { ":pizza:", "🍕" }, + { ":place_of_worship:", "🛐" }, + { ":plate_with_cutlery:", "🍽" }, + { ":play_or_pause_button:", "⏯" }, + { ":point_down:", "👇" }, + { ":point_left:", "👈" }, + { ":point_right:", "👉" }, + { ":point_up:", "☝" }, + { ":point_up_2:", "👆" }, + { ":poland:", "🇵🇱" }, + { ":police_car:", "🚓" }, + { ":policeman:", "👮" }, + { ":policewoman:", "👮♀" }, + { ":poodle:", "🐩" }, + { ":poop:", "💩" }, + { ":popcorn:", "🍿" }, + { ":portugal:", "🇵🇹" }, + { ":post_office:", "🏣" }, + { ":postal_horn:", "📯" }, + { ":postbox:", "📮" }, + { ":potable_water:", "🚰" }, + { ":potato:", "🥔" }, + { ":pouch:", "👝" }, + { ":poultry_leg:", "🍗" }, + { ":pound:", "💷" }, + { ":pout:", "😡" }, + { ":pouting_cat:", "😾" }, + { ":pouting_man:", "🙎♂" }, + { ":pouting_woman:", "🙎" }, + { ":pray:", "🙏" }, + { ":prayer_beads:", "📿" }, + { ":pregnant_woman:", "🤰" }, + { ":previous_track_button:", "⏮" }, + { ":prince:", "🤴" }, + { ":princess:", "👸" }, + { ":printer:", "🖨" }, + { ":puerto_rico:", "🇵🇷" }, + { ":punch:", "👊" }, + { ":purple_heart:", "💜" }, + { ":purse:", "👛" }, + { ":pushpin:", "📌" }, + { ":put_litter_in_its_place:", "🚮" }, + { ":qatar:", "🇶🇦" }, + { ":question:", "❓" }, + { ":rabbit:", "🐰" }, + { ":rabbit2:", "🐇" }, + { ":racehorse:", "🐎" }, + { ":racing_car:", "🏎" }, + { ":radio:", "📻" }, + { ":radio_button:", "🔘" }, + { ":radioactive:", "☢" }, + { ":rage:", "😡" }, + { ":railway_car:", "🚃" }, + { ":railway_track:", "🛤" }, + { ":rainbow:", "🌈" }, + { ":rainbow_flag:", "🏳🌈" }, + { ":raised_back_of_hand:", "🤚" }, + { ":raised_hand:", "✋" }, + { ":raised_hand_with_fingers_splayed:", "🖐" }, + { ":raised_hands:", "🙌" }, + { ":raising_hand:", "🙋" }, + { ":raising_hand_man:", "🙋♂" }, + { ":raising_hand_woman:", "🙋" }, + { ":ram:", "🐏" }, + { ":ramen:", "🍜" }, + { ":rat:", "🐀" }, + { ":record_button:", "⏺" }, + { ":recycle:", "♻" }, + { ":red_car:", "🚗" }, + { ":red_circle:", "🔴" }, + { ":registered:", "®" }, + { ":relaxed:", "☺" }, + { ":relieved:", "😌" }, + { ":reminder_ribbon:", "🎗" }, + { ":repeat:", "🔁" }, + { ":repeat_one:", "🔂" }, + { ":rescue_worker_helmet:", "⛑" }, + { ":restroom:", "🚻" }, + { ":reunion:", "🇷🇪" }, + { ":revolving_hearts:", "💞" }, + { ":rewind:", "⏪" }, + { ":rhinoceros:", "🦏" }, + { ":ribbon:", "🎀" }, + { ":rice:", "🍚" }, + { ":rice_ball:", "🍙" }, + { ":rice_cracker:", "🍘" }, + { ":rice_scene:", "🎑" }, + { ":right_anger_bubble:", "🗯" }, + { ":ring:", "💍" }, + { ":robot:", "🤖" }, + { ":rocket:", "🚀" }, + { ":rofl:", "🤣" }, + { ":roll_eyes:", "🙄" }, + { ":roller_coaster:", "🎢" }, + { ":romania:", "🇷🇴" }, + { ":rooster:", "🐓" }, + { ":rose:", "🌹" }, + { ":rosette:", "🏵" }, + { ":rotating_light:", "🚨" }, + { ":round_pushpin:", "📍" }, + { ":rowboat:", "🚣" }, + { ":rowing_man:", "🚣" }, + { ":rowing_woman:", "🚣♀" }, + { ":ru:", "🇷🇺" }, + { ":rugby_football:", "🏉" }, + { ":runner:", "🏃" }, + { ":running:", "🏃" }, + { ":running_man:", "🏃" }, + { ":running_shirt_with_sash:", "🎽" }, + { ":running_woman:", "🏃♀" }, + { ":rwanda:", "🇷🇼" }, + { ":sa:", "🈂" }, + { ":sagittarius:", "♐" }, + { ":sailboat:", "⛵" }, + { ":sake:", "🍶" }, + { ":samoa:", "🇼🇸" }, + { ":san_marino:", "🇸🇲" }, + { ":sandal:", "👡" }, + { ":santa:", "🎅" }, + { ":sao_tome_principe:", "🇸🇹" }, + { ":satellite:", "📡" }, + { ":satisfied:", "😆" }, + { ":saudi_arabia:", "🇸🇦" }, + { ":saxophone:", "🎷" }, + { ":school:", "🏫" }, + { ":school_satchel:", "🎒" }, + { ":scissors:", "✂" }, + { ":scorpion:", "🦂" }, + { ":scorpius:", "♏" }, + { ":scream:", "😱" }, + { ":scream_cat:", "🙀" }, + { ":scroll:", "📜" }, + { ":seat:", "💺" }, + { ":secret:", "㊙" }, + { ":see_no_evil:", "🙈" }, + { ":seedling:", "🌱" }, + { ":selfie:", "🤳" }, + { ":senegal:", "🇸🇳" }, + { ":serbia:", "🇷🇸" }, + { ":seven:", "7⃣" }, + { ":seychelles:", "🇸🇨" }, + { ":shallow_pan_of_food:", "🥘" }, + { ":shamrock:", "☘" }, + { ":shark:", "🦈" }, + { ":shaved_ice:", "🍧" }, + { ":sheep:", "🐑" }, + { ":shell:", "🐚" }, + { ":shield:", "🛡" }, + { ":shinto_shrine:", "⛩" }, + { ":ship:", "🚢" }, + { ":shirt:", "👕" }, + { ":shit:", "💩" }, + { ":shoe:", "👞" }, + { ":shopping:", "🛍" }, + { ":shopping_cart:", "🛒" }, + { ":shower:", "🚿" }, + { ":shrimp:", "🦐" }, + { ":sierra_leone:", "🇸🇱" }, + { ":signal_strength:", "📶" }, + { ":singapore:", "🇸🇬" }, + { ":sint_maarten:", "🇸🇽" }, + { ":six:", "6⃣" }, + { ":six_pointed_star:", "🔯" }, + { ":ski:", "🎿" }, + { ":skier:", "⛷" }, + { ":skull:", "💀" }, + { ":skull_and_crossbones:", "☠" }, + { ":sleeping:", "😴" }, + { ":sleeping_bed:", "🛌" }, + { ":sleepy:", "😪" }, + { ":slightly_frowning_face:", "🙁" }, + { ":slightly_smiling_face:", "🙂" }, + { ":slot_machine:", "🎰" }, + { ":slovakia:", "🇸🇰" }, + { ":slovenia:", "🇸🇮" }, + { ":small_airplane:", "🛩" }, + { ":small_blue_diamond:", "🔹" }, + { ":small_orange_diamond:", "🔸" }, + { ":small_red_triangle:", "🔺" }, + { ":small_red_triangle_down:", "🔻" }, + { ":smile:", "😄" }, + { ":smile_cat:", "😸" }, + { ":smiley:", "😃" }, + { ":smiley_cat:", "😺" }, + { ":smiling_imp:", "😈" }, + { ":smirk:", "😏" }, + { ":smirk_cat:", "😼" }, + { ":smoking:", "🚬" }, + { ":snail:", "🐌" }, + { ":snake:", "🐍" }, + { ":sneezing_face:", "🤧" }, + { ":snowboarder:", "🏂" }, + { ":snowflake:", "❄" }, + { ":snowman:", "⛄" }, + { ":snowman_with_snow:", "☃" }, + { ":sob:", "😭" }, + { ":soccer:", "⚽" }, + { ":solomon_islands:", "🇸🇧" }, + { ":somalia:", "🇸🇴" }, + { ":soon:", "🔜" }, + { ":sos:", "🆘" }, + { ":sound:", "🔉" }, + { ":south_africa:", "🇿🇦" }, + { ":south_georgia_south_sandwich_islands:", "🇬🇸" }, + { ":south_sudan:", "🇸🇸" }, + { ":space_invader:", "👾" }, + { ":spades:", "♠" }, + { ":spaghetti:", "🍝" }, + { ":sparkle:", "❇" }, + { ":sparkler:", "🎇" }, + { ":sparkles:", "✨" }, + { ":sparkling_heart:", "💖" }, + { ":speak_no_evil:", "🙊" }, + { ":speaker:", "🔈" }, + { ":speaking_head:", "🗣" }, + { ":speech_balloon:", "💬" }, + { ":speedboat:", "🚤" }, + { ":spider:", "🕷" }, + { ":spider_web:", "🕸" }, + { ":spiral_calendar:", "🗓" }, + { ":spiral_notepad:", "🗒" }, + { ":spoon:", "🥄" }, + { ":squid:", "🦑" }, + { ":sri_lanka:", "🇱🇰" }, + { ":st_barthelemy:", "🇧🇱" }, + { ":st_helena:", "🇸🇭" }, + { ":st_kitts_nevis:", "🇰🇳" }, + { ":st_lucia:", "🇱🇨" }, + { ":st_pierre_miquelon:", "🇵🇲" }, + { ":st_vincent_grenadines:", "🇻🇨" }, + { ":stadium:", "🏟" }, + { ":star:", "⭐" }, + { ":star2:", "🌟" }, + { ":star_and_crescent:", "☪" }, + { ":star_of_david:", "✡" }, + { ":stars:", "🌠" }, + { ":station:", "🚉" }, + { ":statue_of_liberty:", "🗽" }, + { ":steam_locomotive:", "🚂" }, + { ":stew:", "🍲" }, + { ":stop_button:", "⏹" }, + { ":stop_sign:", "🛑" }, + { ":stopwatch:", "⏱" }, + { ":straight_ruler:", "📏" }, + { ":strawberry:", "🍓" }, + { ":stuck_out_tongue:", "😛" }, + { ":stuck_out_tongue_closed_eyes:", "😝" }, + { ":stuck_out_tongue_winking_eye:", "😜" }, + { ":studio_microphone:", "🎙" }, + { ":stuffed_flatbread:", "🥙" }, + { ":sudan:", "🇸🇩" }, + { ":sun_behind_large_cloud:", "🌥" }, + { ":sun_behind_rain_cloud:", "🌦" }, + { ":sun_behind_small_cloud:", "🌤" }, + { ":sun_with_face:", "🌞" }, + { ":sunflower:", "🌻" }, + { ":sunglasses:", "😎" }, + { ":sunny:", "☀" }, + { ":sunrise:", "🌅" }, + { ":sunrise_over_mountains:", "🌄" }, + { ":surfer:", "🏄" }, + { ":surfing_man:", "🏄" }, + { ":surfing_woman:", "🏄♀" }, + { ":suriname:", "🇸🇷" }, + { ":sushi:", "🍣" }, + { ":suspension_railway:", "🚟" }, + { ":swaziland:", "🇸🇿" }, + { ":sweat:", "😓" }, + { ":sweat_drops:", "💦" }, + { ":sweat_smile:", "😅" }, + { ":sweden:", "🇸🇪" }, + { ":sweet_potato:", "🍠" }, + { ":swimmer:", "🏊" }, + { ":swimming_man:", "🏊" }, + { ":swimming_woman:", "🏊♀" }, + { ":switzerland:", "🇨🇭" }, + { ":symbols:", "🔣" }, + { ":synagogue:", "🕍" }, + { ":syria:", "🇸🇾" }, + { ":syringe:", "💉" }, + { ":taco:", "🌮" }, + { ":tada:", "🎉" }, + { ":taiwan:", "🇹🇼" }, + { ":tajikistan:", "🇹🇯" }, + { ":tanabata_tree:", "🎋" }, + { ":tangerine:", "🍊" }, + { ":tanzania:", "🇹🇿" }, + { ":taurus:", "♉" }, + { ":taxi:", "🚕" }, + { ":tea:", "🍵" }, + { ":telephone:", "☎" }, + { ":telephone_receiver:", "📞" }, + { ":telescope:", "🔭" }, + { ":tennis:", "🎾" }, + { ":tent:", "⛺" }, + { ":thailand:", "🇹🇭" }, + { ":thermometer:", "🌡" }, + { ":thinking:", "🤔" }, + { ":thought_balloon:", "💭" }, + { ":three:", "3⃣" }, + { ":thumbsdown:", "👎" }, + { ":thumbsup:", "👍" }, + { ":ticket:", "🎫" }, + { ":tickets:", "🎟" }, + { ":tiger:", "🐯" }, + { ":tiger2:", "🐅" }, + { ":timer_clock:", "⏲" }, + { ":timor_leste:", "🇹🇱" }, + { ":tipping_hand_man:", "💁♂" }, + { ":tipping_hand_woman:", "💁" }, + { ":tired_face:", "😫" }, + { ":tm:", "™" }, + { ":togo:", "🇹🇬" }, + { ":toilet:", "🚽" }, + { ":tokelau:", "🇹🇰" }, + { ":tokyo_tower:", "🗼" }, + { ":tomato:", "🍅" }, + { ":tonga:", "🇹🇴" }, + { ":tongue:", "👅" }, + { ":top:", "🔝" }, + { ":tophat:", "🎩" }, + { ":tornado:", "🌪" }, + { ":tr:", "🇹🇷" }, + { ":trackball:", "🖲" }, + { ":tractor:", "🚜" }, + { ":traffic_light:", "🚥" }, + { ":train:", "🚋" }, + { ":train2:", "🚆" }, + { ":tram:", "🚊" }, + { ":triangular_flag_on_post:", "🚩" }, + { ":triangular_ruler:", "📐" }, + { ":trident:", "🔱" }, + { ":trinidad_tobago:", "🇹🇹" }, + { ":triumph:", "😤" }, + { ":trolleybus:", "🚎" }, + { ":trophy:", "🏆" }, + { ":tropical_drink:", "🍹" }, + { ":tropical_fish:", "🐠" }, + { ":truck:", "🚚" }, + { ":trumpet:", "🎺" }, + { ":tshirt:", "👕" }, + { ":tulip:", "🌷" }, + { ":tumbler_glass:", "🥃" }, + { ":tunisia:", "🇹🇳" }, + { ":turkey:", "🦃" }, + { ":turkmenistan:", "🇹🇲" }, + { ":turks_caicos_islands:", "🇹🇨" }, + { ":turtle:", "🐢" }, + { ":tuvalu:", "🇹🇻" }, + { ":tv:", "📺" }, + { ":twisted_rightwards_arrows:", "🔀" }, + { ":two:", "2⃣" }, + { ":two_hearts:", "💕" }, + { ":two_men_holding_hands:", "👬" }, + { ":two_women_holding_hands:", "👭" }, + { ":u5272:", "🈹" }, + { ":u5408:", "🈴" }, + { ":u55b6:", "🈺" }, + { ":u6307:", "🈯" }, + { ":u6708:", "🈷" }, + { ":u6709:", "🈶" }, + { ":u6e80:", "🈵" }, + { ":u7121:", "🈚" }, + { ":u7533:", "🈸" }, + { ":u7981:", "🈲" }, + { ":u7a7a:", "🈳" }, + { ":uganda:", "🇺🇬" }, + { ":uk:", "🇬🇧" }, + { ":ukraine:", "🇺🇦" }, + { ":umbrella:", "☔" }, + { ":unamused:", "😒" }, + { ":underage:", "🔞" }, + { ":unicorn:", "🦄" }, + { ":united_arab_emirates:", "🇦🇪" }, + { ":unlock:", "🔓" }, + { ":up:", "🆙" }, + { ":upside_down_face:", "🙃" }, + { ":uruguay:", "🇺🇾" }, + { ":us:", "🇺🇸" }, + { ":us_virgin_islands:", "🇻🇮" }, + { ":uzbekistan:", "🇺🇿" }, + { ":v:", "✌" }, + { ":vanuatu:", "🇻🇺" }, + { ":vatican_city:", "🇻🇦" }, + { ":venezuela:", "🇻🇪" }, + { ":vertical_traffic_light:", "🚦" }, + { ":vhs:", "📼" }, + { ":vibration_mode:", "📳" }, + { ":video_camera:", "📹" }, + { ":video_game:", "🎮" }, + { ":vietnam:", "🇻🇳" }, + { ":violin:", "🎻" }, + { ":virgo:", "♍" }, + { ":volcano:", "🌋" }, + { ":volleyball:", "🏐" }, + { ":vs:", "🆚" }, + { ":vulcan_salute:", "🖖" }, + { ":walking:", "🚶" }, + { ":walking_man:", "🚶" }, + { ":walking_woman:", "🚶♀" }, + { ":wallis_futuna:", "🇼🇫" }, + { ":waning_crescent_moon:", "🌘" }, + { ":waning_gibbous_moon:", "🌖" }, + { ":warning:", "⚠" }, + { ":wastebasket:", "🗑" }, + { ":watch:", "⌚" }, + { ":water_buffalo:", "🐃" }, + { ":watermelon:", "🍉" }, + { ":wave:", "👋" }, + { ":wavy_dash:", "〰" }, + { ":waxing_crescent_moon:", "🌒" }, + { ":waxing_gibbous_moon:", "🌔" }, + { ":wc:", "🚾" }, + { ":weary:", "😩" }, + { ":wedding:", "💒" }, + { ":weight_lifting_man:", "🏋" }, + { ":weight_lifting_woman:", "🏋♀" }, + { ":western_sahara:", "🇪🇭" }, + { ":whale:", "🐳" }, + { ":whale2:", "🐋" }, + { ":wheel_of_dharma:", "☸" }, + { ":wheelchair:", "♿" }, + { ":white_check_mark:", "✅" }, + { ":white_circle:", "⚪" }, + { ":white_flag:", "🏳" }, + { ":white_flower:", "💮" }, + { ":white_large_square:", "⬜" }, + { ":white_medium_small_square:", "◽" }, + { ":white_medium_square:", "◻" }, + { ":white_small_square:", "▫" }, + { ":white_square_button:", "🔳" }, + { ":wilted_flower:", "🥀" }, + { ":wind_chime:", "🎐" }, + { ":wind_face:", "🌬" }, + { ":wine_glass:", "🍷" }, + { ":wink:", "😉" }, + { ":wolf:", "🐺" }, + { ":woman:", "👩" }, + { ":woman_artist:", "👩🎨" }, + { ":woman_astronaut:", "👩🚀" }, + { ":woman_cartwheeling:", "🤸♀" }, + { ":woman_cook:", "👩🍳" }, + { ":woman_facepalming:", "🤦♀" }, + { ":woman_factory_worker:", "👩🏭" }, + { ":woman_farmer:", "👩🌾" }, + { ":woman_firefighter:", "👩🚒" }, + { ":woman_health_worker:", "👩⚕" }, + { ":woman_judge:", "👩⚖" }, + { ":woman_juggling:", "🤹♀" }, + { ":woman_mechanic:", "👩🔧" }, + { ":woman_office_worker:", "👩💼" }, + { ":woman_pilot:", "👩✈" }, + { ":woman_playing_handball:", "🤾♀" }, + { ":woman_playing_water_polo:", "🤽♀" }, + { ":woman_scientist:", "👩🔬" }, + { ":woman_shrugging:", "🤷♀" }, + { ":woman_singer:", "👩🎤" }, + { ":woman_student:", "👩🎓" }, + { ":woman_teacher:", "👩🏫" }, + { ":woman_technologist:", "👩💻" }, + { ":woman_with_turban:", "👳♀" }, + { ":womans_clothes:", "👚" }, + { ":womans_hat:", "👒" }, + { ":women_wrestling:", "🤼♀" }, + { ":womens:", "🚺" }, + { ":world_map:", "🗺" }, + { ":worried:", "😟" }, + { ":wrench:", "🔧" }, + { ":writing_hand:", "✍" }, + { ":x:", "❌" }, + { ":yellow_heart:", "💛" }, + { ":yemen:", "🇾🇪" }, + { ":yen:", "💴" }, + { ":yin_yang:", "☯" }, + { ":yum:", "😋" }, + { ":zambia:", "🇿🇲" }, + { ":zap:", "⚡" }, + { ":zero:", "0⃣" }, + { ":zimbabwe:", "🇿🇼" }, + { ":zipper_mouth_face:", "🤐" }, + { ":zzz:", "💤" } +}; + +static const int g_numEmojiEntities = (int)(sizeof(g_emojiEntities)/sizeof(*g_emojiEntities)); + +EmojiEntityMapper *EmojiEntityMapper::s_instance = 0; + +EmojiEntityMapper::EmojiEntityMapper() +{ + m_name2symGh = new QDict<int>(1009); + m_name2symGh->setAutoDelete(TRUE); + // 2 loops to be able to give precedence to the unicodeName (CLDR) + for (int i = 0; i < g_numEmojiEntities; i++) + { + m_name2symGh->insert(g_emojiEntities[i].name, new int(i)); + } +} + +EmojiEntityMapper::~EmojiEntityMapper() +{ + delete m_name2symGh; +} + +/** Returns the one and only instance of the Emoji entity mapper */ +EmojiEntityMapper *EmojiEntityMapper::instance() +{ + if (s_instance==0) + { + s_instance = new EmojiEntityMapper; + } + return s_instance; +} + +/** Deletes the one and only instance of the Emoji entity mapper */ +void EmojiEntityMapper::deleteInstance() +{ + delete s_instance; + s_instance=0; +} + +/*! + * @brief Returns a code for the requested Emoji entity name + * @param symName Emoji entity name + * @return the code for the requested Emoji entity name, + * in case the requested Emoji item does not exist `-1` is returned. + */ +int EmojiEntityMapper::symbol2index(const QCString &symName) const +{ + int *val = m_name2symGh->find(symName); + return val ? *val : -1; +} + +/*! + * @brief Writes the list of supported emojis to the given file. + */ +void EmojiEntityMapper::writeEmojiFile(QFile &file) +{ + FTextStream t(&file); + for (int i = 0; i < g_numEmojiEntities; i++) + { + t << g_emojiEntities[i].name << endl; + } +} + +/*! @brief Access routine to the unicode sequence for the Emoji entity + * + * @param symb code of the requested Emoji entity returned by symbol2index() + * @return the unicode sequence of the Emoji entity, + */ +const char *EmojiEntityMapper::unicode(int index) const +{ + return index>=0 && index<g_numEmojiEntities ? g_emojiEntities[index].unicode : 0; +} + +/*! @brief Access routine to the name of the Emoji entity + * + * @param symb code of the requested Emoji entity returned by symbol2index() + * @return the name of the Emoji entity in GitHub format (i.e. :smile:) + */ +const char *EmojiEntityMapper::name(int index) const +{ + return index>=0 && index<g_numEmojiEntities ? g_emojiEntities[index].name : 0; +} + + diff --git a/src/emoji.h b/src/emoji.h new file mode 100644 index 0000000..f24a2c0 --- /dev/null +++ b/src/emoji.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2018 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 EMOJIENTITY_H +#define EMOJIENTITY_H + +#include <qdict.h> +#include <qfile.h> + +class FTextStream; + +/** @brief Singleton helper class to map emoji entities to other formats */ +class EmojiEntityMapper +{ + public: + static EmojiEntityMapper *instance(); + static void deleteInstance(); + const char *name(int index) const; + const char *unicode(int index) const; + void writeEmojiFile(QFile &file); + int symbol2index(const QCString &symName) const; + + private: + EmojiEntityMapper(); + ~EmojiEntityMapper(); + static EmojiEntityMapper *s_instance; + QDict<int> *m_name2symGh; +}; + +#endif diff --git a/src/entry.cpp b/src/entry.cpp index 9d15ec8..b3693cd 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -73,11 +73,14 @@ Entry::Entry(const Entry &e) spec = e.spec; initLines = e.initLines; stat = e.stat; + localToc = e.localToc; explicitExternal = e.explicitExternal; proto = e.proto; subGrouping = e.subGrouping; callGraph = e.callGraph; callerGraph = e.callerGraph; + referencedByRelation = e.referencedByRelation; + referencesRelation = e.referencesRelation; virt = e.virt; args = e.args; bitfields = e.bitfields; @@ -167,7 +170,7 @@ Entry::Entry(const Entry &e) SectionInfo *s; for (;(s=sli2.current());++sli2) { - anchors->append(new SectionInfo(*s)); + anchors->append(s); // shallow copy, object are owned by Doxygen::sectionDict } // deep copy type constraint list @@ -218,6 +221,8 @@ void Entry::reset() { static bool entryCallGraph = Config_getBool(CALL_GRAPH); static bool entryCallerGraph = Config_getBool(CALLER_GRAPH); + static bool entryReferencedByRelation = Config_getBool(REFERENCED_BY_RELATION); + static bool entryReferencesRelation = Config_getBool(REFERENCES_RELATION); //printf("Entry::reset()\n"); name.resize(0); type.resize(0); @@ -249,6 +254,8 @@ void Entry::reset() mGrpId = -1; callGraph = entryCallGraph; callerGraph = entryCallerGraph; + referencedByRelation = entryReferencedByRelation; + referencesRelation = entryReferencesRelation; section = EMPTY_SEC; mtype = Method; virt = Normal; @@ -263,6 +270,7 @@ void Entry::reset() protection = Public; groupDocType = GROUPDOC_NORMAL; id.resize(0); + metaData.resize(0); m_sublist->clear(); extends->clear(); groups->clear(); diff --git a/src/entry.h b/src/entry.h index f1b81ef..44e47da 100644 --- a/src/entry.h +++ b/src/entry.h @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -33,21 +33,21 @@ class ArgumentList; struct ListItemInfo; /** This class stores information about an inheritance relation - */ -struct BaseInfo + */ +struct BaseInfo { /*! Creates an object representing an inheritance relation */ - BaseInfo(const char *n,Protection p,Specifier v) : + BaseInfo(const char *n,Protection p,Specifier v) : name(n),prot(p),virt(v) {} QCString name; //!< the name of the base class Protection prot; //!< inheritance type Specifier virt; //!< virtualness }; -/** This struct is used to capture the tag file information - * for an Entry. +/** This struct is used to capture the tag file information + * for an Entry. */ -struct TagInfo +struct TagInfo { QCString tagName; QCString fileName; @@ -55,7 +55,7 @@ struct TagInfo }; /** Represents an unstructured piece of information, about an - * entity found in the sources. + * entity found in the sources. * * parseMain() in scanner.l will generate a tree of these * entries. @@ -65,13 +65,13 @@ class Entry public: /*! Kind of entries that are supported */ - enum Sections { - CLASS_SEC = 0x00000001, + enum Sections { + CLASS_SEC = 0x00000001, NAMESPACE_SEC = 0x00000010, COMPOUND_MASK = CLASS_SEC, SCOPE_MASK = COMPOUND_MASK | NAMESPACE_SEC, - - CLASSDOC_SEC = 0x00000800, + + CLASSDOC_SEC = 0x00000800, STRUCTDOC_SEC = 0x00001000, UNIONDOC_SEC = 0x00002000, EXCEPTIONDOC_SEC = 0x00004000, @@ -81,7 +81,7 @@ class Entry CATEGORYDOC_SEC = 0x00040000, SERVICEDOC_SEC = 0x00080000, SINGLETONDOC_SEC = 0x00100000, - COMPOUNDDOC_MASK = CLASSDOC_SEC | STRUCTDOC_SEC | UNIONDOC_SEC | + COMPOUNDDOC_MASK = CLASSDOC_SEC | STRUCTDOC_SEC | UNIONDOC_SEC | INTERFACEDOC_SEC | EXCEPTIONDOC_SEC | PROTOCOLDOC_SEC | CATEGORYDOC_SEC | SERVICEDOC_SEC | SINGLETONDOC_SEC, @@ -91,14 +91,14 @@ class Entry ENUMDOC_SEC = 0x01000000, ENUM_SEC = 0x02000000, - EMPTY_SEC = 0x03000000, - PAGEDOC_SEC = 0x04000000, + EMPTY_SEC = 0x03000000, + PAGEDOC_SEC = 0x04000000, VARIABLE_SEC = 0x05000000, FUNCTION_SEC = 0x06000000, TYPEDEF_SEC = 0x07000000, - MEMBERDOC_SEC = 0x08000000, + MEMBERDOC_SEC = 0x08000000, OVERLOADDOC_SEC = 0x09000000, - EXAMPLE_SEC = 0x0a000000, + EXAMPLE_SEC = 0x0a000000, VARIABLEDOC_SEC = 0x0b000000, FILEDOC_SEC = 0x0c000000, DEFINEDOC_SEC = 0x0d000000, @@ -112,9 +112,10 @@ class Entry PACKAGE_SEC = 0x15000000, PACKAGEDOC_SEC = 0x16000000, OBJCIMPL_SEC = 0x17000000, - DIRDOC_SEC = 0x18000000 - ,EXPORTED_INTERFACE_SEC = 0x19000000 - ,INCLUDED_SERVICE_SEC = 0x1A000000 + DIRDOC_SEC = 0x18000000, + EXPORTED_INTERFACE_SEC = 0x19000000, + INCLUDED_SERVICE_SEC = 0x1A000000, + EXAMPLE_LINENO_SEC = 0x1B000000, }; // class specifiers (add new items to the end) @@ -133,7 +134,8 @@ class Entry static const uint64 Enum = (1ULL<<12); // for Java-style enums static const uint64 Service = (1ULL<<13); // UNO IDL static const uint64 Singleton = (1ULL<<14); // UNO IDL - static const uint64 ForwardDecl = (1ULL<<15); // forward declarad template classes + static const uint64 ForwardDecl = (1ULL<<15); // forward declared template classes + static const uint64 Local = (1ULL<<16); // for Slice types // member specifiers (add new items to the beginning) static const uint64 PrivateGettable = (1ULL<<20); // C# private getter @@ -204,7 +206,7 @@ class Entry /*! Returns the parent for this Entry or 0 if this entry has no parent. */ Entry *parent() const { return m_parent; } - /*! Returns the list of children for this Entry + /*! Returns the list of children for this Entry * @see addSubEntry() and removeSubEntry() */ const QList<Entry> *children() const { return m_sublist; } @@ -212,14 +214,14 @@ class Entry /*! Adds entry \a e as a child to this entry */ void addSubEntry (Entry* e) ; - /*! Removes entry \a e from the list of children. - * Returns a pointer to the entry or 0 if the entry was not a child. + /*! Removes entry \a e from the list of children. + * Returns a pointer to the entry or 0 if the entry was not a child. * Note the entry will not be deleted. - */ + */ Entry *removeSubEntry(Entry *e); /*! Restore the state of this Entry to the default value it has - * at construction time. + * at construction time. */ void reset(); @@ -233,7 +235,7 @@ class Entry // identification int section; //!< entry type (see Sections); - QCString type; //!< member type + QCString type; //!< member type QCString name; //!< member name TagInfo *tagInfo; //!< tag file info @@ -241,14 +243,16 @@ class Entry Protection protection; //!< class protection MethodTypes mtype; //!< signal, slot, (dcop) method, or property? uint64 spec; //!< class/member specifiers - int initLines; //!< define/variable initializer lines to show + int initLines; //!< define/variable initializer lines to show bool stat; //!< static ? bool explicitExternal; //!< explicitly defined as external? bool proto; //!< prototype ? bool subGrouping; //!< automatically group class members? bool callGraph; //!< do we need to draw the call graph? bool callerGraph; //!< do we need to draw the caller graph? - Specifier virt; //!< virtualness of the entry + bool referencedByRelation;//!< do we need to show the referenced by relation? + bool referencesRelation; //!< do we need to show the references relation? + Specifier virt; //!< virtualness of the entry QCString args; //!< member argument string QCString bitfields; //!< member's bit fields ArgumentList *argList; //!< member arguments as a list @@ -276,7 +280,7 @@ class Entry int bodyLine; //!< line number of the definition in the source int endBodyLine; //!< line number where the definition ends int mGrpId; //!< member group id - QList<BaseInfo> *extends; //!< list of base classes + QList<BaseInfo> *extends; //!< list of base classes QList<Grouping> *groups; //!< list of groups this entry belongs to QList<SectionInfo> *anchors; //!< list of anchors defined in this entry QCString fileName; //!< file this entry was extracted from @@ -288,6 +292,8 @@ class Entry bool artificial; //!< Artificially introduced item GroupDocType groupDocType; QCString id; //!< libclang id + LocalToc localToc; + QCString metaData; //!< Slice metadata static int num; //!< counts the total number of entries @@ -295,7 +301,7 @@ class Entry /// return the command name used to define GROUPDOC_SEC const char *groupDocCmd() const { - switch( groupDocType ) + switch( groupDocType ) { case GROUPDOC_NORMAL: return "\\defgroup"; case GROUPDOC_ADD: return "\\addgroup"; @@ -305,11 +311,11 @@ class Entry } Grouping::GroupPri_t groupingPri() const { - if( section != GROUPDOC_SEC ) + if( section != GROUPDOC_SEC ) { return Grouping::GROUPING_LOWEST; } - switch( groupDocType ) + switch( groupDocType ) { case GROUPDOC_NORMAL: return Grouping::GROUPING_AUTO_DEF; case GROUPDOC_ADD: return Grouping::GROUPING_AUTO_ADD; @@ -318,11 +324,11 @@ class Entry } } - private: + private: void createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd); Entry *m_parent; //!< parent node in the tree QList<Entry> *m_sublist; //!< entries that are children of this one - Entry &operator=(const Entry &); + Entry &operator=(const Entry &); }; /** Wrapper for a node in the Entry tree. @@ -355,13 +361,13 @@ class EntryNav private: - // navigation + // navigation EntryNav *m_parent; //!< parent node in the tree QList<EntryNav> *m_subList; //!< entries that are children of this one // identification int m_section; //!< entry type (see Sections); - QCString m_type; //!< member type + QCString m_type; //!< member type QCString m_name; //!< member name TagInfo *m_tagInfo; //!< tag file info FileDef *m_fileDef; diff --git a/src/example.h b/src/example.h index cf30827..321982b 100644 --- a/src/example.h +++ b/src/example.h @@ -36,7 +36,7 @@ struct Example class ExampleSDict : public SDict<Example> { public: - ExampleSDict(int size=17) : SDict<Example>(size) {} + ExampleSDict(int size=17) : SDict<Example>(size) { setAutoDelete(TRUE); } ~ExampleSDict() {} private: int compareValues(const Example *item1,const Example *item2) const diff --git a/src/filedef.cpp b/src/filedef.cpp index 2cfe37a..f9f68d1 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -85,6 +85,9 @@ FileDef::FileDef(const char *p,const char *nm, setReference(lref); setDiskName(dn?dn:nm); m_classSDict = 0; + m_interfaceSDict = 0; + m_structSDict = 0; + m_exceptionSDict = 0; m_includeList = 0; m_includeDict = 0; m_includedByList = 0; @@ -112,6 +115,9 @@ FileDef::FileDef(const char *p,const char *nm, FileDef::~FileDef() { delete m_classSDict; + delete m_interfaceSDict; + delete m_structSDict; + delete m_exceptionSDict; delete m_includeDict; delete m_includeList; delete m_includedByDict; @@ -239,18 +245,25 @@ void FileDef::writeTagFile(FTextStream &tagFile) case LayoutDocEntry::FileClasses: { if (m_classSDict) - { - SDict<ClassDef>::Iterator ci(*m_classSDict); - ClassDef *cd; - for (ci.toFirst();(cd=ci.current());++ci) - { - if (cd->isLinkableInProject()) - { - tagFile << " <class kind=\"" << cd->compoundTypeString() << - "\">" << convertToXML(cd->name()) << "</class>" << endl; - } - } - } + writeClassesToTagFile(tagFile, m_classSDict); + } + break; + case LayoutDocEntry::FileInterfaces: + { + if (m_interfaceSDict) + writeClassesToTagFile(tagFile, m_interfaceSDict); + } + break; + case LayoutDocEntry::FileStructs: + { + if (m_structSDict) + writeClassesToTagFile(tagFile, m_structSDict); + } + break; + case LayoutDocEntry::FileExceptions: + { + if (m_exceptionSDict) + writeClassesToTagFile(tagFile, m_exceptionSDict); } break; case LayoutDocEntry::FileNamespaces: @@ -348,6 +361,10 @@ void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title) { ol.disable(OutputGenerator::Latex); } + if (ol.isEnabled(OutputGenerator::Docbook) && !Config_getBool(DOCBOOK_PROGRAMLISTING)) + { + ol.disable(OutputGenerator::Docbook); + } if (ol.isEnabled(OutputGenerator::RTF) && !Config_getBool(RTF_SOURCE_CODE)) { ol.disable(OutputGenerator::RTF); @@ -413,6 +430,20 @@ void FileDef::writeBriefDescription(OutputList &ol) ol.writeSynopsis(); } +void FileDef::writeClassesToTagFile(FTextStream &tagFile, ClassSDict *d) +{ + SDict<ClassDef>::Iterator ci(*d); + ClassDef *cd; + for (ci.toFirst();(cd=ci.current());++ci) + { + if (cd->isLinkableInProject()) + { + tagFile << " <class kind=\"" << cd->compoundTypeString() << + "\">" << convertToXML(cd->name()) << "</class>" << endl; + } + } +} + void FileDef::writeIncludeFiles(OutputList &ol) { if (m_includeList && m_includeList->count()>0) @@ -553,10 +584,10 @@ void FileDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title, if (m_namespaceSDict) m_namespaceSDict->writeDeclaration(ol,title,isConstantGroup); } -void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title) +void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d) { // write list of classes - if (m_classSDict) m_classSDict->writeDeclaration(ol,0,title,FALSE); + if (d) d->writeDeclaration(ol,0,title,FALSE); } void FileDef::writeInlineClasses(OutputList &ol) @@ -642,14 +673,38 @@ void FileDef::writeSummaryLinks(OutputList &ol) SrcLangExt lang=getLanguage(); for (eli.toFirst();(lde=eli.current());++eli) { - if ((lde->kind()==LayoutDocEntry::FileClasses && - m_classSDict && m_classSDict->declVisible()) || - (lde->kind()==LayoutDocEntry::FileNamespaces && - m_namespaceSDict && m_namespaceSDict->declVisible()) - ) + if (lde->kind()==LayoutDocEntry::FileClasses && m_classSDict && m_classSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "nested-classes"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::FileInterfaces && m_interfaceSDict && m_interfaceSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "interfaces"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::FileStructs && m_structSDict && m_structSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "structs"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::FileExceptions && m_exceptionSDict && m_exceptionSDict->declVisible()) { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; - QCString label = lde->kind()==LayoutDocEntry::FileClasses ? "nested-classes" : "namespaces"; + QCString label = "exceptions"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::FileNamespaces && m_namespaceSDict && m_namespaceSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "namespaces"; ol.writeSummaryLink(0,label,ls->title(lang),first); first=FALSE; } @@ -777,9 +832,27 @@ void FileDef::writeDocumentation(OutputList &ol) case LayoutDocEntry::FileClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; - writeClassDeclarations(ol,ls->title(lang)); + writeClassDeclarations(ol,ls->title(lang),m_classSDict); } - break; + break; + case LayoutDocEntry::FileInterfaces: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title(lang),m_interfaceSDict); + } + break; + case LayoutDocEntry::FileStructs: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title(lang),m_structSDict); + } + break; + case LayoutDocEntry::FileExceptions: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title(lang),m_exceptionSDict); + } + break; case LayoutDocEntry::FileNamespaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; @@ -838,6 +911,9 @@ void FileDef::writeDocumentation(OutputList &ol) case LayoutDocEntry::NamespaceNestedNamespaces: case LayoutDocEntry::NamespaceNestedConstantGroups: case LayoutDocEntry::NamespaceClasses: + case LayoutDocEntry::NamespaceInterfaces: + case LayoutDocEntry::NamespaceStructs: + case LayoutDocEntry::NamespaceExceptions: case LayoutDocEntry::NamespaceInlineClasses: case LayoutDocEntry::GroupClasses: case LayoutDocEntry::GroupInlineClasses: @@ -937,6 +1013,7 @@ void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); + static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); static bool rtfSourceCode = Config_getBool(RTF_SOURCE_CODE); DevNullCodeDocInterface devNullIntf; QCString title = m_docname; @@ -947,6 +1024,7 @@ void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) QCString pageTitle = theTranslator->trSourceFile(title); ol.disable(OutputGenerator::Man); if (!latexSourceCode) ol.disable(OutputGenerator::Latex); + if (!docbookSourceCode) ol.disable(OutputGenerator::Docbook); if (!rtfSourceCode) ol.disable(OutputGenerator::RTF); bool isDocFile = isDocumentationFile(); @@ -978,13 +1056,14 @@ void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) if (isLinkable()) { + ol.pushGeneratorState(); if (latexSourceCode) ol.disable(OutputGenerator::Latex); if (rtfSourceCode) ol.disable(OutputGenerator::RTF); + if (docbookSourceCode) ol.disable(OutputGenerator::Docbook); ol.startTextLink(getOutputFileBase(),0); ol.parseText(theTranslator->trGotoDocumentation()); ol.endTextLink(); - if (latexSourceCode) ol.enable(OutputGenerator::Latex); - if (rtfSourceCode) ol.enable(OutputGenerator::RTF); + ol.popGeneratorState(); } (void)sameTu; @@ -1153,6 +1232,14 @@ void FileDef::insertMember(MemberDef *md) addMemberToList(MemberListType_decTypedefMembers,md); addMemberToList(MemberListType_docTypedefMembers,md); break; + case MemberType_Sequence: + addMemberToList(MemberListType_decSequenceMembers,md); + addMemberToList(MemberListType_docSequenceMembers,md); + break; + case MemberType_Dictionary: + addMemberToList(MemberListType_decDictionaryMembers,md); + addMemberToList(MemberListType_docDictionaryMembers,md); + break; case MemberType_Enumeration: addMemberToList(MemberListType_decEnumMembers,md); addMemberToList(MemberListType_docEnumMembers,md); @@ -1177,17 +1264,36 @@ void FileDef::insertMember(MemberDef *md) void FileDef::insertClass(ClassDef *cd) { if (cd->isHidden()) return; - if (m_classSDict==0) + + ClassSDict *d=0; + ClassSDict **dd=&m_classSDict; + + if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) { - m_classSDict = new ClassSDict(17); + if (cd->compoundType()==ClassDef::Interface) + { + dd = &m_interfaceSDict; + } + else if (cd->compoundType()==ClassDef::Struct) + { + dd = &m_structSDict; + } + else if (cd->compoundType()==ClassDef::Exception) + { + dd = &m_exceptionSDict; + } } + + if (*dd==0) *dd = new ClassSDict(17); + d = *dd; + if (Config_getBool(SORT_BRIEF_DOCS)) { - m_classSDict->inSort(cd->name(),cd); + d->inSort(cd->name(),cd); } else { - m_classSDict->append(cd->name(),cd); + d->append(cd->name(),cd); } } @@ -1420,13 +1526,11 @@ bool FileDef::generateSourceFile() const { static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool verbatimHeaders = Config_getBool(VERBATIM_HEADERS); - QCString extension = name().right(4); return !isReference() && (sourceBrowser || (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC) ) && - extension!=".doc" && extension!=".txt" && extension!=".dox" && - extension!=".md" && name().right(9)!=".markdown"; + !isDocumentationFile(); } diff --git a/src/filedef.h b/src/filedef.h index 9167249..fe3c81d 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -201,7 +201,7 @@ class FileDef : public Definition void writeSourceLink(OutputList &ol); void writeNamespaceDeclarations(OutputList &ol,const QCString &title, bool isConstantGroup); - void writeClassDeclarations(OutputList &ol,const QCString &title); + void writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d); void writeInlineClasses(OutputList &ol); void startMemberDeclarations(OutputList &ol); void endMemberDeclarations(OutputList &ol); @@ -209,6 +209,7 @@ class FileDef : public Definition void endMemberDocumentation(OutputList &ol); void writeDetailedDescription(OutputList &ol,const QCString &title); void writeBriefDescription(OutputList &ol); + void writeClassesToTagFile(FTextStream &t,ClassSDict *d); QDict<IncludeInfo> *m_includeDict; QList<IncludeInfo> *m_includeList; @@ -233,6 +234,9 @@ class FileDef : public Definition MemberGroupSDict *m_memberGroupSDict; NamespaceSDict *m_namespaceSDict; ClassSDict *m_classSDict; + ClassSDict *m_interfaceSDict; + ClassSDict *m_structSDict; + ClassSDict *m_exceptionSDict; bool m_subGrouping; }; diff --git a/src/formula.cpp b/src/formula.cpp index 6fe617d..c252e07 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -69,8 +69,10 @@ void FormulaList::generateBitmaps(const char *path) FTextStream t(&f); if (Config_getBool(LATEX_BATCHMODE)) t << "\\batchmode" << endl; t << "\\documentclass{article}" << endl; + t << "\\usepackage{ifthen}" << endl; t << "\\usepackage{epsfig}" << endl; // for those who want to include images writeExtraLatexPackages(t); + writeLatexSpecialFormulaChars(t); t << "\\pagestyle{empty}" << endl; t << "\\begin{document}" << endl; int page=0; @@ -96,8 +98,7 @@ void FormulaList::generateBitmaps(const char *path) { //printf("Running latex...\n"); //system("latex _formulas.tex </dev/null >/dev/null"); - QCString latexCmd = Config_getString(LATEX_CMD_NAME); - if (latexCmd.isEmpty()) latexCmd="latex"; + QCString latexCmd = "latex"; portable_sysTimerStart(); if (portable_system(latexCmd,"_formulas.tex")!=0) { diff --git a/src/fortrancode.l b/src/fortrancode.l index 501b492..0e610fd 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -37,7 +37,7 @@ #include <ctype.h> #include <qregexp.h> #include <qdir.h> -#include <qstringlist.h> +#include <qcstringlist.h> #include "entry.h" #include "doxygen.h" #include "message.h" @@ -86,7 +86,7 @@ class UseEntry { public: QCString module; // just for debug - QStringList onlyNames; /* entries of the ONLY-part */ + QCStringList onlyNames; /* entries of the ONLY-part */ }; /** @@ -105,10 +105,11 @@ class UseSDict : public SDict<UseEntry> class Scope { public: - QStringList useNames; //!< contains names of used modules + QCStringList useNames; //!< contains names of used modules QDict<void> localVars; //!< contains names of local variables + QDict<void> externalVars; //!< contains names of external entities - Scope() : localVars(7, FALSE /*caseSensitive*/) {} + Scope() : localVars(7, FALSE /*caseSensitive*/), externalVars(7, FALSE /*caseSensitive*/) {} }; /*===================================================================*/ @@ -122,7 +123,8 @@ static QCString currentClass=0; //!< name of the current enclosing static UseSDict *useMembers= new UseSDict; //!< info about used modules static UseEntry *useEntry = 0; //!< current use statement info static QList<Scope> scopeStack; -// static QStringList *currentUseNames= new QStringList; //! contains names of used modules of current program unit +static bool g_isExternal = false; +// static QCStringList *currentUseNames= new QCStringList; //! contains names of used modules of current program unit static QCString str=""; //!> contents of fortran string static CodeOutputInterface * g_code; @@ -159,6 +161,9 @@ static char stringStartSymbol; // single or double quote // declared from referenced names static int bracketCount = 0; +// signal when in type / class /procedure declaration +static int inTypeDecl = 0; + static bool g_endComment; static void endFontClass() @@ -431,7 +436,7 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam Scope *scope; for (it.toLast();(scope=it.current());--it) { - if (scope->localVars.find(memberName)) + if (scope->localVars.find(memberName) && (!scope->externalVars.find(memberName))) return FALSE; } @@ -475,7 +480,7 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam if (ue) { // check if only-list exists and if current entry exists is this list - QStringList &only= ue->onlyNames; + QCStringList &only= ue->onlyNames; if (only.isEmpty()) { //cout << " found in module " << moduleName << " entry " << memberName << endl; @@ -483,10 +488,10 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam } else { - for ( QStringList::Iterator it = only.begin(); it != only.end(); ++it) + for ( QCStringList::Iterator it = only.begin(); it != only.end(); ++it) { //cout << " search in only: " << moduleName << ":: " << memberName << "==" << (*it)<< endl; - if (memberName == (*it).utf8()) + if (memberName == *it) { return TRUE; // found in ONLY-part of use list } @@ -629,9 +634,9 @@ static void endScope() Scope *scope = scopeStack.getLast(); scopeStack.removeLast(); - for ( QStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) + for ( QCStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) { - useMembers->remove((*it).utf8()); + useMembers->remove(*it); } delete scope; } @@ -645,7 +650,10 @@ static void addUse(const QCString &moduleName) static void addLocalVar(const QCString &varName) { if (!scopeStack.isEmpty()) + { scopeStack.getLast()->localVars.insert(varName, (void*)1); + if (g_isExternal) scopeStack.getLast()->externalVars.insert(varName, (void*)1); + } } //---------------------------------------------------------------------------- @@ -684,17 +692,18 @@ NUM_TYPE (complex|integer|logical|real) LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.) KIND {ARGS} CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS})) -TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE) +TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE|ENUMERATOR) INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")" -ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE) +ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|(NON_)?RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE) ACCESS_SPEC (PROTECTED|PRIVATE|PUBLIC) /* Assume that attribute statements are almost the same as attributes. */ ATTR_STMT {ATTR_SPEC}|DIMENSION FLOW (DO|SELECT|CASE|SELECT{BS}(CASE|TYPE)|WHERE|IF|THEN|ELSE|WHILE|FORALL|ELSEWHERE|ELSEIF|RETURN|CONTINUE|EXIT|GO{BS}TO) COMMANDS (FORMAT|CONTAINS|MODULE{BS_}PROCEDURE|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|PRESENT|DEALLOCATE|NULLIFY|SIZE|INQUIRE|OPEN|CLOSE|FLUSH|DATA|COMMON) IGNORE (CALL) -PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)? +PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)?0 +LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")" /* | */ @@ -775,12 +784,12 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I BEGIN(Use); } <Use>"ONLY" { // TODO: rename - startFontClass("keywordtype"); - codifyLines(yytext); - endFontClass(); + startFontClass("keywordtype"); + codifyLines(yytext); + endFontClass(); yy_push_state(YY_START); - BEGIN(UseOnly); - } + BEGIN(UseOnly); + } <Use>{ID} { QCString tmp = yytext; tmp = tmp.lower(); @@ -813,7 +822,8 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I unput(*yytext); yy_pop_state();YY_FTN_RESET } -<Start>"import"{BS_} { +<*>"import"{BS}/"\n" | +<*>"import"{BS_} { startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); @@ -825,6 +835,11 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I generateLink(*g_code, yytext); g_insideBody=FALSE; } +<Import>("ONLY"|"NONE"|"ALL") { + startFontClass("keywordtype"); + codifyLines(yytext); + endFontClass(); + } /*-------- fortran module -----------------------------------------*/ <Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { // startScope(); @@ -835,15 +850,29 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I BEGIN(ClassName); if (!qstricmp(yytext,"module")) currentModule="module"; } +<Start>("enum")/{BS_}|{BS}{COMMA}{BS}{LANGUAGE_BIND_SPEC}|\n { // + startScope(); + startFontClass("keyword"); + codifyLines(yytext); + endFontClass(); + yy_push_state(YY_START); + BEGIN(ClassName); + currentClass="class"; + } +<*>{LANGUAGE_BIND_SPEC} { // + startFontClass("keyword"); + codifyLines(yytext); + endFontClass(); + } <Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n { // - startScope(); - startFontClass("keyword"); - codifyLines(yytext); - endFontClass(); + startScope(); + startFontClass("keyword"); + codifyLines(yytext); + endFontClass(); yy_push_state(YY_START); - BEGIN(ClassName); - currentClass="class"; - } + BEGIN(ClassName); + currentClass="class"; + } <ClassName>{ID} { if (currentModule == "module") { @@ -853,22 +882,26 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I generateLink(*g_code,yytext); yy_pop_state(); } -<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable deklaration +<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable declaration startFontClass("keyword"); g_code->codify(yytext); endFontClass(); } <ClassName>\n { // interface may be without name yy_pop_state(); - YY_FTN_REJECT; - } + YY_FTN_REJECT; + } +<Start>^{BS}"end"({BS_}"enum").* { // just reset currentClass, rest is done in following rule + currentClass=0; + YY_FTN_REJECT; + } <Start>^{BS}"end"({BS_}"type").* { // just reset currentClass, rest is done in following rule currentClass=0; - YY_FTN_REJECT; + YY_FTN_REJECT; } <Start>^{BS}"end"({BS_}"module").* { // just reset currentModule, rest is done in following rule currentModule=0; - YY_FTN_REJECT; + YY_FTN_REJECT; } /*-------- subprog definition -------------------------------------*/ <Start>({PREFIX}{BS_})?{TYPE_SPEC}{BS_}({PREFIX}{BS_})?{BS}/{SUBPROG}{BS_} { // TYPE_SPEC is for old function style function result @@ -876,7 +909,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I codifyLines(yytext); endFontClass(); } -<Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found +<Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found startFontClass("keyword"); codifyLines(yytext); endFontClass(); @@ -901,7 +934,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I yy_pop_state(); YY_FTN_RESET } -<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface")?{BS} { // Fortran subroutine or function ends +<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends //cout << "===> end function " << yytext << endl; endScope(); startFontClass("keyword"); @@ -914,7 +947,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I generateLink(*g_code,yytext); yy_pop_state(); } -<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends +<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends //cout << "===> end function " << yytext << endl; endScope(); startFontClass("keyword"); @@ -922,7 +955,18 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I endFontClass(); } /*-------- variable declaration ----------------------------------*/ +<Start>^{BS}"real"/[,:( ] { // real is a bit tricky as it is a data type but also a function. + yy_push_state(YY_START); + BEGIN(Declaration); + startFontClass("keywordtype"); + g_code->codify(yytext); + endFontClass(); + } <Start>{TYPE_SPEC}/[,:( ] { + QCString typ = yytext; + typ = removeRedundantWhiteSpace(typ.lower()); + if (QString(typ).startsWith("real")) YY_FTN_REJECT; + if (typ == "type" || typ == "class" || typ == "procedure") inTypeDecl = 1; yy_push_state(YY_START); BEGIN(Declaration); startFontClass("keywordtype"); @@ -930,11 +974,18 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I endFontClass(); } <Start>{ATTR_SPEC} { + if (QCString(yytext) == "external") + { + yy_push_state(YY_START); + BEGIN(Declaration); + g_isExternal = true; + } startFontClass("keywordtype"); g_code->codify(yytext); endFontClass(); } -<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable deklaration +<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable declaration + if (QCString(yytext) == "external") g_isExternal = true; startFontClass("keywordtype"); g_code->codify(yytext); endFontClass(); @@ -946,8 +997,11 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I g_code->codify(yytext); endFontClass(); } - else if (g_currentMemberDef && ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString() != QCString("subroutine"))) || - g_currentMemberDef->isVariable())) + else if (g_currentMemberDef && + ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString()!=QCString("subroutine") || inTypeDecl)) || + g_currentMemberDef->isVariable() || g_currentMemberDef->isEnumValue() + ) + ) { generateLink(*g_code, yytext); } @@ -956,22 +1010,23 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I g_code->codify(yytext); addLocalVar(yytext); } - } -<Declaration>{BS}("=>"|"="){BS} { // Procedure binding - BEGIN(DeclarationBinding); - g_code->codify(yytext); - } -<DeclarationBinding>{ID} { // Type bound procedure link + } +<Declaration>{BS}("=>"|"="){BS} { // Procedure binding + BEGIN(DeclarationBinding); + g_code->codify(yytext); + } +<DeclarationBinding>{ID} { // Type bound procedure link generateLink(*g_code, yytext); yy_pop_state(); - } -<Declaration>[(] { // start of array specification + } +<Declaration>[(] { // start of array or type / class specification bracketCount++; g_code->codify(yytext); } <Declaration>[)] { // end array specification bracketCount--; + if (!bracketCount) inTypeDecl = 0; g_code->codify(yytext); } @@ -1003,6 +1058,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I g_contLineNr++; if (!(g_hasContLine && g_hasContLine[g_contLineNr - 1])) { + g_isExternal = false; yy_pop_state(); } YY_FTN_RESET @@ -1029,11 +1085,20 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I // fixed form continuation line YY_FTN_REJECT; } + else if (QCString(yytext).stripWhiteSpace().lower() == "type") + { + yy_push_state(YY_START); + BEGIN(Declaration); + startFontClass("keywordtype"); + g_code->codify(QCString(yytext).stripWhiteSpace()); + endFontClass(); + g_code->codify(yytext + 4); + } else { - g_insideBody=TRUE; + g_insideBody=TRUE; generateLink(*g_code, yytext); - g_insideBody=FALSE; + g_insideBody=FALSE; } } @@ -1142,9 +1207,6 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I g_insideBody=FALSE; } /*------ strings --------------------------------------------------*/ -<*>"\\\\" { str+=yytext; /* ignore \\ */} -<*>"\\\""|\\\' { str+=yytext; /* ignore \" */} - <String>\n { // string with \n inside g_contLineNr++; str+=yytext; @@ -1175,14 +1237,16 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I /*-----------------------------------------------------------------------------*/ <*>\n { - if (g_endComment) - { - g_endComment=FALSE; - } - else - { - codifyLines(yytext); - } + if (g_endComment) + { + g_endComment=FALSE; + } + else + { + codifyLines(yytext); + // comment cannot extend over the end of a line so should always be terminatd at the end of the line. + if (g_currentFontClass && !strcmp(g_currentFontClass,"comment")) endFontClass(); + } g_contLineNr++; YY_FTN_RESET } diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 85b6de9..5f10669 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -164,6 +164,7 @@ static Entry* global_root = 0 ; static Entry* file_root = 0 ; static Entry* current = 0 ; static Entry* last_entry = 0 ; +static Entry* last_enum = 0 ; static ScanVar v_type = V_IGNORE; // type of parsed variable static QList<Entry> moduleProcedures; // list of all interfaces which contain unresolved // module procedures @@ -198,6 +199,8 @@ static SymbolModifiers currentModifiers; //! Holds program scope->symbol name->symbol modifiers. static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers; +static Entry *global_scope = NULL; +static int anonCount = 0 ; //----------------------------------------------------------------------------- static int yyread(char *buf,int max_size); @@ -226,6 +229,9 @@ static QCString extractFromParens(const QCString name); static CommentInPrepass* locatePrepassComment(int from, int to); static void updateVariablePrepassComment(int from, int to); static void newLine(); +static void initEntry(); + +static const char *stateToString(int state); //----------------------------------------------------------------------------- #undef YY_INPUT @@ -248,6 +254,7 @@ SUBPROG (subroutine|function) B [ \t] BS [ \t]* BS_ [ \t]+ +BT_ ([ \t]+|[ \t]*"(") COMMA {BS},{BS} ARGS_L0 ("("[^)]*")") ARGS_L1a [^()]*"("[^)]*")"[^)]* @@ -260,7 +267,7 @@ NUM_TYPE (complex|integer|logical|real) LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.) KIND {ARGS} CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS})) -TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?) +TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|ENUMERATOR|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?) INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")" ATTR_SPEC (EXTERNAL|ALLOCATABLE|DIMENSION{ARGS}|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}?|DEFERRED|NON_OVERRIDABLE|CONTIGUOUS|VOLATILE|VALUE) @@ -271,7 +278,7 @@ ATTR_STMT {ATTR_SPEC}|DIMENSION|{ACCESS_SPEC} EXTERNAL_STMT (EXTERNAL) CONTAINS CONTAINS -PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)? +PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON_)?RECURSIVE|IMPURE|PURE|ELEMENTAL)? SCOPENAME ({ID}{BS}"::"{BS})* %option noyywrap @@ -297,6 +304,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* %x Variable %x Initialization %x ArrayInitializer +%x Enum %x Typedef %x TypedefBody %x TypedefBodyContains @@ -377,14 +385,6 @@ SCOPENAME ({ID}{BS}"::"{BS})* /*------ ignore strings that are not initialization strings */ -<*>"\\\\" { if (yy_top_state() == Initialization - || yy_top_state() == ArrayInitializer) - initializer+=yytext; - } -<*>"\\\""|\\\' { if (yy_top_state() == Initialization - || yy_top_state() == ArrayInitializer) - initializer+=yytext; - } <String>\"|\' { // string ends with next quote without previous backspace if (yytext[0]!=stringStartSymbol) { yyColNr -= (int)yyleng; REJECT; } // single vs double quote if (yy_top_state() == Initialization @@ -558,7 +558,18 @@ SCOPENAME ({ID}{BS}"::"{BS})* if (!endScope(current_root)) yyterminate(); defaultProtection = Public; - yy_pop_state(); + if (global_scope) + { + if (global_scope != (Entry *) -1) + yy_push_state(Start); + else + yy_pop_state(); // cannot pop artrificial entry + } + else + { + yy_push_state(Start); + global_scope = (Entry *)-1; // signal that the global_scope has already been used. + } } <Module>{ID} { addModule(yytext, TRUE); @@ -602,7 +613,7 @@ abstract { current->spec |= Entry::AbstractClass; } extends{ARGS} { - QCString basename = extractFromParens(yytext); + QCString basename = extractFromParens(yytext).lower(); current->extends->append(new BaseInfo(basename, Public, Normal)); } public { @@ -667,7 +678,8 @@ private { addCurrentEntry(1); } {BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */ - last_entry->args = yytext; + QCString args = yytext; + last_entry->args = args.lower(); } "\n" { currentModifiers = SymbolModifiers(); @@ -711,8 +723,17 @@ private { {ID} { } } -<Start,ModuleBody,TypedefBody,SubprogBody>{ +<Start,ModuleBody,TypedefBody,SubprogBody,Enum>{ ^{BS}{TYPE_SPEC}/{SEPARATE} { + last_enum = 0; + if (YY_START == Enum) + { + argType = "@"; // enum marker + } + else + { + argType = QCString(yytext).simplifyWhiteSpace().lower(); + } current->bodyLine = yyLineNr + 1; current->endBodyLine = yyLineNr + lineCountPrepass; /* variable declaration starts */ @@ -721,7 +742,6 @@ private { addModule(NULL); yy_push_state(ModuleBody); //anon program } - argType = QCString(yytext).simplifyWhiteSpace().lower(); yy_push_state(AttributeList); } /* Dimitri: macro expansion should already be done during preprocessing not here! @@ -773,8 +793,10 @@ private { } {ID} { } -^{BS}"type"{BS_}"is"/{BS_} { } +^{BS}"type"{BS_}"is"/{BT_} { } ^{BS}"type"{BS}"=" { } +^{BS}"class"{BS_}"is"/{BT_} { } +^{BS}"class"{BS_}"default" { } } <AttributeList>{ {COMMA} {} @@ -817,17 +839,30 @@ private { modifiers[current_root][name.lower()] |= currentModifiers; argName= name; - v_type= V_IGNORE; - if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC) - { // new variable entry - v_type = V_VARIABLE; + v_type= V_IGNORE; + if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC) + { // new variable entry + v_type = V_VARIABLE; current->section = Entry::VARIABLE_SEC; - current->name = argName; - current->type = argType; - current->fileName = yyFileName; - current->bodyLine = yyLineNr; // used for source reference + current->name = argName; + current->type = argType; + current->fileName = yyFileName; + current->bodyLine = yyLineNr; // used for source reference current->startLine = yyLineNr; - addCurrentEntry(1); + if (argType == "@") + { + current_root->addSubEntry(current); + current = new Entry(*current); + // add to the scope surrounding the enum (copy!) + current_root->parent()->addSubEntry(current); + last_enum = current; + current = new Entry ; + initEntry(); + } + else + { + addCurrentEntry(1); + } } else if (!argType.isEmpty()) { // declaration of parameter list: add type for corr. parameter @@ -963,19 +998,72 @@ private { { updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr); yy_pop_state(); // end initialization - if (v_type == V_VARIABLE) last_entry->initializer= initializer; + if (last_enum) + { + last_enum->initializer= initializer; + } + else + { + if (v_type == V_VARIABLE) last_entry->initializer= initializer; + } } else initializer+=", "; } <Initialization>"\n"|"!" { //| yy_pop_state(); // end initialization - if (v_type == V_VARIABLE) last_entry->initializer= initializer; + if (last_enum) + { + last_enum->initializer= initializer; + } + else + { + if (v_type == V_VARIABLE) last_entry->initializer= initializer; + } yyColNr -= 1; unput(*yytext); } <Initialization>. { initializer+=yytext; } +<*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} { + if(YY_START == Start) + { + addModule(NULL); + yy_push_state(ModuleBody); //anon program + } + + yy_push_state(Enum); + current->protection = defaultProtection; + typeProtection = defaultProtection; + typeMode = true; + + current->spec |= Entry::Struct; + current->name.resize(0); + current->args.resize(0); + current->name.sprintf("@%d",anonCount++); + + current->section = Entry::ENUM_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + if ((current_root) && + (current_root->section == Entry::CLASS_SEC + || current_root->section == Entry::NAMESPACE_SEC)) + { + current->name = current_root->name + "::" + current->name; + } + + addCurrentEntry(1); + startScope(last_entry); + BEGIN( Enum ) ; + } +<Enum>"end"{BS}"enum" { + last_entry->parent()->endBodyLine = yyLineNr; + if (!endScope(current_root)) + yyterminate(); + typeMode = false; + yy_pop_state(); + } /*------ fortran subroutine/function handling ------------------------------------------------------------*/ /* Start is initial condition */ @@ -1098,7 +1186,6 @@ private { yy_push_state(YY_START); BEGIN(StrIgnore); debugStr="*!"; - //fprintf(stderr,"start comment %d\n",yyLineNr); } } } @@ -1117,6 +1204,7 @@ private { { Entry *tmp_entry = current; current = last_entry; // temporarily switch to the previous entry + if (last_enum) current = last_enum; handleCommentBlock(docBlock,TRUE); current=tmp_entry; } @@ -1132,7 +1220,7 @@ private { docBlock.resize(0); } -<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains>"!>" { +<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,Enum>"!>" { yy_push_state(YY_START); current->docLine = yyLineNr; docBlockJavaStyle = FALSE; @@ -1552,7 +1640,10 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) } // fallthrough default: - if(column==6 && emptyLabel) { // continuation + if (!commented && (column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9)) { // remove numbers, i.e. labels from first 5 positions. + newContents[j]=' '; + } + else if(column==6 && emptyLabel) { // continuation if (!commented) fullCommentLine=FALSE; if (c != '0') { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3 newContents[j]=' '; @@ -2017,14 +2108,23 @@ static void startScope(Entry *scope) */ static bool endScope(Entry *scope, bool isGlobalRoot) { + if (global_scope == scope) + { + global_scope = NULL; + return TRUE; + } + if (global_scope == (Entry *) -1) + { + return TRUE; + } //cout<<"end scope: "<<scope->name<<endl; if (current_root->parent() || isGlobalRoot) { current_root= current_root->parent(); /* end substructure */ } - else + else // if (current_root != scope) { - fprintf(stderr,"parse error in end <scopename>"); + fprintf(stderr,"parse error in end <scopename>\n"); scanner_abort(); return FALSE; } @@ -2558,6 +2658,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra yyFileName = fileName; msg("Parsing file %s...\n",yyFileName.data()); + global_scope = rt; startScope(rt); // implies current_root = rt initParser(); groupEnterFile(yyFileName,yyLineNr); @@ -2579,7 +2680,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra fortranscannerYYlex(); groupLeaveFile(yyFileName,yyLineNr); - endScope(current_root, TRUE); // TRUE - global root + if (global_scope && global_scope != (Entry *) -1) endScope(current_root, TRUE); // TRUE - global root //debugCompounds(rt); //debug @@ -2660,7 +2761,7 @@ void FortranLanguageScanner::parsePrototype(const char *text) static void scanner_abort() { fprintf(stderr,"********************************************************************\n"); - fprintf(stderr,"Error in file %s line: %d, state: %d\n",yyFileName.data(),yyLineNr,YY_START); + fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyFileName.data(),yyLineNr,YY_START,stateToString(YY_START)); fprintf(stderr,"********************************************************************\n"); EntryListIterator eli(*global_root->children()); @@ -2689,3 +2790,47 @@ extern "C" { // some bogus code to keep the compiler happy } #endif +#define scanStateToString(x) case x: resultString = #x; break; +static const char *stateToString(int state) +{ + const char *resultString; + switch(state) + { + scanStateToString(INITIAL) + scanStateToString(Subprog) + scanStateToString(SubprogPrefix) + scanStateToString(Parameterlist) + scanStateToString(SubprogBody) + scanStateToString(SubprogBodyContains) + scanStateToString(Start) + scanStateToString(Comment) + scanStateToString(Module) + scanStateToString(Program) + scanStateToString(ModuleBody) + scanStateToString(ModuleBodyContains) + scanStateToString(AttributeList) + scanStateToString(Variable) + scanStateToString(Initialization) + scanStateToString(ArrayInitializer) + scanStateToString(Enum) + scanStateToString(Typedef) + scanStateToString(TypedefBody) + scanStateToString(TypedefBodyContains) + scanStateToString(InterfaceBody) + scanStateToString(StrIgnore) + scanStateToString(String) + scanStateToString(Use) + scanStateToString(UseOnly) + scanStateToString(ModuleProcedure) + scanStateToString(Prepass) + scanStateToString(DocBlock) + scanStateToString(DocBackLine) + scanStateToString(EndDoc) + scanStateToString(BlockData) + scanStateToString(Prototype) + scanStateToString(PrototypeSubprog) + scanStateToString(PrototypeArgs) + default: resultString = "Unknown"; break; + } + return resultString; +} diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 14c94a3..ea57eb7 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -35,6 +35,7 @@ #include "docparser.h" #include "htmldocvisitor.h" #include "filedef.h" +#include "classdef.h" #include "util.h" #include "resourcemgr.h" @@ -171,11 +172,10 @@ void FTVHelp::decContentsDepth() /*! Add a list item to the contents file. * \param isDir TRUE if the item is a directory, FALSE if it is a text - * \param name The name of the item. + * \param name the name of the item. * \param ref the URL of to the item. * \param file the file containing the definition of the item * \param anchor the anchor within the file. - * \param name the name of the item. * \param separateIndex put the entries in a separate index file * \param addToNavIndex add this entry to the quick navigation index * \param def Definition corresponding to this entry @@ -257,7 +257,7 @@ void FTVHelp::generateIndent(FTextStream &t, FTVNode *n,bool opened) while (p) { indent++; p=p->parent; } if (n->isDir) { - QCString dir = opened ? "▼" : "▶"; + QCString dir = opened ? "▼" : "►"; t << "<span style=\"width:" << (indent*16) << "px;display:inline-block;\"> </span>" << "<span id=\"arr_" << generateIndentLabel(n,0) << "\" class=\"arrow\" "; t << "onclick=\"toggleFolder('" << generateIndentLabel(n,0) << "')\""; @@ -304,7 +304,7 @@ void FTVHelp::generateLink(FTextStream &t,FTVNode *n) } else { - t << ">"; + t << "\">"; } t << convertToHtml(n->name); t << "</a>"; @@ -332,6 +332,27 @@ static void generateBriefDoc(FTextStream &t,Definition *def) } } +static char compoundIcon(ClassDef *cd) +{ + char icon='C'; + if (cd->getLanguage() == SrcLangExt_Slice) + { + if (cd->compoundType()==ClassDef::Interface) + { + icon='I'; + } + else if (cd->compoundType()==ClassDef::Struct) + { + icon='S'; + } + else if (cd->compoundType()==ClassDef::Exception) + { + icon='E'; + } + } + return icon; +} + void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,int maxLevel,int &index) { QListIterator<FTVNode> nli(nl); @@ -360,11 +381,19 @@ void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,in } else if (n->def && n->def->definitionType()==Definition::TypeNamespace) { - t << "<span class=\"icona\"><span class=\"icon\">N</span></span>"; + if (n->def->getLanguage() == SrcLangExt_Slice) + { + t << "<span class=\"icona\"><span class=\"icon\">M</span></span>"; + } + else + { + t << "<span class=\"icona\"><span class=\"icon\">N</span></span>"; + } } else if (n->def && n->def->definitionType()==Definition::TypeClass) { - t << "<span class=\"icona\"><span class=\"icon\">C</span></span>"; + char icon=compoundIcon(dynamic_cast<ClassDef*>(n->def)); + t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>"; } else { @@ -408,11 +437,19 @@ void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,in } else if (n->def && n->def->definitionType()==Definition::TypeNamespace) { - t << "<span class=\"icona\"><span class=\"icon\">N</span></span>"; + if (n->def->getLanguage() == SrcLangExt_Slice) + { + t << "<span class=\"icona\"><span class=\"icon\">M</span></span>"; + } + else + { + t << "<span class=\"icona\"><span class=\"icon\">N</span></span>"; + } } else if (n->def && n->def->definitionType()==Definition::TypeClass) { - t << "<span class=\"icona\"><span class=\"icon\">C</span></span>"; + char icon=compoundIcon(dynamic_cast<ClassDef*>(n->def)); + t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>"; } else { @@ -791,10 +828,13 @@ void FTVHelp::generateTreeViewInline(FTextStream &t) } //printf("preferred depth=%d\n",preferredDepth); - t << "<table class=\"directory\">\n"; - int index=0; - generateTree(t,m_indentNodes[0],0,preferredDepth,index); - t << "</table>\n"; + if (m_indentNodes[0].count()) + { + t << "<table class=\"directory\">\n"; + int index=0; + generateTree(t,m_indentNodes[0],0,preferredDepth,index); + t << "</table>\n"; + } t << "</div><!-- directory -->\n"; } diff --git a/src/groupdef.cpp b/src/groupdef.cpp index ccfa0df..e543d16 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -165,7 +165,7 @@ bool GroupDef::addClass(const ClassDef *cd) if (i==-1) i=qn.find('.'); bool found=FALSE; //printf("i=%d\n",i); - if (i!=-1) + if (i>0) { // add nested classes (e.g. A::B, A::C) after their parent (A) in // order of insertion @@ -1220,8 +1220,14 @@ void GroupDef::writeDocumentation(OutputList &ol) case LayoutDocEntry::NamespaceNestedNamespaces: case LayoutDocEntry::NamespaceNestedConstantGroups: case LayoutDocEntry::NamespaceClasses: + case LayoutDocEntry::NamespaceInterfaces: + case LayoutDocEntry::NamespaceStructs: + case LayoutDocEntry::NamespaceExceptions: case LayoutDocEntry::NamespaceInlineClasses: case LayoutDocEntry::FileClasses: + case LayoutDocEntry::FileInterfaces: + case LayoutDocEntry::FileStructs: + case LayoutDocEntry::FileExceptions: case LayoutDocEntry::FileNamespaces: case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 8b6d26c..6386cb8 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -34,15 +34,46 @@ #include "filedef.h" #include "memberdef.h" #include "htmlentity.h" +#include "emoji.h" #include "plantuml.h" static const int NUM_HTML_LIST_TYPES = 4; static const char types[][NUM_HTML_LIST_TYPES] = {"1", "a", "i", "A"}; +enum contexts_t +{ + NONE, // 0 + STARTLI, // 1 + STARTDD, // 2 + ENDLI, // 3 + ENDDD, // 4 + STARTTD, // 5 + ENDTD, // 6 + INTERLI, // 7 + INTERDD, // 8 + INTERTD // 9 +}; +static const char *contexts[10] = +{ "", // 0 + "startli", // 1 + "startdd", // 2 + "endli", // 3 + "enddd", // 4 + "starttd", // 5 + "endtd", // 6 + "interli", // 7 + "interdd", // 8 + "intertd" // 9 +}; static QCString convertIndexWordToAnchor(const QString &word) { static char hex[] = "0123456789abcdef"; + static int cnt = 0; QCString result="a"; + QCString cntStr; + result += cntStr.setNum(cnt); + result += "_"; + cnt++; const char *str = word.data(); unsigned char c; if (str) @@ -108,6 +139,7 @@ static bool mustBeOutsideParagraph(DocNode *n) case DocNode::Kind_HtmlBlockQuote: /* \parblock */ case DocNode::Kind_ParBlock: + case DocNode::Kind_IncOperator: return TRUE; case DocNode::Kind_Verbatim: { @@ -126,21 +158,81 @@ static bool mustBeOutsideParagraph(DocNode *n) return FALSE; } -static QString htmlAttribsToString(const HtmlAttribList &attribs) +static bool isDocVerbatimVisible(DocVerbatim *s) +{ + switch(s->type()) + { + case DocVerbatim::ManOnly: + case DocVerbatim::LatexOnly: + case DocVerbatim::XmlOnly: + case DocVerbatim::RtfOnly: + case DocVerbatim::DocbookOnly: + return FALSE; + default: + return TRUE; + } +} + +static bool isDocIncludeVisible(DocInclude *s) +{ + switch (s->type()) + { + case DocInclude::DontInclude: + case DocInclude::LatexInclude: + return FALSE; + default: + return TRUE; + } +} + +static bool isDocIncOperatorVisible(DocIncOperator *s) +{ + switch (s->type()) + { + case DocIncOperator::Skip: + return FALSE; + default: + return TRUE; + } +} + +static bool isInvisibleNode(DocNode *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)) + ; +} + +static QString htmlAttribsToString(const HtmlAttribList &attribs, bool img_tag = FALSE) { QString result; HtmlAttribListIterator li(attribs); HtmlAttrib *att; + bool alt_set = FALSE; + for (li.toFirst();(att=li.current());++li) { if (!att->value.isEmpty()) // ignore attribute without values as they - // are not XHTML compliant + // are not XHTML compliant, with the exception + // of the alt attribute with the img tag { result+=" "; result+=att->name; result+="=\""+convertToXML(att->value)+"\""; + if (att->name == "alt") alt_set = TRUE; } } + if (!alt_set && img_tag) + { + result+=" alt=\"\""; + } return result; } @@ -201,6 +293,20 @@ void HtmlDocVisitor::visit(DocSymbol *s) } } +void HtmlDocVisitor::visit(DocEmoji *s) +{ + if (m_hide) return; + const char *res = EmojiEntityMapper::instance()->unicode(s->index()); + if (res) + { + m_t << res; + } + else + { + m_t << s->name(); + } +} + void HtmlDocVisitor::writeObfuscatedMailAddress(const QCString &url) { m_t << "<a href=\"#\" onclick=\"location.href='mai'+'lto:'"; @@ -263,6 +369,12 @@ void HtmlDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Bold: if (s->enable()) m_t << "<b" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</b>"; break; + case DocStyleChange::Strike: + if (s->enable()) m_t << "<strike" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</strike>"; + break; + case DocStyleChange::Underline: + if (s->enable()) m_t << "<u" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</u>"; + break; case DocStyleChange::Italic: if (s->enable()) m_t << "<em" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</em>"; break; @@ -349,7 +461,6 @@ static void visitCaption(HtmlDocVisitor *parent, QList<DocNode> children) for (cli.toFirst();(n=cli.current());++cli) n->accept(parent); } - void HtmlDocVisitor::visit(DocVerbatim *s) { if (m_hide) return; @@ -389,10 +500,12 @@ void HtmlDocVisitor::visit(DocVerbatim *s) m_t << "</pre>" /*<< PREFRAG_END*/; forceStartParagraph(s); break; - case DocVerbatim::HtmlOnly: - if (s->isBlock()) forceEndParagraph(s); - m_t << s->text(); - if (s->isBlock()) forceStartParagraph(s); + case DocVerbatim::HtmlOnly: + { + if (s->isBlock()) forceEndParagraph(s); + m_t << s->text(); + if (s->isBlock()) forceStartParagraph(s); + } break; case DocVerbatim::ManOnly: case DocVerbatim::LatexOnly: @@ -550,8 +663,12 @@ void HtmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::DontInclude: break; - case DocInclude::HtmlInclude: - m_t << inc->text(); + case DocInclude::HtmlInclude: + { + if (inc->isBlock()) forceEndParagraph(inc); + m_t << inc->text(); + if (inc->isBlock()) forceStartParagraph(inc); + } break; case DocInclude::LatexInclude: break; @@ -624,7 +741,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op) // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { - forceStartParagraph(op); + forceEndParagraph(op); if (!m_hide) m_t << PREFRAG_START; pushEnabled(); m_hide=TRUE; @@ -879,24 +996,24 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) } isFirst=isFirstChildNode((DocParBlock*)p->parent(),p); isLast =isLastChildNode ((DocParBlock*)p->parent(),p); - t=0; + t=NONE; if (isFirst) { if (kind==DocNode::Kind_HtmlListItem || kind==DocNode::Kind_SecRefItem) { - t=1; + t=STARTLI; } else if (kind==DocNode::Kind_HtmlDescData || kind==DocNode::Kind_XRefItem || kind==DocNode::Kind_SimpleSect) { - t=2; + t=STARTDD; } else if (kind==DocNode::Kind_HtmlCell || kind==DocNode::Kind_ParamList) { - t=5; + t=STARTTD; } } if (isLast) @@ -904,18 +1021,37 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) if (kind==DocNode::Kind_HtmlListItem || kind==DocNode::Kind_SecRefItem) { - t=3; + t=ENDLI; } else if (kind==DocNode::Kind_HtmlDescData || kind==DocNode::Kind_XRefItem || kind==DocNode::Kind_SimpleSect) { - t=4; + t=ENDDD; } else if (kind==DocNode::Kind_HtmlCell || kind==DocNode::Kind_ParamList) { - t=6; + 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; @@ -923,47 +1059,51 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) case DocNode::Kind_AutoListItem: isFirst=isFirstChildNode((DocAutoListItem*)p->parent(),p); isLast =isLastChildNode ((DocAutoListItem*)p->parent(),p); - t=1; // not used + t=STARTLI; // not used break; case DocNode::Kind_SimpleListItem: isFirst=TRUE; isLast =TRUE; - t=1; // not used + t=STARTLI; // not used break; case DocNode::Kind_ParamList: isFirst=TRUE; isLast =TRUE; - t=1; // not used + t=STARTLI; // not used break; case DocNode::Kind_HtmlListItem: isFirst=isFirstChildNode((DocHtmlListItem*)p->parent(),p); isLast =isLastChildNode ((DocHtmlListItem*)p->parent(),p); - if (isFirst) t=1; - if (isLast) t=3; + 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=1; - if (isLast) t=3; + 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=2; - if (isLast) t=4; + 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=2; - if (isLast) t=4; + 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=2; - if (isLast) t=4; + 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 @@ -971,12 +1111,14 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast) { 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=5; - if (isLast) t=6; + if (isFirst) t=STARTTD; + if (isLast) t=ENDTD; + if (!isFirst && !isLast) t = INTERTD; break; default: break; @@ -1028,8 +1170,7 @@ void HtmlDocVisitor::visitPre(DocPara *p) uint nodeIndex = 0; if (p && nodeIndex<p->children().count()) { - while (nodeIndex<p->children().count() && - p->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace) + while (nodeIndex<p->children().count() && isInvisibleNode(p->children().at(nodeIndex))) { nodeIndex++; } @@ -1044,19 +1185,10 @@ void HtmlDocVisitor::visitPre(DocPara *p) } } - // check if this paragraph is the first or last child of a <li> or <dd>. + // check if this paragraph is the first or last or intermediate child of a <li> or <dd>. // this allows us to mark the tag with a special class so we can // fix the otherwise ugly spacing. int t; - static const char *contexts[7] = - { "", // 0 - "startli", // 1 - "startdd", // 2 - "endli", // 3 - "enddd", // 4 - "starttd", // 5 - "endtd" // 6 - }; bool isFirst; bool isLast; t = getParagraphContext(p,isFirst,isLast); @@ -1106,7 +1238,7 @@ void HtmlDocVisitor::visitPost(DocPara *p) int nodeIndex = p->children().count()-1; if (nodeIndex>=0) { - while (nodeIndex>=0 && p->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace) + while (nodeIndex>=0 && isInvisibleNode(p->children().at(nodeIndex))) { nodeIndex--; } @@ -1477,7 +1609,22 @@ void HtmlDocVisitor::visitPre(DocImage *img) { if (img->type()==DocImage::Html) { - forceEndParagraph(img); + bool inlineImage = img->isInlineImage(); + bool typeSVG = FALSE; + + QCString url = img->url(); + if (url.isEmpty()) + { + typeSVG = (img->name().right(4)==".svg"); + } + else + { + typeSVG = (url.right(4)==".svg"); + } + if (!inlineImage) + { + forceEndParagraph(img); + } if (m_hide) return; QString baseName=img->name(); int i; @@ -1485,20 +1632,19 @@ void HtmlDocVisitor::visitPre(DocImage *img) { baseName=baseName.right(baseName.length()-i-1); } - m_t << "<div class=\"image\">" << endl; - QCString url = img->url(); + if (!inlineImage) m_t << "<div class=\"image\">" << endl; QCString sizeAttribs; if (!img->width().isEmpty()) { sizeAttribs+=" width=\""+img->width()+"\""; } - if (!img->height().isEmpty()) + if (!img->height().isEmpty()) // link to local file { sizeAttribs+=" height=\""+img->height()+"\""; } if (url.isEmpty()) { - if (img->name().right(4)==".svg") + if (typeSVG) { m_t << "<object type=\"image/svg+xml\" data=\"" << img->relPath() << img->name() << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) << ">" << baseName @@ -1508,27 +1654,39 @@ void HtmlDocVisitor::visitPre(DocImage *img) { m_t << "<img src=\"" << img->relPath() << img->name() << "\" alt=\"" << baseName << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) - << "/>" << endl; + << (inlineImage ? " class=\"inline\"" : "/>\n"); } } - else + else // link to URL { - if (url.right(4)==".svg") + if (typeSVG) { m_t << "<object type=\"image/svg+xml\" data=\"" << correctURL(url,img->relPath()) - << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) << "></object>" << endl; + << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) + << "></object>" << endl; } else { m_t << "<img src=\"" << correctURL(url,img->relPath()) << "\"" - << sizeAttribs << htmlAttribsToString(img->attribs()) - << "/>" << endl; + << sizeAttribs << htmlAttribsToString(img->attribs(), TRUE) + << (inlineImage ? " class=\"inline\"" : "/>\n"); } } if (img->hasCaption()) { - m_t << "<div class=\"caption\">" << endl; - m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img)); + if (inlineImage) + { + m_t << " title=\""; + } + else + { + m_t << "<div class=\"caption\">" << endl; + m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img)); + } + } + else if (inlineImage) + { + m_t << "/>" << endl; } } else // other format -> skip @@ -1538,17 +1696,24 @@ void HtmlDocVisitor::visitPre(DocImage *img) } } -void HtmlDocVisitor::visitPost(DocImage *img) +void HtmlDocVisitor::visitPost(DocImage *img) { if (img->type()==DocImage::Html) { if (m_hide) return; + bool inlineImage = img->isInlineImage(); if (img->hasCaption()) { - m_t << "</div>"; + if (inlineImage) + m_t << "\"/>\n "; + else + m_t << "</div>"; + } + if (!inlineImage) + { + m_t << "</div>" << endl; + forceStartParagraph(img); } - m_t << "</div>" << endl; - forceStartParagraph(img); } else // other format { @@ -2176,16 +2341,13 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n) int nodeIndex = para->children().findRef(n); nodeIndex--; if (nodeIndex<0) return; // first node - while (nodeIndex>=0 && - para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace - ) + while (nodeIndex>=0 && isInvisibleNode(para->children().at(nodeIndex))) { - nodeIndex--; + nodeIndex--; } if (nodeIndex>=0) { DocNode *n = para->children().at(nodeIndex); - //printf("n=%p kind=%d outside=%d\n",n,n->kind(),mustBeOutsideParagraph(n)); if (mustBeOutsideParagraph(n)) return; } nodeIndex--; @@ -2217,16 +2379,14 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n) if (styleOutsideParagraph) return; nodeIndex++; if (nodeIndex==numNodes) return; // last node - while (nodeIndex<numNodes && - para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace - ) + while (nodeIndex<numNodes && isInvisibleNode(para->children().at(nodeIndex))) { nodeIndex++; } if (nodeIndex<numNodes) { DocNode *n = para->children().at(nodeIndex); - if (mustBeOutsideParagraph(n)) return; + if (mustBeOutsideParagraph(n)) return; // next element also outside paragraph } else { @@ -2237,8 +2397,8 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n) bool isFirst; bool isLast; getParagraphContext(para,isFirst,isLast); - //printf("forceStart first=%d last=%d\n",isFirst,isLast); if (isFirst && isLast) needsTag = FALSE; + //printf("forceStart first=%d last=%d needsTag=%d\n",isFirst,isLast,needsTag); if (needsTag) m_t << "<p" << getDirHtmlClassOfNode(getTextDirByConfig(para, nodeIndex)) << ">"; diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h index 2ff9f75..7184f0f 100644 --- a/src/htmldocvisitor.h +++ b/src/htmldocvisitor.h @@ -43,6 +43,7 @@ class HtmlDocVisitor : public DocVisitor void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); diff --git a/src/htmlentity.cpp b/src/htmlentity.cpp index 3d95705..543f86b 100644 --- a/src/htmlentity.cpp +++ b/src/htmlentity.cpp @@ -314,7 +314,9 @@ static struct htmlEntityInfo { SYM(Quot), "\"", "\"", "\"", """, "\"", "\"", "\"", { "\"", DocSymbol::Perl_char }}, { SYM(Minus), "-", "-", "-", "-", "-\\/", "-", "-", { "-", DocSymbol::Perl_char }}, { SYM(Plus), "+", "+", "+", "+", "+", "+", "+", { "+", DocSymbol::Perl_char }}, - { SYM(Dot), ".", ".", ".", ".", ".", ".", ".", { ".", DocSymbol::Perl_char }} + { SYM(Dot), ".", ".", ".", ".", ".", ".", ".", { ".", DocSymbol::Perl_char }}, + { SYM(Colon), ":", ":", ":", ":", ":", ":", ":", { ":", DocSymbol::Perl_char }}, + { SYM(Equal), "=", "=", "=", "=", "=", "=", "=", { "=", DocSymbol::Perl_char }} }; static const int g_numHtmlEntities = (int)(sizeof(g_htmlEntities)/ sizeof(*g_htmlEntities)); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index cc3e61d..efd2108 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -17,6 +17,7 @@ #include <stdlib.h> +#include <assert.h> #include <qdir.h> #include <qregexp.h> #include "message.h" @@ -375,7 +376,7 @@ static QCString substituteHtmlKeywords(const QCString &s, mathJaxJs += "\n"; } mathJaxJs += "</script>"; - mathJaxJs += "<script type=\"text/javascript\" async src=\"" + path + "MathJax.js\"></script>\n"; + mathJaxJs += "<script type=\"text/javascript\" async=\"async\" src=\"" + path + "MathJax.js\"></script>\n"; } // first substitute generic keywords @@ -606,7 +607,7 @@ void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo, if (desc) { m_t << "<div class=\"ttdoc\">"; - docify(desc); // desc is already HTML escaped; but there are still < and > signs + docify(desc); m_t << "</div>"; } if (!defInfo.file.isEmpty()) @@ -690,6 +691,7 @@ HtmlGenerator::HtmlGenerator() : OutputGenerator() { dir=Config_getString(HTML_OUTPUT); m_emptySection=FALSE; + m_sectionCount=0; } HtmlGenerator::~HtmlGenerator() @@ -1117,7 +1119,8 @@ void HtmlGenerator::startIndexItem(const char *ref,const char *f) } t << "href=\""; t << externalRef(relPath,ref,TRUE); - if (f) t << f << Doxygen::htmlFileExtension << "\">"; + if (f) t << f << Doxygen::htmlFileExtension; + t << "\">"; } else { @@ -1381,20 +1384,34 @@ void HtmlGenerator::startClassDiagram() void HtmlGenerator::endClassDiagram(const ClassDiagram &d, const char *fileName,const char *name) { + QGString result; + FTextStream tt(&result); + endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); - t << " <div class=\"center\">" << endl; - t << " <img src=\""; - t << relPath << fileName << ".png\" usemap=\"#" << convertToId(name); - t << "_map\" alt=\"\"/>" << endl; - t << " <map id=\"" << convertToId(name); - t << "_map\" name=\"" << convertToId(name); - t << "_map\">" << endl; - - d.writeImage(t,dir,relPath,fileName); - t << " </div>"; + d.writeImage(tt,dir,relPath,fileName); + if (!result.isEmpty()) + { + t << " <div class=\"center\">" << endl; + t << " <img src=\""; + t << relPath << fileName << ".png\" usemap=\"#" << convertToId(name); + t << "_map\" alt=\"\"/>" << endl; + t << " <map id=\"" << convertToId(name); + t << "_map\" name=\"" << convertToId(name); + t << "_map\">" << endl; + t << result; + t << " </map>" << endl; + t << "</div>"; + } + else + { + t << " <div class=\"center\">" << endl; + t << " <img src=\""; + t << relPath << fileName << ".png\" alt=\"\"/>" << endl; + t << " </div>"; + } endSectionContent(t); m_sectionCount++; } @@ -1428,13 +1445,7 @@ void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char * t << " inherit " << inheritId; } t << "\">"; - switch(annoType) - { - case 0: t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break; - case 1: t << "<td class=\"memItemLeft\" >"; break; - case 2: t << "<td class=\"memItemLeft\" valign=\"top\">"; break; - default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break; - } + insertMemberAlignLeft(annoType, true); } void HtmlGenerator::endMemberItem() @@ -1466,7 +1477,19 @@ void HtmlGenerator::insertMemberAlign(bool templ) t << " </td><td class=\"" << className << "\" valign=\"bottom\">"; } -void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId) +void HtmlGenerator::insertMemberAlignLeft(int annoType, bool initTag) +{ + if (!initTag) t << " </td>"; + switch(annoType) + { + case 0: t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break; + case 1: t << "<td class=\"memItemLeft\" >"; break; + case 2: t << "<td class=\"memItemLeft\" valign=\"top\">"; break; + default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break; + } +} + +void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId, bool typ) { DBG_HTML(t << "<!-- startMemberDescription -->" << endl) if (m_emptySection) @@ -1479,7 +1502,10 @@ void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheri { t << " inherit " << inheritId; } - t << "\"><td class=\"mdescLeft\"> </td><td class=\"mdescRight\">"; + t << "\">"; + t << "<td class=\"mdescLeft\"> </td>"; + if (typ) t << "<td class=\"mdescLeft\"> </td>"; + t << "<td class=\"mdescRight\">";; } void HtmlGenerator::endMemberDescription() @@ -1505,7 +1531,7 @@ void HtmlGenerator::endMemberSections() } } -void HtmlGenerator::startMemberHeader(const char *anchor) +void HtmlGenerator::startMemberHeader(const char *anchor, int typ) { DBG_HTML(t << "<!-- startMemberHeader -->" << endl) if (!m_emptySection) @@ -1518,7 +1544,7 @@ void HtmlGenerator::startMemberHeader(const char *anchor) t << "<table class=\"memberdecls\">" << endl; m_emptySection=FALSE; } - t << "<tr class=\"heading\"><td colspan=\"2\"><h2 class=\"groupheader\">"; + t << "<tr class=\"heading\"><td colspan=\"" << typ << "\"><h2 class=\"groupheader\">"; if (anchor) { t << "<a name=\"" << anchor << "\"></a>" << endl; @@ -1933,25 +1959,16 @@ void HtmlGenerator::endDescTableData() t << "</td>"; } -void HtmlGenerator::startSimpleSect(SectionTypes, - const char *filename,const char *anchor, - const char *title) +void HtmlGenerator::startExamples() { - t << "<dl><dt><b>"; - if (filename) - { - writeObjectLink(0,filename,anchor,title); - } - else - { - docify(title); - } - t << "</b></dt>"; + t << "<dl class=\"section examples\"><dt>"; + docify(theTranslator->trExamples()); + t << "</dt>"; } -void HtmlGenerator::endSimpleSect() +void HtmlGenerator::endExamples() { - t << "</dl>"; + t << "</dl>" << endl; } void HtmlGenerator::startParamList(ParamListTypes, @@ -2036,24 +2053,37 @@ static bool quickLinkVisible(LayoutNavEntry::Kind kind) static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); switch (kind) { - case LayoutNavEntry::MainPage: return TRUE; - case LayoutNavEntry::User: return TRUE; - case LayoutNavEntry::UserGroup: return TRUE; - case LayoutNavEntry::Pages: return indexedPages>0; - case LayoutNavEntry::Modules: return documentedGroups>0; - case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces; - case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces; - case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0; - case LayoutNavEntry::Classes: return annotatedClasses>0; - case LayoutNavEntry::ClassList: return annotatedClasses>0; - case LayoutNavEntry::ClassIndex: return annotatedClasses>0; - case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0; - case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0; - case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles; - case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles; - case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; - //case LayoutNavEntry::Dirs: return documentedDirs>0; - case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0; + case LayoutNavEntry::MainPage: return TRUE; + case LayoutNavEntry::User: return TRUE; + case LayoutNavEntry::UserGroup: return TRUE; + case LayoutNavEntry::Pages: return indexedPages>0; + case LayoutNavEntry::Modules: return documentedGroups>0; + case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces; + case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces; + case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0; + case LayoutNavEntry::Classes: return annotatedClasses>0; + case LayoutNavEntry::ClassList: return annotatedClasses>0; + case LayoutNavEntry::ClassIndex: return annotatedClasses>0; + case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0; + case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0; + case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles; + case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles; + case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; + case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0; + case LayoutNavEntry::Interfaces: return annotatedInterfaces>0; + case LayoutNavEntry::InterfaceList: return annotatedInterfaces>0; + case LayoutNavEntry::InterfaceIndex: return annotatedInterfaces>0; + case LayoutNavEntry::InterfaceHierarchy: return hierarchyInterfaces>0; + case LayoutNavEntry::Structs: return annotatedStructs>0; + case LayoutNavEntry::StructList: return annotatedStructs>0; + case LayoutNavEntry::StructIndex: return annotatedStructs>0; + case LayoutNavEntry::Exceptions: return annotatedExceptions>0; + case LayoutNavEntry::ExceptionList: return annotatedExceptions>0; + case LayoutNavEntry::ExceptionIndex: return annotatedExceptions>0; + case LayoutNavEntry::ExceptionHierarchy: return hierarchyExceptions>0; + case LayoutNavEntry::None: // should never happen, means not properly initialized + assert(kind != LayoutNavEntry::None); + return FALSE; } return FALSE; } @@ -2179,9 +2209,17 @@ static void writeDefaultQuickLinks(FTextStream &t,bool compact, case HLI_Modules: kind = LayoutNavEntry::Modules; break; //case HLI_Directories: kind = LayoutNavEntry::Dirs; break; case HLI_Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break; - case HLI_Hierarchy: kind = LayoutNavEntry::ClassHierarchy; break; + case HLI_ClassHierarchy: kind = LayoutNavEntry::ClassHierarchy; break; + case HLI_InterfaceHierarchy: kind = LayoutNavEntry::InterfaceHierarchy; break; + case HLI_ExceptionHierarchy: kind = LayoutNavEntry::ExceptionHierarchy; break; case HLI_Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break; - case HLI_Annotated: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break; + case HLI_Interfaces: kind = LayoutNavEntry::InterfaceIndex; altKind = LayoutNavEntry::Interfaces; break; + case HLI_Structs: kind = LayoutNavEntry::StructIndex; altKind = LayoutNavEntry::Structs; break; + case HLI_Exceptions: kind = LayoutNavEntry::ExceptionIndex; altKind = LayoutNavEntry::Exceptions; break; + case HLI_AnnotatedClasses: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break; + case HLI_AnnotatedInterfaces: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces; break; + case HLI_AnnotatedStructs: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs; break; + case HLI_AnnotatedExceptions: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions; break; case HLI_Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break; case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break; case HLI_Functions: kind = LayoutNavEntry::ClassMembers; break; @@ -2191,6 +2229,12 @@ static void writeDefaultQuickLinks(FTextStream &t,bool compact, case HLI_UserGroup: kind = LayoutNavEntry::UserGroup; break; case HLI_ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; highlightParent = TRUE; break; + case HLI_InterfaceVisible: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces; + highlightParent = TRUE; break; + case HLI_StructVisible: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs; + highlightParent = TRUE; break; + case HLI_ExceptionVisible: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions; + highlightParent = TRUE; break; case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; highlightParent = TRUE; break; case HLI_FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; @@ -2354,7 +2398,7 @@ void HtmlGenerator::writeSearchPage() if (cf.open(IO_WriteOnly)) { FTextStream t(&cf); - t << "<script language=\"php\">\n\n"; + t << "<?php\n\n"; t << "$config = array(\n"; t << " 'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n"; t << " 'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n"; @@ -2372,7 +2416,7 @@ void HtmlGenerator::writeSearchPage() t << " 'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n"; t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n"; t << ");\n\n"; - t << "</script>\n"; + t << "?>\n"; } ResourceMgr::instance().copyResource("search_functions.php",htmlOutput); @@ -2403,10 +2447,10 @@ void HtmlGenerator::writeSearchPage() t << "</div>" << endl; } - t << "<script language=\"php\">\n"; + t << "<?php\n"; t << "require_once \"search_functions.php\";\n"; t << "main();\n"; - t << "</script>\n"; + t << "?>\n"; // Write empty navigation path, to make footer connect properly if (generateTreeView) @@ -2708,13 +2752,16 @@ void HtmlGenerator::writeInheritedSectionTitle( DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;) QCString a = anchor; if (!a.isEmpty()) a.prepend("#"); - QCString classLink = QCString("<a class=\"el\" href=\""); + QCString classLink = QCString("<a class=\"el\" "); if (ref) { - classLink+= externalLinkTarget() + externalRef(relPath,ref,TRUE); + classLink+= externalLinkTarget(); + classLink += " href=\""; + classLink+= externalRef(relPath,ref,TRUE); } else { + classLink += "href=\""; classLink+=relPath; } classLink+=file+Doxygen::htmlFileExtension+a; diff --git a/src/htmlgen.h b/src/htmlgen.h index 82f0c17..221269f 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -175,7 +175,7 @@ class HtmlGenerator : public OutputGenerator void endMemberSections(); void startHeaderSection(); void endHeaderSection(); - void startMemberHeader(const char *); + void startMemberHeader(const char *, int); void endMemberHeader(); void startMemberSubtitle(); void endMemberSubtitle(); @@ -200,7 +200,8 @@ class HtmlGenerator : public OutputGenerator void endMemberGroup(bool); void insertMemberAlign(bool); - void startMemberDescription(const char *anchor,const char *inheritId); + void insertMemberAlignLeft(int,bool); + void startMemberDescription(const char *anchor,const char *inheritId, bool typ); void endMemberDescription(); void startMemberDeclaration() {} void endMemberDeclaration(const char *anchor,const char *inheritId); @@ -245,13 +246,10 @@ class HtmlGenerator : public OutputGenerator void endCenter() { t << "</center>" << endl; } void startSmall() { t << "<small>" << endl; } void endSmall() { t << "</small>" << endl; } - //void startDescList(SectionTypes) { t << "<dl compact><dt><b>" << endl; } - //void endDescList() { t << "</dl>"; } - void startSimpleSect(SectionTypes,const char *,const char *,const char *); - void endSimpleSect(); + void startExamples(); + void endExamples(); void startParamList(ParamListTypes,const char *); void endParamList(); - //void writeDescItem() { t << "<dd>" << endl; } void startSection(const char *,const char *,SectionInfo::SectionType); void endSection(const char *,SectionInfo::SectionType); void addIndexItem(const char *,const char *); diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index ad56de8..3ed3d64 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -115,7 +115,7 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2, { return; } - if (dict->find(key)==0) // new key + if (dict->find(key+anchor)==0) // new key { //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n", // level1,level2,url,anchor); @@ -125,7 +125,7 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2, f->anchor = anchor; f->link = hasLink; f->reversed = reversed; - dict->append(key,f); + dict->append(key+anchor,f); } } @@ -187,7 +187,7 @@ void HtmlHelpIndex::writeFields(FTextStream &t) level1 = f->name.copy(); } - if (level1!=lastLevel1) + //if (level1!=lastLevel1) { // finish old list at level 2 if (level2Started) t << " </UL>" << endl; level2Started=FALSE; diff --git a/src/index.cpp b/src/index.cpp index 24c0290..7bb9574 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -21,6 +21,7 @@ #include <stdlib.h> +#include <assert.h> #include <qtextstream.h> #include <qdatetime.h> #include <qdir.h> @@ -55,6 +56,14 @@ int annotatedClasses; int annotatedClassesPrinted; int hierarchyClasses; +int annotatedInterfaces; +int annotatedInterfacesPrinted; +int hierarchyInterfaces; +int annotatedStructs; +int annotatedStructsPrinted; +int annotatedExceptions; +int annotatedExceptionsPrinted; +int hierarchyExceptions; int documentedFiles; int documentedGroups; int documentedNamespaces; @@ -66,23 +75,34 @@ int documentedHtmlFiles; int documentedPages; int documentedDirs; -static int countClassHierarchy(); +static int countClassHierarchy(ClassDef::CompoundType ct); static void countFiles(int &htmlFiles,int &files); static int countGroups(); static int countDirs(); static int countNamespaces(); -static int countAnnotatedClasses(int *cp); +static int countAnnotatedClasses(int *cp,ClassDef::CompoundType ct); static void countRelatedPages(int &docPages,int &indexPages); void countDataStructures() { - annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated" - hierarchyClasses = countClassHierarchy(); // "hierarchy" - countFiles(documentedHtmlFiles,documentedFiles); // "files" - countRelatedPages(documentedPages,indexedPages); // "pages" - documentedGroups = countGroups(); // "modules" - documentedNamespaces = countNamespaces(); // "namespaces" - documentedDirs = countDirs(); // "dirs" + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted, ClassDef::Class); // "classes" + "annotated" + hierarchyClasses = countClassHierarchy(ClassDef::Class); // "hierarchy" + // "interfaces" + "annotated" + annotatedInterfaces = sliceOpt ? countAnnotatedClasses(&annotatedInterfacesPrinted, ClassDef::Interface) : 0; + // "interfacehierarchy" + hierarchyInterfaces = sliceOpt ? countClassHierarchy(ClassDef::Interface) : 0; + // "structs" + "annotated" + annotatedStructs = sliceOpt ? countAnnotatedClasses(&annotatedStructsPrinted, ClassDef::Struct) : 0; + // "exceptions" + "annotated" + annotatedExceptions = sliceOpt ? countAnnotatedClasses(&annotatedExceptionsPrinted, ClassDef::Exception) : 0; + // "exceptionhierarchy" + hierarchyExceptions = sliceOpt ? countClassHierarchy(ClassDef::Exception) : 0; + countFiles(documentedHtmlFiles,documentedFiles); // "files" + countRelatedPages(documentedPages,indexedPages); // "pages" + documentedGroups = countGroups(); // "modules" + documentedNamespaces = countNamespaces(); // "namespaces" + documentedDirs = countDirs(); // "dirs" // "globals" // "namespacemembers" // "functions" @@ -94,9 +114,12 @@ static void startIndexHierarchy(OutputList &ol,int level) ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Html); if (level<6) ol.startIndexList(); - ol.enableAll(); + ol.popGeneratorState(); + + ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); + ol.disable(OutputGenerator::Docbook); ol.startItemList(); ol.popGeneratorState(); } @@ -107,8 +130,11 @@ static void endIndexHierarchy(OutputList &ol,int level) ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Html); if (level<6) ol.endIndexList(); - ol.enableAll(); + ol.popGeneratorState(); + + ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); ol.disable(OutputGenerator::RTF); ol.endItemList(); ol.popGeneratorState(); @@ -798,8 +824,10 @@ static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) //---------------------------------------------------------------------------- -static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex) +static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex, + ClassDef::CompoundType ct) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); ClassSDict::Iterator cli(*cl); ClassDef *cd; for (;(cd=cli.current());++cli) @@ -818,6 +846,10 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FT } b=!hasVisibleRoot(cd->subClasses()); } + else if (sliceOpt && cd->compoundType() != ct) + { + continue; + } else { b=!hasVisibleRoot(cd->baseClasses()); @@ -892,7 +924,7 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FT } } -static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) +static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex,ClassDef::CompoundType ct) { initClassHierarchy(Doxygen::classSDict); initClassHierarchy(Doxygen::hiddenClasses); @@ -902,8 +934,8 @@ static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) ol.disable(OutputGenerator::Html); } bool started=FALSE; - writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex); - writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex); + writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex,ct); + writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex,ct); if (started) { endIndexHierarchy(ol,0); @@ -920,13 +952,18 @@ static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) //---------------------------------------------------------------------------- -static int countClassesInTreeList(const ClassSDict &cl) +static int countClassesInTreeList(const ClassSDict &cl, ClassDef::CompoundType ct) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); int count=0; ClassSDict::Iterator cli(cl); ClassDef *cd; for (;(cd=cli.current());++cli) { + if (sliceOpt && cd->compoundType() != ct) + { + continue; + } if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes { if (cd->isVisibleInHierarchy()) // should it be visible @@ -941,13 +978,13 @@ static int countClassesInTreeList(const ClassSDict &cl) return count; } -static int countClassHierarchy() +static int countClassHierarchy(ClassDef::CompoundType ct) { int count=0; initClassHierarchy(Doxygen::classSDict); initClassHierarchy(Doxygen::hiddenClasses); - count+=countClassesInTreeList(*Doxygen::classSDict); - count+=countClassesInTreeList(*Doxygen::hiddenClasses); + count+=countClassesInTreeList(*Doxygen::classSDict, ct); + count+=countClassesInTreeList(*Doxygen::hiddenClasses, ct); return count; } @@ -959,12 +996,13 @@ static void writeHierarchicalIndex(OutputList &ol) ol.pushGeneratorState(); //1.{ ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy); QCString title = lne ? lne->title() : theTranslator->trClassHierarchy(); bool addToIndex = lne==0 || lne->visible(); - startFile(ol,"hierarchy",0, title, HLI_Hierarchy); + startFile(ol,"hierarchy",0, title, HLI_ClassHierarchy); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); @@ -973,15 +1011,16 @@ static void writeHierarchicalIndex(OutputList &ol) if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) { + ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); + ol.disable(OutputGenerator::Docbook); ol.startParagraph(); ol.startTextLink("inherits",0); ol.parseText(theTranslator->trGotoGraphicalHierarchy()); ol.endTextLink(); ol.endParagraph(); - ol.enable(OutputGenerator::Latex); - ol.enable(OutputGenerator::RTF); + ol.popGeneratorState(); } ol.parseText(lne ? lne->intro() : theTranslator->trClassHierarchyDescription()); ol.endTextBlock(); @@ -994,7 +1033,7 @@ static void writeHierarchicalIndex(OutputList &ol) ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); - writeClassHierarchy(ol,0,addToIndex); + writeClassHierarchy(ol,0,addToIndex,ClassDef::Class); Doxygen::indexList->enable(); ol.popGeneratorState(); @@ -1013,7 +1052,7 @@ static void writeHierarchicalIndex(OutputList &ol) Doxygen::indexList->addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE); } FTVHelp* ftv = new FTVHelp(FALSE); - writeClassHierarchy(ol,ftv,addToIndex); + writeClassHierarchy(ol,ftv,addToIndex,ClassDef::Class); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); @@ -1040,7 +1079,7 @@ static void writeGraphicalClassHierarchy(OutputList &ol) ol.disableAllBut(OutputGenerator::Html); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy); QCString title = lne ? lne->title() : theTranslator->trClassHierarchy(); - startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy"); + startFile(ol,"inherits",0,title,HLI_ClassHierarchy,FALSE,"hierarchy"); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); @@ -1060,6 +1099,220 @@ static void writeGraphicalClassHierarchy(OutputList &ol) //---------------------------------------------------------------------------- +static void writeHierarchicalInterfaceIndex(OutputList &ol) +{ + if (hierarchyInterfaces==0) return; + ol.pushGeneratorState(); + //1.{ + ol.disable(OutputGenerator::Man); + + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::InterfaceHierarchy); + QCString title = lne ? lne->title() : theTranslator->trInterfaceHierarchy(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"interfacehierarchy",0, title, HLI_InterfaceHierarchy); + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + ol.startContents(); + ol.startTextBlock(); + + if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) + { + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + ol.startParagraph(); + ol.startTextLink("interfaceinherits",0); + ol.parseText(theTranslator->trGotoGraphicalHierarchy()); + ol.endTextLink(); + ol.endParagraph(); + ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::RTF); + } + ol.parseText(lne ? lne->intro() : theTranslator->trInterfaceHierarchyDescription()); + ol.endTextBlock(); + + // --------------- + // Static interface hierarchy for Latex/RTF + // --------------- + ol.pushGeneratorState(); + //2.{ + ol.disable(OutputGenerator::Html); + Doxygen::indexList->disable(); + + writeClassHierarchy(ol,0,addToIndex,ClassDef::Interface); + + Doxygen::indexList->enable(); + ol.popGeneratorState(); + //2.} + + // --------------- + // Dynamic interface hierarchical index for HTML + // --------------- + ol.pushGeneratorState(); + //2.{ + ol.disableAllBut(OutputGenerator::Html); + + { + if (addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,title,0,"interfacehierarchy",0,TRUE,TRUE); + } + FTVHelp* ftv = new FTVHelp(FALSE); + writeClassHierarchy(ol,ftv,addToIndex,ClassDef::Interface); + QGString outStr; + FTextStream t(&outStr); + ftv->generateTreeViewInline(t); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + ol.writeString(outStr); + ol.popGeneratorState(); + delete ftv; + } + ol.popGeneratorState(); + //2.} + // ------ + + endFile(ol); + ol.popGeneratorState(); + //1.} +} + +//---------------------------------------------------------------------------- + +static void writeGraphicalInterfaceHierarchy(OutputList &ol) +{ + if (hierarchyInterfaces==0) return; + ol.disableAllBut(OutputGenerator::Html); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::InterfaceHierarchy); + QCString title = lne ? lne->title() : theTranslator->trInterfaceHierarchy(); + startFile(ol,"interfaceinherits",0,title,HLI_InterfaceHierarchy,FALSE,"interfacehierarchy"); + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + ol.startContents(); + ol.startTextBlock(); + ol.startParagraph(); + ol.startTextLink("interfacehierarchy",0); + ol.parseText(theTranslator->trGotoTextualHierarchy()); + ol.endTextLink(); + ol.endParagraph(); + ol.endTextBlock(); + DotGfxHierarchyTable g("interface_",ClassDef::Interface); + ol.writeGraphicalHierarchy(g); + endFile(ol); + ol.enableAll(); +} + +//---------------------------------------------------------------------------- + +static void writeHierarchicalExceptionIndex(OutputList &ol) +{ + if (hierarchyExceptions==0) return; + ol.pushGeneratorState(); + //1.{ + ol.disable(OutputGenerator::Man); + + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ExceptionHierarchy); + QCString title = lne ? lne->title() : theTranslator->trExceptionHierarchy(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"exceptionhierarchy",0, title, HLI_ExceptionHierarchy); + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + ol.startContents(); + ol.startTextBlock(); + + if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) + { + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + ol.startParagraph(); + ol.startTextLink("exceptioninherits",0); + ol.parseText(theTranslator->trGotoGraphicalHierarchy()); + ol.endTextLink(); + ol.endParagraph(); + ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::RTF); + } + ol.parseText(lne ? lne->intro() : theTranslator->trExceptionHierarchyDescription()); + ol.endTextBlock(); + + // --------------- + // Static exception hierarchy for Latex/RTF + // --------------- + ol.pushGeneratorState(); + //2.{ + ol.disable(OutputGenerator::Html); + Doxygen::indexList->disable(); + + writeClassHierarchy(ol,0,addToIndex,ClassDef::Exception); + + Doxygen::indexList->enable(); + ol.popGeneratorState(); + //2.} + + // --------------- + // Dynamic exception hierarchical index for HTML + // --------------- + ol.pushGeneratorState(); + //2.{ + ol.disableAllBut(OutputGenerator::Html); + + { + if (addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,title,0,"exceptionhierarchy",0,TRUE,TRUE); + } + FTVHelp* ftv = new FTVHelp(FALSE); + writeClassHierarchy(ol,ftv,addToIndex,ClassDef::Exception); + QGString outStr; + FTextStream t(&outStr); + ftv->generateTreeViewInline(t); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + ol.writeString(outStr); + ol.popGeneratorState(); + delete ftv; + } + ol.popGeneratorState(); + //2.} + // ------ + + endFile(ol); + ol.popGeneratorState(); + //1.} +} + +//---------------------------------------------------------------------------- + +static void writeGraphicalExceptionHierarchy(OutputList &ol) +{ + if (hierarchyExceptions==0) return; + ol.disableAllBut(OutputGenerator::Html); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ExceptionHierarchy); + QCString title = lne ? lne->title() : theTranslator->trExceptionHierarchy(); + startFile(ol,"exceptioninherits",0,title,HLI_ExceptionHierarchy,FALSE,"exceptionhierarchy"); + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + ol.startContents(); + ol.startTextBlock(); + ol.startParagraph(); + ol.startTextLink("exceptionhierarchy",0); + ol.parseText(theTranslator->trGotoTextualHierarchy()); + ol.endTextLink(); + ol.endParagraph(); + ol.endTextBlock(); + DotGfxHierarchyTable g("exception_",ClassDef::Exception); + ol.writeGraphicalHierarchy(g); + endFile(ol); + ol.enableAll(); +} + +//---------------------------------------------------------------------------- + static void countFiles(int &htmlFiles,int &files) { htmlFiles=0; @@ -1170,6 +1423,7 @@ static void writeFileIndex(OutputList &ol) ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileList); @@ -1317,8 +1571,9 @@ static int countNamespaces() //---------------------------------------------------------------------------- -void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly) +void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly,ClassDef::CompoundType ct) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (clDict) { ClassSDict::Iterator cli(*clDict); @@ -1340,6 +1595,11 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO } } + if (sliceOpt && cd->compoundType() != ct) + { + continue; + } + if (!globalOnly || cd->getOuterScope()==0 || cd->getOuterScope()==Doxygen::globalScope @@ -1377,7 +1637,7 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO if (count>0) { ftv->incContentsDepth(); - writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE); + writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE,ct); ftv->decContentsDepth(); } } @@ -1387,8 +1647,9 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO } static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv, - bool rootOnly,bool showClasses,bool addToIndex) + bool rootOnly,bool showClasses,bool addToIndex,ClassDef::CompoundType ct) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (nsDict) { NamespaceSDict::Iterator nli(*nsDict); @@ -1399,7 +1660,7 @@ static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv, (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { - bool hasChildren = namespaceHasVisibleChild(nd,showClasses); + bool hasChildren = namespaceHasVisibleChild(nd,showClasses,sliceOpt,ct); bool isLinkable = nd->isLinkableInProject(); QCString ref; @@ -1430,10 +1691,26 @@ static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv, { if (addToIndex) Doxygen::indexList->incContentsDepth(); ftv->incContentsDepth(); - writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex); + writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex,ct); if (showClasses) { - writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE); + ClassSDict *d = nd->getClassSDict(); + if (sliceOpt) + { + if (ct == ClassDef::Interface) + { + d = nd->getInterfaceSDict(); + } + else if (ct == ClassDef::Struct) + { + d = nd->getStructSDict(); + } + else if (ct == ClassDef::Exception) + { + d = nd->getExceptionSDict(); + } + } + writeClassTree(d,ftv,addToIndex,FALSE,ct); } ftv->decContentsDepth(); if (addToIndex) Doxygen::indexList->decContentsDepth(); @@ -1450,6 +1727,7 @@ static void writeNamespaceIndex(OutputList &ol) if (documentedNamespaces==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceList); if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces); // fall back QCString title = lne ? lne->title() : theTranslator->trNamespaceList(); @@ -1532,7 +1810,7 @@ static void writeNamespaceIndex(OutputList &ol) Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex,ClassDef::Class); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); @@ -1553,14 +1831,19 @@ static void writeNamespaceIndex(OutputList &ol) //---------------------------------------------------------------------------- -static int countAnnotatedClasses(int *cp) +static int countAnnotatedClasses(int *cp, ClassDef::CompoundType ct) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); int count=0; int countPrinted=0; ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for (;(cd=cli.current());++cli) { + if (sliceOpt && cd->compoundType() != ct) + { + continue; + } if (cd->isLinkableInProject() && cd->templateMaster()==0) { if (!cd->isEmbeddedInOuterScope()) @@ -1575,12 +1858,14 @@ static int countAnnotatedClasses(int *cp) } -static void writeAnnotatedClassList(OutputList &ol) +static void writeAnnotatedClassList(OutputList &ol,ClassDef::CompoundType ct) { //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList); //bool addToIndex = lne==0 || lne->visible(); + bool first=TRUE; + + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); - ol.startIndexList(); ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; @@ -1593,11 +1878,22 @@ static void writeAnnotatedClassList(OutputList &ol) { continue; } + if (first) + { + ol.startIndexList(); + first=FALSE; + } + + if (sliceOpt && cd->compoundType() != ct) + { + continue; + } ol.pushGeneratorState(); if (cd->isEmbeddedInOuterScope()) { ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); ol.disable(OutputGenerator::RTF); } if (cd->isLinkableInProject() && cd->templateMaster()==0) @@ -1635,7 +1931,7 @@ static void writeAnnotatedClassList(OutputList &ol) } ol.popGeneratorState(); } - ol.endIndexList(); + if (!first) ol.endIndexList(); } inline bool isId1(int c) @@ -1763,8 +2059,10 @@ class UsedIndexLetters : public SIntDict<uint> }; // write an alphabetical index of all class with a header for each letter -static void writeAlphabeticalClassList(OutputList &ol) +static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct, int annotatedCount) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + // What starting letters are used UsedIndexLetters indexLettersUsed; @@ -1775,6 +2073,8 @@ static void writeAlphabeticalClassList(OutputList &ol) int headerItems=0; for (;(cd=cli.current());++cli) { + if (sliceOpt && cd->compoundType() != ct) + continue; if (cd->isLinkableInProject() && cd->templateMaster()==0) { if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture @@ -1810,7 +2110,7 @@ static void writeAlphabeticalClassList(OutputList &ol) const int columns = Config_getInt(COLS_IN_ALPHA_INDEX); int i,j; - int totalItems = headerItems*2 + annotatedClasses; // number of items in the table (headers span 2 items) + int totalItems = headerItems*2 + annotatedCount; // number of items in the table (headers span 2 items) int rows = (totalItems + columns - 1)/columns; // number of rows in the table //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n", @@ -1827,6 +2127,8 @@ static void writeAlphabeticalClassList(OutputList &ol) startLetter=0; for (cli.toFirst();(cd=cli.current());++cli) { + if (sliceOpt && cd->compoundType() != ct) + continue; if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture continue; @@ -1982,11 +2284,12 @@ static void writeAlphabeticalClassList(OutputList &ol) } ol.writeNonBreakableSpace(3); } - ++(*colIterators[j]); - if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8) - { - ol.writeString("</td>"); + else + { + ol.writeString("<td>"); } + ++(*colIterators[j]); + ol.writeString("</td>"); } } else @@ -2032,7 +2335,94 @@ static void writeAlphabeticalIndex(OutputList &ol) } ol.startContents(); - writeAlphabeticalClassList(ol); + writeAlphabeticalClassList(ol, ClassDef::Class, annotatedClasses); + endFile(ol); // contains ol.endContents() + + ol.popGeneratorState(); +} + +//---------------------------------------------------------------------------- + +static void writeAlphabeticalInterfaceIndex(OutputList &ol) +{ + if (annotatedInterfaces==0) return; + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::InterfaceIndex); + QCString title = lne ? lne->title() : theTranslator->trInterfaceIndex(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"interfaces",0,title,HLI_Interfaces); + + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + + if (addToIndex) + { + Doxygen::indexList->addContentsItem(FALSE,title,0,"interfaces",0,FALSE,TRUE); + } + + ol.startContents(); + writeAlphabeticalClassList(ol, ClassDef::Interface, annotatedInterfaces); + endFile(ol); // contains ol.endContents() + + ol.popGeneratorState(); +} + +//---------------------------------------------------------------------------- + +static void writeAlphabeticalStructIndex(OutputList &ol) +{ + if (annotatedStructs==0) return; + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::StructIndex); + QCString title = lne ? lne->title() : theTranslator->trStructIndex(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"structs",0,title,HLI_Structs); + + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + + if (addToIndex) + { + Doxygen::indexList->addContentsItem(FALSE,title,0,"structs",0,FALSE,TRUE); + } + + ol.startContents(); + writeAlphabeticalClassList(ol, ClassDef::Struct, annotatedStructs); + endFile(ol); // contains ol.endContents() + + ol.popGeneratorState(); +} + +//---------------------------------------------------------------------------- + +static void writeAlphabeticalExceptionIndex(OutputList &ol) +{ + if (annotatedExceptions==0) return; + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ExceptionIndex); + QCString title = lne ? lne->title() : theTranslator->trExceptionIndex(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"exceptions",0,title,HLI_Exceptions); + + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + + if (addToIndex) + { + Doxygen::indexList->addContentsItem(FALSE,title,0,"exceptions",0,FALSE,TRUE); + } + + ol.startContents(); + writeAlphabeticalClassList(ol, ClassDef::Exception, annotatedExceptions); endFile(ol); // contains ol.endContents() ol.popGeneratorState(); @@ -2059,7 +2449,7 @@ static void writeAnnotatedIndex(OutputList &ol) bool addToIndex = lne==0 || lne->visible(); - startFile(ol,"annotated",0,title,HLI_Annotated); + startFile(ol,"annotated",0,title,HLI_AnnotatedClasses); startTitle(ol,0); ol.parseText(title); @@ -2078,7 +2468,7 @@ static void writeAnnotatedIndex(OutputList &ol) ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); - writeAnnotatedClassList(ol); + writeAnnotatedClassList(ol, ClassDef::Class); Doxygen::indexList->enable(); ol.popGeneratorState(); @@ -2096,8 +2486,239 @@ static void writeAnnotatedIndex(OutputList &ol) Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Class); + writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Class); + QGString outStr; + FTextStream t(&outStr); + ftv->generateTreeViewInline(t); + ol.writeString(outStr); + delete ftv; + if (addToIndex) + { + Doxygen::indexList->decContentsDepth(); + } + } + + ol.popGeneratorState(); + // ------ + + endFile(ol); // contains ol.endContents() + ol.popGeneratorState(); +} + +//---------------------------------------------------------------------------- + +static void writeAnnotatedInterfaceIndex(OutputList &ol) +{ + //printf("writeAnnotatedInterfaceIndex: count=%d printed=%d\n", + // annotatedInterfaces,annotatedInterfacesPrinted); + if (annotatedInterfaces==0) return; + + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + if (annotatedInterfacesPrinted==0) + { + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + } + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::InterfaceList); + if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Interfaces); // fall back + QCString title = lne ? lne->title() : theTranslator->trInterfaceList(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"annotatedinterfaces",0,title,HLI_AnnotatedInterfaces); + + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + + ol.startContents(); + + ol.startTextBlock(); + ol.parseText(lne ? lne->intro() : theTranslator->trInterfaceListDescription()); + ol.endTextBlock(); + + // --------------- + // Linear interface index for Latex/RTF + // --------------- + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Html); + Doxygen::indexList->disable(); + + writeAnnotatedClassList(ol, ClassDef::Interface); + + Doxygen::indexList->enable(); + ol.popGeneratorState(); + + // --------------- + // Hierarchical interface index for HTML + // --------------- + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + + { + if (addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedinterfaces",0,TRUE,TRUE); + Doxygen::indexList->incContentsDepth(); + } + FTVHelp* ftv = new FTVHelp(FALSE); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Interface); + writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Interface); + QGString outStr; + FTextStream t(&outStr); + ftv->generateTreeViewInline(t); + ol.writeString(outStr); + delete ftv; + if (addToIndex) + { + Doxygen::indexList->decContentsDepth(); + } + } + + ol.popGeneratorState(); + // ------ + + endFile(ol); // contains ol.endContents() + ol.popGeneratorState(); +} + +//---------------------------------------------------------------------------- + +static void writeAnnotatedStructIndex(OutputList &ol) +{ + //printf("writeAnnotatedStructIndex: count=%d printed=%d\n", + // annotatedStructs,annotatedStructsPrinted); + if (annotatedStructs==0) return; + + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + if (annotatedStructsPrinted==0) + { + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + } + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::StructList); + if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Structs); // fall back + QCString title = lne ? lne->title() : theTranslator->trStructList(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"annotatedstructs",0,title,HLI_AnnotatedStructs); + + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + + ol.startContents(); + + ol.startTextBlock(); + ol.parseText(lne ? lne->intro() : theTranslator->trStructListDescription()); + ol.endTextBlock(); + + // --------------- + // Linear struct index for Latex/RTF + // --------------- + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Html); + Doxygen::indexList->disable(); + + writeAnnotatedClassList(ol, ClassDef::Struct); + + Doxygen::indexList->enable(); + ol.popGeneratorState(); + + // --------------- + // Hierarchical struct index for HTML + // --------------- + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + + { + if (addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedstructs",0,TRUE,TRUE); + Doxygen::indexList->incContentsDepth(); + } + FTVHelp* ftv = new FTVHelp(FALSE); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Struct); + writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Struct); + QGString outStr; + FTextStream t(&outStr); + ftv->generateTreeViewInline(t); + ol.writeString(outStr); + delete ftv; + if (addToIndex) + { + Doxygen::indexList->decContentsDepth(); + } + } + + ol.popGeneratorState(); + // ------ + + endFile(ol); // contains ol.endContents() + ol.popGeneratorState(); +} + +//---------------------------------------------------------------------------- + +static void writeAnnotatedExceptionIndex(OutputList &ol) +{ + //printf("writeAnnotatedExceptionIndex: count=%d printed=%d\n", + // annotatedExceptions,annotatedExceptionsPrinted); + if (annotatedExceptions==0) return; + + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + if (annotatedExceptionsPrinted==0) + { + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + } + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ExceptionList); + if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Exceptions); // fall back + QCString title = lne ? lne->title() : theTranslator->trExceptionList(); + bool addToIndex = lne==0 || lne->visible(); + + startFile(ol,"annotatedexceptions",0,title,HLI_AnnotatedExceptions); + + startTitle(ol,0); + ol.parseText(title); + endTitle(ol,0,0); + + ol.startContents(); + + ol.startTextBlock(); + ol.parseText(lne ? lne->intro() : theTranslator->trExceptionListDescription()); + ol.endTextBlock(); + + // --------------- + // Linear interface index for Latex/RTF + // --------------- + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Html); + Doxygen::indexList->disable(); + + writeAnnotatedClassList(ol, ClassDef::Exception); + + Doxygen::indexList->enable(); + ol.popGeneratorState(); + + // --------------- + // Hierarchical interface index for HTML + // --------------- + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + + { + if (addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedexceptions",0,TRUE,TRUE); + Doxygen::indexList->incContentsDepth(); + } + FTVHelp* ftv = new FTVHelp(FALSE); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Exception); + writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Exception); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); @@ -2211,7 +2832,7 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, if (!firstSection) ol.endItemList(); QCString cs = letterToLabel(ml->letter()); QCString cl = QString(QChar(ml->letter())).utf8(); - QCString anchor=(QCString)"index_"+cs; + QCString anchor=(QCString)"index_"+convertToId(cs); QCString title=(QCString)"- "+cl+" -"; ol.startSection(anchor,title,SectionInfo::Subsection); ol.docify(title); @@ -2383,6 +3004,16 @@ void addNamespaceMemberNameToIndex(MemberDef *md) g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md); documentedNamespaceMembers[NMHL_Typedefs]++; } + else if (md->isSequence()) + { + g_namespaceIndexLetterUsed[NMHL_Sequences].append(letter,md); + documentedNamespaceMembers[NMHL_Sequences]++; + } + else if (md->isDictionary()) + { + g_namespaceIndexLetterUsed[NMHL_Dictionaries].append(letter,md); + documentedNamespaceMembers[NMHL_Dictionaries]++; + } else if (md->isEnumerate()) { g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md); @@ -2440,6 +3071,16 @@ void addFileMemberNameToIndex(MemberDef *md) g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md); documentedFileMembers[FMHL_Typedefs]++; } + else if (md->isSequence()) + { + g_fileIndexLetterUsed[FMHL_Sequences].append(letter,md); + documentedFileMembers[FMHL_Sequences]++; + } + else if (md->isDictionary()) + { + g_fileIndexLetterUsed[FMHL_Dictionaries].append(letter,md); + documentedFileMembers[FMHL_Dictionaries]++; + } else if (md->isEnumerate()) { g_fileIndexLetterUsed[FMHL_Enums].append(letter,md); @@ -2482,7 +3123,7 @@ static void writeQuickMemberIndex(OutputList &ol, anchor=fullName+extension+"#index_"; else anchor=fullName+"_"+letterToLabel(i)+extension+"#index_"; - startQuickIndexItem(ol,anchor+is,i==page,TRUE,first); + startQuickIndexItem(ol,anchor+convertToId(is),i==page,TRUE,first); ol.writeString(ci); endQuickIndexItem(ol); first=FALSE; @@ -2508,8 +3149,8 @@ static const CmhlInfo *getCmhlInfo(int hl) { CmhlInfo("functions", theTranslator->trAll()), CmhlInfo("functions_func", - fortranOpt ? theTranslator->trSubprograms() : - vhdlOpt ? VhdlDocGen::trFunctionAndProc() : + fortranOpt ? theTranslator->trSubprograms() : + vhdlOpt ? theTranslator->trFunctionAndProc() : theTranslator->trFunctions()), CmhlInfo("functions_vars",theTranslator->trVariables()), CmhlInfo("functions_type",theTranslator->trTypedefs()), @@ -2683,15 +3324,18 @@ static const FmhlInfo *getFmhlInfo(int 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); static FmhlInfo fmhlInfo[] = { FmhlInfo("globals", theTranslator->trAll()), FmhlInfo("globals_func", - fortranOpt ? theTranslator->trSubprograms() : - vhdlOpt ? VhdlDocGen::trFunctionAndProc() : + fortranOpt ? theTranslator->trSubprograms() : + vhdlOpt ? theTranslator->trFunctionAndProc() : theTranslator->trFunctions()), - FmhlInfo("globals_vars",theTranslator->trVariables()), + FmhlInfo("globals_vars",sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()), FmhlInfo("globals_type",theTranslator->trTypedefs()), + FmhlInfo("globals_sequ",theTranslator->trSequences()), + FmhlInfo("globals_dict",theTranslator->trDictionaries()), FmhlInfo("globals_enum",theTranslator->trEnumerations()), FmhlInfo("globals_eval",theTranslator->trEnumerationValues()), FmhlInfo("globals_defs",theTranslator->trDefines()) @@ -2827,6 +3471,8 @@ static void writeFileMemberIndex(OutputList &ol) writeFileMemberIndexFiltered(ol,FMHL_Functions); writeFileMemberIndexFiltered(ol,FMHL_Variables); writeFileMemberIndexFiltered(ol,FMHL_Typedefs); + writeFileMemberIndexFiltered(ol,FMHL_Sequences); + writeFileMemberIndexFiltered(ol,FMHL_Dictionaries); writeFileMemberIndexFiltered(ol,FMHL_Enums); writeFileMemberIndexFiltered(ol,FMHL_EnumValues); writeFileMemberIndexFiltered(ol,FMHL_Defines); @@ -2851,15 +3497,18 @@ static const NmhlInfo *getNmhlInfo(int 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); static NmhlInfo nmhlInfo[] = { NmhlInfo("namespacemembers", theTranslator->trAll()), NmhlInfo("namespacemembers_func", - fortranOpt ? theTranslator->trSubprograms() : - vhdlOpt ? VhdlDocGen::trFunctionAndProc() : + fortranOpt ? theTranslator->trSubprograms() : + vhdlOpt ? theTranslator->trFunctionAndProc() : theTranslator->trFunctions()), - NmhlInfo("namespacemembers_vars",theTranslator->trVariables()), + NmhlInfo("namespacemembers_vars",sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()), NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()), + NmhlInfo("namespacemembers_sequ",theTranslator->trSequences()), + NmhlInfo("namespacemembers_dict",theTranslator->trDictionaries()), NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()), NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues()) }; @@ -2999,6 +3648,8 @@ static void writeNamespaceMemberIndex(OutputList &ol) writeNamespaceMemberIndexFiltered(ol,NMHL_Functions); writeNamespaceMemberIndexFiltered(ol,NMHL_Variables); writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs); + writeNamespaceMemberIndexFiltered(ol,NMHL_Sequences); + writeNamespaceMemberIndexFiltered(ol,NMHL_Dictionaries); writeNamespaceMemberIndexFiltered(ol,NMHL_Enums); writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues); if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex) @@ -3017,6 +3668,7 @@ static void writeExampleIndex(OutputList &ol) if (Doxygen::exampleSDict->count()==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples); QCString title = lne ? lne->title() : theTranslator->trExamples(); bool addToIndex = lne==0 || lne->visible(); @@ -3616,6 +4268,7 @@ static void writeGroupIndex(OutputList &ol) ol.pushGeneratorState(); // 1.{ ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Docbook); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules); QCString title = lne ? lne->title() : theTranslator->trModules(); bool addToIndex = lne==0 || lne->visible(); @@ -3883,9 +4536,9 @@ static void writeIndex(OutputList &ol) if (Doxygen::mainPage) { Doxygen::insideMainPage=TRUE; - if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections()) + if (Doxygen::mainPage->localToc().isHtmlEnabled() && Doxygen::mainPage->hasSections()) { - Doxygen::mainPage->writeToc(ol); + Doxygen::mainPage->writeToc(ol,Doxygen::mainPage->localToc()); } ol.startTextBlock(); @@ -3905,6 +4558,7 @@ static void writeIndex(OutputList &ol) // write LaTeX/RTF index //-------------------------------------------------------------------- ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Docbook); ol.enable(OutputGenerator::RTF); ol.startFile("refman",0,0); @@ -3913,6 +4567,7 @@ static void writeIndex(OutputList &ol) { ol.disable(OutputGenerator::Latex); } + ol.disable(OutputGenerator::Docbook); if (projPrefix.isEmpty()) { @@ -3934,6 +4589,7 @@ static void writeIndex(OutputList &ol) ol.parseText(theTranslator->trGeneratedBy()); ol.endIndexSection(isTitlePageAuthor); ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Docbook); ol.lastIndexPage(); if (Doxygen::mainPage) @@ -3973,9 +4629,11 @@ static void writeIndex(OutputList &ol) QCString title = pd->title(); if (title.isEmpty()) title=pd->name(); + ol.disable(OutputGenerator::Docbook); ol.startIndexSection(isPageDocumentation); ol.parseText(title); ol.endIndexSection(isPageDocumentation); + ol.enable(OutputGenerator::Docbook); ol.pushGeneratorState(); // write TOC title (RTF only) ol.disableAllBut(OutputGenerator::RTF); @@ -3997,6 +4655,7 @@ static void writeIndex(OutputList &ol) } } + ol.disable(OutputGenerator::Docbook); if (!Config_getBool(LATEX_HIDE_INDICES)) { //if (indexedPages>0) @@ -4017,26 +4676,56 @@ static void writeIndex(OutputList &ol) ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex())); ol.endIndexSection(isNamespaceIndex); } + if (hierarchyInterfaces>0) + { + ol.startIndexSection(isClassHierarchyIndex); + ol.parseText(/*projPrefix+*/theTranslator->trHierarchicalIndex()); + ol.endIndexSection(isClassHierarchyIndex); + } if (hierarchyClasses>0) { ol.startIndexSection(isClassHierarchyIndex); ol.parseText(/*projPrefix+*/ (fortranOpt ? theTranslator->trCompoundIndexFortran() : - vhdlOpt ? VhdlDocGen::trDesignUnitIndex() : + vhdlOpt ? theTranslator->trHierarchicalIndex() : theTranslator->trHierarchicalIndex() )); ol.endIndexSection(isClassHierarchyIndex); } + if (hierarchyExceptions>0) + { + ol.startIndexSection(isClassHierarchyIndex); + ol.parseText(/*projPrefix+*/theTranslator->trHierarchicalIndex()); + ol.endIndexSection(isClassHierarchyIndex); + } + if (annotatedInterfacesPrinted>0) + { + ol.startIndexSection(isCompoundIndex); + ol.parseText(/*projPrefix+*/theTranslator->trInterfaceIndex()); + ol.endIndexSection(isCompoundIndex); + } if (annotatedClassesPrinted>0) { ol.startIndexSection(isCompoundIndex); ol.parseText(/*projPrefix+*/ (fortranOpt ? theTranslator->trCompoundIndexFortran() : - vhdlOpt ? VhdlDocGen::trDesignUnitIndex() : + vhdlOpt ? theTranslator->trDesignUnitIndex() : theTranslator->trCompoundIndex() )); ol.endIndexSection(isCompoundIndex); } + if (annotatedStructsPrinted>0) + { + ol.startIndexSection(isCompoundIndex); + ol.parseText(/*projPrefix+*/theTranslator->trStructIndex()); + ol.endIndexSection(isCompoundIndex); + } + if (annotatedExceptionsPrinted>0) + { + ol.startIndexSection(isCompoundIndex); + ol.parseText(/*projPrefix+*/theTranslator->trExceptionIndex()); + ol.endIndexSection(isCompoundIndex); + } if (documentedFiles>0) { ol.startIndexSection(isFileIndex); @@ -4044,6 +4733,8 @@ static void writeIndex(OutputList &ol) ol.endIndexSection(isFileIndex); } } + ol.enable(OutputGenerator::Docbook); + if (documentedGroups>0) { ol.startIndexSection(isModuleDocumentation); @@ -4056,12 +4747,30 @@ static void writeIndex(OutputList &ol) ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation())); ol.endIndexSection(isNamespaceDocumentation); } + if (annotatedInterfacesPrinted>0) + { + ol.startIndexSection(isClassDocumentation); + ol.parseText(/*projPrefix+*/theTranslator->trInterfaceDocumentation()); + ol.endIndexSection(isClassDocumentation); + } if (annotatedClassesPrinted>0) { ol.startIndexSection(isClassDocumentation); ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation())); ol.endIndexSection(isClassDocumentation); } + if (annotatedStructsPrinted>0) + { + ol.startIndexSection(isClassDocumentation); + ol.parseText(/*projPrefix+*/theTranslator->trStructDocumentation()); + ol.endIndexSection(isClassDocumentation); + } + if (annotatedExceptionsPrinted>0) + { + ol.startIndexSection(isClassDocumentation); + ol.parseText(/*projPrefix+*/theTranslator->trExceptionDocumentation()); + ol.endIndexSection(isClassDocumentation); + } if (documentedFiles>0) { ol.startIndexSection(isFileDocumentation); @@ -4100,6 +4809,7 @@ static QArray<bool> indexWritten; static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry> &entries) { + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); QListIterator<LayoutNavEntry> li(entries); LayoutNavEntry *lne; for (li.toFirst();(lne=li.current());++li) @@ -4197,8 +4907,101 @@ static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry } break; case LayoutNavEntry::ClassMembers: - msg("Generating member index...\n"); - writeClassMemberIndex(ol); + if (!sliceOpt) + { + msg("Generating member index...\n"); + writeClassMemberIndex(ol); + } + break; + case LayoutNavEntry::Interfaces: + if (sliceOpt && annotatedInterfaces>0 && addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); + Doxygen::indexList->incContentsDepth(); + needsClosing=TRUE; + } + break; + case LayoutNavEntry::InterfaceList: + if (sliceOpt) + { + msg("Generating annotated interface index...\n"); + writeAnnotatedInterfaceIndex(ol); + } + break; + case LayoutNavEntry::InterfaceIndex: + if (sliceOpt) + { + msg("Generating alphabetical interface index...\n"); + writeAlphabeticalInterfaceIndex(ol); + } + break; + case LayoutNavEntry::InterfaceHierarchy: + if (sliceOpt) + { + msg("Generating hierarchical interface index...\n"); + writeHierarchicalInterfaceIndex(ol); + if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) + { + msg("Generating graphical interface hierarchy...\n"); + writeGraphicalInterfaceHierarchy(ol); + } + } + break; + case LayoutNavEntry::Structs: + if (sliceOpt && annotatedStructs>0 && addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); + Doxygen::indexList->incContentsDepth(); + needsClosing=TRUE; + } + break; + case LayoutNavEntry::StructList: + if (sliceOpt) + { + msg("Generating annotated struct index...\n"); + writeAnnotatedStructIndex(ol); + } + break; + case LayoutNavEntry::StructIndex: + if (sliceOpt) + { + msg("Generating alphabetical struct index...\n"); + writeAlphabeticalStructIndex(ol); + } + break; + case LayoutNavEntry::Exceptions: + if (sliceOpt && annotatedExceptions>0 && addToIndex) + { + Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); + Doxygen::indexList->incContentsDepth(); + needsClosing=TRUE; + } + break; + case LayoutNavEntry::ExceptionList: + if (sliceOpt) + { + msg("Generating annotated exception index...\n"); + writeAnnotatedExceptionIndex(ol); + } + break; + case LayoutNavEntry::ExceptionIndex: + if (sliceOpt) + { + msg("Generating alphabetical exception index...\n"); + writeAlphabeticalExceptionIndex(ol); + } + break; + case LayoutNavEntry::ExceptionHierarchy: + if (sliceOpt) + { + msg("Generating hierarchical exception index...\n"); + writeHierarchicalExceptionIndex(ol); + if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) + { + msg("Generating graphical exception hierarchy...\n"); + writeGraphicalExceptionHierarchy(ol); + } + } break; case LayoutNavEntry::Files: { @@ -4280,6 +5083,9 @@ static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry } writeUserGroupStubPage(ol,lne); break; + case LayoutNavEntry::None: + assert(kind != LayoutNavEntry::None); // should never happen, means not properly initialized + break; } if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times { @@ -4309,26 +5115,40 @@ static bool quickLinkVisible(LayoutNavEntry::Kind kind) { static bool showFiles = Config_getBool(SHOW_FILES); static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); switch (kind) { - case LayoutNavEntry::MainPage: return TRUE; - case LayoutNavEntry::User: return TRUE; - case LayoutNavEntry::UserGroup: return TRUE; - case LayoutNavEntry::Pages: return indexedPages>0; - case LayoutNavEntry::Modules: return documentedGroups>0; - case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces; - case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces; - case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0; - case LayoutNavEntry::Classes: return annotatedClasses>0; - case LayoutNavEntry::ClassList: return annotatedClasses>0; - case LayoutNavEntry::ClassIndex: return annotatedClasses>0; - case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0; - case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0; - case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles; - case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles; - case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; - //case LayoutNavEntry::Dirs: return documentedDirs>0; - case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0; + case LayoutNavEntry::MainPage: return TRUE; + case LayoutNavEntry::User: return TRUE; + case LayoutNavEntry::UserGroup: return TRUE; + case LayoutNavEntry::Pages: return indexedPages>0; + case LayoutNavEntry::Modules: return documentedGroups>0; + case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces; + case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces; + case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0; + case LayoutNavEntry::Classes: return annotatedClasses>0; + case LayoutNavEntry::ClassList: return annotatedClasses>0; + case LayoutNavEntry::ClassIndex: return annotatedClasses>0; + case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0; + case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0 && !sliceOpt; + case LayoutNavEntry::Interfaces: return annotatedInterfaces>0; + case LayoutNavEntry::InterfaceList: return annotatedInterfaces>0; + case LayoutNavEntry::InterfaceIndex: return annotatedInterfaces>0; + case LayoutNavEntry::InterfaceHierarchy: return hierarchyInterfaces>0; + case LayoutNavEntry::Structs: return annotatedStructs>0; + case LayoutNavEntry::StructList: return annotatedStructs>0; + case LayoutNavEntry::StructIndex: return annotatedStructs>0; + case LayoutNavEntry::Exceptions: return annotatedExceptions>0; + case LayoutNavEntry::ExceptionList: return annotatedExceptions>0; + case LayoutNavEntry::ExceptionIndex: return annotatedExceptions>0; + case LayoutNavEntry::ExceptionHierarchy: return hierarchyExceptions>0; + case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles; + case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles; + case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; + case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0; + case LayoutNavEntry::None: // should never happen, means not properly initialized + assert(kind != LayoutNavEntry::None); + return FALSE; } return FALSE; } @@ -4381,7 +5201,7 @@ void renderMemberIndicesAsJs(FTextStream &t, else // other pages of multi page index anchor=fullName+"_"+is+extension+"#index_"; t << "{text:\"" << convertToJSString(ci) << "\",url:\"" - << convertToJSString(anchor+is, false) << "\"}"; + << convertToJSString(anchor+convertToId(is), false) << "\"}"; firstLetter=FALSE; } t << "]"; diff --git a/src/index.h b/src/index.h index ace3614..f3e0241 100644 --- a/src/index.h +++ b/src/index.h @@ -184,9 +184,17 @@ enum HighlightedItem HLI_Modules, //HLI_Directories, HLI_Namespaces, - HLI_Hierarchy, + HLI_ClassHierarchy, + HLI_InterfaceHierarchy, + HLI_ExceptionHierarchy, HLI_Classes, - HLI_Annotated, + HLI_Interfaces, + HLI_Structs, + HLI_Exceptions, + HLI_AnnotatedClasses, + HLI_AnnotatedInterfaces, + HLI_AnnotatedStructs, + HLI_AnnotatedExceptions, HLI_Files, HLI_NamespaceMembers, HLI_Functions, @@ -197,6 +205,9 @@ enum HighlightedItem HLI_UserGroup, HLI_ClassVisible, + HLI_InterfaceVisible, + HLI_StructVisible, + HLI_ExceptionVisible, HLI_NamespaceVisible, HLI_FileVisible }; @@ -221,6 +232,8 @@ enum FileMemberHighlight FMHL_Functions, FMHL_Variables, FMHL_Typedefs, + FMHL_Sequences, + FMHL_Dictionaries, FMHL_Enums, FMHL_EnumValues, FMHL_Defines, @@ -233,6 +246,8 @@ enum NamespaceMemberHighlight NMHL_Functions, NMHL_Variables, NMHL_Typedefs, + NMHL_Sequences, + NMHL_Dictionaries, NMHL_Enums, NMHL_EnumValues, NMHL_Total = NMHL_EnumValues+1 @@ -257,7 +272,12 @@ void writeIndexHierarchy(OutputList &ol); void countDataStructures(); extern int annotatedClasses; +extern int annotatedInterfaces; +extern int annotatedStructs; +extern int annotatedExceptions; extern int hierarchyClasses; +extern int hierarchyInterfaces; +extern int hierarchyExceptions; extern int documentedFiles; extern int documentedGroups; extern int documentedNamespaces; diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 5a67c15..5be3fc9 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -18,6 +18,7 @@ #include "htmlattrib.h" #include <qfileinfo.h> #include "latexdocvisitor.h" +#include "latexgen.h" #include "docparser.h" #include "language.h" #include "doxygen.h" @@ -32,6 +33,7 @@ #include "filedef.h" #include "config.h" #include "htmlentity.h" +#include "emoji.h" #include "plantuml.h" const int maxLevels=5; @@ -47,16 +49,23 @@ static const char *getSectionName(int level) return secLabels[QMIN(maxLevels-1,l)]; } -static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, QCString width, QCString height) +static void visitPreStart(FTextStream &t, bool hasCaption, QCString name, QCString width, QCString height, bool inlineImage = FALSE) { - if (hasCaption) + if (inlineImage) { - t << "\n\\begin{DoxyImage}\n"; + t << "\n\\begin{DoxyInlineImage}\n"; } else { - t << "\n\\begin{DoxyImageNoCaption}\n" - " \\mbox{"; + if (hasCaption) + { + t << "\n\\begin{DoxyImage}\n"; + } + else + { + t << "\n\\begin{DoxyImageNoCaption}\n" + " \\mbox{"; + } } t << "\\includegraphics"; @@ -79,7 +88,14 @@ static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, if (width.isEmpty() && height.isEmpty()) { /* default setting */ - t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]"; + if (inlineImage) + { + t << "[height=\\baselineskip,keepaspectratio=true]"; + } + else + { + t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]"; + } } else { @@ -90,21 +106,36 @@ static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, if (hasCaption) { - t << "\n\\doxyfigcaption{"; + if (!inlineImage) + { + t << "\n\\doxyfigcaption{"; + } + else + { + t << "%"; // to catch the caption + } } } -static void visitPostEnd(FTextStream &t, const bool hasCaption) +static void visitPostEnd(FTextStream &t, bool hasCaption, bool inlineImage = FALSE) { - t << "}\n"; // end mbox or caption - if (hasCaption) + if (inlineImage) { - t << "\\end{DoxyImage}\n"; + t << "\n\\end{DoxyInlineImage}\n"; } - else{ - t << "\\end{DoxyImageNoCaption}\n"; + else + { + t << "}\n"; // end mbox or caption + if (hasCaption) + { + t << "\\end{DoxyImage}\n"; + } + else + { + t << "\\end{DoxyImageNoCaption}\n"; + } } } @@ -209,6 +240,23 @@ void LatexDocVisitor::visit(DocSymbol *s) } } +void LatexDocVisitor::visit(DocEmoji *s) +{ + if (m_hide) return; + QCString emojiName = EmojiEntityMapper::instance()->name(s->index()); + if (!emojiName.isEmpty()) + { + QCString imageName=emojiName.mid(1,emojiName.length()-2); // strip : at start and end + m_t << "\\doxygenemoji{"; + filter(emojiName); + m_t << "}{" << imageName << "}"; + } + else + { + m_t << s->name(); + } +} + void LatexDocVisitor::visit(DocURL *u) { if (m_hide) return; @@ -216,11 +264,11 @@ void LatexDocVisitor::visit(DocURL *u) { m_t << "\\href{"; if (u->isEmail()) m_t << "mailto:"; - m_t << u->url() << "}"; + m_t << latexFilterURL(u->url()) << "}"; } - m_t << "{\\tt "; + m_t << "{\\texttt{ "; filter(u->url()); - m_t << "}"; + m_t << "}}"; } void LatexDocVisitor::visit(DocLineBreak *) @@ -241,7 +289,13 @@ void LatexDocVisitor::visit(DocStyleChange *s) 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::Strike: + if (s->enable()) m_t << "\\sout{"; else m_t << "}"; + break; + case DocStyleChange::Underline: + if (s->enable()) m_t << "\\uline{"; else m_t << "}"; break; case DocStyleChange::Italic: if (s->enable()) m_t << "{\\itshape "; else m_t << "}"; @@ -291,10 +345,12 @@ void LatexDocVisitor::visit(DocVerbatim *s) { case DocVerbatim::Code: { - m_t << "\n\\begin{DoxyCode}\n"; + m_t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n"; + LatexCodeGenerator::setDoxyCodeOpen(TRUE); Doxygen::parserManager->getParser(lang) ->parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); + LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCode}\n"; } break; @@ -399,7 +455,8 @@ void LatexDocVisitor::visit(DocInclude *inc) { case DocInclude::IncWithLines: { - m_t << "\n\\begin{DoxyCodeInclude}\n"; + m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; + LatexCodeGenerator::setDoxyCodeOpen(TRUE); QFileInfo cfi( inc->file() ); FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) @@ -415,11 +472,13 @@ void LatexDocVisitor::visit(DocInclude *inc) 0, // memberDef TRUE // show line numbers ); + LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}" << endl; } break; case DocInclude::Include: - m_t << "\n\\begin{DoxyCodeInclude}\n"; + m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; + LatexCodeGenerator::setDoxyCodeOpen(TRUE); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci,inc->context(), inc->text(),langExt,inc->isExample(), @@ -431,6 +490,7 @@ void LatexDocVisitor::visit(DocInclude *inc) 0, // memberDef FALSE ); + LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}\n"; break; case DocInclude::DontInclude: @@ -447,7 +507,8 @@ void LatexDocVisitor::visit(DocInclude *inc) break; case DocInclude::Snippet: { - m_t << "\n\\begin{DoxyCodeInclude}\n"; + m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; + LatexCodeGenerator::setDoxyCodeOpen(TRUE); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, inc->context(), @@ -456,6 +517,7 @@ void LatexDocVisitor::visit(DocInclude *inc) inc->isExample(), inc->exampleFile() ); + LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}" << endl; } break; @@ -463,7 +525,8 @@ void LatexDocVisitor::visit(DocInclude *inc) { QFileInfo cfi( inc->file() ); FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - m_t << "\n\\begin{DoxyCodeInclude}\n"; + m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; + LatexCodeGenerator::setDoxyCodeOpen(TRUE); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, inc->context(), @@ -478,6 +541,7 @@ void LatexDocVisitor::visit(DocInclude *inc) 0, // memberDef TRUE // show line number ); + LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}" << endl; } break; @@ -495,7 +559,8 @@ void LatexDocVisitor::visit(DocIncOperator *op) // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { - if (!m_hide) m_t << "\n\\begin{DoxyCodeInclude}\n"; + if (!m_hide) m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; + LatexCodeGenerator::setDoxyCodeOpen(TRUE); pushEnabled(); m_hide = TRUE; } @@ -515,6 +580,7 @@ void LatexDocVisitor::visit(DocIncOperator *op) if (op->isLast()) { popEnabled(); + LatexCodeGenerator::setDoxyCodeOpen(FALSE); if (!m_hide) m_t << "\n\\end{DoxyCodeInclude}\n"; } else @@ -526,16 +592,28 @@ void LatexDocVisitor::visit(DocIncOperator *op) void LatexDocVisitor::visit(DocFormula *f) { if (m_hide) return; - m_t << f->text(); + const char *p=f->text(); + char c; + if (p) + { + while ((c=*p++)) + { + switch (c) + { + case '\'': m_t << "\\text{'}"; break; + default: m_t << c; break; + } + } + } } void LatexDocVisitor::visit(DocIndexEntry *i) { if (m_hide) return; m_t << "\\index{"; - m_t << latexEscapeLabelName(i->entry(),false); + m_t << latexEscapeLabelName(i->entry()); m_t << "@{"; - m_t << latexEscapeIndexChars(i->entry(),false); + m_t << latexEscapeIndexChars(i->entry()); m_t << "}}"; } @@ -923,11 +1001,11 @@ static void writeStartTableCommand(FTextStream &t,const DocNode *n,int cols) { if (tableIsNested(n)) { - t << "\\begin{tabularx}{\\linewidth}{|*{" << cols << "}{>{\\raggedright\\arraybackslash}X|}}"; + t << "{\\begin{tabularx}{\\linewidth}{|*{" << cols << "}{>{\\raggedright\\arraybackslash}X|}}"; } else { - t << "\\tabulinesep=1mm\n\\begin{longtabu} spread 0pt [c]{*{" << cols << "}{|X[-1]}|}\n"; + t << "\\tabulinesep=1mm\n\\begin{longtabu}spread 0pt [c]{*{" << cols << "}{|X[-1]}|}\n"; } //return isNested ? "TabularNC" : "TabularC"; } @@ -936,7 +1014,7 @@ static void writeEndTableCommand(FTextStream &t,const DocNode *n) { if (tableIsNested(n)) { - t << "\\end{tabularx}\n"; + t << "\\end{tabularx}}\n"; } else { @@ -983,7 +1061,8 @@ void LatexDocVisitor::visitPre(DocHtmlTable *t) if (firstRow && firstRow->isHeading()) { setFirstRow(TRUE); - firstRow->accept(this); + DocNode *n = t->parent(); + if (!tableIsNested(n)) firstRow->accept(this); setFirstRow(FALSE); } } @@ -1009,13 +1088,14 @@ void LatexDocVisitor::visitPost(DocHtmlCaption *c) void LatexDocVisitor::visitPre(DocHtmlRow *r) { setCurrentColumn(0); - if (r->isHeading()) m_t << "\\rowcolor{\\tableheadbgcolor}"; } void LatexDocVisitor::visitPost(DocHtmlRow *row) { if (m_hide) return; + DocNode *n = row->parent() ->parent(); + int c=currentColumn(); while (c<=numCols()) // end of row while inside a row span? { @@ -1033,10 +1113,7 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row) if (span->colSpan>1) // row span is also part of a column span { m_t << "\\multicolumn{" << span->colSpan << "}{"; - m_t << "p{(\\linewidth-\\tabcolsep*" - << numCols() << "-\\arrayrulewidth*" - << row->visibleCells() << ")*" - << span->colSpan <<"/"<< numCols() << "}|}{}"; + m_t << "}|}{}"; } else // solitary row span { @@ -1077,7 +1154,8 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row) m_t << "\n"; - if (row->isHeading() && row->rowIndex()==1) + + if (row->isHeading() && row->rowIndex()==1 && !tableIsNested(n)) { if (firstRow()) { @@ -1119,10 +1197,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) { m_t << "|"; } - m_t << "p{(\\linewidth-\\tabcolsep*" - << numCols() << "-\\arrayrulewidth*" - << row->visibleCells() << ")*" - << span->colSpan <<"/"<< numCols() << "}|}{}"; + m_t << "l|}{" << (c->isHeading()? "\\columncolor{\\tableheadbgcolor}" : "") << "}"; // alignment not relevant, empty column setCurrentColumn(currentColumn()+span->colSpan); } else @@ -1134,6 +1209,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) } int cs = c->colSpan(); + int a = c->alignment(); if (cs>1 && row) { setInColSpan(TRUE); @@ -1142,11 +1218,18 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) { m_t << "|"; } - m_t << "p{(\\linewidth-\\tabcolsep*" - << numCols() << "-\\arrayrulewidth*" - << row->visibleCells() << ")*" - << cs <<"/"<< numCols() << "}|}{"; - if (c->isHeading()) m_t << "\\cellcolor{\\tableheadbgcolor}"; + switch (a) + { + case DocHtmlCell::Right: + m_t << "r|}{"; + break; + case DocHtmlCell::Center: + m_t << "c|}{"; + break; + default: + m_t << "l|}{"; + break; + } } int rs = c->rowSpan(); if (rs>0) @@ -1156,9 +1239,8 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) // c->rowIndex(),c->columnIndex(),c->rowSpan(),c->colSpan(), // currentColumn()); addRowSpan(new ActiveRowSpan(c,rs,cs,currentColumn())); - m_t << "\\multirow{" << rs << "}{\\linewidth}{"; + m_t << "\\multirow{" << rs << "}{*}{"; } - int a = c->alignment(); if (a==DocHtmlCell::Center) { m_t << "\\PBS\\centering "; @@ -1169,7 +1251,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) } if (c->isHeading()) { - m_t << "\\textbf{ "; + m_t << "\\cellcolor{\\tableheadbgcolor}\\textbf{ "; } if (cs>1) { @@ -1217,16 +1299,16 @@ void LatexDocVisitor::visitPre(DocHRef *href) if (Config_getBool(PDF_HYPERLINKS)) { m_t << "\\href{"; - m_t << href->url(); + m_t << latexFilterURL(href->url()); m_t << "}"; } - m_t << "{\\tt "; + m_t << "{\\texttt{ "; } void LatexDocVisitor::visitPost(DocHRef *) { if (m_hide) return; - m_t << "}"; + m_t << "}}"; } void LatexDocVisitor::visitPre(DocHtmlHeader *header) @@ -1251,7 +1333,7 @@ void LatexDocVisitor::visitPre(DocImage *img) gfxName=gfxName.left(gfxName.length()-4); } - visitPreStart(m_t,img->hasCaption(), gfxName, img->width(), img->height()); + visitPreStart(m_t,img->hasCaption(), gfxName, img->width(), img->height(), img->isInlineImage()); } else // other format -> skip { @@ -1265,7 +1347,7 @@ void LatexDocVisitor::visitPost(DocImage *img) if (img->type()==DocImage::Latex) { if (m_hide) return; - visitPostEnd(m_t,img->hasCaption()); + visitPostEnd(m_t,img->hasCaption(), img->isInlineImage()); } else // other format { @@ -1410,11 +1492,8 @@ void LatexDocVisitor::visitPre(DocParamSect *s) filter(theTranslator->trExceptions()); break; case DocParamSect::TemplateParam: - /* TODO: add this - filter(theTranslator->trTemplateParam()); break; - */ m_t << "\n\\begin{DoxyTemplParams}{"; - filter("Template Parameters"); + filter(theTranslator->trTemplateParameters()); break; default: ASSERT(0); @@ -1467,7 +1546,7 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { if (pl->direction()!=DocParamSect::Unspecified) { - m_t << "\\mbox{\\tt "; + m_t << "\\mbox{\\texttt{ "; if (pl->direction()==DocParamSect::In) { m_t << "in"; @@ -1480,7 +1559,7 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { m_t << "in,out"; } - m_t << "} "; + m_t << "}} "; } if (useTable) m_t << " & "; } diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index 881863a..7ea8ae1 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -42,6 +42,7 @@ class LatexDocVisitor : public DocVisitor void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 1511dcb..b860195 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -38,6 +38,8 @@ #include "filename.h" #include "resourcemgr.h" +static bool DoxyCodeOpen = FALSE; +static bool DoxyCodeLineOpen = FALSE; //------------------------------- LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName) @@ -77,8 +79,8 @@ void LatexCodeGenerator::codify(const char *str) //char cs[5]; int spacesToNextTabStop; static int tabSize = Config_getInt(TAB_SIZE); - const int maxLineLen = 108; - QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars + static char *result = NULL; + static int lresult = 0; int i; while ((c=*p)) { @@ -86,13 +88,21 @@ void LatexCodeGenerator::codify(const char *str) { case 0x0c: p++; // remove ^L break; + case ' ': m_t <<" "; + m_col++; + p++; + break; + case '^': m_t <<"\\string^"; + m_col++; + p++; + break; case '\t': spacesToNextTabStop = tabSize - (m_col%tabSize); - m_t << Doxygen::spaces.left(spacesToNextTabStop); + for (i = 0; i < spacesToNextTabStop; i++) m_t <<" "; m_col+=spacesToNextTabStop; p++; break; - case '\n': (usedTableLevels()>0) ? m_t << "\\newline\n" : m_t << '\n'; m_col=0; p++; + case '\n': (usedTableLevels()>0 && !DoxyCodeOpen) ? m_t << "\\newline\n" : m_t << '\n'; m_col=0; p++; break; default: i=0; @@ -100,6 +110,11 @@ void LatexCodeGenerator::codify(const char *str) #undef COPYCHAR // helper macro to copy a single utf8 character, dealing with multibyte chars. #define COPYCHAR() do { \ + if (lresult < (i + 5)) \ + { \ + lresult += 512; \ + result = (char *)realloc(result, lresult); \ + } \ result[i++]=c; p++; \ if (c<0) /* multibyte utf-8 character */ \ { \ @@ -116,30 +131,16 @@ void LatexCodeGenerator::codify(const char *str) result[i++]=*p++; \ } \ } \ - m_col++; \ + m_col++; \ } while(0) - // gather characters until we find whitespace or are at - // the end of a line + // gather characters until we find whitespace or another special character COPYCHAR(); - if (m_col>=maxLineLen) // force line break + while ((c=*p) && + c!=0x0c && c!='\t' && c!='\n' && c!=' ' && c!='^' + ) { - m_t << "\n "; - m_col=0; - } - else // copy more characters - { - while (m_col<maxLineLen && (c=*p) && - c!=0x0c && c!='\t' && c!='\n' && c!=' ' - ) - { - COPYCHAR(); - } - if (m_col>=maxLineLen) // force line break - { - m_t << "\n "; - m_col=0; - } + COPYCHAR(); } result[i]=0; // add terminator //if (m_prettyCode) @@ -164,11 +165,6 @@ void LatexCodeGenerator::writeCodeLink(const char *ref,const char *f, static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); static bool usePDFLatex = Config_getBool(USE_PDFLATEX); int l = qstrlen(name); - if (m_col+l>80) - { - m_t << "\n "; - m_col=0; - } if (!ref && usePDFLatex && pdfHyperlinks) { m_t << "\\mbox{\\hyperlink{"; @@ -181,7 +177,7 @@ void LatexCodeGenerator::writeCodeLink(const char *ref,const char *f, } else { - m_t << name; + codify(name); } m_col+=l; } @@ -190,6 +186,11 @@ void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,co { static bool usePDFLatex = Config_getBool(USE_PDFLATEX); static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + if (!DoxyCodeLineOpen) + { + m_t << "\\DoxyCodeLine{"; + DoxyCodeLineOpen = TRUE; + } if (m_prettyCode) { QCString lineNumber; @@ -223,10 +224,20 @@ void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,co void LatexCodeGenerator::startCodeLine(bool) { m_col=0; + if (!DoxyCodeLineOpen) + { + m_t << "\\DoxyCodeLine{"; + DoxyCodeLineOpen = TRUE; + } } void LatexCodeGenerator::endCodeLine() { + if (DoxyCodeLineOpen) + { + m_t << "}"; + DoxyCodeLineOpen = FALSE; + } codify("\n"); } @@ -240,6 +251,10 @@ void LatexCodeGenerator::endFontClass() m_t << "}"; } +void LatexCodeGenerator::setDoxyCodeOpen(bool val) +{ + DoxyCodeOpen = val; +} //------------------------------- @@ -271,13 +286,15 @@ static void writeLatexMakefile() exit(1); } // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05 - QCString latex_command = Config_getString(LATEX_CMD_NAME); + QCString latex_command = theTranslator->latexCommandName(); QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME); // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05 FTextStream t(&file); if (!Config_getBool(USE_PDFLATEX)) // use plain old latex { - t << "all: refman.dvi" << endl + t << "LATEX_CMD=" << latex_command << endl + << endl + << "all: refman.dvi" << endl << endl << "ps: refman.ps" << endl << endl @@ -294,7 +311,7 @@ static void writeLatexMakefile() t << "\tps2pdf refman.ps refman.pdf" << endl << endl; t << "refman.dvi: clean refman.tex doxygen.sty" << endl << "\techo \"Running latex...\"" << endl - << "\t" << latex_command << " refman.tex" << endl + << "\t$(LATEX_CMD) refman.tex" << endl << "\techo \"Running makeindex...\"" << endl << "\t" << mkidx_command << " refman.idx" << endl; if (generateBib) @@ -302,19 +319,19 @@ static void writeLatexMakefile() t << "\techo \"Running bibtex...\"" << endl; t << "\tbibtex refman" << endl; t << "\techo \"Rerunning latex....\"" << endl; - t << "\t" << latex_command << " refman.tex" << endl; + t << "\t$(LATEX_CMD) refman.tex" << endl; } t << "\techo \"Rerunning latex....\"" << endl - << "\t" << latex_command << " refman.tex" << endl + << "\t$(LATEX_CMD) refman.tex" << endl << "\tlatex_count=8 ; \\" << endl << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl << "\t do \\" << endl << "\t echo \"Rerunning latex....\" ;\\" << endl - << "\t " << latex_command << " refman.tex ;\\" << endl + << "\t $(LATEX_CMD) refman.tex ; \\" << endl << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl << "\t done" << endl << "\t" << mkidx_command << " refman.idx" << endl - << "\t" << latex_command << " refman.tex" << endl << endl + << "\t$(LATEX_CMD) refman.tex" << endl << endl << "refman_2on1.ps: refman.ps" << endl << "\tpsnup -2 refman.ps >refman_2on1.ps" << endl << endl @@ -323,26 +340,28 @@ static void writeLatexMakefile() } else // use pdflatex for higher quality output { + t << "LATEX_CMD=" << latex_command << endl + << endl; t << "all: refman.pdf" << endl << endl << "pdf: refman.pdf" << endl << endl; t << "refman.pdf: clean refman.tex" << endl; - t << "\tpdflatex refman" << endl; + t << "\t$(LATEX_CMD) refman" << endl; t << "\t" << mkidx_command << " refman.idx" << endl; if (generateBib) { t << "\tbibtex refman" << endl; - t << "\tpdflatex refman" << endl; + t << "\t$(LATEX_CMD) refman" << endl; } - t << "\tpdflatex refman" << endl + t << "\t$(LATEX_CMD) refman" << endl << "\tlatex_count=8 ; \\" << endl << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl << "\t do \\" << endl << "\t echo \"Rerunning latex....\" ;\\" << endl - << "\t pdflatex refman ;\\" << endl + << "\t $(LATEX_CMD) refman ;\\" << endl << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl << "\t done" << endl << "\t" << mkidx_command << " refman.idx" << endl - << "\tpdflatex refman" << endl << endl; + << "\t$(LATEX_CMD) refman" << endl << endl; } t << endl @@ -356,7 +375,7 @@ static void writeMakeBat() #if defined(_MSC_VER) QCString dir=Config_getString(LATEX_OUTPUT); QCString fileName=dir+"/make.bat"; - QCString latex_command = Config_getString(LATEX_CMD_NAME); + QCString latex_command = theTranslator->latexCommandName(); QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME); QFile file(fileName); bool generateBib = !Doxygen::citeDict->isEmpty(); @@ -371,14 +390,15 @@ static void writeMakeBat() t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n"; if (!Config_getBool(USE_PDFLATEX)) // use plain old latex { - t << latex_command << " refman.tex\n"; + t << "set LATEX_CMD=" << latex_command << "\n"; + t << "%LATEX_CMD% refman.tex\n"; t << "echo ----\n"; t << mkidx_command << " refman.idx\n"; if (generateBib) { t << "bibtex refman\n"; t << "echo ----\n"; - t << latex_command << " refman.tex\n"; + t << "\t%LATEX_CMD% refman.tex\n"; } t << "setlocal enabledelayedexpansion\n"; t << "set count=8\n"; @@ -390,28 +410,29 @@ static void writeMakeBat() t << "set /a count-=1\n"; t << "if !count! EQU 0 goto :skip\n\n"; t << "echo ----\n"; - t << latex_command << " refman.tex\n"; + t << "%LATEX_CMD% refman.tex\n"; t << "goto :repeat\n"; t << ":skip\n"; t << "endlocal\n"; t << mkidx_command << " refman.idx\n"; - t << latex_command << " refman.tex\n"; + t << "%LATEX_CMD% refman.tex\n"; t << "dvips -o refman.ps refman.dvi\n"; t << "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite " "-sOutputFile=refman.pdf -c save pop -f refman.ps\n"; } else // use pdflatex { - t << "pdflatex refman\n"; + t << "set LATEX_CMD=" << latex_command << "\n"; + t << "%LATEX_CMD% refman\n"; t << "echo ----\n"; t << mkidx_command << " refman.idx\n"; if (generateBib) { t << "bibtex refman" << endl; - t << "pdflatex refman" << endl; + t << "%LATEX_CMD% refman" << endl; } t << "echo ----\n"; - t << "pdflatex refman\n\n"; + t << "%LATEX_CMD% refman\n\n"; t << "setlocal enabledelayedexpansion\n"; t << "set count=8\n"; t << ":repeat\n"; @@ -422,12 +443,12 @@ static void writeMakeBat() t << "set /a count-=1\n"; t << "if !count! EQU 0 goto :skip\n\n"; t << "echo ----\n"; - t << "pdflatex refman\n"; + t << "%LATEX_CMD% refman\n"; t << "goto :repeat\n"; t << ":skip\n"; t << "endlocal\n"; t << mkidx_command << " refman.idx\n"; - t << "pdflatex refman\n"; + t << "%LATEX_CMD% refman\n"; t << "cd /D %Dir_Old%\n"; t << "set Dir_Old=\n"; } @@ -459,6 +480,10 @@ static void writeDefaultHeaderPart1(FTextStream &t) if (Config_getBool(LATEX_BATCHMODE)) t << "\\batchmode\n"; + // to overcome problems wit too many open files + t << "\\let\\mypdfximage\\pdfximage" + "\\def\\pdfximage{\\immediate\\mypdfximage}"; + // Set document class depending on configuration QCString documentClass; if (Config_getBool(COMPACT_LATEX)) @@ -472,8 +497,7 @@ static void writeDefaultHeaderPart1(FTextStream &t) t << "% Packages required by doxygen\n" "\\usepackage{fixltx2e}\n" // for \textsubscript "\\usepackage{calc}\n" - "\\usepackage{doxygen}\n" - "\\usepackage[export]{adjustbox} % also loads graphicx\n"; + "\\usepackage{doxygen}\n"; QStrList extraLatexStyle = Config_getList(LATEX_EXTRA_STYLESHEET); for (uint i=0; i<extraLatexStyle.count(); ++i) { @@ -504,6 +528,7 @@ static void writeDefaultHeaderPart1(FTextStream &t) "\\usepackage{textcomp}\n" "\\usepackage[nointegrals]{wasysym}\n" "\\usepackage[table]{xcolor}\n" + "\\usepackage{ifpdf,ifxetex}\n" "\n"; // Language support @@ -516,9 +541,13 @@ static void writeDefaultHeaderPart1(FTextStream &t) } // Define default fonts - t << "% Font selection\n" - "\\usepackage[T1]{fontenc}\n" - "\\usepackage[scaled=.90]{helvet}\n" + t << "% Font selection\n"; + QCString fontenc = theTranslator->latexFontenc(); + if (!fontenc.isEmpty()) + { + t << "\\usepackage[" << fontenc << "]{fontenc}\n"; + } + t << "\\usepackage[scaled=.90]{helvet}\n" "\\usepackage{courier}\n" "\\usepackage{amssymb}\n" "\\usepackage{sectsty}\n" @@ -534,6 +563,17 @@ static void writeDefaultHeaderPart1(FTextStream &t) "\\newcommand{\\+}{\\discretionary{\\mbox{\\scriptsize$\\hookleftarrow$}}{}{}}\n" "\n"; + QCString emojiDir=Config_getString(LATEX_EMOJI_DIRECTORY); + if (emojiDir.isEmpty()) emojiDir = "."; + emojiDir = substitute(emojiDir,"\\","/"); + t << "% Arguments of doxygenemoji:\n" + "% 1) ':<text>:' form of the emoji, already \"LaTeX\"-escaped\n" + "% 2) file with the name of the emoji without the .png extension\n" + "% in case image exist use this otherwise use the ':<text>:' form\n"; + t << "\\newcommand{\\doxygenemoji}[2]{%\n" + " \\IfFileExists{" << emojiDir << "/#2.png}{\\raisebox{-0.1em}{\\includegraphics[height=0.9em]{" << emojiDir << "/#2.png}}}{#1}%\n" + "}\n"; + // Define page & text layout QCString paperName=Config_getEnum(PAPER_TYPE); // "a4wide" package is obsolete (see bug 563698) @@ -553,7 +593,9 @@ static void writeDefaultHeaderPart1(FTextStream &t) "\\hbadness=750\n" "\\setlength{\\emergencystretch}{15pt}\n" "\\setlength{\\parindent}{0cm}\n" - "\\setlength{\\parskip}{3ex plus 2ex minus 2ex}\n"; + "\\newcommand{\\doxynormalparskip}{\\setlength{\\parskip}{3ex plus 2ex minus 2ex}}\n" + "\\newcommand{\\doxytocparskip}{\\setlength{\\parskip}{1ex plus 0ex minus 0ex}}\n" + "\\doxynormalparskip\n"; // Redefine paragraph/subparagraph environments, using sectsty fonts t << "\\makeatletter\n" "\\renewcommand{\\paragraph}{%\n" @@ -615,23 +657,40 @@ static void writeDefaultHeaderPart1(FTextStream &t) "\\usepackage{natbib}\n" "\\usepackage[titles]{tocloft}\n" "\\setcounter{tocdepth}{3}\n" - "\\setcounter{secnumdepth}{5}\n" - "\\makeindex\n" - "\n"; + "\\setcounter{secnumdepth}{5}\n"; + + QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD); + if (!latex_mkidx_command.isEmpty()) + { + if (latex_mkidx_command[0] == '\\') + t << latex_mkidx_command << "\n"; + else + t << '\\' << latex_mkidx_command << "\n"; + } + else + { + t << "\\makeindex\n"; + } + t << "\n"; writeExtraLatexPackages(t); + writeLatexSpecialFormulaChars(t); // Hyperlinks bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); if (pdfHyperlinks) { t << "% Hyperlinks (required, but should be loaded last)\n" - "\\usepackage{ifpdf}\n" "\\ifpdf\n" " \\usepackage[pdftex,pagebackref=true]{hyperref}\n" "\\else\n" - " \\usepackage[ps2pdf,pagebackref=true]{hyperref}\n" + " \\ifxetex\n" + " \\usepackage[pagebackref=true]{hyperref}\n" + " \\else\n" + " \\usepackage[ps2pdf,pagebackref=true]{hyperref}\n" + " \\fi\n" "\\fi\n" + "\n" "\\hypersetup{%\n" " colorlinks=true,%\n" " linkcolor=blue,%\n" @@ -652,12 +711,23 @@ static void writeDefaultHeaderPart1(FTextStream &t) t << "\\usepackage{caption}\n" << "\\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}\n\n"; + + // in page table of contents + t << "\\usepackage{etoc}\n" + "\\etocsettocstyle{\\doxytocparskip}{\\doxynormalparskip}\n"; + + // prevent numbers overlap the titles in toc + t << "\\renewcommand{\\numberline}[1]{#1~}\n"; + // End of preamble, now comes the document contents t << "%===== C O N T E N T S =====\n" "\n" "\\begin{document}\n"; - if (theTranslator->idLanguage()=="greek") - t << "\\selectlanguage{greek}\n"; + QCString documentPre = theTranslator->latexDocumentPre(); + if (!documentPre.isEmpty()) + { + t << documentPre; + } t << "\n"; // Front matter @@ -748,10 +818,15 @@ static void writeDefaultFooter(FTextStream &t) t << "\\newpage\n" "\\phantomsection\n" "\\clearemptydoublepage\n" - "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trRTFGeneralIndex() << "}\n" + "\\addcontentsline{toc}{" << unit << "}{\\indexname}\n" "\\printindex\n" - "\n" - "\\end{document}\n"; + "\n"; + QCString documentPost = theTranslator->latexDocumentPost(); + if (!documentPost.isEmpty()) + { + t << documentPost; + } + t << "\\end{document}\n"; } void LatexGenerator::writeHeaderFile(QFile &f) @@ -1304,12 +1379,12 @@ void LatexGenerator::startHtmlLink(const char *url) t << url; t << "}"; } - t << "{\\tt "; + t << "{\\texttt{ "; } void LatexGenerator::endHtmlLink() { - t << "}"; + t << "}}"; } //void LatexGenerator::writeMailLink(const char *url) @@ -1320,7 +1395,7 @@ void LatexGenerator::endHtmlLink() // t << url; // t << "}"; // } -// t << "{\\tt "; +// t << "\\texttt{ "; // docify(url); // t << "}"; //} @@ -1328,7 +1403,7 @@ void LatexGenerator::endHtmlLink() void LatexGenerator::writeStartAnnoItem(const char *,const char *, const char *path,const char *name) { - t << "\\item\\contentsline{section}{\\bf "; + t << "\\item\\contentsline{section}\\textbf{ "; if (path) docify(path); docify(name); t << "} "; @@ -1363,7 +1438,7 @@ void LatexGenerator::endIndexValue(const char *name,bool /*hasBrief*/) //void LatexGenerator::writeClassLink(const char *,const char *, // const char *,const char *name) //{ -// t << "{\\bf "; +// t << "\\textbf{ "; // docify(name); // t << "}"; //} @@ -1454,9 +1529,9 @@ void LatexGenerator::endTitleHead(const char *fileName,const char *name) if (name) { t << "\\label{" << stripPath(fileName) << "}\\index{"; - t << latexEscapeLabelName(name,insideTabbing); + t << latexEscapeLabelName(name); t << "@{"; - t << latexEscapeIndexChars(name,insideTabbing); + t << latexEscapeIndexChars(name); t << "}}" << endl; } } @@ -1505,7 +1580,7 @@ void LatexGenerator::endGroupHeader(int) t << "}" << endl; } -void LatexGenerator::startMemberHeader(const char *) +void LatexGenerator::startMemberHeader(const char *,int) { if (Config_getBool(COMPACT_LATEX)) { @@ -1537,27 +1612,27 @@ void LatexGenerator::startMemberDoc(const char *clname, t << "\\index{"; if (clname) { - t << latexEscapeLabelName(clname,insideTabbing); + t << latexEscapeLabelName(clname); t << "@{"; - t << latexEscapeIndexChars(clname,insideTabbing); + t << latexEscapeIndexChars(clname); t << "}!"; } - t << latexEscapeLabelName(memname,insideTabbing); + t << latexEscapeLabelName(memname); t << "@{"; - t << latexEscapeIndexChars(memname,insideTabbing); + t << latexEscapeIndexChars(memname); t << "}}" << endl; t << "\\index{"; - t << latexEscapeLabelName(memname,insideTabbing); + t << latexEscapeLabelName(memname); t << "@{"; - t << latexEscapeIndexChars(memname,insideTabbing); + t << latexEscapeIndexChars(memname); t << "}"; if (clname) { t << "!"; - t << latexEscapeLabelName(clname,insideTabbing); + t << latexEscapeLabelName(clname); t << "@{"; - t << latexEscapeIndexChars(clname,insideTabbing); + t << latexEscapeIndexChars(clname); t << "}"; } t << "}" << endl; @@ -1575,7 +1650,7 @@ void LatexGenerator::startMemberDoc(const char *clname, { t << "\\texorpdfstring{"; } - t << latexEscapeIndexChars(title,insideTabbing); + t << latexEscapeIndexChars(title); if (pdfHyperlinks) { t << "}{" << latexEscapePDFString(title) << "}"; @@ -1650,16 +1725,16 @@ void LatexGenerator::addIndexItem(const char *s1,const char *s2) if (s1) { t << "\\index{"; - t << latexEscapeLabelName(s1,insideTabbing); + t << latexEscapeLabelName(s1); t << "@{"; - t << latexEscapeIndexChars(s1,insideTabbing); + t << latexEscapeIndexChars(s1); t << "}"; if (s2) { t << "!"; - t << latexEscapeLabelName(s2,insideTabbing); + t << latexEscapeLabelName(s2); t << "@{"; - t << latexEscapeIndexChars(s2,insideTabbing); + t << latexEscapeIndexChars(s2); t << "}"; } t << "}"; @@ -1793,7 +1868,7 @@ void LatexGenerator::endMemberItem() t << endl; } -void LatexGenerator::startMemberDescription(const char *,const char *) +void LatexGenerator::startMemberDescription(const char *,const char *,bool) { if (!insideTabbing) { @@ -2030,22 +2105,14 @@ void LatexGenerator::endDescItem() } } -void LatexGenerator::startSimpleSect(SectionTypes,const char *file, - const char *anchor,const char *title) +void LatexGenerator::startExamples() { t << "\\begin{Desc}\n\\item["; - if (file) - { - writeObjectLink(0,file,anchor,title); - } - else - { - docify(title); - } + docify(theTranslator->trExamples()); t << "]"; } -void LatexGenerator::endSimpleSect() +void LatexGenerator::endExamples() { t << "\\end{Desc}" << endl; } @@ -2076,7 +2143,7 @@ void LatexGenerator::endParameterList() void LatexGenerator::startParameterType(bool first,const char *key) { t << "\\item[{"; - if (!first && key) t << key; + if (!first && key) docify(key); } void LatexGenerator::endParameterType() @@ -2102,7 +2169,7 @@ void LatexGenerator::endParameterName(bool last,bool /*emptyList*/,bool closeBra void LatexGenerator::exceptionEntry(const char* prefix,bool closeBracket) { if (prefix) - t << " " << prefix; + t << " " << prefix << "("; else if (closeBracket) t << ")"; t << " "; @@ -2159,12 +2226,17 @@ void LatexGenerator::endConstraintList() void LatexGenerator::startCodeFragment() { - t << "\n\\begin{DoxyCode}\n"; + t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n"; + DoxyCodeOpen = TRUE; } void LatexGenerator::endCodeFragment() { + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + t << "\\end{DoxyCode}\n"; + DoxyCodeOpen = FALSE; } void LatexGenerator::startInlineHeader() diff --git a/src/latexgen.h b/src/latexgen.h index 430d250..1460000 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -51,6 +51,7 @@ class LatexCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const char *) {} void setCurrentDoc(Definition *,const char *,bool) {} void addWord(const char *,bool) {} + static void setDoxyCodeOpen(bool val); private: void _writeCodeLink(const char *className, @@ -169,7 +170,7 @@ class LatexGenerator : public OutputGenerator void endMemberSections() {} void startHeaderSection() {} void endHeaderSection() {} - void startMemberHeader(const char *); + void startMemberHeader(const char *,int); void endMemberHeader(); void startMemberSubtitle() {} void endMemberSubtitle() {} @@ -194,6 +195,7 @@ class LatexGenerator : public OutputGenerator void endMemberGroup(bool); void insertMemberAlign(bool) {} + void insertMemberAlignLeft(int,bool){} void writeRuler() { t << endl << endl; } void writeAnchor(const char *fileName,const char *name); @@ -225,7 +227,7 @@ class LatexGenerator : public OutputGenerator void endCenter() { t << "\\end{center}" << endl; } void startSmall() { t << "\\footnotesize "; } void endSmall() { t << "\\normalsize "; } - void startMemberDescription(const char *,const char *); + void startMemberDescription(const char *,const char *,bool); void endMemberDescription(); void startMemberDeclaration() {} void endMemberDeclaration(const char *,const char *) {} @@ -233,8 +235,8 @@ class LatexGenerator : public OutputGenerator const char *,const char *,const char *) {} void startDescList(SectionTypes) { t << "\\begin{Desc}\n\\item["; } void endDescList() { t << "\\end{Desc}" << endl; } - void startSimpleSect(SectionTypes,const char *,const char *,const char *); - void endSimpleSect(); + void startExamples(); + void endExamples(); void startParamList(ParamListTypes,const char *title); void endParamList(); void startDescForItem() { t << "\\par" << endl; } diff --git a/src/layout.cpp b/src/layout.cpp index fdc9f4c..393e05d 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -50,6 +50,9 @@ static const char layout_default[] = #define COMPILE_FOR_4_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4) \ COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3)+ADD_OPTION(langId4,text4) +#define COMPILE_FOR_5_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4,langId5,text5) \ + COMPILE_FOR_4_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4)+ADD_OPTION(langId5,text5) + static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE) { QCString visible = attrib.value("visible").utf8(); @@ -265,6 +268,7 @@ class LayoutParser : public QXmlDefaultHandler //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); //bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); // start & end handlers m_sHandler.insert("doxygenlayout", @@ -310,7 +314,7 @@ class LayoutParser : public QXmlDefaultHandler new StartElementHandlerSection(this,LayoutDocEntry::ClassNestedClasses,&LayoutParser::startSectionEntry, COMPILE_FOR_2_OPTIONS( theTranslator->trCompounds(), - SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), SrcLangExt_Fortran,theTranslator->trDataTypes() ))); m_sHandler.insert("class/memberdecl/services", @@ -331,9 +335,10 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("class/memberdecl/publicmethods", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_pubMethods, - COMPILE_FOR_1_OPTION( + COMPILE_FOR_2_OPTIONS( theTranslator->trPublicMembers(), - SrcLangExt_ObjC,theTranslator->trInstanceMethods() + SrcLangExt_ObjC,theTranslator->trInstanceMethods(), + SrcLangExt_Slice,theTranslator->trOperations() ))); m_sHandler.insert("class/memberdecl/publicstaticmethods", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, @@ -344,7 +349,11 @@ class LayoutParser : public QXmlDefaultHandler ))); m_sHandler.insert("class/memberdecl/publicattributes", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubAttribs,theTranslator->trPublicAttribs())); + MemberListType_pubAttribs, + COMPILE_FOR_1_OPTION( + theTranslator->trPublicAttribs(), + SrcLangExt_Slice,theTranslator->trDataMembers() + ))); m_sHandler.insert("class/memberdecl/publicstaticattributes", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs())); @@ -440,17 +449,22 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("class/memberdef/functions", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_functionMembers, - COMPILE_FOR_2_OPTIONS( + COMPILE_FOR_3_OPTIONS( theTranslator->trMemberFunctionDocumentation(), SrcLangExt_ObjC,theTranslator->trMethodDocumentation(), - SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran() + SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran(), + SrcLangExt_Slice,theTranslator->trOperationDocumentation() ))); m_sHandler.insert("class/memberdef/related", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation())); m_sHandler.insert("class/memberdef/variables", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_variableMembers,theTranslator->trMemberDataDocumentation())); + MemberListType_variableMembers, + COMPILE_FOR_1_OPTION( + theTranslator->trMemberDataDocumentation(), + SrcLangExt_Slice,theTranslator->trDataMemberDocumentation() + ))); m_sHandler.insert("class/memberdef/properties", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_propertyMembers,theTranslator->trPropertyDocumentation())); @@ -477,28 +491,45 @@ class LayoutParser : public QXmlDefaultHandler new StartElementHandler(this,&LayoutParser::startMemberDecl)); m_sHandler.insert("namespace/memberdecl/nestednamespaces", new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedNamespaces,&LayoutParser::startSectionEntry, - COMPILE_FOR_4_OPTIONS( + COMPILE_FOR_5_OPTIONS( theTranslator->trNamespaces(), SrcLangExt_Java,theTranslator->trPackages(), SrcLangExt_VHDL,theTranslator->trPackages(), SrcLangExt_IDL,theTranslator->trModules(), - SrcLangExt_Fortran,theTranslator->trModules() - ))); + SrcLangExt_Fortran,theTranslator->trModules(), + SrcLangExt_Slice,(sliceOpt ? + theTranslator->trModules() : + theTranslator->trNamespaces())))); m_sHandler.insert("namespace/memberdecl/constantgroups", new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedConstantGroups,&LayoutParser::startSectionEntry, theTranslator->trConstantGroups())); + m_sHandler.insert("namespace/memberdecl/interfaces", + new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInterfaces,&LayoutParser::startSectionEntry, + theTranslator->trSliceInterfaces())); m_sHandler.insert("namespace/memberdecl/classes", new StartElementHandlerSection(this,LayoutDocEntry::NamespaceClasses,&LayoutParser::startSectionEntry, COMPILE_FOR_2_OPTIONS( theTranslator->trCompounds(), - SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), SrcLangExt_Fortran,theTranslator->trDataTypes() ))); + m_sHandler.insert("namespace/memberdecl/structs", + new StartElementHandlerSection(this,LayoutDocEntry::NamespaceStructs,&LayoutParser::startSectionEntry, + theTranslator->trStructs())); + m_sHandler.insert("namespace/memberdecl/exceptions", + new StartElementHandlerSection(this,LayoutDocEntry::NamespaceExceptions,&LayoutParser::startSectionEntry, + theTranslator->trExceptions())); m_sHandler.insert("namespace/memberdecl/membergroups", new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry)); m_sHandler.insert("namespace/memberdecl/typedefs", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_decTypedefMembers,theTranslator->trTypedefs())); + m_sHandler.insert("namespace/memberdecl/sequences", + new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, + MemberListType_decSequenceMembers,theTranslator->trSequences())); + m_sHandler.insert("namespace/memberdecl/dictionaries", + new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, + MemberListType_decDictionaryMembers,theTranslator->trDictionaries())); m_sHandler.insert("namespace/memberdecl/enums", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_decEnumMembers,theTranslator->trEnumerations())); @@ -508,11 +539,12 @@ class LayoutParser : public QXmlDefaultHandler COMPILE_FOR_2_OPTIONS( theTranslator->trFunctions(), SrcLangExt_Fortran,theTranslator->trSubprograms(), - SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc() + SrcLangExt_VHDL,theTranslator->trFunctionAndProc() ))); m_sHandler.insert("namespace/memberdecl/variables", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decVarMembers,theTranslator->trVariables())); + MemberListType_decVarMembers, + sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables())); m_eHandler.insert("namespace/memberdecl", new EndElementHandler(this,&LayoutParser::endMemberDecl)); m_sHandler.insert("namespace/memberdef", @@ -526,6 +558,13 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("namespace/memberdef/typedefs", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation())); + m_sHandler.insert("namespace/memberdef/sequences", + new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, + MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation())); + m_sHandler.insert("namespace/memberdef/dictionaries", + new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, + MemberListType_docDictionaryMembers, + theTranslator->trDictionaryDocumentation())); m_sHandler.insert("namespace/memberdef/enums", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation())); @@ -538,7 +577,9 @@ class LayoutParser : public QXmlDefaultHandler ))); m_sHandler.insert("namespace/memberdef/variables", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docVarMembers,theTranslator->trVariableDocumentation())); + MemberListType_docVarMembers, + sliceOpt ? theTranslator->trConstantDocumentation() : + theTranslator->trVariableDocumentation())); m_eHandler.insert("namespace/memberdef", new EndElementHandler(this,&LayoutParser::endMemberDef)); m_eHandler.insert("namespace", @@ -566,20 +607,30 @@ class LayoutParser : public QXmlDefaultHandler new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry)); m_sHandler.insert("file/memberdecl", new StartElementHandler(this,&LayoutParser::startMemberDecl)); + m_sHandler.insert("file/memberdecl/interfaces", + new StartElementHandlerSection(this,LayoutDocEntry::FileInterfaces,&LayoutParser::startSectionEntry, + theTranslator->trSliceInterfaces())); m_sHandler.insert("file/memberdecl/classes", new StartElementHandlerSection(this,LayoutDocEntry::FileClasses,&LayoutParser::startSectionEntry, COMPILE_FOR_2_OPTIONS( theTranslator->trCompounds(), - SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), SrcLangExt_Fortran,theTranslator->trDataTypes() ))); + m_sHandler.insert("file/memberdecl/structs", + new StartElementHandlerSection(this,LayoutDocEntry::FileStructs,&LayoutParser::startSectionEntry, + theTranslator->trStructs())); + m_sHandler.insert("file/memberdecl/exceptions", + new StartElementHandlerSection(this,LayoutDocEntry::FileExceptions,&LayoutParser::startSectionEntry, + theTranslator->trExceptions())); m_sHandler.insert("file/memberdecl/namespaces", new StartElementHandlerSection(this,LayoutDocEntry::FileNamespaces,&LayoutParser::startSectionEntry, - COMPILE_FOR_3_OPTIONS( + COMPILE_FOR_4_OPTIONS( theTranslator->trNamespaces(), SrcLangExt_Java,theTranslator->trPackages(), SrcLangExt_IDL,theTranslator->trModules(), - SrcLangExt_Fortran,theTranslator->trModules() + SrcLangExt_Fortran,theTranslator->trModules(), + SrcLangExt_Slice,theTranslator->trModules() ))); m_sHandler.insert("file/memberdecl/constantgroups", new StartElementHandlerSection(this,LayoutDocEntry::FileConstantGroups,&LayoutParser::startSectionEntry, @@ -590,6 +641,12 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("file/memberdecl/typedefs", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_decTypedefMembers,theTranslator->trTypedefs())); + m_sHandler.insert("file/memberdecl/sequences", + new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, + MemberListType_decSequenceMembers,theTranslator->trSequences())); + m_sHandler.insert("file/memberdecl/dictionaries", + new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, + MemberListType_decDictionaryMembers,theTranslator->trDictionaries())); m_sHandler.insert("file/memberdecl/enums", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_decEnumMembers,theTranslator->trEnumerations())); @@ -599,11 +656,12 @@ class LayoutParser : public QXmlDefaultHandler COMPILE_FOR_2_OPTIONS( theTranslator->trFunctions(), SrcLangExt_Fortran,theTranslator->trSubprograms(), - SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc() + SrcLangExt_VHDL,theTranslator->trFunctionAndProc() ))); m_sHandler.insert("file/memberdecl/variables", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decVarMembers,theTranslator->trVariables())); + MemberListType_decVarMembers, + sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables())); m_eHandler.insert("file/memberdecl", new EndElementHandler(this,&LayoutParser::endMemberDecl)); @@ -621,6 +679,13 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("file/memberdef/typedefs", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation())); + m_sHandler.insert("file/memberdef/sequences", + new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, + MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation())); + m_sHandler.insert("file/memberdef/dictionaries", + new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, + MemberListType_docDictionaryMembers, + theTranslator->trDictionaryDocumentation())); m_sHandler.insert("file/memberdef/enums", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_docEnumMembers, @@ -660,7 +725,7 @@ class LayoutParser : public QXmlDefaultHandler new StartElementHandlerSection(this,LayoutDocEntry::GroupClasses,&LayoutParser::startSectionEntry, COMPILE_FOR_2_OPTIONS( theTranslator->trCompounds(), - SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), SrcLangExt_Fortran,theTranslator->trDataTypes() ))); m_sHandler.insert("group/memberdecl/namespaces", @@ -689,6 +754,12 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("group/memberdecl/typedefs", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_decTypedefMembers,theTranslator->trTypedefs())); + m_sHandler.insert("group/memberdecl/sequences", + new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, + MemberListType_decSequenceMembers,theTranslator->trSequences())); + m_sHandler.insert("group/memberdecl/dictionaries", + new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, + MemberListType_decDictionaryMembers,theTranslator->trDictionaries())); m_sHandler.insert("group/memberdecl/enums", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, MemberListType_decEnumMembers,theTranslator->trEnumerations())); @@ -701,7 +772,7 @@ class LayoutParser : public QXmlDefaultHandler COMPILE_FOR_2_OPTIONS( theTranslator->trFunctions(), SrcLangExt_Fortran,theTranslator->trSubprograms(), - SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc() + SrcLangExt_VHDL,theTranslator->trFunctionAndProc() ))); m_sHandler.insert("group/memberdecl/variables", new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, @@ -745,6 +816,13 @@ class LayoutParser : public QXmlDefaultHandler m_sHandler.insert("group/memberdef/typedefs", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation())); + m_sHandler.insert("group/memberdef/sequences", + new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, + MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation())); + m_sHandler.insert("group/memberdef/dictionaries", + new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, + MemberListType_docDictionaryMembers, + theTranslator->trDictionaryDocumentation())); m_sHandler.insert("group/memberdef/enums", new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation())); @@ -897,6 +975,7 @@ class LayoutParser : public QXmlDefaultHandler 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) && Config_getBool(GRAPHICAL_HIERARCHY); static bool extractAll = Config_getBool(EXTRACT_ALL); @@ -933,60 +1012,137 @@ class LayoutParser : public QXmlDefaultHandler }, { "namespaces", LayoutNavEntry::Namespaces, - javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModules() : theTranslator->trNamespaces(), - javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), - javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll), + javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt || sliceOpt ? theTranslator->trModules() : theTranslator->trNamespaces(), + javaOpt || vhdlOpt ? theTranslator->trPackages() : 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 ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), + javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(), QCString(), - javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll), + javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt || sliceOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll), "namespaces" }, { "namespacemembers", LayoutNavEntry::NamespaceMembers, - javaOpt || vhdlOpt ? theTranslator->trPackageMembers() : fortranOpt ? theTranslator->trModulesMembers() : theTranslator->trNamespaceMembers(), + javaOpt || vhdlOpt ? theTranslator->trPackageMembers() : fortranOpt || sliceOpt ? theTranslator->trModulesMembers() : theTranslator->trNamespaceMembers(), QCString(), - fortranOpt ? theTranslator->trModulesMemberDescription(extractAll) : theTranslator->trNamespaceMemberDescription(extractAll), + fortranOpt || sliceOpt ? theTranslator->trModulesMemberDescription(extractAll) : theTranslator->trNamespaceMemberDescription(extractAll), "namespacemembers" }, { "classindex", LayoutNavEntry::ClassIndex, - fortranOpt ? theTranslator->trDataTypes() : vhdlOpt ? VhdlDocGen::trDesignUnits() : theTranslator->trCompoundIndex(), + fortranOpt ? theTranslator->trDataTypes() : vhdlOpt ? theTranslator->trDesignUnits() : theTranslator->trCompoundIndex(), QCString(), QCString(), "classes" }, { "classes", LayoutNavEntry::Classes, - fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitList() : theTranslator->trClasses(), + fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? theTranslator->trDesignUnitList() : theTranslator->trClasses(), theTranslator->trCompoundList(), - fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitListDescription() : theTranslator->trCompoundListDescription(), + fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? theTranslator->trDesignUnitListDescription() : theTranslator->trCompoundListDescription(), "annotated" }, { "classlist", LayoutNavEntry::ClassList, - fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitList() : theTranslator->trCompoundList(), + fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? theTranslator->trDesignUnitList() : theTranslator->trCompoundList(), QCString(), - fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitListDescription() : theTranslator->trCompoundListDescription(), + fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? theTranslator->trDesignUnitListDescription() : theTranslator->trCompoundListDescription(), "annotated" }, { "hierarchy", LayoutNavEntry::ClassHierarchy, - vhdlOpt ? VhdlDocGen::trDesignUnitHierarchy() : theTranslator->trClassHierarchy(), + vhdlOpt ? theTranslator->trDesignUnitHierarchy() : theTranslator->trClassHierarchy(), QCString(), theTranslator->trClassHierarchyDescription(), hasGraphicalHierarchy ? "inherits" : "hierarchy" }, { "classmembers", LayoutNavEntry::ClassMembers, - fortranOpt ? theTranslator->trCompoundMembersFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitMembers() : theTranslator->trCompoundMembers(), + fortranOpt ? theTranslator->trCompoundMembersFortran() : vhdlOpt ? theTranslator->trDesignUnitMembers() : theTranslator->trCompoundMembers(), QCString(), fortranOpt ? theTranslator->trCompoundMembersDescriptionFortran(extractAll) : theTranslator->trCompoundMembersDescription(extractAll), "functions" }, + { "interfaceindex", + LayoutNavEntry::InterfaceIndex, + theTranslator->trInterfaceIndex(), + QCString(), + QCString(), + "interfaces" + }, + { "interfaces", + LayoutNavEntry::Interfaces, + theTranslator->trSliceInterfaces(), + theTranslator->trInterfaceList(), + theTranslator->trInterfaceListDescription(), + "annotatedinterfaces" + }, + { "interfacelist", + LayoutNavEntry::InterfaceList, + theTranslator->trInterfaceList(), + QCString(), + theTranslator->trInterfaceListDescription(), + "annotatedinterfaces" + }, + { "interfacehierarchy", + LayoutNavEntry::InterfaceHierarchy, + theTranslator->trInterfaceHierarchy(), + QCString(), + theTranslator->trInterfaceHierarchyDescription(), + hasGraphicalHierarchy ? "interfaceinherits" : "interfacehierarchy" + }, + { "structindex", + LayoutNavEntry::StructIndex, + theTranslator->trStructIndex(), + QCString(), + QCString(), + "structs" + }, + { "structs", + LayoutNavEntry::Structs, + theTranslator->trStructs(), + theTranslator->trStructList(), + theTranslator->trStructListDescription(), + "annotatedstructs" + }, + { "structlist", + LayoutNavEntry::StructList, + theTranslator->trStructList(), + QCString(), + theTranslator->trStructListDescription(), + "annotatedstructs" + }, + { "exceptionindex", + LayoutNavEntry::ExceptionIndex, + theTranslator->trExceptionIndex(), + QCString(), + QCString(), + "exceptions" + }, + { "exceptions", + LayoutNavEntry::Exceptions, + theTranslator->trExceptions(), + theTranslator->trExceptionList(), + theTranslator->trExceptionListDescription(), + "annotatedexceptions" + }, + { "exceptionlist", + LayoutNavEntry::ExceptionList, + theTranslator->trExceptionList(), + QCString(), + theTranslator->trExceptionListDescription(), + "annotatedexceptions" + }, + { "exceptionhierarchy", + LayoutNavEntry::ExceptionHierarchy, + theTranslator->trExceptionHierarchy(), + QCString(), + theTranslator->trExceptionHierarchyDescription(), + hasGraphicalHierarchy ? "exceptioninherits" : "exceptionhierarchy" + }, { "files", LayoutNavEntry::Files, theTranslator->trFile(TRUE,FALSE), @@ -1268,7 +1424,7 @@ class LayoutParser : public QXmlDefaultHandler } private: - LayoutParser() : m_sHandler(163), m_eHandler(17), m_invalidEntry(FALSE) { } + LayoutParser() : m_sHandler(163), m_eHandler(17), m_invalidEntry(FALSE), m_part(0), m_rootNav(NULL) { } ~LayoutParser() { delete m_rootNav; } QDict<StartElementHandler> m_sHandler; diff --git a/src/layout.h b/src/layout.h index 0b9ad9e..b25aa4e 100644 --- a/src/layout.h +++ b/src/layout.h @@ -46,10 +46,11 @@ struct LayoutDocEntry // Namespace specific items NamespaceNestedNamespaces, NamespaceNestedConstantGroups, - NamespaceClasses, NamespaceInlineClasses, + NamespaceClasses, NamespaceInterfaces, NamespaceStructs, NamespaceExceptions, + NamespaceInlineClasses, // File specific items - FileClasses, FileNamespaces, FileConstantGroups, + FileClasses, FileInterfaces, FileStructs, FileExceptions, FileConstantGroups, FileNamespaces, FileIncludes, FileIncludeGraph, FileIncludedByGraph, FileSourceLink, FileInlineClasses, @@ -119,6 +120,7 @@ struct LayoutNavEntry { public: enum Kind { + None = -1, MainPage, Pages, Modules, @@ -130,10 +132,20 @@ struct LayoutNavEntry ClassIndex, ClassHierarchy, ClassMembers, + Interfaces, + InterfaceList, + InterfaceIndex, + InterfaceHierarchy, + Structs, + StructList, + StructIndex, + Exceptions, + ExceptionList, + ExceptionIndex, + ExceptionHierarchy, Files, FileList, FileGlobals, - //Dirs, Examples, User, UserGroup @@ -158,7 +170,7 @@ struct LayoutNavEntry LayoutNavEntry *find(LayoutNavEntry::Kind k,const char *file=0) const; private: - LayoutNavEntry() : m_parent(0) {} + LayoutNavEntry() : m_parent(0), m_kind(None), m_visible(FALSE) {} LayoutNavEntry *m_parent; Kind m_kind; bool m_visible; diff --git a/src/layout_default.xml b/src/layout_default.xml index f087958..373bb20 100644 --- a/src/layout_default.xml +++ b/src/layout_default.xml @@ -9,12 +9,26 @@ <tab type="namespacelist" visible="yes" title="" intro=""/> <tab type="namespacemembers" visible="yes" title="" intro=""/> </tab> + <tab type="interfaces" visible="yes" title=""> + <tab type="interfacelist" visible="yes" title="" intro=""/> + <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/> + <tab type="interfacehierarchy" visible="yes" title="" intro=""/> + </tab> <tab type="classes" visible="yes" title=""> <tab type="classlist" visible="yes" title="" intro=""/> <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> <tab type="hierarchy" visible="yes" title="" intro=""/> <tab type="classmembers" visible="yes" title="" intro=""/> </tab> + <tab type="structs" visible="yes" title=""> + <tab type="structlist" visible="yes" title="" intro=""/> + <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/> + </tab> + <tab type="exceptions" visible="yes" title=""> + <tab type="exceptionlist" visible="yes" title="" intro=""/> + <tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/> + <tab type="exceptionhierarchy" visible="yes" title="" intro=""/> + </tab> <tab type="files" visible="yes" title=""> <tab type="filelist" visible="yes" title="" intro=""/> <tab type="globals" visible="yes" title="" intro=""/> @@ -87,8 +101,13 @@ <memberdecl> <nestednamespaces visible="yes" title=""/> <constantgroups visible="yes" title=""/> + <interfaces visible="yes" title=""/> <classes visible="yes" title=""/> + <structs visible="yes" title=""/> + <exceptions visible="yes" title=""/> <typedefs title=""/> + <sequences title=""/> + <dictionaries title=""/> <enums title=""/> <functions title=""/> <variables title=""/> @@ -98,6 +117,8 @@ <memberdef> <inlineclasses title=""/> <typedefs title=""/> + <sequences title=""/> + <dictionaries title=""/> <enums title=""/> <functions title=""/> <variables title=""/> @@ -113,11 +134,16 @@ <includedbygraph visible="$INCLUDED_BY_GRAPH"/> <sourcelink visible="yes"/> <memberdecl> + <interfaces visible="yes" title=""/> <classes visible="yes" title=""/> + <structs visible="yes" title=""/> + <exceptions visible="yes" title=""/> <namespaces visible="yes" title=""/> <constantgroups visible="yes" title=""/> <defines title=""/> <typedefs title=""/> + <sequences title=""/> + <dictionaries title=""/> <enums title=""/> <functions title=""/> <variables title=""/> @@ -128,6 +154,8 @@ <inlineclasses title=""/> <defines title=""/> <typedefs title=""/> + <sequences title=""/> + <dictionaries title=""/> <enums title=""/> <functions title=""/> <variables title=""/> @@ -147,6 +175,8 @@ <classes visible="yes" title=""/> <defines title=""/> <typedefs title=""/> + <sequences title=""/> + <dictionaries title=""/> <enums title=""/> <enumvalues title=""/> <functions title=""/> @@ -166,6 +196,8 @@ <inlineclasses title=""/> <defines title=""/> <typedefs title=""/> + <sequences title=""/> + <dictionaries title=""/> <enums title=""/> <enumvalues title=""/> <functions title=""/> diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index 2233cc6..beef632 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -30,6 +30,7 @@ #include "parserintf.h" #include "filedef.h" #include "htmlentity.h" +#include "emoji.h" ManDocVisitor::ManDocVisitor(FTextStream &t,CodeOutputInterface &ci, const char *langExt) @@ -89,6 +90,21 @@ void ManDocVisitor::visit(DocSymbol *s) m_firstCol=FALSE; } +void ManDocVisitor::visit(DocEmoji *s) +{ + if (m_hide) return; + const char *res = EmojiEntityMapper::instance()->name(s->index()); + if (res) + { + m_t << res; + } + else + { + m_t << s->name(); + } + m_firstCol=FALSE; +} + void ManDocVisitor::visit(DocURL *u) { if (m_hide) return; @@ -120,6 +136,13 @@ void ManDocVisitor::visit(DocStyleChange *s) if (s->enable()) m_t << "\\fB"; else m_t << "\\fP"; m_firstCol=FALSE; break; + case DocStyleChange::Strike: + /* not supported */ + break; + case DocStyleChange::Underline: //underline is shown as emphasis + 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"; m_firstCol=FALSE; @@ -899,10 +922,7 @@ void ManDocVisitor::visitPre(DocParamSect *s) case DocParamSect::Exception: m_t << theTranslator->trExceptions(); break; case DocParamSect::TemplateParam: - /* TODO: add this - m_t << theTranslator->trTemplateParam(); break; - */ - m_t << "Template Parameters"; break; + m_t << theTranslator->trTemplateParameters(); break; default: ASSERT(0); } diff --git a/src/mandocvisitor.h b/src/mandocvisitor.h index d248c87..8efc223 100644 --- a/src/mandocvisitor.h +++ b/src/mandocvisitor.h @@ -40,6 +40,7 @@ class ManDocVisitor : public DocVisitor void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); diff --git a/src/mangen.cpp b/src/mangen.cpp index 17e6003..b3ae732 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -34,7 +34,7 @@ static QCString getExtension() { /* - * [.][nuber][rest] + * [.][number][rest] * in case of . missing, just ignore it * in case number missing, just place a 3 in front of it */ @@ -283,7 +283,7 @@ void ManGenerator::endGroupHeader(int) upperCase=FALSE; } -void ManGenerator::startMemberHeader(const char *) +void ManGenerator::startMemberHeader(const char *,int) { if (!firstCol) t << endl; t << ".SS \""; @@ -619,9 +619,9 @@ void ManGenerator::startSection(const char *,const char *,SectionInfo::SectionTy { case SectionInfo::Page: startGroupHeader(FALSE); break; case SectionInfo::Section: startGroupHeader(FALSE); break; - case SectionInfo::Subsection: startMemberHeader(0); break; - case SectionInfo::Subsubsection: startMemberHeader(0); break; - case SectionInfo::Paragraph: startMemberHeader(0); break; + case SectionInfo::Subsection: startMemberHeader(0, -1); break; + case SectionInfo::Subsubsection: startMemberHeader(0, -1); break; + case SectionInfo::Paragraph: startMemberHeader(0, -1); break; default: ASSERT(0); break; } } @@ -650,8 +650,25 @@ void ManGenerator::endSection(const char *,SectionInfo::SectionType type) } } -void ManGenerator::startSimpleSect(SectionTypes,const char *, - const char *,const char *title) +void ManGenerator::startExamples() +{ + if (!firstCol) + { t << endl << ".PP" << endl; + firstCol=TRUE; paragraph=TRUE; + col=0; + } + paragraph=FALSE; + startBold(); + docify(theTranslator->trExamples()); + endBold(); + paragraph=TRUE; +} + +void ManGenerator::endExamples() +{ +} + +void ManGenerator::startDescTable(const char *title) { if (!firstCol) { t << endl << ".PP" << endl; @@ -663,10 +680,12 @@ void ManGenerator::startSimpleSect(SectionTypes,const char *, docify(title); endBold(); paragraph=TRUE; + startDescForItem(); } -void ManGenerator::endSimpleSect() +void ManGenerator::endDescTable() { + endDescForItem(); } void ManGenerator::startParamList(ParamListTypes,const char *title) diff --git a/src/mangen.h b/src/mangen.h index b3b9f76..e109355 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -99,9 +99,10 @@ class ManGenerator : public OutputGenerator void endMemberSections() {} void startHeaderSection() {} void endHeaderSection(); - void startMemberHeader(const char *); + void startMemberHeader(const char *,int); void endMemberHeader(); void insertMemberAlign(bool) {} + void insertMemberAlignLeft(int,bool){} void startMemberSubtitle() {} void endMemberSubtitle() {} //void writeListItem(); @@ -160,7 +161,7 @@ class ManGenerator : public OutputGenerator void endCenter() {} void startSmall() {} void endSmall() {} - void startMemberDescription(const char *,const char *) { t << "\n.RI \""; firstCol=FALSE; } + void startMemberDescription(const char *,const char *,bool) { t << "\n.RI \""; firstCol=FALSE; } void endMemberDescription() { t << "\""; firstCol=FALSE; } void startMemberDeclaration() {} void endMemberDeclaration(const char *,const char *) {} @@ -168,8 +169,8 @@ class ManGenerator : public OutputGenerator const char *,const char *,const char *) {} void startDescList(SectionTypes); void endDescList() {} - void startSimpleSect(SectionTypes,const char *,const char *,const char *); - void endSimpleSect(); + void startExamples(); + void endExamples(); void startParamList(ParamListTypes,const char *title); void endParamList(); //void writeDescItem(); @@ -196,9 +197,8 @@ class ManGenerator : public OutputGenerator void endContents() {} void writeNonBreakableSpace(int n) { int i; for (i=0;i<n;i++) t << " "; } - void startDescTable(const char *t) - { startSimpleSect(EnumValues,0,0,t); startDescForItem(); } - void endDescTable() { endDescForItem(); endSimpleSect(); } + void startDescTable(const char *t); + void endDescTable(); void startDescTableRow() {} void endDescTableRow() {} void startDescTableTitle() { startItemListItem(); startBold(); startEmphasis(); endItemListItem(); } diff --git a/src/markdown.cpp b/src/markdown.cpp index d3ec3f1..b00070e 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -76,7 +76,7 @@ // so for example *bla (*.txt) is cool* #define ignoreCloseEmphChar(i) \ (data[i]=='(' || data[i]=='{' || data[i]=='[' || data[i]=='<' || \ - data[i]=='=' || data[i]=='+' || data[i]=='-' || data[i]=='\\' || \ + data[i]=='\\' || \ data[i]=='@') //---------- @@ -240,7 +240,7 @@ static QCString isBlockCommand(const char *data,int offset,int size) { return "f]"; } - else if (data[end]=='}') + else if (data[end]=='{') { return "f}"; } @@ -396,9 +396,11 @@ static int processEmphasis2(GrowBuf &out, const char *data, int size, char c) data[i-1]!='\n' ) { - out.addStr("<strong>"); + if (c == '~') out.addStr("<strike>"); + else out.addStr("<strong>"); processInline(out,data,i); - out.addStr("</strong>"); + if (c == '~') out.addStr("</strike>"); + else out.addStr("</strong>"); return i + 2; } i++; @@ -406,7 +408,7 @@ static int processEmphasis2(GrowBuf &out, const char *data, int size, char c) return 0; } -/** Parsing tripple emphasis. +/** Parsing triple emphasis. * Finds the first closing tag, and delegates to the other emph */ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c) @@ -483,6 +485,8 @@ static int processNmdash(GrowBuf &out,const char *data,int off,int size) { count++; } + if (count==2 && off>=2 && qstrncmp(data-2,"<!",2)==0) return 0; // start HTML comment + if (count==2 && (data[2]=='>')) return 0; // end HTML comment if (count==2 && (off<8 || qstrncmp(data-8,"operator",8)!=0)) // -- => ndash { out.addStr("–"); @@ -614,7 +618,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) char c = data[0]; int ret; - if (size>2 && data[1]!=c) // _bla or *bla + if (size>2 && c!='~' && data[1]!=c) // _bla or *bla { // whitespace cannot follow an opening emphasis if (data[1]==' ' || data[1]=='\n' || @@ -633,7 +637,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) } return ret+2; } - if (size>4 && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla + if (size>4 && c!='~' && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla { if (data[3]==' ' || data[3]=='\n' || (ret = processEmphasis3(out, data+3, size-3, c)) == 0) @@ -645,6 +649,27 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) return 0; } +static void writeMarkdownImage(GrowBuf &out, const char *fmt, bool explicitTitle, QCString title, QCString content, QCString link, FileDef *fd) +{ + out.addStr("@image "); + out.addStr(fmt); + out.addStr(" "); + out.addStr(link.mid(fd ? 0 : 5)); + if (!explicitTitle && !content.isEmpty()) + { + out.addStr(" \""); + out.addStr(content); + out.addStr("\""); + } + else if ((content.isEmpty() || explicitTitle) && !title.isEmpty()) + { + out.addStr(" \""); + out.addStr(title); + out.addStr("\""); + } + out.addStr("\n"); +} + static int processLink(GrowBuf &out,const char *data,int,int size) { QCString content; @@ -842,7 +867,15 @@ static int processLink(GrowBuf &out,const char *data,int,int size) } if (isToc) // special case for [TOC] { - if (g_current) g_current->stat=TRUE; + int level = Config_getInt(TOC_INCLUDE_HEADINGS); + if (level > 0 && level <=5) + { + char levStr[10]; + sprintf(levStr,"%d",level); + out.addStr("@tableofcontents{html:"); + out.addStr(levStr); + out.addStr("}"); + } } else if (isImageLink) { @@ -852,20 +885,10 @@ static int processLink(GrowBuf &out,const char *data,int,int size) (fd=findFileDef(Doxygen::imageNameDict,link,ambig))) // assume doxygen symbol link or local image link { - out.addStr("@image html "); - out.addStr(link.mid(fd ? 0 : 5)); - if (!explicitTitle && !content.isEmpty()) - { - out.addStr(" \""); - out.addStr(content); - out.addStr("\""); - } - else if ((content.isEmpty() || explicitTitle) && !title.isEmpty()) - { - out.addStr(" \""); - out.addStr(title); - out.addStr("\""); - } + writeMarkdownImage(out, "html", explicitTitle, title, content, link, fd); + writeMarkdownImage(out, "latex", explicitTitle, title, content, link, fd); + writeMarkdownImage(out, "rtf", explicitTitle, title, content, link, fd); + writeMarkdownImage(out, "docbook", explicitTitle, title, content, link, fd); } else { @@ -1588,15 +1611,15 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) int columns,start,end,cc; i = findTableColumns(data,size,start,end,columns); - + + int headerStart = start; + int headerEnd = end; + #ifdef USE_ORIGINAL_TABLES out.addStr("<table>"); // write table header, in range [start..end] out.addStr("<tr>"); - - int headerStart = start; - int headerEnd = end; #endif // read cell alignments @@ -1710,9 +1733,6 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) QVector<QVector<TableCell> > tableContents; tableContents.setAutoDelete(TRUE); - int headerStart = start; - int headerEnd = end; - int m=headerStart; QVector<TableCell> *headerContents = new QVector<TableCell>(columns); headerContents->setAutoDelete(TRUE); @@ -1781,22 +1801,20 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) QCString cellTag("th"), cellClass("class=\"markdownTableHead"); for (unsigned row = 0; row < tableContents.size(); row++) { - out.addStr(" <tr class=\"markdownTable"); if (row) { - out.addStr("Body\""); if (row % 2) { - out.addStr(" class=\"markdownTableRowOdd\">\n"); + out.addStr("<tr class=\"markdownTableRowOdd\">\n"); } else { - out.addStr(" class=\"markdownTableRowEven\">\n"); + out.addStr("<tr class=\"markdownTableRowEven\">\n"); } } else { - out.addStr("Head\">\n"); + out.addStr(" <tr class=\"markdownTableHead\">\n"); } for (int c = 0; c < columns; c++) { @@ -1882,7 +1900,7 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) QCString id; if (isHRuler(data,size)) { - out.addStr("<hr>\n"); + out.addStr("\n<hr>\n"); } else if ((level=isAtxHeader(data,size,header,id))) { @@ -1911,27 +1929,6 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) out.addStr(" "); out.addStr(header); out.addStr("\n"); - SectionInfo *si = Doxygen::sectionDict->find(id); - if (si) - { - if (si->lineNr != -1) - { - warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",header.data(),si->fileName.data(),si->lineNr); - } - else - { - warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s)",header.data(),si->fileName.data()); - } - } - else - { - si = new SectionInfo(g_fileName,g_lineNr,id,header,type,level); - if (g_current) - { - g_current->anchors->append(si); - } - Doxygen::sectionDict->append(id,si); - } } else { @@ -1950,7 +1947,7 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) out.addStr(data,size); if (hasLineBreak(data,size)) { - out.addStr("<br>"); + out.addStr("\n"); } } } @@ -2317,7 +2314,7 @@ static QCString processBlocks(const QCString &s,int indent) } else { - out.addStr("<hr>\n"); + out.addStr("\n<hr>\n"); } pi=-1; i=end; @@ -2516,6 +2513,7 @@ QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,cons // setup callback table for special characters g_actions[(unsigned int)'_']=processEmphasis; g_actions[(unsigned int)'*']=processEmphasis; + g_actions[(unsigned int)'~']=processEmphasis; g_actions[(unsigned int)'`']=processCodeSpan; g_actions[(unsigned int)'\\']=processSpecialCommand; g_actions[(unsigned int)'@']=processSpecialCommand; @@ -2548,7 +2546,7 @@ QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,cons // finally process the inline markup (links, emphasis and code spans) processInline(out,s,s.length()); out.addChar(0); - Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n---------\n",qPrint(input),qPrint(out.get())); + Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n=========\n",qPrint(input),qPrint(out.get())); return out.get(); } diff --git a/src/marshal.cpp b/src/marshal.cpp index af14978..1c7d54e 100644 --- a/src/marshal.cpp +++ b/src/marshal.cpp @@ -10,6 +10,7 @@ #include "groupdef.h" #include "example.h" #include "arguments.h" +#include "doxygen.h" #define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!' @@ -141,7 +142,9 @@ void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors) marshalQCString(s,si->fileName); marshalInt(s,si->lineNr); marshalInt(s,si->level); + delete Doxygen::sectionDict->take(si->label); // this dict owns the anchor objects } + anchors->clear(); } } @@ -344,6 +347,15 @@ void marshalMemberLists(StorageIntf *s,SDict<MemberList> *mls) } } +void marshalLocalToc(StorageIntf *s,const LocalToc <) +{ + marshalInt(s,lt.mask()); + marshalInt(s,lt.htmlLevel()); + marshalInt(s,lt.latexLevel()); + marshalInt(s,lt.xmlLevel()); + marshalInt(s,lt.docbookLevel()); +} + void marshalEntry(StorageIntf *s,Entry *e) { marshalUInt(s,HEADER); @@ -355,11 +367,14 @@ void marshalEntry(StorageIntf *s,Entry *e) marshalUInt64(s,e->spec); marshalInt(s,e->initLines); marshalBool(s,e->stat); + marshalLocalToc(s,e->localToc); marshalBool(s,e->explicitExternal); marshalBool(s,e->proto); marshalBool(s,e->subGrouping); marshalBool(s,e->callGraph); marshalBool(s,e->callerGraph); + marshalBool(s,e->referencedByRelation); + marshalBool(s,e->referencesRelation); marshalInt(s,(int)e->virt); marshalQCString(s,e->args); marshalQCString(s,e->bitfields); @@ -399,6 +414,7 @@ void marshalEntry(StorageIntf *s,Entry *e) marshalBool(s,e->artificial); marshalInt(s,(int)e->groupDocType); marshalQCString(s,e->id); + marshalQCString(s,e->metaData); } void marshalEntryTree(StorageIntf *s,Entry *e) @@ -537,11 +553,10 @@ QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s) uint i; uint count = unmarshalUInt(s); if (count==NULL_LIST) return 0; // null list - QList<SectionInfo> *result = new QList<SectionInfo>; - result->setAutoDelete(TRUE); + QList<SectionInfo> *anchors = new QList<SectionInfo>; assert(count<1000000); for (i=0;i<count;i++) - { + { QCString label = unmarshalQCString(s); QCString title = unmarshalQCString(s); QCString ref = unmarshalQCString(s); @@ -549,9 +564,14 @@ QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s) QCString fileName = unmarshalQCString(s); int lineNr = unmarshalInt(s); int level = unmarshalInt(s); - result->append(new SectionInfo(fileName,lineNr,label,title,type,level,ref)); + if (Doxygen::sectionDict->find(label)==0) + { + SectionInfo *si = new SectionInfo(fileName,lineNr,label,title,type,level,ref); + anchors->append(si); + Doxygen::sectionDict->append(label,si); // this dict owns the anchor objects + } } - return result; + return anchors; } QList<ListItemInfo> *unmarshalItemInfoList(StorageIntf *s) @@ -724,6 +744,33 @@ SDict<MemberList> *unmarshalMemberLists(StorageIntf *s) return result; } +LocalToc unmarshalLocalToc(StorageIntf *s) +{ + LocalToc result; + int mask = unmarshalInt(s); + int htmlLevel = unmarshalInt(s); + int latexLevel = unmarshalInt(s); + int xmlLevel = unmarshalInt(s); + int docbookLevel = unmarshalInt(s); + if ((mask & (1<<LocalToc::Html))!=0) + { + result.enableHtml(htmlLevel); + } + if ((mask & (1<<LocalToc::Latex))!=0) + { + result.enableLatex(latexLevel); + } + if ((mask & (1<<LocalToc::Xml))!=0) + { + result.enableXml(xmlLevel); + } + if ((mask & (1<<LocalToc::Docbook))!=0) + { + result.enableDocbook(docbookLevel); + } + return result; +} + Entry * unmarshalEntry(StorageIntf *s) { Entry *e = new Entry; @@ -737,11 +784,14 @@ Entry * unmarshalEntry(StorageIntf *s) e->spec = unmarshalUInt64(s); e->initLines = unmarshalInt(s); e->stat = unmarshalBool(s); + e->localToc = unmarshalLocalToc(s); e->explicitExternal = unmarshalBool(s); e->proto = unmarshalBool(s); e->subGrouping = unmarshalBool(s); e->callGraph = unmarshalBool(s); e->callerGraph = unmarshalBool(s); + e->referencedByRelation = unmarshalBool(s); + e->referencesRelation = unmarshalBool(s); e->virt = (Specifier)unmarshalInt(s); e->args = unmarshalQCString(s); e->bitfields = unmarshalQCString(s); @@ -785,6 +835,7 @@ Entry * unmarshalEntry(StorageIntf *s) e->artificial = unmarshalBool(s); e->groupDocType = (Entry::GroupDocType)unmarshalInt(s); e->id = unmarshalQCString(s); + e->metaData = unmarshalQCString(s); return e; } diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 01f4d8d..a2fcf69 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -101,7 +101,7 @@ static QCString addTemplateNames(const QCString &s,const QCString &n,const QCStr // ol.endParameterName(last==FALSE) // ... // ol.startParameterType(first=FALSE) -// ol.endParamtereType +// ol.endParameterType // ol.startParameterName // ol.endParameterName(last==TRUE) // ... @@ -161,10 +161,12 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) //ol.disableAllBut(OutputGenerator::Html); bool htmlOn = ol.isEnabled(OutputGenerator::Html); bool latexOn = ol.isEnabled(OutputGenerator::Latex); + bool docbookOn = ol.isEnabled(OutputGenerator::Docbook); { // html and latex if (htmlOn) ol.enable(OutputGenerator::Html); if (latexOn) ol.enable(OutputGenerator::Latex); + if (docbookOn) ol.enable(OutputGenerator::Docbook); ol.endMemberDocName(); ol.startParameterList(!md->isObjCMethod()); @@ -172,6 +174,7 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) ol.enableAll(); ol.disable(OutputGenerator::Html); ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); { // other formats if (!md->isObjCMethod()) ol.docify("("); // start argument list @@ -270,6 +273,7 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) // ol.docify(" "); //} ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); ol.disable(OutputGenerator::Html); ol.docify(" "); /* man page */ if (htmlOn) ol.enable(OutputGenerator::Html); @@ -277,12 +281,15 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) ol.startEmphasis(); ol.enable(OutputGenerator::Man); if (latexOn) ol.enable(OutputGenerator::Latex); + if (docbookOn) ol.enable(OutputGenerator::Docbook); if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name); ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); ol.endEmphasis(); ol.enable(OutputGenerator::Man); if (latexOn) ol.enable(OutputGenerator::Latex); + if (docbookOn) ol.enable(OutputGenerator::Docbook); } if (!a->array.isEmpty()) { @@ -338,10 +345,12 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); if (!md->isObjCMethod()) ol.docify(")"); // end argument list ol.enableAll(); if (htmlOn) ol.enable(OutputGenerator::Html); if (latexOn) ol.enable(OutputGenerator::Latex); + if (docbookOn) ol.enable(OutputGenerator::Docbook); if (first) ol.startParameterName(defArgList->count()<2); ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod()); ol.popGeneratorState(); @@ -475,7 +484,7 @@ class MemberDefImpl void init(Definition *def,const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberType mt,const ArgumentList *tal, - const ArgumentList *al + const ArgumentList *al,const char *meta ); ClassDef *classDef; // member of or related to @@ -530,6 +539,8 @@ class MemberDefImpl QList<ArgumentList> *defTmpArgLists; // lists of template argument lists // (for template functions in nested template classes) + QCString metaData; // Slice metadata. + ClassDef *cachedAnonymousType; // if the member has an anonymous compound // as its type then this is computed by // getClassDefOfAnonymousType() and @@ -571,10 +582,12 @@ class MemberDefImpl bool stat; // is it a static function? bool proto; // is it a prototype; bool docEnumValues; // is an enum with documented enum values. - bool annScope; // member is part of an annoymous scope + bool annScope; // member is part of an anonymous scope bool annUsed; bool hasCallGraph; bool hasCallerGraph; + bool hasReferencedByRelation; + bool hasReferencesRelation; bool explExt; // member was explicitly declared external bool tspec; // member is a template specialization bool groupHasDocs; // true if the entry that caused the grouping was documented @@ -617,7 +630,7 @@ void MemberDefImpl::init(Definition *def, const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberType mt,const ArgumentList *tal, - const ArgumentList *al + const ArgumentList *al,const char *meta ) { classDef=0; @@ -638,6 +651,8 @@ void MemberDefImpl::init(Definition *def, defTmpArgLists=0; hasCallGraph = FALSE; hasCallerGraph = FALSE; + hasReferencedByRelation = FALSE; + hasReferencesRelation = FALSE; initLines=0; type=t; if (mt==MemberType_Typedef) type.stripPrefix("typedef "); @@ -700,6 +715,7 @@ void MemberDefImpl::init(Definition *def, { declArgList = 0; } + metaData = meta; templateMaster = 0; classSectionSDict = 0; docsForDefinition = TRUE; @@ -739,17 +755,18 @@ void MemberDefImpl::init(Definition *def, * \param tal The template arguments of this member. * \param al The arguments of this member. This is a structured form of * the string past as argument \a a. + * \param meta Slice metadata. */ MemberDef::MemberDef(const char *df,int dl,int dc, const char *t,const char *na,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r,MemberType mt, - const ArgumentList *tal,const ArgumentList *al + const ArgumentList *tal,const ArgumentList *al,const char *meta ) : Definition(df,dl,dc,removeRedundantWhiteSpace(na)), visited(FALSE) { //printf("MemberDef::MemberDef(%s)\n",na); m_impl = new MemberDefImpl; - m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al); + m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al,meta); number_of_flowkw = 1; m_isLinkableCached = 0; m_isConstructorCached = 0; @@ -1392,7 +1409,7 @@ bool MemberDef::isBriefSectionVisible() const QCString MemberDef::getDeclType() const { QCString ltype(m_impl->type); - if (m_impl->mtype==MemberType_Typedef) + if (isTypedef() && getLanguage() != SrcLangExt_Slice) { ltype.prepend("typedef "); } @@ -1478,6 +1495,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); ol.docify("\n"); ol.popGeneratorState(); } @@ -1501,7 +1519,10 @@ void MemberDef::writeDeclaration(OutputList &ol, // *** write type QCString ltype(m_impl->type); - if (m_impl->mtype==MemberType_Typedef) ltype.prepend("typedef "); + if (isTypedef() && getLanguage() != SrcLangExt_Slice) + { + ltype.prepend("typedef "); + } if (isAlias()) { ltype="using"; @@ -1978,7 +1999,7 @@ void MemberDef::getLabels(QStrList &sl,Definition *container) const bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); if (optVhdl) { - sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers())); + sl.append(theTranslator->trVhdlType(getMemberSpecifiers(),TRUE)); } else { @@ -2309,11 +2330,11 @@ void MemberDef::_writeExamples(OutputList &ol) // write the list of examples that use this member if (hasExamples()) { - ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": "); + ol.startExamples(); ol.startDescForItem(); writeExample(ol,m_impl->exampleSDict); ol.endDescForItem(); - ol.endSimpleSect(); + ol.endExamples(); } } @@ -2346,8 +2367,6 @@ void MemberDef::_writeEnumValues(OutputList &ol,Definition *container, { if (first) { - //ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": "); - //ol.startDescForItem(); ol.startDescTable(theTranslator->trEnumerationValues()); } @@ -2355,28 +2374,17 @@ void MemberDef::_writeEnumValues(OutputList &ol,Definition *container, ol.addIndexItem(fmd->name(),ciname); ol.addIndexItem(ciname,fmd->name()); - //Doxygen::indexList->addIndexItem( - // ciname, // level1 - // fmd->name(), // level2 - // separateMemPages ? cfname : cfiname, // contRef - // cfname, // memRef - // fmd->anchor(), // anchor - // fmd); // memberdef Doxygen::indexList->addIndexItem(container,fmd); - //ol.writeListItem(); ol.startDescTableTitle(); ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString()); first=FALSE; - //ol.startEmphasis(); ol.docify(fmd->name()); - //ol.endEmphasis(); ol.disableAllBut(OutputGenerator::Man); ol.writeString(" "); ol.enableAll(); ol.endDoxyAnchor(cfname,fmd->anchor()); ol.endDescTableTitle(); - //ol.newParagraph(); ol.startDescTableData(); bool hasBrief = !fmd->briefDescription().isEmpty(); @@ -2407,11 +2415,7 @@ void MemberDef::_writeEnumValues(OutputList &ol,Definition *container, } if (!first) { - //ol.endItemList(); ol.endDescTable(); - //ol.endDescForItem(); - //ol.endSimpleSect(); - //ol.writeChar('\n'); } } } @@ -2433,6 +2437,10 @@ QCString MemberDef::displayDefinition() const else { ldef.prepend("enum "); + if (isSliceLocal()) + { + ldef.prepend("local "); + } } } else if (isEnumValue()) @@ -2567,7 +2575,7 @@ void MemberDef::writeDocumentation(MemberList *ml, QCString scopeName = scName; QCString memAnchor = anchor(); - QCString ciname = container->name(); + QCString ciname = container->displayName(); Definition *scopedContainer = container; // see bug 753608 if (container->definitionType()==TypeGroup) { @@ -2576,7 +2584,7 @@ void MemberDef::writeDocumentation(MemberList *ml, else if (getFileDef()) { scopeName=getFileDef()->displayName(); scopedContainer=getFileDef(); } ciname = ((GroupDef *)container)->groupTitle(); } - else if (container->definitionType()==TypeFile && getNamespaceDef()) + else if (container->definitionType()==TypeFile && getNamespaceDef() && lang != SrcLangExt_Python) { // member is in a namespace, but is written as part of the file documentation // as well, so we need to make sure its label is unique. memAnchor.prepend("file_"); @@ -2610,6 +2618,10 @@ void MemberDef::writeDocumentation(MemberList *ml, else { ldef.prepend("enum "); + if (isSliceLocal()) + { + ldef.prepend("local "); + } } } else if (isEnumValue()) @@ -2626,6 +2638,17 @@ void MemberDef::writeDocumentation(MemberList *ml, int i=0,l; static QRegExp r("@[0-9]+"); + if (lang == SrcLangExt_Slice) + { + // Remove the container scope from the member name. + QCString prefix = scName + sep; + int pos = ldef.findRev(prefix.data()); + if(pos != -1) + { + ldef.remove(pos, prefix.length()); + } + } + //---------------------------------------- ol.pushGeneratorState(); @@ -2681,6 +2704,13 @@ void MemberDef::writeDocumentation(MemberList *ml, ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs); ol.startMemberDoc(ciname,name(),memAnchor,title,memCount,memTotal,showInline); + if (!m_impl->metaData.isEmpty() && getLanguage()==SrcLangExt_Slice) + { + ol.startMemberDocPrefixItem(); + ol.docify(m_impl->metaData); + ol.endMemberDocPrefixItem(); + } + ClassDef *cd=getClassDef(); NamespaceDef *nd=getNamespaceDef(); if (!Config_getBool(HIDE_SCOPE_NAMES)) @@ -2785,6 +2815,21 @@ void MemberDef::writeDocumentation(MemberList *ml, { hasParameterList=VhdlDocGen::writeVHDLTypeDocumentation(this,scopedContainer,ol); } + else if (lang==SrcLangExt_Slice) + { + // Eliminate the self-reference. + int pos = ldef.findRev(' '); + linkifyText(TextGeneratorOLImpl(ol), + scopedContainer, + getBodyDef(), + this, + ldef.left(pos) + ); + ol.docify(ldef.mid(pos)); + Definition *scope = cd; + if (scope==0) scope = nd; + hasParameterList=writeDefArgumentList(ol,scope,this); + } else { linkifyText(TextGeneratorOLImpl(ol), @@ -2991,9 +3036,9 @@ void MemberDef::writeDocumentation(MemberList *ml, _writeExamples(ol); _writeTypeConstraints(ol); writeSourceDef(ol,cname); - writeSourceRefs(ol,cname); - writeSourceReffedBy(ol,cname); writeInlineCode(ol,cname); + if (hasReferencesRelation()) writeSourceRefs(ol,cname); + if (hasReferencedByRelation()) writeSourceReffedBy(ol,cname); _writeCallGraph(ol); _writeCallerGraph(ol); @@ -3089,7 +3134,7 @@ QCString MemberDef::fieldType() const type = m_impl->type; } - if (isTypedef()) type.prepend("typedef "); + if (isTypedef() && getLanguage() != SrcLangExt_Slice) type.prepend("typedef "); return simplifyTypeForTable(type); } @@ -3206,13 +3251,18 @@ QCString MemberDef::memberTypeName() const case MemberType_Event: return "event"; case MemberType_Interface: return "interface"; case MemberType_Service: return "service"; + case MemberType_Sequence: return "sequence"; + case MemberType_Dictionary: return "dictionary"; default: return "unknown"; } } void MemberDef::warnIfUndocumented() { - if (m_impl->memberGroup) return; + /* + * Removed bug_303020: + * if (m_impl->memberGroup) return; + */ ClassDef *cd = getClassDef(); NamespaceDef *nd = getNamespaceDef(); FileDef *fd = getFileDef(); @@ -3465,7 +3515,7 @@ MemberDef *MemberDef::createTemplateInstanceMember( methodName, substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs), m_impl->exception, m_impl->prot, - m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0 + m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0, "" ); imd->setArgumentList(actualArgList); imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs)); @@ -3627,6 +3677,8 @@ void MemberDef::writeTagFile(FTextStream &tagFile) case MemberType_Slot: tagFile << "slot"; break; case MemberType_Interface: tagFile << "interface"; break; case MemberType_Service: tagFile << "service"; break; + case MemberType_Sequence: tagFile << "sequence"; break; + case MemberType_Dictionary: tagFile << "dictionary"; break; } if (m_impl->prot!=Public) { @@ -3850,8 +3902,10 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, typeDecl.pushGeneratorState(); typeDecl.disableAllBut(OutputGenerator::Html); typeDecl.enable(OutputGenerator::Latex); + typeDecl.enable(OutputGenerator::Docbook); typeDecl.lineBreak(); typeDecl.disable(OutputGenerator::Latex); + typeDecl.disable(OutputGenerator::Docbook); typeDecl.writeString("  "); typeDecl.popGeneratorState(); } @@ -3962,6 +4016,18 @@ void MemberDef::enableCallerGraph(bool e) if (e) Doxygen::parseSourcesNeeded = TRUE; } +void MemberDef::enableReferencedByRelation(bool e) +{ + m_impl->hasReferencedByRelation=e; + if (e) Doxygen::parseSourcesNeeded = TRUE; +} + +void MemberDef::enableReferencesRelation(bool e) +{ + m_impl->hasReferencesRelation=e; + if (e) Doxygen::parseSourcesNeeded = TRUE; +} + #if 0 bool MemberDef::protectionVisible() const { @@ -4187,6 +4253,16 @@ bool MemberDef::isTypedef() const return m_impl->mtype==MemberType_Typedef; } +bool MemberDef::isSequence() const +{ + return m_impl->mtype==MemberType_Sequence; +} + +bool MemberDef::isDictionary() const +{ + return m_impl->mtype==MemberType_Dictionary; +} + bool MemberDef::isFunction() const { return m_impl->mtype==MemberType_Function; @@ -4524,6 +4600,11 @@ bool MemberDef::livesInsideEnum() const return m_impl->livesInsideEnum; } +bool MemberDef::isSliceLocal() const +{ + return (m_impl->memSpec&Entry::Local)!=0; +} + MemberList *MemberDef::enumFieldList() const { return m_impl->enumFields; @@ -4594,6 +4675,16 @@ bool MemberDef::hasCallerGraph() const return m_impl->hasCallerGraph; } +bool MemberDef::hasReferencedByRelation() const +{ + return m_impl->hasReferencedByRelation; +} + +bool MemberDef::hasReferencesRelation() const +{ + return m_impl->hasReferencesRelation; +} + MemberDef *MemberDef::templateMaster() const { return m_impl->templateMaster; @@ -5106,6 +5197,11 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph()); mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph()); mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph()); + + mdef->enableReferencedByRelation(mdec->hasReferencedByRelation() || mdef->hasReferencedByRelation()); + mdef->enableCallerGraph(mdec->hasReferencesRelation() || mdef->hasReferencesRelation()); + mdec->enableReferencedByRelation(mdec->hasReferencedByRelation() || mdef->hasReferencedByRelation()); + mdec->enableCallerGraph(mdec->hasReferencesRelation() || mdef->hasReferencesRelation()); } } } diff --git a/src/memberdef.h b/src/memberdef.h index bf7ea9a..2c88438 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -48,7 +48,7 @@ class MemberDef : public Definition const char *type,const char *name,const char *args, const char *excp,Protection prot,Specifier virt,bool stat, Relationship related,MemberType t,const ArgumentList *tal, - const ArgumentList *al); + const ArgumentList *al,const char *metaData); ~MemberDef(); DefType definitionType() const { return TypeMember; } // move this member into a different scope @@ -109,6 +109,8 @@ class MemberDef : public Definition bool isEnumerate() const; bool isEnumValue() const; bool isTypedef() const; + bool isSequence() const; + bool isDictionary() const; bool isFunction() const; bool isFunctionPtr() const; bool isDefine() const; @@ -177,6 +179,7 @@ class MemberDef : public Definition bool showInCallGraph() const; bool isStrongEnumValue() const; bool livesInsideEnum() const; + bool isSliceLocal() const; int numberOfFlowKeyWords(); // derived getters @@ -237,6 +240,9 @@ class MemberDef : public Definition bool hasCallGraph() const; bool hasCallerGraph() const; bool visibleMemberGroup(bool hideNoHeader); + // refrenced related members + bool hasReferencesRelation() const; + bool hasReferencedByRelation() const; MemberDef *templateMaster() const; QCString getScopeString() const; @@ -349,6 +355,9 @@ class MemberDef : public Definition void enableCallGraph(bool e); void enableCallerGraph(bool e); + void enableReferencedByRelation(bool e); + void enableReferencesRelation(bool e); + void setTemplateMaster(MemberDef *mt); void addListReference(Definition *d); void setDocsForDefinition(bool b); diff --git a/src/membergroup.cpp b/src/membergroup.cpp index aaa504f..5ee47ab 100644 --- a/src/membergroup.cpp +++ b/src/membergroup.cpp @@ -278,6 +278,16 @@ int MemberGroup::typedefCount() const return memberList->typedefCount(); } +int MemberGroup::sequenceCount() const +{ + return memberList->sequenceCount(); +} + +int MemberGroup::dictionaryCount() const +{ + return memberList->dictionaryCount(); +} + int MemberGroup::protoCount() const { return memberList->protoCount(); diff --git a/src/membergroup.h b/src/membergroup.h index 29fba07..b590d48 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -76,6 +76,8 @@ class MemberGroup int enumCount() const; int enumValueCount() const; int typedefCount() const; + int sequenceCount() const; + int dictionaryCount() const; int protoCount() const; int defineCount() const; int friendCount() const; diff --git a/src/memberlist.cpp b/src/memberlist.cpp index e19cead..a4e5596 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -41,6 +41,8 @@ MemberList::MemberList() : m_listType(MemberListType_pubMethods) m_enumCnt=0; m_enumValCnt=0; m_typeCnt=0; + m_seqCnt=0; + m_dictCnt=0; m_protoCnt=0; m_defCnt=0; m_friendCnt=0; @@ -59,6 +61,8 @@ MemberList::MemberList(MemberListType lt) : m_listType(lt) m_enumCnt=0; m_enumValCnt=0; m_typeCnt=0; + m_seqCnt=0; + m_dictCnt=0; m_protoCnt=0; m_defCnt=0; m_friendCnt=0; @@ -139,7 +143,7 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) //printf("----- countDecMembers count=%d ----\n",count()); m_varCnt=m_funcCnt=m_enumCnt=m_enumValCnt=0; - m_typeCnt=m_protoCnt=m_defCnt=m_friendCnt=0; + m_typeCnt=m_seqCnt=m_dictCnt=m_protoCnt=m_defCnt=m_friendCnt=0; m_numDecMembers=0; QListIterator<MemberDef> mli(*this); MemberDef *md; @@ -168,6 +172,8 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) m_enumValCnt++,m_numDecMembers++; break; case MemberType_Typedef: m_typeCnt++,m_numDecMembers++; break; + case MemberType_Sequence: m_seqCnt++,m_numDecMembers++; break; + case MemberType_Dictionary: m_dictCnt++,m_numDecMembers++; break; //case MemberType_Prototype: m_protoCnt++,m_numDecMembers++; break; case MemberType_Define: if (Config_getBool(EXTRACT_ALL) || md->argsString() || @@ -194,6 +200,8 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) m_enumCnt+=mg->enumCount(); m_enumValCnt+=mg->enumValueCount(); m_typeCnt+=mg->typedefCount(); + m_seqCnt+=mg->sequenceCount(); + m_dictCnt+=mg->dictionaryCount(); m_protoCnt+=mg->protoCount(); m_defCnt+=mg->defineCount(); m_friendCnt+=mg->friendCount(); @@ -314,16 +322,18 @@ bool MemberList::declVisible() const { switch (md->memberType()) { - case MemberType_Define: // fall through - case MemberType_Typedef: // fall through - case MemberType_Variable: // fall through - case MemberType_Function: // fall through - case MemberType_Signal: // fall through - case MemberType_Slot: // fall through - case MemberType_DCOP: // fall through - case MemberType_Property: // fall through - case MemberType_Interface: // fall through - case MemberType_Service: // fall through + case MemberType_Define: // fall through + case MemberType_Typedef: // fall through + case MemberType_Variable: // fall through + case MemberType_Function: // fall through + case MemberType_Signal: // fall through + case MemberType_Slot: // fall through + case MemberType_DCOP: // fall through + case MemberType_Property: // fall through + case MemberType_Interface: // fall through + case MemberType_Service: // fall through + case MemberType_Sequence: // fall through + case MemberType_Dictionary: // fall through case MemberType_Event: return TRUE; case MemberType_Enumeration: @@ -383,17 +393,19 @@ void MemberList::writePlainDeclarations(OutputList &ol, //printf(">>> rendering\n"); switch(md->memberType()) { - case MemberType_Define: // fall through + case MemberType_Define: // fall through //case MemberType_Prototype: // fall through - case MemberType_Typedef: // fall through - case MemberType_Variable: // fall through - case MemberType_Function: // fall through - case MemberType_Signal: // fall through - case MemberType_Slot: // fall through - case MemberType_DCOP: // fall through - case MemberType_Property: // fall through - case MemberType_Interface: // fall through - case MemberType_Service: // fall through + case MemberType_Typedef: // fall through + case MemberType_Variable: // fall through + case MemberType_Function: // fall through + case MemberType_Signal: // fall through + case MemberType_Slot: // fall through + case MemberType_DCOP: // fall through + case MemberType_Property: // fall through + case MemberType_Interface: // fall through + case MemberType_Service: // fall through + case MemberType_Sequence: // fall through + case MemberType_Dictionary: // fall through case MemberType_Event: { if (first) ol.startMemberList(),first=FALSE; @@ -419,6 +431,10 @@ void MemberList::writePlainDeclarations(OutputList &ol, { ol.startDoxyAnchor(md->getOutputFileBase(),0,md->anchor(),md->name(),QCString()); } + if (md->isSliceLocal()) + { + ol.writeString("local "); + } ol.writeString("enum "); ol.insertMemberAlign(); md->writeEnumDeclaration(ol,cd,nd,fd,gd); @@ -921,6 +937,8 @@ void MemberList::marshal(StorageIntf *s) marshalInt(s,m_enumCnt); marshalInt(s,m_enumValCnt); marshalInt(s,m_typeCnt); + marshalInt(s,m_seqCnt); + marshalInt(s,m_dictCnt); marshalInt(s,m_protoCnt); marshalInt(s,m_defCnt); marshalInt(s,m_friendCnt); @@ -953,6 +971,8 @@ void MemberList::unmarshal(StorageIntf *s) m_enumCnt = unmarshalInt(s); m_enumValCnt = unmarshalInt(s); m_typeCnt = unmarshalInt(s); + m_seqCnt = unmarshalInt(s); + m_dictCnt = unmarshalInt(s); m_protoCnt = unmarshalInt(s); m_defCnt = unmarshalInt(s); m_friendCnt = unmarshalInt(s); @@ -1021,6 +1041,8 @@ QCString MemberList::listTypeAsString(MemberListType type) case MemberListType_decDefineMembers: return "define-members"; case MemberListType_decProtoMembers: return "proto-members"; case MemberListType_decTypedefMembers: return "typedef-members"; + case MemberListType_decSequenceMembers: return "sequence-members"; + case MemberListType_decDictionaryMembers: return "dictionary-members"; case MemberListType_decEnumMembers: return "enum-members"; case MemberListType_decFuncMembers: return "func-members"; case MemberListType_decVarMembers: return "var-members"; diff --git a/src/memberlist.h b/src/memberlist.h index 38f0e89..a96f61f 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -50,17 +50,19 @@ class MemberList : private QList<MemberDef> MemberDef *take(uint index); - int varCount() const { ASSERT(m_numDecMembers!=-1); return m_varCnt; } - int funcCount() const { ASSERT(m_numDecMembers!=-1); return m_funcCnt; } - int enumCount() const { ASSERT(m_numDecMembers!=-1); return m_enumCnt; } - int enumValueCount() const { ASSERT(m_numDecMembers!=-1); return m_enumValCnt; } - int typedefCount() const { ASSERT(m_numDecMembers!=-1); return m_typeCnt; } - int protoCount() const { ASSERT(m_numDecMembers!=-1); return m_protoCnt; } - int defineCount() const { ASSERT(m_numDecMembers!=-1); return m_defCnt; } - int friendCount() const { ASSERT(m_numDecMembers!=-1); return m_friendCnt; } - int numDecMembers() const { ASSERT(m_numDecMembers!=-1); return m_numDecMembers; } - int numDocMembers() const { ASSERT(m_numDocMembers!=-1); return m_numDocMembers; } - bool needsSorting() const { return m_needsSorting; } + int varCount() const { ASSERT(m_numDecMembers!=-1); return m_varCnt; } + int funcCount() const { ASSERT(m_numDecMembers!=-1); return m_funcCnt; } + int enumCount() const { ASSERT(m_numDecMembers!=-1); return m_enumCnt; } + int enumValueCount() const { ASSERT(m_numDecMembers!=-1); return m_enumValCnt; } + int typedefCount() const { ASSERT(m_numDecMembers!=-1); return m_typeCnt; } + int sequenceCount() const { ASSERT(m_numDecMembers!=-1); return m_seqCnt; } + int dictionaryCount() const { ASSERT(m_numDecMembers!=-1); return m_dictCnt; } + int protoCount() const { ASSERT(m_numDecMembers!=-1); return m_protoCnt; } + int defineCount() const { ASSERT(m_numDecMembers!=-1); return m_defCnt; } + int friendCount() const { ASSERT(m_numDecMembers!=-1); return m_friendCnt; } + int numDecMembers() const { ASSERT(m_numDecMembers!=-1); return m_numDecMembers; } + int numDocMembers() const { ASSERT(m_numDocMembers!=-1); return m_numDocMembers; } + bool needsSorting() const { return m_needsSorting; } void countDecMembers(bool countEnumValues=FALSE,GroupDef *gd=0); void countDocMembers(bool countEnumValues=FALSE); int countInheritableMembers(ClassDef *inheritedFrom) const; @@ -98,6 +100,8 @@ class MemberList : private QList<MemberDef> int m_enumCnt; int m_enumValCnt; int m_typeCnt; + int m_seqCnt; + int m_dictCnt; int m_protoCnt; int m_defCnt; int m_friendCnt; diff --git a/src/msc.cpp b/src/msc.cpp index 5b73d65..29f96ac 100644 --- a/src/msc.cpp +++ b/src/msc.cpp @@ -217,9 +217,16 @@ void writeMscImageMapFromFile(FTextStream &t,const QCString &inFile, default: t << "unknown"; } - t << "\" alt=\"" - << baseName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl; QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context); - t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">" << imap << "</map>" << endl; + if (!imap.isEmpty()) + { + t << "\" alt=\"" + << baseName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl; + t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">" << imap << "</map>" << endl; + } + else + { + t << "\" alt=\"" << baseName << "\" border=\"0\"/>" << endl; + } } diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index c674760..bc8bb47 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -56,6 +56,9 @@ NamespaceDef::NamespaceDef(const char *df,int dl,int dc, setFileName(name); } classSDict = new ClassSDict(17); + interfaceSDict = new ClassSDict(17); + structSDict = new ClassSDict(17); + exceptionSDict = new ClassSDict(17); namespaceSDict = new NamespaceSDict(17); m_innerCompounds = new SDict<Definition>(17); usingDirList = 0; @@ -87,6 +90,9 @@ NamespaceDef::NamespaceDef(const char *df,int dl,int dc, NamespaceDef::~NamespaceDef() { delete classSDict; + delete interfaceSDict; + delete structSDict; + delete exceptionSDict; delete namespaceSDict; delete m_innerCompounds; delete usingDirList; @@ -164,12 +170,34 @@ void NamespaceDef::addInnerCompound(Definition *d) void NamespaceDef::insertClass(ClassDef *cd) { - if (classSDict->find(cd->name())==0) + ClassSDict *d = classSDict; + + if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + if (cd->compoundType()==ClassDef::Interface) + { + d = interfaceSDict; + } + else if (cd->compoundType()==ClassDef::Struct) + { + d = structSDict; + } + else if (cd->compoundType()==ClassDef::Exception) + { + d = exceptionSDict; + } + } + + if (d->find(cd->name())==0) { if (Config_getBool(SORT_BRIEF_DOCS)) - classSDict->inSort(cd->name(),cd); + { + d->inSort(cd->name(),cd); + } else - classSDict->append(cd->name(),cd); + { + d->append(cd->name(),cd); + } } } @@ -245,6 +273,14 @@ void NamespaceDef::insertMember(MemberDef *md) addMemberToList(MemberListType_decTypedefMembers,md); addMemberToList(MemberListType_docTypedefMembers,md); break; + case MemberType_Sequence: + addMemberToList(MemberListType_decSequenceMembers,md); + addMemberToList(MemberListType_docSequenceMembers,md); + break; + case MemberType_Dictionary: + addMemberToList(MemberListType_decDictionaryMembers,md); + addMemberToList(MemberListType_docDictionaryMembers,md); + break; case MemberType_Enumeration: addMemberToList(MemberListType_decEnumMembers,md); addMemberToList(MemberListType_docEnumMembers,md); @@ -313,19 +349,27 @@ void NamespaceDef::writeTagFile(FTextStream &tagFile) case LayoutDocEntry::NamespaceClasses: { if (classSDict) - { - SDict<ClassDef>::Iterator ci(*classSDict); - ClassDef *cd; - for (ci.toFirst();(cd=ci.current());++ci) - { - if (cd->isLinkableInProject()) - { - tagFile << " <class kind=\"" << cd->compoundTypeString() - << "\">" << convertToXML(cd->name()) << "</class>" << endl; - } - } - } + writeClassesToTagFile(tagFile, classSDict); } + break; + case LayoutDocEntry::NamespaceInterfaces: + { + if (interfaceSDict) + writeClassesToTagFile(tagFile, interfaceSDict); + } + break; + case LayoutDocEntry::NamespaceStructs: + { + if (structSDict) + writeClassesToTagFile(tagFile, structSDict); + } + break; + case LayoutDocEntry::NamespaceExceptions: + { + if (exceptionSDict) + writeClassesToTagFile(tagFile, exceptionSDict); + } + break; case LayoutDocEntry::MemberDecl: { LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; @@ -436,6 +480,24 @@ void NamespaceDef::writeBriefDescription(OutputList &ol) //ol.newParagraph(); //ol.popGeneratorState(); } + + // Write a summary of the Slice definition including metadata. + if (getLanguage() == SrcLangExt_Slice) + { + ol.startParagraph(); + ol.startTypewriter(); + if (!metaData.isEmpty()) + { + ol.docify(metaData); + ol.lineBreak(); + } + ol.docify("module "); + ol.docify(stripScope(name())); + ol.docify(" { ... }"); + ol.endTypewriter(); + ol.endParagraph(); + } + ol.writeSynopsis(); } @@ -467,9 +529,9 @@ void NamespaceDef::endMemberDocumentation(OutputList &ol) } } -void NamespaceDef::writeClassDeclarations(OutputList &ol,const QCString &title) +void NamespaceDef::writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d) { - if (classSDict) classSDict->writeDeclaration(ol,0,title,TRUE); + if (d) d->writeDeclaration(ol,0,title,TRUE); } void NamespaceDef::writeInlineClasses(OutputList &ol) @@ -525,12 +587,38 @@ void NamespaceDef::writeSummaryLinks(OutputList &ol) SrcLangExt lang = getLanguage(); for (eli.toFirst();(lde=eli.current());++eli) { - if ((lde->kind()==LayoutDocEntry::NamespaceClasses && classSDict && classSDict->declVisible()) || - (lde->kind()==LayoutDocEntry::NamespaceNestedNamespaces && namespaceSDict && namespaceSDict->declVisible()) - ) + if (lde->kind()==LayoutDocEntry::NamespaceClasses && classSDict && classSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "nested-classes"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::NamespaceInterfaces && interfaceSDict && interfaceSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "interfaces"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::NamespaceStructs && structSDict && structSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "structs"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::NamespaceExceptions && exceptionSDict && exceptionSDict->declVisible()) { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; - QCString label = lde->kind()==LayoutDocEntry::NamespaceClasses ? "nested-classes" : "namespaces"; + QCString label = "exceptions"; + ol.writeSummaryLink(0,label,ls->title(lang),first); + first=FALSE; + } + else if (lde->kind()==LayoutDocEntry::NamespaceNestedNamespaces && namespaceSDict && namespaceSDict->declVisible()) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = "namespaces"; ol.writeSummaryLink(0,label,ls->title(lang),first); first=FALSE; } @@ -566,6 +654,20 @@ void NamespaceDef::addNamespaceAttributes(OutputList &ol) } } +void NamespaceDef::writeClassesToTagFile(FTextStream &tagFile,ClassSDict *d) +{ + SDict<ClassDef>::Iterator ci(*d); + ClassDef *cd; + for (ci.toFirst();(cd=ci.current());++ci) + { + if (cd->isLinkableInProject()) + { + tagFile << " <class kind=\"" << cd->compoundTypeString() + << "\">" << convertToXML(cd->name()) << "</class>" << endl; + } + } +} + void NamespaceDef::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); @@ -618,7 +720,25 @@ void NamespaceDef::writeDocumentation(OutputList &ol) case LayoutDocEntry::NamespaceClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; - writeClassDeclarations(ol,ls->title(lang)); + writeClassDeclarations(ol,ls->title(lang),classSDict); + } + break; + case LayoutDocEntry::NamespaceInterfaces: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title(lang),interfaceSDict); + } + break; + case LayoutDocEntry::NamespaceStructs: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title(lang),structSDict); + } + break; + case LayoutDocEntry::NamespaceExceptions: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title(lang),exceptionSDict); } break; case LayoutDocEntry::NamespaceNestedNamespaces: @@ -677,6 +797,9 @@ void NamespaceDef::writeDocumentation(OutputList &ol) case LayoutDocEntry::ClassUsedFiles: case LayoutDocEntry::ClassInlineClasses: case LayoutDocEntry::FileClasses: + case LayoutDocEntry::FileInterfaces: + case LayoutDocEntry::FileStructs: + case LayoutDocEntry::FileExceptions: case LayoutDocEntry::FileNamespaces: case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: @@ -779,7 +902,8 @@ int NamespaceDef::countMembers() { MemberList *allMemberList = getMemberList(MemberListType_allMembersList); if (allMemberList) allMemberList->countDocMembers(); - return (allMemberList ? allMemberList->numDocMembers() : 0)+classSDict->count(); + return (allMemberList ? allMemberList->numDocMembers() : 0) + + classSDict->count() + interfaceSDict->count() + structSDict->count() + exceptionSDict->count(); } void NamespaceDef::addUsingDirective(NamespaceDef *nd) @@ -961,7 +1085,7 @@ void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title, bool found=FALSE; for (ni.toFirst();(nd=ni.current()) && !found;++ni) { - if (nd->isLinkable()) + if (nd->isLinkable() && nd->hasDocumentation()) { SrcLangExt lang = nd->getLanguage(); if (SrcLangExt_IDL==lang) @@ -1078,14 +1202,24 @@ void NamespaceDef::sortMemberLists() { classSDict->sort(); } + if (interfaceSDict) + { + interfaceSDict->sort(); + } + if (structSDict) + { + structSDict->sort(); + } + if (exceptionSDict) + { + exceptionSDict->sort(); + } if (namespaceSDict) { namespaceSDict->sort(); } } - - MemberList *NamespaceDef::getMemberList(MemberListType lt) const { QListIterator<MemberList> mli(m_memberLists); @@ -1155,7 +1289,7 @@ QCString NamespaceDef::title() const { pageTitle = theTranslator->trPackage(displayName()); } - else if (lang==SrcLangExt_Fortran) + else if (lang==SrcLangExt_Fortran || lang==SrcLangExt_Slice) { pageTitle = theTranslator->trModuleReference(displayName()); } @@ -1209,3 +1343,7 @@ QCString NamespaceDef::compoundTypeString() const return ""; } +void NamespaceDef::setMetaData(const QCString &m) +{ + metaData = m; +} diff --git a/src/namespacedef.h b/src/namespacedef.h index 8b7d7cc..b46d074 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -97,12 +97,23 @@ class NamespaceDef : public Definition /*! Returns the classes contained in this namespace */ ClassSDict *getClassSDict() const { return classSDict; } + /*! Returns the Slice interfaces contained in this namespace */ + ClassSDict *getInterfaceSDict() const { return interfaceSDict; } + + /*! Returns the Slice structs contained in this namespace */ + ClassSDict *getStructSDict() const { return structSDict; } + + /*! Returns the Slice exceptions contained in this namespace */ + ClassSDict *getExceptionSDict() const { return exceptionSDict; } + /*! Returns the namespaces contained in this namespace */ NamespaceSDict *getNamespaceSDict() const { return namespaceSDict; } QCString title() const; QCString compoundTypeString() const; + void setMetaData(const QCString &m); + bool visited; private: @@ -114,7 +125,7 @@ class NamespaceDef : public Definition void writeBriefDescription(OutputList &ol); void startMemberDeclarations(OutputList &ol); void endMemberDeclarations(OutputList &ol); - void writeClassDeclarations(OutputList &ol,const QCString &title); + void writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d); void writeInlineClasses(OutputList &ol); void writeNamespaceDeclarations(OutputList &ol,const QCString &title, bool isConstantGroup=false); @@ -124,6 +135,7 @@ class NamespaceDef : public Definition void endMemberDocumentation(OutputList &ol); void writeSummaryLinks(OutputList &ol); void addNamespaceAttributes(OutputList &ol); + void writeClassesToTagFile(FTextStream &,ClassSDict *d); QCString fileName; FileList files; @@ -136,10 +148,14 @@ class NamespaceDef : public Definition QList<MemberList> m_memberLists; MemberGroupSDict *memberGroupSDict; ClassSDict *classSDict; + ClassSDict *interfaceSDict; + ClassSDict *structSDict; + ClassSDict *exceptionSDict; NamespaceSDict *namespaceSDict; bool m_subGrouping; enum { NAMESPACE, MODULE, CONSTANT_GROUP, LIBRARY } m_type; bool m_isPublished; + QCString metaData; }; /** A list of NamespaceDef objects. */ diff --git a/src/outputgen.h b/src/outputgen.h index 68356b4..a99cff3 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -145,7 +145,8 @@ class BaseOutputDocInterface : public CodeOutputInterface Since, Date, Bug, Note, Warning, Par, Deprecated, Pre, Post, Invar, Remark, Attention, - Todo, Test, RCS, */ EnumValues, + Todo, Test, RCS, */ + EnumValues, Examples }; @@ -279,9 +280,8 @@ class BaseOutputDocInterface : public CodeOutputInterface virtual void startSmall() = 0; virtual void endSmall() = 0; - virtual void startSimpleSect(SectionTypes t,const char *file, - const char *anchor,const char *title) = 0; - virtual void endSimpleSect() = 0; + virtual void startExamples() = 0; + virtual void endExamples() = 0; virtual void startParamList(ParamListTypes t,const char *title) = 0; virtual void endParamList() = 0; @@ -322,7 +322,7 @@ class BaseOutputDocInterface : public CodeOutputInterface class OutputGenerator : public BaseOutputDocInterface { public: - enum OutputType { Html, Latex, Man, RTF, XML, DEF, Perl }; + enum OutputType { Html, Latex, Man, RTF, XML, DEF, Perl , Docbook}; OutputGenerator(); virtual ~OutputGenerator(); @@ -380,7 +380,7 @@ class OutputGenerator : public BaseOutputDocInterface virtual void endMemberSections() = 0; virtual void startHeaderSection() = 0; virtual void endHeaderSection() = 0; - virtual void startMemberHeader(const char *anchor) = 0; + virtual void startMemberHeader(const char *anchor, int typ) = 0; virtual void endMemberHeader() = 0; virtual void startMemberSubtitle() = 0; virtual void endMemberSubtitle() = 0; @@ -403,6 +403,7 @@ class OutputGenerator : public BaseOutputDocInterface virtual void startMemberGroup() = 0; virtual void endMemberGroup(bool) = 0; virtual void insertMemberAlign(bool) = 0; + virtual void insertMemberAlignLeft(int,bool) = 0; virtual void startMemberDoc(const char *,const char *, const char *,const char *,int,int,bool) = 0; virtual void endMemberDoc(bool) = 0; @@ -414,7 +415,7 @@ class OutputGenerator : public BaseOutputDocInterface virtual void writeStartAnnoItem(const char *type,const char *file, const char *path,const char *name) = 0; virtual void writeEndAnnoItem(const char *name) = 0; - virtual void startMemberDescription(const char *anchor,const char *inheritId) = 0; + virtual void startMemberDescription(const char *anchor,const char *inheritId, bool typ) = 0; virtual void endMemberDescription() = 0; virtual void startMemberDeclaration() = 0; virtual void endMemberDeclaration(const char *anchor,const char *inheritId) = 0; diff --git a/src/outputlist.h b/src/outputlist.h index 0738ed1..5fd8017 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -191,8 +191,8 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startHeaderSection); } void endHeaderSection() { forall(&OutputGenerator::endHeaderSection); } - void startMemberHeader(const char *anchor) - { forall(&OutputGenerator::startMemberHeader,anchor); } + void startMemberHeader(const char *anchor, int typ = 2) + { forall(&OutputGenerator::startMemberHeader,anchor,typ); } void endMemberHeader() { forall(&OutputGenerator::endMemberHeader); } void startMemberSubtitle() @@ -237,6 +237,8 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endMemberGroup,last); } void insertMemberAlign(bool templ=FALSE) { forall(&OutputGenerator::insertMemberAlign,templ); } + void insertMemberAlignLeft(int typ=0, bool templ=FALSE) + { forall(&OutputGenerator::insertMemberAlignLeft,typ,templ); } void writeRuler() { forall(&OutputGenerator::writeRuler); } void writeAnchor(const char *fileName,const char *name) @@ -306,8 +308,8 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startBold); } void endBold() { forall(&OutputGenerator::endBold); } - void startMemberDescription(const char *anchor,const char *inheritId=0) - { forall(&OutputGenerator::startMemberDescription,anchor,inheritId); } + void startMemberDescription(const char *anchor,const char *inheritId=0, bool typ = false) + { forall(&OutputGenerator::startMemberDescription,anchor,inheritId, typ); } void endMemberDescription() { forall(&OutputGenerator::endMemberDescription); } void startMemberDeclaration() @@ -319,11 +321,10 @@ class OutputList : public OutputDocInterface const char *title,const char *name) { forall(&OutputGenerator::writeInheritedSectionTitle,id,ref, file,anchor,title,name); } - void startSimpleSect(SectionTypes t,const char *file,const char *anchor, - const char *title) - { forall(&OutputGenerator::startSimpleSect,t,file,anchor,title); } - void endSimpleSect() - { forall(&OutputGenerator::endSimpleSect); } + void startExamples() + { forall(&OutputGenerator::startExamples); } + void endExamples() + { forall(&OutputGenerator::endExamples); } void startParamList(ParamListTypes t,const char *title) { forall(&OutputGenerator::startParamList,t,title); } void endParamList() diff --git a/src/pagedef.cpp b/src/pagedef.cpp index b2b7dc8..79a78d3 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -35,7 +35,7 @@ PageDef::PageDef(const char *f,int l,const char *n, m_pageScope = 0; m_nestingLevel = 0; m_fileName = ::convertNameToFile(n,FALSE,TRUE); - m_showToc = FALSE; + m_showLineNo = FALSE; } PageDef::~PageDef() @@ -187,6 +187,7 @@ void PageDef::writeDocumentation(OutputList &ol) ol.pushGeneratorState(); //2.{ ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Docbook); ol.disable(OutputGenerator::RTF); ol.disable(OutputGenerator::Man); if (!title().isEmpty() && !name().isEmpty() && si!=0) @@ -207,9 +208,9 @@ void PageDef::writeDocumentation(OutputList &ol) ol.popGeneratorState(); //2.} - if (m_showToc && hasSections()) + if ((m_localToc.isHtmlEnabled() || m_localToc.isLatexEnabled() || m_localToc.isDocbookEnabled()) && hasSections()) { - writeToc(ol); + writeToc(ol, m_localToc); } writePageDocumentation(ol); @@ -269,6 +270,7 @@ void PageDef::writePageDocumentation(OutputList &ol) ol.pushGeneratorState(); ol.disableAll(); ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Docbook); ol.enable(OutputGenerator::RTF); PageSDict::Iterator pdi(*m_subPageDict); @@ -326,8 +328,17 @@ void PageDef::setNestingLevel(int l) m_nestingLevel = l; } -void PageDef::setShowToc(bool b) +void PageDef::setLocalToc(const LocalToc <) { - m_showToc |= b; + m_localToc = lt; } +void PageDef::setShowLineNo(bool b) +{ + m_showLineNo = b; +} + +bool PageDef::showLineNo() const +{ + return m_showLineNo; +} diff --git a/src/pagedef.h b/src/pagedef.h index 41b84cb..a0c3acb 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -34,7 +34,8 @@ class PageDef : public Definition // setters void setFileName(const char *name); - void setShowToc(bool b); + void setLocalToc(const LocalToc &tl); + void setShowLineNo(bool); // getters DefType definitionType() const { return TypePage; } @@ -59,10 +60,11 @@ class PageDef : public Definition bool documentedPage() const; bool hasSubPages() const; bool hasParentPage() const; - bool showToc() const { return m_showToc; } + LocalToc localToc() const { return m_localToc; } void setPageScope(Definition *d){ m_pageScope = d; } Definition *getPageScope() const { return m_pageScope; } QCString displayName(bool=TRUE) const { return !m_title.isEmpty() ? m_title : Definition::name(); } + bool showLineNo() const; void writeDocumentation(OutputList &ol); void writeTagFile(FTextStream &); @@ -75,7 +77,8 @@ class PageDef : public Definition PageSDict *m_subPageDict; // list of pages in the group Definition *m_pageScope; int m_nestingLevel; - bool m_showToc; + LocalToc m_localToc; + bool m_showLineNo; }; class PageSDict : public SDict<PageDef> diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index ef5cbc2..fcc7ef5 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -43,6 +43,7 @@ #include "section.h" #include "util.h" #include "htmlentity.h" +#include "emoji.h" #define PERLOUTPUT_MAX_INDENTATION 40 @@ -299,6 +300,7 @@ public: void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); @@ -428,7 +430,7 @@ private: }; PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output) - : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false) + : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false), m_textblockstart(FALSE) { m_output.openList("doc"); } @@ -609,6 +611,19 @@ void PerlModDocVisitor::visit(DocSymbol *sy) err("perl: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(sy->symbol(),TRUE)); } } +void PerlModDocVisitor::visit(DocEmoji *sy) +{ + enterText(); + const char *name = EmojiEntityMapper::instance()->name(sy->index()); + if (name) + { + m_output.add(name); + } + else + { + m_output.add(sy->name()); + } +} void PerlModDocVisitor::visit(DocURL *u) { @@ -626,6 +641,8 @@ void PerlModDocVisitor::visit(DocStyleChange *s) switch (s->style()) { case DocStyleChange::Bold: style = "bold"; break; + case DocStyleChange::Strike: style = "strike"; break; + case DocStyleChange::Underline: style = "underline"; break; case DocStyleChange::Italic: style = "italic"; break; case DocStyleChange::Code: style = "code"; break; case DocStyleChange::Subscript: style = "subscript"; break; @@ -1254,6 +1271,7 @@ void PerlModDocVisitor::visitPre(DocParamSect *s) err("unknown parameter section found\n"); break; } + m_output.openHash(); openOther(); openSubBlock(type); } @@ -1262,6 +1280,7 @@ void PerlModDocVisitor::visitPost(DocParamSect *) { closeSubBlock(); closeOther(); + m_output.closeHash(); } void PerlModDocVisitor::visitPre(DocParamList *pl) @@ -1566,21 +1585,22 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) bool isFunc=FALSE; switch (md->memberType()) { - case MemberType_Define: memType="define"; break; - case MemberType_EnumValue: memType="enumvalue"; break; - case MemberType_Property: memType="property"; break; - case MemberType_Variable: memType="variable"; break; - case MemberType_Typedef: memType="typedef"; break; - case MemberType_Enumeration: memType="enum"; break; - case MemberType_Function: memType="function"; isFunc=TRUE; break; - case MemberType_Signal: memType="signal"; isFunc=TRUE; break; - //case MemberType_Prototype: memType="prototype"; isFunc=TRUE; break; - case MemberType_Friend: memType="friend"; isFunc=TRUE; break; - case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break; - case MemberType_Slot: memType="slot"; isFunc=TRUE; break; - case MemberType_Event: memType="event"; break; - case MemberType_Interface: memType="interface"; break; - case MemberType_Service: memType="service"; break; + case MemberType_Define: memType="define"; break; + case MemberType_EnumValue: memType="enumvalue"; break; + case MemberType_Property: memType="property"; break; + case MemberType_Variable: memType="variable"; break; + case MemberType_Typedef: memType="typedef"; break; + case MemberType_Enumeration: memType="enum"; break; + case MemberType_Function: memType="function"; isFunc=TRUE; break; + case MemberType_Signal: memType="signal"; isFunc=TRUE; break; + case MemberType_Friend: memType="friend"; isFunc=TRUE; break; + case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break; + case MemberType_Slot: memType="slot"; isFunc=TRUE; break; + case MemberType_Event: memType="event"; break; + case MemberType_Interface: memType="interface"; break; + case MemberType_Service: memType="service"; break; + case MemberType_Sequence: memType="sequence"; break; + case MemberType_Dictionary: memType="dictionary"; break; } m_output.openHash() @@ -1605,7 +1625,7 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) m_output.openList("parameters"); ArgumentList *declAl = md->declArgumentList(); ArgumentList *defAl = md->argumentList(); - if (declAl && declAl->count()>0) + if (declAl && defAl && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); diff --git a/src/plantuml.cpp b/src/plantuml.cpp index 609d5fd..ada035b 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -47,7 +47,7 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con } QCString text = "@startuml\n"; text+=content; - text+="@enduml\n"; + text+="\n@enduml\n"; file.writeBlock( text, text.length() ); file.close(); return baseName; @@ -88,7 +88,9 @@ void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutp { pumlArgs += "-graphvizdot \""; pumlArgs += dotPath; - pumlArgs += "dot\" "; + pumlArgs += "dot"; + pumlArgs += portable_commandExtension(); + pumlArgs += "\" "; } pumlArgs+="-o \""; pumlArgs+=outDir; diff --git a/src/portable.cpp b/src/portable.cpp index 4ad88a4..3dccaed 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -22,10 +22,10 @@ extern char **environ; #endif #include "portable.h" +#include "util.h" #ifndef NODEBUG #include "debug.h" #endif -//#include "doxygen.h" static double g_sysElapsedTime; static QTime g_time; @@ -35,7 +35,12 @@ int portable_system(const char *command,const char *args,bool commandHasConsole) if (command==0) return 1; +#if defined(_WIN32) && !defined(__CYGWIN__) + QCString commandCorrectedPath = substitute(command,'/','\\'); + QCString fullCmd=commandCorrectedPath; +#else QCString fullCmd=command; +#endif fullCmd=fullCmd.stripWhiteSpace(); if (fullCmd.at(0)!='"' && fullCmd.find(' ')!=-1) { @@ -134,7 +139,7 @@ int portable_system(const char *command,const char *args,bool commandHasConsole) // For that case COM is initialized as follows CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - QString commandw = QString::fromUtf8( command ); + QString commandw = QString::fromUtf8( commandCorrectedPath ); QString argsw = QString::fromUtf8( args ); // gswin32 is a GUI api which will pop up a window and run @@ -206,8 +211,8 @@ void portable_setenv(const char *name,const char *value) #if defined(_WIN32) && !defined(__CYGWIN__) SetEnvironmentVariable(name,value); #else - register char **ep = 0; - register size_t size; + char **ep = 0; + size_t size; const size_t namelen=qstrlen(name); const size_t vallen=qstrlen(value) + 1; @@ -458,18 +463,7 @@ void portable_correct_path(void) { #if defined(_WIN32) && !defined(__CYGWIN__) const char *p = portable_getenv("PATH"); - char *q = (char *)malloc(strlen(p) + 1); - strcpy(q, p); - bool found = false; - for (int i = 0 ; i < strlen(q); i++) - { - if (q[i] == '/') - { - q[i] = '\\'; - found = true; - } - } - if (found) portable_setenv("PATH",q); - free(q); + QCString result = substitute(p,'/','\\'); + if (result!=p) portable_setenv("PATH",result.data()); #endif } @@ -1405,7 +1405,7 @@ void addDefine() MemberDef *md=new MemberDef( g_yyFileName,g_yyLineNr-g_yyMLines,g_yyColNr, "#define",g_defName,g_defArgsStr,0, - Public,Normal,FALSE,Member,MemberType_Define,0,0); + Public,Normal,FALSE,Member,MemberType_Define,0,0,""); if (!g_defArgsStr.isEmpty()) { ArgumentList *argList = new ArgumentList; @@ -1739,7 +1739,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) %x SkipString %x CopyLine %x CopyString +%x CopyStringCs %x CopyStringFtn +%x CopyStringFtnDouble %x Include %x IncludeID %x EndImport @@ -1849,9 +1851,21 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <CopyLine>"'"."'" { outputArray(yytext,(int)yyleng); } +<CopyLine>@\" { + if (getLanguageFromFileName(g_yyFileName)!=SrcLangExt_CSharp) REJECT; + outputArray(yytext,(int)yyleng); + BEGIN( CopyStringCs ); + } <CopyLine>\" { outputChar(*yytext); - BEGIN( CopyString ); + if (getLanguageFromFileName(g_yyFileName)!=SrcLangExt_Fortran) + { + BEGIN( CopyString ); + } + else + { + BEGIN( CopyStringFtnDouble ); + } } <CopyLine>\' { if (getLanguageFromFileName(g_yyFileName)!=SrcLangExt_Fortran) REJECT; @@ -1859,17 +1873,30 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN( CopyStringFtn ); } <CopyString>[^\"\\\r\n]+ { + outputArray(yytext,(int)yyleng); + } +<CopyStringCs>[^\"\r\n]+ { outputArray(yytext,(int)yyleng); } <CopyString>\\. { outputArray(yytext,(int)yyleng); } -<CopyString>\" { +<CopyString,CopyStringCs>\" { + outputChar(*yytext); + BEGIN( CopyLine ); + } +<CopyStringFtnDouble>[^\"\\\r\n]+ { + outputArray(yytext,(int)yyleng); + } +<CopyStringFtnDouble>\\. { + outputArray(yytext,(int)yyleng); + } +<CopyStringFtnDouble>\" { outputChar(*yytext); BEGIN( CopyLine ); } <CopyStringFtn>[^\'\\\r\n]+ { - outputArray(yytext,(int)yyleng); + outputArray(yytext,(int)yyleng); } <CopyStringFtn>\\. { outputArray(yytext,(int)yyleng); @@ -1934,6 +1961,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } } <CopyLine>"\\"\r?/\n { // strip line continuation characters + if (getLanguageFromFileName(g_yyFileName)==SrcLangExt_Fortran) outputChar(*yytext); } <CopyLine>. { outputChar(*yytext); @@ -3195,7 +3223,7 @@ void preprocessFile(const char *fileName,BufStr &input,BufStr &output) { CondCtx *ctx = g_condStack.pop(); QCString sectionInfo = " "; - if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label %s ",ctx->sectionId.data()); + if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label '%s' ",ctx->sectionId.stripWhiteSpace().data()); warn(fileName,ctx->lineNr,"Conditional section%sdoes not have " "a corresponding \\endcond command within this file.",sectionInfo.data()); delete ctx; diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index d1dbb74..8d375fc 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -22,6 +22,7 @@ #include <qglobal.h> #include "docvisitor.h" #include "htmlentity.h" +#include "emoji.h" #include "message.h" /*! Concrete visitor implementation for pretty printing */ @@ -68,6 +69,19 @@ class PrintDocVisitor : public DocVisitor printf("print: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE)); } } + void visit(DocEmoji *s) + { + indent_leaf(); + 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())); + } + } void visit(DocURL *u) { indent_leaf(); @@ -91,6 +105,12 @@ class PrintDocVisitor : public DocVisitor case DocStyleChange::Bold: if (s->enable()) printf("<bold>"); else printf("</bold>"); break; + case DocStyleChange::Strike: + if (s->enable()) printf("<strike>"); else printf("</strike>"); + break; + case DocStyleChange::Underline: + if (s->enable()) printf("<underline>"); else printf("</underline>"); + break; case DocStyleChange::Italic: if (s->enable()) printf("<italic>"); else printf("</italic>"); break; @@ -167,7 +187,10 @@ class PrintDocVisitor : public DocVisitor case DocInclude::Include: printf("include"); break; case DocInclude::IncWithLines: printf("incwithlines"); break; case DocInclude::DontInclude: printf("dontinclude"); break; - case DocInclude::HtmlInclude: printf("htmlinclude"); break; + case DocInclude::HtmlInclude: + printf("htmlinclude"); + if (inc->isBlock()) printf(" block=\"yes\""); + break; case DocInclude::LatexInclude: printf("latexinclude"); break; case DocInclude::VerbInclude: printf("verbinclude"); break; case DocInclude::Snippet: printf("snippet"); break; @@ -490,7 +513,7 @@ class PrintDocVisitor : public DocVisitor case DocImage::Rtf: printf("rtf"); break; case DocImage::DocBook: printf("docbook"); break; } - printf("\" %s %s>\n",img->width().data(),img->height().data()); + printf("\" %s %s inline=\"%s\">\n",img->width().data(),img->height().data(),img->isInlineImage() ? "yes" : "no"); } void visitPost(DocImage *) { @@ -634,13 +657,13 @@ class PrintDocVisitor : public DocVisitor void visitPre(DocXRefItem *x) { indent_pre(); - printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\"/>\n", + printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\">\n", x->file().data(),x->anchor().data(),x->title().data()); } void visitPost(DocXRefItem *) { indent_post(); - printf("<xrefitem/>\n"); + printf("</xrefitem>\n"); } void visitPre(DocInternalRef *r) { diff --git a/src/pycode.l b/src/pycode.l index fe1eef5..d9c9f01 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -884,7 +884,7 @@ SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ}) SHORTSTRINGCHAR [^\\\n"] STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING}) STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR") -KEYWORD ("lambda"|"import"|"class"|"assert"|"as"|"from"|"global"|"def"|"True"|"False") +KEYWORD ("lambda"|"import"|"class"|"assert"|"with"|"as"|"from"|"global"|"def"|"True"|"False") FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally") QUOTES ("\""[^"]*"\"") SINGLEQUOTES ("'"[^']*"'") @@ -1091,8 +1091,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT char *s=g_curClassBases.first(); while (s) { - ClassDef *baseDefToAdd; - baseDefToAdd=g_codeClassSDict[s]; + ClassDef *baseDefToAdd=g_codeClassSDict[s]; // Try to find class in global // scope @@ -1311,7 +1310,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT \\. { // espaced char codify(yytext); } - {STRINGPREFIX}?{TRIDOUBLEQUOTE} { // tripple double quotes + {STRINGPREFIX}?{TRIDOUBLEQUOTE} { // triple double quotes codify(yytext); } "'" { // end of the string @@ -1334,7 +1333,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT \\. { // espaced char codify(yytext); } - {STRINGPREFIX}?{TRISINGLEQUOTE} { // tripple single quotes + {STRINGPREFIX}?{TRISINGLEQUOTE} { // triple single quotes codify(yytext); } "\"" { // end of the string @@ -1382,21 +1381,43 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT } */ -<*>{STRINGPREFIX}?{TRISINGLEQUOTE} | +<*>{STRINGPREFIX}?{TRISINGLEQUOTE} { + if (YY_START==SingleQuoteString) REJECT; + startFontClass("stringliteral"); + g_stringContext=YY_START; + g_doubleQuote=yytext[yyleng-1]=='"'; + codify(yytext); + BEGIN(TripleString); + } <*>{STRINGPREFIX}?{TRIDOUBLEQUOTE} { - startFontClass("stringliteral"); + if (YY_START==DoubleQuoteString) REJECT; + startFontClass("stringliteral"); g_stringContext=YY_START; g_doubleQuote=yytext[yyleng-1]=='"'; - codify(yytext); + codify(yytext); BEGIN(TripleString); } <*>{STRINGPREFIX}?"'" { // single quoted string + if (YY_START==SingleQuoteString || + YY_START==DoubleQuoteString || + YY_START==TripleString + ) + { + REJECT; + } startFontClass("stringliteral"); g_stringContext=YY_START; codify(yytext); BEGIN(SingleQuoteString); } <*>{STRINGPREFIX}?"\"" { // double quoted string + if (YY_START==SingleQuoteString || + YY_START==DoubleQuoteString || + YY_START==TripleString + ) + { + REJECT; + } startFontClass("stringliteral"); g_stringContext=YY_START; codify(yytext); @@ -1495,6 +1516,8 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT void resetPythonCodeParserState() { + g_codeClassSDict.setAutoDelete(TRUE); + g_codeClassSDict.clear(); g_currentDefinition = 0; g_currentMemberDef = 0; g_doubleStringIsDoc = FALSE; @@ -1545,6 +1568,7 @@ void parsePythonCode(CodeOutputInterface &od,const char * /*className*/, //-------------------------------------- if (s.isEmpty()) return; printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); + g_codeClassSDict.setAutoDelete(TRUE); TooltipManager::instance()->clearTooltips(); g_code = &od; g_inputString = s; diff --git a/src/pyscanner.l b/src/pyscanner.l index 9c21d41..1596b9d 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -109,7 +109,7 @@ static QCString g_packageName; //static bool g_hideClassDocs; -static QCString g_defVal; +static QGString g_defVal; static int g_braceCount; static bool g_lexInit = FALSE; @@ -118,6 +118,8 @@ static bool g_packageCommentAllowed; static bool g_start_init = FALSE; static int g_search_count = 0; +static QCString g_argType = ""; +static bool g_funcParamsEnd; //----------------------------------------------------------------------------- @@ -487,7 +489,6 @@ SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ}) SHORTSTRINGCHAR [^\\\n"] STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING}) STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR") -KEYWORD ("lambda"|"import"|"class"|"assert"|"as"|"from"|"global"|"def"|"True"|"False") FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally") POUNDCOMMENT "#"[^#\n][^\n]* SCRIPTCOMMENT "#!".* @@ -514,6 +515,8 @@ STARTDOCSYMS "##" %x FunctionDec %x FunctionParams %x FunctionBody +%x FunctionAnnotation +%x FunctionTypeAnnotation %x FunctionParamDefVal /* Class states */ @@ -933,7 +936,6 @@ STARTDOCSYMS "##" } <FunctionDec>{ - {IDENTIFIER} { //found function name if (current->type.isEmpty()) @@ -944,47 +946,59 @@ STARTDOCSYMS "##" current->name = current->name.stripWhiteSpace(); newFunction(); } - {B}":" { // function without arguments + {B}":"{B} { // function without arguments g_specialBlock = TRUE; // expecting a docstring bodyEntry = current; - current->bodyLine = yyLineNr; - BEGIN( FunctionBody ); + BEGIN(FunctionBody); } + "->" { + g_defVal.resize(0); + g_braceCount = 0; + BEGIN(FunctionTypeAnnotation); + } {B}"(" { - BEGIN( FunctionParams ); + g_funcParamsEnd = FALSE; + current->bodyLine = yyLineNr; + BEGIN(FunctionParams); } + ")" { // end of parameter list + current->args = argListToString(current->argList); + g_funcParamsEnd = TRUE; + } } <FunctionParams>{ ({BB}|",") { } + [\*]+ { + g_argType = yytext; + } {IDENTIFIER} { // Name of parameter lineCount(); Argument *a = new Argument; current->argList->append(a); current->argList->getLast()->name = QCString(yytext).stripWhiteSpace(); - current->argList->getLast()->type = ""; + current->argList->getLast()->type = g_argType; + g_argType = ""; } "=" { // default value // TODO: this rule is too simple, need to be able to // match things like =")" as well! g_defVal.resize(0); - g_braceCount=0; + g_braceCount = 0; BEGIN(FunctionParamDefVal); } - - ")" { // end of parameter list - current->args = argListToString(current->argList); + ")" { + unput(*yytext); + BEGIN(FunctionDec); } - ":"{B} { - g_specialBlock = TRUE; // expecting a docstring - bodyEntry = current; - current->bodyLine = yyLineNr; - BEGIN( FunctionBody ); - } + g_defVal.resize(0); + g_braceCount = 0; + BEGIN(FunctionAnnotation); + } {POUNDCOMMENT} { // a comment } {PARAMNONEMPTY} { // Default rule inside arguments. @@ -992,36 +1006,150 @@ STARTDOCSYMS "##" } -<FunctionParamDefVal>{ - "(" { // internal opening brace - g_braceCount++; +<FunctionTypeAnnotation>{ + "{" | + "[" | + "(" { + ++g_braceCount; + g_defVal+=*yytext; + } + "}" | + "]" | + ")" { + --g_braceCount; g_defVal+=*yytext; } - "," | - ")" { - if (g_braceCount==0) // end of default argument + ":" { + if (g_braceCount == 0) + { + current->type = g_defVal.data(); + unput(*yytext); + BEGIN(FunctionDec); + } + else + g_defVal+=*yytext; + } + "'" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionTypeAnnotation; + BEGIN(SingleQuoteString); + } + "\"" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionTypeAnnotation; + BEGIN(DoubleQuoteString); + } + \n { + g_defVal+=*yytext; + incLineNr(); + } + . { + g_defVal+=*yytext; + } +} + +<FunctionAnnotation>{ + "{" | + "[" | + "(" { + ++g_braceCount; + g_defVal+=*yytext; + } + "}" | + "]" { + --g_braceCount; + g_defVal+=*yytext; + } + ")" | + "=" | + "," { + if (g_braceCount == 0) { if (current->argList->getLast()) - { - current->argList->getLast()->defval=g_defVal.stripWhiteSpace(); - } - if (*yytext == ')') - current->args = argListToString(current->argList); + current->argList->getLast()->type += g_defVal.data(); + if (*yytext != ',') + unput(*yytext); BEGIN(FunctionParams); } - else // continue + else { - if (*yytext == ')')g_braceCount--; - g_defVal+=*yytext; - } + if (*yytext == ')') + --g_braceCount; + g_defVal += *yytext; + } + } + "'" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionAnnotation; + BEGIN(SingleQuoteString); + } + "\"" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionAnnotation; + BEGIN(DoubleQuoteString); + } + \n { + g_defVal+=*yytext; + incLineNr(); } . { - g_defVal+=*yytext; + g_defVal+=*yytext; } +} + +<FunctionParamDefVal>{ + "{" | + "[" | + "(" { // internal opening brace, assumption is that we have correct code so braces do match + ++g_braceCount; + g_defVal+=*yytext; + } + "}" | + "]" { + --g_braceCount; + g_defVal+=*yytext; + } + ")" | + "," { + if (g_braceCount == 0) + { + if (current->argList->getLast()) + current->argList->getLast()->defval=QCString(g_defVal.data()).stripWhiteSpace(); + if (*yytext == ')') + unput(*yytext); + BEGIN(FunctionParams); + } + else + { + if (*yytext == ')') + --g_braceCount; + g_defVal += *yytext; + } + } + + "'" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionParamDefVal; + BEGIN( SingleQuoteString ); + } + "\"" { + g_defVal+=*yytext; + g_copyString=&g_defVal; + g_stringContext=FunctionParamDefVal; + BEGIN( DoubleQuoteString ); + } \n { g_defVal+=*yytext; incLineNr(); } + . { + g_defVal+=*yytext; + } } @@ -1168,13 +1296,17 @@ STARTDOCSYMS "##" current->program+=yytext; BEGIN(TripleComment); } - {TRISINGLEQUOTE} { // start of a comment block initTriSingleQuoteBlock(); current->program+=yytext; BEGIN(TripleComment); } - + {STARTDOCSYMS}[#]* { // start of a special comment + initSpecialBlock(); + BEGIN(SpecialComment); + } + {POUNDCOMMENT} { // ignore comment with just one # + } ^{BB} { current->program+=yytext; //current->startLine = yyLineNr; @@ -1187,7 +1319,6 @@ STARTDOCSYMS "##" } ""/({NONEMPTY}|{EXPCHAR}) { - // Just pushback an empty class, and // resume parsing the body. newEntry(); @@ -1380,7 +1511,6 @@ STARTDOCSYMS "##" BEGIN(Search); } <<EOF>> { yyterminate(); - newEntry(); } } @@ -1409,7 +1539,7 @@ STARTDOCSYMS "##" actualDoc.prepend("\\verbatim "); actualDoc.append("\\endverbatim "); } - actualDoc.prepend("\\namespace "+g_moduleScope+"\\_linebr "); + actualDoc.prepend("\\namespace "+g_moduleScope+" "); handleCommentBlock(actualDoc, FALSE); } if ((docBlockContext==ClassBody /*&& !g_hideClassDocs*/) || @@ -1492,7 +1622,7 @@ STARTDOCSYMS "##" \\. { // espaced char addToString(yytext); } - "\"\"\"" { // tripple double quotes + "\"\"\"" { // triple double quotes addToString(yytext); } "'" { // end of the string @@ -1515,7 +1645,7 @@ STARTDOCSYMS "##" \\. { // espaced char addToString(yytext); } - "'''" { // tripple single quotes + "'''" { // triple single quotes addToString(yytext); } "\"" { // end of the string diff --git a/src/qhp.cpp b/src/qhp.cpp index e7c8d10..6ce6b06 100644 --- a/src/qhp.cpp +++ b/src/qhp.cpp @@ -23,7 +23,7 @@ #include "doxygen.h" #include "filedef.h" -#include <qstringlist.h> +#include <qcstringlist.h> #include <string.h> #include <qfile.h> @@ -101,10 +101,10 @@ void Qhp::initialize() { "name", filterName, 0 }; m_doc.open("customFilter", tagAttributes); - QStringList customFilterAttributes = QStringList::split(QChar(' '), Config_getString(QHP_CUST_FILTER_ATTRS)); + QCStringList customFilterAttributes = QCStringList::split(' ', Config_getString(QHP_CUST_FILTER_ATTRS)); for (int i = 0; i < (int)customFilterAttributes.count(); i++) { - m_doc.openCloseContent("filterAttribute", customFilterAttributes[i].utf8()); + m_doc.openCloseContent("filterAttribute", customFilterAttributes[i]); } m_doc.close("customFilter"); } @@ -112,15 +112,15 @@ void Qhp::initialize() m_doc.open("filterSection"); // Add section attributes - QStringList sectionFilterAttributes = QStringList::split(QChar(' '), + QCStringList sectionFilterAttributes = QCStringList::split(' ', Config_getString(QHP_SECT_FILTER_ATTRS)); - if (!sectionFilterAttributes.contains(QString("doxygen"))) + if (!sectionFilterAttributes.contains("doxygen")) { sectionFilterAttributes << "doxygen"; } for (int i = 0; i < (int)sectionFilterAttributes.count(); i++) { - m_doc.openCloseContent("filterAttribute", sectionFilterAttributes[i].utf8()); + m_doc.openCloseContent("filterAttribute", sectionFilterAttributes[i]); } m_toc.open("toc"); diff --git a/src/reflist.cpp b/src/reflist.cpp index 5a80b19..6f2a763 100644 --- a/src/reflist.cpp +++ b/src/reflist.cpp @@ -131,7 +131,15 @@ void RefList::insertIntoList(const char *key,RefItem *item) { if (ri!=item) { - ri->extraItems.append(item); + // We also have to check if the item is not already in the "extra" list + QListIterator<RefItem> li(ri->extraItems); + RefItem *extraItem; + bool doubleItem = false; + for (li.toFirst();(extraItem=li.current());++li) + { + if (item == extraItem) doubleItem = true; + } + if (!doubleItem) ri->extraItems.append(item); } } } @@ -148,8 +156,6 @@ void RefList::generatePage() for (it.toFirst();(item=it.current());++it) { doc += " <dt>"; - doc += "\\anchor "; - doc += item->listAnchor; doc += "\n"; if (item->scope) { @@ -163,21 +169,38 @@ void RefList::generatePage() doc += item->prefix; doc += " \\_internalref "; doc += item->name; - doc += " \""; - doc += item->title; - doc += "\" "; + // escape \'s in title, see issue #5901 + QCString escapedTitle = substitute(item->title,"\\","\\\\"); + if (item->scope && + (item->scope->definitionType()==Definition::TypeClass || + item->scope->definitionType()==Definition::TypeNamespace || + item->scope->definitionType()==Definition::TypeMember || + item->scope->definitionType()==Definition::TypePackage) + ) + { + // prevent Obj-C names in e.g. todo list are seen as emoji + escapedTitle = substitute(escapedTitle,":","∷"); + } + doc += " \""+escapedTitle+"\" "; // write declaration in case a function with arguments if (!item->args.isEmpty()) { - doc += item->args; + // escape @'s in argument list, needed for Java annotations (see issue #6208) + // escape \'s in argument list (see issue #6533) + doc += substitute(substitute(item->args,"@","@@"),"\\","\\\\"); } - doc += "</dt><dd> "; + doc += "</dt><dd> \\anchor "; + doc += item->listAnchor; + doc += " "; doc += item->text; QListIterator<RefItem> li(item->extraItems); RefItem *extraItem; for (li.toFirst();(extraItem=li.current());++li) { - doc += "<p>" + extraItem->text; + doc += "<p> \\anchor "; + doc += extraItem->listAnchor; + doc += " "; + doc += extraItem->text; } doc += "</dd>"; } diff --git a/src/res2cc_cmd.py b/src/res2cc_cmd.py index 7e0322d..86d999d 100755 --- a/src/res2cc_cmd.py +++ b/src/res2cc_cmd.py @@ -98,10 +98,11 @@ def main(): directory = sys.argv[1] files = [] for dirName, subdirList, fileList in walk(directory): - for fname in sorted(fileList): + for fname in fileList: subdir = dirName[len(directory)+1:] if dirName.startswith(directory) else dirName if subdir: files.append(File.factory(directory,subdir,fname)) + files.sort(key=lambda f: f.subdir + "/" + f.fileName) outputFile = open(sys.argv[2],"w") print("#include \"resourcemgr.h\"\n",file=outputFile) for f in files: diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index c85b638..f2edf8b 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -34,6 +34,7 @@ #include "filedef.h" #include "config.h" #include "htmlentity.h" +#include "emoji.h" #include "plantuml.h" //#define DBG_RTF(x) m_t << x @@ -136,6 +137,48 @@ void RTFDocVisitor::visit(DocSymbol *s) m_lastIsPara=FALSE; } +void RTFDocVisitor::visit(DocEmoji *s) +{ + if (m_hide) return; + DBG_RTF("{\\comment RTFDocVisitor::visit(DocEmoji)}\n"); + const char *res = EmojiEntityMapper::instance()->unicode(s->index()); + if (res) + { + const char *p = res; + int val = 0; + int val1 = 0; + while (*p) + { + switch(*p) + { + case '&': case '#': case 'x': + break; + case ';': + val1 = val; + val = 0xd800 + ( ( val1 - 0x10000 ) & 0xffc00 ) / 0x400 - 0x10000; + m_t << "\\u" << val << "?"; + val = 0xdC00 + ( ( val1 - 0x10000 ) & 0x3ff ) - 0x10000 ; + m_t << "\\u" << val << "?"; + val = 0; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + val = val * 16 + *p - '0'; + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + val = val * 16 + *p - 'a' + 10; + break; + } + p++; + } + } + else + { + m_t << s->name(); + } + m_lastIsPara=FALSE; +} + void RTFDocVisitor::visit(DocURL *u) { if (m_hide) return; @@ -192,6 +235,12 @@ void RTFDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Bold: if (s->enable()) m_t << "{\\b "; else m_t << "} "; break; + case DocStyleChange::Strike: + if (s->enable()) m_t << "{\\strike "; else m_t << "} "; + break; + case DocStyleChange::Underline: + if (s->enable()) m_t << "{\\ul "; else m_t << "} "; + break; case DocStyleChange::Italic: if (s->enable()) m_t << "{\\i "; else m_t << "} "; break; @@ -526,9 +575,21 @@ void RTFDocVisitor::visit(DocIncOperator *op) void RTFDocVisitor::visit(DocFormula *f) { if (m_hide) return; - // TODO: do something sensible here, like including a bitmap DBG_RTF("{\\comment RTFDocVisitor::visit(DocFormula)}\n"); - m_t << f->text(); + bool bDisplay = !f->isInline(); + if (bDisplay) + { + m_t << "\\par"; + m_t << "{"; + m_t << "\\pard\\plain"; + m_t << "\\pard"; + m_t << "\\qc"; + } + m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << f->relPath() << f->name() << ".png\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}"; + if (bDisplay) + { + m_t << "\\par}"; + } m_lastIsPara=FALSE; } @@ -586,9 +647,10 @@ void RTFDocVisitor::visitPost(DocAutoList *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoList)}\n"); - m_t << "\\par"; + if (!m_lastIsPara) m_t << "\\par"; m_t << "}" << endl; m_lastIsPara=TRUE; + if (!m_indentLevel) m_t << "\\par"; } void RTFDocVisitor::visitPre(DocAutoListItem *) @@ -1054,7 +1116,7 @@ void RTFDocVisitor::visitPre(DocHtmlHeader *header) m_t << "{" // start section << rtf_Style_Reset; QCString heading; - int level = QMIN(header->level()+2,4); + int level = QMIN(header->level(),5); heading.sprintf("Heading%d",level); // set style m_t << rtf_Style[heading]->reference; @@ -1067,7 +1129,7 @@ void RTFDocVisitor::visitPost(DocHtmlHeader *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n"); - // close open table of contens entry + // close open table of contents entry m_t << "} \\par"; m_t << "}" << endl; // end section m_lastIsPara=TRUE; @@ -1076,27 +1138,37 @@ void RTFDocVisitor::visitPost(DocHtmlHeader *) void RTFDocVisitor::visitPre(DocImage *img) { DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocImage)}\n"); - includePicturePreRTF(img->name(), img->type()==DocImage::Rtf, img->hasCaption()); + includePicturePreRTF(img->name(), img->type()==DocImage::Rtf, img->hasCaption(), img->isInlineImage()); } - -void RTFDocVisitor::includePicturePreRTF(const QCString name, const bool isTypeRTF, const bool hasCaption) +void RTFDocVisitor::includePicturePreRTF(const QCString name, bool isTypeRTF, bool hasCaption, bool inlineImage) { if (isTypeRTF) { - m_t << "\\par" << endl; - m_t << "{" << endl; - m_t << rtf_Style_Reset << endl; - if (hasCaption || m_lastIsPara) m_t << "\\par" << endl; - m_t << "\\pard \\qc { \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \""; + if (!inlineImage) + { + m_t << "\\par" << endl; + m_t << "{" << endl; + m_t << rtf_Style_Reset << endl; + if (hasCaption || m_lastIsPara) m_t << "\\par" << endl; + m_t << "\\pard \\qc "; + } + m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \""; m_t << name; m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}" << endl; - m_t << "\\par" << endl; - if (hasCaption) + if (!inlineImage) + { + m_t << "\\par" << endl; + if (hasCaption) + { + m_t << "\\pard \\qc \\b"; + m_t << "{Image \\field\\flddirty{\\*\\fldinst { SEQ Image \\\\*Arabic }}{\\fldrslt {\\noproof 1}} "; + } + m_lastIsPara=TRUE; + } + else { - m_t << "\\pard \\qc \\b"; - m_t << "{Image \\field\\flddirty{\\*\\fldinst { SEQ Image \\\\*Arabic }}{\\fldrslt {\\noproof 1}} "; + if (hasCaption) m_t << "{\\comment "; // to prevent caption to be shown } - m_lastIsPara=TRUE; } else // other format -> skip { @@ -1108,22 +1180,29 @@ void RTFDocVisitor::includePicturePreRTF(const QCString name, const bool isTypeR void RTFDocVisitor::visitPost(DocImage *img) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocImage)}\n"); - includePicturePostRTF(img->type()==DocImage::Rtf, img->hasCaption()); + includePicturePostRTF(img->type()==DocImage::Rtf, img->hasCaption(), img->isInlineImage()); } -void RTFDocVisitor::includePicturePostRTF(const bool isTypeRTF, const bool hasCaption) +void RTFDocVisitor::includePicturePostRTF(bool isTypeRTF, bool hasCaption, bool inlineImage) { if (isTypeRTF) { if (m_hide) return; - if (hasCaption) + if (inlineImage) { - m_t << "}" <<endl; - m_t << "\\par}" <<endl; + if (hasCaption) m_t << " }"; } else { - m_t << "}" <<endl; + if (hasCaption) + { + m_t << "}" <<endl; + m_t << "\\par}" <<endl; + } + else + { + m_t << "}" <<endl; + } } } else @@ -1276,10 +1355,7 @@ void RTFDocVisitor::visitPre(DocParamSect *s) case DocParamSect::Exception: m_t << theTranslator->trExceptions(); break; case DocParamSect::TemplateParam: - /* TODO: add this - m_t << theTranslator->trTemplateParam(); break; - */ - m_t << "Template Parameters"; break; + m_t << theTranslator->trTemplateParameters(); break; default: ASSERT(0); } @@ -1739,7 +1815,7 @@ void RTFDocVisitor::writeDotFile(DocDotFile *df) { writeDotFile(df->file(), df->hasCaption()); } -void RTFDocVisitor::writeDotFile(const QCString &filename, const bool hasCaption) +void RTFDocVisitor::writeDotFile(const QCString &filename, bool hasCaption) { QCString baseName=filename; int i; @@ -1757,7 +1833,7 @@ void RTFDocVisitor::writeMscFile(DocMscFile *df) { writeMscFile(df->file(), df->hasCaption()); } -void RTFDocVisitor::writeMscFile(const QCString &fileName, const bool hasCaption) +void RTFDocVisitor::writeMscFile(const QCString &fileName, bool hasCaption) { QCString baseName=fileName; int i; @@ -1783,7 +1859,7 @@ void RTFDocVisitor::writeDiaFile(DocDiaFile *df) includePicturePreRTF(baseName + ".png", true, df->hasCaption()); } -void RTFDocVisitor::writePlantUMLFile(const QCString &fileName, const bool hasCaption) +void RTFDocVisitor::writePlantUMLFile(const QCString &fileName, bool hasCaption) { QCString baseName=fileName; int i; diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h index 1e927e7..b7cc3ea 100644 --- a/src/rtfdocvisitor.h +++ b/src/rtfdocvisitor.h @@ -40,6 +40,7 @@ class RTFDocVisitor : public DocVisitor void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); @@ -152,14 +153,14 @@ class RTFDocVisitor : public DocVisitor void pushEnabled(); void popEnabled(); - void includePicturePreRTF(const QCString name, const bool isTypeRTF, const bool hasCaption); - void includePicturePostRTF(const bool isTypeRTF, const bool hasCaption); - void writeDotFile(const QCString &fileName, const bool hasCaption); + 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); void writeDotFile(DocDotFile *); - void writeMscFile(const QCString &fileName, const bool hasCaption); + void writeMscFile(const QCString &fileName, bool hasCaption); void writeMscFile(DocMscFile *); void writeDiaFile(DocDiaFile *); - void writePlantUMLFile(const QCString &fileName, const bool hasCaption); + void writePlantUMLFile(const QCString &fileName, bool hasCaption); //-------------------------------------- // state variables diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 7fcfbb3..2e67c26 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -244,7 +244,22 @@ void RTFGenerator::beginRTFDocument() t <<"\\red128\\green0\\blue0;"; t <<"\\red128\\green128\\blue0;"; t <<"\\red128\\green128\\blue128;"; - t <<"\\red192\\green192\\blue192;}" << endl; + t <<"\\red192\\green192\\blue192;"; + + // code highlighting colors. Note order is important see also RTFGenerator::startFontClass + t <<"\\red0\\green128\\blue0;"; // keyword = index 17 + t <<"\\red96\\green64\\blue32;"; // keywordtype + t <<"\\rede0\\green128\\blue0;"; // keywordflow + t <<"\\red128\\green0\\blue0;"; // comment + t <<"\\red128\\green96\\blue32;"; // preprocessor + t <<"\\red0\\green32\\blue128;"; // stringliteral + t <<"\\red0\\green128\\blue128;"; // charliteral + t <<"\\red255\\green0\\blue255;"; // vhdldigit + t <<"\\red0\\green0\\blue0;"; // vhdlchar + t <<"\\red112\\green0\\blue112;"; // vhdlkeyword + t <<"\\red255\\green0\\blue0;"; // vhdllogic + + t <<"}\n"; DBG_RTF(t <<"{\\comment Beginning style list}\n") t <<"{\\stylesheet\n"; @@ -272,21 +287,22 @@ void RTFGenerator::beginRTFDocument() t << "\\margl1800\\margr1800\\margt1440\\margb1440\\gutter0\\ltrsect}\n"; // sort styles ascending by \s-number via an intermediate QArray - QArray<const StyleData*> array(128); - array.fill(0); QDictIterator<StyleData> iter(rtf_Style); const StyleData* style; + unsigned maxIndex = 0; + for(; (style = iter.current()); ++iter) + { + unsigned index = style->index; + if (maxIndex < index) maxIndex = index; + } + QArray<const StyleData*> array(maxIndex + 1); + array.fill(0); + ASSERT(maxIndex < array.size()); + + iter.toFirst(); for(; (style = iter.current()); ++iter) { unsigned index = style->index; - unsigned size = array.size(); - if (index >= size) - { - // +1 to add at least one element, then align up to multiple of 8 - array.resize((index + 1 + 7) & ~7); - array.fill(0, size); - ASSERT(index < array.size()); - } if (array.at(index) != 0) { QCString key(iter.currentKey()); @@ -575,7 +591,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isTitlePageAuthor: { - t << "Doxgyen. }\n"; + t << " doxygen.}\n"; t << "{\\creatim " << dateToRTFDateString() << "}\n}"; DBG_RTF(t << "{\\comment end of infoblock}\n"); // setup for this section @@ -602,7 +618,7 @@ void RTFGenerator::endIndexSection(IndexSections is) t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style if (rtf_title) // User has overridden document title in extensions file - t << "{\\field\\fldedit {\\*\\fldinst " << rtf_title << " \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par" << endl; + t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par" << endl; else { DocText *root = validatingParseText(projectName); @@ -703,7 +719,7 @@ void RTFGenerator::endIndexSection(IndexSections is) } else if (vhdlOpt) { - t << "{\\tc \\v " << VhdlDocGen::trDesignUnitIndex() << "}"<< endl; + t << "{\\tc \\v " << theTranslator->trDesignUnitIndex() << "}"<< endl; } else { @@ -1626,7 +1642,7 @@ void RTFGenerator::endDescItem() newParagraph(); } -void RTFGenerator::startMemberDescription(const char *,const char *) +void RTFGenerator::startMemberDescription(const char *,const char *,bool) { DBG_RTF(t << "{\\comment (startMemberDescription)}" << endl) t << "{" << endl; @@ -1639,11 +1655,11 @@ void RTFGenerator::endMemberDescription() { DBG_RTF(t << "{\\comment (endMemberDescription)}" << endl) endEmphasis(); - newParagraph(); + //newParagraph(); decrementIndentLevel(); - //t << "\\par"; + t << "\\par"; t << "}" << endl; - //m_omitParagraph = TRUE; + m_omitParagraph = TRUE; } void RTFGenerator::startDescList(SectionTypes) @@ -2165,11 +2181,12 @@ void RTFGenerator::newParagraph() m_omitParagraph = FALSE; } -void RTFGenerator::startParagraph(const char *) +void RTFGenerator::startParagraph(const char *txt) { DBG_RTF(t << "{\\comment startParagraph}" << endl) newParagraph(); t << "{" << endl; + if (QCString(txt) == "reference") t << "\\ql" << endl; } void RTFGenerator::endParagraph() @@ -2617,7 +2634,7 @@ void testRTFOutput(const char *name) err: err("RTF integrity test failed at line %d of %s due to a bracket mismatch.\n" " Please try to create a small code example that produces this error \n" - " and send that to dimitri@stack.nl.\n",line,name); + " and send that to doxygen@gmail.com.\n",line,name); } /** @@ -2712,21 +2729,14 @@ void RTFGenerator::endMemberGroup(bool hasHeader) t << "}"; } -void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anchor,const char *title) +void RTFGenerator::startExamples() { - DBG_RTF(t << "{\\comment (startSimpleSect)}" << endl) + DBG_RTF(t << "{\\comment (startExamples)}" << endl) t << "{"; // ends at endDescList t << "{"; // ends at endDescTitle startBold(); newParagraph(); - if (file) - { - writeObjectLink(0,file,anchor,title); - } - else - { - docify(title); - } + docify(theTranslator->trExamples()); endBold(); t << "}"; newParagraph(); @@ -2734,9 +2744,9 @@ void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anc t << rtf_Style_Reset << rtf_DList_DepthStyle(); } -void RTFGenerator::endSimpleSect() +void RTFGenerator::endExamples() { - DBG_RTF(t << "{\\comment (endSimpleSect)}" << endl) + DBG_RTF(t << "{\\comment (endExamples)}" << endl) m_omitParagraph = FALSE; newParagraph(); decrementIndentLevel(); @@ -2787,7 +2797,7 @@ void RTFGenerator::exceptionEntry(const char* prefix,bool closeBracket) { DBG_RTF(t << "{\\comment (exceptionEntry)}" << endl) if (prefix) - t << " " << prefix; + t << " " << prefix << "("; else if (closeBracket) t << ")"; t << " "; @@ -3041,5 +3051,25 @@ void RTFGenerator::endLabels() { } +void RTFGenerator::startFontClass(const char *name) +{ + int cod = 2; + QCString qname(name); + if (qname == "keyword") cod = 17; + else if (qname == "keywordtype") cod = 18; + else if (qname == "keywordflow") cod = 19; + else if (qname == "comment") cod = 20; + else if (qname == "preprocessor") cod = 21; + else if (qname == "stringliteral") cod = 22; + else if (qname == "charliteral") cod = 23; + else if (qname == "vhdldigit") cod = 24; + else if (qname == "vhdlchar") cod = 25; + else if (qname == "vhdlkeyword") cod = 26; + else if (qname == "vhdllogic") cod = 27; + t << "{\\cf" << cod << " "; +} - +void RTFGenerator::endFontClass() +{ + t << "}"; +} diff --git a/src/rtfgen.h b/src/rtfgen.h index d8f6ca7..b6b32c7 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -103,7 +103,7 @@ class RTFGenerator : public OutputGenerator void endMemberSections() {} void startHeaderSection() {} void endHeaderSection() {} - void startMemberHeader(const char *) { startGroupHeader(FALSE); } + void startMemberHeader(const char *,int) { startGroupHeader(FALSE); } void endMemberHeader() { endGroupHeader(FALSE); } void startMemberSubtitle(); void endMemberSubtitle(); @@ -120,6 +120,7 @@ class RTFGenerator : public OutputGenerator void startMemberTemplateParams() {} void endMemberTemplateParams(const char *,const char *) {} void insertMemberAlign(bool) {} + void insertMemberAlignLeft(int,bool){} void writeRuler() { rtfwriteRuler_thin(); } @@ -156,15 +157,15 @@ class RTFGenerator : public OutputGenerator void startSmall() { t << "{\\sub "; } void endSmall() { t << "}"; } - void startMemberDescription(const char *,const char *); + void startMemberDescription(const char *,const char *,bool); void endMemberDescription(); void startMemberDeclaration() {} void endMemberDeclaration(const char *,const char *) {} void writeInheritedSectionTitle(const char *,const char *,const char *, const char *,const char *,const char *) {} void startDescList(SectionTypes); - void startSimpleSect(SectionTypes,const char *,const char *,const char *); - void endSimpleSect(); + void startExamples(); + void endExamples(); void startParamList(ParamListTypes,const char *); void endParamList(); //void writeDescItem(); @@ -257,8 +258,8 @@ class RTFGenerator : public OutputGenerator void writeLabel(const char *l,bool isLast); void endLabels(); - void startFontClass(const char *) {} - void endFontClass() {} + void startFontClass(const char *); + void endFontClass(); void writeCodeAnchor(const char *) {} void setCurrentDoc(Definition *,const char *,bool) {} diff --git a/src/rtfstyle.cpp b/src/rtfstyle.cpp index 1ea8868..47a8166 100644 --- a/src/rtfstyle.cpp +++ b/src/rtfstyle.cpp @@ -40,6 +40,43 @@ QCString rtf_keywords; char rtf_Style_Reset[] = "\\pard\\plain "; +#define RTF_LatexToc(lvl,nest,nxt,pos,twps) \ + \ + { "LatexTOC"#lvl, \ + "\\s"#nest"\\li"#pos"\\sa"#twps"\\sb"#twps"\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",\ + "\\sbasedon0 \\snext"#nxt" LatexTOC "#lvl \ + } + +#define RTF_ListBullet(lvl,nest,nxt,pos,lvl2) \ + { "ListBullet"#lvl, \ + "\\s"#nest"\\fi-360\\li"#pos"\\widctlpar\\jclisttab\\tx"#pos"{\\*\\pn \\pnlvlbody\\ilvl0\\ls"#lvl2"\\pnrnot0\\pndec }\\ls1\\adjustright \\fs20\\cgrid ", \ + "\\sbasedon0 \\snext"#nxt" \\sautoupd List Bullet "#lvl \ + } + +#define RTF_ListEnum(lvl,nest,nxt,pos) \ + { "ListEnum"#lvl, \ + "\\s"#nest"\\fi-360\\li"#pos"\\widctlpar\\fs20\\cgrid ", \ + "\\sbasedon0 \\snext"#nxt" \\sautoupd List Enum "#lvl \ + } + +#define RTF_CodeExample(lvl,nest,nxt,pos) \ + { "CodeExample"#lvl, \ + "\\s"#nest"\\li"#pos"\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", \ + "\\sbasedon0 \\snext"#nxt" Code Example "#lvl \ + } + +#define RTF_ListContinue(lvl,nest,nxt,pos) \ + { "ListContinue"#lvl, \ + "\\s"#nest"\\li"#pos"\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", \ + "\\sbasedon0 \\snext"#nxt" List Continue "#lvl \ + } + +#define RTF_DescContinue(lvl,nest,nxt,pos) \ + { "DescContinue"#lvl, \ + "\\s"#nest"\\li"#pos"\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", \ + "\\sbasedon0 \\snext"#nxt" DescContinue "#lvl \ + } + Rtf_Style_Default rtf_Style_Default[] = { { "Heading1", @@ -90,246 +127,97 @@ Rtf_Style_Default rtf_Style_Default[] = "\\s30\\li360\\sa60\\sb120\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ", "\\sbasedon0 \\snext30 GroupHeader" }, - { "CodeExample0", - "\\s40\\li0\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext41 Code Example 0" - }, - { "CodeExample1", - "\\s41\\li360\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext42 Code Example 1" - }, - { "CodeExample2", - "\\s42\\li720\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext43 Code Example 2" - }, - { "CodeExample3", - "\\s43\\li1080\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext44 Code Example 3" - }, - { "CodeExample4", - "\\s44\\li1440\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext45 Code Example 4" - }, - { "CodeExample5", - "\\s45\\li1800\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext46 Code Example 5" - }, - { "CodeExample6", - "\\s46\\li2160\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext47 Code Example 6" - }, - { "CodeExample7", - "\\s47\\li2520\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext48 Code Example 7" - }, - { "CodeExample8", - "\\s48\\li2880\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext49 Code Example 8" - }, - { "CodeExample9", - "\\s49\\li3240\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", - "\\sbasedon0 \\snext49 Code Example 9" - }, - { "ListContinue0", - "\\s50\\li0\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext51 List Continue 0" - }, - { "ListContinue1", - "\\s51\\li360\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext52 List Continue 1" - }, - { "ListContinue2", - "\\s52\\li720\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext53 List Continue 2" - }, - { "ListContinue3", - "\\s53\\li1080\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext54 List Continue 3" - }, - { "ListContinue4", - "\\s54\\li1440\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext55 List Continue 4" - }, - { "ListContinue5", - "\\s55\\li1800\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext56 List Continue 5" - }, - { "ListContinue6", - "\\s56\\li2160\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext57 List Continue 6" - }, - { "ListContinue7", - "\\s57\\li2520\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext58 List Continue 7" - }, - { "ListContinue8", - "\\s58\\li2880\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext59 List Continue 8" - }, - { "ListContinue9", - "\\s59\\li3240\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext59 List Continue 9" - }, - { "DescContinue0", - "\\s60\\li0\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext61 DescContinue 0" - }, - { "DescContinue1", - "\\s61\\li360\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext62 DescContinue 1" - }, - { "DescContinue2", - "\\s62\\li720\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext63 DescContinue 2" - }, - { "DescContinue3", - "\\s63\\li1080\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext64 DescContinue 3" - }, - { "DescContinue4", - "\\s64\\li1440\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext65 DescContinue 4" - }, - { "DescContinue5", - "\\s65\\li1800\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext66 DescContinue 5" - }, - { "DescContinue6", - "\\s66\\li2160\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext67 DescContinue 6" - }, - { "DescContinue7", - "\\s67\\li2520\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext68 DescContinue 7" - }, - { "DescContinue8", - "\\s68\\li2880\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext69 DescContinue 8" - }, - { "DescContinue9", - "\\s69\\li3240\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext69 DescContinue 9" - }, - { "LatexTOC0", - "\\s70\\li0\\sa30\\sb30\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext81 LatexTOC 0" - }, - { "LatexTOC1", - "\\s71\\li360\\sa27\\sb27\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext82 LatexTOC 1" - }, - { "LatexTOC2", - "\\s72\\li720\\sa24\\sb24\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext83 LatexTOC 2" - }, - { "LatexTOC3", - "\\s73\\li1080\\sa21\\sb21\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext84 LatexTOC 3" - }, - { "LatexTOC4", - "\\s74\\li1440\\sa18\\sb18\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext85 LatexTOC 4" - }, - { "LatexTOC5", - "\\s75\\li1800\\sa15\\sb15\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext86 LatexTOC 5" - }, - { "LatexTOC6", - "\\s76\\li2160\\sa12\\sb12\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext87 LatexTOC 6" - }, - { "LatexTOC7", - "\\s77\\li2520\\sa9\\sb9\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext88 LatexTOC 7" - }, - { "LatexTOC8", - "\\s78\\li2880\\sa6\\sb6\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext89 LatexTOC 8" - }, - { "LatexTOC9", - "\\s79\\li3240\\sa3\\sb3\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext89 LatexTOC 9" - }, - { "ListBullet0", - "\\s80\\fi-360\\li360\\widctlpar\\jclisttab\\tx360{\\*\\pn \\pnlvlbody\\ilvl0\\ls1\\pnrnot0\\pndec }\\ls1\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext81 \\sautoupd List Bullet 0" - }, - { "ListBullet1", - "\\s81\\fi-360\\li720\\widctlpar\\jclisttab\\tx720{\\*\\pn \\pnlvlbody\\ilvl0\\ls2\\pnrnot0\\pndec }\\ls2\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext82 \\sautoupd List Bullet 1" - }, - { "ListBullet2", - "\\s82\\fi-360\\li1080\\widctlpar\\jclisttab\\tx1080{\\*\\pn \\pnlvlbody\\ilvl0\\ls3\\pnrnot0\\pndec }\\ls3\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext83 \\sautoupd List Bullet 2" - }, - { "ListBullet3", - "\\s83\\fi-360\\li1440\\widctlpar\\jclisttab\\tx1440{\\*\\pn \\pnlvlbody\\ilvl0\\ls4\\pnrnot0\\pndec }\\ls4\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext84 \\sautoupd List Bullet 3" - }, - { "ListBullet4", - "\\s84\\fi-360\\li1800\\widctlpar\\jclisttab\\tx1800{\\*\\pn \\pnlvlbody\\ilvl0\\ls5\\pnrnot0\\pndec }\\ls5\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext85 \\sautoupd List Bullet 4" - }, - { "ListBullet5", - "\\s85\\fi-360\\li2160\\widctlpar\\jclisttab\\tx2160{\\*\\pn \\pnlvlbody\\ilvl0\\ls6\\pnrnot0\\pndec }\\ls6\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext86 \\sautoupd List Bullet 5" - }, - { "ListBullet6", - "\\s86\\fi-360\\li2520\\widctlpar\\jclisttab\\tx2520{\\*\\pn \\pnlvlbody\\ilvl0\\ls7\\pnrnot0\\pndec }\\ls7\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext87 \\sautoupd List Bullet 6" - }, - { "ListBullet7", - "\\s87\\fi-360\\li2880\\widctlpar\\jclisttab\\tx2880{\\*\\pn \\pnlvlbody\\ilvl0\\ls8\\pnrnot0\\pndec }\\ls8\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext88 \\sautoupd List Bullet 7" - }, - { "ListBullet8", - "\\s88\\fi-360\\li3240\\widctlpar\\jclisttab\\tx3240{\\*\\pn \\pnlvlbody\\ilvl0\\ls9\\pnrnot0\\pndec }\\ls9\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext89 \\sautoupd List Bullet 8" - }, - { "ListBullet9", - "\\s89\\fi-360\\li3600\\widctlpar\\jclisttab\\tx3600{\\*\\pn \\pnlvlbody\\ilvl0\\ls10\\pnrnot0\\pndec }\\ls10\\adjustright \\fs20\\cgrid ", - "\\sbasedon0 \\snext89 \\sautoupd List Bullet 9" - }, - { "ListEnum0", - "\\s90\\fi-360\\li360\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext91 \\sautoupd List Enum 0" - }, - { "ListEnum1", - "\\s91\\fi-360\\li720\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext92 \\sautoupd List Enum 1" - }, - { "ListEnum2", - "\\s92\\fi-360\\li1080\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext93 \\sautoupd List Enum 2" - }, - { "ListEnum3", - "\\s93\\fi-360\\li1440\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext94 \\sautoupd List Enum 3" - }, - { "ListEnum4", - "\\s94\\fi-360\\li1800\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext95 \\sautoupd List Enum 4" - }, - { "ListEnum5", - "\\s95\\fi-360\\li2160\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext96 \\sautoupd List Enum 5" - }, - { "ListEnum6", - "\\s96\\fi-360\\li2520\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext96 \\sautoupd List Enum 5" - }, - { "ListEnum7", - "\\s97\\fi-360\\li2880\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext98 \\sautoupd List Enum 7" - }, - { "ListEnum8", - "\\s98\\fi-360\\li3240\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext99 \\sautoupd List Enum 8" - }, - { "ListEnum9", - "\\s99\\fi-360\\li3600\\widctlpar\\fs20\\cgrid ", - "\\sbasedon0 \\snext99 \\sautoupd List Enum 9" - }, + + RTF_CodeExample( 0, 40, 41, 0), + RTF_CodeExample( 1, 41, 42, 360), + RTF_CodeExample( 2, 42, 43, 720), + RTF_CodeExample( 3, 43, 44,1080), + RTF_CodeExample( 4, 44, 45,1440), + RTF_CodeExample( 5, 45, 46,1800), + RTF_CodeExample( 6, 46, 47,2160), + RTF_CodeExample( 7, 47, 48,2520), + RTF_CodeExample( 8, 48, 49,2880), + RTF_CodeExample( 9, 49, 50,3240), + RTF_CodeExample(10, 50, 51,3600), + RTF_CodeExample(11, 51, 52,3960), + RTF_CodeExample(12, 52, 53,4320), + RTF_CodeExample(13, 53, 53,4680), + + RTF_ListContinue( 0, 60, 61, 0), + RTF_ListContinue( 1, 61, 62, 360), + RTF_ListContinue( 2, 62, 63, 720), + RTF_ListContinue( 3, 63, 64,1080), + RTF_ListContinue( 4, 64, 65,1440), + RTF_ListContinue( 5, 65, 66,1800), + RTF_ListContinue( 6, 66, 67,2160), + RTF_ListContinue( 7, 67, 68,2520), + RTF_ListContinue( 8, 68, 69,2880), + RTF_ListContinue( 9, 69, 70,3240), + RTF_ListContinue(10, 70, 71,3600), + RTF_ListContinue(11, 71, 72,3960), + RTF_ListContinue(12, 72, 73,4320), + RTF_ListContinue(13, 73, 73,4680), + + RTF_DescContinue( 0, 80, 81, 0), + RTF_DescContinue( 1, 81, 82, 360), + RTF_DescContinue( 2, 82, 83, 720), + RTF_DescContinue( 3, 83, 84,1080), + RTF_DescContinue( 4, 84, 85,1440), + RTF_DescContinue( 5, 85, 86,1800), + RTF_DescContinue( 6, 86, 87,2160), + RTF_DescContinue( 7, 87, 88,2520), + RTF_DescContinue( 8, 88, 89,2880), + RTF_DescContinue( 9, 89, 90,3240), + RTF_DescContinue(10, 90, 91,3600), + RTF_DescContinue(11, 91, 92,3960), + RTF_DescContinue(12, 92, 93,4320), + RTF_DescContinue(13, 93, 93,4680), + + RTF_LatexToc( 0,100,101, 0,30), + RTF_LatexToc( 1,101,102, 360,27), + RTF_LatexToc( 2,102,103, 720,24), + RTF_LatexToc( 3,103,104,1080,21), + RTF_LatexToc( 4,104,105,1440,18), + RTF_LatexToc( 5,105,106,1800,15), + RTF_LatexToc( 6,106,107,2160,12), + RTF_LatexToc( 7,107,108,2520, 9), + RTF_LatexToc( 8,108,109,2880, 6), + RTF_LatexToc( 9,109,110,3240, 3), + RTF_LatexToc(10,110,111,3600, 3), + RTF_LatexToc(11,111,112,3960, 3), + RTF_LatexToc(12,112,113,4320, 3), + RTF_LatexToc(13,113,113,4680, 3), + + RTF_ListBullet( 0,120,121, 360, 1), + RTF_ListBullet( 1,121,122, 720, 2), + RTF_ListBullet( 2,122,123,1080, 3), + RTF_ListBullet( 3,123,124,1440, 4), + RTF_ListBullet( 4,124,125,1800, 5), + RTF_ListBullet( 5,125,126,2160, 6), + RTF_ListBullet( 6,126,127,2520, 7), + RTF_ListBullet( 7,127,128,2880, 8), + RTF_ListBullet( 8,128,129,3240, 9), + RTF_ListBullet( 9,129,130,3600,10), + RTF_ListBullet(10,130,131,3960,11), + RTF_ListBullet(11,131,132,4320,12), + RTF_ListBullet(12,132,133,4680,13), + RTF_ListBullet(13,133,133,5040,14), + + RTF_ListEnum( 0,140,141, 360), + RTF_ListEnum( 1,141,142, 720), + RTF_ListEnum( 2,142,143,1080), + RTF_ListEnum( 3,143,144,1440), + RTF_ListEnum( 4,144,145,1800), + RTF_ListEnum( 5,145,146,2160), + RTF_ListEnum( 6,146,147,2520), + RTF_ListEnum( 7,147,148,2880), + RTF_ListEnum( 8,148,149,3240), + RTF_ListEnum( 9,149,150,3600), + RTF_ListEnum(10,150,151,3960), + RTF_ListEnum(11,151,152,4320), + RTF_ListEnum(12,152,153,4680), + RTF_ListEnum(13,153,153,5040), + { 0, 0, 0 diff --git a/src/rtfstyle.h b/src/rtfstyle.h index 60f671f..1058351 100644 --- a/src/rtfstyle.h +++ b/src/rtfstyle.h @@ -42,7 +42,7 @@ struct RTFListItemInfo int number; }; -const int rtf_maxIndentLevels = 10; +const int rtf_maxIndentLevels = 13; extern RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels]; diff --git a/src/scanner.l b/src/scanner.l index 08a5e52..7559e0b 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -31,7 +31,7 @@ #include <qstack.h> #include <qregexp.h> #include <qfile.h> - + #include "scanner.h" #include "entry.h" #include "message.h" @@ -126,8 +126,11 @@ static bool insidePHP = FALSE; //!< processing PHP code? static bool insideObjC = FALSE; //!< processing Objective C code? static bool insideCli = FALSE; //!< processing C++/CLI code? static bool insideJS = FALSE; //!< processing JavaScript code? +static bool insideSlice = FALSE; //!< processing Slice code? static bool insideCpp = TRUE; //!< processing C/C++ code +static bool sliceOpt = FALSE; + static bool insideCppQuote = FALSE; static bool insideProtocolList = FALSE; @@ -149,6 +152,7 @@ static QCString *pCopyRawString; static QGString *pCopyCurlyGString; static QGString *pCopyRoundGString; +static QGString *pCopySquareGString; static QGString *pCopyQuotedGString; static QGString *pCopyHereDocGString; static QGString *pCopyRawGString; @@ -218,6 +222,7 @@ static void initParser() insideFormula = FALSE; insideCode=FALSE; insideCli=Config_getBool(CPP_CLI_SUPPORT); + sliceOpt=Config_getBool(OPTIMIZE_OUTPUT_SLICE); previous = 0; firstTypedefEntry = 0; tempEntry = 0; @@ -375,15 +380,16 @@ static bool nameIsOperator(QCString &name) static void setContext() { QCString fileName = yyFileName; - language = getLanguageFromFileName(fileName); - insideIDL = language==SrcLangExt_IDL; - insideJava = language==SrcLangExt_Java; - insideCS = language==SrcLangExt_CSharp; - insideD = language==SrcLangExt_D; - insidePHP = language==SrcLangExt_PHP; - insideObjC = language==SrcLangExt_ObjC; - insideJS = language==SrcLangExt_JS; - insideCpp = language==SrcLangExt_Cpp; + language = getLanguageFromFileName(fileName); + insideIDL = language==SrcLangExt_IDL; + insideJava = language==SrcLangExt_Java; + insideCS = language==SrcLangExt_CSharp; + insideD = language==SrcLangExt_D; + insidePHP = language==SrcLangExt_PHP; + insideObjC = language==SrcLangExt_ObjC; + insideJS = language==SrcLangExt_JS; + insideSlice = language==SrcLangExt_Slice; + insideCpp = language==SrcLangExt_Cpp; if ( insidePHP ) { useOverrideCommands = TRUE; @@ -596,15 +602,11 @@ static int yyread(char *buf,int max_size) /* start command character */ CMD ("\\"|"@") -SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"callgraph"|"callergraph"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"manonly"|"{"|"verbatim"|"dotfile"|"dot"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"details"|"typedef"|"def"|"overload")|("<"{PRE}">") BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] -BS ^(({B}*"//")?)(({B}*"*"+)?){B}* ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* -SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID}) -PHPSCOPENAME ({ID}"\\")+{ID} TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,:]*">")? CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID}) PRE [pP][rR][eE] @@ -734,6 +736,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) %x CopyRound %x CopyCurly %x GCopyRound +%x GCopySquare %x GCopyCurly %x SkipUnionSwitch %x Specialization @@ -761,6 +764,14 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) %x IDLProp %x IDLPropName + /** Slice states */ + +%x SliceMetadata +%x SliceSequence +%x SliceSequenceName +%x SliceDictionary +%x SliceDictionaryName + /** Prototype scanner states */ %x Prototype @@ -1218,6 +1229,38 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) unput('{'); BEGIN( Function ); } +<FindMembers>{B}*"sequence"{BN}*"<"{BN}* { + if (insideSlice) + { + lineCount(); + current->bodyLine = yyLineNr; + current->fileName = yyFileName ; + current->startLine = yyLineNr ; + current->startColumn = yyColNr; + current->args.resize(0); + current->section = Entry::TYPEDEF_SEC ; + isTypedef = TRUE; + BEGIN( SliceSequence ); + } + else + REJECT; + } +<FindMembers>{B}*"dictionary"{BN}*"<"{BN}* { + if (insideSlice) + { + lineCount(); + current->bodyLine = yyLineNr; + current->fileName = yyFileName ; + current->startLine = yyLineNr ; + current->startColumn = yyColNr; + current->args.resize(0); + current->section = Entry::TYPEDEF_SEC ; + isTypedef = TRUE; + BEGIN( SliceDictionary ); + } + else + REJECT; + } <FindMembers>{BN}{1,80} { lineCount(); } @@ -1390,6 +1433,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <FindMembers>{B}*"explicit"{BN}+ { current->spec|=Entry::Explicit; lineCount(); } +<FindMembers>{B}*"local"{BN}+ { current->spec|=Entry::Local; + lineCount(); + } <FindMembers>{B}*"@required"{BN}+ { // Objective C 2.0 protocol required section current->spec=(current->spec & ~Entry::Optional) | Entry::Required; lineCount(); @@ -1424,7 +1470,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers>{B}*"module"{BN}+ { lineCount(); - if (insideIDL) + if (insideIDL || insideSlice) { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; @@ -1527,15 +1573,15 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name = QCString(yytext).stripWhiteSpace(); } } -<FindMembers>{BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java interface +<FindMembers>{BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java/Slice interface lineCount(); - if (insideIDL || insideJava || insideCS || insideD || insidePHP) + if (insideIDL || insideJava || insideCS || insideD || insidePHP || insideSlice) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; - current->spec = Entry::Interface | - // preserve UNO IDL [optional] or published - (current->spec & (Entry::Optional|Entry::Published)); + current->spec = Entry::Interface | + // preserve UNO IDL [optional], published, Slice local + (current->spec & (Entry::Optional|Entry::Published|Entry::Local)); addType( current ) ; current->type += " interface" ; current->fileName = yyFileName; @@ -1599,11 +1645,13 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->bodyLine = yyLineNr; BEGIN( CompoundName ); } -<FindMembers>{B}*"exception"{BN}+ { // Corba IDL exception +<FindMembers>{B}*"exception"{BN}+ { // Corba IDL/Slice exception isTypedef=FALSE; current->section = Entry::CLASS_SEC; + // preserve UNO IDL, Slice local current->spec = Entry::Exception | - (current->spec & Entry::Published); // preserve UNO IDL + (current->spec & Entry::Published) | + (current->spec & Entry::Local); addType( current ) ; current->type += " exception" ; current->fileName = yyFileName; @@ -1622,6 +1670,16 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) bool isVolatile=decl.find("volatile")!=-1; current->section = Entry::CLASS_SEC; addType( current ) ; + uint64 spec = current->spec; + if (insidePHP && current->spec&Entry::Abstract) + { + // convert Abstract to AbstractClass + current->spec=(current->spec&~Entry::Abstract)|Entry::AbstractClass; + } + if (insideSlice && spec&Entry::Local) + { + current->spec|=Entry::Local; + } if (isConst) { current->type += " const"; @@ -1642,11 +1700,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); - if (insidePHP && current->spec&Entry::Abstract) - { - // convert Abstract to AbstractClass - current->spec=(current->spec&~Entry::Abstract)|Entry::AbstractClass; - } BEGIN( CompoundName ) ; } <FindMembers>{B}*"value class{" | // C++/CLI extension @@ -1722,10 +1775,13 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; + uint64 spec = current->spec; current->section = Entry::CLASS_SEC ; + // preserve UNO IDL & Inline attributes, Slice local current->spec = Entry::Struct | (current->spec & Entry::Published) | - (current->spec & Entry::Inline); // preserve UNO IDL & Inline attributes + (current->spec & Entry::Inline) | + (current->spec & Entry::Local); // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; addType( current ) ; @@ -2382,10 +2438,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->protection = Protected; } - else if (javaLike && qstrcmp(yytext,"internal")==0) - { - current->protection = Package; - } else if (javaLike && qstrcmp(yytext,"private")==0) { current->protection = Private; @@ -2842,6 +2894,14 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->initializer+=*yytext; BEGIN(GCopyRound); } +<ReadInitializer>"[" { + if (!insidePHP) REJECT; + lastSquareContext=YY_START; + pCopySquareGString=¤t->initializer; + squareCount=0; + current->initializer+=*yytext; + BEGIN(GCopySquare); + } <ReadInitializer>"{" { lastCurlyContext=YY_START; pCopyCurlyGString=¤t->initializer; @@ -3073,6 +3133,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) *pCopyQuotedGString+=*yytext; BEGIN( lastStringContext ); } +<CopyGString,CopyPHPGString>"<?php" { // we had an odd number of quotes. + *pCopyQuotedGString += yytext; + BEGIN( lastStringContext ); + } <CopyGString,CopyPHPGString>"/*"|"*/"|"//" { *pCopyQuotedGString+=yytext; } @@ -3184,6 +3248,56 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) *pCopyRoundGString+=*yytext; } + /* generic square bracket list copy rules for growable strings, we should only enter here in case of php, left the test part as in GCopyRound to keep it compatible with te round bracket version */ +<GCopySquare>\" { + *pCopySquareGString+=*yytext; + pCopyQuotedGString=pCopySquareGString; + lastStringContext=YY_START; + BEGIN(CopyGString); + } +<GCopySquare>"[" { + *pCopySquareGString+=*yytext; + squareCount++; + } +<GCopySquare>"]" { + *pCopySquareGString+=*yytext; + if (--squareCount<0) + BEGIN(lastSquareContext); + } +<GCopySquare>\n { + lineCount(); + *pCopySquareGString+=*yytext; + } +<GCopySquare>\' { + if (insidePHP) + { + current->initializer+=yytext; + pCopyQuotedGString = pCopySquareGString; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + else + { + *pCopySquareGString+=yytext; + } + } +<GCopySquare>{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + *pCopySquareGString+=yytext; + } + } +<GCopySquare>[^"\[\]\n/]+ { + *pCopySquareGString+=yytext; + } +<GCopySquare>. { + *pCopySquareGString+=*yytext; + } + /* generic curly bracket list copy rules */ <CopyCurly>\" { *pCopyCurlyString+=*yytext; @@ -3392,7 +3506,14 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers>"[" { - if (!insideCS && + if (insideSlice) + { + squareCount=1; + lastSquareContext = YY_START; + current->metaData += "["; + BEGIN( SliceMetadata ); + } + else if (!insideCS && (current->name.isEmpty() || current->name=="typedef" ) @@ -3432,6 +3553,26 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN( Array ) ; } } +<SliceMetadata>"[" { // Global metadata. + squareCount++; + current->metaData += "["; + } +<SliceMetadata>{BN}* { + lineCount(); + } +<SliceMetadata>\"[^\"]*\" { + current->metaData += yytext; + } +<SliceMetadata>"," { + current->metaData += yytext; + } +<SliceMetadata>"]" { + current->metaData += yytext; + if (--squareCount<=0) + { + BEGIN (lastSquareContext); + } + } <IDLAttribute>"]" { // end of IDL function attribute if (--squareCount<=0) @@ -3639,7 +3780,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; - current->type = "@"; // enum marker + if (!(current_root->spec&Entry::Enum)) + { + current->type = "@"; // enum marker + } current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; @@ -3781,6 +3925,28 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine = yyLineNr; + if (current->section == Entry::NAMESPACE_SEC && current->type == "namespace") + { + int split_point; + while ((split_point = current->name.find("::")) != -1) + { + Entry *new_current = new Entry(*current); + current->program = ""; + new_current->doc = ""; + new_current->docLine = 0; + new_current->docFile = ""; + new_current->brief = ""; + new_current->briefLine = 0; + new_current->briefFile = ""; + new_current->name = current->name.mid(split_point + 2); + current->name = current->name.left(split_point); + if (!current_root->name.isEmpty()) current->name.prepend(current_root->name+"::"); + + current_root->addSubEntry(current); + current_root = current; + current = new_current; + } + } QCString &cn = current->name; QCString rn = current_root->name.copy(); //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef); @@ -3818,7 +3984,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current = new Entry(*current); if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || - insideJava || insidePHP || insideCS || insideD || insideJS + insideJava || insidePHP || insideCS || insideD || insideJS || + insideSlice ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); @@ -4794,7 +4961,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <FuncQual>{ID} { // typically a K&R style C function if (insideCS && qstrcmp(yytext,"where")==0) { - // type contraint for a method + // type constraint for a method delete current->typeConstr; current->typeConstr = new ArgumentList; current->typeConstr->append(new Argument); @@ -5290,7 +5457,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } BEGIN( FindMembers ) ; } -<CompoundName>{SCOPENAME}{BN}*/"<" { +<CompoundName>{SCOPENAME}/{BN}*"<" { sharpCount = 0; current->name = yytext ; if (current->spec & Entry::Protocol) @@ -5528,7 +5695,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) roundCount=0; BEGIN(SkipUnionSwitch); } - else if ((insideJava || insidePHP || insideJS) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0)) + else if ((insideJava || insidePHP || insideJS || insideSlice) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0)) { current->type.resize(0); baseProt=Public; @@ -5536,7 +5703,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) baseName.resize(0); BEGIN( BasesProt ) ; } - else if (insideCS && qstrcmp(yytext,"where")==0) // C# type contraint + else if (insideCS && qstrcmp(yytext,"where")==0) // C# type constraint { delete current->typeConstr; current->typeConstr = new ArgumentList; @@ -5816,7 +5983,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) QCString baseScope = yytext; if (insideCS && baseScope.stripWhiteSpace()=="where") { - // type contraint for a class + // type constraint for a class delete current->typeConstr; current->typeConstr = new ArgumentList; current->typeConstr->append(new Argument); @@ -5955,7 +6122,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } if ((current->spec & (Entry::Interface|Entry::Struct)) || insideJava || insidePHP || insideCS || - insideD || insideObjC || insideIDL) + insideD || insideObjC || insideIDL || insideSlice) { baseProt=Public; } @@ -6240,13 +6407,72 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <CSAccessorDecl>"." {} <CSAccessorDecl>\n { lineCount(); } <CSString>"\"" { BEGIN(CSAccessorDecl);} -<CSString>"//" {} /* Otherwise the rule <*>"//" will kick in */ -<CSString>"/*" {} /* Otherwise the rule <*>"/*" will kick in */ +<CSString>"//" {} // Otherwise the rule <*>"//" will kick in +<CSString>"/*" {} // Otherwise the rule <*>"/*" will kick in <CSString>\n { lineCount(); } <CSString>"." {} + /* ---- Slice-specific rules ------ */ + +<SliceSequence>{SCOPENAME} { + if (current->spec&Entry::Local) + { + current->type = "local "; + } + current->type += "sequence<"; + current->type += yytext; + current->type += ">"; + } + +<SliceSequence>{BN}*">"{BN}* { + lineCount(); + BEGIN(SliceSequenceName); + } + +<SliceSequenceName>{ID}{BN}* { + lineCount(); + current->name = yytext ; + current->name = current->name.stripWhiteSpace(); + } + +<SliceSequenceName>";" { + current->section = Entry::VARIABLE_SEC; + current_root->addSubEntry(current); + current = new Entry; + initEntry(); + BEGIN(FindMembers); + } + +<SliceDictionary>{SCOPENAME}{BN}*","{BN}*{SCOPENAME} { + lineCount(); + if (current->spec&Entry::Local) + { + current->type = "local "; + } + current->type += "dictionary<"; + current->type += yytext; + current->type += ">"; + current->type = current->type.simplifyWhiteSpace(); + } +<SliceDictionary>{BN}*">"{BN}* { + lineCount(); + BEGIN(SliceDictionaryName); + } +<SliceDictionaryName>{ID}{BN}* { + lineCount(); + current->name = yytext ; + current->name = current->name.stripWhiteSpace(); + } + +<SliceDictionaryName>";" { + current->section = Entry::VARIABLE_SEC; + current_root->addSubEntry(current); + current = new Entry; + initEntry(); + BEGIN(FindMembers); + } /**********************************************************************************/ /******************** Documentation block related rules ***************************/ @@ -6842,7 +7068,7 @@ static void parseCompounds(Entry *rt) // set default protection based on the compound type if( ce->section==Entry::CLASS_SEC ) // class { - if (insidePHP || insideD || insideJS || insideIDL) + if (insidePHP || insideD || insideJS || insideIDL || insideSlice) { current->protection = protection = Public ; } diff --git a/src/searchindex.cpp b/src/searchindex.cpp index 6276eae..5859d67 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -620,6 +620,14 @@ static void addMemberToSearchIndex(MemberDef *md) { g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md); } + else if (md->isSequence()) + { + g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].symbolList.append(letter,md); + } + else if (md->isDictionary()) + { + g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].symbolList.append(letter,md); + } else if (md->isTypedef()) { g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md); @@ -667,6 +675,14 @@ static void addMemberToSearchIndex(MemberDef *md) { g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md); } + else if (md->isSequence()) + { + g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].symbolList.append(letter,md); + } + else if (md->isDictionary()) + { + g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].symbolList.append(letter,md); + } else if (md->isTypedef()) { g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md); @@ -717,39 +733,54 @@ static QCString searchId(const QCString &s) void createJavascriptSearchIndex() { + bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + // set index names - g_searchIndexInfo[SEARCH_INDEX_ALL].name = "all"; - g_searchIndexInfo[SEARCH_INDEX_CLASSES].name = "classes"; - g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].name = "namespaces"; - g_searchIndexInfo[SEARCH_INDEX_FILES].name = "files"; - g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].name = "functions"; - g_searchIndexInfo[SEARCH_INDEX_VARIABLES].name = "variables"; - g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].name = "typedefs"; - g_searchIndexInfo[SEARCH_INDEX_ENUMS].name = "enums"; - g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].name = "enumvalues"; - g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].name = "properties"; - g_searchIndexInfo[SEARCH_INDEX_EVENTS].name = "events"; - g_searchIndexInfo[SEARCH_INDEX_RELATED].name = "related"; - g_searchIndexInfo[SEARCH_INDEX_DEFINES].name = "defines"; - g_searchIndexInfo[SEARCH_INDEX_GROUPS].name = "groups"; - g_searchIndexInfo[SEARCH_INDEX_PAGES].name = "pages"; + g_searchIndexInfo[SEARCH_INDEX_ALL].name = "all"; + g_searchIndexInfo[SEARCH_INDEX_CLASSES].name = "classes"; + g_searchIndexInfo[SEARCH_INDEX_INTERFACES].name = "interfaces"; + g_searchIndexInfo[SEARCH_INDEX_STRUCTS].name = "structs"; + g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].name = "exceptions"; + g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].name = "namespaces"; + g_searchIndexInfo[SEARCH_INDEX_FILES].name = "files"; + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].name = "functions"; + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].name = "variables"; + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].name = "typedefs"; + g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].name = "sequences"; + g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].name = "dictionaries"; + g_searchIndexInfo[SEARCH_INDEX_ENUMS].name = "enums"; + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].name = "enumvalues"; + g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].name = "properties"; + g_searchIndexInfo[SEARCH_INDEX_EVENTS].name = "events"; + g_searchIndexInfo[SEARCH_INDEX_RELATED].name = "related"; + g_searchIndexInfo[SEARCH_INDEX_DEFINES].name = "defines"; + g_searchIndexInfo[SEARCH_INDEX_GROUPS].name = "groups"; + g_searchIndexInfo[SEARCH_INDEX_PAGES].name = "pages"; // set index texts - g_searchIndexInfo[SEARCH_INDEX_ALL].text = theTranslator->trAll(); - g_searchIndexInfo[SEARCH_INDEX_CLASSES].text = theTranslator->trClasses(); - g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].text = theTranslator->trNamespace(TRUE,FALSE); - g_searchIndexInfo[SEARCH_INDEX_FILES].text = theTranslator->trFile(TRUE,FALSE); - g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].text = theTranslator->trFunctions(); - g_searchIndexInfo[SEARCH_INDEX_VARIABLES].text = theTranslator->trVariables(); - g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].text = theTranslator->trTypedefs(); - g_searchIndexInfo[SEARCH_INDEX_ENUMS].text = theTranslator->trEnumerations(); - g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].text = theTranslator->trEnumerationValues(); - g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].text = theTranslator->trProperties(); - g_searchIndexInfo[SEARCH_INDEX_EVENTS].text = theTranslator->trEvents(); - g_searchIndexInfo[SEARCH_INDEX_RELATED].text = theTranslator->trFriends(); - g_searchIndexInfo[SEARCH_INDEX_DEFINES].text = theTranslator->trDefines(); - g_searchIndexInfo[SEARCH_INDEX_GROUPS].text = theTranslator->trGroup(TRUE,FALSE); - g_searchIndexInfo[SEARCH_INDEX_PAGES].text = theTranslator->trPage(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_ALL].text = theTranslator->trAll(); + g_searchIndexInfo[SEARCH_INDEX_CLASSES].text = theTranslator->trClasses(); + g_searchIndexInfo[SEARCH_INDEX_INTERFACES].text = theTranslator->trSliceInterfaces(); + g_searchIndexInfo[SEARCH_INDEX_STRUCTS].text = theTranslator->trStructs(); + g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].text = theTranslator->trExceptions(); + g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].text = sliceOpt ? theTranslator->trModules() : + theTranslator->trNamespace(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_FILES].text = theTranslator->trFile(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].text = sliceOpt ? theTranslator->trOperations() : + theTranslator->trFunctions(); + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].text = sliceOpt ? theTranslator->trConstants() : + theTranslator->trVariables(); + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].text = theTranslator->trTypedefs(); + g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].text = theTranslator->trSequences(); + g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].text = theTranslator->trDictionaries(); + g_searchIndexInfo[SEARCH_INDEX_ENUMS].text = theTranslator->trEnumerations(); + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].text = theTranslator->trEnumerationValues(); + g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].text = theTranslator->trProperties(); + g_searchIndexInfo[SEARCH_INDEX_EVENTS].text = theTranslator->trEvents(); + g_searchIndexInfo[SEARCH_INDEX_RELATED].text = theTranslator->trFriends(); + g_searchIndexInfo[SEARCH_INDEX_DEFINES].text = theTranslator->trDefines(); + g_searchIndexInfo[SEARCH_INDEX_GROUPS].text = theTranslator->trGroup(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_PAGES].text = theTranslator->trPage(TRUE,FALSE); // add symbols to letter -> symbol list map @@ -762,7 +793,29 @@ void createJavascriptSearchIndex() if (cd->isLinkable() && isId(letter)) { g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,cd); - g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd); + if (sliceOpt) + { + if (cd->compoundType()==ClassDef::Interface) + { + g_searchIndexInfo[SEARCH_INDEX_INTERFACES].symbolList.append(letter,cd); + } + else if (cd->compoundType()==ClassDef::Struct) + { + g_searchIndexInfo[SEARCH_INDEX_STRUCTS].symbolList.append(letter,cd); + } + else if (cd->compoundType()==ClassDef::Exception) + { + g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].symbolList.append(letter,cd); + } + else // cd->compoundType()==ClassDef::Class + { + g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd); + } + } + else // non slice optimisation: group all types under classes + { + g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd); + } } } @@ -927,7 +980,7 @@ void writeJavascriptSearchIndex() FTextStream t(&outFile); t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"" - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl; + " \"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl; t << "<html><head><title></title>" << endl; t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl; t << "<meta name=\"generator\" content=\"Doxygen " << versionString << "\"/>" << endl; @@ -1231,7 +1284,7 @@ void writeJavascriptSearchIndex() { FTextStream t(&f); t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " - "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl; + "\"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl; t << "<html><head><title></title>" << endl; t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl; t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl; diff --git a/src/searchindex.h b/src/searchindex.h index e491f47..0345b41 100644 --- a/src/searchindex.h +++ b/src/searchindex.h @@ -112,22 +112,27 @@ class SearchIndexExternal : public SearchIndexIntf //------- client side search index ---------------------- -#define SEARCH_INDEX_ALL 0 -#define SEARCH_INDEX_CLASSES 1 -#define SEARCH_INDEX_NAMESPACES 2 -#define SEARCH_INDEX_FILES 3 -#define SEARCH_INDEX_FUNCTIONS 4 -#define SEARCH_INDEX_VARIABLES 5 -#define SEARCH_INDEX_TYPEDEFS 6 -#define SEARCH_INDEX_ENUMS 7 -#define SEARCH_INDEX_ENUMVALUES 8 -#define SEARCH_INDEX_PROPERTIES 9 -#define SEARCH_INDEX_EVENTS 10 -#define SEARCH_INDEX_RELATED 11 -#define SEARCH_INDEX_DEFINES 12 -#define SEARCH_INDEX_GROUPS 13 -#define SEARCH_INDEX_PAGES 14 -#define NUM_SEARCH_INDICES 15 +#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 NUM_SEARCH_INDICES 20 class SearchDefinitionList : public QList<Definition> { diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index 6cd9581..a7b8dbb 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -23,11 +23,15 @@ #include "qtbc.h" #include "sqlite3gen.h" #include "doxygen.h" +#include "xmlgen.h" +#include "xmldocvisitor.h" #include "config.h" #include "util.h" +#include "outputlist.h" #include "docparser.h" #include "language.h" +#include "version.h" #include "dot.h" #include "arguments.h" #include "classlist.h" @@ -35,65 +39,129 @@ #include "namespacedef.h" #include "filename.h" #include "groupdef.h" +#include "membername.h" +#include "memberdef.h" #include "pagedef.h" #include "dirdef.h" +#include "section.h" +#include <sys/stat.h> #include <qdir.h> #include <string.h> #include <sqlite3.h> -//#define DBG_CTX(x) printf x -#define DBG_CTX(x) do { } while(0) +// enable to show general debug messages +// #define SQLITE3_DEBUG -const char * schema_queries[][2] = { +// enable to print all executed SQL statements. +// I recommend using the smallest possible input list. +// #define SQLITE3_DEBUG_SQL + +# ifdef SQLITE3_DEBUG +# define DBG_CTX(x) printf x +# else // SQLITE3_DEBUG +# define DBG_CTX(x) do { } while(0) +# endif + +# ifdef SQLITE3_DEBUG_SQL +// used by sqlite3_trace in generateSqlite3() +static void sqlLog(void *dbName, const char *sql){ + msg("SQL: '%s'\n", sql); +} +# endif + +const char * table_schema[][2] = { + /* TABLES */ + { "meta", + "CREATE TABLE IF NOT EXISTS meta (\n" + "\t-- Information about this db and how it was generated.\n" + "\t-- Doxygen info\n" + "\tdoxygen_version TEXT PRIMARY KEY NOT NULL,\n" + /* + Doxygen's version is likely to rollover much faster than the schema, and + at least until it becomes a core output format, we might want to make + fairly large schema changes even on minor iterations for Doxygen itself. + If these tools just track a predefined semver schema version that can + iterate independently, it *might* not be as hard to keep them in sync? + */ + "\tschema_version TEXT NOT NULL, -- Schema-specific semver\n" + "\t-- run info\n" + "\tgenerated_at TEXT NOT NULL,\n" + "\tgenerated_on TEXT NOT NULL,\n" + "\t-- project info\n" + "\tproject_name TEXT NOT NULL,\n" + "\tproject_number TEXT,\n" + "\tproject_brief TEXT\n" + ");" + }, { "includes", "CREATE TABLE IF NOT EXISTS includes (\n" "\t-- #include relations.\n" "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" "\tlocal INTEGER NOT NULL,\n" - "\tid_src INTEGER NOT NULL, -- File id of the includer.\n" - "\tid_dst INTEGER NOT NULL -- File id of the includee.\n" - ");\n" - "CREATE UNIQUE INDEX idx_includes ON includes\n" - "\t(local, id_src, id_dst);" + "\tsrc_id INTEGER NOT NULL REFERENCES path, -- File id of the includer.\n" + "\tdst_id INTEGER NOT NULL REFERENCES path, -- File id of the includee.\n" + /* + In theory we could include name here to be informationally equivalent + with the XML, but I don't see an obvious use for it. + */ + "\tUNIQUE(local, src_id, dst_id) ON CONFLICT IGNORE\n" + ");" }, - { "innerclass", - "CREATE TABLE IF NOT EXISTS innerclass (\n" + { "contains", + "CREATE TABLE IF NOT EXISTS contains (\n" + "\t-- inner/outer relations (file, namespace, dir, class, group, page)\n" "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\trefid INTEGER NOT NULL,\n" - "\tprot INTEGER NOT NULL,\n" - "\tname TEXT NOT NULL\n" - ");" + "\tinner_rowid INTEGER NOT NULL REFERENCES compounddef,\n" + "\touter_rowid INTEGER NOT NULL REFERENCES compounddef\n" + ");" }, - { "files", - "CREATE TABLE IF NOT EXISTS files (\n" - "\t-- Names of source files and includes.\n" - "\tname TEXT PRIMARY KEY NOT NULL\n" - ");" + /* TODO: Path can also share rowids with refid/compounddef/def. (It could + * even collapse into that table...) + * + * I took a first swing at this by changing insertPath() to: + * - accept a FileDef + * - make its own call to insertRefid + * - return a refid struct. + * + * I rolled this back when I had trouble getting a FileDef for all types + * (PageDef in particular). + * + * Note: all colums referencing path would need an update. + */ + { "path", + "CREATE TABLE IF NOT EXISTS path (\n" + "\t-- Paths of source files and includes.\n" + "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + "\ttype INTEGER NOT NULL, -- 1:file 2:dir\n" + "\tlocal INTEGER NOT NULL,\n" + "\tfound INTEGER NOT NULL,\n" + "\tname TEXT NOT NULL\n" + ");" }, - { "refids", - "CREATE TABLE IF NOT EXISTS refids (\n" - "\trefid TEXT PRIMARY KEY NOT NULL\n" - ");" + { "refid", + "CREATE TABLE IF NOT EXISTS refid (\n" + "\t-- Distinct refid for all documented entities.\n" + "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + "\trefid TEXT NOT NULL UNIQUE\n" + ");" }, { "xrefs", "CREATE TABLE IF NOT EXISTS xrefs (\n" - "\t-- Cross reference relation.\n" + "\t-- Cross-reference relation\n" + "\t-- (combines xml <referencedby> and <references> nodes).\n" "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\trefid_src INTEGER NOT NULL, -- referrer id.\n" - "\trefid_dst INTEGER NOT NULL, -- referee id.\n" - "\tid_file INTEGER NOT NULL, -- file where the reference is happening.\n" - "\tline INTEGER NOT NULL, -- line where the reference is happening.\n" - "\tcolumn INTEGER NOT NULL -- column where the reference is happening.\n" - ");\n" - "CREATE UNIQUE INDEX idx_xrefs ON xrefs\n" - "\t(refid_src, refid_dst, id_file, line, column);" + "\tsrc_rowid INTEGER NOT NULL REFERENCES refid, -- referrer id.\n" + "\tdst_rowid INTEGER NOT NULL REFERENCES refid, -- referee id.\n" + "\tcontext TEXT NOT NULL, -- inline, argument, initializer\n" + "\t-- Just need to know they link; ignore duplicates.\n" + "\tUNIQUE(src_rowid, dst_rowid, context) ON CONFLICT IGNORE\n" + ");\n" }, { "memberdef", "CREATE TABLE IF NOT EXISTS memberdef (\n" "\t-- All processed identifiers.\n" - "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\trefid INTEGER NOT NULL, -- see the refids table\n" + "\trowid INTEGER PRIMARY KEY NOT NULL,\n" "\tname TEXT NOT NULL,\n" "\tdefinition TEXT,\n" "\ttype TEXT,\n" @@ -107,7 +175,7 @@ const char * schema_queries[][2] = { "\tstatic INTEGER DEFAULT 0, -- 0:no 1:yes\n" "\tconst INTEGER DEFAULT 0, -- 0:no 1:yes\n" "\texplicit INTEGER DEFAULT 0, -- 0:no 1:yes\n" - "\tinline INTEGER DEFAULT 0, -- 0:no 1:yes\n" + "\tinline INTEGER DEFAULT 0, -- 0:no 1:yes 2:both (set after encountering inline and not-inline)\n" "\tfinal INTEGER DEFAULT 0, -- 0:no 1:yes\n" "\tsealed INTEGER DEFAULT 0, -- 0:no 1:yes\n" "\tnew INTEGER DEFAULT 0, -- 0:no 1:yes\n" @@ -138,55 +206,71 @@ const char * schema_queries[][2] = { "\taddable INTEGER DEFAULT 0, -- 0:no 1:yes\n" "\tremovable INTEGER DEFAULT 0, -- 0:no 1:yes\n" "\traisable INTEGER DEFAULT 0, -- 0:no 1:yes\n" - /// @todo make a `kind' table - "\tkind INTEGER DEFAULT 0, -- 0:define 1:function 2:variable 3:typedef 4:enum 5:enumvalue 6:signal 7:slot 8:friend 9:DCOP 10:property 11:event\n" + "\tkind TEXT NOT NULL, -- 'macro definition' 'function' 'variable' 'typedef' 'enumeration' 'enumvalue' 'signal' 'slot' 'friend' 'dcop' 'property' 'event' 'interface' 'service'\n" "\tbodystart INTEGER DEFAULT 0, -- starting line of definition\n" "\tbodyend INTEGER DEFAULT 0, -- ending line of definition\n" - "\tid_bodyfile INTEGER DEFAULT 0, -- file of definition\n" - "\tid_file INTEGER NOT NULL, -- file where this identifier is located\n" + "\tbodyfile_id INTEGER REFERENCES path, -- file of definition\n" + "\tfile_id INTEGER NOT NULL REFERENCES path, -- file where this identifier is located\n" "\tline INTEGER NOT NULL, -- line where this identifier is located\n" "\tcolumn INTEGER NOT NULL, -- column where this identifier is located\n" - /// @todo make a `detaileddescription' table "\tdetaileddescription TEXT,\n" "\tbriefdescription TEXT,\n" - "\tinbodydescription TEXT\n" - ");" + "\tinbodydescription TEXT,\n" + "\tFOREIGN KEY (rowid) REFERENCES refid (rowid)\n" + ");" + }, + { "member", + "CREATE TABLE IF NOT EXISTS member (\n" + "\t-- Memberdef <-> containing compound relation.\n" + "\t-- Similar to XML listofallmembers.\n" + "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + "\tscope_rowid INTEGER NOT NULL REFERENCES compounddef,\n" + "\tmemberdef_rowid INTEGER NOT NULL REFERENCES memberdef,\n" + "\tprot INTEGER NOT NULL,\n" + "\tvirt INTEGER NOT NULL,\n" + "\tUNIQUE(scope_rowid, memberdef_rowid)\n" + ");" + }, + { "reimplements", + "CREATE TABLE IF NOT EXISTS reimplements (\n" + "\t-- Inherited member reimplmentation relations.\n" + "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + "\tmemberdef_rowid INTEGER NOT NULL REFERENCES memberdef, -- reimplementing memberdef id.\n" + "\treimplemented_rowid INTEGER NOT NULL REFERENCES memberdef, -- reimplemented memberdef id.\n" + "\tUNIQUE(memberdef_rowid, reimplemented_rowid) ON CONFLICT IGNORE\n" + ");\n" }, { "compounddef", "CREATE TABLE IF NOT EXISTS compounddef (\n" - "\t-- class/struct definitions.\n" - "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\tname TEXT NOT NULL,\n" - "\tkind TEXT NOT NULL,\n" - "\trefid INTEGER NOT NULL,\n" - "\tprot INTEGER NOT NULL,\n" - "\tid_file INTEGER NOT NULL,\n" - "\tline INTEGER NOT NULL,\n" - "\tcolumn INTEGER NOT NULL\n" - ");" - }, - { "basecompoundref", - "CREATE TABLE IF NOT EXISTS basecompoundref (\n" - "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\tbase TEXT NOT NULL,\n" - "\tderived TEXT NOT NULL,\n" - "\trefid INTEGER NOT NULL,\n" - "\tprot INTEGER NOT NULL,\n" - "\tvirt INTEGER NOT NULL\n" - ");" + "\t-- Class/struct definitions.\n" + "\trowid INTEGER PRIMARY KEY NOT NULL,\n" + "\tname TEXT NOT NULL,\n" + "\ttitle TEXT,\n" + // probably won't be empty '' or unknown, but the source *could* return them... + "\tkind TEXT NOT NULL, -- 'category' 'class' 'constants' 'dir' 'enum' 'example' 'exception' 'file' 'group' 'interface' 'library' 'module' 'namespace' 'package' 'page' 'protocol' 'service' 'singleton' 'struct' 'type' 'union' 'unknown' ''\n" + "\tprot INTEGER,\n" + "\tfile_id INTEGER NOT NULL REFERENCES path,\n" + "\tline INTEGER NOT NULL,\n" + "\tcolumn INTEGER NOT NULL,\n" + "\theader_id INTEGER REFERENCES path,\n" + "\tdetaileddescription TEXT,\n" + "\tbriefdescription TEXT,\n" + "\tFOREIGN KEY (rowid) REFERENCES refid (rowid)\n" + ");" }, - { "derivedcompoundref", - "CREATE TABLE IF NOT EXISTS derivedcompoundref (\n" - "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\tbase TEXT NOT NULL,\n" - "\tderived TEXT NOT NULL,\n" - "\trefid INTEGER NOT NULL,\n" - "\tprot INTEGER NOT NULL,\n" - "\tvirt INTEGER NOT NULL\n" - ");" + { "compoundref", + "CREATE TABLE IF NOT EXISTS compoundref (\n" + "\t-- Inheritance relation.\n" + "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + "\tbase_rowid INTEGER NOT NULL REFERENCES compounddef,\n" + "\tderived_rowid INTEGER NOT NULL REFERENCES compounddef,\n" + "\tprot INTEGER NOT NULL,\n" + "\tvirt INTEGER NOT NULL,\n" + "\tUNIQUE(base_rowid, derived_rowid)\n" + ");" }, - { "params", - "CREATE TABLE IF NOT EXISTS params (\n" + { "param", + "CREATE TABLE IF NOT EXISTS param (\n" "\t-- All processed parameters.\n" "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" "\tattributes TEXT,\n" @@ -196,24 +280,222 @@ const char * schema_queries[][2] = { "\tarray TEXT,\n" "\tdefval TEXT,\n" "\tbriefdescription TEXT\n" - ");" - "CREATE UNIQUE INDEX idx_params ON params\n" + ");" + "CREATE UNIQUE INDEX idx_param ON param\n" "\t(type, defname);" }, - { "memberdef_params", - "CREATE TABLE IF NOT EXISTS memberdef_params (\n" + { "memberdef_param", + "CREATE TABLE IF NOT EXISTS memberdef_param (\n" "\t-- Junction table for memberdef parameters.\n" "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\tid_memberdef INTEGER NOT NULL,\n" - "\tid_param INTEGER NOT NULL\n" - ");" + "\tmemberdef_id INTEGER NOT NULL REFERENCES memberdef,\n" + "\tparam_id INTEGER NOT NULL REFERENCES param\n" + ");" }, - { "innernamespaces", - "CREATE TABLE IF NOT EXISTS innernamespaces (\n" - "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" - "\trefid INTEGER NOT NULL,\n" - "\tname TEXT NOT NULL\n" - ");" +}; + const char * view_schema[][2] = { + /* VIEWS * + We'll set these up AFTER we build the database, so that they can be indexed, + but so we don't have to pay a performance penalty for inserts as we build. + */ + { + /* + Makes all reference/relation tables easier to use. For example: + 1. query xrefs and join this view on either xrefs.dst_rowid=def.rowid or + xrefs.src_rowid=def.rowid + 2. get everything you need to output a list of references to/from an entity + + Also supports simple name search/lookup for both compound and member types. + + NOTES: + - summary for compounds generalizes title and briefdescription because + there's no single field that works as a quick introduction for both + pages and classes + - May be value in eventually extending this to fulltext or levenshtein + distance-driven lookup/search, but I'm avoiding these for now as it + takes some effort to enable them. + */ + "def", + "CREATE VIEW IF NOT EXISTS def (\n" + "\t-- Combined summary of all -def types for easier joins.\n" + "\trowid,\n" + "\trefid,\n" + "\tkind,\n" + "\tname,\n" + "\tsummary" + ")\n" + "as SELECT \n" + "\trefid.rowid,\n" + "\trefid.refid,\n" + "\tmemberdef.kind,\n" + "\tmemberdef.name,\n" + "\tmemberdef.briefdescription \n" + "FROM refid \n" + "JOIN memberdef ON refid.rowid=memberdef.rowid \n" + "UNION ALL \n" + "SELECT \n" + "\trefid.rowid,\n" + "\trefid.refid,\n" + "\tcompounddef.kind,\n" + "\tcompounddef.name,\n" + "\tCASE \n" + "\t\tWHEN briefdescription IS NOT NULL \n" + "\t\tTHEN briefdescription \n" + "\t\tELSE title \n" + "\tEND summary\n" + "FROM refid \n" + "JOIN compounddef ON refid.rowid=compounddef.rowid;" + }, + { + "local_file", + "CREATE VIEW IF NOT EXISTS local_file (\n" + "\t-- File paths found within the project.\n" + "\trowid,\n" + "\tfound,\n" + "\tname\n" + ")\n" + "as SELECT \n" + "\tpath.rowid,\n" + "\tpath.found,\n" + "\tpath.name\n" + "FROM path WHERE path.type=1 AND path.local=1 AND path.found=1;\n" + }, + { + "external_file", + "CREATE VIEW IF NOT EXISTS external_file (\n" + "\t-- File paths outside the project (found or not).\n" + "\trowid,\n" + "\tfound,\n" + "\tname\n" + ")\n" + "as SELECT \n" + "\tpath.rowid,\n" + "\tpath.found,\n" + "\tpath.name\n" + "FROM path WHERE path.type=1 AND path.local=0;\n" + }, + { + "inline_xrefs", + "CREATE VIEW IF NOT EXISTS inline_xrefs (\n" + "\t-- Crossrefs from inline member source.\n" + "\trowid,\n" + "\tsrc_rowid,\n" + "\tdst_rowid\n" + ")\n" + "as SELECT \n" + "\txrefs.rowid,\n" + "\txrefs.src_rowid,\n" + "\txrefs.dst_rowid\n" + "FROM xrefs WHERE xrefs.context='inline';\n" + }, + { + "argument_xrefs", + "CREATE VIEW IF NOT EXISTS argument_xrefs (\n" + "\t-- Crossrefs from member def/decl arguments\n" + "\trowid,\n" + "\tsrc_rowid,\n" + "\tdst_rowid\n" + ")\n" + "as SELECT \n" + "\txrefs.rowid,\n" + "\txrefs.src_rowid,\n" + "\txrefs.dst_rowid\n" + "FROM xrefs WHERE xrefs.context='argument';\n" + }, + { + "initializer_xrefs", + "CREATE VIEW IF NOT EXISTS initializer_xrefs (\n" + "\t-- Crossrefs from member initializers\n" + "\trowid,\n" + "\tsrc_rowid,\n" + "\tdst_rowid\n" + ")\n" + "as SELECT \n" + "\txrefs.rowid,\n" + "\txrefs.src_rowid,\n" + "\txrefs.dst_rowid\n" + "FROM xrefs WHERE xrefs.context='initializer';\n" + }, + { + "inner_outer", + "CREATE VIEW IF NOT EXISTS inner_outer\n" + "\t-- Joins 'contains' relations to simplify inner/outer 'rel' queries.\n" + "as SELECT \n" + "\tinner.*,\n" + "\touter.*\n" + "FROM def as inner\n" + "\tJOIN contains ON inner.rowid=contains.inner_rowid\n" + "\tJOIN def AS outer ON outer.rowid=contains.outer_rowid;\n" + }, + { + "rel", + "CREATE VIEW IF NOT EXISTS rel (\n" + "\t-- Boolean indicator of relations available for a given entity.\n" + "\t-- Join to (compound-|member-)def to find fetch-worthy relations.\n" + "\trowid,\n" + "\treimplemented,\n" + "\treimplements,\n" + "\tinnercompounds,\n" + "\toutercompounds,\n" + "\tinnerpages,\n" + "\touterpages,\n" + "\tinnerdirs,\n" + "\touterdirs,\n" + "\tinnerfiles,\n" + "\touterfiles,\n" + "\tinnerclasses,\n" + "\touterclasses,\n" + "\tinnernamespaces,\n" + "\touternamespaces,\n" + "\tinnergroups,\n" + "\toutergroups,\n" + "\tmembers,\n" + "\tcompounds,\n" + "\tsubclasses,\n" + "\tsuperclasses,\n" + "\tlinks_in,\n" + "\tlinks_out,\n" + "\targument_links_in,\n" + "\targument_links_out,\n" + "\tinitializer_links_in,\n" + "\tinitializer_links_out\n" + ")\n" + "as SELECT \n" + "\tdef.rowid,\n" + "\tEXISTS (SELECT rowid FROM reimplements WHERE reimplemented_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM reimplements WHERE memberdef_rowid=def.rowid),\n" + "\t-- rowid/kind for inner, [rowid:1/kind:1] for outer\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='page'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='page'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='dir'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='dir'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='file'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='file'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind in (\n" + "'category','class','enum','exception','interface','module','protocol',\n" + "'service','singleton','struct','type','union'\n" + ")),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1] in (\n" + "'category','class','enum','exception','interface','module','protocol',\n" + "'service','singleton','struct','type','union'\n" + ")),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='namespace'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='namespace'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='group'),\n" + "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='group'),\n" + "\tEXISTS (SELECT rowid FROM member WHERE scope_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM member WHERE memberdef_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM compoundref WHERE base_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM compoundref WHERE derived_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM inline_xrefs WHERE dst_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM inline_xrefs WHERE src_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM argument_xrefs WHERE dst_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM argument_xrefs WHERE src_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM initializer_xrefs WHERE dst_rowid=def.rowid),\n" + "\tEXISTS (SELECT rowid FROM initializer_xrefs WHERE src_rowid=def.rowid)\n" + "FROM def ORDER BY def.rowid;" } }; @@ -224,193 +506,298 @@ struct SqlStmt { sqlite3 *db; }; ////////////////////////////////////////////////////// -SqlStmt incl_insert = { "INSERT INTO includes " - "( local, id_src, id_dst ) " - "VALUES " - "(:local,:id_src,:id_dst )" - ,NULL +/* If you add a new statement below, make sure to add it to + prepareStatements(). If sqlite3 is segfaulting (especially in + sqlite3_clear_bindings()), using an un-prepared statement may + be the cause. */ +SqlStmt meta_insert = { + "INSERT INTO meta " + "( doxygen_version, schema_version, generated_at, generated_on, project_name, project_number, project_brief )" + "VALUES " + "(:doxygen_version,:schema_version,:generated_at,:generated_on,:project_name,:project_number,:project_brief )" + ,NULL +}; +////////////////////////////////////////////////////// +SqlStmt incl_insert = { + "INSERT INTO includes " + "( local, src_id, dst_id ) " + "VALUES " + "(:local,:src_id,:dst_id )" + ,NULL }; -SqlStmt incl_select = { "SELECT COUNT(*) FROM includes WHERE " - "local=:local AND id_src=:id_src AND id_dst=:id_dst" - ,NULL +SqlStmt incl_select = { + "SELECT COUNT(*) FROM includes WHERE " + "local=:local AND src_id=:src_id AND dst_id=:dst_id" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt innerclass_insert={"INSERT INTO innerclass " - "( refid, prot, name )" - "VALUES " - "(:refid,:prot,:name )" - ,NULL +SqlStmt contains_insert={ + "INSERT INTO contains " + "( inner_rowid, outer_rowid )" + "VALUES " + "(:inner_rowid,:outer_rowid )" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt files_select = {"SELECT rowid FROM files WHERE name=:name" +SqlStmt path_select = { + "SELECT rowid FROM path WHERE name=:name" ,NULL }; -SqlStmt files_insert = {"INSERT INTO files " - "( name )" - "VALUES " - "(:name )" - ,NULL +SqlStmt path_insert = { + "INSERT INTO path " + "( type, local, found, name )" + "VALUES " + "(:type,:local,:found,:name )" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt refids_select = {"SELECT rowid FROM refids WHERE " - "refid=:refid" - ,NULL +SqlStmt refid_select = { + "SELECT rowid FROM refid WHERE refid=:refid" + ,NULL }; -SqlStmt refids_insert = {"INSERT INTO refids " - "( refid )" - "VALUES " +SqlStmt refid_insert = { + "INSERT INTO refid " + "( refid )" + "VALUES " "(:refid )" - ,NULL + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt xrefs_insert= {"INSERT INTO xrefs " - "( refid_src, refid_dst, id_file, line, column )" - "VALUES " - "(:refid_src,:refid_dst,:id_file,:line,:column )" - ,NULL +SqlStmt xrefs_insert= { + "INSERT INTO xrefs " + "( src_rowid, dst_rowid, context )" + "VALUES " + "(:src_rowid,:dst_rowid,:context )" + ,NULL +};////////////////////////////////////////////////////// +SqlStmt reimplements_insert= { + "INSERT INTO reimplements " + "( memberdef_rowid, reimplemented_rowid )" + "VALUES " + "(:memberdef_rowid,:reimplemented_rowid )" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt memberdef_insert={"INSERT INTO memberdef " - "(" - "refid," - "name," - "definition," - "type," - "argsstring," - "scope," - "initializer," - "bitfield," - "read," - "write," - "prot," - "static," - "const," - "explicit," - "inline," - "final," - "sealed," - "new," - "optional," - "required," - "volatile," - "virt," - "mutable," - "initonly," - "attribute," - "property," - "readonly," - "bound," - "constrained," - "transient," - "maybevoid," - "maybedefault," - "maybeambiguous," - "readable," - "writable," - "gettable," - "protectedsettable," - "protectedgettable," - "settable," - "privatesettable," - "privategettable," - "accessor," - "addable," - "removable," - "raisable," - "kind," - "bodystart," - "bodyend," - "id_bodyfile," - "id_file," - "line," - "column," - "detaileddescription," - "briefdescription," - "inbodydescription" - ")" - "VALUES " - "(" - ":refid," - ":name," - ":definition," - ":type," - ":argsstring," - ":scope," - ":initializer," - ":bitfield," - ":read," - ":write," - ":prot," - ":static," - ":const," - ":explicit," - ":inline," - ":final," - ":sealed," - ":new," - ":optional," - ":required," - ":volatile," - ":virt," - ":mutable," - ":initonly," - ":attribute," - ":property," - ":readonly," - ":bound," - ":constrained," - ":transient," - ":maybevoid," - ":maybedefault," - ":maybeambiguous," - ":readable," - ":writable," - ":gettable," - ":protectedsettable," - ":protectedgettable," - ":settable," - ":privatesettable," - ":privategettable," - ":accessor," - ":addable," - ":removable," - ":raisable," - ":kind," - ":bodystart," - ":bodyend," - ":id_bodyfile," - ":id_file," - ":line," - ":column," - ":detaileddescription," - ":briefdescription," - ":inbodydescription" - ")" - ,NULL +SqlStmt memberdef_exists={ + "SELECT EXISTS (SELECT * FROM memberdef WHERE rowid = :rowid)" + ,NULL +}; + +SqlStmt memberdef_incomplete={ + "SELECT EXISTS (" + "SELECT * FROM memberdef WHERE " + "rowid = :rowid AND inline != 2 AND inline != :new_inline" + ")" + ,NULL +}; + +SqlStmt memberdef_insert={ + "INSERT INTO memberdef " + "(" + "rowid," + "name," + "definition," + "type," + "argsstring," + "scope," + "initializer," + "bitfield," + "read," + "write," + "prot," + "static," + "const," + "explicit," + "inline," + "final," + "sealed," + "new," + "optional," + "required," + "volatile," + "virt," + "mutable," + "initonly," + "attribute," + "property," + "readonly," + "bound," + "constrained," + "transient," + "maybevoid," + "maybedefault," + "maybeambiguous," + "readable," + "writable," + "gettable," + "protectedsettable," + "protectedgettable," + "settable," + "privatesettable," + "privategettable," + "accessor," + "addable," + "removable," + "raisable," + "kind," + "bodystart," + "bodyend," + "bodyfile_id," + "file_id," + "line," + "column," + "detaileddescription," + "briefdescription," + "inbodydescription" + ")" + "VALUES " + "(" + ":rowid," + ":name," + ":definition," + ":type," + ":argsstring," + ":scope," + ":initializer," + ":bitfield," + ":read," + ":write," + ":prot," + ":static," + ":const," + ":explicit," + ":inline," + ":final," + ":sealed," + ":new," + ":optional," + ":required," + ":volatile," + ":virt," + ":mutable," + ":initonly," + ":attribute," + ":property," + ":readonly," + ":bound," + ":constrained," + ":transient," + ":maybevoid," + ":maybedefault," + ":maybeambiguous," + ":readable," + ":writable," + ":gettable," + ":protectedsettable," + ":protectedgettable," + ":settable," + ":privatesettable," + ":privategettable," + ":accessor," + ":addable," + ":removable," + ":raisable," + ":kind," + ":bodystart," + ":bodyend," + ":bodyfile_id," + ":file_id," + ":line," + ":column," + ":detaileddescription," + ":briefdescription," + ":inbodydescription" + ")" + ,NULL +}; +/* +We have a slightly different need than the XML here. The XML can have two +memberdef nodes with the same refid to document the declaration and the +definition. This doesn't play very nice with a referential model. It isn't a +big issue if only one is documented, but in case both are, we'll fall back on +this kludge to combine them in a single row... +*/ +SqlStmt memberdef_update_decl={ + "UPDATE memberdef SET " + "inline = :inline," + "file_id = :file_id," + "line = :line," + "column = :column," + "detaileddescription = 'Declaration: ' || :detaileddescription || 'Definition: ' || detaileddescription," + "briefdescription = 'Declaration: ' || :briefdescription || 'Definition: ' || briefdescription," + "inbodydescription = 'Declaration: ' || :inbodydescription || 'Definition: ' || inbodydescription " + "WHERE rowid = :rowid" + ,NULL +}; +SqlStmt memberdef_update_def={ + "UPDATE memberdef SET " + "inline = :inline," + "bodystart = :bodystart," + "bodyend = :bodyend," + "bodyfile_id = :bodyfile_id," + "detaileddescription = 'Declaration: ' || detaileddescription || 'Definition: ' || :detaileddescription," + "briefdescription = 'Declaration: ' || briefdescription || 'Definition: ' || :briefdescription," + "inbodydescription = 'Declaration: ' || inbodydescription || 'Definition: ' || :inbodydescription " + "WHERE rowid = :rowid" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt compounddef_insert={"INSERT INTO compounddef " - "( name, kind, prot, refid, id_file, line, column ) " - "VALUES " - "(:name,:kind,:prot,:refid,:id_file,:line,:column )" - ,NULL +SqlStmt member_insert={ + "INSERT INTO member " + "( scope_rowid, memberdef_rowid, prot, virt ) " + "VALUES " + "(:scope_rowid,:memberdef_rowid,:prot,:virt )" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt basecompoundref_insert={"INSERT INTO basecompoundref " - "( base, derived, refid, prot, virt ) " - "VALUES " - "(:base,:derived,:refid,:prot,:virt )" - ,NULL +SqlStmt compounddef_insert={ + "INSERT INTO compounddef " + "(" + "rowid," + "name," + "title," + "kind," + "prot," + "file_id," + "line," + "column," + "header_id," + "briefdescription," + "detaileddescription" + ")" + "VALUES " + "(" + ":rowid," + ":name," + ":title," + ":kind," + ":prot," + ":file_id," + ":line," + ":column," + ":header_id," + ":briefdescription," + ":detaileddescription" + ")" + ,NULL +}; +SqlStmt compounddef_exists={ + "SELECT EXISTS (" + "SELECT * FROM compounddef WHERE rowid = :rowid" + ")" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt derivedcompoundref_insert={"INSERT INTO derivedcompoundref " - "( refid, prot, virt, base, derived ) " - "VALUES " - "(:refid,:prot,:virt,:base,:derived )" - ,NULL +SqlStmt compoundref_insert={ + "INSERT INTO compoundref " + "( base_rowid, derived_rowid, prot, virt ) " + "VALUES " + "(:base_rowid,:derived_rowid,:prot,:virt )" + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt params_select = { "SELECT rowid FROM params WHERE " +SqlStmt param_select = { + "SELECT rowid FROM param WHERE " "(attributes IS NULL OR attributes=:attributes) AND " "(type IS NULL OR type=:type) AND " "(declname IS NULL OR declname=:declname) AND " @@ -418,27 +805,22 @@ SqlStmt params_select = { "SELECT rowid FROM params WHERE " "(array IS NULL OR array=:array) AND " "(defval IS NULL OR defval=:defval) AND " "(briefdescription IS NULL OR briefdescription=:briefdescription)" - ,NULL + ,NULL }; -SqlStmt params_insert = { "INSERT INTO params " - "( attributes, type, declname, defname, array, defval, briefdescription ) " - "VALUES " +SqlStmt param_insert = { + "INSERT INTO param " + "( attributes, type, declname, defname, array, defval, briefdescription ) " + "VALUES " "(:attributes,:type,:declname,:defname,:array,:defval,:briefdescription)" - ,NULL -}; -////////////////////////////////////////////////////// -SqlStmt memberdef_params_insert={ "INSERT INTO memberdef_params " - "( id_memberdef, id_param)" - "VALUES " - "(:id_memberdef,:id_param)" - ,NULL + ,NULL }; ////////////////////////////////////////////////////// -SqlStmt innernamespace_insert={"INSERT INTO innernamespaces " - "( refid, name)" - "VALUES " - "(:refid,:name)", - NULL +SqlStmt memberdef_param_insert={ + "INSERT INTO memberdef_param " + "( memberdef_id, param_id)" + "VALUES " + "(:memberdef_id,:param_id)" + ,NULL }; @@ -491,7 +873,7 @@ static bool bindIntParameter(SqlStmt &s,const char *name,int value) { int idx = sqlite3_bind_parameter_index(s.stmt, name); if (idx==0) { - msg("sqlite3_bind_parameter_index(%s)[%s] failed: %s\n", name, s.query, sqlite3_errmsg(s.db)); + msg("sqlite3_bind_parameter_index(%s)[%s] failed to find column: %s\n", name, s.query, sqlite3_errmsg(s.db)); return false; } int rv = sqlite3_bind_int(s.stmt, idx, value); @@ -508,7 +890,7 @@ static int step(SqlStmt &s,bool getRowId=FALSE, bool select=FALSE) int rc = sqlite3_step(s.stmt); if (rc!=SQLITE_DONE && rc!=SQLITE_ROW) { - msg("sqlite3_step: %s\n", sqlite3_errmsg(s.db)); + DBG_CTX(("sqlite3_step: %s (rc: %d)\n", sqlite3_errmsg(s.db), rc)); sqlite3_reset(s.stmt); sqlite3_clear_bindings(s.stmt); return -1; @@ -520,76 +902,122 @@ static int step(SqlStmt &s,bool getRowId=FALSE, bool select=FALSE) return rowid; } -static int insertFile(const char* name) +static int insertPath(QCString name, bool local=TRUE, bool found=TRUE, int type=1) { int rowid=-1; if (name==0) return rowid; - bindTextParameter(files_select,":name",name); - rowid=step(files_select,TRUE,TRUE); + name = stripFromPath(name); + + bindTextParameter(path_select,":name",name.data(),FALSE); + rowid=step(path_select,TRUE,TRUE); if (rowid==0) { - bindTextParameter(files_insert,":name",name); - rowid=step(files_insert,TRUE); + bindTextParameter(path_insert,":name",name.data(),FALSE); + bindIntParameter(path_insert,":type",type); + bindIntParameter(path_insert,":local",local?1:0); + bindIntParameter(path_insert,":found",found?1:0); + rowid=step(path_insert,TRUE); } return rowid; } -static int insertRefid(const char *refid) +static void recordMetadata() { - int rowid=-1; - if (refid==0) return rowid; + bindTextParameter(meta_insert,":doxygen_version",versionString); + bindTextParameter(meta_insert,":schema_version","0.2.0"); //TODO: this should be a constant somewhere; not sure where + bindTextParameter(meta_insert,":generated_at",dateToString(TRUE), FALSE); + bindTextParameter(meta_insert,":generated_on",dateToString(FALSE), FALSE); + bindTextParameter(meta_insert,":project_name",Config_getString(PROJECT_NAME)); + bindTextParameter(meta_insert,":project_number",Config_getString(PROJECT_NUMBER)); + bindTextParameter(meta_insert,":project_brief",Config_getString(PROJECT_BRIEF)); + step(meta_insert); +} - bindTextParameter(refids_select,":refid",refid); - rowid=step(refids_select,TRUE,TRUE); - if (rowid==0) +struct Refid { + int rowid; + const char *refid; + bool created; +}; + +struct Refid insertRefid(const char *refid) +{ + struct Refid ret; + ret.rowid=-1; + ret.refid=refid; + ret.created = FALSE; + if (refid==0) return ret; + + bindTextParameter(refid_select,":refid",refid); + ret.rowid=step(refid_select,TRUE,TRUE); + if (ret.rowid==0) { - bindTextParameter(refids_insert,":refid",refid); - rowid=step(refids_insert,TRUE); + bindTextParameter(refid_insert,":refid",refid); + ret.rowid=step(refid_insert,TRUE); + ret.created = TRUE; } - return rowid; + + return ret; +} + +static bool memberdefExists(struct Refid refid) +{ + bindIntParameter(memberdef_exists,":rowid",refid.rowid); + int test = step(memberdef_exists,TRUE,TRUE); + return test ? true : false; } +static bool memberdefIncomplete(struct Refid refid, const MemberDef* md) +{ + bindIntParameter(memberdef_incomplete,":rowid",refid.rowid); + bindIntParameter(memberdef_incomplete,":new_inline",md->isInline()); + int test = step(memberdef_incomplete,TRUE,TRUE); + return test ? true : false; +} -static bool insertMemberReference(int refid_src, int refid_dst, - int id_file, int line, int column) +static bool compounddefExists(struct Refid refid) { - if (id_file==-1||refid_src==-1||refid_dst==-1) + bindIntParameter(compounddef_exists,":rowid",refid.rowid); + int test = step(compounddef_exists,TRUE,TRUE); + return test ? true : false; +} + +static bool insertMemberReference(struct Refid src_refid, struct Refid dst_refid, const char *context) +{ + if (src_refid.rowid==-1||dst_refid.rowid==-1) return false; if ( - !bindIntParameter(xrefs_insert,":refid_src",refid_src) || - !bindIntParameter(xrefs_insert,":refid_dst",refid_dst) || - !bindIntParameter(xrefs_insert,":id_file",id_file) || - !bindIntParameter(xrefs_insert,":line",line) || - !bindIntParameter(xrefs_insert,":column",column) + !bindIntParameter(xrefs_insert,":src_rowid",src_refid.rowid) || + !bindIntParameter(xrefs_insert,":dst_rowid",dst_refid.rowid) ) { return false; } + else + { + bindTextParameter(xrefs_insert,":context",context); + } step(xrefs_insert); return true; } -static void insertMemberReference(const MemberDef *src, const MemberDef *dst) +static void insertMemberReference(const MemberDef *src, const MemberDef *dst, const char *context) { - QCString qrefid_dst = dst->getOutputFileBase() + "_1" + dst->anchor(); - QCString qrefid_src = src->getOutputFileBase() + "_1" + src->anchor(); - if (dst->getStartBodyLine()!=-1 && dst->getBodyDef()) - { - int refid_src = insertRefid(qrefid_src.data()); - int refid_dst = insertRefid(qrefid_dst.data()); - int id_file = insertFile("no-file"); // TODO: replace no-file with proper file - insertMemberReference(refid_src,refid_dst,id_file,dst->getStartBodyLine(),-1); - } + QCString qdst_refid = dst->getOutputFileBase() + "_1" + dst->anchor(); + QCString qsrc_refid = src->getOutputFileBase() + "_1" + src->anchor(); + + struct Refid src_refid = insertRefid(qsrc_refid); + struct Refid dst_refid = insertRefid(qdst_refid); + insertMemberReference(src_refid,dst_refid,context); } -static void insertMemberFunctionParams(int id_memberdef, const MemberDef *md, const Definition *def) +static void insertMemberFunctionParams(int memberdef_id, const MemberDef *md, const Definition *def) { ArgumentList *declAl = md->declArgumentList(); ArgumentList *defAl = md->argumentList(); - if (declAl!=0 && declAl->count()>0) + if (declAl!=0 && defAl!=0 && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); @@ -600,8 +1028,8 @@ static void insertMemberFunctionParams(int id_memberdef, const MemberDef *md, co if (!a->attrib.isEmpty()) { - bindTextParameter(params_select,":attributes",a->attrib.data()); - bindTextParameter(params_insert,":attributes",a->attrib.data()); + bindTextParameter(param_select,":attributes",a->attrib); + bindTextParameter(param_insert,":attributes",a->attrib); } if (!a->type.isEmpty()) { @@ -612,57 +1040,56 @@ static void insertMemberFunctionParams(int id_memberdef, const MemberDef *md, co QCString *s; while ((s=li.current())) { - QCString qrefid_src = md->getOutputFileBase() + "_1" + md->anchor(); - int refid_src = insertRefid(qrefid_src.data()); - int refid_dst = insertRefid(s->data()); - int id_file = insertFile(stripFromPath(def->getDefFileName())); - insertMemberReference(refid_src,refid_dst,id_file,md->getDefLine(),-1); + QCString qsrc_refid = md->getOutputFileBase() + "_1" + md->anchor(); + struct Refid src_refid = insertRefid(qsrc_refid); + struct Refid dst_refid = insertRefid(s->data()); + insertMemberReference(src_refid,dst_refid, "argument"); ++li; } - bindTextParameter(params_select,":type",a->type.data()); - bindTextParameter(params_insert,":type",a->type.data()); + bindTextParameter(param_select,":type",a->type); + bindTextParameter(param_insert,":type",a->type); } if (!a->name.isEmpty()) { - bindTextParameter(params_select,":declname",a->name.data()); - bindTextParameter(params_insert,":declname",a->name.data()); + bindTextParameter(param_select,":declname",a->name); + bindTextParameter(param_insert,":declname",a->name); } if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name) { - bindTextParameter(params_select,":defname",defArg->name.data()); - bindTextParameter(params_insert,":defname",defArg->name.data()); + bindTextParameter(param_select,":defname",defArg->name); + bindTextParameter(param_insert,":defname",defArg->name); } if (!a->array.isEmpty()) { - bindTextParameter(params_select,":array",a->array.data()); - bindTextParameter(params_insert,":array",a->array.data()); + bindTextParameter(param_select,":array",a->array); + bindTextParameter(param_insert,":array",a->array); } if (!a->defval.isEmpty()) { StringList l; linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,a->defval); - bindTextParameter(params_select,":defval",a->defval.data()); - bindTextParameter(params_insert,":defval",a->defval.data()); + bindTextParameter(param_select,":defval",a->defval); + bindTextParameter(param_insert,":defval",a->defval); } if (defArg) ++defAli; - int id_param=step(params_select,TRUE,TRUE); - if (id_param==0) { - id_param=step(params_insert,TRUE); + int param_id=step(param_select,TRUE,TRUE); + if (param_id==0) { + param_id=step(param_insert,TRUE); } - if (id_param==-1) { - msg("error INSERT params failed\n"); + if (param_id==-1) { + DBG_CTX(("error INSERT params failed\n")); continue; } - bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef); - bindIntParameter(memberdef_params_insert,":id_param",id_param); - step(memberdef_params_insert); + bindIntParameter(memberdef_param_insert,":memberdef_id",memberdef_id); + bindIntParameter(memberdef_param_insert,":param_id",param_id); + step(memberdef_param_insert); } } } -static void insertMemberDefineParams(int id_memberdef,const MemberDef *md, const Definition *def) +static void insertMemberDefineParams(int memberdef_id,const MemberDef *md, const Definition *def) { if (md->argumentList()->count()==0) // special case for "foo()" to // disguish it from "foo". @@ -675,20 +1102,34 @@ static void insertMemberDefineParams(int id_memberdef,const MemberDef *md, const Argument *a; for (ali.toFirst();(a=ali.current());++ali) { - bindTextParameter(params_insert,":defname",a->type.data()); - int id_param=step(params_insert,TRUE); - if (id_param==-1) { - msg("error INSERT param(%s) failed\n", a->type.data()); + bindTextParameter(param_insert,":defname",a->type); + int param_id=step(param_insert,TRUE); + if (param_id==-1) { continue; } - bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef); - bindIntParameter(memberdef_params_insert,":id_param",id_param); - step(memberdef_params_insert); + bindIntParameter(memberdef_param_insert,":memberdef_id",memberdef_id); + bindIntParameter(memberdef_param_insert,":param_id",param_id); + step(memberdef_param_insert); } } } +static void associateMember(const MemberDef *md, struct Refid member_refid, struct Refid scope_refid) +{ + // TODO: skip EnumValue only to guard against recording refids and member records + // for enumvalues until we can support documenting them as entities. + if (md->memberType()==MemberType_EnumValue) return; + if (md->name().at(0)!='@') // skip anonymous members + { + bindIntParameter(member_insert, ":scope_rowid", scope_refid.rowid); + bindIntParameter(member_insert, ":memberdef_rowid", member_refid.rowid); + + bindIntParameter(member_insert, ":prot", md->protection()); + bindIntParameter(member_insert, ":virt", md->virtualness()); + step(member_insert); + } +} static void stripQualifiers(QCString &typeStr) { @@ -720,22 +1161,28 @@ static int prepareStatement(sqlite3 *db, SqlStmt &s) static int prepareStatements(sqlite3 *db) { if ( + -1==prepareStatement(db, meta_insert) || + -1==prepareStatement(db, memberdef_exists) || + -1==prepareStatement(db, memberdef_incomplete) || -1==prepareStatement(db, memberdef_insert) || - -1==prepareStatement(db, files_insert) || - -1==prepareStatement(db, files_select) || - -1==prepareStatement(db, refids_insert) || - -1==prepareStatement(db, refids_select) || + -1==prepareStatement(db, memberdef_update_def) || + -1==prepareStatement(db, memberdef_update_decl) || + -1==prepareStatement(db, member_insert) || + -1==prepareStatement(db, path_insert) || + -1==prepareStatement(db, path_select) || + -1==prepareStatement(db, refid_insert) || + -1==prepareStatement(db, refid_select) || -1==prepareStatement(db, incl_insert)|| -1==prepareStatement(db, incl_select)|| - -1==prepareStatement(db, params_insert) || - -1==prepareStatement(db, params_select) || + -1==prepareStatement(db, param_insert) || + -1==prepareStatement(db, param_select) || -1==prepareStatement(db, xrefs_insert) || - -1==prepareStatement(db, innerclass_insert) || + -1==prepareStatement(db, reimplements_insert) || + -1==prepareStatement(db, contains_insert) || + -1==prepareStatement(db, compounddef_exists) || -1==prepareStatement(db, compounddef_insert) || - -1==prepareStatement(db, basecompoundref_insert) || - -1==prepareStatement(db, derivedcompoundref_insert) || - -1==prepareStatement(db, memberdef_params_insert)|| - -1==prepareStatement(db, innernamespace_insert) + -1==prepareStatement(db, compoundref_insert) || + -1==prepareStatement(db, memberdef_param_insert) ) { return -1; @@ -763,15 +1210,35 @@ static void pragmaTuning(sqlite3 *db) sqlite3_exec(db, "PRAGMA temp_store = MEMORY;", NULL, NULL, &sErrMsg); } -static int initializeSchema(sqlite3* db) +static int initializeTables(sqlite3* db) +{ + int rc; + sqlite3_stmt *stmt = 0; + + msg("Initializing DB schema (tables)...\n"); + for (unsigned int k = 0; k < sizeof(table_schema) / sizeof(table_schema[0]); k++) + { + const char *q = table_schema[k][1]; + char *errmsg; + rc = sqlite3_exec(db, q, NULL, NULL, &errmsg); + if (rc != SQLITE_OK) + { + msg("failed to execute query: %s\n\t%s\n", q, errmsg); + return -1; + } + } + return 0; +} + +static int initializeViews(sqlite3* db) { int rc; sqlite3_stmt *stmt = 0; - msg("Initializing DB schema...\n"); - for (unsigned int k = 0; k < sizeof(schema_queries) / sizeof(schema_queries[0]); k++) + msg("Initializing DB schema (views)...\n"); + for (unsigned int k = 0; k < sizeof(view_schema) / sizeof(view_schema[0]); k++) { - const char *q = schema_queries[k][1]; + const char *q = view_schema[k][1]; char *errmsg; rc = sqlite3_exec(db, q, NULL, NULL, &errmsg); if (rc != SQLITE_OK) @@ -784,40 +1251,122 @@ static int initializeSchema(sqlite3* db) } //////////////////////////////////////////// -static void writeInnerClasses(const ClassSDict *cl) +/* TODO: +I collapsed all innerX tables into 'contains', which raises the prospect that +all of these very similar writeInnerX funcs could be refactored into a one, +or a small set of common parts. + +I think the hurdles are: +- picking a first argument that every call location can pass +- which yields a consistent iterator +- accommodates PageDef's slightly different rules for generating the + inner_refid (unless I'm missing a method that would uniformly return + the correct refid for all types). +*/ +static void writeInnerClasses(const ClassSDict *cl, struct Refid outer_refid) { if (!cl) return; ClassSDict::Iterator cli(*cl); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes { - int refid = insertRefid(cd->getOutputFileBase()); - bindIntParameter(innerclass_insert,":refid", refid); - bindIntParameter(innerclass_insert,":prot",cd->protection()); - bindTextParameter(innerclass_insert,":name",cd->name()); - step(innerclass_insert); + struct Refid inner_refid = insertRefid(cd->getOutputFileBase()); + + bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid); + bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid); + step(contains_insert); } } } +static void writeInnerPages(const PageSDict *pl, struct Refid outer_refid) +{ + if (!pl) return; + + PageSDict::Iterator pli(*pl); + const PageDef *pd; + for (pli.toFirst();(pd=pli.current());++pli) + { + struct Refid inner_refid = insertRefid( + pd->getGroupDef() ? pd->getOutputFileBase()+"_"+pd->name() : pd->getOutputFileBase() + ); + + bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid); + bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid); + step(contains_insert); -static void writeInnerNamespaces(const NamespaceSDict *nl) + } +} + +static void writeInnerGroups(const GroupList *gl, struct Refid outer_refid) +{ + if (gl) + { + GroupListIterator gli(*gl); + const GroupDef *sgd; + for (gli.toFirst();(sgd=gli.current());++gli) + { + struct Refid inner_refid = insertRefid(sgd->getOutputFileBase()); + + bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid); + bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid); + step(contains_insert); + } + } +} + +static void writeInnerFiles(const FileList *fl, struct Refid outer_refid) +{ + if (fl) + { + QListIterator<FileDef> fli(*fl); + const FileDef *fd; + for (fli.toFirst();(fd=fli.current());++fli) + { + struct Refid inner_refid = insertRefid(fd->getOutputFileBase()); + + bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid); + bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid); + step(contains_insert); + } + } +} + +static void writeInnerDirs(const DirList *dl, struct Refid outer_refid) +{ + if (dl) + { + QListIterator<DirDef> subdirs(*dl); + const DirDef *subdir; + for (subdirs.toFirst();(subdir=subdirs.current());++subdirs) + { + struct Refid inner_refid = insertRefid(subdir->getOutputFileBase()); + + bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid); + bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid); + step(contains_insert); + } + } +} + +static void writeInnerNamespaces(const NamespaceSDict *nl, struct Refid outer_refid) { if (nl) { NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { - if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes + if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymous scopes { - int refid = insertRefid(nd->getOutputFileBase()); - bindIntParameter(innernamespace_insert,":refid",refid); - bindTextParameter(innernamespace_insert,":name",nd->name(),FALSE); - step(innernamespace_insert); + struct Refid inner_refid = insertRefid(nd->getOutputFileBase()); + + bindIntParameter(contains_insert,":inner_rowid",inner_refid.rowid); + bindIntParameter(contains_insert,":outer_rowid",outer_refid.rowid); + step(contains_insert); } } } @@ -837,24 +1386,24 @@ static void writeTemplateArgumentList(const ArgumentList * al, if (!a->type.isEmpty()) { #warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type); - bindTextParameter(params_select,":type",a->type); - bindTextParameter(params_insert,":type",a->type); + bindTextParameter(param_select,":type",a->type); + bindTextParameter(param_insert,":type",a->type); } if (!a->name.isEmpty()) { - bindTextParameter(params_select,":declname",a->name); - bindTextParameter(params_insert,":declname",a->name); - bindTextParameter(params_select,":defname",a->name); - bindTextParameter(params_insert,":defname",a->name); + bindTextParameter(param_select,":declname",a->name); + bindTextParameter(param_insert,":declname",a->name); + bindTextParameter(param_select,":defname",a->name); + bindTextParameter(param_insert,":defname",a->name); } if (!a->defval.isEmpty()) { #warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval); - bindTextParameter(params_select,":defval",a->defval); - bindTextParameter(params_insert,":defval",a->defval); + bindTextParameter(param_select,":defval",a->defval); + bindTextParameter(param_insert,":defval",a->defval); } - if (!step(params_select,TRUE,TRUE)) - step(params_insert); + if (!step(param_select,TRUE,TRUE)) + step(param_insert); } } } @@ -871,15 +1420,132 @@ static void writeTemplateList(const ClassDef *cd) { writeTemplateArgumentList(cd->templateArguments(),cd,0); } + +QCString getSQLDocBlock(const Definition *scope, + const Definition *def, + const QCString &doc, + const QCString &fileName, + int lineNr) +{ + QGString s; + if (doc.isEmpty()) return s.data(); + FTextStream t(&s); + DocNode *root = validatingParseDoc( + fileName, + lineNr, + const_cast<Definition*>(scope), + const_cast<MemberDef*>(reinterpret_cast<const MemberDef*>(def)), + doc, + FALSE, + FALSE + ); + XMLCodeGenerator codeGen(t); + // create a parse tree visitor for XML + XmlDocVisitor *visitor = new XmlDocVisitor(t,codeGen); + root->accept(visitor); + delete visitor; + delete root; + QCString result = convertCharEntitiesToUTF8(s.data()); + return result.data(); +} + +static void getSQLDesc(SqlStmt &s,const char *col,const char *value,const Definition *def) +{ + bindTextParameter( + s, + col, + getSQLDocBlock( + def->getOuterScope(), + def, + value, + def->docFile(), + def->docLine() + ), + FALSE + ); +} //////////////////////////////////////////// +/* (updated Sep 01 2018) +DoxMemberKind and DoxCompoundKind (compound.xsd) gave me some +faulty assumptions about "kind" strings, so I compiled a reference + +The XML schema claims: + DoxMemberKind: (14) + dcop define enum event friend function interface property prototype + service signal slot typedef variable + + DoxCompoundKind: (17) + category class dir example exception file group interface module + namespace page protocol service singleton struct type union + +Member kind comes from MemberDef::memberTypeName() + types.h defines 14 MemberType_*s + _DCOP _Define _Enumeration _EnumValue _Event _Friend _Function _Interface + _Property _Service _Signal _Slot _Typedef _Variable + - xml doesn't include enumvalue here + (but renders enumvalue as) a sub-node of memberdef/templateparamlist + - xml includes 'prototype' that is unlisted here + vestigial? commented out in docsets.cpp and perlmodgen.cpp + MemberDef::memberTypeName() can return 15 strings: + (sorted by MemberType to match above; quoted because whitespace...) + "dcop" "macro definition" "enumeration" "enumvalue" "event" "friend" + "function" "interface" "property" "service" "signal" "slot" "typedef" + "variable" + + Above describes potential values for memberdef.kind + +Compound kind is more complex. *Def::compoundTypeString() + ClassDef kind comes from ::compoundTypeString() + classdef.h defines 9 compound types + Category Class Exception Interface Protocol Service Singleton Struct Union + But ClassDef::compoundTypeString() "could" return 13 strings + - default "unknown" shouldn't actually return + - other 12 can vary by source language; see method for specifics + category class enum exception interface module protocol service + singleton struct type union + + DirDef, FileDef, GroupDef have no method to return a string + tagfile/outputs hard-code kind to 'dir' 'file' or 'group' + + NamespaceDef kind comes from ::compoundTypeString() + NamespaceDef::compoundTypeString() "could" return 6 strings + - default empty ("") string + - other 5 differ by source language + constants library module namespace package + + PageDef also has no method to return a string + - some locations hard-code the kind to 'page' + - others conditionally output 'page' or 'example' + + All together, that's 23 potential strings (21 excl "" and unknown) + "" category class constants dir enum example exception file group + interface library module namespace package page protocol service singleton + struct type union unknown + + Above describes potential values for compounddef.kind + +For reference, there are 35 potential values of def.kind (33 excl "" and unknown): + "" "category" "class" "constants" "dcop" "dir" "enum" "enumeration" + "enumvalue" "event" "example" "exception" "file" "friend" "function" "group" + "interface" "library" "macro definition" "module" "namespace" "package" + "page" "property" "protocol" "service" "signal" "singleton" "slot" "struct" + "type" "typedef" "union" "unknown" "variable" + +This is relevant because the 'def' view generalizes memberdef and compounddef, +and two member+compound kind strings (interface and service) overlap. + +I have no grasp of whether a real user docset would include one or more +member and compound using the interface or service kind. +*/ + ////////////////////////////////////////////////////////////////////////////// -static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) +static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_refid, const Definition *def) { // + declaration/definition arg lists // + reimplements // + reimplementedBy - // + exceptions + // - exceptions // + const/volatile specifiers // - examples // + source definition @@ -893,18 +1559,102 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) // enum values are written as part of the enum if (md->memberType()==MemberType_EnumValue) return; if (md->isHidden()) return; - //if (md->name().at(0)=='@') return; // anonymous member - // group members are only visible in their group - //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return; QCString memType; // memberdef QCString qrefid = md->getOutputFileBase() + "_1" + md->anchor(); - int refid = insertRefid(qrefid.data()); + struct Refid refid = insertRefid(qrefid); + + associateMember(md, refid, scope_refid); + + // compacting duplicate defs + if(!refid.created && memberdefExists(refid) && memberdefIncomplete(refid, md)) + { + /* + For performance, ideal to skip a member we've already added. + Unfortunately, we can have two memberdefs with the same refid documenting + the declaration and definition. memberdefIncomplete() uses the 'inline' + value to figure this out. Once we get to this point, we should *only* be + seeing the *other* type of def/decl, so we'll set inline to a new value (2), + indicating that this entry covers both inline types. + */ + struct SqlStmt memberdef_update; + + // definitions have bodyfile/start/end + if (md->getStartBodyLine()!=-1) + { + memberdef_update = memberdef_update_def; + int bodyfile_id = insertPath(md->getBodyDef()->absFilePath(),!md->getBodyDef()->isReference()); + if (bodyfile_id == -1) + { + sqlite3_clear_bindings(memberdef_update.stmt); + } + else + { + bindIntParameter(memberdef_update,":bodyfile_id",bodyfile_id); + bindIntParameter(memberdef_update,":bodystart",md->getStartBodyLine()); + bindIntParameter(memberdef_update,":bodyend",md->getEndBodyLine()); + } + } + // declarations don't + else + { + memberdef_update = memberdef_update_decl; + if (md->getDefLine() != -1) + { + int file_id = insertPath(md->getDefFileName(),!md->isReference()); + if (file_id!=-1) + { + bindIntParameter(memberdef_update,":file_id",file_id); + bindIntParameter(memberdef_update,":line",md->getDefLine()); + bindIntParameter(memberdef_update,":column",md->getDefColumn()); + } + } + } - bindIntParameter(memberdef_insert,":refid", refid); - bindIntParameter(memberdef_insert,":kind",md->memberType()); + bindIntParameter(memberdef_update, ":rowid", refid.rowid); + // value 2 indicates we've seen "both" inline types. + bindIntParameter(memberdef_update,":inline", 2); + + /* in case both are used, append/prepend descriptions */ + getSQLDesc(memberdef_update,":briefdescription",md->briefDescription(),md); + getSQLDesc(memberdef_update,":detaileddescription",md->documentation(),md); + getSQLDesc(memberdef_update,":inbodydescription",md->inbodyDocumentation(),md); + + step(memberdef_update,TRUE); + + // don't think we need to repeat params; should have from first encounter + + // + source references + // The cross-references in initializers only work when both the src and dst + // are defined. + MemberSDict *mdict = md->getReferencesMembers(); + if (mdict!=0) + { + MemberSDict::IteratorDict mdi(*mdict); + const MemberDef *rmd; + for (mdi.toFirst();(rmd=mdi.current());++mdi) + { + insertMemberReference(md,rmd, "inline"); + } + } + // + source referenced by + mdict = md->getReferencedByMembers(); + if (mdict!=0) + { + MemberSDict::IteratorDict mdi(*mdict); + const MemberDef *rmd; + for (mdi.toFirst();(rmd=mdi.current());++mdi) + { + insertMemberReference(rmd,md, "inline"); + } + } + return; + } + + bindIntParameter(memberdef_insert,":rowid", refid.rowid); + bindTextParameter(memberdef_insert,":kind",md->memberTypeName(),FALSE); bindIntParameter(memberdef_insert,":prot",md->protection()); bindIntParameter(memberdef_insert,":static",md->isStatic()); @@ -973,6 +1723,7 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) bindIntParameter(memberdef_insert,":settable",md->isSettable()); bindIntParameter(memberdef_insert,":privatesettable",md->isPrivateSettable()); bindIntParameter(memberdef_insert,":protectedsettable",md->isProtectedSettable()); + if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak()) { @@ -995,6 +1746,18 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) bindIntParameter(memberdef_insert,":raisable",md->isRaisable()); } + const MemberDef *rmd = md->reimplements(); + if(rmd) + { + QCString qreimplemented_refid = rmd->getOutputFileBase() + "_1" + rmd->anchor(); + + struct Refid reimplemented_refid = insertRefid(qreimplemented_refid); + + bindIntParameter(reimplements_insert,":memberdef_rowid", refid.rowid); + bindIntParameter(reimplements_insert,":reimplemented_rowid", reimplemented_refid.rowid); + step(reimplements_insert,TRUE); + } + // + declaration/definition arg lists if (md->memberType()!=MemberType_Define && md->memberType()!=MemberType_Enumeration @@ -1008,9 +1771,9 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) stripQualifiers(typeStr); StringList l; linkifyText(TextGeneratorSqlite3Impl(l), def, md->getBodyDef(),md,typeStr); - if (typeStr.data()) + if (typeStr) { - bindTextParameter(memberdef_insert,":type",typeStr.data(),FALSE); + bindTextParameter(memberdef_insert,":type",typeStr,FALSE); } if (md->definition()) @@ -1029,7 +1792,7 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) // Extract references from initializer if (md->hasMultiLineInitializer() || md->hasOneLineInitializer()) { - bindTextParameter(memberdef_insert,":initializer",md->initializer().data()); + bindTextParameter(memberdef_insert,":initializer",md->initializer()); StringList l; linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,md->initializer()); @@ -1044,11 +1807,10 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) s->data(), md->getBodyDef()->getDefFileName().data(), md->getStartBodyLine())); - QCString qrefid_src = md->getOutputFileBase() + "_1" + md->anchor(); - int refid_src = insertRefid(qrefid_src.data()); - int refid_dst = insertRefid(s->data()); - int id_file = insertFile(stripFromPath(md->getBodyDef()->getDefFileName())); - insertMemberReference(refid_src,refid_dst,id_file,md->getStartBodyLine(),-1); + QCString qsrc_refid = md->getOutputFileBase() + "_1" + md->anchor(); + struct Refid src_refid = insertRefid(qsrc_refid); + struct Refid dst_refid = insertRefid(s->data()); + insertMemberReference(src_refid,dst_refid, "initializer"); } ++li; } @@ -1056,34 +1818,35 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) if ( md->getScopeString() ) { - bindTextParameter(memberdef_insert,":scope",md->getScopeString().data(),FALSE); + bindTextParameter(memberdef_insert,":scope",md->getScopeString(),FALSE); } // +Brief, detailed and inbody description - bindTextParameter(memberdef_insert,":briefdescription",md->briefDescription(),FALSE); - bindTextParameter(memberdef_insert,":detaileddescription",md->documentation(),FALSE); - bindTextParameter(memberdef_insert,":inbodydescription",md->inbodyDocumentation(),FALSE); + getSQLDesc(memberdef_insert,":briefdescription",md->briefDescription(),md); + getSQLDesc(memberdef_insert,":detaileddescription",md->documentation(),md); + getSQLDesc(memberdef_insert,":inbodydescription",md->inbodyDocumentation(),md); // File location if (md->getDefLine() != -1) { - int id_file = insertFile(stripFromPath(md->getDefFileName())); - if (id_file!=-1) + int file_id = insertPath(md->getDefFileName(),!md->isReference()); + if (file_id!=-1) { - bindIntParameter(memberdef_insert,":id_file",id_file); + bindIntParameter(memberdef_insert,":file_id",file_id); bindIntParameter(memberdef_insert,":line",md->getDefLine()); bindIntParameter(memberdef_insert,":column",md->getDefColumn()); + // definitions also have bodyfile/start/end if (md->getStartBodyLine()!=-1) { - int id_bodyfile = insertFile(stripFromPath(md->getBodyDef()->absFilePath())); - if (id_bodyfile == -1) + int bodyfile_id = insertPath(md->getBodyDef()->absFilePath(),!md->getBodyDef()->isReference()); + if (bodyfile_id == -1) { sqlite3_clear_bindings(memberdef_insert.stmt); } else { - bindIntParameter(memberdef_insert,":id_bodyfile",id_bodyfile); + bindIntParameter(memberdef_insert,":bodyfile_id",bodyfile_id); bindIntParameter(memberdef_insert,":bodystart",md->getStartBodyLine()); bindIntParameter(memberdef_insert,":bodyend",md->getEndBodyLine()); } @@ -1091,16 +1854,16 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) } } - int id_memberdef=step(memberdef_insert,TRUE); + int memberdef_id=step(memberdef_insert,TRUE); if (isFunc) { - insertMemberFunctionParams(id_memberdef,md,def); + insertMemberFunctionParams(memberdef_id,md,def); } else if (md->memberType()==MemberType_Define && md->argsString()) { - insertMemberDefineParams(id_memberdef,md,def); + insertMemberDefineParams(memberdef_id,md,def); } // + source references @@ -1110,10 +1873,10 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) if (mdict!=0) { MemberSDict::IteratorDict mdi(*mdict); - MemberDef *rmd; + const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { - insertMemberReference(md,rmd);//,mdi.currentKey()); + insertMemberReference(md,rmd, "inline"); } } // + source referenced by @@ -1121,62 +1884,79 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def) if (mdict!=0) { MemberSDict::IteratorDict mdi(*mdict); - MemberDef *rmd; + const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { - insertMemberReference(rmd,md);//,mdi.currentKey()); + insertMemberReference(rmd,md, "inline"); } } } static void generateSqlite3Section( const Definition *d, const MemberList *ml, + struct Refid scope_refid, const char * /*kind*/, const char * /*header*/=0, const char * /*documentation*/=0) { if (ml==0) return; MemberListIterator mli(*ml); - MemberDef *md; - int count=0; + const MemberDef *md; + for (mli.toFirst();(md=mli.current());++mli) { + // TODO: necessary? just tracking what xmlgen does; xmlgen says: // namespace members are also inserted in the file scope, but // to prevent this duplication in the XML output, we filter those here. if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0) { - count++; + generateSqlite3ForMember(md, scope_refid, d); } } - if (count==0) return; // empty list - for (mli.toFirst();(md=mli.current());++mli) +} + +static void associateAllClassMembers(const ClassDef *cd, struct Refid scope_refid) +{ + if (cd->memberNameInfoSDict()) { - // namespace members are also inserted in the file scope, but - // to prevent this duplication in the XML output, we filter those here. - //if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0) + MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict()); + MemberNameInfo *mni; + for (mnii.toFirst();(mni=mnii.current());++mnii) { - generateSqlite3ForMember(md,d); + MemberNameInfoIterator mii(*mni); + MemberInfo *mi; + for (mii.toFirst();(mi=mii.current());++mii) + { + MemberDef *md = mi->memberDef; + QCString qrefid = md->getOutputFileBase() + "_1" + md->anchor(); + associateMember(md, insertRefid(qrefid), scope_refid); + } } } } - +// many kinds: category class enum exception interface +// module protocol service singleton struct type union +// enum is Java only (and is distinct from enum memberdefs) static void generateSqlite3ForClass(const ClassDef *cd) { + // NOTE: Skeptical about XML's version of these + // 'x' marks missing items XML claims to include + + // + brief description + // + detailed description + // + template argument list(s) + // + include file + // + member groups + // x inheritance DOT diagram // + list of direct super classes // + list of direct sub classes - // + include file // + list of inner classes - // - template argument list(s) - // + member groups + // x collaboration DOT diagram // + list of all members - // - brief description - // - detailed description - // - inheritance DOT diagram - // - collaboration DOT diagram - // - user defined member sections - // - standard member sections - // - detailed member documentation + // x user defined member sections + // x standard member sections + // x detailed member documentation // - examples using the class if (cd->isReference()) return; // skip external references. @@ -1184,43 +1964,86 @@ static void generateSqlite3ForClass(const ClassDef *cd) if (cd->name().find('@')!=-1) return; // skip anonymous compounds. if (cd->templateMaster()!=0) return; // skip generated template instances. - msg("Generating Sqlite3 output for class %s\n",cd->name().data()); + struct Refid refid = insertRefid(cd->getOutputFileBase()); + + // can omit a class that already has a refid + if(!refid.created && compounddefExists(refid)){return;} + + bindIntParameter(compounddef_insert,":rowid", refid.rowid); bindTextParameter(compounddef_insert,":name",cd->name()); + bindTextParameter(compounddef_insert,":title",cd->title(), FALSE); bindTextParameter(compounddef_insert,":kind",cd->compoundTypeString(),FALSE); bindIntParameter(compounddef_insert,":prot",cd->protection()); - int refid = insertRefid(cd->getOutputFileBase()); - bindIntParameter(compounddef_insert,":refid", refid); - int id_file = insertFile(stripFromPath(cd->getDefFileName())); - bindIntParameter(compounddef_insert,":id_file",id_file); + int file_id = insertPath(cd->getDefFileName()); + bindIntParameter(compounddef_insert,":file_id",file_id); bindIntParameter(compounddef_insert,":line",cd->getDefLine()); bindIntParameter(compounddef_insert,":column",cd->getDefColumn()); + // + include file + /* + TODO: I wonder if this can actually be cut (just here) + + We were adding this "include" to the "includes" table alongside + other includes (from a FileDef). However, FileDef and ClassDef are using + "includes" nodes in very a different way: + - With FileDef, it means the file includes another. + - With ClassDef, it means you should include this file to use this class. + + Because of this difference, I added a column to compounddef, header_id, and + linked it back to the appropriate file. We could just add a nullable text + column that would hold a string equivalent to what the HTML docs include, + but the logic for generating it is embedded in + ClassDef::writeIncludeFiles(OutputList &ol). + + That said, at least on the handful of test sets I have, header_id == file_id, + suggesting it could be cut and clients might be able to reconstruct it from + other values if there's a solid heuristic for *when a class will + have a header file*. + */ + IncludeInfo *ii=cd->includeInfo(); + if (ii) + { + QCString nm = ii->includeName; + if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName(); + if (!nm.isEmpty()) + { + int header_id=insertPath(ii->fileDef->absFilePath(),!ii->fileDef->isReference()); + DBG_CTX(("-----> ClassDef includeInfo for %s\n", nm.data())); + DBG_CTX((" local : %d\n", ii->local)); + DBG_CTX((" imported : %d\n", ii->imported)); + DBG_CTX((" indirect : %d\n", ii->indirect)); + DBG_CTX(("header: %s\n", ii->fileDef->absFilePath().data())); + DBG_CTX((" file_id : %d\n", file_id)); + DBG_CTX((" header_id: %d\n", header_id)); + + if(header_id!=-1) + { + bindIntParameter(compounddef_insert,":header_id",header_id); + } + } + } + + getSQLDesc(compounddef_insert,":briefdescription",cd->briefDescription(),cd); + getSQLDesc(compounddef_insert,":detaileddescription",cd->documentation(),cd); + step(compounddef_insert); // + list of direct super classes if (cd->baseClasses()) { BaseClassListIterator bcli(*cd->baseClasses()); - BaseClassDef *bcd; + const BaseClassDef *bcd; for (bcli.toFirst();(bcd=bcli.current());++bcli) { - int refid = insertRefid(bcd->classDef->getOutputFileBase()); - bindIntParameter(basecompoundref_insert,":refid", refid); - bindIntParameter(basecompoundref_insert,":prot",bcd->prot); - bindIntParameter(basecompoundref_insert,":virt",bcd->virt); - - if (!bcd->templSpecifiers.isEmpty()) - { - bindTextParameter(basecompoundref_insert,":base",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE); - } - else - { - bindTextParameter(basecompoundref_insert,":base",bcd->classDef->displayName(),FALSE); - } - bindTextParameter(basecompoundref_insert,":derived",cd->displayName(),FALSE); - step(basecompoundref_insert); + struct Refid base_refid = insertRefid(bcd->classDef->getOutputFileBase()); + struct Refid derived_refid = insertRefid(cd->getOutputFileBase()); + bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid); + bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid); + bindIntParameter(compoundref_insert,":prot",bcd->prot); + bindIntParameter(compoundref_insert,":virt",bcd->virt); + step(compoundref_insert); } } @@ -1228,54 +2051,23 @@ static void generateSqlite3ForClass(const ClassDef *cd) if (cd->subClasses()) { BaseClassListIterator bcli(*cd->subClasses()); - BaseClassDef *bcd; + const BaseClassDef *bcd; for (bcli.toFirst();(bcd=bcli.current());++bcli) { - bindTextParameter(derivedcompoundref_insert,":base",cd->displayName(),FALSE); - if (!bcd->templSpecifiers.isEmpty()) - { - bindTextParameter(derivedcompoundref_insert,":derived",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE); - } - else - { - bindTextParameter(derivedcompoundref_insert,":derived",bcd->classDef->displayName(),FALSE); - } - int refid = insertRefid(bcd->classDef->getOutputFileBase()); - bindIntParameter(derivedcompoundref_insert,":refid", refid); - bindIntParameter(derivedcompoundref_insert,":prot",bcd->prot); - bindIntParameter(derivedcompoundref_insert,":virt",bcd->virt); - step(derivedcompoundref_insert); + struct Refid derived_refid = insertRefid(bcd->classDef->getOutputFileBase()); + struct Refid base_refid = insertRefid(cd->getOutputFileBase()); + bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid); + bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid); + bindIntParameter(compoundref_insert,":prot",bcd->prot); + bindIntParameter(compoundref_insert,":virt",bcd->virt); + step(compoundref_insert); } } - // + include file - IncludeInfo *ii=cd->includeInfo(); - if (ii) - { - QCString nm = ii->includeName; - if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName(); - if (!nm.isEmpty()) - { - int id_dst=insertFile(nm); - if (id_dst!=-1) { - bindIntParameter(incl_select,":local",ii->local); - bindIntParameter(incl_select,":id_src",id_file); - bindIntParameter(incl_select,":id_dst",id_dst); - int count=step(incl_select,TRUE,TRUE); - if (count==0) - { - bindIntParameter(incl_insert,":local",ii->local); - bindIntParameter(incl_insert,":id_src",id_file); - bindIntParameter(incl_insert,":id_dst",id_dst); - step(incl_insert); - } - } - } - } // + list of inner classes - writeInnerClasses(cd->getClassSDict()); + writeInnerClasses(cd->getClassSDict(),refid); - // - template argument list(s) + // + template argument list(s) writeTemplateList(cd); // + member groups @@ -1285,41 +2077,62 @@ static void generateSqlite3ForClass(const ClassDef *cd) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - generateSqlite3Section(cd,mg->members(),"user-defined",mg->header(), + generateSqlite3Section(cd,mg->members(),refid,"user-defined",mg->header(), mg->documentation()); } } - // + list of all members + // this is just a list of *local* members QListIterator<MemberList> mli(cd->getMemberLists()); MemberList *ml; for (mli.toFirst();(ml=mli.current());++mli) { if ((ml->listType()&MemberListType_detailedLists)==0) { - generateSqlite3Section(cd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType())); + generateSqlite3Section(cd,ml,refid,"user-defined"); } } + + // + list of all members + associateAllClassMembers(cd, refid); } +// kinds: constants library module namespace package static void generateSqlite3ForNamespace(const NamespaceDef *nd) { // + contained class definitions // + contained namespace definitions // + member groups // + normal members - // - brief desc - // - detailed desc - // - location + // + brief desc + // + detailed desc + // + location (file_id, line, column) // - files containing (parts of) the namespace definition if (nd->isReference() || nd->isHidden()) return; // skip external references + struct Refid refid = insertRefid(nd->getOutputFileBase()); + if(!refid.created && compounddefExists(refid)){return;} + bindIntParameter(compounddef_insert,":rowid", refid.rowid); + + bindTextParameter(compounddef_insert,":name",nd->name()); + bindTextParameter(compounddef_insert,":title",nd->title(), FALSE); + bindTextParameter(compounddef_insert,":kind","namespace",FALSE); + + int file_id = insertPath(nd->getDefFileName()); + bindIntParameter(compounddef_insert,":file_id",file_id); + bindIntParameter(compounddef_insert,":line",nd->getDefLine()); + bindIntParameter(compounddef_insert,":column",nd->getDefColumn()); + + getSQLDesc(compounddef_insert,":briefdescription",nd->briefDescription(),nd); + getSQLDesc(compounddef_insert,":detaileddescription",nd->documentation(),nd); + + step(compounddef_insert); // + contained class definitions - writeInnerClasses(nd->getClassSDict()); + writeInnerClasses(nd->getClassSDict(),refid); // + contained namespace definitions - writeInnerNamespaces(nd->getNamespaceSDict()); + writeInnerNamespaces(nd->getNamespaceSDict(),refid); // + member groups if (nd->getMemberGroupSDict()) @@ -1328,7 +2141,7 @@ static void generateSqlite3ForNamespace(const NamespaceDef *nd) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - generateSqlite3Section(nd,mg->members(),"user-defined",mg->header(), + generateSqlite3Section(nd,mg->members(),refid,"user-defined",mg->header(), mg->documentation()); } } @@ -1340,29 +2153,48 @@ static void generateSqlite3ForNamespace(const NamespaceDef *nd) { if ((ml->listType()&MemberListType_declarationLists)!=0) { - generateSqlite3Section(nd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType())); + generateSqlite3Section(nd,ml,refid,"user-defined"); } } } +// kind: file static void generateSqlite3ForFile(const FileDef *fd) { // + includes files // + includedby files - // - include graph - // - included by graph + // x include graph + // x included by graph // + contained class definitions // + contained namespace definitions // + member groups // + normal members - // - brief desc - // - detailed desc - // - source code - // - location + // + brief desc + // + detailed desc + // x source code + // + location (file_id, line, column) // - number of lines if (fd->isReference()) return; // skip external references + struct Refid refid = insertRefid(fd->getOutputFileBase()); + if(!refid.created && compounddefExists(refid)){return;} + bindIntParameter(compounddef_insert,":rowid", refid.rowid); + + bindTextParameter(compounddef_insert,":name",fd->name(),FALSE); + bindTextParameter(compounddef_insert,":title",fd->title(),FALSE); + bindTextParameter(compounddef_insert,":kind","file",FALSE); + + int file_id = insertPath(fd->getDefFileName()); + bindIntParameter(compounddef_insert,":file_id",file_id); + bindIntParameter(compounddef_insert,":line",fd->getDefLine()); + bindIntParameter(compounddef_insert,":column",fd->getDefColumn()); + + getSQLDesc(compounddef_insert,":briefdescription",fd->briefDescription(),fd); + getSQLDesc(compounddef_insert,":detaileddescription",fd->documentation(),fd); + + step(compounddef_insert); + // + includes files IncludeInfo *ii; if (fd->includeFileList()) @@ -1370,15 +2202,48 @@ static void generateSqlite3ForFile(const FileDef *fd) QListIterator<IncludeInfo> ili(*fd->includeFileList()); for (ili.toFirst();(ii=ili.current());++ili) { - int id_src=insertFile(fd->absFilePath().data()); - int id_dst=insertFile(ii->includeName.data()); + int src_id=insertPath(fd->absFilePath(),!fd->isReference()); + int dst_id; + QCString dst_path; + + if(ii->fileDef) // found file + { + if(ii->fileDef->isReference()) + { + // strip tagfile from path + QCString tagfile = ii->fileDef->getReference(); + dst_path = ii->fileDef->absFilePath().copy(); + dst_path.stripPrefix(tagfile+":"); + } + else + { + dst_path = ii->fileDef->absFilePath(); + } + dst_id = insertPath(dst_path,ii->local); + } + else // can't find file + { + dst_id = insertPath(ii->includeName,ii->local,FALSE); + } + + DBG_CTX(("-----> FileDef includeInfo for %s\n", ii->includeName.data())); + DBG_CTX((" local: %d\n", ii->local)); + DBG_CTX((" imported: %d\n", ii->imported)); + DBG_CTX((" indirect: %d\n", ii->indirect)); + if(ii->fileDef) + { + DBG_CTX(("include: %s\n", ii->fileDef->absFilePath().data())); + } + DBG_CTX((" src_id : %d\n", src_id)); + DBG_CTX((" dst_id: %d\n", dst_id)); + bindIntParameter(incl_select,":local",ii->local); - bindIntParameter(incl_select,":id_src",id_src); - bindIntParameter(incl_select,":id_dst",id_dst); + bindIntParameter(incl_select,":src_id",src_id); + bindIntParameter(incl_select,":dst_id",dst_id); if (step(incl_select,TRUE,TRUE)==0) { bindIntParameter(incl_insert,":local",ii->local); - bindIntParameter(incl_insert,":id_src",id_src); - bindIntParameter(incl_insert,":id_dst",id_dst); + bindIntParameter(incl_insert,":src_id",src_id); + bindIntParameter(incl_insert,":dst_id",dst_id); step(incl_insert); } } @@ -1390,15 +2255,37 @@ static void generateSqlite3ForFile(const FileDef *fd) QListIterator<IncludeInfo> ili(*fd->includedByFileList()); for (ili.toFirst();(ii=ili.current());++ili) { - int id_src=insertFile(ii->includeName); - int id_dst=insertFile(fd->absFilePath()); + int dst_id=insertPath(fd->absFilePath(),!fd->isReference()); + int src_id; + QCString src_path; + + if(ii->fileDef) // found file + { + if(ii->fileDef->isReference()) + { + // strip tagfile from path + QCString tagfile = ii->fileDef->getReference(); + src_path = ii->fileDef->absFilePath().copy(); + src_path.stripPrefix(tagfile+":"); + } + else + { + src_path = ii->fileDef->absFilePath(); + } + src_id = insertPath(src_path,ii->local); + } + else // can't find file + { + src_id = insertPath(ii->includeName,ii->local,FALSE); + } + bindIntParameter(incl_select,":local",ii->local); - bindIntParameter(incl_select,":id_src",id_src); - bindIntParameter(incl_select,":id_dst",id_dst); + bindIntParameter(incl_select,":src_id",src_id); + bindIntParameter(incl_select,":dst_id",dst_id); if (step(incl_select,TRUE,TRUE)==0) { bindIntParameter(incl_insert,":local",ii->local); - bindIntParameter(incl_insert,":id_src",id_src); - bindIntParameter(incl_insert,":id_dst",id_dst); + bindIntParameter(incl_insert,":src_id",src_id); + bindIntParameter(incl_insert,":dst_id",dst_id); step(incl_insert); } } @@ -1407,13 +2294,13 @@ static void generateSqlite3ForFile(const FileDef *fd) // + contained class definitions if (fd->getClassSDict()) { - writeInnerClasses(fd->getClassSDict()); + writeInnerClasses(fd->getClassSDict(),refid); } // + contained namespace definitions if (fd->getNamespaceSDict()) { - writeInnerNamespaces(fd->getNamespaceSDict()); + writeInnerNamespaces(fd->getNamespaceSDict(),refid); } // + member groups @@ -1423,7 +2310,7 @@ static void generateSqlite3ForFile(const FileDef *fd) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - generateSqlite3Section(fd,mg->members(),"user-defined",mg->header(), + generateSqlite3Section(fd,mg->members(),refid,"user-defined",mg->header(), mg->documentation()); } } @@ -1435,24 +2322,201 @@ static void generateSqlite3ForFile(const FileDef *fd) { if ((ml->listType()&MemberListType_declarationLists)!=0) { - generateSqlite3Section(fd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType())); + generateSqlite3Section(fd,ml,refid,"user-defined"); } } } +// kind: group static void generateSqlite3ForGroup(const GroupDef *gd) { -#warning WorkInProgress + // + members + // + member groups + // + files + // + classes + // + namespaces + // - packages + // + pages + // + child groups + // - examples + // + brief description + // + detailed description + + if (gd->isReference()) return; // skip external references. + + struct Refid refid = insertRefid(gd->getOutputFileBase()); + if(!refid.created && compounddefExists(refid)){return;} + bindIntParameter(compounddef_insert,":rowid", refid.rowid); + + bindTextParameter(compounddef_insert,":name",gd->name()); + bindTextParameter(compounddef_insert,":title",gd->groupTitle(), FALSE); + bindTextParameter(compounddef_insert,":kind","group",FALSE); + + int file_id = insertPath(gd->getDefFileName()); + bindIntParameter(compounddef_insert,":file_id",file_id); + bindIntParameter(compounddef_insert,":line",gd->getDefLine()); + bindIntParameter(compounddef_insert,":column",gd->getDefColumn()); + + getSQLDesc(compounddef_insert,":briefdescription",gd->briefDescription(),gd); + getSQLDesc(compounddef_insert,":detaileddescription",gd->documentation(),gd); + + step(compounddef_insert); + + // + files + writeInnerFiles(gd->getFiles(),refid); + + // + classes + writeInnerClasses(gd->getClasses(),refid); + + // + namespaces + writeInnerNamespaces(gd->getNamespaces(),refid); + + // + pages + writeInnerPages(gd->getPages(),refid); + + // + groups + writeInnerGroups(gd->getSubGroups(),refid); + + // + member groups + if (gd->getMemberGroupSDict()) + { + MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict()); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + generateSqlite3Section(gd,mg->members(),refid,"user-defined",mg->header(), + mg->documentation()); + } + } + + // + members + QListIterator<MemberList> mli(gd->getMemberLists()); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + if ((ml->listType()&MemberListType_declarationLists)!=0) + { + generateSqlite3Section(gd,ml,refid,"user-defined"); + } + } } +// kind: dir static void generateSqlite3ForDir(const DirDef *dd) { -#warning WorkInProgress + // + dirs + // + files + // + briefdescription + // + detaileddescription + // + location (below uses file_id, line, column; XML just uses file) + if (dd->isReference()) return; // skip external references + + struct Refid refid = insertRefid(dd->getOutputFileBase()); + if(!refid.created && compounddefExists(refid)){return;} + bindIntParameter(compounddef_insert,":rowid", refid.rowid); + + bindTextParameter(compounddef_insert,":name",dd->displayName()); + bindTextParameter(compounddef_insert,":kind","dir",FALSE); + + int file_id = insertPath(dd->getDefFileName(),TRUE,TRUE,2); + bindIntParameter(compounddef_insert,":file_id",file_id); + + /* + line and column are weird here, but: + - dir goes into compounddef with all of the others + - the semantics would be fine if we set them to NULL here + - but defining line and column as NOT NULL is an important promise + for other compounds, so I don't want to loosen it + + For reference, the queries return 1. + 0 or -1 make more sense, but I see that as a change for DirDef. + */ + bindIntParameter(compounddef_insert,":line",dd->getDefLine()); + bindIntParameter(compounddef_insert,":column",dd->getDefColumn()); + + getSQLDesc(compounddef_insert,":briefdescription",dd->briefDescription(),dd); + getSQLDesc(compounddef_insert,":detaileddescription",dd->documentation(),dd); + + step(compounddef_insert); + + // + files + writeInnerDirs(&dd->subDirs(),refid); + + // + files + writeInnerFiles(dd->getFiles(),refid); } +// kinds: page, example static void generateSqlite3ForPage(const PageDef *pd,bool isExample) { -#warning WorkInProgress + // + name + // + title + // + brief description + // + documentation (detailed description) + // + inbody documentation + // + sub pages + if (pd->isReference()) return; // skip external references. + + // TODO: do we more special handling if isExample? + + QCString qrefid = pd->getOutputFileBase(); + if (pd->getGroupDef()) + { + qrefid+=(QCString)"_"+pd->name(); + } + if (qrefid=="index") qrefid="indexpage"; // to prevent overwriting the generated index page. + + struct Refid refid = insertRefid(qrefid); + + // can omit a page that already has a refid + if(!refid.created && compounddefExists(refid)){return;} + + bindIntParameter(compounddef_insert,":rowid",refid.rowid); + // + name + bindTextParameter(compounddef_insert,":name",pd->name()); + + QCString title; + if (pd==Doxygen::mainPage) // main page is special + { + if (!pd->title().isEmpty() && pd->title().lower()!="notitle") + { + title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title())); + } + else + { + title = Config_getString(PROJECT_NAME); + } + } + else + { + SectionInfo *si = Doxygen::sectionDict->find(pd->name()); + if (si) + { + title = si->title; + } + + if(!title){title = pd->title();} + } + + // + title + bindTextParameter(compounddef_insert,":title",title,FALSE); + + bindTextParameter(compounddef_insert,":kind", isExample ? "example" : "page"); + + int file_id = insertPath(pd->getDefFileName()); + + bindIntParameter(compounddef_insert,":file_id",file_id); + bindIntParameter(compounddef_insert,":line",pd->getDefLine()); + bindIntParameter(compounddef_insert,":column",pd->getDefColumn()); + + // + brief description + getSQLDesc(compounddef_insert,":briefdescription",pd->briefDescription(),pd); + // + documentation (detailed description) + getSQLDesc(compounddef_insert,":detaileddescription",pd->documentation(),pd); + + step(compounddef_insert); + // + sub pages + writeInnerPages(pd->getSubPages(),refid); } @@ -1463,6 +2527,7 @@ static sqlite3* openDbConnection() QDir sqlite3Dir(outputDirectory); sqlite3 *db; int rc; + struct stat buf; rc = sqlite3_initialize(); if (rc != SQLITE_OK) @@ -1470,7 +2535,21 @@ static sqlite3* openDbConnection() msg("sqlite3_initialize failed\n"); return NULL; } - rc = sqlite3_open_v2(outputDirectory+"/doxygen_sqlite3.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + + + if (stat (outputDirectory+"/doxygen_sqlite3.db", &buf) == 0) + { + msg("doxygen_sqlite3.db already exists! aborting sqlite3 output generation!\n"); + msg("If you wish to re-generate the database, remove or archive the existing copy first.\n"); + return NULL; + } + + rc = sqlite3_open_v2( + outputDirectory+"/doxygen_sqlite3.db", + &db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, + 0 + ); if (rc != SQLITE_OK) { sqlite3_close(db); @@ -1497,10 +2576,16 @@ void generateSqlite3() { return; } + +# ifdef SQLITE3_DEBUG + // debug: show all executed statements + sqlite3_trace(db, &sqlLog, NULL); +# endif + beginTransaction(db); pragmaTuning(db); - if (-1==initializeSchema(db)) + if (-1==initializeTables(db)) return; if ( -1 == prepareStatements(db) ) @@ -1509,9 +2594,11 @@ void generateSqlite3() return; } + recordMetadata(); + // + classes ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { msg("Generating Sqlite3 output for class %s\n",cd->name().data()); @@ -1520,7 +2607,7 @@ void generateSqlite3() // + namespaces NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { msg("Generating Sqlite3 output for namespace %s\n",nd->name().data()); @@ -1533,7 +2620,7 @@ void generateSqlite3() for (;(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); - FileDef *fd; + const FileDef *fd; for (;(fd=fni.current());++fni) { msg("Generating Sqlite3 output for file %s\n",fd->name().data()); @@ -1543,7 +2630,7 @@ void generateSqlite3() // + groups GroupSDict::Iterator gli(*Doxygen::groupSDict); - GroupDef *gd; + const GroupDef *gd; for (;(gd=gli.current());++gli) { msg("Generating Sqlite3 output for group %s\n",gd->name().data()); @@ -1553,7 +2640,7 @@ void generateSqlite3() // + page { PageSDict::Iterator pdi(*Doxygen::pageSDict); - PageDef *pd=0; + const PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating Sqlite3 output for page %s\n",pd->name().data()); @@ -1563,7 +2650,7 @@ void generateSqlite3() // + dirs { - DirDef *dir; + const DirDef *dir; DirSDict::Iterator sdi(*Doxygen::directories); for (sdi.toFirst();(dir=sdi.current());++sdi) { @@ -1575,7 +2662,7 @@ void generateSqlite3() // + examples { PageSDict::Iterator pdi(*Doxygen::exampleSDict); - PageDef *pd=0; + const PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating Sqlite3 output for example %s\n",pd->name().data()); @@ -1590,6 +2677,11 @@ void generateSqlite3() generateSqlite3ForPage(Doxygen::mainPage,FALSE); } + // TODO: copied from initializeSchema; not certain if we should say/do more + // if there's a failure here? + if (-1==initializeViews(db)) + return; + endTransaction(db); } diff --git a/src/tagreader.cpp b/src/tagreader.cpp index dfa8511..45543de 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -18,6 +18,7 @@ #include "tagreader.h" +#include <assert.h> #include <stdio.h> #include <stdarg.h> @@ -27,7 +28,7 @@ #include <qfileinfo.h> #include <qlist.h> #include <qstring.h> -#include <qstringlist.h> +#include <qcstringlist.h> #include "entry.h" #include "classdef.h" @@ -39,6 +40,7 @@ #include "filedef.h" #include "filename.h" #include "section.h" +#include "groupdef.h" /** Information about an linkable anchor */ class TagAnchorInfo @@ -95,17 +97,18 @@ class TagMemberInfo class TagClassInfo { public: - enum Kind { Class, Struct, Union, Interface, Exception, Protocol, Category, Enum, Service, Singleton }; - TagClassInfo() { bases=0, templateArguments=0; members.setAutoDelete(TRUE); isObjC=FALSE; } + enum Kind { None=-1, Class, Struct, Union, Interface, Exception, Protocol, Category, Enum, Service, Singleton }; + TagClassInfo() { bases=0, templateArguments=0; members.setAutoDelete(TRUE); isObjC=FALSE; kind = None; } ~TagClassInfo() { delete bases; delete templateArguments; } QCString name; QCString filename; QCString clangId; + QCString anchor; TagAnchorInfoList docAnchors; QList<BaseInfo> *bases; QList<TagMemberInfo> members; QList<QCString> *templateArguments; - QStringList classList; + QCStringList classList; Kind kind; bool isObjC; }; @@ -118,8 +121,8 @@ class TagNamespaceInfo QCString name; QCString filename; QCString clangId; - QStringList classList; - QStringList namespaceList; + QCStringList classList; + QCStringList namespaceList; TagAnchorInfoList docAnchors; QList<TagMemberInfo> members; }; @@ -133,7 +136,7 @@ class TagPackageInfo QCString filename; TagAnchorInfoList docAnchors; QList<TagMemberInfo> members; - QStringList classList; + QCStringList classList; }; /** Container for include info that can be read from a tagfile */ @@ -157,8 +160,8 @@ class TagFileInfo QCString filename; TagAnchorInfoList docAnchors; QList<TagMemberInfo> members; - QStringList classList; - QStringList namespaceList; + QCStringList classList; + QCStringList namespaceList; QList<TagIncludeInfo> includes; }; @@ -172,12 +175,12 @@ class TagGroupInfo QCString filename; TagAnchorInfoList docAnchors; QList<TagMemberInfo> members; - QStringList subgroupList; - QStringList classList; - QStringList namespaceList; - QStringList fileList; - QStringList pageList; - QStringList dirList; + QCStringList subgroupList; + QCStringList classList; + QCStringList namespaceList; + QCStringList fileList; + QCStringList pageList; + QCStringList dirList; }; /** Container for page specific info that can be read from a tagfile */ @@ -197,8 +200,8 @@ class TagDirInfo QCString name; QCString filename; QCString path; - QStringList subdirList; - QStringList fileList; + QCStringList subdirList; + QCStringList fileList; TagAnchorInfoList docAnchors; }; @@ -381,7 +384,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unknown compound attribute `%s' found!\n",kind.data()); + warn("Unknown compound attribute `%s' found!",kind.data()); m_state = Invalid; } if (isObjC=="yes" && m_curClass) @@ -409,7 +412,7 @@ class TagFileParser : public QXmlDefaultHandler case InPackage: m_tagFilePackages.append(m_curPackage); m_curPackage=0; break; default: - warn("tag `compound' was not expected!\n"); + warn("tag `compound' was not expected!"); } } @@ -455,7 +458,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->members.append(m_curMember); break; case InGroup: m_curGroup->members.append(m_curMember); break; case InPackage: m_curPackage->members.append(m_curMember); break; - default: warn("Unexpected tag `member' found\n"); break; + default: warn("Unexpected tag `member' found"); break; } } @@ -473,7 +476,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Found enumvalue tag outside of member tag\n"); + warn("Found `enumvalue' tag outside of member tag"); } } @@ -501,7 +504,7 @@ class TagFileParser : public QXmlDefaultHandler case InMember: m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; case InPackage: m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; case InDir: m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; - default: warn("Unexpected tag `member' found\n"); break; + default: warn("Unexpected tag `docanchor' found"); break; } } @@ -514,7 +517,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->classList.append(m_curString); break; case InGroup: m_curGroup->classList.append(m_curString); break; case InPackage: m_curPackage->classList.append(m_curString); break; - default: warn("Unexpected tag `class' found\n"); break; + default: warn("Unexpected tag `class' found"); break; } } @@ -525,7 +528,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->classList.append(m_curString); break; case InFile: m_curFile->namespaceList.append(m_curString); break; case InGroup: m_curGroup->namespaceList.append(m_curString); break; - default: warn("Unexpected tag `namespace' found\n"); break; + default: warn("Unexpected tag `namespace' found"); break; } } @@ -535,7 +538,7 @@ class TagFileParser : public QXmlDefaultHandler { case InGroup: m_curGroup->fileList.append(m_curString); break; case InDir: m_curDir->fileList.append(m_curString); break; - default: warn("Unexpected tag `file' found\n"); break; + default: warn("Unexpected tag `file' found"); break; } } @@ -544,7 +547,7 @@ class TagFileParser : public QXmlDefaultHandler switch(m_state) { case InGroup: m_curGroup->fileList.append(m_curString); break; - default: warn("Unexpected tag `page' found\n"); break; + default: warn("Unexpected tag `page' found"); break; } } @@ -553,7 +556,7 @@ class TagFileParser : public QXmlDefaultHandler switch(m_state) { case InDir: m_curDir->subdirList.append(m_curString); break; - default: warn("Unexpected tag `page' found\n"); break; + default: warn("Unexpected tag `dir' found"); break; } } @@ -577,7 +580,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `type' found\n"); + warn("Unexpected tag `type' found"); } } @@ -593,7 +596,7 @@ class TagFileParser : public QXmlDefaultHandler case InDir: m_curDir->name = m_curString; break; case InMember: m_curMember->name = m_curString; break; case InPackage: m_curPackage->name = m_curString; break; - default: warn("Unexpected tag `name' found\n"); break; + default: warn("Unexpected tag `name' found"); break; } } @@ -627,7 +630,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `base' found\n"); + warn("Unexpected tag `base' found"); } } @@ -639,7 +642,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `base' found\n"); + warn("Unexpected tag `base' found"); } } @@ -656,7 +659,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `includes' found\n"); + warn("Unexpected tag `includes' found"); } m_curString=""; } @@ -679,7 +682,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `templarg' found\n"); + warn("Unexpected tag `templarg' found"); } } @@ -694,7 +697,7 @@ class TagFileParser : public QXmlDefaultHandler case InPage: m_curPage->filename = m_curString; break; case InPackage: m_curPackage->filename = m_curString; break; case InDir: m_curDir->filename = m_curString; break; - default: warn("Unexpected tag `filename' found\n"); break; + default: warn("Unexpected tag `filename' found"); break; } } @@ -704,7 +707,7 @@ class TagFileParser : public QXmlDefaultHandler { case InFile: m_curFile->path = m_curString; break; case InDir: m_curDir->path = m_curString; break; - default: warn("Unexpected tag `path' found\n"); break; + default: warn("Unexpected tag `path' found"); break; } } @@ -714,9 +717,13 @@ class TagFileParser : public QXmlDefaultHandler { m_curMember->anchor = m_curString; } + else if (m_state==InClass) + { + m_curClass->anchor = m_curString; + } else { - warn("Unexpected tag `anchor' found\n"); + warn("Unexpected tag `anchor' found"); } } @@ -736,7 +743,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("warning: Unexpected tag `anchor' found\n"); + warn("Unexpected tag `clangid' found"); } } @@ -750,7 +757,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `anchorfile' found\n"); + warn("Unexpected tag `anchorfile' found"); } } @@ -762,7 +769,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `arglist' found\n"); + warn("Unexpected tag `arglist' found"); } } void endTitle() @@ -771,7 +778,7 @@ class TagFileParser : public QXmlDefaultHandler { case InGroup: m_curGroup->title = m_curString; break; case InPage: m_curPage->title = m_curString; break; - default: warn("Unexpected tag `title' found\n"); break; + default: warn("Unexpected tag `title' found"); break; } } @@ -783,7 +790,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `subgroup' found\n"); + warn("Unexpected tag `subgroup' found"); } } @@ -878,7 +885,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unknown tag `%s' found!\n",name.data()); + warn("Unknown tag `%s' found!",name.data()); } return TRUE; } @@ -893,7 +900,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unknown tag `%s' found!\n",name.data()); + warn("Unknown tag `%s' found!",name.data()); } return TRUE; } @@ -1009,11 +1016,11 @@ void TagFileParser::dump() { msg("namespace `%s'\n",nd->name.data()); msg(" filename `%s'\n",nd->filename.data()); - QStringList::Iterator it; + QCStringList::Iterator it; for ( it = nd->classList.begin(); it != nd->classList.end(); ++it ) { - msg( " class: %s \n", (*it).latin1() ); + msg( " class: %s \n", (*it).data() ); } QListIterator<TagMemberInfo> mci(nd->members); @@ -1034,16 +1041,16 @@ void TagFileParser::dump() { msg("file `%s'\n",fd->name.data()); msg(" filename `%s'\n",fd->filename.data()); - QStringList::Iterator it; + QCStringList::Iterator it; for ( it = fd->namespaceList.begin(); it != fd->namespaceList.end(); ++it ) { - msg( " namespace: %s \n", (*it).latin1() ); + msg( " namespace: %s \n", (*it).data() ); } for ( it = fd->classList.begin(); it != fd->classList.end(); ++it ) { - msg( " class: %s \n", (*it).latin1() ); + msg( " class: %s \n", (*it).data() ); } QListIterator<TagMemberInfo> mci(fd->members); @@ -1072,31 +1079,31 @@ void TagFileParser::dump() { msg("group `%s'\n",gd->name.data()); msg(" filename `%s'\n",gd->filename.data()); - QStringList::Iterator it; + QCStringList::Iterator it; for ( it = gd->namespaceList.begin(); it != gd->namespaceList.end(); ++it ) { - msg( " namespace: %s \n", (*it).latin1() ); + msg( " namespace: %s \n", (*it).data() ); } for ( it = gd->classList.begin(); it != gd->classList.end(); ++it ) { - msg( " class: %s \n", (*it).latin1() ); + msg( " class: %s \n", (*it).data() ); } for ( it = gd->fileList.begin(); it != gd->fileList.end(); ++it ) { - msg( " file: %s \n", (*it).latin1() ); + msg( " file: %s \n", (*it).data() ); } for ( it = gd->subgroupList.begin(); it != gd->subgroupList.end(); ++it ) { - msg( " subgroup: %s \n", (*it).latin1() ); + msg( " subgroup: %s \n", (*it).data() ); } for ( it = gd->pageList.begin(); it != gd->pageList.end(); ++it ) { - msg( " page: %s \n", (*it).latin1() ); + msg( " page: %s \n", (*it).data() ); } QListIterator<TagMemberInfo> mci(gd->members); @@ -1126,16 +1133,16 @@ void TagFileParser::dump() { msg("dir `%s'\n",dd->name.data()); msg(" path `%s'\n",dd->path.data()); - QStringList::Iterator it; + QCStringList::Iterator it; for ( it = dd->fileList.begin(); it != dd->fileList.end(); ++it ) { - msg( " file: %s \n", (*it).latin1() ); + msg( " file: %s \n", (*it).data() ); } for ( it = dd->subdirList.begin(); it != dd->subdirList.end(); ++it ) { - msg( " subdir: %s \n", (*it).latin1() ); + msg( " subdir: %s \n", (*it).data() ); } } } @@ -1157,7 +1164,7 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) } else { - warn("Duplicate anchor %s found\n",ta->label.data()); + warn("Duplicate anchor %s found",ta->label.data()); } } } @@ -1322,6 +1329,9 @@ void TagFileParser::buildLists(Entry *root) case TagClassInfo::Category: ce->spec = Entry::Category; break; case TagClassInfo::Service: ce->spec = Entry::Service; break; case TagClassInfo::Singleton: ce->spec = Entry::Singleton; break; + case TagClassInfo::None: // should never happen, means not properly initialized + assert(tci->kind != TagClassInfo::None); + break; } ce->name = tci->name; if (tci->kind==TagClassInfo::Protocol) @@ -1331,6 +1341,7 @@ void TagFileParser::buildLists(Entry *root) addDocAnchors(ce,tci->docAnchors); TagInfo *ti = new TagInfo; ti->tagName = m_tagName; + ti->anchor = tci->anchor; ti->fileName = tci->filename; ce->id = tci->clangId; ce->tagInfo = ti; @@ -1459,6 +1470,22 @@ void TagFileParser::buildLists(Entry *root) root->addSubEntry(ge); } + // set subgroup relations bug_774118 + for (git.toFirst();(tgi=git.current());++git) + { + QCStringList::Iterator it; + for ( it = tgi->subgroupList.begin(); it != tgi->subgroupList.end(); ++it ) + { + QListIterator<Entry> eli(*(root->children())); + Entry *childNode; + for (eli.toFirst();(childNode=eli.current());++eli) + { + if (childNode->name == (*it)) break; + } + childNode->groups->append(new Grouping(tgi->name,Grouping::GROUPING_INGROUP)); + } + } + // build page list QListIterator<TagPageInfo> pgit(m_tagFilePages); TagPageInfo *tpi; diff --git a/src/tclscanner.l b/src/tclscanner.l index 791ecc4..ca5294b 100644 --- a/src/tclscanner.l +++ b/src/tclscanner.l @@ -25,7 +25,7 @@ #include <ctype.h> #include <qstring.h> -#include <qstringlist.h> +#include <qcstringlist.h> #include <qlist.h> #include <qmap.h> #include <qarray.h> @@ -369,7 +369,7 @@ int Tcl_SplitList( } // END of tclUtil.c -void tcl_split_list(QString &str, QStringList &list) +void tcl_split_list(QCString &str, QCStringList &list) { int argc; const char **argv; @@ -383,17 +383,20 @@ void tcl_split_list(QString &str, QStringList &list) { str=str.mid(1,str.length()-2); } - if (Tcl_SplitList(str.ascii(),&argc,&argv) != TCL_OK) + if (!str.isEmpty()) { - list.append(str); - } - else - { - for (int i = 0; i < argc; i++) + if (Tcl_SplitList(str,&argc,&argv) != TCL_OK) { - list.append(argv[i]); + list.append(str); + } + else + { + for (int i = 0; i < argc; i++) + { + list.append(argv[i]); + } + ckfree((char *) argv); } - ckfree((char *) argv); } } @@ -409,7 +412,7 @@ typedef struct Entry *entry_cl; // if set contain the current class Entry *entry_scan; // current scan entry Protection protection; // current protections state - QStringList after; // option/value list (options: NULL comment keyword script) + QCStringList after; // option/value list (options: NULL comment keyword script) } tcl_scan; //* Structure containing all internal global variables. @@ -446,7 +449,7 @@ static struct Entry* entry_file; // entry of current file Entry* entry_current; // currently used entry Entry* entry_inside; // contain entry of current scan context - QStringList list_commandwords; // list of command words + QCStringList list_commandwords; // list of command words QList<tcl_scan> scan; // stack of scan contexts QAsciiDict<Entry> ns; // all read namespace entries QAsciiDict<Entry> cl; // all read class entries @@ -602,7 +605,7 @@ Entry* tcl_entry_class(const QCString cl) // @return 1 if keyword and 0 otherwise static int tcl_keyword(QCString str) { - static QStringList myList; + static QCStringList myList; static int myInit=1; if (myInit) { @@ -639,7 +642,7 @@ static int tcl_keyword(QCString str) myList <<"tkerror"<<"tkwait"<<"tk_bisque"<<"tk_focusNext"<<"tk_focusPrev"<<"tk_focusFollowsMouse"<<"tk_popup"<<"tk_setPalette"<<"tk_textCut"<<"tk_TextCopy"<<"tk_textPaste"<<"chooseColor"<<"tk_chooseColor"<<"tk_chooseDirectory"<<"tk_dialog"<<"tk_getOpenFile"<<"tkDialog"<<"tk_getSaveFile"<<"tk_messageBox"; myList <<"winfo"<<"wm"; myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel"; - myList.sort(); + //myList.sort(); myInit=0; } str=str.stripWhiteSpace(); @@ -703,6 +706,7 @@ static void tcl_codify(const char *s,const char *str) } else { + if (*(p-2)==0x1A) *(p-2) = '\0'; // remove ^Z tcl.code->codify(sp); done=TRUE; } @@ -726,7 +730,7 @@ static void tcl_codify(const char *s,const char *str) static void tcl_codify(const char *s,const QString &str) { if (tcl.code==NULL) return; - tcl_codify(s,str.utf8()); + tcl_codify(s,str); } //! Codify 'str' with special font class 's'. @@ -739,7 +743,7 @@ static void tcl_codify(const char *s,const QCString &str) static void tcl_codify_cmd(const char *s,int i) { - tcl_codify(s,(*tcl.list_commandwords.at(i)).utf8()); + tcl_codify(s,(*tcl.list_commandwords.at(i))); } //! codify a string token // @@ -1192,7 +1196,7 @@ tcl_inf("line=%d\n",myScan->line1); myStart=i; break; } - tcl_codify(myScan->after[i].utf8(),myScan->after[i+1].utf8()); + tcl_codify(myScan->after[i],myScan->after[i+1]); } yy_delete_buffer(myScan->buffer_state); yy_pop_state(); @@ -1427,7 +1431,6 @@ tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data()); yyless(0); tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data()); return; - myWhite=0; break; default: tcl_err("wrong state: %d\n",what); @@ -1607,12 +1610,12 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); } //! Parse given \c arglist . -static void tcl_command_ARGLIST(QString &arglist) +static void tcl_command_ARGLIST(QCString &arglist) { D Argument *myArg; - QStringList myArgs; - QString myArglist=""; + QCStringList myArgs; + QCString myArglist=""; if (!tcl.entry_current->argList) { @@ -1621,14 +1624,14 @@ D tcl_split_list(arglist,myArgs); for (uint i=0;i<myArgs.count();i++) { - QStringList myArgs1; + QCStringList myArgs1; myArg=new Argument; tcl_split_list(*myArgs.at(i),myArgs1); if (myArgs1.count()==2) { - myArg->name= (*myArgs1.at(0)).utf8(); - myArg->defval= (*myArgs1.at(1)).utf8(); + myArg->name= (*myArgs1.at(0)); + myArg->defval= (*myArgs1.at(1)); if (myArg->defval.isEmpty()) { myArg->defval = " "; @@ -1637,13 +1640,13 @@ D } else { - myArg->name= (*myArgs.at(i)).utf8(); - myArglist += QString(myArg->name) + " "; + myArg->name= (*myArgs.at(i)); + myArglist += myArg->name + " "; } tcl.entry_current->argList->append(myArg); } arglist = myArglist; - tcl.entry_current->args = arglist.utf8(); + tcl.entry_current->args = arglist; } //! Create link. @@ -1762,7 +1765,7 @@ static void tcl_codify_link(QCString name) //! scan general argument for brackets // -// parses (*tcl.list_commandwords.at(i)).utf8() and checks for brackets. +// parses (*tcl.list_commandwords.at(i)) and checks for brackets. // Starts a new scan context if needed (*myScan==0 and brackets found). // Returns NULL or the created scan context. // @@ -1772,7 +1775,7 @@ static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOu bool insideQuotes=false; unsigned int insideBrackets=0; unsigned int insideBraces=0; - myName = (*tcl.list_commandwords.at(i)).utf8(); + myName = (*tcl.list_commandwords.at(i)); if (i%2 != 0) { // handle white space @@ -1860,7 +1863,7 @@ D // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked] for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++) { - myString += (*tcl.list_commandwords.at(i)).utf8(); + myString += (*tcl.list_commandwords.at(i)); } myScan = tcl_scan_start('?', myString, myScan->ns, myScan->entry_cl, myScan->entry_fn); @@ -1881,7 +1884,7 @@ D unsigned int lastOptionIndex = 0; for (i = 2; i<tcl.list_commandwords.count(); i += 2) { - token = (*tcl.list_commandwords.at(i)).utf8(); + token = (*tcl.list_commandwords.at(i)); if (token == "--") { lastOptionIndex = i; @@ -1912,7 +1915,7 @@ D int size; const char *elem; const char *next; - token = (*tcl.list_commandwords.at(lastOptionIndex + 4)).utf8(); + token = (*tcl.list_commandwords.at(lastOptionIndex + 4)); if (token[0] == '{') { inBraces = true; @@ -1965,15 +1968,15 @@ D //printf("detected: switch ?options? string pattern body ?pattern body ...?\n"); myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false); myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false); - //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2)).utf8()); + //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2))); for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4) { myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace myScan = tcl_command_ARG(myScan, i + 1, false); // pattern myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace - myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3)).utf8()); // script - //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)).utf8()); - //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3)).utf8()); + myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3))); // script + //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)))); + //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3))); } } else @@ -2006,7 +2009,7 @@ D //! Handle internal tcl commands. // "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?" -static void tcl_command_IF(QStringList type) +static void tcl_command_IF(QCStringList type) { D tcl_codify_cmd("keyword",0); @@ -2125,7 +2128,7 @@ D tcl_codify_cmd(NULL,3); tcl_codify_cmd(NULL,4); tcl_codify_cmd(NULL,5); - tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName); + tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); if (myNs.length()) { myEntryNs = tcl_entry_namespace(myNs); @@ -2164,7 +2167,7 @@ D tcl_codify_cmd(NULL,3); tcl_codify_cmd(NULL,4); tcl_codify_cmd(NULL,5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); if (myNs.length()) { myEntryCl = tcl_entry_class(myNs); @@ -2204,7 +2207,7 @@ D tcl_codify_cmd(NULL,1); tcl_codify_cmd(NULL,2); tcl_codify_cmd(NULL,3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName); if (myNs.length()) { myEntryCl = tcl_entry_class(myNs); @@ -2239,7 +2242,7 @@ D tcl_codify_cmd("keyword",0); tcl_codify_cmd(NULL,1); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)),myNs,myName); if (myNs.length()) { myEntryCl = tcl_entry_class(myNs); @@ -2277,7 +2280,7 @@ D tcl_codify_cmd(NULL,3); tcl_codify_cmd(NULL,4); tcl_codify_cmd(NULL,5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); if (myNs.length()) { myName = myNs+"::"+myName; @@ -2290,12 +2293,12 @@ D tcl.entry_main->addSubEntry(tcl.entry_current); tcl.ns.insert(myName,tcl.entry_current); //myEntryNs = tcl.entry_current; - myStr = (*tcl.list_commandwords.at(6)).utf8(); + myStr = (*tcl.list_commandwords.at(6)); if (tcl.list_commandwords.count() > 7) { for (uint i=7;i<tcl.list_commandwords.count();i++) { - myStr.append((*tcl.list_commandwords.at(i)).utf8()); + myStr.append((*tcl.list_commandwords.at(i))); } tcl.word_is=' '; } @@ -2314,7 +2317,7 @@ D tcl_codify_cmd(NULL,1); tcl_codify_cmd("NULL",2); tcl_codify_cmd("NULL",3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); if (myNs.length()) { myName = myNs+"::"+myName; @@ -2346,7 +2349,7 @@ D tcl_codify_cmd("NULL",3); tcl_codify_cmd("NULL",4); tcl_codify_cmd("NULL",5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); if (myNs.length()) { myName = myNs+"::"+myName; @@ -2376,13 +2379,13 @@ D tcl_codify_cmd(NULL,1); tcl_codify_cmd("NULL",2); tcl_codify_cmd("NULL",3); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); if (myNs.length()) { myName = myNs+"::"+myName; } myEntryCl = tcl_entry_class(myName); - myStr = (*tcl.list_commandwords.at(4)).utf8(); + myStr = (*tcl.list_commandwords.at(4)); // // special cases first // oo::define classname method methodname args script @@ -2399,7 +2402,7 @@ D } Entry *myEntry; QCString myMethod; - tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)).utf8(),myNs,myMethod); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)),myNs,myMethod); // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR tcl.fn.remove(myMethod); tcl.entry_current->section = Entry::FUNCTION_SEC; @@ -2433,7 +2436,7 @@ D { for (uint i=5;i<tcl.list_commandwords.count();i++) { - myStr.append((*tcl.list_commandwords.at(i)).utf8()); + myStr.append((*tcl.list_commandwords.at(i))); } tcl.word_is=' '; } @@ -2454,7 +2457,7 @@ D { tcl_codify_cmd(NULL,i); } - tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)),myNs,myName); if (myNs.length()) {// qualified variables go into namespace myEntry = tcl_entry_namespace(myNs); @@ -2534,7 +2537,7 @@ tcl_inf("->\n"); yy_pop_state(); // check command - QCString myStr = (*tcl.list_commandwords.at(0)).utf8(); + QCString myStr = (*tcl.list_commandwords.at(0)); tcl_scan *myScanBackup=tcl.scan.at(0); int myLevel = 0; Protection myProt = tcl.protection; @@ -2579,7 +2582,7 @@ tcl_inf("->\n"); myProt = tcl.protection; goto command_end; } - myStr = (*tcl.list_commandwords.at(0)).utf8(); + myStr = (*tcl.list_commandwords.at(0)); // remove leading "::" and apply TCL_SUBST if (myStr.left(2)=="::") myStr = myStr.mid(2); if (tcl.config_subst.contains(myStr)) @@ -2623,7 +2626,7 @@ tcl_inf("->\n"); } if (myStr=="namespace") { - if ((*tcl.list_commandwords.at(2)).utf8()=="eval") + if ((*tcl.list_commandwords.at(2))=="eval") { if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;} tcl_command_NAMESPACE(); @@ -2646,7 +2649,7 @@ tcl_inf("->\n"); } if (myStr=="oo::class") { - if ((*tcl.list_commandwords.at(2)).utf8()=="create") + if ((*tcl.list_commandwords.at(2))=="create") { if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;} tcl_command_OO_CLASS(); @@ -2686,7 +2689,7 @@ tcl_inf("->\n"); { for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2) { - tcl.scan.at(0)->entry_cl->extends->append(new BaseInfo((*tcl.list_commandwords.at(i)).utf8(),Public,Normal)); + tcl.scan.at(0)->entry_cl->extends->append(new BaseInfo((*tcl.list_commandwords.at(i)),Public,Normal)); } } goto command_end; @@ -2730,12 +2733,12 @@ if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN? */ if (myStr=="if" && tcl.list_commandwords.count() > 4) { - QStringList myType; + QCStringList myType; myType << "keyword" << "NULL" << "expr" << "NULL"; char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f.. for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2) { - QCString myStr=(*tcl.list_commandwords.at(i)).utf8(); + QCString myStr=(*tcl.list_commandwords.at(i)); if (myState=='x') { if (myStr=="then") @@ -2796,7 +2799,7 @@ if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN? tcl_command_OTHER(); goto command_end; command_warn:// print warning message because of wrong used syntax - tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").ascii()); + tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").data()); tcl_command_OTHER(); command_end:// add remaining text to current context if (!myText.isEmpty()) @@ -3024,11 +3027,6 @@ void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, } tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inlineFragment); //tcl_inf("%s\n"input.data()); - if (isExampleBlock) - { - tcl_codify(NULL,input); - return; - } tcl_init(); tcl.collectXRefs = collectXRefs; tcl.memberdef = memberDef; @@ -3047,8 +3045,15 @@ tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inli } tcl.file_name = ""; tcl.this_parser = NULL; - tcl.entry_main = tcl_entry_new(); - tcl_parse(myNs,myCls); + if (isExampleBlock) + { + tcl_codify(NULL,input); + } + else + { + tcl.entry_main = tcl_entry_new(); + tcl_parse(myNs,myCls); + } tcl.code->endCodeLine(); tcl.scan.clear(); tcl.ns.clear(); diff --git a/src/template.cpp b/src/template.cpp index 3e39d3c..b1435ce 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -698,7 +698,7 @@ class FilterTexLabel { if (v.isValid() && (v.type()==TemplateVariant::String)) { - return TemplateVariant(latexEscapeLabelName(v.toString(),FALSE),TRUE); + return TemplateVariant(latexEscapeLabelName(v.toString()),TRUE); } else { @@ -717,7 +717,7 @@ class FilterTexIndex { if (v.isValid() && (v.type()==TemplateVariant::String)) { - return TemplateVariant(latexEscapeIndexChars(v.toString(),FALSE),TRUE); + return TemplateVariant(latexEscapeIndexChars(v.toString()),TRUE); } else { diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp index 8c8ecad..b6c90e3 100644 --- a/src/textdocvisitor.cpp +++ b/src/textdocvisitor.cpp @@ -21,6 +21,7 @@ #include "message.h" #include "util.h" #include "htmlentity.h" +#include "emoji.h" //------------------------------------------------------------------------- @@ -37,6 +38,18 @@ void TextDocVisitor::visit(DocSymbol *s) } } +void TextDocVisitor::visit(DocEmoji *s) +{ + const char *res = EmojiEntityMapper::instance()->name(s->index()); + if (res) + { + filter(res); + } + else + { + filter(s->name()); + } +} void TextDocVisitor::filter(const char *str) { @@ -50,11 +63,6 @@ void TextDocVisitor::filter(const char *str) switch(c) { case '\n': m_t << " "; break; - case '"': m_t << """; break; - case '\'': m_t << "'"; break; - case '<': m_t << "<"; break; - case '>': m_t << ">"; break; - case '&': m_t << "&"; break; default: m_t << c; } } diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h index 1bbc357..bbc70e8 100644 --- a/src/textdocvisitor.h +++ b/src/textdocvisitor.h @@ -40,6 +40,7 @@ class TextDocVisitor : public DocVisitor 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 *) {} diff --git a/src/translator.h b/src/translator.h index 7092174..ac55911 100644 --- a/src/translator.h +++ b/src/translator.h @@ -19,6 +19,8 @@ #define TRANSLATOR_H #include "classdef.h" +#include "config.h" +#include "vhdldocgen.h" /** Abstract base class for all translatable text fragments. */ class Translator @@ -41,6 +43,36 @@ class Translator virtual QCString idLanguage() = 0; virtual QCString latexLanguageSupportCommand() = 0; + /*! + * Sets the LaTeX font encoding to be used. The default is set to `T1`, + * in case another font encoding has to be used this can be specified with + * this routine. In case no font encoding is required the empty string + * can be returned. + */ + virtual QCString latexFontenc() { return "T1"; } + /*! + * Sets the commands to be insered directly after the `\\begin{document}` + * in the LaTeX document. + */ + virtual QCString latexDocumentPre() { return ""; } + /*! + * Sets the commands to be insered directly before the `\\end{document}` + * in the LaTeX document. + */ + virtual QCString latexDocumentPost() { return ""; } + /*! + * Set the name to be used as latex command. + */ + virtual QCString latexCommandName() + { + QCString latex_command = Config_getString(LATEX_CMD_NAME); + if (latex_command.isEmpty()) latex_command = "latex"; + if (Config_getBool(USE_PDFLATEX)) + { + if (latex_command == "latex") latex_command = "pdflatex"; + } + return latex_command; + } // --- Language translation methods ------------------- @@ -570,6 +602,50 @@ class Translator virtual QCString trSingletonReference(const char *sName) = 0; virtual QCString trServiceGeneratedFromFiles(bool single) = 0; virtual QCString trSingletonGeneratedFromFiles(bool single) = 0; + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trDesignUnitHierarchy() = 0; + virtual QCString trDesignUnitList() = 0; + virtual QCString trDesignUnitMembers() = 0; + virtual QCString trDesignUnitListDescription() = 0; + virtual QCString trDesignUnitIndex() = 0; + virtual QCString trDesignUnits() = 0; + virtual QCString trFunctionAndProc() = 0; + virtual QCString trVhdlType(uint64 type,bool single) = 0; + virtual QCString trCustomReference(const char *name) = 0; + + virtual QCString trConstants() = 0; + virtual QCString trConstantDocumentation() = 0; + virtual QCString trSequences() = 0; + virtual QCString trSequenceDocumentation() = 0; + virtual QCString trDictionaries() = 0; + virtual QCString trDictionaryDocumentation() = 0; + virtual QCString trSliceInterfaces() = 0; + virtual QCString trInterfaceIndex() = 0; + virtual QCString trInterfaceList() = 0; + virtual QCString trInterfaceListDescription() = 0; + virtual QCString trInterfaceHierarchy() = 0; + virtual QCString trInterfaceHierarchyDescription() = 0; + virtual QCString trInterfaceDocumentation() = 0; + virtual QCString trStructs() = 0; + virtual QCString trStructIndex() = 0; + virtual QCString trStructList() = 0; + virtual QCString trStructListDescription() = 0; + virtual QCString trStructDocumentation() = 0; + virtual QCString trExceptionIndex() = 0; + virtual QCString trExceptionList() = 0; + virtual QCString trExceptionListDescription() = 0; + virtual QCString trExceptionHierarchy() = 0; + virtual QCString trExceptionHierarchyDescription() = 0; + virtual QCString trExceptionDocumentation() = 0; + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) = 0; + virtual QCString trOperations() = 0; + virtual QCString trOperationDocumentation() = 0; + virtual QCString trDataMembers() = 0; + virtual QCString trDataMemberDocumentation() = 0; }; #endif diff --git a/src/translator_adapter.h b/src/translator_adapter.h index 254876a..b0c8a24 100644 --- a/src/translator_adapter.h +++ b/src/translator_adapter.h @@ -41,7 +41,128 @@ class TranslatorAdapterBase : public Translator }; -class TranslatorAdapter_1_8_4 : public TranslatorAdapterBase +class TranslatorAdapter_1_8_15 : public TranslatorAdapterBase +{ + public: + virtual QCString updateNeededMessage() + { return createUpdateNeededMessage(idLanguage(),"release 1.8.15"); } + + virtual QCString trDesignUnitHierarchy() + { return english.trDesignUnitHierarchy(); } + + virtual QCString trDesignUnitList() + { return english.trDesignUnitList(); } + + virtual QCString trDesignUnitMembers() + { return english.trDesignUnitMembers(); } + + virtual QCString trDesignUnitListDescription() + { return english.trDesignUnitListDescription(); } + + virtual QCString trDesignUnitIndex() + { return english.trDesignUnitIndex(); } + + virtual QCString trDesignUnits() + { return english.trDesignUnits(); } + + virtual QCString trFunctionAndProc() + { return english.trFunctionAndProc(); } + + virtual QCString trVhdlType(uint64 type,bool single) + { return english.trVhdlType(type,single); } + + virtual QCString trCustomReference(const char *name) + { return english.trCustomReference(name); } + + virtual QCString trConstants() + { return english.trConstants(); } + + virtual QCString trConstantDocumentation() + { return english.trConstantDocumentation(); } + + virtual QCString trSequences() + { return english.trSequences(); } + + virtual QCString trSequenceDocumentation() + { return english.trSequenceDocumentation(); } + + virtual QCString trDictionaries() + { return english.trDictionaries(); } + + virtual QCString trDictionaryDocumentation() + { return english.trDictionaryDocumentation(); } + + virtual QCString trSliceInterfaces() + { return english.trSliceInterfaces(); } + + virtual QCString trInterfaceIndex() + { return english.trInterfaceIndex(); } + + virtual QCString trInterfaceList() + { return english.trInterfaceList(); } + + virtual QCString trInterfaceListDescription() + { return english.trInterfaceListDescription(); } + + virtual QCString trInterfaceHierarchy() + { return english.trInterfaceHierarchy(); } + + virtual QCString trInterfaceHierarchyDescription() + { return english.trInterfaceHierarchyDescription(); } + + virtual QCString trInterfaceDocumentation() + { return english.trInterfaceDocumentation(); } + + virtual QCString trStructs() + { return english.trStructs(); } + + virtual QCString trStructIndex() + { return english.trStructIndex(); } + + virtual QCString trStructList() + { return english.trStructList(); } + + virtual QCString trStructListDescription() + { return english.trStructListDescription(); } + + virtual QCString trStructDocumentation() + { return english.trStructDocumentation(); } + + virtual QCString trExceptionIndex() + { return english.trExceptionIndex(); } + + virtual QCString trExceptionList() + { return english.trExceptionList(); } + + virtual QCString trExceptionListDescription() + { return english.trExceptionListDescription(); } + + virtual QCString trExceptionHierarchy() + { return english.trExceptionHierarchy(); } + + virtual QCString trExceptionHierarchyDescription() + { return english.trExceptionHierarchyDescription(); } + + virtual QCString trExceptionDocumentation() + { return english.trExceptionDocumentation(); } + + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { return english.trCompoundReferenceSlice(clName,compType,isLocal); } + + virtual QCString trOperations() + { return english.trOperations(); } + + virtual QCString trOperationDocumentation() + { return english.trOperationDocumentation(); } + + virtual QCString trDataMembers() + { return english.trDataMembers(); } + + virtual QCString trDataMemberDocumentation() + { return english.trDataMemberDocumentation(); } +}; + +class TranslatorAdapter_1_8_4 : public TranslatorAdapter_1_8_15 { public: virtual QCString updateNeededMessage() @@ -295,4 +416,3 @@ class TranslatorAdapter_1_4_6 : public TranslatorAdapter_1_5_4 }; #endif - diff --git a/src/translator_am.h b/src/translator_am.h index 6f5e671..5b4c446 100644 --- a/src/translator_am.h +++ b/src/translator_am.h @@ -32,8 +32,8 @@ class TranslatorArmenian : public TranslatorAdapter_1_8_0 /* Used to get the command(s) for the language support. */
virtual QCString latexLanguageSupportCommand()
{
- return "<pre>\\usepackage[latin]{armtex}\n"
- "\\usepackage[armscii8]{inputenc}\n</pre>";
+ return "\\usepackage[latin]{armtex}\n"
+ "\\usepackage[armscii8]{inputenc}\n";
}
// --- Language translation methods -------------------
diff --git a/src/translator_br.h b/src/translator_br.h index a294ee0..c2d079a 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 1997-2017 by Dimitri van Heesch. + * Copyright (C) 1997-2018 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 @@ -10,14 +10,16 @@ * Documents produced by Doxygen are derivative workns derived from the * input used in their production; they are not affected by this license. * - * Brazilian Portuguese translation version 20100531 + * Brazilian Portuguese translation * Maintainer: - * Fabio "FJTC" Jun Takada Chino <jun-chino at uol.com.br> + * Fabio "FJTC" Jun Takada Chino <fjtc at brokenbits dot com dot br> * Collaborators: - * Emerson Ferreira <nuskorpios at gmail dot com> + * Emerson Ferreira <nuskorpios at gmail dot com> * Thanks to Jorge Ramos, Fernando Carijo and others for their contributions. * * History: + * 20180612: + * - Updated to 1.8.15; * 20170123: * - Full translation revision; * - trLegendDocs() is now synchronized with the English version; @@ -45,7 +47,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian : public Translator +class TranslatorBrazilian : public TranslatorAdapter_1_8_15 { public: @@ -608,7 +610,7 @@ class TranslatorBrazilian : public Translator { QCString result="Referência"; if (isTemplate) result+=" do <em>Template</em>"; - if (compType == ClassDef::Protocol) + if (compType == ClassDef::Protocol) { result+=" do "; } @@ -834,7 +836,7 @@ class TranslatorBrazilian : public Translator * documentation. It should be an abbreviation of the word page. */ virtual QCString trPageAbbreviation() - { + { // Decidi mudar de página para "p." para ficar mais compacto. return "p."; } @@ -2082,9 +2084,122 @@ class TranslatorBrazilian : public Translator return result; } - -////////////////////////////////////////////////////////////////////////// - + ////////////////////////////////////////////////////////////////////////// + // new since 1.8.15 + ////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Hierarquia da Unidade de Design"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Lista de Unidades de Design"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Membros da Unidade de Design"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Esta é uma lista de todos os membros de unidades de design " + "com ligações para as entidades às quais pertencem:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Índice de Unidades de Design"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Unidades de Design"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funções/Procedimentos/Processos"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Biblioteca"; + else return "Bibliotecas"; + case VhdlDocGen::PACKAGE: + if (single) return "Pacote"; + else return "Pacotes"; + case VhdlDocGen::SIGNAL: + if (single) return "Sinal"; + else return "Sinais"; + case VhdlDocGen::COMPONENT: + if (single) return "Componente"; + else return "Componentes"; + case VhdlDocGen::CONSTANT: + if (single) return "Constante"; + else return "Constantes"; + case VhdlDocGen::ENTITY: + if (single) return "Entidade"; + else return "Entidades"; + case VhdlDocGen::TYPE: + if (single) return "Tipo"; + else return "Tipos"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtipo"; + else return "Subtipos"; + case VhdlDocGen::FUNCTION: + if (single) return "Função"; + else return "Funções"; + case VhdlDocGen::RECORD: + if (single) return "Registro"; + else return "Registros"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedimento"; + else return "Procedimentos"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Arquitetura"; + else return "Arquiteturas"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Atributo"; + else return "Atributos"; + case VhdlDocGen::PROCESS: + if (single) return "Processo"; + else return "Processos"; + case VhdlDocGen::PORT: + if (single) return "Porta"; + else return "Portas"; + case VhdlDocGen::USE: + if (single) return "cláusula de uso"; + else return "cláusulas de uso"; + case VhdlDocGen::GENERIC: + if (single) return "Generico"; + else return "Genericos"; + case VhdlDocGen::PACKAGE_BODY: + return "Corpo do Pacote"; + case VhdlDocGen::UNITS: + return "Unidades"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Variável Compartilhada"; + else return "Variáveis Compartilhadas"; + case VhdlDocGen::VFILE: + if (single) return "Arquivo"; + else return "Arquivos"; + case VhdlDocGen::GROUP: + if (single) return "Grupo"; + else return "Grupos"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instância"; + else return "Instâncias"; + case VhdlDocGen::ALIAS: + if (single) return "Apelido"; + else return "Apelidos"; + case VhdlDocGen::CONFIG: + if (single) return "Configuração"; + else return "Configurações"; + case VhdlDocGen::MISCELLANEOUS: + return "Outros"; // Is this correct for VHDL? + case VhdlDocGen::UCF_CONST: + return "Restrições"; + default: + return "Classe"; + } + } + virtual QCString trCustomReference(const char *name) + { return "Referência de " + QCString(name); } }; #endif diff --git a/src/translator_cn.h b/src/translator_cn.h index fc0cf3c..0e559c1 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_8_15 { public: /*! Used for identification of the language. The identification @@ -53,8 +53,20 @@ class TranslatorChinese : public Translator */ virtual QCString latexLanguageSupportCommand() { + return "\\usepackage{CJKutf8}\n"; + } + virtual QCString latexFontenc() + { return ""; } + virtual QCString latexDocumentPre() + { + return "\\begin{CJK}{UTF8}{min}\n"; + } + virtual QCString latexDocumentPost() + { + return "\\end{CJK}\n"; + } /*! used in the compound documentation before a list of related functions. */ diff --git a/src/translator_cz.h b/src/translator_cz.h index 056d0e4..9d6c489 100644 --- a/src/translator_cz.h +++ b/src/translator_cz.h @@ -85,7 +85,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_8_15 { public: // --- Language control methods ------------------- @@ -96,7 +96,13 @@ class TranslatorCzech : public Translator virtual QCString latexLanguageSupportCommand() { return "\\usepackage[T2A]{fontenc}\n" - "\\usepackage[czech]{babel}\n"; + "\\usepackage[czech]{babel}\n" + "\\usepackage{regexpatch}\n" + "\\makeatletter\n" + "% Change the `-` delimiter to an active character\n" + "\\xpatchparametertext\\@@@cmidrule{-}{\\cA-}{}{}\n" + "\\xpatchparametertext\\@cline{-}{\\cA-}{}{}\n" + "\\makeatother\n"; } // --- Language translation methods ------------------- diff --git a/src/translator_de.h b/src/translator_de.h index d63bdcf..bf5ce5e 100644 --- a/src/translator_de.h +++ b/src/translator_de.h @@ -133,7 +133,7 @@ // 2017/10/12 Arnd Weber (arnd dot weber at bafg dot de) // Beatrix Konz // - Updated for 1.8.13 -// - Resynced trMemberDataDocumentation() and trFileMembers() to include the +// - Resynced trMemberDataDocumentation() and trFileMembers() to include the // boolean switch OPTIMIZE_OUTPUT_FOR_C // - Replaced "\t" by " " // @@ -143,7 +143,7 @@ #ifndef TRANSLATOR_DE_H #define TRANSLATOR_DE_H -class TranslatorGerman : public Translator +class TranslatorGerman : public TranslatorAdapter_1_8_15 { public: @@ -316,8 +316,17 @@ class TranslatorGerman : public Translator /*! This is an introduction to the class hierarchy. */ virtual QCString trClassHierarchyDescription() - { return "Die Liste der Ableitungen ist -mit Einschränkungen- " - "alphabetisch sortiert:"; + { + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return "Hier folgt eine hierarchische Auflistung der " + "Entwurfseinheiten:"; + } + else + { + return "Die Liste der Ableitungen ist -mit Einschränkungen- " + "alphabetisch sortiert:"; + } } /*! This is an introduction to the list with all files. */ @@ -469,6 +478,10 @@ class TranslatorGerman : public Translator { return "Datenstruktur-Dokumentation"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return "Entwurfseinheiten-Dokumentation"; + } else { return "Klassen-Dokumentation"; @@ -1982,7 +1995,7 @@ class TranslatorGerman : public Translator /*! Used file list for a Java enum */ virtual QCString trEnumGeneratedFromFiles(bool single) { QCString result = "Die Dokumentation für diesen enum wurde aus "; - if (single) + if (single) result += "der folgenden Datei"; else result += "den folgenden Dateien"; @@ -2125,6 +2138,123 @@ class TranslatorGerman : public Translator } ////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Entwurfseinheiten-Hierarchie"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Auflistung der Entwurfseinheiten"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Entwurfseinheiten-Elemente"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Hier folgt die Aufzählung aller Entwurfseinheiten und deren " + "Elemente mit einer Kurzbeschreibung:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Entwurfseinheiten-Verzeichnis"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Entwurfseinheiten"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funktionen/Prozeduren/Prozesse"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Bibliothek"; + else return "Bibliotheken"; + case VhdlDocGen::PACKAGE: + if (single) return "Paket"; + else return "Pakete"; + case VhdlDocGen::SIGNAL: + if (single) return "Signal"; + else return "Signale"; + case VhdlDocGen::COMPONENT: + if (single) return "Komponente"; + else return "Komponenten"; + case VhdlDocGen::CONSTANT: + if (single) return "Konstante"; + else return "Konstanten"; + case VhdlDocGen::ENTITY: + if (single) return "Entwurfseinheit"; + else return "Entwurfseinheiten"; + case VhdlDocGen::TYPE: + if (single) return "Typ"; + else return "Typen"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtyp"; + else return "Subtypen"; + case VhdlDocGen::FUNCTION: + if (single) return "Funktion"; + else return "Funktionen"; + case VhdlDocGen::RECORD: + if (single) return "Datenstruktur"; + else return "Datenstrukturen"; + case VhdlDocGen::PROCEDURE: + if (single) return "Prozedur"; + else return "Prozeduren"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Architektur"; + else return "Architekturen"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Attribut"; + else return "Attribute"; + case VhdlDocGen::PROCESS: + if (single) return "Prozess"; + else return "Prozesse"; + case VhdlDocGen::PORT: + if (single) return "Schnittstelle"; + else return "Schnittstellen"; + case VhdlDocGen::USE: + if (single) return "Use Klausel"; + else return "Use Klauseln"; + case VhdlDocGen::GENERIC: + if (single) return "Parameter"; + else return "Parameter"; + case VhdlDocGen::PACKAGE_BODY: + return "Paketkörper"; + case VhdlDocGen::UNITS: + return "Einheiten"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Geteilte Variable"; + else return "Geteilte Variablen"; + case VhdlDocGen::VFILE: + if (single) return "Datei"; + else return "Dateien"; + case VhdlDocGen::GROUP: + if (single) return "Gruppe"; + else return "Gruppen"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instanziierung"; + else return "Instanziierungen"; + case VhdlDocGen::ALIAS: + if (single) return "Alias"; + else return "Aliase"; + case VhdlDocGen::CONFIG: + if (single) return "Konfiguration"; + else return "Konfigurationen"; + case VhdlDocGen::MISCELLANEOUS: + return "Verschiedenes"; + case VhdlDocGen::UCF_CONST: + return "Constraints"; + default: + return "Klasse"; + } + } + virtual QCString trCustomReference(const char *name) + { return QCString(name)+"-Referenz"; } + + ////////////////////////////////////////////////////////////////////////// }; diff --git a/src/translator_dk.h b/src/translator_dk.h index e98cfa8..70e9032 100644 --- a/src/translator_dk.h +++ b/src/translator_dk.h @@ -116,8 +116,7 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 virtual QCString latexLanguageSupportCommand() { return - "\\usepackage[danish]{babel}\n" - "\\usepackage[T1]{fontenc}\n"; + "\\usepackage[danish]{babel}\n"; } // --- Language translation methods ------------------- diff --git a/src/translator_en.h b/src/translator_en.h index 190ba79..400e59c 100644 --- a/src/translator_en.h +++ b/src/translator_en.h @@ -224,8 +224,16 @@ class TranslatorEnglish : public Translator /*! This is an introduction to the class hierarchy. */ virtual QCString trClassHierarchyDescription() - { return "This inheritance list is sorted roughly, " - "but not completely, alphabetically:"; + { + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return "Here is a hierarchical list of all entities:"; + } + else + { + return "This inheritance list is sorted roughly, " + "but not completely, alphabetically:"; + } } /*! This is an introduction to the list with all files. */ @@ -245,6 +253,10 @@ class TranslatorEnglish : public Translator { return "Here are the data structures with brief descriptions:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Here are the classes with brief descriptions:"; + } else { return "Here are the classes, structs, " @@ -1993,6 +2005,255 @@ class TranslatorEnglish : public Translator } ////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Design Unit Hierarchy"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Design Unit List"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Design Unit Members"; } + /** 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 "Design Unit Index"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Design Units"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Functions/Procedures/Processes"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Library"; + else return "Libraries"; + case VhdlDocGen::PACKAGE: + if (single) return "Package"; + else return "Packages"; + case VhdlDocGen::SIGNAL: + if (single) return "Signal"; + else return "Signals"; + case VhdlDocGen::COMPONENT: + if (single) return "Component"; + else return "Components"; + case VhdlDocGen::CONSTANT: + if (single) return "Constant"; + else return "Constants"; + case VhdlDocGen::ENTITY: + if (single) return "Entity"; + else return "Entities"; + case VhdlDocGen::TYPE: + if (single) return "Type"; + else return "Types"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtype"; + else return "Subtypes"; + case VhdlDocGen::FUNCTION: + if (single) return "Function"; + else return "Functions"; + case VhdlDocGen::RECORD: + if (single) return "Record"; + else return "Records"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedure"; + else return "Procedures"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Architecture"; + else return "Architectures"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Attribute"; + else return "Attributes"; + case VhdlDocGen::PROCESS: + if (single) return "Process"; + else return "Processes"; + case VhdlDocGen::PORT: + if (single) return "Port"; + else return "Ports"; + case VhdlDocGen::USE: + if (single) return "use clause"; + else return "Use Clauses"; + case VhdlDocGen::GENERIC: + if (single) return "Generic"; + else return "Generics"; + case VhdlDocGen::PACKAGE_BODY: + return "Package Body"; + case VhdlDocGen::UNITS: + return "Units"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Shared Variable"; + else return "Shared Variables"; + case VhdlDocGen::VFILE: + if (single) return "File"; + else return "Files"; + case VhdlDocGen::GROUP: + if (single) return "Group"; + else return "Groups"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instantiation"; + else return "Instantiations"; + case VhdlDocGen::ALIAS: + if (single) return "Alias"; + else return "Aliases"; + case VhdlDocGen::CONFIG: + if (single) return "Configuration"; + else return "Configurations"; + case VhdlDocGen::MISCELLANEOUS: + return "Miscellaneous"; + case VhdlDocGen::UCF_CONST: + return "Constraints"; + default: + return "Class"; + } + } + virtual QCString trCustomReference(const char *name) + { return QCString(name)+" Reference"; } + + /* Slice */ + virtual QCString trConstants() + { + return "Constants"; + } + virtual QCString trConstantDocumentation() + { + return "Constant Documentation"; + } + virtual QCString trSequences() + { + return "Sequences"; + } + virtual QCString trSequenceDocumentation() + { + return "Sequence Documentation"; + } + virtual QCString trDictionaries() + { + return "Dictionaries"; + } + virtual QCString trDictionaryDocumentation() + { + return "Dictionary Documentation"; + } + virtual QCString trSliceInterfaces() + { + return "Interfaces"; + } + virtual QCString trInterfaceIndex() + { + return "Interface Index"; + } + virtual QCString trInterfaceList() + { + return "Interface List"; + } + virtual QCString trInterfaceListDescription() + { + return "Here are the interfaces with brief descriptions:"; + } + virtual QCString trInterfaceHierarchy() + { + return "Interface Hierarchy"; + } + virtual QCString trInterfaceHierarchyDescription() + { + return "This inheritance list is sorted roughly, but not completely, alphabetically:"; + } + virtual QCString trInterfaceDocumentation() + { + return "Interface Documentation"; + } + virtual QCString trStructs() + { + return "Structs"; + } + virtual QCString trStructIndex() + { + return "Struct Index"; + } + virtual QCString trStructList() + { + return "Struct List"; + } + virtual QCString trStructListDescription() + { + return "Here are the structs with brief descriptions:"; + } + virtual QCString trStructDocumentation() + { + return "Struct Documentation"; + } + virtual QCString trExceptionIndex() + { + return "Exception Index"; + } + virtual QCString trExceptionList() + { + return "Exception List"; + } + virtual QCString trExceptionListDescription() + { + return "Here are the exceptions with brief descriptions:"; + } + virtual QCString trExceptionHierarchy() + { + return "Exception Hierarchy"; + } + virtual QCString trExceptionHierarchyDescription() + { + return "This inheritance list is sorted roughly, but not completely, alphabetically:"; + } + virtual QCString trExceptionDocumentation() + { + return "Exception Documentation"; + } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result=(QCString)clName; + if (isLocal) result+=" Local"; + switch(compType) + { + case ClassDef::Class: result+=" Class"; break; + case ClassDef::Struct: result+=" Struct"; break; + case ClassDef::Union: result+=" Union"; break; + case ClassDef::Interface: result+=" Interface"; break; + case ClassDef::Protocol: result+=" Protocol"; break; + case ClassDef::Category: result+=" Category"; break; + case ClassDef::Exception: result+=" Exception"; break; + default: break; + } + result+=" Reference"; + return result; + } + virtual QCString trOperations() + { + return "Operations"; + } + virtual QCString trOperationDocumentation() + { + return "Operation Documentation"; + } + virtual QCString trDataMembers() + { + return "Data Members"; + } + virtual QCString trDataMemberDocumentation() + { + return "Data Member Documentation"; + } + +////////////////////////////////////////////////////////////////////////// }; diff --git a/src/translator_es.h b/src/translator_es.h index 8922297..b28ed75 100644 --- a/src/translator_es.h +++ b/src/translator_es.h @@ -34,7 +34,7 @@ * Updated to 1.8.4 by Bartomeu Creus Navarro (17-julio-2013) */ -class TranslatorSpanish : public Translator +class TranslatorSpanish : public TranslatorAdapter_1_8_15 { public: @@ -2057,6 +2057,254 @@ class TranslatorSpanish : public Translator } ////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Jerarquía de unidades de diseño"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Lista de unidades de diseño"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Miembros de las unidades de diseño"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Aquí hay una lista de todos los miembros de la unidad de diseño con " + "enlaces a las entidades a las que pertenecen:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Indice de unidades de diseño"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Unidades de Diseño"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funciones/Procedimientos/Procesos"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Libreria"; + else return "Librerias"; + case VhdlDocGen::PACKAGE: + if (single) return "Paquete"; + else return "Paquetes"; + case VhdlDocGen::SIGNAL: + if (single) return "Señal"; + else return "Señales"; + case VhdlDocGen::COMPONENT: + if (single) return "Componente"; + else return "Componentes"; + case VhdlDocGen::CONSTANT: + if (single) return "Constante"; + else return "Constantes"; + case VhdlDocGen::ENTITY: + if (single) return "Entidad"; + else return "Entidades"; + case VhdlDocGen::TYPE: + if (single) return "Tipo"; + else return "Tipos"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtipo"; + else return "Subtipos"; + case VhdlDocGen::FUNCTION: + if (single) return "Función"; + else return "Funciones"; + case VhdlDocGen::RECORD: + if (single) return "Registro"; + else return "Registros"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedimiento"; + else return "Procedimientos"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Arquitectura"; + else return "Arquitecturas"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Atributo"; + else return "Atributos"; + case VhdlDocGen::PROCESS: + if (single) return "Proceso"; + else return "Procesos"; + case VhdlDocGen::PORT: + if (single) return "Puerto"; + else return "Puertos"; + case VhdlDocGen::USE: + if (single) return "cláusula de uso"; + else return "Cláusulas de uso"; + case VhdlDocGen::GENERIC: + if (single) return "Genérico"; + else return "Genéricos"; + case VhdlDocGen::PACKAGE_BODY: + return "Cuerpo del paquete"; + case VhdlDocGen::UNITS: + return "Unidades"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Variable Compartida"; + else return "Variable Compartidas"; + case VhdlDocGen::VFILE: + if (single) return "Fichero"; + else return "Ficheros"; + case VhdlDocGen::GROUP: + if (single) return "Grupo"; + else return "Grupos"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instanciación"; + else return "Instanciaciones"; + case VhdlDocGen::ALIAS: + if (single) return "Alias"; + else return "Aliases"; + case VhdlDocGen::CONFIG: + if (single) return "Configuración"; + else return "Configuraciones"; + case VhdlDocGen::MISCELLANEOUS: + return "Varios"; + case VhdlDocGen::UCF_CONST: + return "Restricciones"; + default: + return "Clase"; + } + } + virtual QCString trCustomReference(const char *name) + { return "Referencia"+QCString(name); } + + virtual QCString trConstants() + { + return "Constantes"; + } + virtual QCString trConstantDocumentation() + { + return "Documentación de constante"; + } + virtual QCString trSequences() + { + return "Secuencias"; + } + virtual QCString trSequenceDocumentation() + { + return "Documentación de secuencia"; + } + virtual QCString trDictionaries() + { + return "Diccionarios"; + } + virtual QCString trDictionaryDocumentation() + { + return "Documentación de diccionario"; + } + virtual QCString trSliceInterfaces() + { + return "Interfaces"; + } + virtual QCString trInterfaceIndex() + { + return "Indice de interfaces"; + } + virtual QCString trInterfaceList() + { + return "Lista de interfaces"; + } + virtual QCString trInterfaceListDescription() + { + return "Aquí están las interfaces con una breve descripción:"; + } + virtual QCString trInterfaceHierarchy() + { + return "Jerarquía de interfaces"; + } + virtual QCString trInterfaceHierarchyDescription() + { + return "Este listado de herencia está ordenado de forma aproximada, pero no completamente en orden alfabético:"; + } + virtual QCString trInterfaceDocumentation() + { + return "Documentación de interfaz"; + } + virtual QCString trStructs() + { + return "Estructuras"; + } + virtual QCString trStructIndex() + { + return "Indice de estructuras"; + } + virtual QCString trStructList() + { + return "Lista de estructuras"; + } + virtual QCString trStructListDescription() + { + return "Aquí están las estructuras de datos con una breve descripción:"; + } + virtual QCString trStructDocumentation() + { + return "Documentación estructura"; + } + virtual QCString trExceptionIndex() + { + return "Indice de excepciones"; + } + virtual QCString trExceptionList() + { + return "Lista de excepciones"; + } + virtual QCString trExceptionListDescription() + { + return "Aquí están las excepciones con una breve descripción:"; + } + virtual QCString trExceptionHierarchy() + { + return "Jerarquía de excepciones"; + } + virtual QCString trExceptionHierarchyDescription() + { + return "Este listado de herencia está ordenado de forma aproximada, pero no completamente en orden alfabético:"; + } + virtual QCString trExceptionDocumentation() + { + return "Documentación de excepción"; + } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result="Referencia de"; + switch(compType) + { + case ClassDef::Class: result+=" la Clase"; break; + case ClassDef::Struct: result+=" la Estructura"; break; + case ClassDef::Union: result+=" la Unión"; break; + case ClassDef::Interface: result+=" la Interfaz"; break; + case ClassDef::Protocol: result+="l Protocolo"; break; + case ClassDef::Category: result+=" la Categoría"; break; + case ClassDef::Exception: result+=" la Excepción"; break; + default: break; + } + if (isLocal) result+=" Local"; + result+=(QCString)clName; + return result; + } + virtual QCString trOperations() + { + return "Operaciones"; + } + virtual QCString trOperationDocumentation() + { + return "Documentación de operación"; + } + virtual QCString trDataMembers() + { + return "Miembros de datos"; + } + virtual QCString trDataMemberDocumentation() + { + return "Documentación miembro de datos"; + } + +////////////////////////////////////////////////////////////////////////// }; diff --git a/src/translator_fr.h b/src/translator_fr.h index 9775a29..f355619 100644 --- a/src/translator_fr.h +++ b/src/translator_fr.h @@ -103,7 +103,7 @@ // Translator class (by the local maintainer) when the localized // translator is made up-to-date again. -class TranslatorFrench : public Translator +class TranslatorFrench : public TranslatorAdapter_1_8_15 { public: @@ -2055,6 +2055,258 @@ class TranslatorFrench : public Translator } ////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Hiérarchie des unités de conception"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Liste des unités de conception"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Membres des unités de conception"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Liste de tous les membres des unités de conception avec liens vers " + "les entités auxquelles ils appartiennent :"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Index des unités de conception"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Unités de conception"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Fonctions/Procédures/Processes"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Librairie"; + else return "Librairies"; + case VhdlDocGen::PACKAGE: + if (single) return "Paquetage"; + else return "Paquetages"; + case VhdlDocGen::SIGNAL: + if (single) return "Signal"; + else return "Signaux"; + case VhdlDocGen::COMPONENT: + if (single) return "Composant"; + else return "Composants"; + case VhdlDocGen::CONSTANT: + if (single) return "Constante"; + else return "Constantes"; + case VhdlDocGen::ENTITY: + if (single) return "Entité"; + else return "Entités"; + case VhdlDocGen::TYPE: + if (single) return "Type"; + else return "Types"; + case VhdlDocGen::SUBTYPE: + if (single) return "Sous-type"; + else return "Sous-types"; + case VhdlDocGen::FUNCTION: + if (single) return "Fonction"; + else return "Fonctions"; + case VhdlDocGen::RECORD: + if (single) return "Enregistrement"; + else return "Enregistrements"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procédure"; + else return "Procédures"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Architecture"; + else return "Architectures"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Attribut"; + else return "Attributs"; + case VhdlDocGen::PROCESS: + if (single) return "Process"; + else return "Processes"; + case VhdlDocGen::PORT: + if (single) return "Port"; + else return "Ports"; + case VhdlDocGen::USE: + if (single) return "Clause d'utilisation"; + else return "Clauses d'utilisation"; + case VhdlDocGen::GENERIC: + if (single) return "Generique"; + else return "Generiques"; + case VhdlDocGen::PACKAGE_BODY: + return "Corps du paquetage"; + case VhdlDocGen::UNITS: + return "Unités"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Variable partagée"; + else return "Variables partagées"; + case VhdlDocGen::VFILE: + if (single) return "Fichier"; + else return "Fichiers"; + case VhdlDocGen::GROUP: + if (single) return "Groupe"; + else return "Groupes"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instanciation"; + else return "Instanciations"; + case VhdlDocGen::ALIAS: + if (single) return "Alias"; + else return "Alias"; + case VhdlDocGen::CONFIG: + if (single) return "Configuration"; + else return "Configurations"; + case VhdlDocGen::MISCELLANEOUS: + return "Divers"; + case VhdlDocGen::UCF_CONST: + return "Contraintes"; + default: + return "Classe"; + } + } + virtual QCString trCustomReference(const char *name) + { return QCString("Référence ") + QCString(name); } + + virtual QCString trConstants() + { + return "Constantes"; + } + virtual QCString trConstantDocumentation() + { + return "Documentation des constantes"; + } + virtual QCString trSequences() + { + return "Séquences"; + } + virtual QCString trSequenceDocumentation() + { + return "Documentation des séquences"; + } + virtual QCString trDictionaries() + { + return "Dictionnaires"; + } + virtual QCString trDictionaryDocumentation() + { + return "Documentation des dictionnaires"; + } + virtual QCString trSliceInterfaces() + { + return "Interfaces"; + } + virtual QCString trInterfaceIndex() + { + return "Index des interfaces"; + } + virtual QCString trInterfaceList() + { + return "Liste des interfaces"; + } + virtual QCString trInterfaceListDescription() + { + return "Liste des interfaces avec une brève description :"; + } + virtual QCString trInterfaceHierarchy() + { + return "Hiérarchies des interfaces"; + } + virtual QCString trInterfaceHierarchyDescription() + { + return "Cette liste d'héritage est classée approximativement par ordre alphabétique :"; + } + virtual QCString trInterfaceDocumentation() + { + return "Documentation des interfaces"; + } + virtual QCString trStructs() + { + return "Structures"; + } + virtual QCString trStructIndex() + { + return "Index des structures"; + } + virtual QCString trStructList() + { + return "Liste des structures"; + } + virtual QCString trStructListDescription() + { + return "Liste des structures avec une brève description :"; + } + virtual QCString trStructDocumentation() + { + return "Documentation des structures"; + } + virtual QCString trExceptionIndex() + { + return "Index des exceptions"; + } + virtual QCString trExceptionList() + { + return "Liste des exceptions"; + } + virtual QCString trExceptionListDescription() + { + return "Liste des exceptions avec une brève description :"; + } + virtual QCString trExceptionHierarchy() + { + return "Hiérarchies des exceptions"; + } + virtual QCString trExceptionHierarchyDescription() + { + return "Cette liste d'héritage est classée approximativement par ordre alphabétique :"; + } + virtual QCString trExceptionDocumentation() + { + return "Documentation des exceptions"; + } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result = "Référence de "; + + switch(compType) + { + case ClassDef::Class: result+="la classe "; break; + case ClassDef::Struct: result+="la structure "; break; + case ClassDef::Interface: result+="l'interface "; break; + case ClassDef::Exception: result+="l'exception "; break; + default: break; + } + + if(isLocal) + { + result += "locale "; + } + + result += (QCString)clName; + + return result; + } + virtual QCString trOperations() + { + return "Opérations"; + } + virtual QCString trOperationDocumentation() + { + return "Documentation des opérations"; + } + virtual QCString trDataMembers() + { + return "Champs de données"; + } + virtual QCString trDataMemberDocumentation() + { + return "Documentation des champs de données"; + } + +////////////////////////////////////////////////////////////////////////// }; diff --git a/src/translator_gr.h b/src/translator_gr.h index 8b7afe1..6ed43db 100644 --- a/src/translator_gr.h +++ b/src/translator_gr.h @@ -42,7 +42,7 @@ #ifndef TRANSLATOR_GR_H #define TRANSLATOR_GR_H -class TranslatorGreek : public Translator +class TranslatorGreek : public TranslatorAdapter_1_8_15 { public: @@ -59,8 +59,8 @@ class TranslatorGreek : public Translator virtual QCString latexLanguageSupportCommand() { - //return "\\usepackage[greek,english]{babel}\n\\usepackage[iso-8859-7]{inputenc}\n"; - return "\\usepackage[greek,english]{babel}\n"; + return "\\usepackage[greek,english]{babel}\n" + "\\usepackage{alphabeta}\n"; } // --- Language translation methods ------------------- diff --git a/src/translator_hu.h b/src/translator_hu.h index 17f0d44..44363c9 100644 --- a/src/translator_hu.h +++ b/src/translator_hu.h @@ -13,21 +13,46 @@ * */ - /* - * Original Hungarian translation by - * György Földvári <foldvari@diatronltd.com> - * - * Extended, revised and updated by - * Ákos Kiss <akiss@users.sourceforge.net> - * - * Further extended, revised and updated by - * Tamási Ferenc <tf551@hszk.bme.hu> - */ +/* + * Original Hungarian translation by + * György Földvári <foldvari@diatronltd.com> + * + * Extended, revised and updated by + * Ákos Kiss <akiss@users.sourceforge.net> + * + * Further extended, revised and updated by + * Ferenc Tamási <tf551@hszk.bme.hu> + * + * Further extended, since 1.4.6 to 1.8.4 + * László Kmety <silverkml@gmail.com> + */ #ifndef TRANSLATOR_HU_H #define TRANSLATOR_HU_H -class TranslatorHungarian : public TranslatorAdapter_1_4_6 +/*! + 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. +*/ +class TranslatorHungarian : public TranslatorAdapter_1_8_15 { private: const char * zed(char c) @@ -45,12 +70,29 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 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 "hungarian"; } - /*! Used to get the command(s) for the language support. This method - * was designed for languages which do not prefer babel package. - * If this methods returns empty string, then the latexBabelPackage() - * method is used to generate the command for using the babel package. + + /*! 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() { @@ -117,6 +159,9 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 virtual QCString trIncludingInheritedMembers() { return " osztály tagjainak teljes listája, az örökölt tagokkal együtt."; } + /*! this is put at the author sections at the bottom of man pages. + * parameter s is name of the project name. + */ virtual QCString trGeneratedAutomatically(const char *s) { QCString result="Ezt a dokumentációt a Doxygen készítette "; if (s) result+=(QCString)" a" + zed(s[0])+s+(QCString)" projekthez"; @@ -243,7 +288,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 } if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - result+="struktúra- és úniómező"; + result+="struktúra- és uniómező"; } else { @@ -254,7 +299,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 { if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - result+="a megfelelő struktúra-/úniódokumentációra minden mezőnél:"; + result+="a megfelelő struktúra/unió dokumentációra minden mezőnél:"; } else { @@ -265,7 +310,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 { if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - result+="a struktúrákra/úniókra, amikhez tartoznak:"; + result+="a struktúrákra/uniókra, amikhez tartoznak:"; } else { @@ -575,8 +620,8 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 case ClassDef::Struct: result+=" struktúra"; break; case ClassDef::Union: result+=" unió"; break; case ClassDef::Interface: result+=" interfész"; break; - case ClassDef::Protocol: result+=" protocol"; break; // translate me! - case ClassDef::Category: result+=" category"; break; // translate me! + case ClassDef::Protocol: result+=" protokoll"; break; + case ClassDef::Category: result+=" kategória"; break; case ClassDef::Exception: result+=" kivétel"; break; default: break; } @@ -726,8 +771,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 */ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single) - { // here s is one of " Class", " Struct" or " Union" - // single is true implies a single file + { // single is true implies a single file QCString result=(QCString)"Ez a dokumentáció "; switch(compType) { @@ -735,8 +779,8 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 case ClassDef::Struct: result+="a struktúráról"; break; case ClassDef::Union: result+="az unióról"; break; case ClassDef::Interface: result+="az interfészről"; break; - case ClassDef::Protocol: result+="protocol"; break; // translate me! - case ClassDef::Category: result+="category"; break; // translate me! + case ClassDef::Protocol: result+="a protokollról"; break; + case ClassDef::Category: result+="a kategóriáról"; break; case ClassDef::Exception: result+="a kivételről"; break; default: break; } @@ -960,7 +1004,9 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 { return "Jelmagyarázat"; } - /*! page explaining how the dot graph's should be interpreted */ + /*! 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 @@ -995,29 +1041,31 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 " Used *m_usedClass;\n" "};\n" "\\endcode\n" - "Ha a konfigurációs fájl \\c MAX_DOT_GRAPH_HEIGHT elemének értékét " - "240-re állítjuk, az eredmény a következő ábra lesz:" - "<p><center><img src=\"graph_legend."+getDotImageExtension()+"\"></center>\n" + "Az eredmény a következő ábra lesz:" + "<p><center><img alt=\"\" src=\"graph_legend."+getDotImageExtension()+"\"></center></p>\n" "<p>\n" - "Az ábrán levő dobozok jelentése:\n" + "A fenti ábrán levő dobozok jelentése a következő:\n" "<ul>\n" "<li>Kitöltött fekete doboz jelzi azt az osztályt vagy struktúrát," - "amelyről az ábra szól.\n" - "<li>Fekete keret jelzi a dokumentált osztályokat és struktúrákat.\n" - "<li>Szürke keret jelzi a nem dokumentált osztályokat és struktúrákat.\n" + "amelyről az ábra szól.</li>\n" + "<li>Fekete keret jelzi a dokumentált osztályokat és struktúrákat.</li>\n" + "<li>Szürke keret jelzi a nem dokumentált osztályokat és struktúrákat.</li>\n" "<li>Piros keret jelzi azokat az osztályokat és struktúrákat, amelyeknél vágás miatt nem látható " "az összes leszármaztatási kapcsolat. Egy ábra vágásra kerül, ha nem fér bele " - "a megadott tartományba." + "a megadott tartományba.</li>\n" "</ul>\n" - "A nyilak jelentése:\n" + "<p>\n" + "A nyilak jelentése a következő:\n" + "</p>\n" "<ul>\n" - "<li>Sötétkék nyíl jelzi a publikus származtatást.\n" - "<li>Sötétzöld nyíl jelzi a védett származtatást.\n" - "<li>Sötétvörös nyíl jelzi a privát származtatást.\n" + "<li>Sötétkék nyíl jelzi a publikus származtatás " + "kapcsolatát két osztály között.</li>\n" + "<li>Sötétzöld nyíl jelzi a védett származtatást.</li>\n" + "<li>Sötétvörös nyíl jelzi a privát származtatást.</li>\n" "<li>Lila szaggatott nyíl jelzi, ha az osztály egy másikat használ vagy tartalmaz. " - "A nyíl felirata jelzi a változó(k) nevét, amelyeken keresztül a másik osztály kapcsolódik.\n" + "A nyíl felirata jelzi a változó(k) nevét, amelyeken keresztül a másik osztály kapcsolódik.</li>\n" "<li>Sárga szaggatott nyíl jelzi a kapcsolatot a sablonpéldány és a példányosított " - "osztálysablon között. A nyíl felirata jelzi a pélány sablonparamétereit.\n" + "osztálysablon között. A nyíl felirata jelzi a pélány sablonparamétereit.</li>\n" "</ul>\n"; } @@ -1086,7 +1134,7 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 /*! The description of the package index page */ virtual QCString trPackageListDescription() { - return "A csomagok rövid leírásai (amennyiben léteznek):"; + return "A csomagok rövid leírásai (ha léteznek):"; } /*! The link name in the Quick links header for each page */ virtual QCString trPackages() @@ -1167,10 +1215,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trClass(bool first_capital, bool /*singular*/) + virtual QCString trClass(bool first_capital, bool singular) { QCString result((first_capital ? "Osztály" : "osztály")); - //if (!singular) result+="es"; + //if (!singular) result+="ok"; return result; } @@ -1178,10 +1226,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trFile(bool first_capital, bool /*singular*/) + virtual QCString trFile(bool first_capital, bool singular) { QCString result((first_capital ? "Fájl" : "fájl")); - //if (!singular) result+="s"; + if (!singular) result+="ok"; return result; } @@ -1189,10 +1237,11 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trNamespace(bool first_capital, bool /*singular*/) + virtual QCString trNamespace(bool first_capital, bool singular) { - QCString result((first_capital ? "Névtér" : "névtér")); - //if (!singular) result+="s"; + QCString result(""); + if (!singular) result+=first_capital ? "Névterek" : "névterek"; + else result+=first_capital ? "Névtér" : "névtér"; return result; } @@ -1200,10 +1249,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trGroup(bool first_capital, bool /*singular*/) + virtual QCString trGroup(bool first_capital, bool singular) { - QCString result((first_capital ? "Csoport" : "csoport")); - //if (!singular) result+="s"; + QCString result((first_capital ? "Modul" : "modul")); + if (!singular) result+="ok"; return result; } @@ -1211,10 +1260,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trPage(bool first_capital, bool /*singular*/) + virtual QCString trPage(bool first_capital, bool singular) { QCString result((first_capital ? "Oldal" : "oldal")); - //if (!singular) result+="s"; + if (!singular) result+="ak"; return result; } @@ -1222,10 +1271,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trMember(bool first_capital, bool /*singular*/) + virtual QCString trMember(bool first_capital, bool singular) { QCString result((first_capital ? "Tag" : "tag")); - //if (!singular) result+="s"; + if (!singular) result+="ok"; return result; } @@ -1233,10 +1282,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 * be followed by a single name or by a list of names * of the category. */ - virtual QCString trGlobal(bool first_capital, bool /*singular*/) + virtual QCString trGlobal(bool first_capital, bool singular) { QCString result((first_capital ? "Globális elem" : "globális elem")); - //if (!singular) result+="s"; + if (!singular) result+="ek"; return result; } @@ -1490,9 +1539,490 @@ class TranslatorHungarian : public TranslatorAdapter_1_4_6 */ virtual QCString trOverloadText() { - return "Ez egy túlterhelt tagfüggvény." - "A fenti függvénytől csak argumentumaiban különbözik."; + return "Ez egy túlterhelt tagfüggvény, " + "a kényelem érdekében. A fenti függvénytől csak abban különbözik, " + "hogy milyen argumentumokat fogad el."; + } + + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.6 +////////////////////////////////////////////////////////////////////////// + + /*! This is used to introduce a caller (or called-by) graph */ + virtual QCString trCallerGraph() + { + return "A függvény hívó gráfja:"; + } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration values + */ + virtual QCString trEnumerationValueDocumentation() + { return "Enumerációs-érték dokumentáció"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.5.4 (mainly for Fortran) +////////////////////////////////////////////////////////////////////////// + + /*! header that is put before the list of member subprograms (Fortran). */ + virtual QCString trMemberFunctionDocumentationFortran() + { return "Tagfüggvény/Alprogram dokumentáció"; } + + /*! This is put above each page as a link to the list of annotated data types (Fortran). */ + virtual QCString trCompoundListFortran() + { return "Adattípusok listája"; } + + /*! This is put above each page as a link to all members of compounds (Fortran). */ + virtual QCString trCompoundMembersFortran() + { return "Adatmezők"; } + + /*! This is an introduction to the annotated compound list (Fortran). */ + virtual QCString trCompoundListDescriptionFortran() + { return "Rövid leírással ellátott adattípusok:"; } + + /*! This is an introduction to the page with all data types (Fortran). */ + virtual QCString trCompoundMembersDescriptionFortran(bool extractAll) + { + QCString result="Az összes "; + if (!extractAll) + { + result+="dokumentált "; + } + result+="adattípusú tagváltozó"; + result+=" hivatkozásokkal ellátva "; + if (!extractAll) + { + result+="az egyes adattagok adatszerkezetének dokumentációjára"; + } + else + { + result+="azokhoz az adattípusokhoz, amelyekhez tartoznak:"; + } + return result; + } + /*! This is used in LaTeX as the title of the chapter with the + * annotated compound index (Fortran). + */ + virtual QCString trCompoundIndexFortran() + { return "Adattípus index"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all data types (Fortran). + */ + virtual QCString trTypeDocumentation() + { return "Adattípus dokumentáció"; } + /*! This is used in the documentation of a file as a header before the + * list of (global) subprograms (Fortran). + */ + virtual QCString trSubprograms() + { return "Függvények/Alprogramok"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for subprograms (Fortran) + */ + virtual QCString trSubprogramDocumentation() + { return "Függvény/Alprogram dokumentáció"; } + + /*! This is used in the documentation of a file/namespace/group before + * the list of links to documented compounds (Fortran) + */ + virtual QCString trDataTypes() + { return "Adattípusok"; } + + /*! used as the title of page containing all the index of all modules (Fortran). */ + virtual QCString trModulesList() + { return "Modulok listája"; } + + /*! used as an introduction to the modules list (Fortran) */ + virtual QCString trModulesListDescription(bool extractAll) + { + QCString result="Az összes "; + if (!extractAll) result+="dokumentált "; + result+="rövid leírással ellátott modul:"; + return result; + } + + /*! used as the title of the HTML page of a module/type (Fortran) */ + virtual QCString trCompoundReferenceFortran(const char *clName, + ClassDef::CompoundType compType, + bool isTemplate) + { + QCString result=(QCString)clName; + switch(compType) + { + case ClassDef::Class: result+=" modul"; break; + case ClassDef::Struct: result+=" típus"; break; + case ClassDef::Union: result+=" unió"; break; + case ClassDef::Interface: result+=" interfész"; break; + case ClassDef::Protocol: result+=" protokoll"; break; + case ClassDef::Category: result+=" kategória"; break; + case ClassDef::Exception: result+=" kivétel"; break; + default: break; + } + if (isTemplate) result+=" sablon"; + result+=" hivatkozás"; + return result; + } + /*! used as the title of the HTML page of a module (Fortran) */ + virtual QCString trModuleReference(const char *namespaceName) + { + QCString result=namespaceName; + result+=" modul hivatkozás"; + return result; + } + + /*! This is put above each page as a link to all members of modules. (Fortran) */ + virtual QCString trModulesMembers() + { return "Modul adattagok"; } + + /*! This is an introduction to the page with all modules members (Fortran) */ + virtual QCString trModulesMemberDescription(bool extractAll) + { + QCString result="Az összes "; + if (!extractAll) result+="dokumentált "; + result+="modul adattagja hivatkozásokkal ellátva "; + if (extractAll) + { + result+="az egyes adattagok moduljainak dokumentációjára:"; + } + else + { + result+="azokhoz a modulokhoz, amelyekhez tartoznak:"; + } + return result; + } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all modules (Fortran). + */ + virtual QCString trModulesIndex() + { return "Modulok indexe"; } + + /*! 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 ? "Modul" : "modul")); + if (!singular) result+="s"; + 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)"Ez a dokumentáció "; + switch(compType) + { + case ClassDef::Class: result+="a modulról"; break; + case ClassDef::Struct: result+="a típusról"; break; + case ClassDef::Union: result+="az unióról"; break; + case ClassDef::Interface: result+="az interfészról"; break; + case ClassDef::Protocol: result+="a protokollról"; break; + case ClassDef::Category: result+="a kategóriáról"; break; + case ClassDef::Exception: result+="a kivételről"; break; + default: break; + } + result+=" a következő fájl"; + if (!single) result+="ok"; + result+=" alapján készült:"; + 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 ? "Típus" : "típus")); + if (!singular) result+="ok"; + 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 ? "Alprogram" : "alprogram")); + if (!singular) result+="ok"; + return result; + } + + /*! C# Type Constraint list */ + virtual QCString trTypeConstraints() + { + return "Típuskorlátozások"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.6.0 (mainly for the new search engine) +////////////////////////////////////////////////////////////////////////// + + /*! directory relation for \a name */ + virtual QCString trDirRelation(const char *name) + { + return QCString(name)+" kapcsolat"; + } + + /*! Loading message shown when loading search results */ + virtual QCString trLoading() + { + return "Betöltés..."; + } + + /*! Label used for search results in the global namespace */ + virtual QCString trGlobalNamespace() + { + return "Globális névtér"; + } + + /*! Message shown while searching */ + virtual QCString trSearching() + { + return "Keresés..."; + } + + /*! Text shown when no search results are found */ + virtual QCString trNoMatches() + { + return "Nincs egyezés"; + } + +////////////////////////////////////////////////////////////////////////// +// 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 char *name) + { + return (QCString)"Fájl a(z) "+name+" könyvtárban"; + } + + /*! 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 char *name) + { + return (QCString)"Tartalmazott fájl a(z) "+name+" könyvtárban"; + } + + /** 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[] = { "Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat","Vasárnap" }; + static const char *months[] = { "Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December" }; + 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 "Bibliográfia"; } + + /*! Text for copyright paragraph */ + virtual QCString trCopyright() + { return "Szerzői jog"; } + + /*! Header for the graph showing the directory dependencies */ + virtual QCString trDirDepGraph(const char *name) + { return QCString("Könyvtár függőségi gráf a(z) ")+name+"-könyvtárhoz:"; } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.0 +////////////////////////////////////////////////////////////////////////// + + /*! Detail level selector shown for hierarchical indices */ + virtual QCString trDetailLevel() + { return "részletességi szint"; } + + /*! Section header for list of template parameters */ + virtual QCString trTemplateParameters() + { return "Sablon paraméterek"; } + + /*! Used in dot graph when UML_LOOK is enabled and there are many fields */ + virtual QCString trAndMore(const QCString &number) + { return "és "+number+" elemmel több..."; } + + /*! Used file list for a Java enum */ + virtual QCString trEnumGeneratedFromFiles(bool single) + { QCString result = "A dokumentáció ehhez az enum-hoz a következő fájl"; + if (!single) result+="ok"; + result+=" alapján készült:"; + return result; + } + + /*! Header of a Java enum page (Java enums are represented as classes). */ + virtual QCString trEnumReference(const char *name) + { return QCString(name)+" felsoroló referencia"; } + + /*! Used for a section containing inherited members */ + virtual QCString trInheritedFrom(const char *members,const char *what) + { return QCString(members)+" a(z) "+what+" osztályból származnak"; } + + /*! Header of the sections with inherited members specific for the + * base class(es) + */ + virtual QCString trAdditionalInheritedMembers() + { return "További örökölt tagok"; } + +////////////////////////////////////////////////////////////////////////// +// 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 ? "engedélyez" : "letilt"; + return "Kattintson a(z) "+opt+" panel synchronisation"; + } + + /*! 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 kategória szerint."; + } + + /*! 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 kiterjesztett osztály."; + } + + /*! 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 "Osztály metódusok"; + } + + /*! 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 "Példány metódusok"; + } + + /*! Used as the header of the member functions of an Objective-C class. + */ + virtual QCString trMethodDocumentation() + { + return "Metódus dokumentáció"; + } + + /*! Used as the title of the design overview picture created for the + * VHDL output. + */ + virtual QCString trDesignOverview() + { + return "Dizájn áttekintés"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.8.4 +////////////////////////////////////////////////////////////////////////// + + /** old style UNO IDL services: implemented interfaces */ + virtual QCString trInterfaces() + { return "Exportált interfészek"; } + + /** old style UNO IDL services: inherited services */ + virtual QCString trServices() + { return "Mellékelt szolgáltatások"; } + + /** UNO IDL constant groups */ + virtual QCString trConstantGroups() + { return "Konstans csoportok"; } + + /** UNO IDL constant groups */ + virtual QCString trConstantGroupReference(const char *namespaceName) + { + QCString result=namespaceName; + result+=" konstans csoport referencia"; + return result; + } + /** UNO IDL service page title */ + virtual QCString trServiceReference(const char *sName) + { + QCString result=(QCString)sName; + result+=" szolgáltatás referencia"; + return result; + } + /** UNO IDL singleton page title */ + virtual QCString trSingletonReference(const char *sName) + { + QCString result=(QCString)sName; + result+=" egyke példány referencia"; + return result; + } + /** UNO IDL service page */ + virtual QCString trServiceGeneratedFromFiles(bool single) + { + // single is true implies a single file + QCString result=(QCString)"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:"; + return result; + } + /** UNO IDL singleton page */ + virtual QCString trSingletonGeneratedFromFiles(bool single) + { + // single is true implies a single file + QCString result=(QCString)"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:"; + return result; + } + +////////////////////////////////////////////////////////////////////////// + }; #endif diff --git a/src/translator_it.h b/src/translator_it.h index 8f08b5a..9638a01 100644 --- a/src/translator_it.h +++ b/src/translator_it.h @@ -89,7 +89,7 @@ #ifndef TRANSLATOR_IT_H #define TRANSLATOR_IT_H -class TranslatorItalian : public Translator +class TranslatorItalian : public TranslatorAdapter_1_8_15 { public: diff --git a/src/translator_je.h b/src/translator_je.h index 835a516..d555421 100644 --- a/src/translator_je.h +++ b/src/translator_je.h @@ -36,7 +36,19 @@ class TranslatorJapaneseEn : public TranslatorEnglish { return "japanese-en"; } virtual QCString latexLanguageSupportCommand() { - return "platex"; + return "\\usepackage{CJKutf8}\n"; + } + virtual QCString latexFontenc() + { + return ""; + } + virtual QCString latexDocumentPre() + { + return "\\begin{CJK}{UTF8}{min}\n"; + } + virtual QCString latexDocumentPost() + { + return "\\end{CJK}\n"; } virtual QCString trRTFansicp() { diff --git a/src/translator_jp.h b/src/translator_jp.h index c4f92c2..fc0d65d 100644 --- a/src/translator_jp.h +++ b/src/translator_jp.h @@ -69,7 +69,7 @@ Doxygen の開発の方でもそれはそれでいーんじゃん?みたいな #ifndef TRANSLATOR_JP_H #define TRANSLATOR_JP_H -class TranslatorJapanese : public Translator +class TranslatorJapanese : public TranslatorAdapter_1_8_15 { public: virtual QCString idLanguage() @@ -77,8 +77,20 @@ class TranslatorJapanese : public Translator virtual QCString latexLanguageSupportCommand() { + return "\\usepackage{CJKutf8}\n"; + } + virtual QCString latexFontenc() + { return ""; } + virtual QCString latexDocumentPre() + { + return "\\begin{CJK}{UTF8}{min}\n"; + } + virtual QCString latexDocumentPost() + { + return "\\end{CJK}\n"; + } /*! used in the compound documentation before a list of related functions. */ virtual QCString trRelatedFunctions() diff --git a/src/translator_ke.h b/src/translator_ke.h index 525cf84..c9f488c 100644 --- a/src/translator_ke.h +++ b/src/translator_ke.h @@ -35,12 +35,22 @@ class TranslatorKoreanEn : public TranslatorEnglish { return "korean-en"; } virtual QCString latexLanguageSupportCommand() { - return "\\usepackage{hfont}\n"; + return "\\usepackage{kotex}\n"; } virtual QCString trRTFansicp() { return "949"; } + virtual QCString latexCommandName() + { + QCString latex_command = Config_getString(LATEX_CMD_NAME); + if (latex_command.isEmpty()) latex_command = "latex"; + if (Config_getBool(USE_PDFLATEX)) + { + if (latex_command == "latex") latex_command = "xelatex"; + } + return latex_command; + } /*! Used as ansicpg for RTF fcharset * \see trRTFansicp() for a table of possible values. diff --git a/src/translator_kr.h b/src/translator_kr.h index 7e95e3b..fb1c356 100644 --- a/src/translator_kr.h +++ b/src/translator_kr.h @@ -48,7 +48,7 @@ Translator class (by the local maintainer) when the localized translator is made up-to-date again. */ -class TranslatorKorean : public Translator +class TranslatorKorean : public TranslatorAdapter_1_8_15 { protected: friend class TranslatorAdapterBase; @@ -86,7 +86,17 @@ class TranslatorKorean : public Translator // I'm not sure what this should be. // When I figure it out, I'll update this. // see http://www.ktug.or.kr/jsboard/read.php?table=operate&no=4422&page=1 - return "\\usepackage{hfont}\n"; + return "\\usepackage{kotex}\n"; + } + virtual QCString latexCommandName() + { + QCString latex_command = Config_getString(LATEX_CMD_NAME); + if (latex_command.isEmpty()) latex_command = "latex"; + if (Config_getBool(USE_PDFLATEX)) + { + if (latex_command == "latex") latex_command = "xelatex"; + } + return latex_command; } // --- Language translation methods ------------------- diff --git a/src/translator_lv.h b/src/translator_lv.h index 2736bb0..bd579da 100644 --- a/src/translator_lv.h +++ b/src/translator_lv.h @@ -76,7 +76,7 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 */ virtual QCString latexLanguageSupportCommand() { - return "\\usepackage[LV]{fontenc}\n" + return "\\usepackage[T2A]{fontenc}\n" "\\usepackage[latvian]{babel}\n"; } diff --git a/src/translator_nl.h b/src/translator_nl.h index 241cf97..7cecc7d 100644 --- a/src/translator_nl.h +++ b/src/translator_nl.h @@ -93,8 +93,15 @@ class TranslatorDutch : public Translator QCString trSearch() { return "Zoeken"; } QCString trClassHierarchyDescription() - { return "Deze inheritance lijst is min of meer alfabetisch " - "gesorteerd:"; + { + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) + { + return "Hieronder is een hiërarchische lijst met alle entiteiten:"; + } + else + { + return "Deze inheritance lijst is min of meer alfabetisch gesorteerd:"; + } } QCString trFileListDescription(bool extractAll) { @@ -1586,6 +1593,198 @@ class TranslatorDutch : public Translator } ////////////////////////////////////////////////////////////////////////// +// new since 1.8.15 +////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Ontwerp Eenheid Hiërarchie"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Ontwerp Eenheid Lijst"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Ontwerp Eenheid Members"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "hieronder volgt de lijst met all ontwerp eenheden met links " + "naar de entiteiten waar ze bij behoren:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Ontwerp Eenheid Index"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Ontwerp Eenheden"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Functies/Procedures/Processen"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Bibliotheek"; + else return "Bibliotheken"; + case VhdlDocGen::PACKAGE: + if (single) return "Package"; + else return "Packages"; + case VhdlDocGen::SIGNAL: + if (single) return "Signal"; + else return "Signals"; + case VhdlDocGen::COMPONENT: + if (single) return "Bestanddeel"; + else return "Bestanddelen"; + case VhdlDocGen::CONSTANT: + if (single) return "Konstante"; + else return "Konstanten"; + case VhdlDocGen::ENTITY: + if (single) return "Entiteit"; + else return "Entiteiten"; + case VhdlDocGen::TYPE: + if (single) return "Type"; + else return "Types"; + case VhdlDocGen::SUBTYPE: + if (single) return "Ondertype"; + else return "Ondertypes"; + case VhdlDocGen::FUNCTION: + if (single) return "Funktie"; + else return "Funkties"; + case VhdlDocGen::RECORD: + if (single) return "Record"; + else return "Records"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedure"; + else return "Procedures"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Architectuur"; + else return "Architecturen"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Attribuut"; + else return "Attributen"; + case VhdlDocGen::PROCESS: + if (single) return "Proces"; + else return "Processen"; + case VhdlDocGen::PORT: + if (single) return "Poort"; + else return "Porten"; + case VhdlDocGen::USE: + if (single) return "gebruiks clausule"; + else return "Gebruiks Clausules"; + case VhdlDocGen::GENERIC: + if (single) return "Algemeen"; + else return "Algemene"; + case VhdlDocGen::PACKAGE_BODY: + return "Package Body"; + case VhdlDocGen::UNITS: + return "Eenheden"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Gedeelde Variable"; + else return "Gedeelde Variablen"; + case VhdlDocGen::VFILE: + if (single) return "Bestand"; + else return "Bestanden"; + case VhdlDocGen::GROUP: + if (single) return "Groep"; + else return "Groepen"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instantiëring"; + else return "Instantiëringen"; + case VhdlDocGen::ALIAS: + if (single) return "Alias"; + else return "Aliases"; + case VhdlDocGen::CONFIG: + if (single) return "Configuratie"; + else return "Configuraties"; + case VhdlDocGen::MISCELLANEOUS: + return "Diverse"; + case VhdlDocGen::UCF_CONST: + return "Limiteringen"; + default: + return "Klasse"; + } + } + virtual QCString trCustomReference(const char *name) + { return QCString(name)+" Referentie"; } + + /* Slice */ + virtual QCString trConstants() + { return "Konstanten"; } + virtual QCString trConstantDocumentation() + { return "Documentatie van konstanten"; } + virtual QCString trSequences() + { return "Reeksen"; } + virtual QCString trSequenceDocumentation() + { return "Documentatie van reeksen"; } + virtual QCString trDictionaries() + { return "Vertalingslijsten"; } + virtual QCString trDictionaryDocumentation() + { return "Documentatie van vertalingslijsten"; } + virtual QCString trSliceInterfaces() + { return "Interfaces"; } + virtual QCString trInterfaceIndex() + { return "Index van interfaces"; } + virtual QCString trInterfaceList() + { return "Lijst van interfaces"; } + virtual QCString trInterfaceListDescription() + { return "Hieronder volgt de lijst met alle interfaces, elk met een korte beschrijving:"; } + virtual QCString trInterfaceHierarchy() + { return "Interface Hiërarchie"; } + virtual QCString trInterfaceHierarchyDescription() + { return "Deze inheritance lijst is min of meer alfabetisch gesorteerd:"; } + virtual QCString trInterfaceDocumentation() + { return "Documentatie van interfaces"; } + virtual QCString trStructs() + { return "Structs"; } + virtual QCString trStructIndex() + { return "Index van struct"; } + virtual QCString trStructList() + { return "Lijst van struct"; } + virtual QCString trStructListDescription() + { return "Hieronder volgt de lijst met alle structs, elk met een korte beschrijving:"; } + virtual QCString trStructDocumentation() + { return "Documentatie van structs"; } + virtual QCString trExceptionIndex() + { return "Index van exceptions"; } + virtual QCString trExceptionList() + { return "Lijst van exceptions"; } + virtual QCString trExceptionListDescription() + { return "Hieronder volgt de lijst met alle exeptions, elk met een korte beschrijving:"; } + virtual QCString trExceptionHierarchy() + { return "Exception Hiërarchie"; } + virtual QCString trExceptionHierarchyDescription() + { return "Deze inheritance lijst is min of meer alfabetisch gesorteerd:"; } + virtual QCString trExceptionDocumentation() + { return "Documentatie van exceptions"; } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result=(QCString)clName; + if (isLocal) result+=" Lokale"; + switch(compType) + { + case ClassDef::Class: result+=" Class"; break; + case ClassDef::Struct: result+=" Struct"; break; + case ClassDef::Union: result+=" Union"; break; + case ClassDef::Interface: result+=" Interface"; break; + case ClassDef::Protocol: result+=" Protocol"; break; + case ClassDef::Category: result+=" Category"; break; + case ClassDef::Exception: result+=" Exception"; break; + default: break; + } + result+=" Referentie"; + return result; + } + virtual QCString trOperations() + { return "Bewerkingen"; } + virtual QCString trOperationDocumentation() + { return "Documentatie van bewerkingen"; } + virtual QCString trDataMembers() + { return "Data members"; } + virtual QCString trDataMemberDocumentation() + { return "Documentatie van data members"; } + ////////////////////////////////////////////////////////////////////////// }; #endif diff --git a/src/translator_no.h b/src/translator_no.h index 58b596a..eccd952 100644 --- a/src/translator_no.h +++ b/src/translator_no.h @@ -72,8 +72,7 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 virtual QCString latexLanguageSupportCommand() { return - "\\usepackage[norwegian]{babel}\n" - "\\usepackage[T1]{fontenc}\n"; + "\\usepackage[norsk]{babel}\n"; } // --- Language translation methods ------------------- diff --git a/src/translator_pl.h b/src/translator_pl.h index 421f407..e0ecc8f 100644 --- a/src/translator_pl.h +++ b/src/translator_pl.h @@ -44,8 +44,14 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 */ QCString latexLanguageSupportCommand() { - return "\\usepackage{polski}\n" - "\\usepackage[T1]{fontenc}\n"; + return "\\usepackage[polish]{babel}\n" + "\\let\\lll\\undefined\n"; /* to overcome problems with the <<< + symbol as defined in the amssymb + package, and the Polish symbol + "Latin Small Letter L With Stroke" + ł or ł or ł + We take the amssymb symbol as leading. + */ } // --- Language translation methods ------------------- diff --git a/src/translator_pt.h b/src/translator_pt.h index c58bf64..23faf7f 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2018 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 @@ -10,9 +10,9 @@ * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * - * Portuguese translation version 20110428 + * Portuguese translation version * Maintainer (from 04/28/2011): - * Fabio "FJTC" Jun Takada Chino <jun-chino at uol.com.br> + * Fabio "FJTC" Jun Takada Chino <fjtc at brokenbits dot com dot br> * Maintainer (until 04/28/2011): * Rui Godinho Lopes <rui at ruilopes.com> * @@ -24,6 +24,8 @@ * VERSION HISTORY * --------------- * History: + * 20180612: + * - Updated to 1.8.15; * 20131129: * - Updated to 1.8.5; * - Translation in the method trFileMembers() fixed; @@ -55,7 +57,7 @@ #define TRANSLATOR_PT_H -class TranslatorPortuguese : public Translator +class TranslatorPortuguese : public TranslatorAdapter_1_8_15 { public: @@ -85,7 +87,10 @@ class TranslatorPortuguese : public Translator * the empty string is returned in this implementation. */ virtual QCString latexLanguageSupportCommand() - { return "Portuguese"; } + { + return + "\\usepackage[portuges]{babel}\n"; + } // --- Language translation methods ------------------- @@ -2016,7 +2021,124 @@ class TranslatorPortuguese : public Translator return result; } -////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// + // new since 1.8.15 + ////////////////////////////////////////////////////////////////////////// + + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Hierarquia da Unidade de Design"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Lista de Unidades de Design"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Membros da Unidade de Design"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Esta é uma lista de todos os membros de unidades de design " + "com ligações para as entidades às quais pertencem:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Índice de Unidades de Design"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Unidades de Design"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funções/Procedimentos/Processos"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Biblioteca"; + else return "Bibliotecas"; + case VhdlDocGen::PACKAGE: + if (single) return "Pacote"; + else return "Pacotes"; + case VhdlDocGen::SIGNAL: + if (single) return "Sinal"; + else return "Sinais"; + case VhdlDocGen::COMPONENT: + if (single) return "Componente"; + else return "Componentes"; + case VhdlDocGen::CONSTANT: + if (single) return "Constante"; + else return "Constantes"; + case VhdlDocGen::ENTITY: + if (single) return "Entidade"; + else return "Entidades"; + case VhdlDocGen::TYPE: + if (single) return "Tipo"; + else return "Tipos"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtipo"; + else return "Subtipos"; + case VhdlDocGen::FUNCTION: + if (single) return "Função"; + else return "Funções"; + case VhdlDocGen::RECORD: + if (single) return "Registro"; + else return "Registros"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedimento"; + else return "Procedimentos"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Arquitetura"; + else return "Arquiteturas"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Atributo"; + else return "Atributos"; + case VhdlDocGen::PROCESS: + if (single) return "Processo"; + else return "Processos"; + case VhdlDocGen::PORT: + if (single) return "Porta"; + else return "Portas"; + case VhdlDocGen::USE: + if (single) return "cláusula de uso"; + else return "cláusulas de uso"; + case VhdlDocGen::GENERIC: + if (single) return "Generico"; + else return "Genericos"; + case VhdlDocGen::PACKAGE_BODY: + return "Corpo do Pacote"; + case VhdlDocGen::UNITS: + return "Unidades"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Variável Compartilhada"; + else return "Variáveis Compartilhadas"; + case VhdlDocGen::VFILE: + if (single) return "Ficheiro"; + else return "Ficheiros"; + case VhdlDocGen::GROUP: + if (single) return "Grupo"; + else return "Grupos"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instância"; + else return "Instâncias"; + case VhdlDocGen::ALIAS: + if (single) return "Apelido"; + else return "Apelidos"; + case VhdlDocGen::CONFIG: + if (single) return "Configuração"; + else return "Configurações"; + case VhdlDocGen::MISCELLANEOUS: + return "Outros"; // Is this correct for VHDL? + case VhdlDocGen::UCF_CONST: + return "Restrições"; + default: + return "Classe"; + } + } + virtual QCString trCustomReference(const char *name) + { return "Referência de " + QCString(name); } + + ////////////////////////////////////////////////////////////////////////// }; #endif diff --git a/src/translator_ro.h b/src/translator_ro.h index 661578b..6f0c197 100644 --- a/src/translator_ro.h +++ b/src/translator_ro.h @@ -42,7 +42,7 @@ #define TRANSLATOR_RO_H -class TranslatorRomanian : public Translator +class TranslatorRomanian : public TranslatorAdapter_1_8_15 { public: diff --git a/src/translator_ru.h b/src/translator_ru.h index 54c0202..9d92888 100644 --- a/src/translator_ru.h +++ b/src/translator_ru.h @@ -26,7 +26,7 @@ #ifndef TRANSLATOR_RU_H #define TRANSLATOR_RU_H -class TranslatorRussian : public Translator +class TranslatorRussian : public TranslatorAdapter_1_8_15 { public: /*! Used for identification of the language. */ diff --git a/src/translator_sc.h b/src/translator_sc.h index d2b3954..e8191df 100644 --- a/src/translator_sc.h +++ b/src/translator_sc.h @@ -71,6 +71,11 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 */ virtual QCString latexLanguageSupportCommand() { + return "\\usepackage[T2A]{fontenc}\n" + "\\usepackage[russian]{babel}\n"; + } + virtual QCString latexFontenc() + { return ""; } diff --git a/src/translator_si.h b/src/translator_si.h index 792053e..2dd7e5b 100644 --- a/src/translator_si.h +++ b/src/translator_si.h @@ -36,7 +36,7 @@ class TranslatorSlovene : public TranslatorAdapter_1_4_6 */ QCString latexLanguageSupportCommand() { - return "\\usepackage[slovene]{babel}\n\\usepackage[T1]{fontenc}\n"; + return "\\usepackage[slovene]{babel}\n"; } QCString trRelatedFunctions() { return "Povezane funkcije"; } diff --git a/src/translator_sk.h b/src/translator_sk.h index 3a925ec..9ee8252 100644 --- a/src/translator_sk.h +++ b/src/translator_sk.h @@ -32,7 +32,7 @@ #ifndef TRANSLATOR_SK_H #define TRANSLATOR_SK_H -class TranslatorSlovak : public Translator +class TranslatorSlovak : public TranslatorAdapter_1_8_15 { public: // --- Language control methods ------------------- @@ -41,8 +41,14 @@ class TranslatorSlovak : public Translator { return "slovak"; } virtual QCString latexLanguageSupportCommand() - { return "\\usepackage[slovak]{babel}\n"; } - + { return "\\usepackage[slovak]{babel}\n" + "\\usepackage{regexpatch}\n" + "\\makeatletter\n" + "% Change the `-` delimiter to an active character\n" + "\\xpatchparametertext\\@@@cmidrule{-}{\\cA-}{}{}\n" + "\\xpatchparametertext\\@cline{-}{\\cA-}{}{}\n" + "\\makeatother\n"; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ diff --git a/src/translator_sv.h b/src/translator_sv.h index 88fffd9..5da89df 100644 --- a/src/translator_sv.h +++ b/src/translator_sv.h @@ -120,7 +120,7 @@ Problem! #ifndef TRANSLATOR_SE_H #define TRANSLATOR_SE_H -class TranslatorSwedish : public Translator +class TranslatorSwedish : public TranslatorAdapter_1_8_15 { public: diff --git a/src/translator_tw.h b/src/translator_tw.h index 26a6db6..9e9092d 100644 --- a/src/translator_tw.h +++ b/src/translator_tw.h @@ -41,7 +41,7 @@ // Translator class (by the local maintainer) when the localized // translator is made up-to-date again. -class TranslatorChinesetraditional : public Translator +class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15 { public: @@ -72,8 +72,20 @@ class TranslatorChinesetraditional : public Translator */ virtual QCString latexLanguageSupportCommand() { + return "\\usepackage{CJKutf8}\n"; + } + virtual QCString latexFontenc() + { return ""; } + virtual QCString latexDocumentPre() + { + return "\\begin{CJK}{UTF8}{min}\n"; + } + virtual QCString latexDocumentPost() + { + return "\\end{CJK}\n"; + } // --- Language translation methods ------------------- diff --git a/src/translator_vi.h b/src/translator_vi.h index a0046b0..b391b0c 100644 --- a/src/translator_vi.h +++ b/src/translator_vi.h @@ -78,9 +78,23 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 */ virtual QCString latexLanguageSupportCommand() { + return + "\\usepackage[vietnamese]{babel}\n"; + } + virtual QCString latexFontenc() + { return ""; } - + virtual QCString latexCommandName() + { + QCString latex_command = Config_getString(LATEX_CMD_NAME); + if (latex_command.isEmpty()) latex_command = "latex"; + if (Config_getBool(USE_PDFLATEX)) + { + if (latex_command == "latex") latex_command = "xelatex"; + } + return latex_command; + } // --- Language translation methods ------------------- /*! used in the compound documentation before a list of related functions. */ diff --git a/src/types.h b/src/types.h index 806e6fc..4d305b6 100644 --- a/src/types.h +++ b/src/types.h @@ -16,6 +16,7 @@ #ifndef TYPES_H #define TYPES_H +#include <string.h> #include <qcstring.h> /** @file @@ -55,7 +56,8 @@ enum SrcLangExt SrcLangExt_XML = 0x04000, SrcLangExt_Tcl = 0x08000, SrcLangExt_Markdown = 0x10000, - SrcLangExt_SQL = 0x20000 + SrcLangExt_SQL = 0x20000, + SrcLangExt_Slice = 0x40000 }; /** Grouping info */ @@ -191,15 +193,20 @@ enum MemberListType MemberListType_interfaceMembers = 71 + MemberListType_detailedLists, MemberListType_services = 72, MemberListType_serviceMembers = 73 + MemberListType_detailedLists, + + MemberListType_decSequenceMembers = 74 + MemberListType_declarationLists, + MemberListType_docSequenceMembers = 75 + MemberListType_documentationLists, + MemberListType_decDictionaryMembers = 76 + MemberListType_declarationLists, + MemberListType_docDictionaryMembers = 77 + MemberListType_documentationLists }; -enum MemberType -{ +enum MemberType +{ MemberType_Define, - MemberType_Function, - MemberType_Variable, - MemberType_Typedef, - MemberType_Enumeration, + MemberType_Function, + MemberType_Variable, + MemberType_Typedef, + MemberType_Enumeration, MemberType_EnumValue, MemberType_Signal, MemberType_Slot, @@ -209,6 +216,8 @@ enum MemberType MemberType_Event, MemberType_Interface, MemberType_Service, + MemberType_Sequence, + MemberType_Dictionary }; enum FortranFormat @@ -218,4 +227,56 @@ enum FortranFormat FortranFormat_Fixed }; +class LocalToc +{ + public: + enum Type { + None = 0, // initial value + Html = 0, // index / also to be used as bit position in mask (1 << Html) + Latex = 1, // ... + Xml = 2, // ... + Docbook = 3, // ... + numTocTypes = 4 // number of enum values + }; + LocalToc() : m_mask(None) { memset(m_level,0,sizeof(m_level)); } + + // setters + void enableHtml(int level) + { + m_mask|=(1<<Html); + m_level[Html]=level; + } + void enableLatex(int level) + { + m_mask|=(1<<Latex); + m_level[Latex]=level; + } + void enableXml(int level) + { + m_mask|=(1<<Xml); + m_level[Xml]=level; + } + void enableDocbook(int level) + { + m_mask|=(1<<Docbook); + m_level[Docbook]=level; + } + + // getters + bool isHtmlEnabled() const { return (m_mask & (1<<Html))!=0; } + bool isLatexEnabled() const { return (m_mask & (1<<Latex))!=0; } + bool isXmlEnabled() const { return (m_mask & (1<<Xml))!=0; } + bool isDocbookEnabled() const { return (m_mask & (1<<Docbook))!=0; } + bool nothingEnabled() const { return m_mask == None; } + int htmlLevel() const { return m_level[Html]; } + int latexLevel() const { return m_level[Latex]; } + int xmlLevel() const { return m_level[Xml]; } + int docbookLevel() const { return m_level[Docbook]; } + int mask() const { return m_mask; } + + private: + int m_mask; + int m_level[numTocTypes]; +}; + #endif diff --git a/src/util.cpp b/src/util.cpp index 3af1a90..08c13fb 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -251,6 +251,7 @@ void writePageRef(OutputDocInterface &od,const char *cn,const char *mn) 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(); @@ -323,7 +324,6 @@ int guessSection(const char *name) n.right(4)==".c++" || n.right(5)==".java" || n.right(2)==".m" || - n.right(2)==".M" || n.right(3)==".mm" || n.right(3)==".ii" || // inline n.right(4)==".ixx" || @@ -333,14 +333,15 @@ int guessSection(const char *name) n.right(4)==".xml" || n.right(4)==".sql" ) return Entry::SOURCE_SEC; - if (n.right(2)==".h" || // header - n.right(3)==".hh" || - n.right(4)==".hxx" || - n.right(4)==".hpp" || - n.right(4)==".h++" || - n.right(4)==".idl" || - n.right(4)==".ddl" || - n.right(5)==".pidl" + if (n.right(2)==".h" || // header + n.right(3)==".hh" || + n.right(4)==".hxx" || + n.right(4)==".hpp" || + n.right(4)==".h++" || + n.right(4)==".idl" || + n.right(4)==".ddl" || + n.right(5)==".pidl" || + n.right(4)==".ice" ) return Entry::HEADER_SEC; return 0; } @@ -1782,7 +1783,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) pc = c; i++; c = src[i]; - *dst+=c; + *dst++=c; } else if (c=='"') { @@ -1846,7 +1847,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) case '*': if (i>0 && pc!=' ' && pc!='\t' && pc!=':' && pc!='*' && pc!='&' && pc!='(' && pc!='/' && - pc!='.' && (osp<9 || (pc=='>' && osp==11))) + pc!='.' && (osp<9 || !(pc=='>' && osp==11))) // avoid splitting &&, **, .*, operator*, operator->* { *dst++=' '; @@ -1856,7 +1857,11 @@ QCString removeRedundantWhiteSpace(const QCString &s) case '&': if (i>0 && isId(pc)) { - *dst++=' '; + if (nc != '=') + // avoid splitting operator&= + { + *dst++=' '; + } } *dst++=c; break; @@ -1890,11 +1895,18 @@ QCString removeRedundantWhiteSpace(const QCString &s) if (g_charAroundSpace.charMap[(uchar)pc].before && g_charAroundSpace.charMap[(uchar)nc].after && !(pc==',' && nc=='.') && - (osp<8 || (osp>=8 && isId(nc))) // e.g. "operator >>" -> "operator>>", but not "operator int" -> operatorint" + (osp<8 || (osp>=8 && pc!='"' && isId(nc)) || (osp>=8 && pc!='"' && nc!='"')) + // e.g. 'operator >>' -> 'operator>>', + // 'operator "" _x' -> 'operator""_x', + // but not 'operator int' -> 'operatorint' ) { // keep space *dst++=' '; } + else if ((pc=='*' || pc=='&' || pc=='.') && nc=='>') + { + *dst++=' '; + } } break; default: @@ -2212,6 +2224,7 @@ void writeExample(OutputList &ol,ExampleSDict *ed) //if (latexEnabled) ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); + ol.disable(OutputGenerator::Docbook); // link for Html / man //printf("writeObjectLink(file=%s)\n",e->file.data()); ol.writeObjectLink(0,e->file,e->anchor,e->name); @@ -2588,7 +2601,7 @@ QCString dateToString(bool includeTime) static bool warnedOnce=FALSE; if (!warnedOnce) { - warn_uncond("Environment variable SOURCE_DATA_EPOCH must have a value smaller than or equal to %llu; actual value %llu\n",UINT_MAX,epoch); + warn_uncond("Environment variable SOURCE_DATE_EPOCH must have a value smaller than or equal to %llu; actual value %llu\n",UINT_MAX,epoch); warnedOnce=TRUE; } } @@ -2662,7 +2675,7 @@ Protection classInheritedProtectionLevel(ClassDef *cd,ClassDef *bcd,Protection p if (level==256) { err("Internal inconsistency: found class %s seem to have a recursive " - "inheritance relation! Please send a bug report to dimitri@stack.nl\n",cd->name().data()); + "inheritance relation! Please send a bug report to doxygen@gmail.com\n",cd->name().data()); } else if (cd->baseClasses()) { @@ -5287,6 +5300,22 @@ QCString substitute(const QCString &s,const QCString &src,const QCString &dst,in return result; } +/// substitute all occurrences of \a srcChar in \a s by \a dstChar +QCString substitute(const QCString &s,char srcChar,char dstChar) +{ + int l=s.length(); + QCString result(l+1); + char *q=result.rawData(); + if (l>0) + { + const char *p=s.data(); + char c; + while ((c=*p++)) *q++ = (c==srcChar) ? dstChar : c; + } + *q='\0'; + return result; +} + //---------------------------------------------------------------------- QCString substituteKeywords(const QCString &s,const char *title, @@ -5913,6 +5942,66 @@ QCString convertToXML(const char *s) return growBuf.get(); } +/*! Converts a string to an DocBook-encoded string */ +QCString convertToDocBook(const char *s) +{ + static GrowBuf growBuf; + growBuf.clear(); + if (s==0) return ""; + const unsigned char *q; + int cnt; + const unsigned char *p=(const unsigned char *)s; + char c; + while ((c=*p++)) + { + switch (c) + { + case '<': growBuf.addStr("<"); break; + case '>': growBuf.addStr(">"); break; + case '&': // possibility to have a special symbol + q = p; + cnt = 2; // we have to count & and ; as well + while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9')) + { + cnt++; + q++; + } + if (*q == ';') + { + --p; // we need & as well + DocSymbol::SymType res = HtmlEntityMapper::instance()->name2sym(QCString((char *)p).left(cnt)); + if (res == DocSymbol::Sym_Unknown) + { + p++; + growBuf.addStr("&"); + } + else + { + growBuf.addStr(HtmlEntityMapper::instance()->docbook(res)); + q++; + p = q; + } + } + else + { + growBuf.addStr("&"); + } + break; + case '\'': growBuf.addStr("'"); break; + case '"': growBuf.addStr("""); break; + case '\007': growBuf.addStr("␇"); break; + case 1: case 2: case 3: case 4: case 5: case 6: case 8: + case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: + case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: + case 27: case 28: case 29: case 30: case 31: + break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char) + default: growBuf.addChar(c); break; + } + } + growBuf.addChar(0); + return growBuf.get(); +} + /*! Converts a string to a HTML-encoded string */ QCString convertToHtml(const char *s,bool keepEntities) { @@ -6468,7 +6557,7 @@ QCString mergeScopes(const QCString &leftScope,const QCString &rightScope) // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C" // case leftScope=="A::B" rightScope=="B" => result = "A::B" bool found=FALSE; - while ((i=leftScope.findRev("::",p))!=-1) + while ((i=leftScope.findRev("::",p))>0) { if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2))) { @@ -6557,6 +6646,8 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, // append documentation block to the page. pd->setDocumentation(doc,fileName,startLine); //printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pd,name); + // append (x)refitems to the page. + pd->setRefItems(sli); } else // new page { @@ -6722,6 +6813,16 @@ void filterLatexString(FTextStream &t,const char *str, { switch(c) { + 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) + { + t << "{\\ucr}"; + p += 2; + } + else + t << (char)c; + break; case '\\': t << "\\(\\backslash\\)"; break; case '{': t << "\\{"; break; case '}': t << "\\}"; break; @@ -6743,6 +6844,16 @@ void filterLatexString(FTextStream &t,const char *str, { switch(c) { + 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) + { + t << "{\\ucr}"; + p += 2; + } + else + t << (char)c; + break; case '#': t << "\\#"; break; case '$': t << "\\$"; break; case '%': t << "\\%"; break; @@ -6826,7 +6937,7 @@ void filterLatexString(FTextStream &t,const char *str, } } -QCString latexEscapeLabelName(const char *s,bool insideTabbing) +QCString latexEscapeLabelName(const char *s) { QGString result; QCString tmp(qstrlen(s)+1); @@ -6856,14 +6967,14 @@ QCString latexEscapeLabelName(const char *s,bool insideTabbing) p++; } tmp[i]=0; - filterLatexString(t,tmp.data(),insideTabbing); + filterLatexString(t,tmp,TRUE); break; } } return result.data(); } -QCString latexEscapeIndexChars(const char *s,bool insideTabbing) +QCString latexEscapeIndexChars(const char *s) { QGString result; QCString tmp(qstrlen(s)+1); @@ -6894,7 +7005,7 @@ QCString latexEscapeIndexChars(const char *s,bool insideTabbing) p++; } tmp[i]=0; - filterLatexString(t,tmp.data(),insideTabbing); + filterLatexString(t,tmp.data(),TRUE); break; } } @@ -6925,6 +7036,25 @@ QCString latexEscapePDFString(const char *s) return result.data(); } +QCString latexFilterURL(const char *s) +{ + QGString result; + FTextStream t(&result); + const char *p=s; + char c; + while ((c=*p++)) + { + switch (c) + { + case '#': t << "\\#"; break; + default: + t << c; + break; + } + } + return result.data(); +} + QCString rtfFormatBmkStr(const char *name) { @@ -7135,6 +7265,7 @@ g_lang2extMap[] = { "objective-c", "c", SrcLangExt_ObjC }, { "c", "c", SrcLangExt_Cpp }, { "c++", "c", SrcLangExt_Cpp }, + { "slice", "c", SrcLangExt_Slice }, { "python", "python", SrcLangExt_Python }, { "fortran", "fortran", SrcLangExt_Fortran }, { "fortranfree", "fortranfree", SrcLangExt_Fortran }, @@ -7240,6 +7371,7 @@ void initDefaultExtensionMapping() updateLanguageMapping(".qsf", "vhdl"); updateLanguageMapping(".md", "md"); updateLanguageMapping(".markdown", "md"); + updateLanguageMapping(".ice", "slice"); } void addCodeOnlyMappings() @@ -7391,23 +7523,23 @@ int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos) { if (((uchar)c&0xE0)==0xC0) { - bytes++; // 11xx.xxxx: >=2 byte character + bytes+=1; // 11xx.xxxx: >=2 byte character } if (((uchar)c&0xF0)==0xE0) { - bytes++; // 111x.xxxx: >=3 byte character + bytes+=2; // 111x.xxxx: >=3 byte character } if (((uchar)c&0xF8)==0xF0) { - bytes++; // 1111.xxxx: >=4 byte character + bytes+=3; // 1111.xxxx: >=4 byte character } if (((uchar)c&0xFC)==0xF8) { - bytes++; // 1111.1xxx: >=5 byte character + bytes+=4; // 1111.1xxx: >=5 byte character } if (((uchar)c&0xFE)==0xFC) { - bytes++; // 1111.1xxx: 6 byte character + bytes+=5; // 1111.1xxx: 6 byte character } } else if (c=='&') // skip over character entities @@ -7441,11 +7573,10 @@ QCString parseCommentAsText(const Definition *scope,const MemberDef *md, root->accept(visitor); delete visitor; delete root; - QCString result = convertCharEntitiesToUTF8(s.data()); + QCString result = convertCharEntitiesToUTF8(s.data()).stripWhiteSpace(); int i=0; int charCnt=0; int l=result.length(); - bool addEllipsis=FALSE; while ((i=nextUtf8CharPosition(result,l,i))<l) { charCnt++; @@ -7456,19 +7587,17 @@ QCString parseCommentAsText(const Definition *scope,const MemberDef *md, while ((i=nextUtf8CharPosition(result,l,i))<l && charCnt<100) { charCnt++; - if (result.at(i)>=0 && isspace(result.at(i))) - { - addEllipsis=TRUE; - } - else if (result.at(i)==',' || - result.at(i)=='.' || - result.at(i)=='?') + if (result.at(i)==',' || + result.at(i)=='.' || + result.at(i)=='!' || + result.at(i)=='?') { + i++; // we want to be "behind" last inspected character break; } } } - if (addEllipsis || charCnt==100) result=result.left(i)+"..."; + if ( i < l) result=result.left(i)+"..."; return result.data(); } @@ -7913,8 +8042,8 @@ bool readInputFile(const char *fileName,BufStr &inBuf,bool filter,bool isSourceC int start=0; if (size>=2 && - ((inBuf.at(0)==-1 && inBuf.at(1)==-2) || // Litte endian BOM - (inBuf.at(0)==-2 && inBuf.at(1)==-1) // big endian BOM + (((uchar)inBuf.at(0)==0xFF && (uchar)inBuf.at(1)==0xFE) || // Little endian BOM + ((uchar)inBuf.at(0)==0xFE && (uchar)inBuf.at(1)==0xFF) // big endian BOM ) ) // UCS-2 encoded file { @@ -8077,7 +8206,7 @@ QCString externalRef(const QCString &relPath,const QCString &ref,bool href) return result; } -/** Writes the intensity only bitmap representated by \a data as an image to +/** Writes the intensity only bitmap represented by \a data as an image to * directory \a dir using the colors defined by HTML_COLORSTYLE_*. */ void writeColoredImgData(const char *dir,ColoredImgDataItem data[]) @@ -8276,6 +8405,7 @@ QCString langToString(SrcLangExt lang) case SrcLangExt_SQL: return "SQL"; case SrcLangExt_Tcl: return "Tcl"; case SrcLangExt_Markdown: return "Markdown"; + case SrcLangExt_Slice: return "Slice"; } return "Unknown"; } @@ -8407,12 +8537,9 @@ bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile) void addDocCrossReference(MemberDef *src,MemberDef *dst) { - static bool referencedByRelation = Config_getBool(REFERENCED_BY_RELATION); - static bool referencesRelation = Config_getBool(REFERENCES_RELATION); - //printf("--> addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data()); if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types - if ((referencedByRelation || dst->hasCallerGraph()) && + if ((dst->hasReferencedByRelation() || dst->hasCallerGraph()) && src->showInCallGraph() ) { @@ -8428,7 +8555,7 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst) mdDecl->addSourceReferencedBy(src); } } - if ((referencesRelation || src->hasCallGraph()) && + if ((src->hasReferencesRelation() || src->hasCallGraph()) && src->showInCallGraph() ) { @@ -8515,7 +8642,7 @@ uint getUtf8CodeToUpper( const QCString& s, int idx ) //-------------------------------------------------------------------------------------- -bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses) +bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct) { if (nd->getNamespaceSDict()) { @@ -8527,21 +8654,41 @@ bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses) { return TRUE; } - else if (namespaceHasVisibleChild(cnd,includeClasses)) + else if (namespaceHasVisibleChild(cnd,includeClasses,filterClasses,ct)) { return TRUE; } } } - if (includeClasses && nd->getClassSDict()) + if (includeClasses) { - ClassSDict::Iterator cli(*nd->getClassSDict()); - ClassDef *cd; - for (;(cd=cli.current());++cli) + ClassSDict *d = nd->getClassSDict(); + if (filterClasses) { - if (cd->isLinkableInProject() && cd->templateMaster()==0) - { - return TRUE; + if (ct == ClassDef::Interface) + { + d = nd->getInterfaceSDict(); + } + else if (ct == ClassDef::Struct) + { + d = nd->getStructSDict(); + } + else if (ct == ClassDef::Exception) + { + d = nd->getExceptionSDict(); + } + } + + if (d) + { + ClassSDict::Iterator cli(*d); + ClassDef *cd; + for (;(cd=cli.current());++cli) + { + if (cd->isLinkableInProject() && cd->templateMaster()==0) + { + return TRUE; + } } } } @@ -8830,6 +8977,32 @@ void writeExtraLatexPackages(FTextStream &t) } } +void writeLatexSpecialFormulaChars(FTextStream &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; + minus[3]= 0; + sup2[0]= 0xC2; + sup2[1]= 0xB2; + sup2[2]= 0; + sup3[0]= 0xC2; + sup3[1]= 0xB3; + sup3[2]= 0; + + t << "\\usepackage{newunicodechar}\n" + " \\newunicodechar{" << pminus << "}{${}^{-}$}% Superscript minus\n" + " \\newunicodechar{" << psup2 << "}{${}^{2}$}% Superscript two\n" + " \\newunicodechar{" << psup3 << "}{${}^{3}$}% Superscript three\n" + "\n"; +} + //------------------------------------------------------ static int g_usedTableLevels = 0; @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -18,7 +18,7 @@ #ifndef UTIL_H #define UTIL_H -/*! \file +/*! \file * \brief A bunch of utility functions. */ @@ -26,6 +26,8 @@ #include <ctype.h> #include "types.h" #include "sortdict.h" +#include "docparser.h" +#include "classdef.h" //-------------------------------------------------------------------- @@ -69,7 +71,7 @@ class TextGeneratorIntf virtual void writeBreak(int indent) const = 0; virtual void writeLink(const char *extRef,const char *file, const char *anchor,const char *text - ) const = 0; + ) const = 0; }; /** Implements TextGeneratorIntf for an OutputDocInterface stream. */ @@ -138,11 +140,11 @@ QCString fileToString(const char *name,bool filter=FALSE,bool isSourceCode=FALSE QCString dateToString(bool); bool getDefs(const QCString &scopeName, - const QCString &memberName, - const char *, - MemberDef *&md, + const QCString &memberName, + const char *, + MemberDef *&md, ClassDef *&cd, - FileDef *&fd, + FileDef *&fd, NamespaceDef *&nd, GroupDef *&gd, bool forceEmptyScope=FALSE, @@ -194,6 +196,7 @@ QCString substituteClassNames(const QCString &s); QCString substitute(const QCString &s,const QCString &src,const QCString &dst); QCString substitute(const QCString &s,const QCString &src,const QCString &dst,int skip_seq); +QCString substitute(const QCString &s,char srcChar,char dstChar); QCString clearBlock(const char *s,const char *begin,const char *end); @@ -259,7 +262,7 @@ void initClassHierarchy(ClassSDict *cl); bool hasVisibleRoot(BaseClassList *bcl); bool classHasVisibleChildren(ClassDef *cd); -bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses); +bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct); bool classVisibleInIndex(ClassDef *cd); int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level=0); @@ -283,6 +286,8 @@ QCString convertToLaTeX(const QCString &s,bool insideTabbing=FALSE,bool keepSpac QCString convertToXML(const char *s); +QCString convertToDocBook(const char *s); + QCString convertToJSString(const char *s, bool applyTextDir = true); QCString getOverloadDocs(); @@ -342,9 +347,10 @@ void filterLatexString(FTextStream &t,const char *str, bool insideItem=FALSE, bool keepSpaces=FALSE); -QCString latexEscapeLabelName(const char *s,bool insideTabbing); -QCString latexEscapeIndexChars(const char *s,bool insideTabbing); +QCString latexEscapeLabelName(const char *s); +QCString latexEscapeIndexChars(const char *s); QCString latexEscapePDFString(const char *s); +QCString latexFilterURL(const char *s); QCString rtfFormatBmkStr(const char *name); @@ -388,7 +394,7 @@ SrcLangExt getLanguageFromFileName(const QCString& fileName); void initDefaultExtensionMapping(); void addCodeOnlyMappings(); -MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, +MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, const char *n); bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n); @@ -477,10 +483,10 @@ void convertProtectionLevel( bool mainPageHasTitle(); bool openOutputFile(const char *outFile,QFile &f); void writeExtraLatexPackages(FTextStream &t); +void writeLatexSpecialFormulaChars(FTextStream &t); int usedTableLevels(); void incUsedTableLevels(); void decUsedTableLevels(); #endif - diff --git a/src/vhdlcode.l b/src/vhdlcode.l index ce1f92b..aa15183 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -31,7 +31,7 @@ #include <ctype.h> #include <qregexp.h> #include <qdir.h> -#include <qstringlist.h> +#include <qcstringlist.h> #include "entry.h" #include "doxygen.h" @@ -94,7 +94,7 @@ static QCString g_exampleFile; static QCString g_classScope; -static QCString g_CurrScope; +static bool g_CurrARCH = FALSE; static FileDef * g_sourceFileDef; static Definition * g_currentDefinition; @@ -109,7 +109,7 @@ static int g_braceCount=0; static void writeFont(const char *s,const char* text); static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName); static bool writeColoredWord(QCString& word ); -static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE); +static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE, const char *curr_class=0); static void endFontClass(); static void startFontClass(const char *s); //------------------------------------------------------------------- @@ -138,8 +138,8 @@ static bool checkVhdlString(QCString &name) int len=name.length(); if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2) { - QStringList qrl=QStringList::split(regg,name,FALSE); - if (VhdlDocGen::isNumber(qrl[0].utf8())) + QCStringList qrl=QCStringList::split(regg,name); + if (VhdlDocGen::isNumber(qrl[0])) { g_code->codify("\""); startFontClass("vhdllogic"); @@ -291,7 +291,7 @@ static void writeWord(const char *word,const char* curr_class=0,bool classLink=F } else { - generateClassOrGlobalLink(*g_code,temp); + generateClassOrGlobalLink(*g_code,temp,FALSE,curr_class); } } else @@ -328,7 +328,7 @@ static void writeWord(const char *word,const char* curr_class=0,bool classLink=F } else { - generateClassOrGlobalLink(*g_code,temp); + generateClassOrGlobalLink(*g_code,temp,FALSE,curr_class); } } else @@ -370,7 +370,7 @@ static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,b //g_code->codify(sp); if (comment) { - writeFont("keyword",line.data()); + writeFont("comment",line.data()); } else { @@ -381,9 +381,9 @@ static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,b else { if (comment) - writeFont("keyword",sp); + writeFont("comment",sp); else - writeWord(sp,cl,classlink); + writeWord(sp,cl,classlink); done=TRUE; } } @@ -510,7 +510,7 @@ static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& m }// generateMemLink -static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/) +static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/, const char *curr_class) { QCString className=clName; @@ -521,6 +521,11 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName //bool isLocal=FALSE; className.stripPrefix("_"); cd = getClass(className.data()); + if (!cd && curr_class) + { + if (QCString(curr_class).contains(QRegExp("::"+QCString(clName)+"$"))) cd = getClass(curr_class); + } + while (cd) { //className.stripPrefix("_"); @@ -686,8 +691,8 @@ static void writeFuncProto() codifyLines(g_FuncProto.data(),g_CurrClass.data()); return; } - QStringList qlist=QStringList::split(name,g_FuncProto,FALSE); - QCString temp=qlist[0].utf8(); + QCStringList qlist=QCStringList::split(name,g_FuncProto); + QCString temp=qlist[0]; codifyLines(temp.data(),g_CurrClass.data()); g_FuncProto.stripPrefix(temp.data()); temp.resize(0); @@ -759,7 +764,7 @@ DIGITSS [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")* ALLTYPESMAP {B}*[_a-zA-Z0-9. ]+{BN}* ALLTYPESMAP1 {BN}*[_a-zA-Z0-9.() ]+{BN}* -ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME} +ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}{BN}+("is") PROCESS ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+ END1 {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for") @@ -768,7 +773,7 @@ END3 {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;] END4 {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;] ENDEFUNC {END3}|{END4}|{END2} -KEYWORD ("new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in") +KEYWORD ("of"|"new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in") TYPEKW ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration") FUNC ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(") @@ -807,6 +812,7 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI %x ClassVar %x ClassesName %x Map +%x End %x Body %% @@ -825,11 +831,11 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI QCString tt(vhdlcodeYYtext); VhdlDocGen::deleteAllChars(tt,','); QRegExp r("=>"); - QStringList ql=QStringList::split(r,tt,FALSE); + QCStringList ql=QCStringList::split(r,tt); if (ql.count()>=2) { unsigned int index=0; - QCString t1=ql[0].utf8(); + QCString t1=ql[0]; char cc=t1.at(index); while (cc==' ' || cc=='\t') { @@ -860,7 +866,7 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI } codifyLines("=>"); index=0; - QCString s2=ql[1].utf8(); + QCString s2=ql[1]; t1=s2; cc=t1.at(index); while (cc==' ' || cc=='\t') @@ -953,7 +959,7 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI tt=tt.lower(); VhdlDocGen::deleteAllChars(tt,';'); tt.stripWhiteSpace(); - QStringList ql=QStringList::split(regg,tt,FALSE); + QCStringList ql=QCStringList::split(regg,tt); int index=ql.findIndex(QCString("if"))+1; index+=ql.findIndex(QCString("case"))+1; index+=ql.findIndex(QCString("loop"))+1; @@ -1058,14 +1064,7 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI g_CurrClass.append(vhdlcodeYYtext); g_CurrClass=g_CurrClass.stripWhiteSpace(); - if (!writeColoredWord(g_CurrScope)) - { - generateClassOrGlobalLink(*g_code,vhdlcodeYYtext); - } - else - { - codifyLines(vhdlcodeYYtext,g_CurrClass.data()); - } + generateClassOrGlobalLink(*g_code,vhdlcodeYYtext); BEGIN(Bases); } @@ -1169,13 +1168,12 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI <ParsePackage>[^:;]* { //found package QCString temp(vhdlcodeYYtext); - QStringList strl=QStringList::split(".",temp,FALSE); - + QCStringList strl=QCStringList::split(".",temp); if (strl.count()>2) { - QCString s1=strl[0].utf8(); - QCString s2=strl[1].utf8(); - QCString s3=strl[2].utf8(); + QCString s1=strl[0]; + QCString s2=strl[1]; + QCString s3=strl[2]; s1.append("."); s3.prepend("."); codifyLines(s1.data(),g_CurrClass.data()); @@ -1284,6 +1282,7 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI //temp+=("-"); //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3); QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3); + g_CurrARCH = TRUE; temp+="::"; temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1); g_CurrClass=temp; @@ -1291,15 +1290,14 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI codifyLines(vhdlcodeYYtext,temp.data(),TRUE); //generateClassOrGlobalLink(*g_code,temp.data()); isPackageBody=FALSE; - BEGIN(ClassName); } <Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME} { // found package body QCString ss(vhdlcodeYYtext); QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2); - QStringList ql=QStringList::split(temp,ss,FALSE); - QCString ll=ql[0].utf8(); + QCStringList ql=QCStringList::split(temp,ss); + QCString ll=ql[0]; codifyLines(ll.data(),g_CurrClass.data()); temp=temp.stripWhiteSpace(); temp.prepend("_"); @@ -1371,6 +1369,41 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI } +<Bases>"end"{BN}+"architecture"{BN}+{FUNCNAME} { + codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE); + g_CurrARCH = FALSE; + } +<Bases>"end"{BN}+{FUNCNAME} { + if (g_CurrARCH) + { + codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE); + g_CurrARCH = FALSE; + } + else + REJECT; + } +<Bases>"end" { + appStringLower(g_PrevString,vhdlcodeYYtext); + QCString temp(vhdlcodeYYtext); + temp=temp.stripWhiteSpace(); + + writeColoredWord(temp); + BEGIN(End); + } +<End>{ID} { + appStringLower(g_PrevString,vhdlcodeYYtext); + QCString temp(vhdlcodeYYtext); + temp=temp.stripWhiteSpace(); + + if (!writeColoredWord(temp)) + { + generateClassOrGlobalLink(*g_code,temp.data()); + } + } +<End>";" { + codifyLines(vhdlcodeYYtext); + BEGIN(Bases); + } <Bases>{KEYWORD} { // found keyword QCString qcs(vhdlcodeYYtext); if (!writeColoredWord(qcs)) @@ -1445,11 +1478,11 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI writeFont("keyword",vhdlcodeYYtext); } -<Bases>^{B}*{XILINX}[^\n]* { - writeWord(yytext); - //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE); - } - +<Bases>^{B}*{XILINX}/[^a-zA-Z0-9_] { + writeWord(yytext); + //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE); + } + <Bases>^{B}*"set_"[^\n]* { writeWord(yytext); } @@ -1464,37 +1497,38 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI } <*>\n{TEXTT} { // found normal or special comment on its own line - QCString text(vhdlcodeYYtext); - int i=text.find("--"); - if (text.mid(i,3)=="--!" && // hide special comment - Config_getBool(STRIP_CODE_COMMENTS)) - { - g_yyLineNr++; // skip complete line - } - else // normal comment - { - // startFontClass("keyword"); - codifyLines(text,0,FALSE,TRUE); - // endFontClass(); - } + QCString text(vhdlcodeYYtext); + int i=text.find("--"); + if (text.mid(i,3)=="--!") // && // hide special comment + { + if (!Config_getBool(STRIP_CODE_COMMENTS)) + { + codifyLines(text,0,FALSE,TRUE); + } + else g_yyLineNr++; // skip complete line, but count line + } + else // normal comment + { + codifyLines(text,0,FALSE,TRUE); + } } <*>{TEXTT} { // found normal or special comment after something - QCString text(vhdlcodeYYtext); - int i=text.find("--"); - if (text.mid(i,3)=="--!" && - Config_getBool(STRIP_CODE_COMMENTS)) - { - // hide special comment - } - else // normal comment - { - // startFontClass("keyword"); - codifyLines(text,0,FALSE,TRUE); - // endFontClass(); - } + QCString text(vhdlcodeYYtext); + int i=text.find("--"); + if (text.mid(i,3)=="--!") + { + // hide special comment + if (!Config_getBool(STRIP_CODE_COMMENTS)) + { + codifyLines(text,0,FALSE,TRUE); + } + } + else // normal comment + { + codifyLines(text,0,FALSE,TRUE); + } } - %% /*@ ---------------------------------------------------------------------------- diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index dcf7f42..b18bd3f 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -26,7 +26,7 @@ #include <string.h> #include <qcstring.h> #include <qfileinfo.h> -#include <qstringlist.h> +#include <qcstringlist.h> #include <qmap.h> /* --------------------------------------------------------------- */ @@ -61,7 +61,7 @@ #include "vhdlcode.h" #include "plantuml.h" //#define DEBUGFLOW -#define theTranslator_vhdlType VhdlDocGen::trVhdlType +#define theTranslator_vhdlType theTranslator->trVhdlType static QDict<QCString> g_vhdlKeyDict0(17,FALSE); static QDict<QCString> g_vhdlKeyDict1(17,FALSE); @@ -299,10 +299,10 @@ static QCString formatBriefNote(const QCString &brief,ClassDef * cd) int k=cd->briefLine(); - QStringList qsl=QStringList::split(ep,brief); + QCStringList qsl=QCStringList::split(ep,brief); for(uint j=0;j<qsl.count();j++) { - QCString qcs=qsl[j].data(); + QCString qcs=qsl[j]; vForm+=parseCommentAsText(cd,NULL,qcs,file,k); k++; vForm+='\n'; @@ -602,7 +602,7 @@ const char* g_vhdlKeyWordMap1[] = { "natural","unsigned","signed","string","boolean", "bit","bit_vector","character", "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer", - "real","float","ufixed","sfixed","time",0 + "real","float","ufixed","sfixed","time","positive",0 }; // logic @@ -667,7 +667,7 @@ const char* g_vhdlKeyWordMap3[] = QCString* VhdlDocGen::findKeyWord(const QCString& tmp) { static QCString vhdlkeyword("vhdlkeyword"); - static QCString vhdltype("comment"); + static QCString vhdltype("keywordtype"); static QCString vhdllogic("vhdllogic"); static QCString preprocessor("keywordflow"); @@ -968,7 +968,6 @@ QCString VhdlDocGen::getClassTitle(const ClassDef *cd) int ii=cd->protection(); pageTitle+=" "; pageTitle+=theTranslator_vhdlType(ii+2,TRUE); - pageTitle+=" "; return pageTitle; } // getClassTitle @@ -1029,8 +1028,8 @@ void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol) } else if (ii==VhdlDocGen::ARCHITECTURE) { - QStringList qlist=QStringList::split("-",nn,FALSE); - nn=qlist[1].utf8(); + QCStringList qlist=QCStringList::split("-",nn); + nn=qlist[1]; cd=VhdlDocGen::getClass(nn.data()); } @@ -1042,9 +1041,9 @@ void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol) for (int i=0;i<j;i++) { QCString *temp=ql.at(i); - QStringList qlist=QStringList::split("-",*temp,FALSE); - QCString s1=qlist[0].utf8(); - QCString s2=qlist[1].utf8(); + QCStringList qlist=QCStringList::split("-",*temp); + QCString s1=qlist[0]; + QCString s2=qlist[1]; s1.stripPrefix("_"); if (j==1) s1.resize(0); ClassDef*cc = getClass(temp->data()); @@ -1076,8 +1075,8 @@ void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd) QCString jj=citer->className(); if (cd != citer && jj.contains('-')!=-1) { - QStringList ql=QStringList::split("-",jj,FALSE); - QCString temp=ql[1].utf8(); + QCStringList ql=QCStringList::split("-",jj); + QCString temp=ql[1]; if (qstricmp(cd->className(),temp)==0) { QCString *cl=new QCString(jj); @@ -1096,10 +1095,10 @@ ClassDef* VhdlDocGen::findArchitecture(const ClassDef *cd) for ( ; (citer=cli.current()) ; ++cli ) { QCString jj=citer->name(); - QStringList ql=QStringList::split(":",jj,FALSE); + QCStringList ql=QCStringList::split(":",jj); if (ql.count()>1) { - if (ql[0].utf8()==nn ) + if (ql[0]==nn ) { return citer; } @@ -1212,15 +1211,15 @@ void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist, QCString VhdlDocGen::getIndexWord(const char* c,int index) { - QStringList ql; + QCStringList ql; QCString temp(c); QRegExp reg("[\\s:|]"); - ql=QStringList::split(reg,temp,FALSE); + ql=QCStringList::split(reg,temp); if (ql.count() > (unsigned int)index) { - return ql[index].utf8(); + return ql[index]; } return ""; @@ -1241,42 +1240,6 @@ QCString VhdlDocGen::getProtectionName(int prot) return ""; } -QCString VhdlDocGen::trTypeString(uint64 type) -{ - switch(type) - { - case VhdlDocGen::LIBRARY: return "Library"; - case VhdlDocGen::ENTITY: return "Entity"; - case VhdlDocGen::PACKAGE_BODY: return "Package Body"; - case VhdlDocGen::ATTRIBUTE: return "Attribute"; - case VhdlDocGen::PACKAGE: return "Package"; - case VhdlDocGen::SIGNAL: return "Signal"; - case VhdlDocGen::COMPONENT: return "Component"; - case VhdlDocGen::CONSTANT: return "Constant"; - case VhdlDocGen::TYPE: return "Type"; - case VhdlDocGen::SUBTYPE: return "Subtype"; - case VhdlDocGen::FUNCTION: return "Function"; - case VhdlDocGen::RECORD: return "Record"; - case VhdlDocGen::PROCEDURE: return "Procedure"; - case VhdlDocGen::ARCHITECTURE: return "Architecture"; - case VhdlDocGen::USE: return "Package"; - case VhdlDocGen::PROCESS: return "Process"; - case VhdlDocGen::PORT: return "Port"; - case VhdlDocGen::GENERIC: return "Generic"; - case VhdlDocGen::UNITS: return "Units"; - //case VhdlDocGen::PORTMAP: return "Port Map"; - case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable"; - case VhdlDocGen::GROUP: return "Group"; - case VhdlDocGen::VFILE: return "File"; - case VhdlDocGen::INSTANTIATION: return "Instantiation"; - case VhdlDocGen::ALIAS: return "Alias"; - case VhdlDocGen::CONFIG: return "Configuration"; - case VhdlDocGen::MISCELLANEOUS: return "Miscellaneous"; - case VhdlDocGen::UCF_CONST: return "Constraints"; - default: return ""; - } -} // convertType - /*! * deletes a char backwards in a string */ @@ -1790,7 +1753,7 @@ void VhdlDocGen::writeVhdlDeclarations(MemberList* ml, VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP); VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::INSTANTIATION,FALSE),0,FALSE,VhdlDocGen::INSTANTIATION); VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS); - VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS),0,FALSE,VhdlDocGen::MISCELLANEOUS); + VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS,TRUE),0,FALSE,VhdlDocGen::MISCELLANEOUS); // configurations must be added to global file definitions. VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG); @@ -2096,19 +2059,21 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, writeLink(mdef,ol); ol.docify(" "); - ol.insertMemberAlign(); if (mm==VhdlDocGen::GENERIC) { + ol.insertMemberAlign(); ol.startBold(); VhdlDocGen::formatString(largs,ol,mdef); ol.endBold(); } else { + ol.insertMemberAlignLeft(isAnonymous, false); ol.docify(" "); ol.startBold(); VhdlDocGen::formatString(ltype,ol,mdef); ol.endBold(); + ol.insertMemberAlign(); ol.docify(" "); VhdlDocGen::formatString(largs,ol,mdef); } @@ -2263,11 +2228,11 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, ol.endMemberItem(); if (!mdef->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC) /* && !annMemb */) { - QCString s=mdef->briefDescription(); - ol.startMemberDescription(mdef->anchor()); + QCString s=mdef->briefDescription(); + ol.startMemberDescription(mdef->anchor(), NULL, mm == VhdlDocGen::PORT); ol.generateDoc(mdef->briefFile(),mdef->briefLine(), - mdef->getOuterScope()?mdef->getOuterScope():d, - mdef,s.data(),TRUE,FALSE,0,TRUE,FALSE); + mdef->getOuterScope()?mdef->getOuterScope():d, + mdef,s.data(),TRUE,FALSE,0,TRUE,FALSE); if (detailsVisible) { ol.pushGeneratorState(); @@ -2364,7 +2329,7 @@ void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol, if (title) { - ol.startMemberHeader(title); + ol.startMemberHeader(convertToId(title),type == VhdlDocGen::PORT ? 3 : 2); ol.parseText(title); ol.endMemberHeader(); ol.docify(" "); @@ -2416,7 +2381,7 @@ bool VhdlDocGen::writeClassType( ClassDef *& cd, OutputList &ol ,QCString & cname) { int id=cd->protection(); - QCString qcs = VhdlDocGen::trTypeString(id+2); + QCString qcs = theTranslator->trVhdlType(id+2,TRUE); cname=VhdlDocGen::getClassName(cd); ol.startBold(); ol.writeString(qcs.data()); @@ -2426,128 +2391,6 @@ bool VhdlDocGen::writeClassType( ClassDef *& cd, return FALSE; }// writeClassLink -QCString VhdlDocGen::trVhdlType(uint64 type,bool sing) -{ - switch(type) - { - case VhdlDocGen::LIBRARY: - if (sing) return "Library"; - else return "Libraries"; - case VhdlDocGen::PACKAGE: - if (sing) return "Package"; - else return "Packages"; - case VhdlDocGen::SIGNAL: - if (sing) return "Signal"; - else return "Signals"; - case VhdlDocGen::COMPONENT: - if (sing) return "Component"; - else return "Components"; - case VhdlDocGen::CONSTANT: - if (sing) return "Constant"; - else return "Constants"; - case VhdlDocGen::ENTITY: - if (sing) return "Entity"; - else return "Entities"; - case VhdlDocGen::TYPE: - if (sing) return "Type"; - else return "Types"; - case VhdlDocGen::SUBTYPE: - if (sing) return "Subtype"; - else return "Subtypes"; - case VhdlDocGen::FUNCTION: - if (sing) return "Function"; - else return "Functions"; - case VhdlDocGen::RECORD: - if (sing) return "Record"; - else return "Records"; - case VhdlDocGen::PROCEDURE: - if (sing) return "Procedure"; - else return "Procedures"; - case VhdlDocGen::ARCHITECTURE: - if (sing) return "Architecture"; - else return "Architectures"; - case VhdlDocGen::ATTRIBUTE: - if (sing) return "Attribute"; - else return "Attributes"; - case VhdlDocGen::PROCESS: - if (sing) return "Process"; - else return "Processes"; - case VhdlDocGen::PORT: - if (sing) return "Port"; - else return "Ports"; - case VhdlDocGen::USE: - if (sing) return "use clause"; - else return "Use Clauses"; - case VhdlDocGen::GENERIC: - if (sing) return "Generic"; - else return "Generics"; - case VhdlDocGen::PACKAGE_BODY: - return "Package Body"; - case VhdlDocGen::UNITS: - return "Units"; - case VhdlDocGen::SHAREDVARIABLE: - if (sing) return "Shared Variable"; - return "Shared Variables"; - case VhdlDocGen::VFILE: - if (sing) return "File"; - return "Files"; - case VhdlDocGen::GROUP: - if (sing) return "Group"; - return "Groups"; - case VhdlDocGen::INSTANTIATION: - if (sing) return "Instantiation"; - else return "Instantiations"; - case VhdlDocGen::ALIAS: - if (sing) return "Alias"; - return "Aliases"; - case VhdlDocGen::CONFIG: - if (sing) return "Configuration"; - return "Configurations"; - case VhdlDocGen::MISCELLANEOUS: - return "Miscellaneous"; - case VhdlDocGen::UCF_CONST: - return "Constraints"; - default: - return "Class"; - } -} - -QCString VhdlDocGen::trDesignUnitHierarchy() -{ - return "Design Unit Hierarchy"; -} - -QCString VhdlDocGen::trDesignUnitList() -{ - return "Design Unit List"; -} - -QCString VhdlDocGen::trDesignUnitMembers() -{ - return "Design Unit Members"; -} - -QCString VhdlDocGen::trDesignUnitListDescription() -{ - return "Here is a list of all design unit members with links to " - "the Entities they belong to:"; -} - -QCString VhdlDocGen::trDesignUnitIndex() -{ - return "Design Unit Index"; -} - -QCString VhdlDocGen::trDesignUnits() -{ - return "Design Units"; -} - -QCString VhdlDocGen::trFunctionAndProc() -{ - return "Functions/Procedures/Processes"; -} - /*! writes a link if the string is linkable else a formatted string */ @@ -2623,8 +2466,8 @@ void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname) if (cname.isEmpty()) return; mdef->writeSourceDef(ol,cname); - mdef->writeSourceRefs(ol,cname); - mdef->writeSourceReffedBy(ol,cname); + if (mdef->hasReferencesRelation()) mdef->writeSourceRefs(ol,cname); + if (mdef->hasReferencedByRelation()) mdef->writeSourceReffedBy(ol,cname); } @@ -2835,11 +2678,11 @@ QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch) if (!entity.contains(":")) return ""; QRegExp exp("[:()\\s]"); - QStringList ql=QStringList::split(exp,entity,FALSE); + QCStringList ql=QCStringList::split(exp,entity); //int ii=ql.findIndex(ent); assert(ql.count()>=2); - label = ql[0].utf8(); - entity = ql[1].utf8(); + label = ql[0]; + entity = ql[1]; if ((index=entity.findRev("."))>=0) { entity.remove(0,index+1); @@ -2847,8 +2690,8 @@ QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch) if (ql.count()==3) { - arch= ql[2].utf8(); - ql=QStringList::split(exp,arch,FALSE); + arch= ql[2]; + ql=QCStringList::split(exp,arch); if (ql.count()>1) // expression { arch=""; @@ -2865,16 +2708,16 @@ QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch) QRegExp exp("[()\\s]"); QCString label=""; - QStringList ql=QStringList::split(exp,entity,FALSE); + QCStringList ql=QCStringList::split(exp,entity); if (ql.contains("open")) { return "open"; } - label=ql[0].utf8(); + label=ql[0]; - entity = ql[1].utf8(); + entity = ql[1]; if ((index=entity.findRev("."))>=0) { entity.remove(0,index+1); @@ -2882,7 +2725,7 @@ QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch) if (ql.count()==3) { - arch=ql[2].utf8(); + arch=ql[2]; } return label; } @@ -3000,7 +2843,7 @@ void assignBinding(VhdlConfNode * conf) QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower(); QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower(); - QStringList ql=QStringList::split(",",inst1); + QCStringList ql=QCStringList::split(",",inst1); for (uint j=0;j<ql.count();j++) { @@ -3012,7 +2855,7 @@ void assignBinding(VhdlConfNode * conf) } else { - archy1=comp+":"+ql[j].utf8(); + archy1=comp+":"+ql[j]; sign1=cur->type+":"+cur->name; } @@ -3147,7 +2990,8 @@ ferr: Public, Normal, cur->stat,Member, MemberType_Variable, 0, - 0); + 0, + ""); if (ar->getOutputFileBase()) { @@ -3186,11 +3030,11 @@ ferr: void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef) { - QStringList ql=QStringList::split("#",largs,FALSE); + QCStringList ql=QCStringList::split("#",largs,FALSE); uint len=ql.count(); for(uint i=0;i<len;i++) { - QCString n=ql[i].utf8(); + QCString n=ql[i]; VhdlDocGen::formatString(n,ol,mdef); if ((len-i)>1) ol.lineBreak(); } @@ -3203,14 +3047,14 @@ void VhdlDocGen::writeRecUnitDocu( QCString largs) { - QStringList ql=QStringList::split("#",largs,FALSE); + QCStringList ql=QCStringList::split("#",largs); uint len=ql.count(); ol.startParameterList(TRUE); bool first=TRUE; for(uint i=0;i<len;i++) { - QCString n=ql[i].utf8(); + QCString n=ql[i]; ol.startParameterType(first,""); ol.endParameterType(); ol.startParameterName(TRUE); @@ -3643,14 +3487,14 @@ void FlowChart::alignCommentNode(FTextStream &t,QCString com) { uint max=0; QCString s; - QStringList ql=QStringList::split("\n",com); + QCStringList ql=QCStringList::split("\n",com); for (uint j=0;j<ql.count();j++) { - s=(QCString)ql[j].utf8(); + s=(QCString)ql[j]; if (max<s.length()) max=s.length(); } - s=ql.last().utf8(); + s=ql.last(); int diff=max-s.length(); QCString n(1); @@ -3665,7 +3509,7 @@ void FlowChart::alignCommentNode(FTextStream &t,QCString com) for (uint j=0;j<ql.count();j++) { - s=(QCString)ql[j].utf8(); + s=ql[j]; if (j<ql.count()-1) { s+="\n"; @@ -3993,7 +3837,7 @@ void FlowChart::createSVG() //const MemberDef *m=VhdlDocGen::getFlowMember(); //if (m) - // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data()); + // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",theTranslator->trVhdlType(m->getMemberSpecifiers(),TRUE),m->name().data(),m->getFileDef()->name().data()); QCString dir=" -o \""+ov+qcs+"\""; ov+="/flow_design.dot"; diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index bd190ca..9dd8417 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -150,33 +150,6 @@ class VhdlDocGen static bool isMisc(const MemberDef *mdef); //----------------------------------------------------- - // translatable items - - static QCString trTypeString(uint64 type); - static QCString trVhdlType(uint64 type,bool sing=true); - - // trClassHierarchy. - static QCString trDesignUnitHierarchy(); - - // trCompoundList - static QCString trDesignUnitList(); - - // trCompoundMembers. - static QCString trDesignUnitMembers(); - - // trCompoundListDescription - static QCString trDesignUnitListDescription(); - - // trCompounds - static QCString trDesignUnits(); - - // trCompoundIndex - static QCString trDesignUnitIndex(); - - // trFunctions - static QCString trFunctionAndProc(); - - //----------------------------------------------------- static void prepareComment(QCString&); static void formatString(const QCString&,OutputList& ol,const MemberDef*); diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index 953cd6b..81a7ca1 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -12,7 +12,7 @@ #include <qcstring.h> #include <qfileinfo.h> -#include <qstringlist.h> +#include <qcstringlist.h> #include "vhdljjparser.h" #include "vhdlcode.h" #include "vhdldocgen.h" @@ -80,9 +80,9 @@ static struct int iDocLine; } str_doc; -static bool doxComment=FALSE; // doxygen comment ? static QCString strComment; static int iCodeLen; +static const char *vhdlFileName = 0; bool checkMultiComment(QCString& qcs,int line); QList<Entry>* getEntryAtLine(const Entry* ce,int line); @@ -99,59 +99,6 @@ Entry* getVhdlCompound() return NULL; } -void startCodeBlock(int index) -{ - int ll=strComment.length(); - if (!gBlock) gBlock = new Entry; - iCodeLen=inputString.findRev(strComment.data())+ll; - // fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll); - gBlock->reset(); - int len=strComment.length(); - QCString name=strComment.right(len-index);// - name=VhdlDocGen::getIndexWord(name.data(),1); - if (!name) - gBlock->name="misc"+ VhdlDocGen::getRecordNumber(); - else - gBlock->name=name; - - gBlock->startLine=yyLineNr; - gBlock->bodyLine=yyLineNr; - - strComment=strComment.left(index); - VhdlDocGen::prepareComment(strComment); - gBlock->brief+=strComment; -} - -void makeInlineDoc(int endCode) -{ - int len=endCode-iCodeLen; - if (!gBlock) gBlock = new Entry; - QCString par=inputString.mid(iCodeLen,len); - //fprintf(stderr,"\n inline code: \n<%s>",par.data()); - gBlock->doc=par; - gBlock->inbodyDocs=par; - gBlock->section=Entry::VARIABLE_SEC; - gBlock->spec=VhdlDocGen::MISCELLANEOUS; - gBlock->fileName = yyFileName; - gBlock->endBodyLine=yyLineNr-1; - gBlock->lang=SrcLangExt_VHDL; - Entry *temp=new Entry(*gBlock); - Entry* compound=getVhdlCompound(); - - if (compound) - { - compound->addSubEntry(temp); - } - else - { - temp->type="misc"; // global code like library ieee... - VhdlParser::current_root->addSubEntry(temp); - } - strComment.resize(0); - gBlock->reset(); -}// makeInlineDoc - - bool isConstraintFile(const QCString &fileName,const QCString &ext) { return fileName.right(ext.length())==ext; @@ -200,6 +147,7 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En VhdlParser::current=new Entry(); VhdlParser::initEntry(VhdlParser::current); groupEnterFile(fileName,yyLineNr); + vhdlFileName = fileName; lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h VhdlParserIF::parseVhdlfile(fileBuf,inLine); @@ -213,6 +161,7 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En yyFileName.resize(0); libUse.clear(); VhdlDocGen::resetCodeVhdlParserState(); + vhdlFileName = 0; } void VhdlParser::lineCount() @@ -279,20 +228,6 @@ void VhdlParser::newEntry() initEntry(current); } -bool checkInlineCode(QCString & doc) -{ - int index=doc.find("\\code"); - - if (index>0) - { - strComment+=doc; - startCodeBlock(index); - doxComment=TRUE; - return true; - } - return false; -} - void VhdlParser::handleFlowComment(const char* doc) { lineCount(doc); @@ -310,7 +245,6 @@ void VhdlParser::handleFlowComment(const char* doc) void VhdlParser::handleCommentBlock(const char* doc1,bool brief) { int position=0; - static bool isIn; QCString doc; doc.append(doc1); // fprintf(stderr,"\n %s",doc.data()); @@ -322,22 +256,6 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) return; } - isIn=checkInlineCode(doc); - bool isEndCode=doc.contains("\\endcode"); - // empty comment --! - if (isEndCode) - { - int end=inputString.find(doc.data(),iCodeLen); - makeInlineDoc(end); - strComment.resize(0); - isIn=false; - } - if (isIn) - { - isIn=false; - return; - } - VhdlDocGen::prepareComment(doc); bool needsEntry=FALSE; @@ -463,11 +381,11 @@ void VhdlParser::addVhdlType(const char *n,int startLine,int section, spec= VhdlDocGen::GENERIC; } - QStringList ql=QStringList::split(",",name,FALSE); + QCStringList ql=QCStringList::split(",",name); for (uint u=0;u<ql.count();u++) { - current->name=ql[u].utf8(); + current->name=ql[u]; current->startLine=startLine; current->bodyLine=startLine; current->section=section; @@ -524,11 +442,11 @@ void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn) VhdlDocGen::deleteAllChars(current->args,' '); if (!fname.isEmpty()) { - QStringList q1=QStringList::split(",",fname); + QCStringList q1=QCStringList::split(",",fname); for (uint ii=0;ii<q1.count();ii++) { Argument *arg=new Argument; - arg->name=q1[ii].utf8(); + arg->name=q1[ii]; current->argList->append(arg); } } @@ -622,12 +540,12 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, { (void)s5; // avoid unused warning QCString name=s2; - QStringList ql=QStringList::split(",",name,FALSE); + QCStringList ql=QCStringList::split(",",name); for (uint u=0;u<ql.count();u++) { Argument *arg=new Argument; - arg->name=ql[u].utf8(); + arg->name=ql[u]; if (s3) { arg->type=s3; @@ -788,31 +706,12 @@ void VhdlParser::setMultCommentLine() void VhdlParser::oneLineComment(QCString qcs) { - bool isEndCode=qcs.contains("\\endcode"); - - int index = qcs.find("\\code"); - if (isEndCode) - { - int end = inputString.find(qcs.data(),iCodeLen); - makeInlineDoc(end); - } - else if (index > 0) - { - // assert(false); - strComment=qcs; - startCodeBlock(index); - strComment.resize(0); - } - - if (!isEndCode && index==-1) - { int j=qcs.find("--!"); qcs=qcs.right(qcs.length()-3-j); if (!checkMultiComment(qcs,iDocLine)) { handleCommentBlock(qcs,TRUE); } - } } @@ -851,3 +750,7 @@ QList<Entry>* getEntryAtLine(const Entry* ce,int line) return &lineEntry; } +const char *getVhdlFileName(void) +{ + return vhdlFileName; +} diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index a0851d7..3a2ed61 100644 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -7,6 +7,7 @@ #include <assert.h> #include <ctype.h> #include <qarray.h> +#include <qcstringlist.h> #include <qfile.h> #include <qdict.h> @@ -14,7 +15,6 @@ #include "types.h" #include "entry.h" #include "vhdldocgen.h" -#include "qstringlist.h" #include "vhdlcode.h" #include "memberlist.h" #include "config.h" @@ -30,7 +30,6 @@ class ClassSDict; class FileStorage; class ClassDef; class MemberDef; -class QStringList; struct VhdlConfNode; diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 93765b1..a65695c 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -31,6 +31,7 @@ #include "filename.h" #include "config.h" #include "htmlentity.h" +#include "emoji.h" static void visitCaption(XmlDocVisitor *parent, QList<DocNode> children) { @@ -39,10 +40,10 @@ static void visitCaption(XmlDocVisitor *parent, QList<DocNode> children) for (cli.toFirst();(n=cli.current());++cli) n->accept(parent); } -static void visitPreStart(FTextStream &t, const char *cmd, const bool doCaption, +static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption, XmlDocVisitor *parent, QList<DocNode> children, const QCString &name, bool writeType, DocImage::Type type, const QCString &width, - const QCString &height) + const QCString &height, bool inlineImage = FALSE) { t << "<" << cmd; if (writeType) @@ -65,10 +66,11 @@ static void visitPreStart(FTextStream &t, const char *cmd, const bool doCaption, { t << " width=\"" << convertToXML(width) << "\""; } - else if (!height.isEmpty()) + if (!height.isEmpty()) { t << " height=\"" << convertToXML(height) << "\""; } + if (inlineImage) t << " inline=\"yes\">"; if (doCaption) { t << " caption=\""; @@ -133,6 +135,24 @@ void XmlDocVisitor::visit(DocSymbol *s) } } +void XmlDocVisitor::visit(DocEmoji *s) +{ + if (m_hide) return; + 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())); + m_t << "\"/>"; + } + else + { + m_t << s->name(); + } +} + void XmlDocVisitor::visit(DocURL *u) { if (m_hide) return; @@ -164,6 +184,12 @@ void XmlDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Bold: if (s->enable()) m_t << "<bold>"; else m_t << "</bold>"; break; + case DocStyleChange::Strike: + if (s->enable()) m_t << "<strike>"; else m_t << "</strike>"; + break; + case DocStyleChange::Underline: + if (s->enable()) m_t << "<underline>"; else m_t << "</underline>"; + break; case DocStyleChange::Italic: if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>"; break; @@ -307,7 +333,14 @@ void XmlDocVisitor::visit(DocInclude *inc) case DocInclude::DontInclude: break; case DocInclude::HtmlInclude: - m_t << "<htmlonly>"; + if (inc->isBlock()) + { + m_t << "<htmlonly block=\"yes\">"; + } + else + { + m_t << "<htmlonly>"; + } filter(inc->text()); m_t << "</htmlonly>"; break; @@ -488,7 +521,7 @@ void XmlDocVisitor::visitPre(DocPara *) void XmlDocVisitor::visitPost(DocPara *) { if (m_hide) return; - m_t << "</para>"; + m_t << "</para>" << endl; } void XmlDocVisitor::visitPre(DocRoot *) @@ -767,7 +800,7 @@ void XmlDocVisitor::visitPre(DocImage *img) { baseName=baseName.right(baseName.length()-i-1); } - visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height()); + visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height(), img ->isInlineImage()); // copy the image to the output dir FileDef *fd; diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h index c65688f..c2c6537 100644 --- a/src/xmldocvisitor.h +++ b/src/xmldocvisitor.h @@ -41,6 +41,7 @@ class XmlDocVisitor : public DocVisitor void visit(DocLinkedWord *); void visit(DocWhiteSpace *); void visit(DocSymbol *); + void visit(DocEmoji *); void visit(DocURL *); void visit(DocLineBreak *); void visit(DocHorRuler *); diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 0f46c6e..985a3e7 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -97,6 +97,8 @@ class XmlSectionMapper : public QIntDict<char> insert(MemberListType_decDefineMembers,"define"); insert(MemberListType_decProtoMembers,"prototype"); insert(MemberListType_decTypedefMembers,"typedef"); + insert(MemberListType_decSequenceMembers,"sequence"); + insert(MemberListType_decDictionaryMembers,"dictionary"); insert(MemberListType_decEnumMembers,"enum"); insert(MemberListType_decFuncMembers,"func"); insert(MemberListType_decVarMembers,"var"); @@ -175,7 +177,7 @@ static void writeCombineScript() " <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n" " <xsl:template match=\"/\">\n" " <doxygen version=\"{doxygenindex/@version}\">\n" - " <!-- Load all doxgen generated xml files -->\n" + " <!-- Load all doxygen generated xml files -->\n" " <xsl:for-each select=\"doxygenindex/compound\">\n" " <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n" " </xsl:for-each>\n" @@ -222,146 +224,117 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf /** Generator for producing XML formatted source code. */ -class XMLCodeGenerator : public CodeOutputInterface +void XMLCodeGenerator::codify(const char *text) { - public: - - XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1), m_isMemberRef(FALSE), m_col(0), - m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE), m_insideSpecialHL(FALSE) {} - virtual ~XMLCodeGenerator() { } - - void codify(const char *text) - { - XML_DB(("(codify \"%s\")\n",text)); - if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag) - { - m_t << "<highlight class=\"normal\">"; - m_normalHLNeedStartTag=FALSE; - } - writeXMLCodeString(m_t,text,m_col); - } - void writeCodeLink(const char *ref,const char *file, - const char *anchor,const char *name, - const char *tooltip) - { - XML_DB(("(writeCodeLink)\n")); - if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag) - { - m_t << "<highlight class=\"normal\">"; - m_normalHLNeedStartTag=FALSE; - } - writeXMLLink(m_t,ref,file,anchor,name,tooltip); - m_col+=qstrlen(name); - } - void writeTooltip(const char *, const DocLinkInfo &, const char *, - const char *, const SourceLinkInfo &, const SourceLinkInfo & - ) - { - XML_DB(("(writeToolTip)\n")); - } - void startCodeLine(bool) - { - XML_DB(("(startCodeLine)\n")); - m_t << "<codeline"; - if (m_lineNumber!=-1) - { - m_t << " lineno=\"" << m_lineNumber << "\""; - if (!m_refId.isEmpty()) - { - m_t << " refid=\"" << m_refId << "\""; - if (m_isMemberRef) - { - m_t << " refkind=\"member\""; - } - else - { - m_t << " refkind=\"compound\""; - } - } - if (!m_external.isEmpty()) - { - m_t << " external=\"" << m_external << "\""; - } - } - m_t << ">"; - m_insideCodeLine=TRUE; - m_col=0; - } - void endCodeLine() - { - XML_DB(("(endCodeLine)\n")); - if (!m_insideSpecialHL && !m_normalHLNeedStartTag) - { - m_t << "</highlight>"; - m_normalHLNeedStartTag=TRUE; - } - m_t << "</codeline>" << endl; // non DocBook - m_lineNumber = -1; - m_refId.resize(0); - m_external.resize(0); - m_insideCodeLine=FALSE; - } - void startFontClass(const char *colorClass) + XML_DB(("(codify \"%s\")\n",text)); + if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag) + { + m_t << "<highlight class=\"normal\">"; + m_normalHLNeedStartTag=FALSE; + } + writeXMLCodeString(m_t,text,m_col); +} +void XMLCodeGenerator::writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip) +{ + XML_DB(("(writeCodeLink)\n")); + if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag) + { + m_t << "<highlight class=\"normal\">"; + m_normalHLNeedStartTag=FALSE; + } + writeXMLLink(m_t,ref,file,anchor,name,tooltip); + m_col+=qstrlen(name); +} +void XMLCodeGenerator::writeTooltip(const char *, const DocLinkInfo &, const char *, + const char *, const SourceLinkInfo &, const SourceLinkInfo & + ) +{ + XML_DB(("(writeToolTip)\n")); +} +void XMLCodeGenerator::startCodeLine(bool) +{ + XML_DB(("(startCodeLine)\n")); + m_t << "<codeline"; + if (m_lineNumber!=-1) + { + m_t << " lineno=\"" << m_lineNumber << "\""; + if (!m_refId.isEmpty()) { - XML_DB(("(startFontClass)\n")); - if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag) + m_t << " refid=\"" << m_refId << "\""; + if (m_isMemberRef) { - m_t << "</highlight>"; - m_normalHLNeedStartTag=TRUE; + m_t << " refkind=\"member\""; } - m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook - m_insideSpecialHL=TRUE; - } - void endFontClass() - { - XML_DB(("(endFontClass)\n")); - m_t << "</highlight>"; // non DocBook - m_insideSpecialHL=FALSE; - } - void writeCodeAnchor(const char *) - { - XML_DB(("(writeCodeAnchor)\n")); - } - void writeLineNumber(const char *extRef,const char *compId, - const char *anchorId,int l) - { - XML_DB(("(writeLineNumber)\n")); - // we remember the information provided here to use it - // at the <codeline> start tag. - m_lineNumber = l; - if (compId) + else { - m_refId=compId; - if (anchorId) m_refId+=(QCString)"_1"+anchorId; - m_isMemberRef = anchorId!=0; - if (extRef) m_external=extRef; + m_t << " refkind=\"compound\""; } } - void setCurrentDoc(Definition *,const char *,bool) + if (!m_external.isEmpty()) { + m_t << " external=\"" << m_external << "\""; } - void addWord(const char *,bool) - { - } - - void finish() - { - if (m_insideCodeLine) endCodeLine(); - } - - private: - FTextStream &m_t; - QCString m_refId; - QCString m_external; - int m_lineNumber; - bool m_isMemberRef; - int m_col; - - bool m_insideCodeLine; - bool m_normalHLNeedStartTag; - bool m_insideSpecialHL; -}; - + } + m_t << ">"; + m_insideCodeLine=TRUE; + m_col=0; +} +void XMLCodeGenerator::endCodeLine() +{ + XML_DB(("(endCodeLine)\n")); + if (!m_insideSpecialHL && !m_normalHLNeedStartTag) + { + m_t << "</highlight>"; + m_normalHLNeedStartTag=TRUE; + } + m_t << "</codeline>" << endl; // non DocBook + m_lineNumber = -1; + m_refId.resize(0); + m_external.resize(0); + m_insideCodeLine=FALSE; +} +void XMLCodeGenerator::startFontClass(const char *colorClass) +{ + XML_DB(("(startFontClass)\n")); + if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag) + { + m_t << "</highlight>"; + m_normalHLNeedStartTag=TRUE; + } + m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook + m_insideSpecialHL=TRUE; +} +void XMLCodeGenerator::endFontClass() +{ + XML_DB(("(endFontClass)\n")); + m_t << "</highlight>"; // non DocBook + m_insideSpecialHL=FALSE; +} +void XMLCodeGenerator::writeCodeAnchor(const char *) +{ + XML_DB(("(writeCodeAnchor)\n")); +} +void XMLCodeGenerator::writeLineNumber(const char *extRef,const char *compId, + const char *anchorId,int l) +{ + XML_DB(("(writeLineNumber)\n")); + // we remember the information provided here to use it + // at the <codeline> start tag. + m_lineNumber = l; + if (compId) + { + m_refId=compId; + if (anchorId) m_refId+=(QCString)"_1"+anchorId; + m_isMemberRef = anchorId!=0; + if (extRef) m_external=extRef; + } +} +void XMLCodeGenerator::finish() +{ + if (m_insideCodeLine) endCodeLine(); +} static void writeTemplateArgumentList(ArgumentList *al, FTextStream &t, @@ -554,20 +527,22 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De bool isFunc=FALSE; switch (md->memberType()) { - case MemberType_Define: memType="define"; break; - case MemberType_Function: memType="function"; isFunc=TRUE; break; - case MemberType_Variable: memType="variable"; break; - case MemberType_Typedef: memType="typedef"; break; - case MemberType_Enumeration: memType="enum"; break; - case MemberType_EnumValue: ASSERT(0); break; - case MemberType_Signal: memType="signal"; isFunc=TRUE; break; - case MemberType_Slot: memType="slot"; isFunc=TRUE; break; - case MemberType_Friend: memType="friend"; isFunc=TRUE; break; - case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break; - case MemberType_Property: memType="property"; break; - case MemberType_Event: memType="event"; break; - case MemberType_Interface: memType="interface"; break; - case MemberType_Service: memType="service"; break; + case MemberType_Define: memType="define"; break; + case MemberType_Function: memType="function"; isFunc=TRUE; break; + case MemberType_Variable: memType="variable"; break; + case MemberType_Typedef: memType="typedef"; break; + case MemberType_Enumeration: memType="enum"; break; + case MemberType_EnumValue: ASSERT(0); break; + case MemberType_Signal: memType="signal"; isFunc=TRUE; break; + case MemberType_Slot: memType="slot"; isFunc=TRUE; break; + case MemberType_Friend: memType="friend"; isFunc=TRUE; break; + case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break; + case MemberType_Property: memType="property"; break; + case MemberType_Event: memType="event"; break; + case MemberType_Interface: memType="interface"; break; + case MemberType_Service: memType="service"; break; + case MemberType_Sequence: memType="sequence"; break; + case MemberType_Dictionary: memType="dictionary"; break; } ti << " <member refid=\"" << memberOutputFileBase(md) @@ -1163,7 +1138,7 @@ static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t) NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { - if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes + if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymous scopes { t << " <innernamespace refid=\"" << nd->getOutputFileBase() << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl; @@ -1838,9 +1813,62 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) } } writeInnerPages(pd->getSubPages(),t); - if(pd->showToc()) - { - t << " <tableofcontents/>" << endl; + if (pd->localToc().isXmlEnabled()) + { + t << " <tableofcontents>" << endl; + SectionDict *sectionDict = pd->getSectionDict(); + SDict<SectionInfo>::Iterator li(*sectionDict); + SectionInfo *si; + int level=1,l; + bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; + int maxLevel = pd->localToc().xmlLevel(); + for (li.toFirst();(si=li.current());++li) + { + if (si->type==SectionInfo::Section || + si->type==SectionInfo::Subsection || + si->type==SectionInfo::Subsubsection || + si->type==SectionInfo::Paragraph) + { + //printf(" level=%d title=%s\n",level,si->title.data()); + int nextLevel = (int)si->type; + if (nextLevel>level) + { + for (l=level;l<nextLevel;l++) + { + if (l < maxLevel) t << " <tableofcontents>" << endl; + } + } + else if (nextLevel<level) + { + for (l=level;l>nextLevel;l--) + { + if (l <= maxLevel && inLi[l]) t << " </tocsect>" << endl; + inLi[l]=FALSE; + if (l <= maxLevel) t << " </tableofcontents>" << endl; + } + } + if (nextLevel <= maxLevel) + { + if (inLi[nextLevel]) t << " </tocsect>" << endl; + QCString titleDoc = convertToXML(si->title); + t << " <tocsect>" << endl; + t << " <name>" << (si->title.isEmpty()?si->label:titleDoc) << "</name>" << endl; + t << " <reference>" << convertToXML(pageName) << "_1" << convertToXML(si -> label) << "</reference>" << endl; + inLi[nextLevel]=TRUE; + level = nextLevel; + } + } + } + while (level>1 && level <= maxLevel) + { + if (inLi[level]) t << " </tocsect>" << endl; + inLi[level]=FALSE; + t << " </tableofcontents>" << endl; + level--; + } + if (level <= maxLevel && inLi[level]) t << " </tocsect>" << endl; + inLi[level]=FALSE; + t << " </tableofcontents>" << endl; } t << " <briefdescription>" << endl; writeXMLDocBlock(t,pd->briefFile(),pd->briefLine(),pd,0,pd->briefDescription()); diff --git a/src/xmlgen.h b/src/xmlgen.h index 0447591..0555546 100644 --- a/src/xmlgen.h +++ b/src/xmlgen.h @@ -15,6 +15,48 @@ #ifndef XMLGEN_H #define XMLGEN_H +#include "outputgen.h" + +class XMLCodeGenerator : public CodeOutputInterface +{ + public: + + XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1), m_isMemberRef(FALSE), m_col(0), + m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE), m_insideSpecialHL(FALSE) {} + virtual ~XMLCodeGenerator() { } + + void codify(const char *text); + void writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip); + void writeTooltip(const char *, const DocLinkInfo &, const char *, + const char *, const SourceLinkInfo &, const SourceLinkInfo & + ); + void startCodeLine(bool); + void endCodeLine(); + void startFontClass(const char *colorClass); + void endFontClass(); + void writeCodeAnchor(const char *); + void writeLineNumber(const char *extRef,const char *compId, + const char *anchorId,int l); + void setCurrentDoc(Definition *,const char *,bool){} + void addWord(const char *,bool){} + + void finish(); + + private: + FTextStream &m_t; + QCString m_refId; + QCString m_external; + int m_lineNumber; + bool m_isMemberRef; + int m_col; + + bool m_insideCodeLine; + bool m_normalHLNeedStartTag; + bool m_insideSpecialHL; +}; + void generateXML(); #endif |