/****************************************************************************** * * $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 "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" #ifndef WIN32 #include #endif #define YY_NEVER_INTERACTIVE 1 MemberGroupDict memberGroupDict(1009); // dictionary of the member groups heading /* ----------------------------------------------------------------- * * 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 lastCodeState; static int lastAfterDocContext; static int lastGroupContext; static int lastMemberGroupContext; static int lastFormulaContext; static int lastAnchorContext; static int nextDefContext; static int overloadContext; 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 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 = -1; 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 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; // 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 QCString *copyArgString; static ArgumentList *currentArgumentList; static QCString *currentTemplateSpec; //----------------------------------------------------------------------------- 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; memberGroupId = -1; 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 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 ( 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) { QCString 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 int newMemberGroupId() { static int curGroupId=0; return curGroupId++; } 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); //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 void addToBody(const char *text); static void addToBodyCond(const char *text); /* ----------------------------------------------------------------- */ #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] %option noyywrap %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 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 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 GroupDocArg1 %x GroupDocArg2 %x GroupName %x GroupHeader %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 SkipTemplate %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 if (memberGroupId!=-1) { warn("Warning: Missing \\endmgroup in file %s\n",yyFileName); memberGroupId=-1; } 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(); } */ " 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="<"; copyArgString=&templateStr; currentArgumentContext = FindMembers; //printf("Start template list\n"); BEGIN( ReadTempArgs ); } /* for now the using statement is completely ignored */ "using"{BN}+ { lineCount(); BEGIN(Using); } ";" { BEGIN(FindMembers); } {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; 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} { lineCount(); if (YY_START==FindMembers) { addType( current ) ; current->name = yytext; } else { current->name += yytext; } QCString tmp=yytext; if (tmp.right(8)=="operator") BEGIN( Operator ); else BEGIN(FindMembers); } {B}*"#" { lastCPPContext = YY_START; BEGIN( SkipCPP ) ; } {B}*"#"{B}*"define" { BEGIN( Define ); } . \\[\r]*"\n"[\r]* { yyLineNr++ ; } [\r]*\n[\r]* { yyLineNr++ ; BEGIN( lastCPPContext) ; } {ID}/"(" { 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->name = yytext; BEGIN(DefineEnd); } \n { //printf("End define\n"); 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; BEGIN(FindMembers); } \\\n . [*&]+ { current->name += yytext ; } ";"{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; 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); } } "=" { BEGIN(NextSemi); } [:;,] { QCString oldType = current->type.copy(); QCString oldDocs = current->doc.copy(); if ( *yytext != ':') { current->type=current->type.simplifyWhiteSpace(); current->args=current->args.simplifyWhiteSpace(); current->name=current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC ; current->fileName = yyFileName; current->startLine = yyLineNr; 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; } // 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 ) ; } } "[" { current->args += yytext ; sharpCount=1; BEGIN( Array ) ; } "]" { current->args += *yytext ; if (--sharpCount<=0) BEGIN( FindMembers ) ; } "[" { current->args += *yytext ; sharpCount++; } . { current->args += *yytext ; } "<" { 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; } "=" { BEGIN(FindFieldArg); } "," { //printf("adding `%s' `%s' `%s' to enum `%s'\n", // current->type.data(), current->name.data(), // current->args.data(), current_root->name.data()); 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; } "," { 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 ; ++bracketCount ; } "}" { if ( bracketCount ) { current->program += yytext ; --bracketCount ; } else { QCString &cn = current->name; QCString rn = stripAnnonymousScope(current_root->name); //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) { // a namespace ends with a closing bracket current->reset(); current->protection = protection ; current->sig = sig; current->virt = virt; current->stat = gstat; current->slot = slot; 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; 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.length()>0) { 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.length()>0 && 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(); //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; BEGIN( FindMembers ); } } "=" { BEGIN(MemberSpecSkip); } "{" { bracketCount=0; lastCurlyContext = MemberSpecSkip; previous = current; BEGIN(SkipCurly); } "," { BEGIN(MemberSpec); } ";" { unput(';'); BEGIN(MemberSpec); } {BN}+ { current->program += yytext ; lineCount() ; } . { current->program += yytext ; } "("({ID}{BN}*"::"{BN}*)*("*"{BN}*)+ { 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); } "(" { // a function returning a function current->args += *yytext ; bracketCount=0; BEGIN( FuncFunc ); } ")" { BEGIN(FindMembers); } "(" { current->args += *yytext ; ++bracketCount; } ")" { current->args += *yytext ; if ( bracketCount ) --bracketCount; 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; bracketCount++; } ")" { current->type += *yytext; if (bracketCount) --bracketCount; else BEGIN(Function); } {BN}*","{BN}* { lineCount() ; current->type += ", " ; } {BN}+ { lineCount() ; current->type += ' ' ; } . { current->type += *yytext; } "(" { current->args = yytext; currentArgumentContext = FuncQual; 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; } [^\n\\\"\']+ { *copyArgString+=yytext; } [^\/\n\)\(\"\']+ { *copyArgString+=yytext; } {BN}* { *copyArgString+=" "; lineCount(); } \" { *copyArgString+=*yytext; lastCopyArgStringContext = YY_START; BEGIN( CopyArgString ); } "(" { *copyArgString+=*yytext; argRoundCount=0; lastCopyArgContext = YY_START; BEGIN( CopyArgRound ); } ")" { *copyArgString+=*yytext; stringToArgumentList(*copyArgString,current->argList); BEGIN( currentArgumentContext ); } "<" { *copyArgString+=*yytext; argSharpCount=0; BEGIN( CopyArgSharp ); } ">" { *copyArgString+=*yytext; //printf("end template list %s\n",copyArgString->data()); stringToArgumentList(*copyArgString,currentArgumentList); BEGIN( currentArgumentContext ); } "(" { argRoundCount++; *copyArgString+=*yytext; } ")" { *copyArgString+=*yytext; if (argRoundCount>0) argRoundCount--; else BEGIN( lastCopyArgContext ); } "<" { argSharpCount++; *copyArgString+=*yytext; } ">" { *copyArgString+=*yytext; if (argRoundCount>0) argRoundCount--; else BEGIN( ReadTempArgs ); } \\. { *copyArgString+=yytext; } \" { *copyArgString+=*yytext; BEGIN( lastCopyArgStringContext ); } "'"\\[0-7]{1,3}"'" { *copyArgString+=yytext; } "'"\\."'" { *copyArgString+=yytext; } "'"."'" { *copyArgString+=yytext; } \n { yyLineNr++; *copyArgString+=*yytext; } . { *copyArgString+=*yytext; } /*------------------------------------------------------------------------*/ "(" { current->args += *yytext ; ++bracketCount ; } ")" { current->args += *yytext ; if ( bracketCount ) --bracketCount ; 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 ) ; } "(" { current->exception += *yytext ; ++bracketCount ; } ")" { current->exception += *yytext ; if ( bracketCount ) --bracketCount ; 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.isNull() && 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.isNull() && current->type.find(re,0)!=-1) { //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' groupId=%d groupHeader=`%s'\n", // current->name.data(),current->mGrpId,current->mGrpId!=-1 ? // memberGroupDict[current->mGrpId]->header().data() : ""); 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 == '{' ) { addToBody(yytext); BEGIN( SkipCurly ) ; } else if( *yytext == ':' ) { addToBody(yytext); BEGIN( SkipInits ) ; } else BEGIN( FindMembers ) ; } "{" { addToBody(yytext); lastCurlyContext = FindMembers; BEGIN( SkipCurly ) ; } "{" { addToBody(yytext); ++bracketCount ; } "}" { addToBody(yytext); if( bracketCount ) --bracketCount ; else BEGIN( lastCurlyContext ) ; } "}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { if ( bracketCount ) { addToBody(yytext); --bracketCount ; } else { 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); } . { addToBody(yytext); } \n { addToBody(yytext); yyLineNr++; lastCurlyContext = FindMembers; BEGIN( SkipCurly ); } \\[\r]*"\n"[\r]* { addToBody(yytext); yyLineNr++; } "/*" { addToBody(yytext); } "*/" { addToBody(yytext); } "//".* { addToBody(yytext); } . { 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} { current->name = yytext ; BEGIN( ClassVar ); } /* {ID}/{BN}*"{" { // we probably got some M$ extension current->name = yytext ; } {ID}/{BN}*":" { // we probably got some M$ extension current->name = yytext ; } */ {ID} { if (isTypedef) { typedefDict.insert(yytext,new QCString(current->name)); current->type.prepend("typedef "); } current->type += ' ' ; current->type += current->name ; current->name = yytext ; //BEGIN( FindMembers ); } [(\[] { // probably a function anyway unput('('); BEGIN( FindMembers ); } ":" { current->type.resize(0); if (current->section == Entry::INTERFACE_SEC) baseProt=Public; else baseProt=Private; baseVirt=Normal; baseName.resize(0); BEGIN( Bases ) ; } [;=*&] { unput(*yytext); BEGIN( FindMembers ); } {B}*"{"{B}* { current->fileName = yyFileName ; current->startLine = yyLineNr ; current->name = removeRedundantWhiteSpace(current->name); if (current->name.length()==0 && !isTypedef) // anonymous compound current->name.sprintf("@%d",anonCount++); BEGIN( Curly ) ; } "virtual" { baseVirt = Virtual; } "public" { baseProt = Public; } "protected" { baseProt = Protected; } "private" { baseProt = Private; } ({ID}{BN}*"::"{BN}*)*{ID} { //current->extends->append( // new BaseInfo(yytext,baseProt,baseVirt) //) ; baseName += yytext; current->args += ' ' ; current->args += yytext ; } "<" { 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.length()>0) current->extends->append( new BaseInfo(baseName,baseProt,baseVirt) ); baseProt=Private; baseVirt=Normal; baseName.resize(0); } {B}*"{"{B}* { current->fileName = yyFileName ; current->startLine = yyLineNr ; current->name = removeRedundantWhiteSpace(current->name); if (baseName.length()>0) current->extends->append( new BaseInfo(baseName,baseProt,baseVirt) ); BEGIN( Curly ) ; } {BN}+ { current->program += yytext ; lineCount() ; } "/*" { current->program += yytext ; } "//" { current->program += yytext ; } [^\n\*]+ { current->program += yytext ; } .*"*/" { current->program += yytext ; BEGIN( Curly ) ; } . { current->program += *yytext ; } ("//"{B}*)?"/*!" { 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(); bracketCount=0; BEGIN( SkipCurlyBlock ); } "@short"{B}+ { lastBriefContext=Doc; BEGIN( ClassDocBrief ); } ^(({B}*"*"+)?){BL} { lineCount(); if (!current->brief.stripWhiteSpace().isEmpty()) { BEGIN( tmpDocType ); } } "@" { unput(*yytext); BEGIN(Doc); } ^{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 ); } ("\\"|"@")"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}* { 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}*("\\"|"@")"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}*("\\"|"@")"interface"{B}* { current->section = Entry::INTERFACEDOC_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); } ("\\"|"@")mgroup{B}+ { //printf("--> mgroup found!\n"); lastMemberGroupContext = YY_START; if (memberGroupId!=-1) { warn("Warning: ignoring nested mgroup command " "at line %d of %s. Previous command was found at line %d\n", yyLineNr,yyFileName,lastMemberGroupLine); } else { memberGroupId = newMemberGroupId(); current->mGrpId = memberGroupId; lastMemberGroupLine = yyLineNr; } BEGIN(GroupHeader); } ("\\"|"@")endmgroup/[^a-z_A-Z0-9] { //printf("--> endmgroup found!\n"); memberGroupId = -1; current->mGrpId = -1; } [^\n]*/"\n" { QCString header = ((QCString)yytext).stripWhiteSpace(); memberGroupDict.insert(memberGroupId, new MemberGroup(memberGroupId,header) ); BEGIN(lastMemberGroupContext); } ("\\"|"@")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; } "*/" { checkDocs(); 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 QCString(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(); } "operator"{B}*"("{B}*")" { current->name+=yytext; } "(" { current->args+=*yytext; currentArgumentContext = ClassDocFuncQual; 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(); } . { current->doc += *yytext; } . { current->brief += *yytext; } \n { yyLineNr++; current->doc += *yytext; } [\n\r]{B}*"//"[!/] \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 ); } "*/" { checkDocs(); 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 ) ; } %% //---------------------------------------------------------------------------- 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.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, union, or interface 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 QCString &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 QCString &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 QCString &txtString) { inputString = txtString; outDoc = new OutputList(&ol); inputPosition = 0; scanYYrestart( scanYYin ); BEGIN( Text ); scanYYlex(); if (memberGroupId!=-1) { warn("Warning: Missing \\endmgroup in file %s\n",yyFileName); memberGroupId=-1; } ol+=*outDoc; delete outDoc; return; } //---------------------------------------------------------------------------- void parseExample(OutputList &ol,const QCString &docString, const char *fileName) { initParser(); initParseCodeContext(); exampleDoc=TRUE; // cross reference with member docs exampleName=fileName; parseDocument(ol,docString); } //---------------------------------------------------------------------------- extern "C" { // some bogus code to keep the compiler happy void scannerYYdummy() { yy_flex_realloc(0,0); } }