/***************************************************************************** * * * * Copyright (C) 1997-2001 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 #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" #include "reflist.h" #include "code.h" #define YY_NEVER_INTERACTIVE 1 /* ----------------------------------------------------------------- * * statics */ 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 lastSkipHtmlCommentContext; static int lastIfContext; 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 padCount = 0 ; static int todoStartContext = 0; static QCString todoString; static int testStartContext = 0; static QCString testString; static int bugStartContext = 0; static QCString bugString; 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 = 1 ; static int anonCount = 0 ; static char yyFileName[4096] ; static int lastMemberGroupLine; static MethodTypes mtype; static bool gstat; static bool removeSlashes; static Specifier virt; static Specifier baseVirt; static QCString msType,msName,msArgs; static int memberGroupId = NOGROUP; static QCString memberGroupHeader; static QCString memberGroupDocs; static bool isTypedef; static char afterDocTerminator; static int tmpDocType; static QCString sectionLabel; static QCString sectionTitle; static SectionInfo::SectionType sectionType; static QCString funcPtrType; static QCString templateStr; static QCString aliasName; static QCString baseName; static QCString* specName; static QCString formulaText; static bool insideIDL = FALSE; static bool insideJava = FALSE; static bool insideCppQuote = FALSE; static int argRoundCount; static int argSharpCount; static int currentArgumentContext; static int lastCopyArgStringContext; static int lastCopyArgContext; static QCString *copyArgString; static QCString fullArgString; static ArgumentList *currentArgumentList; static QCString *currentTemplateSpec; static char lastCopyArgChar; static QCString *pCopyRoundString; static QCString *pCopyCurlyString; static QCString *pCopyQuotedString; static QCString *pSkipDoc; static QStack autoGroupStack; static Grouping lastDefGroup( "", Grouping::GROUPING_LOWEST ); static bool insideFormula; static bool insideTryBlock=FALSE; static int depthIf; //----------------------------------------------------------------------------- static void initParser() { sectionLabel.resize(0); sectionTitle.resize(0); baseName.resize(0); formulaText.resize(0); protection = Public; baseProt = Public; sharpCount = 0; roundCount = 0; curlyCount = 0; memberGroupId = NOGROUP; mtype = Method; gstat = FALSE; virt = Normal; baseVirt = Normal; isTypedef = FALSE; autoGroupStack.clear(); insideTryBlock = FALSE; insideIDL = FALSE; autoGroupStack.setAutoDelete(TRUE); lastDefGroup.groupname.resize(0); } static void initEntry() { current->protection = protection ; current->mtype = mtype; current->virt = virt; current->stat = gstat; current->mGrpId = memberGroupId; if (!autoGroupStack.isEmpty()) { current->groups->append(new Grouping(*autoGroupStack.top())); } } //----------------------------------------------------------------------------- /// remove any automatic grouping and add new one (if given) static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri ) { /* remove auto group name from current entry and discard it */ Grouping *g = current->groups->first(); int i=0; while (g) { if (g->pri <= Grouping::GROUPING_AUTO_DEF) { current->groups->remove(i); i--; } g=current->groups->next(); i++; } /* use new group name instead? */ if ( newgroup ) { current->groups->append(new Grouping(*newgroup, pri)); } } static int newMemberGroupId() { static int curGroupId=0; return curGroupId++; } static void startGroup(); static void endGroup(); //----------------------------------------------------------------------------- static void lineCount() { for( const char* c = yytext ; *c ; ++c ) yyLineNr += (*c == '\n') ; } 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 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 void newDocState(); //----------------------------------------------------------------- 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 (Doxygen::sectionDict.find(sectionLabel)==0) { SectionInfo *si=new SectionInfo(sectionLabel,sectionTitle,sectionType); si->fileName = current->name; //printf("Adding section addr=%p label=`%s' sectionTitle=`%s' fileName=%s\n",si,sectionLabel.data(),sectionTitle.data(),si->fileName.data()); Doxygen::sectionDict.insert(sectionLabel,si); current->anchors->append(new QCString(sectionLabel)); } else { warn(yyFileName,yyLineNr, "Warning: Duplicate label %s found!",sectionLabel.data()); } sectionTitle.resize(0); } // 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=Doxygen::formulaDict[fText])==0) { f = new Formula(fText); Doxygen::formulaList.append(f); Doxygen::formulaDict.insert(fText,f); formLabel.sprintf("\\form#%d",f->getId()); Doxygen::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 checkFormula() { if (insideFormula) { warn(yyFileName,yyLineNr,"Warning: End of comment block while inside formula."); } } static void checkDocs() { checkFormula(); 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(yyFileName,yyLineNr,"Warning: Found lonely '<' symbol at the start of the documentation."); } } #if 0 static QCString extractName(const QCString &s) { //static const QRegExp id("[a-z_A-Z][a-z_A-Z0-9]*"); //int i,p=0,l; //while ((i=id.match(s,p,&l))!=-1) //{ // QCString idstr=s.mid(i,l); // if (idstr!="struct" && idstr!="class" && idstr!="union") // { // // return idstr; // } // p=i+l; //} //return ""; QCString result=s; if (result.left(7)=="struct ") result=result.right(result.length()-7); if (result.left(6)=="class " ) result=result.right(result.length()-6); if (result.left(6)=="union " ) result=result.right(result.length()-6); int l=result.length()-1; while (l>=0 && (result.at(l)=='*' || result.at(l)==' ' || isspace(result.at(l))) ) l--; return removeRedundantWhiteSpace(result.left(l+1)); } #endif static void setContext() { QCString fileName = yyFileName; insideIDL = fileName.right(4)==".idl"; insideJava = fileName.right(5)==".java"; } static void prependScope() { if (current_root->section & Entry::SCOPE_MASK) { //printf("--- prependScope %s to %s\n",current_root->name.data(),current->name.data()); current->name.prepend(current_root->name+"::"); if (current_root->tArgLists) { if (current->tArgLists==0) { current->tArgLists = new QList; current->tArgLists->setAutoDelete(TRUE); } //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count()); QListIterator talsi(*current_root->tArgLists); ArgumentList *srcAl=0; for (talsi.toLast();(srcAl=talsi.current());--talsi) { ArgumentList *dstAl = new ArgumentList; dstAl->setAutoDelete(TRUE); QListIterator tali(*srcAl); Argument *a; for (;(a=tali.current());++tali) { dstAl->append(new Argument(*a)); //printf("appending argument %s %s\n",a->type.data(),a->name.data()); } current->tArgLists->insert(0,dstAl); } } } } /* ----------------------------------------------------------------- */ #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; } %} CMD ("\\"|"@") SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"ingroup"|"latexonly"|"htmlonly"|"{"|"verbatim") BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] BS ^(({B}*"//")?)(({B}*"*"+)?){B}* FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+] FILEECHAR [a-z_A-Z0-9\-\+] FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"") ID [a-z_A-Z][a-z_A-Z0-9]* LABELID [a-z_A-Z][a-z_A-Z0-9\-]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) ATTR ({B}+[^>\n]*)? A [aA] BR [bB][rR] PRE [pP][rR][eE] TABLE [tT][aA][bB][lL][eE] P [pP] UL [uU][lL] OL [oO][lL] DL [dD][lL] TITLE [tT][iI][tT][lL][eE] %option noyywrap %x Define %x DefineArg %x DefineEnd %x CompoundName %x ClassVar %x ClassTemplSpec %x Bases %x BasesProt %x NextSemi %x BitFields %x FindMembers %x FindMemberName %x FindFields %x FindFieldArg %x Function %x FuncRound %x ExcpRound %x FuncQual %x Operator %x Array %x ReadBody %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 SkipSection %x IfGuard %x IfNotGuard %x TypedefName %x TryFunctionBlock %x TryFunctionBlockEnd %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 DocBaseClass %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 TodoParam %x TestParam %x BugParam %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 SkipHtmlComment %x ReadFormulaShort %x ReadFormulaLong %x AnchorLabel %x ReadInitializer %x CopyString %x CopyRound %x CopyCurly %x IDLUnionCase %x NSAliasName %x NSAliasArg %x PackageName %% <*>\x06[^\x06]*\x06 { // new file if (memberGroupId!=NOGROUP) { warn(yyFileName,yyLineNr,"Warning: Missing //@}"); 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 ; setContext(); msg("Parsing file %s...\n",yyFileName); current_root = global_root ; initParser(); current->reset(); int sec=guessSection(yyFileName); if (sec) { current->name = yyFileName; current->section = sec; current_root->addSubEntry(current); current = new Entry; } BEGIN( FindMembers ); } <*>\x0d "{" { curlyCount=0; BEGIN(SkipCurlyBlock); } "(" { roundCount=0; BEGIN(SkipRoundBlock); } "(" { ++roundCount; } ")" { if (roundCount ) --roundCount ; else BEGIN( NextSemi ) ; } "{" { ++curlyCount ; } "}" { if( curlyCount ) { --curlyCount ; } else BEGIN( NextSemi ); } "'"\\[0-7]{1,3}"'" "'"\\."'" "'".{1,4}"'" \" { lastStringContext=NextSemi; BEGIN(SkipString); } [;,] { unput(*yytext); BEGIN( FindMembers ); } [;,] { unput(*yytext); BEGIN( FindMembers ); } {B}*("properties"|"__property"){BN}*":"{BN}* { // IDL or Borland C++ builder property current->mtype = mtype = Property; current->protection = protection = Public ; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } {B}*"k_dcop"{BN}*":"{BN}* { current->mtype = mtype = DCOP; current->protection = protection = Public ; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } {B}*"signals"{BN}*":"{BN}* { current->mtype = mtype = Signal; current->protection = protection = Public ; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } {B}*"public"{BN}*"slots"{BN}*":"{BN}* { current->protection = protection = Public ; current->mtype = mtype = Slot; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount(); } {B}*"protected"{BN}*"slots"{BN}*":"{BN}* { current->protection = protection = Protected ; current->mtype = mtype = Slot; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount(); } {B}*"private"{BN}*"slots"{BN}*":"{BN}* { current->protection = protection = Private ; current->mtype = mtype = Slot; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount(); } {B}*("public"|"methods"|"__published"){BN}*":"{BN}* { current->protection = protection = Public ; current->mtype = mtype = Method; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } {B}*"protected"{BN}*":"{BN}* { current->protection = protection = Protected ; current->mtype = mtype = Method; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } {B}*"private"{BN}*":"{BN}* { current->protection = protection = Private ; current->mtype = mtype = Method; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } {BN}+ { lineCount(); } {B}*"package"{BN}+ { // Java package lineCount(); BEGIN(PackageName); } {ID}("."{ID})* { current->name = yytext; current->fileName = yyFileName; current->startLine = yyLineNr; current->section=Entry::PACKAGE_SEC; current_root->addSubEntry(current); current = new Entry ; initEntry(); } ";" { BEGIN(FindMembers); } {B}*"static"{BN}+ { //current->type += " static "; current->stat = TRUE; lineCount(); } {B}*"extern"{BN}+ { current->stat = FALSE; current->explicitExternal = TRUE; lineCount(); } {B}*"virtual"{BN}+ { current->type += " virtual "; current->virt = Virtual; lineCount(); } {B}*"abstract"{BN}+ { current->type += " abstract "; current->virt = Pure; lineCount(); } {B}*"inline"{BN}+ { current->memSpec|=Entry::Inline; lineCount(); } {B}*"mutable"{BN}+ { current->memSpec|=Entry::Mutable; lineCount(); } {B}*"explicit"{BN}+ { current->memSpec|=Entry::Explicit; lineCount(); } /* {B}*"import"{BN}+ { // IDL import keyword BEGIN( NextSemi ); } */ {B}*"typename"{BN}+ { lineCount(); } {B}*"namespace"{BN}*/[^a-z_A-Z0-9] { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; current->type = "namespace" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount(); BEGIN( CompoundName ); } {B}*"module"{BN}+ { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; current->type = "module" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount(); BEGIN( CompoundName ); } {B}*"library"{BN}+ { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; current->type = "library" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount(); BEGIN( CompoundName ); } {B}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba IDL interface isTypedef=FALSE; current->section = Entry::INTERFACE_SEC; addType( current ) ; current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount(); BEGIN( CompoundName ); } {B}*"exception"{BN}+ { // Corba IDL exception isTypedef=FALSE; current->section = Entry::EXCEPTION_SEC; addType( current ) ; current->type += " exception" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount(); BEGIN( CompoundName ); } {B}*(("typedef"{BN}+)?)("volatile"{BN}+)?"class"{BN}+ { isTypedef=((QCString)yytext).find("typedef")!=-1; current->section = Entry::CLASS_SEC; addType( current ) ; current->type += " class" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; //if (current->mtArgList) // transfer template arguments //{ // if (current->tArgList) // { // delete current->tArgList; // } // current->tArgList = current->mtArgList; // current->mtArgList = 0; //} lineCount() ; BEGIN( CompoundName ) ; } {B}*(("typedef"{BN}+)?)("volatile"{BN}+)?"struct"{BN}+ { isTypedef=((QCString)yytext).find("typedef")!=-1; current->section = Entry::STRUCT_SEC ; addType( current ) ; current->type += " struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; //if (current->mtArgList) // transfer template arguments //{ // if (current->tArgList) // { // delete current->tArgList; // } // current->tArgList = current->mtArgList; // current->mtArgList = 0; //} lineCount() ; BEGIN( CompoundName ) ; } {B}*(("typedef"{BN}+)?)("volatile"{BN}+)?"union"{BN}+ { isTypedef=((QCString)yytext).find("typedef")!=-1; current->section = Entry::UNION_SEC ; addType( current ) ; current->type += " union" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount() ; BEGIN( CompoundName ) ; } {B}*(("typedef"{BN}+)?)"enum"{BN}+ { isTypedef=((QCString)yytext).find("typedef")!=-1; current->section = Entry::ENUM_SEC ; addType( current ) ; current->type += " enum" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; lineCount() ; BEGIN( CompoundName ) ; } "("{BN}*")"{BN}*/"(" { lineCount(); current->name += yytext ; current->name = current->name.simplifyWhiteSpace(); BEGIN( FindMembers ) ; } [^(] { lineCount(); current->name += *yytext ; } "<>" { /* skip guided templ specifiers */ } "(" { current->name = current->name.simplifyWhiteSpace(); unput(*yytext); BEGIN( FindMembers ) ; } "template"({BN}*)"<"/[>]? { lineCount(); // class template specifier already found => member template specifier // already inside class => member template specifier //if (current->tArgList /*|| (current_root->section&Entry::COMPOUND_MASK)*/) //{ // printf("-------> member template \n"); if (current->tArgLists==0) { current->tArgLists = new QList; current->tArgLists->setAutoDelete(TRUE); } ArgumentList *al = new ArgumentList; al->setAutoDelete(TRUE); current->tArgLists->append(al); currentArgumentList = al; //if (current->mtArgList) // { // if (current->tArgList) // { // delete current->tArgList; // } // current->tArgList = current->mtArgList; // current->mtArgList = 0; // } // 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; BEGIN( ReadTempArgs ); } "namespace"{BN}+/{ID}{BN}*"=" { // namespace alias lineCount(); BEGIN( NSAliasName ); } {ID} { aliasName = yytext; BEGIN( NSAliasArg ); } ({ID}"::")*{ID} { //printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext); if (current_root->name.isEmpty()) { Doxygen::namespaceAliasDict.insert(aliasName,new QCString(yytext)); } else { Doxygen::namespaceAliasDict.insert(current_root->name+"::"+aliasName, new QCString(current_root->name+"::"+yytext)); } } ";" { BEGIN( FindMembers ); } "using"{BN}+ { current->startLine=yyLineNr; lineCount(); BEGIN(Using); } "namespace"{BN}+ { lineCount(); BEGIN(UsingDirective); } {ID}{BN}*"::"{BN}*{ID}({BN}*"::"{BN}*{ID})* { current->name=yytext; current->fileName = yyFileName; current->section=Entry::USINGDECL_SEC; //printf("Found using declaration %s\n",yytext); current_root->addSubEntry(current); current = new Entry ; initEntry(); BEGIN(Using); } {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 ; initEntry(); BEGIN(Using); } ";" { BEGIN(FindMembers); } {SCOPENAME}{BN}*"<>" { // guided template decl QCString n=yytext; addType( current ); current->name=n.left(n.length()-2); } {SCOPENAME}{BN}*/"<" { // Note: this could be a return type! sharpCount=0; lineCount(); addType( current ); //if (current->mtArgList && current->tArgList==0) //{ // current->tArgList=current->mtArgList; // current->mtArgList=0; //} 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 ); } "<<" { current->name+=yytext; *currentTemplateSpec+=yytext; } "<" { current->name+='<'; *currentTemplateSpec+='<'; sharpCount++; } ">>" { current->name+=yytext; *currentTemplateSpec+=yytext; } ">" { 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} { // correct for misinterpreting return type as scope name: example: A func() //printf("YY_START=%d current->tArgList=%p current->mtArgList=%p\n", // YY_START,current->tArgList,current->mtArgList); //if (YY_START==FindMembers /*&& current->tArgList*/ && current->mtArgList==0) //{ // current->mtArgList=current->tArgList; // current->tArgList=0; // current->scopeSpec.resize(0); //} lineCount(); if (insideIDL && yyleng==9 && strcmp(yytext,"cpp_quote")==0) { BEGIN(CppQuote); } else if (insideIDL && yyleng==6 && strcmp(yytext,"import")==0) { BEGIN(NextSemi); } else if (insideIDL && strcmp(yytext,"case")==0) { BEGIN(IDLUnionCase); } else if (insideTryBlock && strcmp(yytext,"catch")==0) { insideTryBlock=FALSE; BEGIN(TryFunctionBlock); } else { if (YY_START==FindMembers) { addType( current ) ; } if (insideJava && strcmp(yytext,"public")==0) { current->protection = Public; } else if (insideJava && strcmp(yytext,"protected")==0) { current->protection = Protected; } else if (insideJava && strcmp(yytext,"private")==0) { current->protection = Private; } else { if (YY_START==FindMembers) current->name = yytext; else current->name += yytext; } QCString tmp=yytext; if (nameIsOperator(tmp)) BEGIN( Operator ); else BEGIN(FindMembers); } } "::" { current->name+=yytext; } "("{B}*"\"" { insideCppQuote=TRUE; BEGIN(FindMembers); } "::" ":" { BEGIN(FindMembers); } \n { yyLineNr++; } . \n { yyLineNr++; } "{" { curlyCount=0; lastCurlyContext = TryFunctionBlockEnd ; BEGIN( SkipCurly ); } . "catch" { BEGIN(TryFunctionBlock); } . { unput(*yytext); BEGIN( FindMembers ); } ")" { 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 ; initEntry(); BEGIN(FindMembers); } \\[\r]?\n { yyLineNr++; } \" { if (insideIDL && insideCppQuote) { BEGIN(EndCppQuote); } else { lastStringContext=DefineEnd; BEGIN(SkipString); } } . [*&]+ { current->name += yytext ; addType( current ); } ";"{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_getBool("JAVADOC_AUTOBRIEF")) { 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_getBool("JAVADOC_AUTOBRIEF")) { current->brief.resize(0); BEGIN(AfterDocBrief); } else { current->doc.resize(0); BEGIN(AfterDoc); } } {BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); lastAfterDocContext = YY_START; if (YY_START==DefineEnd) { afterDocTerminator = '\n'; yyLineNr--; } else afterDocTerminator = 0; if (yytext[yyleng-3]=='/') { current->brief.resize(0); BEGIN(AfterDocLine); } else if (yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF")) { current->brief.resize(0); BEGIN(AfterDocBrief); } else { current->doc.resize(0); BEGIN(AfterDoc); } } ("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { startGroup(); tmpDocType=-1; if (current_root->section & Entry::SCOPE_MASK) current->inside = current_root->name+"::"; if (yytext[1]=='/') // C++ style comment { current->brief.resize(0); lastDocContext = YY_START; BEGIN( LineDoc ); } else // C style comment { current->doc.resize(0); lastDocContext = YY_START; removeSlashes=FALSE; BEGIN( Doc ); } } "//"([!/]?){B}*{CMD}"}"|"/*"([!*]?){B}*{CMD}"}"{B}*"*/" { endGroup(); } "=" { 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}"'" "'"\\."'" "'".{1,4}"'" \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; } "'".{1,4}"'" { *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; } "'".{1,4}"'" { *pCopyCurlyString+=yytext; } [^"'{}\/\n]+ { *pCopyCurlyString+=yytext; } \n { yyLineNr++; *pCopyCurlyString+=*yytext; } ":" { if (current->type.isEmpty()) // bit pad field { addType(current); current->name.sprintf("__pad%d__",padCount++); } BEGIN(BitFields); current->bitfields+=":"; } . { current->bitfields+=*yytext; } [;,] { QCString oldType = current->type.copy(); 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 (Doxygen::typedefDict[current->name]==0 && !dest.isEmpty()) // { // //printf("1>>>>>>>>>> adding %s->%s\n",current->name.data(),dest.data()); // QCString scope; // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name; // Doxygen::typedefDict.insert(current->name, new TypedefInfo(dest,scope)); // } //} 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 ) ; if ( *yytext == ',') { current = new Entry(*current); current->name.resize(0); current->args.resize(0); current->initializer.resize(0); current->bitfields.resize(0); int i=oldType.length(); while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--; current->type = oldType.left(i); } else { current = new Entry ; initEntry(); } BEGIN( FindMembers ) ; } "[" { if (current->name.isEmpty() || current->name=="typedef") // 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); if (!current->name.isEmpty()) { 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 ; initEntry(); } else // probably a redundant , { current->reset(); } } /* "," { unput(*yytext); BEGIN(FindFields); } */ [^\r\n{}"'/]* { current->program += yytext ; } "//".* { current->program += yytext ; } \"[^\r\n"]*\" { current->program += yytext ; } "/*"{B}* { current->program += yytext ; lastContext = ReadBody ; BEGIN( Comment ) ; } "/*"{BL} { current->program += yytext ; ++yyLineNr ; lastContext = ReadBody ; BEGIN( Comment ) ; } "'"\\[0-7]{1,3}"'" { current->program += yytext; } "'"\\."'" { current->program += yytext; } "'".{1,4}"'" { current->program += yytext; } "{" { current->program += yytext ; ++curlyCount ; } "}" { //err("ReadBody count=%d\n",curlyCount); if ( curlyCount>0 ) { current->program += yytext ; --curlyCount ; } else { current->endBodyLine = yyLineNr; QCString &cn = current->name; QCString rn = current_root->name.copy(); //printf("cn=`%s' rn=`%s'\n",cn.data(),rn.data()); if (!cn.isEmpty() && !rn.isEmpty()) { prependScope(); //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 || insideJava ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); initEntry(); BEGIN( FindMembers ) ; } else { BEGIN( MemberSpec ) ; } } } } {ID} { if (current->section == Entry::ENUM_SEC) { current->program+=","; // add field terminator } current->name=yytext; prependScope(); 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; initEntry(); 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->mtype = current->mtype; varEntry->virt = current->virt; varEntry->stat = current->stat; 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 "); // //printf("current->name = %s %s\n",current->name.data(),msName.data()); // if (!current->name.isEmpty() && current->name.at(0)!='@') // { // //printf("2>>>>>>>>>> adding %s->%s\n",msName.data(),current->name.data()); // QCString scope; // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name; // Doxygen::typedefDict.insert(msName,new TypedefInfo(current->name,scope)); // } //} 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; // deep copy group list QListIterator gli(*current->groups); Grouping *g; for (;(g=gli.current());++gli) { varEntry->groups->append(new Grouping(*g)); } //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(); initEntry(); 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; roundCount=0; //current->type += yytext; BEGIN( FuncPtr ); } {SCOPENAME} { current->name = yytext; if (current->name=="const" || current->name=="volatile") { funcPtrType += current->name; } else { 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 function pointer lineCount(); current->type+=funcPtrType+")"; BEGIN(FindMembers); } ")"{BN}*/"[" { // an array of variables lineCount(); current->type+=funcPtrType.data(); current->args += ")"; BEGIN(FindMembers); } "(" { // a function returning a function current->args += *yytext ; roundCount=0; BEGIN( FuncFunc ); } "["[^\n\]]*"]" { funcPtrType+=yytext; } ")" { 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; } "(" { if (!current->name.isEmpty()) { 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; yyLineNr++; if (lastCopyArgChar!=0) unput(lastCopyArgChar); BEGIN( ReadFuncArgType ); } [^\n]+ { fullArgString+=yytext; } \n { fullArgString+=*yytext; yyLineNr++; } . { fullArgString+=*yytext; } "<" { *copyArgString+=*yytext; fullArgString+=*yytext; argSharpCount=1; 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++; //printf("argSharpCount++=%d copy\n",argSharpCount); *copyArgString+=*yytext; fullArgString+=*yytext; } ">" { *copyArgString+=*yytext; fullArgString+=*yytext; argSharpCount--; if (argSharpCount>0) { //printf("argSharpCount--=%d copy\n",argSharpCount); } else { BEGIN( ReadTempArgs ); //printf("end of argSharpCount\n"); } } \\. { *copyArgString+=yytext; fullArgString+=yytext; } \" { *copyArgString+=*yytext; fullArgString+=*yytext; BEGIN( lastCopyArgStringContext ); } "'"\\[0-7]{1,3}"'" { *copyArgString+=yytext; fullArgString+=yytext; } "'"\\."'" { *copyArgString+=yytext; fullArgString+=yytext; } "'".{1,4}"'" { *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}*"try"{BN}+ { /* try-function-block */ insideTryBlock=TRUE; } {BN}*"throw"{BN}*"(" { current->exception = " throw (" ; roundCount=0; lineCount() ; BEGIN( ExcpRound ) ; } {BN}*"raises"{BN}*"(" { current->exception = " raises (" ; lineCount() ; roundCount=0; 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 ; roundCount=0; BEGIN( FuncRound ) ; } "#" { lastCPPContext = YY_START; BEGIN(SkipCPP); } ":" { BEGIN(SkipInits); } [;{] { 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::COMPOUND_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 ; initEntry(); lastCurlyContext = FindMembers; if( *yytext == '{' ) { if (current_root->section & Entry::COMPOUND_MASK) previous->memSpec = previous->memSpec | Entry::Inline; //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 ) ; unput('{'); BEGIN( Function ); } "{" { //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_getBool("JAVADOC_AUTOBRIEF")) BEGIN(AfterDocBrief); else BEGIN(AfterDoc); } } "}" { //addToBody("}"); current = tempEntry; BEGIN( lastCurlyContext ); } "'"\\[0-7]{1,3}"'" { //addToBody(yytext); } "'"\\."'" { //addToBody(yytext); } "'".{1,4}"'" { //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 ); } {SCOPENAME}{BN}*/"(" { if (insideIDL && strncmp(yytext,"switch",6)==0 && !isId(yytext[6])) { // Corba IDL style union roundCount=0; BEGIN(SkipUnionSwitch); } else { addType(current); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); BEGIN( FindMembers ); } } {ID} { if (insideIDL && strcmp(yytext,"switch")==0) { // Corba IDL style union roundCount=0; BEGIN(SkipUnionSwitch); } else if (insideJava && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) { current->type.resize(0); baseProt=Public; baseVirt=Normal; baseName.resize(0); BEGIN( BasesProt ) ; } else { //if (isTypedef) //{ // //QCString dest = extractName(current->name); // //printf("3>>>>>>>>>> adding %s->%s\n",yytext,current->name.data()); // QCString scope; // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name; // Doxygen::typedefDict.insert(yytext,new TypedefInfo(current->name,scope)); // //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 || current->section == Entry::STRUCT_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( ReadBody ) ; } "virtual" { baseVirt = Virtual; } "public" { baseProt = Public; } "protected" { baseProt = Protected; } "private" { baseProt = Private; } {BN} { lineCount(); } . { unput(*yytext); BEGIN(Bases); } ("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} { QCString bName = yytext; bName = bName.stripWhiteSpace(); bool globalScope = bName.at(0)==':' && baseName.isEmpty(); if (!globalScope) baseName += bName; else baseName += (bName.data()+2); current->args += ' '; if (!globalScope) current->args += bName; else current->args += (bName.data()+2); } {BN}*{ID}("."{ID})* { // Java style class QCString name = yytext; int i=name.findRev('.'); if (i!=-1) // strip part before dots { name=name.right(name.length()-i-1); } baseName += name; current->args += ' '; current->args += name; } "<" { 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; } ">>" { *specName += yytext; } . { *specName += *yytext; } "<" { ++sharpCount; } ">" { if (--sharpCount<=0) BEGIN ( lastSkipSharpContext ); } "(" { ++roundCount; } ")" { if (--roundCount<=0) BEGIN ( lastSkipRoundContext ); } ","|({BN}+"implements"{BN}*) { lineCount(); current->args += ',' ; current->name = removeRedundantWhiteSpace(current->name); if (!baseName.isEmpty()) current->extends->append( new BaseInfo(baseName,baseProt,baseVirt) ); if (current->section == Entry::INTERFACE_SEC || insideJava) 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( ReadBody ) ; } {B}*"(" { 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==ReadBody) 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_getBool("JAVADOC_AUTOBRIEF")) // use the Qt style { tmpDocType=-1; if (YY_START==ReadBody) current->doc+="\n\n"; else current->doc.resize(0); BEGIN( Doc ); } else // Use the javadoc style { if (YY_START==ReadBody) { tmpDocType=-1; current->doc+="\n\n"; lastDocContext = ReadBody; 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}*("{")? { lineCount(); } "{" { 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] { current->brief+="."; } "."[ \t\r\n] { lineCount(); current->brief+="."; BEGIN( tmpDocType ); } {B}*/{SECTIONCMD} { current->doc+=yytext; BEGIN( tmpDocType ); } "<"({TABLE}|{UL}|{OL}|{DL}){ATTR}|{P}">" { // end brief upon encountering any of these //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; current->groupdoctype = Entry::GROUPDOC_NORMAL; BEGIN( GroupDocArg1 ); } {B}*{CMD}"addtogroup"{B}+ { current->section = Entry::GROUPDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; current->groupdoctype = Entry::GROUPDOC_ADD; BEGIN( GroupDocArg1 ); } {B}*{CMD}"weakgroup"{B}+ { current->section = Entry::GROUPDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; current->groupdoctype = Entry::GROUPDOC_WEAK; 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"[^\n]*\n { lastDefGroup.groupname.resize(0); memberGroupHeader=&yytext[5]; memberGroupHeader=memberGroupHeader.stripWhiteSpace(); current->section = Entry::MEMBERGRP_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; yyLineNr++; BEGIN( lastDocContext ); } {CMD}"name"{B}+ { lastDefGroup.groupname.resize(0); current->section = Entry::MEMBERGRP_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; memberGroupHeader.resize(0); memberGroupDocs.resize(0); BEGIN(GroupHeader); } " 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 ; mtype = Method; gstat = FALSE; virt = Normal; memberGroupId = NOGROUP; scanYYlex() ; delete current; current=0; ce->program.resize(0); if (depthIf>0) { warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); } } parseCompounds(ce); } } //---------------------------------------------------------------------------- void parseMain(Entry *rt) { initParser(); anonCount = 0; depthIf = 0; protection = Public; mtype = Method; gstat = FALSE; virt = Normal; current_root = rt; global_root = rt; current = new Entry; inputString = rt->program; inputPosition = 0; scanYYrestart( scanYYin ); BEGIN( FindMembers ); scanYYlex(); if (depthIf>0) { warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); } rt->program.resize(0); delete current; current=0; parseCompounds(rt); } //---------------------------------------------------------------------------- extern "C" { // some bogus code to keep the compiler happy void scannerYYdummy() { yy_flex_realloc(0,0); } }