/****************************************************************************** * * $Id$ * * Copyright (C) 1997-1999 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. * * All output generated with Doxygen is not covered by this license. * */ %{ /* * includes */ #include #include #include #include #include #include #include #include #include #include "scanner.h" #include "entry.h" #include "doxygen.h" #include "message.h" #include "config.h" #include "util.h" #include "index.h" #include "defargs.h" #include "language.h" #ifndef WIN32 #include #endif #define YY_NEVER_INTERACTIVE 1 /* ----------------------------------------------------------------- * * statics */ static bool insideArgumentList; static QString className; static QString memberName; static QString refName; static OutputList * outDoc; static QString code; static QString linkRef; static QString linkText; static QString codeBlock; static const char * inputString; static int inputPosition; static int lastContext; static int lastCContext; static int lastDocContext; static int lastDocRelContext; static int lastCPPContext; static int lastSkipSharpContext; static int lastSkipRoundContext; static int lastBriefContext; static int lastVerbState; static int lastStringContext; static int lastCurlyContext; static int lastCodeState; static int lastAfterDocContext; static int lastGroupContext; static int lastFormulaContext; static int lastAnchorContext; static int nextDefContext; static Protection protection; static Protection baseProt; static int bracketCount = 0 ; static int sharpCount = 0 ; static int roundCount = 0 ; static int ifCount = 0 ; static Entry* current_root = 0 ; static Entry* global_root = 0 ; static Entry* current = 0 ; static int yyLineNr = 0 ; static int anonCount = 0 ; static char yyFileName[2048] ; static bool sig; static bool slot; static bool gstat; static bool removeSlashes; static Specifier virt; static Specifier baseVirt; static bool exampleDoc; static QString exampleName; static QString htmlUrl,htmlText; static QString currentIncludeFile; static QString msType,msName,msArgs; static int includeFileOffset = 0; static int includeFileLength = 0; static bool firstLine; static bool isTypedef; static bool inParamBlock; static bool inExceptionBlock; static bool inSeeBlock; static bool inReturnBlock; static bool inAuthorBlock; static bool inVersionBlock; static bool inDateBlock; static bool inBugBlock; static bool inWarningBlock; static bool inParBlock; static bool firstSeeArg; static bool javaDocSee; static char afterDocTerminator; static int tmpDocType; static QString sectionLabel; static QString sectionTitle; static SectionInfo::SectionType sectionType; static QString funcPtrType; static QString templateStr; static QString baseName; static QString *specName; static QString formulaText; static QString sectionRef; // state variable for reading the argument list of a function static int argRoundCount; static int argSharpCount; static int currentArgumentContext; static int lastCopyArgStringContext; static int lastCopyArgContext; static QString *copyArgString; //----------------------------------------------------------------------------- static void initParser() { insideArgumentList=FALSE; className.resize(0); memberName.resize(0); refName.resize(0); code.resize(0); linkRef.resize(0); linkText.resize(0); codeBlock.resize(0); htmlUrl.resize(0); htmlText.resize(0); currentIncludeFile.resize(0); sectionLabel.resize(0); sectionTitle.resize(0); baseName.resize(0); formulaText.resize(0); protection = Public; baseProt = Public; bracketCount = 0; sharpCount = 0; roundCount = 0; ifCount = 0; sig = FALSE; slot = FALSE; gstat = FALSE; virt = Normal; baseVirt = Normal; includeFileOffset = 0; includeFileLength = 0; firstLine = TRUE; isTypedef = FALSE; inParamBlock = FALSE; inExceptionBlock = FALSE; inSeeBlock = FALSE; inReturnBlock = FALSE; inAuthorBlock = FALSE; inVersionBlock = FALSE; inDateBlock = FALSE; inBugBlock = FALSE; inWarningBlock = FALSE; inParBlock = FALSE; firstSeeArg = FALSE; javaDocSee = FALSE; } //----------------------------------------------------------------------------- void scanString(const char *s); //----------------------------------------------------------------------------- class TableElem { public: TableElem(int r,int c); ~TableElem(); int getRow() { return row; } int getCol() { return col; } OutputList *outputList() { return ol; } private: OutputList *ol; int row; int col; }; TableElem::TableElem(int r,int c) { //printf("TableElem::TableElem(%d,%d)\n",r,c); ol=new OutputList(outDoc); outDoc=ol; row=r; col=c; } TableElem::~TableElem() { //printf("TableElem::~TableElem(%d,%d)\n",row,col); delete ol; } class Table { public: Table(); ~Table(); void newRow(); void newElem(); private: OutputList *parentDoc; QList *elemList; int curRow; int curCol; int rows; int cols; }; Table::Table() { parentDoc=outDoc; elemList=new QList; elemList->setAutoDelete(TRUE); curRow=curCol=rows=cols=0; } Table::~Table() { //printf("Table::~Table()\n"); // use elemList & cols & rows if (cols>0 && rows>0) { parentDoc->startTable(cols); TableElem *e=elemList->first(); while (e) { if (e->getRow()>0) { if (e->getCol()==0) { if (e->getRow()>1) parentDoc->endTableRow(); parentDoc->nextTableRow(); } else { parentDoc->nextTableColumn(); } *parentDoc+=*e->outputList(); parentDoc->endTableColumn(); } e=elemList->next(); } parentDoc->endTable(); } delete elemList; outDoc=parentDoc; } void Table::newRow() { //printf("Table::newRow()\n"); curRow++; if (curRow>rows) rows=curRow; curCol=0; } void Table::newElem() { //printf("Table::newElem(%d,%d)\n",curRow,curCol); TableElem *te = new TableElem(curRow,curCol); elemList->append(te); curCol++; if (curCol>cols) cols=curCol; } static QStack tableStack; static Table *curTable; static void startTable() { //printf("startTable()\n"); curTable=new Table; tableStack.push(curTable); } static void endTable() { //printf("endTable()\n"); delete tableStack.pop(); // the destructor adds the table to the stream! curTable=tableStack.top(); } //----------------------------------------------------------------------------- static void lineCount() { for( const char* c = yytext ; *c ; ++c ) yyLineNr += (*c == '\n') ; } static void endArgumentList() { if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); } } static void addType( Entry* current ) { if( current->type.length() ) current->type += ' ' ; current->type += current->name ; current->name.resize(0) ; if( current->type.length() ) current->type += ' ' ; current->type += current->args ; current->args.resize(0) ; current->argList->clear(); } static void includeFile(OutputList &ol,const char *fileName,bool quiet) { //FileInfo *f; bool ambig; FileDef *fd; if ((fd=findFileDef(&exampleNameDict,fileName,ambig))) { currentIncludeFile=fileToString(fd->absFilePath()); includeFileOffset=0; includeFileLength=currentIncludeFile.length(); OutputList codeFrag(&ol); parseCode(codeFrag,0,currentIncludeFile,exampleDoc,exampleName); if (!quiet) { ol.startCodeFragment(); ol+=codeFrag; ol.endCodeFragment(); } } else if (ambig) { warn("Include file name %s is ambigious.\n",fileName); warn("Possible candidates:\n"); //includeFileList.writeMatches(fileName); showFileDefMatches(&exampleNameDict,fileName); } else { warn("Warning: example file %s is not found. ",fileName); warn("Check your EXAMPLE_PATH\n"); } } static void verbIncludeFile(OutputList &ol,const char *name) { //FileInfo *f; bool ambig; FileDef *fd; if ((fd=findFileDef(&exampleNameDict,name,ambig))) { ol.startCodeFragment(); ol.codify(fileToString(fd->absFilePath())); ol.endCodeFragment(); } else if (ambig) { warn("Include file name %s is ambigious.\n",name); warn("Possible candidates:\n"); showFileDefMatches(&exampleNameDict,name); } else { warn("Warning: example file %s is not found. ",name); warn("Check your EXAMPLE_PATH\n"); } } static QString stripQuotes(const char *s) { QString name; if (s==0 || *s==0) return name; name=s; if (name.at(0)=='"' && name.at(name.length()-1)=='"') { name=name.mid(1,name.length()-2); } return name; } static QString stripKnownExtensions(const char *text) { QString result=text; if (result.right(4)==".tex") result=result.left(result.length()-4); else if (result.right(5)==".html") result=result.left(result.length()-5); //printf("%s stripKnowExtensions(%s)\n",result.data(),text); return result; } static void skipLine(OutputList &ol,const char *key) { bool found=FALSE; while (!found) { QString s; char c; while ( includeFileOffset0 || includeFileOffset==includeFileLength) found=TRUE; } if (s.find(key)!=-1) { ol.writeString(" "); parseCode(ol,className,s,exampleDoc,exampleName); ol.writeString("\n"); } } static void showUntil(OutputList &ol,const char *key) { bool found=FALSE; while (!found) { QString s; char c; while ( includeFileOffset0) { ol.writeString(" "); parseCode(ol,className,s,exampleDoc,exampleName); ol.writeString("\n"); if (s.find(key)!=-1) found=TRUE; } if (includeFileOffset==includeFileLength) found=TRUE; } } static void newDocState(); //----------------------------------------------------------------- static bool inBlock() { return inParamBlock || inSeeBlock || inReturnBlock || inAuthorBlock || inVersionBlock || inDateBlock || inWarningBlock || inBugBlock || inParBlock || inExceptionBlock; } static void endBlock() { outDoc->endDescList(); inParamBlock=inSeeBlock=inReturnBlock=inAuthorBlock= inVersionBlock=inDateBlock=inBugBlock=inWarningBlock= inParBlock=inExceptionBlock=FALSE; } static void addSection() { //printf("New section pageName=%s label=%s title=%s\n", // current->name.data(),sectionLabel.data(),sectionTitle.data()); if (sectionLabel.isEmpty()) return; if (sectionDict[sectionLabel]==0) { SectionInfo *si=new SectionInfo(sectionLabel,sectionTitle,sectionType); sectionDict.insert(sectionLabel,si); current->anchors->append(new QString(sectionLabel)); } else { warn("Warning: Duplicate label %s found!\n",sectionLabel.data()); } } // Adds a formula text to the list/dictionary of formulas if it was // not already added. Returns the label of the formula. static QString addFormula() { QString formLabel; QString fText=formulaText.simplifyWhiteSpace(); Formula *f=0; if ((f=formulaDict[fText])==0) { f = new Formula(fText); formulaList.append(f); formulaDict.insert(fText,f); formLabel.sprintf("\\form#%d",f->getId()); formulaNameDict.insert(formLabel,f); } else { formLabel.sprintf("\\form#%d",f->getId()); } return formLabel; } /* ----------------------------------------------------------------- */ #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; while( c < max_size && inputString[inputPosition] ) { *buf = inputString[inputPosition++] ; //printf("%d (%c)\n",*buf,*buf); c++; buf++; } return c; } //ATTR ((({BN}+[^\>]+)/">")?) %} BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] BS ^(({B}*"//")?)(({B}*"*"+)?){B}* FILE ([a-z_A-Z0-9\.\\:\/\-\+]+)|("\""[^\n\"]+"\"") FILEMASK [a-z_A-Z0-9\.\\:\/\-\+]+"."[a-z_A-Z0-9\.\-\+]*[a-z_A-Z0-9\-\+] ID [a-z_A-Z][a-z_A-Z0-9]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) SCOPEMASK {ID}?(("::"|"#")?(~)?{ID})+ URLMASK [a-z_A-Z0-9\~\:\@\#\.\-\+\/]+ ATTR ({B}+[^>\n]*)? A [aA] BOLD [bB] BODY [bB][oO][dD][yY] BR [bB][rR] EM [eE][mM] CENTER [cC][eE][nN][tT][eE][rR] CODE [cC][oO][dD][eE] DL [dD][lL] DD [dD][dD] DT [dD][tT] DFN [dD][fF][nN] FORM [fF][oO][rR][mM] H1 [hH]1 H2 [hH]2 H3 [hH][3-6] HEAD [hH][eE][aA][dD] HR [hH][rR] HREF [hH][rR][eE][fF] I [iI] IMG [iI][mM][gG] INPUT [iI][nN][pP][uU][tT] LI [lL][iI] META [mM][eE][tT][aA] MULTICOL [mM][uU][lL][tT][iI][cC][oO][lL] NAME [nN][aA][mM][eE] OL [oO][lL] P [pP] PRE [pP][rR][eE] SMALL [sS][mM][aA][lL][lL] STRONG [sS][tT][rR][oO][nN][gG] SUB [sS][uU][bB] SUP [sS][uU][pP] SRC [sS][rR][cC] TABLE [tT][aA][bB][lL][eE] TITLE [tT][iI][tT][lL][eE] TD [tT][dD] TR [tT][rR] TT [tT][tT] UL [uU][lL] VAR [vV][aA][rR] %x Define %x DefineArg %x DefineEnd %x Include %x ClassName %x ClassVar %x Bases %x NextSemi %x FindMembers %x FindMemberName %x FindFields %x FindFieldArg %x Function %x FuncRound %x ExcpRound %x FuncQual %x Operator %x Array %x Curly %x Using %x NameSpaceDocArg1 %x SkipCurly %x SkipCurlyCpp %x SkipString %x SkipInits %x SkipCPP %x SkipCPPBlock %x SkipComment %x SkipCxxComment %x SkipBlock %x SkipCode %x Sharp %x SkipSharp %x SkipRound %x TypedefName %x Comment %x Doc %x JavaDoc %x ClassDoc %x LineDoc %x DefLineDoc %x ClassDocArg1 %x ClassDocArg2 %x ClassDocArg3 %x ClassDocFunc %x ClassDocFuncPtr %x ClassDocFuncQual %x ClassDocFuncExc %x ClassDocDefine %x ClassDocRelates %x ClassDocBrief %x ClassDocOverload %x ClassDefineArgs %x GroupDocArg1 %x GroupDocArg2 %x GroupName %x AfterDoc %x AfterDocBrief %x AfterDocLine %x PageDoc %x PageDocTitle %x PageDocArg1 %x PageDocArg2 %x FileDocArg1 %x FileDocArg2 %x ExampleDoc %x ExampleDocArg1 %x EnumDoc %x EnumDocArg1 %x FuncPtr %x EndFuncPtr %x FuncFunc %x FuncFuncEnd %x FuncFuncType %x MemberSpec %x MemberSpecSkip %x SkipVerbatim %x Text %x DocScan %x DocParam %x DocException %x DocHtmlScan %x DocLatexScan %x DocEmphasis %x DocBold %x DocCode %x DocCodeBlock %x DocInternal %x DocLink %x DocLinkText %x DocSkipWord %x DocInclude %x DocDontInclude %x DocDescItem %x DocHtmlLink %x DocHtmlAnchor %x DocHtmlHref1 %x DocHtmlHref2 %x DocBaseClass %x DocSkiplineKey %x DocSkipKey %x DocLineKey %x DocUntilKey %x DocKeyEnd %x DocPar %x DocRefName %x DocVerbatim %x DocVerbInc %x DocIndexWord %x DocRef %x DocRefArg %x DocRefArgStart %x DocRefItem %x DocRefItemName %x SectionLabel %x SectionTitle %x EndTemplate %x CopyArgString %x CopyArgRound %x CopyArgSharp %x ReadFuncArgType %x ReadTempArgs %x Specialization %x DocSkipHtmlComment %x ReadFormulaShort %x ReadFormulaLong %x AnchorLabel %% <*>\x06[^\x06]*\x06 { // new file yyLineNr= 1 ; int i; for( i = 0 ; yytext[i+1] != 6 ; i++ ) yyFileName[i] = yytext[i+1] ; yyFileName[i] = 0 ; msg("Parsing file %s...\n",yyFileName); current_root = global_root ; initParser(); current->reset(); int sec=guessSection(yyFileName); if (sec) { current->name = yyFileName; current->name = current->name; current->section = sec; current_root->addSubEntry(current); current = new Entry; } BEGIN( FindMembers ); } <*>\x0d /* ^{BL} { if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); } else { outDoc->newParagraph(); } if (inBlock()) endBlock(); } */ " removing %s\n",yytext); } /* [^\n\@\*\.\\]+ { current->brief+=yytext; } */ . { //printf("---> copy %c\n",*yytext); current->brief+=*yytext; } \n { current->brief+=' '; lineCount(); } "."[ \t\r\n] { lineCount(); current->brief+="."; BEGIN( tmpDocType ); } ("\\"|"@")"internal" { current->doc+="\\internal"; BEGIN( tmpDocType ); } {B}*("\\"|"@")("fn"|"var"|"typedef"){B}* { current->section = Entry::MEMBERDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocFunc ); } {B}*("\\"|"@")"def"{B}* { nextDefContext = YY_START==LineDoc ? DefLineDoc : ClassDoc; current->section = Entry::DEFINEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocDefine ); } {B}*("\\"|"@")"overload"{B}* { BEGIN( ClassDocOverload ); } {B}*"\n" { QString orgDoc = current->doc; current->doc = getOverloadDocs(); current->doc += "\n\n"; current->doc += orgDoc; yyLineNr++; BEGIN( Doc ); } . { unput(*yytext); current->section = Entry::OVERLOADDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocFunc ); } {B}*("\\"|"@")"enum"{B}* { current->section = Entry::ENUMDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( EnumDocArg1 ); } {B}*("\\"|"@")"defgroup"{B}* { current->section = Entry::GROUPDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( GroupDocArg1 ); } {B}*("\\"|"@")"namespace"{B}* { current->section = Entry::NAMESPACEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( NameSpaceDocArg1 ); } {B}*("\\"|"@")"class"{B}* { current->section = Entry::CLASSDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*("\\"|"@")"union"{B}* { current->section = Entry::UNIONDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*("\\"|"@")"struct"{B}* { current->section = Entry::STRUCTDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*("\\"|"@")"page"{B}* { current->section = Entry::PAGEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( PageDocArg1 ); } {B}*("\\"|"@")"file"{B}* { current->section = Entry::FILEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( FileDocArg1 ); } {B}*("\\"|"@")"example"{B}* { current->section = Entry::EXAMPLE_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ExampleDocArg1 ); } {FILE} { current->name = stripQuotes(yytext); BEGIN( ExampleDoc ); } {B}*("\\"|"@")"relate"[sd]{B}* { lastDocRelContext = YY_START; BEGIN( ClassDocRelates ); } {ID} { current->relates = yytext; BEGIN( lastDocRelContext ); } {SCOPENAME} { current->name = yytext; newDocState(); } "\n" { warn("Warning: missing argument after " "\\namespace at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; } {SCOPENAME} { current->name = yytext; // prepend outer scope name if (current_root->section & Entry::SCOPE_MASK) { current->name.prepend(current_root->name+"::"); } BEGIN( ClassDocArg2 ); } "\n" { warn("Warning: missing argument after " "\\class at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; } {ID}(".html"?) { current->name = yytext; if (current->name.right(5)==".html") current->name=current->name.left(current->name.length()-5); BEGIN(GroupDocArg2); } "\n" { warn("Warning: missing argument after " "\\defgroup at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; BEGIN( Doc ); } .* { current->type = yytext; current->type = current->type.stripWhiteSpace(); newDocState(); } "\n" { newDocState(); } {FILE} { //printf("ClassDocArg2=%s\n",yytext); current->includeFile = stripQuotes(yytext); BEGIN( ClassDocArg3 ); } {BL} { yyLineNr++; newDocState(); } {FILE} { //printf("ClassDocArg3=%s\n",yytext); current->includeName = stripQuotes(yytext); newDocState(); } {BL} { yyLineNr++; newDocState(); } {FILE} { current->name = stripQuotes(yytext); newDocState(); } "\n" { //warn("Warning: missing argument after " // "\\file at line %d of %s.\n",yyLineNr,yyFileName); current->name = yyFileName; yyLineNr++; newDocState(); } {FILE} { current->name = stripQuotes(yytext); BEGIN( PageDocArg2 ); } "\n" { warn("Warning: missing argument after " "\\page at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; BEGIN( Doc ); } .*"\n" { yyLineNr++; current->args = yytext; BEGIN( PageDoc ); } {SCOPEID} { current->name = yytext; if (current_root->section & Entry::SCOPE_MASK) { current->name.prepend(current_root->name+"::"); } newDocState(); } "\n" { warn("Warning: missing argument after " "\\enum at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; BEGIN( Doc ); } "\\refitem".*"\n" { current->doc+=yytext; } ("\\"|"@")"section"{B}+ { sectionType=SectionInfo::Section; BEGIN(SectionLabel); } ("\\"|"@")"subsection"{B}+ { sectionType=SectionInfo::Subsection; BEGIN(SectionLabel); } ("\\"|"@")anchor{B}+ { lastAnchorContext = YY_START; sectionType=SectionInfo::Anchor; BEGIN(AnchorLabel); } "\\\\verbatim"/[^a-z_A-Z0-9] { current->doc+="\\\\verbatim"; } ("\\"|"@")"verbatim"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->doc+="\\verbatim"; BEGIN(SkipVerbatim); } "\\addindex"{B}+[^\n]+ { current->doc+=yytext; } "\\\\code"/[^a-z_A-Z0-9] { current->doc+="\\\\code"; } ("\\"|"@")"code"/[^a-z_A-Z0-9] { lastCodeState=YY_START; current->doc+="\\code"; BEGIN(SkipCode); } "<"{PRE}{ATTR}">" { lastCodeState=YY_START; current->doc+="
";
					  BEGIN(SkipCode);
  					}
("\\"|"@")"endverbatim"/[^a-z_A-Z0-9] {
  					  current->doc+=yytext;
  					  BEGIN(lastVerbState);
  					}
[^ \t\/\\\n]*		{
  					  current->doc+=yytext;
  					}
^"//"			{
  					  if (!removeSlashes)
					    current->doc+=yytext;
  					}
  /*
^"//"({B}*"*"+)?		{
  					  if (!removeSlashes)
					    current->doc+=yytext;
  					}
^{B}*"*"+			
  */
"//"|"/*"			{ 
  					  current->doc+=yytext; 
  					}
"\n"			{
  					  yyLineNr++;
					  current->doc+=*yytext;
  					}
.				{
  					  current->doc+=*yytext;
  					}
("\\"|"@")"endcode"		{
  					  current->doc+="\\endcode";
					  BEGIN(lastCodeState);
  					}
""		{
  					  current->doc+="
"; BEGIN(lastCodeState); } ^"//"({B}*"*"+)? { if (!removeSlashes) current->doc+=yytext; } ^{B}*"*"+ "//" { current->doc+=yytext; } [^ \*\t\/\\\n]+ { current->doc+=yytext; } \n { yyLineNr++; current->doc+=*yytext; } . { current->doc+=*yytext; } {ID} { sectionLabel=yytext; addSection(); current->doc += "\\anchor "+sectionLabel+"\n"; BEGIN(lastAnchorContext); } {ID} { sectionLabel=yytext; sectionTitle.resize(0); BEGIN(SectionTitle); } [^\n*]*/"\n" { sectionTitle+=yytext; sectionTitle=sectionTitle.stripWhiteSpace(); addSection(); current->doc += "\\section "+sectionLabel+"\n"; BEGIN(PageDoc); } "*" { sectionTitle+=yytext; } "\n" { yyLineNr++ ; current->doc+=yytext; } [a-z_A-Z0-9 \t]+ { current->doc += yytext; } . { current->doc += yytext; } ^{B}*"//" "//" { current->doc += yytext; } "\\\\f"[$\[\]] { current->doc += &yytext[1]; } "\\f$" { lastFormulaContext = YY_START; formulaText="$"; BEGIN(ReadFormulaShort); } "\\f[" { lastFormulaContext = YY_START; formulaText="\\["; BEGIN(ReadFormulaLong); } "\\f$" { formulaText+="$"; if (lastFormulaContext==ClassDocBrief) current->brief += addFormula(); else current->doc += addFormula(); BEGIN(lastFormulaContext); } "\\f]" { formulaText+="\\]"; if (lastFormulaContext==ClassDocBrief) current->brief += addFormula(); else current->doc += addFormula(); BEGIN(lastFormulaContext); } . { formulaText+=*yytext; } "*/" { if (YY_START==ClassDocBrief && lastBriefContext==Doc) { current->doc += "\n\n"; BEGIN( lastDocContext ); } else { current->doc += "\n\n"; //printf("Add docs for class %s\n",current->name.data()); current_root->addSubEntry(current); current = new Entry ; current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; } BEGIN( FindMembers ); } "<"{TITLE}">" { current->args.resize(0); current->argList->clear(); BEGIN( PageDocTitle); } \n { yyLineNr++; current->args+=" "; } [^\n\<] { current->args+=yytext; } "" { BEGIN( PageDoc ); } ("\\"|"@")"ingroup"{B}+ { lastGroupContext = YY_START; lineCount(); BEGIN( GroupName ); } {ID} { current->groups->append( new QString(yytext) ); } \n { yyLineNr++; BEGIN( lastGroupContext ); } {B}*("\\brief"|"@short") { lastBriefContext=YY_START; BEGIN( ClassDocBrief ); } {B}*"\\inherit"{B}+ { BEGIN( DocBaseClass ); } {ID} { //printf("Adding base class %s\n",yytext); current->extends->append( new BaseInfo(yytext,Public,Normal) ); } \n { yyLineNr++; BEGIN( ClassDoc ); } {BS}{BL} { current->brief=current->brief.stripWhiteSpace(); yyLineNr++; BEGIN( lastBriefContext ); } "\n" { yyLineNr++ ; current->brief += " "; } "<"{BR}{ATTR}">" {BS}/("\\"|"@")"ingroup" { current->brief=current->brief.stripWhiteSpace(); BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"author" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"internal" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"version" { BEGIN( lastBriefContext ); } {BS}/"\\date" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"param" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"exception" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"return" { BEGIN( lastBriefContext ); } {BS}/("\\sa"|"@see") { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"bug" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"warning" { BEGIN( lastBriefContext ); } {BS}/("\\"|"@")"par"{BN}+ { BEGIN( lastBriefContext ); } {BS}/("\\brief"|"@short"){BN}+ { lastBriefContext=YY_START; BEGIN( ClassDocBrief ); } . { current->brief += *yytext; } {ID}/"(" { current->name = yytext; BEGIN( ClassDefineArgs ); } {ID} { current->name = yytext; if (nextDefContext==ClassDoc) newDocState(); else BEGIN( nextDefContext ); } ")" { current->args+=")"; if (nextDefContext==ClassDoc) newDocState(); else BEGIN( nextDefContext ); } . { current->args+= yytext; } "\n" { yyLineNr++; current->name = current->name.stripWhiteSpace(); if (current->section == Entry::MEMBERDOC_SEC && current->args.length()==0) current->section = Entry::VARIABLEDOC_SEC; newDocState(); } "(" { current->args+=*yytext; currentArgumentContext = ClassDocFuncQual; copyArgString=¤t->args; BEGIN( ReadFuncArgType ) ; } "("({B}*"*")+ { current->name+="(*"; BEGIN( ClassDocFuncPtr ); } {SCOPENAME} { current->name+=yytext; } ")" { current->name+=')'; BEGIN( ClassDocFunc ); } {B}*"const"{B}* { current->args += " const "; current->argList->constSpecifier=TRUE; } {B}*"volatile"{B}* { current->args += " volatile "; current->argList->volatileSpecifier=TRUE; } {B}*"="{B}*"0"{B}* { current->args += " = 0"; current->virt = Pure; current->argList->pureSpecifier=TRUE; } "throw"{B}*"(" { current->exception = "throw("; BEGIN(ClassDocFuncExc); } ")" { current->exception += ')'; BEGIN(ClassDocFuncQual); } . { current->exception += *yytext; } . { current->name += *yytext; } "\n" { yyLineNr++; current->name = current->name.stripWhiteSpace(); newDocState(); } . { current->doc += *yytext; } . { current->brief += *yytext; } \n { yyLineNr++; current->doc += *yytext; } \n { yyLineNr++; BEGIN( lastDocContext ); } \n { yyLineNr++; unput('/');unput('*'); BEGIN( ClassDoc ); } "/*"|"//" { current->brief+=yytext; } \n { if (afterDocTerminator!=0) unput(afterDocTerminator); BEGIN(lastAfterDocContext); } . { current->brief+=yytext; } "/*"|"//" { current->brief+=yytext; } ^{B}*"*"+/[^/\n] \n { current->brief+=yytext; yyLineNr++; } . { current->brief+=*yytext; } ^{B}*"*"/[^/\n]{BL} { yyLineNr++; if (!current->brief.stripWhiteSpace().isEmpty()) BEGIN(AfterDoc); } "*/" { if (afterDocTerminator!=0) unput(afterDocTerminator); BEGIN(lastAfterDocContext); } "."/{BN} { BEGIN(AfterDoc); } ("\\"|"@")"brief" { BEGIN(AfterDocBrief); } "/*"|"//" { current->doc+=yytext; } ^{B}*"*"+/[^/] \n { current->doc+=yytext; yyLineNr++; } . { current->doc+=*yytext; } "*/" { if (afterDocTerminator!=0) unput(afterDocTerminator); BEGIN(lastAfterDocContext); } "*/" { current->doc += "\n\n"; err("Warning: unexpected end of " "documentation block found in " "file %s at line %d\n",yyFileName,yyLineNr); BEGIN( lastDocContext ); } "*/" { current->doc += "\n\n"; BEGIN( lastDocContext ); } "*/" { unput('/');unput('*'); BEGIN( tmpDocType ); } ^{B}*(("//"{B}*)?)"*"+/[^/] "/*" { current->doc += yytext; } .*\n { yyLineNr++ ; BEGIN( lastCContext ) ; } <*>. <*>\n { yyLineNr++ ; } "//"|"/*" <*>"/*" { lastCContext = YY_START ; BEGIN( SkipComment ) ; } {B}*"*/" { BEGIN( lastCContext ) ; } <*>"//" { lastCContext = YY_START ; BEGIN( SkipCxxComment ) ; } %% //---------------------------------------------------------------------------- void scanString(const char *s) { const char *oldInputString = inputString; int oldInputPosition = inputPosition; int oldRule = YY_START; YY_BUFFER_STATE oldBuffer = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(scanYYin, YY_BUF_SIZE)); inputString = s; inputPosition = 0; BEGIN( Text ); scanYYlex(); yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(oldBuffer); inputString = oldInputString; inputPosition = oldInputPosition; BEGIN( oldRule ); } //---------------------------------------------------------------------------- static void newDocState() { if (tmpDocType!=-1) { tmpDocType=ClassDoc; BEGIN(JavaDoc); } else { BEGIN(ClassDoc); } } //---------------------------------------------------------------------------- void parseCompounds(Entry *rt) { //printf("parseCompounds(%s)\n",rt->name.data()); EntryListIterator eli(*rt->sublist); Entry *ce; for (;(ce=eli.current());++eli) { if (ce->program.length()>0) { //printf("-- %s ---------\n%s\n---------------\n", // ce->name.data(),ce->program.data()); // init scanner state inputString = ce->program; inputPosition = 0; scanYYrestart( scanYYin ) ; if (ce->section==Entry::ENUM_SEC) BEGIN( FindFields ) ; else BEGIN( FindMembers ) ; current_root = ce ; strcpy( yyFileName, ce->fileName ) ; yyLineNr = ce->startLine ; //current->reset(); current = new Entry; // set default protection based on the compound type if( ce->section==Entry::CLASS_SEC ) // class current->protection = protection = Private ; else if (ce->section == Entry::ENUM_SEC ) // enum current->protection = protection = ce->protection; else if (ce->name.length()>0 && ce->name.at(0)=='@') // anonymous union current->protection = protection = ce->protection; else // named struct or union current->protection = protection = Public ; sig = FALSE; slot = FALSE; gstat = FALSE; virt = Normal; scanYYlex() ; delete current; ce->program.resize(0); } parseCompounds(ce); } } //---------------------------------------------------------------------------- void parseMain(Entry *rt) { initParser(); anonCount = 0; protection = Public; sig = FALSE; slot = FALSE; gstat = FALSE; virt = Normal; current_root = rt; global_root = rt; current = new Entry; inputString = rt->program; //printf("parseDoc=`%s'\n",inputString); inputPosition = 0; ifCount=0; scanYYrestart( scanYYin ); BEGIN( FindMembers ); scanYYlex(); rt->program.resize(0); delete current; parseCompounds(rt); } //---------------------------------------------------------------------------- void parseDocument(OutputList &ol,const QString &docString) { //inParamBlock=inSeeBlock=inReturnBlock=FALSE; curTable = 0; outDoc = new OutputList(&ol); currentIncludeFile.resize(0); includeFileOffset=0; includeFileLength=0; if (!docString) return; linkRef = ""; linkText = ""; inputString = docString; inputPosition = 0; scanYYrestart( scanYYin ); BEGIN( DocScan ); insideArgumentList = FALSE; scanYYlex(); if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); } if (inBlock()) endBlock(); ol+=*outDoc; delete outDoc; return; } //---------------------------------------------------------------------------- void parseDoc(OutputList &ol,const char *clName, const char *memName,const QString &docString) { initParser(); initParseCodeContext(); exampleDoc=FALSE; // do not cross reference with member docs className=clName; memberName=memName; if (memName) { refName=className+"::"+memberName; } else { refName=className; } parseDocument(ol,docString); } //---------------------------------------------------------------------------- void parseText(OutputList &ol,const QString &txtString) { inputString = txtString; outDoc = new OutputList(&ol); inputPosition = 0; scanYYrestart( scanYYin ); BEGIN( Text ); scanYYlex(); ol+=*outDoc; delete outDoc; return; } //---------------------------------------------------------------------------- void parseExample(OutputList &ol,const QString &docString, const char *fileName) { initParser(); initParseCodeContext(); exampleDoc=TRUE; // cross reference with member docs exampleName=fileName; parseDocument(ol,docString); } //---------------------------------------------------------------------------- extern "C" { // some sillyness to keep the compiler happy int scanYYwrap() { return 1 ; } void bogus() { yy_flex_realloc(0,0); } }