diff options
Diffstat (limited to 'src')
48 files changed, 6204 insertions, 154 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index fcb5f70..f52fa9d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -53,6 +53,6 @@ clean: Makefile.libdoxygen Makefile.doxygen Makefile.doxytag Makefile.doxysearch distclean: clean -$(RM) scanner.cpp doc.cpp code.cpp config.cpp pre.cpp ce_lex.cpp \ ce_parse.cpp ce_parse.h doxytag.cpp tag.cpp \ - declinfo.cpp defargs.cpp commentcnv.cpp + declinfo.cpp defargs.cpp commentcnv.cpp doctokenizer.cpp FORCE: diff --git a/src/classdef.cpp b/src/classdef.cpp index 8393aed..eb0f199 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -725,7 +725,7 @@ void ClassDef::writeDetailedDescription(OutputList &ol, OutputList &briefOutput, ol.disableAllBut(OutputGenerator::RTF); ol.newParagraph(); ol.popGeneratorState(); - parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); + parseDoc(ol,docFile(),docLine(),name(),0,documentation()+"\n"); } // write examples if (exampleFlag) @@ -773,7 +773,7 @@ void ClassDef::writeDocumentation(OutputList &ol) OutputList briefOutput(&ol); if (!briefDescription().isEmpty()) { - parseDoc(briefOutput,m_defFileName,m_defLine,name(),0,briefDescription()); + parseDoc(briefOutput,briefFile(),briefLine(),name(),0,briefDescription()); if (!Config_getBool("DETAILS_AT_TOP")) { ol+=briefOutput; @@ -2466,7 +2466,7 @@ void ClassDef::addListReferences() { addRefItem(specialListItems(), theTranslator->trClass(TRUE,TRUE), - getOutputFileBase(),name() + getOutputFileBase(),displayName() ); MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; diff --git a/src/classlist.cpp b/src/classlist.cpp index 04664ef..fcda558 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -117,7 +117,7 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f if (!cd->briefDescription().isEmpty()) { ol.startMemberDescription(); - parseDoc(ol,cd->getDefFileName(),cd->getDefLine(),cd->name(),0,cd->briefDescription()); + parseDoc(ol,cd->briefFile(),cd->briefLine(),cd->name(),0,cd->briefDescription()); if ((!cd->briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) || !cd->documentation().isEmpty()) { diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp new file mode 100644 index 0000000..eb7c25a --- /dev/null +++ b/src/cmdmapper.cpp @@ -0,0 +1,214 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#include "cmdmapper.h" + +CommandMap cmdMap[] = +{ + { "a", CMD_EMPHASIS }, + { "addindex", CMD_ADDINDEX }, + { "anchor", CMD_ANCHOR }, + { "arg", CMD_LI }, + { "attention", CMD_ATTENTION }, + { "author", CMD_AUTHOR }, + { "b", CMD_BOLD }, + { "bug", CMD_BUG }, + { "c", CMD_CODE }, + { "code", CMD_STARTCODE }, + { "copydoc", CMD_COPYDOC }, + { "date", CMD_DATE }, + { "deprecated", CMD_DEPRECATED }, + { "dontinclude", CMD_DONTINCLUDE }, + { "dotfile", CMD_DOTFILE }, + { "e", CMD_EMPHASIS }, + { "em", CMD_EMPHASIS }, + { "endcode", CMD_ENDCODE }, + { "endhtmlonly", CMD_ENDHTMLONLY }, + { "endlatexonly", CMD_ENDLATEXONLY }, + { "endlink", CMD_ENDLINK }, + { "endsecreflist", CMD_ENDSECREFLIST }, + { "endverbatim", CMD_ENDVERBATIM }, + { "exception", CMD_EXCEPTION }, + { "form", CMD_FORMULA }, + { "htmlinclude", CMD_HTMLINCLUDE }, + { "htmlonly", CMD_HTMLONLY }, + { "image", CMD_IMAGE }, + { "include", CMD_INCLUDE }, + { "internal", CMD_INTERNAL }, + { "invariant", CMD_INVARIANT }, + { "javalink", CMD_JAVALINK }, + { "latexonly", CMD_LATEXONLY }, + { "li", CMD_LI }, + { "line", CMD_LINE }, + { "link", CMD_LINK }, + { "n", CMD_LINEBREAK }, + { "note", CMD_NOTE }, + { "p", CMD_CODE }, + { "par", CMD_PAR }, + { "param", CMD_PARAM }, + { "post", CMD_POST }, + { "pre", CMD_PRE }, + { "ref", CMD_REF }, + { "refitem", CMD_SECREFITEM }, + { "remark", CMD_REMARK }, + { "remarks", CMD_REMARK }, + { "result", CMD_RETURN }, + { "return", CMD_RETURN }, + { "returns", CMD_RETURN }, + { "retval", CMD_RETVAL }, + { "sa", CMD_SA }, + { "secreflist", CMD_SECREFLIST }, + { "section", CMD_SECTION }, + { "see", CMD_SA }, + { "since", CMD_SINCE }, + { "skip", CMD_SKIP }, + { "skipline", CMD_SKIPLINE }, + { "test", CMD_TEST }, + { "throw", CMD_EXCEPTION }, + { "todo", CMD_TODO }, + { "until", CMD_UNTIL }, + { "verbatim", CMD_VERBATIM }, + { "verbinclude", CMD_VERBINCLUDE }, + { "version", CMD_VERSION }, + { "warning", CMD_WARNING }, + { "authors", CMD_AUTHOR }, + { "throws", CMD_EXCEPTION }, + { "\\", CMD_BSLASH }, + { "@", CMD_AT }, + { "<", CMD_LESS }, + { ">", CMD_GREATER }, + { "&", CMD_AMP }, + { "$", CMD_DOLLAR }, + { "#", CMD_HASH }, + { "%", CMD_PERCENT }, + { "~", CMD_LANGSWITCH }, + { 0, 0 } +}; + +//---------------------------------------------------------------------------- + +int CmdMapper::map(const char *name) +{ + return instance()->find(name); +} + +void CmdMapper::freeInstance() +{ + delete m_instance; m_instance=0; +} + +CmdMapper *CmdMapper::instance() +{ + if (m_instance==0) m_instance = new CmdMapper; + return m_instance; +} + +CmdMapper::CmdMapper() : m_map(89) +{ + m_map.setAutoDelete(TRUE); + CommandMap *p = cmdMap; + while (p->cmdName) + { + m_map.insert(p->cmdName,new int(p->cmdId)); + p++; + } +} +int CmdMapper::find(const char *name) +{ + int *result = m_map.find(name); + if (result) return *result; else return CMD_UNKNOWN; +} + +CmdMapper *CmdMapper::m_instance=0; + +//---------------------------------------------------------------------------- + +CommandMap htmlTagMap[] = +{ + { "strong", HTML_BOLD }, + { "center", HTML_CENTER }, + { "table", HTML_TABLE }, + { "caption", HTML_CAPTION }, + { "small", HTML_SMALL }, + { "code", HTML_CODE }, + { "dfn", HTML_CODE }, + { "var", HTML_EMPHASIS }, + { "img", HTML_IMG }, + { "pre", HTML_PRE }, + { "sub", HTML_SUB }, + { "sup", HTML_SUP }, + { "tr", HTML_TR }, + { "td", HTML_TD }, + { "th", HTML_TH }, + { "ol", HTML_OL }, + { "ul", HTML_UL }, + { "li", HTML_LI }, + { "tt", HTML_CODE }, + { "kbd", HTML_CODE }, + { "em", HTML_EMPHASIS }, + { "hr", HTML_HR }, + { "dl", HTML_DL }, + { "dt", HTML_DT }, + { "dd", HTML_DD }, + { "br", HTML_BR }, + { "i", HTML_EMPHASIS }, + { "a", HTML_A }, + { "b", HTML_BOLD }, + { "p", HTML_P }, + { "h1", HTML_H1 }, + { "h2", HTML_H2 }, + { "h3", HTML_H3 }, +}; + +//---------------------------------------------------------------------------- + +int HtmlTagMapper::map(const char *name) +{ + return instance()->find(name); +} + +void HtmlTagMapper::freeInstance() +{ + delete m_instance; m_instance=0; +} + +HtmlTagMapper *HtmlTagMapper::instance() +{ + if (m_instance==0) m_instance = new HtmlTagMapper; + return m_instance; +} + +HtmlTagMapper::HtmlTagMapper() : m_map(89) +{ + m_map.setAutoDelete(TRUE); + CommandMap *p = htmlTagMap; + while (p->cmdName) + { + m_map.insert(p->cmdName,new int(p->cmdId)); + p++; + } +} +int HtmlTagMapper::find(const char *name) +{ + int *result = m_map.find(name); + if (result) return *result; else return HTML_UNKNOWN; +} + +HtmlTagMapper *HtmlTagMapper::m_instance=0; + +//---------------------------------------------------------------------------- diff --git a/src/cmdmapper.h b/src/cmdmapper.h new file mode 100644 index 0000000..09a8e92 --- /dev/null +++ b/src/cmdmapper.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef _CMDMAPPER_H +#define _CMDMAPPER_H + +#include <qdict.h> + +struct CommandMap +{ + const char *cmdName; + int cmdId; +}; + +const int SIMPLESECT_BIT = 0x1000; + +enum CommandType +{ + CMD_UNKNOWN=0, + CMD_ADDINDEX=1, /* DocIndex, word as arg */ + CMD_ANCHOR=2, + CMD_ATTENTION=3 | SIMPLESECT_BIT, + CMD_AUTHOR=4 | SIMPLESECT_BIT, + CMD_BOLD=5, + CMD_BUG=6 | SIMPLESECT_BIT, + CMD_CODE=7, + CMD_COPYDOC=8, /* reference yields subtree */ + CMD_DATE=9 | SIMPLESECT_BIT, + CMD_DEPRECATED=10 | SIMPLESECT_BIT, + CMD_DONTINCLUDE=11, /* file name */ + CMD_DOTFILE=12, /* file name */ + CMD_EMPHASIS =13, + CMD_ENDCODE=14, + CMD_ENDHTMLONLY=15, + CMD_ENDLATEXONLY=16, + CMD_ENDLINK=17, + CMD_ENDVERBATIM=18 , + CMD_EXCEPTION=19 | SIMPLESECT_BIT, + CMD_HTMLINCLUDE=20 , + CMD_HTMLONLY=21 , + CMD_IMAGE=22 , /* some number of arguments */ + CMD_INCLUDE=23 , + CMD_INTERNAL=24 , /* node, with sub paragraphs? */ + CMD_INVARIANT=25| SIMPLESECT_BIT , + CMD_LATEXONLY=26 , + CMD_LI=27 , + CMD_LINE=28 , + CMD_LINK=29 , /* argument + "text", TODO {@link...} */ + CMD_NOTE=30 | SIMPLESECT_BIT , + CMD_PAR=31 | SIMPLESECT_BIT , + CMD_PARAM=32 | SIMPLESECT_BIT, + CMD_POST=33 | SIMPLESECT_BIT, + CMD_PRE=34 | SIMPLESECT_BIT , + CMD_REF=35 , + CMD_SECREFITEM=36 , + CMD_REMARK=37 | SIMPLESECT_BIT , + CMD_RETURN=38 | SIMPLESECT_BIT , + CMD_RETVAL=39 | SIMPLESECT_BIT, + CMD_SA=40 | SIMPLESECT_BIT , + CMD_SECTION=41 , + CMD_SINCE=42 | SIMPLESECT_BIT, + CMD_SKIP=43 , + CMD_SKIPLINE=44 , + CMD_STARTCODE=45, + CMD_JAVALINK=46, + CMD_TEST=47 | SIMPLESECT_BIT, + CMD_TODO=48 | SIMPLESECT_BIT, + CMD_UNTIL=49 , + CMD_VERBATIM=50 , + CMD_VERBINCLUDE=51 , + CMD_VERSION=52 | SIMPLESECT_BIT, + CMD_WARNING=53 | SIMPLESECT_BIT , + CMD_BSLASH=54 , + CMD_AT=55 , + CMD_LESS=56 , + CMD_GREATER=57 , + CMD_AMP=58 , + CMD_DOLLAR=59 , + CMD_HASH=60 , + CMD_PERCENT=61, + CMD_LINEBREAK=62, + CMD_FORMULA=63, + CMD_SECREFLIST=64, + CMD_ENDSECREFLIST=65, + CMD_LANGSWITCH=66 +}; + +enum HtmlTagType +{ + HTML_UNKNOWN = 0, + HTML_CENTER = 1, + HTML_TABLE = 2, + HTML_CAPTION = 3, + HTML_SMALL = 4, + HTML_CODE = 5, + HTML_IMG = 6, + HTML_PRE = 7, + HTML_SUB = 8, + HTML_SUP = 9, + HTML_TR = 10, + HTML_TD = 11, + HTML_TH = 12, + HTML_OL = 13, + HTML_UL = 14, + HTML_LI = 15, + HTML_EMPHASIS = 16, + HTML_HR = 17, + HTML_DL = 18, + HTML_DT = 19, + HTML_DD = 20, + HTML_BR = 21, + HTML_A = 22, + HTML_BOLD = 23, + HTML_P = 24, + HTML_H1 = 25, + HTML_H2 = 26, + HTML_H3 = 27 +}; + +class CmdMapper +{ + public: + static int map(const char *name); + static void freeInstance(); + + private: + static CmdMapper *instance(); + CmdMapper(); + int find(const char *name); + QDict<int> m_map; + static CmdMapper *m_instance; +}; + +class HtmlTagMapper +{ + public: + static int map(const char *name); + static void freeInstance(); + + private: + static HtmlTagMapper *instance(); + HtmlTagMapper(); + int find(const char *name); + QDict<int> m_map; + static HtmlTagMapper *m_instance; +}; + + +#endif diff --git a/src/debug.cpp b/src/debug.cpp index 8932622..e9f3135 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -38,18 +38,23 @@ void Debug::print(DebugMask mask,int prio,const char *fmt,...) static int labelToEnumValue(const char *l) { QCString label=l; - if (label=="FindMembers") + label=label.lower(); + if (label=="findmembers") return Debug::FindMembers; - else if (label=="Functions") + else if (label=="functions") return Debug::Functions; - else if (label=="Variables") + else if (label=="variables") return Debug::Variables; - else if (label=="Preprocessor") + else if (label=="preprocessor") return Debug::Preprocessor; - else if (label=="Classes") + else if (label=="classes") return Debug::Classes; - else if (label=="CommentCnv") + else if (label=="commentcnv") return Debug::CommentCnv; + else if (label=="validate") + return Debug::Validate; + else if (label=="printtree") + return Debug::PrintTree; else return 0; } diff --git a/src/debug.h b/src/debug.h index 22c463b..4cec994 100644 --- a/src/debug.h +++ b/src/debug.h @@ -28,7 +28,9 @@ class Debug Variables = 0x00000004, Preprocessor = 0x00000008, Classes = 0x00000010, - CommentCnv = 0x00000020 + CommentCnv = 0x00000020, + Validate = 0x00000040, + PrintTree = 0x00000080 }; static void print(DebugMask mask,int prio,const char *fmt,...); static void setFlag(const char *label); diff --git a/src/definition.cpp b/src/definition.cpp index dcdaa72..5d5ca03 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -54,6 +54,8 @@ Definition::Definition(const char *df,int dl, m_outerScope=Doxygen::globalScope; m_partOfGroups=0; m_specialListItems=0; + m_briefLine=1; + m_docFile=1; } Definition::~Definition() @@ -109,6 +111,8 @@ void Definition::writeDocAnchorsToTagFile() void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) { + if (d==0) return; + //printf("Definition::setDocumentation(%s,%s,%d)\n",d,docFile,docLine); if (stripWhiteSpace) m_doc=((QCString)d).stripWhiteSpace(); else @@ -119,6 +123,8 @@ void Definition::setDocumentation(const char *d,const char *docFile,int docLine, void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) { + if (b==0) return; + //printf("Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); m_brief=QCString(b).stripWhiteSpace(); int bl=m_brief.length(); if (bl>0) // add puntuation if needed @@ -30,6 +30,10 @@ #include <qstack.h> #include <qregexp.h> +// new experimental parser +#include "docparser.h" +#include "debug.h" + #include "doc.h" #include "code.h" #include "message.h" @@ -103,6 +107,8 @@ static QCString curDotFileCaption; static QCString internalRefFile; static QCString internalRefAnchor; static QCString caption; +static QCString refItemText; +static QCString addIndexWord; static QStack<char> currentListIndent; // indent stack of all list items static bool insideItemList = FALSE; @@ -1438,6 +1444,7 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? ); } <DocScan>{CMD}"addindex"{B}+ { + addIndexWord.resize(0); BEGIN(DocIndexWord); } <DocScan>"\\form#"[0-9]+ { @@ -1449,9 +1456,17 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? outDoc->writeFormula(formName,formula->getFormulaText()); } } -<DocIndexWord>[^\n]+ { +<DocIndexWord>"\\&" { addIndexWord+='&'; } +<DocIndexWord>"\\>" { addIndexWord+='>'; } +<DocIndexWord>"\\<" { addIndexWord+='<'; } +<DocIndexWord>"\\@" { addIndexWord+='@'; } +<DocIndexWord>"\\$" { addIndexWord+='$'; } +<DocIndexWord>"\\#" { addIndexWord+='#'; } +<DocIndexWord>"\\\\" { addIndexWord+='\\'; } +<DocIndexWord>. { addIndexWord+=*yytext; } +<DocIndexWord>\n { //printf("Adding %s to index\n",yytext); - outDoc->addIndexItem(yytext,0); + outDoc->addIndexItem(addIndexWord,0); BEGIN(DocScan); } <DocScan>{CMD}("arg"|"li")/{BN} { @@ -1768,7 +1783,7 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? if (inBlock()) endBlock(); inReturnBlock=TRUE; currentListIndent.push("P"); - outDoc->startSimpleSect(BaseOutputDocInterface::Return,0,0,theTranslator->trReturns()+" :"); + outDoc->startSimpleSect(BaseOutputDocInterface::Return,0,0,theTranslator->trReturns()+":"); outDoc->writeDescItem(); } } @@ -1881,7 +1896,7 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? outDoc->startDescTableData(); BEGIN(DocScan); } -<DocScan>{CMD}"section "{ID}"\n" { +<DocScan>{CMD}"section "{ID}" " { QCString secName=&yytext[9]; // skip "\section " secName=secName.left(secName.length()-1); // remove \n //printf("SectionName %s found\n",secName.data()); @@ -1889,18 +1904,16 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? if ((sec=Doxygen::sectionDict[secName])) { //printf("Title %s\n",sec->title.data()); - outDoc->startSection(sec->label,sec->title, - sec->type==SectionInfo::Subsection); + outDoc->startSection(sec->label,sec->title,sec->type); scanString(sec->title); - outDoc->endSection(sec->label, - sec->type==SectionInfo::Subsection); + outDoc->endSection(sec->label,sec->type); } else { warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s in the documentation of this entity!",yytext); } } -<DocScan>{CMD}"anchor "{ID}"\n" { +<DocScan>{CMD}"anchor "{ID}" " { QCString secName=&yytext[8]; secName=secName.left(secName.length()-1); SectionInfo *sec; @@ -1934,6 +1947,12 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? <DocScan>{CMD}"ref"/{BN} { BEGIN(DocRefName); } +<DocScan>{CMD}"secreflist"/{BN} { + outDoc->startSectionRefList(); + } +<DocScan>{CMD}"endsecreflist"/{BN} { + outDoc->endSectionRefList(); + } <DocScan>{CMD}"refitem"/{BN} { BEGIN(DocRefItem); } @@ -2036,14 +2055,22 @@ LINKMASK [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+({B}*("const"|"volatile"))? } <DocRefItem>{ID} { sectionRef=yytext; + refItemText.resize(0); BEGIN(DocRefItemName); } -<DocRefItemName>.*/"\n" { +<DocRefItemName>"\\&" { refItemText+='&'; } +<DocRefItemName>"\\>" { refItemText+='>'; } +<DocRefItemName>"\\<" { refItemText+='<'; } +<DocRefItemName>"\\@" { refItemText+='@'; } +<DocRefItemName>"\\$" { refItemText+='$'; } +<DocRefItemName>"\\#" { refItemText+='#'; } +<DocRefItemName>"\\\\" { refItemText+='\\'; } +<DocRefItemName>. { refItemText+=*yytext; } +<DocRefItemName>\n { SectionInfo *sec; - QCString text=yytext; if ((sec=Doxygen::sectionDict[sectionRef])) { - outDoc->writeSectionRefItem(sec->fileName,sec->label,text.stripWhiteSpace()); + outDoc->writeSectionRefItem(sec->fileName,sec->label,refItemText.stripWhiteSpace()); } else { @@ -2917,6 +2944,12 @@ void resolveCopyDocCommands(const char *scope,QCString &docString) void parseDoc(OutputDocInterface &od,const char *fileName,int startLine, const char *clName,MemberDef *md,const QCString &docStr) { + + if (Debug::isFlagSet(Debug::Validate)) + { + validatingParseDoc(fileName,startLine,docStr); + } + strcpy(yyFileName,fileName); yyLineNr = startLine; diff --git a/src/docparser.cpp b/src/docparser.cpp new file mode 100644 index 0000000..90441bc --- /dev/null +++ b/src/docparser.cpp @@ -0,0 +1,3037 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <qfile.h> +#include <qfileinfo.h> +#include <qcstring.h> +#include <qstack.h> +#include <qdict.h> + +#include "doxygen.h" +#include "debug.h" + +#include "docparser.h" +#include "doctokenizer.h" +#include "cmdmapper.h" +#include "printdocvisitor.h" + +#define DBG(x) do {} while(0) +//#define DBG(x) printf x + +//--------------------------------------------------------------------------- + +static QStack<DocNode> g_nodeStack; +static QStack<DocStyleChange> g_styleStack; + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a preformatted node */ +static bool insidePRE(DocNode *n) +{ + while (n) + { + if (n->kind()==DocNode::Kind_HtmlPre) return TRUE; + n=n->parent(); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a html list item node */ +static bool insideLI(DocNode *n) +{ + while (n) + { + if (n->kind()==DocNode::Kind_HtmlListItem) return TRUE; + n=n->parent(); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a unordered html list node */ +static bool insideUL(DocNode *n) +{ + while (n) + { + if (n->kind()==DocNode::Kind_HtmlList && + ((DocHtmlList *)n)->type()==DocHtmlList::Unordered) return TRUE; + n=n->parent(); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a ordered html list node */ +static bool insideOL(DocNode *n) +{ + while (n) + { + if (n->kind()==DocNode::Kind_HtmlList && + ((DocHtmlList *)n)->type()==DocHtmlList::Ordered) return TRUE; + n=n->parent(); + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +/*! Returns TRUE iff node n is a child of a language node */ +static bool insideLang(DocNode *n) +{ + while (n) + { + if (n->kind()==DocNode::Kind_Language) return TRUE; + n=n->parent(); + } + return FALSE; +} + + +//--------------------------------------------------------------------------- + +// forward declaration +static bool defaultHandleToken(DocNode *parent,int tok, + QList<DocNode> &children,bool + handleWord=TRUE); + + +static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, + const QCString &cmdName) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return tok; + } + while ((tok=doctokenizerYYlex()) && tok!=TK_WHITESPACE && tok!=TK_NEWPARA) + { + if (!defaultHandleToken(parent,tok,children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command \\%s as the argument of a \\%s command at line %d\n", + g_token->name.data(),cmdName.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + return tok==TK_NEWPARA ? TK_NEWPARA : RetVal_OK; +} + +static void handleStyleEnter(DocNode *parent,QList<DocNode> &children,DocStyleChange::Style s) +{ + DBG(("HandleStyleEnter\n")); + DocStyleChange *sc= new DocStyleChange(parent,g_nodeStack.count(),s,TRUE); + children.append(sc); + g_styleStack.push(sc); +} + +static void handleStyleLeave(DocNode *parent,QList<DocNode> &children,DocStyleChange::Style s,const char *tagName) +{ + DBG(("HandleStyleLeave\n")); + if (g_styleStack.isEmpty() || // no style change + g_styleStack.top()->style()!=s || // wrong style change + g_styleStack.top()->position()!=g_nodeStack.count() // wrong position + ) + { + printf("Error: found </%s> tag at line %d without matching <%s> in the same paragraph\n", + tagName,doctokenizerYYlineno,tagName); + } + else // end the section + { + DocStyleChange *sc= new DocStyleChange(parent,g_nodeStack.count(),s,FALSE); + children.append(sc); + g_styleStack.pop(); + } +} + +static void handlePendingStyleCommands(DocNode *parent,QList<DocNode> &children) +{ + if (!g_styleStack.isEmpty()) + { + DocStyleChange *sc = g_styleStack.top(); + while (sc && sc->position()>=g_nodeStack.count()) + { // there are unclosed style modifiers in the paragraph + const char *cmd; + switch (sc->style()) + { + case DocStyleChange::Bold: cmd = "b"; break; + case DocStyleChange::Italic: cmd = "em"; break; + case DocStyleChange::Code: cmd = "code"; break; + case DocStyleChange::Center: cmd = "center"; break; + case DocStyleChange::Small: cmd = "small"; break; + case DocStyleChange::Subscript: cmd = "subscript"; break; + case DocStyleChange::Superscript: cmd = "superscript"; break; + } + printf("Error: end of paragraph at line %d without end of style " + "command </%s>\n",doctokenizerYYlineno,cmd); + children.append(new DocStyleChange(parent,g_nodeStack.count(),sc->style(),FALSE)); + g_styleStack.pop(); + sc = g_styleStack.top(); + } + } +} + +/* Helper function that deals with the most common tokens allowed in + * title like sections. + * @param parent Parent node, owner of the children list passed as + * the third argument. + * @param tok The token to process. + * @param children The list of child nodes to which the node representing + * the token can be added. + * @param handleWord Indicates if word token should be processed + * @retval TRUE The token was handled. + * @retval FALSE The token was not handled. + */ +static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool + handleWord=TRUE) +{ + DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); + if (tok==TK_WORD || tok==TK_SYMBOL || tok==TK_URL || + tok==TK_COMMAND || tok==TK_HTMLTAG + ) + { + DBG((" name=%s",g_token->name.data())); + } + DBG(("\n")); + QCString tokenName = g_token->name; + switch (tok) + { + case TK_COMMAND: + switch (CmdMapper::map(tokenName)) + { + case CMD_BSLASH: + children.append(new DocSymbol(parent,DocSymbol::BSlash)); + break; + case CMD_AT: + children.append(new DocSymbol(parent,DocSymbol::At)); + break; + case CMD_LESS: + children.append(new DocSymbol(parent,DocSymbol::Less)); + break; + case CMD_GREATER: + children.append(new DocSymbol(parent,DocSymbol::Greater)); + break; + case CMD_AMP: + children.append(new DocSymbol(parent,DocSymbol::Amp)); + break; + case CMD_DOLLAR: + children.append(new DocSymbol(parent,DocSymbol::Dollar)); + break; + case CMD_HASH: + children.append(new DocSymbol(parent,DocSymbol::Hash)); + break; + case CMD_PERCENT: + children.append(new DocSymbol(parent,DocSymbol::Percent)); + break; + case CMD_EMPHASIS: + { + children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,TRUE)); + int retval=handleStyleArgument(parent,children,tokenName); + children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,FALSE)); + if (retval==TK_NEWPARA) goto handlepara; + } + break; + case CMD_BOLD: + { + children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,TRUE)); + int retval=handleStyleArgument(parent,children,tokenName); + children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,FALSE)); + if (retval==TK_NEWPARA) goto handlepara; + } + break; + case CMD_CODE: + { + children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,TRUE)); + int retval=handleStyleArgument(parent,children,tokenName); + children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,FALSE)); + if (retval==TK_NEWPARA) goto handlepara; + } + break; + case CMD_HTMLONLY: + { + doctokenizerYYsetStateHtmlOnly(); + int retval = doctokenizerYYlex(); + children.append(new DocVerbatim(parent,g_token->verb,DocVerbatim::HtmlOnly)); + if (retval==0) printf("Error: htmlonly section ended without end marker at line %d\n", + doctokenizerYYlineno); + doctokenizerYYsetStatePara(); + } + break; + case CMD_LATEXONLY: + { + doctokenizerYYsetStateLatexOnly(); + int retval = doctokenizerYYlex(); + children.append(new DocVerbatim(parent,g_token->verb,DocVerbatim::LatexOnly)); + if (retval==0) printf("Error: latexonly section ended without end marker at line %d\n", + doctokenizerYYlineno); + doctokenizerYYsetStatePara(); + } + break; + case CMD_FORMULA: + { + DocFormula *form=new DocFormula(parent,g_token->id); + children.append(form); + } + break; + default: + return FALSE; + } + break; + case TK_HTMLTAG: + { + switch (HtmlTagMapper::map(tokenName)) + { + case HTML_BOLD: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Bold); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Bold,tokenName); + } + break; + case HTML_CODE: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Code); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Code,tokenName); + } + break; + case HTML_EMPHASIS: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Italic); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Italic,tokenName); + } + break; + case HTML_SUB: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Subscript); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Subscript,tokenName); + } + break; + case HTML_SUP: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Superscript); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Superscript,tokenName); + } + break; + case HTML_CENTER: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Center); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Center,tokenName); + } + break; + case HTML_SMALL: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Small); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Small,tokenName); + } + break; + default: + return FALSE; + break; + } + } + break; + case TK_SYMBOL: + { + char letter='\0'; + DocSymbol::SymType s = DocSymbol::decodeSymbol(tokenName,&letter); + if (s!=DocSymbol::Unknown) + { + children.append(new DocSymbol(parent,s,letter)); + } + else + { + return FALSE; + } + } + break; + case TK_WHITESPACE: + case TK_NEWPARA: +handlepara: + if (insidePRE(parent) || !children.isEmpty()) + { + children.append(new DocWhiteSpace(parent,g_token->chars)); + } + break; + case TK_WORD: + if (handleWord) + children.append(new DocWord(parent,g_token->name)); + else + return FALSE; + break; + case TK_URL: + children.append(new DocURL(parent,g_token->name)); + break; + default: + return FALSE; + } + return TRUE; +} + + +//--------------------------------------------------------------------------- + +DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName,char *letter) +{ + int l=symName.length(); + DBG(("decodeSymbol(%s) l=%d\n",symName.data(),l)); + if (symName=="©") return DocSymbol::Copy; + else if (symName=="<") return DocSymbol::Less; + else if (symName==">") return DocSymbol::Greater; + else if (symName=="&") return DocSymbol::Amp; + else if (symName=="'") return DocSymbol::Apos; + else if (symName==""") return DocSymbol::Quot; + else if (symName=="ß") return DocSymbol::Szlig; + else if (symName==" ") return DocSymbol::Nbsp; + else if (l==6 && symName.right(4)=="uml;") + { + *letter=symName.at(1); + return DocSymbol::Uml; + } + else if (l==8 && symName.right(6)=="acute;") + { + *letter=symName.at(1); + return DocSymbol::Acute; + } + else if (l==8 && symName.right(6)=="grave;") + { + *letter=symName.at(1); + return DocSymbol::Grave; + } + else if (l==7 && symName.right(5)=="circ;") + { + *letter=symName.at(1); + return DocSymbol::Circ; + } + else if (l==8 && symName.right(6)=="tilde;") + { + *letter=symName.at(1); + return DocSymbol::Tilde; + } + else if (l==8 && symName.right(6)=="cedil;") + { + *letter=symName.at(1); + return DocSymbol::Cedil; + } + else if (l==7 && symName.right(5)=="ring;") + { + *letter=symName.at(1); + return DocSymbol::Ring; + } + return DocSymbol::Unknown; +} + +//--------------------------------------------------------------------------- + +int DocLanguage::parse() +{ + int retval; + DBG(("DocLanguage::parse() start\n")); + g_nodeStack.push(this); + + // parse one or more paragraphs + do + { + DocPara *par = new DocPara(this); + m_children.append(par); + retval=par->parse(); + } + while (retval==TK_NEWPARA); + + DBG(("DocLanguage::parse() end\n")); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +void DocSecRefItem::parse() +{ + DBG(("DocSecRefItem::parse() start\n")); + g_nodeStack.push(this); + + doctokenizerYYsetStateTitle(); + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a \\refitem at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + doctokenizerYYsetStatePara(); + handlePendingStyleCommands(this,m_children); + DBG(("DocSecRefItem::parse() end\n")); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); +} + +//--------------------------------------------------------------------------- + +void DocSecRefList::parse() +{ + DBG(("DocSecRefList::parse() start\n")); + g_nodeStack.push(this); + + int tok=doctokenizerYYlex(); + // skip white space + while (tok==TK_WHITESPACE) tok=doctokenizerYYlex(); + // handle items + while (tok) + { + if (tok==TK_COMMAND) + { + switch (CmdMapper::map(g_token->name)) + { + case CMD_SECREFITEM: + { + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after \\refitem command at line %d\n", + doctokenizerYYlineno); + break; + } + tok=doctokenizerYYlex(); + if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of \\refitem at line %d.\n", + tokToString(tok),doctokenizerYYlineno); + break; + } + + DocSecRefItem *item = new DocSecRefItem(this,g_token->name); + m_children.append(item); + item->parse(); + } + break; + case CMD_ENDSECREFLIST: + goto endsecreflist; + default: + printf("Error: Illegal command %s as part of a \\secreflist at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + goto endsecreflist; + } + } + else + { + printf("Error: Unexpected token %s inside section reference list at line %d\n", + tokToString(tok),doctokenizerYYlineno); + goto endsecreflist; + } + tok=doctokenizerYYlex(); + } + +endsecreflist: + DBG(("DocSecRefList::parse() end\n")); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); +} + + + +//--------------------------------------------------------------------------- + +void DocRef::parse() +{ + g_nodeStack.push(this); + DBG(("DocRef::parse() start\n")); + + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a \\ref at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + + handlePendingStyleCommands(this,m_children); + DBG(("DocRef::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); +} + +//--------------------------------------------------------------------------- + +QCString DocLink::parse(bool isJavaLink) +{ + QCString result; + g_nodeStack.push(this); + DBG(("DocLink::parse() start\n")); + + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children,FALSE)) + { + switch (tok) + { + case TK_COMMAND: + switch (CmdMapper::map(g_token->name)) + { + case CMD_ENDLINK: + if (isJavaLink) + { + printf("Error: {@link.. ended with @endlink command at line %d\n", + doctokenizerYYlineno); + } + goto endlink; + default: + printf("Error: Illegal command %s as part of a \\ref at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_WORD: + if (isJavaLink) // special case to detect closing } + { + QCString w = g_token->name; + uint l=w.length(); + int p; + if (w=="}") + { + goto endlink; + } + else if ((p=w.find('}'))!=-1) + { + m_children.append(new DocWord(this,w.left(p))); + if ((uint)p<l-1) // something left after the } (for instance a .) + { + result=w.right(l-p-1); + } + goto endlink; + } + } + m_children.append(new DocWord(this,g_token->name)); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + if (tok==0) + { + printf("Error: Unexpected end of comment at line %d while inside" + " link command\n",doctokenizerYYlineno); + } +endlink: + + handlePendingStyleCommands(this,m_children); + DBG(("DocLink::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return result; +} + + +//--------------------------------------------------------------------------- + +void DocDotFile::parse() +{ + g_nodeStack.push(this); + DBG(("DocDotFile::parse() start\n")); + + doctokenizerYYsetStateTitle(); + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a \\dotfile at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + doctokenizerYYsetStatePara(); + + handlePendingStyleCommands(this,m_children); + DBG(("DocDotFile::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); +} + + +//--------------------------------------------------------------------------- + +void DocImage::parse() +{ + g_nodeStack.push(this); + DBG(("DocImage::parse() start\n")); + + doctokenizerYYsetStateTitle(); + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a \\image at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + doctokenizerYYsetStatePara(); + + handlePendingStyleCommands(this,m_children); + DBG(("DocImage::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); +} + + +//--------------------------------------------------------------------------- + +int DocHtmlHeader::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocHtmlHeader::parse() start\n")); + + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a <h%d> tag at line %d\n", + g_token->name.data(),m_level,doctokenizerYYlineno); + break; + case TK_HTMLTAG: + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_H1 && g_token->endTag) // found </h1> tag + { + if (m_level!=1) + { + printf("Error: <h%d> ended with </h1> at line %d\n", + m_level,doctokenizerYYlineno); + } + goto endheader; + } + else if (tagId==HTML_H2 && g_token->endTag) // found </h2> tag + { + if (m_level!=2) + { + printf("Error: <h%d> ended with </h2> at line %d\n", + m_level,doctokenizerYYlineno); + } + goto endheader; + } + else if (tagId==HTML_H3 && g_token->endTag) // found </h3> tag + { + if (m_level!=3) + { + printf("Error: <h%d> ended with </h3> at line %d\n", + m_level,doctokenizerYYlineno); + } + goto endheader; + } + else + { + printf("Error: Unexpected html tag <%s%s> found at line %d within <h%d> context\n", + g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno,m_level); + } + } + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + if (tok==0) + { + printf("Error: Unexpected end of comment at line %d while inside" + " <h%d> tag\n",doctokenizerYYlineno,m_level); + } +endheader: + handlePendingStyleCommands(this,m_children); + DBG(("DocHtmlHeader::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHRef::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocHRef::parse() start\n")); + + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a <a>..</a> block at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_HTMLTAG: + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_A && g_token->endTag) // found </a> tag + { + goto endhref; + } + else + { + printf("Error: Unexpected html tag <%s%s> found at line %d within <a href=...> context\n", + g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno); + } + } + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + if (tok==0) + { + printf("Error: Unexpected end of comment at line %d while inside" + " <a href=...> tag\n",doctokenizerYYlineno); + } +endhref: + handlePendingStyleCommands(this,m_children); + DBG(("DocHRef::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocInternal::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocInternal::parse() start\n")); + + // first parse any number of paragraphs + do + { + DocPara *par = new DocPara(this); + retval=par->parse(); + if (!par->isEmpty()) m_children.append(par); + if (retval==TK_LISTITEM) + { + printf("Error: Invalid list item found at line %d!\n",doctokenizerYYlineno); + } + } while (retval!=0 && retval!=RetVal_Section); + + // then parse any number of level1 sections + while (retval==RetVal_Section) + { + SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; + int secLev = sec->type==SectionInfo::Subsection ? 2 : 1; + if (secLev!=1) // wrong level + { + printf("Error: Expected level 1 section, found a section with level %d at line %d.\n",secLev,doctokenizerYYlineno); + break; + } + else + { + DocSection *s=new DocSection(this,secLev,g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + } + + if (retval==RetVal_Internal) + { + printf("Error: \\internal command found inside internal section\n"); + } + + DBG(("DocInternal::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocIndexEntry::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocIndexEntry::parse() start\n")); + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after \\addindex command at line %d\n", + doctokenizerYYlineno); + goto endindexentry; + } + while ((tok=doctokenizerYYlex()) && tok!=TK_WHITESPACE && tok!=TK_NEWPARA) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a \\addindex at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + if (tok!=TK_WHITESPACE) retval=tok; +endindexentry: + handlePendingStyleCommands(this,m_children); + DBG(("DocIndexEntry::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlCaption::parse() +{ + int retval=0; + g_nodeStack.push(this); + DBG(("DocHtmlCaption::parse() start\n")); + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a <caption> tag at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_HTMLTAG: + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_CAPTION && g_token->endTag) // found </caption> tag + { + retval = RetVal_OK; + goto endcaption; + } + else + { + printf("Error: Unexpected html tag <%s%s> found at line %d within <caption> context\n", + g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno); + } + } + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + if (tok==0) + { + printf("Error: Unexpected end of comment at line %d while inside" + " <caption> tag\n",doctokenizerYYlineno); + } +endcaption: + handlePendingStyleCommands(this,m_children); + DBG(("DocHtmlCaption::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlCell::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocHtmlCell::parse() start\n")); + + // parse one or more paragraphs + do + { + DocPara *par = new DocPara(this); + m_children.append(par); + retval=par->parse(); + } + while (retval==TK_NEWPARA); + + DBG(("DocHtmlCell::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlRow::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocHtmlRow::parse() start\n")); + + bool isHeading=FALSE; + // get next token + int tok=doctokenizerYYlex(); + // skip whitespace + while (tok==TK_WHITESPACE) tok=doctokenizerYYlex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_TD && !g_token->endTag) // found <td> tag + { + } + else if (tagId==HTML_TH && !g_token->endTag) // found <th> tag + { + isHeading=TRUE; + } + else // found some other tag + { + printf("Error: expected <td> or <th> tag at line %d but " + "found <%s> instead!\n",doctokenizerYYlineno,g_token->name.data()); + goto endrow; + } + } + else if (tok==0) // premature end of comment + { + printf("Error: unexpected end of comment at line %d while looking" + " for a html description title\n",doctokenizerYYlineno); + goto endrow; + } + else // token other than html token + { + printf("Error: expected <td> or <th> tag at line %d but found %s token instead!\n", + doctokenizerYYlineno,tokToString(tok)); + goto endrow; + } + + // parse one or more cells + do + { + DocHtmlCell *td=new DocHtmlCell(this,isHeading); + m_children.append(td); + retval=td->parse(); + isHeading = retval==RetVal_TableHCell; + } + while (retval==RetVal_TableCell || retval==RetVal_TableHCell); + +endrow: + DBG(("DocHtmlRow::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlTable::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocHtmlTable::parse() start\n")); + +getrow: + // get next token + int tok=doctokenizerYYlex(); + // skip whitespace + while (tok==TK_WHITESPACE) tok=doctokenizerYYlex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_TR && !g_token->endTag) // found <tr> tag + { + // no caption, just rows + retval=RetVal_TableRow; + } + else if (tagId==HTML_CAPTION && !g_token->endTag) // found <caption> tag + { + if (m_caption) + { + printf("Error: table already has a caption, found another one at line %d\n", + doctokenizerYYlineno); + } + else + { + m_caption = new DocHtmlCaption(this); + retval=m_caption->parse(); + + if (retval==RetVal_OK) // caption was parsed ok + { + goto getrow; + } + } + } + else // found wrong token + { + printf("Error: expected <tr> or <caption> tag at line %d but " + "found <%s%s> instead!\n",doctokenizerYYlineno, + g_token->endTag ? "/" : "", g_token->name.data()); + } + } + else if (tok==0) // premature end of comment + { + printf("Error: unexpected end of comment at line %d while looking" + " for a <tr> or <caption> tag\n",doctokenizerYYlineno); + } + else // token other than html token + { + printf("Error: expected <tr> tag at line %d but found %s token instead!\n", + doctokenizerYYlineno,tokToString(tok)); + } + + // parse one or more rows + while (retval==RetVal_TableRow) + { + DocHtmlRow *tr=new DocHtmlRow(this); + m_children.append(tr); + retval=tr->parse(); + } + + DBG(("DocHtmlTable::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval==RetVal_EndTable ? RetVal_OK : retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlDescTitle::parse() +{ + int retval=0; + g_nodeStack.push(this); + DBG(("DocHtmlDescTitle::parse() start\n")); + + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a <dt> tag at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_HTMLTAG: + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_DD && !g_token->endTag) // found <dd> tag + { + retval = RetVal_DescData; + goto endtitle; + } + else if (tagId==HTML_DT && g_token->endTag) + { + // ignore </dt> tag. + } + else + { + printf("Error: Unexpected html tag <%s%s> found at line %d within <dt> context\n", + g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno); + } + } + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + if (tok==0) + { + printf("Error: Unexpected end of comment at line %d while inside" + " <dt> tag\n",doctokenizerYYlineno); + } +endtitle: + handlePendingStyleCommands(this,m_children); + DBG(("DocHtmlDescTitle::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlDescData::parse() +{ + int retval=0; + g_nodeStack.push(this); + DBG(("DocHtmlDescData::parse() start\n")); + + do + { + DocPara *par = new DocPara(this); + m_children.append(par); + retval=par->parse(); + } + while (retval==TK_NEWPARA); + + DBG(("DocHtmlDescData::parse() end\n")); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlDescList::parse() +{ + int retval=RetVal_OK; + g_nodeStack.push(this); + DBG(("DocHtmlDescList::parse() start\n")); + + // get next token + int tok=doctokenizerYYlex(); + // skip whitespace + while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_DT && !g_token->endTag) // found <dt> tag + { + // continue + } + else // found some other tag + { + printf("Error: expected <dt> tag at line %d but " + "found <%s> instead!\n",doctokenizerYYlineno,g_token->name.data()); + goto enddesclist; + } + } + else if (tok==0) // premature end of comment + { + printf("Error: unexpected end of comment at line %d while looking" + " for a html description title\n",doctokenizerYYlineno); + goto enddesclist; + } + else // token other than html token + { + printf("Error: expected <dt> tag at line %d but found %s token instead!\n", + doctokenizerYYlineno,tokToString(tok)); + goto enddesclist; + } + + do + { + DocHtmlDescTitle *dt=new DocHtmlDescTitle(this); + m_children.append(dt); + DocHtmlDescData *dd=new DocHtmlDescData(this); + m_children.append(dd); + retval=dt->parse(); + if (retval==RetVal_DescData) + { + retval=dd->parse(); + } + else + { + // error + break; + } + } while (retval==RetVal_DescTitle); + + if (retval==0) + { + printf("Error: unexpected end of comment at line %d while inside <dl> block\n", + doctokenizerYYlineno); + } + +enddesclist: + + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + DBG(("DocHtmlDescList::parse() end\n")); + return retval==RetVal_EndDesc ? RetVal_OK : retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlPre::parse() +{ + int rv; + g_nodeStack.push(this); + + do + { + DocPara *par = new DocPara(this); + m_children.append(par); + rv=par->parse(); + } + while (rv==TK_NEWPARA); + + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return rv==RetVal_EndPre ? RetVal_OK : rv; +} + +//--------------------------------------------------------------------------- + +int DocHtmlListItem::parse() +{ + DBG(("DocHtmlListItem::parse() start\n")); + int retval=0; + g_nodeStack.push(this); + + // parse one or more paragraphs + do + { + DocPara *par = new DocPara(this); + m_children.append(par); + retval=par->parse(); + } + while (retval==TK_NEWPARA); + + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + DBG(("DocHtmlListItem::parse() end retval=%x\n",retval)); + return retval; +} + +//--------------------------------------------------------------------------- + +int DocHtmlList::parse() +{ + DBG(("DocHtmlList::parse() start\n")); + int retval=RetVal_OK; + g_nodeStack.push(this); + + // get next token + int tok=doctokenizerYYlex(); + // skip whitespace + while (tok==TK_WHITESPACE) tok=doctokenizerYYlex(); + // should find a html tag now + if (tok==TK_HTMLTAG) + { + int tagId=HtmlTagMapper::map(g_token->name); + if (tagId==HTML_LI && !g_token->endTag) // found <li> tag + { + // ok, we can go on. + } + else // found some other tag + { + printf("Error: expected <li> tag at line %d but " + "found <%s> instead!\n",doctokenizerYYlineno,g_token->name.data()); + goto endlist; + } + } + else if (tok==0) // premature end of comment + { + printf("Error: unexpected end of comment at line %d while looking" + " for a html list item\n",doctokenizerYYlineno); + goto endlist; + } + else // token other than html token + { + printf("Error: expected <li> tag at line %d but found %s token instead!\n", + doctokenizerYYlineno,tokToString(tok)); + goto endlist; + } + + do + { + DocHtmlListItem *li=new DocHtmlListItem(this); + m_children.append(li); + retval=li->parse(); + } while (retval==RetVal_ListItem); + + if (retval==0) + { + printf("Error: unexpected end of comment at line %d while inside <%cl> block\n", + doctokenizerYYlineno,m_type==Unordered ? 'u' : 'o'); + } + +endlist: + DBG(("DocHtmlList::parse() end retval=%x\n",retval)); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval==RetVal_EndList ? RetVal_OK : retval; +} + +//--------------------------------------------------------------------------- + +int DocSimpleListItem::parse() +{ + g_nodeStack.push(this); + int rv=m_paragraph->parse(); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return rv; +} + +//-------------------------------------------------------------------------- + +int DocSimpleList::parse() +{ + g_nodeStack.push(this); + int rv; + do + { + DocSimpleListItem *li=new DocSimpleListItem(this); + m_children.append(li); + rv=li->parse(); + } while (rv==RetVal_ListItem); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return (rv!=TK_NEWPARA) ? rv : RetVal_OK; +} + +//-------------------------------------------------------------------------- + +int DocAutoListItem::parse() +{ + int retval = RetVal_OK; + g_nodeStack.push(this); + retval=m_paragraph->parse(); + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//-------------------------------------------------------------------------- + +int DocAutoList::parse() +{ + int retval = RetVal_OK; + g_nodeStack.push(this); + // first item or sub list => create new list + do + { + DocAutoListItem *li = new DocAutoListItem(this); + m_children.append(li); + retval=li->parse(); + } + 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 + ); + + DocNode *n=g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//-------------------------------------------------------------------------- + +void DocTitle::parse() +{ + DBG(("DocTitle::parse() start\n")); + g_nodeStack.push(this); + doctokenizerYYsetStateTitle(); + int tok; + while ((tok=doctokenizerYYlex())) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command %s as part of a title section at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + doctokenizerYYsetStatePara(); + handlePendingStyleCommands(this,m_children); + DBG(("DocTitle::parse() end\n")); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); +} + +//-------------------------------------------------------------------------- + +DocSimpleSect::DocSimpleSect(DocNode *parent,Type t) : + m_parent(parent), m_type(t) +{ + m_paragraph = new DocPara(this); + //m_params.setAutoDelete(TRUE); + m_title = 0; +} + +DocSimpleSect::~DocSimpleSect() +{ + delete m_paragraph; + delete m_title; +} + +void DocSimpleSect::accept(DocVisitor *v) +{ + v->visitPre(this); + if (m_title) m_title->accept(v); + m_paragraph->accept(v); + v->visitPost(this); +} + +int DocSimpleSect::parse(bool userTitle) +{ + DBG(("DocSimpleSect::parse() start\n")); + g_nodeStack.push(this); + + // handle case for user defined title + if (userTitle) + { + m_title = new DocTitle(this); + m_title->parse(); + } + + int retval = m_paragraph->parse(); + + DBG(("DocSimpleSect::parse() end retval=%d\n",retval)); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); + return retval; // 0==EOF, TK_NEWPARA, TK_LISTITEM, TK_ENDLIST, RetVal_SimpleSec +} + +void DocSimpleSect::addParam(const QCString &name) +{ + m_params.append(name); +} + +//-------------------------------------------------------------------------- + +int DocPara::handleSimpleSection(DocSimpleSect::Type t) +{ + DocSimpleSect *ss=new DocSimpleSect(this,t); + m_children.append(ss); + int rv = ss->parse(t==DocSimpleSect::User); + return (rv!=TK_NEWPARA) ? rv : RetVal_OK; +} + +int DocPara::handleParamSection(const QCString &cmdName,DocSimpleSect::Type t) +{ + int tok=doctokenizerYYlex(); + DocSimpleSect *ss=new DocSimpleSect(this,t); + m_children.append(ss); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + } + doctokenizerYYsetStateParam(); + tok=doctokenizerYYlex(); + doctokenizerYYsetStatePara(); + while (tok==TK_WORD) /* there is a parameter name */ + { + ss->addParam(g_token->name); + tok=doctokenizerYYlex(); + } + if (tok==0) /* premature end of comment block */ + { + printf("Error: unexpected end of comment block at line %d while parsing the " + "argument of command %s\n",doctokenizerYYlineno, cmdName.data()); + return 0; + } + ASSERT(tok==TK_WHITESPACE); + int rv = ss->parse(FALSE); + return (rv!=TK_NEWPARA) ? rv : RetVal_OK; +} + +#if 0 +int DocPara::handleStyleArgument(const QCString &cmdName) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + while ((tok=doctokenizerYYlex()) && tok!=TK_WHITESPACE && tok!=TK_NEWPARA) + { + if (!defaultHandleToken(this,tok,m_children)) + { + switch (tok) + { + case TK_COMMAND: + printf("Error: Illegal command \\%s as the argument of a \\%s command at line %d\n", + g_token->name.data(),cmdName.data(),doctokenizerYYlineno); + break; + case TK_SYMBOL: + printf("Error: Unsupported symbol %s found at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + default: + printf("Error: Unexpected token %s at line %d\n", + g_token->name.data(),doctokenizerYYlineno); + break; + } + } + } + return tok==TK_NEWPARA ? TK_NEWPARA : RetVal_OK; +} + +void DocPara::handleStyleEnter(DocStyleChange::Style s) +{ + DBG(("HandleStyleEnter\n")); + DocStyleChange *sc= new DocStyleChange(this,g_nodeStack.count(),s,TRUE); + m_children.append(sc); + g_styleStack.push(sc); +} + +void DocPara::handleStyleLeave(DocStyleChange::Style s,const char *tagName) +{ + DBG(("HandleStyleLeave\n")); + if (g_styleStack.isEmpty() || // no style change + g_styleStack.top()->style()!=s || // wrong style change + g_styleStack.top()->position()!=g_nodeStack.count() // wrong position + ) + { + printf("Error: found </%s> tag at line %d without matching <%s> in the same paragraph\n", + tagName,doctokenizerYYlineno,tagName); + } + else // end the section + { + DocStyleChange *sc= new DocStyleChange(this,g_nodeStack.count(),s,FALSE); + m_children.append(sc); + g_styleStack.pop(); + } +} +#endif + +int DocPara::handleXRefItem(DocXRefItem::Type t) +{ + int retval=doctokenizerYYlex(); + ASSERT(retval==TK_WHITESPACE); + doctokenizerYYsetStateXRefItem(); + retval=doctokenizerYYlex(); + if (retval!=0) + { + m_children.append(new DocXRefItem(this,g_token->id,t)); + } + doctokenizerYYsetStatePara(); + return retval; +} + +void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStatePattern(); + tok=doctokenizerYYlex(); + doctokenizerYYsetStatePara(); + if (tok==0) + { + printf("Error: unexpected end of comment block at line %d while parsing the " + "argument of command %s\n",doctokenizerYYlineno, cmdName.data()); + return; + } + else if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + return; + } + DocIncOperator *op = new DocIncOperator(this,t,g_token->name); + m_children.append(op); +} + +void DocPara::handleImage(const QCString &cmdName) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + tok=doctokenizerYYlex(); + if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + return; + } + tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + DocImage::Type t; + QCString imgType = g_token->name.lower(); + if (imgType=="html") t=DocImage::Html; + else if (imgType=="latex") t=DocImage::Latex; + else if (imgType=="rtf") t=DocImage::Rtf; + else + { + printf("Error: image type %s specified as the first argument of " + "%s at line %d is not valid.\n", + imgType.data(),cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStateFile(); + tok=doctokenizerYYlex(); + if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStatePara(); + DocImage *img = new DocImage(this,g_token->name,t); + m_children.append(img); + img->parse(); +} + +void DocPara::handleDotFile(const QCString &cmdName) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStateFile(); + tok=doctokenizerYYlex(); + if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStatePara(); + DocDotFile *df = new DocDotFile(this,g_token->name); + m_children.append(df); + df->parse(); +} + +void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStateLink(); + tok=doctokenizerYYlex(); + if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStatePara(); + DocLink *lnk = new DocLink(this,g_token->name); + m_children.append(lnk); + QCString leftOver = lnk->parse(isJavaLink); + if (!leftOver.isEmpty()) + { + m_children.append(new DocWord(this,leftOver)); + } +} + +void DocPara::handleRef(const QCString &cmdName) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStateRef(); + tok=doctokenizerYYlex(); // get the reference id + DocRef *ref=0; + if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + goto endref; + } + ref = new DocRef(this,g_token->name); + m_children.append(ref); + ref->parse(); +endref: + doctokenizerYYsetStatePara(); +} + + +int DocPara::handleLanguageSwitch() +{ + int retval=RetVal_OK; + + if (!insideLang(this)) // start a language section at this level + { + do + { + int tok = doctokenizerYYlex(); + if (tok==TK_WHITESPACE) + { + // end of language specific sections + retval=RetVal_OK; + goto endlang; + } + else if (tok==TK_NEWPARA) + { + // end of language specific sections + retval = tok; + goto endlang; + } + else if (tok==TK_WORD) + { + DocLanguage *dl = new DocLanguage(this,g_token->name); + m_children.append(dl); + retval = dl->parse(); + } + else + { + printf("Error: Unexpected token %s as parameter of \\~ at line %d\n", + tokToString(tok),doctokenizerYYlineno); + goto endlang; + } + } + while (retval==RetVal_SwitchLang); + } + else // return from this section + { + retval = RetVal_SwitchLang; + } +endlang: + return retval; +} + +void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) +{ + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + return; + } + doctokenizerYYsetStateFile(); + tok=doctokenizerYYlex(); + doctokenizerYYsetStatePara(); + if (tok==0) + { + printf("Error: unexpected end of comment block at line %d while parsing the " + "argument of command %s\n",doctokenizerYYlineno, cmdName.data()); + return; + } + else if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + return; + } + DocInclude *inc = new DocInclude(this,g_token->name,t); + m_children.append(inc); +} + + +int DocPara::handleCommand(const QCString &cmdName) +{ + int retval = RetVal_OK; + switch (CmdMapper::map(cmdName)) + { + case CMD_UNKNOWN: + printf("Error: Found unknown command `\\%s' at line %d\n",cmdName.data(),doctokenizerYYlineno); + break; + case CMD_EMPHASIS: + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE)); + retval=handleStyleArgument(this,m_children,cmdName); + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,FALSE)); + break; + case CMD_BOLD: + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,TRUE)); + retval=handleStyleArgument(this,m_children,cmdName); + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,FALSE)); + break; + case CMD_CODE: + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,TRUE)); + retval=handleStyleArgument(this,m_children,cmdName); + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,FALSE)); + break; + case CMD_BSLASH: + m_children.append(new DocSymbol(this,DocSymbol::BSlash)); + break; + case CMD_AT: + m_children.append(new DocSymbol(this,DocSymbol::At)); + break; + case CMD_LESS: + m_children.append(new DocSymbol(this,DocSymbol::Less)); + break; + case CMD_GREATER: + m_children.append(new DocSymbol(this,DocSymbol::Greater)); + break; + case CMD_AMP: + m_children.append(new DocSymbol(this,DocSymbol::Amp)); + break; + case CMD_DOLLAR: + m_children.append(new DocSymbol(this,DocSymbol::Dollar)); + break; + case CMD_HASH: + m_children.append(new DocSymbol(this,DocSymbol::Hash)); + break; + case CMD_PERCENT: + m_children.append(new DocSymbol(this,DocSymbol::Percent)); + break; + case CMD_SA: + retval = handleSimpleSection(DocSimpleSect::See); + break; + case CMD_RETURN: + retval = handleSimpleSection(DocSimpleSect::Return); + break; + case CMD_AUTHOR: + retval = handleSimpleSection(DocSimpleSect::Author); + break; + case CMD_VERSION: + retval = handleSimpleSection(DocSimpleSect::Version); + break; + case CMD_SINCE: + retval = handleSimpleSection(DocSimpleSect::Since); + break; + case CMD_DATE: + retval = handleSimpleSection(DocSimpleSect::Date); + break; + case CMD_NOTE: + retval = handleSimpleSection(DocSimpleSect::Note); + break; + case CMD_WARNING: + retval = handleSimpleSection(DocSimpleSect::Warning); + break; + case CMD_PRE: + retval = handleSimpleSection(DocSimpleSect::Pre); + break; + case CMD_POST: + retval = handleSimpleSection(DocSimpleSect::Post); + break; + case CMD_INVARIANT: + retval = handleSimpleSection(DocSimpleSect::Invar); + break; + case CMD_REMARK: + retval = handleSimpleSection(DocSimpleSect::Remark); + break; + case CMD_ATTENTION: + retval = handleSimpleSection(DocSimpleSect::Attention); + break; + case CMD_PAR: + retval = handleSimpleSection(DocSimpleSect::User); + break; + case CMD_LI: + { + DocSimpleList *sl=new DocSimpleList(this); + m_children.append(sl); + retval = sl->parse(); + } + break; + case CMD_SECTION: + { + // get the argument of the section command. + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + break; + } + tok=doctokenizerYYlex(); + if (tok==0) + { + printf("Error: unexpected end of comment block at line %d while parsing the " + "argument of command %s\n",doctokenizerYYlineno, cmdName.data()); + break; + } + else if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + break; + } + g_token->sectionId = g_token->name; + retval = RetVal_Section; + } + break; + case CMD_STARTCODE: + { + doctokenizerYYsetStateCode(); + retval = doctokenizerYYlex(); + m_children.append(new DocVerbatim(this,g_token->verb,DocVerbatim::Code)); + if (retval==0) printf("Error: code section ended without end marker at line %d\n", + doctokenizerYYlineno); + doctokenizerYYsetStatePara(); + } + break; + case CMD_HTMLONLY: + { + doctokenizerYYsetStateHtmlOnly(); + retval = doctokenizerYYlex(); + m_children.append(new DocVerbatim(this,g_token->verb,DocVerbatim::HtmlOnly)); + if (retval==0) printf("Error: htmlonly section ended without end marker at line %d\n", + doctokenizerYYlineno); + doctokenizerYYsetStatePara(); + } + break; + case CMD_LATEXONLY: + { + doctokenizerYYsetStateLatexOnly(); + retval = doctokenizerYYlex(); + m_children.append(new DocVerbatim(this,g_token->verb,DocVerbatim::LatexOnly)); + if (retval==0) printf("Error: latexonly section ended without end marker at line %d\n", + doctokenizerYYlineno); + doctokenizerYYsetStatePara(); + } + break; + case CMD_VERBATIM: + { + doctokenizerYYsetStateVerbatim(); + retval = doctokenizerYYlex(); + m_children.append(new DocVerbatim(this,g_token->verb,DocVerbatim::Verbatim)); + if (retval==0) printf("Error: verbatim section ended without end marker at line %d\n", + doctokenizerYYlineno); + doctokenizerYYsetStatePara(); + } + break; + case CMD_ENDCODE: + case CMD_ENDHTMLONLY: + case CMD_ENDLATEXONLY: + case CMD_ENDLINK: + case CMD_ENDVERBATIM: + printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno); + break; + case CMD_PARAM: + retval = handleParamSection(cmdName,DocSimpleSect::Param); + break; + case CMD_RETVAL: + retval = handleParamSection(cmdName,DocSimpleSect::RetVal); + break; + case CMD_EXCEPTION: + retval = handleParamSection(cmdName,DocSimpleSect::Exception); + break; + case CMD_BUG: + retval = handleXRefItem(DocXRefItem::Bug); + break; + case CMD_TODO: + retval = handleXRefItem(DocXRefItem::Todo); + break; + case CMD_TEST: + retval = handleXRefItem(DocXRefItem::Test); + break; + case CMD_DEPRECATED: + retval = handleXRefItem(DocXRefItem::Deprecated); + break; + case CMD_LINEBREAK: + { + DocLineBreak *lb = new DocLineBreak(this); + m_children.append(lb); + } + break; + case CMD_ANCHOR: + { + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + break; + } + tok=doctokenizerYYlex(); + if (tok==0) + { + printf("Error: unexpected end of comment block at line %d while parsing the " + "argument of command %s\n",doctokenizerYYlineno, cmdName.data()); + break; + } + else if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + break; + } + DocAnchor *anchor = new DocAnchor(this,g_token->name); + m_children.append(anchor); + } + break; + case CMD_ADDINDEX: + { + DocIndexEntry *ie = new DocIndexEntry(this); + m_children.append(ie); + retval = ie->parse(); + } + break; + case CMD_INTERNAL: + retval = RetVal_Internal; + break; + case CMD_COPYDOC: + { + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + printf("Error: expected whitespace after %s command at line %d\n", + cmdName.data(),doctokenizerYYlineno); + break; + } + tok=doctokenizerYYlex(); + if (tok==0) + { + printf("Error: unexpected end of comment block at line %d while parsing the " + "argument of command %s\n",doctokenizerYYlineno, cmdName.data()); + break; + } + else if (tok!=TK_WORD) + { + printf("Error: unexpected token %s as the argument of %s at line %d.\n", + tokToString(tok),cmdName.data(),doctokenizerYYlineno); + break; + } + DocCopy *cpy = new DocCopy(this,g_token->name); + m_children.append(cpy); + } + break; + case CMD_INCLUDE: + handleInclude(cmdName,DocInclude::Include); + break; + case CMD_DONTINCLUDE: + handleInclude(cmdName,DocInclude::DontInclude); + break; + case CMD_HTMLINCLUDE: + handleInclude(cmdName,DocInclude::HtmlInclude); + break; + case CMD_VERBINCLUDE: + handleInclude(cmdName,DocInclude::VerbInclude); + break; + case CMD_SKIP: + handleIncludeOperator(cmdName,DocIncOperator::Skip); + break; + case CMD_UNTIL: + handleIncludeOperator(cmdName,DocIncOperator::Until); + break; + case CMD_SKIPLINE: + handleIncludeOperator(cmdName,DocIncOperator::SkipLine); + break; + case CMD_LINE: + handleIncludeOperator(cmdName,DocIncOperator::Line); + break; + case CMD_IMAGE: + handleImage(cmdName); + break; + case CMD_DOTFILE: + handleDotFile(cmdName); + break; + case CMD_LINK: + handleLink(cmdName,FALSE); + break; + case CMD_JAVALINK: + handleLink(cmdName,TRUE); + break; + case CMD_REF: + handleRef(cmdName); + break; + case CMD_SECREFLIST: + { + DocSecRefList *list = new DocSecRefList(this); + m_children.append(list); + list->parse(); + } + break; + case CMD_SECREFITEM: + printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno); + break; + case CMD_ENDSECREFLIST: + printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno); + break; + case CMD_FORMULA: + { + DocFormula *form=new DocFormula(this,g_token->id); + m_children.append(form); + } + break; + case CMD_LANGSWITCH: + retval = handleLanguageSwitch(); + break; + default: + // we should not get here! + ASSERT(0); + break; + } + ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec || + retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_NEWPARA || + retval==RetVal_Section || retval==RetVal_EndList || + retval==RetVal_Internal || retval==RetVal_SwitchLang + ); + return retval; +} + +#if 0 +void DocPara::handlePendingStyleCommands() +{ + if (!g_styleStack.isEmpty()) + { + DocStyleChange *sc = g_styleStack.top(); + while (sc && sc->position()>=g_nodeStack.count()) + { // there are unclosed style modifiers in the paragraph + const char *cmd; + switch (sc->style()) + { + case DocStyleChange::Bold: cmd = "b"; break; + case DocStyleChange::Italic: cmd = "em"; break; + case DocStyleChange::Code: cmd = "code"; break; + case DocStyleChange::Center: cmd = "center"; break; + case DocStyleChange::Small: cmd = "small"; break; + case DocStyleChange::Subscript: cmd = "subscript"; break; + case DocStyleChange::Superscript: cmd = "superscript"; break; + } + printf("Error: end of paragraph at line %d without end of style " + "command </%s>\n",doctokenizerYYlineno,cmd); + m_children.append(new DocStyleChange(this,g_nodeStack.count(),sc->style(),FALSE)); + g_styleStack.pop(); + sc = g_styleStack.top(); + } + } +} +#endif + +int DocPara::handleHtmlStartTag(const QCString &tagName,const QList<Option> &tagOptions) +{ + DBG(("handleHtmlStartTag(%s,%d)\n",tagName.data(),tagOptions.count())); + int retval=RetVal_OK; + int tagId = HtmlTagMapper::map(tagName); + switch (tagId) + { + case HTML_UL: + { + DocHtmlList *list = new DocHtmlList(this,DocHtmlList::Unordered); + m_children.append(list); + retval=list->parse(); + } + break; + case HTML_OL: + { + DocHtmlList *list = new DocHtmlList(this,DocHtmlList::Ordered); + m_children.append(list); + retval=list->parse(); + } + break; + case HTML_LI: + if (!insideUL(this) && !insideOL(this)) + { + printf("Error: lonely <li> tag found at line %d\n",doctokenizerYYlineno); + } + else + { + retval=RetVal_ListItem; + } + break; + case HTML_PRE: + { + DocHtmlPre *pre = new DocHtmlPre(this); + m_children.append(pre); + retval=pre->parse(); + } + break; + case HTML_BOLD: + handleStyleEnter(this,m_children,DocStyleChange::Bold); + break; + case HTML_CODE: + handleStyleEnter(this,m_children,DocStyleChange::Code); + break; + case HTML_EMPHASIS: + handleStyleEnter(this,m_children,DocStyleChange::Italic); + break; + case HTML_SUB: + handleStyleEnter(this,m_children,DocStyleChange::Subscript); + break; + case HTML_SUP: + handleStyleEnter(this,m_children,DocStyleChange::Superscript); + break; + case HTML_CENTER: + handleStyleEnter(this,m_children,DocStyleChange::Center); + break; + case HTML_SMALL: + handleStyleEnter(this,m_children,DocStyleChange::Small); + break; + case HTML_P: + retval=TK_NEWPARA; + break; + case HTML_DL: + { + DocHtmlDescList *list = new DocHtmlDescList(this); + m_children.append(list); + retval=list->parse(); + } + break; + case HTML_DT: + retval = RetVal_DescTitle; + break; + case HTML_DD: + printf("Error: Unexpected tag <dd> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_TABLE: + { + DocHtmlTable *table = new DocHtmlTable(this); + m_children.append(table); + retval=table->parse(); + } + break; + case HTML_TR: + retval = RetVal_TableRow; + break; + case HTML_TD: + retval = RetVal_TableCell; + break; + case HTML_TH: + retval = RetVal_TableHCell; + break; + case HTML_CAPTION: + printf("Error: Unexpected tag <caption> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_BR: + { + DocLineBreak *lb = new DocLineBreak(this); + m_children.append(lb); + } + break; + case HTML_HR: + { + DocHorRuler *hr = new DocHorRuler(this); + m_children.append(hr); + } + break; + case HTML_A: + { + QListIterator<Option> li(tagOptions); + Option *opt; + for (li.toFirst();(opt=li.current());++li) + { + if (opt->name=="name") // <a name=label> tag + { + if (!opt->value.isEmpty()) + { + DocAnchor *anc = new DocAnchor(this,opt->value); + m_children.append(anc); + break; // stop looking for other tag options + } + else + { + printf("Error: found <a> tag at line %d with name option but without value!\n", + doctokenizerYYlineno); + } + } + else if (opt->name=="href") // <a href=url>..</a> tag + { + DocHRef *href = new DocHRef(this,opt->value); + m_children.append(href); + retval = href->parse(); + break; + } + else // unsupport option for tag a + { + } + } + } + break; + case HTML_H1: + { + DocHtmlHeader *header = new DocHtmlHeader(this,1); + m_children.append(header); + retval = header->parse(); + } + break; + case HTML_H2: + { + DocHtmlHeader *header = new DocHtmlHeader(this,2); + m_children.append(header); + retval = header->parse(); + } + break; + case HTML_H3: + { + DocHtmlHeader *header = new DocHtmlHeader(this,3); + m_children.append(header); + retval = header->parse(); + } + break; + case HTML_IMG: + { + QListIterator<Option> li(tagOptions); + Option *opt; + for (li.toFirst();(opt=li.current());++li) + { + if (opt->name=="src" && !opt->value.isEmpty()) + { + DocImage *img = new DocImage(this,opt->value,DocImage::Html); + m_children.append(img); + } + } + } + break; + case HTML_UNKNOWN: + printf("Error: Unsupported html tag <%s> found at line %d\n", + tagName.data(), doctokenizerYYlineno); + break; + default: + // we should not get here! + ASSERT(0); + break; + } + return retval; +} + +int DocPara::handleHtmlEndTag(const QCString &tagName) +{ + DBG(("handleHtmlEndTag(%s)\n",tagName.data())); + int tagId = HtmlTagMapper::map(tagName); + int retval=RetVal_OK; + switch (tagId) + { + case HTML_UL: + if (!insideUL(this)) + { + printf("Error: found </ul> tag at line %d without matching <ul>\n", + doctokenizerYYlineno); + } + else + { + retval=RetVal_EndList; + } + break; + case HTML_OL: + if (!insideOL(this)) + { + printf("Error: found </ol> tag at line %d without matching <ol>\n", + doctokenizerYYlineno); + } + else + { + retval=RetVal_EndList; + } + break; + case HTML_LI: + if (!insideLI(this)) + { + printf("Error: found </li> tag at line %d without matching <li>\n", + doctokenizerYYlineno); + } + else + { + // ignore </li> tags + } + break; + case HTML_PRE: + if (!insidePRE(this)) + { + printf("Error: found </pre> tag at line %d without matching <pre>\n", + doctokenizerYYlineno); + } + else + { + retval=RetVal_EndPre; + } + break; + case HTML_BOLD: + handleStyleLeave(this,m_children,DocStyleChange::Bold,"b"); + break; + case HTML_CODE: + handleStyleLeave(this,m_children,DocStyleChange::Code,"code"); + break; + case HTML_EMPHASIS: + handleStyleLeave(this,m_children,DocStyleChange::Italic,"em"); + break; + case HTML_SUB: + handleStyleLeave(this,m_children,DocStyleChange::Subscript,"sub"); + break; + case HTML_SUP: + handleStyleLeave(this,m_children,DocStyleChange::Superscript,"sup"); + break; + case HTML_CENTER: + handleStyleLeave(this,m_children,DocStyleChange::Center,"center"); + break; + case HTML_SMALL: + handleStyleLeave(this,m_children,DocStyleChange::Small,"small"); + break; + case HTML_P: + // ignore </p> tag + break; + case HTML_DL: + retval=RetVal_EndDesc; + break; + case HTML_DT: + // ignore </dt> tag + break; + case HTML_DD: + // ignore </dd> tag + break; + case HTML_TABLE: + retval=RetVal_EndTable; + break; + case HTML_TR: + // ignore </tr> tag + break; + case HTML_TD: + // ignore </td> tag + break; + case HTML_TH: + // ignore </th> tag + break; + case HTML_CAPTION: + printf("Error: Unexpected tag </caption> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_BR: + printf("Error: Illegal </br> tag found\n"); + break; + case HTML_H1: + printf("Error: Unexpected tag </h1> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_H2: + printf("Error: Unexpected tag </h2> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_H3: + printf("Error: Unexpected tag </h3> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_IMG: + printf("Error: Unexpected tag </img> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_HR: + printf("Error: Unexpected tag </hr> found at line %d\n", + doctokenizerYYlineno); + break; + case HTML_A: + //printf("Error: Unexpected tag </a> found at line %d\n", + // doctokenizerYYlineno); + // ignore </a> tag (can be part of <a name=...></a> + break; + case HTML_UNKNOWN: + printf("Error: Unsupported html tag </%s> found at line %d\n", + tagName.data(), doctokenizerYYlineno); + break; + default: + // we should not get here! + ASSERT(0); + break; + } + return retval; +} + +int DocPara::parse() +{ + DBG(("DocPara::parse() start\n")); + g_nodeStack.push(this); + int tok; + int retval=0; + while ((tok=doctokenizerYYlex())) // get the next token + { +reparsetoken: + DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); + if (tok==TK_WORD || tok==TK_SYMBOL || tok==TK_URL || + tok==TK_COMMAND || tok==TK_HTMLTAG + ) + { + DBG((" name=%s",g_token->name.data())); + } + DBG(("\n")); + switch(tok) + { + case TK_WORD: + m_children.append(new DocWord(this,g_token->name)); + break; + case TK_URL: + m_children.append(new DocURL(this,g_token->name)); + break; + case TK_WHITESPACE: + // prevent leading whitespace and collapse multiple whitespace areas + if (insidePRE(this) || // all whitespace is relavant + ( // keep only whitespace after words, URL or symbols + !m_children.isEmpty() && + ( + m_children.last()->kind()==DocNode::Kind_Word || + m_children.last()->kind()==DocNode::Kind_URL || + m_children.last()->kind()==DocNode::Kind_Symbol + ) + ) + ) + { + m_children.append(new DocWhiteSpace(this,g_token->chars)); + } + break; + case TK_LISTITEM: + { + DBG(("found list item at %d parent=%d\n",g_token->indent,parent()->kind())); + DocNode *n=parent(); + while (n && n->kind()!=DocNode::Kind_AutoList) n=n->parent(); + if (n) // we found an auto list up in the hierarchy + { + DocAutoList *al = (DocAutoList *)n; + DBG(("previous list item at %d\n",al->indent())); + if (al->indent()>=g_token->indent) + // new item at the same or lower indent level + { + retval=TK_LISTITEM; + goto endparagraph; + } + } + // first item or sub list => create new list + DocAutoList *al=0; + do + { + al = new DocAutoList(this,g_token->indent,g_token->isEnumList); + m_children.append(al); + retval = al->parse(); + } while (retval==TK_LISTITEM && // new list + al->indent()==g_token->indent // at some indent level + ); + + // check the return value + if (retval==RetVal_SimpleSec) // auto list ended due to simple section command + { + // Reparse the token that ended the section at this level, + // so a new simple section will be started at this level. + // This is the same as unputting the last read token and continuing. + g_token->name = g_token->simpleSectName; + tok = TK_COMMAND; + DBG(("reparsing command %s\n",g_token->name.data())); + goto reparsetoken; + } + else if (retval==TK_ENDLIST) + { + if (al->indent()>g_token->indent) // end list + { + goto endparagraph; + } + else // continue with current paragraph + { + } + } + else // paragraph ended due to TK_NEWPARA, TK_LISTITEM, or EOF + { + goto endparagraph; + } + } + break; + case TK_ENDLIST: + DBG(("Found end of list inside of paragraph at line %d\n",doctokenizerYYlineno)); + if (parent()->kind()==DocNode::Kind_AutoListItem) + { + ASSERT(parent()->parent()->kind()==DocNode::Kind_AutoList); + DocAutoList *al = (DocAutoList *)parent()->parent(); + if (al->indent()>=g_token->indent) + { + // end of list marker ends this paragraph + retval=TK_ENDLIST; + goto endparagraph; + } + else + { + printf("Error: End of list marker found at line %d " + "has invalid indent level ",doctokenizerYYlineno); + } + } + else + { + printf("Error: End of list marker found at line %d without any preceding " + "list items\n",doctokenizerYYlineno); + } + break; + case TK_COMMAND: + { + // see if we have to start a simple section + int cmd = CmdMapper::map(g_token->name); + DocNode *n=parent(); + while (n && n->kind()!=DocNode::Kind_SimpleSect) n=n->parent(); + if (cmd&SIMPLESECT_BIT) + { + if (n // already in a simple section + //|| // no section or root as parent + // (parent()->kind()!=DocNode::Kind_Root && + // parent()->kind()!=DocNode::Kind_Section + // ) + ) + { + // simple section cannot start in this paragraph, need + // to unwind the stack and remember the command. + g_token->simpleSectName = g_token->name.copy(); + retval=RetVal_SimpleSec; + goto endparagraph; + } + } + // see if we are in a simple list + n=parent(); + while (n && n->kind()!=DocNode::Kind_SimpleListItem) n=n->parent(); + if (n) + { + if (cmd==CMD_LI) + { + retval=RetVal_ListItem; + goto endparagraph; + } + } + + // handle the command + retval=handleCommand(g_token->name.copy()); + + // check the return value + if (retval==RetVal_SimpleSec) + { + // Reparse the token that ended the section at this level, + // so a new simple section will be started at this level. + // This is the same as unputting the last read token and continuing. + g_token->name = g_token->simpleSectName; + tok = TK_COMMAND; + DBG(("reparsing command %s\n",g_token->name.data())); + goto reparsetoken; + } + else if (retval==RetVal_OK) + { + // the command ended normally, keep scanner for new tokens. + retval = 0; + } + else // end of file, end of paragraph, start or end of section + // or some auto list marker + { + goto endparagraph; + } + } + break; + case TK_HTMLTAG: + { + if (!g_token->endTag) // found a start tag + { + retval = handleHtmlStartTag(g_token->name,g_token->options); + } + else // found an end tag + { + retval = handleHtmlEndTag(g_token->name); + } + if (retval==RetVal_OK) + { + // the command ended normally, keep scanner for new tokens. + retval = 0; + } + else + { + goto endparagraph; + } + } + break; + case TK_SYMBOL: + break; + case TK_NEWPARA: + retval=TK_NEWPARA; + goto endparagraph; + } + } +endparagraph: + handlePendingStyleCommands(this,m_children); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); + DBG(("DocPara::parse() end retval=%x\n",retval)); + ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || + retval==TK_ENDLIST || retval>RetVal_OK + ); + + if (!(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || + retval==TK_ENDLIST || retval>RetVal_OK + )) printf("DocPara::parse: Error retval=%x unexpected at line %d!\n",retval,doctokenizerYYlineno); + return retval; +} + +//-------------------------------------------------------------------------- + +int DocSection::parse() +{ + DBG(("DocSection::parse() start %s\n",g_token->sectionId.data())); + int retval=RetVal_OK; + g_nodeStack.push(this); + + // first parse any number of paragraphs + do + { + DocPara *par = new DocPara(this); + retval=par->parse(); + if (!par->isEmpty()) m_children.append(par); + if (retval==TK_LISTITEM) + { + printf("Error: Invalid list item found at line %d!\n",doctokenizerYYlineno); + } + } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Internal); + + // then parse any number of nested sections + while (retval==RetVal_Section) // more sections follow + { + SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; + int secLev = sec->type==SectionInfo::Subsection ? 2 : 1; + if (secLev==level()) // new section at same level + { + break; + } + if (secLev!=level()+1) // new section at wrong level + { + printf("Error: Expected level %d section, found a section " + "with level %d at line %d.\n",level()+1,secLev,doctokenizerYYlineno); + retval=0; // stop parsing any further. + break; + } + else // nested section + { + DocSection *s=new DocSection(this,secLev,g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + } + ASSERT(retval==0 || retval==RetVal_Section); + + DBG(("DocSection::parse() end\n")); + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); + return retval; +} + +//-------------------------------------------------------------------------- + +void DocRoot::parse() +{ + g_nodeStack.push(this); + doctokenizerYYsetStatePara(); + DocPara *par=0; + int retval=0; + + // first parse any number of paragraphs + do + { + par = new DocPara(this); + retval=par->parse(); + if (!par->isEmpty()) m_children.append(par); + if (retval==TK_LISTITEM) + { + printf("Error: Invalid list item found at line %d!\n",doctokenizerYYlineno); + } + } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Internal); + + // then parse any number of level1 sections + while (retval==RetVal_Section) + { + SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; + int secLev = sec->type==SectionInfo::Subsection ? 2 : 1; + if (secLev!=1) // wrong level + { + printf("Error: Expected level 1 section, found a section with level %d at line %d.\n",secLev,doctokenizerYYlineno); + break; + } + else + { + DocSection *s=new DocSection(this,secLev,g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + } + + if (retval==RetVal_Internal) + { + DocInternal *in = new DocInternal(this); + m_children.append(in); + retval = in->parse(); + } + + DocNode *n = g_nodeStack.pop(); + ASSERT(n==this); +} + +//-------------------------------------------------------------------------- + +void validatingParseDoc(const char *fileName,int startLine,const char *input) +{ + //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input); + // + printf("========== validating %s at line %d\n",fileName,startLine); + g_token = new TokenInfo; + + doctokenizerYYlineno=startLine; + doctokenizerYYinit(input); + + // build abstract syntax tree + DocRoot *root = new DocRoot; + root->parse(); + + if (Debug::isFlagSet(Debug::PrintTree)) + { + // pretty print the result + PrintDocVisitor *v = new PrintDocVisitor; + root->accept(v); + } + + delete root; + + delete g_token; + + // TODO: These should be called at the end of the program. + //doctokenizerYYcleanup(); + //CmdMapper::freeInstance(); + //HtmlTagMapper::freeInstance(); +} + diff --git a/src/docparser.h b/src/docparser.h new file mode 100644 index 0000000..bbe5575 --- /dev/null +++ b/src/docparser.h @@ -0,0 +1,900 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef _DOCPARSER_H +#define _DOCPARSER_H + +#include <qlist.h> +#include <qstrlist.h> +#include <stdio.h> + +#include "docvisitor.h" +#include "doctokenizer.h" + +//--------------------------------------------------------------------------- + +/*! Main entry point */ +void validatingParseDoc(const char *fileName,int startLine,const char *input); + +//--------------------------------------------------------------------------- + +/*! Abstract node interface with type information. */ +class DocNode +{ + public: + enum Kind { Kind_Root = 0, + Kind_Word = 1, + Kind_WhiteSpace = 2, + Kind_Para = 3, + Kind_AutoList = 4, + Kind_AutoListItem = 5, + Kind_Symbol = 6, + Kind_URL = 7, + Kind_StyleChange = 8, + Kind_SimpleSect = 9, + Kind_Title = 10, + Kind_SimpleList = 11, + Kind_SimpleListItem = 12, + Kind_Section = 13, + Kind_Verbatim = 14, + Kind_XRefItem = 15, + Kind_HtmlList = 16, + Kind_HtmlListItem = 17, + Kind_HtmlPre = 18, + Kind_HtmlDescList = 19, + Kind_HtmlDescData = 20, + Kind_HtmlDescTitle = 21, + Kind_HtmlTable = 22, + Kind_HtmlRow = 23, + Kind_HtmlCell = 24, + Kind_HtmlCaption = 25, + Kind_LineBreak = 26, + Kind_HorRuler = 27, + Kind_Anchor = 28, + Kind_IndexEntry = 29, + Kind_Internal = 30, + Kind_HRef = 31, + Kind_Copy = 32, + Kind_Include = 33, + Kind_IncOperator = 34, + Kind_HtmlHeader = 35, + Kind_Image = 36, + Kind_DotFile = 37, + Kind_Link = 38, + Kind_Ref = 39, + Kind_Formula = 40, + Kind_SecRefItem = 41, + Kind_SecRefList = 42, + Kind_Language = 43 + }; + virtual ~DocNode() {} + virtual Kind kind() const = 0; + virtual DocNode *parent() const = 0; + virtual void accept(DocVisitor *) = 0; +}; + +/*! Default accept implementation for compound nodes in the abstract + * syntax tree. + */ +template<class T> class CompAccept +{ + public: + CompAccept() { m_children.setAutoDelete(TRUE); } + void accept(T *obj, DocVisitor *v) + { + v->visitPre(obj); + QListIterator<DocNode> cli(m_children); + DocNode *n; + for (cli.toFirst();(n=cli.current());++cli) n->accept(v); + v->visitPost(obj); + } + + protected: + QList<DocNode> m_children; +}; + + +/*! Node representing a word + */ +// TODO: check for word starting \# or having () and try to link to them +class DocWord : public DocNode +{ + public: + DocWord(DocNode *parent,const QCString &word) : + m_parent(parent), m_word(word) {} + QCString word() const { return m_word; } + Kind kind() const { return Kind_Word; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + QCString m_word; +}; + +/*! Node representing an URL (or email address) */ +class DocURL : public DocNode +{ + public: + DocURL(DocNode *parent,const QCString &url) : + m_parent(parent), m_url(url) {} + QCString url() const { return m_url; } + Kind kind() const { return Kind_URL; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + QCString m_url; +}; + +/*! Node representing a line break */ +class DocLineBreak : public DocNode +{ + public: + DocLineBreak(DocNode *parent) : + m_parent(parent) {} + Kind kind() const { return Kind_LineBreak; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; +}; + +/*! Node representing a horizonal ruler */ +class DocHorRuler : public DocNode +{ + public: + DocHorRuler(DocNode *parent) : + m_parent(parent) {} + Kind kind() const { return Kind_HorRuler; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; +}; + +/*! Node representing an anchor */ +// TODO: not just ignore </a>... +class DocAnchor : public DocNode +{ + public: + DocAnchor(DocNode *parent,const QCString &anchor) : + m_parent(parent), m_anchor(anchor) {} + Kind kind() const { return Kind_Anchor; } + DocNode *parent() const { return m_parent; } + QCString anchor() const { return m_anchor; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + QCString m_anchor; +}; + +/*! Node representing a style change */ +class DocStyleChange : public DocNode +{ + public: + enum Style { Bold, Italic, Code, Center, Small, + Subscript, Superscript + }; + DocStyleChange(DocNode *parent,uint position,Style s,bool enable) : + m_parent(parent), m_position(position), m_style(s), m_enable(enable) {} + Kind kind() const { return Kind_StyleChange; } + Style style() const { return m_style; } + bool enable() const { return m_enable; } + uint position() const { return m_position; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + uint m_position; + Style m_style; + bool m_enable; +}; + +/*! Node representing a special symbol */ +class DocSymbol : public DocNode +{ + public: + enum SymType { Unknown=0, BSlash,At,Less,Greater,Amp,Dollar,Hash,Percent, + Copy, Apos, Quot, Uml, Acute, Grave, Circ, Tilde, Szlig, + Cedil, Ring, Nbsp + }; + DocSymbol(DocNode *parent,SymType s,char letter='\0') : + m_parent(parent), m_symbol(s), m_letter(letter) {} + SymType symbol() const { return m_symbol; } + char letter() const { return m_letter; } + Kind kind() const { return Kind_Symbol; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + static SymType decodeSymbol(const QCString &symName,char *letter); + + private: + DocNode *m_parent; + SymType m_symbol; + char m_letter; +}; + +/*! Node representing some amount of white space */ +class DocWhiteSpace : public DocNode +{ + public: + DocWhiteSpace(DocNode *parent,const QCString &chars) : + m_parent(parent), m_chars(chars) {} + Kind kind() const { return Kind_WhiteSpace; } + QCString chars() const { return m_chars; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + private: + DocNode *m_parent; + QCString m_chars; +}; + +/*! Verbatim, unparsed text fragment */ +class DocVerbatim : public DocNode +{ + public: + enum Type { Code, HtmlOnly, LatexOnly, Verbatim }; + DocVerbatim(DocNode *parent,const QCString &text, Type t) : + m_parent(parent), m_text(text), m_type(t) {} + Kind kind() const { return Kind_Verbatim; } + Type type() const { return m_type; } + QCString text() const { return m_text; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + QCString m_text; + Type m_type; +}; + +/*! "to be copied" documentation block */ +// TODO: Find the matching block and insert it. +// (This should be a separate pass, or can we do it in one pass?). +class DocCopy : public DocNode +{ + public: + DocCopy(DocNode *parent,const QCString &link) : + m_parent(parent), m_link(link) {} + Kind kind() const { return Kind_Copy; } + QCString link() const { return m_link; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + QCString m_link; +}; + +/*! include/dontinclude block */ +// TODO: locate the file and handle it. +class DocInclude : public DocNode +{ + public: + enum Type { Include, DontInclude, VerbInclude, HtmlInclude }; + DocInclude(DocNode *parent,const QCString &file,Type t) : + m_parent(parent), m_file(file), m_type(t) {} + Kind kind() const { return Kind_Include; } + QCString file() const { return m_file; } + Type type() const { return m_type; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + QCString m_file; + Type m_type; +}; + +/*! include/dontinclude operator block */ +// TODO: check which file we should be working on and do the operation +class DocIncOperator : public DocNode +{ + public: + enum Type { Line, SkipLine, Skip, Until }; + DocIncOperator(DocNode *parent,Type t,const QCString &pat) : + m_parent(parent), m_type(t), m_pattern(pat) {} + Kind kind() const { return Kind_IncOperator; } + Type type() const { return m_type; } + QCString pattern() const { return m_pattern; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + Type m_type; + QCString m_pattern; +}; + +/*! Item of a cross-referenced list */ +// TODO: lookup id and insert parsed documentation +// (second pass to avoid context saving in the scanner?) +class DocXRefItem : public DocNode +{ + public: + enum Type { Bug, Test, Todo, Deprecated }; + DocXRefItem(DocNode *parent,int id,Type t) : + m_parent(parent), m_id(id), m_type(t) {} + Kind kind() const { return Kind_XRefItem; } + Type type() const { return m_type; } + int id() const { return m_id; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + int m_id; + Type m_type; +}; + +/*! Item of a cross-referenced list */ +class DocFormula : public DocNode +{ + public: + DocFormula(DocNode *parent,int id) : + m_parent(parent), m_id(id) {} + Kind kind() const { return Kind_Formula; } + int id() const { return m_id; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { v->visit(this); } + + private: + DocNode *m_parent; + int m_id; +}; + +/*! Node representing a entry in the index */ +class DocIndexEntry : public CompAccept<DocIndexEntry>, public DocNode +{ + public: + DocIndexEntry(DocNode *parent) : m_parent(parent) { } + Kind kind() const { return Kind_IndexEntry; } + int parse(); + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocIndexEntry>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Auto List */ +class DocAutoList : public CompAccept<DocAutoList>, public DocNode +{ + public: + DocAutoList(DocNode *parent,int indent,bool isEnumList) : + m_parent(parent), m_indent(indent), m_isEnumList(isEnumList) {} + Kind kind() const { return Kind_AutoList; } + int parse(); + bool isEnumList() const { return m_isEnumList; } + int indent() const { return m_indent; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocAutoList>::accept(this,v); } + + private: + DocNode *m_parent; + int m_indent; + bool m_isEnumList; +}; + + +/*! Simple section title */ +class DocTitle : public CompAccept<DocTitle>, public DocNode +{ + public: + DocTitle(DocNode *parent) : m_parent(parent) {} + void parse(); + Kind kind() const { return Kind_Title; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocTitle>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Image */ +class DocImage : public CompAccept<DocImage>, public DocNode +{ + public: + enum Type { Html, Latex, Rtf }; + DocImage(DocNode *parent,const QCString &name,Type t) : + m_parent(parent), m_name(name), m_type(t) {} + void parse(); + Kind kind() const { return Kind_Image; } + Type type() const { return m_type; } + QCString name() const { return m_name; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocImage>::accept(this,v); } + + private: + DocNode *m_parent; + QCString m_name; + Type m_type; +}; + +/*! Node representing a dot file */ +class DocDotFile : public CompAccept<DocDotFile>, public DocNode +{ + public: + DocDotFile(DocNode *parent,const QCString &name) : + m_parent(parent), m_name(name) { } + void parse(); + Kind kind() const { return Kind_DotFile; } + QCString name() const { return m_name; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocDotFile>::accept(this,v); } + + private: + DocNode *m_parent; + QCString m_name; +}; + +/*! Node representing a link to some item */ +// TODO: resolve link +class DocLink : public CompAccept<DocLink>, public DocNode +{ + public: + DocLink(DocNode *parent,const QCString &target) : + m_parent(parent), m_target(target) {} + QCString parse(bool); + Kind kind() const { return Kind_Link; } + QCString target() const { return m_target; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocLink>::accept(this,v); } + + private: + DocNode *m_parent; + QCString m_target; +}; + +/*! Node representing a reference to some item */ +// TODO: resolve reference +class DocRef : public CompAccept<DocRef>, public DocNode +{ + public: + DocRef(DocNode *parent,const QCString &target) : + m_parent(parent), m_target(target) {} + void parse(); + Kind kind() const { return Kind_Ref; } + QCString target() const { return m_target; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocRef>::accept(this,v); } + + private: + DocNode * m_parent; + QCString m_target; +}; + +/*! Simple section */ +class DocSimpleSect : public DocNode +{ + public: + enum Type + { + Unknown, See, Return, Author, Version, Since, Date, + Note, Warning, Pre, Post, Invar, Remark, Attention, User, + Param, RetVal, Exception + }; + DocSimpleSect(DocNode *parent,Type t); + virtual ~DocSimpleSect(); + int parse(bool userTitle); + Kind kind() const { return Kind_SimpleSect; } + void addParam(const QCString &name); + const QStrList ¶meters() const { return m_params; } + Type sectionType() const { return m_type; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v); + + private: + DocNode * m_parent; + DocPara * m_paragraph; + Type m_type; + DocTitle * m_title; + QStrList m_params; +}; + +/*! Language specific node */ +class DocLanguage : public CompAccept<DocLanguage>, public DocNode +{ + public: + DocLanguage(DocNode *parent,const QCString &id) : + m_parent(parent), m_id(id) {} + QCString id() const { return m_id; } + int parse(); + Kind kind() const { return Kind_Language; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocLanguage>::accept(this,v); } + + private: + DocNode * m_parent; + QCString m_id; +}; + +/*! Hypertext reference */ +class DocHRef : public CompAccept<DocHRef>, public DocNode +{ + public: + DocHRef(DocNode *parent,const QCString &url) : + m_parent(parent), m_url(url) {} + int parse(); + QCString url() const { return m_url; } + Kind kind() const { return Kind_HRef; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHRef>::accept(this,v); } + + private: + DocNode * m_parent; + QCString m_url; +}; + +/*! Html heading */ +class DocHtmlHeader : public CompAccept<DocHtmlHeader>, public DocNode +{ + public: + DocHtmlHeader(DocNode *parent,int level) : + m_parent(parent), m_level(level) {} + int parse(); + int level() const { return m_level; } + Kind kind() const { return Kind_HtmlHeader; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlHeader>::accept(this,v); } + + private: + DocNode * m_parent; + int m_level; +}; + +/*! Html description item */ +class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>, public DocNode +{ + public: + DocHtmlDescTitle(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlDescTitle; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlDescTitle>::accept(this,v); } + + private: + DocNode * m_parent; +}; + +/*! Html description list */ +class DocHtmlDescList : public CompAccept<DocHtmlDescList>, public DocNode +{ + public: + DocHtmlDescList(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlDescList; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlDescList>::accept(this,v); } + + private: + DocNode * m_parent; +}; + +/*! Normal section */ +class DocSection : public CompAccept<DocSection>, public DocNode +{ + public: + DocSection(DocNode *parent,int level,const QCString &id) : + m_parent(parent), m_level(level), m_id(id) {} + int parse(); + Kind kind() const { return Kind_Section; } + int level() const { return m_level; } + QCString id() const { return m_id; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocSection>::accept(this,v); } + + private: + DocNode *m_parent; + int m_level; + QCString m_id; +}; + +/*! Reference to a section */ +class DocSecRefItem : public CompAccept<DocSecRefItem>, public DocNode +{ + public: + DocSecRefItem(DocNode *parent,const QCString &target) : + m_parent(parent), m_target(target) {} + void parse(); + Kind kind() const { return Kind_SecRefItem; } + QCString target() const { return m_target; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocSecRefItem>::accept(this,v); } + + private: + DocNode *m_parent; + QCString m_target; +}; + +/*! List of section references */ +class DocSecRefList : public CompAccept<DocSecRefList>, public DocNode +{ + public: + DocSecRefList(DocNode *parent) : m_parent(parent) {} + void parse(); + Kind kind() const { return Kind_SecRefList; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocSecRefList>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Internal section of documentation */ +// TODO: decide if it should be visible +// Separate pass to remove internal parts? +class DocInternal : public CompAccept<DocInternal>, public DocNode +{ + public: + DocInternal(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_Internal; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocInternal>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Simple list */ +class DocSimpleList : public CompAccept<DocSimpleList>, public DocNode +{ + public: + DocSimpleList(DocNode *parent) : m_parent(parent) {} + Kind kind() const { return Kind_SimpleList; } + int parse(); + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocSimpleList>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Html list */ +class DocHtmlList : public CompAccept<DocHtmlList>, public DocNode +{ + public: + enum Type { Unordered, Ordered }; + DocHtmlList(DocNode *parent,Type t) : m_parent(parent), m_type(t) {} + Kind kind() const { return Kind_HtmlList; } + Type type() const { return m_type; } + int parse(); + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlList>::accept(this,v); } + + private: + DocNode *m_parent; + Type m_type; +}; + +/*! Paragraph in the documentation tree */ +class DocPara : public CompAccept<DocPara>, public DocNode +{ + public: + DocPara(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_Para; } + DocNode *parent() const { return m_parent; } + bool isEmpty() const { return m_children.isEmpty(); } + void accept(DocVisitor *v) { CompAccept<DocPara>::accept(this,v); } + + int handleCommand(const QCString &cmdName); + int handleHtmlStartTag(const QCString &tagName,const QList<Option> &tagOptions); + int handleHtmlEndTag(const QCString &tagName); + int handleSimpleSection(DocSimpleSect::Type t); + int handleXRefItem(DocXRefItem::Type t); + int handleParamSection(const QCString &cmdName,DocSimpleSect::Type t); + //void handleStyleEnter(DocStyleChange::Style t); + //void handleStyleLeave(DocStyleChange::Style t,const char *tagName); + //void handlePendingStyleCommands(); + void handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t); + void handleImage(const QCString &cmdName); + void handleDotFile(const QCString &cmdName); + void handleInclude(const QCString &cmdName,DocInclude::Type t); + void handleLink(const QCString &cmdName,bool isJavaLink); + void handleRef(const QCString &cmdName); + int handleLanguageSwitch(); + + + private: + DocNode *m_parent; + QCString m_sectionId; +}; + +/*! Node representing an item of a auto list */ +class DocAutoListItem : public DocNode +{ + public: + DocAutoListItem(DocNode *parent) : m_parent(parent) + { m_paragraph=new DocPara(this); } + int parse(); + virtual ~DocAutoListItem() { delete m_paragraph; } + Kind kind() const { return Kind_AutoListItem; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) + { + v->visitPre(this); + m_paragraph->accept(v); + v->visitPost(this); + } + private: + DocNode *m_parent; + DocPara *m_paragraph; +}; + +/*! Simple list item */ +class DocSimpleListItem : public DocNode +{ + public: + DocSimpleListItem(DocNode *parent) : m_parent(parent) + { m_paragraph=new DocPara(this); } + int parse(); + virtual ~DocSimpleListItem() { delete m_paragraph; } + Kind kind() const { return Kind_SimpleListItem; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) + { + v->visitPre(this); + m_paragraph->accept(v); + v->visitPost(this); + } + + private: + DocNode *m_parent; + DocPara *m_paragraph; +}; + +/*! Html list item */ +class DocHtmlListItem : public CompAccept<DocHtmlListItem>, public DocNode +{ + public: + DocHtmlListItem(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlListItem; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlListItem>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Html description data */ +class DocHtmlDescData : public CompAccept<DocHtmlDescData>, public DocNode +{ + public: + DocHtmlDescData(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlDescData; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlDescData>::accept(this,v); } + + private: + DocNode * m_parent; +}; + + +/*! Html list item */ +class DocHtmlPre : public CompAccept<DocHtmlPre>, public DocNode +{ + public: + DocHtmlPre(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlPre; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlPre>::accept(this,v); } + + private: + DocNode *m_parent; +}; + +/*! Html table cell */ +class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode +{ + public: + DocHtmlCell(DocNode *parent,bool isHeading) : + m_parent(parent), m_isHeading(isHeading) {} + int parse(); + bool isHeading() const { return m_isHeading; } + Kind kind() const { return Kind_HtmlCell; } + DocNode *parent() const { return m_parent; } + uint numCells() const { return m_children.count(); } + void accept(DocVisitor *v) { CompAccept<DocHtmlCell>::accept(this,v); } + + private: + DocNode * m_parent; + bool m_isHeading; +}; + +/*! Html table caption */ +class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode +{ + public: + DocHtmlCaption(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlCaption; } + DocNode *parent() const { return m_parent; } + void accept(DocVisitor *v) { CompAccept<DocHtmlCaption>::accept(this,v); } + + private: + DocNode * m_parent; +}; + +/*! Html table row */ +class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode +{ + public: + DocHtmlRow(DocNode *parent) : m_parent(parent) {} + int parse(); + Kind kind() const { return Kind_HtmlRow; } + DocNode *parent() const { return m_parent; } + uint numCells() const { return m_children.count(); } + void accept(DocVisitor *v) { CompAccept<DocHtmlRow>::accept(this,v); } + + private: + DocNode * m_parent; +}; + +/*! Html table */ +class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode +{ + public: + DocHtmlTable(DocNode *parent) : m_parent(parent) { m_caption=0; } + ~DocHtmlTable() { delete m_caption; } + int parse(); + Kind kind() const { return Kind_HtmlTable; } + DocNode *parent() const { return m_parent; } + uint numRows() const { return m_children.count(); } + uint numCols() const + { + 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()); + } + return cols; + } + void accept(DocVisitor *v) { CompAccept<DocHtmlTable>::accept(this,v); } + + private: + DocNode * m_parent; + DocHtmlCaption *m_caption; +}; + + +/*! Root node of documentation tree */ +class DocRoot : public CompAccept<DocRoot>, public DocNode +{ + public: + DocRoot() {} + void parse(); + Kind kind() const { return Kind_Root; } + DocNode *parent() const { return 0; } + void accept(DocVisitor *v) { CompAccept<DocRoot>::accept(this,v); } +}; + + +#endif diff --git a/src/doctokenizer.h b/src/doctokenizer.h new file mode 100644 index 0000000..8e0abee --- /dev/null +++ b/src/doctokenizer.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef _DOCTOKENIZER_H +#define _DOCTOKENIZER_H + +#include <qcstring.h> +#include <qlist.h> + +enum Tokens +{ + TK_WORD = 1, + TK_WHITESPACE = 2, + TK_LISTITEM = 3, + TK_ENDLIST = 4, + TK_COMMAND = 5, + TK_HTMLTAG = 6, + TK_SYMBOL = 7, + TK_NEWPARA = 8, + TK_RCSTAG = 9, + TK_URL = 10, + + RetVal_OK = 0x10000, + RetVal_SimpleSec = 0x10001, + RetVal_ListItem = 0x10002, + RetVal_Section = 0x10003, + RetVal_EndList = 0x10004, + RetVal_EndPre = 0x10005, + RetVal_DescData = 0x10006, + RetVal_DescTitle = 0x10007, + RetVal_EndDesc = 0x10008, + RetVal_TableRow = 0x10009, + RetVal_TableCell = 0x1000A, + RetVal_TableHCell = 0x1000B, + RetVal_EndTable = 0x1000C, + RetVal_Internal = 0x1000D, + RetVal_SwitchLang = 0x1000E +}; + +struct Option +{ + QCString name; + QCString value; +}; + +struct TokenInfo +{ + TokenInfo() { options.setAutoDelete(TRUE); } + + // unknown token + char unknownChar; + + // command token + QCString name; + + // command text (RCS tag) + QCString text; + + // comment blocks + + // list token info + bool isEnumList; + int indent; + + // sections + QCString sectionId; + + // simple section + QCString simpleSectName; + + // verbatim fragment + QCString verb; + + // xrefitem + int id; + + // html tag + QList<Option> options; + bool endTag; + + // whitespace + QCString chars; +}; + +// globals +extern TokenInfo *g_token; +extern int doctokenizerYYlineno; +extern FILE *doctokenizerYYin; + +// helper functions +const char *tokToString(int token); + +// operations on the scanner +void doctokenizerYYinit(const char *input); +void doctokenizerYYcleanup(); +void doctokenizerYYpushContext(); +bool doctokenizerYYpopContext(); +int doctokenizerYYlex(); +void doctokenizerYYsetStatePara(); +void doctokenizerYYsetStateTitle(); +void doctokenizerYYsetStateCode(); +void doctokenizerYYsetStateHtmlOnly(); +void doctokenizerYYsetStateLatexOnly(); +void doctokenizerYYsetStateVerbatim(); +void doctokenizerYYsetStateParam(); +void doctokenizerYYsetStateXRefItem(); +void doctokenizerYYsetStateFile(); +void doctokenizerYYsetStatePattern(); +void doctokenizerYYsetStateLink(); +void doctokenizerYYsetStateRef(); + +#endif diff --git a/src/doctokenizer.l b/src/doctokenizer.l new file mode 100644 index 0000000..31d6d7f --- /dev/null +++ b/src/doctokenizer.l @@ -0,0 +1,577 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +%{ + +#include <qfile.h> +#include <qcstring.h> +#include <qstack.h> +#include <qdict.h> + +#include "doctokenizer.h" +#include "cmdmapper.h" +#include "config.h" + +#define YY_NEVER_INTERACTIVE 1 + +//-------------------------------------------------------------------------- + +static int g_commentState; +TokenInfo *g_token = 0; +static int g_inputPos = 0; +static const char *g_inputString; + +struct DocLexerContext +{ + TokenInfo *token; + int rule; + int inputPos; + const char *inputString; + YY_BUFFER_STATE state; +}; + +static QStack<DocLexerContext> g_lexerStack; + +//-------------------------------------------------------------------------- + +void doctokenizerYYpushContext() +{ + DocLexerContext *ctx = new DocLexerContext; + ctx->rule = YY_START; + ctx->token = g_token; + ctx->inputPos = g_inputPos; + ctx->inputString = g_inputString; + ctx->state = YY_CURRENT_BUFFER; + g_lexerStack.push(ctx); + yy_switch_to_buffer(yy_create_buffer(doctokenizerYYin, YY_BUF_SIZE)); +} + +bool doctokenizerYYpopContext() +{ + if (g_lexerStack.isEmpty()) return FALSE; + DocLexerContext *ctx = g_lexerStack.pop(); + g_inputPos = ctx->inputPos; + g_inputString = ctx->inputString; + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(ctx->state); + BEGIN(ctx->rule); + delete ctx; + return TRUE; +} + + +//-------------------------------------------------------------------------- + +const char *tokToString(int token) +{ + switch (token) + { + case 0: return "TK_EOF"; + case TK_WORD: return "TK_WORD"; + case TK_WHITESPACE: return "TK_WHITESPACE"; + case TK_LISTITEM: return "TK_LISTITEM"; + case TK_ENDLIST: return "TK_ENDLIST"; + case TK_COMMAND: return "TK_COMMAND"; + case TK_HTMLTAG: return "TK_HTMLTAG"; + case TK_SYMBOL: return "TK_SYMBOL"; + case TK_NEWPARA: return "TK_NEWPARA"; + case TK_RCSTAG: return "TK_RCSTAG"; + case TK_URL: return "TK_URL"; + } + return "ERROR"; +} + +static int computeIndent(const char *str,int length) +{ + int i; + int indent=0; + int tabSize=Config_getInt("TAB_SIZE"); + for (i=0;i<length;i++) + { + if (str[i]=='\t') + { + indent+=tabSize - (indent%tabSize); + } + else if (str[i]=='\n') + { + indent=0; + } + else + { + indent++; + } + } + return indent; +} + +/*! converts input string \a opt into a list of Options. Each + * option is a name, value pair. The result is stored in g_token->options + */ +static void parseOptions(const QCString &opt) +{ + //printf("parseOptions(%s)\n",opt.data()); + QCString options=opt; + g_token->options.clear(); + int len = options.length(); + char c; + int i=0,startName,endName,startOption,endOption; + while (i<len) + { + c=options.at(i); + // skip spaces + while (i<len && c==' ') { c=options.at(++i); } + startName=i; + // search for end of name + while (i<len && c!=' ' && c!='=') { c=options.at(++i); } + endName=i; + Option *opt = new Option; + opt->name = options.mid(startName,endName-startName).lower(); + // skip spaces + while (i<len && c==' ') { c=options.at(++i); } + if (options.at(i)=='=') // option has value + { + i++; + // skip spaces + while (i<len && c==' ') { c=options.at(++i); } + if (options.at(i)=='\'') // option '...' + { + i++; + startOption=i; + // search for matching quote + while (i<len && c!='\'') { c=options.at(++i); } + endOption=i; + i++; + } + else if (options.at(i)=='"') // option "..." + { + i++; + startOption=i; + // search for matching quote + while (i<len && c!='"') { c=options.at(++i); } + endOption=i; + i++; + } + else // value without any quotes + { + startOption=i; + // search for separator + while (i<len && c!=' ') { c=options.at(++i); } + endOption=i; + i++; + } + opt->value = options.mid(startOption,endOption-startOption); + } + else // start next option + { + } + //printf("=====> Adding option name=<%s> value=<%s>\n", + // opt->name.data(),opt->value.data()); + g_token->options.append(opt); + } +} + +//-------------------------------------------------------------------------- + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); + +static int yyread(char *buf,int max_size) +{ + int c=0; + const char *src=g_inputString+g_inputPos; + while ( c < max_size && *src ) *buf++ = *src++, c++; + g_inputPos+=c; + return c; +} + +//-------------------------------------------------------------------------- + +%} + +CMD ("\\"|"@") +WS [ \t\r\n] +NONWS [^ \t\r\n] +BLANK [ \t\r] +ID [a-z_A-Z][a-z_A-Z0-9]* +OPTSTARS ("//"{BLANK}*)?"*"*{BLANK}* +LISTITEM {BLANK}*{OPTSTARS}"-"("#")?{WS} +ENDLIST {BLANK}*{OPTSTARS}"."{BLANK}*\n +ATTRIB {ID}("="(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'"><]+))? +URLCHAR [a-z_A-Z0-9\!\~\:\;\'\$\?\@\&\%\#\.\-\+\/\=] +URLMASK (([a-z_A-Z][^\>\"\n]*{URLCHAR})|({URLCHAR}+))([({]{URLCHAR}*[)}])? +FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+] +FILEECHAR [a-z_A-Z0-9\-\+] +FILEMASK {FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)* +LINKMASK [^ \t\n\r\\@<&$]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"))? +SPCMD1 {CMD}[a-z_A-Z0-9]+ +SPCMD2 {CMD}[\\@<>&$#%~] +SPCMD3 {CMD}form#[0-9]+ +WORD1 [^ \t\n\r\\@<&$]+ +WORD2 [^ \t\n\r\\@<&$]+"("[^\n)]*")"({BLANK}*("const"|"volatile"))? + +%option noyywrap +%option yylineno + +%x St_Para +%x St_Comment +%x St_Title +%x St_Code +%x St_HtmlOnly +%x St_LatexOnly +%x St_Verbatim +%x St_Param +%x St_XRefItem +%x St_File +%x St_Pattern +%x St_Link +%x St_Ref +%x St_Ref2 + +%% + /* TODO: \~lang_id */ +<St_Para>\r /* skip carriage return */ +<St_Para>^{LISTITEM} { /* list item */ + QCString text=yytext; + int dashPos = text.findRev('-'); + g_token->isEnumList = text.at(dashPos+1)=='#'; + g_token->indent = computeIndent(yytext,dashPos); + return TK_LISTITEM; + } +<St_Para>{BLANK}*\n{LISTITEM} { /* list item on next line */ + QCString text=yytext; + text=text.right(text.length()-text.find('\n')-1); + int dashPos = text.findRev('-'); + g_token->isEnumList = text.at(dashPos+1)=='#'; + g_token->indent = computeIndent(text,dashPos); + return TK_LISTITEM; + } +<St_Para>^{ENDLIST} { /* end list */ + int dotPos = QCString(yytext).findRev('.'); + g_token->indent = computeIndent(yytext,dotPos); + return TK_ENDLIST; + } +<St_Para>{BLANK}*\n{ENDLIST} { /* end list on next line */ + QCString text=yytext; + text=text.right(text.length()-text.find('\n')-1); + int dotPos = text.findRev('.'); + g_token->indent = computeIndent(text,dotPos); + return TK_ENDLIST; + } +<St_Para>"{"{BLANK}*"@link" { + g_token->name = "javalink"; + return TK_COMMAND; + } +<St_Para>{SPCMD3} { + g_token->name = "form"; + bool ok; + g_token->id = QCString(yytext).right(yyleng-6).toInt(&ok); + ASSERT(ok); + return TK_COMMAND; + } +<St_Para>{SPCMD1} | +<St_Para>{SPCMD2} { /* special command */ + g_token->name = yytext+1; + return TK_COMMAND; + } +<St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK} { + g_token->name=yytext; + return TK_URL; + } +<St_Para>[a-z_A-Z0-9.-]+"@"[a-z_A-Z0-9.-]+ { + g_token->name=yytext; + return TK_URL; + } +<St_Para>"$"{ID}":"[^\n$]+"$" { /* RCS tag */ + QCString tagName(yytext+1); + int i=tagName.find(':'); + g_token->name = tagName.left(i); + g_token->text = tagName.mid(i+1,tagName.length()-i-2); + return TK_RCSTAG; + } +<St_Para>"$("{ID}")" { /* environment variable */ + QCString name = &yytext[2]; + name = name.left(name.length()-1); + QCString value = getenv(name); + for (int i=value.length()-1;i>=0;i--) unput(value.at(i)); + } +<St_Para>"<"(("/")?){ID}({BLANK}+{ATTRIB})*">" { /* html tag */ + g_token->name = yytext; + int startNamePos=1; + if (g_token->name.at(1)=='/') startNamePos++; + int optSep = g_token->name.find(' '); + if (optSep!=-1) // tag has one or more options + { + parseOptions(g_token->name.mid(optSep+1,g_token->name.length()-optSep-2)); + g_token->name=g_token->name.mid(startNamePos,optSep-1).lower(); + } + else // tag without options, strip brackets + { + g_token->name=g_token->name.mid(startNamePos,g_token->name.length()-startNamePos-1).lower(); + } + g_token->endTag = startNamePos==2; + return TK_HTMLTAG; + } +<St_Para>"&"{ID}";" { /* special symbol */ + g_token->name = yytext; + return TK_SYMBOL; + } +<St_Para>{WORD1} | /* word, #word, or %word */ +<St_Para>{WORD2} { /* function call */ + g_token->name = yytext; + return TK_WORD; + /* dummy code to please the compiler, removing this + results in a warning on my machine */ goto find_rule; + } +<St_Para>{BLANK}+ | +<St_Para>{BLANK}*\n{BLANK}* { /* white space */ + g_token->chars=yytext; + return TK_WHITESPACE; + } +<St_Para>({BLANK}*\n)+{BLANK}*\n { + /* start of a new paragraph */ + return TK_NEWPARA; + } +<St_Code>{CMD}"endcode" { + return RetVal_OK; + } +<St_Code>[^\\@\n]+ | +<St_Code>\n | +<St_Code>. { + g_token->verb+=yytext; + } +<St_HtmlOnly>{CMD}"endhtmlonly" { + return RetVal_OK; + } +<St_HtmlOnly>[^\\@\n]+ | +<St_HtmlOnly>\n | +<St_HtmlOnly>. { + g_token->verb+=yytext; + } +<St_LatexOnly>{CMD}"endlatexonly" { + return RetVal_OK; + } +<St_LatexOnly>[^\\@\n]+ | +<St_LatexOnly>\n | +<St_LatexOnly>. { + g_token->verb+=yytext; + } +<St_Verbatim>{CMD}"endverbatim" { + return RetVal_OK; + } +<St_Verbatim>[^\\@\n]+ | +<St_Verbatim>\n | +<St_Verbatim>. { /* Verbatim text */ + g_token->verb+=yytext; + } +<St_Title>"&"{ID}";" { /* symbol */ + g_token->name = yytext; + return TK_SYMBOL; + } +<St_Title>{SPCMD1} | +<St_Title>{SPCMD2} { /* special command */ + g_token->name = yytext+1; + return TK_COMMAND; + } +<St_Title>{WORD1} | +<St_Title>{WORD2} { /* word */ + g_token->name = yytext; + return TK_WORD; + } +<St_Title>[ \t]+ { + g_token->chars=yytext; + return TK_WHITESPACE; + } +<St_Title>\n { /* new line => end of title */ + return 0; + } +<St_Ref>{ID} { + g_token->name=yytext; + return TK_WORD; + } +<St_Ref>{BLANK}+ { + return 0; + } +<St_Ref>{BLANK}+"\"" { + BEGIN(St_Ref2); + } +<St_Ref>\n { + unput(*yytext); + return 0; + } +<St_Ref>. { + unput(*yytext); + return 0; + } +<St_Ref2>"&"{ID}";" { /* symbol */ + g_token->name = yytext; + return TK_SYMBOL; + } +<St_Ref2>{SPCMD1} | +<St_Ref2>{SPCMD2} { /* special command */ + g_token->name = yytext+1; + return TK_COMMAND; + } +<St_Ref2>[^ \t\n\r\\@<&$"]+ | +<St_Ref2>[^ \t\n\r\\@<&$"]+"("[^\n")]*")"({BLANK}*("const"|"volatile"))? { + /* word */ + g_token->name = yytext; + return TK_WORD; + } +<St_Ref2>[ \t]+ { + g_token->chars=yytext; + return TK_WHITESPACE; + } +<St_Ref2>"\""|\n { /* " or \n => end of title */ + return 0; + } +<St_XRefItem>[0-9]+\n { + QCString numStr=yytext; + numStr=numStr.left(yyleng-1); + g_token->id=numStr.toInt(); + return RetVal_OK; + } +<St_Para,St_Title,St_Ref2>"<!--" { /* html style comment block */ + g_commentState = YY_START; + BEGIN(St_Comment); + } +<St_Param>"\""[^\n\"]+"\"" { + g_token->name = yytext+1; + g_token->name = g_token->name.left(yyleng-2); + return TK_WORD; + } +<St_Param>[^ \t\n,]+ { + g_token->name = yytext; + return TK_WORD; + } +<St_Param>{WS}*","{WS}* /* param separator */ +<St_Param>{WS} { + g_token->chars=yytext; + return TK_WHITESPACE; + } +<St_File>{FILEMASK} { + g_token->name = yytext; + return TK_WORD; + } +<St_File>"\""[^\n\"]+"\"" { + QCString text=yytext; + g_token->name = text.mid(1,text.length()-2); + return TK_WORD; + } +<St_Pattern>[^\r\n]+ { + g_token->name = yytext; + g_token->name = g_token->name.stripWhiteSpace(); + return TK_WORD; + } +<St_Link>{LINKMASK} { + g_token->name = yytext; + return TK_WORD; + } +<St_Comment>"-->" { /* end of html comment */ + BEGIN(g_commentState); + } +<St_Comment>[^-\n]+ /* inside html comment */ +<St_Comment>. /* inside html comment */ +<*>\n { + printf("Error: Unexpected new line character at line %d\n",yylineno); + } +<*>. { + printf("Error: Unexpected character `%s' at line %d\n",yytext,yylineno); + } +%% + +//-------------------------------------------------------------------------- + +void doctokenizerYYinit(const char *input) +{ + g_inputString = input; + g_inputPos = 0; + BEGIN(St_Para); +} + +void doctokenizerYYsetStatePara() +{ + BEGIN(St_Para); +} + +void doctokenizerYYsetStateTitle() +{ + BEGIN(St_Title); +} + +void doctokenizerYYsetStateCode() +{ + g_token->verb.resize(0); + BEGIN(St_Code); +} + +void doctokenizerYYsetStateHtmlOnly() +{ + g_token->verb.resize(0); + BEGIN(St_HtmlOnly); +} + +void doctokenizerYYsetStateLatexOnly() +{ + g_token->verb.resize(0); + BEGIN(St_LatexOnly); +} + +void doctokenizerYYsetStateVerbatim() +{ + g_token->verb.resize(0); + BEGIN(St_Verbatim); +} + +void doctokenizerYYsetStateParam() +{ + BEGIN(St_Param); +} + +void doctokenizerYYsetStateXRefItem() +{ + BEGIN(St_XRefItem); +} + +void doctokenizerYYsetStateFile() +{ + BEGIN(St_File); +} + +void doctokenizerYYsetStatePattern() +{ + BEGIN(St_Pattern); +} + +void doctokenizerYYsetStateLink() +{ + BEGIN(St_Link); +} + +void doctokenizerYYsetStateRef() +{ + BEGIN(St_Ref); +} + +void doctokenizerYYcleanup() +{ + yy_delete_buffer( YY_CURRENT_BUFFER ); +} + +extern "C" { // some bogus code to keep the compiler happy + void doctokenizerYYdummy() { yy_flex_realloc(0,0); } +} diff --git a/src/docvisitor.h b/src/docvisitor.h new file mode 100644 index 0000000..d72ef0f --- /dev/null +++ b/src/docvisitor.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef _DOCVISITOR_H +#define _DOCVISITOR_H + +class DocWord; +class DocWhiteSpace; +class DocAutoList; +class DocAutoListItem; +class DocPara; +class DocRoot; +class DocSymbol; +class DocURL; +class DocStyleChange; +class DocSimpleSect; +class DocTitle; +class DocSimpleList; +class DocSimpleListItem; +class DocSection; +class DocVerbatim; +class DocXRefItem; +class DocHtmlList; +class DocHtmlListItem; +class DocHtmlPre; +class DocHtmlDescList; +class DocHtmlDescTitle; +class DocHtmlDescData; +class DocHtmlTable; +class DocHtmlRow; +class DocHtmlCell; +class DocHtmlCaption; +class DocLineBreak; +class DocHorRuler; +class DocAnchor; +class DocIndexEntry; +class DocInternal; +class DocHRef; +class DocCopy; +class DocInclude; +class DocIncOperator; +class DocHtmlHeader; +class DocImage; +class DocDotFile; +class DocLink; +class DocRef; +class DocFormula; +class DocSecRefItem; +class DocSecRefList; +class DocLanguage; + +/*! @brief Abstract visitor that participates in the visitor pattern. + */ +class DocVisitor +{ + public: + /*! @name Visitor functions for leaf nodes */ + virtual void visit(DocWord *) = 0; + virtual void visit(DocWhiteSpace *) = 0; + virtual void visit(DocSymbol *) = 0; + virtual void visit(DocURL *) = 0; + virtual void visit(DocStyleChange *) = 0; + virtual void visit(DocVerbatim *) = 0; + virtual void visit(DocXRefItem *) = 0; + virtual void visit(DocLineBreak *) = 0; + virtual void visit(DocHorRuler *) = 0; + virtual void visit(DocAnchor *) = 0; + virtual void visit(DocCopy *) = 0; + virtual void visit(DocInclude *) = 0; + virtual void visit(DocIncOperator *) = 0; + virtual void visit(DocFormula *) = 0; + + /*! @name Visitor functions for internal nodes */ + virtual void visitPre(DocAutoList *) = 0; + virtual void visitPost(DocAutoList *) = 0; + virtual void visitPre(DocAutoListItem *) = 0; + virtual void visitPost(DocAutoListItem *) = 0; + virtual void visitPre(DocPara *) = 0; + virtual void visitPost(DocPara *) = 0; + virtual void visitPre(DocRoot *) = 0; + virtual void visitPost(DocRoot *) = 0; + virtual void visitPre(DocSimpleSect *) = 0; + virtual void visitPost(DocSimpleSect *) = 0; + virtual void visitPre(DocTitle *) = 0; + virtual void visitPost(DocTitle *) = 0; + virtual void visitPre(DocSimpleList *) = 0; + virtual void visitPost(DocSimpleList *) = 0; + virtual void visitPre(DocSimpleListItem *) = 0; + virtual void visitPost(DocSimpleListItem *) = 0; + virtual void visitPre(DocSection *) = 0; + virtual void visitPost(DocSection *) = 0; + virtual void visitPre(DocHtmlList *) = 0; + virtual void visitPost(DocHtmlListItem *) = 0; + virtual void visitPre(DocHtmlListItem *) = 0; + virtual void visitPost(DocHtmlList *) = 0; + virtual void visitPre(DocHtmlPre *) = 0; + virtual void visitPost(DocHtmlPre *) = 0; + virtual void visitPre(DocHtmlDescList *) = 0; + virtual void visitPost(DocHtmlDescList *) = 0; + virtual void visitPre(DocHtmlDescTitle *) = 0; + virtual void visitPost(DocHtmlDescTitle *) = 0; + virtual void visitPre(DocHtmlDescData *) = 0; + virtual void visitPost(DocHtmlDescData *) = 0; + virtual void visitPre(DocHtmlTable *) = 0; + virtual void visitPost(DocHtmlRow *) = 0; + virtual void visitPre(DocHtmlCell *) = 0; + virtual void visitPost(DocHtmlCell *) = 0; + virtual void visitPre(DocHtmlRow *) = 0; + virtual void visitPost(DocHtmlTable *) = 0; + virtual void visitPre(DocHtmlCaption *) = 0; + virtual void visitPost(DocHtmlCaption *) = 0; + virtual void visitPre(DocIndexEntry *) = 0; + virtual void visitPost(DocIndexEntry *) = 0; + virtual void visitPre(DocInternal *) = 0; + virtual void visitPost(DocInternal *) = 0; + virtual void visitPre(DocHRef *) = 0; + virtual void visitPost(DocHRef *) = 0; + virtual void visitPre(DocHtmlHeader *) = 0; + virtual void visitPost(DocHtmlHeader *) = 0; + virtual void visitPre(DocImage *) = 0; + virtual void visitPost(DocImage *) = 0; + virtual void visitPre(DocDotFile *) = 0; + virtual void visitPost(DocDotFile *) = 0; + virtual void visitPre(DocLink *) = 0; + virtual void visitPost(DocLink *) = 0; + virtual void visitPre(DocRef *) = 0; + virtual void visitPost(DocRef *) = 0; + virtual void visitPre(DocSecRefItem *) = 0; + virtual void visitPost(DocSecRefItem *) = 0; + virtual void visitPre(DocSecRefList *) = 0; + virtual void visitPost(DocSecRefList *) = 0; + virtual void visitPre(DocLanguage *) = 0; + virtual void visitPost(DocLanguage *) = 0; +}; + +#endif diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 388a323..20dedec 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -5988,9 +5988,9 @@ static void generatePageDocs() if (!pi->title.isEmpty() && !pi->name.isEmpty() && (si=Doxygen::sectionDict.find(pi->name))!=0) { - outputList->startSection(si->label,si->title,si->type==SectionInfo::Subsection); + outputList->startSection(si->label,si->title,si->type); outputList->docify(si->title); - outputList->endSection(si->label,si->type==SectionInfo::Subsection); + outputList->endSection(si->label,si->type); } outputList->startTextBlock(); parseDoc(*outputList,pi->defFileName,pi->defLine,0,0,pi->doc); diff --git a/src/filedef.cpp b/src/filedef.cpp index 2f79a6b..c4fd5f4 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -118,7 +118,7 @@ void FileDef::writeDetailedDocumentation(OutputList &ol) ol.endGroupHeader(); if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) { - parseDoc(ol,filepath,1,0,0,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),0,0,briefDescription()); } if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") && !documentation().isEmpty()) @@ -129,7 +129,7 @@ void FileDef::writeDetailedDocumentation(OutputList &ol) { //if (doc.at(dl-1)!='.' && doc.at(dl-1)!='!' && doc.at(dl-1)!='?') // doc+='.'; - parseDoc(ol,filepath,1,0,0,documentation()+"\n"); + parseDoc(ol,docFile(),docLine(),0,0,documentation()+"\n"); } //printf("Writing source ref for file %s\n",name().data()); if (Config_getBool("SOURCE_BROWSER")) @@ -189,7 +189,7 @@ void FileDef::writeDocumentation(OutputList &ol) } else if (briefDescription()) { - parseDoc(ol,filepath,1,0,0,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),0,0,briefDescription()); ol.writeString(" \n"); ol.disableAllBut(OutputGenerator::Html); ol.startTextLink(0,"_details"); diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 3380b59..03f64e0 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -356,7 +356,7 @@ void GroupDef::writeDetailedDocumentation(OutputList &ol) // repeat brief description if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),name(),0,briefDescription()); ol.newParagraph(); } } @@ -364,7 +364,7 @@ void GroupDef::writeDetailedDocumentation(OutputList &ol) // write documentation if (!documentation().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); + parseDoc(ol,docFile(),docLine(),name(),0,documentation()+"\n"); } } } @@ -386,7 +386,7 @@ void GroupDef::writeDocumentation(OutputList &ol) } else if (!briefDescription().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),name(),0,briefDescription()); ol.writeString(" \n"); ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); @@ -430,7 +430,7 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(); - parseDoc(ol,m_defFileName,m_defLine,0,0,fd->briefDescription()); + parseDoc(ol,briefFile(),briefLine(),0,0,fd->briefDescription()); ol.endMemberDescription(); ol.newParagraph(); } @@ -461,7 +461,7 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!nd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(); - parseDoc(ol,m_defFileName,m_defLine,0,0,nd->briefDescription()); + parseDoc(ol,briefFile(),briefLine(),0,0,nd->briefDescription()); ol.endMemberDescription(); ol.newParagraph(); } @@ -491,7 +491,7 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!gd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(); - parseDoc(ol,m_defFileName,m_defLine,0,0,gd->briefDescription()); + parseDoc(ol,briefFile(),briefLine(),0,0,gd->briefDescription()); ol.endMemberDescription(); ol.newParagraph(); } @@ -546,9 +546,9 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!pi->title.isEmpty() && !pi->name.isEmpty() && (si=Doxygen::sectionDict[pi->name])!=0) { - ol.startSection(si->label,si->title,TRUE); + ol.startSection(si->label,si->title,SectionInfo::Subsection); ol.docify(si->title); - ol.endSection(si->label,TRUE); + ol.endSection(si->label,SectionInfo::Subsection); } ol.startTextBlock(); parseDoc(ol,pi->defFileName,pi->defLine,0,0,pi->doc); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index cdacaaa..a8291fc 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -517,16 +517,28 @@ void HtmlGenerator::endGroupHeader() t << "</h2>" << endl; } -void HtmlGenerator::startSection(const char *lab,const char *,bool sub) +void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) { - if (sub) t << "<h3>"; else t << "<h2>"; + switch(type) + { + case SectionInfo::Page: t << "<h1>"; break; + case SectionInfo::Section: t << "<h2>"; break; + case SectionInfo::Subsection: t << "<h3>"; break; + default: ASSERT(0); break; + } t << "<a name=\"" << lab << "\">"; } -void HtmlGenerator::endSection(const char *,bool sub) +void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type) { t << "</a>" << endl; - if (sub) t << "</h3>"; else t << "</h2>"; + switch(type) + { + case SectionInfo::Page: t << "</h1>"; break; + case SectionInfo::Section: t << "</h2>"; break; + case SectionInfo::Subsection: t << "</h3>"; break; + default: ASSERT(0); break; + } } void HtmlGenerator::writeSectionRef(const char *ref,const char *name, @@ -558,7 +570,7 @@ void HtmlGenerator::writeSectionRefItem(const char *name,const char *lab, { QCString refName=name; if (refName.right(htmlFileExtensionLength)!=htmlFileExtension) refName+=htmlFileExtension; - t << "<a href=\"" << refName << "#" << lab << "\">"; + t << "<li><a href=\"" << refName << "#" << lab << "\">"; docify(title); t << "</a>"; } @@ -1205,4 +1217,15 @@ void HtmlGenerator::endParamList() t << "</dl>"; } +void HtmlGenerator::startSectionRefList() +{ + t << "<multicol cols=3>" << endl; + t << "<ul>" << endl; +} + +void HtmlGenerator::endSectionRefList() +{ + t << "</ul>" << endl; + t << "</multicol>" << endl; +} diff --git a/src/htmlgen.h b/src/htmlgen.h index 1075e49..6f93ca4 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -197,8 +197,8 @@ class HtmlGenerator : public OutputGenerator void endParamList(); void endDescTitle() { t << "</b>"; } void writeDescItem() { t << "<dd>" << endl; } - void startSection(const char *,const char *,bool); - void endSection(const char *,bool); + void startSection(const char *,const char *,SectionInfo::SectionType); + void endSection(const char *,SectionInfo::SectionType); void writeSectionRef(const char *,const char *,const char *,const char *); void writeSectionRefItem(const char *,const char *,const char *); //void writeSectionRefAnchor(const char *,const char *,const char *); @@ -264,6 +264,9 @@ class HtmlGenerator : public OutputGenerator void startLatexOnly() {} void endLatexOnly() {} + void startSectionRefList(); + void endSectionRefList(); + private: QCString lastTitle; QCString lastFile; diff --git a/src/index.cpp b/src/index.cpp index 2754080..ac20381 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1012,7 +1012,7 @@ void writeFileIndex(OutputList &ol) { //ol.docify(" ("); parseDoc(ol, - fd->absFilePath(),1, + fd->briefFile(),fd->briefLine(), 0,0, abbreviate(fd->briefDescription(),fd->name())); //ol.docify(")"); @@ -1135,7 +1135,7 @@ void writeNamespaceIndex(OutputList &ol) { //ol.docify(" ("); parseDoc(ol, - nd->getDefFileName(),nd->getDefLine(), + nd->briefFile(),nd->briefLine(), nd->name(),0, abbreviate(nd->briefDescription(),nd->displayName())); //ol.docify(")"); @@ -1211,7 +1211,7 @@ void writeAnnotatedClassList(OutputList &ol) { //ol.docify(" ("); parseDoc(ol, - cd->getDefFileName(),cd->getDefLine(), + cd->briefFile(),cd->briefLine(), cd->name(),0, abbreviate(cd->briefDescription(),cd->name())); //ol.docify(")"); @@ -1581,9 +1581,9 @@ void writeMemberList(OutputList &ol,bool useSections) lastChar=cs[0]=tolower(name.at(0));cs[1]='\0'; QCString anchor=(QCString)"index_"+cs; QCString title=(QCString)"- "+cs+" -"; - ol.startSection(anchor,title,TRUE); + ol.startSection(anchor,title,SectionInfo::Subsection); ol.docify(title); - ol.endSection(anchor,TRUE); + ol.endSection(anchor,SectionInfo::Subsection); ol.startItemList(); first=FALSE; } @@ -1763,9 +1763,9 @@ void writeFileMemberList(OutputList &ol,bool useSections) lastChar=cs[0]=tolower(name.at(0));cs[1]='\0'; QCString anchor=(QCString)"index_"+cs; QCString title=(QCString)"- "+cs+" -"; - ol.startSection(anchor,title,TRUE); + ol.startSection(anchor,title,SectionInfo::Subsection); ol.docify(title); - ol.endSection(anchor,TRUE); + ol.endSection(anchor,SectionInfo::Subsection); ol.startItemList(); first=FALSE; } @@ -1841,9 +1841,9 @@ void writeNamespaceMemberList(OutputList &ol,bool useSections) lastChar=cs[0]=tolower(name.at(0));cs[1]='\0'; QCString anchor=(QCString)"index_"+cs; QCString title=(QCString)"- "+cs+" -"; - ol.startSection(anchor,title,TRUE); + ol.startSection(anchor,title,SectionInfo::Subsection); ol.docify(title); - ol.endSection(anchor,TRUE); + ol.endSection(anchor,SectionInfo::Subsection); ol.startItemList(); first=FALSE; } @@ -2589,7 +2589,7 @@ void writeGroupList(OutputList &ol) ol.endTextLink(); ol.endDescItem(); parseDoc(ol, - gd->getDefFileName(),gd->getDefLine(), + gd->briefFile(),gd->briefLine(), 0,0,gd->briefDescription()); ol.newParagraph(); //} diff --git a/src/latexgen.cpp b/src/latexgen.cpp index fa6a104..45e26e7 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -1199,7 +1199,7 @@ void LatexGenerator::addIndexItem(const char *s1,const char *s2) } -void LatexGenerator::startSection(const char *lab,const char *,bool sub) +void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) { if (Config_getBool("PDF_HYPERLINKS")) { @@ -1208,15 +1208,29 @@ void LatexGenerator::startSection(const char *lab,const char *,bool sub) t << "\\"; if (Config_getBool("COMPACT_LATEX")) { - if (sub) t << "subsubsection{"; else t << "subsection{"; + switch(type) + { + case SectionInfo::Page: t << "subsection"; break; + case SectionInfo::Section: t << "subsubsection"; break; + case SectionInfo::Subsection: t << "paragraph"; break; + default: ASSERT(0); break; + } + t << "{"; } else { - if (sub) t << "subsection{"; else t << "section{"; + switch(type) + { + case SectionInfo::Page: t << "section"; break; + case SectionInfo::Section: t << "subsection"; break; + case SectionInfo::Subsection: t << "subsubsection"; break; + default: ASSERT(0); break; + } + t << "{"; } } -void LatexGenerator::endSection(const char *lab,bool) +void LatexGenerator::endSection(const char *lab,SectionInfo::SectionType) { t << "}\\label{" << lab << "}" << endl; } @@ -1259,7 +1273,7 @@ void LatexGenerator::writeSectionRef(const char *ref,const char *, void LatexGenerator::writeSectionRefItem(const char *,const char *lab, const char *title) { - t << "\\contentsline{section}{"; + t << "\\item \\contentsline{section}{"; docify(title); t << "}{\\ref{" << lab << "}}{}" << endl; } @@ -1942,3 +1956,17 @@ void LatexGenerator::endParamList() t << "\\end{Desc}" << endl; } +void LatexGenerator::startSectionRefList() +{ + t << "\\footnotesize" << endl; + t << "\\begin{multicols}{2}" << endl; + t << "\\begin{CompactList}" << endl; +} + +void LatexGenerator::endSectionRefList() +{ + t << "\\end{CompactList}" << endl; + t << "\\end{multicols}" << endl; + t << "\\normalsize" << endl; +} + diff --git a/src/latexgen.h b/src/latexgen.h index e29a813..6ce7785 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -214,8 +214,8 @@ class LatexGenerator : public OutputGenerator void endParamList(); void endDescTitle() { t << "]"; } void writeDescItem() { t << "\\par" << endl; } - void startSection(const char *,const char *,bool); - void endSection(const char *,bool); + void startSection(const char *,const char *,SectionInfo::SectionType); + void endSection(const char *,SectionInfo::SectionType); void writeSectionRef(const char *,const char *,const char *,const char *); void writeSectionRefItem(const char *,const char *,const char *); //void writeSectionRefAnchor(const char *,const char *,const char *); @@ -281,6 +281,9 @@ class LatexGenerator : public OutputGenerator void startLatexOnly() {} void endLatexOnly() {} + void startSectionRefList(); + void endSectionRefList(); + private: void latin2ToLatex(unsigned char); LatexGenerator(const LatexGenerator &); diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 796ce76..ac5c03d 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -19,6 +19,7 @@ CONFIG = console warn_on staticlib $extraopts HEADERS = bufstr.h \ classdef.h \ classlist.h \ + cmdmapper.h \ code.h \ commentcnv.h \ constexp.h \ @@ -28,6 +29,9 @@ HEADERS = bufstr.h \ doxygen.h \ scanner.h \ doc.h \ + docparser.h \ + doctokenizer.h \ + docvisitor.h \ dot.h \ doxygen.h \ entry.h \ @@ -58,6 +62,7 @@ HEADERS = bufstr.h \ page.h \ pngenc.h \ pre.h \ + printdocvisitor.h \ qtbc.h \ reflist.h \ rtfgen.h \ @@ -100,6 +105,7 @@ SOURCES = ce_lex.cpp \ ce_parse.cpp \ classdef.cpp \ classlist.cpp \ + cmdmapper.cpp \ code.cpp \ commentcnv.cpp \ cppvalue.cpp \ @@ -111,6 +117,8 @@ SOURCES = ce_lex.cpp \ definition.cpp \ diagram.cpp \ doc.cpp \ + docparser.cpp \ + doctokenizer.cpp \ dot.cpp \ doxygen.cpp \ entry.cpp \ diff --git a/src/libdoxygen.t b/src/libdoxygen.t index da0e45c..6b6b32e 100644 --- a/src/libdoxygen.t +++ b/src/libdoxygen.t @@ -62,6 +62,9 @@ sub GenerateDep { #$ GenerateDep("doc.cpp","doc.l"); $(LEX) -PdocYY -t doc.l >doc.cpp +#$ GenerateDep("doctokenizer.cpp","doctokenizer.l"); + $(LEX) -PdoctokenizerYY -t doctokenizer.l >doctokenizer.cpp + #$ GenerateDep("commentcnv.cpp","commentcnv.l"); $(LEX) -PcommentcnvYY -t commentcnv.l >commentcnv.cpp diff --git a/src/mangen.cpp b/src/mangen.cpp index ec3eff1..8364d65 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -536,32 +536,30 @@ void ManGenerator::endMemberGroup(bool) firstCol=FALSE; } -void ManGenerator::startSection(const char *,const char *,bool sub) +void ManGenerator::startSection(const char *,const char *,SectionInfo::SectionType type) { if( !inHeader ) { - if( sub ) + switch(type) { - startMemberHeader(); - } - else - { - startGroupHeader(); + case SectionInfo::Page: startGroupHeader(); break; + case SectionInfo::Section: startGroupHeader(); break; + case SectionInfo::Subsection: startMemberHeader(); break; + default: ASSERT(0); break; } } } -void ManGenerator::endSection(const char *,bool sub) +void ManGenerator::endSection(const char *,SectionInfo::SectionType type) { if( !inHeader ) { - if( sub ) - { - endMemberHeader(); - } - else + switch(type) { - endGroupHeader(); + case SectionInfo::Page: endGroupHeader(); break; + case SectionInfo::Section: endGroupHeader(); break; + case SectionInfo::Subsection: endMemberHeader(); break; + default: ASSERT(0); break; } } else diff --git a/src/mangen.h b/src/mangen.h index 3277716..d81242a 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -187,8 +187,8 @@ class ManGenerator : public OutputGenerator void endParamList(); void endDescTitle(); void writeDescItem(); - void startSection(const char *,const char *,bool); - void endSection(const char *,bool); + void startSection(const char *,const char *,SectionInfo::SectionType); + void endSection(const char *,SectionInfo::SectionType); void writeSectionRef(const char *,const char *,const char *,const char *) {} void writeSectionRefItem(const char *,const char *,const char *) {} //void writeSectionRefAnchor(const char *,const char *,const char *) {} @@ -248,6 +248,9 @@ class ManGenerator : public OutputGenerator void startLatexOnly() {} void endLatexOnly() {} + void startSectionRefList() {} + void endSectionRefList() {} + private: bool firstCol; bool paragraph; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 930e915..a00fcf1 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -858,7 +858,7 @@ void MemberDef::writeDeclaration(OutputList &ol, !annMemb) { ol.startMemberDescription(); - parseDoc(ol,m_defFileName,m_defLine,cname,this,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),cname,this,briefDescription()); if (detailsVisible) { ol.pushGeneratorState(); @@ -1201,14 +1201,14 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ) /* || !annMemb */ ) { - parseDoc(ol,m_defFileName,m_defLine,scopeName,this,brief); + parseDoc(ol,briefFile(),briefLine(),scopeName,this,brief); ol.newParagraph(); } /* write detailed description */ if (!detailed.isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,scopeName,this,detailed+"\n"); + parseDoc(ol,docFile(),docLine(),scopeName,this,detailed+"\n"); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::RTF); ol.newParagraph(); @@ -1234,7 +1234,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.docify(a->name); ol.endDescTableTitle(); ol.startDescTableData(); - parseDoc(ol,m_defFileName,m_defLine,scopeName,this,a->docs+"\n"); + parseDoc(ol,docFile(),docLine(),scopeName,this,a->docs+"\n"); ol.endDescTableData(); } } @@ -1285,7 +1285,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (!fmd->briefDescription().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,scopeName,fmd,fmd->briefDescription()); + parseDoc(ol,fmd->briefFile(),fmd->briefLine(),scopeName,fmd,fmd->briefDescription()); //ol.newParagraph(); } if (!fmd->briefDescription().isEmpty() && @@ -1295,7 +1295,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, } if (!fmd->documentation().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,scopeName,fmd,fmd->documentation()+"\n"); + parseDoc(ol,fmd->docFile(),fmd->docLine(),scopeName,fmd,fmd->documentation()+"\n"); } ol.endDescTableData(); } @@ -1709,13 +1709,13 @@ void MemberDef::addListReference(Definition *d) MemberList *MemberDef::getSectionList(Definition *d) const { - return (d!=0 && classSectionSDict) ? classSectionSDict->find((int)d) : 0; + return (d!=0 && classSectionSDict) ? classSectionSDict->find((char *)d) : 0; } void MemberDef::setSectionList(Definition *d, MemberList *sl) { - if (classSectionSDict==0) classSectionSDict = new SIntDict<MemberList>(7); - classSectionSDict->append((int)d,sl); + if (classSectionSDict==0) classSectionSDict = new SDict<MemberList>(7); + classSectionSDict->append((char *)d,sl); } Specifier MemberDef::virtualness() const diff --git a/src/memberdef.h b/src/memberdef.h index 51c0f7c..073b5f6 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -309,7 +309,7 @@ class MemberDef : public Definition int groupStartLine; // line " " " " " bool groupHasDocs; // true if the entry that caused the grouping was documented MemberDef *m_templateMaster; - SIntDict<MemberList> *classSectionSDict; + SDict<MemberList> *classSectionSDict; bool docsForDefinition; // TRUE => documentation block is put before // definition. // FALSE => block is put before declaration. diff --git a/src/memberlist.cpp b/src/memberlist.cpp index ffc5631..71c5feb 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -342,7 +342,7 @@ void MemberList::writePlainDeclarations(OutputList &ol, { ol.startMemberDescription(); parseDoc(ol, - md->getDefFileName(),md->getDefLine(), + md->briefFile(),md->briefLine(), cd?cd->name().data():0,md, md->briefDescription() ); diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index f24de91..48e1814 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -202,7 +202,7 @@ void NamespaceDef::writeDetailedDocumentation(OutputList &ol) ol.startTextBlock(); if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),name(),0,briefDescription()); } if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") && !documentation().isEmpty()) @@ -211,7 +211,7 @@ void NamespaceDef::writeDetailedDocumentation(OutputList &ol) } if (!documentation().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); + parseDoc(ol,docFile(),docLine(),name(),0,documentation()+"\n"); ol.newParagraph(); } ol.endTextBlock(); @@ -250,7 +250,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) } else if (!briefDescription().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,briefDescription()); + parseDoc(ol,briefFile(),briefLine(),name(),0,briefDescription()); ol.writeString(" \n"); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -366,7 +366,7 @@ void NamespaceDef::addListReferences() { addRefItem(specialListItems(), theTranslator->trNamespace(TRUE,TRUE), - getOutputFileBase(),name() + getOutputFileBase(),displayName() ); MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; diff --git a/src/outputgen.h b/src/outputgen.h index 7b6a082..6452f3b 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -24,6 +24,7 @@ #include <qfile.h> #include <qstack.h> #include "index.h" +#include "section.h" class ClassDiagram; class DotClassGraph; @@ -234,8 +235,8 @@ class BaseOutputDocInterface virtual void startTitle() = 0; virtual void endTitle() = 0; virtual void writeAnchor(const char *fileName,const char *name) = 0; - virtual void startSection(const char *,const char *,bool) = 0; - virtual void endSection(const char *,bool) = 0; + virtual void startSection(const char *,const char *,SectionInfo::SectionType) = 0; + virtual void endSection(const char *,SectionInfo::SectionType) = 0; virtual void writeSectionRef(const char *,const char *, const char *,const char *) = 0; virtual void writeSectionRefItem(const char *,const char *,const char *) = 0; @@ -273,6 +274,9 @@ class BaseOutputDocInterface virtual void startLatexOnly() = 0; virtual void endLatexOnly() = 0; + virtual void startSectionRefList() = 0; + virtual void endSectionRefList() = 0; + /*! Writes an ASCII string to the output. This function should keep * spaces visible, should break lines at a newline and should convert * tabs to the right number of spaces. diff --git a/src/outputlist.cpp b/src/outputlist.cpp index 7e91e35..d0a2114 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -273,9 +273,11 @@ FORALL2(ParamListTypes a1,const char *a2,a1,a2) FORALL1(IndexSections a1,a1) FORALL2(const char *a1,const char *a2,a1,a2) FORALL2(const char *a1,bool a2,a1,a2) +FORALL2(const char *a1,SectionInfo::SectionType a2,a1,a2) FORALL3(ClassDiagram &a1,const char *a2,const char *a3,a1,a2,a3) FORALL3(const char *a1,const char *a2,const char *a3,a1,a2,a3) FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3) +FORALL3(const char *a1,const char *a2,SectionInfo::SectionType a3,a1,a2,a3) FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3) FORALL4(SectionTypes a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) diff --git a/src/outputlist.h b/src/outputlist.h index 0a2beb4..2dc34af 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -344,10 +344,10 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startIndent); } void endIndent() { forall(&OutputGenerator::endIndent); } - void startSection(const char *lab,const char *title,bool sub) - { forall(&OutputGenerator::startSection,lab,title,sub); } - void endSection(const char *lab,bool sub) - { forall(&OutputGenerator::endSection,lab,sub); } + void startSection(const char *lab,const char *title,SectionInfo::SectionType t) + { forall(&OutputGenerator::startSection,lab,title,t); } + void endSection(const char *lab,SectionInfo::SectionType t) + { forall(&OutputGenerator::endSection,lab,t); } void writeSectionRef(const char *ref,const char *file, const char *anchor, const char *title) { forall(&OutputGenerator::writeSectionRef,ref,file,anchor,title); } @@ -452,6 +452,11 @@ class OutputList : public OutputDocInterface void endLatexOnly() { forall(&OutputGenerator::endLatexOnly); } + void startSectionRefList() + { forall(&OutputGenerator::startSectionRefList); } + void endSectionRefList() + { forall(&OutputGenerator::endSectionRefList); } + #if 0 void startPlainFile(const char *name) { forall(&OutputGenerator::startPlainFile,name); } @@ -501,7 +506,9 @@ class OutputList : public OutputDocInterface FORALLPROTO2(ParamListTypes,const char *); FORALLPROTO2(const char *,const char *); FORALLPROTO2(const char *,bool); + FORALLPROTO2(const char *,SectionInfo::SectionType); FORALLPROTO3(const char *,const char *,bool); + FORALLPROTO3(const char *,const char *,SectionInfo::SectionType); FORALLPROTO3(uchar,uchar,uchar); FORALLPROTO3(const char *,const char *,const char *); FORALLPROTO3(ClassDiagram &,const char *,const char *); diff --git a/src/packagedef.cpp b/src/packagedef.cpp index afd8709..8e1c3ae 100644 --- a/src/packagedef.cpp +++ b/src/packagedef.cpp @@ -61,7 +61,7 @@ void PackageDef::writeDocumentation(OutputList &ol) OutputList briefOutput(&ol); if (!briefDescription().isEmpty()) { - parseDoc(briefOutput,m_defFileName,m_defLine,name(),0,briefDescription()); + parseDoc(briefOutput,briefFile(),briefLine(),name(),0,briefDescription()); ol+=briefOutput; ol.writeString(" \n"); ol.pushGeneratorState(); @@ -114,7 +114,7 @@ void PackageDef::writeDocumentation(OutputList &ol) // write documentation if (!documentation().isEmpty()) { - parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); + parseDoc(ol,docFile(),docLine(),name(),0,documentation()+"\n"); } } diff --git a/src/pngenc.cpp b/src/pngenc.cpp index 5fb20d5..ce36b95 100644 --- a/src/pngenc.cpp +++ b/src/pngenc.cpp @@ -30,6 +30,8 @@ #include "pngenc.h" #include "message.h" +#undef jmpbuf + static void user_error_fn(png_structp, png_const_charp error_msg) { err("%s\n", error_msg); diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h new file mode 100644 index 0000000..f20099a --- /dev/null +++ b/src/printdocvisitor.h @@ -0,0 +1,598 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2002 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef _PRINTDOCVISITOR_H +#define _PRINTDOCVISITOR_H + +#include "docvisitor.h" + +/*! Concrete visitor implementation for pretty printing */ +class PrintDocVisitor : public DocVisitor +{ + public: + PrintDocVisitor() : m_indent(0), m_needsEnter(FALSE), m_insidePre(FALSE) {} + + //-------------------------------------- + + void visit(DocWord *w) + { + indent_leaf(); + printf("%s",w->word().data()); + } + void visit(DocWhiteSpace *w) + { + indent_leaf(); + if (m_insidePre) + { + printf("%s",w->chars().data()); + } + else + { + printf(" "); + } + } + void visit(DocSymbol *s) + { + indent_leaf(); + switch(s->symbol()) + { + case DocSymbol::BSlash: printf("\\"); break; + case DocSymbol::At: printf("@"); break; + case DocSymbol::Less: printf("<"); break; + case DocSymbol::Greater: printf(">"); break; + case DocSymbol::Amp: printf("&"); break; + case DocSymbol::Dollar: printf("$"); break; + case DocSymbol::Hash: printf("#"); break; + case DocSymbol::Percent: printf("%%"); break; + case DocSymbol::Copy: printf("©"); break; + case DocSymbol::Apos: printf("'"); break; + case DocSymbol::Quot: printf("\""); break; + case DocSymbol::Uml: printf("&%cuml;",s->letter()); break; + case DocSymbol::Acute: printf("&%cacute;",s->letter()); break; + case DocSymbol::Grave: printf("&%cgrave;",s->letter()); break; + case DocSymbol::Circ: printf("&%ccirc;",s->letter()); break; + case DocSymbol::Tilde: printf("&%ctilde;",s->letter()); break; + case DocSymbol::Szlig: printf("ß"); break; + case DocSymbol::Cedil: printf("&%ccedul;",s->letter()); break; + case DocSymbol::Ring: printf("&%cring;",s->letter()); break; + case DocSymbol::Nbsp: printf(" "); break; + default: + printf("Error: unknown symbol found\n"); + } + } + void visit(DocURL *u) + { + indent_leaf(); + printf("%s",u->url().data()); + } + void visit(DocLineBreak *) + { + indent_leaf(); + printf("<br/>"); + } + void visit(DocHorRuler *) + { + indent_leaf(); + printf("<hr>"); + } + void visit(DocStyleChange *s) + { + indent_leaf(); + switch (s->style()) + { + case DocStyleChange::Bold: + if (s->enable()) printf("<bold>"); else printf("</bold>"); + break; + case DocStyleChange::Italic: + if (s->enable()) printf("<italic>"); else printf("</italic>"); + break; + case DocStyleChange::Code: + if (s->enable()) printf("<code>"); else printf("</code>"); + break; + case DocStyleChange::Subscript: + if (s->enable()) printf("<sub>"); else printf("</sub>"); + break; + case DocStyleChange::Superscript: + if (s->enable()) printf("<sup>"); else printf("</sup>"); + break; + case DocStyleChange::Center: + if (s->enable()) printf("<center>"); else printf("</center>"); + break; + case DocStyleChange::Small: + if (s->enable()) printf("<small>"); else printf("</small>"); + break; + } + } + void visit(DocVerbatim *s) + { + indent_leaf(); + switch(s->type()) + { + case DocVerbatim::Code: printf("<code>"); break; + case DocVerbatim::Verbatim: printf("<verbatim>"); break; + case DocVerbatim::HtmlOnly: printf("<htmlonly>"); break; + case DocVerbatim::LatexOnly: printf("<latexonly>"); break; + } + printf("%s",s->text().data()); + switch(s->type()) + { + case DocVerbatim::Code: printf("</code>"); break; + case DocVerbatim::Verbatim: printf("</verbatim>"); break; + case DocVerbatim::HtmlOnly: printf("</htmlonly>"); break; + case DocVerbatim::LatexOnly: printf("</latexonly>"); break; + } + } + void visit(DocXRefItem *x) + { + indent_leaf(); + printf("<xrefitem id=\"%d\"/>",x->id()); + } + void visit(DocAnchor *a) + { + indent_leaf(); + printf("<anchor name=\"%s\"/>",a->anchor().data()); + } + void visit(DocCopy *c) + { + indent_leaf(); + printf("<copy link=\"%s\"/>",c->link().data()); + } + void visit(DocInclude *inc) + { + indent_leaf(); + printf("<include file=\"%s\" type=\"",inc->file().data()); + switch(inc->type()) + { + case DocInclude::Include: printf("include"); break; + case DocInclude::DontInclude: printf("dontinclude"); break; + case DocInclude::HtmlInclude: printf("htmlinclude"); break; + case DocInclude::VerbInclude: printf("verbinclude"); break; + } + printf("\"/>"); + } + void visit(DocIncOperator *op) + { + indent_leaf(); + printf("<incoperator pattern=\"%s\" type=\"",op->pattern().data()); + switch(op->type()) + { + case DocIncOperator::Line: printf("line"); break; + case DocIncOperator::Skip: printf("skip"); break; + case DocIncOperator::SkipLine: printf("skipline"); break; + case DocIncOperator::Until: printf("until"); break; + } + printf("\"/>"); + } + void visit(DocFormula *f) + { + indent_leaf(); + printf("<formula id=%d/>",f->id()); + } + + //-------------------------------------- + + void visitPre(DocAutoList *l) + { + indent_pre(); + if (l->isEnumList()) + { + printf("<ol>\n"); + } + else + { + printf("<ul>\n"); + } + } + void visitPost(DocAutoList *l) + { + indent_post(); + if (l->isEnumList()) + { + printf("</ol>\n"); + } + else + { + printf("</ul>\n"); + } + } + void visitPre(DocAutoListItem *) + { + indent_pre(); + printf("<li>\n"); + } + void visitPost(DocAutoListItem *) + { + indent_post(); + printf("</li>\n"); + } + void visitPre(DocPara *) + { + indent_pre(); + printf("<para>\n"); + } + void visitPost(DocPara *) + { + indent_post(); + printf("</para>\n"); + } + void visitPre(DocRoot *) + { + indent_pre(); + printf("<root>\n"); + } + void visitPost(DocRoot *) + { + indent_post(); + printf("</root>\n"); + } + void visitPre(DocSimpleSect *s) + { + indent_pre(); + printf("<simplesect type="); + switch(s->sectionType()) + { + case DocSimpleSect::See: printf("see"); break; + case DocSimpleSect::Return: printf("return"); break; + case DocSimpleSect::Author: printf("author"); break; + case DocSimpleSect::Version: printf("version"); break; + case DocSimpleSect::Since: printf("since"); break; + case DocSimpleSect::Date: printf("date"); break; + case DocSimpleSect::Note: printf("note"); break; + case DocSimpleSect::Warning: printf("warning"); break; + case DocSimpleSect::Pre: printf("pre"); break; + case DocSimpleSect::Post: printf("post"); break; + case DocSimpleSect::Invar: printf("invar"); break; + case DocSimpleSect::Remark: printf("remark"); break; + case DocSimpleSect::Attention: printf("attention"); break; + case DocSimpleSect::User: printf("user"); break; + case DocSimpleSect::Param: + { + printf("param["); + QStrListIterator li(s->parameters()); + const char *s; + bool first=TRUE; + for (li.toFirst();(s=li.current());++li) + { + if (!first) printf(","); else first=FALSE; + printf("%s",s); + } + printf("]"); + } + break; + case DocSimpleSect::RetVal: + { + printf("retval["); + QStrListIterator li(s->parameters()); + const char *s; + bool first=TRUE; + for (li.toFirst();(s=li.current());++li) + { + if (!first) printf(","); else first=FALSE; + printf("%s",s); + } + printf("]"); + } + break; + case DocSimpleSect::Exception: printf("exception"); break; + { + printf("exception["); + QStrListIterator li(s->parameters()); + const char *s; + bool first=TRUE; + for (li.toFirst();(s=li.current());++li) + { + if (!first) printf(","); else first=FALSE; + printf("%s",s); + } + printf("]"); + } + break; + case DocSimpleSect::Unknown: printf("unknown"); break; + } + printf(">\n"); + } + void visitPost(DocSimpleSect *) + { + indent_post(); + printf("</simplesect>\n"); + } + void visitPre(DocTitle *) + { + indent_pre(); + printf("<title>\n"); + } + void visitPost(DocTitle *) + { + indent_post(); + printf("</title>\n"); + } + void visitPre(DocSimpleList *) + { + indent_pre(); + printf("<ul>\n"); + } + void visitPost(DocSimpleList *) + { + indent_post(); + printf("</ul>\n"); + } + void visitPre(DocSimpleListItem *) + { + indent_pre(); + printf("<li>\n"); + } + void visitPost(DocSimpleListItem *) + { + indent_post(); + printf("</li>\n"); + } + void visitPre(DocSection *s) + { + indent_pre(); + printf("<sect%d>\n",s->level()); + } + void visitPost(DocSection *s) + { + indent_post(); + printf("</sect%d>\n",s->level()); + } + void visitPre(DocHtmlList *s) + { + indent_pre(); + if (s->type()==DocHtmlList::Ordered) printf("<ol>\n"); else printf("<ul>\n"); + } + void visitPost(DocHtmlList *s) + { + indent_post(); + if (s->type()==DocHtmlList::Ordered) printf("</ol>\n"); else printf("</ul>\n"); + } + void visitPre(DocHtmlListItem *) + { + indent_pre(); + printf("<li>\n"); + } + void visitPost(DocHtmlListItem *) + { + indent_post(); + printf("</li>\n"); + } + void visitPre(DocHtmlPre *) + { + indent_pre(); + printf("<pre>\n"); + m_insidePre=TRUE; + } + void visitPost(DocHtmlPre *) + { + m_insidePre=FALSE; + indent_post(); + printf("</pre>\n"); + } + void visitPre(DocHtmlDescList *) + { + indent_pre(); + printf("<dl>\n"); + } + void visitPost(DocHtmlDescList *) + { + indent_post(); + printf("</dl>\n"); + } + void visitPre(DocHtmlDescTitle *) + { + indent_pre(); + printf("<dt>\n"); + } + void visitPost(DocHtmlDescTitle *) + { + indent_post(); + printf("</dt>\n"); + } + void visitPre(DocHtmlDescData *) + { + indent_pre(); + printf("<dd>\n"); + } + void visitPost(DocHtmlDescData *) + { + indent_post(); + printf("</dd>\n"); + } + void visitPre(DocHtmlTable *t) + { + indent_pre(); + printf("<table rows=\"%d\" cols=\"%d\">\n", + t->numRows(),t->numCols()); + } + void visitPost(DocHtmlTable *) + { + indent_post(); + printf("</table>\n"); + } + void visitPre(DocHtmlRow *) + { + indent_pre(); + printf("<tr>\n"); + } + void visitPost(DocHtmlRow *) + { + indent_post(); + printf("</tr>\n"); + } + void visitPre(DocHtmlCell *c) + { + indent_pre(); + printf("<t%c>\n",c->isHeading()?'h':'d'); + } + void visitPost(DocHtmlCell *c) + { + indent_post(); + printf("</t%c>\n",c->isHeading()?'h':'d'); + } + void visitPre(DocHtmlCaption *) + { + indent_pre(); + printf("<caption>\n"); + } + void visitPost(DocHtmlCaption *) + { + indent_post(); + printf("</caption>\n"); + } + void visitPre(DocIndexEntry *) + { + indent_pre(); + printf("<indexentry>\n"); + } + void visitPost(DocIndexEntry *) + { + indent_post(); + printf("</indexentry>\n"); + } + void visitPre(DocInternal *) + { + indent_pre(); + printf("<internal>\n"); + } + void visitPost(DocInternal *) + { + indent_post(); + printf("</internal>\n"); + } + void visitPre(DocHRef *href) + { + indent_pre(); + printf("<a url=\"%s\">\n",href->url().data()); + } + void visitPost(DocHRef *) + { + indent_post(); + printf("</a>\n"); + } + void visitPre(DocHtmlHeader *header) + { + indent_pre(); + printf("<h%d>\n",header->level()); + } + void visitPost(DocHtmlHeader *header) + { + indent_post(); + printf("</h%d>\n",header->level()); + } + void visitPre(DocImage *img) + { + indent_pre(); + printf("<image src=\"%s\">\n",img->name().data()); + } + void visitPost(DocImage *) + { + indent_post(); + printf("</image>\n"); + } + void visitPre(DocDotFile *df) + { + indent_pre(); + printf("<dotfile src=\"%s\">\n",df->name().data()); + } + void visitPost(DocDotFile *) + { + indent_post(); + printf("</dotfile>\n"); + } + void visitPre(DocLink *lnk) + { + indent_pre(); + printf("<link target=\"%s\">\n",lnk->target().data()); + } + void visitPost(DocLink *) + { + indent_post(); + printf("</link>\n"); + } + void visitPre(DocRef *ref) + { + indent_pre(); + printf("<ref target=\"%s\">\n",ref->target().data()); + } + void visitPost(DocRef *) + { + indent_post(); + printf("</ref>\n"); + } + void visitPre(DocSecRefItem *ref) + { + indent_pre(); + printf("<secrefitem target=\"%s\">\n",ref->target().data()); + } + void visitPost(DocSecRefItem *) + { + indent_post(); + printf("</secrefitem>\n"); + } + void visitPre(DocSecRefList *) + { + indent_pre(); + printf("<secreflist>\n"); + } + void visitPost(DocSecRefList *) + { + indent_post(); + printf("</secreflist>\n"); + } + void visitPre(DocLanguage *l) + { + indent_pre(); + printf("<language id=%s>\n",l->id().data()); + } + void visitPost(DocLanguage *) + { + indent_post(); + printf("</language>\n"); + } + + private: + // helper functions + void indent() + { + if (m_needsEnter) printf("\n"); + for (int i=0;i<m_indent;i++) printf("."); + m_needsEnter=FALSE; + } + void indent_leaf() + { + if (!m_needsEnter) indent(); + m_needsEnter=TRUE; + } + void indent_pre() + { + indent(); + m_indent++; + } + void indent_post() + { + m_indent--; + indent(); + } + + // member variables + int m_indent; + bool m_needsEnter; + bool m_insidePre; +}; + +#endif diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 7e813f9..0dfb1a4 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -2070,32 +2070,30 @@ void RTFGenerator::endDescList() } -void RTFGenerator::startSection(const char *,const char *title,bool sub) +void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type) { DBG_RTF(t << "{\\comment (startSection)}" << endl) t << "{"; t<< Rtf_Style_Reset; - if (sub) - { - // set style - t << Rtf_Style["Heading3"]->reference; - // make table of contents entry - t << "{\\tc\\tcl3 \\v "; - docify(title); - t << "}" << endl; - } - else - { - // set style - t << Rtf_Style["Heading2"]->reference; - // make table of contents entry - t << "{\\tc\\tcl2 \\v "; - docify(title); - t << "}" << endl; - } + int num=4; + switch(type) + { + case SectionInfo::Page: num=2; break; + case SectionInfo::Section: num=3; break; + case SectionInfo::Subsection: num=4; break; + default: ASSERT(0); break; + } + QCString heading; + heading.sprintf("Heading%d",num); + // set style + t << Rtf_Style[heading]->reference; + // make table of contents entry + t << "{\\tc\\tcl" << num << " \\v "; + docify(title); + t << "}" << endl; } -void RTFGenerator::endSection(const char *lab,bool) +void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType) { DBG_RTF(t << "{\\comment (endSection)}" << endl) newParagraph(); diff --git a/src/rtfgen.h b/src/rtfgen.h index 7c6640a..8a41391 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -183,8 +183,8 @@ class RTFGenerator : public OutputGenerator void endParamList(); void endDescTitle(); void writeDescItem(); - void startSection(const char *,const char *,bool); - void endSection(const char *,bool); + void startSection(const char *,const char *,SectionInfo::SectionType); + void endSection(const char *,SectionInfo::SectionType); void writeSectionRef(const char *,const char *,const char *,const char *); void writeSectionRefItem(const char *,const char *,const char *); //void writeSectionRefAnchor(const char *,const char *,const char *); @@ -251,6 +251,9 @@ class RTFGenerator : public OutputGenerator void startLatexOnly() {} void endLatexOnly() {} + void startSectionRefList() {} + void endSectionRefList() {} + static bool preProcessFileInplace(const char *path,const char *name); private: diff --git a/src/scanner.l b/src/scanner.l index 468e1ad..e1930cc 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -485,7 +485,7 @@ static int yyread(char *buf,int max_size) /* start command character */ CMD ("\\"|"@") -SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"ingroup"|"latexonly"|"htmlonly"|"{"|"verbatim"|"dotfile"|"defgroup"|"addtogroup"|"weakgroup") +SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"ingroup"|"latexonly"|"htmlonly"|"{"|"verbatim"|"dotfile"|"defgroup"|"addtogroup"|"weakgroup")|("<"{PRE}">") BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] @@ -2956,6 +2956,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <FindMembers,FindFields,MemberSpec,FuncQual,Operator,ClassVar,Bases>"//!" { current->brief.resize(0); + current->briefFile=yyFileName; + current->briefLine=yyLineNr; tmpDocType=-1; lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) @@ -2970,6 +2972,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <FindMembers,FindFields,MemberSpec,FuncQual,Operator,ClassVar,Bases>"///"/[^/] { current->brief.resize(0); + current->briefFile=yyFileName; + current->briefLine=yyLineNr; tmpDocType=-1; lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) @@ -3416,12 +3420,14 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) "Warning: missing argument after " "\\page." ); + current->doc+="\n"; yyLineNr++; BEGIN( Doc ); } <PageDocArg2>.*"\n" { yyLineNr++; current->args = yytext; + current->doc+="\n"; BEGIN( PageDoc ); } <EnumDocArg1>{SCOPEID} { @@ -3594,7 +3600,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <AnchorLabel>{LABELID} { sectionLabel=yytext; addSection(); - current->doc += "\\anchor "+sectionLabel+"\n"; + current->doc += "\\anchor "+sectionLabel+" "; BEGIN(lastAnchorContext); } <SectionLabel>{LABELID} { @@ -3605,7 +3611,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <SectionTitle>[^\n*]*/"\n" { sectionTitle+=yytext; sectionTitle=sectionTitle.stripWhiteSpace(); - current->doc += "\\section "+sectionLabel+"\n"; + current->doc += "\\section "+sectionLabel+" "; addSection(); BEGIN(PageDoc); } @@ -3643,7 +3649,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <Doc,ExampleDoc,PageDoc,ClassDoc>"//" { current->doc += yytext; } <LineDoc,JavaDoc,ClassDocBrief>"//" { current->brief += yytext; } <Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>("\\\\"|"@@")"f"[$\[\]] { - current->doc += &yytext[1]; + current->doc += yytext; } <Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>{CMD}"f$" { lastFormulaContext = YY_START; @@ -3727,6 +3733,12 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN( BugParam ); } else if (YY_START==ClassDocBrief && + lastBriefContext==DeprecatedParam) + { + unput('/');unput('*'); // make sure we have something to read + BEGIN( DeprecatedParam ); + } + else if (YY_START==ClassDocBrief && lastBriefContext==Doc) { current->doc += "\n\n"; @@ -3757,16 +3769,16 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <PageDocTitle>"</"{TITLE}">" { BEGIN( PageDoc ); } /* escaped versions of the conditional commands (for putting them in the docs) */ -<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } -<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } -<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } -<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } -<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } -<LineDoc,JavaDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } -<LineDoc,JavaDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } -<LineDoc,JavaDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } -<LineDoc,JavaDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } -<LineDoc,JavaDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->doc+=yytext; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->doc+=yytext; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->doc+=yytext; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->doc+=yytext; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->doc+=yytext; } +<LineDoc,JavaDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->brief+=yytext; } +<LineDoc,JavaDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->brief+=yytext; } +<LineDoc,JavaDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->brief+=yytext; } +<LineDoc,JavaDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->brief+=yytext; } +<LineDoc,JavaDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->brief+=yytext; } /* conditional commands */ <ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"{B}+ { @@ -3897,7 +3909,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) if (!current->doc.isEmpty()) current->doc+=" <p>"; if (lastBriefContext==TodoParam || lastBriefContext==TestParam || - lastBriefContext==BugParam + lastBriefContext==BugParam || + lastBriefContext==DeprecatedParam ) { unput('\n'); @@ -3939,6 +3952,16 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) unput('\n'); // make sure we have something to read BEGIN( BugParam ); } + else if + (lastBriefContext==DeprecatedParam && + (slStartContext==LineDoc || + slStartContext==AfterDocLine + ) + ) + { + unput('\n'); // make sure we have something to read + BEGIN( DeprecatedParam ); + } else { current->brief += " "; diff --git a/src/section.h b/src/section.h index ce7683d..7868036 100644 --- a/src/section.h +++ b/src/section.h @@ -25,10 +25,11 @@ #include "sortdict.h" class Definition; +class PageInfo; struct SectionInfo { - enum SectionType { Section, Subsection, Anchor }; + enum SectionType { Page, Section, Subsection, Anchor }; SectionInfo(const char *l,const char *t,SectionType st,const char *r=0) { label=l; title=t; type=st; ref=r; definition=0; pageRef=0; generated=FALSE; } ~SectionInfo() {} diff --git a/src/translator_br.h b/src/translator_br.h index e361f6b..f5e65e1 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -13,9 +13,11 @@ * Brazilian Portuguese version by * Fabio "FJTC" Jun Takada Chino <chino@icmc.sc.usp.br> * http://www.icmc.sc.usp.br/~chino - * Version: 1.2.17 (2002/07/10) + * Version: 1.2.18 (2002/07/30) * * History: + * 1.2.18 (2002/07/30): + * - Updated to Doxygen 1.2.18 * 1.2.17 (2002/07/10): * - Updated to Doxygen 1.2.17. * 1.2.13.2 (2002/05/10): @@ -25,7 +27,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian: public TranslatorAdapter_1_2_17 +class TranslatorBrazilian: public Translator { public: @@ -804,7 +806,7 @@ class TranslatorBrazilian: public TranslatorAdapter_1_2_17 * This note is for brazilians only. * Esta é uma boa tradução para "deprecated"? */ - return "Descontinuada"; + return "Descontinuado(a)"; } ////////////////////////////////////////////////////////////////////////// @@ -1348,5 +1350,17 @@ class TranslatorBrazilian: public TranslatorAdapter_1_2_17 return "Conteúdo"; } +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return "Lista de Descontinuados(as)"; + } + }; #endif diff --git a/src/translator_cz.h b/src/translator_cz.h index f997bda..25eb4a5 100644 --- a/src/translator_cz.h +++ b/src/translator_cz.h @@ -141,6 +141,9 @@ // 2002/07/08 (my birthday! ;) // - The new trRTFTableOfContents() implemented. // +// 2002/07/29 +// - The new trDeprecatedList() implemented. +// // Todo // ---- // - The trReimplementedFromList() should pass the kind of the @@ -160,7 +163,7 @@ // probably slightly faster. -class TranslatorCzech : public TranslatorAdapter_1_2_17 +class TranslatorCzech : public Translator { private: /*! The decode() inline assumes the source written in the @@ -1517,9 +1520,20 @@ class TranslatorCzech : public TranslatorAdapter_1_2_17 */ virtual QCString trRTFTableOfContents() { - return "Obsah"; + return decode("Obsah"); } +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return decode("Seznam zastaralých prvkù"); + } }; #endif // TRANSLATOR_CZ_H diff --git a/src/translator_hr.h b/src/translator_hr.h index c53326a..13eaa7f 100644 --- a/src/translator_hr.h +++ b/src/translator_hr.h @@ -50,7 +50,7 @@ #ifndef TRANSLATOR_HR_H #define TRANSLATOR_HR_H -class TranslatorCroatian : public TranslatorAdapter_1_2_17 +class TranslatorCroatian : public Translator { private: /*! to avoid macro redefinition from translator_cz.h */ @@ -1051,7 +1051,17 @@ class TranslatorCroatian : public TranslatorAdapter_1_2_17 { return decode("Sadr¾aj"); } +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return "Popis zastarjelih metoda"; + } }; #endif diff --git a/src/translator_pt.h b/src/translator_pt.h index 02d6916..a3a3903 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -14,11 +14,13 @@ * input used in their production; they are not affected by this license. * * The translation into Portuguese was provided by - * Rui Godinho Lopes <ruiglopes@yahoo.com> + * Rui Godinho Lopes <rui@ruilopes.com> * http://www.ruilopes.com * * VERSION HISTORY * --------------- + * 006 30 july 2002 + * ! Updated for doxygen v1.2.17 * 005 10 july 2002 * ! Updated for doxygen v1.2.16 * 004 03 march 2002 @@ -36,7 +38,7 @@ #ifndef TRANSLATOR_PT_H #define TRANSLATOR_PT_H -class TranslatorPortuguese : public TranslatorAdapter_1_2_17 +class TranslatorPortuguese : public Translator { public: @@ -1382,6 +1384,18 @@ class TranslatorPortuguese : public TranslatorAdapter_1_2_17 return "Índice"; } +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return "Lista de Deprecados"; + } + }; #endif diff --git a/src/translator_ru.h b/src/translator_ru.h index 172a3e6..903caac 100644 --- a/src/translator_ru.h +++ b/src/translator_ru.h @@ -50,7 +50,7 @@ #ifndef TRANSLATOR_RU_H #define TRANSLATOR_RU_H -class TranslatorRussian : public TranslatorAdapter_1_2_17 +class TranslatorRussian : public Translator { private: /*! The Decode() inline assumes the source written in the @@ -1406,6 +1406,17 @@ class TranslatorRussian : public TranslatorAdapter_1_2_17 return decode("ïÇÌÁ×ÌÅÎÉÅ"); } +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return decode( "óÐÉÓÏË ÕÓÔÁÒÅ×ÛÉÈ ÏÐÒÅÄÅÌÅÎÉÊ É ÏÐÉÓÁÎÉÊ" ); + } }; #endif diff --git a/src/translator_sk.h b/src/translator_sk.h index 3092514..e85d286 100644 --- a/src/translator_sk.h +++ b/src/translator_sk.h @@ -23,7 +23,7 @@ #ifndef TRANSLATOR_SK_H #define TRANSLATOR_SK_H -class TranslatorSlovak : public TranslatorAdapter_1_2_13 +class TranslatorSlovak : public Translator { private: /*! The Decode() inline assumes the source written in the @@ -1342,6 +1342,50 @@ class TranslatorSlovak : public TranslatorAdapter_1_2_13 { return Decode("Odkazuje sa na"); } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.13 +////////////////////////////////////////////////////////////////////////// + + /*! used in member documentation blocks to produce a list of + * members that are implemented by this one. + */ + virtual QCString trImplementedFromList(int numEntries) + { + return "Implementuje " + trWriteList(numEntries) + "."; + } + + /*! used in member documentation blocks to produce a list of + * all members that implement this member. + */ + virtual QCString trImplementedInList(int numEntries) + { + return Decode("Implementované v " + trWriteList(numEntries) + "."); + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.16 +////////////////////////////////////////////////////////////////////////// + + /*! used in RTF documentation as a heading for the Table + * of Contents. + */ + virtual QCString trRTFTableOfContents() + { + return "Obsah"; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.2.17 +////////////////////////////////////////////////////////////////////////// + + /*! Used as the header of the list of item that have been + * flagged deprecated + */ + virtual QCString trDeprecatedList() + { + return "Zastarané metódy"; + } }; #endif // TRANSLATOR_SK_H diff --git a/src/util.cpp b/src/util.cpp index 7a48266..5b0ed19 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -3453,7 +3453,7 @@ void addRelatedPage(const char *name,const QCString &ptitle, // a page name is a label as well! SectionInfo *si=new SectionInfo( - pi->name,pi->title,SectionInfo::Section,pi->reference); + pi->name,pi->title,SectionInfo::Page,pi->reference); if (gd) { si->fileName=gd->getOutputFileBase(); @@ -3501,7 +3501,7 @@ void addRefItem(const QList<ListItemInfo> *sli, QCString doc(1000); doc += "<dl><dt>\\anchor "; doc += item->listAnchor; - doc += "\n"; + doc += " "; doc += prefix; doc += " \\_internalref "; doc += name; diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 8d8f78f..0eb94d2 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -544,21 +544,33 @@ class XMLGenerator : public OutputDocInterface docify(url); m_t << "</email>"; } - void startSection(const char *id,const char *,bool subsection) + void startSection(const char *id,const char *,SectionInfo::SectionType type) { XML_DB(("(startSection)\n")); endParMode(); m_t << "<sect"; - if (subsection) m_t << "2"; else m_t << "1"; + switch(type) + { + case SectionInfo::Page: m_t << "1"; break; + case SectionInfo::Section: m_t << "2"; break; + case SectionInfo::Subsection: m_t << "3"; break; + default: ASSERT(0); break; + } m_t << " id=\"" << id << "\">"; startNestedPar(); m_inParStack.top() = TRUE; } - void endSection(const char *,bool subsection) + void endSection(const char *,SectionInfo::SectionType type) { XML_DB(("(endSection)\n")); m_t << "</sect"; - if (subsection) m_t << "2"; else m_t << "1"; + switch(type) + { + case SectionInfo::Page: m_t << "1"; break; + case SectionInfo::Section: m_t << "2"; break; + case SectionInfo::Subsection: m_t << "3"; break; + default: ASSERT(0); break; + } m_t << ">"; m_inParStack.top() = FALSE; endNestedPar(); @@ -875,6 +887,14 @@ class XMLGenerator : public OutputDocInterface XML_DB(("(endLatexOnly)\n")); m_t << "</latexonly>" << endl; } + void startSectionRefList() + { + XML_DB(("(startSectionRefList)\n")); + } + void endSectionRefList() + { + XML_DB(("(endSectionRefList)\n")); + } // Generator specific functions |