diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2007-07-19 13:04:41 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2007-07-19 13:04:41 (GMT) |
commit | 29a8f144739c86ffad8db2f0c09de66bb641d2e2 (patch) | |
tree | 7c115c97f09109f537a6eb50b9baa3c0cd91d07d /src | |
parent | 01147699a7fb267e9d9247bdfb640f46e2164d3a (diff) | |
download | Doxygen-29a8f144739c86ffad8db2f0c09de66bb641d2e2.zip Doxygen-29a8f144739c86ffad8db2f0c09de66bb641d2e2.tar.gz Doxygen-29a8f144739c86ffad8db2f0c09de66bb641d2e2.tar.bz2 |
Release-1.5.2-20070719
Diffstat (limited to 'src')
-rw-r--r-- | src/classdef.cpp | 67 | ||||
-rw-r--r-- | src/classdef.h | 1 | ||||
-rw-r--r-- | src/cmdmapper.cpp | 3 | ||||
-rw-r--r-- | src/commentcnv.l | 2 | ||||
-rw-r--r-- | src/commentscan.l | 4 | ||||
-rw-r--r-- | src/config.l | 10 | ||||
-rw-r--r-- | src/definition.cpp | 6 | ||||
-rw-r--r-- | src/docparser.cpp | 8 | ||||
-rw-r--r-- | src/dot.cpp | 152 | ||||
-rw-r--r-- | src/dot.h | 5 | ||||
-rw-r--r-- | src/doxygen.cpp | 70 | ||||
-rw-r--r-- | src/entry.cpp | 136 | ||||
-rw-r--r-- | src/entry.h | 1 | ||||
-rw-r--r-- | src/filedef.cpp | 5 | ||||
-rw-r--r-- | src/htmlgen.cpp | 187 | ||||
-rw-r--r-- | src/htmlgen.h | 12 | ||||
-rw-r--r-- | src/latexgen.cpp | 52 | ||||
-rw-r--r-- | src/latexgen.h | 11 | ||||
-rw-r--r-- | src/mangen.cpp | 66 | ||||
-rw-r--r-- | src/mangen.h | 11 | ||||
-rw-r--r-- | src/marshal.cpp | 2 | ||||
-rw-r--r-- | src/memberdef.cpp | 39 | ||||
-rw-r--r-- | src/memberdef.h | 1 | ||||
-rw-r--r-- | src/namespacedef.cpp | 4 | ||||
-rw-r--r-- | src/outputgen.h | 14 | ||||
-rw-r--r-- | src/outputlist.h | 25 | ||||
-rw-r--r-- | src/pyscanner.l | 11 | ||||
-rw-r--r-- | src/rtfdocvisitor.cpp | 35 | ||||
-rw-r--r-- | src/rtfgen.cpp | 106 | ||||
-rw-r--r-- | src/rtfgen.h | 12 | ||||
-rw-r--r-- | src/scanner.l | 203 | ||||
-rw-r--r-- | src/textdocvisitor.cpp | 9 | ||||
-rw-r--r-- | src/textdocvisitor.h | 6 | ||||
-rw-r--r-- | src/util.cpp | 159 | ||||
-rw-r--r-- | src/util.h | 3 |
35 files changed, 1030 insertions, 408 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index bbfe3e8..1991a4a 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -85,6 +85,9 @@ class ClassDefImpl /*! Template arguments of this class */ ArgumentList *tempArgs; + /*! Type constraints for template parameters */ + ArgumentList *typeConstraints; + /*! Files that were used for generating the class documentation. */ QStrList files; @@ -189,6 +192,7 @@ void ClassDefImpl::init(const char *defFileName, const char *name, allMemberNameInfoSDict = 0; incInfo=0; tempArgs=0; + typeConstraints=0; prot=Public; nspace=0; fileDef=0; @@ -244,6 +248,7 @@ ClassDefImpl::~ClassDefImpl() delete variableInstances; delete templBaseClassNames; delete tempArgs; + delete typeConstraints; } // constructs a new class definition @@ -870,6 +875,7 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType { ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::RTF); ol.newParagraph(); ol.enableAll(); ol.disableAllBut(OutputGenerator::Man); @@ -879,12 +885,12 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType // write documentation if (!documentation().isEmpty()) { - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::RTF); - ol.newParagraph(); - ol.popGeneratorState(); - ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE); + //ol.newParagraph(); + ol.parseDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE); } + // write type constraints + writeTypeConstraints(ol,this,m_impl->typeConstraints); + // write examples if (exampleFlag && m_impl->exampleSDict) { @@ -894,7 +900,7 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType writeExample(ol,m_impl->exampleSDict); ol.endSimpleSect(); } - ol.newParagraph(); + //ol.newParagraph(); writeSourceDef(ol,name()); ol.endTextBlock(); } @@ -1021,17 +1027,6 @@ void ClassDef::writeClassDiagrams(OutputList &ol) ol.startDotGraph(); ol.parseText(theTranslator->trClassDiagram(displayName())); ol.endDotGraph(inheritanceGraph); - if (Config_getBool("GENERATE_LEGEND")) - { - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - ol.writeString("<center><font size=\"2\">["); - ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension); - ol.docify(theTranslator->trLegend()); - ol.endHtmlLink(); - ol.writeString("]</font></center>"); - ol.popGeneratorState(); - } ol.popGeneratorState(); renderDiagram = TRUE; } @@ -1048,7 +1043,8 @@ void ClassDef::writeClassDiagrams(OutputList &ol) renderDiagram = TRUE; } - if (Config_getBool("CLASS_DIAGRAMS") && renderDiagram) + if (renderDiagram) // if we already show the inheritance relations graphically, + // then hide the text version { ol.disableAllBut(OutputGenerator::Man); } @@ -1138,7 +1134,7 @@ void ClassDef::writeClassDiagrams(OutputList &ol) ol.newParagraph(); } - if (Config_getBool("CLASS_DIAGRAMS") && renderDiagram) + if (renderDiagram) { ol.enableAll(); } @@ -1153,15 +1149,6 @@ void ClassDef::writeClassDiagrams(OutputList &ol) ol.startDotGraph(); ol.parseText(theTranslator->trCollaborationDiagram(displayName())); ol.endDotGraph(usageImplGraph); - if (Config_getBool("GENERATE_LEGEND")) - { - ol.disableAllBut(OutputGenerator::Html); - ol.writeString("<center><font size=\"2\">["); - ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension); - ol.docify(theTranslator->trLegend()); - ol.endHtmlLink(); - ol.writeString("]</font></center>"); - } ol.popGeneratorState(); } } @@ -1229,8 +1216,10 @@ void ClassDef::writeDocumentation(OutputList &ol) if (!Config_getBool("DETAILS_AT_TOP")) { ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE); - ol.writeString(" \n"); ol.pushGeneratorState(); + ol.disable(OutputGenerator::RTF); + ol.writeString(" \n"); + ol.enable(OutputGenerator::RTF); ol.disableAllBut(OutputGenerator::Html); ol.startTextLink(0,"_details"); @@ -1329,12 +1318,13 @@ void ClassDef::writeDocumentation(OutputList &ol) writeClassDiagrams(ol); // write link to list of all members (HTML only) - if (m_impl->allMemberNameInfoSDict && + if (m_impl->allMemberNameInfoSDict && !Config_getBool("OPTIMIZE_OUTPUT_FOR_C") ) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); + ol.newParagraph(); ol.startTextLink(getMemberListFileName(),0); ol.parseText(theTranslator->trListOfAllMembers()); ol.endTextLink(); @@ -1345,11 +1335,11 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.endTextBlock(); // write detailed description if the user wants it near the top - if (Config_getBool("DETAILS_AT_TOP")) { + if (Config_getBool("DETAILS_AT_TOP")) + { writeDetailedDescription(ol,pageType,exampleFlag); } - /////////////////////////////////////////////////////////////////////////// //// Member declarations + brief descriptions /////////////////////////////////////////////////////////////////////////// @@ -1866,6 +1856,19 @@ void ClassDef::setTemplateArguments(ArgumentList *al) } } +void ClassDef::setTypeConstraints(ArgumentList *al) +{ + if (al==0) return; + if (!m_impl->typeConstraints) delete m_impl->typeConstraints; + m_impl->typeConstraints = new ArgumentList; + ArgumentListIterator ali(*al); + Argument *a; + for (;(a=ali.current());++ali) + { + m_impl->typeConstraints->append(new Argument(*a)); + } +} + /*! Returns \c TRUE iff this class or a class inheriting from this class * is \e not defined in an external tag file. */ diff --git a/src/classdef.h b/src/classdef.h index b03ae52..1cfccc2 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -294,6 +294,7 @@ class ClassDef : public Definition void setTemplateArguments(ArgumentList *al); void setTemplateBaseClassNames(QDict<int> *templateNames); void setTemplateMaster(ClassDef *tm); + void setTypeConstraints(ArgumentList *al); void addMembersToTemplateInstance(ClassDef *cd,const char *templSpec); void makeTemplateArgument(bool b=TRUE); void setCategoryOf(ClassDef *cd); diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp index c4469c7..e6f74f0 100644 --- a/src/cmdmapper.cpp +++ b/src/cmdmapper.cpp @@ -26,6 +26,7 @@ CommandMap cmdMap[] = { "arg", CMD_LI }, { "attention", CMD_ATTENTION }, { "author", CMD_AUTHOR }, + { "authors", CMD_AUTHORS }, { "b", CMD_BOLD }, { "c", CMD_CODE }, { "code", CMD_STARTCODE }, @@ -89,8 +90,6 @@ CommandMap cmdMap[] = { "verbinclude", CMD_VERBINCLUDE }, { "version", CMD_VERSION }, { "warning", CMD_WARNING }, - { "author", CMD_AUTHOR }, - { "authors", CMD_AUTHORS }, { "throws", CMD_EXCEPTION }, { "\\", CMD_BSLASH }, { "@", CMD_AT }, diff --git a/src/commentcnv.l b/src/commentcnv.l index b12d9d8..465c951 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -168,6 +168,7 @@ static void endCondSection() } } +#if 0 /** remove and executes cond and endcond commands in \a s */ static QCString handleCondCmdInAliases(const QCString &s) { @@ -223,6 +224,7 @@ static QCString handleCondCmdInAliases(const QCString &s) result+=s.right(s.length()-p); return result; } +#endif /** copies string \a s with length \a len to the output, while * replacing any alias commands found in the string. diff --git a/src/commentscan.l b/src/commentscan.l index 553b93a..9a7f698 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -198,6 +198,7 @@ static DocCmdMap docCmdMap[] = { "arg", 0, TRUE }, { "attention", 0, TRUE }, { "author", 0, TRUE }, + { "authors", 0, TRUE }, { "date", 0, TRUE }, { "dotfile", 0, TRUE }, { "htmlinclude", 0, TRUE }, @@ -212,7 +213,9 @@ static DocCmdMap docCmdMap[] = { "param", 0, TRUE }, { "post", 0, TRUE }, { "pre", 0, TRUE }, + { "remark", 0, TRUE }, { "remarks", 0, TRUE }, + { "result", 0, TRUE }, { "return", 0, TRUE }, { "returns", 0, TRUE }, { "retval", 0, TRUE }, @@ -220,6 +223,7 @@ static DocCmdMap docCmdMap[] = { "see", 0, TRUE }, { "since", 0, TRUE }, { "throw", 0, TRUE }, + { "throws", 0, TRUE }, { "until", 0, TRUE }, { "verbinclude", 0, TRUE }, { "version", 0, TRUE }, diff --git a/src/config.l b/src/config.l index e3faf84..cb73dfb 100644 --- a/src/config.l +++ b/src/config.l @@ -2222,6 +2222,16 @@ void Config::create() FALSE ); cb->addDependency("GENERATE_HTML"); + cb = addBool( + "HTML_DYNAMIC_SECTIONS", + "If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML \n" + "documentation will contain sections that can be hidden and shown after the \n" + "page has loaded. For this to work a browser that supports \n" + "JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox \n" + "Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). \n", + FALSE + ); + cb->addDependency("GENERATE_HTML"); cs = addString( "CHM_FILE", "If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \n" diff --git a/src/definition.cpp b/src/definition.cpp index bfcfbad..668e566 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -551,7 +551,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *) QCString lineStr,anchorStr; lineStr.sprintf("%d",m_impl->body->startLine); anchorStr.sprintf(Htags::useHtags ? "L%d" : "l%05d",m_impl->body->startLine); - ol.newParagraph(); + ol.startParagraph(); if (lineMarkerPos<fileMarkerPos) // line marker before file marker { // write text left from linePos marker @@ -616,6 +616,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *) ol.parseText(refText.right( refText.length()-lineMarkerPos-2)); } + ol.endParagraph(); } else { @@ -691,7 +692,7 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, ol.pushGeneratorState(); if (Config_getBool("SOURCE_BROWSER") && members) { - ol.newParagraph(); + ol.startParagraph(); ol.parseText(text); ol.docify(" "); @@ -772,6 +773,7 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, } ol.parseText(ldefLine.right(ldefLine.length()-index)); ol.writeString("."); + ol.endParagraph(); } ol.popGeneratorState(); } diff --git a/src/docparser.cpp b/src/docparser.cpp index 01d88ae..e9d16af 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -368,11 +368,15 @@ static void checkUndocumentedParams() } if (g_memberDef->inheritsDocsFrom()) { - warn_doc_error(g_memberDef->getDefFileName(),g_memberDef->getDefLine(),errMsg); + warn_doc_error(g_memberDef->getDefFileName(), + g_memberDef->getDefLine(), + substitute(errMsg,"%","%%")); } else { - warn_doc_error(g_memberDef->docFile(),g_memberDef->docLine(),errMsg); + warn_doc_error(g_memberDef->docFile(), + g_memberDef->docLine(), + substitute(errMsg,"%","%%")); } } } diff --git a/src/dot.cpp b/src/dot.cpp index 603fc38..412eeda 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -242,7 +242,7 @@ static bool readBoundingBoxEPS(const char *fileName,int *width,int *height) { int numBytes = f.readLine(buf,maxLineLen-1); // read line buf[numBytes]='\0'; - if (strncmp(buf,bb.data(),bb.length()-1)==0) // found PageBoundBox string + if (strncmp(buf,bb.data(),bb.length()-1)==0) // found PageBoundingBox string { int x,y; if (sscanf(buf+bb.length(),"%d %d %d %d",&x,&y,width,height)!=4) @@ -543,7 +543,6 @@ static QCString escapeTooltip(const QCString &tooltip) switch(c) { case '\\': result+="\\\\"; break; - case '"': result+="\\\""; break; default: result+=c; break; } } @@ -1398,44 +1397,98 @@ void DotClassGraph::determineTruncatedNodes(QList<DotNode> &queue,bool includePa } } -void DotClassGraph::determineVisibleNodes(QList<DotNode> &queue, - int &maxNodes,bool includeParents) +bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, + int maxNodes,bool includeParents) { - while (queue.count()>0 && maxNodes>0) + QList<DotNode> childQueue; + QList<DotNode> parentQueue; + QArray<int> childTreeWidth; + QArray<int> parentTreeWidth; + childQueue.append(rootNode); + if (includeParents) parentQueue.append(rootNode); + bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop + // despite being marked visible in the child loop + while ((childQueue.count()>0 || parentQueue.count()>0) && maxNodes>0) { static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH"); - DotNode *n = queue.take(0); - //printf("*** Processing node %p queue=%d maxNodes=%d m_children=%p " - // "m_parents=%p distance=%d maxDistance=%d\n", - // n,queue.count(),maxNodes,n->m_children,n->m_parents,n->distance(), - // maxDistance); - if (!n->isVisible() && n->distance()<maxDistance) // not yet processed + if (childQueue.count()>0) { - //printf(" Marked as visible!\n"); - n->markAsVisible(); - maxNodes--; - // add direct children - if (n->m_children) + DotNode *n = childQueue.take(0); + int distance = n->distance(); + if (!n->isVisible() && distance<maxDistance) // not yet processed { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) + if (distance>0) { - queue.append(dn); + int oldSize=(int)childTreeWidth.size(); + if (distance>oldSize) + { + childTreeWidth.resize(QMAX(childTreeWidth.size(),(uint)distance)); + int i; for (i=oldSize;i<distance;i++) childTreeWidth[i]=0; + } + childTreeWidth[distance-1]+=n->label().length(); + } + n->markAsVisible(); + maxNodes--; + // add direct children + if (n->m_children) + { + QListIterator<DotNode> li(*n->m_children); + DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + childQueue.append(dn); + } } } - // add direct parents - if (n->m_parents && includeParents) + } + if (includeParents && parentQueue.count()>0) + { + DotNode *n = parentQueue.take(0); + if ((!n->isVisible() || firstNode) && n->distance()<maxDistance) // not yet processed { - QListIterator<DotNode> li(*n->m_parents); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) + firstNode=FALSE; + int distance = n->distance(); + if (distance>0) { - queue.append(dn); + int oldSize = (int)parentTreeWidth.size(); + if (distance>oldSize) + { + parentTreeWidth.resize(QMAX(parentTreeWidth.size(),(uint)distance)); + int i; for (i=oldSize;i<distance;i++) parentTreeWidth[i]=0; + } + parentTreeWidth[distance-1]+=n->label().length(); + } + n->markAsVisible(); + maxNodes--; + // add direct parents + if (n->m_parents) + { + QListIterator<DotNode> li(*n->m_parents); + DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + parentQueue.append(dn); + } } } } } + int maxWidth=0; + int maxHeight=(int)QMAX(childTreeWidth.size(),parentTreeWidth.size()); + uint i; + for (i=0;i<childTreeWidth.size();i++) + { + if (childTreeWidth[i]>maxWidth) maxWidth=childTreeWidth[i]; + } + for (i=0;i<parentTreeWidth.size();i++) + { + if (parentTreeWidth[i]>maxWidth) maxWidth=parentTreeWidth[i]; + } + //printf("max tree width=%d, max tree height=%d\n",maxWidth,maxHeight); + return maxWidth>80 && maxHeight<12; // used metric to decide to render the tree + // from left to right instead of top to bottom, + // with the idea to render very wide trees in + // left to right order. } void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base,int distance) @@ -1564,19 +1617,17 @@ DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t) if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE,1); //} - static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES"); - int maxNodes = nodes; + static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES"); //int directChildNodes = 1; //if (m_startNode->m_children!=0) // directChildNodes+=m_startNode->m_children->count(); //if (t==DotNode::Inheritance && m_startNode->m_parents!=0) // directChildNodes+=m_startNode->m_parents->count(); //if (directChildNodes>maxNodes) maxNodes=directChildNodes; + //openNodeQueue.append(m_startNode); + m_lrRank = determineVisibleNodes(m_startNode,maxNodes,t==DotNode::Inheritance); QList<DotNode> openNodeQueue; openNodeQueue.append(m_startNode); - determineVisibleNodes(openNodeQueue,maxNodes,t==DotNode::Inheritance); - openNodeQueue.clear(); - openNodeQueue.append(m_startNode); determineTruncatedNodes(openNodeQueue,t==DotNode::Inheritance); m_diskName = cd->getFileBase().copy(); @@ -1733,7 +1784,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out, GraphOutputFormat format, const char *path, const char *relPath, - bool isTBRank, + bool /*isTBRank*/, bool generateImageMap) { QDir d(path); @@ -1772,7 +1823,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out, m_graphType, baseName, format, - !isTBRank, + m_lrRank, //!isTBRank, m_graphType==DotNode::Inheritance, TRUE ) @@ -1853,20 +1904,33 @@ QCString DotClassGraph::writeGraph(QTextStream &out, } else if (format==EPS) // produce tex to include the .eps image { - int width,height; + int width=420,height=600; if (!readBoundingBoxEPS(baseName+".eps",&width,&height)) { err("Error: Could not extract bounding box from .eps!\n"); QDir::setCurrent(oldDir); return baseName; } - int maxWidth = 420; /* approx. page width in points */ + //printf("Got EPS size %d,%d\n",width,height); + int maxWidth = 400; /* approx. page width in points, excl. margins */ + int maxHeight = 400; /* approx. page height in points, excl. margins */ out << "\\nopagebreak\n" "\\begin{figure}[H]\n" "\\begin{center}\n" - "\\leavevmode\n" - "\\includegraphics[width=" << QMIN(width/2,maxWidth) - << "pt]{" << baseName << "}\n" + "\\leavevmode\n"; + if (width>maxWidth) + { + out << "\\includegraphics[width=" << maxWidth << "pt]"; + } + else if (height>maxHeight) + { + out << "\\includegraphics[height=" << maxHeight << "pt]"; + } + else + { + out << "\\includegraphics[width=" << width/2 << "pt]"; + } + out << "{" << baseName << "}\n" "\\end{center}\n" "\\end{figure}\n"; } @@ -2204,7 +2268,7 @@ void DotInclDepGraph::writeXML(QTextStream &t) int DotCallGraph::m_curNodeNumber = 0; -void DotCallGraph::buildGraph(DotNode *n,MemberDef *md) +void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance) { LockingPtr<MemberSDict> refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); if (!refs.isNull()) @@ -2223,6 +2287,7 @@ void DotCallGraph::buildGraph(DotNode *n,MemberDef *md) { n->addChild(bn,0,0,0); bn->addParent(n); + bn->setDistance(distance); } else { @@ -2246,9 +2311,10 @@ void DotCallGraph::buildGraph(DotNode *n,MemberDef *md) ); n->addChild(bn,0,0,0); bn->addParent(n); + bn->setDistance(distance); m_usedNodes->insert(uniqueId,bn); - buildGraph(bn,rmd); + buildGraph(bn,rmd,distance+1); } } } @@ -2259,8 +2325,9 @@ void DotCallGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes) { while (queue.count()>0 && maxNodes>0) { + static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH"); DotNode *n = queue.take(0); - if (!n->isVisible()) // not yet processed + if (!n->isVisible() && n->distance()<maxDistance) // not yet processed { n->markAsVisible(); maxNodes--; @@ -2329,9 +2396,10 @@ DotCallGraph::DotCallGraph(MemberDef *md,bool inverse) uniqueId.data(), TRUE // root node ); + m_startNode->setDistance(0); m_usedNodes = new QDict<DotNode>(1009); m_usedNodes->insert(uniqueId,m_startNode); - buildGraph(m_startNode,md); + buildGraph(m_startNode,md,1); static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES"); int maxNodes = nodes; @@ -168,7 +168,7 @@ class DotClassGraph private: void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance); - void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes,bool includeParents); + bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents); void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents); void addClass(ClassDef *cd,DotNode *n,int prot,const char *label, const char *usedName,const char *templSpec, @@ -179,6 +179,7 @@ class DotClassGraph static int m_curNodeNumber; DotNode::GraphType m_graphType; QCString m_diskName; + bool m_lrRank; }; /** @brief Representation of an include dependency graph */ @@ -216,7 +217,7 @@ class DotCallGraph ~DotCallGraph(); QCString writeGraph(QTextStream &t, GraphOutputFormat f, const char *path,const char *relPath,bool writeImageMap=TRUE); - void buildGraph(DotNode *n,MemberDef *md); + void buildGraph(DotNode *n,MemberDef *md,int distance); bool isTrivial() const; bool isTooBig() const; void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 3042aa0..54ace8a 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -1164,6 +1164,7 @@ static void addClassToContext(EntryNav *rootNav) cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); cd->setIsObjectiveC(root->objc); cd->setHidden(root->hidden); + cd->setTypeConstraints(root->typeConstr); //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data()); ArgumentList *tArgList = @@ -1357,6 +1358,8 @@ static void buildNamespaceList(EntryNav *rootNav) rootNav->loadEntry(g_storage); Entry *root = rootNav->entry(); + //printf("** buildNamespaceList(%s)\n",root->name.data()); + QCString fullName = root->name; if (root->section==Entry::PACKAGEDOC_SEC) { @@ -1422,6 +1425,7 @@ static void buildNamespaceList(EntryNav *rootNav) nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->addSectionsToDefinition(root->anchors); + nd->setHidden(root->hidden); //printf("Adding namespace to group\n"); addNamespaceToGroups(root,nd); @@ -2577,6 +2581,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, const QCString &rname,bool isFriend) { Entry *root = rootNav->entry(); + FileDef *fd=rootNav->fileDef(); int l,i; static QRegExp re("([a-z_A-Z0-9: ]*[ *]*[ ]*"); @@ -2598,7 +2603,8 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, else mtype=MemberDef::Function; // strip redundant template specifier for constructors - if ((i=name.find('<'))!=-1 && name.find('>')!=-1) + if ((fd==0 || getLanguageFromFileName(fd->name())==SrcLangExt_Cpp) && + (i=name.find('<')!=-1) && name.find('>')!=-1) { name=name.left(i); } @@ -2622,7 +2628,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, md->setBodySegment(root->bodyLine,root->endBodyLine); md->setMemberSpecifiers(root->spec); md->setMemberGroupId(root->mGrpId); - FileDef *fd=rootNav->fileDef(); + md->setTypeConstraints(root->typeConstr); md->setBodyDef(fd); md->setFileDef(fd); //md->setScopeTemplateArguments(root->tArgList); @@ -2964,6 +2970,7 @@ static void buildFunctionList(EntryNav *rootNav) md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setPrototype(root->proto); md->setDocsForDefinition(!root->proto); + md->setTypeConstraints(root->typeConstr); //md->setBody(root->body); md->setBodySegment(root->bodyLine,root->endBodyLine); FileDef *fd=rootNav->fileDef(); @@ -5539,6 +5546,7 @@ static void findMember(EntryNav *rootNav, md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); md->setTemplateSpecialization(TRUE); + md->setTypeConstraints(root->typeConstr); md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); @@ -5599,6 +5607,7 @@ static void findMember(EntryNav *rootNav, root->protection,root->virt,root->stat,TRUE, mtype,tArgList,root->argList); md->setTagInfo(rootNav->tagInfo()); + md->setTypeConstraints(root->typeConstr); md->setMemberClass(cd); md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); @@ -9288,7 +9297,7 @@ void parseInput() cleanUpDoxygen(); exit(1); } - + QCString &xmlOutput = Config_getString("XML_OUTPUT"); bool &generateXml = Config_getBool("GENERATE_XML"); if (xmlOutput.isEmpty() && generateXml) @@ -9709,6 +9718,21 @@ void parseInput() msg("Computing dependencies between directories...\n"); computeDirDependencies(); } + + msg("Counting data structures...\n"); + countDataStructures(); + + msg("Resolving user defined references...\n"); + resolveUserReferences(); + + msg("Finding anchors and sections in the documentation...\n"); + findSectionsInDocumentation(); + + transferFunctionReferences(); + + msg("Combining using relations...\n"); + combineUsingRelations(); + } void generateOutput() @@ -9734,31 +9758,6 @@ void generateOutput() initDocParser(); - //{ - // QCString fileName = Config_getString("HTML_OUTPUT")+"/filetree.html"; - // QFile f(fileName); - // if (f.open(IO_WriteOnly)) - // { - // QTextStream t(&f); - // t << "<html>\n"; - // t << " <head>\n"; - // t << " <style type=\"text/css\">\n"; - // t << " <!--\n"; - // t << " .directory { font-size: 10pt; font-weight: bold; }\n"; - // t << " .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }\n"; - // t << " .directory p { margin: 0px; white-space: nowrap; }\n"; - // t << " .directory div { display: visible; margin: 0px; }\n"; - // t << " .directory img { vertical-align: middle; }\n"; - // t << " -->\n"; - // t << " </style>\n"; - // t << " </head>\n"; - // t << " <body>\n"; - // generateFileTree(t); - // t << " </body>\n"; - // t << "</html>\n"; - // } - //} - outputList = new OutputList(TRUE); if (Config_getBool("GENERATE_HTML")) { @@ -9766,6 +9765,7 @@ void generateOutput() HtmlGenerator::init(); if (Config_getBool("GENERATE_HTMLHELP")) HtmlHelp::getInstance()->initialize(); if (Config_getBool("GENERATE_TREEVIEW")) FTVHelp::getInstance()->initialize(); + if (Config_getBool("HTML_DYNAMIC_SECTIONS")) HtmlGenerator::generateSectionImages(); copyStyleSheet(); } if (Config_getBool("GENERATE_LATEX")) @@ -9842,18 +9842,6 @@ void generateOutput() // count the number of documented elements in the lists we have built. // If the result is 0 we do not generate the lists and omit the // corresponding links in the index. - msg("Counting data structures...\n"); - countDataStructures(); - - msg("Resolving user defined references...\n"); - resolveUserReferences(); - - msg("Combining using relations...\n"); - combineUsingRelations(); - - msg("Finding anchors and sections in the documentation...\n"); - findSectionsInDocumentation(); - msg("Generating index page...\n"); writeIndex(*outputList); @@ -9865,7 +9853,6 @@ void generateOutput() { generateFileSources(); } - transferFunctionReferences(); msg("Generating file documentation...\n"); generateFileDocs(); @@ -9958,6 +9945,7 @@ void generateOutput() if (Config_getBool("GENERATE_HTML") && Config_getBool("DOT_CLEANUP")) removeDoxFont(Config_getString("HTML_OUTPUT")); if (Config_getBool("GENERATE_RTF") && Config_getBool("DOT_CLEANUP")) removeDoxFont(Config_getString("RTF_OUTPUT")); + if (Config_getBool("GENERATE_XML")) { msg("Generating XML output...\n"); diff --git a/src/entry.cpp b/src/entry.cpp index 77830c0..edb54c1 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -27,122 +27,6 @@ #define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!' -#if 0 -static bool saveEntry(Entry *e,StorageIntf *f) -{ - marshalUInt(f,HEADER); - marshalInt(f,(int)e->protection); - marshalInt(f,(int)e->mtype); - marshalInt(f,e->spec); - marshalInt(f,e->initLines); - marshalBool(f,e->stat); - marshalBool(f,e->explicitExternal); - marshalBool(f,e->proto); - marshalBool(f,e->subGrouping); - marshalBool(f,e->callGraph); - marshalBool(f,e->callerGraph); - marshalInt(f,(int)e->virt); - marshalQCString(f,e->args); - marshalQCString(f,e->bitfields); - marshalArgumentList(f,e->argList); - marshalArgumentLists(f,e->tArgLists); - marshalQGString(f,e->program); - marshalQGString(f,e->initializer); - marshalQCString(f,e->includeFile); - marshalQCString(f,e->includeName); - marshalQCString(f,e->doc); - marshalInt(f,e->docLine); - marshalQCString(f,e->docFile); - marshalQCString(f,e->brief); - marshalInt(f,e->briefLine); - marshalQCString(f,e->briefFile); - marshalQCString(f,e->inbodyDocs); - marshalInt(f,e->inbodyLine); - marshalQCString(f,e->inbodyFile); - marshalQCString(f,e->relates); - marshalBool(f,e->relatesDup); - marshalQCString(f,e->read); - marshalQCString(f,e->write); - marshalQCString(f,e->inside); - marshalQCString(f,e->exception); - marshalInt(f,e->bodyLine); - marshalInt(f,e->endBodyLine); - marshalInt(f,e->mGrpId); - marshalBaseInfoList(f,e->extends); - marshalGroupingList(f,e->groups); - marshalSectionInfoList(f,e->anchors); - marshalQCString(f,e->fileName); - marshalInt(f,e->startLine); - marshalItemInfoList(f,e->sli); - marshalBool(f,e->objc); - marshalBool(f,e->hidden); - marshalInt(f,(int)e->groupDocType); - return TRUE; -} - -static bool loadEntry(Entry *e,StorageIntf *f) -{ - uint header=unmarshalUInt(f); - if (header!=HEADER) - { - printf("Internal error: Invalid header %x for entry in storage file %s\n", - header,Doxygen::entryDBFileName.data()); - exit(1); - } - e->protection = (Protection)unmarshalInt(f); - e->mtype = (MethodTypes)unmarshalInt(f); - e->spec = unmarshalInt(f); - e->initLines = unmarshalInt(f); - e->stat = unmarshalBool(f); - e->explicitExternal = unmarshalBool(f); - e->proto = unmarshalBool(f); - e->subGrouping = unmarshalBool(f); - e->callGraph = unmarshalBool(f); - e->callerGraph = unmarshalBool(f); - e->virt = (Specifier)unmarshalInt(f); - e->args = unmarshalQCString(f); - e->bitfields = unmarshalQCString(f); - delete e->argList; - e->argList = unmarshalArgumentList(f); - e->tArgLists = unmarshalArgumentLists(f); - e->program = unmarshalQGString(f); - e->initializer = unmarshalQGString(f); - e->includeFile = unmarshalQCString(f); - e->includeName = unmarshalQCString(f); - e->doc = unmarshalQCString(f); - e->docLine = unmarshalInt(f); - e->docFile = unmarshalQCString(f); - e->brief = unmarshalQCString(f); - e->briefLine = unmarshalInt(f); - e->briefFile = unmarshalQCString(f); - e->inbodyDocs = unmarshalQCString(f); - e->inbodyLine = unmarshalInt(f); - e->inbodyFile = unmarshalQCString(f); - e->relates = unmarshalQCString(f); - e->relatesDup = unmarshalBool(f); - e->read = unmarshalQCString(f); - e->write = unmarshalQCString(f); - e->inside = unmarshalQCString(f); - e->exception = unmarshalQCString(f); - e->bodyLine = unmarshalInt(f); - e->endBodyLine = unmarshalInt(f); - e->mGrpId = unmarshalInt(f); - delete e->extends; - e->extends = unmarshalBaseInfoList(f); - delete e->groups; - e->groups = unmarshalGroupingList(f); - delete e->anchors; - e->anchors = unmarshalSectionInfoList(f); - e->fileName = unmarshalQCString(f); - e->startLine = unmarshalInt(f); - e->sli = unmarshalItemInfoList(f); - e->objc = unmarshalBool(f); - e->hidden = unmarshalBool(f); - e->groupDocType = (Entry::GroupDocType)unmarshalInt(f); - return TRUE; -} -#endif - //------------------------------------------------------------------ /*! the argument list is documented if one of its @@ -181,6 +65,7 @@ Entry::Entry() argList->setAutoDelete(TRUE); //printf("Entry::Entry() tArgList=0\n"); tArgLists = 0; + typeConstr = 0; mGrpId = -1; tagInfo = 0; sli = 0; @@ -245,6 +130,8 @@ Entry::Entry(const Entry &e) anchors = new QList<SectionInfo>; argList = new ArgumentList; argList->setAutoDelete(TRUE); + typeConstr = new ArgumentList; + typeConstr->setAutoDelete(TRUE); tArgLists = 0; groupDocType = e.groupDocType; @@ -290,6 +177,16 @@ Entry::Entry(const Entry &e) argList->volatileSpecifier = e.argList->volatileSpecifier; argList->pureSpecifier = e.argList->pureSpecifier; + // deep copy type contraint list + if (e.typeConstr) + { + QListIterator<Argument> tcli(*e.typeConstr); + for (;(a=tcli.current());++tcli) + { + typeConstr->append(new Argument(*a)); + } + } + // deep copy template argument lists if (e.tArgLists) { @@ -391,9 +288,10 @@ void Entry::reset() groups->clear(); anchors->clear(); argList->clear(); - if (tagInfo) { delete tagInfo; tagInfo=0; } - if (tArgLists) { delete tArgLists; tArgLists=0; } - if (sli) { delete sli; sli=0; } + if (tagInfo) { delete tagInfo; tagInfo=0; } + if (tArgLists) { delete tArgLists; tArgLists=0; } + if (sli) { delete sli; sli=0; } + if (typeConstr) { delete typeConstr; typeConstr=0; } //if (mtArgList) { delete mtArgList; mtArgList=0; } } diff --git a/src/entry.h b/src/entry.h index ede809c..1a51944 100644 --- a/src/entry.h +++ b/src/entry.h @@ -349,6 +349,7 @@ class Entry QCString write; //!< property write accessor QCString inside; //!< name of the class in which documents are found QCString exception; //!< throw specification + ArgumentList *typeConstr; //!< where clause (C#) for type constraints int bodyLine; //!< line number of the definition in the source int endBodyLine; //!< line number where the definition ends int mGrpId; //!< member group id diff --git a/src/filedef.cpp b/src/filedef.cpp index 45b7ea6..3588a45 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -168,6 +168,7 @@ void FileDef::writeDetailedDocumentation(OutputList &ol) ol.startGroupHeader(); ol.parseText(theTranslator->trDetailedDescription()); ol.endGroupHeader(); + ol.startTextBlock(); if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) { ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE); @@ -192,7 +193,7 @@ void FileDef::writeDetailedDocumentation(OutputList &ol) //printf("Writing source ref for file %s\n",name().data()); if (Config_getBool("SOURCE_BROWSER")) { - ol.newParagraph(); + ol.startParagraph(); QCString refText = theTranslator->trDefinedInSourceFile(); int fileMarkerPos = refText.find("@0"); if (fileMarkerPos!=-1) // should always pass this. @@ -203,7 +204,9 @@ void FileDef::writeDetailedDocumentation(OutputList &ol) ol.parseText(refText.right( refText.length()-fileMarkerPos-2)); // text right from marker 2 } + ol.endParagraph(); } + ol.endTextBlock(); } } diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index d923186..5442ed7 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -46,7 +46,7 @@ static const char defaultStyleSheet[] = #include "doxygen_css.h" ; -const char search_script[]= +static const char search_script[]= #include "search_php.h" ; @@ -488,7 +488,29 @@ static void writeTabData(const char *dir) } } -//----------------------------------------------------------------------- +//------------------------------------------------------------------------ + +unsigned char open_gif[] = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x09, 0x00, 0x09, 0x00, 0xf0, 0x00, + 0x00, 0x8e, 0xaf, 0xc4, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, + 0x00, 0x02, 0x0d, 0x8c, 0x8f, 0xa9, 0xcb, 0xe0, 0xff, 0x02, 0x8c, 0x66, + 0x26, 0x7a, 0x51, 0x01, 0x00, 0x3b +}; +unsigned int open_gif_len = 54; + +unsigned char closed_gif[] = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x09, 0x00, 0x09, 0x00, 0xf0, 0x00, + 0x00, 0x8e, 0xaf, 0xc4, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, + 0x00, 0x02, 0x10, 0x8c, 0x03, 0xa7, 0x98, 0xcb, 0xad, 0x80, 0x84, 0x66, + 0xca, 0x38, 0x57, 0xd6, 0xf4, 0xd0, 0x02, 0x00, 0x3b +}; +unsigned int closed_gif_len = 57; + + + +//------------------------- Pictures for the Tabs ------------------------ HtmlGenerator::HtmlGenerator() : OutputGenerator() { @@ -598,6 +620,54 @@ void HtmlGenerator::writeFooterFile(QFile &file) << "</html>\n"; } +static void generateDynamicSections(QTextStream &t,const QCString &relPath) +{ + if (Config_getBool("HTML_DYNAMIC_SECTIONS")) + { + t << + "<script type=\"text/javascript\">\n" + "<!--\n" + "function changeDisplayState (e){\n" + " var num=this.id.replace(/[^[0-9]/g,'');\n" + " var button=this.firstChild;\n" + " var sectionDiv=document.getElementById('dynsection'+num);\n" + " if (sectionDiv.style.display=='none'||sectionDiv.style.display==''){\n" + " sectionDiv.style.display='block';\n" + " button.src='" << relPath << "open.gif';\n" + " }else{\n" + " sectionDiv.style.display='none';\n" + " button.src='" << relPath << "closed.gif';\n" + " }\n" + "}\n" + "function initDynSections(){\n" + " var divs=document.getElementsByTagName('div');\n" + " var sectionCounter=1;\n" + " for(var i=0;i<divs.length-1;i++){\n" + " if(divs[i].className=='dynheader'&&divs[i+1].className=='dynsection'){\n" + " var header=divs[i];\n" + " var section=divs[i+1];\n" + " var button=header.firstChild;\n" + " if (button!='IMG'){\n" + " divs[i].insertBefore(document.createTextNode(' '),divs[i].firstChild);\n" + " button=document.createElement('img');\n" + " divs[i].insertBefore(button,divs[i].firstChild);\n" + " }\n" + " header.style.cursor='pointer';\n" + " header.onclick=changeDisplayState;\n" + " header.id='dynheader'+sectionCounter;\n" + " button.src='" << relPath << "closed.gif';\n" + " section.id='dynsection'+sectionCounter;\n" + " section.style.display='none';\n" + " sectionCounter++;\n" + " }\n" + " }\n" + "}\n" + "window.onload = initDynSections;\n" + "-->\n" + "</script>\n"; + } +} + void HtmlGenerator::startFile(const char *name,const char *, const char *title) @@ -635,9 +705,9 @@ void HtmlGenerator::startFile(const char *name,const char *, } t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " << versionString << " -->" << endl; + generateDynamicSections(t,relPath); } - static void writePageFooter(QTextStream &t,const QCString &lastTitle, const QCString relPath) { @@ -751,6 +821,16 @@ void HtmlGenerator::newParagraph() t << endl << "<p>" << endl; } +void HtmlGenerator::startParagraph() +{ + t << endl << "<p>"; +} + +void HtmlGenerator::endParagraph() +{ + t << "</p>" << endl; +} + void HtmlGenerator::writeString(const char *text) { t << text; @@ -1033,18 +1113,22 @@ void HtmlGenerator::writeChar(char c) void HtmlGenerator::startClassDiagram() { - t << "<p>"; + //t << "<p>"; + t << "<div class=\"dynheader\">" << endl; } void HtmlGenerator::endClassDiagram(ClassDiagram &d, const char *fileName,const char *name) { + t << "</div>" << endl; + t << "<div class=\"dynsection\">" << endl; t << "\n<p><center><img src=\"" << relPath << fileName << ".png\" usemap=\"#" << name << "_map\"" << " border=\"0\" alt=\"\"></center>" << endl << "<map name=\"" << name << "_map\">" << endl; d.writeImage(t,dir,relPath,fileName); + t << "</div>" << endl; } @@ -1402,49 +1486,75 @@ void HtmlGenerator::endMemberDoc(bool hasArgs) void HtmlGenerator::startDotGraph() { + t << "<div class=\"dynheader\">" << endl; } void HtmlGenerator::endDotGraph(DotClassGraph &g) { + t << "</div>" << endl; + t << "<div class=\"dynsection\">" << endl; g.writeGraph(t,BITMAP,dir,relPath); + if (Config_getBool("GENERATE_LEGEND")) + { + t << "<center><font size=\"2\">["; + startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension); + t << theTranslator->trLegend(); + endHtmlLink(); + t << "]</font></center>"; + } + t << "</div>" << endl; } void HtmlGenerator::startInclDepGraph() { + t << "<div class=\"dynheader\">" << endl; } void HtmlGenerator::endInclDepGraph(DotInclDepGraph &g) { + t << "</div>" << endl; + t << "<div class=\"dynsection\">" << endl; g.writeGraph(t,BITMAP,dir,relPath); + t << "</div>" << endl; } - void HtmlGenerator::startGroupCollaboration() { + t << "<div class=\"dynheader\">" << endl; } void HtmlGenerator::endGroupCollaboration(DotGroupCollaboration &g) { + t << "</div>" << endl; + t << "<div class=\"dynsection\">" << endl; g.writeGraph(t,BITMAP,dir,relPath); + t << "</div>" << endl; } - void HtmlGenerator::startCallGraph() { + t << "<div class=\"dynheader\">" << endl; } void HtmlGenerator::endCallGraph(DotCallGraph &g) { + t << "</div>" << endl; + t << "<div class=\"dynsection\">" << endl; g.writeGraph(t,BITMAP,dir,relPath); + t << "</div>" << endl; } void HtmlGenerator::startDirDepGraph() { + t << "<div class=\"dynheader\">" << endl; } void HtmlGenerator::endDirDepGraph(DotDirDeps &g) { + t << "</div>" << endl; + t << "<div class=\"dynsection\">" << endl; g.writeGraph(t,BITMAP,dir,relPath); + t << "</div>" << endl; } void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g) @@ -1966,3 +2076,68 @@ void HtmlGenerator::writeSearchPage() } } +void HtmlGenerator::generateSectionImages() +{ + { + QCString fileName = Config_getString("HTML_OUTPUT")+"/open.gif"; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + { + f.writeBlock((char*)open_gif,open_gif_len); + } + } + { + QCString fileName = Config_getString("HTML_OUTPUT")+"/closed.gif"; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + { + f.writeBlock((char*)closed_gif,closed_gif_len); + } + } +} + +void HtmlGenerator::startConstraintList(const char *header) +{ + t << "<div class=\"typeconstraint\">" << endl; + t << "<dl compact><dt><b>" << header << "</b><dt><dd>" << endl; + t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl; +} + +void HtmlGenerator::startConstraintParam() +{ + t << "<tr><td valign=\"top\"><em>"; +} + +void HtmlGenerator::endConstraintParam() +{ + t << "</em></td>"; +} + +void HtmlGenerator::startConstraintType() +{ + t << "<td> :</td><td valign=\"top\"><em>"; +} + +void HtmlGenerator::endConstraintType() +{ + t << "</em></td>"; +} + +void HtmlGenerator::startConstraintDocs() +{ + t << "<td> "; +} + +void HtmlGenerator::endConstraintDocs() +{ + t << "</td></tr>" << endl; +} + +void HtmlGenerator::endConstraintList() +{ + t << "</table>" << endl; + t << "</dl>" << endl; + t << "</div>" << endl; +} + + diff --git a/src/htmlgen.h b/src/htmlgen.h index 8ca87d0..5c318be 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -63,6 +63,8 @@ class HtmlGenerator : public OutputGenerator void endTitle() { t << "</h1>"; } void newParagraph(); + void startParagraph(); + void endParagraph(); void writeString(const char *text); void startIndexList(); void endIndexList(); @@ -219,6 +221,15 @@ class HtmlGenerator : public OutputGenerator void startParameterList(bool); void endParameterList(); + void startConstraintList(const char *); + void startConstraintParam(); + void endConstraintParam(); + void startConstraintType(); + void endConstraintType(); + void startConstraintDocs(); + void endConstraintDocs(); + void endConstraintList(); + void startFontClass(const char *s) { t << "<span class=\"" << s << "\">"; } void endFontClass() { t << "</span>"; } @@ -227,6 +238,7 @@ class HtmlGenerator : public OutputGenerator void linkableSymbol(int,const char *,Definition *,Definition *) {} static void writeSearchPage(); + static void generateSectionImages(); private: QCString lastTitle; diff --git a/src/latexgen.cpp b/src/latexgen.cpp index ab06be0..356c7b4 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -873,6 +873,15 @@ void LatexGenerator::newParagraph() t << endl << endl; } +void LatexGenerator::startParagraph() +{ + t << endl << endl; +} + +void LatexGenerator::endParagraph() +{ +} + void LatexGenerator::writeString(const char *text) { t << text; @@ -1598,3 +1607,46 @@ void LatexGenerator::printDoc(DocNode *n,const char *langExt) delete visitor; } +void LatexGenerator::startConstraintList(const char *header) +{ + t << "\\begin{Desc}\n\\item["; + docify(header); + t << "]"; + t << "\\begin{description}" << endl; +} + +void LatexGenerator::startConstraintParam() +{ + t << "\\item[{\\em "; +} + +void LatexGenerator::endConstraintParam() +{ +} + +void LatexGenerator::startConstraintType() +{ + t << "} : {\\em "; +} + +void LatexGenerator::endConstraintType() +{ + t << "}]"; +} + +void LatexGenerator::startConstraintDocs() +{ +} + +void LatexGenerator::endConstraintDocs() +{ +} + +void LatexGenerator::endConstraintList() +{ + t << "\\end{description}" << endl; + t << "\\end{Desc}" << endl; +} + + + diff --git a/src/latexgen.h b/src/latexgen.h index 214256f..c130d75 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -61,6 +61,8 @@ class LatexGenerator : public OutputGenerator void endTitle() { t << "}"; } void newParagraph(); + void startParagraph(); + void endParagraph(); void writeString(const char *text); void startIndexList() { t << "\\begin{CompactList}" << endl; } void endIndexList() { t << "\\end{CompactList}" << endl; } @@ -210,6 +212,15 @@ class LatexGenerator : public OutputGenerator void startParameterList(bool) {} void endParameterList() {} + void startConstraintList(const char *); + void startConstraintParam(); + void endConstraintParam(); + void startConstraintType(); + void endConstraintType(); + void startConstraintDocs(); + void endConstraintDocs(); + void endConstraintList(); + void startFontClass(const char *) {} void endFontClass() {} diff --git a/src/mangen.cpp b/src/mangen.cpp index f8bfb57..220dee2 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -179,6 +179,21 @@ void ManGenerator::newParagraph() paragraph=TRUE; } +void ManGenerator::startParagraph() +{ + if (!paragraph) + { + if (!firstCol) t << endl; + t << ".PP" << endl; + firstCol=TRUE; + } + paragraph=TRUE; +} + +void ManGenerator::endParagraph() +{ +} + void ManGenerator::writeString(const char *text) { docify(text); @@ -640,3 +655,54 @@ void ManGenerator::printDoc(DocNode *n,const char *langExt) paragraph = FALSE; } +void ManGenerator::startConstraintList(const char *header) +{ + if (!firstCol) + { t << endl << ".PP" << endl; + firstCol=TRUE; paragraph=TRUE; + col=0; + } + paragraph=FALSE; + startBold(); + docify(header); + endBold(); + paragraph=TRUE; +} + +void ManGenerator::startConstraintParam() +{ + writeListItem(); + startEmphasis(); +} + +void ManGenerator::endConstraintParam() +{ + endEmphasis(); + t << " : "; +} + +void ManGenerator::startConstraintType() +{ + startEmphasis(); +} + +void ManGenerator::endConstraintType() +{ + endEmphasis(); +} + +void ManGenerator::startConstraintDocs() +{ +} + +void ManGenerator::endConstraintDocs() +{ + t << endl; firstCol=TRUE; +} + +void ManGenerator::endConstraintList() +{ +} + + + diff --git a/src/mangen.h b/src/mangen.h index 38b566a..45ef306 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -60,6 +60,8 @@ class ManGenerator : public OutputGenerator void endTitle(); void newParagraph(); + void startParagraph(); + void endParagraph(); void writeString(const char *text); void startIndexList() {} void endIndexList() { newParagraph(); } @@ -268,6 +270,15 @@ class ManGenerator : public OutputGenerator //void startSectionRefList() {} //void endSectionRefList() {} + void startConstraintList(const char *); + void startConstraintParam(); + void endConstraintParam(); + void startConstraintType(); + void endConstraintType(); + void startConstraintDocs(); + void endConstraintDocs(); + void endConstraintList(); + void writeCodeAnchor(const char *) {} void linkableSymbol(int,const char *,Definition *,Definition *) {} diff --git a/src/marshal.cpp b/src/marshal.cpp index a08c20a..a11a25f 100644 --- a/src/marshal.cpp +++ b/src/marshal.cpp @@ -390,6 +390,7 @@ void marshalEntry(StorageIntf *s,Entry *e) marshalQCString(s,e->write); marshalQCString(s,e->inside); marshalQCString(s,e->exception); + marshalArgumentList(s,e->typeConstr); marshalInt(s,e->bodyLine); marshalInt(s,e->endBodyLine); marshalInt(s,e->mGrpId); @@ -774,6 +775,7 @@ Entry * unmarshalEntry(StorageIntf *s) e->write = unmarshalQCString(s); e->inside = unmarshalQCString(s); e->exception = unmarshalQCString(s); + e->typeConstr = unmarshalArgumentList(s); e->bodyLine = unmarshalInt(s); e->endBodyLine = unmarshalInt(s); e->mGrpId = unmarshalInt(s); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index dffbb82..bc8c76e 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -346,6 +346,7 @@ class MemberDefImpl ArgumentList *declArgList; // argument list of this member declaration ArgumentList *tArgList; // template argument list of function template + ArgumentList *typeConstraints; // type constraints for template parameters MemberDef *templateMaster; QList<ArgumentList> *defTmpArgLists; // lists of template argument lists // (for template functions in nested template classes) @@ -410,6 +411,7 @@ MemberDefImpl::MemberDefImpl() : defArgList(0), declArgList(0), tArgList(0), + typeConstraints(0), defTmpArgLists(0), classSectionSDict(0) { @@ -422,6 +424,7 @@ MemberDefImpl::~MemberDefImpl() delete enumFields; delete defArgList; delete tArgList; + delete typeConstraints; delete defTmpArgLists; delete classSectionSDict; delete declArgList; @@ -2014,10 +2017,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, // write class that contains a member that is reimplemented by this one if (bcd->isLinkable()) { - ol.disable(OutputGenerator::RTF); - ol.newParagraph(); - ol.enableAll(); - + ol.startParagraph(); QCString reimplFromLine; if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface) { @@ -2062,6 +2062,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, { err("Error: translation error: no marker in trReimplementsFromList()\n"); } + ol.endParagraph(); } //ol.writeString("."); @@ -2087,9 +2088,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, { mli.toFirst(); // write the list of classes that overwrite this member - ol.disable(OutputGenerator::RTF); - ol.newParagraph(); - ol.enable(OutputGenerator::RTF); + ol.startParagraph(); QCString reimplInLine; if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface)) @@ -2137,6 +2136,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, index=newIndex+matchLen; } ol.parseText(reimplInLine.right(reimplInLine.length()-index)); + ol.endParagraph(); } } @@ -2150,6 +2150,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.endSimpleSect(); } + if (m_impl->typeConstraints) + { + writeTypeConstraints(ol,this,m_impl->typeConstraints); + } + // write reference to the source writeSourceDef(ol,cname); writeSourceRefs(ol,cname); @@ -2635,7 +2640,8 @@ bool MemberDef::isDestructor() const } else // other languages { - return name().find('~')!=-1 && name().find("operator")==-1; + return (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI + && name().find("operator")==-1; } } @@ -2780,6 +2786,21 @@ void MemberDef::setDeclArgumentList(ArgumentList *al) m_impl->declArgList = al; } +void MemberDef::setTypeConstraints(ArgumentList *al) +{ + if (al==0) return; + makeResident(); + if (m_impl->typeConstraints) delete m_impl->typeConstraints; + m_impl->typeConstraints = new ArgumentList; + m_impl->typeConstraints->setAutoDelete(TRUE); + ArgumentListIterator ali(*al); + Argument *a; + for (;(a=ali.current());++ali) + { + m_impl->typeConstraints->append(new Argument(*a)); + } +} + void MemberDef::findSectionsInDocumentation() { makeResident(); @@ -3648,6 +3669,7 @@ void MemberDef::flushToDisk() const marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList); marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList); marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList); + marshalArgumentList (Doxygen::symbolStorage,m_impl->typeConstraints); marshalObjPointer (Doxygen::symbolStorage,m_impl->templateMaster); marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists); marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedAnonymousType); @@ -3746,6 +3768,7 @@ void MemberDef::loadFromDisk() const m_impl->defArgList = unmarshalArgumentList (Doxygen::symbolStorage); m_impl->declArgList = unmarshalArgumentList (Doxygen::symbolStorage); m_impl->tArgList = unmarshalArgumentList (Doxygen::symbolStorage); + m_impl->typeConstraints = unmarshalArgumentList (Doxygen::symbolStorage); m_impl->templateMaster = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); m_impl->defTmpArgLists = unmarshalArgumentLists(Doxygen::symbolStorage); m_impl->cachedAnonymousType = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage); diff --git a/src/memberdef.h b/src/memberdef.h index c396346..385b353 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -281,6 +281,7 @@ class MemberDef : public Definition void setArgumentList(ArgumentList *al); void setDeclArgumentList(ArgumentList *al); void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists); + void setTypeConstraints(ArgumentList *al); // namespace related members void setNamespace(NamespaceDef *nd); diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index fe69505..d021764 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -259,7 +259,7 @@ void NamespaceDef::writeDetailedDocumentation(OutputList &ol) if (!documentation().isEmpty()) { ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE); - ol.newParagraph(); + //ol.newParagraph(); } ol.endTextBlock(); } @@ -321,8 +321,10 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.popGeneratorState(); } ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::RTF); ol.newParagraph(); ol.enable(OutputGenerator::Man); + ol.enable(OutputGenerator::RTF); ol.writeSynopsis(); ol.endTextBlock(); diff --git a/src/outputgen.h b/src/outputgen.h index 0a7c06c..9118ef4 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -132,6 +132,11 @@ class BaseOutputDocInterface : public CodeOutputInterface /*! Starts a new paragraph */ virtual void newParagraph() = 0; + /*! Starts a new paragraph */ + virtual void startParagraph() = 0; + /*! End a paragraph */ + virtual void endParagraph() = 0; + /*! Writes a link to an object in the documentation. * \param ref If this is non-zero, the object is to be found in * an external documentation file. @@ -376,6 +381,15 @@ class OutputGenerator : public BaseOutputDocInterface virtual void startParameterList(bool) = 0; virtual void endParameterList() = 0; + virtual void startConstraintList(const char *) = 0; + virtual void startConstraintParam() = 0; + virtual void endConstraintParam() = 0; + virtual void startConstraintType() = 0; + virtual void endConstraintType() = 0; + virtual void startConstraintDocs() = 0; + virtual void endConstraintDocs() = 0; + virtual void endConstraintList() = 0; + protected: QTextStream fs; QByteArray a; diff --git a/src/outputlist.h b/src/outputlist.h index 4a8a0d7..30f8e64 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -97,6 +97,10 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endTitle); } void newParagraph() { forall(&OutputGenerator::newParagraph); } + void startParagraph() + { forall(&OutputGenerator::startParagraph); } + void endParagraph() + { forall(&OutputGenerator::endParagraph); } void writeString(const char *text) { forall(&OutputGenerator::writeString,text); } void startIndexList() @@ -370,6 +374,25 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startParameterList,openBracket); } void endParameterList() { forall(&OutputGenerator::endParameterList); } + + void startConstraintList(const char *header) + { forall(&OutputGenerator::startConstraintList,header); } + void startConstraintParam() + { forall(&OutputGenerator::startConstraintParam); } + void endConstraintParam() + { forall(&OutputGenerator::endConstraintParam); } + void startConstraintType() + { forall(&OutputGenerator::startConstraintType); } + void endConstraintType() + { forall(&OutputGenerator::endConstraintType); } + void startConstraintDocs() + { forall(&OutputGenerator::startConstraintDocs); } + void endConstraintDocs() + { forall(&OutputGenerator::endConstraintDocs); } + void endConstraintList() + { forall(&OutputGenerator::endConstraintList); } + + void startFontClass(const char *c) { forall(&OutputGenerator::startFontClass,c); } void endFontClass() @@ -396,6 +419,8 @@ class OutputList : public OutputDocInterface } void linkableSymbol(int,const char *,Definition *,Definition *) {} + + private: void debug(); void clear(); diff --git a/src/pyscanner.l b/src/pyscanner.l index 913f88e..ed3f10b 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -1000,6 +1000,7 @@ STARTDOCSYMS ^{B}"##"/[^#] // prepend scope in case of nested classes if (current_root->section&Entry::SCOPE_MASK) { + printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data()); current->name.prepend(current_root->name+"::"); } @@ -1476,11 +1477,15 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) QFileInfo fi(fileName); g_moduleScope = findPackageScope(fileName); - if (!g_moduleScope.isEmpty()) + QString baseName=fi.baseName(); + if (baseName!="__init__") // package initializer file is not a package itself { - g_moduleScope+="::"; + if (!g_moduleScope.isEmpty()) + { + g_moduleScope+="::"; + } + g_moduleScope+=baseName; } - g_moduleScope+=fi.baseName(); current = new Entry; current->name = g_moduleScope; diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 05fe40d..e835811 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -259,7 +259,7 @@ void RTFDocVisitor::visit(DocLineBreak *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n"); - m_t << "\\par\n"; + m_t << "\\par"; m_lastIsPara=TRUE; } @@ -310,7 +310,7 @@ void RTFDocVisitor::visit(DocStyleChange *s) else { m_insidePre=FALSE; - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; } m_lastIsPara=TRUE; @@ -442,7 +442,7 @@ void RTFDocVisitor::visit(DocInclude *inc) inc->text().latin1(), inc->isExample(), inc->exampleFile(), &fd); - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; } break; @@ -454,7 +454,7 @@ void RTFDocVisitor::visit(DocInclude *inc) ->parseCode(m_ci,inc->context(), inc->text().latin1(),inc->isExample(), inc->exampleFile()); - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; break; case DocInclude::DontInclude: @@ -466,7 +466,7 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); filter(inc->text()); - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; break; } @@ -506,7 +506,7 @@ void RTFDocVisitor::visit(DocIncOperator *op) popEnabled(); if (!m_hide) { - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; } m_lastIsPara=TRUE; @@ -553,7 +553,7 @@ void RTFDocVisitor::visitPost(DocAutoList *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoList)}\n"); - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; m_lastIsPara=TRUE; } @@ -593,7 +593,8 @@ void RTFDocVisitor::visitPost(DocPara *p) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n"); - if (!p->isLast() && // omit <p> for last paragraph + if (!m_lastIsPara && + !p->isLast() && // omit <p> for last paragraph !(p->parent() && // and for parameters & sections p->parent()->kind()==DocNode::Kind_ParamSect ) @@ -669,7 +670,7 @@ void RTFDocVisitor::visitPre(DocSimpleSect *s) if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) { m_t << ":"; - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}"; // end bold incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); @@ -779,7 +780,7 @@ void RTFDocVisitor::visitPost(DocHtmlList *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlList)}\n"); - m_t << "\\par" << endl << "}" << endl; + m_t << "\\par" << "}" << endl; m_lastIsPara=TRUE; } @@ -858,7 +859,7 @@ void RTFDocVisitor::visitPost(DocHtmlDescData *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescData)}\n"); - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; decIndentLevel(); m_lastIsPara=TRUE; @@ -959,7 +960,7 @@ void RTFDocVisitor::visitPost(DocInternal *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternal)}\n"); - m_t << "\\par" << endl; + m_t << "\\par"; decIndentLevel(); m_t << "}"; // end desc m_lastIsPara=TRUE; @@ -1025,7 +1026,7 @@ void RTFDocVisitor::visitPost(DocHtmlHeader *) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n"); - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; // end section m_lastIsPara=TRUE; } @@ -1131,8 +1132,8 @@ void RTFDocVisitor::visitPost(DocSecRefList *) if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefList)}\n"); decIndentLevel(); - m_t << "\\par" << endl; - m_t << "}"; + m_t << "\\par"; + m_t << "}" << endl; m_lastIsPara=TRUE; } @@ -1177,7 +1178,7 @@ void RTFDocVisitor::visitPre(DocParamSect *s) ASSERT(0); } m_t << ":"; - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}" << endl; incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); @@ -1268,7 +1269,7 @@ void RTFDocVisitor::visitPre(DocXRefItem *x) filter(x->title()); } m_t << ":"; - m_t << "\\par" << endl; + m_t << "\\par"; m_t << "}"; // end bold incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index f6fb8af..37e2ddd 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -852,6 +852,7 @@ void RTFGenerator::lineBreak() { DBG_RTF(t << "{\\comment (lineBreak)}" << endl) t << "\\par" << endl; + m_omitParagraph = TRUE; } void RTFGenerator::writeString(const char *text) @@ -863,16 +864,16 @@ void RTFGenerator::startIndexList() { DBG_RTF(t << "{\\comment (startIndexList)}" << endl) t << "{" << endl; + t << "\\par" << endl; incrementIndentLevel(); t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl; - newParagraph(); m_omitParagraph = TRUE; } void RTFGenerator::endIndexList() { DBG_RTF(t << "{\\comment (endIndexList)}" << endl) - newParagraph(); + t << "\\par"; t << "}"; decrementIndentLevel(); m_omitParagraph = TRUE; @@ -881,6 +882,7 @@ void RTFGenerator::endIndexList() /*! start bullet list */ void RTFGenerator::startItemList() { + newParagraph(); DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl) t << "{"; incrementIndentLevel(); @@ -954,8 +956,8 @@ void RTFGenerator::endIndexItem(const char *ref,const char *fn) { t << endl; } - newParagraph(); m_omitParagraph = TRUE; + newParagraph(); } //void RTFGenerator::writeIndexFileItem(const char *,const char *text) @@ -1048,17 +1050,19 @@ void RTFGenerator::startIndexKey() void RTFGenerator::endIndexKey() { + DBG_RTF(t << "{\\comment (endIndexKey)}" << endl) } void RTFGenerator::startIndexValue(bool hasBrief) { + DBG_RTF(t << "{\\comment (startIndexValue)}" << endl) t << " "; if (hasBrief) t << "("; } void RTFGenerator::endIndexValue(const char *name,bool hasBrief) { - DBG_RTF(t << "{\\comment (endIndexKey)}" << endl) + DBG_RTF(t << "{\\comment (endIndexValue)}" << endl) if (hasBrief) t << ")"; t << "} "; if (name) @@ -1071,6 +1075,7 @@ void RTFGenerator::endIndexValue(const char *name,bool hasBrief) { t << endl; } + m_omitParagraph=FALSE; newParagraph(); } @@ -1353,7 +1358,7 @@ void RTFGenerator::startGroupHeader() void RTFGenerator::endGroupHeader() { DBG_RTF(t <<"{\\comment endGroupHeader}" << endl) - newParagraph(); + t << "\\par" << endl; t << rtf_Style_Reset << endl; } @@ -1496,7 +1501,9 @@ void RTFGenerator::endMemberDescription() endEmphasis(); newParagraph(); decrementIndentLevel(); - t << "\\par}" << endl; + //t << "\\par"; + t << "}" << endl; + //m_omitParagraph = TRUE; } void RTFGenerator::startDescList(SectionTypes) @@ -1714,6 +1721,7 @@ void RTFGenerator::writeChar(char c) void RTFGenerator::startClassDiagram() { + DBG_RTF(t <<"{\\comment startClassDiagram }" << endl) } void RTFGenerator::endClassDiagram(ClassDiagram &d, @@ -1987,9 +1995,9 @@ void RTFGenerator::startTextBlock(bool dense) } } -void RTFGenerator::endTextBlock(bool paraBreak) +void RTFGenerator::endTextBlock(bool /*paraBreak*/) { - if (paraBreak) newParagraph(); + newParagraph(); DBG_RTF(t << "{\\comment endTextBlock}" << endl) t << "}" << endl; //m_omitParagraph = TRUE; @@ -1999,12 +2007,26 @@ void RTFGenerator::newParagraph() { if (!m_omitParagraph) { - DBG_RTF(t << "{\\comment (newParagraph)}" << endl) + DBG_RTF(t << "{\\comment (newParagraph)}" << endl) t << "\\par" << endl; } m_omitParagraph = FALSE; } +void RTFGenerator::startParagraph() +{ + DBG_RTF(t << "{\\comment startParagraph}" << endl) + newParagraph(); + t << "{" << endl; +} + +void RTFGenerator::endParagraph() +{ + DBG_RTF(t << "{\\comment endParagraph}" << endl) + t << "}\\par" << endl; + m_omitParagraph = TRUE; +} + void RTFGenerator::startMemberSubtitle() { DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl) @@ -2496,6 +2518,7 @@ void RTFGenerator::printDoc(DocNode *n,const char *langExt) RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,langExt); n->accept(visitor); delete visitor; + m_omitParagraph = TRUE; } void RTFGenerator::rtfwriteRuler_doubleline() @@ -2545,3 +2568,68 @@ void RTFGenerator::postProcess(QByteArray &a) enc.resize(off); a = enc; } + +void RTFGenerator::startConstraintList(const char *header) +{ + DBG_RTF(t << "{\\comment (startConstraintList)}" << endl) + t << "{"; // ends at endConstraintList + t << "{"; + startBold(); + newParagraph(); + docify(header); + endBold(); + t << "}"; + newParagraph(); + incrementIndentLevel(); + t << rtf_Style_Reset << rtf_DList_DepthStyle(); +} + +void RTFGenerator::startConstraintParam() +{ + DBG_RTF(t << "{\\comment (startConstraintParam)}" << endl) + startEmphasis(); +} + +void RTFGenerator::endConstraintParam() +{ + DBG_RTF(t << "{\\comment (endConstraintParam)}" << endl) + endEmphasis(); + t << " : "; +} + +void RTFGenerator::startConstraintType() +{ + DBG_RTF(t << "{\\comment (startConstraintType)}" << endl) + startEmphasis(); +} + +void RTFGenerator::endConstraintType() +{ + DBG_RTF(t << "{\\comment (endConstraintType)}" << endl) + endEmphasis(); + t << " "; +} + +void RTFGenerator::startConstraintDocs() +{ + DBG_RTF(t << "{\\comment (startConstraintDocs)}" << endl) +} + +void RTFGenerator::endConstraintDocs() +{ + DBG_RTF(t << "{\\comment (endConstraintDocs)}" << endl) + newParagraph(); +} + +void RTFGenerator::endConstraintList() +{ + DBG_RTF(t << "{\\comment (endConstraintList)}" << endl) + newParagraph(); + decrementIndentLevel(); + m_omitParagraph = TRUE; + t << "}"; +} + + + + diff --git a/src/rtfgen.h b/src/rtfgen.h index 2183237..577cc40 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -64,6 +64,8 @@ class RTFGenerator : public OutputGenerator void endTitle() {} void newParagraph(); + void startParagraph(); + void endParagraph(); void writeString(const char *text); void startIndexList(); void endIndexList(); @@ -255,6 +257,16 @@ class RTFGenerator : public OutputGenerator void startParameterList(bool) {} void endParameterList() {} + void startConstraintList(const char *); + void startConstraintParam(); + void endConstraintParam(); + void startConstraintType(); + void endConstraintType(); + void startConstraintDocs(); + void endConstraintDocs(); + void endConstraintList(); + + void startFontClass(const char *) {} void endFontClass() {} diff --git a/src/scanner.l b/src/scanner.l index 8fd1672..09c52fb 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -68,6 +68,7 @@ static int lastClassTemplSpecContext; static int lastPreLineCtrlContext; static int lastSkipVerbStringContext; static int lastCommentInArgContext; +static int lastCSConstraint; static Protection protection; static Protection baseProt; static int sharpCount = 0 ; @@ -82,6 +83,7 @@ static Entry* current = 0 ; static Entry* previous = 0 ; static Entry* tempEntry = 0 ; static Entry* firstTypedefEntry = 0 ; +static Entry* memspecEntry = 0 ; static int yyLineNr = 1 ; static int anonCount = 0 ; static int anonNSCount = 0 ; @@ -303,7 +305,7 @@ static QCString stripQuotes(const char *s) static void startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); -static void handleParametersCommentBlocks(); +static void handleParametersCommentBlocks(ArgumentList *al); //----------------------------------------------------------------- @@ -359,7 +361,6 @@ static void prependScope() for (talsi.toLast();(srcAl=talsi.current());--talsi) { ArgumentList *dstAl = new ArgumentList; - dstAl->setAutoDelete(TRUE); QListIterator<Argument> tali(*srcAl); Argument *a; for (;(a=tali.current());++tali) @@ -544,7 +545,7 @@ FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+ ID "$"?[a-z_A-Z][a-z_A-Z0-9]* LABELID [a-z_A-Z][a-z_A-Z0-9\-]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) -SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) +SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID}) TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")? FTSCOPE {ID}("<"[a-z_A-Z0-9\*\&,]*">")? CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID}) @@ -572,7 +573,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) %x DefineEnd %x CompoundName %x ClassVar -%x CSConstraint +%x CSConstraintName +%x CSConstraintType %x ClassCategory %x ClassTemplSpec %x CliPropertyType @@ -1477,7 +1479,6 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->tArgLists->setAutoDelete(TRUE); } ArgumentList *al = new ArgumentList; - al->setAutoDelete(TRUE); current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template; current->tArgLists->append(al); currentArgumentList = al; @@ -2052,11 +2053,6 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } <FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { - //Entry *tmp = current; - //if (previous) - //{ - // current = previous; - //} //handleGroupStartCommand(current->name); if (previous && previous->section==Entry::GROUPDOC_SEC) { @@ -2866,6 +2862,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else { current_root->addSubEntry( current ) ; + memspecEntry = current; current = new Entry(*current); if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || @@ -2874,6 +2871,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); initEntry(); + memspecEntry = 0; BEGIN( FindMembers ) ; } else @@ -2934,6 +2932,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); current_root->addSubEntry( current ) ; + memspecEntry = current; current = new Entry(*current); unput(';'); BEGIN( MemberSpec ) ; @@ -3004,60 +3003,73 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) //printf("msName=%s current->name=%s\n",msName.data(),current->name.data()); if (!msName.isEmpty() && msName!=current->name) // skip typedef T {} T; { - Entry *varEntry=new Entry; - varEntry->protection = current->protection ; - varEntry->mtype = current->mtype; - varEntry->virt = current->virt; - varEntry->stat = current->stat; - varEntry->section = Entry::VARIABLE_SEC; - varEntry->name = msName.stripWhiteSpace(); - varEntry->type = current->type.simplifyWhiteSpace()+" "; - varEntry->args = msArgs; //current->args.simplifyWhiteSpace(); - //if (!current->name.isEmpty() && current->name[0]!='@' && - // current->parent->section & Entry::COMPOUND_MASK) - // varEntry->type+=current->parent->name+"::"; - if (isTypedef) + static bool optimizeForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C"); + // case 1: typedef struct _S { ... } S_t; + // -> omit typedef and use S_t as the struct name + if (optimizeForC && + isTypedef && + (current->spec&(Entry::Struct|Entry::Union)) && + msType.stripWhiteSpace().isEmpty() && + memspecEntry) { - varEntry->type.prepend("typedef "); - // //printf("current->name = %s %s\n",current->name.data(),msName.data()); - // if (!current->name.isEmpty() && current->name.at(0)!='@') - // { - // //printf("2>>>>>>>>>> adding %s->%s\n",msName.data(),current->name.data()); - // QCString scope; - // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name; - // Doxygen::typedefDict.insert(msName,new TypedefInfo(current->name,scope)); - // } + memspecEntry->name=msName; } - varEntry->type+=current->name+msType; - varEntry->fileName = yyFileName; - varEntry->startLine = yyLineNr; - varEntry->doc = current->doc.copy(); - varEntry->brief = current->brief.copy(); - varEntry->mGrpId = current->mGrpId; - - // deep copy group list - QListIterator<Grouping> gli(*current->groups); - Grouping *g; - for (;(g=gli.current());++gli) - { - varEntry->groups->append(new Grouping(*g)); - } - if (current->sli) // copy special list items + else // case 2: create a typedef field { - QListIterator<ListItemInfo> li(*current->sli); - ListItemInfo *lii; - for (li.toFirst();(lii=li.current());++li) + Entry *varEntry=new Entry; + varEntry->protection = current->protection ; + varEntry->mtype = current->mtype; + varEntry->virt = current->virt; + varEntry->stat = current->stat; + varEntry->section = Entry::VARIABLE_SEC; + varEntry->name = msName.stripWhiteSpace(); + varEntry->type = current->type.simplifyWhiteSpace()+" "; + varEntry->args = msArgs; + if (isTypedef) { - varEntry->addSpecialListItem(lii->type,lii->itemId); + varEntry->type.prepend("typedef "); + // //printf("current->name = %s %s\n",current->name.data(),msName.data()); + } + if (optimizeForC && + isTypedef && + (current->spec&(Entry::Struct|Entry::Union)) && + memspecEntry + ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;" + { + varEntry->type+=memspecEntry->name+msType; + } + else // case 2: use _S as type for for pS_t + { + varEntry->type+=current->name+msType; + } + varEntry->fileName = yyFileName; + varEntry->startLine = yyLineNr; + varEntry->doc = current->doc.copy(); + varEntry->brief = current->brief.copy(); + varEntry->mGrpId = current->mGrpId; + + // deep copy group list + QListIterator<Grouping> gli(*current->groups); + Grouping *g; + for (;(g=gli.current());++gli) + { + varEntry->groups->append(new Grouping(*g)); + } + if (current->sli) // copy special list items + { + QListIterator<ListItemInfo> li(*current->sli); + ListItemInfo *lii; + for (li.toFirst();(lii=li.current());++li) + { + varEntry->addSpecialListItem(lii->type,lii->itemId); + } } - //delete current->sli; - //current->sli = 0; - } - //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n", - // varEntry->type.data(),varEntry->name.data(), - // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); - current_root->addSubEntry(varEntry); + //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n", + // varEntry->type.data(),varEntry->name.data(), + // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); + current_root->addSubEntry(varEntry); + } } if (*yytext==';') { @@ -3066,6 +3078,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) msArgs.resize(0); isTypedef=FALSE; firstTypedefEntry=0; + memspecEntry=0; current->reset(); initEntry(); BEGIN( FindMembers ); @@ -3272,7 +3285,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); - handleParametersCommentBlocks(); + handleParametersCommentBlocks(current->argList); /* remember the current documentation block, since we could overwrite it with the documentation of @@ -3295,7 +3308,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) unput(yytext[i]); } stringToArgumentList(fullArgString,current->argList); - handleParametersCommentBlocks(); + handleParametersCommentBlocks(current->argList); BEGIN( currentArgumentContext ); } else // not a define @@ -3347,7 +3360,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); - handleParametersCommentBlocks(); + handleParametersCommentBlocks(current->argList); BEGIN( currentArgumentContext ); } else @@ -3657,7 +3670,16 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) yyLineNr++; } <FuncQual>{ID} { // typically a K&R style C function - if (checkForKnRstyleC()) + if (insideCS && strcmp(yytext,"where")==0) + { + // type contraint for a method + delete current->typeConstr; + current->typeConstr = new ArgumentList; + current->typeConstr->append(new Argument); + lastCSConstraint = YY_START; + BEGIN( CSConstraintName ); + } + else if (checkForKnRstyleC()) { //fprintf(stderr,"===> got a K&R style function\n"); current->args = yytext; @@ -4181,7 +4203,11 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } else if (insideCS && strcmp(yytext,"where")==0) // C# type contraint { - BEGIN( CSConstraint ); + delete current->typeConstr; + current->typeConstr = new ArgumentList; + current->typeConstr->append(new Argument); + lastCSConstraint = YY_START; + BEGIN( CSConstraintName ); } else { @@ -4216,14 +4242,53 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) BEGIN( FindMembers ); } } -<CSConstraint>"{" { +<CSConstraintType,CSConstraintName>("/*"[*!]|"//"[/!])("<"?) { // special comment + fullArgString.resize(0); + lastCopyArgChar='#'; // end marker + lastCommentInArgContext=YY_START; + if (yytext[1]=='/') + BEGIN( CopyArgCommentLine ); + else + BEGIN( CopyArgComment ); + } +<CSConstraintType,CSConstraintName>"#" { // artifically inserted token to signal end of comment block + current->typeConstr->last()->docs = fullArgString; + } +<CSConstraintType>"{" { // end of type constraint reached + // parse documentation of the constraints + handleParametersCommentBlocks(current->typeConstr); unput('{'); - BEGIN( ClassVar ); + BEGIN( lastCSConstraint ); } -<CSConstraint>\n { +<CSConstraintName>":" { + BEGIN( CSConstraintType ); + } +<CSConstraintName>{ID} { + // parameter name + current->typeConstr->last()->name=yytext; + } +<CSConstraintType>"where" { // another constraint for a different param + current->typeConstr->append(new Argument); + BEGIN( CSConstraintName ); + } +<CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? { + if (current->typeConstr->last()->type.isEmpty()) + // first type constraint for this parameter + { + current->typeConstr->last()->type=yytext; + } + else // new type constraint for same parameter + { + QCString name = current->typeConstr->last()->name; + current->typeConstr->append(new Argument); + current->typeConstr->last()->name=name; + current->typeConstr->last()->type=yytext; + } + } +<CSConstraintName,CSConstraintType>\n { yyLineNr++; } -<CSConstraint>. { +<CSConstraintName,CSConstraintType>. { } <ClassCategory>{ID} { current->name+=yytext; @@ -5000,10 +5065,10 @@ static void handleCommentBlock(const QCString &doc,bool brief) } } -static void handleParametersCommentBlocks() +static void handleParametersCommentBlocks(ArgumentList *al) { //printf(">>>>>>> handleParametersCommentBlocks()\n"); - ArgumentListIterator ali(*current->argList); + ArgumentListIterator ali(*al); Argument *a; for (ali.toFirst();(a=ali.current());++ali) { diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp index fe5573b..9e5cd21 100644 --- a/src/textdocvisitor.cpp +++ b/src/textdocvisitor.cpp @@ -71,8 +71,13 @@ void TextDocVisitor::filter(const char *str) c=*p++; switch(c) { - case '\n': m_t << " "; break; - default: m_t << c; + case '\n': m_t << " "; break; + case '"': m_t << """; break; + case '\'': m_t << "'"; break; + case '<': m_t << "<"; break; + case '>': m_t << ">"; break; + case '&': m_t << "&"; break; + default: m_t << c; } } } diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h index cf7788a..8e70da9 100644 --- a/src/textdocvisitor.h +++ b/src/textdocvisitor.h @@ -36,11 +36,11 @@ class TextDocVisitor : public DocVisitor // visitor functions for leaf nodes //-------------------------------------- - void visit(DocWord *w) { m_t << w->word(); } - void visit(DocLinkedWord *w) { m_t << w->word(); } + void visit(DocWord *w) { filter(w->word()); } + void visit(DocLinkedWord *w) { filter(w->word()); } void visit(DocWhiteSpace *) { m_t << " "; } void visit(DocSymbol *); - void visit(DocURL *u) { m_t << u->url(); } + void visit(DocURL *u) { filter(u->url()); } void visit(DocLineBreak *) { m_t << " "; } void visit(DocHorRuler *) {} void visit(DocStyleChange *) {} diff --git a/src/util.cpp b/src/util.cpp index 0723ae4..fde2dab 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -500,10 +500,11 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, ip--; } type=type.left(ip+1); + type.stripPrefix("const "); // strip leading "const" + type.stripPrefix("struct "); // strip leading "struct" + type.stripPrefix("union "); // strip leading "union" int sp=0; - if (type.stripPrefix("const ")) sp+=6; // strip leading "const" - if (type.stripPrefix("struct ")) sp+=7; // strip leading "struct" - if (type.stripPrefix("union ")) sp+=6; // strip leading "union" + tl=type.length(); // length may have been changed while (sp<tl && type.at(sp)==' ') sp++; MemberDef *memTypeDef = 0; ClassDef *result = getResolvedClassRec(md->getOuterScope(), @@ -697,9 +698,13 @@ static Definition *followPath(Definition *start,FileDef *fileScope,const QCStrin } } Definition *next = current->findInnerCompound(qualScopePart); - //printf("++ Looking for %s inside %s result %p\n",qualScopePart.data(),current->name().data(),next?next->name().data():"<null>"); + //printf("++ Looking for %s inside %s result %s\n", + // qualScopePart.data(), + // current->name().data(), + // next?next->name().data():"<null>"); if (next==0) // failed to follow the path { + //printf("==> next==0!\n"); if (current->definitionType()==Definition::TypeNamespace) { current = endOfPathIsUsedClass( @@ -715,6 +720,7 @@ static Definition *followPath(Definition *start,FileDef *fileScope,const QCStrin else // continue to follow scope { current = next; + //printf("==> current = %p\n",current); } ps=is+l; } @@ -1295,6 +1301,7 @@ ClassDef *getResolvedClassRec(Definition *scope, if (di->definitionType()==DefinitionIntf::TypeSymbolList) // not a unique name { + //printf(" name is not unique\n"); DefinitionListIterator dli(*(DefinitionList*)di); Definition *d; int count=0; @@ -1307,6 +1314,7 @@ ClassDef *getResolvedClassRec(Definition *scope, } else // unique name { + //printf(" name is unique\n"); Definition *d = (Definition *)di; getResolvedSymbol(scope,fileScope,d,explicitScopePart, minDistance,bestMatch,bestTypedef,bestTemplSpec, @@ -1426,12 +1434,29 @@ QCString removeRedundantWhiteSpace(const QCString &s) { nextChar: char c=s.at(i); - if ((csp==0 && (i==0 || !isId(constScope[i-1])) || (csp>0 && csp<6)) && - c==constScope[csp] - ) csp++; else csp=0; - if ((vsp==0 && (i==0 || !isId(virtualScope[i-1])) || (vsp>0 && vsp<8)) && - c==virtualScope[vsp] - ) vsp++; else vsp=0; + + // search for "const" + if (csp<6 && c==constScope[csp] && // character matches substring "const" + (csp>0 || // if it is the first character + i==0 || // the previous may not be a digit + !isId(s.at(i-1)) + ) + ) + csp++; + else // reset counter + csp=0; + + // search for "virtual" + if (vsp<8 && c==virtualScope[vsp] && // character matches substring "virtual" + (vsp>0 || // if it is the first character + i==0 || // the previous may not be a digit + !isId(s.at(i-1)) + ) + ) + vsp++; + else // reset counter + vsp=0; + if (c=='"') // quoted string { i++; @@ -1478,30 +1503,40 @@ nextChar: result+=' '; result+=s.at(i); } - else if (c=='t' && csp==5 && (i<5 || !isId(s.at(i-5))) && - !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || s.at(i+1)==')' || - s.at(i+1)==',' || s.at(i+1)=='\0')) + else if (c=='t' && csp==5 /*&& (i<5 || !isId(s.at(i-5)))*/ && + !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || + s.at(i+1)==')' || + s.at(i+1)==',' || + s.at(i+1)=='\0' + ) + ) // prevent const ::A from being converted to const::A { result+="t "; if (s.at(i+1)==' ') i++; csp=0; } - else if (c==':' && csp==6 && (i<6 || !isId(s.at(i-6)))) // replace const::A by const ::A + else if (c==':' && csp==6 /*&& (i<6 || !isId(s.at(i-6)))*/) + // replace const::A by const ::A { result+=" :"; csp=0; } - else if (c=='l' && vsp==7 && (i<7 || !isId(s.at(i-7))) && - !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || s.at(i+1)==')' || - s.at(i+1)==',' || s.at(i+1)=='\0')) + else if (c=='l' && vsp==7 /*&& (i<7 || !isId(s.at(i-7)))*/ && + !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || + s.at(i+1)==')' || + s.at(i+1)==',' || + s.at(i+1)=='\0' + ) + ) // prevent virtual ::A from being converted to virtual::A { result+="l "; if (s.at(i+1)==' ') i++; vsp=0; } - else if (c==':' && vsp==8 && (i<8 || !isId(s.at(i-8)))) // replace virtual::A by virtual ::A + else if (c==':' && vsp==8 /*&& (i<8 || !isId(s.at(i-8)))*/) + // replace virtual::A by virtual ::A { result+=" :"; vsp=0; @@ -1552,7 +1587,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope, bool keepSpaces) { //printf("`%s'\n",text); - static QRegExp regExp("[a-z_A-Z][~a-z_A-Z0-9.:]*"); + static QRegExp regExp("[a-z_A-Z][~!a-z_A-Z0-9.:]*"); QCString txtStr=text; int strLen = txtStr.length(); //printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%d\n", @@ -1571,7 +1606,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope, ) { // add non-word part to the result - floatingIndex+=newIndex-skipIndex; + floatingIndex+=newIndex-skipIndex+matchLen; bool insideString=FALSE; int i; for (i=index;i<newIndex;i++) @@ -1579,24 +1614,28 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope, if (txtStr.at(i)=='"') insideString=!insideString; } - if (strLen>30 && floatingIndex>25 && autoBreak) // try to insert a split point + //printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak); + if (strLen>25 && floatingIndex>20 && autoBreak) // try to insert a split point { QCString splitText = txtStr.mid(skipIndex,newIndex-skipIndex); int splitLength = splitText.length(); - int i=splitText.find('<'); - if (i==-1) i=splitText.find(','); + int offset=1; + i=splitText.find(','); + if (i==-1) { i=splitText.find('<'); if (i!=-1) offset=0; } + if (i==-1) i=splitText.find('>'); if (i==-1) i=splitText.find(' '); + //printf("splitText=[%s] len=%d i=%d offset=%d\n",splitText.data(),splitLength,i,offset); if (i!=-1) // add a link-break at i in case of Html output { - out.writeString(splitText.left(i+1),keepSpaces); + out.writeString(splitText.left(i+offset),keepSpaces); out.writeBreak(); - out.writeString(splitText.right(splitLength-i-1),keepSpaces); + out.writeString(splitText.right(splitLength-i-offset),keepSpaces); + floatingIndex=splitLength-i-offset+matchLen; } else { out.writeString(splitText,keepSpaces); } - floatingIndex=splitLength-i-1; } else { @@ -1686,7 +1725,6 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope, // set next start point in the string //printf("index=%d/%d\n",index,txtStr.length()); skipIndex=index=newIndex+matchLen; - floatingIndex+=matchLen; } // add last part of the string to the result. //ol.docify(txtStr.right(txtStr.length()-skipIndex)); @@ -2893,14 +2931,17 @@ static QCString stripDeclKeywords(const QCString &s) // forward decl for circular dependencies static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type); -QCString getCanonicalTemplateSpec(Definition *d,FileDef *,const QCString& spec) +QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec) { + QCString templSpec = spec.stripWhiteSpace(); - //if (!templSpec.isEmpty() && templSpec.at(0) == '<') - //{ - // templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace()); - //} - QCString resolvedType = resolveTypeDef(d,spec); + // this part had been commented out before... but it is needed to match for instance + // std::list<std::string> against list<string> so it is now back again! + if (!templSpec.isEmpty() && templSpec.at(0) == '<') + { + templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace()); + } + QCString resolvedType = resolveTypeDef(d,templSpec); if (!resolvedType.isEmpty()) // not known as a typedef either { templSpec = resolvedType; @@ -2926,6 +2967,8 @@ static QCString getCanonicalTypeForIdentifier( { symName=word; } + //printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n", + // word.data(),tSpec?tSpec->data():"<none>",templSpec.data()); ClassDef *cd = 0; MemberDef *mType = 0; @@ -2942,7 +2985,7 @@ static QCString getCanonicalTypeForIdentifier( } if (cd && cd->isUsedOnly()) cd=0; // ignore types introduced by usage relations - //printf(" symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n", + //printf(" getCanonicalTypeForIdentifer: symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n", // symName.data(), // word.data(), // cd?cd->name().data():"<none>", @@ -3020,6 +3063,7 @@ static QCString getCanonicalTypeForIdentifier( result = resolvedType; } } + //printf("getCanonicalTypeForIdentifier [%s]->[%s]\n",word.data(),result.data()); return result; } @@ -3038,7 +3082,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type) type.stripPrefix("typename "); type = removeRedundantWhiteSpace(type); - //printf("extractCanonicalType(type=%s) def=%s file=%s\n",type.data(), + //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",type.data(), // d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>"); static QRegExp id("[a-z_A-Z][:a-z_A-Z0-9]*"); @@ -3112,7 +3156,7 @@ static bool matchArgument2( if (srcA->array!=dstA->array) // nomatch for char[] against char { NOMATCH - return FALSE; + return FALSE; } QCString sSrcName = " "+srcA->name; QCString sDstName = " "+dstA->name; @@ -3147,14 +3191,14 @@ static bool matchArgument2( if (srcA->canType==dstA->canType) { MATCH - return TRUE; + return TRUE; } else { //printf(" Canonical types do not match [%s]<->[%s]\n", // srcA->canType.data(),dstA->canType.data()); NOMATCH - return FALSE; + return FALSE; } } @@ -3173,12 +3217,12 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr if (match) { MATCH - return TRUE; + return TRUE; } else { NOMATCH - return FALSE; + return FALSE; } } @@ -3190,7 +3234,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr a->type = "void"; srcAl->append(a); MATCH - return TRUE; + return TRUE; } if ( dstAl->count()==0 && srcAl->count()==1 && srcAl->getFirst()->type=="void" ) @@ -3199,13 +3243,13 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr a->type = "void"; dstAl->append(a); MATCH - return TRUE; + return TRUE; } if (srcAl->count() != dstAl->count()) { NOMATCH - return FALSE; // different number of arguments -> no match + return FALSE; // different number of arguments -> no match } if (checkCV) @@ -3213,12 +3257,12 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr if (srcAl->constSpecifier != dstAl->constSpecifier) { NOMATCH - return FALSE; // one member is const, the other not -> no match + return FALSE; // one member is const, the other not -> no match } if (srcAl->volatileSpecifier != dstAl->volatileSpecifier) { NOMATCH - return FALSE; // one member is volatile, the other not -> no match + return FALSE; // one member is volatile, the other not -> no match } } @@ -3233,11 +3277,11 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr ) { NOMATCH - return FALSE; + return FALSE; } } MATCH - return TRUE; // all arguments match + return TRUE; // all arguments match } @@ -5953,6 +5997,7 @@ SrcLangExt getLanguageFromFileName(const QCString fileName) extLookup.insert(".idl", new int(SrcLangExt_IDL)); extLookup.insert(".ddl", new int(SrcLangExt_IDL)); extLookup.insert(".odl", new int(SrcLangExt_IDL)); + extLookup.insert(".ddl", new int(SrcLangExt_IDL)); extLookup.insert(".java", new int(SrcLangExt_Java)); extLookup.insert(".jsl", new int(SrcLangExt_Java)); extLookup.insert(".as", new int(SrcLangExt_Java)); @@ -6243,4 +6288,24 @@ QCString expandAlias(const QCString &aliasName,const QCString &aliasValue) return result; } +void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al) +{ + if (al==0) return; + ol.startConstraintList("Type constraints"); // TODO: add to translator! + ArgumentListIterator ali(*al); + Argument *a; + for (;(a=ali.current());++ali) + { + ol.startConstraintParam(); + ol.parseText(a->name); + ol.endConstraintParam(); + ol.startConstraintType(); + linkifyText(TextGeneratorOLImpl(ol),d,0,0,a->type); + ol.endConstraintType(); + ol.startConstraintDocs(); + ol.parseDoc(d->docFile(),d->docLine(),d,0,a->docs,TRUE,FALSE); + ol.endConstraintDocs(); + } + ol.endConstraintList(); +} @@ -343,5 +343,8 @@ QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argLis QCString resolveAliasCmd(const QCString aliasCmd); QCString expandAlias(const QCString &aliasName,const QCString &aliasValue); +void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al); + + #endif |