diff -r 932c358ece3e -r d8fccb2cd802 Orb/Doxygen/src/scanner.l --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orb/Doxygen/src/scanner.l Fri Apr 23 20:47:58 2010 +0100 @@ -0,0 +1,5780 @@ +/***************************************************************************** + * + * + * + * Copyright (C) 1997-2008 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +%{ + +/* + * includes + */ +#include +#include +#include +#include + +#include "qtbc.h" +#include +#include +#include +#include +#include + +#include "scanner.h" +#include "entry.h" +#include "message.h" +#include "config.h" +#include "doxygen.h" +#include "util.h" +#include "defargs.h" +#include "language.h" +#include "commentscan.h" +#include "code.h" + +#define YY_NEVER_INTERACTIVE 1 + +/* ----------------------------------------------------------------- + * + * statics + */ +static ParserInterface *g_thisParser; +static const char * inputString; +static int inputPosition; +static QFile inputFile; +static int lastContext; +static int lastCContext; +static int lastDocContext; +static int lastCPPContext; +static int lastSkipSharpContext; +static int lastSkipRoundContext; +static int lastStringContext; +static int lastCurlyContext; +static int lastRoundContext; +static int lastSquareContext; +static int lastInitializerContext; +static int lastClassTemplSpecContext; +static int lastPreLineCtrlContext; +static int lastSkipVerbStringContext; +static int lastCommentInArgContext; +static int lastCSConstraint; +static Protection protection; +static Protection baseProt; +static int sharpCount = 0 ; +static int roundCount = 0 ; +static int curlyCount = 0 ; +static int squareCount = 0 ; +static int padCount = 0 ; +static QCString slString; +static Entry* current_root = 0 ; +static Entry* global_root = 0 ; +static Entry* current = 0 ; +static Entry* previous = 0 ; +static Entry* tempEntry = 0 ; +static Entry* firstTypedefEntry = 0 ; +static Entry* memspecEntry = 0 ; +static int yyLineNr = 1 ; +static int anonCount = 0 ; +static int anonNSCount = 0 ; +static QCString yyFileName; +static MethodTypes mtype; +static bool gstat; +static bool removeSlashes; +static Specifier virt; +static Specifier baseVirt; +static QCString msType,msName,msArgs; +static bool isTypedef; +static int tmpDocType; +static QCString sectionLabel; +static QCString sectionTitle; +static QCString funcPtrType; +static QCString templateStr; +static QCString aliasName; +static QCString baseName; +static QCString* specName; +static QCString formulaText; +static QCString formulaEnd; +static bool useOverrideCommands = FALSE; + +static bool insideIDL = FALSE; //!< processing IDL code? +static bool insideJava = FALSE; //!< processing Java code? +static bool insideCS = FALSE; //!< processing C# code? +static bool insideD = FALSE; //!< processing D code? +static bool insidePHP = FALSE; //!< processing PHP code? +static bool insideObjC = FALSE; //!< processing Objective C code? +static bool insideCli = FALSE; //!< processing C++/CLI code? +static bool insideJS = FALSE; //!< processing JavaScript code? + +static bool insideCppQuote = FALSE; +static bool insideProtocolList = FALSE; + +static int argRoundCount; +static int argSharpCount; +static int currentArgumentContext; +static int lastCopyArgStringContext; +static int lastCopyArgContext; +static QCString *copyArgString; +static QCString fullArgString; + +static ArgumentList *currentArgumentList; +static char lastCopyArgChar; + +static QCString *pCopyQuotedString; +static QCString *pCopyRoundString; +static QCString *pCopyCurlyString; + +static QGString *pCopyCurlyGString; +static QGString *pCopyRoundGString; +static QGString *pCopyQuotedGString; +static QGString *pSkipVerbString; +static QStack autoGroupStack; + +static bool insideFormula; +static bool insideTryBlock=FALSE; +static bool insideCode; +static bool needsSemi; + +static int depthIf; +static int initBracketCount; +static QCString memberGroupRelates; +static QCString memberGroupInside; +static QCString xrefItemKey; +static QCString xrefItemTitle; +static QCString xrefListTitle; + +static QCString g_skipBlockName; +static QCString oldStyleArgType; +static QCString docBackup; +static QCString briefBackup; +static bool g_inputFromFile; + +static int docBlockContext; +static QCString docBlock; +static QCString docBlockName; +static bool docBlockInBody; +static bool docBlockAutoBrief; +static char docBlockTerm; + +static QCString idlAttr; +static QCString idlProp; + +static bool g_lexInit = FALSE; +static bool externC; + + +//----------------------------------------------------------------------------- + +// forward declarations +//static void handleGroupStartCommand(const char *header); +//static void handleGroupEndCommand(); + +//----------------------------------------------------------------------------- + +static void initParser() +{ + sectionLabel.resize(0); + sectionTitle.resize(0); + baseName.resize(0); + formulaText.resize(0); + protection = Public; + baseProt = Public; + sharpCount = 0; + roundCount = 0; + curlyCount = 0; + mtype = Method; + gstat = FALSE; + virt = Normal; + baseVirt = Normal; + isTypedef = FALSE; + autoGroupStack.clear(); + insideTryBlock = FALSE; + autoGroupStack.setAutoDelete(TRUE); + insideFormula = FALSE; + insideCode=FALSE; + insideCli=Config_getBool("CPP_CLI_SUPPORT"); + previous = 0; +} + +static void initEntry() +{ + if (insideJava) + { + protection = (current_root->spec & Entry::Interface) ? Public : Package; + } + current->protection = protection ; + current->mtype = mtype; + current->virt = virt; + current->stat = gstat; + current->objc = insideObjC; + //if (!autoGroupStack.isEmpty()) + //{ + // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); + // current->groups->append(new Grouping(*autoGroupStack.top())); + //} + initGroupInfo(current); + isTypedef=FALSE; +} + + +//----------------------------------------------------------------------------- + +///// remove any automatic grouping and add new one (if given) +//static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri ) +//{ +// /* remove auto group name from current entry and discard it */ +// Grouping *g = current->groups->first(); +// int i=0; +// while (g) +// { +// if (g->pri <= Grouping::GROUPING_AUTO_DEF) +// { +// current->groups->remove(i); +// i--; +// } +// g=current->groups->next(); +// i++; +// } +// +// /* use new group name instead? */ +// if ( newgroup ) +// { +// current->groups->append(new Grouping(*newgroup, pri)); +// } +//} +// +//static int newMemberGroupId() +//{ +// static int curGroupId=0; +// return curGroupId++; +//} +// +// forward declarations +//static void startGroupInDoc(); +//static void endGroup(); + +//----------------------------------------------------------------------------- + +static void lineCount() +{ + for( const char* c = yytext ; *c ; ++c ) + yyLineNr += (*c == '\n') ; +} + +static void addType( Entry* current ) +{ + uint tl=current->type.length(); + if( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.') + { + current->type += ' ' ; + } + current->type += current->name ; + current->name.resize(0) ; + tl=current->type.length(); + if( tl>0 && !current->args.isEmpty() && current->type.at(tl-1)!='.') + { + current->type += ' ' ; + } + current->type += current->args ; + current->args.resize(0) ; + current->argList->clear(); +} + + +static QCString stripQuotes(const char *s) +{ + QCString name; + if (s==0 || *s==0) return name; + name=s; + if (name.at(0)=='"' && name.at(name.length()-1)=='"') + { + name=name.mid(1,name.length()-2); + } + return name; +} + +//----------------------------------------------------------------- + +static void startCommentBlock(bool); +static void handleCommentBlock(const QCString &doc,bool brief); +static void handleParametersCommentBlocks(ArgumentList *al); + +//----------------------------------------------------------------- + +static bool nameIsOperator(QCString &name) +{ + int i=name.find("operator"); + if (i==-1) return FALSE; + if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X + if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator + return FALSE; // case TEXToperatorTEXT +} + +//----------------------------------------------------------------------------- + +static void setContext() +{ + QCString fileName = yyFileName; + SrcLangExt langExt = getLanguageFromFileName(fileName); + insideIDL = langExt==SrcLangExt_IDL; + insideJava = langExt==SrcLangExt_Java; + insideCS = langExt==SrcLangExt_CSharp; + insideD = langExt==SrcLangExt_D; + insidePHP = langExt==SrcLangExt_PHP; + insideObjC = langExt==SrcLangExt_ObjC; + insideJS = langExt==SrcLangExt_JS; + if ( insidePHP ) + { + useOverrideCommands = TRUE; + } + //printf("setContext(%s) insideIDL=%d insideJava=%d insideCS=%d " + // "insideD=%d insidePHP=%d insideObjC=%d\n", + // yyFileName.data(),insideIDL,insideJava,insideCS,insideD,insidePHP,insideObjC + // ); +} + +//----------------------------------------------------------------------------- + +static void prependScope() +{ + if (current_root->section & Entry::SCOPE_MASK) + { + //printf("--- prependScope %s to %s\n",current_root->name.data(),current->name.data()); + current->name.prepend(current_root->name+"::"); + if (current_root->tArgLists) + { + if (current->tArgLists==0) + { + current->tArgLists = new QList; + current->tArgLists->setAutoDelete(TRUE); + } + //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count()); + QListIterator talsi(*current_root->tArgLists); + ArgumentList *srcAl=0; + for (talsi.toLast();(srcAl=talsi.current());--talsi) + { + ArgumentList *dstAl = new ArgumentList; + QListIterator tali(*srcAl); + Argument *a; + for (;(a=tali.current());++tali) + { + dstAl->append(new Argument(*a)); + //printf("appending argument %s %s\n",a->type.data(),a->name.data()); + } + current->tArgLists->insert(0,dstAl); + } + } + } +} + +//----------------------------------------------------------------------------- + +/*! Returns TRUE iff the current entry could be a K&R style C function */ +static bool checkForKnRstyleC() +{ + if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file + if (!current->argList) return FALSE; // must have arguments + ArgumentListIterator ali(*current->argList); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + // in K&R style argument do not have a type, but doxygen expects a type + // so it will think the argument has no name + if (a->type.isEmpty() || !a->name.isEmpty()) return FALSE; + } + return TRUE; +} + +//----------------------------------------------------------------------------- + +static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName) +{ + int si = current->args.length(); + if (oldStyleArgType.isEmpty()) // new argument + { + static QRegExp re("([^)]*)"); + int bi1 = current->args.findRev(re); + int bi2 = bi1!=-1 ? current->args.findRev(re,bi1-1) : -1; + char c; + if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)" + { + int s=bi2+1; + oldStyleArgType = current->args.left(s); + int i=s; + while (iargs.at(i))=='*' || isspace((uchar)c))) i++; + oldStyleArgType += current->args.mid(s,i-s); + s=i; + while (iargs.at(i))) i++; + oldStyleArgName = current->args.mid(s,i-s); + oldStyleArgType+=current->args.mid(i); + } + else if (bi1!=-1) // redundant braces like in "int (*var)" + { + int s=bi1; + oldStyleArgType = current->args.left(s); + s++; + int i=s+1; + while (iargs.at(i))=='*' || isspace((uchar)c))) i++; + oldStyleArgType += current->args.mid(s,i-s); + s=i; + while (iargs.at(i))) i++; + oldStyleArgName = current->args.mid(s,i-s); + } + else // normal "int *var" + { + int l=si,i=l-1,j; + char c; + // look for start of name in "type *name" + while (i>=0 && isId(current->args.at(i))) i--; + j=i+1; + // look for start of *'s + while (i>=0 && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i--; + i++; + if (i!=l) + { + oldStyleArgType=current->args.left(i); + oldStyleArgPtr=current->args.mid(i,j-i); + oldStyleArgName=current->args.mid(j).stripWhiteSpace(); + } + else + { + oldStyleArgName=current->args.copy().stripWhiteSpace(); + } + } + } + else // continuation like *arg2 in "int *args,*arg2" + { + int l=si,j=0; + char c; + while (jargs.at(j))=='*' || isspace((uchar)c))) j++; + if (j>0) + { + oldStyleArgPtr=current->args.left(j); + oldStyleArgName=current->args.mid(j).stripWhiteSpace(); + } + else + { + oldStyleArgName=current->args.copy().stripWhiteSpace(); + } + } + //fprintf(stderr,"type=%s ptr=%s name=%s\n",oldStyleArgType.data(),oldStyleArgPtr.data(),oldStyleArgName.data()); +} + +//----------------------------------------------------------------------------- + +/*! Update the argument \a name with additional \a type info. For K&R style + * function the type is found \e after the argument list, so this routine + * in needed to fix up. + */ +static void addKnRArgInfo(const QCString &type,const QCString &name, + const QCString &brief,const QCString &docs) +{ + if (current->argList==0) return; + ArgumentListIterator ali(*current->argList); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + if (a->type==name) + { + a->type=type.stripWhiteSpace(); + if (a->type.left(9)=="register ") // strip keyword + { + a->type=a->type.mid(9); + } + a->name=name.stripWhiteSpace(); + if (!brief.isEmpty() && !docs.isEmpty()) + { + a->docs=brief+"\n\n"+docs; + } + else if (!brief.isEmpty()) + { + a->docs=brief; + } + else + { + a->docs=docs; + } + } + } +} + +//----------------------------------------------------------------------------- + + +void fixArgumentListForJavaScript(ArgumentList *al) +{ + if (al==0) return; + ArgumentListIterator ali(*al); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + if (!a->type.isEmpty() && a->name.isEmpty()) + { // a->type is actually the (typeless) parameter name, so move it + a->name=a->type; + a->type.resize(0); + } + } +} + +/* ----------------------------------------------------------------- */ +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); + +static int yyread(char *buf,int max_size) +{ + int c=0; + if (g_inputFromFile) + { + c = inputFile.readBlock(buf,max_size); + if (c==-1) yy_fatal_error("input in flex scanner failed"); + } + else + { + while( c < max_size && inputString[inputPosition] ) + { + *buf = inputString[inputPosition++] ; + //printf("%d (%c)\n",*buf,*buf); + c++; buf++; + } + } + return c; +} + +%} + + /* start command character */ +CMD ("\\"|"@") +SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"callgraph"|"callergraph"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"{"|"verbatim"|"dotfile"|"dot"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"details"|"typedef"|"def"|"overload")|("<"{PRE}">") +BN [ \t\n\r] +BL [ \t\r]*"\n" +B [ \t] +BS ^(({B}*"//")?)(({B}*"*"+)?){B}* +FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+] +FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+] +FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"") +ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* +SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) +SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID}) +TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")? +FTSCOPE {ID}("<"[a-z_A-Z0-9\*\&,]*">")? +CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID}) +PRE [pP][rR][eE] +CODE [cC][oO][dD][eE] +CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) +PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] +IDLATTR ("["[^\]]*"]"){BN}* +TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) + +%option noyywrap + + /* language parsing states */ + +%x Define +%x DefineEnd +%x CompoundName +%x ClassVar +%x CSConstraintName +%x CSConstraintType +%x ClassCategory +%x ClassTemplSpec +%x CliPropertyType +%x CliPropertyIndex +%x CliOverride +%x Bases +%x BasesProt +%x NextSemi +%x BitFields +%x FindMembers +%x FindMembersPHP +%x FindMemberName +%x FindFields +%x FindFieldArg +%x Function +%x FuncRound +%x ExcpRound +%x ExcpList +%x FuncQual +%x Operator +%x Array +%x ReadBody +%x ReadNSBody +%x ReadBodyIntf +%x Using +%x UsingDirective +%x SkipCurly +%x SkipCurlyCpp +%x SkipCurlyEndDoc +%x SkipString +%x SkipPHPString +%x SkipInits +%x SkipCPP +%x SkipCPPBlock +%x SkipComment +%x SkipCxxComment +%x SkipCurlyBlock +%x SkipRoundBlock +%x Sharp +%x SkipSharp +%x SkipRound +%x SkipSquare +%x SkipRemainder +%x TypedefName +%x TryFunctionBlock +%x TryFunctionBlockEnd +%x Comment +%x PackageName +%x JavaImport +%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 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 GCopyCurly +%x SkipUnionSwitch +%x Specialization +%x FuncPtrInit +%x FuncFunc +%x FuncFuncEnd +%x FuncFuncType +%x FuncFuncArray +%x CopyArgString +%x CopyArgPHPString +%x CopyArgRound +%x CopyArgSharp +%x CopyArgComment +%x CopyArgCommentLine +%x CopyArgVerbatim + +%x IDLAttribute +%x IDLProp +%x IDLPropName + + /** Prototype scanner states */ + +%x Prototype +%x PrototypePtr +%x PrototypeQual +%x PrototypeExc +%x PrototypeSkipLine + + /** comment parsing states */ + +%x DocLine +%x DocBlock +%x DocCopyBlock + +%% + +"{" { + curlyCount=0; + needsSemi = TRUE; + BEGIN(SkipCurlyBlock); + } +"(" { + roundCount=0; + BEGIN(SkipRoundBlock); + } +"(" { + ++roundCount; + } +")" { + if (roundCount ) + --roundCount ; + else + BEGIN( NextSemi ) ; + } +"{" { + ++curlyCount ; + } +"}" { + if( curlyCount ) + { + --curlyCount ; + } + else if (needsSemi) + { + BEGIN( NextSemi ); + } + else + { + BEGIN( FindMembers ); + } + } +\' { + if (insidePHP) + { + lastStringContext=NextSemi; + BEGIN(SkipPHPString); + } + } +{CHARLIT} { if (insidePHP) REJECT; } +\" { + lastStringContext=NextSemi; + BEGIN(SkipString); + } +[;,] { + unput(*yytext); + BEGIN( FindMembers ); + } +[;,] { + unput(*yytext); + BEGIN( FindMembers ); + } +"""" { // PHP code start + lineCount() ; + BEGIN( FindMembers ); + } +[^\n<]+ { // Non-PHP code text, ignore + } +\n { // Non-PHP code text, ignore + yyLineNr++; + } +. { // Non-PHP code text, ignore + } +"?>"|"" { // PHP code end + if (insidePHP) + BEGIN( FindMembersPHP ); + else + REJECT; + } +{PHPKW} { if (insidePHP) + BEGIN( NextSemi ); + else + REJECT; + } +"%{"[^\n]* { // Mozilla XPIDL lang-specific block + if (!insideIDL) + REJECT; + } +"%}" { // Mozilla XPIDL lang-specific block end + if (!insideIDL) + REJECT; + } +{B}*("properties"){BN}*":"{BN}* { // IDL or Borland C++ builder property + current->mtype = mtype = Property; + current->protection = protection = Public ; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } + +{B}*"k_dcop"{BN}*":"{BN}* { current->mtype = mtype = DCOP; + current->protection = protection = Public ; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } + +{B}*("signals"|"Q_SIGNALS"){BN}*":"{BN}* { current->mtype = mtype = Signal; + + current->protection = protection = Public ; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } + +{B}*"public"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { + current->protection = protection = Public ; + current->mtype = mtype = Slot; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount(); + } + +{B}*"protected"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { + current->protection = protection = Protected ; + current->mtype = mtype = Slot; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount(); + } + +{B}*"private"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { + current->protection = protection = Private ; + current->mtype = mtype = Slot; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount(); + } +{B}*("public"|"methods"|"__published"){BN}*":"{BN}* { + current->protection = protection = Public ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +{B}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package... + if (insideCli) + { + current->protection = protection = Package ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } + else + { + REJECT; + } + } +{B}*"protected"{BN}*":"{BN}* { + current->protection = protection = Protected ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +{B}*"private"{BN}*":"{BN}* { + current->protection = protection = Private ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +{B}*"event"{BN}+ { + if (insideCli) + { + // C++/CLI event + lineCount() ; + current->mtype = mtype = Event; + current->bodyLine = yyLineNr; + curlyCount=0; + BEGIN( CliPropertyType ); + } + else if (insideCS) + { + lineCount() ; + current->mtype = Event; + current->bodyLine = yyLineNr; + } + else + { + REJECT; + } + } +{B}*"property"{BN}+ { + if (insideCli) + { + // C++/CLI property + lineCount() ; + current->mtype = mtype = Property; + current->bodyLine = yyLineNr; + curlyCount=0; + BEGIN( CliPropertyType ); + } + else + { + REJECT; + } + } +{ID} { + addType( current ); + current->name = yytext; + } +"[" { // C++/CLI indexed property + current->name += yytext; + BEGIN( CliPropertyIndex ); + } +"{" { + curlyCount=0; + //printf("event: '%s' '%s'\n",current->type.data(),current->name.data()); + BEGIN( CSAccessorDecl ); + } +";" { + unput(*yytext); + BEGIN( FindMembers ); + } +\n { + yyLineNr++; + } +{B}* { + } +. { + addType( current ); + current->type += yytext; + } +"]" { + BEGIN( CliPropertyType ); + current->name+=yytext; + } +. { + current->name+=yytext; + } +{B}*"property"{BN}+ { + if (!current->type.isEmpty()) + { + REJECT; + } + else + { + current->mtype = mtype = Property; + lineCount(); + } + } +{B}*"@private"{BN}+ { + current->protection = protection = Private ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +{B}*"@protected"{BN}+ { + current->protection = protection = Protected ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +{B}*"@public"{BN}+ { + current->protection = protection = Public ; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +[\-+]{BN}* { + if (!insideObjC) + { + REJECT; + } + else + { + lineCount(); + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + current->section = Entry::FUNCTION_SEC; + current->protection = protection = Public ; + current->objc = TRUE; + current->virt = Virtual; + current->stat=yytext[0]=='+'; + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + BEGIN( ObjCMethod ); + } + } +"(" { // start of method's return type + BEGIN( ObjCReturnType ); + } +{ID} { // found method name + if (current->type.isEmpty()) + { + current->type = "id"; + } + current->name = yytext; + } +":"{B}* { // start of parameter list + current->name += ':'; + Argument *a = new Argument; + current->argList->append(a); + BEGIN( ObjCParams ); + } +[^)]* { // TODO: check if nested braches are possible. + current->type = yytext; + } +")" { + BEGIN( ObjCMethod ); + } +({ID})?":" { // Keyword of parameter + QCString keyw = yytext; + keyw=keyw.left(keyw.length()-1); // strip : + if (keyw.isEmpty()) + { + current->name += " :"; + } + else + { + current->name += keyw+":"; + } + if (current->argList->getLast()->type.isEmpty()) + { + current->argList->getLast()->type="id"; + } + Argument *a = new Argument; + a->attrib=(QCString)"["+keyw+"]"; + current->argList->append(a); + } +{ID}{BN}* { // name of parameter + lineCount(); + current->argList->getLast()->name=QCString(yytext).stripWhiteSpace(); + } +","{BN}*"..." { // name of parameter + lineCount(); + // do we want the comma as part of the name? + //current->name += ","; + Argument *a = new Argument; + a->attrib="[,]"; + a->type="..."; + current->argList->append(a); + } + /* +":" { + current->name += ':'; + } + */ +"(" { + BEGIN( ObjCParamType ); + } +[^)]* { + current->argList->getLast()->type=QCString(yytext).stripWhiteSpace(); + } +")"/{B}* { + BEGIN( ObjCParams ); + } +";" { // end of method declaration + if (current->argList->getLast() && current->argList->getLast()->type.isEmpty()) + { + current->argList->getLast()->type="id"; + } + current->args = argListToString(current->argList); + //printf("argList=%s\n",current->args.data()); + unput(';'); + BEGIN( Function ); + } +(";"{BN}+)?"{" { // start of a method body + lineCount(); + //printf("Type=%s Name=%s args=%s\n", + // current->type.data(),current->name.data(),argListToString(current->argList).data() + // ); + if (current->argList->getLast() && current->argList->getLast()->type.isEmpty()) + { + current->argList->getLast()->type="id"; + } + current->args = argListToString(current->argList); + unput('{'); + BEGIN( Function ); + } +{BN}{1,80} { + lineCount(); + } +"@"({ID}".")*{ID}{BN}*"(" { + if (insideJava) // Java annotation + { + lineCount(); + lastSkipRoundContext = YY_START; + roundCount=1; + BEGIN( SkipRound ); + } + else if (strncmp(yytext,"@property",9)==0) // ObjC 2.0 property + { + current->mtype = mtype = Property; + current->spec|=Entry::Readable | Entry::Writable | Entry::Assign; + current->protection = Public ; + unput('('); + BEGIN( ObjCPropAttr ); + } + else + { + REJECT; + } + } +"getter="{ID} { + current->read = yytext+7; + } +"setter="{ID} { + current->write = yytext+7; + } +"readonly" { + current->spec&=~Entry::Writable; + } +"readwrite" { // default + } +"assign" { // default + } +"retain" { + current->spec&=~Entry::Assign; + current->spec|=Entry::Retain; + } +"copy" { + current->spec&=~Entry::Assign; + current->spec|=Entry::Copy; + } +"nonatmic" { + current->spec|=Entry::NonAtomic; + } +")" { + BEGIN(FindMembers); + } +"@"{ID} { + if (insideJava) // Java annotation + { + // skip annotation + } + else if (strcmp(yytext,"@property")==0) // ObjC 2.0 property + { + current->mtype = mtype = Property; + current->spec|=Entry::Writable | Entry::Readable | Entry::Assign; + current->protection = Public ; + } + else if (strcmp(yytext,"@synthesize")==0) + { + BEGIN( ObjCSkipStatement ); + } + else if (strcmp(yytext,"@dynamic")==0) + { + BEGIN( ObjCSkipStatement ); + } + else + { + REJECT; + } + } +";" { + BEGIN(FindMembers); + } +{ID}("."{ID})* { + isTypedef=FALSE; + current->name = yytext; + current->name = substitute(current->name,".","::"); + current->section = Entry::NAMESPACE_SEC; + current->type = "namespace" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount(); + curlyCount=0; + current_root->addSubEntry(current); + current_root = current ; + current = new Entry ; + initEntry(); + BEGIN( FindMembers ) ; + } +";" { + BEGIN(FindMembers); + } +{B}*"initonly"{BN}+ { + current->type += " initonly "; + if (insideCli) current->spec |= Entry::Initonly; + lineCount(); + } +{B}*"static"{BN}+ { current->type += " static "; + current->stat = TRUE; + lineCount(); + } +{B}*"extern"{BN}+ { + current->stat = FALSE; + current->explicitExternal = TRUE; + lineCount(); + } +{B}*"virtual"{BN}+ { current->type += " virtual "; + current->virt = Virtual; + lineCount(); + } +{B}*"abstract"{BN}+ { + if (!insidePHP) + { + current->type += " abstract "; + current->virt = Pure; + } + else + { + current->spec|=Entry::Abstract; + } + lineCount(); + } +{B}*"inline"{BN}+ { current->spec|=Entry::Inline; + lineCount(); + } +{B}*"mutable"{BN}+ { current->spec|=Entry::Mutable; + lineCount(); + } +{B}*"explicit"{BN}+ { current->spec|=Entry::Explicit; + lineCount(); + } +{B}*"@required"{BN}+ { // Objective C 2.0 protocol required section + current->spec=(current->spec & ~Entry::Optional) | Entry::Required; + lineCount(); + } +{B}*"@optional"{BN}+ { // Objective C 2.0 protocol optional section + current->spec=(current->spec & ~Entry::Required) | Entry::Optional; + lineCount(); + } + /* +{B}*"import"{BN}+ { // IDL import keyword + BEGIN( NextSemi ); + } + */ +{B}*"typename"{BN}+ { lineCount(); } +{B}*"namespace"{BN}*/[^a-z_A-Z0-9] { + isTypedef=FALSE; + current->section = Entry::NAMESPACE_SEC; + current->type = "namespace" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount(); + BEGIN( CompoundName ); + } +{B}*"module"{BN}+ { + lineCount(); + if (insideIDL) + { + isTypedef=FALSE; + current->section = Entry::NAMESPACE_SEC; + current->type = "module" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } + else if (insideD) + { + lineCount(); + BEGIN(PackageName); + } + else + { + addType( current ) ; + current->name = QCString(yytext).stripWhiteSpace(); + } + } +{B}*"library"{BN}+ { + lineCount(); + if (insideIDL) + { + isTypedef=FALSE; + current->section = Entry::NAMESPACE_SEC; + current->type = "library" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } + else + { + addType( current ) ; + current->name = QCString(yytext).stripWhiteSpace(); + } + } +{B}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba IDL/Java interface + lineCount(); + if (insideIDL || insideJava || insideCS || insideD || insidePHP) + { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Interface; + addType( current ) ; + current->type += " interface" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } + else + { + addType( current ) ; + current->name = QCString(yytext).stripWhiteSpace(); + } + } +{B}*"@implementation"{BN}+ { // Objective-C class implementation + lineCount(); + isTypedef=FALSE; + current->section = Entry::OBJCIMPL_SEC; + current->objc = insideObjC = TRUE; + current->protection = protection = Public ; + addType( current ) ; + current->type += " implementation" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } +{B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute + lineCount(); + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Interface; + current->objc = insideObjC = !insideJava; + current->protection = protection = Public ; + addType( current ) ; + current->type += " interface" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } +{B}*"@protocol"{BN}+ { // Objective-C protocol definition + lineCount(); + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Protocol; + current->objc = insideObjC = TRUE; + current->protection = protection = Public ; + addType( current ) ; + current->type += " protocol" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } +{B}*"exception"{BN}+ { // Corba IDL exception + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Exception; + addType( current ) ; + current->type += " exception" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount(); + BEGIN( CompoundName ); + } +"@class" | // for Objective C class declarations +{B}*{TYPEDEFPREFIX}"class{" | +{B}*{TYPEDEFPREFIX}"class"{BN}+ { + isTypedef=((QCString)yytext).find("typedef")!=-1; + current->section = Entry::CLASS_SEC; + addType( current ) ; + current->type += " class" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + current->objc = insideObjC = yytext[0]=='@'; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + if (insidePHP && current->spec&Entry::Abstract) + { + // convert Abstract to AbstractClass + current->spec=(current->spec&~Entry::Abstract)|Entry::AbstractClass; + } + BEGIN( CompoundName ) ; + } +{B}*"value class{" | // C++/CLI extension +{B}*"value class"{BN}+ { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Value; + addType( current ) ; + current->type += " value class" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*"ref class{" | // C++/CLI extension +{B}*"ref class"{BN}+ { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Ref; + addType( current ) ; + current->type += " ref class" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*"interface class{" | // C++/CLI extension +{B}*"interface class"{BN}+ { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Interface; + addType( current ) ; + current->type += " interface class" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*"coclass"{BN}+ { + if (insideIDL) + { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + addType( current ) ; + current->type += " coclass" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + BEGIN( CompoundName ) ; + } + else + { + addType(current); + current->name = yytext; + current->name = current->name.stripWhiteSpace(); + lineCount(); + } + } +{B}*{TYPEDEFPREFIX}"struct{" | +{B}*{TYPEDEFPREFIX}"struct"/{BN}+ { + isTypedef=((QCString)yytext).find("typedef")!=-1; + current->section = Entry::CLASS_SEC ; + current->spec = Entry::Struct; + // bug 582676: can be a struct nested in an interface so keep insideObjC state + //current->objc = insideObjC = FALSE; + addType( current ) ; + current->type += " struct" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*"value struct{" | // C++/CLI extension +{B}*"value struct"{BN}+ { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Struct | Entry::Value; + addType( current ) ; + current->type += " value struct" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*"ref struct{" | // C++/CLI extension +{B}*"ref struct"{BN}+ { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Struct | Entry::Ref; + addType( current ) ; + current->type += " ref struct" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*"interface struct{" | // C++/CLI extension +{B}*"interface struct"{BN}+ { + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Struct | Entry::Interface; + addType( current ) ; + current->type += " interface struct"; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*{TYPEDEFPREFIX}"union{" | +{B}*{TYPEDEFPREFIX}"union"{BN}+ { + isTypedef=((QCString)yytext).find("typedef")!=-1; + current->section = Entry::CLASS_SEC; + current->spec = Entry::Union; + // bug 582676: can be a struct nested in an interface so keep insideObjC state + //current->objc = insideObjC = FALSE; + addType( current ) ; + current->type += " union" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?"{" | +{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?{BN}+ { // for IDL: typedef [something] enum + isTypedef=((QCString)yytext).find("typedef")!=-1; + current->section = Entry::ENUM_SEC ; + addType( current ) ; + current->type += " enum" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + lineCount() ; + if (yytext[yyleng-1]=='{') unput('{'); + BEGIN( CompoundName ) ; + } +"("{BN}*")"({BN}*"<"[^>]*">"){BN}*/"(" { // A::operator()(int arg) + lineCount(); + current->name += "()"; + BEGIN( FindMembers ); + } +"("{BN}*")"{BN}*/"(" { + lineCount(); + current->name += yytext ; + current->name = current->name.simplifyWhiteSpace(); + BEGIN( FindMembers ) ; + } +";" { // can occur when importing members + unput(';'); + BEGIN( FindMembers ) ; + } +[^(] { + lineCount(); + current->name += *yytext ; + } +"<>" { /* skip guided templ specifiers */ } +"(" { + current->name = current->name.simplifyWhiteSpace(); + unput(*yytext); + BEGIN( FindMembers ) ; + } +("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension + lineCount(); + if (current->tArgLists==0) + { + current->tArgLists = new QList; + current->tArgLists->setAutoDelete(TRUE); + } + ArgumentList *al = new ArgumentList; + current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template; + current->tArgLists->append(al); + currentArgumentList = al; + templateStr="<"; + fullArgString = templateStr; + copyArgString = &templateStr; + currentArgumentContext = FindMembers; + BEGIN( ReadTempArgs ); + } +"namespace"{BN}+/{ID}{BN}*"=" { // namespace alias + lineCount(); + BEGIN( NSAliasName ); + } +{ID} { + aliasName = yytext; + BEGIN( NSAliasArg ); + } +({ID}"::")*{ID} { + //printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext); + //if (current_root->name.isEmpty()) + //{ + // TODO: namespace aliases are now treated as global entities + // while they should be aware of the scope they are in + Doxygen::namespaceAliasDict.insert(aliasName,new QCString(yytext)); + //} + //else + //{ + // Doxygen::namespaceAliasDict.insert(current_root->name+"::"+aliasName, + // new QCString(current_root->name+"::"+yytext)); + //} + } +";" { + BEGIN( FindMembers ); + } +({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive + lineCount(); + QCString scope=yytext; + current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-2),".","::")); + current->fileName = yyFileName; + current->section=Entry::USINGDIR_SEC; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + BEGIN(Using); + } +({ID}{BN}*"."{BN}*)+{ID} { // class import => add as a using declaration + lineCount(); + QCString scope=yytext; + current->name=removeRedundantWhiteSpace(substitute(scope,".","::")); + current->fileName = yyFileName; + if (insideD) + { + current->section=Entry::USINGDIR_SEC; + } + else + { + //printf("import name = %s -> %s\n",yytext,current->name.data()); + current->section=Entry::USINGDECL_SEC; + } + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + BEGIN(Using); + } +"using"{BN}+ { + current->startLine=yyLineNr; + lineCount(); + BEGIN(Using); + } +"namespace"{BN}+ { lineCount(); BEGIN(UsingDirective); } +{ID}{BN}*({BN}*("::"|"."){BN}*{ID})* { + lineCount(); + current->name=yytext; + current->fileName = yyFileName; + current->section=Entry::USINGDECL_SEC; + current_root->addSubEntry(current); + current = new Entry ; + if (insideCS) /* Hack: in C# a using declaration and + directive have the same syntax, so we + also add it as a using directive here + */ + { + current->name=yytext; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->section=Entry::USINGDIR_SEC; + current_root->addSubEntry(current); + current = new Entry ; + } + initEntry(); + BEGIN(Using); + } +{SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext); + current->fileName = yyFileName; + current->section=Entry::USINGDIR_SEC; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + BEGIN(Using); + } +";" { BEGIN(FindMembers); } +{SCOPENAME}{BN}*"<>" { // guided template decl + QCString n=yytext; + addType( current ); + current->name=n.left(n.length()-2); + } +{SCOPENAME}{BN}*/"<" { // Note: this could be a return type! + sharpCount=0; + lineCount(); + addType( current ); + current->name=yytext; + current->name=current->name.stripWhiteSpace(); + //current->scopeSpec.resize(0); + // currentTemplateSpec = ¤t->scopeSpec; + if (nameIsOperator(current->name)) + BEGIN( Operator ); + else + BEGIN( EndTemplate ); + } +{SCOPENAME}{BN}*/"<" { + sharpCount=0; + roundCount=0; + lineCount(); + current->name+=((QCString)yytext).stripWhiteSpace(); + //current->memberSpec.resize(0); + // currentTemplateSpec = ¤t->memberSpec; + if (nameIsOperator(current->name)) + BEGIN( Operator ); + else + BEGIN( EndTemplate ); + } +"<<" { + current->name+=yytext; + // *currentTemplateSpec+=yytext; + } +"<" { + current->name+='<'; + // *currentTemplateSpec+='<'; + sharpCount++; + } +">>" { + if (insideJava || insideCS || insideCli || roundCount==0) + { + unput('>'); + unput(' '); + unput('>'); + } + else + { + current->name+=yytext; + } + // *currentTemplateSpec+=yytext; + } +">" { + current->name+='>'; + // *currentTemplateSpec+='>'; + if (--sharpCount<=0) + { + //printf("Found %s\n",current->name.data()); + BEGIN(FindMembers); + } + } +">"{BN}*"(" { + lineCount(); + current->name+='>'; + // *currentTemplateSpec+='>'; + if (--sharpCount<=0) + { + current->args = "("; + currentArgumentContext = FuncQual; + fullArgString = current->args.copy(); + copyArgString = ¤t->args; + //printf("Found %s\n",current->name.data()); + BEGIN( ReadFuncArgType ) ; + } + } +">"{BN}*/"("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance + lineCount(); + current->name+='>'; + BEGIN(FindMembers); + } +">"{BN}*/"::" { + lineCount(); + current->name+='>'; + // *currentTemplateSpec+='>'; + if (--sharpCount<=0) + { + BEGIN(FindMemberName); + } + } +"(" { current->name+=*yytext; + roundCount++; + } +")" { current->name+=*yytext; + if (roundCount>0) roundCount--; + } +. { + current->name+=*yytext; + // *currentTemplateSpec+=*yytext; + } +"define"{BN}*"("{BN}*["'] { + if (insidePHP) + { + current->bodyLine = yyLineNr; + BEGIN( DefinePHP ); + } + else + REJECT; + } +"Q_OBJECT" { // Qt object macro + } +"Q_PROPERTY" { // Qt property declaration + current->protection = protection = Public ; + current->mtype = mtype = Property; + current->type.resize(0); + BEGIN(QtPropType); + } +"(" { // start of property arguments + } +")" { // end of property arguments + unput(';'); + BEGIN(FindMembers); + } +"const"|"volatile" { + current->type+=yytext; + } +{B}+ { + current->type+=yytext; + } +({FTSCOPE}"::")*{FTSCOPE} { + current->type+=yytext; + BEGIN(QtPropName); + } +{ID} { + current->name=yytext; + BEGIN(QtPropAttr); + } +"READ" { + current->spec |= Entry::Readable; + BEGIN(QtPropRead); + } +"WRITE" { + current->spec |= Entry::Writable; + BEGIN(QtPropWrite); + } +"RESET"{B}+{ID} { // reset method => not supported yet + } +"SCRIPTABLE"{B}+{ID} { // scriptable property => not supported yet + } +"DESIGNABLE"{B}+{ID} { // designable property => not supported yet + } +{ID} { + current->read = yytext; + BEGIN(QtPropAttr); + } +{ID} { + current->write = yytext; + BEGIN(QtPropAttr); + } +"friend"{BN}+("class"|"union"|"struct"){BN}+ { + current->name=yytext; + BEGIN(FindMembers); + } +{SCOPENAME} { + lineCount(); + if (insideIDL && yyleng==9 && strcmp(yytext,"cpp_quote")==0) + { + BEGIN(CppQuote); + } + else if ((insideIDL || insideJava || insideD) && yyleng==6 && strcmp(yytext,"import")==0) + { + if (insideIDL) + BEGIN(NextSemi); + else // insideJava or insideD + BEGIN(JavaImport); + } + else if (insideJava && strcmp(yytext,"package")==0) + { + lineCount(); + BEGIN(PackageName); + } + else if (insideIDL && strcmp(yytext,"case")==0) + { + BEGIN(IDLUnionCase); + } + else if (insideTryBlock && strcmp(yytext,"catch")==0) + { + insideTryBlock=FALSE; + BEGIN(TryFunctionBlock); + } + else if (insideJS && strcmp(yytext,"var")==0) + { // javascript variable + current->type="var"; + } + else if (insideJS && strcmp(yytext,"function")==0) + { // javascript function + current->type="function"; + } + else + { + if (YY_START==FindMembers) + { + addType( current ) ; + } + bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS; + if (javaLike && strcmp(yytext,"public")==0) + { + current->protection = Public; + } + else if (javaLike && strcmp(yytext,"protected")==0) + { + current->protection = Protected; + } + else if (javaLike && strcmp(yytext,"private")==0) + { + current->protection = Private; + } + else if (javaLike && strcmp(yytext,"static")==0) + { + if (YY_START==FindMembers) + current->name = yytext; + else + current->name += yytext; + current->stat = TRUE; + } + else + { + if (YY_START==FindMembers) + current->name = yytext; + else + current->name += yytext; + if (current->name.left(7)=="static ") + { + current->stat = TRUE; + current->name= current->name.mid(7); + } + else if (current->name.left(7)=="inline ") + { + if (current->type.isEmpty()) + { + current->type="inline"; + } + else + { + current->type+="inline "; + } + current->name= current->name.mid(7); + } + else if (current->name.left(6)=="const ") + { + if (current->type.isEmpty()) + { + current->type="const"; + } + else + { + current->type+="const "; + } + current->name=current->name.mid(6); + } + } + QCString tmp=yytext; + if (nameIsOperator(tmp)) + { + BEGIN( Operator ); + } + else + { + BEGIN(FindMembers); + } + } + } +[0-9]{ID} { // some number where we did not expect one + } +"." { + if (insideJava || insideCS || insideD) + { + current->name+="."; + } + } +"::" { + current->name+=yytext; + } +"("{B}*"\"" { + insideCppQuote=TRUE; + BEGIN(FindMembers); + } +"::" +":" { BEGIN(FindMembers); } +\n { yyLineNr++; } +. +\n { yyLineNr++; } +"{" { + curlyCount=0; + lastCurlyContext = TryFunctionBlockEnd ; + BEGIN( SkipCurly ); + } +. +"catch" { BEGIN(TryFunctionBlock); } +\n { unput(*yytext); // added to fix bug id 601138 + BEGIN( FindMembers ); + } +. { unput(*yytext); + BEGIN( FindMembers ); + } +")" { + insideCppQuote=FALSE; + BEGIN(FindMembers); + } +{B}*"#" { if (insidePHP) + REJECT; + lastCPPContext = YY_START; + BEGIN( SkipCPP ) ; + } +{B}*"#"{B}*("cmake")?"define" { + if (insidePHP) + REJECT; + current->bodyLine = yyLineNr; + BEGIN( Define ); + } +{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */ + yyLineNr = atoi(&yytext[1]); + //printf("setting line number to %d\n",yyLineNr); + lastPreLineCtrlContext = YY_START; + current->program+=yytext; + BEGIN( PreLineCtrl ); + } +"\""[^\n\"]*"\"" { + yyFileName = stripQuotes(yytext); + current->program+=yytext; + } +. { + current->program+=yytext; + } +\n { + current->program+=yytext; + yyLineNr++; + BEGIN( lastPreLineCtrlContext ); + } +. +\\[\r]*"\n"[\r]* { yyLineNr++ ; } +[\r]*\n[\r]* { yyLineNr++ ; + BEGIN( lastCPPContext) ; + } +{ID}{B}*"(" { + current->name = yytext; + current->name = current->name.left(current->name.length()-1).stripWhiteSpace(); + current->args = "("; + current->bodyLine = yyLineNr; + currentArgumentContext = DefineEnd; + fullArgString=current->args.copy(); + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + } + /* +")" { + //printf("Define with args\n"); + current->args += ')'; + BEGIN( DefineEnd ); + } +. { + current->args += *yytext; + } + */ +{ID} { + //printf("Define `%s' without args\n",yytext); + current->bodyLine = yyLineNr; + current->name = yytext; + BEGIN(DefineEnd); + } +\n { + //printf("End define\n"); + yyLineNr++; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->type.resize(0); + current->args = current->args.simplifyWhiteSpace(); + current->name = current->name.stripWhiteSpace(); + current->section = Entry::DEFINE_SEC; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + BEGIN(FindMembers); + } +";" { + //printf("End define\n"); + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->type.resize(0); + current->args = current->args.simplifyWhiteSpace(); + current->name = current->name.stripWhiteSpace(); + current->section = Entry::ENUM_SEC; //HACK! + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + BEGIN(FindMembers); + } +. +\\[\r]?\n { + yyLineNr++; + } +\" { + if (insideIDL && insideCppQuote) + { + BEGIN(EndCppQuote); + } + else + { + lastStringContext=DefineEnd; + BEGIN(SkipString); + } + } +. +{ID}["']{BN}*","{BN}* { + current->name = yytext; + current->name = current->name.stripWhiteSpace(); + current->name = current->name.left(current->name.length()-1).stripWhiteSpace(); + current->name = current->name.left(current->name.length()-1); + current->args = "("; + current->bodyLine = yyLineNr; + lastRoundContext = DefinePHPEnd; + pCopyRoundString = ¤t->args; + roundCount = 0; + BEGIN( CopyRound ); + } + +[\^%] { // ^ and % are C++/CLI extensions + if (insideCli) + { + addType( current ); + current->name = yytext ; + } + else + { + REJECT; + } + } +[*&]+ { + current->name += yytext ; + addType( current ); + } +";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { + lineCount(); + if (current->bodyLine==-1) + { + current->bodyLine=yyLineNr; + } + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) || + ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") ); + docBlock.resize(0); + docBlockTerm = ';'; + if (yytext[yyleng-3]=='/') + { + startCommentBlock(TRUE); + BEGIN( DocLine ); + } + else + { + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } + } +","{BN}*("/**"|"//!"|"/*!"|"///")"<" { + lineCount(); + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) || + ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") ); + docBlock.resize(0); + docBlockTerm = ','; + if (yytext[yyleng-3]=='/') + { + startCommentBlock(TRUE); + BEGIN( DocLine ); + } + else + { + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } + } +{BN}*("/**"|"//!"|"/*!"|"///")"<" { + lineCount(); + if (current->bodyLine==-1) + { + current->bodyLine=yyLineNr; + } + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) || + ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") ); + docBlock.resize(0); + docBlockTerm = 0; + if (yytext[yyleng-3]=='/') + { + startCommentBlock(TRUE); + BEGIN( DocLine ); + } + else + { + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } + } + +("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { + //handleGroupStartCommand(current->name); + if (previous && previous->section==Entry::GROUPDOC_SEC) + { + // link open command to the group defined in the previous entry + openGroup(previous,yyFileName,yyLineNr); + } + else + { + // link open command to the current entry + openGroup(current,yyFileName,yyLineNr); + } + //current = tmp; + initEntry(); + if (yytext[1]=='/') + { + if (yytext[2]=='!' || yytext[2]=='/') + { + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockAutoBrief = FALSE; + docBlock.resize(0); + docBlockTerm = 0; + startCommentBlock(TRUE); + BEGIN(DocLine); + } + else + { + lastCContext=YY_START; + BEGIN(SkipCxxComment); + } + } + else + { + if (yytext[2]=='!' || yytext[2]=='*') + { + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlock.resize(0); + docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) || + ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") ); + docBlockTerm = 0; + startCommentBlock(FALSE); + BEGIN(DocBlock); + } + else + { + lastCContext=YY_START; + BEGIN(SkipComment); + } + } + } +"//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}".*"*/" { + closeGroup(current,yyFileName,yyLineNr); + } +"=" { // in PHP code this could also be due to "bodyLine = yyLineNr; + lastInitializerContext = YY_START; + initBracketCount=0; + BEGIN(ReadInitializer); + } + /* Read initializer rules */ +"(" { + lastRoundContext=YY_START; + pCopyRoundGString=¤t->initializer; + roundCount=0; + current->initializer+=*yytext; + BEGIN(GCopyRound); + } +"{" { + lastCurlyContext=YY_START; + pCopyCurlyGString=¤t->initializer; + curlyCount=0; + current->initializer+=*yytext; + BEGIN(GCopyCurly); + } +[;,] { + //printf(">> initializer `%s' <<\n",current->initializer.data()); + if (*yytext==';' || lastInitializerContext==FindFields) + { + unput(*yytext); + BEGIN(lastInitializerContext); + } + else if (*yytext==',' && initBracketCount==0) // for "int a=0,b=0" + { + unput(*yytext); + BEGIN(lastInitializerContext); + } + else + { + current->initializer+=*yytext; + } + } +\" { + if (insideIDL && insideCppQuote) + { + BEGIN(EndCppQuote); + } + else + { + lastStringContext=YY_START; + current->initializer+=*yytext; + pCopyQuotedGString=¤t->initializer; + BEGIN(CopyGString); + } + } +"->" { + current->initializer+=yytext; + } +"<<" { + current->initializer+=yytext; + } +">>" { + current->initializer+=yytext; + } +[<\[{(] { + initBracketCount++; + current->initializer+=*yytext; + } +[>\]})] { + initBracketCount--; + current->initializer+=*yytext; + } +\' { + if (insidePHP) + { + current->initializer+=yytext; + pCopyQuotedGString = ¤t->initializer; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + else + { + current->initializer+=yytext; + } + } +{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + current->initializer+=yytext; + } + } +\n { + current->initializer+=*yytext; + yyLineNr++; + } +"@\"" { + //printf("insideCS=%d\n",insideCS); + current->initializer+=yytext; + if (!insideCS && !insideObjC) + { + REJECT; + } + else + { + // C#/ObjC verbatim string + lastSkipVerbStringContext=YY_START; + pSkipVerbString=¤t->initializer; + BEGIN(SkipVerbString); + } + } +[^\n"]+ { + *pSkipVerbString+=yytext; + } +"\"\"" { // quote escape + *pSkipVerbString+=yytext; + } +"\"" { + *pSkipVerbString+=*yytext; + BEGIN(lastSkipVerbStringContext); + } +\n { + *pSkipVerbString+=*yytext; + yyLineNr++; + } +. { + *pSkipVerbString+=*yytext; + } +"?>" { + if (insidePHP) + BEGIN( FindMembersPHP ); + else + current->initializer+=yytext; + } +. { + current->initializer+=*yytext; + } + + /* generic quoted string copy rules */ +\\. { + *pCopyQuotedString+=yytext; + } +\" { + *pCopyQuotedString+=*yytext; + BEGIN( lastStringContext ); + } +\' { + *pCopyQuotedString+=*yytext; + BEGIN( lastStringContext ); + } +"/*"|"*/"|"//" { + *pCopyQuotedString+=yytext; + } +\n { + *pCopyQuotedString+=*yytext; + yyLineNr++; + } +. { + *pCopyQuotedString+=*yytext; + } + + /* generic quoted growable string copy rules */ +\\. { + *pCopyQuotedGString+=yytext; + } +\" { + *pCopyQuotedGString+=*yytext; + BEGIN( lastStringContext ); + } +\' { + *pCopyQuotedGString+=*yytext; + BEGIN( lastStringContext ); + } +"/*"|"*/"|"//" { + *pCopyQuotedGString+=yytext; + } +\n { + *pCopyQuotedGString+=*yytext; + yyLineNr++; + } +. { + *pCopyQuotedGString+=*yytext; + } + + /* generic round bracket list copy rules */ +\" { + *pCopyRoundString+=*yytext; + pCopyQuotedString=pCopyRoundString; + lastStringContext=YY_START; + BEGIN(CopyString); + } +"(" { + *pCopyRoundString+=*yytext; + roundCount++; + } +")" { + *pCopyRoundString+=*yytext; + if (--roundCount<0) + BEGIN(lastRoundContext); + } +\n { + yyLineNr++; + *pCopyRoundString+=*yytext; + } +\' { + if (insidePHP) + { + current->initializer+=yytext; + pCopyQuotedString = pCopyRoundString; + lastStringContext=YY_START; + BEGIN(CopyPHPString); + } + else + { + *pCopyRoundString+=yytext; + } + } +{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + *pCopyRoundString+=yytext; + } + } +[^"'()\n]+ { + *pCopyRoundString+=yytext; + } +. { + *pCopyRoundString+=*yytext; + } + + /* generic round bracket list copy rules for growable strings */ +\" { + *pCopyRoundGString+=*yytext; + pCopyQuotedGString=pCopyRoundGString; + lastStringContext=YY_START; + BEGIN(CopyGString); + } +"(" { + *pCopyRoundGString+=*yytext; + roundCount++; + } +")" { + *pCopyRoundGString+=*yytext; + if (--roundCount<0) + BEGIN(lastRoundContext); + } +\n { + yyLineNr++; + *pCopyRoundGString+=*yytext; + } +\' { + if (insidePHP) + { + current->initializer+=yytext; + pCopyQuotedGString = pCopyRoundGString; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + else + { + *pCopyRoundGString+=yytext; + } + } +{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + *pCopyRoundGString+=yytext; + } + } +[^"'()\n/]+ { + *pCopyRoundGString+=yytext; + } +. { + *pCopyRoundGString+=*yytext; + } + + /* generic curly bracket list copy rules */ +\" { + *pCopyCurlyString+=*yytext; + pCopyQuotedString=pCopyCurlyString; + lastStringContext=YY_START; + BEGIN(CopyString); + } +\' { + *pCopyCurlyString+=*yytext; + if (insidePHP) + { + pCopyQuotedString=pCopyCurlyString; + lastStringContext=YY_START; + BEGIN(CopyPHPString); + } + } +"{" { + *pCopyCurlyString+=*yytext; + curlyCount++; + } +"}" { + *pCopyCurlyString+=*yytext; + if (--curlyCount<0) + BEGIN(lastCurlyContext); + } +{CHARLIT} { if (insidePHP) + { + REJECT; + } + else + { + *pCopyCurlyString+=yytext; + } + } +[^"'{}\/\n]+ { + *pCopyCurlyString+=yytext; + } +"/" { *pCopyCurlyString+=yytext; } +\n { + yyLineNr++; + *pCopyCurlyString+=*yytext; + } +. { + *pCopyCurlyString+=*yytext; + } + + /* generic curly bracket list copy rules for growable strings */ +^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker + } +^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker + QCString line = QCString(yytext); + int s = line.find(' '); + int e = line.find('"',s); + yyLineNr = line.mid(s,e-s).toInt(); + if (yytext[yyleng-1]=='\n') + { + yyLineNr++; + } + } +\" { + *pCopyCurlyGString+=*yytext; + pCopyQuotedGString=pCopyCurlyGString; + lastStringContext=YY_START; + BEGIN(CopyGString); + } +\' { + *pCopyCurlyGString+=*yytext; + if (insidePHP) + { + pCopyQuotedGString=pCopyCurlyGString; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + } +"{" { + *pCopyCurlyGString+=*yytext; + curlyCount++; + } +"}" { + *pCopyCurlyGString+=*yytext; + if (--curlyCount<0) + BEGIN(lastCurlyContext); + } +{CHARLIT} { if (insidePHP) + { + REJECT; + } + else + { + *pCopyCurlyGString+=yytext; + } + } +[^"'{}\/\n]+ { + *pCopyCurlyGString+=yytext; + } +"/" { *pCopyCurlyGString+=yytext; } +\n { + yyLineNr++; + *pCopyCurlyGString+=*yytext; + } +. { + *pCopyCurlyGString+=*yytext; + } + + /* ---------------------- */ + + +":" { + if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" + { + addType(current); + current->name.sprintf("__pad%d__",padCount++); + } + BEGIN(BitFields); + current->bitfields+=":"; + } +. { + current->bitfields+=*yytext; + } +[;,] { + //printf("scanner.l: [;,] name=%s, endBodyLine=%d\n", current->name.data(), current->endBodyLine); + QCString oldType = current->type.copy(); + if (current->bodyLine==-1) + { + current->bodyLine = yyLineNr; + } + if ( insidePHP && current->type.left(3) == "var" ) + { + current->type = current->type.mid(3); + } + if (isTypedef && current->type.left(8)!="typedef ") + { + current->type.prepend("typedef "); + } + bool needNewCurrent=FALSE; + if (!current->name.isEmpty() && current->section!=Entry::ENUM_SEC) + { + current->type=current->type.simplifyWhiteSpace(); + current->args=removeRedundantWhiteSpace(current->args); + current->name=current->name.stripWhiteSpace(); + if (current->section==Entry::CLASS_SEC) // remove spec for "struct Bla bla;" + { + current->spec = 0; + } + current->section = Entry::VARIABLE_SEC ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + //printf("scanner.l: [;,] file=%s line=%d\n", current->fileName.data(), current->startLine); + current_root->addSubEntry( current ) ; + needNewCurrent=TRUE; + } + if ( *yytext == ',') + { + if (needNewCurrent) + { + current = new Entry(*current); + } + current->name.resize(0); + current->args.resize(0); + current->brief.resize(0); + current->doc.resize(0); + current->initializer.resize(0); + current->bitfields.resize(0); + int i=oldType.length(); + while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--; + current->type = oldType.left(i); + } + else + { + if (needNewCurrent) + { + current = new Entry ; + } + else if (current->groups) + { + current->groups->clear(); + } + initEntry(); + } + BEGIN( FindMembers ) ; + } + +"[" { + if (!insideCS && + (current->name.isEmpty() || + current->name=="typedef" + ) + ) // IDL function property + { + squareCount=1; + lastSquareContext = YY_START; + idlAttr.resize(0); + idlProp.resize(0); + current->mtype = mtype; + BEGIN( IDLAttribute ); + } + else if (insideCS && + current->name.isEmpty()) + { + squareCount=1; + lastSquareContext = YY_START; + // Skip the C# attribute + // for this member + current->args.resize(0); + BEGIN( SkipSquare ); + } + else + { + current->args += yytext ; + squareCount=1; + BEGIN( Array ) ; + } + } +"]" { + // end of IDL function attribute + if (--squareCount<=0) + { + lineCount(); + if (current->mtype == Property) + BEGIN( IDLPropName ); + else + BEGIN( lastSquareContext ); + } + } +"propput" { + if (Config_getBool("IDL_PROPERTY_SUPPORT")) + { + current->mtype = Property; + } + current->spec |= Entry::Settable; + } +"propget" { + if (Config_getBool("IDL_PROPERTY_SUPPORT")) + { + current->mtype = Property; + } + current->spec |= Entry::Gettable; + } +. { + } +{BN}*{ID}{BN}* { + // return type (probably HRESULT) - skip it + } +{ID}{BN}*"(" { + current->name = yytext; + current->name = current->name.left(current->name.length()-1).stripWhiteSpace(); + current->startLine = yyLineNr; + BEGIN( IDLProp ); + } +{BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter + idlAttr = yytext; + idlAttr=idlAttr.stripWhiteSpace(); + } +{ID} { // property type + idlProp = yytext; + } +{BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);) + if (!current->args) + current->args = "("; + else + current->args += ", "; + current->args += idlAttr; + current->args += " "; + current->args += idlProp; // prop was actually type of extra parameter + current->args += " "; + current->args += yytext; + current->args = current->args.left(current->args.length() - 1); // strip comma + idlProp.resize(0); + idlAttr.resize(0); + BEGIN( IDLProp ); + } +{BN}*{ID}{BN}*")"{BN}* { + // the parameter name for the property - just skip. + } +";" { + current->fileName = yyFileName; + current->type = idlProp; + current->args = current->args.simplifyWhiteSpace(); + if (current->args) + current->args += ")"; + current->name = current->name.stripWhiteSpace(); + current->section = Entry::VARIABLE_SEC; + current_root->addSubEntry(current); + current = new Entry; + initEntry(); + BEGIN( FindMembers ); + } +. { // spaces, *, or other stuff + //idlProp+=yytext; + } +"]" { current->args += *yytext ; + if (--squareCount<=0) + BEGIN( FindMembers ) ; + } +"]" { current->args += *yytext ; + if (--squareCount<=0) + BEGIN( Function ) ; + } +"[" { current->args += *yytext ; + squareCount++; + } +. { current->args += *yytext ; } +"[" { squareCount++; } +"]" { + if (--squareCount<=0) + BEGIN( lastSquareContext ); + } +\" { + lastStringContext=YY_START; + BEGIN( SkipString ); + } +[^\n\[\]\"]+ +"<" { addType( current ) ; + current->type += yytext ; + BEGIN( Sharp ) ; + } +">" { current->type += *yytext ; + if (--sharpCount<=0) + BEGIN( FindMembers ) ; + } +"<" { current->type += *yytext ; + sharpCount++; + } +{BN}+ { + lineCount(); + } +. { current->type += *yytext ; } +{ID} { + current->bodyLine = yyLineNr; + current->name = yytext; + } +"(" { + // Java enum initializer + unput('('); + lastInitializerContext = YY_START; + initBracketCount=0; + BEGIN(ReadInitializer); + } +"=" { + lastInitializerContext = YY_START; + initBracketCount=0; + BEGIN(ReadInitializer); + } +";" { + if (insideJava) // last enum field in Java class + { + if (!current->name.isEmpty()) + { + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->type = "@"; // enum marker + current->args = current->args.simplifyWhiteSpace(); + current->name = current->name.stripWhiteSpace(); + current->section = Entry::VARIABLE_SEC; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + } + + // TODO: skip until the end of the scope + BEGIN( SkipRemainder ); + } + else + { + REJECT; + } + } +\n { + yyLineNr++; + } +[^\n]* +"," { + //printf("adding `%s' `%s' `%s' to enum `%s' (mGrpId=%d)\n", + // current->type.data(), current->name.data(), + // current->args.data(), current_root->name.data(),current->mGrpId); + if (!current->name.isEmpty()) + { + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->type = "@"; // enum marker + current->args = current->args.simplifyWhiteSpace(); + current->name = current->name.stripWhiteSpace(); + current->section = Entry::VARIABLE_SEC; + // add to the scope of the enum + current_root->addSubEntry(current); + if (!insideCS && !insideJava) // for C# and Java 1.5+ enum values always have to be explicitly qualified + { + current = new Entry(*current); + // add to the scope surrounding the enum (copy!) + current_root->parent()->addSubEntry(current); + } + current = new Entry ; + initEntry(); + } + else // probably a redundant , + { + current->reset(); + } + } +"[" { // attribute list in IDL + squareCount=1; + lastSquareContext = YY_START; + BEGIN(SkipSquare); + } + /* +"," { unput(*yytext); BEGIN(FindFields); } + */ +[^\r\n\#{}"@'/]* { current->program += yytext ; } +"//".* { current->program += yytext ; } +"#".* { if (!insidePHP) + REJECT; + // append PHP comment. + current->program += yytext ; + } +@\" { current->program += yytext ; + pSkipVerbString = ¤t->program; + lastSkipVerbStringContext=YY_START; + BEGIN( SkipVerbString ); + } +\" { current->program += yytext ; + pCopyQuotedGString = ¤t->program; + lastStringContext=YY_START; + BEGIN( CopyGString ); + } +"/*"{B}* { current->program += yytext ; + lastContext = YY_START ; + BEGIN( Comment ) ; + } +"/*"{BL} { current->program += yytext ; + ++yyLineNr ; + lastContext = YY_START ; + BEGIN( Comment ) ; + } +"'" { + if (!insidePHP) + { + current->program += yytext; + } + else + { // begin of single quoted string + current->program += yytext; + pCopyQuotedGString = ¤t->program; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + } +{CHARLIT} { + if (insidePHP) + { + REJECT; // for PHP code single quotes + // are used for strings of arbitrary length + } + else + { + current->program += yytext; + } + } +"{" { current->program += yytext ; + ++curlyCount ; + } +"}" { + current->program += yytext ; + --curlyCount ; + } +"}" { //err("ReadBody count=%d\n",curlyCount); + if ( curlyCount>0 ) + { + current->program += yytext ; + --curlyCount ; + } + else + { + current->endBodyLine = yyLineNr; + QCString &cn = current->name; + QCString rn = current_root->name.copy(); + //printf("cn=`%s' rn=`%s'\n",cn.data(),rn.data()); + if (!cn.isEmpty() && !rn.isEmpty()) + { + prependScope(); + } + if (isTypedef && cn.isEmpty()) + { + //printf("Typedef Name\n"); + BEGIN( TypedefName ); + } + else + { + if (current->section == Entry::ENUM_SEC) + { + current->program+=','; // add field terminator + } + // add compound definition to the tree + current->args=removeRedundantWhiteSpace(current->args); + // was: current->args.simplifyWhiteSpace(); + current->type = current->type.simplifyWhiteSpace(); + current->name = current->name.stripWhiteSpace(); + //printf("adding `%s' `%s' `%s' brief=%s insideObjC=%d %x\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data(),insideObjC,current->section); + if (insideObjC && + ((current->spec&Entry::Interface) || (current->spec==Entry::Category)) + ) // method definition follows + { + BEGIN( ReadBodyIntf ) ; + } + else + { + current_root->addSubEntry( current ) ; + memspecEntry = current; + current = new Entry(*current); + if (current->section==Entry::NAMESPACE_SEC || + (current->spec==Entry::Interface) || + insideJava || insidePHP || insideCS || insideD || insideJS + ) + { // namespaces and interfaces and java classes ends with a closing bracket without semicolon + current->reset(); + initEntry(); + memspecEntry = 0; + BEGIN( FindMembers ) ; + } + else + { + //current->doc.resize(0); + //current->brief.resize(0); + BEGIN( MemberSpec ) ; + } + } + } + } + } +"}"{BN}+"typedef"{BN}+ { //err("ReadBody count=%d\n",curlyCount); + lineCount(); + if ( curlyCount>0 ) + { + current->program += yytext ; + --curlyCount ; + } + else + { + isTypedef = TRUE; + current->endBodyLine = yyLineNr; + QCString &cn = current->name; + QCString rn = current_root->name.copy(); + if (!cn.isEmpty() && !rn.isEmpty()) + { + prependScope(); + } + BEGIN( TypedefName ); + } + } +("const"|"volatile"){BN} { // late "const" or "volatile" keyword + lineCount(); + current->type.prepend(yytext); + } +{ID} { + if (current->section == Entry::ENUM_SEC) + { + current->program+=","; // add field terminator + } + current->name=yytext; + prependScope(); + current->args = current->args.simplifyWhiteSpace(); + current->type = current->type.simplifyWhiteSpace(); + //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data()); + current_root->addSubEntry( current ) ; + if (!firstTypedefEntry) + { + firstTypedefEntry = current; + } + current = new Entry; + initEntry(); + isTypedef=TRUE; // to undo reset by initEntry() + BEGIN(MemberSpecSkip); + } +";" { /* typedef of anonymous type */ + current->name.sprintf("@%d",anonCount++); + if (current->section == Entry::ENUM_SEC) + { + current->program+=','; // add field terminator + } + // add compound definition to the tree + current->args = current->args.simplifyWhiteSpace(); + current->type = current->type.simplifyWhiteSpace(); + current_root->addSubEntry( current ) ; + memspecEntry = current; + current = new Entry(*current); + unput(';'); + BEGIN( MemberSpec ) ; + } +([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved. + lineCount(); + int i=0,l=yyleng,j; + while (ispec&Entry::Struct) + { + msType.prepend("struct "+firstTypedefEntry->name); + } + else if (firstTypedefEntry->spec&Entry::Union) + { + msType.prepend("union "+firstTypedefEntry->name); + } + else if (firstTypedefEntry->section==Entry::ENUM_SEC) + { + msType.prepend("enum "+firstTypedefEntry->name); + } + else + { + msType.prepend(firstTypedefEntry->name); + } + } + } +[,;] { + //printf("current->name=`%s' msName=`%s'\n",current->name.data(),msName.data()); + if (msName.isEmpty() && !current->name.isEmpty()) + { + // see if the compound does not have a name or is inside another + // annonymous compound. If so we insert a + // special `annonymous' variable. + //Entry *p=current_root; + Entry *p=current; + while (p) + { + // only look for class scopes, not namespace scopes + if ((p->section & Entry::COMPOUND_MASK) && !p->name.isEmpty()) + { + //printf("Trying scope `%s'\n",p->name.data()); + int i=p->name.findRev("::"); + int pi = (i==-1) ? 0 : i+2; + if (p->name.at(pi)=='@') + { + // annonymous compound inside -> insert dummy variable name + //printf("Adding annonymous variable for scope %s\n",p->name.data()); + msName.sprintf("@%d",anonCount++); + break; + } + } + //p=p->parent; + if (p==current) p=current_root; else p=p->parent(); + } + } + //printf("msName=%s current->name=%s\n",msName.data(),current->name.data()); + if (!msName.isEmpty() && msName!=current->name) // skip typedef T {} T; + { + static bool typedefHidesStruct = Config_getBool("TYPEDEF_HIDES_STRUCT"); + // case 1: typedef struct _S { ... } S_t; + // -> omit typedef and use S_t as the struct name + if (typedefHidesStruct && + isTypedef && + ((current->spec&(Entry::Struct|Entry::Union)) || + current->section==Entry::ENUM_SEC )&& + msType.stripWhiteSpace().isEmpty() && + memspecEntry) + { + memspecEntry->name=msName; + } + else // case 2: create a typedef field + { + Entry *varEntry=new Entry; + varEntry->protection = current->protection ; + varEntry->mtype = current->mtype; + varEntry->virt = current->virt; + varEntry->stat = current->stat; + varEntry->section = Entry::VARIABLE_SEC; + varEntry->name = msName.stripWhiteSpace(); + varEntry->type = current->type.simplifyWhiteSpace()+" "; + varEntry->args = msArgs; + if (isTypedef) + { + varEntry->type.prepend("typedef "); + // //printf("current->name = %s %s\n",current->name.data(),msName.data()); + } + if (typedefHidesStruct && + isTypedef && + (current->spec&(Entry::Struct|Entry::Union)) && + memspecEntry + ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;" + { + varEntry->type+=memspecEntry->name+msType; + } + else // case 2: use _S as type for for pS_t + { + varEntry->type+=current->name+msType; + } + varEntry->fileName = yyFileName; + varEntry->startLine = yyLineNr; + varEntry->doc = current->doc.copy(); + varEntry->brief = current->brief.copy(); + varEntry->mGrpId = current->mGrpId; + + // deep copy group list + QListIterator gli(*current->groups); + Grouping *g; + for (;(g=gli.current());++gli) + { + varEntry->groups->append(new Grouping(*g)); + } + if (current->sli) // copy special list items + { + QListIterator li(*current->sli); + ListItemInfo *lii; + for (li.toFirst();(lii=li.current());++li) + { + varEntry->addSpecialListItem(lii->type,lii->itemId); + } + } + + //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n", + // varEntry->type.data(),varEntry->name.data(), + // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); + current_root->addSubEntry(varEntry); + } + } + if (*yytext==';') + { + msType.resize(0); + msName.resize(0); + msArgs.resize(0); + isTypedef=FALSE; + firstTypedefEntry=0; + memspecEntry=0; + current->reset(); + initEntry(); + BEGIN( FindMembers ); + } + else + { + current->doc.resize(0); + current->brief.resize(0); + } + } +"=" { + lastInitializerContext=YY_START; + initBracketCount=0; + BEGIN(ReadInitializer); + /* BEGIN(MemberSpecSkip); */ + } + /* +"{" { + curlyCount=0; + lastCurlyContext = MemberSpecSkip; + previous = current; + BEGIN(SkipCurly); + } + */ +"," { BEGIN(MemberSpec); } +";" { unput(';'); BEGIN(MemberSpec); } +{BN}+ { current->program += yytext ; + lineCount() ; + } +"@end"/[^a-z_A-Z0-9] { // end of Objective C block + current_root->addSubEntry( current ) ; + current=new Entry; + initEntry(); + insideObjC=FALSE; + BEGIN( FindMembers ); + } +. { current->program += yytext ; } + +"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A::func_t)(args...) */ +("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[] */ + if (insidePHP) // reference parameter + { + REJECT + } + else + { + current->bodyLine = yyLineNr; + lineCount(); + addType(current); + funcPtrType=yytext; + roundCount=0; + //current->type += yytext; + BEGIN( FuncPtr ); + } + } +{SCOPENAME} { + current->name = yytext; + if (nameIsOperator(current->name)) + { + BEGIN( FuncPtrOperator ); + } + else + { + if (current->name=="const" || current->name=="volatile") + { + funcPtrType += current->name; + } + else + { + BEGIN( EndFuncPtr ); + } + } + } +. { + //printf("Error: FuncPtr `%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName); + } +"("{BN}*")"{BN}*/"(" { + current->name += yytext; + current->name = current->name.simplifyWhiteSpace(); + lineCount(); + } +\n { + yyLineNr++; + current->name += *yytext; + } +"(" { + unput(*yytext); + BEGIN( EndFuncPtr ); + } +. { + current->name += *yytext; + } +")"{BN}*/";" { // a variable with extra braces + lineCount(); + current->type+=funcPtrType.data()+1; + BEGIN(FindMembers); + } +")"{BN}*/"(" { // a function pointer + lineCount(); + current->type+=funcPtrType+")"; + BEGIN(FindMembers); + } +")"{BN}*/"[" { // an array of variables + lineCount(); + current->type+=funcPtrType.data(); + current->args += ")"; + BEGIN(FindMembers); + } +"(" { // a function returning a function or + // a function returning a pointer to an array + current->args += *yytext ; + //roundCount=0; + //BEGIN( FuncFunc ); + current->bodyLine = yyLineNr; + currentArgumentContext = FuncFuncEnd; + fullArgString=current->args.copy(); + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + } +"["[^\n\]]*"]" { + funcPtrType+=yytext; + } +")" { + BEGIN(FindMembers); + } +"(" { + current->args += *yytext ; + ++roundCount; + } +")" { + current->args += *yytext ; + if ( roundCount ) + --roundCount; + else + { + BEGIN(FuncFuncEnd); + } + } +")"{BN}*"(" { + lineCount(); + current->type+=funcPtrType+")("; + BEGIN(FuncFuncType); + } +")"{BN}*/[;{] { + lineCount(); + current->type+=funcPtrType.data()+1; + BEGIN(Function); + } +")"{BN}*/"[" { // function returning a pointer to an array + lineCount(); + current->type+=funcPtrType; + current->args+=")"; + BEGIN(FuncFuncArray); + } +. { + current->args += *yytext; + } +"(" { + current->type += *yytext; + roundCount++; + } +")" { + current->type += *yytext; + if (roundCount) + --roundCount; + else + BEGIN(Function); + } +{BN}*","{BN}* { lineCount() ; current->type += ", " ; } +{BN}+ { lineCount() ; current->type += ' ' ; } +. { + current->type += *yytext; + } +"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")(" { // for catching typedef void (__stdcall *f)() like definitions + if (current->type.left(7)=="typedef" && current->bodyLine==-1) + // the bodyLine check is to prevent this guard to be true more than once + { + current->bodyLine = yyLineNr; + BEGIN( GetCallType ); + } + else if (!current->name.isEmpty()) // normal function + { + current->args = yytext; + current->bodyLine = yyLineNr; + currentArgumentContext = FuncQual; + fullArgString=current->args.copy(); + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + //printf(">>> Read function arguments!\n"); + } + } +{BN}*{ID}{BN}*"*" { + lineCount(); + addType(current); + funcPtrType="("; + funcPtrType+=yytext; + roundCount=0; + BEGIN( FuncPtr ); + } +"(" { + if (!current->name.isEmpty()) + { + current->args = yytext; + current->bodyLine = yyLineNr; + currentArgumentContext = FuncQual; + fullArgString=current->args.copy(); + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + //printf(">>> Read function arguments current->argList->count()=%d\n",current->argList->count()); + } + } + /* +"("{BN}*("void"{BN}*)?")" { + lineCount(); + current->args = "()"; + BEGIN( FuncQual ); + } + */ + + /*- Function argument reading rules ---------------------------------------*/ + +[^ \/\r\t\n\)\(\"\'#]+ { *copyArgString+=yytext; + fullArgString+=yytext; + } +[^\n\\\"\']+ { *copyArgString+=yytext; + fullArgString+=yytext; + } +[^\/\n\)\(\"\']+ { + *copyArgString+=yytext; + fullArgString+=yytext; + } +{BN}* { + *copyArgString+=" "; + fullArgString+=" "; + lineCount(); + } +\" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + lastCopyArgStringContext = YY_START; + BEGIN( CopyArgString ); + } +"(" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + argRoundCount=0; + lastCopyArgContext = YY_START; + BEGIN( CopyArgRound ); + } +")" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + stringToArgumentList(fullArgString,current->argList); + if (insideJS) + { + fixArgumentListForJavaScript(current->argList); + } + handleParametersCommentBlocks(current->argList); + + /* remember the current documentation block, since + we could overwrite it with the documentation of + a function argument, which we then have to correct later + on + */ + docBackup = current->doc; + briefBackup = current->brief; + + BEGIN( currentArgumentContext ); + } + /* a special comment */ +("/*"[*!]|"//"[/!])("<"?) { + if (currentArgumentContext==DefineEnd) + { + // for defines we interpret a comment + // as documentation for the define + int i;for (i=yyleng-1;i>=0;i--) + { + unput(yytext[i]); + } + stringToArgumentList(fullArgString,current->argList); + handleParametersCommentBlocks(current->argList); + BEGIN( currentArgumentContext ); + } + else // not a define + { + // for functions we interpret a comment + // as documentation for the argument + fullArgString+=yytext; + lastCopyArgChar=0; + lastCommentInArgContext=YY_START; + if (yytext[1]=='/') + BEGIN( CopyArgCommentLine ); + else + BEGIN( CopyArgComment ); + } + } + /* a non-special comment */ +"/**/" { /* empty comment */ } +"/*" { + lastCContext = YY_START; + BEGIN( SkipComment ); + } +"//" { + lastCContext = YY_START; + BEGIN( SkipCxxComment ); + } + /* +"'#" { if (insidePHP) + REJECT; + *copyArgString+=yytext; + fullArgString+=yytext; + } +"#" { + if (!insidePHP) + REJECT; + lastCContext = YY_START; + BEGIN( SkipCxxComment ); + } + */ + /* `)' followed by a special comment */ +")"{BN}*("/*"[*!]|"//"[/!])"<" { + lineCount(); + if (currentArgumentContext==DefineEnd) + { + // for defines we interpret a comment + // as documentation for the define + int i;for (i=yyleng-1;i>0;i--) + { + unput(yytext[i]); + } + *copyArgString+=*yytext; + fullArgString+=*yytext; + stringToArgumentList(fullArgString,current->argList); + handleParametersCommentBlocks(current->argList); + BEGIN( currentArgumentContext ); + } + else + { + // for functions we interpret a comment + // as documentation for the last argument + lastCopyArgChar=*yytext; + QCString text=&yytext[1]; + text=text.stripWhiteSpace(); + lastCommentInArgContext=YY_START; + fullArgString+=text; + if (text.find("//")!=-1) + BEGIN( CopyArgCommentLine ); + else + BEGIN( CopyArgComment ); + } + } +^{B}*"*"+/{BN}+ +[^\n\\\@\*]+ { fullArgString+=yytext; } +"*/" { fullArgString+=yytext; + if (lastCopyArgChar!=0) + unput(lastCopyArgChar); + BEGIN( lastCommentInArgContext ); + } +\n { fullArgString+=yytext; + yyLineNr++; + if (lastCopyArgChar!=0) + unput(lastCopyArgChar); + BEGIN( lastCommentInArgContext ); + } +{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!) + docBlockName=&yytext[1]; + fullArgString+=yytext; + BEGIN(CopyArgVerbatim); + } +{CMD}("f$"|"f["|"f{") { + docBlockName=&yytext[1]; + if (docBlockName.at(1)=='[') + { + docBlockName.at(1)='}'; + } + if (docBlockName.at(1)=='{') + { + docBlockName.at(1)='}'; + } + fullArgString+=yytext; + BEGIN(CopyArgVerbatim); + } +[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9] { // end of verbatim block + fullArgString+=yytext; + if (yytext[1]=='f') // end of formula + { + BEGIN(CopyArgCommentLine); + } + if (&yytext[4]==docBlockName) + { + BEGIN(CopyArgCommentLine); + } + } +[^\\\@\n]+ { fullArgString+=yytext; } +. { fullArgString+=*yytext; } +\n { fullArgString+=*yytext; yyLineNr++; } +. { fullArgString+=*yytext; } +{CMD}("brief"|"short"){B}+ { + warn(yyFileName,yyLineNr, + "Warning: Ignoring %cbrief command inside argument documentation",*yytext + ); + fullArgString+=' '; + } +"<" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + argSharpCount=1; + BEGIN( CopyArgSharp ); + } +">" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + //printf("end template list %s\n",copyArgString->data()); + stringToArgumentList(fullArgString,currentArgumentList); + BEGIN( currentArgumentContext ); + } +"(" { + argRoundCount++; + *copyArgString+=*yytext; + fullArgString+=*yytext; + } +")" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + if (argRoundCount>0) + argRoundCount--; + else + BEGIN( lastCopyArgContext ); + } +"<" { + argSharpCount++; + //printf("argSharpCount++=%d copy\n",argSharpCount); + *copyArgString+=*yytext; + fullArgString+=*yytext; + } +">" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + argSharpCount--; + if (argSharpCount>0) + { + //printf("argSharpCount--=%d copy\n",argSharpCount); + } + else + { + BEGIN( ReadTempArgs ); + //printf("end of argSharpCount\n"); + } + } +\\. { + *copyArgString+=yytext; + fullArgString+=yytext; + } +\" { + *copyArgString+=*yytext; + fullArgString+=*yytext; + BEGIN( lastCopyArgStringContext ); + } +\' { + *copyArgString+=*yytext; + fullArgString+=*yytext; + BEGIN( lastCopyArgStringContext ); + } +{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + *copyArgString+=yytext; + fullArgString+=yytext; + } + } +\' { + *copyArgString+=yytext; + fullArgString+=yytext; + if (insidePHP) + { + lastCopyArgStringContext=YY_START; + BEGIN(CopyArgPHPString); + } + } +\n { + yyLineNr++; + *copyArgString+=*yytext; + fullArgString+=*yytext; + } +. { + *copyArgString+=*yytext; + fullArgString+=*yytext; + } + + + + /*------------------------------------------------------------------------*/ + + +"(" { current->args += *yytext ; + ++roundCount ; + } +")" { current->args += *yytext ; + if ( roundCount ) + --roundCount ; + else + BEGIN( FuncQual ) ; + } + /* +"#" { if (insidePHP) + REJECT; + lastCPPContext = YY_START; + BEGIN(SkipCPP); + } + */ +[{:;,] { + if ( strcmp(yytext,";")==0 && + insidePHP && + !containsWord(current->type,"function") ) + { + current->reset(); + initEntry(); + BEGIN( FindMembers ); + } + else + { + unput(*yytext); BEGIN( Function ); + } + } +{BN}*"abstract"{BN}* { // pure virtual member function + lineCount() ; + current->virt = Pure; + current->args += " override "; + } +{BN}*"override"{BN}* { // overridden virtual member function + lineCount() ; + current->spec |= Entry::Override; + current->args += " override "; + } +{BN}*"sealed"{BN}* { // sealed member function + lineCount() ; + current->spec |= Entry::Sealed; + current->args += " sealed "; + } +{BN}*"new"{BN}* { // new member function + lineCount() ; + current->spec |= Entry::New; + current->args += " new "; + } +{BN}*"const"{BN}* { // const member function + lineCount() ; + current->args += " const "; + current->argList->constSpecifier=TRUE; + } +{BN}*"volatile"{BN}* { // volatile member function + lineCount() ; + current->args += " volatile "; + current->argList->volatileSpecifier=TRUE; + } +{BN}*"="{BN}*"0"{BN}* { // pure virtual member function + lineCount() ; + current->args += " = 0"; + current->virt = Pure; + current->argList->pureSpecifier=TRUE; + } +{BN}*","{BN}* { + lineCount() ; + current->args += ", " ; + } +{BN}+ { + lineCount() ; + current->args += ' ' ; + } +"#" { if (insidePHP) + REJECT; + lastCPPContext = YY_START; + BEGIN(SkipCPP); + } +"=" { + if (insideCli && + (current_root->section&Entry::COMPOUND_MASK) + ) + { + BEGIN(CliOverride); + } + else + { + // typically an initialized function pointer + lastInitializerContext=YY_START; + initBracketCount=0; + BEGIN(ReadInitializer); + } + } +{ID} { + } +"{" { + unput(*yytext); + BEGIN(FuncQual); + } +\n { + yyLineNr++; + } +. { + } +[{;] { + unput(*yytext); + BEGIN(FuncQual); + } +\" { + current->args += *yytext; + pCopyQuotedString=¤t->args; + lastStringContext=FuncPtrInit; + BEGIN(CopyString); + } +\' { + current->args += *yytext; + if (insidePHP) + { + pCopyQuotedString=¤t->args; + lastStringContext=FuncPtrInit; + BEGIN(CopyPHPString); + } + } +{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + current->args += yytext; + } + } +{ID} { + current->args += yytext; + } +. { + current->args += *yytext; + } +\n { + current->args += *yytext; + yyLineNr++; + } +{ID} { // typically a K&R style C function + if (insideCS && strcmp(yytext,"where")==0) + { + // type contraint for a method + delete current->typeConstr; + current->typeConstr = new ArgumentList; + current->typeConstr->append(new Argument); + lastCSConstraint = YY_START; + BEGIN( CSConstraintName ); + } + else if (checkForKnRstyleC()) + { + //fprintf(stderr,"===> got a K&R style function\n"); + current->args = yytext; + oldStyleArgType.resize(0); + BEGIN(OldStyleArgs); + } + else + { + current->args += yytext; + } + } +[,;] { + QCString oldStyleArgPtr; + QCString oldStyleArgName; + splitKnRArg(oldStyleArgPtr,oldStyleArgName); + QCString doc,brief; + if (current->doc!=docBackup) + { + doc=current->doc.copy(); + current->doc=docBackup; + } + if (current->brief!=briefBackup) + { + brief=current->brief.copy(); + current->brief=briefBackup; + } + addKnRArgInfo(oldStyleArgType+oldStyleArgPtr, + oldStyleArgName,brief,doc); + current->args.resize(0); + if (*yytext==';') oldStyleArgType.resize(0); + } +{ID} { current->args += yytext; } +"{" { + current->args = argListToString(current->argList); + unput('{'); + BEGIN(FuncQual); + } +. { current->args += *yytext; } +. { current->args += *yytext; } +{BN}*"try"{BN}+ { /* try-function-block */ + insideTryBlock=TRUE; + lineCount(); + } +{BN}*"throw"{BN}*"(" { // C++ style throw clause + current->exception = " throw (" ; + roundCount=0; + lineCount() ; + BEGIN( ExcpRound ) ; + } +{BN}*"raises"{BN}*"(" { + current->exception = " raises (" ; + lineCount() ; + roundCount=0; + BEGIN( ExcpRound ) ; + } +{BN}*"throws"{BN}+ { // Java style throw clause + current->exception = " throws " ; + lineCount() ; + BEGIN( ExcpList ); + } +"(" { current->exception += *yytext ; + ++roundCount ; + } +")" { current->exception += *yytext ; + if ( roundCount ) + --roundCount ; + else + BEGIN( FuncQual ) ; + } +. { + current->exception += *yytext; + } +"{" { + unput('{'); BEGIN( FuncQual ); + } +";" { + unput(';'); BEGIN( FuncQual ); + } +"\n" { + current->exception += ' '; + yyLineNr++; + } +. { + current->exception += *yytext; + } +"(" { current->type += current->name ; + current->name = current->args ; + current->args = yytext ; + roundCount=0; + BEGIN( FuncRound ) ; + } +":" { + if (!insidePHP) BEGIN(SkipInits); + } +[;{,] { + current->name=current->name.simplifyWhiteSpace(); + current->type=current->type.simplifyWhiteSpace(); + current->args=removeRedundantWhiteSpace(current->args); + // was: current->args.simplifyWhiteSpace(); + current->fileName = yyFileName; + current->startLine = yyLineNr; + static QRegExp re("([^)]*\\[*&][^)]*)"); // (...*...) + if (*yytext!=';' || (current_root->section&Entry::COMPOUND_MASK) ) + { + int tempArg=current->name.find('<'); + QCString tempName; + if (tempArg==-1) tempName=current->name; else tempName=current->name.left(tempArg); + if (!current->type.isEmpty() && + (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef ")) + { + //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data()); + current->section = Entry::VARIABLE_SEC ; + } + else + { + //printf("Scanner.l: found in class function: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data()); + current->section = Entry::FUNCTION_SEC ; + current->proto = *yytext==';'; + } + } + else // a global function prototype or function variable + { + //printf("Scanner.l: prototype? type=`%s' name=`%s' args=`%s'\n",current->type.data(),current->name.data(),current->args.data()); + if (!current->type.isEmpty() && + (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef ")) + { + //printf("Scanner.l: found function variable!\n"); + current->section = Entry::VARIABLE_SEC; + } + else + { + //printf("Scanner.l: found prototype\n"); + current->section = Entry::FUNCTION_SEC; + current->proto = TRUE; + } + } + //printf("Adding entry `%s'\n",current->name.data()); + if ( insidePHP) + { + if (findAndRemoveWord(current->type,"final")) + { + current->spec |= Entry::Final; + } + if (findAndRemoveWord(current->type,"abstract")) + { + current->spec |= Entry::Abstract; + } + } + if ( insidePHP && !containsWord(current->type,"function")) + { + initEntry(); + if ( *yytext == '{' ) + { + lastCurlyContext = FindMembers; + curlyCount=0; + BEGIN( SkipCurly ); + } + else + { + BEGIN( FindMembers ); + } + } + else + { + if ( insidePHP) + { + findAndRemoveWord(current->type,"function"); + } + previous = current; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); + // Objective C 2.0: Required/Optional section + if (previous->spec & (Entry::Optional | Entry::Required)) + { + current->spec |= previous->spec & (Entry::Optional|Entry::Required); + } + lastCurlyContext = FindMembers; + if ( *yytext == ',' ) + { + current->type = previous->type.data(); + } + if ( *yytext == '{' ) + { + if ( !insidePHP && (current_root->section & Entry::COMPOUND_MASK) ) + { + previous->spec |= Entry::Inline; + } + //addToBody(yytext); + curlyCount=0; + BEGIN( SkipCurly ) ; + } + else + { + if (previous->section!=Entry::VARIABLE_SEC) + previous->bodyLine=-1; // a function/member declaration + BEGIN( FindMembers ) ; + } + } + } +"{" { + //addToBody(yytext); + //lastCurlyContext = FindMembers; + //curlyCount=0; + //BEGIN( SkipCurly ) ; + unput('{'); + BEGIN( Function ); + } +"{" { + //addToBody(yytext); + ++curlyCount ; + } +"}" { + //addToBody(yytext); + if( curlyCount ) + { + --curlyCount ; + } + else + { +#if 0 + if (!Config_getBool("HIDE_IN_BODY_DOCS") && + !current->doc.isEmpty()) + { + // copy documentation found inside the body + // to the previous item + if (previous->inbodyLine==-1) + { + previous->inbodyLine = current->docLine; + previous->inbodyFile = current->docFile; + } + //printf("*** inbodyDocs+=%s\n",current->doc.data()); + previous->inbodyDocs += current->doc; + current->doc.resize(0); + } +#endif + if (current->sli && previous) // copy special list items + { + QListIterator li(*current->sli); + ListItemInfo *lii; + for (li.toFirst();(lii=li.current());++li) + { + previous->addSpecialListItem(lii->type,lii->itemId); + } + delete current->sli; + current->sli = 0; + } + if (previous) previous->endBodyLine=yyLineNr; + BEGIN( lastCurlyContext ) ; + } + } +"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { + lineCount(); + if ( curlyCount ) + { + //addToBody(yytext); + --curlyCount ; + } + else + { + current->endBodyLine=yyLineNr; + + tempEntry = current; // temporarily switch to the previous entry + current = previous; + + docBlockContext = SkipCurlyEndDoc; + docBlockInBody = FALSE; + docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) || + ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") ); + docBlock.resize(0); + docBlockTerm = '}'; + if (yytext[yyleng-3]=='/') + { + startCommentBlock(TRUE); + BEGIN( DocLine ); + } + else + { + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } + } + } +"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { // desc is followed by another one + docBlockContext = SkipCurlyEndDoc; + docBlockInBody = FALSE; + docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) || + ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") ); + docBlock.resize(0); + docBlockTerm = '}'; + if (yytext[yyleng-3]=='/') + { + startCommentBlock(TRUE); + BEGIN( DocLine ); + } + else + { + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } + } +"}" { + //addToBody("}"); + current = tempEntry; + BEGIN( lastCurlyContext ); + } +\" { + //addToBody(yytext); + lastStringContext=SkipCurly; + BEGIN( SkipString ); + } +^{B}*"#" { + if (insidePHP) + REJECT; + //addToBody(yytext); + BEGIN( SkipCurlyCpp ); + } +\n { + yyLineNr++; + //addToBody(yytext); + } +[^\n#"'@\\/{}]+ { + //addToBody(yytext); + } +\n { + //addToBody(yytext); + yyLineNr++; + lastCurlyContext = FindMembers; + BEGIN( SkipCurly ); + } +\\[\r]*"\n"[\r]* { + //addToBody(yytext); + yyLineNr++; + } +"/*" { + //addToBody(yytext); + lastCContext = YY_START; + BEGIN(SkipComment); + } +"//" { + //addToBody(yytext); + lastCContext = YY_START; + BEGIN(SkipCxxComment); + } +\" { + lastStringContext=YY_START; + BEGIN( SkipString ); + } +; { + warn(yyFileName,yyLineNr, + "Warning: Found ';' while parsing initializer list! " + "(doxygen could be confused by a macro call without semicolon)" + ); + BEGIN( FindMembers ); + } +"#" { + if (!insidePHP) + REJECT; + //addToBody(yytext); + lastCContext = YY_START; + BEGIN(SkipCxxComment); + } +@\" { + if (!insideCS) REJECT; + // C# verbatim string + lastSkipVerbStringContext=YY_START; + pSkipVerbString=¤t->initializer; + BEGIN(SkipVerbString); + } +{CHARLIT} { + if (insidePHP) REJECT; + } +\' { + if (insidePHP) + { + lastStringContext=YY_START; + BEGIN(SkipPHPString); + } + } +. { } +\\. { } +\" { + BEGIN( lastStringContext ); + } +\' { + BEGIN( lastStringContext ); + } +"/*"|"*/"|"//" { } +\n { + yyLineNr++; + } +. { } +";" { + current->section = Entry::EMPTY_SEC ; + current->type.resize(0) ; + current->name.resize(0) ; + current->args.resize(0) ; + current->argList->clear(); + BEGIN( FindMembers ) ; + } +{SCOPENAME}{BN}*/"<" { + sharpCount = 0; + current->name = yytext ; + if (current->spec & Entry::Protocol) + { + current->name+="-p"; + } + lineCount(); + lastClassTemplSpecContext = ClassVar; + if (insideObjC) // protocol list + { + BEGIN( ObjCProtocolList ); + } + else if (insideCS) // C# generic class + { + BEGIN( CSGeneric ); + } + else // C++ template specialization + { + roundCount=0; + BEGIN( ClassTemplSpec ); + } + } +"<" { + if (current->tArgLists==0) + { + current->tArgLists = new QList; + current->tArgLists->setAutoDelete(TRUE); + } + ArgumentList *al = new ArgumentList; + current->spec |= Entry::Template; + current->tArgLists->append(al); + currentArgumentList = al; + templateStr="<"; + current->name += "<"; + fullArgString = templateStr; + copyArgString = ¤t->name; + currentArgumentContext = ClassVar; + BEGIN( ReadTempArgs ); + } +"<" { + insideProtocolList=TRUE; + BEGIN( Bases ); + } +">"({BN}*"::"{BN}*{SCOPENAME})? { + current->name += yytext; + lineCount(); + if (--sharpCount<=0) + { + current->name = removeRedundantWhiteSpace(current->name); + if (current->spec & Entry::Protocol) + { // Objective-C protocol + unput('{'); // fake start of body + BEGIN( ClassVar ); + } + else + { + BEGIN( lastClassTemplSpecContext ); + } + } + } +"<" { + current->name += yytext; + sharpCount++; + } +. { + current->name += yytext; + } +{SCOPENAME}{BN}*";" { // forward declaration + unput(';'); + current->reset(); + if (isTypedef) // typedef of a class, put typedef keyword back + { + current->type.prepend("typedef"); + } + BEGIN( FindMembers ); + } +{SCOPENAME}/"(" { + current->name = yytext ; + lineCount(); + if (current->spec & Entry::Protocol) + { + current->name += "-p"; + } + BEGIN( ClassVar ); + } +{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line + // e.g. @protocol A,B; + current->reset(); + } +{SCOPENAME} { + current->name = yytext ; + lineCount(); + if (current->spec & Entry::Protocol) + { + current->name += "-p"; + } + if ((current->spec & Entry::Protocol) || + current->section == Entry::OBJCIMPL_SEC) + { + unput('{'); // fake start of body + } + BEGIN( ClassVar ); + } +{CSSCOPENAME} { // C# style scope + current->name = substitute(yytext,".","::"); + lineCount(); + BEGIN( ClassVar ); + } +{SCOPENAME}{BN}*/"(" { + if (insideIDL && strncmp(yytext,"switch",6)==0 && !isId(yytext[6])) + { + // Corba IDL style union + roundCount=0; + BEGIN(SkipUnionSwitch); + } + else + { + addType(current); + current->name = yytext; + current->name = current->name.stripWhiteSpace(); + lineCount(); + BEGIN( FindMembers ); + } + } +"," { + if (isTypedef) + { + // multiple types in one typedef + unput(','); + current->type.prepend("typedef "); + BEGIN(FindMembers); + } + else + { + // Multiple class forward declaration + } + } +("sealed"|"abstract")/{BN}*(":"|"{") { + if (insideCli) + { + if (yytext[0]=='s') // sealed + current->spec |= Entry::SealedClass; + else // abstract + current->spec |= Entry::AbstractClass; + BEGIN( ClassVar ); + } + else + { + REJECT; + } + } +{ID} { + if (insideIDL && strcmp(yytext,"switch")==0) + { + // Corba IDL style union + roundCount=0; + BEGIN(SkipUnionSwitch); + } + else if ((insideJava || insidePHP || insideJS) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) + { + current->type.resize(0); + baseProt=Public; + baseVirt=Normal; + baseName.resize(0); + BEGIN( BasesProt ) ; + } + else if (insideCS && strcmp(yytext,"where")==0) // C# type contraint + { + delete current->typeConstr; + current->typeConstr = new ArgumentList; + current->typeConstr->append(new Argument); + lastCSConstraint = YY_START; + BEGIN( CSConstraintName ); + } + else if (insideCli && strcmp(yytext,"abstract")) + { + current->spec|=Entry::Abstract; + } + else if (insideCli && strcmp(yytext,"sealed")) + { + current->spec|=Entry::Sealed; + } + else + { + if (current->section == Entry::ENUM_SEC) + { // found "enum a b" -> variable + current->section = Entry::VARIABLE_SEC ; + } + current->type += ' ' ; + current->type += current->name ; + current->name = yytext ; + + if (nameIsOperator(current->name)) + { + BEGIN( Operator ); + } + } + } +[(\[] { + if (insideObjC && *yytext=='(') // class category + { + current->name+='('; + if (current->section!=Entry::OBJCIMPL_SEC) + { + current->spec|=Entry::Category; + } + BEGIN( ClassCategory ); + } + else + { + // probably a function anyway + unput(*yytext); + BEGIN( FindMembers ); + } + } +"/**/" { /* empty comment */ } +("/*"[*!]|"//"[/!])("<"?) { // special comment + fullArgString.resize(0); + lastCopyArgChar='#'; // end marker + lastCommentInArgContext=YY_START; + if (yytext[1]=='/') + BEGIN( CopyArgCommentLine ); + else + BEGIN( CopyArgComment ); + } +"#" { // artifically inserted token to signal end of comment block + current->typeConstr->last()->docs = fullArgString; + } +"{" { // end of type constraint reached + // parse documentation of the constraints + handleParametersCommentBlocks(current->typeConstr); + unput('{'); + BEGIN( lastCSConstraint ); + } +";" { + handleParametersCommentBlocks(current->typeConstr); + unput(';'); + BEGIN( lastCSConstraint ); + } +":" { + BEGIN( CSConstraintType ); + } +{ID} { + // parameter name + current->typeConstr->last()->name=yytext; + } +"where" { // another constraint for a different param + current->typeConstr->append(new Argument); + BEGIN( CSConstraintName ); + } +({ID}".")*{ID}("<"{ID}">")?("()")? { + if (current->typeConstr->last()->type.isEmpty()) + // first type constraint for this parameter + { + current->typeConstr->last()->type=yytext; + } + else // new type constraint for same parameter + { + QCString name = current->typeConstr->last()->name; + current->typeConstr->append(new Argument); + current->typeConstr->last()->name=name; + current->typeConstr->last()->type=yytext; + } + } +\n { + yyLineNr++; + } +. { + } +{ID} { + current->name+=yytext; + } +")" { + current->name+=')'; + if ((current->section & Entry::Protocol) || + current->section == Entry::OBJCIMPL_SEC) + { + unput('{'); // fake start of body + } + else // category has no variables so push back an empty body + { + unput('}'); + unput('{'); + } + BEGIN( ClassVar ); + } +":" { + current->type.resize(0); + if ((current->spec & Entry::Interface) || + (current->spec & Entry::Struct) || + (current->spec & Entry::Ref) || + (current->spec & Entry::Value) || + insidePHP || insideCS || insideD || insideObjC + ) + baseProt=Public; + else + baseProt=Private; + baseVirt=Normal; + baseName.resize(0); + BEGIN( BasesProt ) ; + } +[;=*&] { + unput(*yytext); + if (isTypedef) // typedef of a class, put typedef keyword back + { + current->type.prepend("typedef"); + } + BEGIN( FindMembers ); + } +"///"/[^/] { + if (!insideObjC) + { + REJECT; + } + else + { + lineCount(); + current->program+=yytext; + current->fileName = yyFileName ; + current->startLine = yyLineNr ; + curlyCount=0; + BEGIN( ReadBodyIntf ); + } + } +("//"{B}*)?"/**"/[^/*] | +("//"{B}*)?"/*!" | +"//!" | +[\-+]{BN}* { + if (!insideObjC) + { + REJECT; + } + else + { + lineCount(); + current->program+=yytext; + current->fileName = yyFileName ; + current->startLine = yyLineNr ; + curlyCount=0; + BEGIN( ReadBodyIntf ); + } + } +{B}*"{"{B}* { + current->fileName = yyFileName ; + current->startLine = yyLineNr ; + current->name = removeRedundantWhiteSpace(current->name); + if (current->name.isEmpty() && !isTypedef) // anonymous compound + { + if (current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces + { + if (Config_getBool("EXTRACT_ANON_NSPACES")) // use visible name + { + current->name="anonymous_namespace{"+stripPath(current->fileName)+"}"; + } + else // use invisible name + { + current->name.sprintf("@%d",anonNSCount); + } + } + else + { + current->name.sprintf("@%d",anonCount++); + } + } + curlyCount=0; + if (current_root && // not a nested struct inside an @interface section + !(current_root->spec & Entry::Interface) && + ((current->spec & (Entry::Interface | Entry::Protocol | Entry::Category) || + current->section==Entry::OBJCIMPL_SEC) + ) && + insideObjC + ) + { // ObjC body that ends with @end + BEGIN( ReadBodyIntf ); + } + else if (current->section==Entry::NAMESPACE_SEC) + { // namespace body + BEGIN( ReadNSBody ); + } + else + { // class body + BEGIN( ReadBody ) ; + } + } +"virtual"{BN}+ { lineCount(); baseVirt = Virtual; } +"public"{BN}+ { lineCount(); baseProt = Public; } +"protected"{BN}+ { lineCount(); baseProt = Protected; } +"private"{BN}+ { lineCount(); baseProt = Private; } +{BN} { lineCount(); } +. { unput(*yytext); BEGIN(Bases); } +("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} { + QCString baseScope = yytext; + if (insideCS && baseScope.stripWhiteSpace()=="where") + { + // type contraint for a class + delete current->typeConstr; + current->typeConstr = new ArgumentList; + current->typeConstr->append(new Argument); + lastCSConstraint = YY_START; + BEGIN( CSConstraintName ); + } + else + { + baseName+=yytext; + current->args += ' '; + current->args += yytext; + } + } +{BN}*{ID}("."{ID})* { // Java style class + QCString name = substitute(yytext,".","::"); + baseName += name; + current->args += ' '; + current->args += name; + } +\n/{BN}*[^{, \t\n] { + if (!insideObjC) + { + REJECT; + } + else + { + yyLineNr++; + unput('{'); + } + } +"@end" { // empty ObjC interface + unput('d'); // insert fake body: {}@end + unput('n'); + unput('e'); + unput('@'); + unput('}'); + unput('{'); + } +"<" { current->name += *yytext; + sharpCount=1; + roundCount=0; + lastSkipSharpContext = YY_START; + specName = ¤t->name; + BEGIN ( Specialization ); + } +"<" { + sharpCount=1; + roundCount=0; + lastSkipSharpContext = YY_START; + if (insideObjC) // start of protocol list + { + unput(','); + } + else // template specialization + { + baseName += *yytext; + specName = &baseName; + BEGIN ( Specialization ); + } + } +"<" { *specName += *yytext; + if (roundCount==0) sharpCount++; + } +">" { + *specName += *yytext; + if (roundCount==0 && --sharpCount<=0) + BEGIN(lastSkipSharpContext); + } +{BN}+ { lineCount(); *specName +=' '; } +"<<" { *specName += yytext; } +">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template... + unput('>'); + unput(' '); + unput('>'); + } +">>" { + if (insideCS) // for C# >> ends a nested template + { + REJECT; + } + else // for C++ >> is a bitshift + // operator and > > would end + // a nested template. + // We require the bitshift to be enclosed in braces. + // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html + { + if (roundCount>0) + { + *specName += yytext; + } + else + { + unput('>'); + unput(' '); + unput('>'); + } + } + } +"typename"{BN}+ { lineCount(); } +"(" { *specName += *yytext; roundCount++; } +")" { *specName += *yytext; roundCount--; } +. { + *specName += *yytext; + } +"<" { ++sharpCount; } +">" { if (--sharpCount<=0) + BEGIN ( lastSkipSharpContext ); + } +"(" { ++roundCount; } +")" { if (--roundCount<=0) + BEGIN ( lastSkipRoundContext ); + } +","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount(); + if (insideProtocolList) + { + baseName+="-p"; + } + else + { + current->args += ',' ; + } + current->name = removeRedundantWhiteSpace(current->name); + if (!baseName.isEmpty()) + { + current->extends->append( + new BaseInfo(baseName,baseProt,baseVirt) + ); + } + if ((current->spec & Entry::Interface) || + insideJava || insidePHP || insideCS || + insideD || insideObjC) + { + baseProt=Public; + } + else + { + baseProt=Private; + } + baseVirt=Normal; + baseName.resize(0); + if (*yytext=='>') + { // end of a ObjC protocol list + insideProtocolList=FALSE; + if (yyleng==1) + { + unput('{'); // dummy start body + } + else + { + yyless(1); + } + } + else + { + if (*yytext==',' && insideObjC) // Begin of protocol list + { + insideProtocolList=TRUE; + } + BEGIN(BasesProt); + } + } +{B}*"{"{B}* { current->fileName = yyFileName ; + current->startLine = yyLineNr ; + current->name = removeRedundantWhiteSpace(current->name); + if (!baseName.isEmpty()) + current->extends->append( + new BaseInfo(baseName,baseProt,baseVirt) + ); + curlyCount=0; + if (insideObjC) + { + BEGIN( ReadBodyIntf ); + } + else + { + BEGIN( ReadBody ) ; + } + } +{B}*"(" { + roundCount++; + } +")" { + if (--roundCount==0) + { + BEGIN(ClassVar); + } + } +\n { yyLineNr++; } +. +{BN}+ { current->program += yytext ; + lineCount() ; + } +"/*" { current->program += yytext ; } +"//" { current->program += yytext ; } +{CMD}("code"|"verbatim") { + insideCode=TRUE; + current->program += yytext ; + } +{CMD}("endcode"|"endverbatim") { + insideCode=FALSE; + current->program += yytext ; + } +[^ \.\t\r\n\/\*]+ { current->program += yytext ; } +"*/" { current->program += yytext ; + if (!insideCode) BEGIN( lastContext ) ; + } +. { current->program += *yytext ; } + +("//"{B}*)?"/*!" { + //printf("Start doc block at %d\n",yyLineNr); + removeSlashes=(yytext[1]=='/'); + tmpDocType=-1; + if (!current->doc.isEmpty()) + { + current->doc+="\n\n"; + } + else + { + current->docLine = yyLineNr; + current->docFile = yyFileName; + } + + lastDocContext = YY_START; + if (current_root->section & Entry::SCOPE_MASK) + { + current->inside = current_root->name+"::"; + } + docBlockContext = YY_START; + docBlockInBody = YY_START==SkipCurly; + docBlockAutoBrief = Config_getBool("QT_AUTOBRIEF"); + docBlock.resize(0); + if (docBlockAutoBrief) + { + current->briefLine = yyLineNr; + current->briefFile = yyFileName; + } + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } +("//"{B}*)?"/**"/[^/*] { + removeSlashes=(yytext[1]=='/'); + lastDocContext = YY_START; + + //printf("Found comment block at %s:%d\n",yyFileName,yyLineNr); + if (current_root->section & Entry::SCOPE_MASK) + { + current->inside = current_root->name+"::"; + } + current->docLine = yyLineNr; + current->docFile = yyFileName; + docBlockContext = YY_START; + docBlockInBody = YY_START==SkipCurly; + docBlockAutoBrief = Config_getBool("JAVADOC_AUTOBRIEF"); + docBlock.resize(0); + if (docBlockAutoBrief) + { + current->briefLine = yyLineNr; + current->briefFile = yyFileName; + } + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } +"//!" { + tmpDocType=-1; + lastDocContext = YY_START; + if (current_root->section & Entry::SCOPE_MASK) + { + current->inside = current_root->name+"::"; + } + docBlockContext = YY_START; + docBlockInBody = YY_START==SkipCurly; + docBlockAutoBrief = FALSE; + docBlock.resize(0); + startCommentBlock(current->brief.isEmpty()); + BEGIN( DocLine ); + } +"///"/[^/] { + tmpDocType=-1; + lastDocContext = YY_START; + if (current_root->section & Entry::SCOPE_MASK) + { + current->inside = current_root->name+"::"; + } + docBlockContext = YY_START; + docBlockInBody = YY_START==SkipCurly; + docBlockAutoBrief = FALSE; + docBlock.resize(0); + startCommentBlock(current->brief.isEmpty()); + BEGIN( DocLine ); + } +"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? { + lineCount(); + externC=TRUE; + } +"{" { + if (externC) + { + externC=FALSE; + } + else if (insideCS && + !current->name.isEmpty() && + !current->type.isEmpty()) + { + if (containsWord(current->type,"event")) // event + { + current->mtype = mtype = Event; + } + else // property + { + current->mtype = mtype = Property; + } + current->bodyLine = yyLineNr; + curlyCount=0; + BEGIN( CSAccessorDecl ); + } + else + { + if ((insideJava || insideCS || insideD) && + current->name.isEmpty() + ) + { + // static Java initializer + needsSemi = FALSE; + if (current->stat) + { + current->name="[static initializer]"; + current->type.resize(0); + } + else + { + current->name="[instance initializer]"; + } + unput(*yytext); + BEGIN( Function ); + } + else + { + needsSemi = TRUE; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + curlyCount=0; + BEGIN( SkipCurlyBlock ); + } + } + } +"{" { curlyCount++; } +"}" { + if (curlyCount) + { + curlyCount--; + } + else + { + mtype = Method; + unput(';'); + BEGIN(FindMembers); + } + } +"set" { if (curlyCount==0) current->spec |= Entry::Settable; } +"get" { if (curlyCount==0) current->spec |= Entry::Gettable; } +"add" { if (curlyCount==0) current->spec |= Entry::Addable; } +"remove" { if (curlyCount==0) current->spec |= Entry::Removable; } +"raise" { if (curlyCount==0) current->spec |= Entry::Raisable; } +. {} +\n { yyLineNr++; } + + + + + /**********************************************************************************/ + /******************** Documentation block related rules ***************************/ + /**********************************************************************************/ + + /* ---- Single line comments ------ */ +[^\n]*"\n"[ \t]*"//"[/!] { // continuation of multiline C++-style comment + docBlock+=yytext; + docBlock.resize(docBlock.size() - 3); + yyLineNr++; + } +[^\n]*/"\n" { // whole line + docBlock+=yytext; + handleCommentBlock(docBlock,current->brief.isEmpty()); + BEGIN( docBlockContext ); + } + + /* ---- Comments blocks ------ */ + +"*"*"*/" { // end of comment block + handleCommentBlock(docBlock,FALSE); + BEGIN(docBlockContext); + } +^{B}*("//")?{B}*"*"+/[^//] { // start of a comment line + } +^{B}*("//"){B}* { // strip embedded C++ comments if at the start of a line + } +"//" { // slashes in the middle of a comment block + docBlock+=yytext; + } +"/*" { // start of a new comment in the + // middle of a comment block + docBlock+=yytext; + } +("@@"|"\\\\"){ID}/[^a-z_A-Z0-9] { // escaped command + docBlock+=yytext; + } +{CMD}("f$"|"f["|"f{") { + docBlock+=yytext; + docBlockName=&yytext[1]; + if (docBlockName.at(1)=='{') + { + docBlockName.at(1)='}'; + } + BEGIN(DocCopyBlock); + } +"<"{PRE}">" { + docBlock+=yytext; + docBlockName="
";
+  					  BEGIN(DocCopyBlock);
+  					}
+{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9]	{ // verbatim command (which could contain nested comments!)
+                                          docBlock+=yytext;
+				          docBlockName=&yytext[1];
+  					  BEGIN(DocCopyBlock);
+  					}
+{B}*""                  {
+  					  if (insideCS)
+					  {
+					    docBlock+=yytext;
+					    docBlockName="";
+					    BEGIN(DocCopyBlock);
+					  }
+					  else
+					  {
+					    REJECT;
+					  }
+  					}
+[^@*\/\\\n]+			{ // any character that isn't special
+  					  docBlock+=yytext;
+  					}
+\n				{ // newline
+  					  yyLineNr++;
+					  docBlock+=*yytext;
+  					}
+.				{ // command block
+					  docBlock+=*yytext;
+  					}
+
+ /* ---- Copy verbatim sections ------ */
+
+""		{ // end of a 
 block
+  					  docBlock+=yytext;
+					  if (docBlockName=="
")
+					  {
+  					    BEGIN(DocBlock);
+					  }
+  					}
+""		{ // end of a  block
+  					  docBlock+=yytext;
+					  if (docBlockName=="")
+					  {
+  					    BEGIN(DocBlock);
+					  }
+  					}
+[\\@]("f$"|"f]"|"f}")     {
+  					  docBlock+=yytext;
+					  BEGIN(DocBlock);
+  					}
+[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endmanonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+  					  docBlock+=yytext;
+					  if (&yytext[4]==docBlockName)
+					  {
+  					    BEGIN(DocBlock);
+					  }
+  					}
+^{B}*"*"+/{BN}+		{ // start of a comment line
+  					  if (docBlockName=="verbatim")
+					  {
+					    REJECT;
+					  }
+  					}
+[^\<@/*\]\$\\\n]+		{ // any character that is not special
+  					  docBlock+=yytext;
+  					}
+"/*"|"*/"|"//"		{
+  					  docBlock+=yytext;
+					}
+\n			{ // newline
+  					  docBlock+=*yytext;
+					  yyLineNr++;
+  					}
+.				{ // any other character
+  					  docBlock+=*yytext;
+  					}
+<>			{
+  					  warn(yyFileName,yyLineNr,
+					      "Warning: reached end of file while inside a %s block!\n"
+					      "The command that should end the block seems to be missing!\n",
+					      docBlockName.data());
+  					  yyterminate();
+  					}
+
+
+    /* ------------- Prototype parser -------------- */
+
+"operator"{B}*"("{B}*")"	{
+  					  current->name+=yytext;
+  					}
+"("			       {
+  					  current->args+=*yytext;
+					  currentArgumentContext = PrototypeQual;
+					  fullArgString = current->args.copy();
+					  copyArgString = ¤t->args;
+					  BEGIN( ReadFuncArgType ) ;
+  					}
+"("({ID}"::")*({B}*[&*])+	{
+  					  current->type+=current->name+yytext;
+					  current->name.resize(0);
+  					  BEGIN( PrototypePtr );
+  					}
+{SCOPENAME}		{
+  					  current->name+=yytext;
+  					}
+"("			{
+  					  current->args+=*yytext;
+					  currentArgumentContext = PrototypeQual;
+					  fullArgString = current->args.copy();
+					  copyArgString = ¤t->args;
+					  BEGIN( ReadFuncArgType ) ;
+  					}
+")"			{
+  					  current->type+=')';
+  					  BEGIN( Prototype );
+  					}
+.				{
+  					  current->name+=yytext;
+  					}
+"{"			{
+  					  BEGIN( PrototypeSkipLine);
+  					}
+{B}*"const"{B}*    	{ 
+  					  current->args += " const "; 
+					  current->argList->constSpecifier=TRUE;
+					}
+{B}*"volatile"{B}* 	{ 
+  					  current->args += " volatile "; 
+					  current->argList->volatileSpecifier=TRUE;
+					}
+{B}*"="{B}*"0"{B}*	{ 
+					  current->args += " = 0"; 
+					  current->virt = Pure; 
+					  current->argList->pureSpecifier=TRUE;
+					}
+"throw"{B}*"("	        {
+  					  current->exception = "throw(";
+					  BEGIN(PrototypeExc);
+  					}
+")"			{
+  					  current->exception += ')';
+					  BEGIN(PrototypeQual);
+  					}
+.			        {
+  					  current->exception += *yytext;
+  					}
+.			{
+  					  current->args += *yytext;
+  					}
+.	                        {
+  					  current->name += *yytext;
+  					}
+.			{
+  					}
+
+
+  /* ------------ Generic rules -------------- */
+
+
+.*"\\\n"		{  // line continuation
+  					  yyLineNr++; 
+  					}
+.*/\n			{ 
+					  BEGIN( lastCContext ) ;
+					}
+[^\*\n]+
+<*>\n					{ yyLineNr++ ; }
+<*>\"					{
+					  if (insideIDL && insideCppQuote)
+					  {
+					    BEGIN(EndCppQuote);
+					  }
+					}
+<*>"#"				        {	
+  					  if (!insidePHP)
+  					    REJECT;
+  					  lastCContext = YY_START ;
+					  BEGIN( SkipCxxComment ) ;
+					}
+<*>\'					{
+  					  if (insidePHP)
+					  {
+  					    lastStringContext=YY_START;
+					    BEGIN(SkipPHPString);
+					  }
+  					}
+<*>\"					{
+  					  if (insidePHP)
+					  {
+  					    lastStringContext=YY_START;
+					    BEGIN(SkipString);
+					  }
+  					}
+<*>.
+"//"|"/*"
+<*>"/*"					{ lastCContext = YY_START ;
+					  BEGIN( SkipComment ) ;
+					}
+{B}*"*/"			{ BEGIN( lastCContext ) ; }
+<*>"//"				        {	
+  					  lastCContext = YY_START ;
+					  BEGIN( SkipCxxComment ) ;
+					}
+%%
+
+//----------------------------------------------------------------------------
+
+static void startCommentBlock(bool brief)
+{
+  if (brief)
+  {
+    current->briefFile = yyFileName;
+    current->briefLine = yyLineNr;
+  }
+  else
+  {
+    current->docFile = yyFileName;
+    current->docLine = yyLineNr;
+  }
+}
+  
+//----------------------------------------------------------------------------
+
+static void newEntry()
+{
+  current_root->addSubEntry(current);
+  previous = current;
+  current = new Entry ;
+  initEntry();
+}
+
+static void handleCommentBlock(const QCString &doc,bool brief)
+{
+  static bool hideInBodyDocs = Config_getBool("HIDE_IN_BODY_DOCS");
+  int position=0;
+  bool needsEntry=FALSE;
+  if (docBlockInBody && hideInBodyDocs) return;
+  //printf("parseCommentBlock [%s]\n",doc.data());
+  int lineNr = brief ? current->briefLine : current->docLine;   // line of block start
+  while (parseCommentBlock(
+	g_thisParser,
+	docBlockInBody && previous ? previous : current,
+	doc,        // text
+	yyFileName, // file
+	lineNr,     // line of block start
+	docBlockInBody ? FALSE : brief, 
+	docBlockInBody ? FALSE : docBlockAutoBrief,
+	docBlockInBody,
+	protection,
+        position,
+        needsEntry
+        )
+     ) 
+  {
+    //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
+    if (needsEntry) newEntry();
+  }
+  if (needsEntry)
+  {
+    newEntry();
+  }
+
+  if (docBlockTerm)
+  {
+    unput(docBlockTerm);
+    docBlockTerm=0;
+  }
+}
+
+static void handleParametersCommentBlocks(ArgumentList *al)
+{
+  //printf(">>>>>>> handleParametersCommentBlocks()\n");
+  ArgumentListIterator ali(*al);
+  Argument *a;
+  for (ali.toFirst();(a=ali.current());++ali)
+  {
+    //printf("    Param %s docs=%s\n",a->name.data(),a->docs.data());
+    if (!a->docs.isEmpty())
+    {
+      int position=0;
+      bool needsEntry;
+
+      // save context
+      QCString orgDoc   = current->doc;
+      QCString orgBrief = current->brief;
+      int orgDocLine    = current->docLine;
+      int orgBriefLine  = current->briefLine;
+
+      current->doc.resize(0);
+      current->brief.resize(0);
+
+      //printf("handleParametersCommentBlock [%s]\n",doc.data());
+      while (parseCommentBlock(
+	     g_thisParser,
+	     current,
+	     a->docs,            // text
+	     yyFileName,         // file
+	     current->docLine,   // line of block start
+	     FALSE, 
+	     FALSE,
+	     FALSE,
+	     protection,
+	     position,
+	     needsEntry
+	    )
+	  ) 
+      {
+	//printf("handleParametersCommentBlock position=%d [%s]\n",position,doc.data()+position);
+	if (needsEntry) newEntry();
+      }
+      if (needsEntry)
+      {
+	newEntry();
+      }
+      a->docs = current->doc;
+
+      // restore context
+      current->doc       = orgDoc;
+      current->brief     = orgBrief;
+      current->docLine   = orgDocLine;
+      current->briefLine = orgBriefLine;
+    }
+  }
+}
+
+
+//----------------------------------------------------------------------------
+
+static void parseCompounds(Entry *rt)
+{
+  //printf("parseCompounds(%s)\n",rt->name.data());
+  g_inputFromFile = FALSE;
+  EntryListIterator eli(*rt->children());
+  Entry *ce;
+  for (;(ce=eli.current());++eli)
+  {
+    if (!ce->program.isEmpty())
+    {
+      //printf("-- %s ---------\n%s\n---------------\n",
+      //  ce->name.data(),ce->program.data());
+      // init scanner state
+      padCount=0;
+      depthIf = 0;
+      inputString = ce->program;
+      inputPosition = 0;
+      scanYYrestart( scanYYin ) ;
+      if (ce->section==Entry::ENUM_SEC)
+	BEGIN( FindFields ) ;
+      else
+	BEGIN( FindMembers ) ;
+      current_root = ce ;
+      yyFileName = ce->fileName;
+      //setContext();
+      yyLineNr = ce->startLine ;
+      insideObjC = ce->objc;
+      //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC);
+      //current->reset();
+      if (current) delete current;
+      current = new Entry;
+      gstat = FALSE;
+      int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
+      // set default protection based on the compound type
+      if( ce->section==Entry::CLASS_SEC ) // class
+      {
+
+        if (insidePHP || insideD || insideJS)
+	{
+          current->protection = protection = Public ; 
+	}
+	else if (insideJava)
+	{
+          current->protection = protection = Package ; 
+	}
+	else if (ce->spec&(Entry::Interface | Entry::Ref | Entry::Value | Entry::Struct | Entry::Union))
+	{
+	  if (ce->objc)
+	  {
+	    current->protection = protection = Protected ;
+	  }
+	  else
+	  {
+	    current->protection = protection = Public ;
+	  }
+	}
+	else 
+	{
+          current->protection = protection = Private ;
+	}
+      }
+      else if (ce->section == Entry::ENUM_SEC ) // enum
+      {
+	current->protection = protection = ce->protection;
+      }
+      else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
+      {
+	if (ce->section == Entry::NAMESPACE_SEC ) // unnamed namespace
+	{
+          current->stat = gstat = TRUE;
+	}
+	current->protection = protection = ce->protection;
+      }
+      else // named struct, union, protocol, category
+      {
+	current->protection = protection = Public ;
+      }
+      mtype = Method;
+      virt = Normal;
+      //printf("name=%s current->stat=%d gstat=%d\n",ce->name.data(),current->stat,gstat);
+
+      //memberGroupId = DOX_NOGROUP;
+      //memberGroupRelates.resize(0);
+      //memberGroupInside.resize(0);
+      groupEnterCompound(yyFileName,yyLineNr,ce->name);
+      
+      scanYYlex() ;
+      g_lexInit=TRUE;
+      //forceEndGroup();
+
+      groupLeaveCompound(yyFileName,yyLineNr,ce->name);
+      
+      delete current; current=0;
+      ce->program.resize(0);
+
+
+      if (depthIf>0)
+      {
+	warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+      }
+    }
+    parseCompounds(ce);
+  }
+}
+
+//----------------------------------------------------------------------------
+
+static void parseMain(const char *fileName,const char *fileBuf,Entry *rt)
+{
+  initParser();
+  //g_inputFromFile = TRUE;
+
+  inputString = fileBuf;
+  inputPosition = 0;
+  g_inputFromFile = FALSE;
+
+  //anonCount     = 0;  // don't reset per file
+  depthIf       = 0;
+  protection    = Public;
+  mtype         = Method;
+  gstat         = FALSE;
+  virt          = Normal;
+  current_root  = rt;
+  global_root   = rt;
+  inputFile.setName(fileName);
+  if (inputFile.open(IO_ReadOnly))
+  {
+    yyLineNr= 1 ; 
+    yyFileName = fileName;
+    setContext();
+    msg("Parsing file %s...\n",yyFileName.data());
+
+    current_root  = rt ;
+    initParser();
+    groupEnterFile(yyFileName,yyLineNr);
+    current       = new Entry;
+    //printf("current=%p current_root=%p\n",current,current_root);
+    int sec=guessSection(yyFileName);
+    if (sec)
+    {
+      current->name    = yyFileName;
+      current->section = sec;
+      current_root->addSubEntry(current);
+      current          = new Entry;
+    }
+    current->reset();
+    scanYYrestart( scanYYin );
+    if ( insidePHP )
+    {
+      BEGIN( FindMembersPHP );
+    }
+    else
+    {
+      BEGIN( FindMembers );
+    }
+
+    scanYYlex();
+    g_lexInit=TRUE;
+
+    if (YY_START==Comment)
+    {
+      warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
+    }
+
+    //forceEndGroup();
+    groupLeaveFile(yyFileName,yyLineNr);
+
+    if (depthIf>0)
+    {
+      warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+    }
+
+    rt->program.resize(0);
+    delete current; current=0;
+
+    parseCompounds(rt);
+
+    inputFile.close();
+
+    anonNSCount++;
+  }
+}
+
+//----------------------------------------------------------------------------
+
+static void parsePrototype(const QCString &text)
+{
+  //printf("**** parsePrototype(%s) begin\n",text.data());
+  if (text.isEmpty()) 
+  {
+    warn(yyFileName,yyLineNr,"Empty prototype found!");
+    return;
+  }
+
+  const char *orgInputString;
+  int orgInputPosition;
+  YY_BUFFER_STATE orgState;
+  bool orgInputFromFile;
+  
+  // save scanner state
+  orgState = YY_CURRENT_BUFFER;
+  yy_switch_to_buffer(yy_create_buffer(scanYYin, YY_BUF_SIZE));
+  orgInputString = inputString; 
+  orgInputPosition = inputPosition;
+  orgInputFromFile = g_inputFromFile;
+
+  // set new string
+  inputString = text;
+  inputPosition = 0;
+  g_inputFromFile = FALSE;
+  scanYYrestart( scanYYin );
+  BEGIN(Prototype);
+  scanYYlex();
+  g_lexInit=TRUE;
+
+  current->name = current->name.stripWhiteSpace();
+  if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty())
+    current->section = Entry::VARIABLEDOC_SEC;
+
+  // restore original scanner state
+  YY_BUFFER_STATE tmpState = YY_CURRENT_BUFFER;
+  yy_switch_to_buffer(orgState);
+  yy_delete_buffer(tmpState);
+  inputString = orgInputString; 
+  inputPosition = orgInputPosition;
+  g_inputFromFile = orgInputFromFile;
+
+  //printf("**** parsePrototype end\n");
+}
+
+void scanFreeScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+  if (g_lexInit)
+  {
+    scanYYlex_destroy();
+  }
+#endif
+}
+
+//static void handleGroupStartCommand(const char *header)
+//{
+//  memberGroupHeader=header;
+//  startGroupInDoc();
+//}
+//
+//static void handleGroupEndCommand()
+//{
+//  endGroup();
+//  previous=0;
+//}
+
+//----------------------------------------------------------------------------
+
+void CLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root)
+{
+  g_thisParser = this;
+  ::parseMain(fileName,fileBuf,root);
+}
+
+void CLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
+                   const char * scopeName,
+                   const QCString & input,
+                   bool isExampleBlock,
+                   const char * exampleName,
+                   FileDef * fileDef,
+                   int startLine,
+                   int endLine,
+                   bool inlineFragment,
+		   MemberDef *memberDef
+                  )
+{
+  ::parseCCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,
+               fileDef,startLine,endLine,inlineFragment,memberDef);
+}
+
+bool CLanguageScanner::needsPreprocessing(const QCString &extension)
+{
+  QCString fe=extension.lower();
+  return 
+   !( fe==".java" || fe==".as"  || fe==".d"    || fe==".php" || 
+      fe==".php4" || fe==".inc" || fe==".phtml" 
+    );
+}
+
+void CLanguageScanner::resetCodeParserState()
+{
+  ::resetCCodeParserState();
+}
+
+void CLanguageScanner::parsePrototype(const char *text)
+{
+  ::parsePrototype(text);
+}
+
+//----------------------------------------------------------------------------
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION) 
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+  void scannerYYdummy() { yy_flex_realloc(0,0); } 
+}
+#endif
+