1 /*****************************************************************************
5 * Copyright (C) 1997-2014 by Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
42 #include "commentscan.h"
44 #include "arguments.h"
46 #include "clangparser.h"
48 #define YY_NEVER_INTERACTIVE 1
51 /* -----------------------------------------------------------------
55 static ParserInterface *g_thisParser;
56 static const char * inputString;
57 static int inputPosition;
58 static QFile inputFile;
59 static int lastContext;
60 static int lastCContext;
61 static int lastDocContext;
62 static int lastCPPContext;
63 static int lastSkipSharpContext;
64 static int lastSkipRoundContext;
65 static int lastStringContext;
66 static int lastCurlyContext;
67 static int lastRoundContext;
68 static int lastSquareContext;
69 static int lastInitializerContext;
70 static int lastClassTemplSpecContext;
71 static int lastPreLineCtrlContext;
72 static int lastSkipVerbStringContext;
73 static int lastCommentInArgContext;
74 static int lastRawStringContext;
75 static int lastCSConstraint;
76 static int lastHereDocContext;
77 static int lastDefineContext;
78 static int lastAlignAsContext;
79 static Protection protection;
80 static Protection baseProt;
81 static int sharpCount = 0 ;
82 static int roundCount = 0 ;
83 static int curlyCount = 0 ;
84 static int squareCount = 0 ;
85 static int padCount = 0 ;
86 static QCString slString;
87 static Entry* current_root = 0 ;
88 static Entry* global_root = 0 ;
89 static Entry* current = 0 ;
90 static Entry* previous = 0 ;
91 static Entry* tempEntry = 0 ;
92 static Entry* firstTypedefEntry = 0 ;
93 static Entry* memspecEntry = 0 ;
94 static int yyLineNr = 1 ;
95 static int yyBegLineNr = yyLineNr ;
96 static int yyColNr = 1 ;
97 static int yyBegColNr = yyColNr ;
98 static int anonCount = 0 ;
99 static int anonNSCount = 0 ;
100 static QCString yyFileName;
101 static MethodTypes mtype;
103 static bool removeSlashes;
104 static Specifier virt;
105 static Specifier baseVirt;
106 static QCString msType,msName,msArgs;
107 static bool isTypedef;
108 static int tmpDocType;
109 static QCString sectionLabel;
110 static QCString sectionTitle;
111 static QCString funcPtrType;
112 static QCString templateStr;
113 static QCString aliasName;
114 static QCString baseName;
115 static QCString* specName;
116 static QCString formulaText;
117 static QCString formulaEnd;
118 static bool useOverrideCommands = FALSE;
120 static SrcLangExt language;
121 static bool insideIDL = FALSE; //!< processing IDL code?
122 static bool insideJava = FALSE; //!< processing Java code?
123 static bool insideCS = FALSE; //!< processing C# code?
124 static bool insideD = FALSE; //!< processing D code?
125 static bool insidePHP = FALSE; //!< processing PHP code?
126 static bool insideObjC = FALSE; //!< processing Objective C code?
127 static bool insideCli = FALSE; //!< processing C++/CLI code?
128 static bool insideJS = FALSE; //!< processing JavaScript code?
129 static bool insideCpp = TRUE; //!< processing C/C++ code
131 static bool insideCppQuote = FALSE;
132 static bool insideProtocolList = FALSE;
134 static int argRoundCount;
135 static int argSharpCount;
136 static int currentArgumentContext;
137 static int lastCopyArgStringContext;
138 static int lastCopyArgContext;
139 static QCString *copyArgString;
140 static QCString fullArgString;
142 static ArgumentList *currentArgumentList;
143 static char lastCopyArgChar;
145 static QCString *pCopyQuotedString;
146 static QCString *pCopyRoundString;
147 static QCString *pCopyCurlyString;
148 static QCString *pCopyRawString;
150 static QGString *pCopyCurlyGString;
151 static QGString *pCopyRoundGString;
152 static QGString *pCopyQuotedGString;
153 static QGString *pCopyHereDocGString;
154 static QGString *pCopyRawGString;
155 static QGString *pSkipVerbString;
156 static QStack<Grouping> autoGroupStack;
158 static bool insideFormula;
159 static bool insideTryBlock=FALSE;
160 static bool insideCode;
161 static bool needsSemi;
163 //static int depthIf;
164 static int initBracketCount;
165 static QCString memberGroupRelates;
166 static QCString memberGroupInside;
167 static QCString xrefItemKey;
168 static QCString xrefItemTitle;
169 static QCString xrefListTitle;
171 static QCString g_skipBlockName;
172 static QCString oldStyleArgType;
173 static QCString docBackup;
174 static QCString briefBackup;
176 static int docBlockContext;
177 static QGString docBlock;
178 static QCString docBlockName;
179 static bool docBlockInBody;
180 static bool docBlockAutoBrief;
181 static char docBlockTerm;
183 static QCString idlAttr;
184 static QCString idlProp;
186 static bool g_lexInit = FALSE;
189 static QCString g_delimiter;
193 static int g_fencedSize=0;
194 static bool g_nestedComment=0;
196 //-----------------------------------------------------------------------------
198 // forward declarations
199 //static void handleGroupStartCommand(const char *header);
200 //static void handleGroupEndCommand();
202 //-----------------------------------------------------------------------------
204 static void initParser()
206 sectionLabel.resize(0);
207 sectionTitle.resize(0);
209 formulaText.resize(0);
220 autoGroupStack.clear();
221 insideTryBlock = FALSE;
222 autoGroupStack.setAutoDelete(TRUE);
223 insideFormula = FALSE;
225 insideCli=Config_getBool("CPP_CLI_SUPPORT");
227 firstTypedefEntry = 0;
232 static void initEntry()
236 protection = (current_root->spec & (Entry::Interface|Entry::Enum)) ? Public : Package;
238 current->protection = protection ;
239 current->mtype = mtype;
240 current->virt = virt;
241 current->stat = gstat;
242 current->lang = language;
243 //printf("*** initEntry() language=%d\n",language);
244 //if (!autoGroupStack.isEmpty())
246 // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data());
247 // current->groups->append(new Grouping(*autoGroupStack.top()));
249 initGroupInfo(current);
254 //-----------------------------------------------------------------------------
256 ///// remove any automatic grouping and add new one (if given)
257 //static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri )
259 // /* remove auto group name from current entry and discard it */
260 // Grouping *g = current->groups->first();
264 // if (g->pri <= Grouping::GROUPING_AUTO_DEF)
266 // current->groups->remove(i);
269 // g=current->groups->next();
273 // /* use new group name instead? */
276 // current->groups->append(new Grouping(*newgroup, pri));
280 //static int newMemberGroupId()
282 // static int curGroupId=0;
283 // return curGroupId++;
286 // forward declarations
287 //static void startGroupInDoc();
288 //static void endGroup();
290 //-----------------------------------------------------------------------------
292 static void lineCount()
294 static int tabSize = Config_getInt("TAB_SIZE");
296 for (p = yytext ; *p ; ++p )
300 yyLineNr++,g_column=0,yyColNr=1;
304 g_column+=tabSize - (g_column%tabSize);
308 g_column++,yyColNr++;
311 //printf("lineCount()=%d\n",g_column);
314 static inline int computeIndent(const char *s,int startIndent)
317 static int tabSize=Config_getInt("TAB_SIZE");
322 if (c=='\t') col+=tabSize-(col%tabSize);
323 else if (c=='\n') col=0;
329 static void addType( Entry* current )
331 uint tl=current->type.length();
332 if( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.')
334 current->type += ' ' ;
336 current->type += current->name ;
337 current->name.resize(0) ;
338 tl=current->type.length();
339 if( tl>0 && !current->args.isEmpty() && current->type.at(tl-1)!='.')
341 current->type += ' ' ;
343 current->type += current->args ;
344 current->args.resize(0) ;
345 current->argList->clear();
349 static QCString stripQuotes(const char *s)
352 if (s==0 || *s==0) return name;
354 if (name.at(0)=='"' && name.at(name.length()-1)=='"')
356 name=name.mid(1,name.length()-2);
361 //-----------------------------------------------------------------
363 static void startCommentBlock(bool);
364 static void handleCommentBlock(const QCString &doc,bool brief);
365 static void handleParametersCommentBlocks(ArgumentList *al);
367 //-----------------------------------------------------------------
369 static bool nameIsOperator(QCString &name)
371 int i=name.find("operator");
372 if (i==-1) return FALSE;
373 if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X
374 if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator
375 return FALSE; // case TEXToperatorTEXT
378 //-----------------------------------------------------------------------------
380 static void setContext()
382 QCString fileName = yyFileName;
383 language = getLanguageFromFileName(fileName);
384 insideIDL = language==SrcLangExt_IDL;
385 insideJava = language==SrcLangExt_Java;
386 insideCS = language==SrcLangExt_CSharp;
387 insideD = language==SrcLangExt_D;
388 insidePHP = language==SrcLangExt_PHP;
389 insideObjC = language==SrcLangExt_ObjC;
390 insideJS = language==SrcLangExt_JS;
391 insideCpp = language==SrcLangExt_Cpp;
394 useOverrideCommands = TRUE;
396 //printf("setContext(%s) insideIDL=%d insideJava=%d insideCS=%d "
397 // "insideD=%d insidePHP=%d insideObjC=%d\n",
398 // yyFileName.data(),insideIDL,insideJava,insideCS,insideD,insidePHP,insideObjC
402 //-----------------------------------------------------------------------------
404 static void prependScope()
406 if (current_root->section & Entry::SCOPE_MASK)
408 //printf("--- prependScope %s to %s\n",current_root->name.data(),current->name.data());
409 current->name.prepend(current_root->name+"::");
410 if (current_root->tArgLists)
412 if (current->tArgLists==0)
414 current->tArgLists = new QList<ArgumentList>;
415 current->tArgLists->setAutoDelete(TRUE);
417 //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count());
418 QListIterator<ArgumentList> talsi(*current_root->tArgLists);
419 ArgumentList *srcAl=0;
420 for (talsi.toLast();(srcAl=talsi.current());--talsi)
422 ArgumentList *dstAl = new ArgumentList;
423 QListIterator<Argument> tali(*srcAl);
425 for (;(a=tali.current());++tali)
427 dstAl->append(new Argument(*a));
428 //printf("appending argument %s %s\n",a->type.data(),a->name.data());
430 current->tArgLists->insert(0,dstAl);
436 //-----------------------------------------------------------------------------
438 /*! Returns TRUE iff the current entry could be a K&R style C function */
439 static bool checkForKnRstyleC()
441 if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file
442 if (!current->argList) return FALSE; // must have arguments
443 ArgumentListIterator ali(*current->argList);
445 for (ali.toFirst();(a=ali.current());++ali)
447 // in K&R style argument do not have a type, but doxygen expects a type
448 // so it will think the argument has no name
449 if (a->type.isEmpty() || !a->name.isEmpty()) return FALSE;
454 //-----------------------------------------------------------------------------
456 static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName)
458 int si = current->args.length();
459 if (oldStyleArgType.isEmpty()) // new argument
461 static QRegExp re("([^)]*)");
462 int bi1 = current->args.findRev(re);
463 int bi2 = bi1!=-1 ? current->args.findRev(re,bi1-1) : -1;
465 if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
468 oldStyleArgType = current->args.left(s);
470 while (i<si && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i++;
471 oldStyleArgType += current->args.mid(s,i-s);
473 while (i<si && isId(current->args.at(i))) i++;
474 oldStyleArgName = current->args.mid(s,i-s);
475 oldStyleArgType+=current->args.mid(i);
477 else if (bi1!=-1) // redundant braces like in "int (*var)"
480 oldStyleArgType = current->args.left(s);
483 while (i<si && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i++;
484 oldStyleArgType += current->args.mid(s,i-s);
486 while (i<si && isId(current->args.at(i))) i++;
487 oldStyleArgName = current->args.mid(s,i-s);
489 else // normal "int *var"
493 // look for start of name in "type *name"
494 while (i>=0 && isId(current->args.at(i))) i--;
496 // look for start of *'s
497 while (i>=0 && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i--;
501 oldStyleArgType=current->args.left(i);
502 oldStyleArgPtr=current->args.mid(i,j-i);
503 oldStyleArgName=current->args.mid(j).stripWhiteSpace();
507 oldStyleArgName=current->args.copy().stripWhiteSpace();
511 else // continuation like *arg2 in "int *args,*arg2"
515 while (j<l && ((c=current->args.at(j))=='*' || isspace((uchar)c))) j++;
518 oldStyleArgPtr=current->args.left(j);
519 oldStyleArgName=current->args.mid(j).stripWhiteSpace();
523 oldStyleArgName=current->args.copy().stripWhiteSpace();
528 //-----------------------------------------------------------------------------
530 /*! Update the argument \a name with additional \a type info. For K&R style
531 * function the type is found \e after the argument list, so this routine
532 * in needed to fix up.
534 static void addKnRArgInfo(const QCString &type,const QCString &name,
535 const QCString &brief,const QCString &docs)
537 if (current->argList==0) return;
538 ArgumentListIterator ali(*current->argList);
540 for (ali.toFirst();(a=ali.current());++ali)
544 a->type=type.stripWhiteSpace();
545 if (a->type.left(9)=="register ") // strip keyword
547 a->type=a->type.mid(9);
549 a->name=name.stripWhiteSpace();
550 if (!brief.isEmpty() && !docs.isEmpty())
552 a->docs=brief+"\n\n"+docs;
554 else if (!brief.isEmpty())
566 //-----------------------------------------------------------------------------
569 void fixArgumentListForJavaScript(ArgumentList *al)
572 ArgumentListIterator ali(*al);
574 for (ali.toFirst();(a=ali.current());++ali)
576 if (!a->type.isEmpty() && a->name.isEmpty())
577 { // a->type is actually the (typeless) parameter name, so move it
584 /* ----------------------------------------------------------------- */
586 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
588 static int yyread(char *buf,int max_size)
591 while( c < max_size && inputString[inputPosition] )
593 *buf = inputString[inputPosition++] ;
594 //printf("%d (%c)\n",*buf,*buf);
602 /* start command character */
604 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"|"docbookonly"|"manonly"|"{"|"verbatim"|"dotfile"|"dot"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"details"|"typedef"|"def"|"overload")|("<"{PRE}">")
608 BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
609 ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
610 SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
611 SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID})
612 PHPSCOPENAME ({ID}"\\")+{ID}
613 TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,:]*">")?
614 CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
616 CODE [cC][oO][dD][eE]
617 CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
618 PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
619 IDLATTR ("["[^\]]*"]"){BN}*
620 TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
621 RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
622 RAWEND ")"[^ \t\(\)\\]{0,16}\"
623 ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
624 ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
625 LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
626 BITOP "&"|"|"|"^"|"<<"|">>"|"~"
627 OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
631 /* language parsing states */
692 %x TryFunctionBlockEnd
718 %x UNOIDLAttributeBlock
753 %x CopyArgCommentLine
766 /** Prototype scanner states */
774 /** comment parsing states */
785 BEGIN(SkipCurlyBlock);
789 BEGIN(SkipRoundBlock);
791 <SkipRoundBlock>"(" {
794 <SkipRoundBlock>")" {
800 <SkipCurlyBlock>"{" {
803 <SkipCurlyBlock>"}" {
814 BEGIN( FindMembers );
820 lastStringContext=NextSemi;
821 BEGIN(SkipPHPString);
824 <NextSemi>{CHARLIT} { if (insidePHP) REJECT; }
826 lastStringContext=NextSemi;
831 BEGIN( FindMembers );
835 BEGIN( FindMembers );
837 <EnumBaseType>[{;,] {
838 current->args = current->args.simplifyWhiteSpace();
842 <FindMembers>"<?php" { // PHP code with unsupported extension?
845 <FindMembersPHP>"<?"("php"?) { // PHP code start
846 BEGIN( FindMembers );
848 <FindMembersPHP>"<script"{BN}+"language"{BN}*"="{BN}*['"]?"php"['"]?{BN}*">" { // PHP code start
850 BEGIN( FindMembers );
852 <FindMembersPHP>[^\n<]+ { // Non-PHP code text, ignore
854 <FindMembersPHP>\n { // Non-PHP code text, ignore
857 <FindMembersPHP>. { // Non-PHP code text, ignore
859 <FindMembers>"?>"|"</script>" { // PHP code end
861 BEGIN( FindMembersPHP );
865 <FindMembers>{PHPKW} { if (insidePHP)
870 <FindMembers>"%{"[^\n]* { // Mozilla XPIDL lang-specific block
874 <FindMembers>"%}" { // Mozilla XPIDL lang-specific block end
878 <FindMembers>{B}*("properties"){BN}*":"{BN}* { // IDL or Borland C++ builder property
879 current->mtype = mtype = Property;
880 current->protection = protection = Public ;
881 current->type.resize(0);
882 current->name.resize(0);
883 current->args.resize(0);
884 current->argList->clear();
888 <FindMembers>{B}*"k_dcop"{BN}*":"{BN}* { current->mtype = mtype = DCOP;
889 current->protection = protection = Public ;
890 current->type.resize(0);
891 current->name.resize(0);
892 current->args.resize(0);
893 current->argList->clear();
897 <FindMembers>{B}*("signals"|"Q_SIGNALS"){BN}*":"{BN}* { current->mtype = mtype = Signal;
899 current->protection = protection = Public ;
900 current->type.resize(0);
901 current->name.resize(0);
902 current->args.resize(0);
903 current->argList->clear();
907 <FindMembers>{B}*"public"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
908 current->protection = protection = Public ;
909 current->mtype = mtype = Slot;
910 current->type.resize(0);
911 current->name.resize(0);
912 current->args.resize(0);
913 current->argList->clear();
917 <FindMembers>{B}*"protected"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
918 current->protection = protection = Protected ;
919 current->mtype = mtype = Slot;
920 current->type.resize(0);
921 current->name.resize(0);
922 current->args.resize(0);
923 current->argList->clear();
927 <FindMembers>{B}*"private"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
928 current->protection = protection = Private ;
929 current->mtype = mtype = Slot;
930 current->type.resize(0);
931 current->name.resize(0);
932 current->args.resize(0);
933 current->argList->clear();
936 <FindMembers>{B}*("public"|"methods"|"__published"){BN}*":"{BN}* {
937 current->protection = protection = Public ;
938 current->mtype = mtype = Method;
939 current->type.resize(0);
940 current->name.resize(0);
941 current->args.resize(0);
942 current->argList->clear();
945 <FindMembers>{B}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package...
948 current->protection = protection = Package ;
949 current->mtype = mtype = Method;
950 current->type.resize(0);
951 current->name.resize(0);
952 current->args.resize(0);
953 current->argList->clear();
961 <FindMembers>{B}*"protected"{BN}*":"{BN}* {
962 current->protection = protection = Protected ;
963 current->mtype = mtype = Method;
964 current->type.resize(0);
965 current->name.resize(0);
966 current->args.resize(0);
967 current->argList->clear();
970 <FindMembers>{B}*"private"{BN}*":"{BN}* {
971 current->protection = protection = Private ;
972 current->mtype = mtype = Method;
973 current->type.resize(0);
974 current->name.resize(0);
975 current->args.resize(0);
976 current->argList->clear();
979 <FindMembers>{B}*"event"{BN}+ {
984 current->mtype = mtype = Event;
985 current->bodyLine = yyLineNr;
987 BEGIN( CliPropertyType );
992 current->mtype = Event;
993 current->bodyLine = yyLineNr;
1000 <FindMembers>{B}*"property"{BN}+ {
1005 current->mtype = mtype = Property;
1006 current->bodyLine = yyLineNr;
1008 BEGIN( CliPropertyType );
1015 <CliPropertyType>{ID} {
1017 current->name = yytext;
1019 <CliPropertyType>"[" { // C++/CLI indexed property
1020 current->name += yytext;
1021 BEGIN( CliPropertyIndex );
1023 <CliPropertyType>"{" {
1025 //printf("event: '%s' '%s'\n",current->type.data(),current->name.data());
1026 BEGIN( CSAccessorDecl );
1028 <CliPropertyType>";" {
1030 BEGIN( FindMembers );
1032 <CliPropertyType>\n {
1035 <CliPropertyType>{B}* {
1037 <CliPropertyType>. {
1039 current->type += yytext;
1041 <CliPropertyIndex>"]" {
1042 BEGIN( CliPropertyType );
1043 current->name+=yytext;
1045 <CliPropertyIndex>. {
1046 current->name+=yytext;
1049 <FindMembers>{B}*"property"{BN}+ {
1050 if (!current->type.isEmpty())
1056 current->mtype = mtype = Property;
1061 <FindMembers>{B}*"@private"{BN}+ {
1062 current->protection = protection = Private ;
1063 current->mtype = mtype = Method;
1064 current->type.resize(0);
1065 current->name.resize(0);
1066 current->args.resize(0);
1067 current->argList->clear();
1070 <FindMembers>{B}*"@protected"{BN}+ {
1071 current->protection = protection = Protected ;
1072 current->mtype = mtype = Method;
1073 current->type.resize(0);
1074 current->name.resize(0);
1075 current->args.resize(0);
1076 current->argList->clear();
1079 <FindMembers>{B}*"@public"{BN}+ {
1080 current->protection = protection = Public ;
1081 current->mtype = mtype = Method;
1082 current->type.resize(0);
1083 current->name.resize(0);
1084 current->args.resize(0);
1085 current->argList->clear();
1088 <FindMembers>[\-+]{BN}* {
1096 current->fileName = yyFileName;
1097 current->startLine = yyLineNr;
1098 current->startColumn = yyColNr;
1099 current->bodyLine = yyLineNr;
1100 current->section = Entry::FUNCTION_SEC;
1101 current->protection = protection = Public ;
1102 language = current->lang = SrcLangExt_ObjC;
1104 current->virt = Virtual;
1105 current->stat=yytext[0]=='+';
1106 current->mtype = mtype = Method;
1107 current->type.resize(0);
1108 current->name.resize(0);
1109 current->args.resize(0);
1110 current->argList->clear();
1111 BEGIN( ObjCMethod );
1114 <ObjCMethod>"(" { // start of method's return type
1115 BEGIN( ObjCReturnType );
1117 <ObjCMethod>{ID} { // found method name
1118 if (current->type.isEmpty())
1120 current->type = "id";
1122 current->name = yytext;
1123 if (insideCpp || insideObjC)
1125 current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
1128 <ObjCMethod>":"{B}* { // start of parameter list
1129 current->name += ':';
1130 Argument *a = new Argument;
1131 current->argList->append(a);
1132 BEGIN( ObjCParams );
1134 <ObjCReturnType>[^)]* { // TODO: check if nested braches are possible.
1135 current->type = yytext;
1137 <ObjCReturnType>")" {
1138 BEGIN( ObjCMethod );
1140 <ObjCParams>({ID})?":" { // Keyword of parameter
1141 QCString keyw = yytext;
1142 keyw=keyw.left(keyw.length()-1); // strip :
1145 current->name += " :";
1149 current->name += keyw+":";
1151 if (current->argList->getLast()->type.isEmpty())
1153 current->argList->getLast()->type="id";
1155 Argument *a = new Argument;
1156 a->attrib=(QCString)"["+keyw+"]";
1157 current->argList->append(a);
1159 <ObjCParams>{ID}{BN}* { // name of parameter
1161 current->argList->getLast()->name=QCString(yytext).stripWhiteSpace();
1163 <ObjCParams>","{BN}*"..." { // name of parameter
1165 // do we want the comma as part of the name?
1166 //current->name += ",";
1167 Argument *a = new Argument;
1170 current->argList->append(a);
1174 current->name += ':';
1179 current->argList->getLast()->type.resize(0);
1180 BEGIN( ObjCParamType );
1182 <ObjCParamType>"(" {
1184 current->argList->getLast()->type+=yytext;
1186 <ObjCParamType>")"/{B}* {
1189 BEGIN( ObjCParams );
1193 current->argList->getLast()->type+=yytext;
1197 <ObjCParamType>[^()]* {
1198 current->argList->getLast()->type+=QCString(yytext).stripWhiteSpace();
1200 <ObjCMethod,ObjCParams>";" { // end of method declaration
1201 if (current->argList->getLast() && current->argList->getLast()->type.isEmpty())
1203 current->argList->getLast()->type="id";
1205 current->args = argListToString(current->argList);
1206 //printf("argList=%s\n",current->args.data());
1210 <ObjCMethod,ObjCParams>(";"{BN}+)?"{" { // start of a method body
1212 //printf("Type=%s Name=%s args=%s\n",
1213 // current->type.data(),current->name.data(),argListToString(current->argList).data()
1215 if (current->argList->getLast() && current->argList->getLast()->type.isEmpty())
1217 current->argList->getLast()->type="id";
1219 current->args = argListToString(current->argList);
1223 <FindMembers>{BN}{1,80} {
1226 <FindMembers>"@"({ID}".")*{ID}{BN}*"(" {
1227 if (insideJava) // Java annotation
1230 lastSkipRoundContext = YY_START;
1234 else if (qstrncmp(yytext,"@property",9)==0) // ObjC 2.0 property
1236 current->mtype = mtype = Property;
1237 current->spec|=Entry::Readable | Entry::Writable | Entry::Assign;
1238 current->protection = Public ;
1240 BEGIN( ObjCPropAttr );
1247 <ObjCPropAttr>"getter="{ID} {
1248 current->read = yytext+7;
1250 <ObjCPropAttr>"setter="{ID} {
1251 current->write = yytext+7;
1253 <ObjCPropAttr>"readonly" {
1254 current->spec&=~Entry::Writable;
1256 <ObjCPropAttr>"readwrite" { // default
1258 <ObjCPropAttr>"assign" { // default
1260 <ObjCPropAttr>"unsafe_unretained" {
1261 current->spec&=~Entry::Assign;
1262 current->spec|=Entry::Unretained;
1264 <ObjCPropAttr>"retain" {
1265 current->spec&=~Entry::Assign;
1266 current->spec|=Entry::Retain;
1268 <ObjCPropAttr>"copy" {
1269 current->spec&=~Entry::Assign;
1270 current->spec|=Entry::Copy;
1272 <ObjCPropAttr>"weak" {
1273 current->spec&=~Entry::Assign;
1274 current->spec|=Entry::Weak;
1276 <ObjCPropAttr>"strong" {
1277 current->spec&=~Entry::Assign;
1278 current->spec|=Entry::Strong;
1280 <ObjCPropAttr>"nonatomic" {
1281 current->spec|=Entry::NonAtomic;
1286 <FindMembers>"@"{ID} {
1287 if (insideJava) // Java annotation
1291 else if (qstrcmp(yytext,"@property")==0) // ObjC 2.0 property
1293 current->mtype = mtype = Property;
1294 current->spec|=Entry::Writable | Entry::Readable;
1295 current->protection = Public ;
1297 else if (qstrcmp(yytext,"@synthesize")==0)
1299 BEGIN( ObjCSkipStatement );
1301 else if (qstrcmp(yytext,"@dynamic")==0)
1303 BEGIN( ObjCSkipStatement );
1310 <ObjCSkipStatement>";" {
1313 <PackageName>{ID}(("."|"\\"){ID})* {
1315 //printf("Found namespace %s lang=%d\n",yytext,current->lang);
1316 current->name = yytext;
1317 current->name = substitute(current->name,".","::");
1318 current->name = substitute(current->name,"\\","::");
1319 current->section = Entry::NAMESPACE_SEC;
1320 current->type = "namespace" ;
1321 current->fileName = yyFileName;
1322 current->startLine = yyLineNr;
1323 current->startColumn = yyColNr;
1324 current->bodyLine = yyLineNr;
1328 current_root->addSubEntry(current);
1329 current_root = current ;
1330 current = new Entry ;
1336 BEGIN( ReadNSBody );
1338 <FindMembers>{B}*"initonly"{BN}+ {
1339 current->type += " initonly ";
1340 if (insideCli) current->spec |= Entry::Initonly;
1343 <FindMembers>{B}*"static"{BN}+ { current->type += " static ";
1344 current->stat = TRUE;
1347 <FindMembers>{B}*"extern"{BN}+ {
1348 current->stat = FALSE;
1349 current->explicitExternal = TRUE;
1352 <FindMembers>{B}*"virtual"{BN}+ { current->type += " virtual ";
1353 current->virt = Virtual;
1356 <FindMembers>{B}*"published"{BN}+ { // UNO IDL published keyword
1360 current->spec |= Entry::Published;
1367 <FindMembers>{B}*"abstract"{BN}+ {
1370 current->type += " abstract ";
1373 current->virt = Pure;
1377 current->spec|=Entry::Abstract;
1382 current->spec|=Entry::Abstract;
1386 <FindMembers>{B}*"inline"{BN}+ { current->spec|=Entry::Inline;
1389 <FindMembers>{B}*"mutable"{BN}+ { current->spec|=Entry::Mutable;
1392 <FindMembers>{B}*"explicit"{BN}+ { current->spec|=Entry::Explicit;
1395 <FindMembers>{B}*"@required"{BN}+ { // Objective C 2.0 protocol required section
1396 current->spec=(current->spec & ~Entry::Optional) | Entry::Required;
1399 <FindMembers>{B}*"@optional"{BN}+ { // Objective C 2.0 protocol optional section
1400 current->spec=(current->spec & ~Entry::Required) | Entry::Optional;
1404 <FindMembers>{B}*"import"{BN}+ { // IDL import keyword
1408 <FindMembers>{B}*"typename"{BN}+ { lineCount(); }
1409 <FindMembers>{B}*"namespace"{BN}*/[^a-z_A-Z0-9] {
1411 current->section = Entry::NAMESPACE_SEC;
1412 current->type = "namespace" ;
1413 current->fileName = yyFileName;
1414 current->startLine = yyLineNr;
1415 current->startColumn = yyColNr;
1416 current->bodyLine = yyLineNr;
1420 BEGIN( PackageName );
1424 BEGIN( CompoundName );
1427 <FindMembers>{B}*"module"{BN}+ {
1432 current->section = Entry::NAMESPACE_SEC;
1433 current->type = "module" ;
1434 current->fileName = yyFileName;
1435 current->startLine = yyLineNr;
1436 current->startColumn = yyColNr;
1437 current->bodyLine = yyLineNr;
1438 BEGIN( CompoundName );
1447 addType( current ) ;
1448 current->name = QCString(yytext).stripWhiteSpace();
1451 <FindMembers>{B}*"library"{BN}+ {
1456 current->section = Entry::NAMESPACE_SEC;
1457 current->type = "library" ;
1458 current->fileName = yyFileName;
1459 current->startLine = yyLineNr;
1460 current->startColumn = yyColNr;
1461 current->bodyLine = yyLineNr;
1462 BEGIN( CompoundName );
1466 addType( current ) ;
1467 current->name = QCString(yytext).stripWhiteSpace();
1470 <FindMembers>{B}*"constants"{BN}+ { // UNO IDL constant group
1475 current->section = Entry::NAMESPACE_SEC;
1476 current->type = "constants";
1477 current->fileName = yyFileName;
1478 current->startLine = yyLineNr;
1479 current->startColumn = yyColNr;
1480 current->bodyLine = yyLineNr;
1481 BEGIN( CompoundName );
1485 addType( current ) ;
1486 current->name = QCString(yytext).stripWhiteSpace();
1489 <FindMembers>{BN}*("service"){BN}+ { // UNO IDL service
1494 current->section = Entry::CLASS_SEC;
1495 current->spec = Entry::Service |
1496 // preserve UNO IDL [optional] or published
1497 (current->spec & (Entry::Optional|Entry::Published));
1498 addType( current ) ;
1499 current->type += " service " ;
1500 current->fileName = yyFileName;
1501 current->startLine = yyLineNr;
1502 current->bodyLine = yyLineNr;
1503 BEGIN( CompoundName );
1505 else // TODO is addType right? just copy/pasted
1507 addType( current ) ;
1508 current->name = QCString(yytext).stripWhiteSpace();
1511 <FindMembers>{BN}*("singleton"){BN}+ { // UNO IDL singleton
1516 current->section = Entry::CLASS_SEC;
1517 current->spec = Entry::Singleton |
1518 (current->spec & Entry::Published); // preserve
1519 addType( current ) ;
1520 current->type += " singleton " ;
1521 current->fileName = yyFileName;
1522 current->startLine = yyLineNr;
1523 current->bodyLine = yyLineNr;
1524 BEGIN( CompoundName );
1526 else // TODO is addType right? just copy/pasted
1528 addType( current ) ;
1529 current->name = QCString(yytext).stripWhiteSpace();
1532 <FindMembers>{BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java interface
1534 if (insideIDL || insideJava || insideCS || insideD || insidePHP)
1537 current->section = Entry::CLASS_SEC;
1538 current->spec = Entry::Interface |
1539 // preserve UNO IDL [optional] or published
1540 (current->spec & (Entry::Optional|Entry::Published));
1541 addType( current ) ;
1542 current->type += " interface" ;
1543 current->fileName = yyFileName;
1544 current->startLine = yyLineNr;
1545 current->startColumn = yyColNr;
1546 current->bodyLine = yyLineNr;
1547 BEGIN( CompoundName );
1551 addType( current ) ;
1552 current->name = QCString(yytext).stripWhiteSpace();
1555 <FindMembers>{B}*"@implementation"{BN}+ { // Objective-C class implementation
1558 current->section = Entry::OBJCIMPL_SEC;
1559 language = current->lang = SrcLangExt_ObjC;
1561 current->protection = protection = Public ;
1562 addType( current ) ;
1563 current->type += " implementation" ;
1564 current->fileName = yyFileName;
1565 current->startLine = yyLineNr;
1566 current->bodyLine = yyLineNr;
1567 BEGIN( CompoundName );
1569 <FindMembers>{B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute
1572 current->section = Entry::CLASS_SEC;
1573 current->spec = Entry::Interface;
1576 language = current->lang = SrcLangExt_ObjC;
1579 current->protection = protection = Public ;
1580 addType( current ) ;
1581 current->type += " interface" ;
1582 current->fileName = yyFileName;
1583 current->startLine = yyLineNr;
1584 current->startColumn = yyColNr;
1585 current->bodyLine = yyLineNr;
1586 BEGIN( CompoundName );
1588 <FindMembers>{B}*"@protocol"{BN}+ { // Objective-C protocol definition
1591 current->section = Entry::CLASS_SEC;
1592 current->spec = Entry::Protocol;
1593 language = current->lang = SrcLangExt_ObjC;
1595 current->protection = protection = Public ;
1596 addType( current ) ;
1597 current->type += " protocol" ;
1598 current->fileName = yyFileName;
1599 current->startLine = yyLineNr;
1600 current->startColumn = yyColNr;
1601 current->bodyLine = yyLineNr;
1602 BEGIN( CompoundName );
1604 <FindMembers>{B}*"exception"{BN}+ { // Corba IDL exception
1606 current->section = Entry::CLASS_SEC;
1607 current->spec = Entry::Exception |
1608 (current->spec & Entry::Published); // preserve UNO IDL
1609 addType( current ) ;
1610 current->type += " exception" ;
1611 current->fileName = yyFileName;
1612 current->startLine = yyLineNr;
1613 current->startColumn = yyColNr;
1614 current->bodyLine = yyLineNr;
1616 BEGIN( CompoundName );
1618 <FindMembers>"@class" | // for Objective C class declarations
1619 <FindMembers>{B}*{TYPEDEFPREFIX}"class{" |
1620 <FindMembers>{B}*{TYPEDEFPREFIX}"class"{BN}+ {
1621 QCString decl = yytext;
1622 isTypedef=decl.find("typedef")!=-1;
1623 bool isConst=decl.find("const")!=-1;
1624 bool isVolatile=decl.find("volatile")!=-1;
1625 current->section = Entry::CLASS_SEC;
1626 addType( current ) ;
1629 current->type += " const";
1631 else if (isVolatile)
1633 current->type += " volatile";
1635 current->type += " class" ;
1636 current->fileName = yyFileName;
1637 current->startLine = yyLineNr;
1638 current->startColumn = yyColNr;
1639 current->bodyLine = yyLineNr;
1642 language = current->lang = SrcLangExt_ObjC;
1646 if (yytext[yyleng-1]=='{') unput('{');
1647 if (insidePHP && current->spec&Entry::Abstract)
1649 // convert Abstract to AbstractClass
1650 current->spec=(current->spec&~Entry::Abstract)|Entry::AbstractClass;
1652 BEGIN( CompoundName ) ;
1654 <FindMembers>{B}*"value class{" | // C++/CLI extension
1655 <FindMembers>{B}*"value class"{BN}+ {
1657 current->section = Entry::CLASS_SEC;
1658 current->spec = Entry::Value;
1659 addType( current ) ;
1660 current->type += " value class" ;
1661 current->fileName = yyFileName;
1662 current->startLine = yyLineNr;
1663 current->startColumn = yyColNr;
1664 current->bodyLine = yyLineNr;
1666 if (yytext[yyleng-1]=='{') unput('{');
1667 BEGIN( CompoundName ) ;
1669 <FindMembers>{B}*"ref class{" | // C++/CLI extension
1670 <FindMembers>{B}*"ref class"{BN}+ {
1672 current->section = Entry::CLASS_SEC;
1673 current->spec = Entry::Ref;
1674 addType( current ) ;
1675 current->type += " ref class" ;
1676 current->fileName = yyFileName;
1677 current->startLine = yyLineNr;
1678 current->startColumn = yyColNr;
1679 current->bodyLine = yyLineNr;
1681 if (yytext[yyleng-1]=='{') unput('{');
1682 BEGIN( CompoundName ) ;
1684 <FindMembers>{B}*"interface class{" | // C++/CLI extension
1685 <FindMembers>{B}*"interface class"{BN}+ {
1687 current->section = Entry::CLASS_SEC;
1688 current->spec = Entry::Interface;
1689 addType( current ) ;
1690 current->type += " interface class" ;
1691 current->fileName = yyFileName;
1692 current->startLine = yyLineNr;
1693 current->startColumn = yyColNr;
1694 current->bodyLine = yyLineNr;
1696 if (yytext[yyleng-1]=='{') unput('{');
1697 BEGIN( CompoundName ) ;
1699 <FindMembers>{B}*"coclass"{BN}+ {
1703 current->section = Entry::CLASS_SEC;
1704 addType( current ) ;
1705 current->type += " coclass" ;
1706 current->fileName = yyFileName;
1707 current->startLine = yyLineNr;
1708 current->startColumn = yyColNr;
1709 current->bodyLine = yyLineNr;
1711 BEGIN( CompoundName ) ;
1716 current->name = yytext;
1717 current->name = current->name.stripWhiteSpace();
1721 <FindMembers>{B}*{TYPEDEFPREFIX}"struct{" |
1722 <FindMembers>{B}*{TYPEDEFPREFIX}"struct"/{BN}+ {
1723 QCString decl = yytext;
1724 isTypedef=decl.find("typedef")!=-1;
1725 bool isConst=decl.find("const")!=-1;
1726 bool isVolatile=decl.find("volatile")!=-1;
1727 current->section = Entry::CLASS_SEC ;
1728 current->spec = Entry::Struct |
1729 (current->spec & Entry::Published); // preserve UNO IDL
1730 // bug 582676: can be a struct nested in an interface so keep insideObjC state
1731 //current->objc = insideObjC = FALSE;
1732 addType( current ) ;
1735 current->type += " const";
1737 else if (isVolatile)
1739 current->type += " volatile";
1741 current->type += " struct" ;
1742 current->fileName = yyFileName;
1743 current->startLine = yyLineNr;
1744 current->startColumn = yyColNr;
1745 current->bodyLine = yyLineNr;
1747 if (yytext[yyleng-1]=='{') unput('{');
1748 BEGIN( CompoundName ) ;
1750 <FindMembers>{B}*"value struct{" | // C++/CLI extension
1751 <FindMembers>{B}*"value struct"{BN}+ {
1753 current->section = Entry::CLASS_SEC;
1754 current->spec = Entry::Struct | Entry::Value;
1755 addType( current ) ;
1756 current->type += " value struct" ;
1757 current->fileName = yyFileName;
1758 current->startLine = yyLineNr;
1759 current->startColumn = yyColNr;
1760 current->bodyLine = yyLineNr;
1762 if (yytext[yyleng-1]=='{') unput('{');
1763 BEGIN( CompoundName ) ;
1765 <FindMembers>{B}*"ref struct{" | // C++/CLI extension
1766 <FindMembers>{B}*"ref struct"{BN}+ {
1768 current->section = Entry::CLASS_SEC;
1769 current->spec = Entry::Struct | Entry::Ref;
1770 addType( current ) ;
1771 current->type += " ref struct" ;
1772 current->fileName = yyFileName;
1773 current->startLine = yyLineNr;
1774 current->startColumn = yyColNr;
1775 current->bodyLine = yyLineNr;
1777 if (yytext[yyleng-1]=='{') unput('{');
1778 BEGIN( CompoundName ) ;
1780 <FindMembers>{B}*"interface struct{" | // C++/CLI extension
1781 <FindMembers>{B}*"interface struct"{BN}+ {
1783 current->section = Entry::CLASS_SEC;
1784 current->spec = Entry::Struct | Entry::Interface;
1785 addType( current ) ;
1786 current->type += " interface struct";
1787 current->fileName = yyFileName;
1788 current->startLine = yyLineNr;
1789 current->startColumn = yyColNr;
1790 current->bodyLine = yyLineNr;
1792 if (yytext[yyleng-1]=='{') unput('{');
1793 BEGIN( CompoundName ) ;
1795 <FindMembers>{B}*{TYPEDEFPREFIX}"union{" |
1796 <FindMembers>{B}*{TYPEDEFPREFIX}"union"{BN}+ {
1797 QCString decl=yytext;
1798 isTypedef=decl.find("typedef")!=-1;
1799 bool isConst=decl.find("const")!=-1;
1800 bool isVolatile=decl.find("volatile")!=-1;
1801 current->section = Entry::CLASS_SEC;
1802 current->spec = Entry::Union;
1803 // bug 582676: can be a struct nested in an interface so keep insideObjC state
1804 //current->objc = insideObjC = FALSE;
1805 addType( current ) ;
1808 current->type += " const";
1810 else if (isVolatile)
1812 current->type += " volatile";
1814 current->type += " union" ;
1815 current->fileName = yyFileName;
1816 current->startLine = yyLineNr;
1817 current->startColumn = yyColNr;
1818 current->bodyLine = yyLineNr;
1820 if (yytext[yyleng-1]=='{') unput('{');
1821 BEGIN( CompoundName ) ;
1823 <FindMembers>{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?"{" |
1824 <FindMembers>{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?{BN}+ { // for IDL: typedef [something] enum
1825 QCString text=yytext;
1826 isTypedef = text.find("typedef")!=-1;
1827 bool isStrongEnum = text.find("struct")!=-1 || text.find("class")!=-1;
1830 current->section = Entry::CLASS_SEC;
1831 current->spec = Entry::Enum;
1835 current->section = Entry::ENUM_SEC ;
1837 addType( current ) ;
1838 current->type += " enum";
1841 current->spec |= Entry::Strong;
1843 current->fileName = yyFileName;
1844 current->startLine = yyLineNr;
1845 current->startColumn = yyColNr;
1846 current->bodyLine = yyLineNr;
1848 if (yytext[yyleng-1]=='{') unput('{');
1849 BEGIN( CompoundName ) ;
1851 <Operator>"("{BN}*")"({BN}*"<"[^>]*">"){BN}*/"(" { // A::operator()<int>(int arg)
1853 current->name += "()";
1854 BEGIN( FindMembers );
1856 <Operator>"("{BN}*")"{BN}*/"(" {
1858 current->name += yytext ;
1859 current->name = current->name.simplifyWhiteSpace();
1860 BEGIN( FindMembers ) ;
1862 <Operator>";" { // can occur when importing members
1864 BEGIN( FindMembers ) ;
1868 current->name += *yytext ;
1870 <Operator>"<>" { /* skip guided templ specifiers */ }
1872 current->name = current->name.simplifyWhiteSpace();
1874 BEGIN( FindMembers ) ;
1876 <FindMembers>("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension
1878 if (current->tArgLists==0)
1880 current->tArgLists = new QList<ArgumentList>;
1881 current->tArgLists->setAutoDelete(TRUE);
1883 ArgumentList *al = new ArgumentList;
1884 //current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template;
1885 current->tArgLists->append(al);
1886 currentArgumentList = al;
1888 fullArgString = templateStr;
1889 copyArgString = &templateStr;
1890 currentArgumentContext = FindMembers;
1891 BEGIN( ReadTempArgs );
1893 <FindMembers>"namespace"{BN}+/{ID}{BN}*"=" { // namespace alias
1895 BEGIN( NSAliasName );
1899 BEGIN( NSAliasArg );
1901 <NSAliasArg>({ID}"::")*{ID} {
1902 //printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext);
1903 //if (current_root->name.isEmpty())
1905 // TODO: namespace aliases are now treated as global entities
1906 // while they should be aware of the scope they are in
1907 Doxygen::namespaceAliasDict.insert(aliasName,new QCString(yytext));
1911 // Doxygen::namespaceAliasDict.insert(current_root->name+"::"+aliasName,
1912 // new QCString(current_root->name+"::"+yytext));
1916 BEGIN( FindMembers );
1918 <PHPUse>({ID}{BN}*"\\"{BN}*)*{ID}/{BN}+"as" {
1923 <PHPUse>({ID}{BN}*"\\"{BN}*)*{ID} {
1925 current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::"));
1926 //printf("PHP: adding use relation: %s\n",current->name.data());
1927 current->fileName = yyFileName;
1928 // add a using declaraton
1929 current->section=Entry::USINGDECL_SEC;
1930 current_root->addSubEntry(current);
1931 current = new Entry(*current);
1932 // also add it as a using directive
1933 current->section=Entry::USINGDIR_SEC;
1934 current_root->addSubEntry(current);
1935 current = new Entry ;
1937 aliasName.resize(0);
1939 <PHPUseAs>{BN}+"as"{BN}+ {
1943 //printf("PHP: adding use as relation: %s->%s\n",yytext,aliasName.data());
1944 Doxygen::namespaceAliasDict.insert(yytext,
1945 new QCString(removeRedundantWhiteSpace(
1946 substitute(aliasName,"\\","::"))));
1947 aliasName.resize(0);
1949 <PHPUse,PHPUseAs>[,;] {
1959 <JavaImport>({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive
1961 QCString scope=yytext;
1962 current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::"));
1963 current->fileName = yyFileName;
1964 current->section=Entry::USINGDIR_SEC;
1965 current_root->addSubEntry(current);
1966 current = new Entry;
1970 <JavaImport>({ID}{BN}*"."{BN}*)+{ID} { // class import => add as a using declaration
1972 QCString scope=yytext;
1973 current->name=removeRedundantWhiteSpace(substitute(scope,".","::"));
1974 current->fileName = yyFileName;
1977 current->section=Entry::USINGDIR_SEC;
1981 //printf("import name = %s -> %s\n",yytext,current->name.data());
1982 current->section=Entry::USINGDECL_SEC;
1984 current_root->addSubEntry(current);
1985 current = new Entry ;
1989 <FindMembers>"using"{BN}+ {
1990 current->startLine=yyLineNr;
1991 current->startColumn = yyColNr;
1995 <Using>"namespace"{BN}+ { lineCount(); BEGIN(UsingDirective); }
1996 <Using>({ID}{BN}*("::"|"."){BN}*)*({ID}|{OPERATOR}) {
1998 current->name=yytext;
1999 current->fileName = yyFileName;
2000 current->section=Entry::USINGDECL_SEC;
2001 current->startLine = yyLineNr;
2002 current_root->addSubEntry(current);
2004 current = new Entry ;
2005 if (insideCS) /* Hack: in C# a using declaration and
2006 directive have the same syntax, so we
2007 also add it as a using directive here
2010 current->name=yytext;
2011 current->fileName = yyFileName;
2012 current->startLine = yyLineNr;
2013 current->startColumn = yyColNr;
2014 current->section=Entry::USINGDIR_SEC;
2015 current_root->addSubEntry(current);
2016 current = new Entry ;
2021 <Using>"=" { // C++11 style template alias?
2025 previous->section=Entry::VARIABLE_SEC;
2026 previous->type = "typedef "+previous->args;
2027 previous->type=previous->type.simplifyWhiteSpace();
2028 previous->args.resize(0);
2029 previous->name=previous->name.stripWhiteSpace();
2030 previous->bodyLine = yyLineNr;
2031 previous->spec |= Entry::Alias;
2034 <UsingAlias>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" {
2035 docBlockContext = UsingAliasEnd;
2036 docBlockInBody = FALSE;
2037 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
2038 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
2040 indent.fill(' ',computeIndent(yytext,g_column));
2045 if (yytext[yyleng-3]=='/')
2047 startCommentBlock(TRUE);
2052 startCommentBlock(FALSE);
2057 previous->args+=yytext;
2060 previous->args+=yytext;
2063 <UsingAliasEnd>";" {
2064 previous->doc = current->doc;
2065 previous->brief = current->brief;
2066 current->doc.resize(0);
2067 current->brief.resize(0);
2071 <UsingDirective>{SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext);
2072 current->fileName = yyFileName;
2073 current->section=Entry::USINGDIR_SEC;
2074 current_root->addSubEntry(current);
2075 current = new Entry ;
2079 <Using>";" { BEGIN(FindMembers); }
2080 <FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl
2083 current->name=n.left(n.length()-2);
2085 <FindMembers>{SCOPENAME}{BN}*/"<" { // Note: this could be a return type!
2090 current->name=yytext;
2091 current->name=current->name.stripWhiteSpace();
2092 //current->scopeSpec.resize(0);
2093 // currentTemplateSpec = ¤t->scopeSpec;
2094 if (nameIsOperator(current->name))
2097 BEGIN( EndTemplate );
2099 <FindMemberName>{SCOPENAME}{BN}*/"<" {
2103 current->name+=((QCString)yytext).stripWhiteSpace();
2104 //current->memberSpec.resize(0);
2105 // currentTemplateSpec = ¤t->memberSpec;
2106 if (nameIsOperator(current->name))
2109 BEGIN( EndTemplate );
2111 <EndTemplate>"<<<" {
2118 lastHereDocContext = YY_START;
2122 <ClassTemplSpec,EndTemplate>"<<" {
2123 current->name+=yytext;
2124 // *currentTemplateSpec+=yytext;
2129 // *currentTemplateSpec+='<';
2132 current->name+=yytext;
2134 <ClassTemplSpec,EndTemplate>">>" {
2135 if (insideJava || insideCS || insideCli || roundCount==0)
2143 current->name+=yytext;
2145 // *currentTemplateSpec+=yytext;
2149 // *currentTemplateSpec+='>';
2150 if (roundCount==0 && --sharpCount<=0)
2152 //printf("Found %s\n",current->name.data());
2156 <EndTemplate>">"{BN}*"(" {
2159 // *currentTemplateSpec+='>';
2160 if (roundCount==0 && --sharpCount<=0)
2162 current->bodyLine = yyLineNr;
2163 current->args = "(";
2164 currentArgumentContext = FuncQual;
2165 fullArgString = current->args.copy();
2166 copyArgString = ¤t->args;
2167 //printf("Found %s\n",current->name.data());
2168 BEGIN( ReadFuncArgType ) ;
2171 <EndTemplate>">"{BN}*/"("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance
2179 <EndTemplate>">"{BN}*/"::" {
2182 // *currentTemplateSpec+='>';
2183 if (roundCount==0 && --sharpCount<=0)
2185 BEGIN(FindMemberName);
2188 <ClassTemplSpec,EndTemplate>"(" { current->name+=*yytext;
2191 <ClassTemplSpec,EndTemplate>")" { current->name+=*yytext;
2192 if (roundCount>0) roundCount--;
2195 current->name+=*yytext;
2196 // *currentTemplateSpec+=*yytext;
2198 <FindMembers>"define"{BN}*"("{BN}*["'] {
2201 current->bodyLine = yyLineNr;
2207 <CopyHereDoc>{ID} { // PHP heredoc
2208 g_delimiter = yytext;
2209 *pCopyHereDocGString += yytext;
2210 BEGIN(CopyHereDocEnd);
2212 <CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc
2213 g_delimiter = &yytext[1];
2214 *pCopyHereDocGString += yytext;
2215 BEGIN(CopyHereDocEnd);
2217 <HereDoc>{ID} { // PHP heredoc
2218 g_delimiter = yytext;
2221 <HereDoc>"'"{ID}/"'" { // PHP nowdoc
2222 g_delimiter = &yytext[1];
2225 <HereDocEnd>^{ID} { // id at start of the line could mark the end of the block
2226 if (g_delimiter==yytext) // it is the end marker
2228 BEGIN(lastHereDocContext);
2232 <CopyHereDocEnd>^{ID} { // id at start of the line could mark the end of the block
2233 *pCopyHereDocGString += yytext;
2234 if (g_delimiter==yytext) // it is the end marker
2236 BEGIN(lastHereDocContext);
2239 <CopyHereDocEnd>\n {
2240 *pCopyHereDocGString += yytext;
2243 *pCopyHereDocGString += yytext;
2245 <FindMembers>"Q_OBJECT" { // Qt object macro
2247 <FindMembers>"Q_PROPERTY" { // Qt property declaration
2248 //current->protection = protection = Public ; // see bug734245
2249 current->mtype = mtype = Property;
2250 current->type.resize(0);
2253 <QtPropType>"(" { // start of property arguments
2255 <QtPropAttr>")" { // end of property arguments
2259 <QtPropType>"const"|"volatile"|"unsigned"|"signed"|"long"|"short" {
2260 current->type+=yytext;
2263 current->type+=yytext;
2265 <QtPropType>({TSCOPE}"::")*{TSCOPE} {
2266 current->type+=yytext;
2270 current->name=yytext;
2273 <QtPropAttr>"READ" {
2274 current->spec |= Entry::Readable;
2277 <QtPropAttr>"WRITE" {
2278 current->spec |= Entry::Writable;
2281 <QtPropAttr>"RESET"{B}+{ID} { // reset method => not supported yet
2283 <QtPropAttr>"SCRIPTABLE"{B}+{ID} { // scriptable property => not supported yet
2285 <QtPropAttr>"DESIGNABLE"{B}+{ID} { // designable property => not supported yet
2288 current->read = yytext;
2292 current->write = yytext;
2295 <FindMembers>"friend"{BN}+("class"|"union"|"struct"){BN}+ {
2296 current->name=yytext;
2299 <FindMembers,FindMemberName>{SCOPENAME} {
2300 if (insideCpp || insideObjC)
2302 current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
2305 yyBegLineNr=yyLineNr;
2307 if (insideIDL && yyleng==9 && qstrcmp(yytext,"cpp_quote")==0)
2311 else if ((insideIDL || insideJava || insideD) && yyleng==6 && qstrcmp(yytext,"import")==0)
2315 else // insideJava or insideD
2318 else if (insidePHP && qstrcmp(yytext,"use")==0)
2322 else if (insideJava && qstrcmp(yytext,"package")==0)
2327 else if (insideIDL && qstrcmp(yytext,"case")==0)
2329 BEGIN(IDLUnionCase);
2331 else if (insideTryBlock && qstrcmp(yytext,"catch")==0)
2333 insideTryBlock=FALSE;
2334 BEGIN(TryFunctionBlock);
2336 else if (insideCpp && qstrcmp(yytext,"alignas")==0)
2338 lastAlignAsContext = YY_START;
2341 else if (insideJS && qstrcmp(yytext,"var")==0)
2342 { // javascript variable
2343 current->type="var";
2345 else if (insideJS && qstrcmp(yytext,"function")==0)
2346 { // javascript function
2347 current->type="function";
2349 else if (insideCS && qstrcmp(yytext,"this")==0)
2352 addType( current ) ;
2353 current->name="this";
2356 else if (insideCpp && qstrcmp(yytext,"static_assert")==0)
2358 // C++11 static_assert
2359 BEGIN(StaticAssert);
2361 else if (insideCpp && qstrcmp(yytext,"decltype")==0)
2363 // C++11 decltype(x)
2364 current->type+=yytext;
2369 if (YY_START==FindMembers)
2371 addType( current ) ;
2373 bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS;
2374 if (javaLike && qstrcmp(yytext,"public")==0)
2376 current->protection = Public;
2378 else if (javaLike && qstrcmp(yytext,"protected")==0)
2380 current->protection = Protected;
2382 else if (javaLike && qstrcmp(yytext,"internal")==0)
2384 current->protection = Package;
2386 else if (javaLike && qstrcmp(yytext,"private")==0)
2388 current->protection = Private;
2390 else if (javaLike && qstrcmp(yytext,"static")==0)
2392 if (YY_START==FindMembers)
2393 current->name = yytext;
2395 current->name += yytext;
2396 current->stat = TRUE;
2400 if (YY_START==FindMembers)
2401 current->name = yytext;
2403 current->name += yytext;
2404 if (current->name.left(7)=="static ")
2406 current->stat = TRUE;
2407 current->name= current->name.mid(7);
2409 else if (current->name.left(7)=="inline ")
2411 if (current->type.isEmpty())
2413 current->type="inline";
2417 current->type+="inline ";
2419 current->name= current->name.mid(7);
2421 else if (current->name.left(6)=="const ")
2423 if (current->type.isEmpty())
2425 current->type="const";
2429 current->type+="const ";
2431 current->name=current->name.mid(6);
2434 QCString tmp=yytext;
2435 if (nameIsOperator(tmp))
2446 lastSkipRoundContext = FindMembers;
2450 <StaticAssert>{BN}+ { lineCount(); }
2451 <StaticAssert>. { // variable with static_assert as name?
2456 current->type+=yytext;
2457 lastRoundContext=FindMembers;
2458 pCopyRoundString=¤t->type;
2462 <DeclType>{BN}+ { lineCount(); }
2467 <CSIndexer>"["[^\n\]]*"]" {
2468 current->name+=removeRedundantWhiteSpace(yytext);
2471 <FindMembers>[0-9]{ID} { // some number where we did not expect one
2474 if (insideJava || insideCS || insideD)
2480 current->name+=yytext;
2482 <CppQuote>"("{B}*"\"" {
2483 insideCppQuote=TRUE;
2487 <IDLUnionCase>":" { BEGIN(FindMembers); }
2488 <IDLUnionCase>\n { lineCount(); }
2490 <TryFunctionBlock>\n { lineCount(); }
2491 <TryFunctionBlock>"{" {
2493 lastCurlyContext = TryFunctionBlockEnd ;
2497 <TryFunctionBlockEnd>{BN}*"catch" { lineCount(); BEGIN(TryFunctionBlock); // {BN}* added to fix bug 611193
2499 <TryFunctionBlockEnd>\n { unput(*yytext); // rule added to fix bug id 601138
2500 BEGIN( FindMembers );
2502 <TryFunctionBlockEnd>. { unput(*yytext);
2503 BEGIN( FindMembers );
2506 insideCppQuote=FALSE;
2509 <FindMembers,FindFields>{B}*"#" { if (insidePHP)
2511 lastCPPContext = YY_START;
2514 <FindMembers,FindFields>{B}*"#"{B}*("cmake")?"define" {
2517 current->bodyLine = yyLineNr;
2518 lastDefineContext = YY_START;
2521 <FindMembers,ReadBody,ReadNSBody,ReadBodyIntf,SkipCurly,SkipCurlyCpp>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
2522 yyLineNr = atoi(&yytext[1]);
2523 //printf("setting line number to %d\n",yyLineNr);
2524 lastPreLineCtrlContext = YY_START;
2525 if (YY_START==ReadBody ||
2526 YY_START==ReadNSBody ||
2527 YY_START==ReadBodyIntf)
2529 current->program+=yytext;
2531 BEGIN( PreLineCtrl );
2533 <PreLineCtrl>"\""[^\n\"]*"\"" {
2534 yyFileName = stripQuotes(yytext);
2535 if (lastPreLineCtrlContext==ReadBody ||
2536 lastPreLineCtrlContext==ReadNSBody ||
2537 lastPreLineCtrlContext==ReadBodyIntf)
2539 current->program+=yytext;
2543 if (lastPreLineCtrlContext==ReadBody ||
2544 lastPreLineCtrlContext==ReadNSBody ||
2545 lastPreLineCtrlContext==ReadBodyIntf)
2547 current->program+=yytext;
2551 if (lastPreLineCtrlContext==ReadBody ||
2552 lastPreLineCtrlContext==ReadNSBody ||
2553 lastPreLineCtrlContext==ReadBodyIntf)
2555 current->program+=yytext;
2558 BEGIN( lastPreLineCtrlContext );
2561 <SkipCPP>\\[\r]*"\n"[\r]* { lineCount(); }
2562 <SkipCPP>[\r]*\n[\r]* { lineCount();
2563 BEGIN( lastCPPContext) ;
2565 <Define>{ID}{B}*"(" {
2566 current->name = yytext;
2567 current->name = current->name.left(current->name.length()-1).stripWhiteSpace();
2568 current->args = "(";
2569 current->bodyLine = yyLineNr;
2570 currentArgumentContext = DefineEnd;
2571 fullArgString=current->args.copy();
2572 copyArgString=¤t->args;
2573 BEGIN( ReadFuncArgType ) ;
2577 //printf("Define with args\n");
2578 current->args += ')';
2582 current->args += *yytext;
2586 //printf("Define `%s' without args\n",yytext);
2587 if (insideCpp || insideObjC)
2589 current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
2591 current->bodyLine = yyLineNr;
2592 current->name = yytext;
2596 //printf("End define: doc=%s docFile=%s docLine=%d\n",current->doc.data(),current->docFile.data(),current->docLine);
2598 current->fileName = yyFileName;
2599 current->startLine = yyLineNr;
2600 current->startColumn = yyColNr;
2601 current->type.resize(0);
2602 current->args = current->args.simplifyWhiteSpace();
2603 current->name = current->name.stripWhiteSpace();
2604 current->section = Entry::DEFINE_SEC;
2605 current_root->addSubEntry(current);
2606 current = new Entry ;
2608 BEGIN(lastDefineContext);
2611 //printf("End define\n");
2612 current->fileName = yyFileName;
2613 current->startLine = yyLineNr;
2614 current->startColumn = yyColNr;
2615 current->type.resize(0);
2616 current->type = "const";
2617 QCString init = current->initializer.data();
2618 init = init.simplifyWhiteSpace();
2619 init = init.left(init.length()-1);
2620 current->initializer = init;
2621 current->name = current->name.stripWhiteSpace();
2622 current->section = Entry::VARIABLE_SEC;
2623 current_root->addSubEntry(current);
2624 current = new Entry ;
2629 <DefineEnd>\\[\r]?\n {
2633 if (insideIDL && insideCppQuote)
2639 lastStringContext=DefineEnd;
2644 <DefinePHP>{ID}["']{BN}*","{BN}* {
2645 current->name = yytext;
2646 current->name = current->name.stripWhiteSpace();
2647 current->name = current->name.left(current->name.length()-1).stripWhiteSpace();
2648 current->name = current->name.left(current->name.length()-1);
2649 current->bodyLine = yyLineNr;
2650 lastRoundContext = DefinePHPEnd;
2651 pCopyRoundGString = ¤t->initializer;
2653 BEGIN( GCopyRound );
2656 <FindMembers>[\^%] { // ^ and % are C++/CLI extensions
2660 current->name = yytext ;
2667 <FindMembers>[*&]+ {
2668 current->name += yytext ;
2671 <FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" {
2672 if (current->bodyLine==-1)
2674 current->bodyLine=yyLineNr;
2676 docBlockContext = YY_START;
2677 docBlockInBody = FALSE;
2678 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
2679 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
2682 indent.fill(' ',computeIndent(yytext,g_column));
2684 //printf("indent=%d\n",computeIndent(yytext+1,g_column));
2688 if (YY_START==EnumBaseType && current->section==Entry::ENUM_SEC)
2690 current->bitfields = ":"+current->args;
2691 current->args.resize(0);
2692 current->section=Entry::VARIABLE_SEC;
2694 if (yytext[yyleng-3]=='/')
2696 startCommentBlock(TRUE);
2701 startCommentBlock(FALSE);
2705 <MemberSpec,FindFields,FindMembers,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs>","{BN}*("/**"|"//!"|"/*!"|"///")"<" {
2706 docBlockContext = YY_START;
2707 docBlockInBody = FALSE;
2708 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
2709 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
2712 indent.fill(' ',computeIndent(yytext,g_column));
2717 if (YY_START==EnumBaseType && current->section==Entry::ENUM_SEC)
2719 current->bitfields = ":"+current->args;
2720 current->args.resize(0);
2721 current->section=Entry::VARIABLE_SEC;
2723 if (yytext[yyleng-3]=='/')
2725 startCommentBlock(TRUE);
2730 startCommentBlock(FALSE);
2734 <DefineEnd,FindFields,FindFieldArg,ReadInitializer,OldStyleArgs>{BN}*("/**"|"//!"|"/*!"|"///")"<" {
2735 if (current->bodyLine==-1)
2737 current->bodyLine=yyLineNr;
2739 docBlockContext = YY_START;
2740 docBlockInBody = FALSE;
2741 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
2742 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
2744 indent.fill(' ',computeIndent(yytext,g_column));
2749 if (yytext[yyleng-3]=='/')
2751 startCommentBlock(TRUE);
2756 startCommentBlock(FALSE);
2761 <FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") {
2762 //handleGroupStartCommand(current->name);
2763 if (previous && previous->section==Entry::GROUPDOC_SEC)
2765 // link open command to the group defined in the previous entry
2766 openGroup(previous,yyFileName,yyLineNr);
2770 // link open command to the current entry
2771 openGroup(current,yyFileName,yyLineNr);
2777 if (yytext[2]=='!' || yytext[2]=='/')
2779 docBlockContext = YY_START;
2780 docBlockInBody = FALSE;
2781 docBlockAutoBrief = FALSE;
2784 startCommentBlock(TRUE);
2789 lastCContext=YY_START;
2790 BEGIN(SkipCxxComment);
2795 if (yytext[2]=='!' || yytext[2]=='*')
2797 docBlockContext = YY_START;
2798 docBlockInBody = FALSE;
2800 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
2801 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
2803 startCommentBlock(FALSE);
2808 lastCContext=YY_START;
2813 <FindMembers,FindFields,ReadInitializer>"//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}"[^*]*"*/" {
2814 closeGroup(current,yyFileName,yyLineNr);
2816 <FindMembers>"=" { // in PHP code this could also be due to "<?="
2817 current->bodyLine = yyLineNr;
2818 current->initializer = yytext;
2819 lastInitializerContext = YY_START;
2821 BEGIN(ReadInitializer);
2823 <UNOIDLAttributeBlock>{BN}*[gs]"et"{BN}+"raises"{BN}*"("{BN}*{SCOPENAME}{BN}*(","{BN}*{SCOPENAME}{BN}*)*")"{BN}*";" {
2825 current->exception += " ";
2826 current->exception += removeRedundantWhiteSpace(yytext);
2828 <UNOIDLAttributeBlock>"}" {
2829 current->exception += " }";
2832 /* Read initializer rules */
2833 <ReadInitializer>"(" {
2834 lastRoundContext=YY_START;
2835 pCopyRoundGString=¤t->initializer;
2837 current->initializer+=*yytext;
2840 <ReadInitializer>"{" {
2841 lastCurlyContext=YY_START;
2842 pCopyCurlyGString=¤t->initializer;
2844 current->initializer+=*yytext;
2847 <ReadInitializer>[;,] {
2848 //printf(">> initializer `%s' <<\n",current->initializer.data());
2849 if (*yytext==';' && (current_root->spec&Entry::Enum))
2851 current->fileName = yyFileName;
2852 current->startLine = yyLineNr;
2853 current->startColumn = yyColNr;
2854 current->args = current->args.simplifyWhiteSpace();
2855 current->name = current->name.stripWhiteSpace();
2856 current->section = Entry::VARIABLE_SEC;
2857 current_root->addSubEntry(current);
2858 current = new Entry;
2862 else if (*yytext==';' || (lastInitializerContext==FindFields && initBracketCount==0)) // initBracketCount==0 was added for bug 665778
2865 BEGIN(lastInitializerContext);
2867 else if (*yytext==',' && initBracketCount==0) // for "int a=0,b=0"
2870 BEGIN(lastInitializerContext);
2874 current->initializer+=*yytext;
2877 <ReadInitializer>{RAWBEGIN} { // C++11 raw string
2884 QCString text=yytext;
2885 current->initializer+=text;
2886 int i=text.find('"');
2887 g_delimiter = yytext+i+1;
2888 g_delimiter=g_delimiter.left(g_delimiter.length()-1);
2889 lastRawStringContext = YY_START;
2890 pCopyRawGString = ¤t->initializer;
2892 //printf("RawGString delimiter='%s'\n",delimiter.data());
2895 <RawGString>{RAWEND} {
2896 *pCopyRawGString+=yytext;
2897 QCString delimiter = yytext+1;
2898 delimiter=delimiter.left(delimiter.length()-1);
2899 if (delimiter==g_delimiter)
2901 BEGIN(lastRawStringContext);
2904 <RawGString>[^)\n]+ {
2905 *pCopyRawGString+=yytext;
2908 *pCopyRawGString+=yytext;
2911 *pCopyRawGString+=yytext;
2914 <RawString>{RAWEND} {
2915 *pCopyRawString+=yytext;
2916 fullArgString+=yytext;
2917 QCString delimiter = yytext+1;
2918 delimiter=delimiter.left(delimiter.length()-1);
2919 if (delimiter==g_delimiter)
2921 BEGIN(lastRawStringContext);
2925 *pCopyRawString+=yytext;
2926 fullArgString+=yytext;
2929 *pCopyRawString+=yytext;
2930 fullArgString+=yytext;
2933 *pCopyRawString+=yytext;
2934 fullArgString+=yytext;
2937 <ReadInitializer>\" {
2938 if (insideIDL && insideCppQuote)
2944 lastStringContext=YY_START;
2945 current->initializer+=yytext;
2946 pCopyQuotedGString=¤t->initializer;
2950 <ReadInitializer>"->" {
2951 current->initializer+=yytext;
2953 <ReadInitializer>"<<" {
2954 current->initializer+=yytext;
2956 <ReadInitializer>">>" {
2957 current->initializer+=yytext;
2959 <ReadInitializer>[<\[{(] {
2961 current->initializer+=*yytext;
2963 <ReadInitializer>[>\]})] {
2965 current->initializer+=*yytext;
2967 <ReadInitializer>\' {
2970 current->initializer+=yytext;
2971 pCopyQuotedGString = ¤t->initializer;
2972 lastStringContext=YY_START;
2973 BEGIN(CopyPHPGString);
2977 current->initializer+=yytext;
2980 <ReadInitializer>{CHARLIT} {
2987 current->initializer+=yytext;
2990 <ReadInitializer>\n {
2991 current->initializer+=*yytext;
2994 <ReadInitializer>"@\"" {
2995 //printf("insideCS=%d\n",insideCS);
2996 current->initializer+=yytext;
2997 if (!insideCS && !insideObjC)
3003 // C#/ObjC verbatim string
3004 lastSkipVerbStringContext=YY_START;
3005 pSkipVerbString=¤t->initializer;
3006 BEGIN(SkipVerbString);
3009 <SkipVerbString>[^\n"]+ {
3010 *pSkipVerbString+=yytext;
3012 <SkipVerbString>"\"\"" { // quote escape
3013 *pSkipVerbString+=yytext;
3015 <SkipVerbString>"\"" {
3016 *pSkipVerbString+=*yytext;
3017 BEGIN(lastSkipVerbStringContext);
3019 <SkipVerbString>\n {
3020 *pSkipVerbString+=*yytext;
3024 *pSkipVerbString+=*yytext;
3026 <ReadInitializer>"?>" {
3028 BEGIN( FindMembersPHP );
3030 current->initializer+=yytext;
3032 <ReadInitializer>. {
3033 current->initializer+=*yytext;
3036 /* generic quoted string copy rules */
3037 <CopyString,CopyPHPString>\\. {
3038 *pCopyQuotedString+=yytext;
3041 *pCopyQuotedString+=*yytext;
3042 BEGIN( lastStringContext );
3045 *pCopyQuotedString+=*yytext;
3046 BEGIN( lastStringContext );
3048 <CopyString,CopyPHPString>"/*"|"*/"|"//" {
3049 *pCopyQuotedString+=yytext;
3051 <CopyString,CopyPHPString>\n {
3052 *pCopyQuotedString+=*yytext;
3055 <CopyString,CopyPHPString>. {
3056 *pCopyQuotedString+=*yytext;
3059 /* generic quoted growable string copy rules */
3060 <CopyGString,CopyPHPGString>\\. {
3061 *pCopyQuotedGString+=yytext;
3064 *pCopyQuotedGString+=*yytext;
3065 BEGIN( lastStringContext );
3067 <CopyPHPGString>\' {
3068 *pCopyQuotedGString+=*yytext;
3069 BEGIN( lastStringContext );
3071 <CopyGString,CopyPHPGString>"/*"|"*/"|"//" {
3072 *pCopyQuotedGString+=yytext;
3074 <CopyGString,CopyPHPGString>\n {
3075 *pCopyQuotedGString+=*yytext;
3078 <CopyGString,CopyPHPGString>. {
3079 *pCopyQuotedGString+=*yytext;
3082 /* generic round bracket list copy rules */
3084 *pCopyRoundString+=*yytext;
3085 pCopyQuotedString=pCopyRoundString;
3086 lastStringContext=YY_START;
3090 *pCopyRoundString+=*yytext;
3094 *pCopyRoundString+=*yytext;
3096 BEGIN(lastRoundContext);
3100 *pCopyRoundString+=*yytext;
3105 current->initializer+=yytext;
3106 pCopyQuotedString = pCopyRoundString;
3107 lastStringContext=YY_START;
3108 BEGIN(CopyPHPString);
3112 *pCopyRoundString+=yytext;
3115 <CopyRound>{CHARLIT} {
3122 *pCopyRoundString+=yytext;
3125 <CopyRound>[^"'()\n]+ {
3126 *pCopyRoundString+=yytext;
3129 *pCopyRoundString+=*yytext;
3132 /* generic round bracket list copy rules for growable strings */
3134 *pCopyRoundGString+=*yytext;
3135 pCopyQuotedGString=pCopyRoundGString;
3136 lastStringContext=YY_START;
3140 *pCopyRoundGString+=*yytext;
3144 *pCopyRoundGString+=*yytext;
3146 BEGIN(lastRoundContext);
3150 *pCopyRoundGString+=*yytext;
3155 current->initializer+=yytext;
3156 pCopyQuotedGString = pCopyRoundGString;
3157 lastStringContext=YY_START;
3158 BEGIN(CopyPHPGString);
3162 *pCopyRoundGString+=yytext;
3165 <GCopyRound>{CHARLIT} {
3172 *pCopyRoundGString+=yytext;
3175 <GCopyRound>[^"'()\n/]+ {
3176 *pCopyRoundGString+=yytext;
3179 *pCopyRoundGString+=*yytext;
3182 /* generic curly bracket list copy rules */
3184 *pCopyCurlyString+=*yytext;
3185 pCopyQuotedString=pCopyCurlyString;
3186 lastStringContext=YY_START;
3190 *pCopyCurlyString+=*yytext;
3193 pCopyQuotedString=pCopyCurlyString;
3194 lastStringContext=YY_START;
3195 BEGIN(CopyPHPString);
3199 *pCopyCurlyString+=*yytext;
3203 *pCopyCurlyString+=*yytext;
3205 BEGIN(lastCurlyContext);
3207 <CopyCurly>{CHARLIT} { if (insidePHP)
3213 *pCopyCurlyString+=yytext;
3216 <CopyCurly>[^"'{}\/\n]+ {
3217 *pCopyCurlyString+=yytext;
3219 <CopyCurly>"/" { *pCopyCurlyString+=yytext; }
3222 *pCopyCurlyString+=*yytext;
3225 *pCopyCurlyString+=*yytext;
3228 /* generic curly bracket list copy rules for growable strings */
3229 <GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker
3231 <GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker
3232 QCString line = QCString(yytext);
3233 int s = line.find(' ');
3234 int e = line.find('"',s);
3235 yyLineNr = line.mid(s,e-s).toInt();
3236 if (yytext[yyleng-1]=='\n')
3243 *pCopyCurlyGString+=*yytext;
3244 pCopyQuotedGString=pCopyCurlyGString;
3245 lastStringContext=YY_START;
3249 *pCopyCurlyGString+=*yytext;
3252 pCopyQuotedGString=pCopyCurlyGString;
3253 lastStringContext=YY_START;
3254 BEGIN(CopyPHPGString);
3258 *pCopyCurlyGString+=*yytext;
3262 *pCopyCurlyGString+=*yytext;
3264 BEGIN(lastCurlyContext);
3266 <GCopyCurly>{CHARLIT} { if (insidePHP)
3272 *pCopyCurlyGString+=yytext;
3275 <GCopyCurly>[^"'{}\/\n,]+ {
3276 *pCopyCurlyGString+=yytext;
3279 *pCopyCurlyGString+=yytext;
3281 <GCopyCurly>"/" { *pCopyCurlyGString+=yytext; }
3284 *pCopyCurlyGString+=*yytext;
3287 *pCopyCurlyGString+=*yytext;
3290 /* ---------------------- */
3294 if (current->type.isEmpty() &&
3295 current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}'
3297 current->section=Entry::ENUM_SEC;
3298 current->name.resize(0);
3299 current->args.resize(0);
3300 BEGIN(EnumBaseType);
3304 if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;"
3307 current->name.sprintf("__pad%d__",padCount++);
3310 current->bitfields+=":";
3314 current->bitfields+=*yytext;
3317 current->args+=*yytext;
3324 QCString oldType = current->type;
3325 if (current->bodyLine==-1)
3327 current->bodyLine = yyLineNr;
3329 if ( insidePHP && current->type.left(3) == "var" )
3331 current->type = current->type.mid(3);
3333 if (isTypedef && current->type.left(8)!="typedef ")
3335 current->type.prepend("typedef ");
3337 bool needNewCurrent=FALSE;
3338 if (!current->name.isEmpty() && current->section!=Entry::ENUM_SEC)
3340 current->type=current->type.simplifyWhiteSpace();
3341 current->args=removeRedundantWhiteSpace(current->args);
3342 current->name=current->name.stripWhiteSpace();
3343 if (current->section==Entry::CLASS_SEC) // remove spec for "struct Bla bla;"
3347 current->section = Entry::VARIABLE_SEC ;
3348 current->fileName = yyFileName;
3349 current->startLine = yyBegLineNr;
3350 current->startColumn = yyBegColNr;
3351 current_root->addSubEntry( current ) ;
3352 needNewCurrent=TRUE;
3354 if ( *yytext == ',')
3356 bool stat = current->stat;
3359 current = new Entry(*current);
3362 current->stat = stat; // the static attribute holds for all variables
3363 current->name.resize(0);
3364 current->args.resize(0);
3365 current->brief.resize(0);
3366 current->doc.resize(0);
3367 current->initializer.resize(0);
3368 current->bitfields.resize(0);
3369 int i=oldType.length();
3370 while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--;
3371 current->type = oldType.left(i);
3379 current = new Entry ;
3381 else if (current->groups)
3383 current->groups->clear();
3391 (current->name.isEmpty() ||
3392 current->name=="typedef"
3394 ) // IDL function property
3397 lastSquareContext = YY_START;
3400 current->mtype = mtype;
3401 BEGIN( IDLAttribute );
3403 else if (insideCS &&
3404 current->name.isEmpty())
3407 lastSquareContext = YY_START;
3408 // Skip the C# attribute
3410 current->args.resize(0);
3411 BEGIN( SkipSquare );
3415 current->args += yytext ;
3421 // end of IDL function attribute
3422 if (--squareCount<=0)
3425 if (current->mtype == Property)
3426 BEGIN( IDLPropName );
3428 BEGIN( lastSquareContext );
3431 <IDLAttribute>"propput" {
3432 if (Config_getBool("IDL_PROPERTY_SUPPORT"))
3434 current->mtype = Property;
3436 current->spec |= Entry::Settable;
3438 <IDLAttribute>"propget" {
3439 if (Config_getBool("IDL_PROPERTY_SUPPORT"))
3441 current->mtype = Property;
3443 current->spec |= Entry::Gettable;
3445 <IDLAttribute>"property" { // UNO IDL property
3446 current->spec |= Entry::Property;
3448 <IDLAttribute>"attribute" { // UNO IDL attribute
3449 current->spec |= Entry::Attribute;
3451 <IDLAttribute>"optional" { // on UNO IDL interface/service/attribute/property
3452 current->spec |= Entry::Optional;
3454 <IDLAttribute>"readonly" { // on UNO IDL attribute or property
3455 current->spec |= Entry::Readonly;
3457 <IDLAttribute>"bound" { // on UNO IDL attribute or property
3458 current->spec |= Entry::Bound;
3460 <IDLAttribute>"removable" { // on UNO IDL property
3461 current->spec |= Entry::Removable;
3463 <IDLAttribute>"constrained" { // on UNO IDL property
3464 current->spec |= Entry::Constrained;
3466 <IDLAttribute>"transient" { // on UNO IDL property
3467 current->spec |= Entry::Transient;
3469 <IDLAttribute>"maybevoid" { // on UNO IDL property
3470 current->spec |= Entry::MaybeVoid;
3472 <IDLAttribute>"maybedefault" { // on UNO IDL property
3473 current->spec |= Entry::MaybeDefault;
3475 <IDLAttribute>"maybeambiguous" { // on UNO IDL property
3476 current->spec |= Entry::MaybeAmbiguous;
3480 <IDLPropName>{BN}*{ID}{BN}* {
3481 // return type (probably HRESULT) - skip it
3483 <IDLPropName>{ID}{BN}*"(" {
3484 current->name = yytext;
3485 current->name = current->name.left(current->name.length()-1).stripWhiteSpace();
3486 current->startLine = yyLineNr;
3487 current->startColumn = yyColNr;
3490 <IDLProp>{BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter
3492 idlAttr=idlAttr.stripWhiteSpace();
3494 <IDLProp>{ID} { // property type
3497 <IDLProp>{BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);)
3499 current->args = "(";
3501 current->args += ", ";
3502 current->args += idlAttr;
3503 current->args += " ";
3504 current->args += idlProp; // prop was actually type of extra parameter
3505 current->args += " ";
3506 current->args += yytext;
3507 current->args = current->args.left(current->args.length() - 1); // strip comma
3512 <IDLProp>{BN}*{ID}{BN}*")"{BN}* {
3513 // the parameter name for the property - just skip.
3516 current->fileName = yyFileName;
3517 current->type = idlProp;
3518 current->args = current->args.simplifyWhiteSpace();
3520 current->args += ")";
3521 current->name = current->name.stripWhiteSpace();
3522 current->section = Entry::VARIABLE_SEC;
3523 current_root->addSubEntry(current);
3524 current = new Entry;
3526 BEGIN( FindMembers );
3528 <IDLProp>. { // spaces, *, or other stuff
3531 <Array>"]" { current->args += *yytext ;
3532 if (--squareCount<=0)
3533 BEGIN( FindMembers ) ;
3535 <FuncFuncArray>"]" { current->args += *yytext ;
3536 if (--squareCount<=0)
3539 <Array,FuncFuncArray>"[" { current->args += *yytext ;
3542 <Array,FuncFuncArray>. { current->args += *yytext ; }
3543 <SkipSquare>"[" { squareCount++; }
3545 if (--squareCount<=0)
3546 BEGIN( lastSquareContext );
3549 lastStringContext=YY_START;
3550 BEGIN( SkipString );
3552 <SkipSquare>[^\n\[\]\"]+
3553 <FindMembers>"<" { addType( current ) ;
3554 current->type += yytext ;
3557 <Sharp>">" { current->type += *yytext ;
3558 if (--sharpCount<=0)
3559 BEGIN( FindMembers ) ;
3561 <Sharp>"<" { current->type += *yytext ;
3567 <Sharp>. { current->type += *yytext ; }
3569 if (insideCpp || insideObjC)
3571 current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
3573 current->bodyLine = yyLineNr;
3574 current->name = yytext;
3577 // Java enum initializer
3579 lastInitializerContext = YY_START;
3581 current->initializer = "=";
3582 BEGIN(ReadInitializer);
3585 lastInitializerContext = YY_START;
3587 current->initializer = yytext;
3588 BEGIN(ReadInitializer);
3591 if (insideJava) // last enum field in Java class
3593 if (!current->name.isEmpty())
3595 current->fileName = yyFileName;
3596 current->startLine = yyLineNr;
3597 current->startColumn = yyColNr;
3598 current->type = "@"; // enum marker
3599 current->args = current->args.simplifyWhiteSpace();
3600 current->name = current->name.stripWhiteSpace();
3601 current->section = Entry::VARIABLE_SEC;
3602 current_root->addSubEntry(current);
3603 current = new Entry ;
3607 BEGIN( FindMembers );
3617 <SkipRemainder>[^\n]*
3619 //printf("adding `%s' `%s' `%s' to enum `%s' (mGrpId=%d)\n",
3620 // current->type.data(), current->name.data(),
3621 // current->args.data(), current_root->name.data(),current->mGrpId);
3622 if (!current->name.isEmpty())
3624 current->fileName = yyFileName;
3625 current->startLine = yyLineNr;
3626 current->startColumn = yyColNr;
3627 if (!(current_root->spec&Entry::Enum))
3629 current->type = "@"; // enum marker
3631 current->args = current->args.simplifyWhiteSpace();
3632 current->name = current->name.stripWhiteSpace();
3633 current->section = Entry::VARIABLE_SEC;
3634 // add to the scope of the enum
3635 current_root->addSubEntry(current);
3636 if (!insideCS && !insideJava &&
3637 !(current_root->spec&Entry::Strong))
3638 // for C# and Java 1.5+ enum values always have to be explicitly qualified,
3639 // same for C++11 style enums (enum class Name {})
3641 current = new Entry(*current);
3642 // add to the scope surrounding the enum (copy!)
3643 current_root->parent()->addSubEntry(current);
3645 current = new Entry ;
3648 else // probably a redundant ,
3654 <FindFields>"[" { // attribute list in IDL
3656 lastSquareContext = YY_START;
3660 <FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); }
3662 <ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<]* { current->program += yytext ; }
3663 <ReadBody,ReadNSBody,ReadBodyIntf>"//".* { current->program += yytext ; }
3664 <ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!insidePHP)
3666 // append PHP comment.
3667 current->program += yytext ;
3669 <ReadBody,ReadNSBody,ReadBodyIntf>@\" { current->program += yytext ;
3670 pSkipVerbString = ¤t->program;
3671 lastSkipVerbStringContext=YY_START;
3672 BEGIN( SkipVerbString );
3674 <ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (insidePHP)
3676 current->program += yytext ;
3677 pCopyHereDocGString = ¤t->program;
3678 lastHereDocContext=YY_START;
3679 BEGIN( CopyHereDoc );
3686 <ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ;
3687 pCopyQuotedGString = ¤t->program;
3688 lastStringContext=YY_START;
3689 BEGIN( CopyGString );
3691 <ReadBody,ReadNSBody,ReadBodyIntf>"/*"{B}* { current->program += yytext ;
3692 lastContext = YY_START ;
3695 <ReadBody,ReadNSBody,ReadBodyIntf>"/*"{BL} { current->program += yytext ;
3697 lastContext = YY_START ;
3700 <ReadBody,ReadNSBody,ReadBodyIntf>"'" {
3703 current->program += yytext;
3706 { // begin of single quoted string
3707 current->program += yytext;
3708 pCopyQuotedGString = ¤t->program;
3709 lastStringContext=YY_START;
3710 BEGIN(CopyPHPGString);
3713 <ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT} {
3716 REJECT; // for PHP code single quotes
3717 // are used for strings of arbitrary length
3721 current->program += yytext;
3724 <ReadBody,ReadNSBody,ReadBodyIntf>"{" { current->program += yytext ;
3728 current->program += yytext ;
3731 <ReadBody,ReadNSBody>"}" { //err("ReadBody count=%d\n",curlyCount);
3734 current->program += yytext ;
3739 current->endBodyLine = yyLineNr;
3740 QCString &cn = current->name;
3741 QCString rn = current_root->name.copy();
3742 //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef);
3743 if (!cn.isEmpty() && !rn.isEmpty())
3747 if (isTypedef && cn.isEmpty())
3749 //printf("Typedef Name\n");
3750 BEGIN( TypedefName );
3754 if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum))
3756 current->program+=','; // add field terminator
3758 // add compound definition to the tree
3759 current->args=removeRedundantWhiteSpace(current->args);
3760 // was: current->args.simplifyWhiteSpace();
3761 current->type = current->type.simplifyWhiteSpace();
3762 current->name = current->name.stripWhiteSpace();
3763 //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);
3765 ((current->spec&Entry::Interface) || (current->spec==Entry::Category))
3766 ) // method definition follows
3768 BEGIN( ReadBodyIntf ) ;
3772 current_root->addSubEntry( current ) ;
3773 memspecEntry = current;
3774 current = new Entry(*current);
3775 if (current->section==Entry::NAMESPACE_SEC ||
3776 (current->spec==Entry::Interface) ||
3777 insideJava || insidePHP || insideCS || insideD || insideJS
3779 { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
3783 BEGIN( FindMembers ) ;
3787 static QRegExp re("@[0-9]+$");
3788 if (!isTypedef && memspecEntry &&
3789 memspecEntry->name.find(re)==-1) // not typedef or anonymous type (see bug691071)
3791 // enabled the next two lines for bug 623424
3792 current->doc.resize(0);
3793 current->brief.resize(0);
3795 BEGIN( MemberSpec ) ;
3801 <ReadBody>"}"{BN}+"typedef"{BN}+ { //err("ReadBody count=%d\n",curlyCount);
3805 current->program += yytext ;
3811 current->endBodyLine = yyLineNr;
3812 QCString &cn = current->name;
3813 QCString rn = current_root->name.copy();
3814 if (!cn.isEmpty() && !rn.isEmpty())
3818 BEGIN( TypedefName );
3821 <TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
3823 current->type.prepend(yytext);
3826 if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum))
3828 current->program+=","; // add field terminator
3830 current->name=yytext;
3832 current->args = current->args.simplifyWhiteSpace();
3833 current->type = current->type.simplifyWhiteSpace();
3834 //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data());
3835 current_root->addSubEntry( current ) ;
3836 if (!firstTypedefEntry)
3838 firstTypedefEntry = current;
3840 current = new Entry;
3842 isTypedef=TRUE; // to undo reset by initEntry()
3843 BEGIN(MemberSpecSkip);
3845 <TypedefName>";" { /* typedef of anonymous type */
3846 current->name.sprintf("@%d",anonCount++);
3847 if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum))
3849 current->program+=','; // add field terminator
3851 // add compound definition to the tree
3852 current->args = current->args.simplifyWhiteSpace();
3853 current->type = current->type.simplifyWhiteSpace();
3854 current_root->addSubEntry( current ) ;
3855 memspecEntry = current;
3856 current = new Entry(*current);
3859 BEGIN( MemberSpec ) ;
3861 <MemberSpec>([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved.
3863 int i=0,l=(int)yyleng,j;
3864 while (i<l && (!isId(yytext[i]))) i++;
3865 msName = QCString(yytext).right(l-i).stripWhiteSpace();
3869 msArgs=msName.right(msName.length()-j);
3870 msName=msName.left(j);
3872 msType=QCString(yytext).left(i);
3874 // handle *pName in: typedef { ... } name, *pName;
3875 if (firstTypedefEntry)
3877 if (firstTypedefEntry->spec&Entry::Struct)
3879 msType.prepend("struct "+firstTypedefEntry->name);
3881 else if (firstTypedefEntry->spec&Entry::Union)
3883 msType.prepend("union "+firstTypedefEntry->name);
3885 else if (firstTypedefEntry->section==Entry::ENUM_SEC)
3887 msType.prepend("enum "+firstTypedefEntry->name);
3891 msType.prepend(firstTypedefEntry->name);
3895 <MemberSpec>"(" { // function with struct return type
3897 current->name = msName;
3903 if (msName.isEmpty() && !current->name.isEmpty())
3905 // see if the compound does not have a name or is inside another
3906 // anonymous compound. If so we insert a
3907 // special `anonymous' variable.
3908 //Entry *p=current_root;
3912 // only look for class scopes, not namespace scopes
3913 if ((p->section & Entry::COMPOUND_MASK) && !p->name.isEmpty())
3915 //printf("Trying scope `%s'\n",p->name.data());
3916 int i=p->name.findRev("::");
3917 int pi = (i==-1) ? 0 : i+2;
3918 if (p->name.at(pi)=='@')
3920 // anonymous compound inside -> insert dummy variable name
3921 //printf("Adding anonymous variable for scope %s\n",p->name.data());
3922 msName.sprintf("@%d",anonCount++);
3927 if (p==current) p=current_root; else p=p->parent();
3930 //printf("msName=%s current->name=%s\n",msName.data(),current->name.data());
3931 if (!msName.isEmpty()
3932 /*&& msName!=current->name*/) // skip typedef T {} T;, removed due to bug608493
3934 static bool typedefHidesStruct = Config_getBool("TYPEDEF_HIDES_STRUCT");
3935 // case 1: typedef struct _S { ... } S_t;
3936 // -> omit typedef and use S_t as the struct name
3937 if (typedefHidesStruct &&
3939 ((current->spec&(Entry::Struct|Entry::Union)) ||
3940 current->section==Entry::ENUM_SEC )&&
3941 msType.stripWhiteSpace().isEmpty() &&
3944 memspecEntry->name=msName;
3946 else // case 2: create a typedef field
3948 Entry *varEntry=new Entry;
3949 varEntry->lang = language;
3950 varEntry->protection = current->protection ;
3951 varEntry->mtype = current->mtype;
3952 varEntry->virt = current->virt;
3953 varEntry->stat = current->stat;
3954 varEntry->section = Entry::VARIABLE_SEC;
3955 varEntry->name = msName.stripWhiteSpace();
3956 varEntry->type = current->type.simplifyWhiteSpace()+" ";
3957 varEntry->args = msArgs;
3960 varEntry->type.prepend("typedef ");
3961 // //printf("current->name = %s %s\n",current->name.data(),msName.data());
3963 if (typedefHidesStruct &&
3965 (current->spec&(Entry::Struct|Entry::Union)) &&
3967 ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
3969 varEntry->type+=memspecEntry->name+msType;
3971 else // case 2: use _S as type for for pS_t
3973 varEntry->type+=current->name+msType;
3975 varEntry->fileName = yyFileName;
3976 varEntry->startLine = yyLineNr;
3977 varEntry->startColumn = yyColNr;
3978 varEntry->doc = current->doc.copy();
3979 varEntry->brief = current->brief.copy();
3980 varEntry->mGrpId = current->mGrpId;
3981 varEntry->initializer = current->initializer;
3983 // deep copy group list
3984 QListIterator<Grouping> gli(*current->groups);
3986 for (;(g=gli.current());++gli)
3988 varEntry->groups->append(new Grouping(*g));
3990 if (current->sli) // copy special list items
3992 QListIterator<ListItemInfo> li(*current->sli);
3994 for (li.toFirst();(lii=li.current());++li)
3996 varEntry->addSpecialListItem(lii->type,lii->itemId);
4000 //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n",
4001 // varEntry->type.data(),varEntry->name.data(),
4002 // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data());
4003 current_root->addSubEntry(varEntry);
4006 if (*yytext==';') // end of a struct/class ...
4008 if (!isTypedef && msName.isEmpty() && memspecEntry && (current->section&Entry::COMPOUND_MASK))
4009 { // case where a class/struct has a doc block after it
4010 if (!current->doc.isEmpty())
4012 memspecEntry->doc += current->doc;
4014 if (!current->brief.isEmpty())
4016 memspecEntry->brief += current->brief;
4023 firstTypedefEntry=0;
4027 BEGIN( FindMembers );
4031 current->doc.resize(0);
4032 current->brief.resize(0);
4037 lastInitializerContext=YY_START;
4039 current->initializer = yytext;
4040 BEGIN(ReadInitializer);
4041 /* BEGIN(MemberSpecSkip); */
4044 <MemberSpecSkip>"{" {
4046 lastCurlyContext = MemberSpecSkip;
4051 <MemberSpecSkip>"," { BEGIN(MemberSpec); }
4052 <MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); }
4053 <ReadBody,ReadNSBody,ReadBodyIntf>{BN}{1,80} { current->program += yytext ;
4056 <ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block
4057 current_root->addSubEntry( current ) ;
4061 BEGIN( FindMembers );
4063 <ReadBody,ReadNSBody,ReadBodyIntf>. { current->program += yytext ; }
4065 <FindMembers>"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
4066 <FindMembers>("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */
4067 if (insidePHP) // reference parameter
4073 current->bodyLine = yyLineNr;
4078 //current->type += yytext;
4082 <FuncPtr>{SCOPENAME} {
4083 current->name = yytext;
4084 if (nameIsOperator(current->name))
4086 BEGIN( FuncPtrOperator );
4090 if (current->name=="const" || current->name=="volatile")
4092 funcPtrType += current->name;
4096 BEGIN( EndFuncPtr );
4101 //printf("error: FuncPtr `%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName);
4103 <FuncPtrOperator>"("{BN}*")"{BN}*/"(" {
4104 current->name += yytext;
4105 current->name = current->name.simplifyWhiteSpace();
4108 <FuncPtrOperator>\n {
4110 current->name += *yytext;
4112 <FuncPtrOperator>"(" {
4114 BEGIN( EndFuncPtr );
4116 <FuncPtrOperator>. {
4117 current->name += *yytext;
4119 <EndFuncPtr>")"{BN}*/";" { // a variable with extra braces
4121 current->type+=funcPtrType.data()+1;
4124 <EndFuncPtr>")"{BN}*/"(" { // a function pointer
4126 current->type+=funcPtrType+")";
4129 <EndFuncPtr>")"{BN}*/"[" { // an array of variables
4131 current->type+=funcPtrType.data();
4132 current->args += ")";
4135 <EndFuncPtr>"(" { // a function returning a function or
4136 // a function returning a pointer to an array
4137 current->args += *yytext ;
4139 //BEGIN( FuncFunc );
4140 current->bodyLine = yyLineNr;
4141 currentArgumentContext = FuncFuncEnd;
4142 fullArgString=current->args.copy();
4143 copyArgString=¤t->args;
4144 BEGIN( ReadFuncArgType ) ;
4146 <EndFuncPtr>"["[^\n\]]*"]" {
4147 funcPtrType+=yytext;
4153 current->args += *yytext ;
4157 current->args += *yytext ;
4165 <FuncFuncEnd>")"{BN}*"(" {
4167 current->type+=funcPtrType+")(";
4168 BEGIN(FuncFuncType);
4170 <FuncFuncEnd>")"{BN}*/[;{] {
4172 current->type+=funcPtrType.data()+1;
4175 <FuncFuncEnd>")"{BN}*/"[" { // function returning a pointer to an array
4177 current->type+=funcPtrType;
4179 BEGIN(FuncFuncArray);
4182 current->args += *yytext;
4185 current->type += *yytext;
4189 current->type += *yytext;
4195 <FuncFuncType>{BN}*","{BN}* { lineCount() ; current->type += ", " ; }
4196 <FuncFuncType>{BN}+ { lineCount() ; current->type += ' ' ; }
4198 current->type += *yytext;
4200 <FindMembers>"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")(" { // for catching typedef void (__stdcall *f)() like definitions
4201 if (current->type.left(7)=="typedef" && current->bodyLine==-1)
4202 // the bodyLine check is to prevent this guard to be true more than once
4204 current->bodyLine = yyLineNr;
4205 BEGIN( GetCallType );
4207 else if (!current->name.isEmpty()) // normal function
4209 current->args = yytext;
4210 current->bodyLine = yyLineNr;
4211 currentArgumentContext = FuncQual;
4212 fullArgString=current->args.copy();
4213 copyArgString=¤t->args;
4214 BEGIN( ReadFuncArgType ) ;
4215 //printf(">>> Read function arguments!\n");
4218 <GetCallType>{BN}*{ID}{BN}*"*" {
4222 funcPtrType+=yytext;
4227 if (!current->name.isEmpty())
4229 current->args = yytext;
4230 current->bodyLine = yyLineNr;
4231 currentArgumentContext = FuncQual;
4232 fullArgString=current->args.copy();
4233 copyArgString=¤t->args;
4234 BEGIN( ReadFuncArgType ) ;
4235 //printf(">>> Read function arguments current->argList->count()=%d\n",current->argList->count());
4239 <FindMembers>"("{BN}*("void"{BN}*)?")" {
4241 current->args = "()";
4246 /*- Function argument reading rules ---------------------------------------*/
4248 <ReadFuncArgType>[^ \/\r\t\n\)\(\"\'#]+ { *copyArgString+=yytext;
4249 fullArgString+=yytext;
4251 <CopyArgString,CopyArgPHPString>[^\n\\\"\']+ { *copyArgString+=yytext;
4252 fullArgString+=yytext;
4254 <CopyArgRound>[^\/\n\)\(\"\']+ {
4255 *copyArgString+=yytext;
4256 fullArgString+=yytext;
4258 <ReadFuncArgType,ReadTempArgs>{BN}* {
4259 *copyArgString+=" ";
4263 <ReadFuncArgType,CopyArgRound,CopyArgSharp,ReadTempArgs>{RAWBEGIN} {
4264 g_delimiter = yytext+2;
4265 g_delimiter=g_delimiter.left(g_delimiter.length()-1);
4266 lastRawStringContext = YY_START;
4267 pCopyRawString = copyArgString;
4268 *pCopyRawString+=yytext;
4269 fullArgString+=yytext;
4272 <ReadFuncArgType,CopyArgRound,CopyArgSharp,ReadTempArgs>\" {
4273 *copyArgString+=*yytext;
4274 fullArgString+=*yytext;
4275 lastCopyArgStringContext = YY_START;
4276 BEGIN( CopyArgString );
4278 <ReadFuncArgType,ReadTempArgs>"(" {
4279 *copyArgString+=*yytext;
4280 fullArgString+=*yytext;
4282 lastCopyArgContext = YY_START;
4283 BEGIN( CopyArgRound );
4285 <ReadFuncArgType>")" {
4286 *copyArgString+=*yytext;
4287 fullArgString+=*yytext;
4288 stringToArgumentList(fullArgString,current->argList);
4291 fixArgumentListForJavaScript(current->argList);
4293 handleParametersCommentBlocks(current->argList);
4295 /* remember the current documentation block, since
4296 we could overwrite it with the documentation of
4297 a function argument, which we then have to correct later
4300 docBackup = current->doc;
4301 briefBackup = current->brief;
4303 BEGIN( currentArgumentContext );
4305 /* a special comment */
4306 <ReadFuncArgType,ReadTempArgs>("/*"[*!]|"//"[/!])("<"?) {
4307 if (currentArgumentContext==DefineEnd)
4309 // for defines we interpret a comment
4310 // as documentation for the define
4311 int i;for (i=(int)yyleng-1;i>=0;i--)
4315 stringToArgumentList(fullArgString,current->argList);
4316 handleParametersCommentBlocks(current->argList);
4317 BEGIN( currentArgumentContext );
4319 else // not a define
4321 // for functions we interpret a comment
4322 // as documentation for the argument
4323 fullArgString+=yytext;
4325 lastCommentInArgContext=YY_START;
4327 BEGIN( CopyArgCommentLine );
4329 BEGIN( CopyArgComment );
4332 /* a non-special comment */
4333 <ReadFuncArgType,ReadTempArgs>"/**/" { /* empty comment */ }
4334 <ReadFuncArgType,ReadTempArgs>"/*" {
4335 lastCContext = YY_START;
4336 BEGIN( SkipComment );
4338 <ReadFuncArgType,ReadTempArgs>"//" {
4339 lastCContext = YY_START;
4340 BEGIN( SkipCxxComment );
4343 <ReadFuncArgType,ReadTempArgs>"'#" { if (insidePHP)
4345 *copyArgString+=yytext;
4346 fullArgString+=yytext;
4348 <ReadFuncArgType,ReadTempArgs>"#" {
4351 lastCContext = YY_START;
4352 BEGIN( SkipCxxComment );
4355 /* `)' followed by a special comment */
4356 <ReadFuncArgType>")"{BN}*("/*"[*!]|"//"[/!])"<" {
4358 if (currentArgumentContext==DefineEnd)
4360 // for defines we interpret a comment
4361 // as documentation for the define
4362 int i;for (i=(int)yyleng-1;i>0;i--)
4366 *copyArgString+=*yytext;
4367 fullArgString+=*yytext;
4368 stringToArgumentList(fullArgString,current->argList);
4369 handleParametersCommentBlocks(current->argList);
4370 BEGIN( currentArgumentContext );
4374 // for functions we interpret a comment
4375 // as documentation for the last argument
4376 lastCopyArgChar=*yytext;
4377 QCString text=&yytext[1];
4378 text=text.stripWhiteSpace();
4379 lastCommentInArgContext=YY_START;
4380 fullArgString+=text;
4381 if (text.find("//")!=-1)
4382 BEGIN( CopyArgCommentLine );
4384 BEGIN( CopyArgComment );
4387 <CopyArgComment>^{B}*"*"+/{BN}+
4388 <CopyArgComment>[^\n\\\@\*]+ { fullArgString+=yytext; }
4389 <CopyArgComment>"*/" { fullArgString+=yytext;
4390 if (lastCopyArgChar!=0)
4391 unput(lastCopyArgChar);
4392 BEGIN( lastCommentInArgContext );
4394 <CopyArgCommentLine>\n { fullArgString+=yytext;
4396 if (lastCopyArgChar!=0)
4397 unput(lastCopyArgChar);
4398 BEGIN( lastCommentInArgContext );
4400 <CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!)
4401 docBlockName=&yytext[1];
4402 fullArgString+=yytext;
4403 BEGIN(CopyArgVerbatim);
4405 <CopyArgCommentLine>{CMD}("f$"|"f["|"f{") {
4406 docBlockName=&yytext[1];
4407 if (docBlockName.at(1)=='[')
4409 docBlockName.at(1)='}';
4411 if (docBlockName.at(1)=='{')
4413 docBlockName.at(1)='}';
4415 fullArgString+=yytext;
4416 BEGIN(CopyArgVerbatim);
4418 <CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9] { // end of verbatim block
4419 fullArgString+=yytext;
4420 if (yytext[1]=='f') // end of formula
4422 BEGIN(CopyArgCommentLine);
4424 if (&yytext[4]==docBlockName)
4426 BEGIN(CopyArgCommentLine);
4429 <CopyArgCommentLine>[^\\\@\n]+ { fullArgString+=yytext; }
4430 <CopyArgCommentLine>. { fullArgString+=*yytext; }
4431 <CopyArgComment,CopyArgVerbatim>\n { fullArgString+=*yytext; lineCount(); }
4432 <CopyArgComment,CopyArgVerbatim>. { fullArgString+=*yytext; }
4433 <CopyArgComment>{CMD}("brief"|"short"){B}+ {
4434 warn(yyFileName,yyLineNr,
4435 "Ignoring %cbrief command inside argument documentation",*yytext
4440 *copyArgString+=*yytext;
4441 fullArgString+=*yytext;
4443 BEGIN( CopyArgSharp );
4446 *copyArgString+=*yytext;
4447 fullArgString+=*yytext;
4448 //printf("end template list %s\n",copyArgString->data());
4449 stringToArgumentList(fullArgString,currentArgumentList);
4450 BEGIN( currentArgumentContext );
4454 *copyArgString+=*yytext;
4455 fullArgString+=*yytext;
4458 *copyArgString+=*yytext;
4459 fullArgString+=*yytext;
4460 if (argRoundCount>0)
4463 BEGIN( lastCopyArgContext );
4466 *copyArgString+=*yytext;
4467 fullArgString+=*yytext;
4469 lastCopyArgContext = YY_START;
4470 BEGIN( CopyArgRound );
4474 //printf("argSharpCount++=%d copy\n",argSharpCount);
4475 *copyArgString+=*yytext;
4476 fullArgString+=*yytext;
4479 *copyArgString+=*yytext;
4480 fullArgString+=*yytext;
4482 if (argSharpCount>0)
4484 //printf("argSharpCount--=%d copy\n",argSharpCount);
4488 BEGIN( ReadTempArgs );
4489 //printf("end of argSharpCount\n");
4492 <CopyArgString,CopyArgPHPString>\\. {
4493 *copyArgString+=yytext;
4494 fullArgString+=yytext;
4497 *copyArgString+=*yytext;
4498 fullArgString+=*yytext;
4499 BEGIN( lastCopyArgStringContext );
4501 <CopyArgPHPString>\' {
4502 *copyArgString+=*yytext;
4503 fullArgString+=*yytext;
4504 BEGIN( lastCopyArgStringContext );
4506 <ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>{CHARLIT} {
4513 *copyArgString+=yytext;
4514 fullArgString+=yytext;
4517 <ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>\' {
4518 *copyArgString+=yytext;
4519 fullArgString+=yytext;
4522 lastCopyArgStringContext=YY_START;
4523 BEGIN(CopyArgPHPString);
4526 <ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSharp>\n {
4528 *copyArgString+=*yytext;
4529 fullArgString+=*yytext;
4531 <ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSharp>. {
4532 *copyArgString+=*yytext;
4533 fullArgString+=*yytext;
4538 /*------------------------------------------------------------------------*/
4541 <FuncRound>"(" { current->args += *yytext ;
4544 <FuncRound>")" { current->args += *yytext ;
4551 <FuncQual>"#" { if (insidePHP)
4553 lastCPPContext = YY_START;
4558 if ( qstrcmp(yytext,";")==0 &&
4560 !containsWord(current->type,"function") )
4564 BEGIN( FindMembers );
4568 unput(*yytext); BEGIN( Function );
4571 <FuncQual>{BN}*"abstract"{BN}* { // pure virtual member function
4573 current->virt = Pure;
4574 current->args += " override ";
4576 <FuncQual,TrailingReturn>{BN}*"override"{BN}* { // C++11 overridden virtual member function
4578 current->spec |= Entry::Override;
4579 current->args += " override ";
4582 <FuncQual,TrailingReturn>{BN}*"final"{BN}* { // C++11 final method
4584 current->spec |= Entry::Final;
4585 current->args += " final ";
4588 <FuncQual>{BN}*"sealed"{BN}* { // sealed member function
4590 current->spec |= Entry::Sealed;
4591 current->args += " sealed ";
4593 <FuncQual>{BN}*"new"{BN}* { // new member function
4595 current->spec |= Entry::New;
4596 current->args += " new ";
4598 <FuncQual>{BN}*"const"{BN}* { // const member function
4600 current->args += " const ";
4601 current->argList->constSpecifier=TRUE;
4603 <FuncQual>{BN}*"volatile"{BN}* { // volatile member function
4605 current->args += " volatile ";
4606 current->argList->volatileSpecifier=TRUE;
4608 <FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier
4610 current->args += " noexcept ";
4611 current->spec |= Entry::NoExcept;
4613 <FuncQual>{BN}*"noexcept"{BN}*"(" { // noexcept expression
4615 current->args += " noexcept(";
4616 current->spec |= Entry::NoExcept;
4617 lastRoundContext=FuncQual;
4618 pCopyRoundString=¤t->args;
4622 <FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function
4624 current->args += " = 0";
4625 current->virt = Pure;
4626 current->argList->pureSpecifier=TRUE;
4629 <FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member
4631 current->args += " = delete";
4632 current->spec |= Entry::Delete;
4635 <FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator
4637 current->args += " = default";
4638 current->spec |= Entry::Default;
4641 <FuncQual>{BN}*"->"{BN}* {
4643 current->argList->trailingReturnType = " -> ";
4644 current->args += " -> ";
4645 BEGIN(TrailingReturn);
4647 <TrailingReturn>[{;] {
4652 current->argList->trailingReturnType+=yytext;
4653 current->args+=yytext;
4655 <TrailingReturn>\n {
4657 current->argList->trailingReturnType+=yytext;
4660 <FuncRound,FuncFunc>{BN}*","{BN}* {
4662 current->args += ", " ;
4664 <FuncQual,FuncRound,FuncFunc>{BN}+ {
4666 current->args += ' ' ;
4668 <Function,FuncQual,FuncRound,FuncFunc>"#" { if (insidePHP)
4670 lastCPPContext = YY_START;
4675 (current_root->section&Entry::COMPOUND_MASK)
4682 // typically an initialized function pointer
4683 lastInitializerContext=YY_START;
4685 current->initializer = yytext;
4686 BEGIN(ReadInitializer);
4705 current->args += *yytext;
4706 pCopyQuotedString=¤t->args;
4707 lastStringContext=FuncPtrInit;
4711 current->args += *yytext;
4714 pCopyQuotedString=¤t->args;
4715 lastStringContext=FuncPtrInit;
4716 BEGIN(CopyPHPString);
4719 <FuncPtrInit>{CHARLIT} {
4726 current->args += yytext;
4730 current->args += yytext;
4733 current->args += *yytext;
4736 current->args += *yytext;
4739 <FuncQual>{ID} { // typically a K&R style C function
4740 if (insideCS && qstrcmp(yytext,"where")==0)
4742 // type contraint for a method
4743 delete current->typeConstr;
4744 current->typeConstr = new ArgumentList;
4745 current->typeConstr->append(new Argument);
4746 lastCSConstraint = YY_START;
4747 BEGIN( CSConstraintName );
4749 else if (checkForKnRstyleC())
4751 current->args = yytext;
4752 oldStyleArgType.resize(0);
4753 BEGIN(OldStyleArgs);
4757 current->args += yytext;
4760 <OldStyleArgs>[,;] {
4761 QCString oldStyleArgPtr;
4762 QCString oldStyleArgName;
4763 splitKnRArg(oldStyleArgPtr,oldStyleArgName);
4765 if (current->doc!=docBackup)
4767 doc=current->doc.copy();
4768 current->doc=docBackup;
4770 if (current->brief!=briefBackup)
4772 brief=current->brief.copy();
4773 current->brief=briefBackup;
4775 addKnRArgInfo(oldStyleArgType+oldStyleArgPtr,
4776 oldStyleArgName,brief,doc);
4777 current->args.resize(0);
4778 if (*yytext==';') oldStyleArgType.resize(0);
4780 <OldStyleArgs>{ID} { current->args += yytext; }
4782 current->args = argListToString(current->argList);
4786 <OldStyleArgs>. { current->args += *yytext; }
4787 <FuncQual,FuncRound,FuncFunc>. { current->args += *yytext; }
4788 <FuncQual>{BN}*"try:" |
4789 <FuncQual>{BN}*"try"{BN}+ { /* try-function-block */
4790 insideTryBlock=TRUE;
4792 if (yytext[yyleng-1]==':')
4798 <FuncQual>{BN}*"throw"{BN}*"(" { // C++ style throw clause
4799 current->exception = " throw (" ;
4802 BEGIN( ExcpRound ) ;
4804 <FuncQual>{BN}*"raises"{BN}*"(" {
4805 current->exception = " raises (" ;
4808 BEGIN( ExcpRound ) ;
4810 <FuncQual>{BN}*"throws"{BN}+ { // Java style throw clause
4811 current->exception = " throws " ;
4815 <ExcpRound>"(" { current->exception += *yytext ;
4818 <ExcpRound>")" { current->exception += *yytext ;
4825 current->exception += *yytext;
4828 unput('{'); BEGIN( FuncQual );
4831 unput(';'); BEGIN( FuncQual );
4834 current->exception += ' ';
4838 current->exception += *yytext;
4840 <Function>"(" { current->type += current->name ;
4841 current->name = current->args ;
4842 current->args = yytext ;
4844 BEGIN( FuncRound ) ;
4847 if (!insidePHP) BEGIN(SkipInits);
4850 current->name=current->name.simplifyWhiteSpace();
4851 current->type=current->type.simplifyWhiteSpace();
4852 current->args=removeRedundantWhiteSpace(current->args);
4853 // was: current->args.simplifyWhiteSpace();
4854 current->fileName = yyFileName;
4855 current->startLine = yyBegLineNr;
4856 current->startColumn = yyBegColNr;
4857 static QRegExp re("([^)]*[*&][^)]*)"); // (...*...)
4858 if (*yytext!=';' || (current_root->section&Entry::COMPOUND_MASK) )
4860 int tempArg=current->name.find('<');
4861 int ts=current->type.find('<');
4862 int te=current->type.findRev('>');
4863 int ti=current->type.find(re,0);
4865 // bug677315: A<int(void *, char *)> get(); is not a function pointer
4866 bool isFunction = ti==-1 || // not a (...*...) pattern
4867 (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list
4869 //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n",
4870 // current->type.data(),ts,te,ti,isFunction);
4872 if (tempArg==-1) tempName=current->name; else tempName=current->name.left(tempArg);
4873 if (!current->type.isEmpty() &&
4874 (!isFunction || current->type.left(8)=="typedef "))
4876 //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data());
4877 if (isTypedef && current->type.left(8)!="typedef ")
4879 current->type.prepend("typedef ");
4881 current->section = Entry::VARIABLE_SEC ;
4885 //printf("Scanner.l: found in class function: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data());
4886 current->section = Entry::FUNCTION_SEC ;
4887 current->proto = *yytext==';';
4890 else // a global function prototype or function variable
4892 //printf("Scanner.l: prototype? type=`%s' name=`%s' args=`%s'\n",current->type.data(),current->name.data(),current->args.data());
4893 if (!current->type.isEmpty() &&
4894 (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef "))
4896 if (isTypedef && current->type.left(8)!="typedef ")
4898 current->type.prepend("typedef ");
4900 //printf("Scanner.l: found function variable!\n");
4901 current->section = Entry::VARIABLE_SEC;
4905 //printf("Scanner.l: found prototype\n");
4906 current->section = Entry::FUNCTION_SEC;
4907 current->proto = TRUE;
4910 //printf("Adding entry `%s'\n",current->name.data());
4913 if (findAndRemoveWord(current->type,"final"))
4915 current->spec |= Entry::Final;
4917 if (findAndRemoveWord(current->type,"abstract"))
4919 current->spec |= Entry::Abstract;
4922 if ( insidePHP && !containsWord(current->type,"function"))
4925 if ( *yytext == '{' )
4927 lastCurlyContext = FindMembers;
4933 BEGIN( FindMembers );
4940 findAndRemoveWord(current->type,"function");
4943 current_root->addSubEntry(current);
4944 current = new Entry ;
4946 // Objective C 2.0: Required/Optional section
4947 if (previous->spec & (Entry::Optional | Entry::Required))
4949 current->spec |= previous->spec & (Entry::Optional|Entry::Required);
4951 lastCurlyContext = FindMembers;
4952 if ( *yytext == ',' )
4954 current->type = previous->type;
4955 // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
4956 int i=current->type.length();
4957 while (i>0 && (current->type[i-1]=='*' || current->type[i-1]=='&' || current->type[i-1]==' ')) i--;
4958 current->type = current->type.left(i);
4960 if ( *yytext == '{' )
4962 if ( !insidePHP && (current_root->section & Entry::COMPOUND_MASK) )
4964 previous->spec |= Entry::Inline;
4966 //addToBody(yytext);
4968 BEGIN( SkipCurly ) ;
4972 if (previous->section!=Entry::VARIABLE_SEC)
4973 previous->bodyLine=-1; // a function/member declaration
4974 BEGIN( FindMembers ) ;
4978 <SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647)
4982 <SkipInits>"{" { // C++11 style initializer
4987 //addToBody(yytext);
4990 <SkipCurly>"}"/{BN}*("/*!"|"/**"|"//!"|"///")"<!--" | /* see bug710917 */
4992 //addToBody(yytext);
4999 if (current->sli && previous) // copy special list items
5001 QListIterator<ListItemInfo> li(*current->sli);
5003 for (li.toFirst();(lii=li.current());++li)
5005 previous->addSpecialListItem(lii->type,lii->itemId);
5007 delete current->sli;
5010 if (previous) previous->endBodyLine=yyLineNr;
5011 BEGIN( lastCurlyContext ) ;
5014 <SkipCurly>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" {
5018 //addToBody(yytext);
5023 current->endBodyLine=yyLineNr;
5025 tempEntry = current; // temporarily switch to the previous entry
5029 docBlockContext = SkipCurlyEndDoc;
5030 docBlockInBody = FALSE;
5031 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
5032 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
5035 if (yytext[yyleng-3]=='/')
5037 startCommentBlock(TRUE);
5042 startCommentBlock(FALSE);
5047 <SkipCurlyEndDoc>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { // desc is followed by another one
5048 docBlockContext = SkipCurlyEndDoc;
5049 docBlockInBody = FALSE;
5050 docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
5051 ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
5054 if (yytext[yyleng-3]=='/')
5056 startCommentBlock(TRUE);
5061 startCommentBlock(FALSE);
5065 <SkipCurlyEndDoc>"}" {
5067 if (tempEntry) // we can only switch back to current if no new item was created
5069 current = tempEntry;
5072 BEGIN( lastCurlyContext );
5075 //addToBody(yytext);
5076 lastStringContext=SkipCurly;
5077 BEGIN( SkipString );
5079 <SkipCurly>^{B}*"#" {
5082 //addToBody(yytext);
5083 BEGIN( SkipCurlyCpp );
5085 <SkipCurly,SkipInits>\n {
5087 //addToBody(yytext);
5089 <SkipCurly,SkipCurlyCpp>"<<<" {
5096 lastHereDocContext = YY_START;
5100 <SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<]+ {
5101 lineCount(); // for g_column updates
5102 //addToBody(yytext);
5105 //addToBody(yytext);
5107 lastCurlyContext = FindMembers;
5110 <SkipCurlyCpp>\\[\r]*"\n"[\r]* {
5111 //addToBody(yytext);
5114 <SkipInits,SkipCurly,SkipCurlyCpp>"/*" {
5115 //addToBody(yytext);
5116 lastCContext = YY_START;
5119 <SkipInits,SkipCurly,SkipCurlyCpp>"//" {
5120 //addToBody(yytext);
5121 lastCContext = YY_START;
5122 BEGIN(SkipCxxComment);
5126 lastSkipRoundContext=YY_START;
5130 lastStringContext=YY_START;
5131 BEGIN( SkipString );
5134 warn(yyFileName,yyLineNr,
5135 "Found ';' while parsing initializer list! "
5136 "(doxygen could be confused by a macro call without semicolon)"
5138 BEGIN( FindMembers );
5140 <SkipInits,SkipCurly,SkipCurlyCpp>"#" {
5143 //addToBody(yytext);
5144 lastCContext = YY_START;
5145 BEGIN(SkipCxxComment);
5147 <SkipInits,SkipCurly,SkipCurlyCpp>@\" {
5148 if (!insideCS) REJECT;
5149 // C# verbatim string
5150 lastSkipVerbStringContext=YY_START;
5151 pSkipVerbString=¤t->initializer;
5152 BEGIN(SkipVerbString);
5154 <SkipInits,SkipCurly,SkipCurlyCpp>{CHARLIT} {
5155 if (insidePHP) REJECT;
5157 <SkipInits,SkipCurly,SkipCurlyCpp>\' {
5160 lastStringContext=YY_START;
5161 BEGIN(SkipPHPString);
5164 <SkipInits,SkipCurly,SkipCurlyCpp>. { }
5165 <SkipString,SkipPHPString>\\. { }
5167 BEGIN( lastStringContext );
5170 BEGIN( lastStringContext );
5172 <SkipString,SkipPHPString>"/*"|"*/"|"//" { }
5173 <SkipString,SkipPHPString>\n {
5176 <SkipString,SkipPHPString>. { }
5177 <CompoundName>":" { // for "class : public base {} var;" construct, see bug 608359
5182 current->section = Entry::EMPTY_SEC ;
5183 current->type.resize(0) ;
5184 current->name.resize(0) ;
5185 current->args.resize(0) ;
5186 current->argList->clear();
5187 BEGIN( FindMembers ) ;
5190 if (insideIDL && (current->spec & (Entry::Singleton |
5193 // in UNO IDL a service or singleton may be defined
5194 // completely like this: "service Foo : XFoo;"
5195 if (!current->name.isEmpty() && !current_root->name.isEmpty())
5199 current->name = current->name.stripWhiteSpace();
5200 // there can be only one base class here
5201 if (!baseName.isEmpty())
5203 current->extends->append(
5204 new BaseInfo(baseName,Public,Normal));
5207 current_root->addSubEntry( current ) ;
5208 current = new Entry;
5212 current->section = Entry::EMPTY_SEC ;
5213 current->type.resize(0) ;
5214 current->name.resize(0) ;
5215 current->args.resize(0) ;
5216 current->argList->clear();
5218 BEGIN( FindMembers ) ;
5220 <CompoundName>{SCOPENAME}{BN}*/"<" {
5222 current->name = yytext ;
5223 if (current->spec & Entry::Protocol)
5225 current->name+="-p";
5228 lastClassTemplSpecContext = ClassVar;
5229 if (insideObjC) // protocol list
5231 BEGIN( ObjCProtocolList );
5233 else if (insideCS) // C# generic class
5235 //current->name+="-g";
5238 else // C++ template specialization
5241 BEGIN( ClassTemplSpec );
5245 if (current->tArgLists==0)
5247 current->tArgLists = new QList<ArgumentList>;
5248 current->tArgLists->setAutoDelete(TRUE);
5250 ArgumentList *al = new ArgumentList;
5251 // check bug 612858 before enabling the next line
5252 //current->spec |= Entry::Template;
5253 current->tArgLists->append(al);
5254 currentArgumentList = al;
5256 current->name += "<";
5257 fullArgString = templateStr;
5258 copyArgString = ¤t->name;
5259 //copyArgString = &templateStr;
5260 currentArgumentContext = ClassVar;
5261 BEGIN( ReadTempArgs );
5263 <ObjCProtocolList>"<" {
5264 insideProtocolList=TRUE;
5267 <ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
5268 current->name += yytext;
5270 if (--sharpCount<=0)
5272 current->name = removeRedundantWhiteSpace(current->name);
5273 if (current->spec & Entry::Protocol)
5274 { // Objective-C protocol
5275 unput('{'); // fake start of body
5280 BEGIN( lastClassTemplSpecContext );
5284 <ClassTemplSpec>"<" {
5285 current->name += yytext;
5289 current->name += yytext;
5291 <CompoundName>{SCOPENAME}{BN}*";" { // forward declaration
5292 if (current->tArgLists && current->tArgLists->count()>0)
5294 // found a forward template declaration, this has
5295 // a purpose of its own
5296 current->name = yytext;
5297 current->name=current->name.left(current->name.length()-1).stripWhiteSpace();
5298 //printf("template class declaration for %s!\n",current->name.data());
5299 QCString rn = current_root->name.copy();
5300 //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef);
5301 if (!current->name.isEmpty() && !rn.isEmpty())
5305 current->spec|=Entry::ForwardDecl;
5306 current_root->addSubEntry(current);
5307 current = new Entry;
5309 else if (insideIDL &&
5310 (((current_root->spec & (Entry::Interface |
5312 (current->spec & Entry::Interface)) ||
5313 ((current_root->spec & (Entry::Service |
5314 Entry::Singleton)) &&
5315 (current->spec & Entry::Service))))
5317 // interface inside of UNO IDL service or interface
5318 // service inside of UNO IDL service or singleton
5319 // there may be documentation on the member,
5320 // so do not throw it away...
5321 current->name = yytext;
5322 current->name=current->name.left(current->name.length()-1).stripWhiteSpace();
5323 current->section = (current->spec & Entry::Interface)
5324 ? Entry::EXPORTED_INTERFACE_SEC
5325 : Entry::INCLUDED_SERVICE_SEC;
5326 // current->section = Entry::MEMBERDOC_SEC;
5327 current->spec &= ~(Entry::Interface|Entry::Service); // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from different enums in this case... granted only Optional and Interface are actually valid in this context but urgh...
5328 current_root->addSubEntry(current);
5329 current = new Entry;
5335 if (isTypedef) // typedef of a class, put typedef keyword back
5337 current->type.prepend("typedef");
5339 BEGIN( FindMembers );
5341 <CompoundName>{SCOPENAME}/{BN}*"(" {
5342 current->name = yytext ;
5344 if (insideCpp && current->name=="alignas") // C++11
5346 lastAlignAsContext = YY_START;
5351 if (current->spec & Entry::Protocol)
5353 current->name += "-p";
5358 <AlignAs>"(" { roundCount=0;
5359 BEGIN( AlignAsEnd );
5361 <AlignAs>\n { lineCount(); }
5363 <AlignAsEnd>"(" { roundCount++; }
5364 <AlignAsEnd>")" { if (--roundCount<0)
5366 BEGIN( lastAlignAsContext );
5369 <AlignAsEnd>\n { lineCount(); }
5371 <CompoundName>{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line
5372 // e.g. @protocol A,B;
5376 <CompoundName>{SCOPENAME} {
5377 current->name = yytext ;
5378 if (insideCpp || insideObjC)
5380 current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
5383 if (current->spec & Entry::Protocol)
5385 current->name += "-p";
5387 if ((current->spec & Entry::Protocol) ||
5388 current->section == Entry::OBJCIMPL_SEC)
5390 unput('{'); // fake start of body
5394 <CompoundName>{CSSCOPENAME} { // C# style scope
5395 current->name = substitute(yytext,".","::");
5399 <ClassVar>{SCOPENAME}{BN}*/"(" {
5400 if (insideIDL && qstrncmp(yytext,"switch",6)==0 && !isId(yytext[6]))
5402 // Corba IDL style union
5404 BEGIN(SkipUnionSwitch);
5409 current->name = yytext;
5410 current->name = current->name.stripWhiteSpace();
5412 BEGIN( FindMembers );
5418 // multiple types in one typedef
5420 current->type.prepend("typedef ");
5425 // Multiple class forward declaration
5428 <ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
5431 if (yytext[0]=='s') // sealed
5432 current->spec |= Entry::SealedClass;
5434 current->spec |= Entry::AbstractClass;
5443 if (insideCpp || insideObjC)
5445 current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
5447 if (insideIDL && qstrcmp(yytext,"switch")==0)
5449 // Corba IDL style union
5451 BEGIN(SkipUnionSwitch);
5453 else if ((insideJava || insidePHP || insideJS) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0))
5455 current->type.resize(0);
5459 BEGIN( BasesProt ) ;
5461 else if (insideCS && qstrcmp(yytext,"where")==0) // C# type contraint
5463 delete current->typeConstr;
5464 current->typeConstr = new ArgumentList;
5465 current->typeConstr->append(new Argument);
5466 lastCSConstraint = YY_START;
5467 BEGIN( CSConstraintName );
5469 else if (insideCli && qstrcmp(yytext,"abstract")==0)
5471 current->spec|=Entry::Abstract;
5473 else if (insideCli && qstrcmp(yytext,"sealed")==0)
5475 current->spec|=Entry::Sealed;
5477 else if (qstrcmp(yytext,"final")==0)
5479 current->spec|=Entry::Final;
5483 if (current->section == Entry::ENUM_SEC)
5484 { // found "enum a b" -> variable
5485 current->section = Entry::VARIABLE_SEC ;
5487 current->type += ' ' ;
5488 current->type += current->name ;
5489 current->name = yytext ;
5491 if (nameIsOperator(current->name))
5498 if (insideObjC && *yytext=='(') // class category
5501 //if (current->section!=Entry::OBJCIMPL_SEC)
5503 current->spec|=Entry::Category;
5505 BEGIN( ClassCategory );
5509 // probably a function anyway
5511 BEGIN( FindMembers );
5514 <CSConstraintType,CSConstraintName>"/**/" { /* empty comment */ }
5515 <CSConstraintType,CSConstraintName>("/*"[*!]|"//"[/!])("<"?) { // special comment
5516 fullArgString.resize(0);
5517 lastCopyArgChar='#'; // end marker
5518 lastCommentInArgContext=YY_START;
5520 BEGIN( CopyArgCommentLine );
5522 BEGIN( CopyArgComment );
5524 <CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block
5525 current->typeConstr->getLast()->docs = fullArgString;
5527 <CSConstraintType>"{" { // end of type constraint reached
5528 // parse documentation of the constraints
5529 handleParametersCommentBlocks(current->typeConstr);
5531 BEGIN( lastCSConstraint );
5533 <CSConstraintType,CSConstraintName>";" {
5534 handleParametersCommentBlocks(current->typeConstr);
5536 BEGIN( lastCSConstraint );
5538 <CSConstraintName>":" {
5539 BEGIN( CSConstraintType );
5541 <CSConstraintName>{ID} {
5543 current->typeConstr->getLast()->name=yytext;
5545 <CSConstraintType>"where" { // another constraint for a different param
5546 current->typeConstr->append(new Argument);
5547 BEGIN( CSConstraintName );
5549 <CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
5550 if (current->typeConstr->getLast()->type.isEmpty())
5551 // first type constraint for this parameter
5553 current->typeConstr->getLast()->type=yytext;
5555 else // new type constraint for same parameter
5557 QCString name = current->typeConstr->getLast()->name;
5558 current->typeConstr->append(new Argument);
5559 current->typeConstr->getLast()->name=name;
5560 current->typeConstr->getLast()->type=yytext;
5563 <CSConstraintName,CSConstraintType>\n {
5566 <CSConstraintName,CSConstraintType>. {
5568 <ClassCategory>{ID} {
5569 current->name+=yytext;
5571 <ClassCategory>")"/{BN}*"{" {
5575 <ClassCategory>")"/{BN}*"<" {
5577 BEGIN( ObjCProtocolList );
5579 <ClassCategory>")" {
5581 if ((current->section & Entry::Protocol) ||
5582 current->section == Entry::OBJCIMPL_SEC)
5584 unput('{'); // fake start of body
5586 else // category has no variables so push back an empty body
5594 if (current->section==Entry::ENUM_SEC) // enum E:2, see bug 313527,
5595 // or C++11 style enum: 'E : unsigned int {...}'
5597 current->args.resize(0);
5598 BEGIN(EnumBaseType);
5602 current->type.resize(0);
5603 if ((current->spec & Entry::Interface) ||
5604 (current->spec & Entry::Struct) ||
5605 (current->spec & Entry::Ref) ||
5606 (current->spec & Entry::Value) ||
5607 insidePHP || insideCS || insideD || insideObjC || insideIDL
5614 BEGIN( BasesProt ) ;
5619 if (isTypedef) // typedef of a class, put typedef keyword back
5621 current->type.prepend("typedef");
5623 if ((yytext[0]=='*' || yytext[0]=='&') &&
5624 current->section == Entry::ENUM_SEC)
5625 { // found "enum a *b" -> variable
5626 current->section = Entry::VARIABLE_SEC ;
5628 BEGIN( FindMembers );
5630 <Bases,ClassVar>"///"/[^/] {
5638 current->program+=yytext;
5639 current->fileName = yyFileName ;
5640 current->startLine = yyLineNr ;
5641 current->startColumn = yyColNr;
5643 BEGIN( ReadBodyIntf );
5646 <Bases,ClassVar>("//"{B}*)?"/**"/[^/*] |
5647 <Bases,ClassVar>("//"{B}*)?"/*!" |
5648 <Bases,ClassVar>"//!" |
5649 <Bases,ClassVar>[\-+]{BN}* {
5657 current->program+=yytext;
5658 current->fileName = yyFileName ;
5659 current->startLine = yyLineNr ;
5660 current->startColumn = yyColNr;
5662 BEGIN( ReadBodyIntf );
5665 <CompoundName,ClassVar>{B}*"{"{B}* {
5666 current->fileName = yyFileName ;
5667 current->startLine = yyLineNr ;
5668 current->startColumn = yyColNr;
5669 current->name = removeRedundantWhiteSpace(current->name);
5670 if (current->name.isEmpty() && !isTypedef) // anonymous compound
5672 if (current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces
5674 if (Config_getBool("EXTRACT_ANON_NSPACES")) // use visible name
5676 current->name="anonymous_namespace{"+stripPath(current->fileName)+"}";
5678 else // use invisible name
5680 current->name.sprintf("@%d",anonNSCount);
5685 current->name.sprintf("@%d",anonCount++);
5689 if (current_root && // not a nested struct inside an @interface section
5690 !(current_root->spec & Entry::Interface) &&
5691 ((current->spec & (Entry::Interface | Entry::Protocol | Entry::Category) ||
5692 current->section==Entry::OBJCIMPL_SEC)
5696 { // ObjC body that ends with @end
5697 BEGIN( ReadBodyIntf );
5699 else if (current->section==Entry::NAMESPACE_SEC)
5701 BEGIN( ReadNSBody );
5708 <BasesProt>"virtual"{BN}+ { lineCount(); baseVirt = Virtual; }
5709 <BasesProt>"public"{BN}+ { lineCount(); baseProt = Public; }
5710 <BasesProt>"protected"{BN}+ { lineCount(); baseProt = Protected; }
5711 <BasesProt>"internal"{BN}+ { lineCount(); baseProt = Package; }
5712 <BasesProt>"private"{BN}+ { lineCount(); baseProt = Private; }
5713 <BasesProt>{BN} { lineCount(); }
5714 <BasesProt>. { unput(*yytext); BEGIN(Bases); }
5715 <Bases>("\\")?({ID}"\\")*{ID} { // PHP namespace token, not sure if interspacing is allowed but it gives problems (see bug 640847)
5720 else // PHP base class of the form \Ns\Cl or Ns\Cl
5724 bn = substitute(bn,"\\","::");
5726 current->args += ' ';
5727 current->args += yytext;
5730 <Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} {
5732 QCString baseScope = yytext;
5733 if (insideCS && baseScope.stripWhiteSpace()=="where")
5735 // type contraint for a class
5736 delete current->typeConstr;
5737 current->typeConstr = new ArgumentList;
5738 current->typeConstr->append(new Argument);
5739 lastCSConstraint = YY_START;
5740 BEGIN( CSConstraintName );
5745 current->args += ' ';
5746 current->args += yytext;
5749 <Bases>{BN}*{ID}("."{ID})* { // Java style class
5750 QCString name = substitute(yytext,".","::");
5752 current->args += ' ';
5753 current->args += name;
5755 <ClassVar,Bases>\n/{BN}*[^{, \t\n] {
5766 <ClassVar,Bases>"@end" { // empty ObjC interface
5767 unput('d'); // insert fake body: {}@end
5774 <ClassVar>"<" { current->name += *yytext;
5777 lastSkipSharpContext = YY_START;
5778 specName = ¤t->name;
5779 BEGIN ( Specialization );
5785 lastSkipSharpContext = YY_START;
5786 if (insideObjC) // start of protocol list
5790 else // template specialization
5792 //if (insideCS) // generic
5796 templateStr = yytext;
5797 specName = &templateStr;
5798 BEGIN ( Specialization );
5801 <Specialization>"<" { *specName += *yytext;
5802 if (roundCount==0) sharpCount++;
5804 <Specialization>">" {
5805 *specName += *yytext;
5806 if (roundCount==0 && --sharpCount<=0)
5808 baseName+=removeRedundantWhiteSpace(*specName);
5809 BEGIN(lastSkipSharpContext);
5812 <Specialization>{BN}+ { lineCount(); *specName +=' '; }
5813 <Specialization>"<<" { *specName += yytext; }
5814 <Specialization>">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template...
5819 <Specialization>">>" {
5820 if (insideCS) // for C# >> ends a nested template
5824 else // for C++ >> is a bitshift
5825 // operator and > > would end
5826 // a nested template.
5827 // We require the bitshift to be enclosed in braces.
5828 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
5832 *specName += yytext;
5842 <Specialization>"typename"{BN}+ { lineCount(); }
5843 <Specialization>"(" { *specName += *yytext; roundCount++; }
5844 <Specialization>")" { *specName += *yytext; roundCount--; }
5846 *specName += *yytext;
5848 <SkipRound>"(" { ++roundCount; }
5849 <SkipRound>")" { if (--roundCount<0)
5850 BEGIN ( lastSkipRoundContext );
5853 lastStringContext=SkipRound;
5856 <Bases>","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount();
5857 if (insideProtocolList)
5863 current->args += ',' ;
5865 current->name = removeRedundantWhiteSpace(current->name);
5866 if (!baseName.isEmpty())
5868 current->extends->append(
5869 new BaseInfo(baseName,baseProt,baseVirt)
5872 if ((current->spec & (Entry::Interface|Entry::Struct)) ||
5873 insideJava || insidePHP || insideCS ||
5874 insideD || insideObjC || insideIDL)
5885 { // end of a ObjC protocol list
5886 insideProtocolList=FALSE;
5889 unput('{'); // dummy start body
5898 if (*yytext==',' && insideObjC) // Begin of protocol list
5900 insideProtocolList=TRUE;
5905 <Bases>{B}*"{"{B}* { current->fileName = yyFileName ;
5906 current->startLine = yyLineNr ;
5907 current->startColumn = yyColNr;
5908 current->name = removeRedundantWhiteSpace(current->name);
5909 if (!baseName.isEmpty())
5910 current->extends->append(
5911 new BaseInfo(baseName,baseProt,baseVirt)
5916 BEGIN( ReadBodyIntf );
5923 <SkipUnionSwitch>{B}*"(" {
5926 <SkipUnionSwitch>")" {
5927 if (--roundCount==0)
5932 <SkipUnionSwitch>\n { lineCount(); }
5934 <Comment>{BN}+ { current->program += yytext ;
5937 <Comment>"/*" { current->program += yytext ; }
5938 <Comment>"//" { current->program += yytext ; }
5939 <Comment>{CMD}("code"|"verbatim") {
5941 current->program += yytext ;
5943 <Comment>{CMD}("endcode"|"endverbatim") {
5945 current->program += yytext ;
5947 <Comment>[^ \.\t\r\n\/\*]+ { current->program += yytext ; }
5948 <Comment>"*/" { current->program += yytext ;
5949 if (!insideCode) BEGIN( lastContext ) ;
5951 <Comment>. { current->program += *yytext ; }
5953 <FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>("//"{B}*)?"/*!" {
5954 //printf("Start doc block at %d\n",yyLineNr);
5955 removeSlashes=(yytext[1]=='/');
5957 if (!current->doc.isEmpty())
5959 current->doc+="\n\n";
5963 current->docLine = yyLineNr;
5964 current->docFile = yyFileName;
5967 lastDocContext = YY_START;
5968 if (current_root->section & Entry::SCOPE_MASK)
5970 current->inside = current_root->name+"::";
5972 docBlockContext = YY_START;
5973 docBlockInBody = YY_START==SkipCurly;
5974 docBlockAutoBrief = Config_getBool("QT_AUTOBRIEF");
5977 indent.fill(' ',computeIndent(yytext,g_column));
5980 if (docBlockAutoBrief)
5982 current->briefLine = yyLineNr;
5983 current->briefFile = yyFileName;
5985 startCommentBlock(FALSE);
5988 <FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>("//"{B}*)?"/**"/[^/*] {
5989 removeSlashes=(yytext[1]=='/');
5990 lastDocContext = YY_START;
5992 //printf("Found comment block at %s:%d\n",yyFileName,yyLineNr);
5993 if (current_root->section & Entry::SCOPE_MASK)
5995 current->inside = current_root->name+"::";
5997 current->docLine = yyLineNr;
5998 current->docFile = yyFileName;
5999 docBlockContext = YY_START;
6000 docBlockInBody = YY_START==SkipCurly;
6001 static bool javadocAutoBrief = Config_getBool("JAVADOC_AUTOBRIEF");
6002 docBlockAutoBrief = javadocAutoBrief;
6005 indent.fill(' ',computeIndent(yytext,g_column));
6008 if (docBlockAutoBrief)
6010 current->briefLine = yyLineNr;
6011 current->briefFile = yyFileName;
6013 startCommentBlock(FALSE);
6016 <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"//!" {
6018 lastDocContext = YY_START;
6019 if (current_root->section & Entry::SCOPE_MASK)
6021 current->inside = current_root->name+"::";
6023 docBlockContext = YY_START;
6024 docBlockInBody = YY_START==SkipCurly;
6025 docBlockAutoBrief = FALSE;
6028 indent.fill(' ',computeIndent(yytext,g_column));
6031 startCommentBlock(current->brief.isEmpty());
6034 <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"///"/[^/] {
6036 lastDocContext = YY_START;
6037 if (current_root->section & Entry::SCOPE_MASK)
6039 current->inside = current_root->name+"::";
6041 docBlockContext = YY_START;
6042 docBlockInBody = YY_START==SkipCurly;
6043 docBlockAutoBrief = FALSE;
6045 indent.fill(' ',computeIndent(yytext,g_column));
6047 startCommentBlock(current->brief.isEmpty());
6050 <FindMembers>"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? {
6059 else if (insideCS &&
6060 !current->name.isEmpty() &&
6061 !current->type.isEmpty())
6063 if (containsWord(current->type,"event")) // event
6065 current->mtype = mtype = Event;
6069 current->mtype = mtype = Property;
6071 current->bodyLine = yyLineNr;
6073 BEGIN( CSAccessorDecl );
6075 else if (insideIDL && (current->spec & Entry::Attribute))
6077 // UNO IDL: attributes may have setter and getter
6078 // exception specifications
6079 current->exception = " {";
6080 BEGIN(UNOIDLAttributeBlock);
6084 if ((insideJava || insideCS || insideD) &&
6085 current->name.isEmpty()
6088 // static Java initializer
6092 current->name="[static initializer]";
6093 current->type.resize(0);
6097 current->name="[instance initializer]";
6104 // pre C++11 code -> ignore the initializer
6106 //current->type.resize(0);
6107 //current->name.resize(0);
6108 //current->args.resize(0);
6109 //current->argList->clear();
6111 //BEGIN( SkipCurlyBlock );
6113 // C++11 style initializer list
6114 current->bodyLine = yyLineNr;
6115 current->initializer = yytext;
6116 lastInitializerContext = YY_START;
6118 BEGIN(ReadInitializer);
6122 <CSAccessorDecl>"{" { curlyCount++; }
6123 <CSAccessorDecl>"}" {
6136 <CSAccessorDecl>"private "{BN}*"set" { if (curlyCount==0) current->spec |= Entry::PrivateSettable; }
6137 <CSAccessorDecl>"protected "{BN}*"set" { if (curlyCount==0) current->spec |= Entry::ProtectedSettable; }
6138 <CSAccessorDecl>"private "{BN}*"get" { if (curlyCount==0) current->spec |= Entry::PrivateGettable; }
6139 <CSAccessorDecl>"protected "{BN}*"get" { if (curlyCount==0) current->spec |= Entry::ProtectedGettable; }
6140 <CSAccessorDecl>"set" { if (curlyCount==0) current->spec |= Entry::Settable; }
6141 <CSAccessorDecl>"get" { if (curlyCount==0) current->spec |= Entry::Gettable; }
6142 <CSAccessorDecl>"add" { if (curlyCount==0) current->spec |= Entry::Addable; }
6143 <CSAccessorDecl>"remove" { if (curlyCount==0) current->spec |= Entry::Removable; }
6144 <CSAccessorDecl>"raise" { if (curlyCount==0) current->spec |= Entry::Raisable; }
6145 <CSAccessorDecl>. {}
6146 <CSAccessorDecl>\n { lineCount(); }
6151 /**********************************************************************************/
6152 /******************** Documentation block related rules ***************************/
6153 /**********************************************************************************/
6155 /* ---- Single line comments ------ */
6156 <DocLine>[^\n]*"\n"[ \t]*"//"[/!] { // continuation of multiline C++-style comment
6158 docBlock.resize(docBlock.length() - 3);
6161 <DocLine>{B}*"///"[/]+{B}*/"\n" { // ignore marker line (see bug700345)
6162 handleCommentBlock(docBlock.data(),current->brief.isEmpty());
6163 BEGIN( docBlockContext );
6165 <DocLine>[^\n]*/"\n" { // whole line
6167 handleCommentBlock(docBlock.data(),current->brief.isEmpty());
6168 BEGIN( docBlockContext );
6171 /* ---- Comments blocks ------ */
6173 <DocBlock>"*"*"*/" { // end of comment block
6174 handleCommentBlock(docBlock.data(),FALSE);
6175 BEGIN(docBlockContext);
6177 <DocBlock>^{B}*"*"+/[^/] {
6180 indent.fill(' ',computeIndent(yytext,g_column));
6183 <DocBlock>^{B}*("//")?{B}*"*"+/[^//a-z_A-Z0-9*] { // start of a comment line
6185 indent.fill(' ',computeIndent(yytext,g_column));
6188 <DocBlock>^{B}*("//"){B}* { // strip embedded C++ comments if at the start of a line
6190 <DocBlock>"//" { // slashes in the middle of a comment block
6193 <DocBlock>"/*" { // start of a new comment in the
6194 // middle of a comment block
6197 <DocBlock>("@@"|"\\\\"){ID}/[^a-z_A-Z0-9] { // escaped command
6200 <DocBlock>{CMD}("f$"|"f["|"f{") {
6202 docBlockName=&yytext[1];
6203 if (docBlockName.at(1)=='{')
6205 docBlockName.at(1)='}';
6208 g_nestedComment=FALSE;
6209 BEGIN(DocCopyBlock);
6211 <DocBlock>{B}*"<"{PRE}">" {
6213 docBlockName="<pre>";
6215 g_nestedComment=FALSE;
6216 BEGIN(DocCopyBlock);
6218 <DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!)
6220 docBlockName=&yytext[1];
6222 g_nestedComment=FALSE;
6223 BEGIN(DocCopyBlock);
6225 <DocBlock>"~~~"[~]* {
6228 g_fencedSize=yyleng;
6229 g_nestedComment=FALSE;
6230 BEGIN(DocCopyBlock);
6232 <DocBlock>{B}*"<code>" {
6236 docBlockName="<code>";
6237 g_nestedComment=FALSE;
6238 BEGIN(DocCopyBlock);
6245 <DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
6248 <DocBlock>\n { // newline
6252 <DocBlock>. { // command block
6256 /* ---- Copy verbatim sections ------ */
6258 <DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
6260 if (docBlockName=="<pre>")
6265 <DocCopyBlock>"</"{CODE}">" { // end of a <code> block
6267 if (docBlockName=="<code>")
6272 <DocCopyBlock>[\\@]("f$"|"f]"|"f}") {
6276 <DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
6278 if (&yytext[4]==docBlockName)
6283 <DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
6284 if (docBlockName=="verbatim")
6288 else if (docBlockName=="code")
6295 indent.fill(' ',computeIndent(yytext,0));
6299 <DocCopyBlock>^{B}*"*"+/{BN}+"*"{BN}* { // start of a comment line with two *'s
6300 if (docBlockName=="code")
6303 indent.fill(' ',computeIndent(yytext,0));
6311 <DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
6312 if (docBlockName=="code")
6315 indent.fill(' ',computeIndent(yytext,-1));
6316 docBlock+=indent+"*";
6323 <DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
6324 if (docBlockName=="code")
6327 if (g_nestedComment) // keep * it is part of the code
6329 indent.fill(' ',computeIndent(yytext,-1));
6330 docBlock+=indent+"*";
6332 else // remove * it is part of the comment block
6334 indent.fill(' ',computeIndent(yytext,0));
6343 <DocCopyBlock>"~~~"[~]* {
6345 if (g_fencedSize==yyleng)
6350 <DocCopyBlock>[^\<@/*\]~\$\\\n]+ { // any character that is not special
6353 <DocCopyBlock>"/*"|"*/"|"//" {
6356 g_nestedComment=TRUE;
6358 else if (yytext[0]=='*')
6360 g_nestedComment=FALSE;
6364 <DocCopyBlock>\n { // newline
6368 <DocCopyBlock>. { // any other character
6371 <DocCopyBlock><<EOF>> {
6372 warn(yyFileName,yyLineNr,
6373 "reached end of file while inside a %s block!\n"
6374 "The command that should end the block seems to be missing!\n",
6375 docBlockName.data());
6380 /* ------------- Prototype parser -------------- */
6382 <Prototype>"operator"{B}*"("{B}*")" {
6383 current->name+=yytext;
6386 current->args+=*yytext;
6387 currentArgumentContext = PrototypeQual;
6388 fullArgString = current->args.copy();
6389 copyArgString = ¤t->args;
6390 BEGIN( ReadFuncArgType ) ;
6392 <Prototype>"("({ID}"::")*({B}*[&*])+ {
6393 current->type+=current->name+yytext;
6394 current->name.resize(0);
6395 BEGIN( PrototypePtr );
6397 <PrototypePtr>{SCOPENAME} {
6398 current->name+=yytext;
6401 current->args+=*yytext;
6402 currentArgumentContext = PrototypeQual;
6403 fullArgString = current->args.copy();
6404 copyArgString = ¤t->args;
6405 BEGIN( ReadFuncArgType ) ;
6412 current->name+=yytext;
6414 <PrototypeQual>"{" {
6415 BEGIN( PrototypeSkipLine);
6417 <PrototypeQual>{B}*"const"{B}* {
6418 current->args += " const ";
6419 current->argList->constSpecifier=TRUE;
6421 <PrototypeQual>{B}*"volatile"{B}* {
6422 current->args += " volatile ";
6423 current->argList->volatileSpecifier=TRUE;
6425 <PrototypeQual>{B}*"="{B}*"0"{B}* {
6426 current->args += " = 0";
6427 current->virt = Pure;
6428 current->argList->pureSpecifier=TRUE;
6430 <PrototypeQual>"throw"{B}*"(" {
6431 current->exception = "throw(";
6432 BEGIN(PrototypeExc);
6435 current->exception += ')';
6436 BEGIN(PrototypeQual);
6439 current->exception += *yytext;
6442 current->args += *yytext;
6445 current->name += *yytext;
6447 <PrototypeSkipLine>. {
6451 /* ------------ Generic rules -------------- */
6454 <SkipCxxComment>.*"\\\n" { // line continuation
6464 <SkipCxxComment>.*/\n {
6465 BEGIN( lastCContext ) ;
6467 <SkipComment>[^\*\n]+
6468 <*>\n { lineCount(); }
6470 if (insideIDL && insideCppQuote)
6478 lastCContext = YY_START ;
6479 BEGIN( SkipCxxComment ) ;
6484 lastStringContext=YY_START;
6485 BEGIN(SkipPHPString);
6491 lastStringContext=YY_START;
6496 <SkipComment>"//"|"/*"
6497 <*>"/*" { lastCContext = YY_START ;
6498 BEGIN( SkipComment ) ;
6500 <SkipComment>{B}*"*/" { BEGIN( lastCContext ) ; }
6502 lastCContext = YY_START ;
6503 BEGIN( SkipCxxComment ) ;
6507 //----------------------------------------------------------------------------
6509 static void startCommentBlock(bool brief)
6513 current->briefFile = yyFileName;
6514 current->briefLine = yyLineNr;
6518 current->docFile = yyFileName;
6519 current->docLine = yyLineNr;
6523 //----------------------------------------------------------------------------
6525 static void newEntry()
6527 if (tempEntry==0) // if temp entry is not 0, it holds current,
6528 // and current is actually replaced by previous which was
6529 // already added to current_root, so we should not add it again
6532 current_root->addSubEntry(current);
6536 current = new Entry ;
6540 static void handleCommentBlock(const QCString &doc,bool brief)
6542 static bool hideInBodyDocs = Config_getBool("HIDE_IN_BODY_DOCS");
6544 bool needsEntry=FALSE;
6545 if (docBlockInBody && hideInBodyDocs) return;
6546 //printf("parseCommentBlock [%s] brief=%d\n",doc.data(),brief);
6547 int lineNr = brief ? current->briefLine : current->docLine; // line of block start
6549 // fill in inbodyFile && inbodyLine the first time, see bug 633891
6550 Entry *docEntry = docBlockInBody && previous ? previous : current;
6551 if (docBlockInBody && docEntry && docEntry->inbodyLine==-1)
6553 docEntry->inbodyFile = yyFileName;
6554 docEntry->inbodyLine = lineNr;
6557 while (parseCommentBlock(
6559 docBlockInBody && previous ? previous : current,
6560 stripIndentation(doc), // text
6562 lineNr, // line of block start
6563 docBlockInBody ? FALSE : brief, // isBrief
6564 docBlockInBody ? FALSE : docBlockAutoBrief, // isJavaDocStyle
6565 docBlockInBody, // isInBody
6572 //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
6575 QCString docFile = current->docFile;
6577 current->docFile = docFile;
6578 current->docLine = lineNr;
6588 unput(docBlockTerm);
6593 static void handleParametersCommentBlocks(ArgumentList *al)
6595 //printf(">>>>>>> handleParametersCommentBlocks()\n");
6596 ArgumentListIterator ali(*al);
6598 for (ali.toFirst();(a=ali.current());++ali)
6600 //printf(" Param %s docs=%s\n",a->name.data(),a->docs.data());
6601 if (!a->docs.isEmpty())
6607 QCString orgDoc = current->doc;
6608 QCString orgBrief = current->brief;
6609 int orgDocLine = current->docLine;
6610 int orgBriefLine = current->briefLine;
6612 current->doc.resize(0);
6613 current->brief.resize(0);
6615 //printf("handleParametersCommentBlock [%s]\n",doc.data());
6616 while (parseCommentBlock(
6621 current->docLine, // line of block start
6631 //printf("handleParametersCommentBlock position=%d [%s]\n",position,doc.data()+position);
6632 if (needsEntry) newEntry();
6638 a->docs = current->doc;
6641 current->doc = orgDoc;
6642 current->brief = orgBrief;
6643 current->docLine = orgDocLine;
6644 current->briefLine = orgBriefLine;
6650 //----------------------------------------------------------------------------
6652 static void parseCompounds(Entry *rt)
6654 //printf("parseCompounds(%s)\n",rt->name.data());
6655 EntryListIterator eli(*rt->children());
6657 for (;(ce=eli.current());++eli)
6659 if (!ce->program.isEmpty())
6661 //printf("-- %s ---------\n%s\n---------------\n",
6662 // ce->name.data(),ce->program.data());
6663 // init scanner state
6667 inputString = ce->program;
6669 scannerYYrestart( scannerYYin ) ;
6670 if (ce->section==Entry::ENUM_SEC || (ce->spec&Entry::Enum))
6671 BEGIN( FindFields ) ;
6673 BEGIN( FindMembers ) ;
6675 yyFileName = ce->fileName;
6677 yyLineNr = ce->startLine ;
6678 yyColNr = ce->startColumn ;
6679 insideObjC = ce->lang==SrcLangExt_ObjC;
6680 //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC);
6682 if (current) delete current;
6683 current = new Entry;
6687 // deep copy group list from parent (see bug 727732)
6690 QListIterator<Grouping> gli(*rt->groups);
6692 for (;(g=gli.current());++gli)
6694 ce->groups->append(new Grouping(*g));
6698 int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
6699 // set default protection based on the compound type
6700 if( ce->section==Entry::CLASS_SEC ) // class
6702 if (insidePHP || insideD || insideJS || insideIDL)
6704 current->protection = protection = Public ;
6706 else if (insideJava)
6708 current->protection = protection = (ce->spec & (Entry::Interface|Entry::Enum)) ? Public : Package;
6710 else if (ce->spec&(Entry::Interface | Entry::Ref | Entry::Value | Entry::Struct | Entry::Union))
6712 if (ce->lang==SrcLangExt_ObjC)
6714 current->protection = protection = Protected ;
6718 current->protection = protection = Public ;
6723 current->protection = protection = Private ;
6726 else if (ce->section == Entry::ENUM_SEC ) // enum
6728 current->protection = protection = ce->protection;
6730 else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
6732 if (ce->section == Entry::NAMESPACE_SEC ) // unnamed namespace
6734 current->stat = gstat = TRUE;
6736 current->protection = protection = ce->protection;
6738 else // named struct, union, protocol, category
6740 current->protection = protection = Public ;
6744 //printf("name=%s current->stat=%d gstat=%d\n",ce->name.data(),current->stat,gstat);
6746 //memberGroupId = DOX_NOGROUP;
6747 //memberGroupRelates.resize(0);
6748 //memberGroupInside.resize(0);
6749 groupEnterCompound(yyFileName,yyLineNr,ce->name);
6755 groupLeaveCompound(yyFileName,yyLineNr,ce->name);
6757 delete current; current=0;
6758 ce->program.resize(0);
6763 // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
6770 //----------------------------------------------------------------------------
6772 static void parseMain(const char *fileName,
6773 const char *fileBuf,
6775 bool sameTranslationUnit,
6776 QStrList & filesInSameTranslationUnit)
6780 inputString = fileBuf;
6784 //anonCount = 0; // don't reset per file
6786 protection = Public;
6792 inputFile.setName(fileName);
6793 if (inputFile.open(IO_ReadOnly))
6796 yyFileName = fileName;
6798 bool processWithClang = insideCpp || insideObjC;
6799 if (processWithClang)
6801 if (!sameTranslationUnit) // new file
6803 ClangParser::instance()->start(fileName,filesInSameTranslationUnit);
6807 ClangParser::instance()->switchToFile(fileName);
6810 rt->lang = language;
6811 msg("Parsing file %s...\n",yyFileName.data());
6815 groupEnterFile(yyFileName,yyLineNr);
6816 current = new Entry;
6817 //printf("current=%p current_root=%p\n",current,current_root);
6818 int sec=guessSection(yyFileName);
6821 current->name = yyFileName;
6822 current->section = sec;
6823 current_root->addSubEntry(current);
6824 current = new Entry;
6828 scannerYYrestart( scannerYYin );
6831 BEGIN( FindMembersPHP );
6835 BEGIN( FindMembers );
6841 if (YY_START==Comment)
6843 warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
6847 groupLeaveFile(yyFileName,yyLineNr);
6851 // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
6854 rt->program.resize(0);
6855 if (rt->children()->contains(current)==0)
6856 // it could be that current is already added as a child to rt, so we
6857 // only delete it if this is not the case. See bug 635317.
6859 delete current; current=0;
6871 //----------------------------------------------------------------------------
6873 static void parsePrototype(const QCString &text)
6875 //printf("**** parsePrototype(%s) begin\n",text.data());
6878 warn(yyFileName,yyLineNr,"Empty prototype found!");
6881 if (!current) // nothing to store (see bug683516)
6886 const char *orgInputString;
6887 int orgInputPosition;
6888 YY_BUFFER_STATE orgState;
6890 // save scanner state
6891 orgState = YY_CURRENT_BUFFER;
6892 yy_switch_to_buffer(yy_create_buffer(scannerYYin, YY_BUF_SIZE));
6893 orgInputString = inputString;
6894 orgInputPosition = inputPosition;
6900 scannerYYrestart( scannerYYin );
6905 current->name = current->name.stripWhiteSpace();
6906 if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty())
6907 current->section = Entry::VARIABLEDOC_SEC;
6909 // restore original scanner state
6910 YY_BUFFER_STATE tmpState = YY_CURRENT_BUFFER;
6911 yy_switch_to_buffer(orgState);
6912 yy_delete_buffer(tmpState);
6913 inputString = orgInputString;
6914 inputPosition = orgInputPosition;
6916 //printf("**** parsePrototype end\n");
6919 void scanFreeScanner()
6921 #if defined(YY_FLEX_SUBMINOR_VERSION)
6924 scannerYYlex_destroy();
6929 //static void handleGroupStartCommand(const char *header)
6931 // memberGroupHeader=header;
6932 // startGroupInDoc();
6935 //static void handleGroupEndCommand()
6941 //----------------------------------------------------------------------------
6943 void CLanguageScanner::startTranslationUnit(const char *)
6947 void CLanguageScanner::finishTranslationUnit()
6949 bool processWithClang = insideCpp || insideObjC;
6950 if (processWithClang)
6952 ClangParser::instance()->finish();
6956 void CLanguageScanner::parseInput(const char *fileName,
6957 const char *fileBuf,
6959 bool sameTranslationUnit,
6960 QStrList & filesInSameTranslationUnit)
6962 g_thisParser = this;
6964 printlex(yy_flex_debug, TRUE, __FILE__, fileName);
6966 ::parseMain(fileName,fileBuf,root,
6967 sameTranslationUnit,filesInSameTranslationUnit);
6969 printlex(yy_flex_debug, FALSE, __FILE__, fileName);
6972 void CLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
6973 const char * scopeName,
6974 const QCString & input,
6976 bool isExampleBlock,
6977 const char * exampleName,
6981 bool inlineFragment,
6982 MemberDef *memberDef,
6983 bool showLineNumbers,
6984 Definition *searchCtx,
6988 ::parseCCode(codeOutIntf,scopeName,input,lang,isExampleBlock,exampleName,
6989 fileDef,startLine,endLine,inlineFragment,memberDef,
6990 showLineNumbers,searchCtx,collectXRefs);
6993 bool CLanguageScanner::needsPreprocessing(const QCString &extension)
6995 QCString fe=extension.lower();
6996 SrcLangExt lang = getLanguageFromFileName(extension);
6997 return (SrcLangExt_Cpp == lang) ||
6998 !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
6999 fe==".php4" || fe==".inc" || fe==".phtml"
7003 void CLanguageScanner::resetCodeParserState()
7005 ::resetCCodeParserState();
7008 void CLanguageScanner::parsePrototype(const char *text)
7010 ::parsePrototype(text);
7013 //----------------------------------------------------------------------------
7015 #if !defined(YY_FLEX_SUBMINOR_VERSION)
7016 //----------------------------------------------------------------------------
7017 extern "C" { // some bogus code to keep the compiler happy
7018 void scannerYYdummy() { yy_flex_realloc(0,0); }