/****************************************************************************** * * * * Copyright (C) 1997-2000 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ %{ /* * includes */ #include #include #include #include #include #include "qtbc.h" #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" #include "outputlist.h" #include "membergroup.h" #ifndef WIN32 #include #endif #define YY_NEVER_INTERACTIVE 1 /* ----------------------------------------------------------------- * * statics */ static bool insideArgumentList; static QCString className; static QCString memberName; static QCString refName; static OutputList * outDoc; static QCString code; static QCString linkRef; static QCString linkText; static QCString 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 lastRoundContext; static int lastSquareContext; static int lastCodeState; static int lastAfterDocContext; static int lastGroupContext; static int lastFormulaContext; static int lastAnchorContext; static int lastInitializerContext; static int lastClassTemplSpecContext; static int nextDefContext; static int overloadContext; static Protection protection; static Protection baseProt; static int sharpCount = 0 ; static int roundCount = 0 ; static int curlyCount = 0 ; static int squareCount = 0 ; static int ifCount = 0 ; static Entry* current_root = 0 ; static Entry* global_root = 0 ; static Entry* current = 0 ; static Entry* previous = 0 ; static Entry* tempEntry = 0 ; static int yyLineNr = 0 ; static int anonCount = 0 ; static char yyFileName[2048] ; static int lastMemberGroupLine; static bool sig; static bool slot; static bool gstat; static bool removeSlashes; static Specifier virt; static Specifier baseVirt; static bool exampleDoc; static QCString exampleName; static QCString htmlUrl,htmlText; static QCString currentIncludeFile; static QCString msType,msName,msArgs; static int memberGroupId = NOGROUP; static QCString memberGroupHeader; static QCString memberGroupDocs; static int includeFileOffset = 0; static int includeFileLength = 0; static bool firstLine; static bool isTypedef; static bool inParamBlock; static bool inRetValBlock; static bool inExceptionBlock; static bool inSeeBlock; static bool inReturnBlock; static bool inAuthorBlock; static bool inDeprecatedBlock; static bool inVersionBlock; static bool inDateBlock; static bool inBugBlock; static bool inNoteBlock; static bool inPreBlock; static bool inPostBlock; static bool inInvarBlock; static bool inWarningBlock; static bool inParBlock; static bool firstSeeArg; static char afterDocTerminator; static int tmpDocType; static QCString sectionLabel; static QCString sectionTitle; static SectionInfo::SectionType sectionType; static QCString funcPtrType; static QCString templateStr; static QCString baseName; static QCString *specName; static QCString formulaText; static QCString sectionRef; static bool insideIDL = FALSE; static bool insideCppQuote = FALSE; static int depthIf; // 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 int currentListIndentLevel; static QCString *copyArgString; static QCString fullArgString; static ArgumentList *currentArgumentList; static QCString *currentTemplateSpec; static QCString curImageName; static char lastCopyArgChar; static QCString *pCopyRoundString; static QCString *pCopyCurlyString; static QCString *pCopyQuotedString; //----------------------------------------------------------------------------- static void initParser() { insideArgumentList=FALSE; className.resize(0); memberName.resize(0); refName=""; 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; sharpCount = 0; roundCount = 0; curlyCount = 0; ifCount = 0; memberGroupId = NOGROUP; sig = FALSE; slot = FALSE; gstat = FALSE; virt = Normal; baseVirt = Normal; includeFileOffset = 0; includeFileLength = 0; firstLine = TRUE; isTypedef = FALSE; inParamBlock = FALSE; inRetValBlock = FALSE; inExceptionBlock = FALSE; inSeeBlock = FALSE; inReturnBlock = FALSE; inAuthorBlock = FALSE; inDeprecatedBlock = FALSE; inVersionBlock = FALSE; inDateBlock = FALSE; inBugBlock = FALSE; inNoteBlock = FALSE; inPreBlock = FALSE; inPostBlock = FALSE; inInvarBlock = FALSE; inWarningBlock = FALSE; inParBlock = FALSE; firstSeeArg = 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; ol=0; } 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; elemList=0; 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 forceEndTable() { err("Error: More
tags found than
" "tags in documentation block in file %s!\n",yyFileName); while (!tableStack.isEmpty()) { endTable(); } } //----------------------------------------------------------------------------- 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 QCString stripQuotes(const char *s) { QCString 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 QCString stripKnownExtensions(const char *text) { QCString 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) { QCString s; char c; while ( includeFileOffset listIndentStack; static bool insideItemList = FALSE; static void addListItemMarker(const char *marker) { // find the actual position at which the bullet was found int indent=0; const char *p=marker; char c; while ((c=*p++)) { if (c=='\t') { indent+=Config::tabSize - (indent%Config::tabSize); } else { indent++; } } //printf("list marker found at column %d\n",indent); if (!insideItemList) { outDoc->startItemList(); outDoc->writeListItem(); listIndentStack.push(new int(indent)); insideItemList=TRUE; } else { int *pPrevIndent = listIndentStack.top(); if (*pPrevIndent==indent) // new item at the same indent level { outDoc->writeListItem(); } else if (*pPrevIndentstartItemList(); outDoc->writeListItem(); listIndentStack.push(new int(indent)); } else // end sub item list { listIndentStack.pop(); delete pPrevIndent; outDoc->endItemList(); // safe guard against wrong indenting if (listIndentStack.isEmpty()) { insideItemList=FALSE; warn("Warning: list item with invalid indent found!\n"); } else { outDoc->writeListItem(); } } } } static void forceEndItemList() { int *indent; while ((indent=listIndentStack.pop())!=0) { outDoc->endItemList(); delete indent; } insideItemList=FALSE; } #if 0 static void tryEndItemList() { if (listIndentStack.count()==1) // no subitems => end list { outDoc->endItemList(); delete listIndentStack.pop(); insideItemList=FALSE; } } #endif //----------------------------------------------------------------- static bool inBlock() { return inParamBlock || inRetValBlock || inSeeBlock || inReturnBlock || inAuthorBlock || inVersionBlock || inDateBlock || inWarningBlock || inBugBlock || inNoteBlock || inParBlock || inExceptionBlock || inDeprecatedBlock || inPreBlock || inPostBlock || inInvarBlock; } static void endBlock() { if (inParamBlock || inRetValBlock || inExceptionBlock) { outDoc->endDescTableData(); outDoc->endDescTable(); } outDoc->endDescList(); inParamBlock=inRetValBlock=inSeeBlock=inReturnBlock=inAuthorBlock= inVersionBlock=inDateBlock=inBugBlock=inNoteBlock=inWarningBlock= inParBlock=inExceptionBlock=inDeprecatedBlock=inPreBlock=inPostBlock= inInvarBlock=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); //printf("Adding section addr=%p label=`%s' sectionTitle=`%s' fileName=%s\n",si,sectionLabel.data(),sectionTitle.data(),si->fileName.data()); sectionDict.insert(sectionLabel,si); current->anchors->append(new QCString(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 QCString addFormula() { QCString formLabel; QCString 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; } static bool nameIsOperator(QCString &name) { return name.right(8)=="operator" && (name.length()==8 || !isId(name.at(name.length()-9))); } static void checkDocs() { if ((current->brief.length()>2 && current->brief.at(0)=='<' && current->brief.at(1)==' ') || (current->doc.length()>2 && current->doc.at(0)=='<' && current->doc.at(1)==' ') ) { warn("Warning: Found lonely '<' symbol at the start of the documentation " "at line %d of %s\n",yyLineNr,yyFileName); } } //static bool curLatexState; //static bool curManState; //static bool curHtmlState; // //static void storeOutputListState() //{ // curLatexState = outDoc->isEnabled(OutputGenerator::Latex); // curHtmlState = outDoc->isEnabled(OutputGenerator::Html); // curManState = outDoc->isEnabled(OutputGenerator::Man); //} // //static void restoreOutputListState() //{ // if (curLatexState) // outDoc->enable(OutputGenerator::Latex); // else // outDoc->disable(OutputGenerator::Latex); // if (curHtmlState) // outDoc->enable(OutputGenerator::Html); // else // outDoc->disable(OutputGenerator::Html); // if (curManState) // outDoc->enable(OutputGenerator::Man); // else // outDoc->disable(OutputGenerator::Man); //} enum ImageTypes { IT_Html, IT_Latex }; // search for an image in the imageNameDict and if found // copies the image to the output directory (which is the // html directory if type==0 or the latex directory if type==1) static QCString findAndCopyImage(const char *fileName,ImageTypes type) { QCString result; bool ambig; FileDef *fd; if ((fd=findFileDef(&imageNameDict,fileName,ambig))) { QFile inImage(fd->absFilePath()); if (inImage.open(IO_ReadOnly)) { result = fileName; int i; if ((i=result.findRev('/'))!=-1 || (i=result.findRev('\\'))!=-1) { result.right(result.length()-i-1); } QCString outputDir; switch(type) { case IT_Html: outputDir = Config::htmlOutputDir; break; case IT_Latex: outputDir = Config::latexOutputDir; break; } QCString outputFile = outputDir+"/"+result; QFile outImage(outputFile); if (outImage.open(IO_WriteOnly)) // copy the image { char *buffer = new char[inImage.size()]; inImage.readBlock(buffer,inImage.size()); outImage.writeBlock(buffer,inImage.size()); outImage.flush(); delete buffer; } else { warn("Warning: could not write output image %s\n",outputFile.data()); } } else { warn("Warning: could not open image %s\n",fileName); } } else if (ambig) { warn("Warning: image file name %s is ambigious.\n",fileName); warn("Possible candidates:\n"); //includeFileList.writeMatches(fileName); showFileDefMatches(&imageNameDict,fileName); } else { result=fileName; if (result.left(5)!="http:") { warn("Warning: image file %s is not found in IMAGE_PATH: " "assuming external image. ",fileName); } } return result; } QCString extractName(const QCString &s) { uint i=0; while (i]+)/">")?) %} CMD ("\\"|"@") 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\~\:\@\#\.\-\+\/]+ NONTERM [\{\}\[\]\`\~\@\|\-\+\#\$\/\\\!\%\^\&\*()a-z_A-Z<>0-9] WORD ({NONTERM}+([^\n\t ]*{NONTERM}+)?)|("\""[^\n\"]"\"") 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] DOCPARAM ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"") %option noyywrap %x Define %x DefineArg %x DefineEnd %x Include %x ClassName %x ClassVar %x ClassTemplSpec %x Bases %x BasesProt %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 UsingDirective %x NameSpaceDocArg1 %x SkipCurly %x SkipCurlyCpp %x SkipCurlyEndDoc %x SkipString %x SkipInits %x SkipCPP %x SkipCPPBlock %x SkipComment %x SkipCxxComment %x SkipCurlyBlock %x SkipRoundBlock %x SkipCode %x Sharp %x SkipSharp %x SkipRound %x SkipSquare %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 ClassDocFuncSkipLine %x ClassDocFuncExc %x ClassDocDefine %x ClassDocRelates %x ClassDocBrief %x ClassDocOverload %x ClassDefineArgs %x CppQuote %x EndCppQuote %x GroupDocArg1 %x GroupDocArg2 %x GroupName %x GroupHeader %x StoreGroupDocs %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 DocIf %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 DocImage %x DocHtmlImageName %x DocLatexImageName %x DocLatexImageWidth %x SectionLabel %x SectionTitle %x SkipTemplate %x EndTemplate %x CopyArgString %x CopyArgRound %x CopyArgSharp %x CopyArgComment %x CopyArgCommentLine %x SkipUnionSwitch %x ReadFuncArgType %x ReadTempArgs %x Specialization %x DocSkipHtmlComment %x ReadFormulaShort %x ReadFormulaLong %x AnchorLabel %x ReadInitializer %x CopyString %x CopyRound %x CopyCurly %x IDLUnionCase %% <*>\x06[^\x06]*\x06 { // new file if (memberGroupId!=NOGROUP) { warn("Warning: Missing //@} in file %s\n",yyFileName); memberGroupId=NOGROUP; } yyLineNr= 0 ; // there is always an extra newline at the start of the file int i; for( i = 0 ; yytext[i+1] != 6 ; i++ ) yyFileName[i] = yytext[i+1] ; yyFileName[i] = 0 ; insideIDL = i>4 && strcmp(&yyFileName[i-4],".idl")==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(); } */ ^{B}*(("//"{B}*)?)"*"*{B}*"-"{B}+ { /* found list item marker */ addListItemMarker(yytext); } " member template\n"); if (current->mtArgList) { current->mtArgList->clear(); } else { current->mtArgList = new ArgumentList; current->mtArgList->setAutoDelete(TRUE); } currentArgumentList = current->mtArgList; } else // class template specifier { //printf("-------> class template\n"); if (current->tArgList) { current->tArgList->clear(); } else { current->tArgList = new ArgumentList; current->tArgList->setAutoDelete(TRUE); } currentArgumentList = current->tArgList; } templateStr="<"; fullArgString = templateStr.copy(); copyArgString = &templateStr; currentArgumentContext = FindMembers; //printf("Start template list\n"); BEGIN( ReadTempArgs ); } "using"{BN}+ { current->startLine=yyLineNr; lineCount(); BEGIN(Using); } "namespace"{BN}+ { lineCount(); BEGIN(UsingDirective); } ";" { BEGIN(FindMembers); } {SCOPENAME} { current->name=yytext; current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; //printf("Found using directive %s\n",yytext); current_root->addSubEntry(current); current = new Entry ; current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; BEGIN(Using); } {SCOPENAME}{BN}*"<>" { // guided template decl QCString n=yytext; addType( current ); current->name=n.left(n.length()-2); } {SCOPENAME}{BN}*/"<" { sharpCount=0; lineCount(); addType( current ); current->name=yytext; current->name=current->name.stripWhiteSpace(); current->scopeSpec.resize(0); currentTemplateSpec = ¤t->scopeSpec; if (nameIsOperator(current->name)) BEGIN( Operator ); else BEGIN( EndTemplate ); } {SCOPENAME}{BN}*/"<" { sharpCount=0; lineCount(); current->name+=((QCString)yytext).stripWhiteSpace(); current->memberSpec.resize(0); currentTemplateSpec = ¤t->memberSpec; if (nameIsOperator(current->name)) BEGIN( Operator ); else BEGIN( EndTemplate ); } /* "<" { sharpCount++; } ">" { if (--sharpCount<=0) { BEGIN(FindMembers); } } . */ "<" { current->name+='<'; *currentTemplateSpec+='<'; sharpCount++; } ">" { current->name+='>'; *currentTemplateSpec+='>'; if (--sharpCount<=0) { //printf("Found %s\n",current->name.data()); BEGIN(FindMembers); } } ">"{BN}*"(" { lineCount(); current->name+='>'; *currentTemplateSpec+='>'; if (--sharpCount<=0) { current->args = "("; currentArgumentContext = FuncQual; fullArgString = current->args.copy(); copyArgString = ¤t->args; //printf("Found %s\n",current->name.data()); BEGIN( ReadFuncArgType ) ; } } ">"{BN}*/"::" { lineCount(); current->name+='>'; *currentTemplateSpec+='>'; if (--sharpCount<=0) { BEGIN(FindMemberName); } } . { current->name+=*yytext; *currentTemplateSpec+=*yytext; } {SCOPENAME} { if (insideIDL && yyleng==9 && strcmp(yytext,"cpp_quote")==0) { BEGIN(CppQuote); } else if (insideIDL && strcmp(yytext,"case")==0) { BEGIN(IDLUnionCase); } else { lineCount(); if (YY_START==FindMembers) { addType( current ) ; current->name = yytext; } else { current->name += yytext; } QCString tmp=yytext; if (nameIsOperator(tmp)) BEGIN( Operator ); else BEGIN(FindMembers); } } "("{B}*"\"" { insideCppQuote=TRUE; BEGIN(FindMembers); } "::" ":" { BEGIN(FindMembers); } \n { yyLineNr++; } . ")" { insideCppQuote=FALSE; BEGIN(FindMembers); } {B}*"#" { lastCPPContext = YY_START; BEGIN( SkipCPP ) ; } {B}*"#"{B}*"define" { current->bodyLine = yyLineNr; BEGIN( Define ); } . \\[\r]*"\n"[\r]* { yyLineNr++ ; } [\r]*\n[\r]* { yyLineNr++ ; BEGIN( lastCPPContext) ; } {ID}/"(" { current->bodyLine = yyLineNr; current->name = yytext; BEGIN( DefineArg ); } ")" { //printf("Define with args\n"); current->args += ')'; BEGIN( DefineEnd ); } . { current->args += *yytext; } {ID} { //printf("Define `%s' without args\n",yytext); current->bodyLine = yyLineNr; current->name = yytext; BEGIN(DefineEnd); } \n { //printf("End define\n"); yyLineNr++; current->fileName = yyFileName; current->startLine = yyLineNr; current->type.resize(0); current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::DEFINE_SEC; current_root->addSubEntry(current); current = new Entry ; current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; BEGIN(FindMembers); } \\[\r]?\n { yyLineNr++; } \" { if (insideIDL && insideCppQuote) { BEGIN(EndCppQuote); } else { lastStringContext=DefineEnd; BEGIN(SkipString); } } . [*&]+ { current->name += yytext ; } ";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); if (current->bodyLine==-1) current->bodyLine=yyLineNr; lastAfterDocContext = YY_START; afterDocTerminator = ';'; if (yytext[yyleng-3]=='/') { current->brief.resize(0); BEGIN(AfterDocLine); } else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag) { current->brief.resize(0); BEGIN(AfterDocBrief); } else { current->doc.resize(0); BEGIN(AfterDoc); } } ","{BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); lastAfterDocContext = YY_START; afterDocTerminator = ','; if (yytext[yyleng-3]=='/') { current->brief.resize(0); BEGIN(AfterDocLine); } else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag) { current->brief.resize(0); BEGIN(AfterDocBrief); } else { current->doc.resize(0); BEGIN(AfterDoc); } } {BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); lastAfterDocContext = YY_START; if (YY_START==DefineEnd) afterDocTerminator = '\n'; else afterDocTerminator = 0; if (yytext[yyleng-3]=='/') { current->brief.resize(0); BEGIN(AfterDocLine); } else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag) { current->brief.resize(0); BEGIN(AfterDocBrief); } else { current->doc.resize(0); BEGIN(AfterDoc); } } "//@{"|"/*@{*/" { if (memberGroupId!=NOGROUP) { warn("Warning: ignoring nested member group " "at line %d of %s. Previous command was found at line %d\n", yyLineNr,yyFileName,lastMemberGroupLine); } else if (memberGroupHeader.isEmpty()) { warn("Warning: member group has empty header " "at line %d of %s.\n",yyLineNr,yyFileName); memberGroupHeader="[No header specified!]"; } else { memberGroupId = newMemberGroupId(); current->mGrpId = memberGroupId; lastMemberGroupLine = yyLineNr; } } "//@}"|"/*@}*/" { if (memberGroupId==NOGROUP) { warn("Warning: end of member group without matching begin " "at line %d of %s.\n",yyLineNr,yyFileName); } else { memberHeaderDict.insert(memberGroupId, new QCString(memberGroupHeader.stripWhiteSpace()) ); memberDocDict.insert(memberGroupId, new QCString(memberGroupDocs) ); memberGroupId=NOGROUP; current->mGrpId=NOGROUP; memberGroupHeader.resize(0); memberGroupDocs.resize(0); } } "=" { current->bodyLine = yyLineNr; lastInitializerContext = YY_START; BEGIN(ReadInitializer); } /* Read initializer rules */ "(" { lastRoundContext=YY_START; pCopyRoundString=¤t->initializer; roundCount=0; current->initializer+=*yytext; BEGIN(CopyRound); } "{" { lastCurlyContext=YY_START; pCopyCurlyString=¤t->initializer; curlyCount=0; current->initializer+=*yytext; BEGIN(CopyCurly); } [;,] { //printf(">> initializer `%s' <<\n",current->initializer.data()); unput(*yytext); BEGIN(lastInitializerContext); } \" { if (insideIDL && insideCppQuote) { BEGIN(EndCppQuote); } else { lastStringContext=YY_START; current->initializer+=*yytext; pCopyQuotedString=¤t->initializer; BEGIN(CopyString); } } "'"\\[0-7]{1,3}"'" "'"\\."'" "'"."'" \n { current->initializer+=*yytext; yyLineNr++; } . { current->initializer+=*yytext; } /* generic quoted string copy rules */ \\. { *pCopyQuotedString+=yytext; } \" { *pCopyQuotedString+=*yytext; BEGIN( lastStringContext ); } "/*"|"*/"|"//" { *pCopyQuotedString+=yytext; } \n { *pCopyQuotedString+=*yytext; yyLineNr++; } . { *pCopyQuotedString+=*yytext; } /* generic round bracket list copy rules */ \" { *pCopyRoundString+=*yytext; pCopyQuotedString=pCopyRoundString; lastStringContext=YY_START; BEGIN(CopyString); } "(" { *pCopyRoundString+=*yytext; roundCount++; } ")" { *pCopyRoundString+=*yytext; if (--roundCount<0) BEGIN(lastRoundContext); } \n { yyLineNr++; *pCopyRoundString+=*yytext; } "'"\\[0-7]{1,3}"'" { *pCopyRoundString+=yytext; } "'"\\."'" { *pCopyRoundString+=yytext; } "'"."'" { *pCopyRoundString+=yytext; } [^"'()\n]+ { *pCopyRoundString+=yytext; } /* generic curly bracket list copy rules */ \" { *pCopyCurlyString+=*yytext; pCopyQuotedString=pCopyCurlyString; lastStringContext=YY_START; BEGIN(CopyString); } "{" { *pCopyCurlyString+=*yytext; curlyCount++; } "}" { *pCopyCurlyString+=*yytext; if (--curlyCount<0) BEGIN(lastCurlyContext); } "'"\\[0-7]{1,3}"'" { *pCopyCurlyString+=yytext; } "'"\\."'" { *pCopyCurlyString+=yytext; } "'"."'" { *pCopyCurlyString+=yytext; } [^"'{}\n]+ { *pCopyCurlyString+=yytext; } \n { yyLineNr++; *pCopyCurlyString+=*yytext; } [:;,] { QCString oldType = current->type.copy(); QCString oldDocs = current->doc.copy(); if ( *yytext != ':') { if (current->bodyLine==-1) { current->bodyLine = yyLineNr; } current->type=current->type.simplifyWhiteSpace(); current->args=current->args.simplifyWhiteSpace(); current->name=current->name.stripWhiteSpace(); if (!current->name.isEmpty() && current->type.left(8)=="typedef ") { // add typedef to dictionary QCString dest = extractName(current->type.right(current->type.length()-8)); if (!dest.isEmpty()) { //printf(">>>>>>>>>> adding %s->%s\n",current->name.data(),dest.data()); typedefDict.insert(current->name, new QCString(dest)); } } current->section = Entry::VARIABLE_SEC ; current->fileName = yyFileName; current->startLine = yyLineNr; //printf("New variable type=`%s' name=`%s' groupId=%d\n",current->type.data(),current->name.data(),current->mGrpId); current_root->addSubEntry( current ) ; current = new Entry ; // variable found current->section = Entry::EMPTY_SEC ; current->protection = protection; current->slot = slot = FALSE; current->sig = sig = FALSE; current->virt = Normal; current->stat = gstat; current->mGrpId = memberGroupId; } // skip expression or bitfield if needed if ( *yytext == ':') { BEGIN( NextSemi ); } else { if ( *yytext == ',' ) { int i=oldType.length(); while (i>0 && (oldType[i-1]=='*' || oldType[i-1]==' ')) i--; current->type = oldType.left(i); current->doc = oldDocs; } BEGIN( FindMembers ) ; } } "[" { if (current->name.isEmpty()) // IDL function property { squareCount=1; lastSquareContext = YY_START; BEGIN(SkipSquare); } else { current->args += yytext ; squareCount=1; BEGIN( Array ) ; } } "]" { current->args += *yytext ; if (--squareCount<=0) BEGIN( FindMembers ) ; } "[" { current->args += *yytext ; squareCount++; } . { current->args += *yytext ; } "[" { squareCount++; } "]" { if (--squareCount<=0) BEGIN( lastSquareContext ); } \" { lastStringContext=YY_START; BEGIN( SkipString ); } [^\n\[\]\"]+ "<" { addType( current ) ; current->type += yytext ; BEGIN( Sharp ) ; } ">" { current->type += *yytext ; if (--sharpCount<=0) BEGIN( FindMembers ) ; } "<" { current->type += *yytext ; sharpCount++; } {BN}+ { lineCount(); } . { current->type += *yytext ; } {ID} { current->name = yytext; } "=" { lastInitializerContext = YY_START; BEGIN(ReadInitializer); } "," { //printf("adding `%s' `%s' `%s' to enum `%s' (mGrpId=%d)\n", // current->type.data(), current->name.data(), // current->args.data(), current_root->name.data(),current->mGrpId); current->fileName = yyFileName; current->startLine = yyLineNr; current->type = "@"; // enum marker current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; // add to the scope of the enum current_root->addSubEntry(current); current = new Entry(*current); // add to the scope surrounding the enum (copy!) current_root->parent->addSubEntry(current); current = new Entry ; current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; } /* "," { unput(*yytext); BEGIN(FindFields); } */ [^\r\n{}"'/]* { current->program += yytext ; } "//".* { current->program += yytext ; } \"[^\r\n"]*\" { current->program += yytext ; } "/*"{B}* { current->program += yytext ; lastContext = Curly ; BEGIN( Comment ) ; } "/*"{BL} { current->program += yytext ; ++yyLineNr ; lastContext = Curly ; BEGIN( Comment ) ; } "'"\\[0-7]{1,3}"'" { current->program += yytext; } "'"\\."'" { current->program += yytext; } "'"."'" { current->program += yytext; } "{" { current->program += yytext ; ++curlyCount ; } "}" { //err("Curly count=%d\n",curlyCount); if ( curlyCount>0 ) { current->program += yytext ; --curlyCount ; } else { current->endBodyLine = yyLineNr; QCString &cn = current->name; //QCString rn = stripAnnonymousScope(current_root->name); QCString rn = current_root->name.copy(); //printf("cn=`%s' rn=`%s'\n",cn.data(),rn.data()); if (!cn.isEmpty() && !rn.isEmpty() && (current_root->section & Entry::SCOPE_MASK)) { cn.prepend(rn+"::"); } if (isTypedef && cn.isEmpty()) { //printf("Typedef Name\n"); BEGIN( TypedefName ); } else { if (current->section == Entry::ENUM_SEC) { current->program+=','; // add field terminator } // add compound definition to the tree current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); //printf("adding `%s' `%s' `%s' brief=%s\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data()); current_root->addSubEntry( current ) ; current = new Entry(*current); if (current->section==Entry::NAMESPACE_SEC || current->section==Entry::INTERFACE_SEC ) { // namespaces and interfaces ends with a closing bracket without semicolon current->reset(); current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; BEGIN( FindMembers ) ; } else BEGIN( MemberSpec ) ; } } } {ID} { if (current->section == Entry::ENUM_SEC) { current->program+=","; // add field terminator } current->name=yytext; if (current_root->section & Entry::SCOPE_MASK) { current->name.prepend(current_root->name+"::"); } current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data()); current_root->addSubEntry( current ) ; current = new Entry; current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; BEGIN(MemberSpecSkip); } ([*&]*{BN}*)*{ID}("["[a-z_A-Z0-9]*"]")* { // the [] part could be improved. lineCount(); int i=0,l=yyleng,j; while (i[,;] { if (msName.isEmpty() && !current->name.isEmpty()) /* && (current->section & Entry::COMPOUND_MASK)) */ { // see if the compound does not have a name or is inside another // annonymous compound. If so we insert a // special `annonymous' variable. Entry *p=current_root; while (p) { // only look for class scopes, not namespace scopes if ((p->section & Entry::COMPOUND_MASK) && !p->name.isEmpty()) { //printf("Trying scope `%s'\n",p->name.data()); int i=p->name.findRev("::"); int pi = (i==-1) ? 0 : i+2; if (p->name.at(pi)=='@') { // annonymous compound inside -> insert dummy variable name //printf("Adding annonymous variable for scope %s\n",p->name.data()); msName.sprintf("@%d",anonCount++); break; } } p=p->parent; } } if (!msName.isEmpty()) { Entry *varEntry=new Entry; varEntry->protection = current->protection ; varEntry->sig = current->sig; varEntry->virt = current->virt; varEntry->stat = current->stat; varEntry->slot = current->slot; varEntry->section = Entry::VARIABLE_SEC; varEntry->name = msName.stripWhiteSpace(); varEntry->type = current->type.simplifyWhiteSpace()+" "; varEntry->args = msArgs; //current->args.simplifyWhiteSpace(); //if (!current->name.isEmpty() && current->name[0]!='@' && // current->parent->section & Entry::COMPOUND_MASK) // varEntry->type+=current->parent->name+"::"; if (isTypedef) varEntry->type.prepend("typedef "); varEntry->type+=current->name+msType; varEntry->fileName = yyFileName; varEntry->startLine = yyLineNr; varEntry->doc = current->doc.copy(); varEntry->brief = current->brief.copy(); varEntry->mGrpId = current->mGrpId; //printf("Add: type=`%s',name=`%s',args=`%s'\n", // varEntry->type.data(),varEntry->name.data(),varEntry->args.data()); current_root->addSubEntry(varEntry); } if (*yytext==';') { msType.resize(0); msName.resize(0); msArgs.resize(0); isTypedef=FALSE; current->reset(); current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; BEGIN( FindMembers ); } } "=" { lastInitializerContext=YY_START; BEGIN(ReadInitializer); /* BEGIN(MemberSpecSkip); */ } /* "{" { curlyCount=0; lastCurlyContext = MemberSpecSkip; previous = current; BEGIN(SkipCurly); } */ "," { BEGIN(MemberSpec); } ";" { unput(';'); BEGIN(MemberSpec); } {BN}+ { current->program += yytext ; lineCount() ; } . { current->program += yytext ; } "("({BN}*{ID}{BN}*"::"{BN}*)*("*"{BN}*)+ { current->bodyLine = yyLineNr; lineCount(); addType(current); funcPtrType=yytext; //current->type += yytext; BEGIN( FuncPtr ); } {SCOPENAME} { current->name = yytext; BEGIN( EndFuncPtr ); } . { //printf("Error: FuncPtr `%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName); } ")"{BN}*/";" { // a variable with extra braces lineCount(); current->type+=funcPtrType.data()+1; BEGIN(FindMembers); } ")"{BN}*/"(" { // a variable function lineCount(); current->type+=funcPtrType+")"; BEGIN(FindMembers); } ")"{BN}*/"[" { lineCount(); current->type+=funcPtrType.data(); current->args += ")"; BEGIN(FindMembers); } "(" { // a function returning a function current->args += *yytext ; roundCount=0; BEGIN( FuncFunc ); } ")" { BEGIN(FindMembers); } "(" { current->args += *yytext ; ++roundCount; } ")" { current->args += *yytext ; if ( roundCount ) --roundCount; else { BEGIN(FuncFuncEnd); } } ")"{BN}*"(" { lineCount(); current->type+=funcPtrType+")("; BEGIN(FuncFuncType); } ")"{BN}*/[;{] { lineCount(); current->type+=funcPtrType.data()+1; BEGIN(Function); } . { current->args += *yytext; } "(" { current->type += *yytext; roundCount++; } ")" { current->type += *yytext; if (roundCount) --roundCount; else BEGIN(Function); } {BN}*","{BN}* { lineCount() ; current->type += ", " ; } {BN}+ { lineCount() ; current->type += ' ' ; } . { current->type += *yytext; } "(" { current->args = yytext; current->bodyLine = yyLineNr; currentArgumentContext = FuncQual; fullArgString=current->args.copy(); copyArgString=¤t->args; BEGIN( ReadFuncArgType ) ; //printf(">>> Read function arguments!\n"); } /* "("{BN}*("void"{BN}*)?")" { lineCount(); current->args = "()"; BEGIN( FuncQual ); } */ /*- Function argument reading rules ---------------------------------------*/ [^ \/\r\t\n\)\(\"\']+ { *copyArgString+=yytext; fullArgString+=yytext; } [^\n\\\"\']+ { *copyArgString+=yytext; fullArgString+=yytext; } [^\/\n\)\(\"\']+ { *copyArgString+=yytext; fullArgString+=yytext; } {BN}* { *copyArgString+=" "; fullArgString+=" "; lineCount(); } \" { *copyArgString+=*yytext; fullArgString+=*yytext; lastCopyArgStringContext = YY_START; BEGIN( CopyArgString ); } "(" { *copyArgString+=*yytext; fullArgString+=*yytext; argRoundCount=0; lastCopyArgContext = YY_START; BEGIN( CopyArgRound ); } ")" { *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); BEGIN( currentArgumentContext ); } /* a special comment */ ("/*"[*!]|"//"[/!])("<"?) { fullArgString+=yytext; lastCopyArgChar=0; if (yytext[1]=='/') BEGIN( CopyArgCommentLine ); else BEGIN( CopyArgComment ); } /* `)' followed by a special comment */ ")"{BN}*("/*"[*!]|"//"[/!])"<" { lineCount(); lastCopyArgChar=*yytext; QCString text=&yytext[1]; text=text.stripWhiteSpace(); fullArgString+=text; if (text.find("//")!=-1) BEGIN( CopyArgCommentLine ); else BEGIN( CopyArgComment ); } [^\n\*]+ { fullArgString+=yytext; } "*/" { fullArgString+=yytext; if (lastCopyArgChar!=0) unput(lastCopyArgChar); BEGIN( ReadFuncArgType ); } \n { fullArgString+=yytext; if (lastCopyArgChar!=0) unput(lastCopyArgChar); BEGIN( ReadFuncArgType ); } [^\n]+ { fullArgString+=yytext; } \n { fullArgString+=*yytext; yyLineNr++; } . { fullArgString+=*yytext; } "<" { *copyArgString+=*yytext; fullArgString+=*yytext; argSharpCount=0; BEGIN( CopyArgSharp ); } ">" { *copyArgString+=*yytext; fullArgString+=*yytext; //printf("end template list %s\n",copyArgString->data()); stringToArgumentList(fullArgString,currentArgumentList); BEGIN( currentArgumentContext ); } "(" { argRoundCount++; *copyArgString+=*yytext; fullArgString+=*yytext; } ")" { *copyArgString+=*yytext; fullArgString+=*yytext; if (argRoundCount>0) argRoundCount--; else BEGIN( lastCopyArgContext ); } "<" { argSharpCount++; *copyArgString+=*yytext; fullArgString+=*yytext; } ">" { *copyArgString+=*yytext; fullArgString+=*yytext; if (argRoundCount>0) argRoundCount--; else BEGIN( ReadTempArgs ); } \\. { *copyArgString+=yytext; fullArgString+=yytext; } \" { *copyArgString+=*yytext; fullArgString+=*yytext; BEGIN( lastCopyArgStringContext ); } "'"\\[0-7]{1,3}"'" { *copyArgString+=yytext; fullArgString+=yytext; } "'"\\."'" { *copyArgString+=yytext; fullArgString+=yytext; } "'"."'" { *copyArgString+=yytext; fullArgString+=yytext; } \n { yyLineNr++; *copyArgString+=*yytext; fullArgString+=*yytext; } . { *copyArgString+=*yytext; fullArgString+=*yytext; } /*------------------------------------------------------------------------*/ "(" { current->args += *yytext ; ++roundCount ; } ")" { current->args += *yytext ; if ( roundCount ) --roundCount ; else BEGIN( FuncQual ) ; } /* "#" { lastCPPContext = YY_START; BEGIN(SkipCPP); } */ [{:;] { unput(*yytext); BEGIN( Function ); } {BN}*"const"{BN}* { lineCount() ; current->args += " const "; current->argList->constSpecifier=TRUE; } {BN}*"volatile"{BN}* { lineCount() ; current->args += " volatile "; current->argList->volatileSpecifier=TRUE; } {BN}*"="{BN}*"0"{BN}* { lineCount() ; current->args += " = 0"; current->virt = Pure; current->argList->pureSpecifier=TRUE; } {BN}*","{BN}* { lineCount() ; current->args += ", " ; } {BN}+ { lineCount() ; current->args += ' ' ; } . { current->args += *yytext; } {BN}*"throw"{BN}*"(" { current->exception = " throw (" ; lineCount() ; BEGIN( ExcpRound ) ; } {BN}*"raises"{BN}*"(" { current->exception = " raises (" ; lineCount() ; BEGIN( ExcpRound ) ; } "(" { current->exception += *yytext ; ++roundCount ; } ")" { current->exception += *yytext ; if ( roundCount ) --roundCount ; else BEGIN( FuncQual ) ; } . { current->exception += yytext; } "(" { current->type += current->name ; current->name = current->args ; current->args = yytext ; BEGIN( FuncRound ) ; } "#" { lastCPPContext = YY_START; BEGIN(SkipCPP); } [:;{] { current->name=current->name.simplifyWhiteSpace(); current->type=current->type.simplifyWhiteSpace(); current->args=current->args.simplifyWhiteSpace(); QCString &cn=current->name; QCString &rn=current_root->name; //printf("current_root->name=`%s'\n",rn.data()); //printf("Function: `%s' `%s' `%s'\n",current->type.data(),cn.data(),current->args.data()); int i; if ((i=cn.findRev("::"))!=-1) // name contains scope { if (cn.left(i)==rn.right(i)) // scope name is redundant { cn=cn.right(cn.length()-i-2); // strip scope //printf("new name=`%s'\n",cn.data()); } } //if (cname.left(current_root->name.length()+2)==current_root->name+"::") //{ // strip redundant scope // current->name=current->name.right(current->name.length()-current_root->name.length()-2); // printf("new name=`%s'\n",current->name.data()); //} current->fileName = yyFileName; current->startLine = yyLineNr; if (*yytext!=';' || (current_root->section&Entry::SCOPE_MASK) ) { int tempArg=current->name.find('<'); QCString tempName; if (tempArg==-1) tempName=current->name; else tempName=current->name.left(tempArg); if (current->type.isEmpty() && tempName.find("operator")==-1 && (tempName.find('*')!=-1 || tempName.find('&')!=-1)) { //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", // current->type.data(),current->name.data(),current->args.data()); current->section = Entry::VARIABLE_SEC ; } else { //printf("Scanner.l: found in class function: `%s' `%s' `%s'\n", // current->type.data(),current->name.data(),current->args.data()); current->section = Entry::FUNCTION_SEC ; } } else // a global function prototype or function variable { //printf("Scanner.l: prototype? type=`%s' name=`%s' args=`%s'\n",current->type.data(),current->name.data(),current->args.data()); QRegExp re("([^)]*)"); if (!current->type.isEmpty() && (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef ")) { //printf("Scanner.l: found function variable!\n"); current->section = Entry::VARIABLE_SEC; } else { //printf("Scanner.l: found prototype\n"); current->section = Entry::FUNCTION_SEC; current->proto = TRUE; } } //printf("Adding entry `%s' inLine`%d' bodyLine=`%d'\n", // current->name.data(),current->inLine,current->bodyLine); previous = current; current_root->addSubEntry(current); current = new Entry ; current->protection = protection; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; current->mGrpId = memberGroupId; lastCurlyContext = FindMembers; if( *yytext == '{' ) { if (current_root->section & Entry::COMPOUND_MASK) previous->inLine = TRUE; //addToBody(yytext); curlyCount=0; BEGIN( SkipCurly ) ; } else if( *yytext == ':' ) { //addToBody(yytext); BEGIN( SkipInits ) ; } else { if (previous->section!=Entry::VARIABLE_SEC) previous->bodyLine=-1; // a function/member declaration BEGIN( FindMembers ) ; } } "{" { //addToBody(yytext); lastCurlyContext = FindMembers; curlyCount=0; BEGIN( SkipCurly ) ; } "{" { //addToBody(yytext); ++curlyCount ; } "}" { //addToBody(yytext); if( curlyCount ) { --curlyCount ; } else { previous->endBodyLine=yyLineNr; BEGIN( lastCurlyContext ) ; } } "}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { if ( curlyCount ) { //addToBody(yytext); --curlyCount ; } else { current->endBodyLine=yyLineNr; lineCount(); tempEntry = current; // temporarily switch to the previous entry current = previous; current->doc.resize(0); current->brief.resize(0); lastAfterDocContext = SkipCurlyEndDoc; afterDocTerminator = '}'; if (yytext[yyleng-3]=='/') BEGIN(AfterDocLine); else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag) BEGIN(AfterDocBrief); else BEGIN(AfterDoc); } } "}" { //addToBody("}"); current = tempEntry; BEGIN( lastCurlyContext ); } "'"\\[0-7]{1,3}"'" { //addToBody(yytext); } "'"\\."'" { //addToBody(yytext); } "'"."'" { //addToBody(yytext); } \" { //addToBody(yytext); lastStringContext=SkipCurly; BEGIN( SkipString ); } ^{B}*"#" { //addToBody(yytext); BEGIN( SkipCurlyCpp ); } \n { yyLineNr++; //addToBody(yytext); } [^\n"'\\/{}]+ { //addToBody(yytext); } \n { //addToBody(yytext); yyLineNr++; lastCurlyContext = FindMembers; BEGIN( SkipCurly ); } \\[\r]*"\n"[\r]* { //addToBody(yytext); yyLineNr++; } "/*" { //addToBody(yytext); lastCContext = YY_START; BEGIN(SkipComment); } "//" { //addToBody(yytext); lastCContext = YY_START; BEGIN(SkipCxxComment); } . { //addToBody(yytext); } \\. { //addToBodyCond(yytext); } \" { //addToBodyCond(yytext); BEGIN( lastStringContext ); } "/*"|"*/"|"//" { //addToBodyCond(yytext); } \n { yyLineNr++; //addToBodyCond(yytext); } . { //addToBodyCond(yytext); } ";" { current->section = Entry::EMPTY_SEC ; current->type.resize(0) ; current->name.resize(0) ; current->args.resize(0) ; current->argList->clear(); BEGIN( FindMembers ) ; } {SCOPENAME}{BN}*/"<" { sharpCount = 0; current->name = yytext ; lineCount(); lastClassTemplSpecContext = ClassVar; BEGIN( ClassTemplSpec ); } ">"({BN}*"::"{BN}*{SCOPENAME})? { current->name += yytext; lineCount(); if (--sharpCount<=0) { current->name = removeRedundantWhiteSpace(current->name); BEGIN( lastClassTemplSpecContext ); } } "<" { current->name += yytext; sharpCount++; } . { current->name += yytext; } {SCOPENAME} { current->name = yytext ; lineCount(); BEGIN( ClassVar ); } {ID} { if (insideIDL && strcmp(yytext,"switch")==0) { // Corba IDL style union roundCount=0; BEGIN(SkipUnionSwitch); } else { if (isTypedef) { QCString dest = extractName(current->name); typedefDict.insert(yytext,new QCString(current->name)); //current->extends->append( // new BaseInfo(yytext,Public,Normal) // ); } current->type += ' ' ; current->type += current->name ; current->name = yytext ; //BEGIN( FindMembers ); } } [(\[] { // probably a function anyway unput(*yytext); BEGIN( FindMembers ); } ":" { current->type.resize(0); if (current->section == Entry::INTERFACE_SEC) baseProt=Public; else baseProt=Private; baseVirt=Normal; baseName.resize(0); BEGIN( BasesProt ) ; } [;=*&] { unput(*yytext); if (isTypedef) // typedef of a class, put typedef keyword back { current->type.prepend("typedef"); } BEGIN( FindMembers ); } {B}*"{"{B}* { current->fileName = yyFileName ; current->startLine = yyLineNr ; current->name = removeRedundantWhiteSpace(current->name); if (current->name.isEmpty() && !isTypedef) // anonymous compound current->name.sprintf("@%d",anonCount++); curlyCount=0; BEGIN( Curly ) ; } "virtual" { baseVirt = Virtual; } "public" { baseProt = Public; } "protected" { baseProt = Protected; } "private" { baseProt = Private; } {BN} { lineCount(); } . { unput(*yytext); BEGIN(Bases); } ("::")*{BN}*({ID}{BN}*"::"{BN}*)*{ID} { //current->extends->append( // new BaseInfo(yytext,baseProt,baseVirt) //) ; if (*yytext != ':') baseName += yytext; else baseName += (yytext+2); current->args += ' '; if (*yytext != ':') current->args += yytext; else current->args += (yytext+2); } "<" { current->name += *yytext; sharpCount=1; lastSkipSharpContext = YY_START; specName = ¤t->name; BEGIN ( Specialization ); } "<" { baseName += *yytext; sharpCount=1; lastSkipSharpContext = YY_START; specName = &baseName; BEGIN ( Specialization ); } "<" { *specName += *yytext; sharpCount++; } ">" { *specName += *yytext; if (--sharpCount<=0) BEGIN(lastSkipSharpContext); } {BN}+ { lineCount(); *specName +=' '; } . { *specName += *yytext; } "<" { ++sharpCount; } ">" { if (--sharpCount<=0) BEGIN ( lastSkipSharpContext ); } "(" { ++roundCount; } ")" { if (--roundCount<=0) BEGIN ( lastSkipRoundContext ); } "," { current->args += ',' ; current->name = removeRedundantWhiteSpace(current->name); if (!baseName.isEmpty()) current->extends->append( new BaseInfo(baseName,baseProt,baseVirt) ); if (current->section == Entry::INTERFACE_SEC) baseProt=Public; else baseProt=Private; baseVirt=Normal; baseName.resize(0); BEGIN(BasesProt); } {B}*"{"{B}* { current->fileName = yyFileName ; current->startLine = yyLineNr ; current->name = removeRedundantWhiteSpace(current->name); if (!baseName.isEmpty()) current->extends->append( new BaseInfo(baseName,baseProt,baseVirt) ); curlyCount=0; BEGIN( Curly ) ; } "(" { roundCount++; } ")" { if (--roundCount==0) { BEGIN(ClassVar); } } \n { yyLineNr++; } . {BN}+ { current->program += yytext ; lineCount() ; } "/*" { current->program += yytext ; } "//" { current->program += yytext ; } [^\n\*]+ { current->program += yytext ; } .*"*/" { current->program += yytext ; BEGIN( lastContext ) ; } . { current->program += *yytext ; } ("//"{B}*)?"/*!" { //printf("Start doc block at %d\n",yyLineNr); removeSlashes=(yytext[1]=='/'); tmpDocType=-1; if (YY_START==Curly) current->doc+="\n\n"; else current->doc.resize(0); lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) current->inside = current_root->name+"::"; BEGIN( Doc ); } ("//"{B}*)?"/**"/[^/*] { removeSlashes=(yytext[1]=='/'); lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) current->inside = current_root->name+"::"; if (!Config::autoBriefFlag) // use the Qt style { tmpDocType=-1; if (YY_START==Curly) current->doc+="\n\n"; else current->doc.resize(0); BEGIN( Doc ); } else // Use the javadoc style { if (YY_START==Curly) { tmpDocType=-1; current->doc+="\n\n"; lastDocContext = Curly; BEGIN( Doc ); } else { tmpDocType=Doc; current->doc.resize(0); current->brief.resize(0); BEGIN( JavaDoc ); } } } "//!" { current->brief.resize(0); tmpDocType=-1; lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) current->inside = current_root->name+"::"; BEGIN( LineDoc ); } "///"/[^/] { current->brief.resize(0); tmpDocType=-1; lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) current->inside = current_root->name+"::"; BEGIN( LineDoc ); } "extern"{BN}+"\"C"("++")?"\""{BN}*("{")? "{" { current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); curlyCount=0; BEGIN( SkipCurlyBlock ); } {CMD}("brief"|"short"){B}+ { lastBriefContext=tmpDocType; BEGIN( ClassDocBrief ); } ^(({B}*"*"+)?){BL} { lineCount(); if (!current->brief.stripWhiteSpace().isEmpty()) { BEGIN( tmpDocType ); } } /* "@" { unput(*yytext); BEGIN(ClassDoc); } */ ^{B}*"*"+/[^/] { //printf("---> 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 ); } {CMD}("image"|"author"|"internal"|"version"|"date"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note") { current->doc+=yytext; BEGIN( tmpDocType ); } "<"{TABLE}{ATTR}">" { current->doc+=yytext; int i; for (i=yyleng-1;i>=0;i--) { unput(yytext[i]); } BEGIN( tmpDocType ); } {B}*{CMD}("fn"|"var"|"typedef"){B}* { current->section = Entry::MEMBERDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocFunc ); } {B}*{CMD}"def"{B}+ { nextDefContext = YY_START==LineDoc ? DefLineDoc : ClassDoc; current->section = Entry::DEFINEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocDefine ); } {B}*{CMD}"overload"{B}* { overloadContext = YY_START; BEGIN( ClassDocOverload ); } {B}*/"\n" { QCString orgDoc = current->doc; current->doc = getOverloadDocs(); current->doc += "\n\n"; current->doc += orgDoc; BEGIN( overloadContext ); } {B}*/"*/" { QCString orgDoc = current->doc; current->doc = getOverloadDocs(); current->doc += "\n\n"; current->doc += orgDoc; BEGIN( overloadContext ); } . { unput(*yytext); current->section = Entry::OVERLOADDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocFunc ); } {B}*{CMD}"enum"{B}* { current->section = Entry::ENUMDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( EnumDocArg1 ); } {B}*{CMD}"defgroup"{B}* { current->section = Entry::GROUPDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( GroupDocArg1 ); } {B}*{CMD}"namespace"{B}* { current->section = Entry::NAMESPACEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( NameSpaceDocArg1 ); } {B}*{CMD}"class"{B}* { current->section = Entry::CLASSDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*{CMD}"union"{B}* { current->section = Entry::UNIONDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*{CMD}"struct"{B}* { current->section = Entry::STRUCTDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*{CMD}"interface"{B}* { current->section = Entry::INTERFACEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*{CMD}"idlexcept"{B}* { current->section = Entry::EXCEPTIONDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ClassDocArg1 ); } {B}*{CMD}"page"{B}* { current->section = Entry::PAGEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( PageDocArg1 ); } {B}*{CMD}"mainpage"{B}* { current->section = Entry::MAINPAGEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( PageDocArg2 ); } {B}*{CMD}"file"{B}* { current->section = Entry::FILEDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( FileDocArg1 ); } {B}*{CMD}"example"{B}* { current->section = Entry::EXAMPLE_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; BEGIN( ExampleDocArg1 ); } {CMD}"name"{B}+ { //printf("--> mgroup found!\n"); current->section = Entry::MEMBERGRP_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; //lastMemberGroupContext = lastDocContext; //lastDocContext = StoreGroupDocs; memberGroupHeader.resize(0); memberGroupDocs.resize(0); BEGIN(GroupHeader); } {FILE} { current->name = stripQuotes(yytext); BEGIN( ExampleDoc ); } {B}*{CMD}"relate"[sd]{B}* { lastDocRelContext = YY_START; BEGIN( ClassDocRelates ); } {ID} { current->relates = yytext; BEGIN( lastDocRelContext ); } {SCOPENAME} { current->name = yytext; newDocState(); } "\\"{B}*"\n" { yyLineNr++; } "\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+"::"); } lastClassTemplSpecContext = ClassDocArg2; BEGIN( ClassTemplSpec ); } {SCOPENAME} { current->name = yytext; // prepend outer scope name if (current_root->section & Entry::SCOPE_MASK) { current->name.prepend(current_root->name+"::"); } BEGIN( ClassDocArg2 ); } "\\"{B}*"\n" { yyLineNr++; } "\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); } "\\"{B}*"\n" { yyLineNr++; } "\n" { warn("Warning: missing argument after " "\\defgroup at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; BEGIN( Doc ); } [^\n\*]+ { current->type += yytext; current->type = current->type.stripWhiteSpace(); } . { current->type += yytext; } "\\"{B}*"\n" { yyLineNr++; } "*/" { unput('/');unput('*'); newDocState(); } "\n" { newDocState(); } {FILE} { //printf("ClassDocArg2=%s\n",yytext); current->includeFile = stripQuotes(yytext); BEGIN( ClassDocArg3 ); } "\\"{B}*"\n" { yyLineNr++; } "\n" { yyLineNr++; newDocState(); } [<]?{FILE}[>]? { //printf("ClassDocArg3=%s\n",yytext); current->includeName = yytext; newDocState(); } "\\"{B}*"\n" { yyLineNr++; } "\n" { yyLineNr++; newDocState(); } {FILE} { current->name = stripQuotes(yytext); newDocState(); } "\\"{B}*"\n" { yyLineNr++; } "\n" { current->name = yyFileName; yyLineNr++; newDocState(); } {FILE} { current->name = stripQuotes(yytext); BEGIN( PageDocArg2 ); } "\\"{B}*"\n" { yyLineNr++; } "\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(); } "\\"{B}*"\n" { yyLineNr++; } "\n" { warn("Warning: missing argument after " "\\enum at line %d of %s.\n",yyLineNr,yyFileName); yyLineNr++; BEGIN( Doc ); } {CMD}"refitem".*"\n" { current->doc+=yytext; } {CMD}"section"{B}+ { sectionType=SectionInfo::Section; BEGIN(SectionLabel); } {CMD}"subsection"{B}+ { sectionType=SectionInfo::Subsection; BEGIN(SectionLabel); } . { memberGroupHeader+=*yytext; } "*/" { unput('/');unput('*'); //printf("Found memberGroup=`%s'\n",memberGroupHeader.data()); newDocState(); } \n { yyLineNr++; //printf("Found memberGroup=`%s'\n",memberGroupHeader.data()); newDocState(); } "$" { //printf("StoreGroupDocs memberGroupId=%d brief=`%s' doc=`%s'!\n",memberGroupId,current->brief.data(),current->doc.data()); memberGroupDocs=current->brief.stripWhiteSpace(); current->doc = current->doc.stripWhiteSpace(); if (!memberGroupDocs.isEmpty() && !current->doc.isEmpty()) { memberGroupDocs+="\n\n"; } memberGroupDocs+=current->doc; current->doc.resize(0); current->brief.resize(0); BEGIN(lastDocContext); } {CMD}"anchor"{B}+ { lastAnchorContext = YY_START; sectionType=SectionInfo::Anchor; BEGIN(AnchorLabel); } ("\\\\"|"@@")"verbatim"/[^a-z_A-Z0-9] { current->doc+="\\\\verbatim"; } {CMD}"verbatim"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->doc+="\\verbatim"; BEGIN(SkipVerbatim); } {CMD}"addindex"{B}+[^\n]+ { current->doc+=yytext; } ("\\\\"|"@@")"code"/[^a-z_A-Z0-9] { current->doc+="\\\\code"; } {CMD}"code"/[^a-z_A-Z0-9] { lastCodeState=YY_START; current->doc+="\\code"; BEGIN(SkipCode); } "<"{PRE}{ATTR}">" { lastCodeState=YY_START; current->doc+="
";
					  BEGIN(SkipCode);
  					}
{CMD}"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;
  					}
{CMD}"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; } "//" { current->brief += yytext; } ("\\\\"|"@@")"f"[$\[\]] { current->doc += &yytext[1]; } {CMD}"f$" { lastFormulaContext = YY_START; formulaText="$"; BEGIN(ReadFormulaShort); } {CMD}"f[" { lastFormulaContext = YY_START; formulaText="\\["; BEGIN(ReadFormulaLong); } {CMD}"f$" { formulaText+="$"; if (lastFormulaContext==ClassDocBrief || lastFormulaContext==LineDoc || lastFormulaContext==JavaDoc ) current->brief += addFormula(); else current->doc += addFormula(); BEGIN(lastFormulaContext); } {CMD}"f]" { formulaText+="\\]"; if (lastFormulaContext==ClassDocBrief || lastFormulaContext==LineDoc || lastFormulaContext==JavaDoc ) current->brief += addFormula(); else current->doc += addFormula(); BEGIN(lastFormulaContext); } . { formulaText+=*yytext; } {B}*"*/" { checkDocs(); //printf("current->section=%x\n",current->section); if (YY_START==SkipCode) // premature end of code block { err("Error: comment block ended inside \\code ... \\endcode block at line %d in %s!\n", yyLineNr,yyFileName); current->doc += "\\endcode\n\n"; BEGIN( lastDocContext ); } else if (YY_START==ClassDocBrief && lastBriefContext==Doc) { current->doc += "\n\n"; BEGIN( lastDocContext ); } else if (current->section==Entry::MEMBERGRP_SEC) { unput('$'); BEGIN( StoreGroupDocs ); } 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; current->mGrpId = memberGroupId; BEGIN( FindMembers ); } } "<"{TITLE}">" { current->args.resize(0); current->argList->clear(); BEGIN( PageDocTitle); } \n { yyLineNr++; current->args+=" "; } [^\n\<] { current->args+=yytext; } "" { BEGIN( PageDoc ); } {CMD}"ingroup"{B}+ { lastGroupContext = YY_START; lineCount(); BEGIN( GroupName ); } {ID} { current->groups->append( new QCString(yytext) ); } \n { yyLineNr++; BEGIN( lastGroupContext ); } {B}*{CMD}("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(); if (!current->doc.isEmpty()) current->doc+="

"; yyLineNr++; BEGIN( lastBriefContext ); } "\n" { yyLineNr++ ; current->brief += " "; } "<"{BR}{ATTR}">" {BS}/{CMD}"ingroup" { current->brief=current->brief.stripWhiteSpace(); BEGIN( lastBriefContext ); } {BS}/{CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see") { BEGIN( lastBriefContext ); } {BS}/{CMD}("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; } "\\"{B}*"\n" { yyLineNr++; } "\n" { yyLineNr++; current->name = current->name.stripWhiteSpace(); if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty()) current->section = Entry::VARIABLEDOC_SEC; newDocState(); } "operator"{B}*"("{B}*")" { current->name+=yytext; } "(" { current->args+=*yytext; currentArgumentContext = ClassDocFuncQual; fullArgString = current->args.copy(); copyArgString = ¤t->args; BEGIN( ReadFuncArgType ) ; } "("({B}*"*")+ { current->name+="(*"; BEGIN( ClassDocFuncPtr ); } {SCOPENAME} { current->name+=yytext; } ")" { current->name+=')'; BEGIN( ClassDocFunc ); } "{" { BEGIN( ClassDocFuncSkipLine); } {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(); } [a-z_A-Z0-9]+ { current->doc += yytext; } ("\\\\"|"@@") { current->doc += yytext; } . { current->doc += *yytext; } . { current->brief += *yytext; } \n { yyLineNr++; current->doc += *yytext; } [\n\r]+{B}*"//"[!/] { lineCount(); } \n { yyLineNr++; BEGIN( lastDocContext ); } \n { yyLineNr++; unput('/');unput('*'); BEGIN( ClassDoc ); } "/*"|"//" { current->brief+=yytext; } \n { yyLineNr++; if (afterDocTerminator!=0) unput(afterDocTerminator); BEGIN(lastAfterDocContext); } \n{B}*("//!<"|"///<") { yyLineNr++; BEGIN(AfterDocLine); } \n{B}*("/*!<"|"/**<") { yyLineNr++; BEGIN(AfterDoc); } . { 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); } {CMD}"internal" { current->brief+="\\internal"; } {CMD}"internal" { current->doc+="\\internal"; } {CMD}"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 ); } "*/" { checkDocs(); current->doc += "\n\n"; //printf("End of docs at line %d\n",yyLineNr); BEGIN( lastDocContext ); } "*/" { unput('/');unput('*'); BEGIN( tmpDocType ); } ^{B}*(("//"{B}*)?)"*"+[ \t]*"-"{B}+ { current->doc += yytext; } ^{B}*(("//"{B}*)?)"*"+/[^/] ^{B}*(("//"{B}*)?)"*"+{B}+ { current->doc+=' '; } "/*" { current->doc += yytext; } .*/\n { BEGIN( lastCContext ) ; } [^\*\n]+ <*>\n { yyLineNr++ ; } <*>\" { if (insideIDL && insideCppQuote) { BEGIN(EndCppQuote); } } <*>. "//"|"/*" <*>"/*" { lastCContext = YY_START ; BEGIN( SkipComment ) ; } {B}*"*/" { BEGIN( lastCContext ) ; } <*>"//" { lastCContext = YY_START ; BEGIN( SkipCxxComment ) ; } %% //---------------------------------------------------------------------------- //static void addToBody(const char *text) //{ // if (Config::includeSourceFlag) // previous->body+=text; //} //static void addToBodyCond(const char *text) //{ // if (Config::includeSourceFlag && lastStringContext==SkipCurly) // previous->body+=text; //} //---------------------------------------------------------------------------- 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.isEmpty()) { //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 ; //printf("---> Inner block starts at line %d\n",yyLineNr); //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.isEmpty() && ce->name.at(0)=='@') // anonymous union current->protection = protection = ce->protection; else // named struct, union, or interface current->protection = protection = Public ; sig = FALSE; slot = FALSE; gstat = FALSE; virt = Normal; current->mGrpId = memberGroupId = ce->mGrpId; scanYYlex() ; delete current; current=0; 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; inputPosition = 0; ifCount=0; scanYYrestart( scanYYin ); BEGIN( FindMembers ); scanYYlex(); rt->program.resize(0); delete current; current=0; parseCompounds(rt); } //---------------------------------------------------------------------------- void parseDocument(OutputList &ol,const QCString &docString) { //inParamBlock=inSeeBlock=inReturnBlock=FALSE; curTable = 0; depthIf = 0; outDoc = new OutputList(&ol); currentIncludeFile.resize(0); includeFileOffset=0; includeFileLength=0; currentListIndentLevel=0; if (!docString) return; linkRef = ""; linkText = ""; inputString = docString; inputPosition = 0; scanYYrestart( scanYYin ); BEGIN( DocScan ); insideArgumentList = FALSE; scanYYlex(); if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); } if (insideItemList) { forceEndItemList(); } if (inBlock()) endBlock(); if (currentListIndentLevel!=0) { if (!refName.isEmpty()) { warn("Warning: Documentation block of %s ended in the middle " "of a list (indent level %d)!\n",refName.data(), currentListIndentLevel); } else if (!exampleName.isEmpty()) { warn("Warning: Documentation block of %s ended in the middle " "of a list (indent level %d)!\n",exampleName.data(), currentListIndentLevel); } else { warn("Warning: Documentation block ended in the middle " "of a list (indent level %d)!\n",currentListIndentLevel); } } if (depthIf!=0) { warn("Warning: Documentation block contains \\if without matching \\endif: %d\n",depthIf); } if (!tableStack.isEmpty()) { forceEndTable(); } ol+=*outDoc; delete outDoc; outDoc=0; return; } //---------------------------------------------------------------------------- void parseDoc(OutputList &ol,const char *clName, const char *memName,const QCString &docString) { //printf("Doc---------\n%s\n---------\n",docString.data()); initParser(); initParseCodeContext(); exampleDoc=FALSE; // do not cross reference with member docs className=clName; memberName=memName; if (memName) { refName=className+"::"+memberName; } else if (clName) { refName=className; } else { refName=""; } parseDocument(ol,docString); } //---------------------------------------------------------------------------- void parseText(OutputList &ol,const QCString &txtString) { if (txtString.isEmpty()) return; inputString = txtString; outDoc = new OutputList(&ol); inputPosition = 0; scanYYrestart( scanYYin ); BEGIN( Text ); scanYYlex(); ol+=*outDoc; delete outDoc; outDoc=0; return; } //---------------------------------------------------------------------------- void parseExample(OutputList &ol,const QCString &docString, const char *fileName) { initParser(); initParseCodeContext(); exampleDoc=TRUE; // cross reference with member docs exampleName=fileName; refName="example "+exampleName; parseDocument(ol,docString); } //---------------------------------------------------------------------------- extern "C" { // some bogus code to keep the compiler happy void scannerYYdummy() { yy_flex_realloc(0,0); } }