diff options
Diffstat (limited to 'src')
43 files changed, 993 insertions, 285 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index bd44c87..5e91836 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -918,7 +918,10 @@ void ClassDef::writeDetailedDocumentationBody(OutputList &ol) ol.startTextBlock(); - writeTemplateSpec(ol,this,compoundTypeString()); + if (getLanguage()==SrcLangExt_Cpp) + { + writeTemplateSpec(ol,this,compoundTypeString()); + } // repeat brief description if (!briefDescription().isEmpty() && repeatBrief) diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp index 5b47db5..5d52557 100644 --- a/src/cmdmapper.cpp +++ b/src/cmdmapper.cpp @@ -186,6 +186,7 @@ CommandMap htmlTagMap[] = { "summary", XML_SUMMARY }, { "term", XML_TERM }, { "value", XML_VALUE }, + { "inheritdoc", XML_INHERITDOC }, { 0, 0 } }; diff --git a/src/cmdmapper.h b/src/cmdmapper.h index 8ff3b22..04bb3ed 100644 --- a/src/cmdmapper.h +++ b/src/cmdmapper.h @@ -181,7 +181,8 @@ enum HtmlTagType XML_TERM = XML_CmdMask + 18, XML_TYPEPARAM = XML_CmdMask + 19, XML_TYPEPARAMREF = XML_CmdMask + 20, - XML_VALUE = XML_CmdMask + 21 + XML_VALUE = XML_CmdMask + 21, + XML_INHERITDOC = XML_CmdMask + 22 }; class Mapper @@ -2284,7 +2284,15 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} g_name+=yytext; BEGIN( FuncCall ); } -<Body>{SCOPEPREFIX}?"operator"{B}*[^\(\n]+/"(" { +<Body>{SCOPEPREFIX}?"operator"/"(" { + addType(); + generateFunctionLink(*g_code,yytext); + g_bracketCount=0; + g_args.resize(0); + g_name+=yytext; + BEGIN( FuncCall ); + } +<Body>{SCOPEPREFIX}?"operator"[^a-z_A-Z0-9\(\n]+/"(" { addType(); generateFunctionLink(*g_code,yytext); g_bracketCount=0; diff --git a/src/commentscan.l b/src/commentscan.l index 966183d..56c0d08 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -2671,7 +2671,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); } - current->doc=stripLeadingAndTrailingEmptyLines(current->doc); + current->doc=stripLeadingAndTrailingEmptyLines(current->doc,current->docLine); if (current->section==Entry::FILEDOC_SEC && current->doc.isEmpty()) { @@ -2693,8 +2693,10 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, } Debug::print(Debug::CommentScan,0, - "brief=[%s]\ndocs=[%s]\ninbody=[%s]\n===========\n", - current->brief.data(),current->doc.data(),current->inbodyDocs.data() + "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n===========\n", + current->briefLine,current->brief.data(), + current->docLine,current->doc.data(), + current->inbodyLine,current->inbodyDocs.data() ); checkFormula(); @@ -2876,7 +2878,7 @@ static void groupAddDocs(Entry *e,const char *fileName) if (e->section==Entry::MEMBERGRP_SEC) { g_memberGroupDocs=e->brief.stripWhiteSpace(); - e->doc = stripLeadingAndTrailingEmptyLines(e->doc); + e->doc = stripLeadingAndTrailingEmptyLines(e->doc,e->docLine); if (!g_memberGroupDocs.isEmpty() && !e->doc.isEmpty()) { g_memberGroupDocs+="\n\n"; diff --git a/src/config.l b/src/config.l index 2988810..5dfbae3 100644 --- a/src/config.l +++ b/src/config.l @@ -1,7 +1,5 @@ /****************************************************************************** * - * - * * Copyright (C) 1997-2012 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its @@ -872,12 +870,13 @@ void Config::convertStrToVal() static void substEnvVarsInString(QCString &s) { - static QRegExp re("\\$\\([a-z_A-Z0-9]+\\)"); + static QRegExp re("\\$\\([a-z_A-Z0-9.-]+\\)"); + static QRegExp re2("\\$\\([a-z_A-Z0-9.-]+\\([a-z_A-Z0-9.-]+\\)\\)"); // For e.g. PROGRAMFILES(X86) if (s.isEmpty()) return; int p=0; int i,l; //printf("substEnvVarInString(%s) start\n",s.data()); - while ((i=re.match(s,p,&l))!=-1) + while ((i=re.match(s,p,&l))!=-1 || (i=re2.match(s,p,&l))!=-1) { //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).data()); QCString env=portable_getenv(s.mid(i+2,l-3)); @@ -1473,7 +1472,8 @@ void Config::check() (Config_getBool("INLINE_INHERITED_MEMB") || Config_getBool("INHERIT_DOCS") || !Config_getBool("HIDE_SCOPE_NAMES") || - !Config_getBool("EXTRACT_PRIVATE") + !Config_getBool("EXTRACT_PRIVATE") || + !Config_getBool("EXTRACT_PACKAGE") ) ) { @@ -1482,15 +1482,18 @@ void Config::check() bool b3 = Config_getBool("HIDE_SCOPE_NAMES"); bool b4 = Config_getBool("EXTRACT_PRIVATE"); bool b5 = Config_getBool("SKIP_FUNCTION_MACROS"); - const char *s1,*s2,*s3,*s4,*s5; + bool b6 = Config_getBool("EXTRACT_PACKAGE"); + const char *s1,*s2,*s3,*s4,*s5,*s6; if (b1) s1=" INLINDE_INHERITED_MEMB = NO (was YES)\n"; else s1=""; if (b2) s2=" INHERIT_DOCS = NO (was YES)\n"; else s2=""; if (!b3) s3=" HIDE_SCOPE_NAMES = YES (was NO)\n"; else s3=""; if (!b4) s4=" EXTRACT_PRIVATE = YES (was NO)\n"; else s4=""; if (b5) s5=" ENABLE_PREPROCESSING = NO (was YES)\n"; else s5=""; + if (!b6) s6=" EXTRACT_PACKAGE = YES (was NO)\n"; else s6=""; + config_err("warning: enabling OPTIMIZE_OUTPUT_VHDL assumes the following settings:\n" - "%s%s%s%s%s",s1,s2,s3,s4,s5 + "%s%s%s%s%s%s",s1,s2,s3,s4,s5,s6 ); Config_getBool("INLINE_INHERITED_MEMB") = FALSE; @@ -1498,6 +1501,7 @@ void Config::check() Config_getBool("HIDE_SCOPE_NAMES") = TRUE; Config_getBool("EXTRACT_PRIVATE") = TRUE; Config_getBool("ENABLE_PREPROCESSING") = FALSE; + Config_getBool("EXTRACT_PACKAGE") = TRUE; } } diff --git a/src/config.xml b/src/config.xml index 20eb5ac..8e12fe0 100644 --- a/src/config.xml +++ b/src/config.xml @@ -652,6 +652,8 @@ blank the following patterns are tested: <value name='*.php3'/> <value name='*.inc'/> <value name='*.m'/> + <value name='*.markdown'/> + <value name='*.md'/> <value name='*.mm'/> <value name='*.dox'/> <value name='*.py'/> diff --git a/src/configoptions.cpp b/src/configoptions.cpp index d34de2a..3573248 100644 --- a/src/configoptions.cpp +++ b/src/configoptions.cpp @@ -928,6 +928,8 @@ void addConfigOptions(Config *cfg) cl->addValue("*.php3"); cl->addValue("*.inc"); cl->addValue("*.m"); + cl->addValue("*.markdown"); + cl->addValue("*.md"); cl->addValue("*.mm"); cl->addValue("*.dox"); cl->addValue("*.py"); diff --git a/src/definition.cpp b/src/definition.cpp index b917cfe..18e6253 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -377,13 +377,20 @@ void Definition::addSectionsToIndex() { //printf(" level=%d title=%s\n",level,si->title.data()); int nextLevel = (int)si->type; + int i; if (nextLevel>level) { - Doxygen::indexList.incContentsDepth(); + for (i=level;i<nextLevel;i++) + { + Doxygen::indexList.incContentsDepth(); + } } else if (nextLevel<level) { - Doxygen::indexList.decContentsDepth(); + for (i=nextLevel;i<level;i++) + { + Doxygen::indexList.decContentsDepth(); + } } Doxygen::indexList.addContentsItem(TRUE,si->title, getReference(), @@ -508,7 +515,7 @@ void Definition::_setDocumentation(const char *d,const char *docFile,int docLine QCString doc = d; if (stripWhiteSpace) { - doc = stripLeadingAndTrailingEmptyLines(doc); + doc = stripLeadingAndTrailingEmptyLines(doc,docLine); } else // don't strip whitespace { diff --git a/src/diagram.cpp b/src/diagram.cpp index c40002c..07fb4aa 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -209,7 +209,12 @@ QCString DiagramItem::label() const { // we use classDef->name() here and not diplayName() in order // to get the name used in the inheritance relation. - result=insertTemplateSpecifierInScope(classDef->name(),templSpec); + QCString n = classDef->name(); + if (n.right(2)=="-g" || n.right(2)=="-p") + { + n = n.left(n.length()-2); + } + result=insertTemplateSpecifierInScope(n,templSpec); } else { diff --git a/src/docparser.cpp b/src/docparser.cpp index 20f365a..17d9685 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -3288,6 +3288,57 @@ int DocHtmlCell::parseXml() return retval; } +int DocHtmlCell::rowSpan() const +{ + int retval = 0; + HtmlAttribList attrs = attribs(); + uint i; + for (i=0; i<attrs.count(); ++i) + { + if (attrs.at(i)->name.lower()=="rowspan") + { + retval = attrs.at(i)->value.toInt(); + break; + } + } + return retval; +} + +int DocHtmlCell::colSpan() const +{ + int retval = 1; + HtmlAttribList attrs = attribs(); + uint i; + for (i=0; i<attrs.count(); ++i) + { + if (attrs.at(i)->name.lower()=="colspan") + { + retval = QMAX(1,attrs.at(i)->value.toInt()); + break; + } + } + return retval; +} + +DocHtmlCell::Alignment DocHtmlCell::alignment() const +{ + HtmlAttribList attrs = attribs(); + uint i; + for (i=0; i<attrs.count(); ++i) + { + if (attrs.at(i)->name.lower()=="align") + { + if (attrs.at(i)->value.lower()=="center") + return Center; + else if (attrs.at(i)->value.lower()=="right") + return Right; + else return Left; + } + } + return Left; +} + + //--------------------------------------------------------------------------- int DocHtmlRow::parse() @@ -3482,6 +3533,8 @@ getrow: retval=tr->parse(); } + computeTableGrid(); + DBG(("DocHtmlTable::parse() end\n")); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); @@ -3524,23 +3577,82 @@ int DocHtmlTable::parseXml() isHeader=FALSE; } + computeTableGrid(); + DBG(("DocHtmlTable::parseXml() end\n")); DocNode *n=g_nodeStack.pop(); ASSERT(n==this); return retval==RetVal_EndTable ? RetVal_OK : retval; } -uint DocHtmlTable::numCols() const +struct ActiveRowSpan { - uint cols=0; - QListIterator<DocNode> cli(m_children); - DocNode *n; - for (cli.toFirst();(n=cli.current());++cli) - { - ASSERT(n->kind()==DocNode::Kind_HtmlRow); - cols=QMAX(cols,((DocHtmlRow *)n)->numCells()); + ActiveRowSpan(int rows,int col) : rowsLeft(rows), column(col) {} + int rowsLeft; + int column; +}; + +typedef QList<ActiveRowSpan> RowSpanList; + +/** determines the location of all cells in a grid, resolving row and + column spans. For each the total number of visible cells is computed, + and the total number of visible columns over all rows is stored. + */ +void DocHtmlTable::computeTableGrid() +{ + //printf("computeTableGrid()\n"); + RowSpanList rowSpans; + rowSpans.setAutoDelete(TRUE); + int maxCols=0; + int rowIdx=1; + QListIterator<DocNode> li(children()); + DocNode *rowNode; + for (li.toFirst();(rowNode=li.current());++li) + { + int colIdx=1; + int cells=0; + if (rowNode->kind()==DocNode::Kind_HtmlRow) + { + uint i; + DocHtmlRow *row = (DocHtmlRow*)rowNode; + QListIterator<DocNode> rli(row->children()); + DocNode *cellNode; + for (rli.toFirst();(cellNode=rli.current());++rli) + { + if (cellNode->kind()==DocNode::Kind_HtmlCell) + { + DocHtmlCell *cell = (DocHtmlCell*)cellNode; + int rs = cell->rowSpan(); + int cs = cell->colSpan(); + + for (i=0;i<rowSpans.count();i++) + { + if (rowSpans.at(i)->rowsLeft>0 && + rowSpans.at(i)->column==colIdx) + { + colIdx=rowSpans.at(i)->column+1; + cells++; + } + } + if (rs>0) rowSpans.append(new ActiveRowSpan(rs,colIdx)); + //printf("found cell at (%d,%d)\n",rowIdx,colIdx); + cell->setRowIndex(rowIdx); + cell->setColumnIndex(colIdx); + colIdx+=cs; + cells++; + } + } + for (i=0;i<rowSpans.count();i++) + { + if (rowSpans.at(i)->rowsLeft>0) rowSpans.at(i)->rowsLeft--; + } + row->setVisibleCells(cells); + row->setRowIndex(rowIdx); + rowIdx++; + } + if (colIdx-1>maxCols) maxCols=colIdx-1; } - return cols; + m_numCols = maxCols; } void DocHtmlTable::accept(DocVisitor *v) @@ -3900,6 +4012,8 @@ int DocHtmlList::parse() } else // found some other tag { + // add dummy item to obtain valid HTML + m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <li> tag but " "found <%s%s> instead!",g_token->endTag?"/":"",qPrint(g_token->name)); doctokenizerYYpushBackHtmlTag(g_token->name); @@ -3908,12 +4022,16 @@ int DocHtmlList::parse() } else if (tok==0) // premature end of comment { + // add dummy item to obtain valid HTML + m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: unexpected end of comment while looking" " for a html list item"); goto endlist; } else // token other than html token { + // add dummy item to obtain valid HTML + m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: expected <li> tag but found %s token instead!", tokToString(tok)); goto endlist; @@ -4063,6 +4181,12 @@ int DocSimpleList::parse() //-------------------------------------------------------------------------- +DocAutoListItem::DocAutoListItem(DocNode *parent,int indent,int num) + : m_indent(indent), m_itemNum(num) +{ + m_parent = parent; +} + int DocAutoListItem::parse() { int retval = RetVal_OK; @@ -4103,6 +4227,14 @@ int DocAutoListItem::parse() //-------------------------------------------------------------------------- +DocAutoList::DocAutoList(DocNode *parent,int indent,bool isEnumList, + int depth) : + m_indent(indent), m_isEnumList(isEnumList), + m_depth(depth) +{ + m_parent = parent; +} + int DocAutoList::parse() { int retval = RetVal_OK; @@ -4111,13 +4243,23 @@ int DocAutoList::parse() // first item or sub list => create new list do { + if (g_token->id!=-1) // explicitly numbered list + { + num=g_token->id; // override num with real number given + } DocAutoListItem *li = new DocAutoListItem(this,m_indent,num++); m_children.append(li); retval=li->parse(); + //printf("DocAutoList::parse(): retval=0x%x g_token->indent=%d m_indent=%d " + // "m_isEnumList=%d g_token->isEnumList=%d g_token->name=%s\n", + // retval,g_token->indent,m_indent,m_isEnumList,g_token->isEnumList, + // g_token->name.data()); + //printf("num=%d g_token->id=%d\n",num,g_token->id); } - while (retval==TK_LISTITEM && // new list item - m_indent==g_token->indent && // at same indent level - m_isEnumList==g_token->isEnumList // of the same kind + while (retval==TK_LISTITEM && // new list item + m_indent==g_token->indent && // at same indent level + m_isEnumList==g_token->isEnumList && // of the same kind + (g_token->id==-1 || g_token->id>=num) // increasing number (or no number) ); DocNode *n=g_nodeStack.pop(); @@ -5762,6 +5904,10 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta warn_doc_error(g_fileName,doctokenizerYYlineno,"warning: Unsupported xml/html tag <%s> found", qPrint(tagName)); m_children.append(new DocWord(this, "<"+tagName+tagHtmlAttribs.toString()+">")); break; + case XML_INHERITDOC: + handleInheritDoc(); + break; + default: // we should not get here! ASSERT(0); @@ -5917,6 +6063,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case XML_SEE: case XML_SEEALSO: case XML_EXCEPTION: + case XML_INHERITDOC: retval = RetVal_CloseXml; break; case XML_C: @@ -6032,7 +6179,8 @@ reparsetoken: DocAutoList *al=0; do { - al = new DocAutoList(this,g_token->indent,g_token->isEnumList, depth); + al = new DocAutoList(this,g_token->indent, + g_token->isEnumList,depth); m_children.append(al); retval = al->parse(); } while (retval==TK_LISTITEM && // new list diff --git a/src/docparser.h b/src/docparser.h index 21a5a25..8e2fae2 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -534,10 +534,7 @@ class DocCopy : /*public CompAccept<DocCopy>,*/ public DocNode class DocAutoList : public CompAccept<DocAutoList>, public DocNode { public: - DocAutoList(DocNode *parent,int indent,bool isEnumList, - int depth) : - m_indent(indent), m_isEnumList(isEnumList), - m_depth(depth) { m_parent = parent; } + DocAutoList(DocNode *parent,int indent,bool isEnumList,int depth); Kind kind() const { return Kind_AutoList; } bool isEnumList() const { return m_isEnumList; } int indent() const { return m_indent; } @@ -555,9 +552,7 @@ class DocAutoList : public CompAccept<DocAutoList>, public DocNode class DocAutoListItem : public CompAccept<DocAutoListItem>, public DocNode { public: - DocAutoListItem(DocNode *parent,int indent,int num) - : m_indent(indent), m_itemNum(num) - { m_parent = parent; } + DocAutoListItem(DocNode *parent,int indent,int num); Kind kind() const { return Kind_AutoListItem; } int itemNumber() const { return m_itemNum; } void accept(DocVisitor *v) { CompAccept<DocAutoListItem>::accept(this,v); } @@ -1144,10 +1139,13 @@ class DocHtmlDescData : public CompAccept<DocHtmlDescData>, public DocNode /*! @brief Node representing a HTML table cell */ class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode { + friend class DocHtmlTable; public: + enum Alignment { Left, Right, Center }; DocHtmlCell(DocNode *parent,const HtmlAttribList &attribs,bool isHeading) : m_isHeading(isHeading), - m_isFirst(FALSE), m_isLast(FALSE), m_attribs(attribs) { m_parent = parent; } + m_isFirst(FALSE), m_isLast(FALSE), m_attribs(attribs), + m_rowIdx(-1), m_colIdx(-1) { m_parent = parent; } bool isHeading() const { return m_isHeading; } bool isFirst() const { return m_isFirst; } bool isLast() const { return m_isLast; } @@ -1158,12 +1156,21 @@ class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode const HtmlAttribList &attribs() const { return m_attribs; } int parse(); int parseXml(); + int rowIndex() const { return m_rowIdx; } + int columnIndex() const { return m_colIdx; } + int rowSpan() const; + int colSpan() const; + Alignment alignment() const; private: + void setRowIndex(int idx) { m_rowIdx = idx; } + void setColumnIndex(int idx) { m_colIdx = idx; } bool m_isHeading; bool m_isFirst; bool m_isLast; - HtmlAttribList m_attribs; + HtmlAttribList m_attribs; + int m_rowIdx; + int m_colIdx; }; /*! @brief Node representing a HTML table caption */ @@ -1185,9 +1192,10 @@ class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode /*! @brief Node representing a HTML table row */ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode { + friend class DocHtmlTable; public: DocHtmlRow(DocNode *parent,const HtmlAttribList &attribs) : - m_attribs(attribs) { m_parent = parent; } + m_attribs(attribs), m_visibleCells(-1), m_rowIdx(-1) { m_parent = parent; } Kind kind() const { return Kind_HtmlRow; } uint numCells() const { return m_children.count(); } void accept(DocVisitor *v) { CompAccept<DocHtmlRow>::accept(this,v); } @@ -1197,9 +1205,15 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode bool isHeading() const { return m_children.count()>0 && ((DocHtmlCell*)m_children.getFirst())->isHeading(); } + void setVisibleCells(int n) { m_visibleCells = n; } + int visibleCells() const { return m_visibleCells; } + int rowIndex() const { return m_rowIdx; } private: + void setRowIndex(int idx) { m_rowIdx = idx; } HtmlAttribList m_attribs; + int m_visibleCells; + int m_rowIdx; }; /*! @brief Node representing a HTML table */ @@ -1215,12 +1229,14 @@ class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode const HtmlAttribList &attribs() const { return m_attribs; } int parse(); int parseXml(); - uint numCols() const; + uint numColumns() const { return m_numCols; } void accept(DocVisitor *v); private: + void computeTableGrid(); DocHtmlCaption *m_caption; HtmlAttribList m_attribs; + int m_numCols; }; /*! @brief Node representing an HTML blockquote */ diff --git a/src/docsets.cpp b/src/docsets.cpp index 272ed69..6852c41 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -163,7 +163,10 @@ void DocSets::initialize() void DocSets::finalize() { - m_nts << indent() << " </Node>" << endl; + if (!m_firstNode.at(m_dc-1)) + { + m_nts << indent() << " </Node>" << endl; + } m_dc--; m_nts << " </Subnodes>" << endl; m_nts << " </Node>" << endl; @@ -225,7 +228,9 @@ void DocSets::addContentsItem(bool isDir, m_firstNode.at(m_dc-1)=FALSE; m_nts << indent() << " <Node>" << endl; m_nts << indent() << " <Name>" << convertToXML(name) << "</Name>" << endl; - m_nts << indent() << " <Path>" << file << Doxygen::htmlFileExtension << "</Path>" << endl; + m_nts << indent() << " <Path>"; + m_nts << file << Doxygen::htmlFileExtension; + m_nts << "</Path>" << endl; if (anchor) { m_nts << indent() << " <Anchor>" << anchor << "</Anchor>" << endl; diff --git a/src/doctokenizer.l b/src/doctokenizer.l index c1c6e19..7f11aca 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -328,7 +328,7 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z OPTSTARS ("//"{BLANK}*)?"*"*{BLANK}* LISTITEM {BLANK}*[-]("#")?{WS} MLISTITEM {BLANK}*[+*]{WS} -OLISTITEM {BLANK}*[1-9][0-9]*"."{WS} +OLISTITEM {BLANK}*[1-9][0-9]*"."{BLANK} ENDLIST {BLANK}*"."{BLANK}*\n ATTRIB {ID}{WS}*("="{WS}*(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'"><]+))? URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=] @@ -426,6 +426,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} QCString text=yytext; int dashPos = text.findRev('-'); g_token->isEnumList = text.at(dashPos+1)=='#'; + g_token->id = -1; g_token->indent = computeIndent(yytext,dashPos); return TK_LISTITEM; } @@ -440,6 +441,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} static QRegExp re("[*+]"); int listPos = text.findRev(re); g_token->isEnumList = FALSE; + g_token->id = -1; g_token->indent = computeIndent(yytext,listPos); return TK_LISTITEM; } @@ -454,7 +456,9 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} QCString text=yytext; static QRegExp re("[1-9]"); int digitPos = text.find(re); + int dotPos = text.find('.',digitPos); g_token->isEnumList = TRUE; + g_token->id = atoi(QCString(yytext).mid(digitPos,dotPos-digitPos)); g_token->indent = computeIndent(yytext,digitPos); return TK_LISTITEM; } @@ -464,6 +468,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} text=text.right(text.length()-text.find('\n')-1); int dashPos = text.findRev('-'); g_token->isEnumList = text.at(dashPos+1)=='#'; + g_token->id = -1; g_token->indent = computeIndent(text,dashPos); return TK_LISTITEM; } @@ -479,11 +484,12 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} text=text.right(text.length()-text.find('\n')-1); int markPos = text.findRev(re); g_token->isEnumList = FALSE; + g_token->id = -1; g_token->indent = computeIndent(text,markPos); return TK_LISTITEM; } } -<St_Para>{BLANK}*\n{OLISTITEM} { /* list item on next line */ +<St_Para>({BLANK}*\n)+{OLISTITEM} { /* list item on next line */ if (!Doxygen::markdownSupport) { REJECT; @@ -491,10 +497,14 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} else { QCString text=yytext; - text=text.right(text.length()-text.find('\n')-1); + int nl=text.findRev('\n'); + int len=text.length(); + text=text.right(len-nl-1); static QRegExp re("[1-9]"); int digitPos = text.find(re); + int dotPos = text.find('.',digitPos); g_token->isEnumList = TRUE; + g_token->id = atoi(QCString(text).mid(digitPos,dotPos-digitPos)); g_token->indent = computeIndent(text,digitPos); return TK_LISTITEM; } @@ -684,7 +694,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3} } else // found end of a paragraph { - g_token->indent=computeIndent(yytext,(int)yyleng-1); + g_token->indent=computeIndent(yytext,(int)yyleng); int i; // put back the indentation (needed for list items) for (i=0;i<g_token->indent;i++) diff --git a/src/dot.cpp b/src/dot.cpp index b952ce2..e178ef1 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -1484,23 +1484,68 @@ void DotNode::setDistance(int distance) static QCString convertLabel(const QCString &l) { QCString result; + QCString bBefore("\\_/<({[: =-+@%#~?$"); + QCString bAfter(">]),;|"); const char *p=l.data(); if (p==0) return result; char c; + char cs[2]; + cs[1]=0; + int len=l.length(); + int charsLeft=len; + int sinceLast=0; + int foldLen=17; // ideal text length while ((c=*p++)) { + QCString replacement; switch(c) { - case '\\': result+="\\\\"; break; - case '\n': result+="\\n"; break; - case '<': result+="\\<"; break; - case '>': result+="\\>"; break; - case '|': result+="\\|"; break; - case '{': result+="\\{"; break; - case '}': result+="\\}"; break; - case '"': result+="\\\""; break; - default: result+=c; break; + case '\\': replacement="\\\\"; break; + case '\n': replacement="\\n"; break; + case '<': replacement="\\<"; break; + case '>': replacement="\\>"; break; + case '|': replacement="\\|"; break; + case '{': replacement="\\{"; break; + case '}': replacement="\\}"; break; + case '"': replacement="\\\""; break; + default: cs[0]=c; replacement=cs; break; } + // Some heuristics to insert newlines to prevent too long + // boxes and at the same time prevent ugly breaks + if (c=='\n') + { + result+=replacement; + foldLen = (3*foldLen+sinceLast+2)/4; + sinceLast=1; + } + else if (charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c)) + { + result+="\\n"; + result+=replacement; + foldLen = (foldLen+sinceLast+1)/2; + sinceLast=1; + } + else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 && + !isupper(c) && isupper(*p)) + { + result+=replacement; + result+="\\n"; + foldLen = (foldLen+sinceLast+1)/2; + sinceLast=0; + } + else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c)) + { + result+=replacement; + result+="\\n"; + foldLen = (foldLen+sinceLast+1)/2; + sinceLast=0; + } + else + { + result+=replacement; + sinceLast++; + } + charsLeft--; } return result; } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 5614692..0759bfe 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -500,7 +500,7 @@ static void addRelatedPage(EntryNav *rootNav) doc=root->brief+"\n\n"+root->doc+root->inbodyDocs; } PageDef *pd = addRelatedPage(root->name,root->args,doc,root->anchors, - root->fileName,root->startLine, + root->docFile,root->docLine, root->sli, gd,rootNav->tagInfo(), root->lang @@ -3942,7 +3942,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, for (mnii.toFirst();(mi=mnii.current());++mnii) { MemberDef *md=mi->memberDef; - if (md->isVariable()) // for each member variable in this class + if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class { //printf(" Found variable %s in class %s\n",md->name().data(),masterCd->name().data()); QCString type=removeRedundantWhiteSpace(md->typeString()); @@ -4483,7 +4483,7 @@ static bool findClassRelation( if (cd->isCSharp() && i!=-1) // C# generic -> add internal -g postfix { baseClassName+="-g"; - templSpec.resize(0); + //templSpec.resize(0); } if (!found) @@ -4556,8 +4556,8 @@ static bool findClassRelation( else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument)) { Debug::print(Debug::Classes,0, - " New undocumented base class `%s' baseClassName=%s isArtificial=%d\n", - biName.data(),baseClassName.data(),isArtificial + " New undocumented base class `%s' baseClassName=%s templSpec=%s isArtificial=%d\n", + biName.data(),baseClassName.data(),templSpec.data(),isArtificial ); baseClass=0; if (isATemplateArgument) @@ -6936,6 +6936,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav) if (!name.isEmpty()) { + //printf("** name=%s\n",name.data()); MemberName *mn = mnsd->find(name); // for all members with this name if (mn) { @@ -6945,23 +6946,26 @@ static void addEnumValuesToEnums(EntryNav *rootNav) { if (md->isEnumerate() && rootNav->children()) { + //printf(" enum with %d children\n",rootNav->children()->count()); EntryNavListIterator eli(*rootNav->children()); // for each enum value EntryNav *e; for (;(e=eli.current());++eli) { SrcLangExt sle; - if (rootNav->fileDef() && - ( (sle=getLanguageFromFileName(rootNav->fileDef()->name()))==SrcLangExt_CSharp - || sle==SrcLangExt_Java || sle==SrcLangExt_XML - ) + if ( + (sle=rootNav->lang())==SrcLangExt_CSharp || + sle==SrcLangExt_Java || + sle==SrcLangExt_XML ) { - // Unlike C++, for C# enum value are only inside the enum + // Unlike C++, for C# & Java enum values are only inside the enum // scope, so we must create them here and only add them to the // enum e->loadEntry(g_storage); Entry *root = e->entry(); - if (md->qualifiedName()==rootNav->name()) // enum value scope matches that of the enum + //printf("md->qualifiedName()=%s rootNav->name()=%s\n", + // md->qualifiedName().data(),rootNav->name().data()); + if (md->qualifiedName()==substitute(rootNav->name(),"::",".")) // enum value scope matches that of the enum { MemberDef *fmd=new MemberDef( root->fileName,root->startLine, @@ -8223,7 +8227,7 @@ static void findMainPage(EntryNav *rootNav) QCString title=root->args.stripWhiteSpace(); //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index"; QCString indexName="index"; - Doxygen::mainPage = new PageDef(root->fileName,root->startLine, + Doxygen::mainPage = new PageDef(root->docFile,root->docLine, indexName, root->brief+root->doc+root->inbodyDocs,title); //setFileNameForSections(root->anchors,"index",Doxygen::mainPage); Doxygen::mainPage->setFileName(indexName); diff --git a/src/doxygen.css b/src/doxygen.css index 30b6261..831831a 100644 --- a/src/doxygen.css +++ b/src/doxygen.css @@ -417,11 +417,14 @@ table.memberdecls { } .memname { - white-space: nowrap; font-weight: bold; margin-left: 6px; } +.memname td { + vertical-align: bottom; +} + .memproto, dl.reflist dt { border-top: 1px solid ##B4; border-left: 1px solid ##B4; diff --git a/src/doxygen_css.h b/src/doxygen_css.h index a3e3589..4b8f7d7 100644 --- a/src/doxygen_css.h +++ b/src/doxygen_css.h @@ -417,11 +417,14 @@ "}\n" "\n" ".memname {\n" -" white-space: nowrap;\n" " font-weight: bold;\n" " margin-left: 6px;\n" "}\n" "\n" +".memname td {\n" +" vertical-align: bottom;\n" +"}\n" +"\n" ".memproto, dl.reflist dt {\n" " border-top: 1px solid ##B4;\n" " border-left: 1px solid ##B4;\n" diff --git a/src/fortrancode.l b/src/fortrancode.l index d7766f4..f4ee358 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -593,9 +593,8 @@ void endScope() // fprintf(stderr,"===> endScope %s",yytext); if (scopeStack.isEmpty()) { - fprintf(stderr,"WARNING: fortrancode.l: stack empty!"); + //fprintf(stderr,"WARNING: fortrancode.l: stack empty!\n"); return; - //exit(-1); } Scope *scope = scopeStack.getLast(); diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 4951b03..4816b50 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -520,6 +520,7 @@ void FTVHelp::finalize() */ void FTVHelp::incContentsDepth() { + //printf("incContentsDepth() indent=%d\n",m_indent); m_indent++; ASSERT(m_indent<MAX_INDENT); } @@ -530,16 +531,20 @@ void FTVHelp::incContentsDepth() */ void FTVHelp::decContentsDepth() { + //printf("decContentsDepth() indent=%d\n",m_indent); ASSERT(m_indent>0); if (m_indent>0) { m_indent--; QList<FTVNode> *nl = &m_indentNodes[m_indent]; FTVNode *parent = nl->getLast(); - QList<FTVNode> *children = &m_indentNodes[m_indent+1]; - while (!children->isEmpty()) + if (parent) { - parent->children.append(children->take(0)); + QList<FTVNode> *children = &m_indentNodes[m_indent+1]; + while (!children->isEmpty()) + { + parent->children.append(children->take(0)); + } } } } diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 60f5104..57d04f7 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -660,7 +660,7 @@ void GroupDef::writeFiles(OutputList &ol,const QCString &title) if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(fd->getOutputFileBase()); - ol.parseDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),FALSE,FALSE); + ol.parseDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE); ol.endMemberDescription(); } fd=fileList->next(); @@ -678,8 +678,18 @@ void GroupDef::writeNamespaces(OutputList &ol,const QCString &title) void GroupDef::writeNestedGroups(OutputList &ol,const QCString &title) { // write list of groups + int count=0; if (groupList->count()>0) { + GroupDef *gd=groupList->first(); + while (gd) + { + if (gd->isVisible()) count++; + gd=groupList->next(); + } + } + if (count>0) + { ol.startMemberHeader("groups"); ol.parseText(title); ol.endMemberHeader(); @@ -687,21 +697,24 @@ void GroupDef::writeNestedGroups(OutputList &ol,const QCString &title) GroupDef *gd=groupList->first(); while (gd) { - ol.startMemberItem(gd->getOutputFileBase(),0); - //ol.docify(theTranslator->trGroup(FALSE,TRUE)); - //ol.docify(" "); - ol.insertMemberAlign(); - ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); - if (!Config_getString("GENERATE_TAGFILE").isEmpty()) - { - Doxygen::tagFile << " <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl; - } - ol.endMemberItem(); - if (!gd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) + if (gd->isVisible()) { - ol.startMemberDescription(gd->getOutputFileBase()); - ol.parseDoc(briefFile(),briefLine(),gd,0,gd->briefDescription(),FALSE,FALSE); - ol.endMemberDescription(); + ol.startMemberItem(gd->getOutputFileBase(),0); + //ol.docify(theTranslator->trGroup(FALSE,TRUE)); + //ol.docify(" "); + ol.insertMemberAlign(); + ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); + if (!Config_getString("GENERATE_TAGFILE").isEmpty()) + { + Doxygen::tagFile << " <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl; + } + ol.endMemberItem(); + if (!gd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) + { + ol.startMemberDescription(gd->getOutputFileBase()); + ol.parseDoc(briefFile(),briefLine(),gd,0,gd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE); + ol.endMemberDescription(); + } } gd=groupList->next(); } @@ -1450,3 +1463,13 @@ void GroupDef::sortSubGroups() groupList->sort(); } +bool GroupDef::isLinkableInProject() const +{ + return !isReference() && isLinkable(); +} + +bool GroupDef::isLinkable() const +{ + return hasUserDocumentation(); +} + diff --git a/src/groupdef.h b/src/groupdef.h index a55137f..5c83b81 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -68,15 +68,9 @@ class GroupDef : public Definition void writeDocumentation(OutputList &ol); void writeMemberPages(OutputList &ol); void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const; - int countMembers() const; - bool isLinkableInProject() const - { - return !isReference(); - } - bool isLinkable() const - { - return TRUE; - } + int countMembers() const; + bool isLinkableInProject() const; + bool isLinkable() const; bool isASubGroup() const; void computeAnchors(); diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 8e8cdbd..dc73510 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -1376,7 +1376,7 @@ void HtmlDocVisitor::visitPre(DocRef *ref) { // when ref->isSubPage()==TRUE we use ref->file() for HTML and // ref->anchor() for LaTeX/RTF - startLink(ref->ref(),ref->file(),ref->relPath(),ref->isSubPage() ? 0 : ref->anchor()); + startLink(ref->ref(),ref->file(),ref->relPath(),ref->isSubPage() ? QCString() : ref->anchor()); } if (!ref->hasLinkText()) filter(ref->targetTitle()); } diff --git a/src/index.cpp b/src/index.cpp index 8f725d5..d92fbc5 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1716,10 +1716,7 @@ void addClassMemberNameToIndex(MemberDef *md) static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS"); ClassDef *cd=0; - if (md->getLanguage()==SrcLangExt_VHDL) - { - VhdlDocGen::adjustRecordMember(md); - } + if (md->isLinkableInProject() && (cd=md->getClassDef()) && @@ -2735,6 +2732,8 @@ static void writeSubPages(PageDef *pd) bool hasSubPages = subPage->hasSubPages(); bool hasSections = subPage->hasSections(); + //printf("subpage %s: addToIndex=%d hasSubPages=%d hasSections=%d\n", + // pd->name().data(),addToIndex,hasSubPages,hasSections); if (addToIndex) { Doxygen::indexList.addContentsItem(hasSubPages,pageTitle, @@ -2933,6 +2932,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* * That is why we should not check if it was visited */ if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) && + gd->isVisible() && (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default ) { @@ -3002,7 +3002,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { - if (md->name().find('@')==-1) + if (md->isVisible() && md->name().find('@')==-1) { Doxygen::indexList.addContentsItem(FALSE, md->name(),md->getReference(), @@ -3017,9 +3017,12 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ClassDef *cd; for (;(cd=it.current());++it) { - Doxygen::indexList.addContentsItem(FALSE, - cd->localName(),cd->getReference(), - cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE); + if (cd->isVisible()) + { + Doxygen::indexList.addContentsItem(FALSE, + cd->localName(),cd->getReference(), + cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE); + } } } else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex) @@ -3028,9 +3031,12 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* NamespaceDef *nd; for (;(nd=it.current());++it) { - Doxygen::indexList.addContentsItem(FALSE, - nd->localName(),nd->getReference(), - nd->getOutputFileBase(),0,FALSE,FALSE); + if (nd->isVisible()) + { + Doxygen::indexList.addContentsItem(FALSE, + nd->localName(),nd->getReference(), + nd->getOutputFileBase(),0,FALSE,FALSE); + } } } else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex) @@ -3039,9 +3045,12 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* FileDef *fd; for (;(fd=it.current());++it) { - Doxygen::indexList.addContentsItem(FALSE, - fd->displayName(),fd->getReference(), - fd->getOutputFileBase(),0,FALSE,FALSE); + if (fd->isVisible()) + { + Doxygen::indexList.addContentsItem(FALSE, + fd->displayName(),fd->getReference(), + fd->getOutputFileBase(),0,FALSE,FALSE); + } } } else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex) @@ -3053,9 +3062,12 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* DirDef *dd; for (;(dd=it.current());++it) { - Doxygen::indexList.addContentsItem(FALSE, - dd->shortName(),dd->getReference(), - dd->getOutputFileBase(),0,FALSE,FALSE); + if (dd->isVisible()) + { + Doxygen::indexList.addContentsItem(FALSE, + dd->shortName(),dd->getReference(), + dd->getOutputFileBase(),0,FALSE,FALSE); + } } } } @@ -3423,9 +3435,9 @@ static void writeIndex(OutputList &ol) ol.disableAllBut(OutputGenerator::Html); QCString defFileName = - Doxygen::mainPage ? Doxygen::mainPage->getDefFileName().data() : "[generated]"; + Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]"; int defLine = - Doxygen::mainPage ? Doxygen::mainPage->getDefLine() : -1; + Doxygen::mainPage ? Doxygen::mainPage->docLine() : -1; QCString title; if (!mainPageHasTitle()) @@ -3500,6 +3512,11 @@ static void writeIndex(OutputList &ol) if (Doxygen::mainPage) { Doxygen::insideMainPage=TRUE; + if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections()) + { + Doxygen::mainPage->writeToc(ol); + } + ol.startTextBlock(); ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0, Doxygen::mainPage->documentation(),TRUE,FALSE diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 4c4dc86..0e9d0c2 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -60,6 +60,7 @@ static const char *getSectionName(int level) return secLabels[QMIN(maxLevels-1,l)]; } +#if 0 static int rowspan(DocHtmlCell *cell) { int retval = 0; @@ -76,6 +77,22 @@ static int rowspan(DocHtmlCell *cell) return retval; } +static int colspan(DocHtmlCell *cell) +{ + int retval = 1; + HtmlAttribList attrs = cell->attribs(); + uint i; + for (i=0; i<attrs.count(); ++i) + { + if (attrs.at(i)->name.lower()=="colspan") + { + retval = QMAX(1,attrs.at(i)->value.toInt()); + break; + } + } + return retval; +} + static int align(DocHtmlCell *cell) { HtmlAttribList attrs = cell->attribs(); @@ -94,6 +111,70 @@ static int align(DocHtmlCell *cell) return 0; } +struct ActiveRowSpan +{ + ActiveRowSpan(int rows,int col) : rowsLeft(rows), column(col) {} + int rowsLeft; + int column; +}; + +typedef QList<ActiveRowSpan> RowSpanList; + +static int determineNumCols(DocHtmlTable *table) +{ + RowSpanList rowSpans; + rowSpans.setAutoDelete(TRUE); + int maxCols=0; + int rowIdx=1; + QListIterator<DocNode> li(table->children()); + DocNode *rowNode; + for (li.toFirst();(rowNode=li.current());++li) + { + int colIdx=1; + int cells=0; + if (rowNode->kind()==DocNode::Kind_HtmlRow) + { + uint i; + DocHtmlRow *row = (DocHtmlRow*)rowNode; + QListIterator<DocNode> rli(row->children()); + DocNode *cellNode; + for (rli.toFirst();(cellNode=rli.current());++rli) + { + if (cellNode->kind()==DocNode::Kind_HtmlCell) + { + DocHtmlCell *cell = (DocHtmlCell*)cellNode; + int rs = rowspan(cell); + int cs = colspan(cell); + + for (i=0;i<rowSpans.count();i++) + { + if (rowSpans.at(i)->rowsLeft>0 && + rowSpans.at(i)->column==colIdx) + { + colIdx=rowSpans.at(i)->column+1; + cells++; + } + } + if (rs>0) rowSpans.append(new ActiveRowSpan(rs,colIdx)); + cell->setRowIndex(rowIdx); + cell->setColumnIndex(colIdx); + colIdx+=cs; + cells++; + } + } + for (i=0;i<rowSpans.count();i++) + { + if (rowSpans.at(i)->rowsLeft>0) rowSpans.at(i)->rowsLeft--; + } + row->setVisibleCells(cells); + rowIdx++; + } + if (colIdx-1>maxCols) maxCols=colIdx-1; + } + return maxCols; +} +#endif + QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) { QCString result; @@ -121,9 +202,10 @@ LatexDocVisitor::LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci, const char *langExt,bool insideTabbing) : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE), m_insideItem(FALSE), m_hide(FALSE), m_insideTabbing(insideTabbing), - m_langExt(langExt), m_currentColumn(0), - m_inRowspan(FALSE) + m_insideTable(FALSE), m_langExt(langExt), m_currentColumn(0), + m_inRowspan(FALSE), m_inColspan(FALSE) { + m_rowSpans.setAutoDelete(TRUE); } //-------------------------------------- @@ -241,7 +323,8 @@ void LatexDocVisitor::visit(DocURL *u) void LatexDocVisitor::visit(DocLineBreak *) { if (m_hide) return; - m_t << "\\par\n"; + if (m_insideTable) m_t << "\\newline\n"; + else m_t << "\\par\n"; } void LatexDocVisitor::visit(DocHorRuler *) @@ -259,7 +342,7 @@ void LatexDocVisitor::visit(DocStyleChange *s) if (s->enable()) m_t << "{\\bfseries "; else m_t << "}"; break; case DocStyleChange::Italic: - if (s->enable()) m_t << "{\\itshape "; else m_t << "\\/}"; + if (s->enable()) m_t << "{\\itshape "; else m_t << "}"; break; case DocStyleChange::Code: if (s->enable()) m_t << "{\\ttfamily "; else m_t << "}"; @@ -862,17 +945,21 @@ void LatexDocVisitor::visitPost(DocHtmlDescData *) void LatexDocVisitor::visitPre(DocHtmlTable *t) { - m_rowspanIndices.clear(); + m_rowSpans.clear(); + m_insideTable=TRUE; if (m_hide) return; if (t->hasCaption()) { m_t << "\\begin{table}[h]"; } - m_t << "\\begin{TabularC}{" << t->numCols() << "}\n\\hline\n"; + m_t << "\\begin{TabularC}{" << t->numColumns() << "}\n"; + m_numCols = t->numColumns(); + m_t << "\\hline\n"; } void LatexDocVisitor::visitPost(DocHtmlTable *t) { + m_insideTable=FALSE; if (m_hide) return; if (t->hasCaption()) { @@ -902,32 +989,67 @@ void LatexDocVisitor::visitPre(DocHtmlRow *r) if (r->isHeading()) m_t << "\\rowcolor{lightgray}"; } -void LatexDocVisitor::visitPost(DocHtmlRow *) +void LatexDocVisitor::visitPost(DocHtmlRow *row) { if (m_hide) return; + int c=m_currentColumn; + while (c<=m_numCols) // end of row while inside a row span? + { + uint i; + for (i=0;i<m_rowSpans.count();i++) + { + ActiveRowSpan *span = m_rowSpans.at(i); + //printf(" founc row span: column=%d rs=%d cs=%d rowIdx=%d cell->rowIdx=%d\n", + // span->column, span->rowSpan,span->colSpan,row->rowIndex(),span->cell->rowIndex()); + if (span->rowSpan>0 && span->column==c && // we are at a cell in a row span + row->rowIndex()>span->cell->rowIndex() // but not the row that started the span + ) + { + m_t << "&"; + if (span->colSpan>1) // row span is also part of a column span + { + m_t << "\\multicolumn{" << span->colSpan << "}{"; + m_t << "p{(\\linewidth-\\tabcolsep*" + << m_numCols << "-\\arrayrulewidth*" + << row->visibleCells() << ")*" + << span->colSpan <<"/"<< m_numCols << "}|}{}"; + } + else // solitary row span + { + m_t << "\\multicolumn{1}{c|}{}"; + } + } + } + c++; + } + m_t << "\\\\"; - QMap<int, int>::Iterator it; int col = 1; - for (it = m_rowspanIndices.begin(); it != m_rowspanIndices.end(); ++it) + uint i; + for (i=0;i<m_rowSpans.count();i++) { - it.data()--; - if (it.data () <= 0) + ActiveRowSpan *span = m_rowSpans.at(i); + if (span->rowSpan>0) span->rowSpan--; + if (span->rowSpan<=0) { - m_rowspanIndices.remove(it); + // inactive span } - else if (0 < it.data() - col) + else if (span->column>col) { - m_t << "\\cline{" << col << "-" << it.data() - col << "}"; + m_t << "\\cline{" << col << "-" << (span->column-1) << "}"; + col = span->column+span->colSpan; + } + else + { + col = span->column+span->colSpan; } - - col = 1 + it.data(); } - if (col <= m_currentColumn) + if (col <= m_numCols) { - m_t << "\\cline{" << col << "-" << m_currentColumn << "}"; + m_t << "\\cline{" << col << "-" << m_numCols << "}"; } m_t << "\n"; @@ -936,30 +1058,82 @@ void LatexDocVisitor::visitPost(DocHtmlRow *) void LatexDocVisitor::visitPre(DocHtmlCell *c) { if (m_hide) return; + + DocHtmlRow *row = 0; + if (c->parent() && c->parent()->kind()==DocNode::Kind_HtmlRow) + { + row = (DocHtmlRow*)c->parent(); + } m_currentColumn++; + //Skip columns that span from above. + uint i; + for (i=0;i<m_rowSpans.count();i++) + { + ActiveRowSpan *span = m_rowSpans.at(i); + if (span->rowSpan>0 && span->column==m_currentColumn) + { + if (row && span->colSpan>1) + { + m_t << "\\multicolumn{" << span->colSpan << "}{"; + if (m_currentColumn /*c->columnIndex()*/==1) // add extra | for first column + { + m_t << "|"; + } + m_t << "p{(\\linewidth-\\tabcolsep*" + << m_numCols << "-\\arrayrulewidth*" + << row->visibleCells() << ")*" + << span->colSpan <<"/"<< m_numCols << "}|}{}"; + m_currentColumn+=span->colSpan; + } + else + { + m_currentColumn++; + } + m_t << "&"; + } + } + +#if 0 QMap<int, int>::Iterator it = m_rowspanIndices.find(m_currentColumn); - while (it!=m_rowspanIndices.end() && 0<it.data()) + if (it!=m_rowspanIndices.end() && it.data()>0) { m_t << "&"; m_currentColumn++; it++; } +#endif - int rs = rowspan(c); + int cs = c->colSpan(); + if (cs>1 && row) + { + m_inColspan = TRUE; + m_t << "\\multicolumn{" << cs << "}{"; + if (c->columnIndex()==1) // add extra | for first column + { + m_t << "|"; + } + m_t << "p{(\\linewidth-\\tabcolsep*" + << m_numCols << "-\\arrayrulewidth*" + << row->visibleCells() << ")*" + << cs <<"/"<< m_numCols << "}|}{"; + if (c->isHeading()) m_t << "\\cellcolor{lightgray}"; + } + int rs = c->rowSpan(); if (rs>0) { m_inRowspan = TRUE; - m_rowspanIndices[m_currentColumn] = rs; + //m_rowspanIndices[m_currentColumn] = rs; + m_rowSpans.append(new ActiveRowSpan(c,rs,cs,m_currentColumn)); m_t << "\\multirow{" << rs << "}{\\linewidth}{"; } - int a = align(c); - if (a==1) + int a = c->alignment(); + if (a==DocHtmlCell::Center) { m_t << "\\PBS\\centering "; } - else if (a==2) + else if (a==DocHtmlCell::Right) { m_t << "\\PBS\\raggedleft "; } @@ -967,6 +1141,10 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c) { m_t << "{\\bf "; } + if (cs>1) + { + m_currentColumn+=cs-1; + } } void LatexDocVisitor::visitPost(DocHtmlCell *c) @@ -981,6 +1159,11 @@ void LatexDocVisitor::visitPost(DocHtmlCell *c) m_inRowspan = FALSE; m_t << "}"; } + if (m_inColspan) + { + m_inColspan = FALSE; + m_t << "}"; + } if (!c->isLast()) m_t << "&"; } diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index b325b21..a4892ce 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -22,7 +22,8 @@ #include "docvisitor.h" #include <qstack.h> #include <qcstring.h> -#include <qmap.h> +#include <qlist.h> +//#include <qmap.h> class FTextStream; class CodeOutputInterface; @@ -134,6 +135,18 @@ class LatexDocVisitor : public DocVisitor private: + struct ActiveRowSpan + { + ActiveRowSpan(DocHtmlCell *c,int rs,int cs,int col) + : cell(c), rowSpan(rs), colSpan(cs), column(col) {} + DocHtmlCell *cell; + int rowSpan; + int colSpan; + int column; + }; + + typedef QList<ActiveRowSpan> RowSpanList; + //-------------------------------------- // helper functions //-------------------------------------- @@ -166,11 +179,14 @@ class LatexDocVisitor : public DocVisitor bool m_insideItem; bool m_hide; bool m_insideTabbing; + bool m_insideTable; + int m_numCols; QStack<bool> m_enabled; QCString m_langExt; - QMap<int, int> m_rowspanIndices; + RowSpanList m_rowSpans; int m_currentColumn; bool m_inRowspan; + bool m_inColspan; }; #endif diff --git a/src/latexgen.cpp b/src/latexgen.cpp index cb36b20..ebf6a43 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -414,6 +414,7 @@ static void writeDefaultStyleSheetPart1(FTextStream &t) "\\RequirePackage{verbatim}\n" "\\RequirePackage{ifthen}\n" "\\RequirePackage{xtab}\n" + "\\RequirePackage{multirow}\n" "\\RequirePackage[table]{xcolor}\n\n"; t << "% Use helvetica font instead of times roman\n" diff --git a/src/lodepng.cpp b/src/lodepng.cpp index 8da4293..638dbf4 100644 --- a/src/lodepng.cpp +++ b/src/lodepng.cpp @@ -31,6 +31,8 @@ You are free to name this file lodepng.cpp or lodepng.c depending on your usage. #include "lodepng.h" #include "portable.h" +#define USE_BRUTE_FORCE_ENCODING 1 + #define VERSION_STRING "20080927" /* ////////////////////////////////////////////////////////////////////////// */ @@ -1033,14 +1035,71 @@ static void addLengthDistance(uivector* values, size_t length, size_t distance) uivector_push_back(values, extra_distance); } -#if 0 +#if USE_BRUTE_FORCE_ENCODING +#define encodeLZ77 encodeLZ77_brute /*the "brute force" version of the encodeLZ7 algorithm, not used anymore, kept here for reference*/ -static void encodeLZ77_brute(uivector* out, const unsigned char* in, size_t size, unsigned windowSize) +static unsigned encodeLZ77_brute(uivector* out, const unsigned char* in, size_t size, unsigned windowSize) { size_t pos; /*using pointer instead of vector for input makes it faster when NOT using optimization when compiling; no influence if optimization is used*/ for(pos = 0; pos < size; pos++) { + /*Phase 1: doxygen images often have long runs of the same color, try to find them*/ + const int minLength = 4; // Minimum length for a run to make sense + + if(pos < size - minLength * 4) + { + size_t p, fp; + size_t current_length; + + /*RGBA pixel run?*/ + p = pos; + fp = pos + 4; + current_length = 0; + + while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) + { + ++p; + ++fp; + ++current_length; + } + + if (current_length > (minLength - 1 ) * 4) /*worth using?*/ + { + uivector_push_back(out, in[pos ]); + uivector_push_back(out, in[pos + 1]); + uivector_push_back(out, in[pos + 2]); + uivector_push_back(out, in[pos + 3]); + addLengthDistance(out, current_length, 4); + + pos += current_length + 4 - 1; /*-1 for loop's pos++*/ + continue; + } + + /*RGB pixel run?*/ + p = pos; + fp = pos + 3; + current_length = 0; + + while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) + { + ++p; + ++fp; + ++current_length; + } + + if (current_length > (minLength - 1 ) * 3) /*worth using?*/ + { + uivector_push_back(out, in[pos ]); + uivector_push_back(out, in[pos + 1]); + uivector_push_back(out, in[pos + 2]); + addLengthDistance(out, current_length, 3); + + pos += current_length + 3 - 1; /*-1 for loop's pos++*/ + continue; + } + } + size_t length = 0, offset = 0; /*the length and offset found for the current position*/ size_t max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/ size_t current_offset; @@ -1082,6 +1141,8 @@ static void encodeLZ77_brute(uivector* out, const unsigned char* in, size_t size pos += (length - 1); } } /*end of the loop through each character of input*/ + + return 0; } #endif @@ -1094,6 +1155,7 @@ making HASH_NUM_CHARACTERS larger (like 8), makes the file size larger but is a making HASH_NUM_CHARACTERS smaller (like 3), makes the file size smaller but is slower */ +#if !defined(USE_BRUTE_FORCE_ENCODING) static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { unsigned result = 0; @@ -1195,6 +1257,7 @@ static unsigned encodeLZ77(uivector* out, const unsigned char* in, size_t size, uivector_cleanup(&tablepos2); return error; } +#endif /* /////////////////////////////////////////////////////////////////////////// */ diff --git a/src/markdown.cpp b/src/markdown.cpp index fb9ff9d..4f182dc 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -895,10 +895,10 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s { QCString codeFragment; convertStringFragment(codeFragment,data+f_begin,f_end-f_begin); - out.addStr("<code>"); + out.addStr("<tt>"); //out.addStr(convertToHtml(codeFragment,TRUE)); out.addStr(escapeSpecialChars(codeFragment)); - out.addStr("</code>"); + out.addStr("</tt>"); } return end; } @@ -1158,13 +1158,20 @@ static int isAtxHeader(const char *data,int size, QCString &header,QCString &id) { int i = 0, end; - int level = 0; + int level = 0, blanks=0; // find start of header text and determine heading level while (i<size && data[i]==' ') i++; - if (i>=size || data[i]!='#') return 0; + if (i>=size || data[i]!='#') + { + return 0; + } while (i<size && level<6 && data[i]=='#') i++,level++; - while (i<size && data[i]==' ') i++; + while (i<size && data[i]==' ') i++,blanks++; + if (level==1 && blanks==0) + { + return 0; // special case to prevent #someid seen as a header (see bug 671395) + } // find end of header text end=i; @@ -1588,17 +1595,26 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) QCString hTag; if (level<5 && !id.isEmpty()) { + SectionInfo::SectionType type = SectionInfo::Anchor; switch(level) { - case 1: out.addStr("@section "); break; - case 2: out.addStr("@subsection "); break; - case 3: out.addStr("@subsubsection "); break; - default: out.addStr("@paragraph "); break; + case 1: out.addStr("@section "); + type=SectionInfo::Section; + break; + case 2: out.addStr("@subsection "); + type=SectionInfo::Subsection; + break; + case 3: out.addStr("@subsubsection "); + type=SectionInfo::Subsubsection; + break; + default: out.addStr("@paragraph "); + type=SectionInfo::Paragraph; + break; } out.addStr(id); out.addStr(" "); out.addStr(header); - SectionInfo *si = new SectionInfo(g_fileName,id,header,SectionInfo::Anchor,level); + SectionInfo *si = new SectionInfo(g_fileName,id,header,type,level); if (g_current) { g_current->anchors->append(si); @@ -1909,7 +1925,8 @@ static QCString processBlocks(const QCString &s,int indent) out.addStr(id); out.addStr(" "); out.addStr(header); - SectionInfo *si = new SectionInfo(g_fileName,id,header,SectionInfo::Anchor,level); + SectionInfo *si = new SectionInfo(g_fileName,id,header, + level==1 ? SectionInfo::Section : SectionInfo::Subsection,level); if (g_current) { g_current->anchors->append(si); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 39a71f8..8ea32e0 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -2233,6 +2233,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, { bool first=TRUE; LockingPtr<MemberList> fmdl=enumFieldList(); + //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0); if (fmdl!=0) { MemberDef *fmd=fmdl->first(); diff --git a/src/pagedef.h b/src/pagedef.h index b4eded5..54aab2e 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -54,6 +54,7 @@ class PageDef : public Definition bool documentedPage() const; bool hasSubPages() const; bool hasParentPage() const; + bool showToc() const { return m_showToc; } void setPageScope(Definition *d){ m_pageScope = d; } Definition *getPageScope() const { return m_pageScope; } QCString displayName() const { return !m_title.isEmpty() ? m_title : Definition::name(); } diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index 78fa313..054cc56 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -1557,6 +1557,11 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) } m_output.closeList(); } + else if (md->argsString()!=0) + { + m_output.addFieldQuotedString("arguments", md->argsString()); + } + if (!md->initializer().isEmpty()) m_output.addFieldQuotedString("initializer", md->initializer()); @@ -2073,6 +2073,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(Start); g_yyLineNr++; } +<Command>"pragma"{B}+"once" { + g_expectGuard = FALSE; + } <Command>{ID} { // unknown directive BEGIN(IgnoreLine); } diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index 7e96c61..cd9ba7b 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -420,7 +420,7 @@ class PrintDocVisitor : public DocVisitor { indent_pre(); printf("<table rows=\"%d\" cols=\"%d\">\n", - t->numRows(),t->numCols()); + t->numRows(),t->numColumns()); } void visitPost(DocHtmlTable *) { diff --git a/src/scanner.l b/src/scanner.l index e6cbd17..7bf8f2b 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -3259,7 +3259,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } else { - if (current->section == Entry::ENUM_SEC) + if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum)) { current->program+=','; // add field terminator } @@ -3329,7 +3329,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->type.prepend(yytext); } <TypedefName>{ID} { - if (current->section == Entry::ENUM_SEC) + if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum)) { current->program+=","; // add field terminator } @@ -3350,7 +3350,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } <TypedefName>";" { /* typedef of anonymous type */ current->name.sprintf("@%d",anonCount++); - if (current->section == Entry::ENUM_SEC) + if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum)) { current->program+=','; // add field terminator } diff --git a/src/searchindex.cpp b/src/searchindex.cpp index c40791e..6757711 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -310,6 +310,7 @@ void SearchIndex::write(const char *fileName) #include "memberdef.h" #include "namespacedef.h" +#include "pagedef.h" #include "classdef.h" #include "filedef.h" #include "language.h" @@ -321,7 +322,8 @@ static const char search_script[]= ; #define MEMBER_INDEX_ENTRIES 256 -#define NUM_SEARCH_INDICES 13 + +#define NUM_SEARCH_INDICES 15 #define SEARCH_INDEX_ALL 0 #define SEARCH_INDEX_CLASSES 1 #define SEARCH_INDEX_NAMESPACES 2 @@ -335,6 +337,8 @@ static const char search_script[]= #define SEARCH_INDEX_EVENTS 10 #define SEARCH_INDEX_RELATED 11 #define SEARCH_INDEX_DEFINES 12 +#define SEARCH_INDEX_GROUPS 13 +#define SEARCH_INDEX_PAGES 14 class SearchIndexList : public SDict< QList<Definition> > { @@ -375,7 +379,7 @@ static void addMemberToSearchIndex( NamespaceDef *nd=0; FileDef *fd=0; GroupDef *gd=0; - if (isLinkable && + if (isLinkable && ( ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) || ((gd=md->getGroupDef()) && gd->isLinkable()) @@ -525,7 +529,9 @@ static const char *g_searchIndexName[NUM_SEARCH_INDICES] = "properties", "events", "related", - "defines" + "defines", + "groups", + "pages" }; @@ -547,6 +553,8 @@ class SearchIndexCategoryMapping categoryLabel[SEARCH_INDEX_EVENTS] = theTranslator->trEvents(); categoryLabel[SEARCH_INDEX_RELATED] = theTranslator->trFriends(); categoryLabel[SEARCH_INDEX_DEFINES] = theTranslator->trDefines(); + categoryLabel[SEARCH_INDEX_GROUPS] = theTranslator->trGroup(TRUE,FALSE); + categoryLabel[SEARCH_INDEX_PAGES] = theTranslator->trPage(TRUE,FALSE); } QCString categoryLabel[NUM_SEARCH_INDICES]; }; @@ -641,6 +649,68 @@ void writeJavascriptSearchIndex() } } } + + // index groups + GroupSDict::Iterator gli(*Doxygen::groupSDict); + GroupDef *gd; + for (gli.toFirst();(gd=gli.current());++gli) + { + if (gd->isLinkable()) + { + QCString title = gd->groupTitle(); + if (!title.isEmpty()) // TODO: able searching for all word in the title + { + uchar charCode = title.at(0); + uint letter = charCode<128 ? tolower(charCode) : charCode; + if (isId(letter)) + { + g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(gd); + g_searchIndexSymbols[SEARCH_INDEX_GROUPS][letter].append(gd); + g_searchIndexCount[SEARCH_INDEX_ALL]++; + g_searchIndexCount[SEARCH_INDEX_GROUPS]++; + } + } + } + } + + // index pages + PageSDict::Iterator pdi(*Doxygen::pageSDict); + PageDef *pd=0; + for (pdi.toFirst();(pd=pdi.current());++pdi) + { + if (pd->isLinkable()) + { + QCString title = pd->title(); + if (!title.isEmpty()) + { + uchar charCode = title.at(0); + uint letter = charCode<128 ? tolower(charCode) : charCode; + if (isId(letter)) + { + g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(pd); + g_searchIndexSymbols[SEARCH_INDEX_PAGES][letter].append(pd); + g_searchIndexCount[SEARCH_INDEX_ALL]++; + g_searchIndexCount[SEARCH_INDEX_PAGES]++; + } + } + } + } + if (Doxygen::mainPage) + { + QCString title = Doxygen::mainPage->title(); + if (!title.isEmpty()) + { + uchar charCode = title.at(0); + uint letter = charCode<128 ? tolower(charCode) : charCode; + if (isId(letter)) + { + g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(Doxygen::mainPage); + g_searchIndexSymbols[SEARCH_INDEX_PAGES][letter].append(Doxygen::mainPage); + g_searchIndexCount[SEARCH_INDEX_ALL]++; + g_searchIndexCount[SEARCH_INDEX_PAGES]++; + } + } + } // sort all lists int i,p; @@ -730,9 +800,6 @@ void writeJavascriptSearchIndex() { Definition *d = dl->first(); QCString id = d->localName(); -// t << "<div class=\"SRResult\" id=\"SR_" -// << searchId(d->localName()) << "\">" << endl; -// t << " <div class=\"SREntry\">\n"; if (!firstEntry) { @@ -740,30 +807,24 @@ void writeJavascriptSearchIndex() } firstEntry=FALSE; - ti << " ['" << searchId(d->localName()) << "',['" - << d->localName() << "',["; + QCString dispName = d->localName(); + if (d->definitionType()==Definition::TypeGroup) + { + dispName = ((GroupDef*)d)->groupTitle(); + } + else if (d->definitionType()==Definition::TypePage) + { + dispName = ((PageDef*)d)->title(); + } + ti << " ['" << searchId(dispName) << "',['" + << convertToXML(dispName) << "',["; if (dl->count()==1) // item with a unique name { MemberDef *md = 0; bool isMemberDef = d->definitionType()==Definition::TypeMember; if (isMemberDef) md = (MemberDef*)d; -// t << " <a id=\"Item" << itemCount << "\" " -// << "onkeydown=\"" -// << "return searchResults.Nav(event," << itemCount << ")\" " -// << "onkeypress=\"" -// << "return searchResults.Nav(event," << itemCount << ")\" " -// << "onkeyup=\"" -// << "return searchResults.Nav(event," << itemCount << ")\" " -// << "class=\"SRSymbol\" "; -// t << externalLinkTarget() << "href=\"" << externalRef("../",d->getReference(),TRUE); -// t << d->getOutputFileBase() << Doxygen::htmlFileExtension; QCString anchor = d->anchor(); -// if (!anchor.isEmpty()) -// { -// t << "#" << anchor; -// } -// t << "\""; ti << "'" << externalRef("../",d->getReference(),TRUE) << d->getOutputFileBase() << Doxygen::htmlFileExtension; @@ -776,24 +837,15 @@ void writeJavascriptSearchIndex() static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW"); if (!extLinksInWindow || d->getReference().isEmpty()) { -// t << " target=\"_parent\""; ti << "1,"; } else { ti << "0,"; } -// t << ">"; -// t << convertToXML(d->localName()); -// t << "</a>" << endl; - if (d->getOuterScope()!=Doxygen::globalScope) { -// t << " <span class=\"SRScope\">" -// << convertToXML(d->getOuterScope()->name()) -// << "</span>" << endl; - ti << "'" << convertToXML(d->getOuterScope()->name()) << "'"; } else if (md) @@ -802,10 +854,6 @@ void writeJavascriptSearchIndex() if (fd==0) fd = md->getFileDef(); if (fd) { -// t << " <span class=\"SRScope\">" -// << convertToXML(fd->localName()) -// << "</span>" << endl; - ti << "'" << convertToXML(fd->localName()) << "'"; } } @@ -817,19 +865,6 @@ void writeJavascriptSearchIndex() } else // multiple items with the same name { -// t << " <a id=\"Item" << itemCount << "\" " -// << "onkeydown=\"" -// << "return searchResults.Nav(event," << itemCount << ")\" " -// << "onkeypress=\"" -// << "return searchResults.Nav(event," << itemCount << ")\" " -// << "onkeyup=\"" -// << "return searchResults.Nav(event," << itemCount << ")\" " -// << "class=\"SRSymbol\" " -// << "href=\"javascript:searchResults.Toggle('SR_" -// << searchId(d->localName()) << "')\">" -// << convertToXML(d->localName()) << "</a>" << endl; -// t << " <div class=\"SRChildren\">" << endl; - QListIterator<Definition> di(*dl); bool overloadedFunction = FALSE; Definition *prevScope = 0; @@ -844,31 +879,7 @@ void writeJavascriptSearchIndex() bool isMemberDef = d->definitionType()==Definition::TypeMember; if (isMemberDef) md = (MemberDef*)d; if (next) nextScope = next->getOuterScope(); - -// t << " <a id=\"Item" << itemCount << "_c" -// << childCount << "\" " -// << "onkeydown=\"" -// << "return searchResults.NavChild(event," -// << itemCount << "," << childCount << ")\" " -// << "onkeypress=\"" -// << "return searchResults.NavChild(event," -// << itemCount << "," << childCount << ")\" " -// << "onkeyup=\"" -// << "return searchResults.NavChild(event," -// << itemCount << "," << childCount << ")\" " -// << "class=\"SRScope\" "; -// if (!d->getReference().isEmpty()) -// { -// t << externalLinkTarget() << externalRef("../",d->getReference(),FALSE); -// } -// t << "href=\"" << externalRef("../",d->getReference(),TRUE); -// t << d->getOutputFileBase() << Doxygen::htmlFileExtension; QCString anchor = d->anchor(); -// if (!anchor.isEmpty()) -// { -// t << "#" << anchor; -// } -// t << "\""; if (childCount>0) { @@ -885,14 +896,12 @@ void writeJavascriptSearchIndex() static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW"); if (!extLinksInWindow || d->getReference().isEmpty()) { -// t << " target=\"_parent\""; ti << "1,"; } else { ti << "0,"; } -// t << ">"; bool found=FALSE; overloadedFunction = ((prevScope!=0 && scope==prevScope) || (scope && scope==nextScope) @@ -903,7 +912,7 @@ void writeJavascriptSearchIndex() if (overloadedFunction) // overloaded member function { prefix+=convertToXML(md->argsString()); - // show argument list to disambiguate overloaded functions + // show argument list to disambiguate overloaded functions } else if (md) // unique member function { @@ -951,21 +960,16 @@ void writeJavascriptSearchIndex() { name = prefix + "("+theTranslator->trGlobalNamespace()+")"; } -// t << name; -// t << "</a>" << endl; ti << "'" << name << "'"; prevScope = scope; childCount++; } -// t << " </div>" << endl; // SRChildren ti << "]]"; } ti << "]"; -// t << " </div>" << endl; // SREntry -// t << "</div>" << endl; // SRResult itemCount++; } if (!firstEntry) @@ -983,7 +987,6 @@ void writeJavascriptSearchIndex() } } } - //ol.popGeneratorState(); { QFile f(searchDirName+"/search.js"); diff --git a/src/util.cpp b/src/util.cpp index 08cf0cf..41b2991 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -848,6 +848,75 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl, return FALSE; } +const int MAX_STACK_SIZE = 1000; + +class AccessStack +{ + public: + AccessStack() : m_index(0) {} + void push(Definition *scope,FileDef *fileScope,Definition *item) + { + if (m_index<MAX_STACK_SIZE) + { + m_elements[m_index].scope = scope; + m_elements[m_index].fileScope = fileScope; + m_elements[m_index].item = item; + m_index++; + } + } + void push(Definition *scope,FileDef *fileScope,Definition *item,const QCString &expScope) + { + if (m_index<MAX_STACK_SIZE) + { + m_elements[m_index].scope = scope; + m_elements[m_index].fileScope = fileScope; + m_elements[m_index].item = item; + m_elements[m_index].expScope = expScope; + m_index++; + } + } + void pop() + { + if (m_index>0) m_index--; + } + bool find(Definition *scope,FileDef *fileScope, Definition *item) + { + int i=0; + for (i=0;i<m_index;i++) + { + AccessElem *e = &m_elements[i]; + if (e->scope==scope && e->fileScope==fileScope && e->item==item) + { + return TRUE; + } + } + return FALSE; + } + bool find(Definition *scope,FileDef *fileScope, Definition *item,const QCString &expScope) + { + int i=0; + for (i=0;i<m_index;i++) + { + AccessElem *e = &m_elements[i]; + if (e->scope==scope && e->fileScope==fileScope && e->item==item && e->expScope==expScope) + { + return TRUE; + } + } + return FALSE; + } + + private: + struct AccessElem + { + Definition *scope; + FileDef *fileScope; + Definition *item; + QCString expScope; + }; + int m_index; + AccessElem m_elements[MAX_STACK_SIZE]; +}; /* Returns the "distance" (=number of levels up) from item to scope, or -1 * if item in not inside scope. @@ -857,15 +926,12 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item) //printf("<isAccesibleFrom(scope=%s,item=%s itemScope=%s)\n", // scope->name().data(),item->name().data(),item->getOuterScope()->name().data()); - QCString key(40); - key.sprintf("%p:%p:%p",scope,fileScope,item); - static QDict<void> visitedDict; - if (visitedDict.find(key)) + static AccessStack accessStack; + if (accessStack.find(scope,fileScope,item)) { - //printf("> already found\n"); - return -1; // already looked at this + return -1; } - visitedDict.insert(key,(void *)0x8); + accessStack.push(scope,fileScope,item); int result=0; // assume we found it int i; @@ -934,7 +1000,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item) result= (i==-1) ? -1 : i+2; } done: - visitedDict.remove(key); + accessStack.pop(); //Doxygen::lookupCache.insert(key,new int(result)); return result; } @@ -964,15 +1030,13 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope, return isAccessibleFrom(scope,fileScope,item); } - QCString key(40+explicitScopePart.length()); - key.sprintf("%p:%p:%p:%s",scope,fileScope,item,explicitScopePart.data()); - static QDict<void> visitedDict; - if (visitedDict.find(key)) + static AccessStack accessStack; + if (accessStack.find(scope,fileScope,item,explicitScopePart)) { - //printf("Already visited!\n"); - return -1; // already looked at this + return -1; } - visitedDict.insert(key,(void *)0x8); + accessStack.push(scope,fileScope,item,explicitScopePart); + //printf(" <isAccessibleFromWithExpScope(%s,%s,%s)\n",scope?scope->name().data():"<global>", // item?item->name().data():"<none>", @@ -1101,9 +1165,10 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope, result= (i==-1) ? -1 : i+2; } } + done: //printf(" > result=%d\n",result); - visitedDict.remove(key); + accessStack.pop(); //Doxygen::lookupCache.insert(key,new int(result)); return result; } @@ -2004,6 +2069,14 @@ QCString tempArgListToString(ArgumentList *al) { if (!a->name.isEmpty()) // add template argument name { + if (a->type.left(4)=="out") // C# covariance + { + result+="out "; + } + else if (a->type.left(3)=="in") // C# contravariance + { + result+="in "; + } result+=a->name; } else // extract name from type @@ -6181,9 +6254,14 @@ bool findAndRemoveWord(QCString &s,const QCString &word) } /** Special version of QCString::stripWhiteSpace() that only strips - * empty lines. + * completely blank lines. + * @param s the string to be stripped + * @param docLine the line number corresponding to the start of the + * string. This will be adjusted based on the number of lines stripped + * from the start. + * @returns The stripped string. */ -QCString stripLeadingAndTrailingEmptyLines(const QCString &s) +QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine) { const char *p = s.data(); if (p==0) return 0; @@ -6194,7 +6272,7 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s) while ((c=*p++)) { if (c==' ' || c=='\t' || c=='\r') i++; - else if (c=='\n') i++,li=i; + else if (c=='\n') i++,li=i,docLine++; else break; } @@ -6592,6 +6670,18 @@ static QCString replaceAliasArguments(const QCString &aliasValue,const QCString markerEnd=0; } } + if (markerStart>0) + { + markerEnd=l; + } + if (markerStart>0 && markerEnd>markerStart) + { + int markerLen = markerEnd-markerStart; + markerList.append(new Marker(markerStart-1, // include backslash + atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1)); + //printf("found marker at %d with len %d and number %d\n", + // markerStart-1,markerLen+1,atoi(aliasValue.mid(markerStart,markerLen))); + } // then we replace the markers with the corresponding arguments in one pass QCString result; @@ -329,7 +329,7 @@ bool containsWord(const QCString &s,const QCString &word); bool findAndRemoveWord(QCString &s,const QCString &word); -QCString stripLeadingAndTrailingEmptyLines(const QCString &s); +QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine); //void stringToSearchIndex(const QCString &docUrlBase,const QCString &title, // const QCString &str, bool priority=FALSE, diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index f603c30..93f5699 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -1598,7 +1598,7 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, ClassDef *kl=0; LockingPtr<ArgumentList> alp = mdef->argumentList(); QCString nn; - VhdlDocGen::adjustRecordMember(mdef) ; + //VhdlDocGen::adjustRecordMember(mdef); if (gd) gd=0; switch(mm) { @@ -1972,6 +1972,7 @@ void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol, } }// writeVHDLDeclarations +#if 0 /* strips the prefix for record and unit members*/ void VhdlDocGen::adjustRecordMember(MemberDef *mdef) { //,OutputList & ol) { @@ -1984,7 +1985,7 @@ void VhdlDocGen::adjustRecordMember(MemberDef *mdef) mdef->setName(nn.data()); } }//adjustRecordMember - +#endif /* strips the prefix for package and package body */ bool VhdlDocGen::writeClassType( ClassDef *& cd, diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index df53088..ec51f6a 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -1,7 +1,5 @@ /****************************************************************************** * - * - * * Copyright (C) 1997-2012 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its @@ -249,7 +247,8 @@ class VhdlDocGen static QCString getRecordNumber(); static QCString getClassName(const ClassDef*); - static void adjustRecordMember(MemberDef *mdef); + // obsolete + // static void adjustRecordMember(MemberDef *mdef); static void writeLink(const MemberDef* mdef,OutputList &ol); static void adjustMemberName(QCString& nn); diff --git a/src/vhdlparser.y b/src/vhdlparser.y index 41c81aa..fac86e8 100644 --- a/src/vhdlparser.y +++ b/src/vhdlparser.y @@ -2068,7 +2068,7 @@ extern YYSTYPE vhdlScanYYlval; void vhdlScanYYerror(const char* /*str*/) { - // fprintf(stderr,"\n<---error at line %d : [ %s] in file : %s ---->",s_str.yyLineNr,s_str.qstr.data(),s_str.fileName); +// fprintf(stderr,"\n<---error at line %d : [ %s] in file : %s ---->",s_str.yyLineNr,s_str.qstr.data(),s_str.fileName); // exit(0); } @@ -2336,10 +2336,11 @@ static void addVhdlType(const QCString &name,int startLine,int section,int spec, for (uint u=0;u<ql.count();u++) { current->name=(QCString)ql[u]; - if (section==Entry::VARIABLE_SEC && !(spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) - { - current->name.prepend(VhdlDocGen::getRecordNumber()); - } + // if (section==Entry::VARIABLE_SEC && !(spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) + // { + // current->name.prepend(VhdlDocGen::getRecordNumber()); + // } + current->startLine=startLine; current->bodyLine=startLine; current->section=section; diff --git a/src/vhdlscanner.l b/src/vhdlscanner.l index 9a7cf3a..9ca68db 100644 --- a/src/vhdlscanner.l +++ b/src/vhdlscanner.l @@ -109,6 +109,8 @@ static void mapLibPackage(const Entry* ce); static Entry* getEntryAtLine(const Entry* ce,int line); static bool addLibUseClause(const QCString &type); +static bool varr=false; +static QCString varName; #define YY_NEVER_INTERACTIVE 1 #define YY_USER_ACTION num_chars += vhdlScanYYleng; @@ -288,8 +290,8 @@ static void lineCount() static void startCodeBlock(int index){ int ll=strComment.length(); - iCodeLen=inputVhdlString.findRev(strComment.data(),num_chars)+ll; - fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll); + iCodeLen=inputVhdlString.findRev(strComment.data())+ll; + // fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll); //assert(false); gBlock.reset(); int len=strComment.length(); @@ -551,6 +553,8 @@ BR [ \t\n\r] pTemp->briefLine=yyLineNr; pTemp->brief+=vhdlScanYYtext; pTemp->briefFile=yyFileName; + pTemp->fileName = yyFileName; + VhdlDocGen::prepareComment(pTemp->brief); } else @@ -568,6 +572,7 @@ BR [ \t\n\r] if (index>0) { startCodeBlock(index); + doxComment=true; } lineCount(); BEGIN(Comment); @@ -585,12 +590,13 @@ BR [ \t\n\r] VhdlDocGen::prepareComment(strComment); - if (index==-1) + if (index==-1 && !doxComment) { handleCommentBlock(strComment,FALSE); } strComment.resize(0);; unput(*vhdlScanYYtext); + doxComment=false; BEGIN(g_lastCommentContext); } @@ -617,7 +623,7 @@ BR [ \t\n\r] //printf("--> handleCommentBlock line %d\n",yyLineNr); Entry* pTemp=getEntryAtLine(current_root,yyLineNr); - if (!isEndCode) + if (!isEndCode && index==-1) { int j=qcs.find("--!"); qcs=qcs.right(qcs.length()-3-j); @@ -625,7 +631,8 @@ BR [ \t\n\r] if (pTemp) { pTemp->briefLine=yyLineNr; - qcs=qcs.stripWhiteSpace(); + pTemp->fileName = yyFileName; + qcs=qcs.stripWhiteSpace(); pTemp->brief+=qcs; pTemp->briefFile=yyFileName; @@ -735,9 +742,10 @@ bool VHDLLanguageScanner::needsPreprocessing(const QCString & /*extension*/) return TRUE; } -void VHDLLanguageScanner::parsePrototype(const char * /*text*/) +void VHDLLanguageScanner::parsePrototype(const char *text) { - assert(FALSE); + varName=text; + varr=true; } // do parsing @@ -916,8 +924,8 @@ static void handleCommentBlock(const QCString &doc,bool brief) current->briefLine = iDocLine; else current->docLine = iDocLine; - - //printf("parseCommentBlock %p [%s]\n",current,doc.data()); + +// printf("parseCommentBlock file<%s>\n [%s]\n",yyFileName.data(),doc.data()); while (parseCommentBlock( g_thisParser, current, @@ -938,6 +946,15 @@ static void handleCommentBlock(const QCString &doc,bool brief) } if (needsEntry) { + if(varr) + { + varr=false; + current->name=varName; + current->section=Entry::VARIABLEDOC_SEC; + varName=""; + strComment.resize(0); + } + newVhdlEntry(); } iDocLine=-1; diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 81acba5..15d4caa 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -585,7 +585,7 @@ void XmlDocVisitor::visitPre(DocHtmlTable *t) { if (m_hide) return; m_t << "<table rows=\"" << t->numRows() - << "\" cols=\"" << t->numCols() << "\">" ; + << "\" cols=\"" << t->numColumns() << "\">" ; } void XmlDocVisitor::visitPost(DocHtmlTable *) |