diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2000-12-17 15:15:12 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2000-12-17 15:15:12 (GMT) |
commit | 00415514455991a9ff44b926c50adda994128924 (patch) | |
tree | 8face58cec7cf3e5e23acec30b6af55f5bed931c /src | |
parent | 5167cf2076e30ed3f6ddd84b76543a0dff207496 (diff) | |
download | Doxygen-00415514455991a9ff44b926c50adda994128924.zip Doxygen-00415514455991a9ff44b926c50adda994128924.tar.gz Doxygen-00415514455991a9ff44b926c50adda994128924.tar.bz2 |
Release-1.2.3-20001217
Diffstat (limited to 'src')
46 files changed, 1750 insertions, 732 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index 775b84f..ac104eb 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -730,7 +730,22 @@ void ClassDef::writeDocumentation(OutputList &ol) } - if (!Config::genTagFile.isEmpty()) tagFile << ">" << name() << ":"; + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <compound kind=\""; + switch(compType) + { + case Class: tagFile << "class"; break; + case Struct: tagFile << "struct"; break; + case Union: tagFile << "union"; break; + case Interface: tagFile << "interface"; break; + case Exception: tagFile << "exception"; break; + } + tagFile << "\">" << endl; + tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; + tagFile << " <filename>" << convertToXML(fileName) << ".html</filename>" << endl; + } + if (Config::classDiagramFlag) ol.disableAllBut(OutputGenerator::Man); @@ -756,7 +771,23 @@ void ClassDef::writeDocumentation(OutputList &ol) ClassDef *cd=bcd->classDef; if (cd->isLinkable()) { - if (!Config::genTagFile.isEmpty()) tagFile << cd->name() << "?"; + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <base"; + if (bcd->prot==Protected) + { + tagFile << " protection=\"protected\""; + } + else if (bcd->prot==Private) + { + tagFile << " protection=\"private\""; + } + if (bcd->virt==Virtual) + { + tagFile << " virtualness=\"virtual\""; + } + tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl; + } ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name()+bcd->templSpecifiers); } else @@ -774,8 +805,6 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.newParagraph(); } - if (!Config::genTagFile.isEmpty()) tagFile << " \"" << fileName << ".html\"\n"; - // write subclasses if ((count=inheritedBy->count())>0) { @@ -1156,6 +1185,11 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.popGeneratorState(); ol.endTextBlock(); + + if (!Config::genTagFile.isEmpty()) + { + tagFile << " </compound>" << endl; + } endFile(ol); } diff --git a/src/classlist.cpp b/src/classlist.cpp index 68436d4..f62ff36 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -21,6 +21,7 @@ #include "outputlist.h" #include "language.h" #include "doc.h" +#include "doxygen.h" ClassList::ClassList() : QList<ClassDef>() { @@ -68,6 +69,10 @@ void ClassList::writeDeclaration(OutputList &ol) ol.startMemberList(); found=TRUE; } + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <class>" << convertToXML(cd->name()) << "</class>" << endl; + } ol.startMemberItem(FALSE); switch (cd->compoundType()) { diff --git a/src/config.l b/src/config.l index 2fcef2f..2aa605c 100644 --- a/src/config.l +++ b/src/config.l @@ -1,4 +1,4 @@ -/* This file was generated by configgen on Sun Dec 3 19:18:43 2000 +/* This file was generated by configgen on Fri Dec 15 14:00:31 2000 * from config_templ.l * * DO NOT EDIT! @@ -2853,6 +2853,15 @@ void checkConfig() if (!dp.exists() || !dp.isFile()) { err("Warning: the dot tool could not be found at %s\n",Config::dotPath.data()); + Config::dotPath=""; + } + else + { + Config::dotPath=dp.dirPath(TRUE)+"/"; +#if defined(_WIN32) // convert slashes + uint i=0,l=Config::dotPath.length(); + for (i=0;i<l;i++) if (Config::dotPath.at(i)=='/') Config::dotPath.at(i)='\\'; +#endif } } else // make sure the string is empty but not null! diff --git a/src/definition.h b/src/definition.h index 7332e61..378faf3 100644 --- a/src/definition.h +++ b/src/definition.h @@ -76,7 +76,7 @@ class Definition bool isReference() const { return !ref.isEmpty(); } void setReference(const char *r) { ref=r; } - QCString getReference() { return ref; } + QCString getReference() const { return ref; } /*! returns the base file name that corresponds with the \a name of this * definition. This replaces a number of special characters in the diff --git a/src/diagram.cpp b/src/diagram.cpp index f9d803c..c60c44d 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -997,7 +997,8 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path, QCString epsBaseName=(QCString)path+"/"+fileName; QCString epsName=epsBaseName+".eps"; - QFile f1(epsName.data()); + QFile f1; + f1.setName(epsName.data()); if (!f1.open(IO_WriteOnly)) { err("Could not open file %s for writing\n",convertToQCString(f1.name()).data()); @@ -1234,11 +1235,11 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path, f1.close(); if (Config::usePDFLatexFlag) { - QCString epstopdfCmd(4096); - //epstopdfCmd.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"", - // epsBaseName.data(),epsBaseName.data()); + QCString epstopdfArgs(4096); + epstopdfArgs.sprintf("\"%s.eps\" -outfile=\"%s.pdf\"", + epsBaseName.data(),epsBaseName.data()); //printf("Converting eps using `%s'\n",epstopdfCmd.data()); - if (iSystem(epstopdfCmd)!=0) + if (iSystem("epstopdf",epstopdfArgs)!=0) { err("Error: Problems running epstopdf. Check your TeX installation!\n"); return; @@ -995,7 +995,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"") } <DocIndexWord>[^\n]+ { //printf("Adding %s to index\n",yytext); - outDoc->addToIndex(yytext,0); + outDoc->addIndexItem(yytext,0); BEGIN(DocScan); } <DocScan>{CMD}("arg"|"li")/{BN} { diff --git a/src/dot.cpp b/src/dot.cpp index 1eff927..c03a31c 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -580,20 +580,18 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path) t << "}" << endl; f.close(); - QCString dotCmd(4096); - dotCmd.sprintf("%sdot -Tgif \"%s\" -o \"%s\"", - Config::dotPath.data(),dotName.data(),gifName.data()); + QCString dotArgs(4096); + dotArgs.sprintf("-Tgif \"%s\" -o \"%s\"",dotName.data(),gifName.data()); //printf("Running: dot -Tgif %s -o %s\n",dotName.data(),gifName.data()); - if (iSystem(dotCmd)!=0) + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); out << "</table>" << endl; return; } - dotCmd.sprintf("%sdot -Timap \"%s\" -o \"%s\"", - Config::dotPath.data(),dotName.data(),mapName.data()); + dotArgs.sprintf("-Timap \"%s\" -o \"%s\"",dotName.data(),mapName.data()); //printf("Running: dot -Timap %s -o %s\n",dotName.data(),mapName.data()); - if (iSystem(dotCmd)!=0) + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); out << "</table>" << endl; @@ -996,11 +994,10 @@ static void findMaximalDotGraph(DotNode *root, writeDotGraph(root,format,baseName,lrRank,renderParents, curDistance,backArrows); - QCString dotCmd(4096); + QCString dotArgs(4096); // create annotated dot file - dotCmd.sprintf("%sdot -Tdot \"%s.dot\" -o \"%s_tmp.dot\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + dotArgs.sprintf("-Tdot \"%s.dot\" -o \"%s_tmp.dot\"",baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); return; @@ -1103,10 +1100,10 @@ void DotClassGraph::writeGraph(QTextStream &out, if (format==GIF) // run dot to create a .gif image { - QCString dotCmd(4096); - dotCmd.sprintf("%sdot -Tgif \"%s.dot\" -o \"%s.gif\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + QCString dotArgs(4096); + dotArgs.sprintf("-Tgif \"%s.dot\" -o \"%s.gif\"", + baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Error: Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); @@ -1115,9 +1112,8 @@ void DotClassGraph::writeGraph(QTextStream &out, if (generateImageMap) { // run dot again to create an image map - dotCmd.sprintf("%sdot -Timap \"%s.dot\" -o \"%s.map\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + dotArgs.sprintf("-Timap \"%s.dot\" -o \"%s.map\"",baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Error: Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); @@ -1146,10 +1142,9 @@ void DotClassGraph::writeGraph(QTextStream &out, } else if (format==EPS) // run dot to create a .eps image { - QCString dotCmd(4096); - dotCmd.sprintf("%sdot -Tps \"%s.dot\" -o \"%s.eps\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + QCString dotArgs(4096); + dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"",baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Error: Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); @@ -1164,10 +1159,10 @@ void DotClassGraph::writeGraph(QTextStream &out, } if (Config::usePDFLatexFlag) { - QCString epstopdfCmd(4096); - epstopdfCmd.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"", + QCString epstopdfArgs(4096); + epstopdfArgs.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"", baseName.data(),baseName.data()); - if (iSystem(epstopdfCmd)!=0) + if (iSystem("epstopdf",epstopdfArgs)!=0) { err("Error: Problems running epstopdf. Check your TeX installation!\n"); QDir::setCurrent(oldDir); @@ -1307,10 +1302,10 @@ void DotInclDepGraph::writeGraph(QTextStream &out, if (format==GIF) { // run dot to create a .gif image - QCString dotCmd(4096); - dotCmd.sprintf("%sdot -Tgif \"%s.dot\" -o \"%s.gif\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + QCString dotArgs(4096); + dotArgs.sprintf("-Tgif \"%s.dot\" -o \"%s.gif\"", + baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); @@ -1320,9 +1315,9 @@ void DotInclDepGraph::writeGraph(QTextStream &out, if (generateImageMap) { // run dot again to create an image map - dotCmd.sprintf("%sdot -Timap \"%s.dot\" -o \"%s.map\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + dotArgs.sprintf("-Timap \"%s.dot\" -o \"%s.map\"", + baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); @@ -1343,10 +1338,10 @@ void DotInclDepGraph::writeGraph(QTextStream &out, else if (format==EPS) { // run dot to create a .eps image - QCString dotCmd(4096); - dotCmd.sprintf("%sdot -Tps \"%s.dot\" -o \"%s.eps\"", - Config::dotPath.data(),baseName.data(),baseName.data()); - if (iSystem(dotCmd)!=0) + QCString dotArgs(4096); + dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"", + baseName.data(),baseName.data()); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); @@ -1361,10 +1356,10 @@ void DotInclDepGraph::writeGraph(QTextStream &out, } if (Config::usePDFLatexFlag) { - QCString epstopdfCmd(4096); - epstopdfCmd.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"", + QCString epstopdfArgs(4096); + epstopdfArgs.sprintf("\"%s.eps\" -outfile=\"%s.pdf\"", baseName.data(),baseName.data()); - if (iSystem(epstopdfCmd)!=0) + if (iSystem("epstopdf",epstopdfArgs)!=0) { err("Error: Problems running epstopdf. Check your TeX installation!\n"); QDir::setCurrent(oldDir); @@ -1435,10 +1430,9 @@ void generateGraphLegend(const char *path) QDir::setCurrent(d.absPath()); // run dot to generate the a .gif image from the graph - QCString dotCmd(4096); - dotCmd.sprintf("%sdot -Tgif graph_legend.dot -o graph_legend.gif", - Config::dotPath.data()); - if (iSystem(dotCmd)!=0) + QCString dotArgs(4096); + dotArgs.sprintf("-Tgif graph_legend.dot -o graph_legend.gif"); + if (iSystem(Config::dotPath+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 4e951bd..3d7ea26 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -40,7 +40,7 @@ #include "config.h" #include "util.h" #include "pre.h" -#include "tag.h" +#include "tagreader.h" #include "dot.h" #include "outputlist.h" @@ -226,14 +226,10 @@ static void addRelatedPage(const char *name,const QCString &ptitle, PageInfo *pi=0; if ((pi=pageSDict->find(name))) { - //warn("Warning: Page %s was already documented. Ignoring documentation " - // "at line %d of %s\n",root->name.data(),root->startLine, - // root->fileName.data()); - // append documentation block to the page. pi->doc+="\n\n"+doc; } - else + else // new page { QCString baseName=name; if (baseName.right(4)==".tex") @@ -380,6 +376,10 @@ static void buildGroupList(Entry *root) else { gd = new GroupDef(root->fileName,root->startLine,root->name,root->type); + if (root->tagInfo) + { + gd->setReference(root->tagInfo->tagName); + } gd->setBriefDescription(root->brief); gd->setDocumentation(root->doc); gd->addSectionsToDefinition(root->anchors); @@ -565,11 +565,9 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) { iName=fd->name(); } - if (Config::verbatimHeaderFlag || Config::sourceBrowseFlag) - // generate code for header + if (fd->generateSourceFile()) // generate code for header { cd->setIncludeFile(fd,iName,local); - //fd->setGenerateSource(TRUE); } else // put #include in the class documentation without link { @@ -728,7 +726,15 @@ static void buildClassList(Entry *root) //printf("New class: namespace `%s' name=`%s'\n",className.data(),namespaceName.data()); - ClassDef *cd=new ClassDef(root->fileName,root->startLine,fullName,sec); + QCString tagName; + QCString refFileName; + if (root->tagInfo) + { + tagName = root->tagInfo->tagName; + refFileName = root->tagInfo->fileName; + } + ClassDef *cd=new ClassDef(root->fileName,root->startLine,fullName,sec, + tagName,refFileName); cd->setDocumentation(root->doc); // copy docs to definition cd->setBriefDescription(root->brief); //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data()); @@ -861,7 +867,12 @@ static void buildNamespaceList(Entry *root) ) */ { - NamespaceDef *nd=new NamespaceDef(root->fileName,root->startLine,fullName); + QCString tagName; + if (root->tagInfo) + { + tagName=root->tagInfo->tagName; + } + NamespaceDef *nd=new NamespaceDef(root->fileName,root->startLine,fullName,tagName); nd->setDocumentation(root->doc); // copy docs to definition nd->setBriefDescription(root->brief); nd->addSectionsToDefinition(root->anchors); @@ -1169,6 +1180,11 @@ static MemberDef *addVariableToClass( root->type,name,root->args,0, prot,Normal,root->stat,FALSE, mtype,0,0); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } md->setMemberClass(cd); //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); @@ -1283,23 +1299,38 @@ static MemberDef *addVariableToFile( MemberName *mn=functionNameDict[name]; if (mn) { + QCString nscope=removeAnonymousScopes(scope); + NamespaceDef *nd=0; + if (!nscope.isEmpty()) + { + nd = getResolvedNamespace(nscope); + } MemberNameIterator mni(*mn); MemberDef *md; for (mni.toFirst();(md=mni.current());++mni) { - QCString nscope=removeAnonymousScopes(scope); - NamespaceDef *nd=0; - if (!nscope.isEmpty()) - { - nd = getResolvedNamespace(nscope); - } - if (nd==0 || md->getNamespaceDef()==nd) + if ((nd==0 && root->fileName==md->getFileDef()->absFilePath()) + || (nd!=0 && md->getNamespaceDef()==nd)) // variable already in the scope { addMemberDocs(root,md,def,0,FALSE); md->setRefItems(root->todoId,root->testId); return md; } + + if (nd==0 && md->isExplicit()!=root->explicitExternal) + { + // merge ingroup specifiers + if (md->getGroupDef()==0 && root->groups->first()) + { + GroupDef *gd=groupDict[root->groups->first()->data()]; + md->setGroupDef(gd); + } + else if (md->getGroupDef()!=0 && root->groups->count()==0) + { + root->groups->append(new QCString(md->getGroupDef()->name())); + } + } } } // new global variable, enum value or typedef @@ -1308,6 +1339,11 @@ static MemberDef *addVariableToFile( root->type,name,root->args,0, Public, Normal,root->stat,FALSE, mtype,0,0); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); md->setDocumentation(root->doc); @@ -1322,6 +1358,7 @@ static MemberDef *addVariableToFile( md->setMemberGroupId(root->mGrpId); md->setBodyDef(fd); md->setDefinition(def); + md->setExplicitExternal(root->explicitExternal); //if (root->mGrpId!=-1) //{ // md->setMemberGroup(memberGroupDict[root->mGrpId]); @@ -1458,8 +1495,7 @@ void buildVarList(Entry *root) QCString type=root->type.stripWhiteSpace(); ClassDef *cd=0; - int ni; - if ((ni=root->name.findRev("::"))!=-1) goto nextMember; + if (root->name.findRev("::")!=-1) goto nextMember; /* skip this member, because it is a * static variable definition (always?), which will be * found in a class scope as well, but then we know the @@ -1634,7 +1670,6 @@ static void buildMemberList(Entry *root) name=name.left(i); } - //if (Config::includeSourceFlag && !root->body.isEmpty()) //{ // printf("Function: %s\n-----------------\n%s\n------------------\n", @@ -1649,9 +1684,12 @@ static void buildMemberList(Entry *root) root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,!root->relates.isEmpty(), mtype,root->mtArgList,root->argList); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } md->setMemberClass(cd); - //md->setDefFile(root->fileName); - //md->setDefLine(root->startLine); md->setDocumentation(root->doc); md->setBriefDescription(root->brief); md->setBodySegment(root->bodyLine,root->endBodyLine); @@ -1752,12 +1790,6 @@ static void buildMemberList(Entry *root) else if (root->parent && !(root->parent->section & Entry::COMPOUND_MASK) && !isMember && - - //rname.find("::")==-1 && // TODO: remove this check - // // it breaks cases like - // // func<A::B>(), but it is needed - // // for detect that A::func() is a member - root->relates.isEmpty() && root->type.left(7)!="extern " && root->type.left(8)!="typedef " @@ -1788,11 +1820,6 @@ static void buildMemberList(Entry *root) QCString nsName,rnsName; if (nd) nsName = nd->name().copy(); if (rnd) rnsName = rnd->name().copy(); - QCString groupName,rgroupName; - if (md->getGroupDef()) groupName=md->getGroupDef()->name().copy(); - if (root->groups && root->groups->first()) rgroupName=root->groups->first()->copy(); - //printf("namespace `%s' `%s'\n",nsName.data(),rnsName.data()); - //printf("groupNames `%s' `%s'\n",groupName.data(),rgroupName.data()); if ( matchArguments(md->argumentList(),root->argList,0,nsName) ) @@ -1801,18 +1828,16 @@ static void buildMemberList(Entry *root) found=(nd && rnd && nsName==rnsName) || // members are in the same namespace ((fd!=0 && // no external reference and fd->absFilePath()==root->fileName // prototype in the same file - ) || - ( - !groupName.isEmpty() || // member is or was part of a group - !rgroupName.isEmpty() - ) + ) ); // otherwise, allow a duplicate global member with the same argument list //printf("combining function with prototype found=%d `%s'<->`%s'!\n", // found,fd->absFilePath().data(),root->fileName.data()); - // merge members documentation and properties + + // merge argument lists mergeArguments(root->argList,md->argumentList()); + // merge documentation if (!md->documentation() && !root->doc.isEmpty()) { md->setDocumentation(root->doc); @@ -1821,6 +1846,7 @@ static void buildMemberList(Entry *root) { md->setBriefDescription(root->brief); } + // merge body definitions if (md->getStartBodyLine()==-1 && root->bodyLine!=-1) { md->setBodySegment(root->bodyLine,root->endBodyLine); @@ -1828,6 +1854,17 @@ static void buildMemberList(Entry *root) md->setBodyDef(findFileDef(inputNameDict,root->fileName,ambig)); } md->addSectionsToDefinition(root->anchors); + + // merge ingroup specifiers + if (md->getGroupDef()==0 && root->groups->first()) + { + GroupDef *gd=groupDict[root->groups->first()->data()]; + md->setGroupDef(gd); + } + else if (md->getGroupDef()!=0 && root->groups->count()==0) + { + root->groups->append(new QCString(md->getGroupDef()->name())); + } } } } @@ -1843,6 +1880,11 @@ static void buildMemberList(Entry *root) root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,FALSE, MemberDef::Function,root->tArgList,root->argList); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); md->setDocumentation(root->doc); @@ -1909,25 +1951,17 @@ static void buildMemberList(Entry *root) if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') { + // add member to namespace nd->insertMember(md); md->setNamespace(nd); md->setRefItems(root->todoId,root->testId); } - else + else if (fd) { - // find file definition - //FileDef *fd=0; - //bool ambig; - //if (!root->fileName.isEmpty() && - // (fd=findFileDef(inputNameDict,root->fileName,ambig)) - // ) - if (fd) - { - // add member to the file - fd->insertMember(md); - md->setFileDef(fd); - md->setRefItems(root->todoId,root->testId); - } + // add member to the file + fd->insertMember(md); + md->setFileDef(fd); + md->setRefItems(root->todoId,root->testId); } // add member to the list of file members @@ -2046,8 +2080,15 @@ static void transferFunctionDocumentation() /* find a matching function declaration and definition for this function */ for (;(md=mni.current());++mni) { - if (md->isPrototype()) mdec=md; - if (md->isFunction() && !md->isStatic() && !md->isPrototype()) mdef=md; + if (md->isPrototype()) + mdec=md; + else if (md->isVariable() && md->isExternal()) + mdec=md; + + if (md->isFunction() && !md->isStatic() && !md->isPrototype()) + mdef=md; + else if (md->isVariable() && !md->isExternal() && !md->isStatic()) + mdef=md; } //printf("mdef=(%p,%s) mdec=(%p,%s)\n", // mdef, mdef ? mdef->name().data() : "", @@ -2335,10 +2376,14 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd, baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); return TRUE; } - else if (insertUndocumented) + else if (scopeOffset==0 && insertUndocumented) { - Debug::print(Debug::Classes,0," Undocumented base class `%s' baseClassName=%s\n",bi->name.data(),baseClassName.data()); - baseClass=new ClassDef(root->fileName,root->startLine,baseClassName,ClassDef::Class); + Debug::print(Debug::Classes,0, + " Undocumented base class `%s' baseClassName=%s\n", + bi->name.data(),baseClassName.data() + ); + baseClass=new ClassDef(root->fileName,root->startLine, + baseClassName,ClassDef::Class); // add base class to this class cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec); // add this class as super class to the base class @@ -3511,6 +3556,11 @@ static void findMember(Entry *root,QCString funcDecl,QCString related,bool overl funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,TRUE, mtype,root->tArgList,root->argList); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } md->setMemberClass(cd); md->setDefinition(funcDecl); QCString doc=getOverloadDocs(); @@ -3589,6 +3639,11 @@ static void findMember(Entry *root,QCString funcDecl,QCString related,bool overl funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,TRUE, mtype,root->tArgList,root->argList); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } //printf("Related member name=`%s' decl=`%s' bodyLine=`%d'\n", // funcName.data(),funcDecl.data(),root->bodyLine); @@ -3738,7 +3793,7 @@ static void findMemberDocumentation(Entry *root) ((root->section==Entry::FUNCTION_SEC // function || (root->section==Entry::VARIABLE_SEC && // variable - !root->type.isEmpty() && root->type.left(8)!="typedef " && + !root->type.isEmpty() && /*root->type.left(8)!="typedef " &&*/ compoundKeywordDict.find(root->type)==0 ) ) && @@ -3857,6 +3912,11 @@ static void findEnums(Entry *root) root->fileName,root->startLine, 0,name,0,0,root->protection,Normal,FALSE,FALSE, MemberDef::Enumeration,0,0); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd); //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); @@ -4238,10 +4298,7 @@ static void generateFileSources() FileDef *fd; for (;(fd=fni.current());++fni) { - bool src = !fd->isReference() && - fd->name().right(4)!=".doc" && fd->name().right(4)!=".txt" && - (Config::verbatimHeaderFlag || Config::sourceBrowseFlag); - if (src) + if (fd->generateSourceFile()) { msg("Generating code for file %s...\n",fd->name().data()); fd->writeSource(*outputList); @@ -4520,6 +4577,32 @@ static void findDefineDocumentation(Entry *root) { //printf("found define `%s' `%s' brief=`%s' doc=`%s'\n", // root->name.data(),root->args.data(),root->brief.data(),root->doc.data()); + + if (root->tagInfo && !root->name.isEmpty()) // define read from a tag file + { + MemberDef *md=new MemberDef("<tagfile>",1, + "#define",root->name,root->args,0, + Public,Normal,FALSE,FALSE,MemberDef::Define,0,0); + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + bool ambig; + QCString filePathName = root->parent->fileName; + FileDef *fd=findFileDef(inputNameDict,filePathName,ambig); + //printf("Searching for `%s' fd=%p\n",filePathName.data(),fd); + md->setFileDef(fd); + MemberName *mn; + if ((mn=functionNameDict[root->name])) + { + mn->append(md); + } + else + { + mn = new MemberName(root->name); + mn->append(md); + functionNameDict.insert(root->name,mn); + functionNameList.inSort(mn); + } + } MemberName *mn=functionNameDict[root->name]; if (mn) { @@ -4723,7 +4806,7 @@ static void generatePageDocs() PageInfo *pi=0; for (pdi.toFirst();(pi=pdi.current());++pdi) { - if (!pi->inGroup) + if (!pi->inGroup && !pi->isReference()) { msg("Generating docs for page %s...\n",pi->name.data()); outputList->disable(OutputGenerator::Man); @@ -4747,6 +4830,15 @@ static void generatePageDocs() outputList->endTextBlock(); endFile(*outputList); outputList->enable(OutputGenerator::Man); + + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <compound kind=\"page\">" << endl; + tagFile << " <name>" << pi->name << "</name>" << endl; + tagFile << " <title>" << pi->title << "</title>" << endl; + tagFile << " <filename>" << pi->name << "</filename>" << endl; + tagFile << " </compound>" << endl; + } } } } @@ -4837,7 +4929,10 @@ static void generateGroupDocs() // "Warning: group %s does not have any (documented) members.", // gd->name().data()); //} - gd->writeDocumentation(*outputList); + if (!gd->isReference()) + { + gd->writeDocumentation(*outputList); + } } } @@ -5065,7 +5160,7 @@ static void generateConfigFile(const char *configFile,bool shortList) //---------------------------------------------------------------------------- -static void readTagFile(const char *tl) +static void readTagFile(Entry *root,const char *tl) { QCString tagLine = tl; QCString fileName; @@ -5077,7 +5172,7 @@ static void readTagFile(const char *tl) destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace(); QFileInfo fi(fileName); tagDestinationDict.insert(fi.fileName(),new QCString(destName)); - //printf("insert tagDestination %s->%s\n",fileName.data(),destName.data()); + //printf("insert tagDestination %s->%s\n",fi.fileName().data(),destName.data()); } else { @@ -5097,7 +5192,7 @@ static void readTagFile(const char *tl) else msg("Reading tag file `%s'...\n",fileName.data()); - parseTagFile(fileName); + parseTagFile(root,fi.absFilePath(),fi.fileName()); } //---------------------------------------------------------------------------- @@ -5921,6 +6016,17 @@ int main(int argc,char **argv) msg("Read %d bytes\n",input.curPos()); } + // Notice: the order of the function calls below is very important! + + if (Config::generateHtml) + { + msg("Reading formula repository...\n"); + readFormulaRepository(); + } + + Entry *root=new Entry; + root->program=input; + /************************************************************************** * Handle Tag Files * @@ -5931,13 +6037,14 @@ int main(int argc,char **argv) s=Config::tagFileList.first(); while (s) { - readTagFile(s); + readTagFile(root,s); s=Config::tagFileList.next(); } - QFile *tag =new QFile(Config::genTagFile); + QFile *tag=0; if (!Config::genTagFile.isEmpty()) { + tag=new QFile(Config::genTagFile); if (!tag->open(IO_WriteOnly)) { err("Error: cannot open tag file %s for writing\n", @@ -5946,23 +6053,13 @@ int main(int argc,char **argv) exit(1); } tagFile.setDevice(tag); + tagFile << "<tagfile>" << endl; } /************************************************************************** * Gather information * **************************************************************************/ - // Notice: the order of the function calls below is very important! - - if (Config::generateHtml) - { - msg("Reading formula repository...\n"); - readFormulaRepository(); - } - - Entry *root=new Entry; - root->program=input; - msg("Parsing input...\n"); parseMain(root); // build a tree of entries @@ -6217,12 +6314,16 @@ int main(int argc,char **argv) { FTVHelp::getInstance()->finalize(); } + if (!Config::genTagFile.isEmpty()) + { + tagFile << "</tagfile>" << endl; + delete tag; + } if (Config::generateHtml) removeDoxFont(Config::htmlOutputDir); if (Config::generateRTF) removeDoxFont(Config::rtfOutputDir); - delete tag; return 0; } diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in index f963466..92c60f8 100644 --- a/src/doxygen.pro.in +++ b/src/doxygen.pro.in @@ -20,7 +20,7 @@ HEADERS = doxygen.h scanner.h doc.h classdef.h classlist.h memberdef.h \ membername.h index.h memberlist.h definition.h \ entry.h logos.h instdox.h message.h code.h \ filedef.h util.h cppvalue.h constexp.h \ - outputgen.h outputlist.h htmlgen.h latexgen.h tag.h \ + outputgen.h outputlist.h htmlgen.h latexgen.h \ filename.h defargs.h groupdef.h gifenc.h diagram.h image.h \ namespacedef.h version.h language.h translator.h \ translator_nl.h translator_se.h translator_cz.h translator_fr.h \ @@ -28,23 +28,26 @@ HEADERS = doxygen.h scanner.h doc.h classdef.h classlist.h memberdef.h \ translator_ru.h translator_pl.h dot.h rtfgen.h xml.h xml_dtd.h \ reflist.h page.h sortdict.h translator_hu.h translator_kr.h \ translator_ro.h translator_si.h translator_cn.h ftvhelp.h \ - treeview.h + treeview.h tagreader.h SOURCES = doxygen.cpp scanner.cpp doc.cpp classdef.cpp classlist.cpp \ memberdef.cpp membername.cpp index.cpp memberlist.cpp \ entry.cpp logos.cpp instdox.cpp message.cpp code.cpp \ config.cpp filedef.cpp util.cpp groupdef.cpp \ outputgen.cpp outputlist.cpp htmlgen.cpp latexgen.cpp mangen.cpp \ cppvalue.cpp ce_lex.cpp ce_parse.cpp pre.cpp \ - tag.cpp filename.cpp declinfo.cpp defargs.cpp define.cpp \ + filename.cpp declinfo.cpp defargs.cpp define.cpp \ diagram.cpp gifenc.cpp image.cpp namespacedef.cpp \ version.cpp language.cpp definition.cpp formula.cpp debug.cpp \ membergroup.cpp htmlhelp.cpp dot.cpp rtfgen.cpp xml.cpp \ - reflist.cpp ftvhelp.cpp -unix:LIBS += -L../qtools -lqtools -win32:INCLUDEPATH += . -win32:LIBS += qtools.lib shell32.lib -win32:TMAKE_LFLAGS += /LIBPATH:..\qtools -win32:TMAKE_CXXFLAGS += -DQT_NODLL -INCLUDEPATH += ../qtools -TARGET = ../bin/doxygen -OBJECTS_DIR = ../objects + reflist.cpp ftvhelp.cpp tagreader.cpp +unix:LIBS += -L../qtools -lqtools +win32:INCLUDEPATH += . +win32-mingw:LIBS += -L../qtools -lqtools +win32-msvc:LIBS += qtools.lib shell32.lib +win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\qtools +win32-borland:LIBS += qtools.lib shell32.lib +win32-borland:TMAKE_LFLAGS += -L..\qtools +win32:TMAKE_CXXFLAGS += -DQT_NODLL +INCLUDEPATH += ../qtools +TARGET = ../bin/doxygen +OBJECTS_DIR = ../objects diff --git a/src/doxygen.t b/src/doxygen.t index be0dcc4..d1f6a64 100644 --- a/src/doxygen.t +++ b/src/doxygen.t @@ -53,9 +53,6 @@ sub GenerateDep { #$ GenerateDep("pre.cpp","pre.l"); $(LEX) -PpreYY -t pre.l >pre.cpp -#$ GenerateDep("tag.cpp","tag.l"); - $(LEX) -PtagYY -t tag.l >tag.cpp - #$ GenerateDep("config.cpp","config.l"); $(LEX) -PconfigYY -t config.l >config.cpp diff --git a/src/doxytag.l b/src/doxytag.l index 001b756..2d9e7b4 100644 --- a/src/doxytag.l +++ b/src/doxytag.l @@ -36,6 +36,27 @@ #include "suffixtree.h" #include "searchindex.h" #include "logos.h" + +static QCString convertToXML(const char *s) +{ + QCString result; + if (s==0) return result; + const char *p=s; + char c; + while ((c=*p++)) + { + switch (c) + { + case '<': result+="<"; break; + case '>': result+=">"; break; + case '&': result+="&"; break; + case '\'': result+="'"; break; + case '"': result+="""; break; + default: result+=c; break; + } + } + return result; +} struct MemberDef { @@ -61,21 +82,20 @@ QDict<ClassDef> fileDict(1009); static bool genTag; static bool genIndex; -static QStrList bases; +static QStrList bases; static QCString inputString; -static int inputPosition; +static int inputPosition; static QCString yyFileName; -static int yyLineNr; +static int yyLineNr; static QCString classFile; static QCString memberRef; static QCString memberName; static QCString memberArgs; static QCString className; -//static bool newClass; static QCString docBaseLink; static QCString docAnchor; static QCString docRefName; -static bool nameBug; +static bool nameBug; static SearchIndex searchIndex; #define YY_NEVER_INTERACTIVE 1 @@ -423,7 +443,8 @@ void parse(QCString &s) void parseFile(QFileInfo &fi) { fprintf(stderr,"Parsing file %s...\n",fi.fileName().data()); - QFile f(fi.absFilePath().data()); + QFile f; + f.setName(fi.absFilePath()); if (f.open(IO_ReadOnly)) { yyFileName = fi.fileName(); @@ -575,7 +596,8 @@ int main(int argc,char **argv) fi.setFile(dir+"/search.cgi"); if (!fi.exists()) { - QFile f(dir+"/search.cgi"); + QFile f; + f.setName(dir+"/search.cgi"); if (f.open(IO_WriteOnly)) { QTextStream t(&f); @@ -601,31 +623,40 @@ int main(int argc,char **argv) } if (genTag) { - QFile f(tagName); + QFile f; + f.setName(tagName); if (f.open(IO_WriteOnly)) { QTextStream t(&f); + t << "<tagfile>" << endl; ClassDef *cd=classList.first(); while (cd) { - if (cd->isFile) t << "&"; else t << ">"; - t << cd->name << ":"; + t << " <compound kind=\""; + if (cd->isFile) t << "file"; else t << "class"; + t << "\">" << endl; + t << " <name>" << convertToXML(cd->name) << "</name>" << endl; char *base=cd->bases.first(); while (base) { - t << base << "?"; + t << " <base>" << convertToXML(base) << "</base>" << endl; base=cd->bases.next(); } - if (!cd->isFile) t << " \"" << cd->fileName << "\""; - t << endl; + t << " <filename>" << convertToXML(cd->fileName) << "</filename>" << endl; MemberDef *md=cd->memberList.first(); while (md) { - t << md->name << " " << md->anchor << " \"" << md->args << "\"" << endl; + t << " <member kind=\"function\">" << endl; + t << " <name>" << convertToXML(md->name) << "</name>" << endl; + t << " <anchor>" << convertToXML(md->anchor) << "</anchor>" << endl; + t << " <arglist>" << convertToXML(md->args) << "</arglist>" << endl; + t << " </member>" << endl; md=cd->memberList.next(); } + t << " </compound>" << endl; cd=classList.next(); } + t << "</tagfile>" << endl; } else { diff --git a/src/doxytag.pro.in b/src/doxytag.pro.in index d91378d..58b2e95 100644 --- a/src/doxytag.pro.in +++ b/src/doxytag.pro.in @@ -19,11 +19,14 @@ CONFIG = console warn_on $extraopts HEADERS = suffixtree.h searchindex.h logos.h version.h SOURCES = doxytag.cpp suffixtree.cpp searchindex.cpp \ logos.cpp version.cpp -unix:LIBS += -L../qtools -lqtools -win32:INCLUDEPATH += . -win32:LIBS += qtools.lib -win32:TMAKE_LFLAGS += /LIBPATH:..\qtools -win32:TMAKE_CXXFLAGS += -DQT_NODLL -INCLUDEPATH += ../qtools -OBJECTS_DIR = ../objects -TARGET = ../bin/doxytag +unix:LIBS += -L../qtools -lqtools +win32:INCLUDEPATH += . +win32-mingw:LIBS += -L../qtools -lqtools +win32-msvc:LIBS += qtools.lib shell32.lib +win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\qtools +win32-borland:LIBS += qtools.lib shell32.lib +win32-borland:TMAKE_LFLAGS += -L..\qtools +win32:TMAKE_CXXFLAGS += -DQT_NODLL +INCLUDEPATH += ../qtools +OBJECTS_DIR = ../objects +TARGET = ../bin/doxytag diff --git a/src/entry.cpp b/src/entry.cpp index a8dfb9b..829bc3b 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -39,6 +39,7 @@ Entry::Entry() tArgList = 0; mtArgList = 0; mGrpId = -1; + tagInfo = 0; reset(); } @@ -75,6 +76,7 @@ Entry::Entry(const Entry &e) initLines = e.initLines; todoId = e.todoId; testId = e.testId; + tagInfo = e.tagInfo; sublist = new QList<Entry>; sublist->setAutoDelete(TRUE); extends = new QList<BaseInfo>; @@ -157,6 +159,7 @@ Entry::Entry(const Entry &e) //printf("appending argument %s %s\n",a->type.data(),a->name.data()); } } + } Entry::~Entry() @@ -170,6 +173,7 @@ Entry::~Entry() delete argList; delete tArgList; delete mtArgList; + delete tagInfo; num--; } @@ -233,6 +237,7 @@ void Entry::reset() groups->clear(); anchors->clear(); argList->clear(); + if (tagInfo) { delete tagInfo; tagInfo=0; } if (tArgList) { delete tArgList; tArgList=0; } if (mtArgList) { delete mtArgList; mtArgList=0; } } diff --git a/src/entry.h b/src/entry.h index c836d87..2968b1e 100644 --- a/src/entry.h +++ b/src/entry.h @@ -93,6 +93,13 @@ class ArgumentList : public QList<Argument> typedef QListIterator<Argument> ArgumentListIterator; +struct TagInfo +{ + QCString tagName; + QCString fileName; + QCString anchor; +}; + /*! Raw entry. parseMain() in scanner.l will generate a tree of these * entries. */ @@ -200,6 +207,7 @@ class Entry int startLine; // start line of entry in the source int todoId; // id of the todo item of this entry int testId; // id of the test item of this entry + TagInfo *tagInfo; // tag file info static int num; // counts the total number of entries private: Entry &operator=(const Entry &); diff --git a/src/filedef.cpp b/src/filedef.cpp index bb75335..b27f8ac 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -119,10 +119,16 @@ void FileDef::writeDocumentation(OutputList &ol) startFile(ol,diskname,pageTitle); startTitle(ol,getOutputFileBase()); parseText(ol,theTranslator->trFileReference(docname)); - endTitle(ol,getOutputFileBase(),getOutputFileBase()); + endTitle(ol,getOutputFileBase(),docName()); //ol.newParagraph(); - if (!Config::genTagFile.isEmpty()) tagFile << "&" << name() << ":\n"; + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <compound kind=\"file\">" << endl; + tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; + tagFile << " <path>" << convertToXML(getPath()) << "</path>" << endl; + tagFile << " <filename>" << convertToXML(diskname) << ".html</filename>" << endl; + } ol.startTextBlock(); //brief=brief.stripWhiteSpace(); @@ -272,7 +278,11 @@ void FileDef::writeDocumentation(OutputList &ol) nd->getOutputFileBase(), 0, nd->name() - ); + ); + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl; + } } else { @@ -422,6 +432,12 @@ void FileDef::writeDocumentation(OutputList &ol) ol.endGroupHeader(); parseText(ol,theTranslator->trGeneratedAutomatically(Config::projectName)); ol.enableAll(); + + if (!Config::genTagFile.isEmpty()) + { + tagFile << " </compound>" << endl; + } + endFile(ol); } @@ -497,6 +513,7 @@ void FileDef::addMembersToMemberGroup() /*! Adds member definition \a md to the list of all members of this file */ void FileDef::insertMember(MemberDef *md) { + //printf("%s:FileDef::insertMember(%s)\n",name().data(),md->name().data()); allMemberList.append(md); switch(md->memberType()) { @@ -524,11 +541,7 @@ void FileDef::insertMember(MemberDef *md) else enumMembers.append(md); break; - case MemberDef::EnumValue: - //if (Config::sortMembersFlag) - // enumValMembers.inSort(md); - //else - // enumValMembers.append(md); + case MemberDef::EnumValue: // enum values are shown inside their enums break; case MemberDef::Prototype: if (Config::sortMembersFlag) @@ -692,3 +705,12 @@ void FileDef::generateXML(QTextStream &t) t << " </compounddef>" << endl; } +bool FileDef::generateSourceFile() const +{ + return !isReference() && + (Config::sourceBrowseFlag || + (Config::verbatimHeaderFlag && guessSection(name())==Entry::HEADER_SEC) + ) && + name().right(4)!=".doc" && name().right(4)!=".txt"; +} + diff --git a/src/filedef.h b/src/filedef.h index fe3a761..510b49a 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -121,12 +121,7 @@ class FileDef : public Definition void addUsingDeclaration(ClassDef *cd); ClassList *getUsedClasses() const { return usingDeclList; } - //void setGenerateSource(bool b) { isSource=b; } - bool generateSourceFile() const - { return !isReference() && - (Config::sourceBrowseFlag || Config::verbatimHeaderFlag) && - name().right(4)!=".doc" && name().right(4)!=".txt"; - } + bool generateSourceFile() const; void addIncludeDependency(FileDef *fd,const char *incName,bool local); void addIncludedByDependency(FileDef *fd,const char *incName,bool local); diff --git a/src/formula.cpp b/src/formula.cpp index 16626fd..abe529a 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -103,7 +103,7 @@ void FormulaList::generateBitmaps(const char *path) { //printf("Running latex...\n"); //system("latex _formulas.tex </dev/null >/dev/null"); - if (iSystem("latex _formulas.tex")!=0) + if (iSystem("latex","_formulas.tex")!=0) { err("Problems running latex. Check your installation or look for typos in _formulas.tex!\n"); formulaError=TRUE; @@ -117,14 +117,14 @@ void FormulaList::generateBitmaps(const char *path) { int pageNum=*pagePtr; msg("Generating image form-%d.gif for formula\n",pageNum); - char dviCmd[256]; + char dviArgs[4096]; QCString formBase; formBase.sprintf("_form%d",pageNum); // run dvips to convert the page with number pageIndex to an // encapsulated postscript. - sprintf(dviCmd,"dvips -q -D 600 -E -n 1 -p %d -o %s.eps _formulas.dvi", + sprintf(dviArgs,"-q -D 600 -E -n 1 -p %d -o %s.eps _formulas.dvi", pageIndex,formBase.data()); - if (iSystem(dviCmd)!=0) + if (iSystem("dvips",dviArgs)!=0) { err("Problems running dvips. Check your installation!\n"); return; @@ -208,13 +208,13 @@ void FormulaList::generateBitmaps(const char *path) WaitForSingleObject(sInfo.hProcess,INFINITE); } #else - char gsCmd[256]; - sprintf(gsCmd,"gs -q -g%dx%d -r%dx%dx -sDEVICE=ppmraw " + char gsArgs[4096]; + sprintf(gsArgs,"-q -g%dx%d -r%dx%dx -sDEVICE=ppmraw " "-sOutputFile=%s.pnm -DNOPAUSE -- %s.ps", gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72), formBase.data(),formBase.data() ); - if (iSystem(gsCmd)!=0) + if (iSystem("gs",gsArgs)!=0) { err("Problem running ghostscript. Check your installation!\n"); return; diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index cac212b..c9e315d 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -37,7 +37,7 @@ unsigned char ftv2blank_gif[] = { 0xcd, 0xbb, 0xff, 0x60, 0x28, 0x8e, 0x64, 0x69, 0x9e, 0x68, 0xaa, 0x3e, 0x11, 0x00, 0x3b }; -unsigned int ftv2blank_gif_len = 135; +const unsigned int ftv2blank_gif_len = 135; unsigned char ftv2doc_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x18, 0x00, 0x16, 0x00, 0xa2, 0x00, @@ -53,7 +53,7 @@ unsigned char ftv2doc_gif[] = { 0x85, 0xfc, 0x42, 0x5c, 0xdb, 0x32, 0x86, 0xf5, 0x0d, 0xce, 0xe8, 0x74, 0xf7, 0x41, 0x6b, 0xbb, 0x39, 0xf0, 0xb8, 0xdc, 0x92, 0x00, 0x00, 0x3b }; -unsigned int ftv2doc_gif_len = 144; +const unsigned int ftv2doc_gif_len = 144; unsigned char ftv2folderclosed_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x18, 0x00, 0x16, 0x00, 0xa2, 0x00, @@ -69,7 +69,7 @@ unsigned char ftv2folderclosed_gif[] = { 0xd5, 0x5a, 0x4e, 0x43, 0x2f, 0x08, 0x43, 0x05, 0x99, 0xcf, 0xe8, 0x49, 0x02, 0x00, 0x3b }; -unsigned int ftv2folderclosed_gif_len = 135; +const unsigned int ftv2folderclosed_gif_len = 135; unsigned char ftv2folderopen_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x18, 0x00, 0x16, 0x00, 0xa2, 0x00, @@ -86,7 +86,7 @@ unsigned char ftv2folderopen_gif[] = { 0x95, 0x88, 0x36, 0x42, 0x27, 0x5f, 0x80, 0x7c, 0x2e, 0xef, 0x46, 0x6b, 0xf8, 0xbc, 0xbd, 0xc3, 0xef, 0xfb, 0x1b, 0x09, 0x00, 0x3b }; -unsigned int ftv2folderopen_gif_len = 154; +const unsigned int ftv2folderopen_gif_len = 154; unsigned char ftv2lastnode_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -102,7 +102,7 @@ unsigned char ftv2lastnode_gif[] = { 0xcd, 0xbb, 0xff, 0x60, 0x28, 0x72, 0xc0, 0x57, 0x7a, 0x67, 0x97, 0x92, 0x4f, 0xe9, 0xb6, 0x63, 0x2c, 0xcf, 0x5e, 0x04, 0x00, 0x3b }; -unsigned int ftv2lastnode_gif_len = 142; +const unsigned int ftv2lastnode_gif_len = 142; unsigned char ftv2link_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x18, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -126,7 +126,7 @@ unsigned char ftv2link_gif[] = { 0x07, 0x8e, 0x8e, 0x89, 0x70, 0x38, 0x93, 0x94, 0x91, 0x22, 0x97, 0x98, 0x99, 0x9a, 0x0f, 0x11, 0x00, 0x3b }; -unsigned int ftv2link_gif_len = 234; +const unsigned int ftv2link_gif_len = 234; unsigned char ftv2mlastnode_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -141,7 +141,7 @@ unsigned char ftv2mlastnode_gif[] = { 0xd9, 0xf5, 0x7a, 0xeb, 0x35, 0x49, 0x82, 0xc0, 0xa0, 0x70, 0x48, 0x2c, 0x1a, 0x35, 0x11, 0x00, 0x3b }; -unsigned int ftv2mlastnode_gif_len = 125; +const unsigned int ftv2mlastnode_gif_len = 125; unsigned char ftv2mnode_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -156,7 +156,7 @@ unsigned char ftv2mnode_gif[] = { 0xd9, 0xf5, 0x7a, 0xeb, 0x35, 0x49, 0x82, 0x40, 0x4c, 0x70, 0x28, 0x24, 0x06, 0x71, 0xc6, 0x0d, 0x52, 0x12, 0x01, 0x00, 0x3b }; -unsigned int ftv2mnode_gif_len = 129; +const unsigned int ftv2mnode_gif_len = 129; unsigned char ftv2node_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -173,7 +173,7 @@ unsigned char ftv2node_gif[] = { 0x4f, 0xe9, 0xb6, 0xd7, 0xba, 0xc9, 0x1a, 0x9d, 0xd9, 0x18, 0x1e, 0x63, 0x11, 0x00, 0x3b }; -unsigned int ftv2node_gif_len = 147; +const unsigned int ftv2node_gif_len = 147; unsigned char ftv2plastnode_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -188,7 +188,7 @@ unsigned char ftv2plastnode_gif[] = { 0xdd, 0xec, 0x04, 0xdb, 0xa7, 0x9a, 0xa3, 0x3d, 0x17, 0x89, 0x04, 0x2a, 0x1a, 0x8f, 0xc8, 0xa4, 0x72, 0xa9, 0x89, 0x00, 0x00, 0x3b }; -unsigned int ftv2plastnode_gif_len = 130; +const unsigned int ftv2plastnode_gif_len = 130; unsigned char ftv2pnode_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -204,7 +204,7 @@ unsigned char ftv2pnode_gif[] = { 0xc6, 0x8c, 0x48, 0x5e, 0xd2, 0xd8, 0x5a, 0x72, 0x9a, 0x93, 0x08, 0x00, 0x3b }; -unsigned int ftv2pnode_gif_len = 133; +const unsigned int ftv2pnode_gif_len = 133; unsigned char ftv2vertline_gif[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x16, 0x00, 0xb3, 0x00, @@ -220,7 +220,7 @@ unsigned char ftv2vertline_gif[] = { 0xcd, 0xbb, 0xff, 0x60, 0x28, 0x72, 0xc0, 0x57, 0x7a, 0x67, 0x97, 0x92, 0x66, 0x8b, 0xba, 0x2a, 0x5c, 0x45, 0x00, 0x3b }; -unsigned int ftv2vertline_gif_len = 140; +const unsigned int ftv2vertline_gif_len = 140; struct ImageInfo { @@ -272,7 +272,16 @@ static void generateFolderTreeViewData() else { QTextStream t(&f); - t << "<html><head><title>" << Config::projectName << "</title></head>" << endl; + t << "<html><head><title>"; + if (Config::projectName.isEmpty()) + { + t << "Doxygen Documentation"; + } + else + { + t << Config::projectName; + } + t << "</title></head>" << endl; t << "<frameset cols=\"" << Config::treeViewWidth << ",*\">" << endl; t << " <frame src=\"tree.html\" name=\"treefrm\">" << endl; t << " <frame src=\"main.html\" name=\"basefrm\">" << endl; @@ -361,7 +370,7 @@ void FTVHelp::initialize() } /* Write the header of the contents file */ m_cts.setDevice(m_cf); - m_cts << "foldersTree = gFld(\"\", \"<b>"; + m_cts << "foldersTree = gFld(\"<b>"; if (Config::projectName.isEmpty()) { m_cts << "Root"; @@ -370,7 +379,7 @@ void FTVHelp::initialize() { m_cts << Config::projectName; } - m_cts << "</b>\", \"\")\n"; + m_cts << "</b>\", \"\", \"\")\n"; } /*! Finalizes the FTV help. This will finish and close the diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 054222a..501ceb0 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -249,7 +249,7 @@ void GroupDef::writeDocumentation(OutputList &ol) startFile(ol,fileName,title); startTitle(ol,getOutputFileBase()); ol.docify(title); - endTitle(ol,getOutputFileBase(),name()); + endTitle(ol,getOutputFileBase(),title); //brief=brief.stripWhiteSpace(); //int bl=brief.length(); @@ -269,6 +269,13 @@ void GroupDef::writeDocumentation(OutputList &ol) ol.popGeneratorState(); } + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <compound kind=\"group\">" << endl; + tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; + tagFile << " <title>" << convertToXML(title) << "</title>" << endl; + tagFile << " <filename>" << convertToXML(fileName) << ".html</filename>" << endl; + } ol.startMemberSections(); if (fileList->count()>0) @@ -284,6 +291,10 @@ void GroupDef::writeDocumentation(OutputList &ol) ol.docify("file "); ol.insertMemberAlign(); ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name()); + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <file>" << convertToXML(fd->name()) << "</file>" << endl; + } ol.endMemberItem(FALSE); if (!fd->briefDescription().isEmpty() && Config::briefMemDescFlag) { @@ -309,6 +320,10 @@ void GroupDef::writeDocumentation(OutputList &ol) ol.docify("namespace "); ol.insertMemberAlign(); ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,nd->name()); + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl; + } ol.endMemberItem(FALSE); if (!nd->briefDescription().isEmpty() && Config::briefMemDescFlag) { @@ -333,6 +348,10 @@ void GroupDef::writeDocumentation(OutputList &ol) ol.startMemberItem(0); //ol.insertMemberAlign(); ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl; + } ol.endMemberItem(FALSE); if (!gd->briefDescription().isEmpty() && Config::briefMemDescFlag) { @@ -396,23 +415,27 @@ void GroupDef::writeDocumentation(OutputList &ol) PageSDictIterator pdi(*pageDict); for (pdi.toFirst();(pi=pdi.current());++pdi) { - QCString pageName; - if (Config::caseSensitiveNames) - pageName=pi->name.copy(); - else - pageName=pi->name.lower(); - - SectionInfo *si=0; - if (!pi->title.isEmpty() && !pi->name.isEmpty() && - (si=sectionDict[pi->name])!=0) + if (!pi->isReference()) { - ol.startSection(si->label,si->title,TRUE); - ol.docify(si->title); - ol.endSection(si->label,TRUE); + QCString pageName = pi->getOutputFileBase(); + + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <page>" << convertToXML(pageName) << "</page>" << endl; + } + + SectionInfo *si=0; + if (!pi->title.isEmpty() && !pi->name.isEmpty() && + (si=sectionDict[pi->name])!=0) + { + ol.startSection(si->label,si->title,TRUE); + ol.docify(si->title); + ol.endSection(si->label,TRUE); + } + ol.startTextBlock(); + parseDoc(ol,pi->defFileName,pi->defLine,0,0,pi->doc); + ol.endTextBlock(); } - ol.startTextBlock(); - parseDoc(ol,pi->defFileName,pi->defLine,0,0,pi->doc); - ol.endTextBlock(); } defineMembers.countDocMembers(TRUE); @@ -475,6 +498,11 @@ void GroupDef::writeDocumentation(OutputList &ol) varMembers.writeDocumentation(ol,name(),this); } + if (!Config::genTagFile.isEmpty()) + { + tagFile << " </compound>" << endl; + } + endFile(ol); ol.popGeneratorState(); } diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index a077ab2..86c90e9 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -304,6 +304,7 @@ void HtmlGenerator::writeString(const char *text) void HtmlGenerator::writeIndexItem(const char *ref,const char *f, const char *name) { + //printf("HtmlGenerator::writeIndexItem(%s,%s,%s)\n",ref,f,name); QCString *dest; t << "<li>"; if (ref || f) diff --git a/src/htmlgen.h b/src/htmlgen.h index 0f3b588..0a0ebf1 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -188,7 +188,7 @@ class HtmlGenerator : public OutputGenerator void writeSectionRef(const char *,const char *,const char *); void writeSectionRefItem(const char *,const char *,const char *); void writeSectionRefAnchor(const char *,const char *,const char *); - void addToIndex(const char *,const char *) {} + void addIndexItem(const char *,const char *) {} void startIndent(); void endIndent(); void writeSynopsis() {} diff --git a/src/index.cpp b/src/index.cpp index 09b2e71..9ef8bc1 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -704,7 +704,7 @@ int countNamespaces() NamespaceDef *nd; for (;(nd=nli.current());++nli) { - if (nd->isLinkableInProject()) count++; + if (nd->isLinkableInProject() && nd->countMembers()>0) count++; } return count; } @@ -726,7 +726,7 @@ void writeNamespaceIndex(OutputList &ol) endTitle(ol,0,0); ol.startTextBlock(); HtmlHelp *htmlHelp = 0; - FTVHelp *ftvHelp = 0; + FTVHelp *ftvHelp = 0; bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag /*&& !Config::htmlHelpGroupsOnly*/; bool hasFtvHelp = Config::generateHtml && Config::ftvHelpFlag /*&& !Config::htmlHelpGroupsOnly*/; if (hasHtmlHelp) @@ -1677,8 +1677,11 @@ int countGroups() GroupDef *gd; for (;(gd=gli.current());++gli) { - gd->visited=FALSE; - count++; + if (!gd->isReference()) + { + gd->visited=FALSE; + count++; + } } return count; } @@ -1751,7 +1754,13 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd) //parseText(ol,gd->groupTitle()); //ol.endTextLink(); - ol.writeIndexItem(0,gd->getOutputFileBase(),gd->groupTitle()); + ol.writeIndexItem(gd->getReference(),gd->getOutputFileBase(),gd->groupTitle()); + if (gd->isReference()) + { + ol.startTypewriter(); + ol.docify(" [external]"); + ol.endTypewriter(); + } //ol.writeStartAnnoItem(0,gd->getOutputFileBase(),0,gd-); //parseText(ol,gd->groupTitle()); @@ -1962,20 +1971,14 @@ void writeGroupIndex(OutputList &ol) if (hasHtmlHelp) { htmlHelp = HtmlHelp::getInstance(); - //if(!Config::htmlHelpGroupsOnly) - //{ - htmlHelp->addContentsItem(TRUE,htmlHelpTitle,"modules"); - htmlHelp->incContentsDepth(); - //} + htmlHelp->addContentsItem(TRUE,htmlHelpTitle,"modules"); + htmlHelp->incContentsDepth(); } if (hasFtvHelp) { ftvHelp = FTVHelp::getInstance(); - //if(!Config::htmlHelpGroupsOnly) - //{ - ftvHelp->addContentsItem(TRUE,0,"modules",0,htmlHelpTitle); - ftvHelp->incContentsDepth(); - //} + ftvHelp->addContentsItem(TRUE,0,"modules",0,ftvHelpTitle); + ftvHelp->incContentsDepth(); } parseText(ol,theTranslator->trModulesDescription()); ol.endTextBlock(); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index e0e72fc..7baafa1 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -494,9 +494,12 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; while (gd && !found) { - if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter"; - t << "{"; //Module Documentation}\n"; - found=TRUE; + if (!gd->isReference()) + { + if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Module Documentation}\n"; + found=TRUE; + } gd=groupList.next(); } } @@ -507,7 +510,7 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; while (nd && !found) { - if (nd->isLinkableInProject()) + if (nd->isLinkableInProject() && nd->countMembers()>0) { if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter"; t << "{"; // Namespace Documentation}\n": @@ -616,14 +619,20 @@ void LatexGenerator::endIndexSection(IndexSections is) bool found=FALSE; while (gd && !found) { - t << "}\n\\input{" << gd->getOutputFileBase() << "}\n"; - found=TRUE; + if (!gd->isReference()) + { + t << "}\n\\input{" << gd->getOutputFileBase() << "}\n"; + found=TRUE; + } gd=groupList.next(); } while (gd) { - if (Config::compactLatexFlag) t << "\\input"; else t << "\\include"; - t << "{" << gd->getOutputFileBase() << "}\n"; + if (!gd->isReference()) + { + if (Config::compactLatexFlag) t << "\\input"; else t << "\\include"; + t << "{" << gd->getOutputFileBase() << "}\n"; + } gd=groupList.next(); } } @@ -1050,7 +1059,7 @@ void LatexGenerator::writeAnchor(const char *fName,const char *name) // writeDoxyAnchor(0,clName,anchor,0); //} -void LatexGenerator::addToIndex(const char *s1,const char *s2) +void LatexGenerator::addIndexItem(const char *s1,const char *s2) { if (s1) { @@ -1067,6 +1076,7 @@ void LatexGenerator::addToIndex(const char *s1,const char *s2) } } + void LatexGenerator::startSection(const char *lab,const char *,bool sub) { if (Config::pdfHyperFlag) @@ -1092,13 +1102,16 @@ void LatexGenerator::writeSectionRef(const char *,const char *lab, t << "}{"; docify(text); t << "}"; + //t << " {\\rm (p.\\,\\pageref{" << lab << "})}"; } else { if (strcmp(lab,text)!=0) // lab!=text { // todo: don't hardcode p. here! - t << "{\\bf " << text << "} {\\rm (p.\\,\\pageref{" << lab << "})}"; + t << "{\\bf "; + docify(text); + t << "} {\\rm (p.\\,\\pageref{" << lab << "})}"; } else { diff --git a/src/latexgen.h b/src/latexgen.h index b08e7b3..4095eb5 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -185,7 +185,7 @@ class LatexGenerator : public OutputGenerator void writeSectionRef(const char *,const char *,const char *); void writeSectionRefItem(const char *,const char *,const char *); void writeSectionRefAnchor(const char *,const char *,const char *); - void addToIndex(const char *,const char *); + void addIndexItem(const char *,const char *); void startIndent() {} void endIndent() {} void writeSynopsis() {} diff --git a/src/mangen.h b/src/mangen.h index 731f35e..39d9f2d 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -175,7 +175,7 @@ class ManGenerator : public OutputGenerator void writeSectionRef(const char *,const char *,const char *) {} void writeSectionRefItem(const char *,const char *,const char *) {} void writeSectionRefAnchor(const char *,const char *,const char *) {} - void addToIndex(const char *,const char *) {} + void addIndexItem(const char *,const char *) {} void startIndent() {} void endIndent() {} void writeSynopsis(); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 5bf7e46..cf6d9c2 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -258,6 +258,7 @@ MemberDef::MemberDef(const char *df,int dl, initLines=0; type=t; args=a; + args=args.stripWhiteSpace(); if (type.isEmpty()) decl=name()+args; else decl=type+" "+name()+args; declLine=0; memberGroup=0; @@ -277,6 +278,7 @@ MemberDef::MemberDef(const char *df,int dl, annEnumType=0; indDepth=0; section=0; + explExt=FALSE; maxInitLines=defMaxInitLines; docEnumValues=FALSE; // copy function template arguments (if any) @@ -507,8 +509,43 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!Config::genTagFile.isEmpty()) { - tagFile << name() << " " << anchor() << " \"" - << argsString() << "\"\n"; + tagFile << " <member kind=\""; + switch (mtype) + { + case Define: tagFile << "define"; break; + case EnumValue: tagFile << "enumvalue"; break; + case Property: tagFile << "property"; break; + case Variable: tagFile << "variable"; break; + case Typedef: tagFile << "typedef"; break; + case Enumeration: tagFile << "enumeration"; break; + case Function: tagFile << "function"; break; + case Signal: tagFile << "signal"; break; + case Prototype: tagFile << "prototype"; break; + case Friend: tagFile << "friend"; break; + case DCOP: tagFile << "dcop"; break; + case Slot: tagFile << "slot"; break; + } + if (prot!=Public) + { + tagFile << "\" protection=\""; + if (prot==Protected) tagFile << "public"; + else /* Private */ tagFile << "protected"; + } + if (virt!=Normal) + { + tagFile << "\" virtualness=\""; + if (virt==Virtual) tagFile << "virtual"; + else /* Pure */ tagFile << "pure"; + } + if (isStatic()) + { + tagFile << "\" static=\"yes"; + } + tagFile << "\">" << endl; + tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; + tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl; + tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl; + tagFile << " </member>" << endl; } Definition *d=0; @@ -593,8 +630,10 @@ void MemberDef::writeDeclaration(OutputList &ol, QCString doxyName=name().copy(); if (!cname.isEmpty()) doxyName.prepend(cname+"::"); ol.startDoxyAnchor(cfname,anchor(),doxyName); - ol.addToIndex(name(),cname); - ol.addToIndex(cname,name()); + + ol.addIndexItem(name(),cname); + ol.addIndexItem(cname,name()); + if (hasHtmlHelp) { htmlHelp->addIndexItem(cname,name(),cfname,anchor()); @@ -1115,8 +1154,10 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, //ol.startItemList(); ol.startDescTable(); } - ol.addToIndex(fmd->name(),cname); - ol.addToIndex(cname,fmd->name()); + + ol.addIndexItem(fmd->name(),cname); + ol.addIndexItem(cname,fmd->name()); + if (Config::generateHtml && Config::htmlHelpFlag) { HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfname,fmd->anchor()); diff --git a/src/memberdef.h b/src/memberdef.h index bee7ca4..7f211f1 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -118,6 +118,7 @@ class MemberDef : public Definition bool isInline() const { return (memSpec&Entry::Inline)!=0; } bool isExplicit() const { return (memSpec&Entry::Explicit)!=0; } bool isMutable() const { return (memSpec&Entry::Mutable)!=0; } + bool isExternal() const { return explExt; } // output info bool isLinkableInProject(); @@ -142,6 +143,7 @@ class MemberDef : public Definition void setMemberClass(ClassDef *cd) { classDef=cd; } void setSectionList(MemberList *sl) { section=sl; } void setGroupDef(GroupDef *gd) { group=gd; } + void setExplicitExternal(bool b) { explExt=b; } void makeRelated() { related=TRUE; } @@ -269,6 +271,7 @@ class MemberDef : public Definition MemberGroup *memberGroup; // group's member definition GroupDef *group; // group in which this member is in + bool explExt; // member was explicitly declared external // disable copying of member defs diff --git a/src/membergroup.h b/src/membergroup.h index 238d688..01312b2 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -22,8 +22,6 @@ #include <qlist.h> #include <qintdict.h> -//#include "definition.h" - #define NOGROUP -1 class MemberDef; diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 17b9226..7a1a538 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -291,8 +291,13 @@ void MemberList::writePlainDeclarations(OutputList &ol, if (md->isLinkableInProject() || md->hasDocumentedEnumValues()) { if (!Config::genTagFile.isEmpty()) - tagFile << md->name() << " " << md->anchor() - << " \"\"" << endl; + { + tagFile << " <member>" << endl; + tagFile << " <name>" << convertToXML(md->name()) << "</name>" << endl; + tagFile << " <anchor>" << convertToXML(md->anchor()) << "</anchor>" << endl; + tagFile << " <arglist>" << convertToXML(md->argsString()) << "</arglist>" << endl; + tagFile << " </member>" << endl; + } md->writeLink(typeDecl,cd,nd,fd,gd); } else @@ -325,9 +330,14 @@ void MemberList::writePlainDeclarations(OutputList &ol, if (fmd->hasDocumentation()) // enum value has docs { - if (!Config::genTagFile.isEmpty()) - tagFile << fmd->name() << " " << fmd->anchor() - << " \"" << fmd->argsString() << "\""; + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <member>" << endl; + tagFile << " <name>" << convertToXML(fmd->name()) << "</name>" << endl; + tagFile << " <anchor>" << convertToXML(fmd->anchor()) << "</anchor>" << endl; + tagFile << " <arglist>" << convertToXML(fmd->argsString()) << "</arglist>" << endl; + tagFile << " </member>" << endl; + } fmd->writeLink(typeDecl,cd,nd,fd,gd); } else // no docs for this enum value diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 6377295..b92d2e5 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -198,7 +198,12 @@ void NamespaceDef::writeDocumentation(OutputList &ol) parseText(ol,theTranslator->trNamespaceReference(name())); endTitle(ol,getOutputFileBase(),name()); - if (!Config::genTagFile.isEmpty()) tagFile << "%" << name() << ":\n"; + if (!Config::genTagFile.isEmpty()) + { + tagFile << " <compound kind=\"namespace\">" << endl; + tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; + tagFile << " <filename>" << convertToXML(fileName) << ".html</filename>" << endl; + } ol.startTextBlock(); @@ -346,7 +351,12 @@ void NamespaceDef::writeDocumentation(OutputList &ol) parseText(ol,theTranslator->trAuthor()); ol.endGroupHeader(); parseText(ol,theTranslator->trGeneratedAutomatically(Config::projectName)); - //ol.enableAll(); + + if (!Config::genTagFile.isEmpty()) + { + tagFile << " </compound>" << endl; + } + ol.popGeneratorState(); endFile(ol); } diff --git a/src/outputgen.h b/src/outputgen.h index 7cc8e18..f890a30 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -176,7 +176,7 @@ class OutputGenerator virtual void writeSectionRefItem(const char *,const char *,const char *) = 0; virtual void writeSectionRefAnchor(const char *,const char *,const char *) = 0; virtual void lineBreak() = 0; - virtual void addToIndex(const char *s1,const char *s2) = 0; + virtual void addIndexItem(const char *s1,const char *s2) = 0; virtual void startIndent() = 0; virtual void endIndent() = 0; virtual void writeSynopsis() = 0; diff --git a/src/outputlist.h b/src/outputlist.h index eb7b03c..b964483 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -71,14 +71,10 @@ class OutputList { forall(&OutputGenerator::writeStyleInfo,part); } void startFile(const char *name,const char *title,bool external) { forall(&OutputGenerator::startFile,name,title,external); } - void startPlainFile(const char *name) - { forall(&OutputGenerator::startPlainFile,name); } void writeFooter(int fase,bool external) { forall(&OutputGenerator::writeFooter,fase,external); } void endFile() { forall(&OutputGenerator::endFile); } - void endPlainFile() - { forall(&OutputGenerator::endPlainFile); } void startTitleHead(const char *fileName) { forall(&OutputGenerator::startTitleHead,fileName); } void endTitleHead(const char *fileName,const char *name) @@ -313,8 +309,8 @@ class OutputList { forall(&OutputGenerator::writeSectionRefItem,page,lab,title); } void writeSectionRefAnchor(const char *page,const char *lab, const char *title) { forall(&OutputGenerator::writeSectionRefAnchor,page,lab,title); } - void addToIndex(const char *s1,const char *s2) - { forall(&OutputGenerator::addToIndex,s1,s2); } + void addIndexItem(const char *s1,const char *s2) + { forall(&OutputGenerator::addIndexItem,s1,s2); } void writeSynopsis() { forall(&OutputGenerator::writeSynopsis); } void startClassDiagram() @@ -389,6 +385,32 @@ class OutputList void endFontClass() { forall(&OutputGenerator::endFontClass); } +#if 0 + void startPlainFile(const char *name) + { forall(&OutputGenerator::startPlainFile,name); } + void endPlainFile() + { forall(&OutputGenerator::endPlainFile); } +#else // this is to work around a bug in the SGI MipsPro compiler + void startPlainFile(const char *name) + { + OutputGenerator *og=outputs->first(); + while (og) + { + if (og->isEnabled()) (og->startPlainFile)(name); + og=outputs->next(); + } + } + void endPlainFile() + { + OutputGenerator *og=outputs->first(); + while (og) + { + if (og->isEnabled()) (og->endPlainFile)(); + og=outputs->next(); + } + } +#endif + private: void debug(); void clear(); @@ -16,6 +16,7 @@ */ #include "sortdict.h" +#include "config.h" class PageInfo { @@ -33,6 +34,15 @@ class PageInfo QCString doc; QCString title; + // external reference? if so then this is the tag file name + QCString reference; + + // functions to get a uniform interface with Definitions + QCString getOutputFileBase() const + { if (Config::caseSensitiveNames) return name; else return name.lower(); } + bool isReference() const { return !reference.isEmpty(); } + QCString getReference() const { return reference; } + // ids int todoId; int testId; diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 22cd3e8..8a1dae2 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -671,7 +671,7 @@ void RTFGenerator::beginRTFDocument() } if (array.at(index) != 0) { - QCString key(iter.currentKey()); + QCString key(convertToQCString(iter.currentKey())); msg("Style '%s' redefines \\s%d.\n", key.data(), index); } array.at(index) = style; @@ -810,8 +810,11 @@ void RTFGenerator::startIndexSection(IndexSections is) bool found=FALSE; while (gd && !found) { - beginRTFChapter(); - found=TRUE; + if (!gd->isReference()) + { + beginRTFChapter(); + found=TRUE; + } gd=groupList.next(); } } @@ -965,10 +968,13 @@ void RTFGenerator::endIndexSection(IndexSections is) t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl; while (gd) { - t << "\\par " << Rtf_Style_Reset << endl; - t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \""; - t << gd->getOutputFileBase(); - t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; + if (!gd->isReference()) + { + t << "\\par " << Rtf_Style_Reset << endl; + t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \""; + t << gd->getOutputFileBase(); + t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; + } gd=groupList.next(); } } @@ -1519,7 +1525,7 @@ void RTFGenerator::endTitleHead(const char *fileName,const char *name) t << "}" << endl; // make an index entry - addToIndex(name,0); + addIndexItem(name,0); //if (name) //{ @@ -1566,8 +1572,8 @@ void RTFGenerator::startMemberDoc(const char *clname, DBG_RTF(t << "{\\comment startMemberDoc}" << endl) if (memname && memname[0]!='@') { - addToIndex(memname,clname); - addToIndex(clname,memname); + addIndexItem(memname,clname); + addIndexItem(clname,memname); } t << Rtf_Style_Reset << Rtf_Style["Heading4"]->reference; //styleStack.push(Rtf_Style_Heading4); @@ -1619,7 +1625,7 @@ void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor) // writeDoxyAnchor(0,clName,anchor,0); //} -void RTFGenerator::addToIndex(const char *s1,const char *s2) +void RTFGenerator::addIndexItem(const char *s1,const char *s2) { if (s1) { diff --git a/src/rtfgen.h b/src/rtfgen.h index 8fc53ad..2631dc0 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -171,7 +171,7 @@ class RTFGenerator : public OutputGenerator void writeSectionRef(const char *,const char *,const char *); void writeSectionRefItem(const char *,const char *,const char *); void writeSectionRefAnchor(const char *,const char *,const char *); - void addToIndex(const char *,const char *); + void addIndexItem(const char *,const char *); void startIndent(); void endIndent(); void writeSynopsis() {} diff --git a/src/scanner.l b/src/scanner.l index eb5c5f6..cfcc689 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -141,6 +141,7 @@ static QCString *pCopyRoundString; static QCString *pCopyCurlyString; static QCString *pCopyQuotedString; static QCString *pSkipDoc; +static QCString autoGroupName; static bool insideFormula; @@ -166,6 +167,18 @@ static void initParser() isTypedef = FALSE; } +static void initEntry() +{ + current->protection = protection ; + current->mtype = mtype; + current->virt = virt; + current->stat = gstat; + current->mGrpId = memberGroupId; + if (!autoGroupName.isEmpty()) + { + current->groups->append(new QCString(autoGroupName)); + } +} //----------------------------------------------------------------------------- static void lineCount() @@ -311,7 +324,7 @@ static int yyread(char *buf,int max_size) %} 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"|"ingroup"|"latexonly"|"htmlonly") +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"|"ingroup"|"latexonly"|"htmlonly"|"{") BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] @@ -469,7 +482,6 @@ TITLE [tT][iI][tT][lL][eE] if (sec) { current->name = yyFileName; - current->name = current->name; current->section = sec; current_root->addSubEntry(current); current = new Entry; @@ -824,11 +836,7 @@ TITLE [tT][iI][tT][lL][eE] //printf("Found using declaration %s\n",yytext); current_root->addSubEntry(current); current = new Entry ; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN(Using); } <UsingDirective>{SCOPENAME} { current->name=yytext; @@ -837,11 +845,7 @@ TITLE [tT][iI][tT][lL][eE] //printf("Found using directive %s\n",yytext); current_root->addSubEntry(current); current = new Entry ; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN(Using); } <Using>";" { BEGIN(FindMembers); } @@ -874,11 +878,19 @@ TITLE [tT][iI][tT][lL][eE] else BEGIN( EndTemplate ); } +<EndTemplate>"<<" { + current->name+=yytext; + *currentTemplateSpec+=yytext; + } <EndTemplate>"<" { current->name+='<'; *currentTemplateSpec+='<'; sharpCount++; } +<EndTemplate>">>" { + current->name+=yytext; + *currentTemplateSpec+=yytext; + } <EndTemplate>">" { current->name+='>'; *currentTemplateSpec+='>'; @@ -1000,11 +1012,7 @@ TITLE [tT][iI][tT][lL][eE] current->section = Entry::DEFINE_SEC; current_root->addSubEntry(current); current = new Entry ; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN(FindMembers); } <DefineEnd>\\[\r]?\n { @@ -1092,7 +1100,7 @@ TITLE [tT][iI][tT][lL][eE] BEGIN(AfterDoc); } } -<FindMembers,FindFields>"//@{"|"/*@{" { +<FindMembers,FindFields>"//"([!*]?){B}*"@{"|"/*"([!*]?){B}*"@{" { if (memberGroupId!=NOGROUP) { warn(yyFileName,yyLineNr,"Warning: ignoring nested member group. " @@ -1130,13 +1138,13 @@ TITLE [tT][iI][tT][lL][eE] BEGIN( Doc ); } } -<FindMembers,FindFields,ReadInitializer>"//@}"|"/*@}*/" { - if (memberGroupId==NOGROUP) +<FindMembers,FindFields,ReadInitializer>"//"([!*]?){B}*"@}"|"/*"([!*]?){B}*"@}"{B}*"*/" { + if (memberGroupId==NOGROUP && autoGroupName.isEmpty()) { warn(yyFileName,yyLineNr, - "Warning: end of member group without matching begin."); + "Warning: end of group without matching begin."); } - else + else if (memberGroupId!=NOGROUP) // end of member group { memberHeaderDict.insert(memberGroupId, new QCString(memberGroupHeader.stripWhiteSpace()) @@ -1145,10 +1153,29 @@ TITLE [tT][iI][tT][lL][eE] new QCString(memberGroupDocs) ); memberGroupId=NOGROUP; - if (YY_START!=ReadInitializer) current->mGrpId=NOGROUP; + if (YY_START!=ReadInitializer) + { + current->mGrpId=NOGROUP; + } memberGroupHeader.resize(0); memberGroupDocs.resize(0); } + else if (!autoGroupName.isEmpty()) // end of group + { + QCString *s = current->groups->first(); + int i=0; + while (s) + { + if (*s==autoGroupName) + { + current->groups->remove(i); + break; + } + s=current->groups->next(); + i++; + } + autoGroupName.resize(0); + } } <FindMembers>"=" { current->bodyLine = yyLineNr; @@ -1285,7 +1312,6 @@ TITLE [tT][iI][tT][lL][eE] } <FindMembers>[;,] { QCString oldType = current->type.copy(); - QCString oldDocs = current->doc.copy(); if (current->bodyLine==-1) { current->bodyLine = yyLineNr; @@ -1308,20 +1334,18 @@ TITLE [tT][iI][tT][lL][eE] current->startLine = yyLineNr; //printf("New variable type=`%s' name=`%s' groupId=%d\n",current->type.data(),current->name.data(),current->mGrpId); current_root->addSubEntry( current ) ; - current = new Entry ; - // variable found - current->section = Entry::EMPTY_SEC ; - current->protection = protection; - current->mtype = Method; - current->virt = Normal; - current->stat = gstat; - current->mGrpId = memberGroupId; - if ( *yytext == ',' ) + if ( *yytext == ',') { + current = new Entry(*current); + current->name.resize(0); int i=oldType.length(); while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--; current->type = oldType.left(i); - current->doc = oldDocs; + } + else + { + current = new Entry ; + initEntry(); } BEGIN( FindMembers ) ; } @@ -1398,11 +1422,7 @@ TITLE [tT][iI][tT][lL][eE] // add to the scope surrounding the enum (copy!) current_root->parent->addSubEntry(current); current = new Entry ; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); } else // probably a redundant , { @@ -1471,11 +1491,7 @@ TITLE [tT][iI][tT][lL][eE] ) { // namespaces and interfaces ends with a closing bracket without semicolon current->reset(); - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN( FindMembers ) ; } else @@ -1498,11 +1514,7 @@ TITLE [tT][iI][tT][lL][eE] //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data()); current_root->addSubEntry( current ) ; current = new Entry; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN(MemberSpecSkip); } <MemberSpec>([*&]*{BN}*)*{ID}("["[a-z_A-Z0-9]*"]")* { // the [] part could be improved. @@ -1587,11 +1599,7 @@ TITLE [tT][iI][tT][lL][eE] msArgs.resize(0); isTypedef=FALSE; current->reset(); - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN( FindMembers ); } } @@ -2021,11 +2029,7 @@ TITLE [tT][iI][tT][lL][eE] previous = current; current_root->addSubEntry(current); current = new Entry ; - current->protection = protection; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); lastCurlyContext = FindMembers; if( *yytext == '{' ) { @@ -2652,7 +2656,7 @@ TITLE [tT][iI][tT][lL][eE] if (current->todoId!=0) { RefItem *item = todoList.getRefItem(current->todoId); - item->text += "<p>"; + item->text += " <p>"; item->text += current->brief; } else @@ -2682,7 +2686,7 @@ TITLE [tT][iI][tT][lL][eE] if (current->testId!=0) { RefItem *item = testList.getRefItem(current->testId); - item->text += "<p>"; + item->text += " <p>"; item->text += current->brief; } else @@ -3024,6 +3028,22 @@ TITLE [tT][iI][tT][lL][eE] lineCount(); BEGIN( GroupName ); } +<ClassDoc,Doc,JavaDoc>{CMD}"{" { + if (current->section == Entry::GROUPDOC_SEC) + { + autoGroupName=current->name; + } + else if (current->section == Entry::MEMBERGRP_SEC) + { + memberGroupId = newMemberGroupId(); + current->mGrpId = memberGroupId; + lastMemberGroupLine = yyLineNr; + } + else + { + warn(yyFileName,yyLineNr,"Warning: @{ may only be used in a group block!\n"); + } + } <ExampleDoc,PageDoc,ClassDoc>. { current->doc += yytext; } <Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>^{B}*"//" <Doc,ExampleDoc,PageDoc,ClassDoc>"//" { current->doc += yytext; } @@ -3122,11 +3142,7 @@ TITLE [tT][iI][tT][lL][eE] //printf("Add docs for class %s\n",current->name.data()); current_root->addSubEntry(current); current = new Entry ; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN( FindMembers ); } } @@ -3175,7 +3191,7 @@ TITLE [tT][iI][tT][lL][eE] <DocBaseClass>\n { yyLineNr++; BEGIN( ClassDoc ); } <ClassDocBrief>{BS}({BL}|"\\n\\n") { current->brief=current->brief.stripWhiteSpace(); - if (!current->doc.isEmpty()) current->doc+="<p>"; + if (!current->doc.isEmpty()) current->doc+=" <p>"; if (lastBriefContext==TodoParam || lastBriefContext==TestParam) { unput('\n'); @@ -3389,23 +3405,19 @@ TITLE [tT][iI][tT][lL][eE] BEGIN(lastAfterDocContext); } <ClassDocRelates,ClassDocFunc,ClassDocDefine,GroupDocArg1,ClassDocArg1,SectionTitle,EnumDocArg1,PageDocArg1,ExampleDocArg1,ClassDefineArgs,GroupName>"*/" { - current->doc += "\n\n"; - warn(yyFileName,yyLineNr, - "Warning: unexpected end of " - "documentation block." - ); - BEGIN( lastDocContext ); + // defer "*/" to a later time + unput('/'); + unput('*'); + // insert \n and decrement the line number to compensate for the artifical newline + unput('\n'); + yyLineNr--; } <FileDocArg1>"*/" { current->name = yyFileName; current->doc += "\n\n"; current_root->addSubEntry(current); current = new Entry ; - current->protection = protection ; - current->mtype = mtype; - current->virt = virt; - current->stat = gstat; - current->mGrpId = memberGroupId; + initEntry(); BEGIN( FindMembers ); } <Doc>"*/" { diff --git a/src/sortdict.h b/src/sortdict.h index 471a447..9c46e9b 100644 --- a/src/sortdict.h +++ b/src/sortdict.h @@ -23,6 +23,25 @@ #include <qlist.h> #include <qdict.h> +template<class T> class SDict; + +/*! internal wrapper class that redirects compareItems() to the + * dictionary + */ +template<class T> +class SList : public QList<T> +{ + public: + SList(SDict<T> *owner) : m_owner(owner) {} + ~SList() {} + int compareItems(GCI item1,GCI item2) + { + return m_owner->compareItems(item1,item2); + } + private: + SDict<T> *m_owner; +}; + /*! Ordered dictionary of elements of type T. * Internally uses a QList<T> and a QDict<T>. */ @@ -30,23 +49,7 @@ template<class T> class SDict { private: - - /*! internal wrapper class that redirects compareItems() to the - * dictionary - */ - class SList : public QList<T> - { - public: - SList(SDict<T> *owner) : m_owner(owner) {} - ~SList() {} - int compareItems(GCI item1,GCI item2) - { - return m_owner->compareItems(item1,item2); - } - private: - SDict<T> *m_owner; - }; - SList *m_list; + SList<T> *m_list; QDict<T> *m_dict; public: @@ -56,7 +59,7 @@ class SDict */ SDict(int size) { - m_list = new SList(this); + m_list = new SList<T>(this); m_dict = new QDict<T>(size); } /*! Destroys the dictionary */ @@ -169,5 +172,4 @@ class SDict }; - #endif diff --git a/src/tag.h b/src/tag.h deleted file mode 100644 index 33b066d..0000000 --- a/src/tag.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2000 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 TAG_H -#define TAG_H - -extern void parseTagFile(const char *fileName); - -#endif diff --git a/src/tag.l b/src/tag.l deleted file mode 100644 index 2030b41..0000000 --- a/src/tag.l +++ /dev/null @@ -1,291 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2000 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. - * - */ - -%{ - -/* - * includes - */ -#include <stdio.h> - -#include "qtbc.h" -#include <qfileinfo.h> - -#include "classdef.h" -#include "filedef.h" -#include "namespacedef.h" -#include "memberdef.h" -#include "doxygen.h" -#include "util.h" -#include "message.h" -#include "defargs.h" - -#define YY_NO_UNPUT -#define YY_NEVER_INTERACTIVE 1 - -static int yyLineNr; -static QCString className; -static QCString fileName; -static QCString namespaceName; -static QCString tagName; -static QCString memberName; -static QCString anchorName; -static QCString argString; -static ClassDef *cd; -static FileDef *fd; -static NamespaceDef *nd; - -static void addClass(const char *name,const char *fileName) -{ - //printf("adding class %s\n",name); - if (name!=0 && strlen(name)>0 && classDict[name]==0) - { - cd = new ClassDef(fileName,1,name,ClassDef::Class,tagName,fileName); - fd = 0; - nd = 0; - classList.inSort(cd); - classDict.insert(className,cd); - } -} - -static void addFile(const char *name) -{ - //printf("adding file %s tagName=`%s'\n",name,tagName.data()); - fd = new FileDef(0,name,tagName); - FileName *mn; - if ((mn=inputNameDict->find(name))) - { - mn->append(fd); - } - else - { - mn = new FileName(name,name); - mn->append(fd); - inputNameList.inSort(mn); - inputNameDict->insert(name,mn); - } - cd = 0; - nd = 0; - //fileList.inSort(fd); - //fileDict.insert(fileName,fd); -} - -static void addNamespace(const char *name) -{ - if ((nd=namespaceDict[name])==0) - { - // TODO: we assume that each namespace is limited to a single tagfile. - // since namespace are open, this need not to be the case. As a result - // namespace may contain members that are located in - // different namespaces! - nd = new NamespaceDef("<tagfile>",1,name,tagName); - namespaceList.inSort(nd); - namespaceDict.insert(name,nd); - } - cd = 0; - fd = 0; -} - -static void addMember(const char *name,const char *anchor,const char *args) -{ - //printf("adding member `%s' `%s'\n",name,anchor); - if (cd || fd) - { - MemberNameDict *mnd=0; - MemberNameList *mnl=0; - MemberDef *md; - ArgumentList *argList = new ArgumentList; - stringToArgumentList(args,argList); - md=new MemberDef("<tagfile>",1, - 0,name,args,0,Public,Normal,FALSE,FALSE, - MemberDef::Function,0,argList); - delete argList; - md->setAnchor(anchor); - md->setReference(tagName); - if (cd) // member of a class - { - md->setMemberClass(cd); - cd->insertMember(md); - mnd=&memberNameDict; - mnl=&memberNameList; - } - else if (nd) // member of a namespace - { - md->setNamespace(nd); - nd->insertMember(md); - mnd=&functionNameDict; - mnl=&functionNameList; - } - else // member of a file - { - md->setFileDef(fd); - fd->insertMember(md); - mnd=&functionNameDict; - mnl=&functionNameList; - } - MemberName *mn = 0; - if ((mn=(*mnd)[memberName])) - { - //printf("mn->inSort()\n"); - mn->append(md); - } - else - { - //printf("mn->append()\n"); - mn=new MemberName(memberName); - mn->append(md); - //printf("Adding memberName=%s\n",mn->memberName()); - mnl->inSort(mn); - mnd->insert(memberName,mn); - } - } -} - -/* ----------------------------------------------------------------- - */ - -%} - -ID [a-z_A-Z0-9]+ -FILE [a-z_A-Z0-9\.\-\+\:\\\/]+ -SCOPE ({ID}"::")*{ID} - -%option noyywrap - -%x Pass1 -%x Pass2 -%x AnchorName -%x ArgString1 -%x ArgString2 -%x ClassName1 -%x ClassName2 -%x FileName -%x NamespaceName -%x BaseClasses -%x ClassFile1 -%x ClassFile2 - -%% - -<Pass1>^">" { // start of a class - BEGIN(ClassName1); - } -<Pass1>^"&" { // start of a file - BEGIN(FileName); - } -<Pass1>^"%" { // start of a namespace - BEGIN(NamespaceName); - } -<Pass1>^[~a-z_A-Z][^ \n]*/" " { - memberName=yytext; - BEGIN(AnchorName); - } -<Pass2>^">" { - BEGIN(ClassName2); - } -<AnchorName>{ID} { - anchorName=yytext; - BEGIN(ArgString1); - } -<ArgString1>"\"" { - BEGIN(ArgString2); - } -<ArgString2>[^\"\n]*/"\"" { - argString=yytext; - addMember(memberName,anchorName,argString); - BEGIN(Pass1); - } -<FileName>{FILE}/":" { - fileName=yytext; - addFile(yytext); - BEGIN(Pass1); - } -<NamespaceName>{SCOPE}/":" { - namespaceName=yytext; - addNamespace(yytext); - BEGIN(Pass1); - } -<ClassName1>{SCOPE}/":" { - className=yytext; - BEGIN(ClassFile1); - } -<ClassFile1>\" { - BEGIN(ClassFile2); - } -<ClassFile2>[^\"]*/\" { - addClass(className,yytext); - BEGIN(Pass1); - } -<ClassFile2>\n { - yyLineNr++; - BEGIN(Pass1); - } -<ClassName2>{ID}/":" { - cd=getClass(yytext); - BEGIN(BaseClasses); - } -<BaseClasses>{ID}/"?" { - ClassDef *bcd=getClass(yytext); - if (cd && bcd) - { - cd->insertBaseClass(bcd,Public,Normal); - bcd->insertSuperClass(cd,Public,Normal); - } - } -<BaseClasses>\n { - yyLineNr++; - BEGIN(Pass2); - } -<*>. -<*>\n { yyLineNr++ ; } - -%% - -/*@ ---------------------------------------------------------------------------- - */ - -void parseTagFile(const char *fileName) -{ - FILE *f=fopen(fileName,"r"); - QFileInfo fi(fileName); - if (!f || !fi.exists()) - { - if (f) fclose(f); - return; - } - tagName = fi.fileName(); - tagYYin = f; - - cd=0; - yyLineNr = 1; - tagYYrestart( tagYYin ); - BEGIN(Pass1); - tagYYlex(); - - rewind(f); - cd=0; - yyLineNr = 1; - tagYYrestart( tagYYin ); - BEGIN(Pass2); - tagYYlex(); - - fclose(f); -} - -//extern "C" { // some bogus code to keep the compiler happy -// int tagYYwrap() { return 1 ; } -//} diff --git a/src/tagreader.cpp b/src/tagreader.cpp new file mode 100644 index 0000000..d01e4bd --- /dev/null +++ b/src/tagreader.cpp @@ -0,0 +1,902 @@ +#include "tagreader.h" + +#include <stdio.h> +#include <qxml.h> +#include <qstack.h> +#include <qdict.h> +#include <qfileinfo.h> +#include <qlist.h> +#include <qstring.h> +#include <qstringlist.h> + +#include "entry.h" +#include "classdef.h" +#include "doxygen.h" +#include "util.h" +#include "message.h" + +/*! Container for member specific info that can be read from a tagfile */ +class TagMemberInfo +{ + public: + TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) {} + QString name; + QString anchor; + QString arglist; + QString kind; + Protection prot; + Specifier virt; + bool isStatic; +}; + +/*! Container for class specific info that can be read from a tagfile */ +class TagClassInfo +{ + public: + enum Kind { Class, Struct, Union, Interface, Exception }; + TagClassInfo() { bases=0, members.setAutoDelete(TRUE); } + ~TagClassInfo() { delete bases; } + QString name; + QString filename; + QList<BaseInfo> *bases; + QList<TagMemberInfo> members; + Kind kind; +}; + +/*! Container for namespace specific info that can be read from a tagfile */ +class TagNamespaceInfo +{ + public: + TagNamespaceInfo() { members.setAutoDelete(TRUE); } + QString name; + QString filename; + QList<TagMemberInfo> members; + QStringList classList; +}; + +/*! Container for file specific info that can be read from a tagfile */ +class TagFileInfo +{ + public: + TagFileInfo() { members.setAutoDelete(TRUE); } + QString name; + QString path; + QString filename; + QList<TagMemberInfo> members; + QStringList classList; + QStringList namespaceList; +}; + +/*! Container for group specific info that can be read from a tagfile */ +class TagGroupInfo +{ + public: + TagGroupInfo() { members.setAutoDelete(TRUE); } + QString name; + QString title; + QString filename; + QList<TagMemberInfo> members; + QStringList subgroupList; + QStringList classList; + QStringList namespaceList; + QStringList fileList; + QStringList pageList; +}; + +/*! Container for page specific info that can be read from a tagfile */ +class TagPageInfo +{ + public: + QString name; + QString title; + QString filename; +}; + + +/*! Tag file parser. + * Reads an XML-structured tagfile and builds up the structure in + * memory. The method buildLists() is used to transfer/translate + * the structures to the doxygen engine. + */ +class TagFileParser : public QXmlDefaultHandler +{ + enum State { Invalid, + InClass, + InFile, + InNamespace, + InGroup, + InPage, + InMember + }; + class StartElementHandler + { + typedef void (TagFileParser::*Handler)(const QXmlAttributes &attrib); + public: + StartElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {} + void operator()(const QXmlAttributes &attrib) { (m_parent->*m_handler)(attrib); } + private: + TagFileParser *m_parent; + Handler m_handler; + }; + class EndElementHandler + { + typedef void (TagFileParser::*Handler)(); + public: + EndElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {} + void operator()() { (m_parent->*m_handler)(); } + private: + TagFileParser *m_parent; + Handler m_handler; + }; + + public: + TagFileParser(const char *tagName) : m_tagName(tagName) {} + + void startCompound( const QXmlAttributes& attrib ) + { + m_curString = ""; + QString kind = attrib.value("kind"); + if (kind=="class") + { + m_curClass = new TagClassInfo; + m_curClass->kind = TagClassInfo::Class; + m_state = InClass; + } + else if (kind=="struct") + { + m_curClass = new TagClassInfo; + m_curClass->kind = TagClassInfo::Struct; + m_state = InClass; + } + else if (kind=="union") + { + m_curClass = new TagClassInfo; + m_curClass->kind = TagClassInfo::Union; + m_state = InClass; + } + else if (kind=="interface") + { + m_curClass = new TagClassInfo; + m_curClass->kind = TagClassInfo::Interface; + m_state = InClass; + } + else if (kind=="exception") + { + m_curClass = new TagClassInfo; + m_curClass->kind = TagClassInfo::Exception; + m_state = InClass; + } + else if (kind=="file") + { + m_curFile = new TagFileInfo; + m_state = InFile; + } + else if (kind=="namespace") + { + m_curNamespace = new TagNamespaceInfo; + m_state = InNamespace; + } + else if (kind=="group") + { + m_curGroup = new TagGroupInfo; + m_state = InGroup; + } + else if (kind=="page") + { + m_curPage = new TagPageInfo; + m_state = InPage; + } + else + { + err("Error: Unknown compound attribute `%s' found!\n",kind.data()); + } + } + void endCompound() + { + switch (m_state) + { + case InClass: m_tagFileClasses.append(m_curClass); + m_curClass=0; break; + case InFile: m_tagFileFiles.append(m_curFile); + m_curFile=0; break; + case InNamespace: m_tagFileNamespaces.append(m_curNamespace); + m_curNamespace=0; break; + case InGroup: m_tagFileGroups.append(m_curGroup); + m_curGroup=0; break; + case InPage: m_tagFilePages.append(m_curPage); + m_curPage=0; break; + default: + err("Error: tag `compound' was not expected!\n"); + } + } + void startMember( const QXmlAttributes& attrib) + { + m_curMember = new TagMemberInfo; + m_curMember->kind = attrib.value("kind"); + QString protStr = attrib.value("protection"); + QString virtStr = attrib.value("virtualness"); + QString staticStr = attrib.value("static"); + if (protStr=="protected") + { + m_curMember->prot = Protected; + } + else if (protStr=="private") + { + m_curMember->prot = Private; + } + if (virtStr=="virtual") + { + m_curMember->virt = Virtual; + } + else if (virtStr=="pure") + { + m_curMember->virt = Pure; + } + if (staticStr=="yes") + { + m_curMember->isStatic = TRUE; + } + m_stateStack.push(new State(m_state)); + m_state = InMember; + } + void endMember() + { + m_state = *m_stateStack.pop(); + switch(m_state) + { + case InClass: m_curClass->members.append(m_curMember); break; + case InFile: m_curFile->members.append(m_curMember); break; + case InNamespace: m_curNamespace->members.append(m_curMember); break; + case InGroup: m_curGroup->members.append(m_curMember); break; + default: err("Error: Unexpected tag `member' found\n"); break; + } + } + void endClass() + { + switch(m_state) + { + case InFile: m_curFile->classList.append(m_curString); break; + case InNamespace: m_curNamespace->classList.append(m_curString); break; + case InGroup: m_curGroup->classList.append(m_curString); break; + default: err("Error: Unexpected tag `class' found\n"); break; + } + } + void endNamespace() + { + switch(m_state) + { + case InFile: m_curFile->namespaceList.append(m_curString); break; + case InGroup: m_curGroup->namespaceList.append(m_curString); break; + default: err("Error: Unexpected tag `namespace' found\n"); break; + } + } + void endFile() + { + switch(m_state) + { + case InGroup: m_curGroup->fileList.append(m_curString); break; + default: err("Error: Unexpected tag `file' found\n"); break; + } + } + void endPage() + { + switch(m_state) + { + case InGroup: m_curGroup->fileList.append(m_curString); break; + default: err("Error: Unexpected tag `page' found\n"); break; + } + } + void startStringValue(const QXmlAttributes& ) + { + m_curString = ""; + } + void endName() + { + switch (m_state) + { + case InClass: m_curClass->name = m_curString; break; + case InFile: m_curFile->name = m_curString; break; + case InNamespace: m_curNamespace->name = m_curString; break; + case InGroup: m_curGroup->name = m_curString; break; + case InPage: m_curPage->name = m_curString; break; + case InMember: m_curMember->name = m_curString; break; + default: err("Error: Unexpected tag `name' found\n"); break; + } + } + void startBase(const QXmlAttributes& attrib ) + { + m_curString=""; + if (m_state==InClass && m_curClass) + { + QString protStr = attrib.value("protection"); + QString virtStr = attrib.value("virtualness"); + Protection prot = Public; + Specifier virt = Normal; + if (protStr=="protected") + { + prot = Protected; + } + else if (protStr=="private") + { + prot = Private; + } + if (virtStr=="virtual") + { + virt = Virtual; + } + if (m_curClass->bases==0) m_curClass->bases = new QList<BaseInfo>; + m_curClass->bases->append(new BaseInfo(m_curString,prot,virt)); + } + else + { + err("Error: Unexpected tag `base' found\n"); + } + } + void endBase() + { + if (m_state==InClass && m_curClass) + { + m_curClass->bases->getLast()->name = m_curString; + } + else + { + err("Error: Unexpected tag `base' found\n"); + } + } + void endFilename() + { + switch (m_state) + { + case InClass: m_curClass->filename = m_curString; break; + case InNamespace: m_curNamespace->filename = m_curString; break; + case InFile: m_curFile->filename = m_curString; break; + case InGroup: m_curGroup->filename = m_curString; break; + case InPage: m_curPage->filename = m_curString; break; + default: err("Error: Unexpected tag `filename' found\n"); break; + } + } + void endPath() + { + switch (m_state) + { + case InFile: m_curFile->path = m_curString; break; + default: err("Error: Unexpected tag `path' found\n"); break; + } + } + void endAnchor() + { + if (m_state==InMember) + { + m_curMember->anchor = m_curString; + } + else + { + err("Error: Unexpected tag `anchor' found\n"); + } + } + void endArglist() + { + if (m_state==InMember) + { + m_curMember->arglist = m_curString; + } + else + { + err("Error: Unexpected tag `arglist' found\n"); + } + } + void endTitle() + { + switch (m_state) + { + case InGroup: m_curGroup->title = m_curString; break; + case InPage: m_curPage->title = m_curString; break; + default: err("Error: Unexpected tag `title' found\n"); break; + } + } + void endSubgroup() + { + if (m_state==InGroup) + { + m_curGroup->subgroupList.append(m_curString); + } + else + { + err("Error: Unexpected tag `subgroup' found\n"); + } + } + void startIgnoreElement(const QXmlAttributes& ) + { + } + void endIgnoreElement() + { + } + + bool startDocument() + { + m_curClass=0; + m_curNamespace=0; + m_curFile=0; + m_curGroup=0; + m_curPage=0; + m_state = Invalid; + m_stateStack.setAutoDelete(TRUE); + m_tagFileClasses.setAutoDelete(TRUE); + m_tagFileFiles.setAutoDelete(TRUE); + m_tagFileNamespaces.setAutoDelete(TRUE); + m_tagFileGroups.setAutoDelete(TRUE); + m_tagFilePages.setAutoDelete(TRUE); + m_startElementHandlers.insert("compound", new StartElementHandler(this,&TagFileParser::startCompound)); + m_startElementHandlers.insert("member", new StartElementHandler(this,&TagFileParser::startMember)); + m_startElementHandlers.insert("name", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("base", new StartElementHandler(this,&TagFileParser::startBase)); + m_startElementHandlers.insert("filename", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("path", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("anchor", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("arglist", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("title", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("subgroup", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("class", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("namespace", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("file", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("page", new StartElementHandler(this,&TagFileParser::startStringValue)); + m_startElementHandlers.insert("tagfile", new StartElementHandler(this,&TagFileParser::startIgnoreElement)); + m_endElementHandlers.insert("compound", new EndElementHandler(this,&TagFileParser::endCompound)); + m_endElementHandlers.insert("member", new EndElementHandler(this,&TagFileParser::endMember)); + m_endElementHandlers.insert("name", new EndElementHandler(this,&TagFileParser::endName)); + m_endElementHandlers.insert("base", new EndElementHandler(this,&TagFileParser::endBase)); + m_endElementHandlers.insert("filename", new EndElementHandler(this,&TagFileParser::endFilename)); + m_endElementHandlers.insert("path", new EndElementHandler(this,&TagFileParser::endPath)); + m_endElementHandlers.insert("anchor", new EndElementHandler(this,&TagFileParser::endAnchor)); + m_endElementHandlers.insert("arglist", new EndElementHandler(this,&TagFileParser::endArglist)); + m_endElementHandlers.insert("title", new EndElementHandler(this,&TagFileParser::endTitle)); + m_endElementHandlers.insert("subgroup", new EndElementHandler(this,&TagFileParser::endSubgroup)); + m_endElementHandlers.insert("class" , new EndElementHandler(this,&TagFileParser::endClass)); + m_endElementHandlers.insert("namespace", new EndElementHandler(this,&TagFileParser::endNamespace)); + m_endElementHandlers.insert("file", new EndElementHandler(this,&TagFileParser::endFile)); + m_endElementHandlers.insert("page", new EndElementHandler(this,&TagFileParser::endPage)); + m_endElementHandlers.insert("tagfile", new EndElementHandler(this,&TagFileParser::endIgnoreElement)); + return TRUE; + } + bool startElement( const QString&, const QString&, + const QString&name, const QXmlAttributes& attrib ) + { + //printf("startElement `%s'\n",name.data()); + StartElementHandler *handler = m_startElementHandlers[name]; + if (handler) + { + (*handler)(attrib); + } + else + { + err("Error: Unknown tag `%s' found!\n",name.data()); + } + return TRUE; + } + bool endElement( const QString&, const QString&, const QString& name ) + { + //printf("endElement `%s'\n",name.data()); + EndElementHandler *handler = m_endElementHandlers[name]; + if (handler) + { + (*handler)(); + } + else + { + err("Error: Unknown tag `%s' found!\n",name.data()); + } + return TRUE; + } + bool characters ( const QString & ch ) + { + m_curString+=ch; + return TRUE; + } + void dump(); + void buildLists(Entry *root); + + private: + void buildMemberList(Entry *ce,QList<TagMemberInfo> &members); + QList<TagClassInfo> m_tagFileClasses; + QList<TagFileInfo> m_tagFileFiles; + QList<TagNamespaceInfo> m_tagFileNamespaces; + QList<TagGroupInfo> m_tagFileGroups; + QList<TagPageInfo> m_tagFilePages; + QDict<StartElementHandler> m_startElementHandlers; + QDict<EndElementHandler> m_endElementHandlers; + TagClassInfo *m_curClass; + TagFileInfo *m_curFile; + TagNamespaceInfo *m_curNamespace; + TagGroupInfo *m_curGroup; + TagPageInfo *m_curPage; + TagMemberInfo *m_curMember; + QCString m_curString; + QString m_tagName; + State m_state; + QStack<State> m_stateStack; +}; + +/*! Error handler for the XML tag file parser. + * Basically dumps all fatal error to stderr using err(). + */ +class TagFileErrorHandler : public QXmlErrorHandler +{ + public: + virtual ~TagFileErrorHandler() {} + bool warning( const QXmlParseException & ) + { + return FALSE; + } + bool error( const QXmlParseException & ) + { + return FALSE; + } + bool fatalError( const QXmlParseException &exception ) + { + err("Fatal error at line %d column %d: %s\n", + exception.lineNumber(),exception.columnNumber(), + exception.message().data()); + return FALSE; + } + QString errorString() { return ""; } + + private: + QString errorMsg; +}; + +/*! Dumps the internal structures. For debugging only! */ +void TagFileParser::dump() +{ + printf("Result:\n"); + QListIterator<TagClassInfo> lci(m_tagFileClasses); + + //============== CLASSES + TagClassInfo *cd; + for (;(cd=lci.current());++lci) + { + printf("class `%s'\n",cd->name.data()); + printf(" filename `%s'\n",cd->filename.data()); + if (cd->bases) + { + QListIterator<BaseInfo> bii(*cd->bases); + BaseInfo *bi; + for ( bii.toFirst() ; (bi=bii.current()) ; ++bii) + { + printf( " base: %s \n", bi->name.data() ); + } + } + + QListIterator<TagMemberInfo> mci(cd->members); + TagMemberInfo *md; + for (;(md=mci.current());++mci) + { + printf(" member:\n"); + printf(" kind: `%s'\n",md->kind.data()); + printf(" name: `%s'\n",md->name.data()); + printf(" anchor: `%s'\n",md->anchor.data()); + printf(" arglist: `%s'\n",md->arglist.data()); + } + } + //============== NAMESPACES + QListIterator<TagNamespaceInfo> lni(m_tagFileNamespaces); + TagNamespaceInfo *nd; + for (;(nd=lni.current());++lni) + { + printf("namespace `%s'\n",nd->name.data()); + printf(" filename `%s'\n",nd->filename.data()); + QStringList::Iterator it; + for ( it = nd->classList.begin(); + it != nd->classList.end(); ++it ) + { + printf( " class: %s \n", (*it).latin1() ); + } + + QListIterator<TagMemberInfo> mci(nd->members); + TagMemberInfo *md; + for (;(md=mci.current());++mci) + { + printf(" member:\n"); + printf(" kind: `%s'\n",md->kind.data()); + printf(" name: `%s'\n",md->name.data()); + printf(" anchor: `%s'\n",md->anchor.data()); + printf(" arglist: `%s'\n",md->arglist.data()); + } + } + //============== FILES + QListIterator<TagFileInfo> lfi(m_tagFileFiles); + TagFileInfo *fd; + for (;(fd=lfi.current());++lfi) + { + printf("file `%s'\n",fd->name.data()); + printf(" filename `%s'\n",fd->filename.data()); + QStringList::Iterator it; + for ( it = fd->namespaceList.begin(); + it != fd->namespaceList.end(); ++it ) + { + printf( " namespace: %s \n", (*it).latin1() ); + } + for ( it = fd->classList.begin(); + it != fd->classList.end(); ++it ) + { + printf( " class: %s \n", (*it).latin1() ); + } + + QListIterator<TagMemberInfo> mci(fd->members); + TagMemberInfo *md; + for (;(md=mci.current());++mci) + { + printf(" member:\n"); + printf(" kind: `%s'\n",md->kind.data()); + printf(" name: `%s'\n",md->name.data()); + printf(" anchor: `%s'\n",md->anchor.data()); + printf(" arglist: `%s'\n",md->arglist.data()); + } + } + + //============== GROUPS + QListIterator<TagGroupInfo> lgi(m_tagFileGroups); + TagGroupInfo *gd; + for (;(gd=lgi.current());++lgi) + { + printf("group `%s'\n",gd->name.data()); + printf(" filename `%s'\n",gd->filename.data()); + QStringList::Iterator it; + for ( it = gd->namespaceList.begin(); + it != gd->namespaceList.end(); ++it ) + { + printf( " namespace: %s \n", (*it).latin1() ); + } + for ( it = gd->classList.begin(); + it != gd->classList.end(); ++it ) + { + printf( " class: %s \n", (*it).latin1() ); + } + for ( it = gd->fileList.begin(); + it != gd->fileList.end(); ++it ) + { + printf( " file: %s \n", (*it).latin1() ); + } + for ( it = gd->subgroupList.begin(); + it != gd->subgroupList.end(); ++it ) + { + printf( " subgroup: %s \n", (*it).latin1() ); + } + for ( it = gd->pageList.begin(); + it != gd->pageList.end(); ++it ) + { + printf( " page: %s \n", (*it).latin1() ); + } + + QListIterator<TagMemberInfo> mci(gd->members); + TagMemberInfo *md; + for (;(md=mci.current());++mci) + { + printf(" member:\n"); + printf(" kind: `%s'\n",md->kind.data()); + printf(" name: `%s'\n",md->name.data()); + printf(" anchor: `%s'\n",md->anchor.data()); + printf(" arglist: `%s'\n",md->arglist.data()); + } + } + //============== PAGES + QListIterator<TagPageInfo> lpi(m_tagFilePages); + TagPageInfo *pd; + for (;(pd=lpi.current());++lpi) + { + printf("page `%s'\n",pd->name.data()); + printf(" title `%s'\n",pd->title.data()); + printf(" filename `%s'\n",pd->filename.data()); + } +} + +void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members) +{ + QListIterator<TagMemberInfo> mii(members); + TagMemberInfo *tmi; + for (;(tmi=mii.current());++mii) + { + Entry *me = new Entry; + me->name = tmi->name; + me->args = tmi->arglist; + me->protection = tmi->prot; + me->virt = tmi->virt; + me->stat = tmi->isStatic; + TagInfo *ti = new TagInfo; + ti->tagName = m_tagName; + ti->anchor = tmi->anchor; + me->tagInfo = ti; + if (tmi->kind=="define") + { + me->type="#define"; + me->section = Entry::DEFINE_SEC; + } + else if (tmi->kind=="enumvalue") + { + me->section = Entry::VARIABLE_SEC; + me->mtype = Method; + } + else if (tmi->kind=="property") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = Property; + } + else if (tmi->kind=="variable") + { + me->section = Entry::VARIABLE_SEC; + me->mtype = Method; + } + else if (tmi->kind=="typedef") + { + me->section = Entry::TYPEDEF_SEC; + me->mtype = Method; + } + else if (tmi->kind=="enumeration") + { + me->section = Entry::ENUM_SEC; + me->mtype = Method; + } + else if (tmi->kind=="function") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = Method; + } + else if (tmi->kind=="signal") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = Signal; + } + else if (tmi->kind=="prototype") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = Method; + } + else if (tmi->kind=="friend") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = Method; + } + else if (tmi->kind=="dcop") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = DCOP; + } + else if (tmi->kind=="slot") + { + me->section = Entry::FUNCTION_SEC; + me->mtype = Slot; + } + ce->addSubEntry(me); + } +} + +void TagFileParser::buildLists(Entry *root) +{ + // build class list + TagClassInfo *tci = m_tagFileClasses.first(); + while (tci) + { + Entry *ce = new Entry; + switch (tci->kind) + { + case TagClassInfo::Class: ce->section = Entry::CLASS_SEC; break; + case TagClassInfo::Struct: ce->section = Entry::STRUCT_SEC; break; + case TagClassInfo::Union: ce->section = Entry::UNION_SEC; break; + case TagClassInfo::Interface: ce->section = Entry::INTERFACE_SEC; break; + case TagClassInfo::Exception: ce->section = Entry::EXCEPTION_SEC; break; + } + ce->name = tci->name; + TagInfo *ti = new TagInfo; + ti->tagName = m_tagName; + ti->fileName = tci->filename; + ce->tagInfo = ti; + // transfer base class list + if (tci->bases) + { + ce->extends = tci->bases; tci->bases = 0; + } + + buildMemberList(ce,tci->members); + root->addSubEntry(ce); + tci = m_tagFileClasses.next(); + } + + // build file list + TagFileInfo *tfi = m_tagFileFiles.first(); + while (tfi) + { + Entry *fe = new Entry; + fe->section = guessSection(tfi->name); + fe->name = tfi->name; + TagInfo *ti = new TagInfo; + ti->tagName = m_tagName; + ti->fileName = tfi->filename; + fe->tagInfo = ti; + + QString fullName = m_tagName+":"+tfi->path+tfi->name; + fe->fileName = fullName; + FileDef *fd = new FileDef(m_tagName+":"+tfi->path,tfi->name,m_tagName); + FileName *mn; + if ((mn=inputNameDict->find(tfi->name))) + { + mn->append(fd); + } + else + { + mn = new FileName(fullName,tfi->name); + mn->append(fd); + inputNameList.inSort(mn); + inputNameDict->insert(tfi->name,mn); + } + buildMemberList(fe,tfi->members); + root->addSubEntry(fe); + tfi = m_tagFileFiles.next(); + } + + // build namespace list + TagNamespaceInfo *tni = m_tagFileNamespaces.first(); + while (tni) + { + Entry *ne = new Entry; + ne->section = Entry::NAMESPACE_SEC; + ne->name = tni->name; + TagInfo *ti = new TagInfo; + ti->tagName = m_tagName; + ti->fileName = tni->filename; + ne->tagInfo = ti; + + buildMemberList(ne,tni->members); + root->addSubEntry(ne); + tni = m_tagFileNamespaces.next(); + } + + // build group list + TagGroupInfo *tgi = m_tagFileGroups.first(); + while (tgi) + { + Entry *ge = new Entry; + ge->section = Entry::GROUPDOC_SEC; + ge->name = tgi->name; + ge->type = tgi->title; + TagInfo *ti = new TagInfo; + ti->tagName = m_tagName; + ti->fileName = tgi->filename; + ge->tagInfo = ti; + + buildMemberList(ge,tgi->members); + root->addSubEntry(ge); + tgi = m_tagFileGroups.next(); + } + + // build page list + TagPageInfo *tpi = m_tagFilePages.first(); + while (tpi) + { + Entry *pe = new Entry; + pe->section = Entry::PAGEDOC_SEC; + pe->name = tpi->name; + pe->args = tpi->title; + TagInfo *ti = new TagInfo; + ti->tagName = m_tagName; + ti->fileName = tpi->filename; + pe->tagInfo = ti; + + root->addSubEntry(pe); + tpi = m_tagFilePages.next(); + } +} + +void parseTagFile(Entry *root,const char *fullName,const char *tagName) +{ + QFileInfo fi(fullName); + if (!fi.exists()) return; + TagFileParser handler( tagName ); + TagFileErrorHandler errorHandler; + QFile xmlFile( fullName ); + QXmlInputSource source( xmlFile ); + QXmlSimpleReader reader; + reader.setContentHandler( &handler ); + reader.setErrorHandler( &errorHandler ); + reader.parse( source ); + handler.buildLists(root); +} + diff --git a/src/tagreader.h b/src/tagreader.h new file mode 100644 index 0000000..1501274 --- /dev/null +++ b/src/tagreader.h @@ -0,0 +1,10 @@ +#ifndef TAGREADER_H +#define TAGREADER_H + +#include "qtbc.h" + +class Entry; + +void parseTagFile(Entry *root,const char *fullPathName,const char *fileName); + +#endif diff --git a/src/translator_de.h b/src/translator_de.h index 44d2ec5..dd32ec8 100644 --- a/src/translator_de.h +++ b/src/translator_de.h @@ -383,7 +383,7 @@ class TranslatorGerman : public Translator QCString trNamespaceList() // used as the title of page containing all the index of all namespaces. - { return ""; } + { return "Lister aller Namensberiche"; } QCString trNamespaceListDescription(bool extractAll) // used as an introduction to the namespace list { diff --git a/src/util.cpp b/src/util.cpp index 8282ccd..dd04fde 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -17,6 +17,9 @@ #include <stdlib.h> #include <ctype.h> +#ifdef _WIN32 +#include <windows.h> +#endif #include "qtbc.h" #include <qregexp.h> @@ -110,8 +113,8 @@ void TextGeneratorXMLImpl::writeLink(const char *extRef,const char *file, //------------------------------------------------------------------------ -/*! Implements an interruptable system call on Unix */ -int iSystem(const char *command) +/*! Implements an interruptable system call on Unix/Windows */ +int iSystem(const char *command,const char *args) { #ifndef _WIN32 /*! taken from the system() manpage on my Linux box */ @@ -122,10 +125,14 @@ int iSystem(const char *command) if (pid==-1) return -1; if (pid==0) { + char buf[4096]; + strcpy(buf,command); + strcat(buf," "); + strcat(buf,args); const char * argv[4]; argv[0] = "sh"; argv[1] = "-c"; - argv[2] = command; + argv[2] = buf; argv[3] = 0; execve("/bin/sh",(char * const *)argv,environ); exit(127); @@ -142,7 +149,33 @@ int iSystem(const char *command) } } #else - return system(command); + SHELLEXECUTEINFO sInfo = { + sizeof(SHELLEXECUTEINFO), /* structure size */ + SEE_MASK_NOCLOSEPROCESS, /* leave the process running */ + NULL, /* window handle */ + NULL, /* action to perform: open */ + command, /* file to execute */ + args, /* argument list */ + NULL, /* use current working dir */ + SW_HIDE, /* minimize on start-up */ + 0, /* application instance handle */ + NULL, /* ignored: id list */ + NULL, /* ignored: class name */ + NULL, /* ignored: key class */ + 0, /* ignored: hot key */ + NULL, /* ignored: icon */ + NULL /* resulting application handle */ + }; + if (!ShellExecuteEx(&sInfo)) + { + return -1; + } + else if (sInfo.hProcess) /* executable was launched, wait for it to finish */ + { + WaitForSingleObject(sInfo.hProcess,INFINITE); + } + return 0; + //return system(command); #endif } @@ -305,13 +338,17 @@ QCString stripFromPath(const QCString &path) int guessSection(const char *name) { QCString n=((QCString)name).lower(); - if (n.right(2)==".c" || + if (n.right(2)==".c" || // source n.right(3)==".cc" || n.right(4)==".cxx" || n.right(4)==".cpp" || - n.right(4)==".c++" + n.right(4)==".c++" || + n.right(3)==".ii" || // inline + n.right(4)==".ixx" || + n.right(4)==".ipp" || + n.right(4)==".i++" ) return Entry::SOURCE_SEC; - if (n.right(2)==".h" || + if (n.right(2)==".h" || // header n.right(3)==".hh" || n.right(4)==".hxx" || n.right(4)==".hpp" || @@ -1257,14 +1294,14 @@ static void trimNamespaceScope(QCString &t1,QCString &t2) */ void stripIrrelevantConstVolatile(QCString &s) { - int i,j; + int i; if (s=="const") { s.resize(0); return; } if (s=="volatile") { s.resize(0); return; } i = s.find("const "); if (i!=-1) { // no & or * after the const - if ((j=s.find('*',i+6))==-1 && (j=s.find('&',i+6))==-1) + if (s.find('*',i+6)==-1 && s.find('&',i+6)==-1) { s=s.left(i)+s.right(s.length()-i-6); } @@ -1273,7 +1310,7 @@ void stripIrrelevantConstVolatile(QCString &s) if (i!=-1) { // no & or * after the volatile - if ((j=s.find('*',i+9))==-1 && (j=s.find('&',i+9))==-1) + if (s.find('*',i+9)==-1 && s.find('&',i+9)==-1) { s=s.left(i)+s.right(s.length()-i-9); } @@ -1993,9 +2030,9 @@ bool getDefs(const QCString &scName,const QCString &memberName, // maybe an namespace, file or group member ? //printf("Testing for global function scopeName=`%s' mScope=`%s' :: mName=`%s'\n", // scopeName.data(),mScope.data(),mName.data()); - //printf(" >member name found\n"); if ((mn=functionNameDict[mName])) // name is known { + //printf(" >member name found\n"); NamespaceDef *fnd=0; int scopeOffset=scopeName.length(); do @@ -2298,13 +2335,11 @@ bool generateRef(OutputList &ol,const char *scName, if (bracePos!=-1) argsStr=tmpName.right(tmpName.length()-bracePos); // create a default link text if none was explicitly given - bool explicitLink=TRUE; if (linkText.isEmpty()) { //if (!scopeUser.isEmpty()) linkText=scopeUser+"::"; linkText=nameStr; if (linkText.left(2)=="::") linkText=linkText.right(linkText.length()-2); - explicitLink=FALSE; } //printf("scope=`%s' name=`%s' arg=`%s' linkText=`%s'\n", // scopeStr.data(),nameStr.data(),argsStr.data(),linkText.data()); @@ -2445,12 +2480,12 @@ bool generateLink(OutputList &ol,const char *clName, { SectionInfo *si=0; if (!pi->name.isEmpty()) si=sectionDict[pi->name]; - ol.writeObjectLink(0,gd->getOutputFileBase(),si ? si->label.data() : 0,lt); + ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),si ? si->label.data() : 0,lt); writePageRef(ol,gd->getOutputFileBase(),si ? si->label.data() : 0); } else { - ol.writeObjectLink(0,pi->name,0,lt); + ol.writeObjectLink(pi->getReference(),pi->getOutputFileBase(),0,lt); writePageRef(ol,pi->name,0); } return TRUE; @@ -2877,3 +2912,23 @@ QCString stripScope(const char *name) return result; } +QCString convertToXML(const char *s) +{ + QCString result; + if (s==0) return result; + const char *p=s; + char c; + while ((c=*p++)) + { + switch (c) + { + case '<': result+="<"; break; + case '>': result+=">"; break; + case '&': result+="&"; break; + case '\'': result+="'"; break; + case '"': result+="""; break; + default: result+=c; break; + } + } + return result; +} @@ -133,6 +133,7 @@ void setFileNameForSections(QList<QCString> *anchorList,const char *fileName); QCString stripAnnonymousScope(const QCString &s); QCString stripAnnonymousNamespaceScope(const QCString &s); QCString stripFromPath(const QCString &path); +QCString convertToXML(const char *s); bool rightScopeMatch(const QCString &scope, const QCString &name); bool leftScopeMatch(const QCString &scope, const QCString &name); void writePageRef(OutputList &ol,const char *cn,const char *mn); @@ -149,7 +150,7 @@ void extractNamespaceName(const QCString &scopeName, QCString &className,QCString &namespaceName); QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ); QCString stripScope(const char *name); -int iSystem(const char *command); +int iSystem(const char *command,const char *args); #endif diff --git a/src/xml.cpp b/src/xml.cpp index fd2cf45..1171a2e 100644 --- a/src/xml.cpp +++ b/src/xml.cpp @@ -22,6 +22,7 @@ #include "message.h" #include "config.h" #include "classlist.h" +#include "util.h" #include <qdir.h> #include <qfile.h> @@ -46,21 +47,7 @@ void generateDTD() void writeXMLString(QTextStream &t,const char *s) { - if (s==0) return; - const char *p=s; - char c; - while ((c=*p++)) - { - switch (c) - { - case '<': t << "<"; break; - case '>': t << ">"; break; - case '&': t << "&"; break; - case '\'': t << "'"; break; - case '"': t << """; break; - default: t << c; break; - } - } + t << convertToXML(s); } void writeXMLLink(QTextStream &t,const char *compoundId,const char *memId, @@ -19,6 +19,7 @@ class QTextStream; void generateXML(); void writeXMLString(QTextStream &t,const char *s); +void writeXMLString(QTextStream &t,const char *s); void writeXMLLink(QTextStream &t,const char *compoundRef,const char *memAnchor, const char *text); |