/***************************************************************************** * * Copyright (C) 1997-2021 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" %option reentrant %option extra-type="struct scannerYY_state *" %top{ #include } %{ /* * 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 "arguments.h" #include "clangparser.h" #include "markdown.h" #include "regex.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 #define USE_STATE2STRING 0 static AtomicInt anonCount; static AtomicInt anonNSCount; struct scannerYY_state { scannerYY_state() : docBlock(std::ios_base::ate) {} OutlineParserInterface *thisParser; CommentScanner commentScanner; const char * inputString = 0; int inputPosition = 0; int lastContext = 0; int lastCContext = 0; int lastDocContext = 0; int lastCPPContext = 0; int lastSkipSharpContext = 0; int lastSkipRoundContext = 0; int lastStringContext = 0; int lastCurlyContext = 0; int lastRoundContext = 0; int lastSquareContext = 0; int lastInitializerContext = 0; int lastClassTemplSpecContext = 0; int lastPreLineCtrlContext = 0; int lastSkipVerbStringContext = 0; int lastCommentInArgContext = 0; int lastRawStringContext = 0; int lastCSConstraint = 0; int lastHereDocContext = 0; int lastDefineContext = 0; int lastAlignAsContext = 0; int lastC11AttributeContext = 0; int lastModifierContext = 0; Protection protection = Public; Protection baseProt = Public; int sharpCount = 0 ; int roundCount = 0 ; int curlyCount = 0 ; int squareCount = 0 ; int padCount = 0 ; std::shared_ptr current; std::shared_ptr current_root; std::shared_ptr previous; std::shared_ptr tempEntry; std::shared_ptr firstTypedefEntry; std::shared_ptr memspecEntry; int yyLineNr = 1 ; int yyBegLineNr = 1 ; int yyColNr = 1 ; int yyBegColNr = 1 ; QCString yyFileName; MethodTypes mtype = Method; bool stat = false; Specifier virt = Normal; Specifier baseVirt = Normal; QCString msType; QCString msName; QCString msArgs; bool isTypedef = false; QCString funcPtrType; QCString templateStr; QCString aliasName; QCString baseName; QCString* specName = 0; SrcLangExt language = SrcLangExt_Unknown; bool insideIDL = false; //!< processing IDL code? bool insideJava = false; //!< processing Java code? bool insideCS = false; //!< processing C# code? bool insideD = false; //!< processing D code? bool insidePHP = false; //!< processing PHP code? bool insideObjC = false; //!< processing Objective C code? bool insideCli = false; //!< processing C++/CLI code? bool insideJS = false; //!< processing JavaScript code? bool insideSlice = false; //!< processing Slice code? bool insideCpp = true; //!< processing C/C++ code bool insideCppQuote = false; bool insideProtocolList = false; int argRoundCount = 0; int argSharpCount = 0; int currentArgumentContext = 0; int lastCopyArgStringContext = 0; int lastCopyArgContext = 0; QCString *copyArgString = 0; QCString fullArgString; QCString dummyRawString; ArgumentList *currentArgumentList = 0; char lastCopyArgChar = '\0'; QCString *pCopyQuotedString = 0; QCString *pCopyRoundString = 0; QCString *pCopyCurlyString = 0; QCString *pCopyRawString = 0; std::ostringstream *pCopyCurlyGString = 0; std::ostringstream *pCopyRoundGString = 0; std::ostringstream *pCopySquareGString = 0; std::ostringstream *pCopyQuotedGString = 0; std::ostringstream *pCopyHereDocGString = 0; std::ostringstream *pCopyRawGString = 0; std::ostringstream *pSkipVerbString = 0; bool insideFormula = false; bool insideTryBlock = false; bool insideCode = false; bool needsSemi = false; int initBracketCount = 0; QCString oldStyleArgType; QCString docBackup; QCString briefBackup; int docBlockContext = 0; std::ostringstream docBlock; QCString docBlockName; bool docBlockInBody = false; bool docBlockAutoBrief = false; char docBlockTerm = '\0'; QCString idlAttr; QCString idlProp; bool odlProp = false; bool lexInit = false; bool externC = false; QCString delimiter; int column = 0; uint fencedSize = 0; bool nestedComment = false; std::vector< std::pair > > outerScopeEntries; QCString programStr; ClangTUParser * clangParser = 0; }; #if USE_STATE2STRING static const char *stateToString(int state); #endif //----------------------------------------------------------------------------- // forward declarations for stateless functions static inline int computeIndent(const char *s,int startIndent); static QCString stripQuotes(const char *s); static bool nameIsOperator(QCString &name); void fixArgumentListForJavaScript(ArgumentList &al); // forward declarations for statefull functions static void initParser(yyscan_t yyscanner); static void initEntry(yyscan_t yyscanner); static void lineCount(yyscan_t yyscanner); static void addType(yyscan_t yyscanner); static void setContext(yyscan_t yyscanner); static void prependScope(yyscan_t yyscanner); static void startCommentBlock(yyscan_t yyscanner,bool); static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief); static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al); static bool checkForKnRstyleC(yyscan_t yyscanner); static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName); static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name, const QCString &brief,const QCString &docs); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); /* ----------------------------------------------------------------- */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); %} /* start command character */ CMD ("\\"|"@") BN [ \t\n\r] BNopt {BN}* BL [ \t\r]*"\n" B [ \t] Bopt {B}* 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_;] PHPUSEKW ("public"|"private"|"protected") 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}) /* no comment start / end signs inside square brackets */ NCOMM [^/\*] // C start comment CCS "/\*" // C end comment CCE "*\/" // Cpp comment CPPC "/\/" // doxygen start comment DCOMM ("/\*!"|"/\**"|"/\/!"|"/\/\/") // Optional any character ANYopt .* // Optional all but newline NONLopt [^\n]* %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 ReadInitializerPtr %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 SpecializationSingleQuote %x SpecializationDoubleQuote %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 %% "{" { yyextra->curlyCount=0; yyextra->needsSemi = TRUE; BEGIN(SkipCurlyBlock); } "(" { yyextra->roundCount=0; BEGIN(SkipRoundBlock); } "(" { ++yyextra->roundCount; } ")" { if (yyextra->roundCount ) --yyextra->roundCount ; else BEGIN( NextSemi ) ; } "{" { ++yyextra->curlyCount ; } "}" { if( yyextra->curlyCount ) { --yyextra->curlyCount ; } else if (yyextra->needsSemi) { BEGIN( NextSemi ); } else { BEGIN( FindMembers ); } } \' { if (yyextra->insidePHP) { yyextra->lastStringContext=NextSemi; BEGIN(SkipPHPString); } } {CHARLIT} { if (yyextra->insidePHP) REJECT; } \" { yyextra->lastStringContext=NextSemi; BEGIN(SkipString); } [;,] { unput(*yytext); BEGIN( FindMembers ); } [;,] { unput(*yytext); BEGIN( FindMembers ); } [{;,] { yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); unput(*yytext); BEGIN( ClassVar ); } "insidePHP = TRUE; } """ { // PHP code start lineCount(yyscanner) ; BEGIN( FindMembers ); } "?>"|"" { // PHP code end if (yyextra->insidePHP) BEGIN( FindMembersPHP ); else REJECT; } [^\n<]+ { // Non-PHP code text, ignore } \n { // Non-PHP code text, ignore lineCount(yyscanner); } . { // Non-PHP code text, ignore } {PHPKW} { if (yyextra->insidePHP) BEGIN( NextSemi ); else REJECT; } "%{"[^\n]* { // Mozilla XPIDL lang-specific block if (!yyextra->insideIDL) REJECT; } "%}" { // Mozilla XPIDL lang-specific block end if (!yyextra->insideIDL) REJECT; } {B}*("properties"){BN}*":"{BN}* { // IDL or Borland C++ builder property yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->protection = yyextra->protection = Public ; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"k_dcop"{BN}*":"{BN}* { yyextra->current->mtype = yyextra->mtype = DCOP; yyextra->current->protection = yyextra->protection = Public ; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*("signals"|"Q_SIGNALS"){BN}*":"{BN}* { yyextra->current->mtype = yyextra->mtype = Signal; yyextra->current->protection = yyextra->protection = Public ; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"public"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { yyextra->current->protection = yyextra->protection = Public ; yyextra->current->mtype = yyextra->mtype = Slot; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner); } {B}*"protected"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { yyextra->current->protection = yyextra->protection = Protected ; yyextra->current->mtype = yyextra->mtype = Slot; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner); } {B}*"private"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { yyextra->current->protection = yyextra->protection = Private ; yyextra->current->mtype = yyextra->mtype = Slot; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner); } {B}*("public"|"methods"|"__published"){BN}*":"{BN}* { yyextra->current->protection = yyextra->protection = Public ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package... if (yyextra->insideCli) { yyextra->current->protection = yyextra->protection = Package ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } else { REJECT; } } {B}*"protected"{BN}*":"{BN}* { yyextra->current->protection = yyextra->protection = Protected ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"private"{BN}*":"{BN}* { yyextra->current->protection = yyextra->protection = Private ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"event"{BN}+ { if (yyextra->insideCli) { // C++/CLI event lineCount(yyscanner) ; yyextra->current->mtype = yyextra->mtype = Event; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->curlyCount=0; BEGIN( CliPropertyType ); } else if (yyextra->insideCS) { lineCount(yyscanner) ; yyextra->current->mtype = Event; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; } else { REJECT; } } {B}*"property"{BN}+ { if (yyextra->insideCli) { // C++/CLI property lineCount(yyscanner) ; yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->curlyCount=0; BEGIN( CliPropertyType ); } else { REJECT; } } {ID} { addType(yyscanner); yyextra->current->name = yytext; } "[" { // C++/CLI indexed property yyextra->current->args = "["; BEGIN( CliPropertyIndex ); } "{" { yyextra->curlyCount=0; //printf("event: '%s' '%s'\n",yyextra->current->type.data(),yyextra->current->name.data()); BEGIN( CSAccessorDecl ); } ";" { unput(*yytext); BEGIN( FindMembers ); } \n { lineCount(yyscanner); } {B}* { } . { addType(yyscanner); yyextra->current->type += yytext; } "]" { BEGIN( CliPropertyType ); yyextra->current->args+=yytext; } . { yyextra->current->args+=yytext; } /* {B}*"property"{BN}+ { if (!yyextra->current->type.isEmpty()) { REJECT; } else { yyextra->current->mtype = yyextra->mtype = Property; lineCount(yyscanner); } } */ {B}*"@private"{BN}+ { yyextra->current->protection = yyextra->protection = Private ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"@protected"{BN}+ { yyextra->current->protection = yyextra->protection = Protected ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } {B}*"@public"{BN}+ { yyextra->current->protection = yyextra->protection = Public ; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); lineCount(yyscanner) ; } [\-+]{BN}* { if (!yyextra->insideObjC) { REJECT; } else { lineCount(yyscanner); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->section = Entry::FUNCTION_SEC; yyextra->current->protection = yyextra->protection = Public ; yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; yyextra->insideObjC = TRUE; yyextra->current->virt = Virtual; yyextra->current->stat=yytext[0]=='+'; yyextra->current->mtype = yyextra->mtype = Method; yyextra->current->type.resize(0); yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->argList.clear(); BEGIN( ObjCMethod ); } } "(" { // start of method's return type BEGIN( ObjCReturnType ); } {ID} { // found method name if (yyextra->current->type.isEmpty()) { yyextra->current->type = "id"; } yyextra->current->name = yytext; if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext); } } ":"{B}* { // start of parameter list yyextra->current->name += ':'; Argument a; yyextra->current->argList.push_back(a); BEGIN( ObjCParams ); } [^)]* { // TODO: check if nested braches are possible. yyextra->current->type = yytext; } ")" { BEGIN( ObjCMethod ); } ({ID})?{BN}*":" { // Keyword of parameter QCString keyw = yytext; keyw=keyw.left(keyw.length()-1).stripWhiteSpace(); // strip : if (keyw.isEmpty()) { yyextra->current->name += " :"; } else { yyextra->current->name += keyw+":"; } if (yyextra->current->argList.back().type.isEmpty()) { yyextra->current->argList.back().type="id"; } Argument a; a.attrib=(QCString)"["+keyw+"]"; yyextra->current->argList.push_back(a); } {ID}{BN}* { // name of parameter lineCount(yyscanner); yyextra->current->argList.back().name=QCString(yytext).stripWhiteSpace(); } ","{BN}*"..." { // name of parameter lineCount(yyscanner); // do we want the comma as part of the name? //yyextra->current->name += ","; Argument a; a.attrib="[,]"; a.type="..."; yyextra->current->argList.push_back(a); } /* ":" { yyextra->current->name += ':'; } */ "(" { yyextra->roundCount=0; yyextra->current->argList.back().type.resize(0); BEGIN( ObjCParamType ); } "(" { yyextra->roundCount++; yyextra->current->argList.back().type+=yytext; } ")"/{B}* { if (yyextra->roundCount<=0) { BEGIN( ObjCParams ); } else { yyextra->current->argList.back().type+=yytext; yyextra->roundCount--; } } [^()]* { yyextra->current->argList.back().type+=QCString(yytext).stripWhiteSpace(); } ";" { // end of method declaration if (!yyextra->current->argList.empty() && yyextra->current->argList.back().type.isEmpty()) { yyextra->current->argList.back().type="id"; } if (yyextra->current->argList.empty()) // method without parameters { yyextra->current->argList.setNoParameters(TRUE); } yyextra->current->args = argListToString(yyextra->current->argList); //printf("argList=%s\n",yyextra->current->args.data()); unput(';'); BEGIN( Function ); } (";"{BN}+)?"{" { // start of a method body lineCount(yyscanner); //printf("Type=%s Name=%s args=%s\n", // yyextra->current->type.data(),yyextra->current->name.data(),argListToString(yyextra->current->argList).data() // ); if (!yyextra->current->argList.empty() && yyextra->current->argList.back().type.isEmpty()) { yyextra->current->argList.back().type="id"; } if (yyextra->current->argList.empty()) // method without parameters { yyextra->current->argList.setNoParameters(TRUE); } yyextra->current->args = argListToString(yyextra->current->argList); unput('{'); BEGIN( Function ); } {B}*"sequence"{BN}*"<"{BN}* { if (yyextra->insideSlice) { lineCount(yyscanner); yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->fileName = yyextra->yyFileName ; yyextra->current->startLine = yyextra->yyLineNr ; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->args.resize(0); yyextra->current->section = Entry::TYPEDEF_SEC ; yyextra->isTypedef = TRUE; BEGIN( SliceSequence ); } else REJECT; } {B}*"dictionary"{BN}*"<"{BN}* { if (yyextra->insideSlice) { lineCount(yyscanner); yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->fileName = yyextra->yyFileName ; yyextra->current->startLine = yyextra->yyLineNr ; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->args.resize(0); yyextra->current->section = Entry::TYPEDEF_SEC ; yyextra->isTypedef = TRUE; BEGIN( SliceDictionary ); } else REJECT; } {BN}{1,80} { lineCount(yyscanner); } "@"({ID}".")*{ID}{BN}*"(" { if (yyextra->insideJava) // Java annotation { lineCount(yyscanner); yyextra->lastSkipRoundContext = YY_START; yyextra->roundCount=0; BEGIN( SkipRound ); } else if (qstrncmp(yytext,"@property",9)==0) // ObjC 2.0 property { yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->spec|=Entry::Readable | Entry::Writable | Entry::Assign; yyextra->current->protection = Public ; unput('('); BEGIN( ObjCPropAttr ); } else { REJECT; } } "getter="{ID} { yyextra->current->read = yytext+7; } "setter="{ID} { yyextra->current->write = yytext+7; } "readonly" { yyextra->current->spec&=~Entry::Writable; } "readwrite" { // default } "assign" { // default } "unsafe_unretained" { yyextra->current->spec&=~Entry::Assign; yyextra->current->spec|=Entry::Unretained; } "retain" { yyextra->current->spec&=~Entry::Assign; yyextra->current->spec|=Entry::Retain; } "copy" { yyextra->current->spec&=~Entry::Assign; yyextra->current->spec|=Entry::Copy; } "weak" { yyextra->current->spec&=~Entry::Assign; yyextra->current->spec|=Entry::Weak; } "strong" { yyextra->current->spec&=~Entry::Assign; yyextra->current->spec|=Entry::Strong; } "nonatomic" { yyextra->current->spec|=Entry::NonAtomic; } ")" { BEGIN(FindMembers); } "@"{ID} { if (yyextra->insideJava) // Java annotation { // skip annotation } else if (qstrcmp(yytext,"@property")==0) // ObjC 2.0 property { yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->spec|=Entry::Writable | Entry::Readable; yyextra->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})* { yyextra->isTypedef=FALSE; //printf("Found namespace %s lang=%d\n",yytext,yyextra->current->lang); yyextra->current->name = yytext; yyextra->current->name = substitute(yyextra->current->name,".","::"); yyextra->current->name = substitute(yyextra->current->name,"\\","::"); yyextra->current->section = Entry::NAMESPACE_SEC; yyextra->current->type = "namespace" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); } ";" { std::shared_ptr tmp = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); yyextra->current_root = tmp; initEntry(yyscanner); BEGIN(FindMembers); } "{" { yyextra->curlyCount=0; BEGIN( ReadNSBody ); } {B}*"initonly"{BN}+ { yyextra->current->type += " initonly "; if (yyextra->insideCli) yyextra->current->spec |= Entry::Initonly; lineCount(yyscanner); } {B}*"static"{BN}+ { yyextra->current->type += " static "; yyextra->current->stat = TRUE; lineCount(yyscanner); } {B}*"extern"{BN}+ { yyextra->current->stat = FALSE; yyextra->current->explicitExternal = TRUE; lineCount(yyscanner); } {B}*"const"{BN}+ { if (yyextra->insideCS) { yyextra->current->type += " const "; if (yyextra->insideCS) yyextra->current->stat = TRUE; lineCount(yyscanner); } else { REJECT; } } {B}*"virtual"{BN}+ { yyextra->current->type += " virtual "; yyextra->current->virt = Virtual; lineCount(yyscanner); } {B}*"constexpr"{BN}+ { if (yyextra->insideCpp) { yyextra->current->type += " constexpr "; yyextra->current->spec |= Entry::ConstExpr; lineCount(yyscanner); } else { REJECT; } } {B}*"published"{BN}+ { // UNO IDL published keyword if (yyextra->insideIDL) { lineCount(yyscanner); yyextra->current->spec |= Entry::Published; } else { REJECT; } } {B}*"abstract"{BN}+ { if (!yyextra->insidePHP) { yyextra->current->type += " abstract "; if (!yyextra->insideJava) { yyextra->current->virt = Pure; } else { yyextra->current->spec|=Entry::Abstract; } } else { yyextra->current->spec|=Entry::Abstract; } lineCount(yyscanner); } {B}*"inline"{BN}+ { yyextra->current->spec|=Entry::Inline; lineCount(yyscanner); } {B}*"mutable"{BN}+ { yyextra->current->spec|=Entry::Mutable; lineCount(yyscanner); } {B}*"explicit"{BN}+ { yyextra->current->spec|=Entry::Explicit; lineCount(yyscanner); } {B}*"local"{BN}+ { yyextra->current->spec|=Entry::Local; lineCount(yyscanner); } {B}*"@required"{BN}+ { // Objective C 2.0 protocol required section yyextra->current->spec=(yyextra->current->spec & ~Entry::Optional) | Entry::Required; lineCount(yyscanner); } {B}*"@optional"{BN}+ { // Objective C 2.0 protocol optional section yyextra->current->spec=(yyextra->current->spec & ~Entry::Required) | Entry::Optional; lineCount(yyscanner); } /* {B}*"import"{BN}+ { // IDL import keyword BEGIN( NextSemi ); } */ {B}*"typename"{BN}+ { lineCount(yyscanner); } {B}*"namespace"{BNopt}/[^a-z_A-Z0-9] { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::NAMESPACE_SEC; yyextra->current->type = "namespace" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); if (yyextra->insidePHP) { BEGIN( PackageName ); } else { BEGIN( CompoundName ); } } {B}*"module"{BN}+ { lineCount(yyscanner); if (yyextra->insideIDL || yyextra->insideSlice) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::NAMESPACE_SEC; yyextra->current->type = "module" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else if (yyextra->insideD) { lineCount(yyscanner); BEGIN(PackageName); } else { addType(yyscanner); yyextra->current->name = QCString(yytext).stripWhiteSpace(); } } {B}*"library"{BN}+ { lineCount(yyscanner); if (yyextra->insideIDL) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::NAMESPACE_SEC; yyextra->current->type = "library" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else { addType(yyscanner); yyextra->current->name = QCString(yytext).stripWhiteSpace(); } } {B}*"constants"{BN}+ { // UNO IDL constant group lineCount(yyscanner); if (yyextra->insideIDL) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::NAMESPACE_SEC; yyextra->current->type = "constants"; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else { addType(yyscanner); yyextra->current->name = QCString(yytext).stripWhiteSpace(); } } {BN}*("service"){BN}+ { // UNO IDL service lineCount(yyscanner); if (yyextra->insideIDL) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Service | // preserve UNO IDL [optional] or published (yyextra->current->spec & (Entry::Optional|Entry::Published)); addType(yyscanner); yyextra->current->type += " service " ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else // TODO is addType right? just copy/pasted { addType(yyscanner); yyextra->current->name = QCString(yytext).stripWhiteSpace(); } } {BN}*("singleton"){BN}+ { // UNO IDL singleton lineCount(yyscanner); if (yyextra->insideIDL) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Singleton | (yyextra->current->spec & Entry::Published); // preserve addType(yyscanner); yyextra->current->type += " singleton " ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else // TODO is addType right? just copy/pasted { addType(yyscanner); yyextra->current->name = QCString(yytext).stripWhiteSpace(); } } {BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java/Slice interface lineCount(yyscanner); if (yyextra->insideIDL || yyextra->insideJava || yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideSlice) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Interface | // preserve UNO IDL [optional], published, Slice local (yyextra->current->spec & (Entry::Optional|Entry::Published|Entry::Local)); addType(yyscanner); yyextra->current->type += " interface" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } else { addType(yyscanner); yyextra->current->name = QCString(yytext).stripWhiteSpace(); } } {B}*"@implementation"{BN}+ { // Objective-C class implementation lineCount(yyscanner); yyextra->isTypedef=FALSE; yyextra->current->section = Entry::OBJCIMPL_SEC; yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; yyextra->insideObjC = TRUE; yyextra->current->protection = yyextra->protection = Public ; addType(yyscanner); yyextra->current->type += " implementation" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } {B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute lineCount(yyscanner); yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Interface; if (!yyextra->insideJava) { yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; yyextra->insideObjC = TRUE; } yyextra->current->protection = yyextra->protection = Public ; addType(yyscanner); yyextra->current->type += " interface" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } {B}*"@protocol"{BN}+ { // Objective-C protocol definition lineCount(yyscanner); yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Protocol; yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; yyextra->insideObjC = TRUE; yyextra->current->protection = yyextra->protection = Public ; addType(yyscanner); yyextra->current->type += " protocol" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( CompoundName ); } {B}*"exception"{BN}+ { // Corba IDL/Slice exception yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; // preserve UNO IDL, Slice local yyextra->current->spec = Entry::Exception | (yyextra->current->spec & Entry::Published) | (yyextra->current->spec & Entry::Local); addType(yyscanner); yyextra->current->type += " exception" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); BEGIN( CompoundName ); } "@class" | // for Objective C class declarations {B}*{TYPEDEFPREFIX}"class{" | {B}*{TYPEDEFPREFIX}"class"{BN}+ { QCString decl = yytext; yyextra->isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; yyextra->current->section = Entry::CLASS_SEC; addType(yyscanner); uint64 spec = yyextra->current->spec; if (yyextra->insidePHP && yyextra->current->spec&Entry::Abstract) { // convert Abstract to AbstractClass yyextra->current->spec=(yyextra->current->spec&~Entry::Abstract)|Entry::AbstractClass; } if (yyextra->insideSlice && spec&Entry::Local) { yyextra->current->spec|=Entry::Local; } if (isConst) { yyextra->current->type += " const"; } else if (isVolatile) { yyextra->current->type += " volatile"; } yyextra->current->type += " class" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; if (yytext[0]=='@') { yyextra->language = yyextra->current->lang = SrcLangExt_ObjC; yyextra->insideObjC = TRUE; } lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"value class{" | // C++/CLI extension {B}*"value class"{BN}+ { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Value; addType(yyscanner); yyextra->current->type += " value class" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"ref class{" | // C++/CLI extension {B}*"ref class"{BN}+ { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Ref; addType(yyscanner); yyextra->current->type += " ref class" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"interface class{" | // C++/CLI extension {B}*"interface class"{BN}+ { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Interface; addType(yyscanner); yyextra->current->type += " interface class" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"coclass"{BN}+ { if (yyextra->insideIDL) { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; addType(yyscanner); yyextra->current->type += " coclass" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; BEGIN( CompoundName ) ; } else { addType(yyscanner); yyextra->current->name = yytext; yyextra->current->name = yyextra->current->name.stripWhiteSpace(); lineCount(yyscanner); } } {B}*{TYPEDEFPREFIX}"struct{" | {B}*{TYPEDEFPREFIX}"struct"/{BN}+ { QCString decl = yytext; yyextra->isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; yyextra->current->section = Entry::CLASS_SEC ; // preserve UNO IDL & Inline attributes, Slice local yyextra->current->spec = Entry::Struct | (yyextra->current->spec & Entry::Published) | (yyextra->current->spec & Entry::Inline) | (yyextra->current->spec & Entry::Local); // bug 582676: can be a struct nested in an interface so keep yyextra->insideObjC state //yyextra->current->objc = yyextra->insideObjC = FALSE; addType(yyscanner); if (isConst) { yyextra->current->type += " const"; } else if (isVolatile) { yyextra->current->type += " volatile"; } yyextra->current->type += " struct" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"value struct{" | // C++/CLI extension {B}*"value struct"{BN}+ { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Struct | Entry::Value; addType(yyscanner); yyextra->current->type += " value struct" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"ref struct{" | // C++/CLI extension {B}*"ref struct"{BN}+ { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Struct | Entry::Ref; addType(yyscanner); yyextra->current->type += " ref struct" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*"interface struct{" | // C++/CLI extension {B}*"interface struct"{BN}+ { yyextra->isTypedef=FALSE; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Struct | Entry::Interface; addType(yyscanner); yyextra->current->type += " interface struct"; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } {B}*{TYPEDEFPREFIX}"union{" | {B}*{TYPEDEFPREFIX}"union"{BN}+ { QCString decl=yytext; yyextra->isTypedef=decl.find("typedef")!=-1; bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Union; // bug 582676: can be a struct nested in an interface so keep yyextra->insideObjC state //yyextra->current->objc = yyextra->insideObjC = FALSE; addType(yyscanner); if (isConst) { yyextra->current->type += " const"; } else if (isVolatile) { yyextra->current->type += " volatile"; } yyextra->current->type += " union" ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; 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; yyextra->isTypedef = text.find("typedef")!=-1; bool isStrongEnum = text.find("struct")!=-1 || text.find("class")!=-1 || yyextra->insideCS; if (yyextra->insideJava) { yyextra->current->section = Entry::CLASS_SEC; yyextra->current->spec = Entry::Enum; } else { yyextra->current->section = Entry::ENUM_SEC ; } addType(yyscanner); yyextra->current->type += " enum"; if (isStrongEnum) { yyextra->current->spec |= Entry::Strong; } yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner) ; if (yytext[yyleng-1]=='{') unput('{'); BEGIN( CompoundName ) ; } "("{BN}*")"({BN}*"<"[^>]*">"){BNopt}/"(" { // A::operator()(int arg) lineCount(yyscanner); yyextra->current->name += "()"; BEGIN( FindMembers ); } "("{BN}*")"{BNopt}/"(" { lineCount(yyscanner); yyextra->current->name += yytext ; yyextra->current->name = yyextra->current->name.simplifyWhiteSpace(); BEGIN( FindMembers ) ; } ";" { // can occur when importing members unput(';'); BEGIN( FindMembers ) ; } [^(] { lineCount(yyscanner); yyextra->current->name += *yytext ; } "<>" { /* skip guided templ specifiers */ } "(" { yyextra->current->name = yyextra->current->name.simplifyWhiteSpace(); unput(*yytext); BEGIN( FindMembers ) ; } ("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension lineCount(yyscanner); ArgumentList al; //yyextra->current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template; yyextra->current->tArgLists.push_back(al); yyextra->currentArgumentList = &yyextra->current->tArgLists.back(); yyextra->templateStr="<"; yyextra->fullArgString = yyextra->templateStr; yyextra->copyArgString = &yyextra->templateStr; yyextra->currentArgumentContext = FindMembers; BEGIN( ReadTempArgs ); } "namespace"{BN}+/{ID}{BN}*"=" { // namespace alias lineCount(yyscanner); BEGIN( NSAliasName ); } {ID} { yyextra->aliasName = yytext; BEGIN( NSAliasArg ); } ({ID}"::")*{ID} { //printf("Inserting namespace alias %s::%s->%s\n",yyextra->current_root->name.data(),yyextra->aliasName.data(),yytext); // TODO: namespace aliases are now treated as global entities // while they should be aware of the scope they are in Doxygen::namespaceAliasMap.insert({yyextra->aliasName.data(),std::string(yytext)}); } ";" { BEGIN( FindMembers ); } ({ID}{BN}*"\\"{BN}*)*{ID}/{BN}+"as" { lineCount(yyscanner); yyextra->aliasName=yytext; BEGIN(PHPUseAs); } ({ID}{BN}*"\\"{BN}*)*{ID} { lineCount(yyscanner); yyextra->current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::")); //printf("PHP: adding use relation: %s\n",yyextra->current->name.data()); yyextra->current->fileName = yyextra->yyFileName; // add a using declaration yyextra->current->section=Entry::USINGDECL_SEC; yyextra->current_root->copyToSubEntry(yyextra->current); // also add it as a using directive yyextra->current->section=Entry::USINGDIR_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); yyextra->aliasName.resize(0); } {BN}+"as"{BN}+ { lineCount(yyscanner); } {PHPUSEKW} { } {ID} { //printf("PHP: adding use as relation: %s->%s\n",yytext,yyextra->aliasName.data()); if (!yyextra->aliasName.isEmpty()) { Doxygen::namespaceAliasMap.insert({yytext, std::string(removeRedundantWhiteSpace( substitute(yyextra->aliasName,"\\","::")).data())}); } yyextra->aliasName.resize(0); } [,;] { if (*yytext==',') { BEGIN(PHPUse); } else { BEGIN(FindMembers); } } ({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive lineCount(yyscanner); QCString scope=yytext; yyextra->current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::")); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->section=Entry::USINGDIR_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN(Using); } ({ID}{BN}*"."{BN}*)+{ID} { // class import => add as a using declaration lineCount(yyscanner); QCString scope=yytext; yyextra->current->name=removeRedundantWhiteSpace(substitute(scope,".","::")); yyextra->current->fileName = yyextra->yyFileName; if (yyextra->insideD) { yyextra->current->section=Entry::USINGDIR_SEC; } else { //printf("import name = %s -> %s\n",yytext,yyextra->current->name.data()); yyextra->current->section=Entry::USINGDECL_SEC; } yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN(Using); } "using"{BN}+ { yyextra->current->startLine=yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; lineCount(yyscanner); BEGIN(Using); } "namespace"{BN}+ { lineCount(yyscanner); BEGIN(UsingDirective); } ({ID}{BN}*("::"|"."){BN}*)*({ID}|{OPERATOR}) { lineCount(yyscanner); yyextra->current->name=yytext; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->section=Entry::USINGDECL_SEC; yyextra->current->startLine = yyextra->yyLineNr; yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); if (yyextra->insideCS) /* Hack: in C# a using declaration and directive have the same syntax, so we also add it as a using directive here */ { yyextra->current->name=yytext; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->section=Entry::USINGDIR_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); } BEGIN(Using); } "=" { // C++11 style template alias? BEGIN(UsingAlias); } ";" { yyextra->previous->section=Entry::VARIABLE_SEC; yyextra->previous->type = "typedef "+yyextra->previous->args; yyextra->previous->type=yyextra->previous->type.simplifyWhiteSpace(); yyextra->previous->args.resize(0); yyextra->previous->name=yyextra->previous->name.stripWhiteSpace(); yyextra->previous->bodyLine = yyextra->yyLineNr; yyextra->previous->bodyColumn = yyextra->yyColNr; yyextra->previous->spec |= Entry::Alias; BEGIN(FindMembers); } ";"{BN}*{DCOMM}"<" { yyextra->docBlockContext = UsingAliasEnd; yyextra->docBlockInBody = FALSE; yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,yyextra->column)); yyextra->docBlock.str(indent.str()); lineCount(yyscanner); yyextra->docBlockTerm = ';'; if (yytext[yyleng-3]=='/') { startCommentBlock(yyscanner,TRUE); BEGIN( DocLine ); } else { startCommentBlock(yyscanner,FALSE); BEGIN( DocBlock ); } } ">>" { yyextra->previous->args+="> >"; // see bug769552 } . { yyextra->previous->args+=yytext; } \n { yyextra->previous->args+=yytext; lineCount(yyscanner); } ";" { yyextra->previous->doc = yyextra->current->doc; yyextra->previous->brief = yyextra->current->brief; yyextra->current->doc.resize(0); yyextra->current->brief.resize(0); unput(';'); BEGIN(UsingAlias); } {SCOPENAME} { yyextra->current->name=removeRedundantWhiteSpace(yytext); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->section=Entry::USINGDIR_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN(Using); } ";" { BEGIN(FindMembers); } {SCOPENAME}{BN}*"<>" { // guided template decl QCString n=yytext; addType(yyscanner); yyextra->current->name=n.left(n.length()-2); } {SCOPENAME}{BNopt}/"<" { // Note: this could be a return type! yyextra->roundCount=0; yyextra->sharpCount=0; lineCount(yyscanner); addType(yyscanner); yyextra->current->name=yytext; yyextra->current->name=yyextra->current->name.stripWhiteSpace(); //yyextra->current->scopeSpec.resize(0); // yyextra->currentTemplateSpec = &yyextra->current->scopeSpec; if (nameIsOperator(yyextra->current->name)) BEGIN( Operator ); else BEGIN( EndTemplate ); } {SCOPENAME}{BNopt}/"<" { yyextra->sharpCount=0; yyextra->roundCount=0; lineCount(yyscanner); yyextra->current->name+=((QCString)yytext).stripWhiteSpace(); //yyextra->current->memberSpec.resize(0); // yyextra->currentTemplateSpec = &yyextra->current->memberSpec; if (nameIsOperator(yyextra->current->name)) BEGIN( Operator ); else BEGIN( EndTemplate ); } "<<<" { if (!yyextra->insidePHP) { REJECT; } else { yyextra->lastHereDocContext = YY_START; BEGIN(HereDoc); } } "<<" { yyextra->current->name+=yytext; // *yyextra->currentTemplateSpec+=yytext; } "<" { if (yyextra->roundCount==0) { // *yyextra->currentTemplateSpec+='<'; yyextra->sharpCount++; } yyextra->current->name+=yytext; } ">>" { if (yyextra->insideJava || yyextra->insideCS || yyextra->insideCli || yyextra->roundCount==0) { unput('>'); unput(' '); unput('>'); } else { yyextra->current->name+=yytext; } // *yyextra->currentTemplateSpec+=yytext; } ">" { yyextra->current->name+='>'; // *yyextra->currentTemplateSpec+='>'; if (yyextra->roundCount==0 && --yyextra->sharpCount<=0) { //printf("Found %s\n",yyextra->current->name.data()); BEGIN(FindMembers); } } ">"{BN}*"(" { lineCount(yyscanner); yyextra->current->name+='>'; // *yyextra->currentTemplateSpec+='>'; if (yyextra->roundCount==0 && --yyextra->sharpCount<=0) { yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->args = "("; yyextra->currentArgumentContext = FuncQual; yyextra->fullArgString = yyextra->current->args.copy(); yyextra->copyArgString = &yyextra->current->args; //printf("Found %s\n",yyextra->current->name.data()); BEGIN( ReadFuncArgType ) ; } } ">"{BNopt}/"("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance lineCount(yyscanner); yyextra->current->name+='>'; if (yyextra->roundCount==0) { BEGIN(FindMembers); } } ">"{BNopt}/"::" { lineCount(yyscanner); yyextra->current->name+='>'; // *yyextra->currentTemplateSpec+='>'; if (yyextra->roundCount==0 && --yyextra->sharpCount<=0) { BEGIN(FindMemberName); } } "(" { yyextra->current->name+=*yytext; yyextra->roundCount++; } ")" { yyextra->current->name+=*yytext; if (yyextra->roundCount>0) yyextra->roundCount--; } . { yyextra->current->name+=*yytext; // *yyextra->currentTemplateSpec+=*yytext; } "define"{BN}*"("{BN}*["'] { if (yyextra->insidePHP) { yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( DefinePHP ); } else REJECT; } {ID} { // PHP heredoc yyextra->delimiter = yytext; *yyextra->pCopyHereDocGString << yytext; BEGIN(CopyHereDocEnd); } "'"{ID}/"'" { // PHP nowdoc yyextra->delimiter = &yytext[1]; *yyextra->pCopyHereDocGString << yytext; BEGIN(CopyHereDocEnd); } {ID} { // PHP heredoc yyextra->delimiter = yytext; BEGIN(HereDocEnd); } "'"{ID}/"'" { // PHP nowdoc yyextra->delimiter = &yytext[1]; BEGIN(HereDocEnd); } ^{ID} { // id at start of the line could mark the end of the block if (yyextra->delimiter==yytext) // it is the end marker { BEGIN(yyextra->lastHereDocContext); } } . { } ^{ID} { // id at start of the line could mark the end of the block *yyextra->pCopyHereDocGString << yytext; if (yyextra->delimiter==yytext) // it is the end marker { BEGIN(yyextra->lastHereDocContext); } } \n { lineCount(yyscanner); *yyextra->pCopyHereDocGString << yytext; } {ID} { *yyextra->pCopyHereDocGString << yytext; } . { *yyextra->pCopyHereDocGString << yytext; } "Q_OBJECT" { // Qt object macro } "Q_PROPERTY" { // Qt property declaration yyextra->current->protection = Public ; // see bug734245 & bug735462 yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->type.resize(0); BEGIN(QtPropType); } "(" { // start of property arguments } ")" { // end of property arguments unput(';'); BEGIN(FindMembers); } {B}+ { yyextra->current->name+=yytext; } "*" { yyextra->current->type+= yyextra->current->name; yyextra->current->type+= yytext; yyextra->current->name=""; } ({TSCOPE}"::")*{TSCOPE} { yyextra->current->type+= yyextra->current->name; yyextra->current->name=yytext; } {B}+"READ"{B}+ { yyextra->current->spec |= Entry::Readable; BEGIN(QtPropRead); } {B}+"WRITE"{B}+ { yyextra->current->spec |= Entry::Writable; BEGIN(QtPropWrite); } {B}+"MEMBER"{B}+{ID} | // member property => not supported yet {B}+"RESET"{B}+{ID} | // reset method => not supported yet {B}+"SCRIPTABLE"{B}+{ID} | // scriptable property => not supported yet {B}+"DESIGNABLE"{B}+{ID} | // designable property => not supported yet {B}+"NOTIFY"{B}+{ID} | // notify property => not supported yet {B}+"REVISION"{B}+{ID} | // revision property => not supported yet {B}+"STORED"{B}+{ID} | // stored property => not supported yet {B}+"USER"{B}+{ID} | // user property => not supported yet {B}+"CONSTANT"{B} | // constant property => not supported yet {B}+"FINAL"{B} { // final property => not supported yet BEGIN(QtPropAttr); } {ID} { yyextra->current->read = yytext; BEGIN(QtPropAttr); } {ID} { yyextra->current->write = yytext; BEGIN(QtPropAttr); } "friend"{BN}+("class"|"union"|"struct"){BN}+ { yyextra->current->name=yytext; BEGIN(FindMembers); } {SCOPENAME} { if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext); } yyextra->yyBegColNr=yyextra->yyColNr; yyextra->yyBegLineNr=yyextra->yyLineNr; lineCount(yyscanner); if (yyextra->insideIDL && yyleng==9 && qstrcmp(yytext,"cpp_quote")==0) { BEGIN(CppQuote); } else if ((yyextra->insideIDL || yyextra->insideJava || yyextra->insideD) && yyleng==6 && qstrcmp(yytext,"import")==0) { if (yyextra->insideIDL) BEGIN(NextSemi); else // yyextra->insideJava or yyextra->insideD BEGIN(JavaImport); } else if (yyextra->insidePHP && qstrcmp(yytext,"use")==0) { BEGIN(PHPUse); } else if (yyextra->insideJava && qstrcmp(yytext,"package")==0) { lineCount(yyscanner); BEGIN(PackageName); } else if (yyextra->insideIDL && qstrcmp(yytext,"case")==0) { BEGIN(IDLUnionCase); } else if (yyextra->insideTryBlock && qstrcmp(yytext,"catch")==0) { yyextra->insideTryBlock=FALSE; BEGIN(TryFunctionBlock); } else if (yyextra->insideCpp && qstrcmp(yytext,"alignas")==0) { yyextra->lastAlignAsContext = YY_START; BEGIN(AlignAs); } else if (yyextra->insideJS && qstrcmp(yytext,"var")==0) { // javascript variable yyextra->current->type="var"; } else if (yyextra->insideJS && qstrcmp(yytext,"function")==0) { // javascript function yyextra->current->type="function"; } else if (yyextra->insideCS && qstrcmp(yytext,"this")==0) { // C# indexer addType(yyscanner); yyextra->current->name="this"; BEGIN(CSIndexer); } else if (yyextra->insideCpp && qstrcmp(yytext,"static_assert")==0) { // C++11 static_assert BEGIN(StaticAssert); } else if (yyextra->insideCpp && qstrcmp(yytext,"decltype")==0) { // C++11 decltype(x) yyextra->current->type+=yytext; BEGIN(DeclType); } else if (yyextra->insideSlice && qstrcmp(yytext,"optional")==0) { if (yyextra->current->type.isEmpty()) { yyextra->current->type = "optional"; } else { yyextra->current->type += " optional"; } yyextra->lastModifierContext = YY_START; BEGIN(SliceOptional); } else { if (YY_START==FindMembers) { addType(yyscanner); } bool javaLike = yyextra->insideJava || yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideJS; if (javaLike && qstrcmp(yytext,"public")==0) { yyextra->current->protection = Public; } else if (javaLike && qstrcmp(yytext,"protected")==0) { yyextra->current->protection = Protected; } else if ((yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideJS) && qstrcmp(yytext,"internal")==0) { yyextra->current->protection = Package; } else if (javaLike && qstrcmp(yytext,"private")==0) { yyextra->current->protection = Private; } else if (javaLike && qstrcmp(yytext,"static")==0) { if (YY_START==FindMembers) yyextra->current->name = yytext; else yyextra->current->name += yytext; yyextra->current->stat = TRUE; } else { if (YY_START==FindMembers) yyextra->current->name = yytext; else yyextra->current->name += yytext; if (yyextra->current->name.left(7)=="static ") { yyextra->current->stat = TRUE; yyextra->current->name= yyextra->current->name.mid(7); } else if (yyextra->current->name.left(7)=="inline ") { if (yyextra->current->type.isEmpty()) { yyextra->current->type="inline"; } else { yyextra->current->type+="inline "; } yyextra->current->name= yyextra->current->name.mid(7); } else if (yyextra->current->name.left(6)=="const ") { if (yyextra->current->type.isEmpty()) { yyextra->current->type="const"; } else { yyextra->current->type+="const "; } yyextra->current->name=yyextra->current->name.mid(6); } } QCString tmp=yytext; if (nameIsOperator(tmp)) { BEGIN( Operator ); } else { yyextra->externC=FALSE; // see bug759247 BEGIN(FindMembers); } } } "(" { yyextra->lastSkipRoundContext = FindMembers; yyextra->roundCount=0; BEGIN(SkipRound); } {BN}+ { lineCount(yyscanner); } . { // variable with static_assert as name? unput(*yytext); BEGIN(FindMembers); } "(" { yyextra->current->type+=yytext; yyextra->lastRoundContext=FindMembers; yyextra->pCopyRoundString=&yyextra->current->type; yyextra->roundCount=0; BEGIN(CopyRound); } {BN}+ { lineCount(yyscanner); } . { unput(*yytext); BEGIN(FindMembers); } "["[^\n\]]*"]" { yyextra->current->name+=removeRedundantWhiteSpace(yytext); BEGIN(FindMembers); } [0-9]{ID} { // some number where we did not expect one } "." { if (yyextra->insideJava || yyextra->insideCS || yyextra->insideD) { yyextra->current->name+="."; } } "::" { yyextra->current->name+=yytext; } "("{B}*"\"" { yyextra->insideCppQuote=TRUE; BEGIN(FindMembers); } "::" ":" { BEGIN(FindMembers); } \n { lineCount(yyscanner); } . \n { lineCount(yyscanner); } "{" { yyextra->curlyCount=0; yyextra->lastCurlyContext = TryFunctionBlockEnd ; BEGIN( SkipCurly ); } . {BN}*"catch" { lineCount(yyscanner); BEGIN(TryFunctionBlock); // {BN}* added to fix bug 611193 } \n { unput(*yytext); // rule added to fix bug id 601138 BEGIN( FindMembers ); } . { unput(*yytext); BEGIN( FindMembers ); } ")" { yyextra->insideCppQuote=FALSE; BEGIN(FindMembers); } {B}*"#" { if (yyextra->insidePHP) REJECT; yyextra->lastCPPContext = YY_START; BEGIN( SkipCPP ) ; } {B}*"#"{B}*("cmake")?"define" { if (yyextra->insidePHP) REJECT; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->lastDefineContext = YY_START; BEGIN( Define ); } {B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */ yyextra->yyLineNr = atoi(&yytext[1]); //printf("setting line number to %d\n",yyextra->yyLineNr); yyextra->lastPreLineCtrlContext = YY_START; if (YY_START==ReadBody || YY_START==ReadNSBody || YY_START==ReadBodyIntf) { yyextra->current->program << yytext; } BEGIN( PreLineCtrl ); } "\""[^\n\"]*"\"" { yyextra->yyFileName = stripQuotes(yytext); if (yyextra->lastPreLineCtrlContext==ReadBody || yyextra->lastPreLineCtrlContext==ReadNSBody || yyextra->lastPreLineCtrlContext==ReadBodyIntf) { yyextra->current->program << yytext; } } . { if (yyextra->lastPreLineCtrlContext==ReadBody || yyextra->lastPreLineCtrlContext==ReadNSBody || yyextra->lastPreLineCtrlContext==ReadBodyIntf) { yyextra->current->program << yytext; } } \n { if (yyextra->lastPreLineCtrlContext==ReadBody || yyextra->lastPreLineCtrlContext==ReadNSBody || yyextra->lastPreLineCtrlContext==ReadBodyIntf) { yyextra->current->program << yytext; } lineCount(yyscanner); BEGIN( yyextra->lastPreLineCtrlContext ); } . \\[\r]*"\n"[\r]* { lineCount(yyscanner); } [\r]*\n[\r]* { lineCount(yyscanner); BEGIN( yyextra->lastCPPContext) ; } {ID}{B}*"(" { yyextra->current->name = yytext; yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace(); yyextra->current->args = "("; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = DefineEnd; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; BEGIN( ReadFuncArgType ) ; } /* ")" { //printf("Define with args\n"); yyextra->current->args += ')'; BEGIN( DefineEnd ); } . { yyextra->current->args += *yytext; } */ {ID} { //printf("Define '%s' without args\n",yytext); if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext); } yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->name = yytext; BEGIN(DefineEnd); } \n { //printf("End define: doc=%s docFile=%s docLine=%d\n",yyextra->current->doc.data(),yyextra->current->docFile.data(),yyextra->current->docLine); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->type.resize(0); yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::DEFINE_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); lineCount(yyscanner); initEntry(yyscanner); BEGIN(yyextra->lastDefineContext); } ";" { //printf("End define\n"); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->type.resize(0); yyextra->current->type = "const"; QCString init = yyextra->current->initializer.str(); init = init.simplifyWhiteSpace(); init = init.left(init.length()-1); yyextra->current->initializer.str(init.str()); yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::VARIABLE_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN(FindMembers); } . \\[\r]?\n { lineCount(yyscanner); } \" { if (yyextra->insideIDL && yyextra->insideCppQuote) { BEGIN(EndCppQuote); } else { yyextra->lastStringContext=DefineEnd; BEGIN(SkipString); } } . {ID}["']{BN}*","{BN}* { yyextra->current->name = yytext; yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace(); yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1); yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->lastRoundContext = DefinePHPEnd; yyextra->pCopyRoundGString = &yyextra->current->initializer; yyextra->roundCount = 0; BEGIN( GCopyRound ); } [\^%] { // ^ and % are C++/CLI extensions if (yyextra->insideCli) { addType(yyscanner); yyextra->current->name = yytext ; } else { REJECT; } } [*&]+ { yyextra->current->name += yytext ; addType(yyscanner); } ";"{BN}*{DCOMM}"<" { if (yyextra->current->bodyLine==-1) { yyextra->current->bodyLine=yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; } yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,yyextra->column)); yyextra->docBlock.str(indent.str()); //printf("indent=%d\n",computeIndent(yytext+1,yyextra->column)); lineCount(yyscanner); yyextra->docBlockTerm = ';'; if (YY_START==EnumBaseType && yyextra->current->section==Entry::ENUM_SEC) { yyextra->current->bitfields = ":"+yyextra->current->args; yyextra->current->args.resize(0); yyextra->current->section=Entry::VARIABLE_SEC; } if (yytext[yyleng-3]=='/') { startCommentBlock(yyscanner,TRUE); BEGIN( DocLine ); } else { startCommentBlock(yyscanner,FALSE); BEGIN( DocBlock ); } } ","{BN}*{DCOMM}"<" { yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,yyextra->column)); yyextra->docBlock.str(indent.str()); lineCount(yyscanner); yyextra->docBlockTerm = ','; if (YY_START==EnumBaseType && yyextra->current->section==Entry::ENUM_SEC) { yyextra->current->bitfields = ":"+yyextra->current->args; yyextra->current->args.resize(0); yyextra->current->section=Entry::VARIABLE_SEC; } if (yytext[yyleng-3]=='/') { startCommentBlock(yyscanner,TRUE); BEGIN( DocLine ); } else { startCommentBlock(yyscanner,FALSE); BEGIN( DocBlock ); } } {BN}*{DCOMM}"<" { if (yyextra->current->bodyLine==-1) { yyextra->current->bodyLine=yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; } yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); QCString indent; indent.fill(' ',computeIndent(yytext,yyextra->column)); yyextra->docBlock.str(indent.str()); lineCount(yyscanner); yyextra->docBlockTerm = 0; if (yytext[yyleng-3]=='/') { startCommentBlock(yyscanner,TRUE); BEGIN( DocLine ); } else { startCommentBlock(yyscanner,FALSE); BEGIN( DocBlock ); } } ({CPPC}([!/]){B}*{CMD}"{")|({CCS}([!*]){B}*{CMD}"{") { //handleGroupStartCommand(yyextra->current->name); if (yyextra->previous && yyextra->previous->section==Entry::GROUPDOC_SEC) { // link open command to the group defined in the yyextra->previous entry yyextra->commentScanner.open(yyextra->previous.get(),yyextra->yyFileName,yyextra->yyLineNr); } else { // link open command to the yyextra->current entry yyextra->commentScanner.open(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr); } //yyextra->current = tmp; initEntry(yyscanner); if (yytext[1]=='/') { if (yytext[2]=='!' || yytext[2]=='/') { yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; yyextra->docBlockAutoBrief = FALSE; yyextra->docBlock.str(std::string()); yyextra->docBlockTerm = 0; startCommentBlock(yyscanner,TRUE); BEGIN(DocLine); } else { yyextra->lastCContext=YY_START; BEGIN(SkipCxxComment); } } else { if (yytext[2]=='!' || yytext[2]=='*') { yyextra->docBlockContext = YY_START; yyextra->docBlockInBody = FALSE; yyextra->docBlock.str(std::string()); yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) || ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) ); yyextra->docBlockTerm = 0; startCommentBlock(yyscanner,FALSE); BEGIN(DocBlock); } else { yyextra->lastCContext=YY_START; BEGIN(SkipComment); } } } {CPPC}([!/]){B}*{CMD}"}".*|{CCS}([!*]){B}*{CMD}"}"[^*]*{CCE} { bool insideEnum = YY_START==FindFields || ((YY_START==ReadInitializer || YY_START==ReadInitializerPtr) && yyextra->lastInitializerContext==FindFields); // see bug746226 yyextra->commentScanner.close(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr,insideEnum); lineCount(yyscanner); } "=>" { if (!yyextra->insideCS) REJECT; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->initializer.str(yytext); yyextra->lastInitializerContext = YY_START; yyextra->initBracketCount=0; yyextra->current->mtype = yyextra->mtype = Property; yyextra->current->spec |= Entry::Gettable; BEGIN(ReadInitializerPtr); } "=" { // in PHP code this could also be due to "current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->initializer.str(yytext); yyextra->lastInitializerContext = YY_START; yyextra->initBracketCount=0; BEGIN(ReadInitializer); } {BN}*[gs]"et"{BN}+"raises"{BN}*"("{BN}*{SCOPENAME}{BN}*(","{BN}*{SCOPENAME}{BN}*)*")"{BN}*";" { lineCount(yyscanner); yyextra->current->exception += " "; yyextra->current->exception += removeRedundantWhiteSpace(yytext); } "}" { yyextra->current->exception += " }"; BEGIN(FindMembers); } /* Read initializer rules */ "(" { yyextra->lastRoundContext=YY_START; yyextra->pCopyRoundGString=&yyextra->current->initializer; yyextra->roundCount=0; yyextra->current->initializer << *yytext; BEGIN(GCopyRound); } "[" { if (!yyextra->insidePHP) REJECT; yyextra->lastSquareContext=YY_START; yyextra->pCopySquareGString=&yyextra->current->initializer; yyextra->squareCount=0; yyextra->current->initializer << *yytext; BEGIN(GCopySquare); } "{" { yyextra->lastCurlyContext=YY_START; yyextra->pCopyCurlyGString=&yyextra->current->initializer; yyextra->curlyCount=0; yyextra->current->initializer << *yytext; BEGIN(GCopyCurly); } [;,] { //printf(">> initializer '%s' <<\n",yyextra->current->initializer.data()); if (*yytext==';' && (yyextra->current_root->spec&Entry::Enum)) { yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::VARIABLE_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN(FindMembers); } else if (*yytext==';' || (yyextra->lastInitializerContext==FindFields && yyextra->initBracketCount==0)) // yyextra->initBracketCount==0 was added for bug 665778 { unput(*yytext); if (YY_START == ReadInitializerPtr) yyextra->current->initializer.str(std::string()); BEGIN(yyextra->lastInitializerContext); } else if (*yytext==',' && yyextra->initBracketCount==0) // for "int a=0,b=0" { unput(*yytext); if (YY_START == ReadInitializerPtr) yyextra->current->initializer.str(std::string()); BEGIN(yyextra->lastInitializerContext); } else { yyextra->current->initializer << *yytext; } } {RAWBEGIN} { // C++11 raw string if (!yyextra->insideCpp) { REJECT; } else { QCString text=yytext; yyextra->current->initializer << text; int i=text.find('"'); yyextra->delimiter = yytext+i+1; yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1); yyextra->lastRawStringContext = YY_START; yyextra->pCopyRawGString = &yyextra->current->initializer; BEGIN(RawGString); //printf("RawGString delimiter='%s'\n",delimiter.data()); } } {RAWEND} { *yyextra->pCopyRawGString << yytext; QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); if (delimiter==yyextra->delimiter) { BEGIN(yyextra->lastRawStringContext); } } [^)\n]+ { *yyextra->pCopyRawGString << yytext; } . { *yyextra->pCopyRawGString << yytext; } \n { *yyextra->pCopyRawGString << yytext; lineCount(yyscanner); } {RAWEND} { *yyextra->pCopyRawString+=yytext; yyextra->fullArgString+=yytext; QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); if (delimiter==yyextra->delimiter) { BEGIN(yyextra->lastRawStringContext); } } [^)]+ { *yyextra->pCopyRawString += yytext; yyextra->fullArgString+=yytext; } . { *yyextra->pCopyRawString += yytext; yyextra->fullArgString+=yytext; } \n { *yyextra->pCopyRawString += yytext; yyextra->fullArgString+=yytext; lineCount(yyscanner); } \" { if (yyextra->insideIDL && yyextra->insideCppQuote) { BEGIN(EndCppQuote); } else { yyextra->lastStringContext=YY_START; yyextra->current->initializer << yytext; yyextra->pCopyQuotedGString=&yyextra->current->initializer; BEGIN(CopyGString); } } "->" { yyextra->current->initializer << yytext; } "<<" { yyextra->current->initializer << yytext; } ">>" { yyextra->current->initializer << yytext; } [<\[{(] { yyextra->initBracketCount++; yyextra->current->initializer << *yytext; } [>\]})] { yyextra->initBracketCount--; yyextra->current->initializer << *yytext; } \' { if (yyextra->insidePHP) { yyextra->current->initializer << yytext; yyextra->pCopyQuotedGString = &yyextra->current->initializer; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPGString); } else { yyextra->current->initializer << yytext; } } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { yyextra->current->initializer << yytext; } } \n { yyextra->current->initializer << *yytext; lineCount(yyscanner); } "@\"" { //printf("yyextra->insideCS=%d\n",yyextra->insideCS); yyextra->current->initializer << yytext; if (!yyextra->insideCS && !yyextra->insideObjC) { REJECT; } else { // C#/ObjC verbatim string yyextra->lastSkipVerbStringContext=YY_START; yyextra->pSkipVerbString=&yyextra->current->initializer; BEGIN(SkipVerbString); } } [^\n"]+ { *yyextra->pSkipVerbString << yytext; } "\"\"" { // quote escape *yyextra->pSkipVerbString << yytext; } "\"" { *yyextra->pSkipVerbString << *yytext; BEGIN(yyextra->lastSkipVerbStringContext); } \n { *yyextra->pSkipVerbString << *yytext; lineCount(yyscanner); } . { *yyextra->pSkipVerbString << *yytext; } "?>" { if (yyextra->insidePHP) BEGIN( FindMembersPHP ); else yyextra->current->initializer << yytext; } . { yyextra->current->initializer << *yytext; } /* generic quoted string copy rules */ \\. { *yyextra->pCopyQuotedString+=yytext; } \" { *yyextra->pCopyQuotedString+=*yytext; BEGIN( yyextra->lastStringContext ); } \' { *yyextra->pCopyQuotedString+=*yytext; BEGIN( yyextra->lastStringContext ); } {CCS}|{CCE}|{CPPC} { *yyextra->pCopyQuotedString+=yytext; } \n { *yyextra->pCopyQuotedString+=*yytext; lineCount(yyscanner); } . { *yyextra->pCopyQuotedString+=*yytext; } /* generic quoted growable string copy rules */ \\. { *yyextra->pCopyQuotedGString << yytext; } \" { *yyextra->pCopyQuotedGString << *yytext; BEGIN( yyextra->lastStringContext ); } \' { *yyextra->pCopyQuotedGString << *yytext; BEGIN( yyextra->lastStringContext ); } "pCopyQuotedGString << yytext; BEGIN( yyextra->lastStringContext ); } {CCS}|{CCE}|{CPPC} { *yyextra->pCopyQuotedGString << yytext; } \n { *yyextra->pCopyQuotedGString << *yytext; lineCount(yyscanner); } . { *yyextra->pCopyQuotedGString << *yytext; } /* generic round bracket list copy rules */ \" { *yyextra->pCopyRoundString += *yytext; yyextra->pCopyQuotedString=yyextra->pCopyRoundString; yyextra->lastStringContext=YY_START; BEGIN(CopyString); } "(" { *yyextra->pCopyRoundString += *yytext; yyextra->roundCount++; } ")" { *yyextra->pCopyRoundString += *yytext; if (--yyextra->roundCount<0) BEGIN(yyextra->lastRoundContext); } \n { lineCount(yyscanner); *yyextra->pCopyRoundString += *yytext; } \' { if (yyextra->insidePHP) { yyextra->current->initializer << yytext; yyextra->pCopyQuotedString = yyextra->pCopyRoundString; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPString); } else { *yyextra->pCopyRoundString += yytext; } } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { *yyextra->pCopyRoundString+=yytext; } } [^"'()\n,]+ { *yyextra->pCopyRoundString+=yytext; } . { *yyextra->pCopyRoundString+=*yytext; } /* generic round bracket list copy rules for growable strings */ \" { *yyextra->pCopyRoundGString << *yytext; yyextra->pCopyQuotedGString=yyextra->pCopyRoundGString; yyextra->lastStringContext=YY_START; BEGIN(CopyGString); } "(" { *yyextra->pCopyRoundGString << *yytext; yyextra->roundCount++; } ")" { *yyextra->pCopyRoundGString << *yytext; if (--yyextra->roundCount<0) BEGIN(yyextra->lastRoundContext); } \n { lineCount(yyscanner); *yyextra->pCopyRoundGString << *yytext; } \' { if (yyextra->insidePHP) { yyextra->current->initializer << yytext; yyextra->pCopyQuotedGString = yyextra->pCopyRoundGString; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPGString); } else { *yyextra->pCopyRoundGString << yytext; } } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { *yyextra->pCopyRoundGString << yytext; } } [^"'()\n\/,]+ { *yyextra->pCopyRoundGString << yytext; } . { *yyextra->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 the round bracket version */ \" { *yyextra->pCopySquareGString << *yytext; yyextra->pCopyQuotedGString=yyextra->pCopySquareGString; yyextra->lastStringContext=YY_START; BEGIN(CopyGString); } "[" { *yyextra->pCopySquareGString << *yytext; yyextra->squareCount++; } "]" { *yyextra->pCopySquareGString << *yytext; if (--yyextra->squareCount<0) BEGIN(yyextra->lastSquareContext); } \n { lineCount(yyscanner); *yyextra->pCopySquareGString << *yytext; } \' { if (yyextra->insidePHP) { yyextra->current->initializer << yytext; yyextra->pCopyQuotedGString = yyextra->pCopySquareGString; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPGString); } else { *yyextra->pCopySquareGString << yytext; } } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { *yyextra->pCopySquareGString << yytext; } } [^"\[\]\n\/,]+ { *yyextra->pCopySquareGString << yytext; } . { *yyextra->pCopySquareGString << *yytext; } /* generic curly bracket list copy rules */ \" { *yyextra->pCopyCurlyString += *yytext; yyextra->pCopyQuotedString=yyextra->pCopyCurlyString; yyextra->lastStringContext=YY_START; BEGIN(CopyString); } \' { *yyextra->pCopyCurlyString += *yytext; if (yyextra->insidePHP) { yyextra->pCopyQuotedString=yyextra->pCopyCurlyString; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPString); } } "{" { *yyextra->pCopyCurlyString += *yytext; yyextra->curlyCount++; } "}" { *yyextra->pCopyCurlyString += *yytext; if (--yyextra->curlyCount<0) BEGIN(yyextra->lastCurlyContext); } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { *yyextra->pCopyCurlyString += yytext; } } [^"'{}\/\n,]+ { *yyextra->pCopyCurlyString += yytext; } "/" { *yyextra->pCopyCurlyString += yytext; } \n { lineCount(yyscanner); *yyextra->pCopyCurlyString += *yytext; } . { *yyextra->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); yyextra->yyLineNr = line.mid(s,e-s).toInt(); if (yytext[yyleng-1]=='\n') { lineCount(yyscanner); yyextra->column=0; } } \" { *yyextra->pCopyCurlyGString << *yytext; yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString; yyextra->lastStringContext=YY_START; BEGIN(CopyGString); } \' { *yyextra->pCopyCurlyGString << *yytext; if (yyextra->insidePHP) { yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPGString); } } "{" { *yyextra->pCopyCurlyGString << *yytext; yyextra->curlyCount++; } "}" { *yyextra->pCopyCurlyGString << *yytext; if (--yyextra->curlyCount<0) BEGIN(yyextra->lastCurlyContext); } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { *yyextra->pCopyCurlyGString << yytext; } } [^"'{}\/\n,]+ { *yyextra->pCopyCurlyGString << yytext; } [,]+ { *yyextra->pCopyCurlyGString << yytext; } "/" { *yyextra->pCopyCurlyGString << yytext; } \n { lineCount(yyscanner); *yyextra->pCopyCurlyGString << *yytext; } . { *yyextra->pCopyCurlyGString << *yytext; } /* ---------------------- */ ":" { if (yyextra->current->type.isEmpty() && yyextra->current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}' { yyextra->current->section=Entry::ENUM_SEC; yyextra->current->name.resize(0); yyextra->current->args.resize(0); BEGIN(EnumBaseType); } else { if (yyextra->current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" { addType(yyscanner); yyextra->current->name.sprintf("__pad%d__",yyextra->padCount++); } BEGIN(BitFields); yyextra->current->bitfields+=":"; } } . { yyextra->current->bitfields+=*yytext; } . { yyextra->current->args+=*yytext; } \n { lineCount(yyscanner); yyextra->current->args+=' '; } [;,] { QCString oldType = yyextra->current->type; if (yyextra->current->bodyLine==-1) { yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; } if ( yyextra->insidePHP && yyextra->current->type.left(3) == "var" ) { yyextra->current->type = yyextra->current->type.mid(3); } if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ") { yyextra->current->type.prepend("typedef "); } bool stat = yyextra->current->stat; if (!yyextra->current->name.isEmpty() && yyextra->current->section!=Entry::ENUM_SEC) { yyextra->current->type=yyextra->current->type.simplifyWhiteSpace(); yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args); yyextra->current->name=yyextra->current->name.stripWhiteSpace(); if (yyextra->current->section==Entry::CLASS_SEC) // remove spec for "struct Bla bla;" { yyextra->current->spec = 0; } yyextra->current->section = Entry::VARIABLE_SEC ; yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyBegLineNr; yyextra->current->startColumn = yyextra->yyBegColNr; yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ; initEntry(yyscanner); } if ( *yytext == ',') { yyextra->current->stat = stat; // the static attribute holds for all variables yyextra->current->name.resize(0); yyextra->current->args.resize(0); yyextra->current->brief.resize(0); yyextra->current->doc.resize(0); yyextra->current->initializer.str(std::string()); yyextra->current->bitfields.resize(0); int i=oldType.length(); while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--; yyextra->current->type = oldType.left(i); } else { yyextra->mtype = Method; yyextra->virt = Normal; yyextra->current->groups.clear(); initEntry(yyscanner); } } "[" { if (yyextra->insideSlice) { yyextra->squareCount=1; yyextra->lastSquareContext = YY_START; yyextra->current->metaData += "["; BEGIN( SliceMetadata ); } else if (!yyextra->insideCS && (yyextra->current->name.isEmpty() || yyextra->current->name=="typedef" ) ) // IDL function property { yyextra->squareCount=1; yyextra->lastSquareContext = YY_START; yyextra->idlAttr.resize(0); yyextra->idlProp.resize(0); yyextra->current->mtype = yyextra->mtype; if (Config_getBool(IDL_PROPERTY_SUPPORT) && yyextra->current->mtype == Property) { // we are yyextra->inside the properties section of a dispinterface yyextra->odlProp = true; yyextra->current->spec |= Entry::Gettable; yyextra->current->spec |= Entry::Settable; } BEGIN( IDLAttribute ); } else if (yyextra->insideCS && yyextra->current->name.isEmpty()) { yyextra->squareCount=1; yyextra->lastSquareContext = YY_START; // Skip the C# attribute // for this member yyextra->current->args.resize(0); BEGIN( SkipSquare ); } else { yyextra->current->args += yytext ; yyextra->squareCount=1; yyextra->externC=FALSE; // see bug759247 BEGIN( Array ) ; } } "[" { // Global metadata. yyextra->squareCount++; yyextra->current->metaData += "["; } {BN}* { lineCount(yyscanner); } \"[^\"]*\" { yyextra->current->metaData += yytext; } "," { yyextra->current->metaData += yytext; } "]" { yyextra->current->metaData += yytext; if (--yyextra->squareCount<=0) { BEGIN (yyextra->lastSquareContext); } } "(" { yyextra->current->type += "("; yyextra->roundCount++; } [0-9]+ { yyextra->current->type += yytext; } ")" { yyextra->current->type += ")"; if(--yyextra->roundCount<=0) { BEGIN (yyextra->lastModifierContext); } } "]" { // end of IDL function attribute if (--yyextra->squareCount<=0) { lineCount(yyscanner); if (yyextra->current->mtype == Property) BEGIN( IDLPropName ); else BEGIN( yyextra->lastSquareContext ); } } "propput" { if (Config_getBool(IDL_PROPERTY_SUPPORT)) { yyextra->current->mtype = Property; } yyextra->current->spec |= Entry::Settable; } "propget" { if (Config_getBool(IDL_PROPERTY_SUPPORT)) { yyextra->current->mtype = Property; } yyextra->current->spec |= Entry::Gettable; } "property" { // UNO IDL property yyextra->current->spec |= Entry::Property; } "attribute" { // UNO IDL attribute yyextra->current->spec |= Entry::Attribute; } "optional" { // on UNO IDL interface/service/attribute/property yyextra->current->spec |= Entry::Optional; } "readonly" { // on UNO IDL attribute or property if (Config_getBool(IDL_PROPERTY_SUPPORT) && yyextra->odlProp) { yyextra->current->spec ^= Entry::Settable; } else { yyextra->current->spec |= Entry::Readonly; } } "bound" { // on UNO IDL attribute or property yyextra->current->spec |= Entry::Bound; } "removable" { // on UNO IDL property yyextra->current->spec |= Entry::Removable; } "constrained" { // on UNO IDL property yyextra->current->spec |= Entry::Constrained; } "transient" { // on UNO IDL property yyextra->current->spec |= Entry::Transient; } "maybevoid" { // on UNO IDL property yyextra->current->spec |= Entry::MaybeVoid; } "maybedefault" { // on UNO IDL property yyextra->current->spec |= Entry::MaybeDefault; } "maybeambiguous" { // on UNO IDL property yyextra->current->spec |= Entry::MaybeAmbiguous; } . { } {BN}*{ID}{BN}* { // return type (probably HRESULT) - skip it if (yyextra->odlProp) { // property type yyextra->idlProp = yytext; } } {ID}{BN}*"(" { yyextra->current->name = yytext; yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace(); yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; BEGIN( IDLProp ); } {BN}*"("{BN}*{ID}{BN}*")"{BN}* { if (yyextra->odlProp) { yyextra->idlProp += yytext; } } {ID}{BNopt}/";" { if (yyextra->odlProp) { yyextra->current->name = yytext; yyextra->idlProp = yyextra->idlProp.stripWhiteSpace(); yyextra->odlProp = false; BEGIN( IDLProp ); } } {BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter yyextra->idlAttr = yytext; yyextra->idlAttr=yyextra->idlAttr.stripWhiteSpace(); } {ID} { // property type yyextra->idlProp = yytext; } {BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);) if (!yyextra->current->args) yyextra->current->args = "("; else yyextra->current->args += ", "; yyextra->current->args += yyextra->idlAttr; yyextra->current->args += " "; yyextra->current->args += yyextra->idlProp; // prop was actually type of extra parameter yyextra->current->args += " "; yyextra->current->args += yytext; yyextra->current->args = yyextra->current->args.left(yyextra->current->args.length() - 1); // strip comma yyextra->idlProp.resize(0); yyextra->idlAttr.resize(0); BEGIN( IDLProp ); } {BN}*{ID}{BN}*")"{BN}* { // the parameter name for the property - just skip. } ";" { yyextra->current->fileName = yyextra->yyFileName; yyextra->current->type = yyextra->idlProp; yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); if (yyextra->current->args) yyextra->current->args += ")"; yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::VARIABLE_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN( FindMembers ); } . { // spaces, *, or other stuff //yyextra->idlProp+=yytext; } "]" { yyextra->current->args += *yytext ; if (--yyextra->squareCount<=0) BEGIN( FindMembers ) ; } "]" { yyextra->current->args += *yytext ; if (--yyextra->squareCount<=0) BEGIN( Function ) ; } "[" { yyextra->current->args += *yytext ; yyextra->squareCount++; } . { yyextra->current->args += *yytext ; } "[" { yyextra->squareCount++; } "]" { if (--yyextra->squareCount<=0) BEGIN( yyextra->lastSquareContext ); } \" { yyextra->lastStringContext=YY_START; BEGIN( SkipString ); } [^\n\[\]\"]+ "<" { addType(yyscanner); yyextra->current->type += yytext ; BEGIN( Sharp ) ; } ">" { yyextra->current->type += *yytext ; if (--yyextra->sharpCount<=0) BEGIN( FindMembers ) ; } "<" { yyextra->current->type += *yytext ; yyextra->sharpCount++; } {BN}+ { yyextra->current->type += ' '; lineCount(yyscanner); } . { yyextra->current->type += *yytext ; } {ID} { if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC)) { yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext); } yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->current->name = yytext; } "(" { // Java enum initializer unput('('); yyextra->lastInitializerContext = YY_START; yyextra->initBracketCount=0; yyextra->current->initializer.str("="); BEGIN(ReadInitializer); } "=" { yyextra->lastInitializerContext = YY_START; yyextra->initBracketCount=0; yyextra->current->initializer.str(yytext); BEGIN(ReadInitializer); } ";" { if (yyextra->insideJava) // yyextra->last enum field in Java class { if (!yyextra->current->name.isEmpty()) { yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; if (!(yyextra->current_root->spec&Entry::Enum)) { yyextra->current->type = "@"; // enum marker } yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::VARIABLE_SEC; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); } BEGIN( FindMembers ); } else { REJECT; } } \n { lineCount(yyscanner); } [^\n]* "," { //printf("adding '%s' '%s' '%s' to enum '%s' (mGrpId=%d)\n", // yyextra->current->type.data(), yyextra->current->name.data(), // yyextra->current->args.data(), yyextra->current_root->name.data(),yyextra->current->mGrpId); if (!yyextra->current->name.isEmpty()) { yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyLineNr; yyextra->current->startColumn = yyextra->yyColNr; if (!(yyextra->current_root->spec&Entry::Enum)) { yyextra->current->type = "@"; // enum marker } yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->name = yyextra->current->name.stripWhiteSpace(); yyextra->current->section = Entry::VARIABLE_SEC; // add to the scope of the enum if (!yyextra->insideCS && !yyextra->insideJava && !(yyextra->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 {}) { // add to the scope surrounding the enum (copy!) // we cannot during it directly as that would invalidate the iterator in parseCompounds. //printf("*** adding outer scope entry for %s\n",yyextra->current->name.data()); yyextra->outerScopeEntries.emplace_back(yyextra->current_root->parent(), std::make_shared(*yyextra->current)); } yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); } else // probably a redundant , { yyextra->current->reset(); initEntry(yyscanner); } } "[" { // attribute list in IDL yyextra->squareCount=1; yyextra->lastSquareContext = YY_START; BEGIN(SkipSquare); } /* "," { unput(*yytext); BEGIN(FindFields); } */ [^\r\n\#{}"@'/<]* { yyextra->current->program << yytext ; } {CPPC}.* { yyextra->current->program << yytext ; } "#".* { if (!yyextra->insidePHP) REJECT; // append PHP comment. yyextra->current->program << yytext ; } @\" { yyextra->current->program << yytext ; yyextra->pSkipVerbString = &yyextra->current->program; yyextra->lastSkipVerbStringContext=YY_START; BEGIN( SkipVerbString ); } "<<<" { if (yyextra->insidePHP) { yyextra->current->program << yytext ; yyextra->pCopyHereDocGString = &yyextra->current->program; yyextra->lastHereDocContext=YY_START; BEGIN( CopyHereDoc ); } else { REJECT; } } \" { yyextra->current->program << yytext ; yyextra->pCopyQuotedGString = &yyextra->current->program; yyextra->lastStringContext=YY_START; BEGIN( CopyGString ); } {CCS}{B}* { yyextra->current->program << yytext ; yyextra->lastContext = YY_START ; BEGIN( Comment ) ; } {CCS}{BL} { yyextra->current->program << yytext ; ++yyextra->yyLineNr ; yyextra->lastContext = YY_START ; BEGIN( Comment ) ; } "'" { if (!yyextra->insidePHP) { yyextra->current->program << yytext; } else { // begin of single quoted string yyextra->current->program << yytext; yyextra->pCopyQuotedGString = &yyextra->current->program; yyextra->lastStringContext=YY_START; BEGIN(CopyPHPGString); } } {CHARLIT} { if (yyextra->insidePHP) { REJECT; // for PHP code single quotes // are used for strings of arbitrary length } else { yyextra->current->program << yytext; } } "{" { yyextra->current->program << yytext ; ++yyextra->curlyCount ; } "}" { yyextra->current->program << yytext ; --yyextra->curlyCount ; } "}" { //err("ReadBody count=%d\n",yyextra->curlyCount); if ( yyextra->curlyCount>0 ) { yyextra->current->program << yytext ; --yyextra->curlyCount ; } else { yyextra->current->endBodyLine = yyextra->yyLineNr; std::shared_ptr original_root = yyextra->current_root; // save root this namespace is in if (yyextra->current->section == Entry::NAMESPACE_SEC && yyextra->current->type == "namespace") { int split_point; // save documentation values QCString doc = yyextra->current->doc; int docLine = yyextra->current->docLine; QCString docFile = yyextra->current->docFile; QCString brief = yyextra->current->brief; int briefLine = yyextra->current->briefLine; QCString briefFile = yyextra->current->briefFile; // reset documentation values yyextra->current->doc = ""; yyextra->current->docLine = 0; yyextra->current->docFile = ""; yyextra->current->brief = ""; yyextra->current->briefLine = 0; yyextra->current->briefFile = ""; while ((split_point = yyextra->current->name.find("::")) != -1) { std::shared_ptr new_current = std::make_shared(*yyextra->current); yyextra->current->program.str(std::string()); new_current->name = yyextra->current->name.mid(split_point + 2); yyextra->current->name = yyextra->current->name.left(split_point); if (!yyextra->current_root->name.isEmpty()) yyextra->current->name.prepend(yyextra->current_root->name+"::"); yyextra->current_root->moveToSubEntryAndKeep(yyextra->current); yyextra->current_root = yyextra->current; yyextra->current = new_current; } // restore documentation values yyextra->current->doc = doc; yyextra->current->docLine = docLine; yyextra->current->docFile = docFile; yyextra->current->brief = brief; yyextra->current->briefLine = briefLine; yyextra->current->briefFile = briefFile; } QCString &cn = yyextra->current->name; QCString rn = yyextra->current_root->name.copy(); //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",cn.data(),rn.data(),yyextra->isTypedef); if (!cn.isEmpty() && !rn.isEmpty()) { prependScope(yyscanner); } if (yyextra->isTypedef && cn.isEmpty()) { //printf("Typedef Name\n"); BEGIN( TypedefName ); } else { if ((yyextra->current->section == Entry::ENUM_SEC) || (yyextra->current->spec&Entry::Enum)) { yyextra->current->program << ','; // add field terminator } // add compound definition to the tree yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args); // was: yyextra->current->args.simplifyWhiteSpace(); yyextra->current->type = yyextra->current->type.simplifyWhiteSpace(); yyextra->current->name = yyextra->current->name.stripWhiteSpace(); //printf("adding '%s' '%s' '%s' brief=%s yyextra->insideObjC=%d %x\n",yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data(),yyextra->current->brief.data(),yyextra->insideObjC,yyextra->current->section); if (yyextra->insideObjC && ((yyextra->current->spec&Entry::Interface) || (yyextra->current->spec==Entry::Category)) ) // method definition follows { BEGIN( ReadBodyIntf ) ; } else { yyextra->memspecEntry = yyextra->current; yyextra->current_root->moveToSubEntryAndKeep( yyextra->current ) ; yyextra->current = std::make_shared(*yyextra->current); if (yyextra->current->section==Entry::NAMESPACE_SEC || (yyextra->current->spec==Entry::Interface) || yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideJS || yyextra->insideSlice ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon yyextra->current->reset(); yyextra->current_root = original_root; // restore scope from before namespace descent initEntry(yyscanner); yyextra->memspecEntry.reset(); BEGIN( FindMembers ) ; } else { static const reg::Ex re(R"(@\d+$)"); if (!yyextra->isTypedef && yyextra->memspecEntry && !reg::search(yyextra->memspecEntry->name.str(),re)) // not typedef or anonymous type (see bug691071) { // enabled the next two lines for bug 623424 yyextra->current->doc.resize(0); yyextra->current->brief.resize(0); } BEGIN( MemberSpec ) ; } } } } } "}"{BN}+"typedef"{BN}+ { //err("ReadBody count=%d\n",yyextra->curlyCount); lineCount(yyscanner); if ( yyextra->curlyCount>0 ) { yyextra->current->program << yytext ; --yyextra->curlyCount ; } else { yyextra->isTypedef = TRUE; yyextra->current->endBodyLine = yyextra->yyLineNr; QCString &cn = yyextra->current->name; QCString rn = yyextra->current_root->name.copy(); if (!cn.isEmpty() && !rn.isEmpty()) { prependScope(yyscanner); } BEGIN( TypedefName ); } } ("const"|"volatile"){BN} { // late "const" or "volatile" keyword lineCount(yyscanner); yyextra->current->type.prepend(yytext); } {ID} { if ((yyextra->current->section == Entry::ENUM_SEC) || (yyextra->current->spec&Entry::Enum)) { yyextra->current->program << ","; // add field terminator } yyextra->current->name=yytext; prependScope(yyscanner); yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->type = yyextra->current->type.simplifyWhiteSpace(); //printf("Adding compound %s %s %s\n",yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); if (!yyextra->firstTypedefEntry) { yyextra->firstTypedefEntry = yyextra->current; } yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ; initEntry(yyscanner); yyextra->isTypedef=TRUE; // to undo reset by initEntry(yyscanner) BEGIN(MemberSpecSkip); } ";" { /* typedef of anonymous type */ yyextra->current->name.sprintf("@%d",anonCount++); if ((yyextra->current->section == Entry::ENUM_SEC) || (yyextra->current->spec&Entry::Enum)) { yyextra->current->program << ','; // add field terminator } // add compound definition to the tree yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->type = yyextra->current->type.simplifyWhiteSpace(); yyextra->memspecEntry = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ; initEntry(yyscanner); unput(';'); BEGIN( MemberSpec ) ; } ([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved. lineCount(yyscanner); int i=0,l=(int)yyleng,j; while (imsName = QCString(yytext).right(l-i).stripWhiteSpace(); j=yyextra->msName.find("["); if (j!=-1) { yyextra->msArgs=yyextra->msName.right(yyextra->msName.length()-j); yyextra->msName=yyextra->msName.left(j); } yyextra->msType=QCString(yytext).left(i); // handle *pName in: typedef { ... } name, *pName; if (yyextra->firstTypedefEntry) { if (yyextra->firstTypedefEntry->spec&Entry::Struct) { yyextra->msType.prepend("struct "+yyextra->firstTypedefEntry->name); } else if (yyextra->firstTypedefEntry->spec&Entry::Union) { yyextra->msType.prepend("union "+yyextra->firstTypedefEntry->name); } else if (yyextra->firstTypedefEntry->section==Entry::ENUM_SEC) { yyextra->msType.prepend("enum "+yyextra->firstTypedefEntry->name); } else { yyextra->msType.prepend(yyextra->firstTypedefEntry->name); } } } "(" { // function with struct return type addType(yyscanner); yyextra->current->name = yyextra->msName; yyextra->current->spec = 0; unput('('); BEGIN(FindMembers); } [,;] { if (yyextra->msName.isEmpty() && !yyextra->current->name.isEmpty()) { // see if the compound does not have a name or is yyextra->inside another // anonymous compound. If so we insert a // special 'anonymous' variable. //Entry *p=yyextra->current_root; const Entry *p=yyextra->current.get(); 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 yyextra->inside -> insert dummy variable name //printf("Adding anonymous variable for scope %s\n",p->name.data()); yyextra->msName.sprintf("@%d",anonCount++); break; } } //p=p->parent; if (p==yyextra->current.get()) p=yyextra->current_root.get(); else p=p->parent(); } } //printf("yyextra->msName=%s yyextra->current->name=%s\n",yyextra->msName.data(),yyextra->current->name.data()); if (!yyextra->msName.isEmpty() /*&& yyextra->msName!=yyextra->current->name*/) // skip typedef T {} T;, removed due to bug608493 { 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 && yyextra->isTypedef && ((yyextra->current->spec&(Entry::Struct|Entry::Union)) || yyextra->current->section==Entry::ENUM_SEC )&& yyextra->msType.stripWhiteSpace().isEmpty() && yyextra->memspecEntry) { yyextra->memspecEntry->name=yyextra->msName; } else // case 2: create a typedef field { std::shared_ptr varEntry=std::make_shared(); varEntry->lang = yyextra->language; varEntry->protection = yyextra->current->protection ; varEntry->mtype = yyextra->current->mtype; varEntry->virt = yyextra->current->virt; varEntry->stat = yyextra->current->stat; varEntry->section = Entry::VARIABLE_SEC; varEntry->name = yyextra->msName.stripWhiteSpace(); varEntry->type = yyextra->current->type.simplifyWhiteSpace()+" "; varEntry->args = yyextra->msArgs; if (yyextra->isTypedef) { varEntry->type.prepend("typedef "); // //printf("yyextra->current->name = %s %s\n",yyextra->current->name.data(),yyextra->msName.data()); } if (typedefHidesStruct && yyextra->isTypedef && (yyextra->current->spec&(Entry::Struct|Entry::Union)) && yyextra->memspecEntry ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;" { varEntry->type+=yyextra->memspecEntry->name+yyextra->msType; } else // case 2: use _S as type for for pS_t { varEntry->type+=yyextra->current->name+yyextra->msType; } varEntry->fileName = yyextra->yyFileName; varEntry->startLine = yyextra->yyLineNr; varEntry->startColumn = yyextra->yyColNr; varEntry->doc = yyextra->current->doc.copy(); varEntry->brief = yyextra->current->brief.copy(); varEntry->mGrpId = yyextra->current->mGrpId; varEntry->initializer.str(yyextra->current->initializer.str()); varEntry->groups = yyextra->current->groups; varEntry->sli = yyextra->current->sli; //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()); yyextra->current_root->moveToSubEntryAndKeep(varEntry); } } if (*yytext==';') // end of a struct/class ... { if (!yyextra->isTypedef && yyextra->msName.isEmpty() && yyextra->memspecEntry && (yyextra->current->section&Entry::COMPOUND_MASK)) { // case where a class/struct has a doc block after it if (!yyextra->current->doc.isEmpty()) { yyextra->memspecEntry->doc += yyextra->current->doc; } if (!yyextra->current->brief.isEmpty()) { yyextra->memspecEntry->brief += yyextra->current->brief; } } yyextra->msType.resize(0); yyextra->msName.resize(0); yyextra->msArgs.resize(0); yyextra->isTypedef=FALSE; yyextra->firstTypedefEntry.reset(); yyextra->memspecEntry.reset(); yyextra->current->reset(); initEntry(yyscanner); BEGIN( FindMembers ); } else { yyextra->current->doc.resize(0); yyextra->current->brief.resize(0); } } "=" { yyextra->lastInitializerContext=YY_START; yyextra->initBracketCount=0; yyextra->current->initializer.str(yytext); BEGIN(ReadInitializer); /* BEGIN(MemberSpecSkip); */ } /* "{" { yyextra->curlyCount=0; yyextra->lastCurlyContext = MemberSpecSkip; yyextra->previous = yyextra->current; BEGIN(SkipCurly); } */ "," { BEGIN(MemberSpec); } ";" { unput(';'); BEGIN(MemberSpec); } {BN}{1,80} { yyextra->current->program << yytext ; lineCount(yyscanner) ; } "@end"/[^a-z_A-Z0-9] { // end of Objective C block yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ; initEntry(yyscanner); yyextra->language = yyextra->current->lang = SrcLangExt_Cpp; // see bug746361 yyextra->insideObjC=FALSE; BEGIN( FindMembers ); } . { yyextra->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 (yyextra->insidePHP) // reference parameter { REJECT } else { yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; lineCount(yyscanner); addType(yyscanner); yyextra->funcPtrType=yytext; yyextra->roundCount=0; //yyextra->current->type += yytext; BEGIN( FuncPtr ); } } {SCOPENAME} { yyextra->current->name = yytext; if (nameIsOperator(yyextra->current->name)) { BEGIN( FuncPtrOperator ); } else { if (yyextra->current->name=="const" || yyextra->current->name=="volatile") { yyextra->funcPtrType += yyextra->current->name; } else { BEGIN( EndFuncPtr ); } } } . { //printf("error: FuncPtr '%c' unexpected at line %d of %s\n",*yytext,yyextra->yyLineNr,yyextra->yyFileName); } "("{BN}*")"{BNopt}/"(" { yyextra->current->name += yytext; yyextra->current->name = yyextra->current->name.simplifyWhiteSpace(); lineCount(yyscanner); } \n { lineCount(yyscanner); yyextra->current->name += *yytext; } "(" { unput(*yytext); BEGIN( EndFuncPtr ); } . { yyextra->current->name += *yytext; } ")"{BNopt}/";" { // a variable with extra braces lineCount(yyscanner); yyextra->current->type+=yyextra->funcPtrType.data()+1; BEGIN(FindMembers); } ")"{BNopt}/"(" { // a function pointer lineCount(yyscanner); yyextra->current->type+=yyextra->funcPtrType+")"; BEGIN(FindMembers); } ")"{BNopt}/"[" { // an array of variables lineCount(yyscanner); yyextra->current->type+=yyextra->funcPtrType.data(); yyextra->current->args += ")"; BEGIN(FindMembers); } "(" { // a function returning a function or // a function returning a pointer to an array yyextra->current->args += *yytext ; //yyextra->roundCount=0; //BEGIN( FuncFunc ); yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = FuncFuncEnd; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; BEGIN( ReadFuncArgType ) ; } "["[^\n\]]*"]" { yyextra->funcPtrType+=yytext; } ")" { BEGIN(FindMembers); } "(" { yyextra->current->args += *yytext ; ++yyextra->roundCount; } ")" { yyextra->current->args += *yytext ; if ( yyextra->roundCount ) --yyextra->roundCount; else { BEGIN(FuncFuncEnd); } } ")"{BN}*"(" { lineCount(yyscanner); yyextra->current->type+=yyextra->funcPtrType+")("; BEGIN(FuncFuncType); } ")"{BNopt}/[;{] { lineCount(yyscanner); yyextra->current->type+=yyextra->funcPtrType.data()+1; BEGIN(Function); } ")"{BNopt}/"[" { // function returning a pointer to an array lineCount(yyscanner); yyextra->current->type+=yyextra->funcPtrType; yyextra->current->args+=")"; BEGIN(FuncFuncArray); } . { yyextra->current->args += *yytext; } "(" { yyextra->current->type += *yytext; yyextra->roundCount++; } ")" { yyextra->current->type += *yytext; if (yyextra->roundCount) --yyextra->roundCount; else BEGIN(Function); } {BN}*","{BN}* { lineCount(yyscanner) ; yyextra->current->type += ", " ; } {BN}+ { lineCount(yyscanner) ; yyextra->current->type += ' ' ; } . { yyextra->current->type += *yytext; } "("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")"{BN}*"(" { // for catching typedef void (__stdcall *f)() like definitions if (yyextra->current->type.left(7)=="typedef" && yyextra->current->bodyLine==-1) // the bodyLine check is to prevent this guard to be true more than once { yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; BEGIN( GetCallType ); } else if (!yyextra->current->name.isEmpty()) // normal function { yyextra->current->args = yytext; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = FuncQual; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; BEGIN( ReadFuncArgType ) ; //printf(">>> Read function arguments!\n"); } } {BN}*{ID}{BN}*"*" { lineCount(yyscanner); addType(yyscanner); yyextra->funcPtrType="("; yyextra->funcPtrType+=yytext; yyextra->roundCount=0; BEGIN( FuncPtr ); } "(" { if (!yyextra->current->name.isEmpty()) { yyextra->current->args = yytext; yyextra->current->bodyLine = yyextra->yyLineNr; yyextra->current->bodyColumn = yyextra->yyColNr; yyextra->currentArgumentContext = FuncQual; yyextra->fullArgString=yyextra->current->args.copy(); yyextra->copyArgString=&yyextra->current->args; BEGIN( ReadFuncArgType ) ; //printf(">>> Read function arguments yyextra->current->argList.size()=%d\n",yyextra->current->argList.size()); } } /* "("{BN}*("void"{BN}*)?")" { lineCount(yyscanner); yyextra->current->args = "()"; BEGIN( FuncQual ); } */ /*- Function argument reading rules ---------------------------------------*/ [^ \/\r\t\n\)\(\"\'#]+ { *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; } [^\n\\\"\']+ { *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; } [^\/\n\)\(\"\']+ { *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; } {BN}* { *yyextra->copyArgString+=" "; yyextra->fullArgString+=" "; lineCount(yyscanner); } {RAWBEGIN} { yyextra->delimiter = yytext+2; yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1); yyextra->lastRawStringContext = YY_START; yyextra->pCopyRawString = yyextra->copyArgString; *yyextra->pCopyRawString+=yytext; yyextra->fullArgString+=yytext; BEGIN(RawString); } \" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->lastCopyArgStringContext = YY_START; BEGIN( CopyArgString ); } "(" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->argRoundCount=0; yyextra->lastCopyArgContext = YY_START; BEGIN( CopyArgRound ); } ")" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString); if (yyextra->insideJS) { fixArgumentListForJavaScript(yyextra->current->argList); } handleParametersCommentBlocks(yyscanner,yyextra->current->argList); /* remember the yyextra->current documentation block, since we could overwrite it with the documentation of a function argument, which we then have to correct later on */ yyextra->docBackup = yyextra->current->doc; yyextra->briefBackup = yyextra->current->brief; BEGIN( yyextra->currentArgumentContext ); } /* a special comment */ ({CCS}[*!]|{CPPC}[/!])("<"?) { if (yyextra->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]); } yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString); handleParametersCommentBlocks(yyscanner,yyextra->current->argList); BEGIN( yyextra->currentArgumentContext ); } else // not a define { // for functions we interpret a comment // as documentation for the argument yyextra->fullArgString+=yytext; yyextra->lastCopyArgChar=0; yyextra->lastCommentInArgContext=YY_START; if (yytext[1]=='/') BEGIN( CopyArgCommentLine ); else BEGIN( CopyArgComment ); } } /* a non-special comment */ {CCS}{CCE} { /* empty comment */ } {CCS} { yyextra->lastCContext = YY_START; BEGIN( SkipComment ); } {CPPC} { yyextra->lastCContext = YY_START; BEGIN( SkipCxxComment ); } /* "'#" { if (yyextra->insidePHP) REJECT; *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; } "#" { if (!yyextra->insidePHP) REJECT; yyextra->lastCContext = YY_START; BEGIN( SkipCxxComment ); } */ /* ')' followed by a special comment */ ")"{BN}*({CCS}[*!]|{CPPC}[/!])"<" { lineCount(yyscanner); if (yyextra->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]); } *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString); handleParametersCommentBlocks(yyscanner,yyextra->current->argList); BEGIN( yyextra->currentArgumentContext ); } else { // for functions we interpret a comment // as documentation for the yyextra->last argument yyextra->lastCopyArgChar=*yytext; QCString text=&yytext[1]; text=text.stripWhiteSpace(); yyextra->lastCommentInArgContext=YY_START; yyextra->fullArgString+=text; if (text.find("//")!=-1) BEGIN( CopyArgCommentLine ); else BEGIN( CopyArgComment ); } } ^{B}*"*"+/{BN}+ [^\n\\\@\*]+ { yyextra->fullArgString+=yytext; } {CCE} { yyextra->fullArgString+=yytext; if (yyextra->lastCopyArgChar!=0) unput(yyextra->lastCopyArgChar); BEGIN( yyextra->lastCommentInArgContext ); } \n { yyextra->fullArgString+=yytext; lineCount(yyscanner); if (yyextra->lastCopyArgChar!=0) unput(yyextra->lastCopyArgChar); BEGIN( yyextra->lastCommentInArgContext ); } {CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) yyextra->docBlockName=&yytext[1]; yyextra->fullArgString+=yytext; BEGIN(CopyArgVerbatim); } {CMD}("f$"|"f["|"f{") { yyextra->docBlockName=&yytext[1]; if (yyextra->docBlockName.at(1)=='[') { yyextra->docBlockName.at(1)='}'; } if (yyextra->docBlockName.at(1)=='{') { yyextra->docBlockName.at(1)='}'; } yyextra->fullArgString+=yytext; BEGIN(CopyArgVerbatim); } [\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9\-] { // end of verbatim block yyextra->fullArgString+=yytext; if (yytext[1]=='f') // end of formula { BEGIN(CopyArgCommentLine); } if (&yytext[4]==yyextra->docBlockName) { BEGIN(CopyArgCommentLine); } } [^\\\@\n]+ { yyextra->fullArgString+=yytext; } . { yyextra->fullArgString+=*yytext; } \n { yyextra->fullArgString+=*yytext; lineCount(yyscanner); } . { yyextra->fullArgString+=*yytext; } {CMD}("brief"|"short"){B}+ { warn(yyextra->yyFileName,yyextra->yyLineNr, "Ignoring %cbrief command inside argument documentation",*yytext ); yyextra->fullArgString+=' '; } "<" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->argSharpCount=1; BEGIN( CopyArgSharp ); } ">" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; //printf("end template list '%s'\n",yyextra->copyArgString->data()); *yyextra->currentArgumentList = *stringToArgumentList(yyextra->language, yyextra->fullArgString); BEGIN( yyextra->currentArgumentContext ); } "(" { yyextra->argRoundCount++; *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; } ")" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; if (yyextra->argRoundCount>0) yyextra->argRoundCount--; else BEGIN( yyextra->lastCopyArgContext ); } "(" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->argRoundCount=0; yyextra->lastCopyArgContext = YY_START; BEGIN( CopyArgRound ); } "<" { yyextra->argSharpCount++; //printf("yyextra->argSharpCount++=%d copy\n",yyextra->argSharpCount); *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; } ">" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; yyextra->argSharpCount--; if (yyextra->argSharpCount>0) { //printf("yyextra->argSharpCount--=%d copy\n",yyextra->argSharpCount); } else { BEGIN( ReadTempArgs ); //printf("end of yyextra->argSharpCount\n"); } } \\. { *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; } \" { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; BEGIN( yyextra->lastCopyArgStringContext ); } \' { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; BEGIN( yyextra->lastCopyArgStringContext ); } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; } } \' { *yyextra->copyArgString+=yytext; yyextra->fullArgString+=yytext; if (yyextra->insidePHP) { yyextra->lastCopyArgStringContext=YY_START; BEGIN(CopyArgPHPString); } } \n { lineCount(yyscanner); *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; } . { *yyextra->copyArgString+=*yytext; yyextra->fullArgString+=*yytext; } /*------------------------------------------------------------------------*/ "(" { yyextra->current->args += *yytext ; ++yyextra->roundCount ; } ")" { yyextra->current->args += *yytext ; if ( yyextra->roundCount ) --yyextra->roundCount ; else BEGIN( FuncQual ) ; } /* "#" { if (yyextra->insidePHP) REJECT; yyextra->lastCPPContext = YY_START; BEGIN(SkipCPP); } */ [{:;,] { if ( qstrcmp(yytext,";")==0 && yyextra->insidePHP && !containsWord(yyextra->current->type,"function") ) { yyextra->current->reset(); initEntry(yyscanner); BEGIN( FindMembers ); } else { unput(*yytext); BEGIN( Function ); } } {BN}*"abstract"{BN}* { // pure virtual member function lineCount(yyscanner) ; yyextra->current->virt = Pure; yyextra->current->args += " override "; } {BN}*"override"{BN}* { // C++11 overridden virtual member function lineCount(yyscanner) ; yyextra->current->spec |= Entry::Override; yyextra->current->args += " override "; BEGIN(FuncQual); } {BN}*"final"{BN}* { // C++11 final method lineCount(yyscanner) ; yyextra->current->spec |= Entry::Final; yyextra->current->args += " final "; BEGIN(FuncQual); } {BN}*"sealed"{BN}* { // sealed member function lineCount(yyscanner) ; yyextra->current->spec |= Entry::Sealed; yyextra->current->args += " sealed "; } {BN}*"new"{BN}* { // new member function lineCount(yyscanner) ; yyextra->current->spec |= Entry::New; yyextra->current->args += " new "; } {BN}*"const"{BN}* { // const member function lineCount(yyscanner) ; yyextra->current->args += " const "; yyextra->current->argList.setConstSpecifier(TRUE); } {BN}*"volatile"{BN}* { // volatile member function lineCount(yyscanner) ; yyextra->current->args += " volatile "; yyextra->current->argList.setVolatileSpecifier(TRUE); } {BN}*"noexcept"{BN}* { // noexcept qualifier lineCount(yyscanner) ; yyextra->current->args += " noexcept "; yyextra->current->spec |= Entry::NoExcept; } {BN}*"noexcept"{BN}*"(" { // noexcept expression lineCount(yyscanner) ; yyextra->current->args += " noexcept("; yyextra->current->spec |= Entry::NoExcept; yyextra->lastRoundContext=FuncQual; yyextra->pCopyRoundString=&yyextra->current->args; yyextra->roundCount=0; BEGIN(CopyRound); } {BN}*"&" { yyextra->current->args += " &"; yyextra->current->argList.setRefQualifier(RefQualifierLValue); } {BN}*"&&" { yyextra->current->args += " &&"; yyextra->current->argList.setRefQualifier(RefQualifierRValue); } {BN}*"="{BN}*"0"{BN}* { // pure virtual member function lineCount(yyscanner) ; yyextra->current->args += " = 0"; yyextra->current->virt = Pure; yyextra->current->argList.setPureSpecifier(TRUE); BEGIN(FuncQual); } {BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member lineCount(yyscanner); yyextra->current->args += " = delete"; yyextra->current->spec |= Entry::Delete; yyextra->current->argList.setIsDeleted(TRUE); BEGIN(FuncQual); } {BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator lineCount(yyscanner); yyextra->current->args += " = default"; yyextra->current->spec |= Entry::Default; BEGIN(FuncQual); } {BN}*"->"{BN}* { lineCount(yyscanner); yyextra->current->argList.setTrailingReturnType(" -> "); yyextra->current->args += " -> "; yyextra->roundCount=0; BEGIN(TrailingReturn); } [{;] { if (yyextra->roundCount>0) REJECT; unput(*yytext); BEGIN(FuncQual); } "(" { yyextra->roundCount++; yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext); yyextra->current->args+=yytext; } ")" { if (yyextra->roundCount>0) { yyextra->roundCount--; } else { warn(yyextra->yyFileName,yyextra->yyLineNr, "Found ')' without opening '(' for trailing return type '%s)...'", yyextra->current->argList.trailingReturnType().data()); } yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext); yyextra->current->args+=yytext; } . { yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext); yyextra->current->args+=yytext; } \n { lineCount(yyscanner); yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext); yyextra->current->args+=' '; } {BN}*","{BN}* { lineCount(yyscanner) ; yyextra->current->args += ", " ; } {BN}+ { lineCount(yyscanner) ; yyextra->current->args += ' ' ; } "#" { if (yyextra->insidePHP) REJECT; yyextra->lastCPPContext = YY_START; BEGIN(SkipCPP); } "=" { if (yyextra->insideCli && (yyextra->current_root->section&Entry::COMPOUND_MASK) ) { BEGIN(CliOverride); } else { // typically an initialized function pointer yyextra->lastInitializerContext=YY_START; yyextra->initBracketCount=0; yyextra->current->initializer.str(yytext); BEGIN(ReadInitializer); } } {ID} { } "{" { unput(*yytext); BEGIN(FuncQual); } \n { lineCount(yyscanner); } . { } [{;] { unput(*yytext); BEGIN(FuncQual); } \" { yyextra->current->args += *yytext; yyextra->pCopyQuotedString=&yyextra->current->args; yyextra->lastStringContext=FuncPtrInit; BEGIN(CopyString); } \' { yyextra->current->args += *yytext; if (yyextra->insidePHP) { yyextra->pCopyQuotedString=&yyextra->current->args; yyextra->lastStringContext=FuncPtrInit; BEGIN(CopyPHPString); } } {CHARLIT} { if (yyextra->insidePHP) { REJECT; } else { yyextra->current->args += yytext; } } {ID} { yyextra->current->args += yytext; } . { yyextra->current->args += *yytext; } \n { yyextra->current->args += *yytext; lineCount(yyscanner); } {ID} { // typically a K&R style C function if (yyextra->insideCS && qstrcmp(yytext,"where")==0) { // type constraint for a method yyextra->current->typeConstr.clear(); yyextra->current->typeConstr.push_back(Argument()); yyextra->lastCSConstraint = YY_START; BEGIN( CSConstraintName ); } else if (checkForKnRstyleC(yyscanner)) { yyextra->current->args = yytext; yyextra->oldStyleArgType.resize(0); BEGIN(OldStyleArgs); } else { yyextra->current->args += yytext; } } [,;] { QCString oldStyleArgPtr; QCString oldStyleArgName; splitKnRArg(yyscanner,oldStyleArgPtr,oldStyleArgName); QCString doc,brief; if (yyextra->current->doc!=yyextra->docBackup) { doc=yyextra->current->doc.copy(); yyextra->current->doc=yyextra->docBackup; } if (yyextra->current->brief!=yyextra->briefBackup) { brief=yyextra->current->brief.copy(); yyextra->current->brief=yyextra->briefBackup; } addKnRArgInfo(yyscanner,yyextra->oldStyleArgType+oldStyleArgPtr, oldStyleArgName,brief,doc); yyextra->current->args.resize(0); if (*yytext==';') yyextra->oldStyleArgType.resize(0); } {ID} { yyextra->current->args += yytext; } "{" { if (yyextra->current->argList.empty()) { yyextra->current->argList.setNoParameters(TRUE); } yyextra->current->args = argListToString(yyextra->current->argList); unput('{'); BEGIN(FuncQual); } . { yyextra->current->args += *yytext; } . { yyextra->current->args += *yytext; } {BN}*"try:" | {BN}*"try"{BN}+ { /* try-function-block */ yyextra->insideTryBlock=TRUE; lineCount(yyscanner); if (yytext[yyleng-1]==':') { unput(':'); BEGIN( Function ); } } {BN}*"throw"{BN}*"(" { // C++ style throw clause yyextra->current->exception = " throw (" ; yyextra->roundCount=0; lineCount(yyscanner) ; BEGIN( ExcpRound ) ; } {BN}*"raises"{BN}*"(" { yyextra->current->exception = " raises (" ; lineCount(yyscanner) ; yyextra->roundCount=0; BEGIN( ExcpRound ) ; } {BN}*"throws"{BN}+ { // Java style throw clause yyextra->current->exception = " throws " ; lineCount(yyscanner) ; BEGIN( ExcpList ); } "(" { yyextra->current->exception += *yytext ; ++yyextra->roundCount ; } ")" { yyextra->current->exception += *yytext ; if ( yyextra->roundCount ) --yyextra->roundCount ; else BEGIN( FuncQual ) ; } . { yyextra->current->exception += *yytext; } "{" { unput('{'); BEGIN( FuncQual ); } ";" { unput(';'); BEGIN( FuncQual ); } "\n" { yyextra->current->exception += ' '; lineCount(yyscanner); } . { yyextra->current->exception += *yytext; } "(" { yyextra->current->type += yyextra->current->name ; yyextra->current->name = yyextra->current->args ; yyextra->current->args = yytext ; yyextra->roundCount=0; BEGIN( FuncRound ) ; } ":" { if (!yyextra->insidePHP) BEGIN(SkipInits); } [;{,] { yyextra->current->name=yyextra->current->name.simplifyWhiteSpace(); yyextra->current->type=yyextra->current->type.simplifyWhiteSpace(); yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args); // was: yyextra->current->args.simplifyWhiteSpace(); yyextra->current->fileName = yyextra->yyFileName; yyextra->current->startLine = yyextra->yyBegLineNr; yyextra->current->startColumn = yyextra->yyBegColNr; static const reg::Ex re(R"(\([^)]*[*&][^)]*\))"); reg::Match match; std::string type = yyextra->current->type.str(); int ti=-1; if (reg::search(type,match,re)) { ti = (int)match.position(); } int ts=yyextra->current->type.find('<'); int te=yyextra->current->type.findRev('>'); // bug677315: A get(); is not a function pointer bool isFunction = ti==-1 || // not a (...*...) pattern (ts!=-1 && tscurrent->type.isEmpty() && (!isFunction || yyextra->current->type.left(8)=="typedef ")); //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n", // yyextra->current->type.data(),ts,te,ti,isFunction); if (*yytext!=';' || (yyextra->current_root->section&Entry::COMPOUND_MASK) ) { int tempArg=yyextra->current->name.find('<'); QCString tempName; if (tempArg==-1) tempName=yyextra->current->name; else tempName=yyextra->current->name.left(tempArg); if (isVariable) { //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ") { yyextra->current->type.prepend("typedef "); } yyextra->current->section = Entry::VARIABLE_SEC ; } else { //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); yyextra->current->section = Entry::FUNCTION_SEC ; yyextra->current->proto = *yytext==';'; } } else // a global function prototype or function variable { //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); if (isVariable) { if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ") { yyextra->current->type.prepend("typedef "); } //printf("Scanner.l: found function variable!\n"); yyextra->current->section = Entry::VARIABLE_SEC; } else { //printf("Scanner.l: found prototype\n"); yyextra->current->section = Entry::FUNCTION_SEC; yyextra->current->proto = TRUE; } } //printf("Adding entry '%s'\n",yyextra->current->name.data()); if ( yyextra->insidePHP) { if (findAndRemoveWord(yyextra->current->type,"final")) { yyextra->current->spec |= Entry::Final; } if (findAndRemoveWord(yyextra->current->type,"abstract")) { yyextra->current->spec |= Entry::Abstract; } } if ( yyextra->insidePHP && !containsWord(yyextra->current->type,"function")) { initEntry(yyscanner); if ( *yytext == '{' ) { yyextra->lastCurlyContext = FindMembers; yyextra->curlyCount=0; BEGIN( SkipCurly ); } else { BEGIN( FindMembers ); } } else { if ( yyextra->insidePHP) { findAndRemoveWord(yyextra->current->type,"function"); } yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); // Objective C 2.0: Required/Optional section if (yyextra->previous->spec & (Entry::Optional | Entry::Required)) { yyextra->current->spec |= yyextra->previous->spec & (Entry::Optional|Entry::Required); } yyextra->lastCurlyContext = FindMembers; if ( *yytext == ',' ) { yyextra->current->type = yyextra->previous->type; // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases) int i=yyextra->current->type.length(); while (i>0 && (yyextra->current->type[i-1]=='*' || yyextra->current->type[i-1]=='&' || yyextra->current->type[i-1]==' ')) i--; yyextra->current->type = yyextra->current->type.left(i); } if ( *yytext == '{' ) { if ( !yyextra->insidePHP && (yyextra->current_root->section & Entry::COMPOUND_MASK) ) { yyextra->previous->spec |= Entry::Inline; } //addToBody(yytext); yyextra->curlyCount=0; BEGIN( SkipCurly ) ; } else { if (yyextra->previous->section!=Entry::VARIABLE_SEC) yyextra->previous->bodyLine=-1; // a function/member declaration BEGIN( FindMembers ) ; } } } ">"{BN}*"{" { // C++11 style initializer (see bug 790788) lineCount(yyscanner); yyextra->curlyCount=1; BEGIN(SkipC11Inits); } {ID}{BN}*"{" { // C++11 style initializer (see bug 688647) lineCount(yyscanner); yyextra->curlyCount=1; BEGIN(SkipC11Inits); } "{" { ++yyextra->curlyCount; } "}" { if ( --yyextra->curlyCount<=0 ) { BEGIN(SkipInits); } } "]]" { BEGIN(yyextra->lastC11AttributeContext); } "{" { // C++11 style initializer unput('{'); BEGIN( Function ); } "{" { //addToBody(yytext); ++yyextra->curlyCount ; } "}"/{BN}*{DCOMM}" Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC); yyextra->current = std::make_shared(); yyextra->stat = FALSE; initEntry(yyscanner); // deep copy group list from parent (see bug 727732) bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS); if (autoGroupNested && !rt->groups.empty() && ce->section!=Entry::ENUM_SEC && !(ce->spec&Entry::Enum)) { ce->groups = rt->groups; } 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 (yyextra->insidePHP || yyextra->insideD || yyextra->insideJS || yyextra->insideIDL || yyextra->insideSlice) { yyextra->current->protection = yyextra->protection = Public ; } else if (yyextra->insideJava) { yyextra->current->protection = yyextra->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) { yyextra->current->protection = yyextra->protection = Protected ; } else { yyextra->current->protection = yyextra->protection = Public ; } } else { yyextra->current->protection = yyextra->protection = Private ; } } else if (ce->section == Entry::ENUM_SEC ) // enum { yyextra->current->protection = yyextra->protection = ce->protection; } else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace { if (ce->section == Entry::NAMESPACE_SEC ) // unnamed namespace { yyextra->current->stat = yyextra->stat = TRUE; } yyextra->current->protection = yyextra->protection = ce->protection; } else // named struct, union, protocol, category { yyextra->current->protection = yyextra->protection = Public ; } yyextra->mtype = Method; yyextra->virt = Normal; //printf("name=%s yyextra->current->stat=%d yyextra->stat=%d\n",ce->name.data(),yyextra->current->stat,yyextra->stat); //memberGroupId = DOX_NOGROUP; //memberGroupRelates.resize(0); //memberGroupInside.resize(0); QCString name = ce->name; yyextra->commentScanner.enterCompound(yyextra->yyFileName,yyextra->yyLineNr,name); scannerYYlex(yyscanner); yyextra->lexInit=TRUE; //forceEndGroup(); yyextra->commentScanner.leaveCompound(yyextra->yyFileName,yyextra->yyLineNr,name); yyextra->programStr.resize(0); ce->program.str(std::string()); //if (depthIf>0) //{ // warn(yyextra->yyFileName,yyextra->yyLineNr,"Documentation block ended in the middle of a conditional section!"); //} } parseCompounds(yyscanner,ce); } } //---------------------------------------------------------------------------- static void parseMain(yyscan_t yyscanner, const char *fileName, const char *fileBuf, const std::shared_ptr &rt, ClangTUParser *clangParser) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; initParser(yyscanner); yyextra->inputString = fileBuf; yyextra->inputPosition = 0; yyextra->column = 0; scannerYYrestart(0,yyscanner); //depthIf = 0; yyextra->protection = Public; yyextra->mtype = Method; yyextra->stat = FALSE; yyextra->virt = Normal; yyextra->current_root = rt; yyextra->yyLineNr = 1 ; yyextra->yyBegLineNr = 1; yyextra->yyBegColNr = 0; yyextra->yyFileName = fileName; yyextra->clangParser = clangParser; setContext(yyscanner); rt->lang = yyextra->language; msg("Parsing file %s...\n",yyextra->yyFileName.data()); yyextra->current_root = rt; initParser(yyscanner); yyextra->commentScanner.enterFile(yyextra->yyFileName,yyextra->yyLineNr); yyextra->current = std::make_shared(); //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root); int sec=guessSection(yyextra->yyFileName); if (sec) { yyextra->current->name = yyextra->yyFileName; yyextra->current->section = sec; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); } yyextra->current->reset(); initEntry(yyscanner); if ( yyextra->insidePHP ) { BEGIN( FindMembersPHP ); } else { BEGIN( FindMembers ); } scannerYYlex(yyscanner); yyextra->lexInit=TRUE; if (YY_START==Comment) { warn(yyextra->yyFileName,yyextra->yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?"); } //forceEndGroup(); yyextra->commentScanner.leaveFile(yyextra->yyFileName,yyextra->yyLineNr); yyextra->programStr.resize(0); rt->program.str(std::string()); parseCompounds(yyscanner,rt); anonNSCount++; // add additional entries that were created during processing for (auto &kv: yyextra->outerScopeEntries) { //printf(">>> adding '%s' to scope '%s'\n",kv.second->name.data(),kv.first->name.data()); kv.first->moveToSubEntryAndKeep(kv.second); } yyextra->outerScopeEntries.clear(); } //---------------------------------------------------------------------------- static void parsePrototype(yyscan_t yyscanner,const QCString &text) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("**** parsePrototype(%s) begin\n",text.data()); if (text.isEmpty()) { warn(yyextra->yyFileName,yyextra->yyLineNr,"Empty prototype found!"); return; } if (!yyextra->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(0, YY_BUF_SIZE, yyscanner), yyscanner); orgInputString = yyextra->inputString; orgInputPosition = yyextra->inputPosition; // set new string yyextra->inputString = text; yyextra->inputPosition = 0; yyextra->column = 0; scannerYYrestart(0, yyscanner); BEGIN(Prototype); scannerYYlex(yyscanner); yyextra->lexInit=TRUE; yyextra->current->name = yyextra->current->name.stripWhiteSpace(); if (yyextra->current->section == Entry::MEMBERDOC_SEC && yyextra->current->args.isEmpty()) yyextra->current->section = Entry::VARIABLEDOC_SEC; // restore original scanner state YY_BUFFER_STATE tmpState = YY_CURRENT_BUFFER; yy_switch_to_buffer(orgState, yyscanner); yy_delete_buffer(tmpState, yyscanner); yyextra->inputString = orgInputString; yyextra->inputPosition = orgInputPosition; //printf("**** parsePrototype end\n"); } //static void handleGroupStartCommand(const char *header) //{ // memberGroupHeader=header; // startGroupInDoc(); //} // //static void handleGroupEndCommand() //{ // endGroup(); // g_previous=0; //} //---------------------------------------------------------------------------- struct COutlineParser::Private { yyscan_t yyscanner; scannerYY_state state; }; COutlineParser::COutlineParser() : p(std::make_unique()) { scannerYYlex_init_extra(&p->state,&p->yyscanner); #ifdef FLEX_DEBUG scannerYYset_debug(1,p->yyscanner); #endif } COutlineParser::~COutlineParser() { scannerYYlex_destroy(p->yyscanner); } void COutlineParser::parseInput(const char *fileName, const char *fileBuf, const std::shared_ptr &root, ClangTUParser *clangParser) { struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; yyextra->thisParser = this; printlex(yy_flex_debug, TRUE, __FILE__, fileName); ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser); printlex(yy_flex_debug, FALSE, __FILE__, fileName); } bool COutlineParser::needsPreprocessing(const QCString &extension) const { QCString fe=extension.lower(); SrcLangExt lang = getLanguageFromFileName(extension); return (SrcLangExt_Cpp == lang) || (SrcLangExt_Lex == lang) || !( fe==".java" || fe==".as" || fe==".d" || fe==".php" || fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5" ); } void COutlineParser::parsePrototype(const char *text) { ::parsePrototype(p->yyscanner,text); } //---------------------------------------------------------------------------- #if USE_STATE2STRING #include "scanner.l.h" #endif