/***************************************************************************** * * * * Copyright (C) 1997-2015 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. * */ %option never-interactive %option prefix="scannerYY" %{ /* * includes */ #include #include #include #include #include #include #include #include #include "scanner.h" #include "entry.h" #include "message.h" #include "config.h" #include "doxygen.h" #include "util.h" #include "defargs.h" #include "language.h" #include "commentscan.h" #include "code.h" #include "arguments.h" #include "clangparser.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 /* ----------------------------------------------------------------- * * statics */ static ParserInterface *g_thisParser; static const char * inputString; static int inputPosition; static QFile inputFile; static int lastContext; static int lastCContext; static int lastDocContext; static int lastCPPContext; static int lastSkipSharpContext; static int lastSkipRoundContext; static int lastStringContext; static int lastCurlyContext; static int lastRoundContext; static int lastSquareContext; static int lastInitializerContext; static int lastClassTemplSpecContext; static int lastPreLineCtrlContext; static int lastSkipVerbStringContext; static int lastCommentInArgContext; static int lastRawStringContext; static int lastCSConstraint; static int lastHereDocContext; static int lastDefineContext; static int lastAlignAsContext; static int lastC11AttributeContext; static int lastModifierContext; 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 Entry* current_root = 0 ; static Entry* global_root = 0 ; static Entry* current = 0 ; static Entry* previous = 0 ; static Entry* tempEntry = 0 ; static Entry* firstTypedefEntry = 0 ; static Entry* memspecEntry = 0 ; static int yyLineNr = 1 ; static int yyBegLineNr = yyLineNr ; static int yyColNr = 1 ; static int yyBegColNr = yyColNr ; static int anonCount = 0 ; static int anonNSCount = 0 ; static QCString yyFileName; static MethodTypes mtype; static bool gstat; static bool removeSlashes; static Specifier virt; static Specifier baseVirt; static QCString msType,msName,msArgs; static bool isTypedef; static int tmpDocType; static QCString sectionLabel; static QCString sectionTitle; static QCString funcPtrType; static QCString templateStr; static QCString aliasName; static QCString baseName; static QCString* specName; static QCString formulaText; static bool useOverrideCommands = FALSE; static SrcLangExt language; static bool insideIDL = FALSE; //!< processing IDL code? static bool insideJava = FALSE; //!< processing Java code? static bool insideCS = FALSE; //!< processing C# code? static bool insideD = FALSE; //!< processing D code? static bool insidePHP = FALSE; //!< processing PHP code? static bool insideObjC = FALSE; //!< processing Objective C code? static bool insideCli = FALSE; //!< processing C++/CLI code? static bool insideJS = FALSE; //!< processing JavaScript code? static bool insideSlice = FALSE; //!< processing Slice code? static bool insideCpp = TRUE; //!< processing C/C++ code static bool sliceOpt = FALSE; static bool insideCppQuote = FALSE; static bool insideProtocolList = 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 char lastCopyArgChar; static QCString *pCopyQuotedString; static QCString *pCopyRoundString; static QCString *pCopyCurlyString; static QCString *pCopyRawString; static QGString *pCopyCurlyGString; static QGString *pCopyRoundGString; static QGString *pCopySquareGString; static QGString *pCopyQuotedGString; static QGString *pCopyHereDocGString; static QGString *pCopyRawGString; static QGString *pSkipVerbString; static QStack autoGroupStack; static bool insideFormula; static bool insideTryBlock=FALSE; static bool insideCode; static bool needsSemi; //static int depthIf; static int initBracketCount; static QCString oldStyleArgType; static QCString docBackup; static QCString briefBackup; static int docBlockContext; static QGString docBlock; static QCString docBlockName; static bool docBlockInBody; static bool docBlockAutoBrief; static char docBlockTerm; static QCString idlAttr; static QCString idlProp; static bool odlProp; static bool g_lexInit = FALSE; static bool externC; static QCString g_delimiter; static int g_column; static int g_fencedSize=0; static bool g_nestedComment=0; //----------------------------------------------------------------------------- // forward declarations //static void handleGroupStartCommand(const char *header); //static void handleGroupEndCommand(); //----------------------------------------------------------------------------- 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; mtype = Method; gstat = FALSE; virt = Normal; baseVirt = Normal; isTypedef = FALSE; autoGroupStack.clear(); insideTryBlock = FALSE; autoGroupStack.setAutoDelete(TRUE); insideFormula = FALSE; insideCode=FALSE; insideCli=Config_getBool(CPP_CLI_SUPPORT); sliceOpt=Config_getBool(OPTIMIZE_OUTPUT_SLICE); previous = 0; firstTypedefEntry = 0; tempEntry = 0; memspecEntry =0; } static void initEntry() { if (insideJava) { protection = (current_root->spec & (Entry::Interface|Entry::Enum)) ? Public : Package; } current->protection = protection ; current->mtype = mtype; current->virt = virt; current->stat = gstat; current->lang = language; //printf("*** initEntry() language=%d\n",language); //if (!autoGroupStack.isEmpty()) //{ // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); // current->groups->append(new Grouping(*autoGroupStack.top())); //} initGroupInfo(current); isTypedef=FALSE; } //----------------------------------------------------------------------------- ///// 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++; //} // // forward declarations //static void startGroupInDoc(); //static void endGroup(); //----------------------------------------------------------------------------- static void lineCount() { static int tabSize = Config_getInt(TAB_SIZE); const char *p; for (p = yytext ; *p ; ++p ) { if (*p=='\n') { yyLineNr++,g_column=0,yyColNr=1; } else if (*p=='\t') { g_column+=tabSize - (g_column%tabSize); } else { g_column++,yyColNr++; } } //printf("lineCount()=%d\n",g_column); } static inline int computeIndent(const char *s,int startIndent) { int col=startIndent; static int tabSize=Config_getInt(TAB_SIZE); const char *p=s; char c; while ((c=*p++)) { if (c=='\t') col+=tabSize-(col%tabSize); else if (c=='\n') col=0; else col++; } return col; } static void addType( Entry* current ) { uint tl=current->type.length(); if( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.') { current->type += ' ' ; } current->type += current->name ; current->name.resize(0) ; tl=current->type.length(); if( tl>0 && !current->args.isEmpty() && current->type.at(tl-1)!='.') { 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 startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); static void handleParametersCommentBlocks(ArgumentList *al); //----------------------------------------------------------------- static bool nameIsOperator(QCString &name) { int i=name.find("operator"); if (i==-1) return FALSE; if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator return FALSE; // case TEXToperatorTEXT } //----------------------------------------------------------------------------- static void setContext() { QCString fileName = yyFileName; language = getLanguageFromFileName(fileName); insideIDL = language==SrcLangExt_IDL; insideJava = language==SrcLangExt_Java; insideCS = language==SrcLangExt_CSharp; insideD = language==SrcLangExt_D; insidePHP = language==SrcLangExt_PHP; insideObjC = language==SrcLangExt_ObjC; insideJS = language==SrcLangExt_JS; insideSlice = language==SrcLangExt_Slice; insideCpp = language==SrcLangExt_Cpp; if ( insidePHP ) { useOverrideCommands = TRUE; } //printf("setContext(%s) insideIDL=%d insideJava=%d insideCS=%d " // "insideD=%d insidePHP=%d insideObjC=%d\n", // yyFileName.data(),insideIDL,insideJava,insideCS,insideD,insidePHP,insideObjC // ); } //----------------------------------------------------------------------------- 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; 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); } } } } //----------------------------------------------------------------------------- /*! Returns TRUE iff the current entry could be a K&R style C function */ static bool checkForKnRstyleC() { if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file if (!current->argList) return FALSE; // must have arguments ArgumentListIterator ali(*current->argList); Argument *a; for (ali.toFirst();(a=ali.current());++ali) { // in K&R style argument do not have a type, but doxygen expects a type // so it will think the argument has no name if (a->type.isEmpty() || !a->name.isEmpty()) return FALSE; } return TRUE; } //----------------------------------------------------------------------------- static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName) { int si = current->args.length(); if (oldStyleArgType.isEmpty()) // new argument { static QRegExp re("([^)]*)"); int bi1 = current->args.findRev(re); int bi2 = bi1!=-1 ? current->args.findRev(re,bi1-1) : -1; char c; if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)" { int s=bi2+1; oldStyleArgType = current->args.left(s); int i=s; while (iargs.at(i))=='*' || isspace((uchar)c))) i++; oldStyleArgType += current->args.mid(s,i-s); s=i; while (iargs.at(i))) i++; oldStyleArgName = current->args.mid(s,i-s); oldStyleArgType+=current->args.mid(i); } else if (bi1!=-1) // redundant braces like in "int (*var)" { int s=bi1; oldStyleArgType = current->args.left(s); s++; int i=s+1; while (iargs.at(i))=='*' || isspace((uchar)c))) i++; oldStyleArgType += current->args.mid(s,i-s); s=i; while (iargs.at(i))) i++; oldStyleArgName = current->args.mid(s,i-s); } else // normal "int *var" { int l=si,i=l-1,j; char c; // look for start of name in "type *name" while (i>=0 && isId(current->args.at(i))) i--; j=i+1; // look for start of *'s while (i>=0 && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i--; i++; if (i!=l) { oldStyleArgType=current->args.left(i); oldStyleArgPtr=current->args.mid(i,j-i); oldStyleArgName=current->args.mid(j).stripWhiteSpace(); } else { oldStyleArgName=current->args.copy().stripWhiteSpace(); } } } else // continuation like *arg2 in "int *args,*arg2" { int l=si,j=0; char c; while (jargs.at(j))=='*' || isspace((uchar)c))) j++; if (j>0) { oldStyleArgPtr=current->args.left(j); oldStyleArgName=current->args.mid(j).stripWhiteSpace(); } else { oldStyleArgName=current->args.copy().stripWhiteSpace(); } } } //----------------------------------------------------------------------------- /*! Update the argument \a name with additional \a type info. For K&R style * function the type is found \e after the argument list, so this routine * in needed to fix up. */ static void addKnRArgInfo(const QCString &type,const QCString &name, const QCString &brief,const QCString &docs) { if (current->argList==0) return; ArgumentListIterator ali(*current->argList); Argument *a; for (ali.toFirst();(a=ali.current());++ali) { if (a->type==name) { a->type=type.stripWhiteSpace(); if (a->type.left(9)=="register ") // strip keyword { a->type=a->type.mid(9); } a->name=name.stripWhiteSpace(); if (!brief.isEmpty() && !docs.isEmpty()) { a->docs=brief+"\n\n"+docs; } else if (!brief.isEmpty()) { a->docs=brief; } else { a->docs=docs; } } } } //----------------------------------------------------------------------------- void fixArgumentListForJavaScript(ArgumentList *al) { if (al==0) return; ArgumentListIterator ali(*al); Argument *a; for (ali.toFirst();(a=ali.current());++ali) { if (!a->type.isEmpty() && a->name.isEmpty()) { // a->type is actually the (typeless) parameter name, so move it a->name=a->type; a->type.resize(0); } } } /* ----------------------------------------------------------------- */ #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; } %} /* start command character */ CMD ("\\"|"@") BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID}) TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,:]*">")? CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID}) PRE [pP][rR][eE] CODE [cC][oO][dD][eE] CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] IDLATTR ("["[^\]]*"]"){BN}* TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"(" RAWEND ")"[^ \t\(\)\\]{0,16}\" ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++" ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|=" LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!" BITOP "&"|"|"|"^"|"<<"|">>"|"~" OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) %option noyywrap /* language parsing states */ %x AlignAs %x AlignAsEnd %x Define %x DefineEnd %x CompoundName %x ClassVar %x CSConstraintName %x CSConstraintType %x CSIndexer %x ClassCategory %x ClassTemplSpec %x CliPropertyType %x CliPropertyIndex %x CliOverride %x Bases %x BasesProt %x NextSemi %x BitFields %x EnumBaseType %x FindMembers %x FindMembersPHP %x FindMemberName %x FindFields %x FindFieldArg %x Function %x FuncRound %x ExcpRound %x ExcpList %x FuncQual %x TrailingReturn %x Operator %x Array %x ReadBody %x ReadNSBody %x ReadBodyIntf %x Using %x UsingAlias %x UsingAliasEnd %x UsingDirective %x SkipCurly %x SkipCurlyCpp %x SkipCurlyEndDoc %x SkipString %x SkipPHPString %x SkipInits %x SkipC11Inits %x SkipC11Attribute %x SkipCPP %x SkipCPPBlock %x SkipComment %x SkipCxxComment %x SkipCurlyBlock %x SkipRoundBlock %x Sharp %x SkipRound %x SkipSquare %x SkipRemainder %x StaticAssert %x DeclType %x TypedefName %x TryFunctionBlock %x TryFunctionBlockEnd %x Comment %x PackageName %x JavaImport %x PHPUse %x PHPUseAs %x CSAccessorDecl %x CSGeneric %x PreLineCtrl %x DefinePHP %x DefinePHPEnd %x OldStyleArgs %x SkipVerbString %x ObjCMethod %x ObjCReturnType %x ObjCParams %x ObjCParamType %x ObjCProtocolList %x ObjCPropAttr %x ObjCSkipStatement %x QtPropType %x QtPropName %x QtPropAttr %x QtPropRead %x QtPropWrite %x ReadInitializer %x UNOIDLAttributeBlock %x GetCallType %x CppQuote %x EndCppQuote %x MemberSpec %x MemberSpecSkip %x EndTemplate %x FuncPtr %x FuncPtrOperator %x EndFuncPtr %x ReadFuncArgType %x ReadTempArgs %x IDLUnionCase %x NSAliasName %x NSAliasArg %x CopyString %x CopyPHPString %x CopyGString %x CopyPHPGString %x CopyRound %x CopyCurly %x GCopyRound %x GCopySquare %x GCopyCurly %x SkipUnionSwitch %x Specialization %x FuncPtrInit %x FuncFunc %x FuncFuncEnd %x FuncFuncType %x FuncFuncArray %x CopyArgString %x CopyArgPHPString %x CopyArgRound %x CopyArgSharp %x CopyArgComment %x CopyArgCommentLine %x CopyArgVerbatim %x HereDoc %x HereDocEnd %x CopyHereDoc %x CopyHereDocEnd %x RawString %x RawGString %x CSString %x IDLAttribute %x IDLProp %x IDLPropName /** Slice states */ %x SliceOptional %x SliceMetadata %x SliceSequence %x SliceSequenceName %x SliceDictionary %x SliceDictionaryName /** Prototype scanner states */ %x Prototype %x PrototypePtr %x PrototypeQual %x PrototypeExc %x PrototypeSkipLine /** comment parsing states */ %x DocLine %x DocBlock %x DocCopyBlock %% "{" { curlyCount=0; needsSemi = TRUE; BEGIN(SkipCurlyBlock); } "(" { roundCount=0; BEGIN(SkipRoundBlock); } "(" { ++roundCount; } ")" { if (roundCount ) --roundCount ; else BEGIN( NextSemi ) ; } "{" { ++curlyCount ; } "}" { if( curlyCount ) { --curlyCount ; } else if (needsSemi) { BEGIN( NextSemi ); } else { BEGIN( FindMembers ); } } \' { if (insidePHP) { lastStringContext=NextSemi; BEGIN(SkipPHPString); } } {CHARLIT} { if (insidePHP) REJECT; } \" { lastStringContext=NextSemi; BEGIN(SkipString); } [;,] { unput(*yytext); BEGIN( FindMembers ); } [;,] { unput(*yytext); BEGIN( FindMembers ); } [{;,] { current->args = current->args.simplifyWhiteSpace(); unput(*yytext); BEGIN( ClassVar ); } """" { // PHP code start lineCount() ; BEGIN( FindMembers ); } [^\n<]+ { // Non-PHP code text, ignore } \n { // Non-PHP code text, ignore lineCount(); } . { // Non-PHP code text, ignore } "?>"|"" { // PHP code end if (insidePHP) BEGIN( FindMembersPHP ); else REJECT; } {PHPKW} { if (insidePHP) BEGIN( NextSemi ); else REJECT; } "%{"[^\n]* { // Mozilla XPIDL lang-specific block if (!insideIDL) REJECT; } "%}" { // Mozilla XPIDL lang-specific block end if (!insideIDL) REJECT; } {B}*("properties"){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"|"Q_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"|"Q_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"|"Q_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"|"Q_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}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package... if (insideCli) { current->protection = protection = Package ; current->mtype = mtype = Method; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); lineCount() ; } else { REJECT; } } {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() ; } {B}*"event"{BN}+ { if (insideCli) { // C++/CLI event lineCount() ; current->mtype = mtype = Event; current->bodyLine = yyLineNr; curlyCount=0; BEGIN( CliPropertyType ); } else if (insideCS) { lineCount() ; current->mtype = Event; current->bodyLine = yyLineNr; } else { REJECT; } } {B}*"property"{BN}+ { if (insideCli) { // C++/CLI property lineCount() ; current->mtype = mtype = Property; current->bodyLine = yyLineNr; curlyCount=0; BEGIN( CliPropertyType ); } else { REJECT; } } {ID} { addType( current ); current->name = yytext; } "[" { // C++/CLI indexed property current->args = "["; BEGIN( CliPropertyIndex ); } "{" { curlyCount=0; //printf("event: '%s' '%s'\n",current->type.data(),current->name.data()); BEGIN( CSAccessorDecl ); } ";" { unput(*yytext); BEGIN( FindMembers ); } \n { lineCount(); } {B}* { } . { addType( current ); current->type += yytext; } "]" { BEGIN( CliPropertyType ); current->args+=yytext; } . { current->args+=yytext; } /* {B}*"property"{BN}+ { if (!current->type.isEmpty()) { REJECT; } else { current->mtype = mtype = Property; lineCount(); } } */ {B}*"@private"{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() ; } {B}*"@protected"{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}*"@public"{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() ; } [\-+]{BN}* { if (!insideObjC) { REJECT; } else { lineCount(); current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; current->section = Entry::FUNCTION_SEC; current->protection = protection = Public ; language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->virt = Virtual; current->stat=yytext[0]=='+'; current->mtype = mtype = Method; current->type.resize(0); current->name.resize(0); current->args.resize(0); current->argList->clear(); BEGIN( ObjCMethod ); } } "(" { // start of method's return type BEGIN( ObjCReturnType ); } {ID} { // found method name if (current->type.isEmpty()) { current->type = "id"; } current->name = yytext; if (insideCpp || insideObjC) { current->id = ClangParser::instance()->lookup(yyLineNr,yytext); } } ":"{B}* { // start of parameter list current->name += ':'; Argument *a = new Argument; current->argList->append(a); BEGIN( ObjCParams ); } [^)]* { // TODO: check if nested braches are possible. current->type = yytext; } ")" { BEGIN( ObjCMethod ); } ({ID})?":" { // Keyword of parameter QCString keyw = yytext; keyw=keyw.left(keyw.length()-1); // strip : if (keyw.isEmpty()) { current->name += " :"; } else { current->name += keyw+":"; } if (current->argList->getLast()->type.isEmpty()) { current->argList->getLast()->type="id"; } Argument *a = new Argument; a->attrib=(QCString)"["+keyw+"]"; current->argList->append(a); } {ID}{BN}* { // name of parameter lineCount(); current->argList->getLast()->name=QCString(yytext).stripWhiteSpace(); } ","{BN}*"..." { // name of parameter lineCount(); // do we want the comma as part of the name? //current->name += ","; Argument *a = new Argument; a->attrib="[,]"; a->type="..."; current->argList->append(a); } /* ":" { current->name += ':'; } */ "(" { roundCount=0; current->argList->getLast()->type.resize(0); BEGIN( ObjCParamType ); } "(" { roundCount++; current->argList->getLast()->type+=yytext; } ")"/{B}* { if (roundCount<=0) { BEGIN( ObjCParams ); } else { current->argList->getLast()->type+=yytext; roundCount--; } } [^()]* { current->argList->getLast()->type+=QCString(yytext).stripWhiteSpace(); } ";" { // end of method declaration if (current->argList->getLast() && current->argList->getLast()->type.isEmpty()) { current->argList->getLast()->type="id"; } current->args = argListToString(current->argList); //printf("argList=%s\n",current->args.data()); unput(';'); BEGIN( Function ); } (";"{BN}+)?"{" { // start of a method body lineCount(); //printf("Type=%s Name=%s args=%s\n", // current->type.data(),current->name.data(),argListToString(current->argList).data() // ); if (current->argList->getLast() && current->argList->getLast()->type.isEmpty()) { current->argList->getLast()->type="id"; } current->args = argListToString(current->argList); unput('{'); BEGIN( Function ); } {B}*"sequence"{BN}*"<"{BN}* { if (insideSlice) { lineCount(); current->bodyLine = yyLineNr; current->fileName = yyFileName ; current->startLine = yyLineNr ; current->startColumn = yyColNr; current->args.resize(0); current->section = Entry::TYPEDEF_SEC ; isTypedef = TRUE; BEGIN( SliceSequence ); } else REJECT; } {B}*"dictionary"{BN}*"<"{BN}* { if (insideSlice) { lineCount(); current->bodyLine = yyLineNr; current->fileName = yyFileName ; current->startLine = yyLineNr ; current->startColumn = yyColNr; current->args.resize(0); current->section = Entry::TYPEDEF_SEC ; isTypedef = TRUE; BEGIN( SliceDictionary ); } else REJECT; } {BN}{1,80} { lineCount(); } "@"({ID}".")*{ID}{BN}*"(" { if (insideJava) // Java annotation { lineCount(); lastSkipRoundContext = YY_START; roundCount=0; BEGIN( SkipRound ); } else if (qstrncmp(yytext,"@property",9)==0) // ObjC 2.0 property { current->mtype = mtype = Property; current->spec|=Entry::Readable | Entry::Writable | Entry::Assign; current->protection = Public ; unput('('); BEGIN( ObjCPropAttr ); } else { REJECT; } } "getter="{ID} { current->read = yytext+7; } "setter="{ID} { current->write = yytext+7; } "readonly" { current->spec&=~Entry::Writable; } "readwrite" { // default } "assign" { // default } "unsafe_unretained" { current->spec&=~Entry::Assign; current->spec|=Entry::Unretained; } "retain" { current->spec&=~Entry::Assign; current->spec|=Entry::Retain; } "copy" { current->spec&=~Entry::Assign; current->spec|=Entry::Copy; } "weak" { current->spec&=~Entry::Assign; current->spec|=Entry::Weak; } "strong" { current->spec&=~Entry::Assign; current->spec|=Entry::Strong; } "nonatomic" { current->spec|=Entry::NonAtomic; } ")" { BEGIN(FindMembers); } "@"{ID} { if (insideJava) // Java annotation { // skip annotation } else if (qstrcmp(yytext,"@property")==0) // ObjC 2.0 property { current->mtype = mtype = Property; current->spec|=Entry::Writable | Entry::Readable; current->protection = Public ; } else if (qstrcmp(yytext,"@synthesize")==0) { BEGIN( ObjCSkipStatement ); } else if (qstrcmp(yytext,"@dynamic")==0) { BEGIN( ObjCSkipStatement ); } else { REJECT; } } ";" { BEGIN(FindMembers); } {ID}(("."|"\\"){ID})* { isTypedef=FALSE; //printf("Found namespace %s lang=%d\n",yytext,current->lang); current->name = yytext; current->name = substitute(current->name,".","::"); current->name = substitute(current->name,"\\","::"); current->section = Entry::NAMESPACE_SEC; current->type = "namespace" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount(); } ";" { current_root->addSubEntry(current); current_root = current ; current = new Entry ; initEntry(); BEGIN(FindMembers); } "{" { curlyCount=0; BEGIN( ReadNSBody ); } {B}*"initonly"{BN}+ { current->type += " initonly "; if (insideCli) current->spec |= Entry::Initonly; lineCount(); } {B}*"static"{BN}+ { current->type += " static "; current->stat = TRUE; lineCount(); } {B}*"extern"{BN}+ { current->stat = FALSE; current->explicitExternal = TRUE; lineCount(); } {B}*"const"{BN}+ { current->type += " const "; if (insideCS) current->stat = TRUE; lineCount(); } {B}*"virtual"{BN}+ { current->type += " virtual "; current->virt = Virtual; lineCount(); } {B}*"constexpr"{BN}+ { if (insideCpp) { current->type += " constexpr "; current->spec |= Entry::ConstExpr; lineCount(); } else { REJECT; } } {B}*"published"{BN}+ { // UNO IDL published keyword if (insideIDL) { lineCount(); current->spec |= Entry::Published; } else { REJECT; } } {B}*"abstract"{BN}+ { if (!insidePHP) { current->type += " abstract "; if (!insideJava) { current->virt = Pure; } else { current->spec|=Entry::Abstract; } } else { current->spec|=Entry::Abstract; } lineCount(); } {B}*"inline"{BN}+ { current->spec|=Entry::Inline; lineCount(); } {B}*"mutable"{BN}+ { current->spec|=Entry::Mutable; lineCount(); } {B}*"explicit"{BN}+ { current->spec|=Entry::Explicit; lineCount(); } {B}*"local"{BN}+ { current->spec|=Entry::Local; lineCount(); } {B}*"@required"{BN}+ { // Objective C 2.0 protocol required section current->spec=(current->spec & ~Entry::Optional) | Entry::Required; lineCount(); } {B}*"@optional"{BN}+ { // Objective C 2.0 protocol optional section current->spec=(current->spec & ~Entry::Required) | Entry::Optional; 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->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount(); if (insidePHP) { BEGIN( PackageName ); } else { BEGIN( CompoundName ); } } {B}*"module"{BN}+ { lineCount(); if (insideIDL || insideSlice) { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; current->type = "module" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } else if (insideD) { lineCount(); BEGIN(PackageName); } else { addType( current ) ; current->name = QCString(yytext).stripWhiteSpace(); } } {B}*"library"{BN}+ { lineCount(); if (insideIDL) { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; current->type = "library" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } else { addType( current ) ; current->name = QCString(yytext).stripWhiteSpace(); } } {B}*"constants"{BN}+ { // UNO IDL constant group lineCount(); if (insideIDL) { isTypedef=FALSE; current->section = Entry::NAMESPACE_SEC; current->type = "constants"; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } else { addType( current ) ; current->name = QCString(yytext).stripWhiteSpace(); } } {BN}*("service"){BN}+ { // UNO IDL service lineCount(); if (insideIDL) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Service | // preserve UNO IDL [optional] or published (current->spec & (Entry::Optional|Entry::Published)); addType( current ) ; current->type += " service " ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } else // TODO is addType right? just copy/pasted { addType( current ) ; current->name = QCString(yytext).stripWhiteSpace(); } } {BN}*("singleton"){BN}+ { // UNO IDL singleton lineCount(); if (insideIDL) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Singleton | (current->spec & Entry::Published); // preserve addType( current ) ; current->type += " singleton " ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } else // TODO is addType right? just copy/pasted { addType( current ) ; current->name = QCString(yytext).stripWhiteSpace(); } } {BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java/Slice interface lineCount(); if (insideIDL || insideJava || insideCS || insideD || insidePHP || insideSlice) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Interface | // preserve UNO IDL [optional], published, Slice local (current->spec & (Entry::Optional|Entry::Published|Entry::Local)); addType( current ) ; current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } else { addType( current ) ; current->name = QCString(yytext).stripWhiteSpace(); } } {B}*"@implementation"{BN}+ { // Objective-C class implementation lineCount(); isTypedef=FALSE; current->section = Entry::OBJCIMPL_SEC; language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->protection = protection = Public ; addType( current ) ; current->type += " implementation" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } {B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute lineCount(); isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Interface; if (!insideJava) { language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; } current->protection = protection = Public ; addType( current ) ; current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } {B}*"@protocol"{BN}+ { // Objective-C protocol definition lineCount(); isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Protocol; language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->protection = protection = Public ; addType( current ) ; current->type += " protocol" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; BEGIN( CompoundName ); } {B}*"exception"{BN}+ { // Corba IDL/Slice exception isTypedef=FALSE; current->section = Entry::CLASS_SEC; // preserve UNO IDL, Slice local current->spec = Entry::Exception | (current->spec & Entry::Published) | (current->spec & Entry::Local); addType( current ) ; current->type += " exception" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount(); BEGIN( CompoundName ); } "@class" | // for Objective C class declarations {B}*{TYPEDEFPREFIX}"class{" | {B}*{TYPEDEFPREFIX}"class"{BN}+ { QCString decl = yytext; isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; current->section = Entry::CLASS_SEC; addType( current ) ; uint64 spec = current->spec; if (insidePHP && current->spec&Entry::Abstract) { // convert Abstract to AbstractClass current->spec=(current->spec&~Entry::Abstract)|Entry::AbstractClass; } if (insideSlice && spec&Entry::Local) { current->spec|=Entry::Local; } if (isConst) { current->type += " const"; } else if (isVolatile) { current->type += " volatile"; } current->type += " class" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; if (yytext[0]=='@') { language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; } lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"value class{" | // C++/CLI extension {B}*"value class"{BN}+ { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Value; addType( current ) ; current->type += " value class" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"ref class{" | // C++/CLI extension {B}*"ref class"{BN}+ { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Ref; addType( current ) ; current->type += " ref class" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"interface class{" | // C++/CLI extension {B}*"interface class"{BN}+ { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Interface; addType( current ) ; current->type += " interface class" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"coclass"{BN}+ { if (insideIDL) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; addType( current ) ; current->type += " coclass" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; BEGIN( CompoundName ) ; } else { addType(current); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); } } {B}*{TYPEDEFPREFIX}"struct{" | {B}*{TYPEDEFPREFIX}"struct"/{BN}+ { QCString decl = yytext; isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; uint64 spec = current->spec; current->section = Entry::CLASS_SEC ; // preserve UNO IDL & Inline attributes, Slice local current->spec = Entry::Struct | (current->spec & Entry::Published) | (current->spec & Entry::Inline) | (current->spec & Entry::Local); // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; addType( current ) ; if (isConst) { current->type += " const"; } else if (isVolatile) { current->type += " volatile"; } current->type += " struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"value struct{" | // C++/CLI extension {B}*"value struct"{BN}+ { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Value; addType( current ) ; current->type += " value struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"ref struct{" | // C++/CLI extension {B}*"ref struct"{BN}+ { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Ref; addType( current ) ; current->type += " ref struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"interface struct{" | // C++/CLI extension {B}*"interface struct"{BN}+ { isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Interface; addType( current ) ; current->type += " interface struct"; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*{TYPEDEFPREFIX}"union{" | {B}*{TYPEDEFPREFIX}"union"{BN}+ { QCString decl=yytext; isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; current->section = Entry::CLASS_SEC; current->spec = Entry::Union; // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; addType( current ) ; if (isConst) { current->type += " const"; } else if (isVolatile) { current->type += " volatile"; } current->type += " union" ; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?"{" | {B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?{BN}+ { // for IDL: typedef [something] enum QCString text=yytext; isTypedef = text.find("typedef")!=-1; bool isStrongEnum = text.find("struct")!=-1 || text.find("class")!=-1 || insideCS; if (insideJava) { current->section = Entry::CLASS_SEC; current->spec = Entry::Enum; } else { current->section = Entry::ENUM_SEC ; } addType( current ) ; current->type += " enum"; if (isStrongEnum) { current->spec |= Entry::Strong; } current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->bodyLine = yyLineNr; lineCount() ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } "("{BN}*")"({BN}*"<"[^>]*">"){BN}*/"(" { // A::operator()(int arg) lineCount(); current->name += "()"; BEGIN( FindMembers ); } "("{BN}*")"{BN}*/"(" { lineCount(); current->name += yytext ; current->name = current->name.simplifyWhiteSpace(); BEGIN( FindMembers ) ; } ";" { // can occur when importing members unput(';'); BEGIN( FindMembers ) ; } [^(] { lineCount(); current->name += *yytext ; } "<>" { /* skip guided templ specifiers */ } "(" { current->name = current->name.simplifyWhiteSpace(); unput(*yytext); BEGIN( FindMembers ) ; } ("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension lineCount(); if (current->tArgLists==0) { current->tArgLists = new QList; current->tArgLists->setAutoDelete(TRUE); } ArgumentList *al = new ArgumentList; //current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template; current->tArgLists->append(al); currentArgumentList = al; templateStr="<"; fullArgString = templateStr; 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()) //{ // TODO: namespace aliases are now treated as global entities // while they should be aware of the scope they are in Doxygen::namespaceAliasDict.insert(aliasName,new QCString(yytext)); //} //else //{ // Doxygen::namespaceAliasDict.insert(current_root->name+"::"+aliasName, // new QCString(current_root->name+"::"+yytext)); //} } ";" { BEGIN( FindMembers ); } ({ID}{BN}*"\\"{BN}*)*{ID}/{BN}+"as" { lineCount(); aliasName=yytext; BEGIN(PHPUseAs); } ({ID}{BN}*"\\"{BN}*)*{ID} { lineCount(); current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::")); //printf("PHP: adding use relation: %s\n",current->name.data()); current->fileName = yyFileName; // add a using declaraton current->section=Entry::USINGDECL_SEC; current_root->addSubEntry(current); current = new Entry(*current); // also add it as a using directive current->section=Entry::USINGDIR_SEC; current_root->addSubEntry(current); current = new Entry ; initEntry(); aliasName.resize(0); } {BN}+"as"{BN}+ { lineCount(); } {ID} { //printf("PHP: adding use as relation: %s->%s\n",yytext,aliasName.data()); Doxygen::namespaceAliasDict.insert(yytext, new QCString(removeRedundantWhiteSpace( substitute(aliasName,"\\","::")))); aliasName.resize(0); } [,;] { if (*yytext==',') { BEGIN(PHPUse); } else { BEGIN(FindMembers); } } ({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive lineCount(); QCString scope=yytext; current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::")); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; current_root->addSubEntry(current); current = new Entry; initEntry(); BEGIN(Using); } ({ID}{BN}*"."{BN}*)+{ID} { // class import => add as a using declaration lineCount(); QCString scope=yytext; current->name=removeRedundantWhiteSpace(substitute(scope,".","::")); current->fileName = yyFileName; if (insideD) { current->section=Entry::USINGDIR_SEC; } else { //printf("import name = %s -> %s\n",yytext,current->name.data()); current->section=Entry::USINGDECL_SEC; } current_root->addSubEntry(current); previous = current; current = new Entry ; initEntry(); BEGIN(Using); } "using"{BN}+ { current->startLine=yyLineNr; current->startColumn = yyColNr; lineCount(); BEGIN(Using); } "namespace"{BN}+ { lineCount(); BEGIN(UsingDirective); } ({ID}{BN}*("::"|"."){BN}*)*({ID}|{OPERATOR}) { lineCount(); current->name=yytext; current->fileName = yyFileName; current->section=Entry::USINGDECL_SEC; current->startLine = yyLineNr; current_root->addSubEntry(current); previous = current; current = new Entry ; if (insideCS) /* Hack: in C# a using declaration and directive have the same syntax, so we also add it as a using directive here */ { current->name=yytext; current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->section=Entry::USINGDIR_SEC; current_root->addSubEntry(current); current = new Entry ; } initEntry(); BEGIN(Using); } "=" { // C++11 style template alias? BEGIN(UsingAlias); } ";" { previous->section=Entry::VARIABLE_SEC; previous->type = "typedef "+previous->args; previous->type=previous->type.simplifyWhiteSpace(); previous->args.resize(0); previous->name=previous->name.stripWhiteSpace(); previous->bodyLine = yyLineNr; previous->spec |= Entry::Alias; BEGIN(FindMembers); } ";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { docBlockContext = UsingAliasEnd; docBlockInBody = FALSE; docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,g_column)); docBlock=indent; lineCount(); docBlockTerm = ';'; if (yytext[yyleng-3]=='/') { startCommentBlock(TRUE); BEGIN( DocLine ); } else { startCommentBlock(FALSE); BEGIN( DocBlock ); } } ">>" { previous->args+="> >"; // see bug769552 } . { previous->args+=yytext; } \n { previous->args+=yytext; lineCount(); } ";" { previous->doc = current->doc; previous->brief = current->brief; current->doc.resize(0); current->brief.resize(0); unput(';'); BEGIN(UsingAlias); } {SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; 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! roundCount=0; 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; roundCount=0; lineCount(); current->name+=((QCString)yytext).stripWhiteSpace(); //current->memberSpec.resize(0); // currentTemplateSpec = ¤t->memberSpec; if (nameIsOperator(current->name)) BEGIN( Operator ); else BEGIN( EndTemplate ); } "<<<" { if (!insidePHP) { REJECT; } else { lastHereDocContext = YY_START; BEGIN(HereDoc); } } "<<" { current->name+=yytext; // *currentTemplateSpec+=yytext; } "<" { if (roundCount==0) { // *currentTemplateSpec+='<'; sharpCount++; } current->name+=yytext; } ">>" { if (insideJava || insideCS || insideCli || roundCount==0) { unput('>'); unput(' '); unput('>'); } else { current->name+=yytext; } // *currentTemplateSpec+=yytext; } ">" { current->name+='>'; // *currentTemplateSpec+='>'; if (roundCount==0 && --sharpCount<=0) { //printf("Found %s\n",current->name.data()); BEGIN(FindMembers); } } ">"{BN}*"(" { lineCount(); current->name+='>'; // *currentTemplateSpec+='>'; if (roundCount==0 && --sharpCount<=0) { current->bodyLine = yyLineNr; current->args = "("; currentArgumentContext = FuncQual; fullArgString = current->args.copy(); copyArgString = ¤t->args; //printf("Found %s\n",current->name.data()); BEGIN( ReadFuncArgType ) ; } } ">"{BN}*/"("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance lineCount(); current->name+='>'; if (roundCount==0) { BEGIN(FindMembers); } } ">"{BN}*/"::" { lineCount(); current->name+='>'; // *currentTemplateSpec+='>'; if (roundCount==0 && --sharpCount<=0) { BEGIN(FindMemberName); } } "(" { current->name+=*yytext; roundCount++; } ")" { current->name+=*yytext; if (roundCount>0) roundCount--; } . { current->name+=*yytext; // *currentTemplateSpec+=*yytext; } "define"{BN}*"("{BN}*["'] { if (insidePHP) { current->bodyLine = yyLineNr; BEGIN( DefinePHP ); } else REJECT; } {ID} { // PHP heredoc g_delimiter = yytext; *pCopyHereDocGString += yytext; BEGIN(CopyHereDocEnd); } "'"{ID}/"'" { // PHP nowdoc g_delimiter = &yytext[1]; *pCopyHereDocGString += yytext; BEGIN(CopyHereDocEnd); } {ID} { // PHP heredoc g_delimiter = yytext; BEGIN(HereDocEnd); } "'"{ID}/"'" { // PHP nowdoc g_delimiter = &yytext[1]; BEGIN(HereDocEnd); } ^{ID} { // id at start of the line could mark the end of the block if (g_delimiter==yytext) // it is the end marker { BEGIN(lastHereDocContext); } } . { } ^{ID} { // id at start of the line could mark the end of the block *pCopyHereDocGString += yytext; if (g_delimiter==yytext) // it is the end marker { BEGIN(lastHereDocContext); } } \n { *pCopyHereDocGString += yytext; } . { *pCopyHereDocGString += yytext; } "Q_OBJECT" { // Qt object macro } "Q_PROPERTY" { // Qt property declaration current->protection = Public ; // see bug734245 & bug735462 current->mtype = mtype = Property; current->type.resize(0); BEGIN(QtPropType); } "(" { // start of property arguments } ")" { // end of property arguments unput(';'); BEGIN(FindMembers); } "const"|"volatile"|"unsigned"|"signed"|"long"|"short" { current->type+=yytext; } {B}+ { current->type+=yytext; } ({TSCOPE}"::")*{TSCOPE} { current->type+=yytext; BEGIN(QtPropName); } {ID} { current->name=yytext; BEGIN(QtPropAttr); } "READ" { current->spec |= Entry::Readable; BEGIN(QtPropRead); } "WRITE" { current->spec |= Entry::Writable; BEGIN(QtPropWrite); } "RESET"{B}+{ID} { // reset method => not supported yet } "SCRIPTABLE"{B}+{ID} { // scriptable property => not supported yet } "DESIGNABLE"{B}+{ID} { // designable property => not supported yet } {ID} { current->read = yytext; BEGIN(QtPropAttr); } {ID} { current->write = yytext; BEGIN(QtPropAttr); } "friend"{BN}+("class"|"union"|"struct"){BN}+ { current->name=yytext; BEGIN(FindMembers); } {SCOPENAME} { if (insideCpp || insideObjC) { current->id = ClangParser::instance()->lookup(yyLineNr,yytext); } yyBegColNr=yyColNr; yyBegLineNr=yyLineNr; lineCount(); if (insideIDL && yyleng==9 && qstrcmp(yytext,"cpp_quote")==0) { BEGIN(CppQuote); } else if ((insideIDL || insideJava || insideD) && yyleng==6 && qstrcmp(yytext,"import")==0) { if (insideIDL) BEGIN(NextSemi); else // insideJava or insideD BEGIN(JavaImport); } else if (insidePHP && qstrcmp(yytext,"use")==0) { BEGIN(PHPUse); } else if (insideJava && qstrcmp(yytext,"package")==0) { lineCount(); BEGIN(PackageName); } else if (insideIDL && qstrcmp(yytext,"case")==0) { BEGIN(IDLUnionCase); } else if (insideTryBlock && qstrcmp(yytext,"catch")==0) { insideTryBlock=FALSE; BEGIN(TryFunctionBlock); } else if (insideCpp && qstrcmp(yytext,"alignas")==0) { lastAlignAsContext = YY_START; BEGIN(AlignAs); } else if (insideJS && qstrcmp(yytext,"var")==0) { // javascript variable current->type="var"; } else if (insideJS && qstrcmp(yytext,"function")==0) { // javascript function current->type="function"; } else if (insideCS && qstrcmp(yytext,"this")==0) { // C# indexer addType( current ) ; current->name="this"; BEGIN(CSIndexer); } else if (insideCpp && qstrcmp(yytext,"static_assert")==0) { // C++11 static_assert BEGIN(StaticAssert); } else if (insideCpp && qstrcmp(yytext,"decltype")==0) { // C++11 decltype(x) current->type+=yytext; BEGIN(DeclType); } else if (insideSlice && qstrcmp(yytext,"optional")==0) { if (current->type.isEmpty()) { current->type = "optional"; } else { current->type += " optional"; } lastModifierContext = YY_START; BEGIN(SliceOptional); } else { if (YY_START==FindMembers) { addType( current ) ; } bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS; if (javaLike && qstrcmp(yytext,"public")==0) { current->protection = Public; } else if (javaLike && qstrcmp(yytext,"protected")==0) { current->protection = Protected; } else if ((insideCS || insideD || insidePHP || insideJS) && qstrcmp(yytext,"internal")==0) { current->protection = Package; } else if (javaLike && qstrcmp(yytext,"private")==0) { current->protection = Private; } else if (javaLike && qstrcmp(yytext,"static")==0) { if (YY_START==FindMembers) current->name = yytext; else current->name += yytext; current->stat = TRUE; } else { if (YY_START==FindMembers) current->name = yytext; else current->name += yytext; if (current->name.left(7)=="static ") { current->stat = TRUE; current->name= current->name.mid(7); } else if (current->name.left(7)=="inline ") { if (current->type.isEmpty()) { current->type="inline"; } else { current->type+="inline "; } current->name= current->name.mid(7); } else if (current->name.left(6)=="const ") { if (current->type.isEmpty()) { current->type="const"; } else { current->type+="const "; } current->name=current->name.mid(6); } } QCString tmp=yytext; if (nameIsOperator(tmp)) { BEGIN( Operator ); } else { externC=FALSE; // see bug759247 BEGIN(FindMembers); } } } "(" { lastSkipRoundContext = FindMembers; roundCount=0; BEGIN(SkipRound); } {BN}+ { lineCount(); } . { // variable with static_assert as name? unput(*yytext); BEGIN(FindMembers); } "(" { current->type+=yytext; lastRoundContext=FindMembers; pCopyRoundString=¤t->type; roundCount=0; BEGIN(CopyRound); } {BN}+ { lineCount(); } . { unput(*yytext); BEGIN(FindMembers); } "["[^\n\]]*"]" { current->name+=removeRedundantWhiteSpace(yytext); BEGIN(FindMembers); } [0-9]{ID} { // some number where we did not expect one } "." { if (insideJava || insideCS || insideD) { current->name+="."; } } "::" { current->name+=yytext; } "("{B}*"\"" { insideCppQuote=TRUE; BEGIN(FindMembers); } "::" ":" { BEGIN(FindMembers); } \n { lineCount(); } . \n { lineCount(); } "{" { curlyCount=0; lastCurlyContext = TryFunctionBlockEnd ; BEGIN( SkipCurly ); } . {BN}*"catch" { lineCount(); BEGIN(TryFunctionBlock); // {BN}* added to fix bug 611193 } \n { unput(*yytext); // rule added to fix bug id 601138 BEGIN( FindMembers ); } . { unput(*yytext); BEGIN( FindMembers ); } ")" { insideCppQuote=FALSE; BEGIN(FindMembers); } {B}*"#" { if (insidePHP) REJECT; lastCPPContext = YY_START; BEGIN( SkipCPP ) ; } {B}*"#"{B}*("cmake")?"define" { if (insidePHP) REJECT; current->bodyLine = yyLineNr; lastDefineContext = YY_START; BEGIN( Define ); } {B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */ yyLineNr = atoi(&yytext[1]); //printf("setting line number to %d\n",yyLineNr); lastPreLineCtrlContext = YY_START; if (YY_START==ReadBody || YY_START==ReadNSBody || YY_START==ReadBodyIntf) { current->program+=yytext; } BEGIN( PreLineCtrl ); } "\""[^\n\"]*"\"" { yyFileName = stripQuotes(yytext); if (lastPreLineCtrlContext==ReadBody || lastPreLineCtrlContext==ReadNSBody || lastPreLineCtrlContext==ReadBodyIntf) { current->program+=yytext; } } . { if (lastPreLineCtrlContext==ReadBody || lastPreLineCtrlContext==ReadNSBody || lastPreLineCtrlContext==ReadBodyIntf) { current->program+=yytext; } } \n { if (lastPreLineCtrlContext==ReadBody || lastPreLineCtrlContext==ReadNSBody || lastPreLineCtrlContext==ReadBodyIntf) { current->program+=yytext; } lineCount(); BEGIN( lastPreLineCtrlContext ); } . \\[\r]*"\n"[\r]* { lineCount(); } [\r]*\n[\r]* { lineCount(); BEGIN( lastCPPContext) ; } {ID}{B}*"(" { current->name = yytext; current->name = current->name.left(current->name.length()-1).stripWhiteSpace(); current->args = "("; current->bodyLine = yyLineNr; currentArgumentContext = DefineEnd; fullArgString=current->args.copy(); copyArgString=¤t->args; BEGIN( ReadFuncArgType ) ; } /* ")" { //printf("Define with args\n"); current->args += ')'; BEGIN( DefineEnd ); } . { current->args += *yytext; } */ {ID} { //printf("Define `%s' without args\n",yytext); if (insideCpp || insideObjC) { current->id = ClangParser::instance()->lookup(yyLineNr,yytext); } current->bodyLine = yyLineNr; current->name = yytext; BEGIN(DefineEnd); } \n { //printf("End define: doc=%s docFile=%s docLine=%d\n",current->doc.data(),current->docFile.data(),current->docLine); lineCount(); current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; 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(lastDefineContext); } ";" { //printf("End define\n"); current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->type.resize(0); current->type = "const"; QCString init = current->initializer.data(); init = init.simplifyWhiteSpace(); init = init.left(init.length()-1); current->initializer = init; current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; current_root->addSubEntry(current); current = new Entry ; initEntry(); BEGIN(FindMembers); } . \\[\r]?\n { lineCount(); } \" { if (insideIDL && insideCppQuote) { BEGIN(EndCppQuote); } else { lastStringContext=DefineEnd; BEGIN(SkipString); } } . {ID}["']{BN}*","{BN}* { current->name = yytext; current->name = current->name.stripWhiteSpace(); current->name = current->name.left(current->name.length()-1).stripWhiteSpace(); current->name = current->name.left(current->name.length()-1); current->bodyLine = yyLineNr; lastRoundContext = DefinePHPEnd; pCopyRoundGString = ¤t->initializer; roundCount = 0; BEGIN( GCopyRound ); } [\^%] { // ^ and % are C++/CLI extensions if (insideCli) { addType( current ); current->name = yytext ; } else { REJECT; } } [*&]+ { current->name += yytext ; addType( current ); } ";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { if (current->bodyLine==-1) { current->bodyLine=yyLineNr; } docBlockContext = YY_START; docBlockInBody = FALSE; docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,g_column)); docBlock=indent; //printf("indent=%d\n",computeIndent(yytext+1,g_column)); lineCount(); docBlockTerm = ';'; if (YY_START==EnumBaseType && current->section==Entry::ENUM_SEC) { current->bitfields = ":"+current->args; current->args.resize(0); current->section=Entry::VARIABLE_SEC; } if (yytext[yyleng-3]=='/') { startCommentBlock(TRUE); BEGIN( DocLine ); } else { startCommentBlock(FALSE); BEGIN( DocBlock ); } } ","{BN}*("/**"|"//!"|"/*!"|"///")"<" { docBlockContext = YY_START; docBlockInBody = FALSE; docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,g_column)); docBlock=indent; lineCount(); docBlockTerm = ','; if (YY_START==EnumBaseType && current->section==Entry::ENUM_SEC) { current->bitfields = ":"+current->args; current->args.resize(0); current->section=Entry::VARIABLE_SEC; } if (yytext[yyleng-3]=='/') { startCommentBlock(TRUE); BEGIN( DocLine ); } else { startCommentBlock(FALSE); BEGIN( DocBlock ); } } {BN}*("/**"|"//!"|"/*!"|"///")"<" { if (current->bodyLine==-1) { current->bodyLine=yyLineNr; } docBlockContext = YY_START; docBlockInBody = FALSE; docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,g_column)); docBlock=indent; lineCount(); docBlockTerm = 0; if (yytext[yyleng-3]=='/') { startCommentBlock(TRUE); BEGIN( DocLine ); } else { startCommentBlock(FALSE); BEGIN( DocBlock ); } } ("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { //handleGroupStartCommand(current->name); if (previous && previous->section==Entry::GROUPDOC_SEC) { // link open command to the group defined in the previous entry openGroup(previous,yyFileName,yyLineNr); } else { // link open command to the current entry openGroup(current,yyFileName,yyLineNr); } //current = tmp; initEntry(); if (yytext[1]=='/') { if (yytext[2]=='!' || yytext[2]=='/') { docBlockContext = YY_START; docBlockInBody = FALSE; docBlockAutoBrief = FALSE; docBlock.resize(0); docBlockTerm = 0; startCommentBlock(TRUE); BEGIN(DocLine); } else { lastCContext=YY_START; BEGIN(SkipCxxComment); } } else { if (yytext[2]=='!' || yytext[2]=='*') { docBlockContext = YY_START; docBlockInBody = FALSE; docBlock.resize(0); docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); docBlockTerm = 0; startCommentBlock(FALSE); BEGIN(DocBlock); } else { lastCContext=YY_START; BEGIN(SkipComment); } } } "//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}"[^*]*"*/" { bool insideEnum = YY_START==FindFields || (YY_START==ReadInitializer && lastInitializerContext==FindFields); // see bug746226 closeGroup(current,yyFileName,yyLineNr,insideEnum); } "=" { // in PHP code this could also be due to "bodyLine = yyLineNr; current->initializer = yytext; lastInitializerContext = YY_START; initBracketCount=0; BEGIN(ReadInitializer); } {BN}*[gs]"et"{BN}+"raises"{BN}*"("{BN}*{SCOPENAME}{BN}*(","{BN}*{SCOPENAME}{BN}*)*")"{BN}*";" { lineCount(); current->exception += " "; current->exception += removeRedundantWhiteSpace(yytext); } "}" { current->exception += " }"; BEGIN(FindMembers); } /* Read initializer rules */ "(" { lastRoundContext=YY_START; pCopyRoundGString=¤t->initializer; roundCount=0; current->initializer+=*yytext; BEGIN(GCopyRound); } "[" { if (!insidePHP) REJECT; lastSquareContext=YY_START; pCopySquareGString=¤t->initializer; squareCount=0; current->initializer+=*yytext; BEGIN(GCopySquare); } "{" { lastCurlyContext=YY_START; pCopyCurlyGString=¤t->initializer; curlyCount=0; current->initializer+=*yytext; BEGIN(GCopyCurly); } [;,] { //printf(">> initializer `%s' <<\n",current->initializer.data()); if (*yytext==';' && (current_root->spec&Entry::Enum)) { current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; current_root->addSubEntry(current); current = new Entry; initEntry(); BEGIN(FindMembers); } else if (*yytext==';' || (lastInitializerContext==FindFields && initBracketCount==0)) // initBracketCount==0 was added for bug 665778 { unput(*yytext); BEGIN(lastInitializerContext); } else if (*yytext==',' && initBracketCount==0) // for "int a=0,b=0" { unput(*yytext); BEGIN(lastInitializerContext); } else { current->initializer+=*yytext; } } {RAWBEGIN} { // C++11 raw string if (!insideCpp) { REJECT; } else { QCString text=yytext; current->initializer+=text; int i=text.find('"'); g_delimiter = yytext+i+1; g_delimiter=g_delimiter.left(g_delimiter.length()-1); lastRawStringContext = YY_START; pCopyRawGString = ¤t->initializer; BEGIN(RawGString); //printf("RawGString delimiter='%s'\n",delimiter.data()); } } {RAWEND} { *pCopyRawGString+=yytext; QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); if (delimiter==g_delimiter) { BEGIN(lastRawStringContext); } } [^)\n]+ { *pCopyRawGString+=yytext; } . { *pCopyRawGString+=yytext; } \n { *pCopyRawGString+=yytext; lineCount(); } {RAWEND} { *pCopyRawString+=yytext; fullArgString+=yytext; QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); if (delimiter==g_delimiter) { BEGIN(lastRawStringContext); } } [^)]+ { *pCopyRawString+=yytext; fullArgString+=yytext; } . { *pCopyRawString+=yytext; fullArgString+=yytext; } \n { *pCopyRawString+=yytext; fullArgString+=yytext; lineCount(); } \" { if (insideIDL && insideCppQuote) { BEGIN(EndCppQuote); } else { lastStringContext=YY_START; current->initializer+=yytext; pCopyQuotedGString=¤t->initializer; BEGIN(CopyGString); } } "->" { current->initializer+=yytext; } "<<" { current->initializer+=yytext; } ">>" { current->initializer+=yytext; } [<\[{(] { initBracketCount++; current->initializer+=*yytext; } [>\]})] { initBracketCount--; current->initializer+=*yytext; } \' { if (insidePHP) { current->initializer+=yytext; pCopyQuotedGString = ¤t->initializer; lastStringContext=YY_START; BEGIN(CopyPHPGString); } else { current->initializer+=yytext; } } {CHARLIT} { if (insidePHP) { REJECT; } else { current->initializer+=yytext; } } \n { current->initializer+=*yytext; lineCount(); } "@\"" { //printf("insideCS=%d\n",insideCS); current->initializer+=yytext; if (!insideCS && !insideObjC) { REJECT; } else { // C#/ObjC verbatim string lastSkipVerbStringContext=YY_START; pSkipVerbString=¤t->initializer; BEGIN(SkipVerbString); } } [^\n"]+ { *pSkipVerbString+=yytext; } "\"\"" { // quote escape *pSkipVerbString+=yytext; } "\"" { *pSkipVerbString+=*yytext; BEGIN(lastSkipVerbStringContext); } \n { *pSkipVerbString+=*yytext; lineCount(); } . { *pSkipVerbString+=*yytext; } "?>" { if (insidePHP) BEGIN( FindMembersPHP ); else current->initializer+=yytext; } . { current->initializer+=*yytext; } /* generic quoted string copy rules */ \\. { *pCopyQuotedString+=yytext; } \" { *pCopyQuotedString+=*yytext; BEGIN( lastStringContext ); } \' { *pCopyQuotedString+=*yytext; BEGIN( lastStringContext ); } "/*"|"*/"|"//" { *pCopyQuotedString+=yytext; } \n { *pCopyQuotedString+=*yytext; lineCount(); } . { *pCopyQuotedString+=*yytext; } /* generic quoted growable string copy rules */ \\. { *pCopyQuotedGString+=yytext; } \" { *pCopyQuotedGString+=*yytext; BEGIN( lastStringContext ); } \' { *pCopyQuotedGString+=*yytext; BEGIN( lastStringContext ); } ""/*"|"*/"|"//" { *pCopyQuotedGString+=yytext; } \n { *pCopyQuotedGString+=*yytext; lineCount(); } . { *pCopyQuotedGString+=*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 { lineCount(); *pCopyRoundString+=*yytext; } \' { if (insidePHP) { current->initializer+=yytext; pCopyQuotedString = pCopyRoundString; lastStringContext=YY_START; BEGIN(CopyPHPString); } else { *pCopyRoundString+=yytext; } } {CHARLIT} { if (insidePHP) { REJECT; } else { *pCopyRoundString+=yytext; } } [^"'()\n]+ { *pCopyRoundString+=yytext; } . { *pCopyRoundString+=*yytext; } /* generic round bracket list copy rules for growable strings */ \" { *pCopyRoundGString+=*yytext; pCopyQuotedGString=pCopyRoundGString; lastStringContext=YY_START; BEGIN(CopyGString); } "(" { *pCopyRoundGString+=*yytext; roundCount++; } ")" { *pCopyRoundGString+=*yytext; if (--roundCount<0) BEGIN(lastRoundContext); } \n { lineCount(); *pCopyRoundGString+=*yytext; } \' { if (insidePHP) { current->initializer+=yytext; pCopyQuotedGString = pCopyRoundGString; lastStringContext=YY_START; BEGIN(CopyPHPGString); } else { *pCopyRoundGString+=yytext; } } {CHARLIT} { if (insidePHP) { REJECT; } else { *pCopyRoundGString+=yytext; } } [^"'()\n/]+ { *pCopyRoundGString+=yytext; } . { *pCopyRoundGString+=*yytext; } /* generic square bracket list copy rules for growable strings, we should only enter here in case of php, left the test part as in GCopyRound to keep it compatible with te round bracket version */ \" { *pCopySquareGString+=*yytext; pCopyQuotedGString=pCopySquareGString; lastStringContext=YY_START; BEGIN(CopyGString); } "[" { *pCopySquareGString+=*yytext; squareCount++; } "]" { *pCopySquareGString+=*yytext; if (--squareCount<0) BEGIN(lastSquareContext); } \n { lineCount(); *pCopySquareGString+=*yytext; } \' { if (insidePHP) { current->initializer+=yytext; pCopyQuotedGString = pCopySquareGString; lastStringContext=YY_START; BEGIN(CopyPHPGString); } else { *pCopySquareGString+=yytext; } } {CHARLIT} { if (insidePHP) { REJECT; } else { *pCopySquareGString+=yytext; } } [^"\[\]\n/]+ { *pCopySquareGString+=yytext; } . { *pCopySquareGString+=*yytext; } /* generic curly bracket list copy rules */ \" { *pCopyCurlyString+=*yytext; pCopyQuotedString=pCopyCurlyString; lastStringContext=YY_START; BEGIN(CopyString); } \' { *pCopyCurlyString+=*yytext; if (insidePHP) { pCopyQuotedString=pCopyCurlyString; lastStringContext=YY_START; BEGIN(CopyPHPString); } } "{" { *pCopyCurlyString+=*yytext; curlyCount++; } "}" { *pCopyCurlyString+=*yytext; if (--curlyCount<0) BEGIN(lastCurlyContext); } {CHARLIT} { if (insidePHP) { REJECT; } else { *pCopyCurlyString+=yytext; } } [^"'{}\/\n]+ { *pCopyCurlyString+=yytext; } "/" { *pCopyCurlyString+=yytext; } \n { lineCount(); *pCopyCurlyString+=*yytext; } . { *pCopyCurlyString+=*yytext; } /* generic curly bracket list copy rules for growable strings */ ^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker } ^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker QCString line = QCString(yytext); int s = line.find(' '); int e = line.find('"',s); yyLineNr = line.mid(s,e-s).toInt(); if (yytext[yyleng-1]=='\n') { lineCount(); g_column=0; } } \" { *pCopyCurlyGString+=*yytext; pCopyQuotedGString=pCopyCurlyGString; lastStringContext=YY_START; BEGIN(CopyGString); } \' { *pCopyCurlyGString+=*yytext; if (insidePHP) { pCopyQuotedGString=pCopyCurlyGString; lastStringContext=YY_START; BEGIN(CopyPHPGString); } } "{" { *pCopyCurlyGString+=*yytext; curlyCount++; } "}" { *pCopyCurlyGString+=*yytext; if (--curlyCount<0) BEGIN(lastCurlyContext); } {CHARLIT} { if (insidePHP) { REJECT; } else { *pCopyCurlyGString+=yytext; } } [^"'{}\/\n,]+ { *pCopyCurlyGString+=yytext; } [,]+ { *pCopyCurlyGString+=yytext; } "/" { *pCopyCurlyGString+=yytext; } \n { lineCount(); *pCopyCurlyGString+=*yytext; } . { *pCopyCurlyGString+=*yytext; } /* ---------------------- */ ":" { if (current->type.isEmpty() && current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}' { current->section=Entry::ENUM_SEC; current->name.resize(0); current->args.resize(0); BEGIN(EnumBaseType); } else { if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" { addType(current); current->name.sprintf("__pad%d__",padCount++); } BEGIN(BitFields); current->bitfields+=":"; } } . { current->bitfields+=*yytext; } . { current->args+=*yytext; } \n { lineCount(); current->args+=' '; } [;,] { QCString oldType = current->type; if (current->bodyLine==-1) { current->bodyLine = yyLineNr; } if ( insidePHP && current->type.left(3) == "var" ) { current->type = current->type.mid(3); } if (isTypedef && current->type.left(8)!="typedef ") { current->type.prepend("typedef "); } bool needNewCurrent=FALSE; if (!current->name.isEmpty() && current->section!=Entry::ENUM_SEC) { current->type=current->type.simplifyWhiteSpace(); current->args=removeRedundantWhiteSpace(current->args); current->name=current->name.stripWhiteSpace(); if (current->section==Entry::CLASS_SEC) // remove spec for "struct Bla bla;" { current->spec = 0; } current->section = Entry::VARIABLE_SEC ; current->fileName = yyFileName; current->startLine = yyBegLineNr; current->startColumn = yyBegColNr; current_root->addSubEntry( current ) ; needNewCurrent=TRUE; } if ( *yytext == ',') { bool stat = current->stat; if (needNewCurrent) { current = new Entry(*current); initEntry(); } current->stat = stat; // the static attribute holds for all variables current->name.resize(0); current->args.resize(0); current->brief.resize(0); current->doc.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 { mtype = Method; virt = Normal; if (needNewCurrent) { current = new Entry ; } else if (current->groups) { current->groups->clear(); } initEntry(); } } "[" { if (insideSlice) { squareCount=1; lastSquareContext = YY_START; current->metaData += "["; BEGIN( SliceMetadata ); } else if (!insideCS && (current->name.isEmpty() || current->name=="typedef" ) ) // IDL function property { squareCount=1; lastSquareContext = YY_START; idlAttr.resize(0); idlProp.resize(0); current->mtype = mtype; if (Config_getBool(IDL_PROPERTY_SUPPORT) && current->mtype == Property) { // we are inside the properties section of a dispinterface odlProp = true; current->spec |= Entry::Gettable; current->spec |= Entry::Settable; } BEGIN( IDLAttribute ); } else if (insideCS && current->name.isEmpty()) { squareCount=1; lastSquareContext = YY_START; // Skip the C# attribute // for this member current->args.resize(0); BEGIN( SkipSquare ); } else { current->args += yytext ; squareCount=1; externC=FALSE; // see bug759247 BEGIN( Array ) ; } } "[" { // Global metadata. squareCount++; current->metaData += "["; } {BN}* { lineCount(); } \"[^\"]*\" { current->metaData += yytext; } "," { current->metaData += yytext; } "]" { current->metaData += yytext; if (--squareCount<=0) { BEGIN (lastSquareContext); } } "(" { current->type += "("; roundCount++; } [0-9]+ { current->type += yytext; } ")" { current->type += ")"; if(--roundCount<=0) { BEGIN (lastModifierContext); } } "]" { // end of IDL function attribute if (--squareCount<=0) { lineCount(); if (current->mtype == Property) BEGIN( IDLPropName ); else BEGIN( lastSquareContext ); } } "propput" { if (Config_getBool(IDL_PROPERTY_SUPPORT)) { current->mtype = Property; } current->spec |= Entry::Settable; } "propget" { if (Config_getBool(IDL_PROPERTY_SUPPORT)) { current->mtype = Property; } current->spec |= Entry::Gettable; } "property" { // UNO IDL property current->spec |= Entry::Property; } "attribute" { // UNO IDL attribute current->spec |= Entry::Attribute; } "optional" { // on UNO IDL interface/service/attribute/property current->spec |= Entry::Optional; } "readonly" { // on UNO IDL attribute or property if (Config_getBool(IDL_PROPERTY_SUPPORT) && odlProp) { current->spec ^= Entry::Settable; } else { current->spec |= Entry::Readonly; } } "bound" { // on UNO IDL attribute or property current->spec |= Entry::Bound; } "removable" { // on UNO IDL property current->spec |= Entry::Removable; } "constrained" { // on UNO IDL property current->spec |= Entry::Constrained; } "transient" { // on UNO IDL property current->spec |= Entry::Transient; } "maybevoid" { // on UNO IDL property current->spec |= Entry::MaybeVoid; } "maybedefault" { // on UNO IDL property current->spec |= Entry::MaybeDefault; } "maybeambiguous" { // on UNO IDL property current->spec |= Entry::MaybeAmbiguous; } . { } {BN}*{ID}{BN}* { // return type (probably HRESULT) - skip it if (odlProp) { // property type idlProp = yytext; } } {ID}{BN}*"(" { current->name = yytext; current->name = current->name.left(current->name.length()-1).stripWhiteSpace(); current->startLine = yyLineNr; current->startColumn = yyColNr; BEGIN( IDLProp ); } {BN}*"("{BN}*{ID}{BN}*")"{BN}* { if (odlProp) { idlProp += yytext; } } {ID}{BN}*/";" { if (odlProp) { current->name = yytext; idlProp = idlProp.stripWhiteSpace(); odlProp = false; BEGIN( IDLProp ); } } {BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter idlAttr = yytext; idlAttr=idlAttr.stripWhiteSpace(); } {ID} { // property type idlProp = yytext; } {BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);) if (!current->args) current->args = "("; else current->args += ", "; current->args += idlAttr; current->args += " "; current->args += idlProp; // prop was actually type of extra parameter current->args += " "; current->args += yytext; current->args = current->args.left(current->args.length() - 1); // strip comma idlProp.resize(0); idlAttr.resize(0); BEGIN( IDLProp ); } {BN}*{ID}{BN}*")"{BN}* { // the parameter name for the property - just skip. } ";" { current->fileName = yyFileName; current->type = idlProp; current->args = current->args.simplifyWhiteSpace(); if (current->args) current->args += ")"; current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; current_root->addSubEntry(current); current = new Entry; initEntry(); BEGIN( FindMembers ); } . { // spaces, *, or other stuff //idlProp+=yytext; } "]" { current->args += *yytext ; if (--squareCount<=0) BEGIN( FindMembers ) ; } "]" { current->args += *yytext ; if (--squareCount<=0) BEGIN( Function ) ; } "[" { 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}+ { current->type += ' '; lineCount(); } . { current->type += *yytext ; } {ID} { if (insideCpp || insideObjC) { current->id = ClangParser::instance()->lookup(yyLineNr,yytext); } current->bodyLine = yyLineNr; current->name = yytext; } "(" { // Java enum initializer unput('('); lastInitializerContext = YY_START; initBracketCount=0; current->initializer = "="; BEGIN(ReadInitializer); } "=" { lastInitializerContext = YY_START; initBracketCount=0; current->initializer = yytext; BEGIN(ReadInitializer); } ";" { if (insideJava) // last enum field in Java class { if (!current->name.isEmpty()) { current->fileName = yyFileName; current->startLine = yyLineNr; current->startColumn = yyColNr; if (!(current_root->spec&Entry::Enum)) { current->type = "@"; // enum marker } current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; current_root->addSubEntry(current); current = new Entry ; initEntry(); } BEGIN( FindMembers ); } else { REJECT; } } \n { lineCount(); } [^\n]* "," { //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->startColumn = yyColNr; if (!(current_root->spec&Entry::Enum)) { 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); if (!insideCS && !insideJava && !(current_root->spec&Entry::Strong)) // for C# and Java 1.5+ enum values always have to be explicitly qualified, // same for C++11 style enums (enum class Name {}) { 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(); initEntry(); } } "[" { // attribute list in IDL squareCount=1; lastSquareContext = YY_START; BEGIN(SkipSquare); } /* "," { unput(*yytext); BEGIN(FindFields); } */ [^\r\n\#{}"@'/<]* { current->program += yytext ; } "//".* { current->program += yytext ; } "#".* { if (!insidePHP) REJECT; // append PHP comment. current->program += yytext ; } @\" { current->program += yytext ; pSkipVerbString = ¤t->program; lastSkipVerbStringContext=YY_START; BEGIN( SkipVerbString ); } "<<<" { if (insidePHP) { current->program += yytext ; pCopyHereDocGString = ¤t->program; lastHereDocContext=YY_START; BEGIN( CopyHereDoc ); } else { REJECT; } } \" { current->program += yytext ; pCopyQuotedGString = ¤t->program; lastStringContext=YY_START; BEGIN( CopyGString ); } "/*"{B}* { current->program += yytext ; lastContext = YY_START ; BEGIN( Comment ) ; } "/*"{BL} { current->program += yytext ; ++yyLineNr ; lastContext = YY_START ; BEGIN( Comment ) ; } "'" { if (!insidePHP) { current->program += yytext; } else { // begin of single quoted string current->program += yytext; pCopyQuotedGString = ¤t->program; lastStringContext=YY_START; BEGIN(CopyPHPGString); } } {CHARLIT} { if (insidePHP) { REJECT; // for PHP code single quotes // are used for strings of arbitrary length } else { current->program += yytext; } } "{" { current->program += yytext ; ++curlyCount ; } "}" { current->program += yytext ; --curlyCount ; } "}" { //err("ReadBody count=%d\n",curlyCount); if ( curlyCount>0 ) { current->program += yytext ; --curlyCount ; } else { current->endBodyLine = yyLineNr; Entry * original_root = current_root; // save root this namespace is in if (current->section == Entry::NAMESPACE_SEC && current->type == "namespace") { int split_point; while ((split_point = current->name.find("::")) != -1) { Entry *new_current = new Entry(*current); current->program = ""; new_current->doc = ""; new_current->docLine = 0; new_current->docFile = ""; new_current->brief = ""; new_current->briefLine = 0; new_current->briefFile = ""; new_current->name = current->name.mid(split_point + 2); current->name = current->name.left(split_point); if (!current_root->name.isEmpty()) current->name.prepend(current_root->name+"::"); current_root->addSubEntry(current); current_root = current; current = new_current; } } QCString &cn = current->name; QCString rn = current_root->name.copy(); //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef); if (!cn.isEmpty() && !rn.isEmpty()) { prependScope(); } if (isTypedef && cn.isEmpty()) { //printf("Typedef Name\n"); BEGIN( TypedefName ); } else { if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum)) { current->program+=','; // add field terminator } // add compound definition to the tree current->args=removeRedundantWhiteSpace(current->args); // was: current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); //printf("adding `%s' `%s' `%s' brief=%s insideObjC=%d %x\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data(),insideObjC,current->section); if (insideObjC && ((current->spec&Entry::Interface) || (current->spec==Entry::Category)) ) // method definition follows { BEGIN( ReadBodyIntf ) ; } else { current_root->addSubEntry( current ) ; memspecEntry = current; current = new Entry(*current); if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || insideJava || insidePHP || insideCS || insideD || insideJS || insideSlice ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); current_root = original_root; // restore scope from before namespace descent initEntry(); memspecEntry = 0; BEGIN( FindMembers ) ; } else { static QRegExp re("@[0-9]+$"); if (!isTypedef && memspecEntry && memspecEntry->name.find(re)==-1) // not typedef or anonymous type (see bug691071) { // enabled the next two lines for bug 623424 current->doc.resize(0); current->brief.resize(0); } BEGIN( MemberSpec ) ; } } } } } "}"{BN}+"typedef"{BN}+ { //err("ReadBody count=%d\n",curlyCount); lineCount(); if ( curlyCount>0 ) { current->program += yytext ; --curlyCount ; } else { isTypedef = TRUE; current->endBodyLine = yyLineNr; QCString &cn = current->name; QCString rn = current_root->name.copy(); if (!cn.isEmpty() && !rn.isEmpty()) { prependScope(); } BEGIN( TypedefName ); } } ("const"|"volatile"){BN} { // late "const" or "volatile" keyword lineCount(); current->type.prepend(yytext); } {ID} { if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum)) { 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 ) ; if (!firstTypedefEntry) { firstTypedefEntry = current; } current = new Entry; initEntry(); isTypedef=TRUE; // to undo reset by initEntry() BEGIN(MemberSpecSkip); } ";" { /* typedef of anonymous type */ current->name.sprintf("@%d",anonCount++); if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum)) { current->program+=','; // add field terminator } // add compound definition to the tree current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); current_root->addSubEntry( current ) ; memspecEntry = current; current = new Entry(*current); initEntry(); unput(';'); BEGIN( MemberSpec ) ; } ([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved. lineCount(); int i=0,l=(int)yyleng,j; while (ispec&Entry::Struct) { msType.prepend("struct "+firstTypedefEntry->name); } else if (firstTypedefEntry->spec&Entry::Union) { msType.prepend("union "+firstTypedefEntry->name); } else if (firstTypedefEntry->section==Entry::ENUM_SEC) { msType.prepend("enum "+firstTypedefEntry->name); } else { msType.prepend(firstTypedefEntry->name); } } } "(" { // function with struct return type addType(current); current->name = msName; current->spec = 0; unput('('); BEGIN(FindMembers); } [,;] { if (msName.isEmpty() && !current->name.isEmpty()) { // see if the compound does not have a name or is inside another // anonymous compound. If so we insert a // special `anonymous' variable. //Entry *p=current_root; Entry *p=current; 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)=='@') { // anonymous compound inside -> insert dummy variable name //printf("Adding anonymous variable for scope %s\n",p->name.data()); msName.sprintf("@%d",anonCount++); break; } } //p=p->parent; if (p==current) p=current_root; else p=p->parent(); } } //printf("msName=%s current->name=%s\n",msName.data(),current->name.data()); if (!msName.isEmpty() /*&& msName!=current->name*/) // skip typedef T {} T;, removed due to bug608493 { static bool typedefHidesStruct = Config_getBool(TYPEDEF_HIDES_STRUCT); // case 1: typedef struct _S { ... } S_t; // -> omit typedef and use S_t as the struct name if (typedefHidesStruct && isTypedef && ((current->spec&(Entry::Struct|Entry::Union)) || current->section==Entry::ENUM_SEC )&& msType.stripWhiteSpace().isEmpty() && memspecEntry) { memspecEntry->name=msName; } else // case 2: create a typedef field { Entry *varEntry=new Entry; varEntry->lang = language; 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; if (isTypedef) { varEntry->type.prepend("typedef "); // //printf("current->name = %s %s\n",current->name.data(),msName.data()); } if (typedefHidesStruct && isTypedef && (current->spec&(Entry::Struct|Entry::Union)) && memspecEntry ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;" { varEntry->type+=memspecEntry->name+msType; } else // case 2: use _S as type for for pS_t { varEntry->type+=current->name+msType; } varEntry->fileName = yyFileName; varEntry->startLine = yyLineNr; varEntry->startColumn = yyColNr; varEntry->doc = current->doc.copy(); varEntry->brief = current->brief.copy(); varEntry->mGrpId = current->mGrpId; varEntry->initializer = current->initializer; // deep copy group list QListIterator gli(*current->groups); Grouping *g; for (;(g=gli.current());++gli) { varEntry->groups->append(new Grouping(*g)); } if (current->sli) // copy special list items { QListIterator li(*current->sli); ListItemInfo *lii; for (li.toFirst();(lii=li.current());++li) { varEntry->addSpecialListItem(lii->type,lii->itemId); } } //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n", // varEntry->type.data(),varEntry->name.data(), // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); current_root->addSubEntry(varEntry); } } if (*yytext==';') // end of a struct/class ... { if (!isTypedef && msName.isEmpty() && memspecEntry && (current->section&Entry::COMPOUND_MASK)) { // case where a class/struct has a doc block after it if (!current->doc.isEmpty()) { memspecEntry->doc += current->doc; } if (!current->brief.isEmpty()) { memspecEntry->brief += current->brief; } } msType.resize(0); msName.resize(0); msArgs.resize(0); isTypedef=FALSE; firstTypedefEntry=0; memspecEntry=0; current->reset(); initEntry(); BEGIN( FindMembers ); } else { current->doc.resize(0); current->brief.resize(0); } } "=" { lastInitializerContext=YY_START; initBracketCount=0; current->initializer = yytext; BEGIN(ReadInitializer); /* BEGIN(MemberSpecSkip); */ } /* "{" { curlyCount=0; lastCurlyContext = MemberSpecSkip; previous = current; BEGIN(SkipCurly); } */ "," { BEGIN(MemberSpec); } ";" { unput(';'); BEGIN(MemberSpec); } {BN}{1,80} { current->program += yytext ; lineCount() ; } "@end"/[^a-z_A-Z0-9] { // end of Objective C block current_root->addSubEntry( current ) ; current=new Entry; initEntry(); language = current->lang = SrcLangExt_Cpp; // see bug746361 insideObjC=FALSE; BEGIN( FindMembers ); } . { current->program += yytext ; } "("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A::func_t)(args...) */ ("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */ if (insidePHP) // reference parameter { REJECT } else { current->bodyLine = yyLineNr; lineCount(); addType(current); funcPtrType=yytext; roundCount=0; //current->type += yytext; BEGIN( FuncPtr ); } } {SCOPENAME} { current->name = yytext; if (nameIsOperator(current->name)) { BEGIN( FuncPtrOperator ); } else { 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}*")"{BN}*/"(" { current->name += yytext; current->name = current->name.simplifyWhiteSpace(); lineCount(); } \n { lineCount(); current->name += *yytext; } "(" { unput(*yytext); BEGIN( EndFuncPtr ); } . { current->name += *yytext; } ")"{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 or // a function returning a pointer to an array current->args += *yytext ; //roundCount=0; //BEGIN( FuncFunc ); current->bodyLine = yyLineNr; currentArgumentContext = FuncFuncEnd; fullArgString=current->args.copy(); copyArgString=¤t->args; BEGIN( ReadFuncArgType ) ; } "["[^\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); } ")"{BN}*/"[" { // function returning a pointer to an array lineCount(); current->type+=funcPtrType; current->args+=")"; BEGIN(FuncFuncArray); } . { 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; } "("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")"{BN}*"(" { // for catching typedef void (__stdcall *f)() like definitions if (current->type.left(7)=="typedef" && current->bodyLine==-1) // the bodyLine check is to prevent this guard to be true more than once { current->bodyLine = yyLineNr; BEGIN( GetCallType ); } else if (!current->name.isEmpty()) // normal function { current->args = yytext; current->bodyLine = yyLineNr; currentArgumentContext = FuncQual; fullArgString=current->args.copy(); copyArgString=¤t->args; BEGIN( ReadFuncArgType ) ; //printf(">>> Read function arguments!\n"); } } {BN}*{ID}{BN}*"*" { lineCount(); addType(current); funcPtrType="("; funcPtrType+=yytext; roundCount=0; BEGIN( FuncPtr ); } "(" { 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 current->argList->count()=%d\n",current->argList->count()); } } /* "("{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(); } {RAWBEGIN} { g_delimiter = yytext+2; g_delimiter=g_delimiter.left(g_delimiter.length()-1); lastRawStringContext = YY_START; pCopyRawString = copyArgString; *pCopyRawString+=yytext; fullArgString+=yytext; BEGIN(RawString); } \" { *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); if (insideJS) { fixArgumentListForJavaScript(current->argList); } handleParametersCommentBlocks(current->argList); /* remember the current documentation block, since we could overwrite it with the documentation of a function argument, which we then have to correct later on */ docBackup = current->doc; briefBackup = current->brief; BEGIN( currentArgumentContext ); } /* a special comment */ ("/*"[*!]|"//"[/!])("<"?) { if (currentArgumentContext==DefineEnd) { // for defines we interpret a comment // as documentation for the define int i;for (i=(int)yyleng-1;i>=0;i--) { unput(yytext[i]); } stringToArgumentList(fullArgString,current->argList); handleParametersCommentBlocks(current->argList); BEGIN( currentArgumentContext ); } else // not a define { // for functions we interpret a comment // as documentation for the argument fullArgString+=yytext; lastCopyArgChar=0; lastCommentInArgContext=YY_START; if (yytext[1]=='/') BEGIN( CopyArgCommentLine ); else BEGIN( CopyArgComment ); } } /* a non-special comment */ "/**/" { /* empty comment */ } "/*" { lastCContext = YY_START; BEGIN( SkipComment ); } "//" { lastCContext = YY_START; BEGIN( SkipCxxComment ); } /* "'#" { if (insidePHP) REJECT; *copyArgString+=yytext; fullArgString+=yytext; } "#" { if (!insidePHP) REJECT; lastCContext = YY_START; BEGIN( SkipCxxComment ); } */ /* `)' followed by a special comment */ ")"{BN}*("/*"[*!]|"//"[/!])"<" { lineCount(); if (currentArgumentContext==DefineEnd) { // for defines we interpret a comment // as documentation for the define int i;for (i=(int)yyleng-1;i>0;i--) { unput(yytext[i]); } *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); handleParametersCommentBlocks(current->argList); BEGIN( currentArgumentContext ); } else { // for functions we interpret a comment // as documentation for the last argument lastCopyArgChar=*yytext; QCString text=&yytext[1]; text=text.stripWhiteSpace(); lastCommentInArgContext=YY_START; fullArgString+=text; if (text.find("//")!=-1) BEGIN( CopyArgCommentLine ); else BEGIN( CopyArgComment ); } } ^{B}*"*"+/{BN}+ [^\n\\\@\*]+ { fullArgString+=yytext; } "*/" { fullArgString+=yytext; if (lastCopyArgChar!=0) unput(lastCopyArgChar); BEGIN( lastCommentInArgContext ); } \n { fullArgString+=yytext; lineCount(); if (lastCopyArgChar!=0) unput(lastCopyArgChar); BEGIN( lastCommentInArgContext ); } {CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) docBlockName=&yytext[1]; fullArgString+=yytext; BEGIN(CopyArgVerbatim); } {CMD}("f$"|"f["|"f{") { docBlockName=&yytext[1]; if (docBlockName.at(1)=='[') { docBlockName.at(1)='}'; } if (docBlockName.at(1)=='{') { docBlockName.at(1)='}'; } fullArgString+=yytext; BEGIN(CopyArgVerbatim); } [\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9\-] { // end of verbatim block fullArgString+=yytext; if (yytext[1]=='f') // end of formula { BEGIN(CopyArgCommentLine); } if (&yytext[4]==docBlockName) { BEGIN(CopyArgCommentLine); } } [^\\\@\n]+ { fullArgString+=yytext; } . { fullArgString+=*yytext; } \n { fullArgString+=*yytext; lineCount(); } . { fullArgString+=*yytext; } {CMD}("brief"|"short"){B}+ { warn(yyFileName,yyLineNr, "Ignoring %cbrief command inside argument documentation",*yytext ); fullArgString+=' '; } "<" { *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 ); } "(" { *copyArgString+=*yytext; fullArgString+=*yytext; argRoundCount=0; lastCopyArgContext = YY_START; BEGIN( CopyArgRound ); } "<" { 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 ); } \' { *copyArgString+=*yytext; fullArgString+=*yytext; BEGIN( lastCopyArgStringContext ); } {CHARLIT} { if (insidePHP) { REJECT; } else { *copyArgString+=yytext; fullArgString+=yytext; } } \' { *copyArgString+=yytext; fullArgString+=yytext; if (insidePHP) { lastCopyArgStringContext=YY_START; BEGIN(CopyArgPHPString); } } \n { lineCount(); *copyArgString+=*yytext; fullArgString+=*yytext; } . { *copyArgString+=*yytext; fullArgString+=*yytext; } /*------------------------------------------------------------------------*/ "(" { current->args += *yytext ; ++roundCount ; } ")" { current->args += *yytext ; if ( roundCount ) --roundCount ; else BEGIN( FuncQual ) ; } /* "#" { if (insidePHP) REJECT; lastCPPContext = YY_START; BEGIN(SkipCPP); } */ [{:;,] { if ( qstrcmp(yytext,";")==0 && insidePHP && !containsWord(current->type,"function") ) { current->reset(); initEntry(); BEGIN( FindMembers ); } else { unput(*yytext); BEGIN( Function ); } } {BN}*"abstract"{BN}* { // pure virtual member function lineCount() ; current->virt = Pure; current->args += " override "; } {BN}*"override"{BN}* { // C++11 overridden virtual member function lineCount() ; current->spec |= Entry::Override; current->args += " override "; BEGIN(FuncQual); } {BN}*"final"{BN}* { // C++11 final method lineCount() ; current->spec |= Entry::Final; current->args += " final "; BEGIN(FuncQual); } {BN}*"sealed"{BN}* { // sealed member function lineCount() ; current->spec |= Entry::Sealed; current->args += " sealed "; } {BN}*"new"{BN}* { // new member function lineCount() ; current->spec |= Entry::New; current->args += " new "; } {BN}*"const"{BN}* { // const member function lineCount() ; current->args += " const "; current->argList->constSpecifier=TRUE; } {BN}*"volatile"{BN}* { // volatile member function lineCount() ; current->args += " volatile "; current->argList->volatileSpecifier=TRUE; } {BN}*"noexcept"{BN}* { // noexcept qualifier lineCount() ; current->args += " noexcept "; current->spec |= Entry::NoExcept; } {BN}*"noexcept"{BN}*"(" { // noexcept expression lineCount() ; current->args += " noexcept("; current->spec |= Entry::NoExcept; lastRoundContext=FuncQual; pCopyRoundString=¤t->args; roundCount=0; BEGIN(CopyRound); } {BN}*"&" { current->args += " &"; current->argList->refQualifier=RefQualifierLValue; } {BN}*"&&" { current->args += " &&"; current->argList->refQualifier=RefQualifierRValue; } {BN}*"="{BN}*"0"{BN}* { // pure virtual member function lineCount() ; current->args += " = 0"; current->virt = Pure; current->argList->pureSpecifier=TRUE; BEGIN(FuncQual); } {BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member lineCount(); current->args += " = delete"; current->spec |= Entry::Delete; current->argList->isDeleted=TRUE; BEGIN(FuncQual); } {BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator lineCount(); current->args += " = default"; current->spec |= Entry::Default; BEGIN(FuncQual); } {BN}*"->"{BN}* { lineCount(); current->argList->trailingReturnType = " -> "; current->args += " -> "; BEGIN(TrailingReturn); } [{;] { unput(*yytext); BEGIN(FuncQual); } . { current->argList->trailingReturnType+=yytext; current->args+=yytext; } \n { lineCount(); current->argList->trailingReturnType+=yytext; current->args+=' '; } {BN}*","{BN}* { lineCount() ; current->args += ", " ; } {BN}+ { lineCount() ; current->args += ' ' ; } "#" { if (insidePHP) REJECT; lastCPPContext = YY_START; BEGIN(SkipCPP); } "=" { if (insideCli && (current_root->section&Entry::COMPOUND_MASK) ) { BEGIN(CliOverride); } else { // typically an initialized function pointer lastInitializerContext=YY_START; initBracketCount=0; current->initializer = yytext; BEGIN(ReadInitializer); } } {ID} { } "{" { unput(*yytext); BEGIN(FuncQual); } \n { lineCount(); } . { } [{;] { unput(*yytext); BEGIN(FuncQual); } \" { current->args += *yytext; pCopyQuotedString=¤t->args; lastStringContext=FuncPtrInit; BEGIN(CopyString); } \' { current->args += *yytext; if (insidePHP) { pCopyQuotedString=¤t->args; lastStringContext=FuncPtrInit; BEGIN(CopyPHPString); } } {CHARLIT} { if (insidePHP) { REJECT; } else { current->args += yytext; } } {ID} { current->args += yytext; } . { current->args += *yytext; } \n { current->args += *yytext; lineCount(); } {ID} { // typically a K&R style C function if (insideCS && qstrcmp(yytext,"where")==0) { // type constraint for a method delete current->typeConstr; current->typeConstr = new ArgumentList; current->typeConstr->append(new Argument); lastCSConstraint = YY_START; BEGIN( CSConstraintName ); } else if (checkForKnRstyleC()) { current->args = yytext; oldStyleArgType.resize(0); BEGIN(OldStyleArgs); } else { current->args += yytext; } } [,;] { QCString oldStyleArgPtr; QCString oldStyleArgName; splitKnRArg(oldStyleArgPtr,oldStyleArgName); QCString doc,brief; if (current->doc!=docBackup) { doc=current->doc.copy(); current->doc=docBackup; } if (current->brief!=briefBackup) { brief=current->brief.copy(); current->brief=briefBackup; } addKnRArgInfo(oldStyleArgType+oldStyleArgPtr, oldStyleArgName,brief,doc); current->args.resize(0); if (*yytext==';') oldStyleArgType.resize(0); } {ID} { current->args += yytext; } "{" { current->args = argListToString(current->argList); unput('{'); BEGIN(FuncQual); } . { current->args += *yytext; } . { current->args += *yytext; } {BN}*"try:" | {BN}*"try"{BN}+ { /* try-function-block */ insideTryBlock=TRUE; lineCount(); if (yytext[yyleng-1]==':') { unput(':'); BEGIN( Function ); } } {BN}*"throw"{BN}*"(" { // C++ style throw clause current->exception = " throw (" ; roundCount=0; lineCount() ; BEGIN( ExcpRound ) ; } {BN}*"raises"{BN}*"(" { current->exception = " raises (" ; lineCount() ; roundCount=0; BEGIN( ExcpRound ) ; } {BN}*"throws"{BN}+ { // Java style throw clause current->exception = " throws " ; lineCount() ; BEGIN( ExcpList ); } "(" { current->exception += *yytext ; ++roundCount ; } ")" { current->exception += *yytext ; if ( roundCount ) --roundCount ; else BEGIN( FuncQual ) ; } . { current->exception += *yytext; } "{" { unput('{'); BEGIN( FuncQual ); } ";" { unput(';'); BEGIN( FuncQual ); } "\n" { current->exception += ' '; lineCount(); } . { current->exception += *yytext; } "(" { current->type += current->name ; current->name = current->args ; current->args = yytext ; roundCount=0; BEGIN( FuncRound ) ; } ":" { if (!insidePHP) BEGIN(SkipInits); } [;{,] { current->name=current->name.simplifyWhiteSpace(); current->type=current->type.simplifyWhiteSpace(); current->args=removeRedundantWhiteSpace(current->args); // was: current->args.simplifyWhiteSpace(); current->fileName = yyFileName; current->startLine = yyBegLineNr; current->startColumn = yyBegColNr; static QRegExp re("([^)]*[*&][^)]*)"); // (...*...) if (*yytext!=';' || (current_root->section&Entry::COMPOUND_MASK) ) { int tempArg=current->name.find('<'); int ts=current->type.find('<'); int te=current->type.findRev('>'); int ti=current->type.find(re,0); // bug677315: A get(); is not a function pointer bool isFunction = ti==-1 || // not a (...*...) pattern (ts!=-1 && tstype.data(),ts,te,ti,isFunction); QCString tempName; if (tempArg==-1) tempName=current->name; else tempName=current->name.left(tempArg); if (!current->type.isEmpty() && (!isFunction || current->type.left(8)=="typedef ")) { //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data()); if (isTypedef && current->type.left(8)!="typedef ") { current->type.prepend("typedef "); } 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 ; current->proto = *yytext==';'; } } 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()); if (!current->type.isEmpty() && (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef ")) { if (isTypedef && current->type.left(8)!="typedef ") { current->type.prepend("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'\n",current->name.data()); if ( insidePHP) { if (findAndRemoveWord(current->type,"final")) { current->spec |= Entry::Final; } if (findAndRemoveWord(current->type,"abstract")) { current->spec |= Entry::Abstract; } } if ( insidePHP && !containsWord(current->type,"function")) { initEntry(); if ( *yytext == '{' ) { lastCurlyContext = FindMembers; curlyCount=0; BEGIN( SkipCurly ); } else { BEGIN( FindMembers ); } } else { if ( insidePHP) { findAndRemoveWord(current->type,"function"); } previous = current; current_root->addSubEntry(current); current = new Entry ; initEntry(); // Objective C 2.0: Required/Optional section if (previous->spec & (Entry::Optional | Entry::Required)) { current->spec |= previous->spec & (Entry::Optional|Entry::Required); } lastCurlyContext = FindMembers; if ( *yytext == ',' ) { current->type = previous->type; // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases) int i=current->type.length(); while (i>0 && (current->type[i-1]=='*' || current->type[i-1]=='&' || current->type[i-1]==' ')) i--; current->type = current->type.left(i); } if ( *yytext == '{' ) { if ( !insidePHP && (current_root->section & Entry::COMPOUND_MASK) ) { previous->spec |= Entry::Inline; } //addToBody(yytext); curlyCount=0; BEGIN( SkipCurly ) ; } else { if (previous->section!=Entry::VARIABLE_SEC) previous->bodyLine=-1; // a function/member declaration BEGIN( FindMembers ) ; } } } ">"{BN}*"{" { // C++11 style initializer (see bug 790788) lineCount(); curlyCount=1; BEGIN(SkipC11Inits); } {ID}{BN}*"{" { // C++11 style initializer (see bug 688647) lineCount(); curlyCount=1; BEGIN(SkipC11Inits); } "{" { ++curlyCount; } "}" { if ( --curlyCount<=0 ) { BEGIN(SkipInits); } } "]]" { BEGIN(lastC11AttributeContext); } "{" { // C++11 style initializer unput('{'); BEGIN( Function ); } "{" { //addToBody(yytext); ++curlyCount ; } "}"/{BN}*("/*!"|"/**"|"//!"|"///")" Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC); //current->reset(); if (current) delete current; current = new Entry; gstat = FALSE; initEntry(); // deep copy group list from parent (see bug 727732) static bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS); if (autoGroupNested && rt->groups && ce->section!=Entry::ENUM_SEC && !(ce->spec&Entry::Enum)) { QListIterator gli(*rt->groups); Grouping *g; for (;(g=gli.current());++gli) { ce->groups->append(new Grouping(*g)); } } int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2; // set default protection based on the compound type if( ce->section==Entry::CLASS_SEC ) // class { if (insidePHP || insideD || insideJS || insideIDL || insideSlice) { current->protection = protection = Public ; } else if (insideJava) { current->protection = protection = (ce->spec & (Entry::Interface|Entry::Enum)) ? Public : Package; } else if (ce->spec&(Entry::Interface | Entry::Ref | Entry::Value | Entry::Struct | Entry::Union)) { if (ce->lang==SrcLangExt_ObjC) { current->protection = protection = Protected ; } else { current->protection = protection = Public ; } } else { 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(ni)=='@') // unnamed union or namespace { if (ce->section == Entry::NAMESPACE_SEC ) // unnamed namespace { current->stat = gstat = TRUE; } current->protection = protection = ce->protection; } else // named struct, union, protocol, category { current->protection = protection = Public ; } mtype = Method; virt = Normal; //printf("name=%s current->stat=%d gstat=%d\n",ce->name.data(),current->stat,gstat); //memberGroupId = DOX_NOGROUP; //memberGroupRelates.resize(0); //memberGroupInside.resize(0); groupEnterCompound(yyFileName,yyLineNr,ce->name); scannerYYlex() ; g_lexInit=TRUE; //forceEndGroup(); groupLeaveCompound(yyFileName,yyLineNr,ce->name); 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); } } //---------------------------------------------------------------------------- static void parseMain(const char *fileName, const char *fileBuf, Entry *rt, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { initParser(); inputString = fileBuf; inputPosition = 0; g_column = 0; //anonCount = 0; // don't reset per file //depthIf = 0; protection = Public; mtype = Method; gstat = FALSE; virt = Normal; current_root = rt; global_root = rt; inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { yyLineNr= 1 ; yyFileName = fileName; setContext(); bool processWithClang = insideCpp || insideObjC; if (processWithClang) { if (!sameTranslationUnit) // new file { ClangParser::instance()->start(fileName,filesInSameTranslationUnit); } else { ClangParser::instance()->switchToFile(fileName); } } rt->lang = language; msg("Parsing file %s...\n",yyFileName.data()); current_root = rt ; initParser(); groupEnterFile(yyFileName,yyLineNr); current = new Entry; //printf("current=%p current_root=%p\n",current,current_root); int sec=guessSection(yyFileName); if (sec) { current->name = yyFileName; current->section = sec; current_root->addSubEntry(current); current = new Entry; } current->reset(); initEntry(); scannerYYrestart( scannerYYin ); if ( insidePHP ) { BEGIN( FindMembersPHP ); } else { BEGIN( FindMembers ); } scannerYYlex(); g_lexInit=TRUE; if (YY_START==Comment) { warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?"); } //forceEndGroup(); groupLeaveFile(yyFileName,yyLineNr); //if (depthIf>0) //{ // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); //} rt->program.resize(0); if (rt->children()->contains(current)==0) // it could be that current is already added as a child to rt, so we // only delete it if this is not the case. See bug 635317. { delete current; current=0; } parseCompounds(rt); inputFile.close(); anonNSCount++; } } //---------------------------------------------------------------------------- static void parsePrototype(const QCString &text) { //printf("**** parsePrototype(%s) begin\n",text.data()); if (text.isEmpty()) { warn(yyFileName,yyLineNr,"Empty prototype found!"); return; } if (!current) // nothing to store (see bug683516) { return; } const char *orgInputString; int orgInputPosition; YY_BUFFER_STATE orgState; // save scanner state orgState = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(scannerYYin, YY_BUF_SIZE)); orgInputString = inputString; orgInputPosition = inputPosition; // set new string inputString = text; inputPosition = 0; g_column = 0; scannerYYrestart( scannerYYin ); BEGIN(Prototype); scannerYYlex(); g_lexInit=TRUE; current->name = current->name.stripWhiteSpace(); if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty()) current->section = Entry::VARIABLEDOC_SEC; // restore original scanner state YY_BUFFER_STATE tmpState = YY_CURRENT_BUFFER; yy_switch_to_buffer(orgState); yy_delete_buffer(tmpState); inputString = orgInputString; inputPosition = orgInputPosition; //printf("**** parsePrototype end\n"); } void scanFreeScanner() { #if defined(YY_FLEX_SUBMINOR_VERSION) if (g_lexInit) { scannerYYlex_destroy(); } #endif } //static void handleGroupStartCommand(const char *header) //{ // memberGroupHeader=header; // startGroupInDoc(); //} // //static void handleGroupEndCommand() //{ // endGroup(); // previous=0; //} //---------------------------------------------------------------------------- void CLanguageScanner::startTranslationUnit(const char *) { } void CLanguageScanner::finishTranslationUnit() { bool processWithClang = insideCpp || insideObjC; if (processWithClang) { ClangParser::instance()->finish(); } } void CLanguageScanner::parseInput(const char *fileName, const char *fileBuf, Entry *root, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { g_thisParser = this; printlex(yy_flex_debug, TRUE, __FILE__, fileName); ::parseMain(fileName,fileBuf,root, sameTranslationUnit,filesInSameTranslationUnit); printlex(yy_flex_debug, FALSE, __FILE__, fileName); } void CLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, const char * scopeName, const QCString & input, SrcLangExt lang, bool isExampleBlock, const char * exampleName, FileDef * fileDef, int startLine, int endLine, bool inlineFragment, const MemberDef *memberDef, bool showLineNumbers, const Definition *searchCtx, bool collectXRefs ) { ::parseCCode(codeOutIntf,scopeName,input,lang,isExampleBlock,exampleName, fileDef,startLine,endLine,inlineFragment,memberDef, showLineNumbers,searchCtx,collectXRefs); } bool CLanguageScanner::needsPreprocessing(const QCString &extension) { QCString fe=extension.lower(); SrcLangExt lang = getLanguageFromFileName(extension); return (SrcLangExt_Cpp == lang) || !( fe==".java" || fe==".as" || fe==".d" || fe==".php" || fe==".php4" || fe==".inc" || fe==".phtml" ); } void CLanguageScanner::resetCodeParserState() { ::resetCCodeParserState(); } void CLanguageScanner::parsePrototype(const char *text) { ::parsePrototype(text); } //---------------------------------------------------------------------------- #if !defined(YY_FLEX_SUBMINOR_VERSION) //---------------------------------------------------------------------------- extern "C" { // some bogus code to keep the compiler happy void scannerYYdummy() { yy_flex_realloc(0,0); } } #endif