Doxygen
scanner.l
浏览该文件的文档.
1 /*****************************************************************************
2  *
3  * Copyright (C) 1997-2021 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 %option never-interactive
16 %option prefix="scannerYY"
17 %option reentrant
18 %option extra-type="struct scannerYY_state *"
19 %top{
20 #include <stdint.h>
21 // forward declare yyscan_t to improve typesafety
22 #define YY_TYPEDEF_YY_SCANNER_T
23 struct yyguts_t;
24 typedef yyguts_t *yyscan_t;
25 }
26 
27 %{
28 
29 /*
30  * includes
31  */
32 
33 #include <algorithm>
34 #include <vector>
35 #include <utility>
36 #include <atomic>
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <assert.h>
41 #include <ctype.h>
42 
43 #include "scanner.h"
44 #include "entry.h"
45 #include "message.h"
46 #include "config.h"
47 #include "doxygen.h"
48 #include "util.h"
49 #include "defargs.h"
50 #include "language.h"
51 #include "commentscan.h"
52 #include "arguments.h"
53 
54 #include "clangparser.h"
55 #include "markdown.h"
56 #include "regex.h"
57 
58 #define YY_NO_INPUT 1
59 #define YY_NO_UNISTD_H 1
60 
61 #define USE_STATE2STRING 0
62 
63 static AtomicInt anonCount;
64 static AtomicInt anonNSCount;
65 
66 struct scannerYY_state
67 {
68  OutlineParserInterface *thisParser;
69  CommentScanner commentScanner;
70  const char * inputString = 0;
71  int inputPosition = 0;
72  int lastContext = 0;
73  int lastCContext = 0;
74  int lastDocContext = 0;
75  int lastCPPContext = 0;
76  int lastSkipSharpContext = 0;
77  int lastSkipRoundContext = 0;
78  int lastStringContext = 0;
79  int lastCurlyContext = 0;
80  int lastRoundContext = 0;
81  int lastSharpContext = 0;
82  int lastSquareContext = 0;
83  int lastInitializerContext = 0;
84  int lastClassTemplSpecContext = 0;
85  int lastPreLineCtrlContext = 0;
86  int lastSkipVerbStringContext = 0;
87  int lastCommentInArgContext = 0;
88  int lastRawStringContext = 0;
89  int lastCSConstraint = 0;
90  int lastHereDocContext = 0;
91  int lastDefineContext = 0;
92  int lastAlignAsContext = 0;
93  int lastC11AttributeContext = 0;
94  int lastModifierContext = 0;
95  Protection protection = Public;
96  Protection baseProt = Public;
97  int sharpCount = 0 ;
98  int roundCount = 0 ;
99  int curlyCount = 0 ;
100  int squareCount = 0 ;
101  int padCount = 0 ;
102  std::shared_ptr<Entry> current;
103  std::shared_ptr<Entry> current_root;
104  std::shared_ptr<Entry> previous;
105  std::shared_ptr<Entry> tempEntry;
106  std::shared_ptr<Entry> firstTypedefEntry;
107  std::shared_ptr<Entry> memspecEntry;
108  int yyLineNr = 1 ;
109  int yyBegLineNr = 1 ;
110  int yyColNr = 1 ;
111  int yyBegColNr = 1 ;
112  QCString yyFileName;
113  MethodTypes mtype = Method;
114  bool stat = false;
115  Specifier virt = Normal;
116  Specifier baseVirt = Normal;
117  QCString msType;
118  QCString msName;
119  QCString msArgs;
120  bool isTypedef = false;
121  QCString funcPtrType;
122  QCString templateStr;
123  QCString aliasName;
124  QCString baseName;
125  QCString* specName = 0;
126 
127  SrcLangExt language = SrcLangExt_Unknown;
128  bool insideIDL = false; //!< processing IDL code?
129  bool insideJava = false; //!< processing Java code?
130  bool insideCS = false; //!< processing C# code?
131  bool insideD = false; //!< processing D code?
132  bool insidePHP = false; //!< processing PHP code?
133  bool insideObjC = false; //!< processing Objective C code?
134  bool insideCli = false; //!< processing C++/CLI code?
135  bool insideJS = false; //!< processing JavaScript code?
136  bool insideSlice = false; //!< processing Slice code?
137  bool insideCpp = true; //!< processing C/C++ code
138 
139  bool insideCppQuote = false;
140  bool insideProtocolList = false;
141 
142  int argRoundCount = 0;
143  int argSquareCount = 0;
144  int argSharpCount = 0;
145  int currentArgumentContext = 0;
146  int lastCopyArgStringContext = 0;
147  int lastCopyArgContext = 0;
148  int requiresContext = 0;
149  QCString *copyArgString = 0;
150  QCString fullArgString;
151  QCString dummyRawString;
152 
153  ArgumentList *currentArgumentList = 0;
154  char lastCopyArgChar = '\0';
155 
156  QCString *pCopyQuotedString = 0;
157  QCString *pCopyRoundString = 0;
158  QCString *pCopyCurlyString = 0;
159  QCString *pCopySharpString = 0;
160  QCString *pCopyRawString = 0;
161  TextStream *pCopyCurlyGString = 0;
162  TextStream *pCopyRoundGString = 0;
163  TextStream *pCopySquareGString = 0;
164  TextStream *pCopyQuotedGString = 0;
165  TextStream *pCopyHereDocGString = 0;
166  TextStream *pCopyRawGString = 0;
167  TextStream *pSkipVerbString = 0;
168 
169  bool insideFormula = false;
170  bool insideTryBlock = false;
171  bool insideCode = false;
172  bool needsSemi = false;
173 
174  int initBracketCount = 0;
175 
176  QCString oldStyleArgType;
177  QCString docBackup;
178  QCString briefBackup;
179 
180  int docBlockContext = 0;
181  TextStream docBlock;
182  QCString docBlockName;
183  bool docBlockInBody = false;
184  bool docBlockAutoBrief = false;
185  char docBlockTerm = '\0';
186 
187  QCString idlAttr;
188  QCString idlProp;
189  bool odlProp = false;
190 
191  bool lexInit = false;
192  bool externLinkage = false;
193 
194  QCString delimiter;
195 
196  int column = 0;
197 
198  uint fencedSize = 0;
199  bool nestedComment = false;
200  std::vector< std::pair<Entry*,std::shared_ptr<Entry> > > outerScopeEntries;
201  QCString programStr;
202 
203  ClangTUParser * clangParser = 0;
204 };
205 
206 #if USE_STATE2STRING
207 static const char *stateToString(int state);
208 #endif
209 //-----------------------------------------------------------------------------
210 
211 // forward declarations for stateless functions
212 static inline int computeIndent(const char *s,int startIndent);
213 static QCString stripQuotes(const char *s);
214 static bool nameIsOperator(QCString &name);
215 void fixArgumentListForJavaScript(ArgumentList &al);
216 
217 // forward declarations for statefull functions
218 static void initParser(yyscan_t yyscanner);
219 static void initEntry(yyscan_t yyscanner);
220 static void lineCount(yyscan_t yyscanner);
221 static void addType(yyscan_t yyscanner);
222 static void setContext(yyscan_t yyscanner);
223 static void prependScope(yyscan_t yyscanner);
224 static void startCommentBlock(yyscan_t yyscanner,bool);
225 static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief);
226 static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al);
227 static bool checkForKnRstyleC(yyscan_t yyscanner);
228 static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName);
229 static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name,
230  const QCString &brief,const QCString &docs);
231 static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
232 
233 /* ----------------------------------------------------------------- */
234 #undef YY_INPUT
235 #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
236 
237 %}
238 
239  /* start command character */
240 CMD ("\\"|"@")
241 BN [ \t\n\r]
242 BNopt {BN}*
243 BL [ \t\r]*"\n"
244 B [ \t]
245 Bopt {B}*
246 ID [$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*
247 SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID})
248 TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,:]*">")?
249 CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
250 PRE [pP][rR][eE]
251 CODE [cC][oO][dD][eE]
252 CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
253 PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
254 PHPUSEKW ("public"|"private"|"protected")
255 IDLATTR ("["[^\]]*"]"){BN}*
256 TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
257 RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
258 RAWEND ")"[^ \t\(\)\\]{0,16}\"
259 ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
260 ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
261 LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"|"<=>"
262 BITOP "&"|"|"|"^"|"<<"|">>"|"~"
263 OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
264 
265  /* no comment start / end signs inside square brackets */
266 NCOMM [^/\*]
267  // C start comment
268 CCS "/\*"
269  // C end comment
270 CCE "*\/"
271  // Cpp comment
272 CPPC "/\/"
273  // doxygen start comment
274 DCOMM ("/\*!"|"/\**"|"/\/!"|"/\/\/")
275 
276  // Optional any character
277 ANYopt .*
278  // Optional all but newline
279 NONLopt [^\n]*
280 
281 %option noyywrap
282 
283  /* language parsing states */
284 
285 %x AlignAs
286 %x AlignAsEnd
287 %x Define
288 %x DefineEnd
289 %x CompoundName
290 %x ClassVar
291 %x CSConstraintName
292 %x CSConstraintType
293 %x CSIndexer
294 %x ClassCategory
295 %x ClassTemplSpec
296 %x CliPropertyType
297 %x CliPropertyIndex
298 %x CliOverride
299 %x Bases
300 %x BasesProt
301 %x NextSemi
302 %x BitFields
303 %x EnumBaseType
304 %x FindMembers
305 %x FindMembersPHP
306 %x FindMemberName
307 %x FindFields
308 %x Function
309 %x FuncRound
310 %x ExcpRound
311 %x ExcpList
312 %x FuncQual
313 %x TrailingReturn
314 %x Operator
315 %x Array
316 %x ReadBody
317 %x ReadNSBody
318 %x ReadBodyIntf
319 %x Using
320 %x UsingAlias
321 %x UsingAliasEnd
322 %x UsingDirective
323 %x SkipCurly
324 %x SkipCurlyCpp
325 %x SkipCurlyEndDoc
326 %x SkipString
327 %x SkipPHPString
328 %x SkipInits
329 %x SkipC11Inits
330 %x SkipC11Attribute
331 %x SkipCPP
332 %x SkipComment
333 %x SkipCxxComment
334 %x SkipCurlyBlock
335 %x SkipRoundBlock
336 %x Sharp
337 %x SkipRound
338 %x SkipSquare
339 %x StaticAssert
340 %x DeclType
341 %x TypedefName
342 %x TryFunctionBlock
343 %x TryFunctionBlockEnd
344 %x Comment
345 %x PackageName
346 %x JavaImport
347 %x PHPUse
348 %x PHPUseAs
349 %x CSAccessorDecl
350 %x CSGeneric
351 %x PreLineCtrl
352 %x DefinePHP
353 %x DefinePHPEnd
354 %x OldStyleArgs
355 %x SkipVerbString
356 %x ObjCMethod
357 %x ObjCReturnType
358 %x ObjCParams
359 %x ObjCParamType
360 %x ObjCProtocolList
361 %x ObjCPropAttr
362 %x ObjCSkipStatement
363 %x QtPropType
364 %x QtPropAttr
365 %x QtPropRead
366 %x QtPropWrite
367 %x ReadInitializer
368 %x ReadInitializerPtr
369 %x UNOIDLAttributeBlock
370 %x GetCallType
371 %x CppQuote
372 %x EndCppQuote
373 %x MemberSpec
374 %x MemberSpecSkip
375 %x EndTemplate
376 %x FuncPtr
377 %x FuncPtrOperator
378 %x EndFuncPtr
379 %x ReadFuncArgType
380 %x ReadTempArgs
381 %x IDLUnionCase
382 %x NSAliasName
383 %x NSAliasArg
384 %x CopyString
385 %x CopyPHPString
386 %x CopyGString
387 %x CopyPHPGString
388 %x CopyRound
389 %x CopySharp
390 %x CopyCurly
391 %x GCopyRound
392 %x GCopySquare
393 %x GCopyCurly
394 %x SkipUnionSwitch
395 %x Specialization
396 %x SpecializationSingleQuote
397 %x SpecializationDoubleQuote
398 %x FuncFunc
399 %x FuncFuncEnd
400 %x FuncFuncType
401 %x FuncFuncArray
402 %x CopyArgString
403 %x CopyArgPHPString
404 %x CopyArgRound
405 %x CopyArgSquare
406 %x CopyArgSharp
407 %x CopyArgComment
408 %x CopyArgCommentLine
409 %x CopyArgVerbatim
410 %x HereDoc
411 %x HereDocEnd
412 %x CopyHereDoc
413 %x CopyHereDocEnd
414 %x RawString
415 %x RawGString
416 %x CSString
417 
418 %x IDLAttribute
419 %x IDLProp
420 %x IDLPropName
421 
422  /** Slice states */
423 
424 %x SliceOptional
425 %x SliceMetadata
426 %x SliceSequence
427 %x SliceSequenceName
428 %x SliceDictionary
429 %x SliceDictionaryName
430 
431  /** Prototype scanner states */
432 
433 %x Prototype
434 %x PrototypePtr
435 %x PrototypeQual
436 %x PrototypeExc
437 %x PrototypeSkipLine
438 
439  /** comment parsing states */
440 
441 %x DocLine
442 %x DocBlock
443 %x DocCopyBlock
444 
445  /** C++20 concepts */
446 
447 %x RequiresClause
448 %x RequiresExpression
449 %x ConceptName
450 
451 %%
452 
453 <NextSemi>"{" {
454  yyextra->curlyCount=0;
455  yyextra->needsSemi = TRUE;
456  BEGIN(SkipCurlyBlock);
457  }
458 <NextSemi>"(" {
459  yyextra->roundCount=0;
460  BEGIN(SkipRoundBlock);
461  }
462 <SkipRoundBlock>"(" {
463  ++yyextra->roundCount;
464  }
465 <SkipRoundBlock>")" {
466  if (yyextra->roundCount )
467  --yyextra->roundCount ;
468  else
469  BEGIN( NextSemi ) ;
470  }
471 <SkipCurlyBlock>"{" {
472  ++yyextra->curlyCount ;
473  }
474 <SkipCurlyBlock>"}" {
475  if( yyextra->curlyCount )
476  {
477  --yyextra->curlyCount ;
478  }
479  else if (yyextra->needsSemi)
480  {
481  BEGIN( NextSemi );
482  }
483  else
484  {
485  BEGIN( FindMembers );
486  }
487  }
488 <NextSemi>\' {
489  if (yyextra->insidePHP)
490  {
491  yyextra->lastStringContext=NextSemi;
492  BEGIN(SkipPHPString);
493  }
494  }
495 <NextSemi>{CHARLIT} { if (yyextra->insidePHP) REJECT; }
496 <NextSemi>\" {
497  yyextra->lastStringContext=NextSemi;
498  BEGIN(SkipString);
499  }
500 <NextSemi>[;,] {
501  unput(*yytext);
502  BEGIN( FindMembers );
503  }
504 <BitFields>[;,] {
505  unput(*yytext);
506  BEGIN( FindMembers );
507  }
508 <EnumBaseType>[{;,] {
509  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
510  unput(*yytext);
511  BEGIN( ClassVar );
512  }
513 <FindMembers>"<?php" { // PHP code with unsupported extension?
514  yyextra->insidePHP = TRUE;
515  }
516 <FindMembersPHP>"<?"("php"?) { // PHP code start
517  BEGIN( FindMembers );
518  }
519 <FindMembersPHP>"<script"{BN}+"language"{BN}*"="{BN}*['"]?"php"['"]?{BN}*">" { // PHP code start
520  lineCount(yyscanner) ;
521  BEGIN( FindMembers );
522  }
523 <FindMembers>"?>"|"</script>" { // PHP code end
524  if (yyextra->insidePHP)
525  BEGIN( FindMembersPHP );
526  else
527  REJECT;
528  }
529 <FindMembersPHP>[^\n<]+ { // Non-PHP code text, ignore
530  }
531 <FindMembersPHP>\n { // Non-PHP code text, ignore
532  lineCount(yyscanner);
533  }
534 <FindMembersPHP>. { // Non-PHP code text, ignore
535  }
536 <FindMembers>{PHPKW} { if (yyextra->insidePHP)
537  BEGIN( NextSemi );
538  else
539  REJECT;
540  }
541 <FindMembers>"%{"[^\n]* { // Mozilla XPIDL lang-specific block
542  if (!yyextra->insideIDL)
543  REJECT;
544  }
545 <FindMembers>"%}" { // Mozilla XPIDL lang-specific block end
546  if (!yyextra->insideIDL)
547  REJECT;
548  }
549 <FindMembers>{B}*("properties"){BN}*":"{BN}* { // IDL or Borland C++ builder property
550  yyextra->current->mtype = yyextra->mtype = Property;
551  yyextra->current->protection = yyextra->protection = Public ;
552  yyextra->current->type.resize(0);
553  yyextra->current->name.resize(0);
554  yyextra->current->args.resize(0);
555  yyextra->current->argList.clear();
556  lineCount(yyscanner) ;
557  }
558 
559 <FindMembers>{B}*"k_dcop"{BN}*":"{BN}* { yyextra->current->mtype = yyextra->mtype = DCOP;
560  yyextra->current->protection = yyextra->protection = Public ;
561  yyextra->current->type.resize(0);
562  yyextra->current->name.resize(0);
563  yyextra->current->args.resize(0);
564  yyextra->current->argList.clear();
565  lineCount(yyscanner) ;
566  }
567 
568 <FindMembers>{B}*("signals"|"Q_SIGNALS"){BN}*":"{BN}* { yyextra->current->mtype = yyextra->mtype = Signal;
569 
570  yyextra->current->protection = yyextra->protection = Public ;
571  yyextra->current->type.resize(0);
572  yyextra->current->name.resize(0);
573  yyextra->current->args.resize(0);
574  yyextra->current->argList.clear();
575  lineCount(yyscanner) ;
576  }
577 
578 <FindMembers>{B}*"public"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
579  yyextra->current->protection = yyextra->protection = Public ;
580  yyextra->current->mtype = yyextra->mtype = Slot;
581  yyextra->current->type.resize(0);
582  yyextra->current->name.resize(0);
583  yyextra->current->args.resize(0);
584  yyextra->current->argList.clear();
585  lineCount(yyscanner);
586  }
587 
588 <FindMembers>{B}*"protected"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
589  yyextra->current->protection = yyextra->protection = Protected ;
590  yyextra->current->mtype = yyextra->mtype = Slot;
591  yyextra->current->type.resize(0);
592  yyextra->current->name.resize(0);
593  yyextra->current->args.resize(0);
594  yyextra->current->argList.clear();
595  lineCount(yyscanner);
596  }
597 
598 <FindMembers>{B}*"private"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
599  yyextra->current->protection = yyextra->protection = Private ;
600  yyextra->current->mtype = yyextra->mtype = Slot;
601  yyextra->current->type.resize(0);
602  yyextra->current->name.resize(0);
603  yyextra->current->args.resize(0);
604  yyextra->current->argList.clear();
605  lineCount(yyscanner);
606  }
607 <FindMembers>{B}*("public"|"methods"|"__published"){BN}*":"{BN}* {
608  yyextra->current->protection = yyextra->protection = Public ;
609  yyextra->current->mtype = yyextra->mtype = Method;
610  yyextra->current->type.resize(0);
611  yyextra->current->name.resize(0);
612  yyextra->current->args.resize(0);
613  yyextra->current->argList.clear();
614  lineCount(yyscanner) ;
615  }
616 <FindMembers>{B}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package...
617  if (yyextra->insideCli)
618  {
619  yyextra->current->protection = yyextra->protection = Package ;
620  yyextra->current->mtype = yyextra->mtype = Method;
621  yyextra->current->type.resize(0);
622  yyextra->current->name.resize(0);
623  yyextra->current->args.resize(0);
624  yyextra->current->argList.clear();
625  lineCount(yyscanner) ;
626  }
627  else
628  {
629  REJECT;
630  }
631  }
632 <FindMembers>{B}*"protected"{BN}*":"{BN}* {
633  yyextra->current->protection = yyextra->protection = Protected ;
634  yyextra->current->mtype = yyextra->mtype = Method;
635  yyextra->current->type.resize(0);
636  yyextra->current->name.resize(0);
637  yyextra->current->args.resize(0);
638  yyextra->current->argList.clear();
639  lineCount(yyscanner) ;
640  }
641 <FindMembers>{B}*"private"{BN}*":"{BN}* {
642  yyextra->current->protection = yyextra->protection = Private ;
643  yyextra->current->mtype = yyextra->mtype = Method;
644  yyextra->current->type.resize(0);
645  yyextra->current->name.resize(0);
646  yyextra->current->args.resize(0);
647  yyextra->current->argList.clear();
648  lineCount(yyscanner) ;
649  }
650 <FindMembers>{B}*"event"{BN}+ {
651  if (yyextra->insideCli)
652  {
653  // C++/CLI event
654  lineCount(yyscanner) ;
655  yyextra->current->mtype = yyextra->mtype = Event;
656  yyextra->current->bodyLine = yyextra->yyLineNr;
657  yyextra->current->bodyColumn = yyextra->yyColNr;
658  yyextra->curlyCount=0;
659  BEGIN( CliPropertyType );
660  }
661  else if (yyextra->insideCS)
662  {
663  lineCount(yyscanner) ;
664  yyextra->current->mtype = Event;
665  yyextra->current->bodyLine = yyextra->yyLineNr;
666  yyextra->current->bodyColumn = yyextra->yyColNr;
667  }
668  else
669  {
670  REJECT;
671  }
672  }
673 <FindMembers>{B}*"property"{BN}+ {
674  if (yyextra->insideCli)
675  {
676  // C++/CLI property
677  lineCount(yyscanner) ;
678  yyextra->current->mtype = yyextra->mtype = Property;
679  yyextra->current->bodyLine = yyextra->yyLineNr;
680  yyextra->current->bodyColumn = yyextra->yyColNr;
681  yyextra->curlyCount=0;
682  BEGIN( CliPropertyType );
683  }
684  else
685  {
686  REJECT;
687  }
688  }
689 <CliPropertyType>{ID} {
690  addType(yyscanner);
691  yyextra->current->name = yytext;
692  }
693 <CliPropertyType>"[" { // C++/CLI indexed property
694  yyextra->current->args = "[";
695  BEGIN( CliPropertyIndex );
696  }
697 <CliPropertyType>"{" {
698  yyextra->curlyCount=0;
699  //printf("event: '%s' '%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name));
700  BEGIN( CSAccessorDecl );
701  }
702 <CliPropertyType>";" {
703  unput(*yytext);
704  BEGIN( FindMembers );
705  }
706 <CliPropertyType>\n {
707  lineCount(yyscanner);
708  }
709 <CliPropertyType>{B}* {
710  }
711 <CliPropertyType>. {
712  addType(yyscanner);
713  yyextra->current->type += yytext;
714  }
715 <CliPropertyIndex>"]" {
716  BEGIN( CliPropertyType );
717  yyextra->current->args+=yytext;
718  }
719 <CliPropertyIndex>. {
720  yyextra->current->args+=yytext;
721  }
722  /*
723 <FindMembers>{B}*"property"{BN}+ {
724  if (!yyextra->current->type.isEmpty())
725  {
726  REJECT;
727  }
728  else
729  {
730  yyextra->current->mtype = yyextra->mtype = Property;
731  lineCount(yyscanner);
732  }
733  }
734  */
735 <FindMembers>{B}*"@private"{BN}+ {
736  yyextra->current->protection = yyextra->protection = Private ;
737  yyextra->current->mtype = yyextra->mtype = Method;
738  yyextra->current->type.resize(0);
739  yyextra->current->name.resize(0);
740  yyextra->current->args.resize(0);
741  yyextra->current->argList.clear();
742  lineCount(yyscanner) ;
743  }
744 <FindMembers>{B}*"@protected"{BN}+ {
745  yyextra->current->protection = yyextra->protection = Protected ;
746  yyextra->current->mtype = yyextra->mtype = Method;
747  yyextra->current->type.resize(0);
748  yyextra->current->name.resize(0);
749  yyextra->current->args.resize(0);
750  yyextra->current->argList.clear();
751  lineCount(yyscanner) ;
752  }
753 <FindMembers>{B}*"@public"{BN}+ {
754  yyextra->current->protection = yyextra->protection = Public ;
755  yyextra->current->mtype = yyextra->mtype = Method;
756  yyextra->current->type.resize(0);
757  yyextra->current->name.resize(0);
758  yyextra->current->args.resize(0);
759  yyextra->current->argList.clear();
760  lineCount(yyscanner) ;
761  }
762 <FindMembers>[\-+]{BN}* {
763  if (!yyextra->insideObjC)
764  {
765  REJECT;
766  }
767  else
768  {
769  lineCount(yyscanner);
770  yyextra->current->fileName = yyextra->yyFileName;
771  yyextra->current->startLine = yyextra->yyLineNr;
772  yyextra->current->startColumn = yyextra->yyColNr;
773  yyextra->current->bodyLine = yyextra->yyLineNr;
774  yyextra->current->bodyColumn = yyextra->yyColNr;
775  yyextra->current->section = Entry::FUNCTION_SEC;
776  yyextra->current->protection = yyextra->protection = Public ;
777  yyextra->language = yyextra->current->lang = SrcLangExt_ObjC;
778  yyextra->insideObjC = TRUE;
779  yyextra->current->virt = Virtual;
780  yyextra->current->stat=yytext[0]=='+';
781  yyextra->current->mtype = yyextra->mtype = Method;
782  yyextra->current->type.resize(0);
783  yyextra->current->name.resize(0);
784  yyextra->current->args.resize(0);
785  yyextra->current->argList.clear();
786  BEGIN( ObjCMethod );
787  }
788  }
789 <ObjCMethod>"(" { // start of method's return type
790  BEGIN( ObjCReturnType );
791  }
792 <ObjCMethod>{ID} { // found method name
793  if (yyextra->current->type.isEmpty())
794  {
795  yyextra->current->type = "id";
796  }
797  yyextra->current->name = yytext;
798  if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
799  {
800  yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
801  }
802  }
803 <ObjCMethod>":"{B}* { // start of parameter list
804  yyextra->current->name += ':';
805  Argument a;
806  yyextra->current->argList.push_back(a);
807  BEGIN( ObjCParams );
808  }
809 <ObjCReturnType>[^)]* { // TODO: check if nested braches are possible.
810  yyextra->current->type = yytext;
811  }
812 <ObjCReturnType>")" {
813  BEGIN( ObjCMethod );
814  }
815 <ObjCParams>({ID})?{BN}*":" { // Keyword of parameter
816  QCString keyw = yytext;
817  keyw=keyw.left(keyw.length()-1).stripWhiteSpace(); // strip :
818  if (keyw.isEmpty())
819  {
820  yyextra->current->name += " :";
821  }
822  else
823  {
824  yyextra->current->name += keyw+":";
825  }
826  if (yyextra->current->argList.back().type.isEmpty())
827  {
828  yyextra->current->argList.back().type="id";
829  }
830  Argument a;
831  a.attrib=(QCString)"["+keyw+"]";
832  yyextra->current->argList.push_back(a);
833  }
834 <ObjCParams>{ID}{BN}* { // name of parameter
835  lineCount(yyscanner);
836  yyextra->current->argList.back().name=QCString(yytext).stripWhiteSpace();
837  }
838 <ObjCParams>","{BN}*"..." { // name of parameter
839  lineCount(yyscanner);
840  // do we want the comma as part of the name?
841  //yyextra->current->name += ",";
842  Argument a;
843  a.attrib="[,]";
844  a.type="...";
845  yyextra->current->argList.push_back(a);
846  }
847  /*
848 <ObjCParams>":" {
849  yyextra->current->name += ':';
850  }
851  */
852 <ObjCParams>"(" {
853  yyextra->roundCount=0;
854  yyextra->current->argList.back().type.resize(0);
855  BEGIN( ObjCParamType );
856  }
857 <ObjCParamType>"(" {
858  yyextra->roundCount++;
859  yyextra->current->argList.back().type+=yytext;
860  }
861 <ObjCParamType>")"/{B}* {
862  if (yyextra->roundCount<=0)
863  {
864  BEGIN( ObjCParams );
865  }
866  else
867  {
868  yyextra->current->argList.back().type+=yytext;
869  yyextra->roundCount--;
870  }
871  }
872 <ObjCParamType>[^()]* {
873  yyextra->current->argList.back().type+=QCString(yytext).stripWhiteSpace();
874  }
875 <ObjCMethod,ObjCParams>";" { // end of method declaration
876  if (!yyextra->current->argList.empty() && yyextra->current->argList.back().type.isEmpty())
877  {
878  yyextra->current->argList.back().type="id";
879  }
880  if (yyextra->current->argList.empty()) // method without parameters
881  {
882  yyextra->current->argList.setNoParameters(TRUE);
883  }
884  yyextra->current->args = argListToString(yyextra->current->argList);
885  //printf("argList=%s\n",qPrint(yyextra->current->args));
886  unput(';');
887  BEGIN( Function );
888  }
889 <ObjCMethod,ObjCParams>(";"{BN}+)?"{" { // start of a method body
890  lineCount(yyscanner);
891  //printf("Type=%s Name=%s args=%s\n",
892  // qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(argListToString(yyextra->current->argList))
893  // );
894  if (!yyextra->current->argList.empty() && yyextra->current->argList.back().type.isEmpty())
895  {
896  yyextra->current->argList.back().type="id";
897  }
898  if (yyextra->current->argList.empty()) // method without parameters
899  {
900  yyextra->current->argList.setNoParameters(TRUE);
901  }
902  yyextra->current->args = argListToString(yyextra->current->argList);
903  unput('{');
904  BEGIN( Function );
905  }
906 <FindMembers>{B}*"sequence"{BN}*"<"{BN}* {
907  if (yyextra->insideSlice)
908  {
909  lineCount(yyscanner);
910  yyextra->current->bodyLine = yyextra->yyLineNr;
911  yyextra->current->bodyColumn = yyextra->yyColNr;
912  yyextra->current->fileName = yyextra->yyFileName ;
913  yyextra->current->startLine = yyextra->yyLineNr ;
914  yyextra->current->startColumn = yyextra->yyColNr;
915  yyextra->current->args.resize(0);
916  yyextra->current->section = Entry::TYPEDEF_SEC ;
917  yyextra->isTypedef = TRUE;
918  BEGIN( SliceSequence );
919  }
920  else
921  REJECT;
922  }
923 <FindMembers>{B}*"dictionary"{BN}*"<"{BN}* {
924  if (yyextra->insideSlice)
925  {
926  lineCount(yyscanner);
927  yyextra->current->bodyLine = yyextra->yyLineNr;
928  yyextra->current->bodyColumn = yyextra->yyColNr;
929  yyextra->current->fileName = yyextra->yyFileName ;
930  yyextra->current->startLine = yyextra->yyLineNr ;
931  yyextra->current->startColumn = yyextra->yyColNr;
932  yyextra->current->args.resize(0);
933  yyextra->current->section = Entry::TYPEDEF_SEC ;
934  yyextra->isTypedef = TRUE;
935  BEGIN( SliceDictionary );
936  }
937  else
938  REJECT;
939  }
940 <FindMembers>{BN}{1,80} {
941  lineCount(yyscanner);
942  }
943 <FindMembers>"@"({ID}".")*{ID}{BN}*"(" {
944  if (yyextra->insideJava) // Java annotation
945  {
946  lineCount(yyscanner);
947  yyextra->lastSkipRoundContext = YY_START;
948  yyextra->roundCount=0;
949  BEGIN( SkipRound );
950  }
951  else if (qstrncmp(yytext,"@property",9)==0) // ObjC 2.0 property
952  {
953  yyextra->current->mtype = yyextra->mtype = Property;
954  yyextra->current->spec|=Entry::Readable | Entry::Writable | Entry::Assign;
955  yyextra->current->protection = Public ;
956  unput('(');
957  BEGIN( ObjCPropAttr );
958  }
959  else
960  {
961  REJECT;
962  }
963  }
964 <ObjCPropAttr>"getter="{ID} {
965  yyextra->current->read = yytext+7;
966  }
967 <ObjCPropAttr>"setter="{ID} {
968  yyextra->current->write = yytext+7;
969  }
970 <ObjCPropAttr>"readonly" {
971  yyextra->current->spec&=~Entry::Writable;
972  }
973 <ObjCPropAttr>"readwrite" { // default
974  }
975 <ObjCPropAttr>"assign" { // default
976  }
977 <ObjCPropAttr>"unsafe_unretained" {
978  yyextra->current->spec&=~Entry::Assign;
979  yyextra->current->spec|=Entry::Unretained;
980  }
981 <ObjCPropAttr>"retain" {
982  yyextra->current->spec&=~Entry::Assign;
983  yyextra->current->spec|=Entry::Retain;
984  }
985 <ObjCPropAttr>"copy" {
986  yyextra->current->spec&=~Entry::Assign;
987  yyextra->current->spec|=Entry::Copy;
988  }
989 <ObjCPropAttr>"weak" {
990  yyextra->current->spec&=~Entry::Assign;
991  yyextra->current->spec|=Entry::Weak;
992  }
993 <ObjCPropAttr>"strong" {
994  yyextra->current->spec&=~Entry::Assign;
995  yyextra->current->spec|=Entry::Strong;
996  }
997 <ObjCPropAttr>"nonatomic" {
998  yyextra->current->spec|=Entry::NonAtomic;
999  }
1000 <ObjCPropAttr>")" {
1001  BEGIN(FindMembers);
1002  }
1003 <FindMembers>"@"{ID} {
1004  if (yyextra->insideJava) // Java annotation
1005  {
1006  // skip annotation
1007  }
1008  else if (qstrcmp(yytext,"@property")==0) // ObjC 2.0 property
1009  {
1010  yyextra->current->mtype = yyextra->mtype = Property;
1011  yyextra->current->spec|=Entry::Writable | Entry::Readable;
1012  yyextra->current->protection = Public ;
1013  }
1014  else if (qstrcmp(yytext,"@synthesize")==0)
1015  {
1016  BEGIN( ObjCSkipStatement );
1017  }
1018  else if (qstrcmp(yytext,"@dynamic")==0)
1019  {
1020  BEGIN( ObjCSkipStatement );
1021  }
1022  else
1023  {
1024  REJECT;
1025  }
1026  }
1027 <ObjCSkipStatement>";" {
1028  BEGIN(FindMembers);
1029  }
1030 <PackageName>{ID}(("."|"\\"){ID})* {
1031  yyextra->isTypedef=FALSE;
1032  //printf("Found namespace %s lang=%d\n",yytext,yyextra->current->lang);
1033  yyextra->current->name = yytext;
1034  yyextra->current->name = substitute(yyextra->current->name,".","::");
1035  yyextra->current->name = substitute(yyextra->current->name,"\\","::");
1036  yyextra->current->section = Entry::NAMESPACE_SEC;
1037  yyextra->current->type = "namespace" ;
1038  yyextra->current->fileName = yyextra->yyFileName;
1039  yyextra->current->startLine = yyextra->yyLineNr;
1040  yyextra->current->startColumn = yyextra->yyColNr;
1041  yyextra->current->bodyLine = yyextra->yyLineNr;
1042  yyextra->current->bodyColumn = yyextra->yyColNr;
1043  lineCount(yyscanner);
1044  }
1045 <PackageName>";" {
1046  std::shared_ptr<Entry> tmp = yyextra->current;
1047  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1048  yyextra->current_root = tmp;
1049  initEntry(yyscanner);
1050  BEGIN(FindMembers);
1051  }
1052 <PackageName>"{" {
1053  yyextra->curlyCount=0;
1054  BEGIN( ReadNSBody );
1055  }
1056 <FindMembers>{B}*"initonly"{BN}+ {
1057  yyextra->current->type += " initonly ";
1058  if (yyextra->insideCli) yyextra->current->spec |= Entry::Initonly;
1059  lineCount(yyscanner);
1060  }
1061 <FindMembers>{B}*"static"{BN}+ { yyextra->current->type += " static ";
1062  yyextra->current->stat = TRUE;
1063  lineCount(yyscanner);
1064  }
1065 <FindMembers>{B}*"extern"{BN}+ {
1066  yyextra->current->stat = FALSE;
1067  yyextra->current->explicitExternal = TRUE;
1068  lineCount(yyscanner);
1069  }
1070 <FindMembers>{B}*"const"{BN}+ { if (yyextra->insideCS)
1071  {
1072  yyextra->current->type += " const ";
1073  if (yyextra->insideCS) yyextra->current->stat = TRUE;
1074  lineCount(yyscanner);
1075  }
1076  else
1077  {
1078  REJECT;
1079  }
1080  }
1081 <FindMembers>{B}*"virtual"{BN}+ { yyextra->current->type += " virtual ";
1082  yyextra->current->virt = Virtual;
1083  lineCount(yyscanner);
1084  }
1085 <FindMembers>{B}*"constexpr"{BN}+ {
1086  if (yyextra->insideCpp)
1087  {
1088  yyextra->current->type += " constexpr ";
1089  yyextra->current->spec |= Entry::ConstExpr;
1090  lineCount(yyscanner);
1091  }
1092  else
1093  {
1094  REJECT;
1095  }
1096  }
1097 <FindMembers>{B}*"published"{BN}+ { // UNO IDL published keyword
1098  if (yyextra->insideIDL)
1099  {
1100  lineCount(yyscanner);
1101  yyextra->current->spec |= Entry::Published;
1102  }
1103  else
1104  {
1105  REJECT;
1106  }
1107  }
1108 <FindMembers>{B}*"abstract"{BN}+ {
1109  if (!yyextra->insidePHP)
1110  {
1111  yyextra->current->type += " abstract ";
1112  if (!yyextra->insideJava)
1113  {
1114  yyextra->current->virt = Pure;
1115  }
1116  else
1117  {
1118  yyextra->current->spec|=Entry::Abstract;
1119  }
1120  }
1121  else
1122  {
1123  yyextra->current->spec|=Entry::Abstract;
1124  }
1125  lineCount(yyscanner);
1126  }
1127 <FindMembers>{B}*"inline"{BN}+ { yyextra->current->spec|=Entry::Inline;
1128  lineCount(yyscanner);
1129  }
1130 <FindMembers>{B}*"mutable"{BN}+ { yyextra->current->spec|=Entry::Mutable;
1131  lineCount(yyscanner);
1132  }
1133 <FindMembers>{B}*"explicit"{BN}+ { yyextra->current->spec|=Entry::Explicit;
1134  lineCount(yyscanner);
1135  }
1136 <FindMembers>{B}*"local"{BN}+ { yyextra->current->spec|=Entry::Local;
1137  lineCount(yyscanner);
1138  }
1139 <FindMembers>{B}*"@required"{BN}+ { // Objective C 2.0 protocol required section
1140  yyextra->current->spec=(yyextra->current->spec & ~Entry::Optional) | Entry::Required;
1141  lineCount(yyscanner);
1142  }
1143 <FindMembers>{B}*"@optional"{BN}+ { // Objective C 2.0 protocol optional section
1144  yyextra->current->spec=(yyextra->current->spec & ~Entry::Required) | Entry::Optional;
1145  lineCount(yyscanner);
1146  }
1147  /*
1148 <FindMembers>{B}*"import"{BN}+ { // IDL import keyword
1149  BEGIN( NextSemi );
1150  }
1151  */
1152 <FindMembers>{B}*"typename"{BN}+ { lineCount(yyscanner); }
1153 <FindMembers>{B}*"namespace"{BNopt}/[^a-z_A-Z0-9] {
1154  yyextra->isTypedef=FALSE;
1155  yyextra->current->section = Entry::NAMESPACE_SEC;
1156  yyextra->current->type = "namespace" ;
1157  yyextra->current->fileName = yyextra->yyFileName;
1158  yyextra->current->startLine = yyextra->yyLineNr;
1159  yyextra->current->startColumn = yyextra->yyColNr;
1160  yyextra->current->bodyLine = yyextra->yyLineNr;
1161  yyextra->current->bodyColumn = yyextra->yyColNr;
1162  lineCount(yyscanner);
1163  if (yyextra->insidePHP)
1164  {
1165  BEGIN( PackageName );
1166  }
1167  else
1168  {
1169  BEGIN( CompoundName );
1170  }
1171  }
1172 <FindMembers>{B}*"module"{BN}+ {
1173  lineCount(yyscanner);
1174  if (yyextra->insideIDL || yyextra->insideSlice)
1175  {
1176  yyextra->isTypedef=FALSE;
1177  yyextra->current->section = Entry::NAMESPACE_SEC;
1178  yyextra->current->type = "module" ;
1179  yyextra->current->fileName = yyextra->yyFileName;
1180  yyextra->current->startLine = yyextra->yyLineNr;
1181  yyextra->current->startColumn = yyextra->yyColNr;
1182  yyextra->current->bodyLine = yyextra->yyLineNr;
1183  yyextra->current->bodyColumn = yyextra->yyColNr;
1184  BEGIN( CompoundName );
1185  }
1186  else if (yyextra->insideD)
1187  {
1188  lineCount(yyscanner);
1189  BEGIN(PackageName);
1190  }
1191  else
1192  {
1193  addType(yyscanner);
1194  yyextra->current->name = QCString(yytext).stripWhiteSpace();
1195  }
1196  }
1197 <FindMembers>{B}*"library"{BN}+ {
1198  lineCount(yyscanner);
1199  if (yyextra->insideIDL)
1200  {
1201  yyextra->isTypedef=FALSE;
1202  yyextra->current->section = Entry::NAMESPACE_SEC;
1203  yyextra->current->type = "library" ;
1204  yyextra->current->fileName = yyextra->yyFileName;
1205  yyextra->current->startLine = yyextra->yyLineNr;
1206  yyextra->current->startColumn = yyextra->yyColNr;
1207  yyextra->current->bodyLine = yyextra->yyLineNr;
1208  yyextra->current->bodyColumn = yyextra->yyColNr;
1209  BEGIN( CompoundName );
1210  }
1211  else
1212  {
1213  addType(yyscanner);
1214  yyextra->current->name = QCString(yytext).stripWhiteSpace();
1215  }
1216  }
1217 <FindMembers>{B}*"constants"{BN}+ { // UNO IDL constant group
1218  lineCount(yyscanner);
1219  if (yyextra->insideIDL)
1220  {
1221  yyextra->isTypedef=FALSE;
1222  yyextra->current->section = Entry::NAMESPACE_SEC;
1223  yyextra->current->type = "constants";
1224  yyextra->current->fileName = yyextra->yyFileName;
1225  yyextra->current->startLine = yyextra->yyLineNr;
1226  yyextra->current->startColumn = yyextra->yyColNr;
1227  yyextra->current->bodyLine = yyextra->yyLineNr;
1228  yyextra->current->bodyColumn = yyextra->yyColNr;
1229  BEGIN( CompoundName );
1230  }
1231  else
1232  {
1233  addType(yyscanner);
1234  yyextra->current->name = QCString(yytext).stripWhiteSpace();
1235  }
1236  }
1237 <FindMembers>{BN}*("service"){BN}+ { // UNO IDL service
1238  lineCount(yyscanner);
1239  if (yyextra->insideIDL)
1240  {
1241  yyextra->isTypedef=FALSE;
1242  yyextra->current->section = Entry::CLASS_SEC;
1243  yyextra->current->spec = Entry::Service |
1244  // preserve UNO IDL [optional] or published
1245  (yyextra->current->spec & (Entry::Optional|Entry::Published));
1246  addType(yyscanner);
1247  yyextra->current->type += " service " ;
1248  yyextra->current->fileName = yyextra->yyFileName;
1249  yyextra->current->startLine = yyextra->yyLineNr;
1250  yyextra->current->bodyLine = yyextra->yyLineNr;
1251  yyextra->current->bodyColumn = yyextra->yyColNr;
1252  BEGIN( CompoundName );
1253  }
1254  else // TODO is addType right? just copy/pasted
1255  {
1256  addType(yyscanner);
1257  yyextra->current->name = QCString(yytext).stripWhiteSpace();
1258  }
1259  }
1260 <FindMembers>{BN}*("singleton"){BN}+ { // UNO IDL singleton
1261  lineCount(yyscanner);
1262  if (yyextra->insideIDL)
1263  {
1264  yyextra->isTypedef=FALSE;
1265  yyextra->current->section = Entry::CLASS_SEC;
1266  yyextra->current->spec = Entry::Singleton |
1267  (yyextra->current->spec & Entry::Published); // preserve
1268  addType(yyscanner);
1269  yyextra->current->type += " singleton " ;
1270  yyextra->current->fileName = yyextra->yyFileName;
1271  yyextra->current->startLine = yyextra->yyLineNr;
1272  yyextra->current->bodyLine = yyextra->yyLineNr;
1273  yyextra->current->bodyColumn = yyextra->yyColNr;
1274  BEGIN( CompoundName );
1275  }
1276  else // TODO is addType right? just copy/pasted
1277  {
1278  addType(yyscanner);
1279  yyextra->current->name = QCString(yytext).stripWhiteSpace();
1280  }
1281  }
1282 <FindMembers>{BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java/Slice interface
1283  lineCount(yyscanner);
1284  if (yyextra->insideIDL || yyextra->insideJava || yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideSlice)
1285  {
1286  yyextra->isTypedef=FALSE;
1287  yyextra->current->section = Entry::CLASS_SEC;
1288  yyextra->current->spec = Entry::Interface |
1289  // preserve UNO IDL [optional], published, Slice local
1290  (yyextra->current->spec & (Entry::Optional|Entry::Published|Entry::Local));
1291  addType(yyscanner);
1292  yyextra->current->type += " interface" ;
1293  yyextra->current->fileName = yyextra->yyFileName;
1294  yyextra->current->startLine = yyextra->yyLineNr;
1295  yyextra->current->startColumn = yyextra->yyColNr;
1296  yyextra->current->bodyLine = yyextra->yyLineNr;
1297  yyextra->current->bodyColumn = yyextra->yyColNr;
1298  BEGIN( CompoundName );
1299  }
1300  else
1301  {
1302  addType(yyscanner);
1303  yyextra->current->name = QCString(yytext).stripWhiteSpace();
1304  }
1305  }
1306 <FindMembers>{B}*"@implementation"{BN}+ { // Objective-C class implementation
1307  lineCount(yyscanner);
1308  yyextra->isTypedef=FALSE;
1309  yyextra->current->section = Entry::OBJCIMPL_SEC;
1310  yyextra->language = yyextra->current->lang = SrcLangExt_ObjC;
1311  yyextra->insideObjC = TRUE;
1312  yyextra->current->protection = yyextra->protection = Public ;
1313  addType(yyscanner);
1314  yyextra->current->type += " implementation" ;
1315  yyextra->current->fileName = yyextra->yyFileName;
1316  yyextra->current->startLine = yyextra->yyLineNr;
1317  yyextra->current->bodyLine = yyextra->yyLineNr;
1318  yyextra->current->bodyColumn = yyextra->yyColNr;
1319  BEGIN( CompoundName );
1320  }
1321 <FindMembers>{B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute
1322  lineCount(yyscanner);
1323  yyextra->isTypedef=FALSE;
1324  yyextra->current->section = Entry::CLASS_SEC;
1325  yyextra->current->spec = Entry::Interface;
1326  if (!yyextra->insideJava)
1327  {
1328  yyextra->language = yyextra->current->lang = SrcLangExt_ObjC;
1329  yyextra->insideObjC = TRUE;
1330  }
1331  yyextra->current->protection = yyextra->protection = Public ;
1332  addType(yyscanner);
1333  yyextra->current->type += " interface" ;
1334  yyextra->current->fileName = yyextra->yyFileName;
1335  yyextra->current->startLine = yyextra->yyLineNr;
1336  yyextra->current->startColumn = yyextra->yyColNr;
1337  yyextra->current->bodyLine = yyextra->yyLineNr;
1338  yyextra->current->bodyColumn = yyextra->yyColNr;
1339  BEGIN( CompoundName );
1340  }
1341 <FindMembers>{B}*"@protocol"{BN}+ { // Objective-C protocol definition
1342  lineCount(yyscanner);
1343  yyextra->isTypedef=FALSE;
1344  yyextra->current->section = Entry::CLASS_SEC;
1345  yyextra->current->spec = Entry::Protocol;
1346  yyextra->language = yyextra->current->lang = SrcLangExt_ObjC;
1347  yyextra->insideObjC = TRUE;
1348  yyextra->current->protection = yyextra->protection = Public ;
1349  addType(yyscanner);
1350  yyextra->current->type += " protocol" ;
1351  yyextra->current->fileName = yyextra->yyFileName;
1352  yyextra->current->startLine = yyextra->yyLineNr;
1353  yyextra->current->startColumn = yyextra->yyColNr;
1354  yyextra->current->bodyLine = yyextra->yyLineNr;
1355  yyextra->current->bodyColumn = yyextra->yyColNr;
1356  BEGIN( CompoundName );
1357  }
1358 <FindMembers>{B}*"exception"{BN}+ { // Corba IDL/Slice exception
1359  yyextra->isTypedef=FALSE;
1360  yyextra->current->section = Entry::CLASS_SEC;
1361  // preserve UNO IDL, Slice local
1362  yyextra->current->spec = Entry::Exception |
1363  (yyextra->current->spec & Entry::Published) |
1364  (yyextra->current->spec & Entry::Local);
1365  addType(yyscanner);
1366  yyextra->current->type += " exception" ;
1367  yyextra->current->fileName = yyextra->yyFileName;
1368  yyextra->current->startLine = yyextra->yyLineNr;
1369  yyextra->current->startColumn = yyextra->yyColNr;
1370  yyextra->current->bodyLine = yyextra->yyLineNr;
1371  yyextra->current->bodyColumn = yyextra->yyColNr;
1372  lineCount(yyscanner);
1373  BEGIN( CompoundName );
1374  }
1375 <FindMembers>"@class" | // for Objective C class declarations
1376 <FindMembers>{B}*{TYPEDEFPREFIX}"class{" |
1377 <FindMembers>{B}*{TYPEDEFPREFIX}"class"{BN}+ {
1378  QCString decl = yytext;
1379  yyextra->isTypedef=decl.find("typedef")!=-1;
1380  bool isConst=decl.find("const")!=-1;
1381  bool isVolatile=decl.find("volatile")!=-1;
1382  yyextra->current->section = Entry::CLASS_SEC;
1383  addType(yyscanner);
1384  uint64 spec = yyextra->current->spec;
1385  if (yyextra->insidePHP && yyextra->current->spec&Entry::Abstract)
1386  {
1387  // convert Abstract to AbstractClass
1388  yyextra->current->spec=(yyextra->current->spec&~Entry::Abstract)|Entry::AbstractClass;
1389  }
1390  if (yyextra->insideSlice && spec&Entry::Local)
1391  {
1392  yyextra->current->spec|=Entry::Local;
1393  }
1394  if (isConst)
1395  {
1396  yyextra->current->type += " const";
1397  }
1398  else if (isVolatile)
1399  {
1400  yyextra->current->type += " volatile";
1401  }
1402  yyextra->current->type += " class" ;
1403  yyextra->current->fileName = yyextra->yyFileName;
1404  yyextra->current->startLine = yyextra->yyLineNr;
1405  yyextra->current->startColumn = yyextra->yyColNr;
1406  yyextra->current->bodyLine = yyextra->yyLineNr;
1407  yyextra->current->bodyColumn = yyextra->yyColNr;
1408  if (yytext[0]=='@')
1409  {
1410  yyextra->language = yyextra->current->lang = SrcLangExt_ObjC;
1411  yyextra->insideObjC = TRUE;
1412  }
1413  lineCount(yyscanner) ;
1414  if (yytext[yyleng-1]=='{') unput('{');
1415  BEGIN( CompoundName ) ;
1416  }
1417 <FindMembers>{B}*"value class{" | // C++/CLI extension
1418 <FindMembers>{B}*"value class"{BN}+ {
1419  yyextra->isTypedef=FALSE;
1420  yyextra->current->section = Entry::CLASS_SEC;
1421  yyextra->current->spec = Entry::Value;
1422  addType(yyscanner);
1423  yyextra->current->type += " value class" ;
1424  yyextra->current->fileName = yyextra->yyFileName;
1425  yyextra->current->startLine = yyextra->yyLineNr;
1426  yyextra->current->startColumn = yyextra->yyColNr;
1427  yyextra->current->bodyLine = yyextra->yyLineNr;
1428  yyextra->current->bodyColumn = yyextra->yyColNr;
1429  lineCount(yyscanner) ;
1430  if (yytext[yyleng-1]=='{') unput('{');
1431  BEGIN( CompoundName ) ;
1432  }
1433 <FindMembers>{B}*"ref class{" | // C++/CLI extension
1434 <FindMembers>{B}*"ref class"{BN}+ {
1435  yyextra->isTypedef=FALSE;
1436  yyextra->current->section = Entry::CLASS_SEC;
1437  yyextra->current->spec = Entry::Ref;
1438  addType(yyscanner);
1439  yyextra->current->type += " ref class" ;
1440  yyextra->current->fileName = yyextra->yyFileName;
1441  yyextra->current->startLine = yyextra->yyLineNr;
1442  yyextra->current->startColumn = yyextra->yyColNr;
1443  yyextra->current->bodyLine = yyextra->yyLineNr;
1444  yyextra->current->bodyColumn = yyextra->yyColNr;
1445  lineCount(yyscanner) ;
1446  if (yytext[yyleng-1]=='{') unput('{');
1447  BEGIN( CompoundName ) ;
1448  }
1449 <FindMembers>{B}*"interface class{" | // C++/CLI extension
1450 <FindMembers>{B}*"interface class"{BN}+ {
1451  yyextra->isTypedef=FALSE;
1452  yyextra->current->section = Entry::CLASS_SEC;
1453  yyextra->current->spec = Entry::Interface;
1454  addType(yyscanner);
1455  yyextra->current->type += " interface class" ;
1456  yyextra->current->fileName = yyextra->yyFileName;
1457  yyextra->current->startLine = yyextra->yyLineNr;
1458  yyextra->current->startColumn = yyextra->yyColNr;
1459  yyextra->current->bodyLine = yyextra->yyLineNr;
1460  yyextra->current->bodyColumn = yyextra->yyColNr;
1461  lineCount(yyscanner) ;
1462  if (yytext[yyleng-1]=='{') unput('{');
1463  BEGIN( CompoundName ) ;
1464  }
1465 <FindMembers>{B}*"coclass"{BN}+ {
1466  if (yyextra->insideIDL)
1467  {
1468  yyextra->isTypedef=FALSE;
1469  yyextra->current->section = Entry::CLASS_SEC;
1470  addType(yyscanner);
1471  yyextra->current->type += " coclass" ;
1472  yyextra->current->fileName = yyextra->yyFileName;
1473  yyextra->current->startLine = yyextra->yyLineNr;
1474  yyextra->current->startColumn = yyextra->yyColNr;
1475  yyextra->current->bodyLine = yyextra->yyLineNr;
1476  yyextra->current->bodyColumn = yyextra->yyColNr;
1477  lineCount(yyscanner) ;
1478  BEGIN( CompoundName ) ;
1479  }
1480  else
1481  {
1482  addType(yyscanner);
1483  yyextra->current->name = yytext;
1484  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
1485  lineCount(yyscanner);
1486  }
1487  }
1488 <FindMembers>{B}*{TYPEDEFPREFIX}"struct{" |
1489 <FindMembers>{B}*{TYPEDEFPREFIX}"struct"/{BN}+ {
1490  QCString decl = yytext;
1491  yyextra->isTypedef=decl.find("typedef")!=-1;
1492  bool isConst=decl.find("const")!=-1;
1493  bool isVolatile=decl.find("volatile")!=-1;
1494  yyextra->current->section = Entry::CLASS_SEC ;
1495  // preserve UNO IDL & Inline attributes, Slice local
1496  yyextra->current->spec = Entry::Struct |
1497  (yyextra->current->spec & Entry::Published) |
1498  (yyextra->current->spec & Entry::Inline) |
1499  (yyextra->current->spec & Entry::Local);
1500  // bug 582676: can be a struct nested in an interface so keep yyextra->insideObjC state
1501  //yyextra->current->objc = yyextra->insideObjC = FALSE;
1502  addType(yyscanner);
1503  if (isConst)
1504  {
1505  yyextra->current->type += " const";
1506  }
1507  else if (isVolatile)
1508  {
1509  yyextra->current->type += " volatile";
1510  }
1511  yyextra->current->type += " struct" ;
1512  yyextra->current->fileName = yyextra->yyFileName;
1513  yyextra->current->startLine = yyextra->yyLineNr;
1514  yyextra->current->startColumn = yyextra->yyColNr;
1515  yyextra->current->bodyLine = yyextra->yyLineNr;
1516  yyextra->current->bodyColumn = yyextra->yyColNr;
1517  lineCount(yyscanner) ;
1518  if (yytext[yyleng-1]=='{') unput('{');
1519  BEGIN( CompoundName ) ;
1520  }
1521 <FindMembers>{B}*"value struct{" | // C++/CLI extension
1522 <FindMembers>{B}*"value struct"{BN}+ {
1523  yyextra->isTypedef=FALSE;
1524  yyextra->current->section = Entry::CLASS_SEC;
1525  yyextra->current->spec = Entry::Struct | Entry::Value;
1526  addType(yyscanner);
1527  yyextra->current->type += " value struct" ;
1528  yyextra->current->fileName = yyextra->yyFileName;
1529  yyextra->current->startLine = yyextra->yyLineNr;
1530  yyextra->current->startColumn = yyextra->yyColNr;
1531  yyextra->current->bodyLine = yyextra->yyLineNr;
1532  yyextra->current->bodyColumn = yyextra->yyColNr;
1533  lineCount(yyscanner) ;
1534  if (yytext[yyleng-1]=='{') unput('{');
1535  BEGIN( CompoundName ) ;
1536  }
1537 <FindMembers>{B}*"ref struct{" | // C++/CLI extension
1538 <FindMembers>{B}*"ref struct"{BN}+ {
1539  yyextra->isTypedef=FALSE;
1540  yyextra->current->section = Entry::CLASS_SEC;
1541  yyextra->current->spec = Entry::Struct | Entry::Ref;
1542  addType(yyscanner);
1543  yyextra->current->type += " ref struct" ;
1544  yyextra->current->fileName = yyextra->yyFileName;
1545  yyextra->current->startLine = yyextra->yyLineNr;
1546  yyextra->current->startColumn = yyextra->yyColNr;
1547  yyextra->current->bodyLine = yyextra->yyLineNr;
1548  yyextra->current->bodyColumn = yyextra->yyColNr;
1549  lineCount(yyscanner) ;
1550  if (yytext[yyleng-1]=='{') unput('{');
1551  BEGIN( CompoundName ) ;
1552  }
1553 <FindMembers>{B}*"interface struct{" | // C++/CLI extension
1554 <FindMembers>{B}*"interface struct"{BN}+ {
1555  yyextra->isTypedef=FALSE;
1556  yyextra->current->section = Entry::CLASS_SEC;
1557  yyextra->current->spec = Entry::Struct | Entry::Interface;
1558  addType(yyscanner);
1559  yyextra->current->type += " interface struct";
1560  yyextra->current->fileName = yyextra->yyFileName;
1561  yyextra->current->startLine = yyextra->yyLineNr;
1562  yyextra->current->startColumn = yyextra->yyColNr;
1563  yyextra->current->bodyLine = yyextra->yyLineNr;
1564  yyextra->current->bodyColumn = yyextra->yyColNr;
1565  lineCount(yyscanner) ;
1566  if (yytext[yyleng-1]=='{') unput('{');
1567  BEGIN( CompoundName ) ;
1568  }
1569 <FindMembers>{B}*{TYPEDEFPREFIX}"union{" |
1570 <FindMembers>{B}*{TYPEDEFPREFIX}"union"{BN}+ {
1571  QCString decl=yytext;
1572  yyextra->isTypedef=decl.find("typedef")!=-1;
1573  bool isConst=decl.find("const")!=-1;
1574  bool isVolatile=decl.find("volatile")!=-1;
1575  yyextra->current->section = Entry::CLASS_SEC;
1576  yyextra->current->spec = Entry::Union;
1577  // bug 582676: can be a struct nested in an interface so keep yyextra->insideObjC state
1578  //yyextra->current->objc = yyextra->insideObjC = FALSE;
1579  addType(yyscanner);
1580  if (isConst)
1581  {
1582  yyextra->current->type += " const";
1583  }
1584  else if (isVolatile)
1585  {
1586  yyextra->current->type += " volatile";
1587  }
1588  yyextra->current->type += " union" ;
1589  yyextra->current->fileName = yyextra->yyFileName;
1590  yyextra->current->startLine = yyextra->yyLineNr;
1591  yyextra->current->startColumn = yyextra->yyColNr;
1592  yyextra->current->bodyLine = yyextra->yyLineNr;
1593  yyextra->current->bodyColumn = yyextra->yyColNr;
1594  lineCount(yyscanner) ;
1595  if (yytext[yyleng-1]=='{') unput('{');
1596  BEGIN( CompoundName ) ;
1597  }
1598 <FindMembers>{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?"{" |
1599 <FindMembers>{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?{BN}+ { // for IDL: typedef [something] enum
1600  QCString text=yytext;
1601  yyextra->isTypedef = text.find("typedef")!=-1;
1602  bool isStrongEnum = text.find("class")!=-1 || yyextra->insideCS;
1603  bool isEnumSytruct = text.find("struct")!=-1;
1604  if (yyextra->insideJava)
1605  {
1606  yyextra->current->section = Entry::CLASS_SEC;
1607  yyextra->current->spec = Entry::Enum;
1608  }
1609  else
1610  {
1611  yyextra->current->section = Entry::ENUM_SEC ;
1612  }
1613  addType(yyscanner);
1614  yyextra->current->type += " enum";
1615  if (isStrongEnum)
1616  {
1617  yyextra->current->spec |= Entry::Strong;
1618  }
1619  if (isEnumSytruct)
1620  {
1621  yyextra->current->spec |= Entry::Strong;
1622  yyextra->current->spec |= Entry::EnumStruct;
1623  }
1624  yyextra->current->fileName = yyextra->yyFileName;
1625  yyextra->current->startLine = yyextra->yyLineNr;
1626  yyextra->current->startColumn = yyextra->yyColNr;
1627  yyextra->current->bodyLine = yyextra->yyLineNr;
1628  yyextra->current->bodyColumn = yyextra->yyColNr;
1629  lineCount(yyscanner) ;
1630  if (yytext[yyleng-1]=='{') unput('{');
1631  BEGIN( CompoundName ) ;
1632  }
1633 <FindMembers>{B}*"concept"{BN}+ { // C++20 concept
1634  yyextra->isTypedef=FALSE;
1635  yyextra->current->section = Entry::CONCEPT_SEC;
1636  addType(yyscanner);
1637  yyextra->current->type += " concept";
1638  yyextra->current->fileName = yyextra->yyFileName;
1639  yyextra->current->startLine = yyextra->yyLineNr;
1640  yyextra->current->startColumn = yyextra->yyColNr;
1641  yyextra->current->bodyLine = yyextra->yyLineNr;
1642  yyextra->current->bodyColumn = yyextra->yyColNr;
1643  lineCount(yyscanner) ;
1644  BEGIN( ConceptName ) ;
1645  }
1646 <Operator>"("{BN}*")"({BN}*"<"[^>]*">"){BNopt}/"(" { // A::operator()<int>(int arg)
1647  lineCount(yyscanner);
1648  yyextra->current->name += "()";
1649  BEGIN( FindMembers );
1650  }
1651 <Operator>"("{BN}*")"{BNopt}/"(" {
1652  lineCount(yyscanner);
1653  yyextra->current->name += yytext ;
1654  yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
1655  BEGIN( FindMembers ) ;
1656  }
1657 <Operator>";" { // can occur when importing members
1658  unput(';');
1659  BEGIN( FindMembers ) ;
1660  }
1661 <Operator>[^(] {
1662  lineCount(yyscanner);
1663  yyextra->current->name += *yytext ;
1664  }
1665 <Operator>"<>" { /* skip guided templ specifiers */ }
1666 <Operator>"(" {
1667  yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
1668  unput(*yytext);
1669  BEGIN( FindMembers ) ;
1670  }
1671 <FindMembers>("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension
1672  lineCount(yyscanner);
1673  ArgumentList al;
1674  //yyextra->current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template;
1675  yyextra->current->tArgLists.push_back(al);
1676  yyextra->currentArgumentList = &yyextra->current->tArgLists.back();
1677  yyextra->templateStr="<";
1678  yyextra->fullArgString = yyextra->templateStr;
1679  yyextra->copyArgString = &yyextra->templateStr;
1680  yyextra->currentArgumentContext = FindMembers;
1681  BEGIN( ReadTempArgs );
1682  }
1683 <FindMembers>"namespace"{BN}+/{ID}{BN}*"=" { // namespace alias
1684  lineCount(yyscanner);
1685  BEGIN( NSAliasName );
1686  }
1687 <NSAliasName>{ID} {
1688  yyextra->aliasName = yytext;
1689  BEGIN( NSAliasArg );
1690  }
1691 <NSAliasArg>({ID}"::")*{ID} {
1692  //printf("Inserting namespace alias %s::%s->%s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->aliasName),yytext);
1693  // TODO: namespace aliases are now treated as global entities
1694  // while they should be aware of the scope they are in
1695  Doxygen::namespaceAliasMap.insert({yyextra->aliasName.str(),std::string(yytext)});
1696  }
1697 <NSAliasArg>";" {
1698  BEGIN( FindMembers );
1699  }
1700 <PHPUse>({ID}{BN}*"\\"{BN}*)*{ID}/{BN}+"as" {
1701  lineCount(yyscanner);
1702  yyextra->aliasName=yytext;
1703  BEGIN(PHPUseAs);
1704  }
1705 <PHPUse>({ID}{BN}*"\\"{BN}*)*{ID} {
1706  lineCount(yyscanner);
1707  yyextra->current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::"));
1708  //printf("PHP: adding use relation: %s\n",qPrint(yyextra->current->name));
1709  yyextra->current->fileName = yyextra->yyFileName;
1710  // add a using declaration
1711  yyextra->current->section=Entry::USINGDECL_SEC;
1712  yyextra->current_root->copyToSubEntry(yyextra->current);
1713  // also add it as a using directive
1714  yyextra->current->section=Entry::USINGDIR_SEC;
1715  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1716  initEntry(yyscanner);
1717  yyextra->aliasName.resize(0);
1718  }
1719 <PHPUseAs>{BN}+"as"{BN}+ {
1720  lineCount(yyscanner);
1721  }
1722 <PHPUseAs>{PHPUSEKW} {
1723  }
1724 <PHPUseAs>{ID} {
1725  //printf("PHP: adding use as relation: %s->%s\n",yytext,qPrint(yyextra->aliasName));
1726  if (!yyextra->aliasName.isEmpty())
1727  {
1728  Doxygen::namespaceAliasMap.insert({yytext,
1729  std::string(removeRedundantWhiteSpace(
1730  substitute(yyextra->aliasName,"\\","::")).str())});
1731  }
1732  yyextra->aliasName.resize(0);
1733  }
1734 <PHPUse,PHPUseAs>[,;] {
1735  if (*yytext==',')
1736  {
1737  BEGIN(PHPUse);
1738  }
1739  else
1740  {
1741  BEGIN(FindMembers);
1742  }
1743  }
1744 <JavaImport>({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive
1745  lineCount(yyscanner);
1746  QCString scope=yytext;
1747  yyextra->current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::"));
1748  yyextra->current->fileName = yyextra->yyFileName;
1749  yyextra->current->section=Entry::USINGDIR_SEC;
1750  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1751  initEntry(yyscanner);
1752  BEGIN(Using);
1753  }
1754 <JavaImport>({ID}{BN}*"."{BN}*)+{ID} { // class import => add as a using declaration
1755  lineCount(yyscanner);
1756  QCString scope=yytext;
1757  yyextra->current->name=removeRedundantWhiteSpace(substitute(scope,".","::"));
1758  yyextra->current->fileName = yyextra->yyFileName;
1759  if (yyextra->insideD)
1760  {
1761  yyextra->current->section=Entry::USINGDIR_SEC;
1762  }
1763  else
1764  {
1765  //printf("import name = %s -> %s\n",yytext,qPrint(yyextra->current->name));
1766  yyextra->current->section=Entry::USINGDECL_SEC;
1767  }
1768  yyextra->previous = yyextra->current;
1769  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1770  initEntry(yyscanner);
1771  BEGIN(Using);
1772  }
1773 <FindMembers>"using"{BN}+ {
1774  yyextra->current->startLine=yyextra->yyLineNr;
1775  yyextra->current->startColumn = yyextra->yyColNr;
1776  lineCount(yyscanner);
1777  BEGIN(Using);
1778  }
1779 <Using>"namespace"{BN}+ { lineCount(yyscanner); BEGIN(UsingDirective); }
1780 <Using>({ID}{BN}*("::"|"."){BN}*)*({ID}|{OPERATOR}) {
1781  lineCount(yyscanner);
1782  yyextra->current->name=yytext;
1783  yyextra->current->fileName = yyextra->yyFileName;
1784  yyextra->current->section=Entry::USINGDECL_SEC;
1785  yyextra->current->startLine = yyextra->yyLineNr;
1786  yyextra->previous = yyextra->current;
1787  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1788  initEntry(yyscanner);
1789  if (yyextra->insideCS) /* Hack: in C# a using declaration and
1790  directive have the same syntax, so we
1791  also add it as a using directive here
1792  */
1793  {
1794  yyextra->current->name=yytext;
1795  yyextra->current->fileName = yyextra->yyFileName;
1796  yyextra->current->startLine = yyextra->yyLineNr;
1797  yyextra->current->startColumn = yyextra->yyColNr;
1798  yyextra->current->section=Entry::USINGDIR_SEC;
1799  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1800  initEntry(yyscanner);
1801  }
1802  BEGIN(Using);
1803  }
1804 <Using>"=" { // C++11 style template alias?
1805  BEGIN(UsingAlias);
1806  }
1807 <UsingAlias>";" {
1808  yyextra->previous->section=Entry::VARIABLE_SEC;
1809  yyextra->previous->args = yyextra->previous->args.stripWhiteSpace();
1810  yyextra->previous->args.stripPrefix("class ");
1811  yyextra->previous->args.stripPrefix("struct ");
1812  yyextra->previous->type = "typedef "+yyextra->previous->args;
1813  yyextra->previous->type=yyextra->previous->type.simplifyWhiteSpace();
1814  yyextra->previous->args.resize(0);
1815  yyextra->previous->name=yyextra->previous->name.stripWhiteSpace();
1816  yyextra->previous->bodyLine = yyextra->yyLineNr;
1817  yyextra->previous->bodyColumn = yyextra->yyColNr;
1818  yyextra->previous->spec |= Entry::Alias;
1819  BEGIN(FindMembers);
1820  }
1821 <UsingAlias>";"{BN}*{DCOMM}"<" {
1822  yyextra->docBlockContext = UsingAliasEnd;
1823  yyextra->docBlockInBody = FALSE;
1824  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
1825  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
1826  QCString indent;
1827  indent.fill(' ',computeIndent(yytext,yyextra->column));
1828  yyextra->docBlock.str(indent.str());
1829  lineCount(yyscanner);
1830 
1831  yyextra->docBlockTerm = ';';
1832  if (yytext[yyleng-3]=='/')
1833  {
1834  startCommentBlock(yyscanner,TRUE);
1835  BEGIN( DocLine );
1836  }
1837  else
1838  {
1839  startCommentBlock(yyscanner,FALSE);
1840  BEGIN( DocBlock );
1841  }
1842  }
1843 <UsingAlias>">>" {
1844  yyextra->previous->args+="> >"; // see bug769552
1845  }
1846 <UsingAlias>. {
1847  yyextra->previous->args+=yytext;
1848  }
1849 <UsingAlias>\n {
1850  yyextra->previous->args+=yytext;
1851  lineCount(yyscanner);
1852  }
1853 <UsingAliasEnd>";" {
1854  yyextra->previous->doc = yyextra->current->doc;
1855  yyextra->previous->brief = yyextra->current->brief;
1856  yyextra->current->doc.resize(0);
1857  yyextra->current->brief.resize(0);
1858  unput(';');
1859  BEGIN(UsingAlias);
1860  }
1861 <UsingDirective>{SCOPENAME} { yyextra->current->name=removeRedundantWhiteSpace(yytext);
1862  yyextra->current->fileName = yyextra->yyFileName;
1863  yyextra->current->section=Entry::USINGDIR_SEC;
1864  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1865  initEntry(yyscanner);
1866  BEGIN(Using);
1867  }
1868 <Using>";" { BEGIN(FindMembers); }
1869 <FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl
1870  QCString n=yytext;
1871  addType(yyscanner);
1872  yyextra->current->name=n.left(n.length()-2);
1873  }
1874 <FindMembers>{SCOPENAME}{BNopt}/"<" { // Note: this could be a return type!
1875  yyextra->roundCount=0;
1876  yyextra->sharpCount=0;
1877  lineCount(yyscanner);
1878  addType(yyscanner);
1879  yyextra->current->name=yytext;
1880  yyextra->current->name=yyextra->current->name.stripWhiteSpace();
1881  //yyextra->current->scopeSpec.resize(0);
1882  // yyextra->currentTemplateSpec = &yyextra->current->scopeSpec;
1883  if (nameIsOperator(yyextra->current->name))
1884  BEGIN( Operator );
1885  else
1886  BEGIN( EndTemplate );
1887  }
1888 <FindMemberName>{SCOPENAME}{BNopt}/"<" {
1889  yyextra->sharpCount=0;
1890  yyextra->roundCount=0;
1891  lineCount(yyscanner);
1892  yyextra->current->name+=((QCString)yytext).stripWhiteSpace();
1893  //yyextra->current->memberSpec.resize(0);
1894  // yyextra->currentTemplateSpec = &yyextra->current->memberSpec;
1895  if (nameIsOperator(yyextra->current->name))
1896  BEGIN( Operator );
1897  else
1898  BEGIN( EndTemplate );
1899  }
1900 <EndTemplate>"<<<" {
1901  if (!yyextra->insidePHP)
1902  {
1903  REJECT;
1904  }
1905  else
1906  {
1907  yyextra->lastHereDocContext = YY_START;
1908  BEGIN(HereDoc);
1909  }
1910  }
1911 <ClassTemplSpec,EndTemplate>"<<" {
1912  yyextra->current->name+=yytext;
1913  // *yyextra->currentTemplateSpec+=yytext;
1914  }
1915 <EndTemplate>"<" {
1916  if (yyextra->roundCount==0)
1917  {
1918  // *yyextra->currentTemplateSpec+='<';
1919  yyextra->sharpCount++;
1920  }
1921  yyextra->current->name+=yytext;
1922  }
1923 <ClassTemplSpec,EndTemplate>">>" {
1924  if (yyextra->insideJava || yyextra->insideCS || yyextra->insideCli || yyextra->roundCount==0)
1925  {
1926  unput('>');
1927  unput(' ');
1928  unput('>');
1929  }
1930  else
1931  {
1932  yyextra->current->name+=yytext;
1933  }
1934  // *yyextra->currentTemplateSpec+=yytext;
1935  }
1936 <EndTemplate>">" {
1937  yyextra->current->name+='>';
1938  // *yyextra->currentTemplateSpec+='>';
1939  if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
1940  {
1941  //printf("Found %s\n",qPrint(yyextra->current->name));
1942  BEGIN(FindMembers);
1943  }
1944  }
1945 <EndTemplate>">"{BN}*"(" {
1946  lineCount(yyscanner);
1947  yyextra->current->name+='>';
1948  // *yyextra->currentTemplateSpec+='>';
1949  --yyextra->sharpCount;
1950  if (yyextra->roundCount==0 && yyextra->sharpCount<=0)
1951  {
1952  yyextra->current->bodyLine = yyextra->yyLineNr;
1953  yyextra->current->bodyColumn = yyextra->yyColNr;
1954  yyextra->current->args = "(";
1955  yyextra->currentArgumentContext = FuncQual;
1956  yyextra->fullArgString = yyextra->current->args;
1957  yyextra->copyArgString = &yyextra->current->args;
1958  //printf("Found %s\n",qPrint(yyextra->current->name));
1959  BEGIN( ReadFuncArgType ) ;
1960  }
1961  else
1962  {
1963  yyextra->current->name+="(";
1964  yyextra->roundCount++;
1965  }
1966  }
1967 <EndTemplate>">"{BNopt}/"("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance
1968  lineCount(yyscanner);
1969  yyextra->current->name+='>';
1970  if (yyextra->roundCount==0)
1971  {
1972  BEGIN(FindMembers);
1973  }
1974  }
1975 <EndTemplate>">"{BNopt}/"::" {
1976  lineCount(yyscanner);
1977  yyextra->current->name+='>';
1978  // *yyextra->currentTemplateSpec+='>';
1979  if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
1980  {
1981  BEGIN(FindMemberName);
1982  }
1983  }
1984 <ClassTemplSpec,EndTemplate>"(" { yyextra->current->name+=*yytext;
1985  yyextra->roundCount++;
1986  }
1987 <ClassTemplSpec,EndTemplate>")" { yyextra->current->name+=*yytext;
1988  if (yyextra->roundCount>0) yyextra->roundCount--;
1989  }
1990 <EndTemplate>. {
1991  yyextra->current->name+=*yytext;
1992  // *yyextra->currentTemplateSpec+=*yytext;
1993  }
1994 <FindMembers>"define"{BN}*"("{BN}*["'] {
1995  if (yyextra->insidePHP)
1996  {
1997  yyextra->current->bodyLine = yyextra->yyLineNr;
1998  yyextra->current->bodyColumn = yyextra->yyColNr;
1999  BEGIN( DefinePHP );
2000  }
2001  else
2002  REJECT;
2003  }
2004 <CopyHereDoc>{ID} { // PHP heredoc
2005  yyextra->delimiter = yytext;
2006  *yyextra->pCopyHereDocGString << yytext;
2007  BEGIN(CopyHereDocEnd);
2008  }
2009 <CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc
2010  yyextra->delimiter = &yytext[1];
2011  *yyextra->pCopyHereDocGString << yytext;
2012  BEGIN(CopyHereDocEnd);
2013  }
2014 <HereDoc>{ID} { // PHP heredoc
2015  yyextra->delimiter = yytext;
2016  BEGIN(HereDocEnd);
2017  }
2018 <HereDoc>"'"{ID}/"'" { // PHP nowdoc
2019  yyextra->delimiter = &yytext[1];
2020  BEGIN(HereDocEnd);
2021  }
2022 <HereDocEnd>^{ID} { // id at start of the line could mark the end of the block
2023  if (yyextra->delimiter==yytext) // it is the end marker
2024  {
2025  BEGIN(yyextra->lastHereDocContext);
2026  }
2027  }
2028 <HereDocEnd>. { }
2029 <CopyHereDocEnd>^{ID} { // id at start of the line could mark the end of the block
2030  *yyextra->pCopyHereDocGString << yytext;
2031  if (yyextra->delimiter==yytext) // it is the end marker
2032  {
2033  BEGIN(yyextra->lastHereDocContext);
2034  }
2035  }
2036 <CopyHereDocEnd>\n {
2037  lineCount(yyscanner);
2038  *yyextra->pCopyHereDocGString << yytext;
2039  }
2040 <CopyHereDocEnd>{ID} {
2041  *yyextra->pCopyHereDocGString << yytext;
2042  }
2043 <CopyHereDocEnd>. {
2044  *yyextra->pCopyHereDocGString << yytext;
2045  }
2046 <FindMembers>"Q_OBJECT" { // Qt object macro
2047  }
2048 <FindMembers>"Q_PROPERTY" { // Qt property declaration
2049  yyextra->current->protection = Public ; // see bug734245 & bug735462
2050  yyextra->current->mtype = yyextra->mtype = Property;
2051  yyextra->current->type.resize(0);
2052  BEGIN(QtPropType);
2053  }
2054 <QtPropType>"(" { // start of property arguments
2055  }
2056 <QtPropAttr>")" { // end of property arguments
2057  unput(';');
2058  BEGIN(FindMembers);
2059  }
2060 <QtPropType>{B}+ {
2061  yyextra->current->name+=yytext;
2062  }
2063 <QtPropType>"*" {
2064  yyextra->current->type+= yyextra->current->name;
2065  yyextra->current->type+= yytext;
2066  yyextra->current->name="";
2067  }
2068 <QtPropType>({TSCOPE}"::")*{TSCOPE} {
2069  yyextra->current->type+= yyextra->current->name;
2070  yyextra->current->name=yytext;
2071  }
2072 <QtPropType,QtPropAttr>{B}+"READ"{B}+ {
2073  yyextra->current->spec |= Entry::Readable;
2074  BEGIN(QtPropRead);
2075  }
2076 <QtPropType,QtPropAttr>{B}+"WRITE"{B}+ {
2077  yyextra->current->spec |= Entry::Writable;
2078  BEGIN(QtPropWrite);
2079  }
2080 <QtPropType,QtPropAttr>{B}+"MEMBER"{B}+{ID} | // member property => not supported yet
2081 <QtPropType,QtPropAttr>{B}+"RESET"{B}+{ID} | // reset method => not supported yet
2082 <QtPropType,QtPropAttr>{B}+"SCRIPTABLE"{B}+{ID} | // scriptable property => not supported yet
2083 <QtPropType,QtPropAttr>{B}+"DESIGNABLE"{B}+{ID} | // designable property => not supported yet
2084 <QtPropType,QtPropAttr>{B}+"NOTIFY"{B}+{ID} | // notify property => not supported yet
2085 <QtPropType,QtPropAttr>{B}+"REVISION"{B}+{ID} | // revision property => not supported yet
2086 <QtPropType,QtPropAttr>{B}+"STORED"{B}+{ID} | // stored property => not supported yet
2087 <QtPropType,QtPropAttr>{B}+"USER"{B}+{ID} | // user property => not supported yet
2088 <QtPropType,QtPropAttr>{B}+"CONSTANT"{B} | // constant property => not supported yet
2089 <QtPropType,QtPropAttr>{B}+"FINAL"{B} { // final property => not supported yet
2090  BEGIN(QtPropAttr);
2091  }
2092 <QtPropRead>{ID} {
2093  yyextra->current->read = yytext;
2094  BEGIN(QtPropAttr);
2095  }
2096 <QtPropWrite>{ID} {
2097  yyextra->current->write = yytext;
2098  BEGIN(QtPropAttr);
2099  }
2100 <FindMembers>"friend"{BN}+("class"|"union"|"struct"){BN}+ {
2101  yyextra->current->name=yytext;
2102  lineCount(yyscanner) ;
2103  BEGIN(FindMembers);
2104  }
2105 <FindMembers>"requires" { // C++20 requires clause
2106  yyextra->current->req.resize(0);
2107  yyextra->requiresContext = YY_START;
2108  BEGIN(RequiresClause);
2109  }
2110 <RequiresClause>"requires"{BN}*/"{" { // requires requires { ... }
2111  lineCount(yyscanner) ;
2112  yyextra->current->req+=yytext;
2113  BEGIN( RequiresExpression ) ;
2114  }
2115 <RequiresClause>"requires"{BN}*"(" { // requires requires(T x) { ... }
2116  lineCount(yyscanner) ;
2117  yyextra->current->req+=yytext;
2118  yyextra->lastRoundContext=RequiresExpression;
2119  yyextra->pCopyRoundString=&yyextra->current->req;
2120  yyextra->roundCount=0;
2121  BEGIN( CopyRound ) ;
2122  }
2123 <RequiresExpression>"{" {
2124  yyextra->current->req+=yytext;
2125  yyextra->lastCurlyContext=RequiresClause;
2126  yyextra->pCopyCurlyString=&yyextra->current->req;
2127  yyextra->curlyCount=0;
2128  BEGIN( CopyCurly ) ;
2129  }
2130 <RequiresExpression>\n {
2131  yyextra->current->req+=' ';
2132  lineCount(yyscanner);
2133  }
2134 <RequiresExpression>. {
2135  yyextra->current->req+=yytext;
2136  }
2137 <RequiresClause>"(" { // requires "(A && B)"
2138  yyextra->current->req+=yytext;
2139  yyextra->lastRoundContext=RequiresClause;
2140  yyextra->pCopyRoundString=&yyextra->current->req;
2141  yyextra->roundCount=0;
2142  BEGIN( CopyRound ) ;
2143  }
2144 <RequiresClause>{ID} { // something like "requires true"
2145  if (yyextra->current->req.stripWhiteSpace().isEmpty())
2146  {
2147  yyextra->current->req=yytext;
2148  BEGIN(yyextra->requiresContext);
2149  }
2150  else
2151  {
2152  REJECT;
2153  }
2154  }
2155 <RequiresClause>{SCOPENAME}{BNopt}"(" { // "requires func(x)"
2156  yyextra->current->req+=yytext;
2157  yyextra->lastRoundContext=RequiresClause;
2158  yyextra->pCopyRoundString=&yyextra->current->req;
2159  yyextra->roundCount=0;
2160  BEGIN( CopyRound );
2161  }
2162 <RequiresClause>{SCOPENAME}{BNopt}"<" { // "requires C<S,T>"
2163  yyextra->current->req+=yytext;
2164  yyextra->lastSharpContext=RequiresClause;
2165  yyextra->pCopySharpString=&yyextra->current->req;
2166  yyextra->sharpCount=0;
2167  BEGIN( CopySharp );
2168  }
2169 <RequiresClause>"||"|"&&" { // "requires A || B" or "requires A && B"
2170  yyextra->current->req+=yytext;
2171  }
2172 <RequiresClause>{BN}+ {
2173  yyextra->current->req+=' ';
2174  lineCount(yyscanner) ;
2175  }
2176 <RequiresClause>. {
2177  unput(*yytext);
2178  yyextra->current->req=yyextra->current->req.simplifyWhiteSpace();
2179  BEGIN(yyextra->requiresContext);
2180  }
2181 <FindMembers,FindMemberName>{SCOPENAME} {
2182  if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
2183  {
2184  yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
2185  }
2186  yyextra->yyBegColNr=yyextra->yyColNr;
2187  yyextra->yyBegLineNr=yyextra->yyLineNr;
2188  lineCount(yyscanner);
2189  if (yyextra->insideIDL && yyleng==9 && qstrcmp(yytext,"cpp_quote")==0)
2190  {
2191  BEGIN(CppQuote);
2192  }
2193  else if ((yyextra->insideIDL || yyextra->insideJava || yyextra->insideD) && yyleng==6 && qstrcmp(yytext,"import")==0)
2194  {
2195  if (yyextra->insideIDL)
2196  BEGIN(NextSemi);
2197  else // yyextra->insideJava or yyextra->insideD
2198  BEGIN(JavaImport);
2199  }
2200  else if (yyextra->insidePHP && qstrcmp(yytext,"use")==0)
2201  {
2202  BEGIN(PHPUse);
2203  }
2204  else if (yyextra->insideJava && qstrcmp(yytext,"package")==0)
2205  {
2206  lineCount(yyscanner);
2207  BEGIN(PackageName);
2208  }
2209  else if (yyextra->insideIDL && qstrcmp(yytext,"case")==0)
2210  {
2211  BEGIN(IDLUnionCase);
2212  }
2213  else if (yyextra->insideTryBlock && qstrcmp(yytext,"catch")==0)
2214  {
2215  yyextra->insideTryBlock=FALSE;
2216  BEGIN(TryFunctionBlock);
2217  }
2218  else if (yyextra->insideCpp && qstrcmp(yytext,"alignas")==0)
2219  {
2220  yyextra->lastAlignAsContext = YY_START;
2221  BEGIN(AlignAs);
2222  }
2223  else if (yyextra->insideJS && qstrcmp(yytext,"var")==0)
2224  { // javascript variable
2225  yyextra->current->type="var";
2226  }
2227  else if (yyextra->insideJS && qstrcmp(yytext,"function")==0)
2228  { // javascript function
2229  yyextra->current->type="function";
2230  }
2231  else if (yyextra->insideCS && qstrcmp(yytext,"this")==0)
2232  {
2233  // C# indexer
2234  addType(yyscanner);
2235  yyextra->current->name="this";
2236  BEGIN(CSIndexer);
2237  }
2238  else if (yyextra->insideCpp && qstrcmp(yytext,"static_assert")==0)
2239  {
2240  // C++11 static_assert
2241  BEGIN(StaticAssert);
2242  }
2243  else if (yyextra->insideCpp && qstrcmp(yytext,"decltype")==0)
2244  {
2245  // C++11 decltype(x)
2246  addType(yyscanner);
2247  if (!yyextra->current->type.isEmpty()) yyextra->current->type+=' ';
2248  yyextra->current->type+=yytext;
2249  BEGIN(DeclType);
2250  }
2251  else if (yyextra->insideSlice && qstrcmp(yytext,"optional")==0)
2252  {
2253  if (yyextra->current->type.isEmpty())
2254  {
2255  yyextra->current->type = "optional";
2256  }
2257  else
2258  {
2259  yyextra->current->type += " optional";
2260  }
2261  yyextra->lastModifierContext = YY_START;
2262  BEGIN(SliceOptional);
2263  }
2264  else
2265  {
2266  if (YY_START==FindMembers)
2267  {
2268  addType(yyscanner);
2269  }
2270  bool javaLike = yyextra->insideJava || yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideJS;
2271  if (javaLike && qstrcmp(yytext,"public")==0)
2272  {
2273  yyextra->current->protection = Public;
2274  }
2275  else if (javaLike && qstrcmp(yytext,"protected")==0)
2276  {
2277  yyextra->current->protection = Protected;
2278  }
2279  else if ((yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideJS) && qstrcmp(yytext,"internal")==0)
2280  {
2281  yyextra->current->protection = Package;
2282  }
2283  else if (javaLike && qstrcmp(yytext,"private")==0)
2284  {
2285  yyextra->current->protection = Private;
2286  }
2287  else if (javaLike && qstrcmp(yytext,"static")==0)
2288  {
2289  if (YY_START==FindMembers)
2290  yyextra->current->name = yytext;
2291  else
2292  yyextra->current->name += yytext;
2293  yyextra->current->stat = TRUE;
2294  }
2295  else
2296  {
2297  if (YY_START==FindMembers)
2298  yyextra->current->name = yytext;
2299  else
2300  yyextra->current->name += yytext;
2301  if (yyextra->current->name.left(7)=="static ")
2302  {
2303  yyextra->current->stat = TRUE;
2304  yyextra->current->name= yyextra->current->name.mid(7);
2305  }
2306  else if (yyextra->current->name.left(7)=="inline ")
2307  {
2308  if (yyextra->current->type.isEmpty())
2309  {
2310  yyextra->current->type="inline";
2311  }
2312  else
2313  {
2314  yyextra->current->type+="inline ";
2315  }
2316  yyextra->current->name= yyextra->current->name.mid(7);
2317  }
2318  else if (yyextra->current->name.left(6)=="const ")
2319  {
2320  if (yyextra->current->type.isEmpty())
2321  {
2322  yyextra->current->type="const";
2323  }
2324  else
2325  {
2326  yyextra->current->type+="const ";
2327  }
2328  yyextra->current->name=yyextra->current->name.mid(6);
2329  }
2330  else if (yyextra->current->name.left(9)=="volatile ")
2331  {
2332  if (yyextra->current->type.isEmpty())
2333  {
2334  yyextra->current->type="volatile";
2335  }
2336  else
2337  {
2338  yyextra->current->type+="volatile ";
2339  }
2340  yyextra->current->name=yyextra->current->name.mid(9);
2341  }
2342  }
2343  QCString tmp=yytext;
2344  if (nameIsOperator(tmp))
2345  {
2346  BEGIN( Operator );
2347  }
2348  else
2349  {
2350  yyextra->externLinkage=FALSE; // see bug759247
2351  BEGIN(FindMembers);
2352  }
2353  }
2354  yyextra->current->name = yyextra->current->name.removeWhiteSpace();
2355  }
2356 <StaticAssert>"(" {
2357  yyextra->lastSkipRoundContext = FindMembers;
2358  yyextra->roundCount=0;
2359  BEGIN(SkipRound);
2360  }
2361 <StaticAssert>{BN}+ { lineCount(yyscanner); }
2362 <StaticAssert>. { // variable with static_assert as name?
2363  unput(*yytext);
2364  BEGIN(FindMembers);
2365  }
2366 <DeclType>"(" {
2367  yyextra->current->type+=yytext;
2368  yyextra->lastRoundContext=FindMembers;
2369  yyextra->pCopyRoundString=&yyextra->current->type;
2370  yyextra->roundCount=0;
2371  BEGIN(CopyRound);
2372  }
2373 <DeclType>{BN}+ { lineCount(yyscanner); }
2374 <DeclType>. {
2375  unput(*yytext);
2376  BEGIN(FindMembers);
2377  }
2378 <CSIndexer>"["[^\n\]]*"]" {
2379  yyextra->current->name+=removeRedundantWhiteSpace(yytext);
2380  BEGIN(FindMembers);
2381  }
2382 <FindMembers>[0-9]{ID} { // some number where we did not expect one
2383  }
2384 <FindMembers>"." {
2385  if (yyextra->insideJava || yyextra->insideCS || yyextra->insideD)
2386  {
2387  yyextra->current->name+=".";
2388  }
2389  }
2390 <FindMembers>"::" {
2391  yyextra->current->name+=yytext;
2392  }
2393 <CppQuote>"("{B}*"\"" {
2394  yyextra->insideCppQuote=TRUE;
2395  BEGIN(FindMembers);
2396  }
2397 <IDLUnionCase>"::"
2398 <IDLUnionCase>":" { BEGIN(FindMembers); }
2399 <IDLUnionCase>\n { lineCount(yyscanner); }
2400 <IDLUnionCase>.
2401 <TryFunctionBlock>\n { lineCount(yyscanner); }
2402 <TryFunctionBlock>"{" {
2403  yyextra->curlyCount=0;
2404  yyextra->lastCurlyContext = TryFunctionBlockEnd ;
2405  BEGIN( SkipCurly );
2406  }
2407 <TryFunctionBlock>.
2408 <TryFunctionBlockEnd>{BN}*"catch" { lineCount(yyscanner); BEGIN(TryFunctionBlock); // {BN}* added to fix bug 611193
2409  }
2410 <TryFunctionBlockEnd>\n { unput(*yytext); // rule added to fix bug id 601138
2411  BEGIN( FindMembers );
2412  }
2413 <TryFunctionBlockEnd>. { unput(*yytext);
2414  BEGIN( FindMembers );
2415  }
2416 <EndCppQuote>")" {
2417  yyextra->insideCppQuote=FALSE;
2418  BEGIN(FindMembers);
2419  }
2420 <FindMembers,FindFields>{B}*"#" { if (yyextra->insidePHP)
2421  REJECT;
2422  yyextra->lastCPPContext = YY_START;
2423  BEGIN( SkipCPP ) ;
2424  }
2425 <FindMembers,FindFields>{B}*"#"{B}*("cmake")?"define" {
2426  if (yyextra->insidePHP)
2427  REJECT;
2428  yyextra->current->bodyLine = yyextra->yyLineNr;
2429  yyextra->current->bodyColumn = yyextra->yyColNr;
2430  yyextra->lastDefineContext = YY_START;
2431  BEGIN( Define );
2432  }
2433 <FindMembers,ReadBody,ReadNSBody,ReadBodyIntf,SkipCurly,SkipCurlyCpp>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
2434  yyextra->yyLineNr = atoi(&yytext[1]);
2435  //printf("setting line number to %d\n",yyextra->yyLineNr);
2436  yyextra->lastPreLineCtrlContext = YY_START;
2437  if (YY_START==ReadBody ||
2438  YY_START==ReadNSBody ||
2439  YY_START==ReadBodyIntf)
2440  {
2441  yyextra->current->program << yytext;
2442  }
2443  BEGIN( PreLineCtrl );
2444  }
2445 <PreLineCtrl>"\""[^\n\"]*"\"" {
2446  yyextra->yyFileName = stripQuotes(yytext);
2447  if (yyextra->lastPreLineCtrlContext==ReadBody ||
2448  yyextra->lastPreLineCtrlContext==ReadNSBody ||
2449  yyextra->lastPreLineCtrlContext==ReadBodyIntf)
2450  {
2451  yyextra->current->program << yytext;
2452  }
2453  }
2454 <PreLineCtrl>. {
2455  if (yyextra->lastPreLineCtrlContext==ReadBody ||
2456  yyextra->lastPreLineCtrlContext==ReadNSBody ||
2457  yyextra->lastPreLineCtrlContext==ReadBodyIntf)
2458  {
2459  yyextra->current->program << yytext;
2460  }
2461  }
2462 <PreLineCtrl>\n {
2463  if (yyextra->lastPreLineCtrlContext==ReadBody ||
2464  yyextra->lastPreLineCtrlContext==ReadNSBody ||
2465  yyextra->lastPreLineCtrlContext==ReadBodyIntf)
2466  {
2467  yyextra->current->program << yytext;
2468  }
2469  lineCount(yyscanner);
2470  BEGIN( yyextra->lastPreLineCtrlContext );
2471  }
2472 <SkipCPP>.
2473 <SkipCPP>\\[\r]*"\n"[\r]* { lineCount(yyscanner); }
2474 <SkipCPP>[\r]*\n[\r]* { lineCount(yyscanner);
2475  BEGIN( yyextra->lastCPPContext) ;
2476  }
2477 <Define>{ID}{B}*"(" {
2478  yyextra->current->name = yytext;
2479  yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
2480  yyextra->current->args = "(";
2481  yyextra->current->bodyLine = yyextra->yyLineNr;
2482  yyextra->current->bodyColumn = yyextra->yyColNr;
2483  yyextra->currentArgumentContext = DefineEnd;
2484  yyextra->fullArgString=yyextra->current->args;
2485  yyextra->copyArgString=&yyextra->current->args;
2486  BEGIN( ReadFuncArgType ) ;
2487  }
2488  /*
2489 <DefineArg>")" {
2490  //printf("Define with args\n");
2491  yyextra->current->args += ')';
2492  BEGIN( DefineEnd );
2493  }
2494 <DefineArg>. {
2495  yyextra->current->args += *yytext;
2496  }
2497  */
2498 <Define>{ID} {
2499  //printf("Define '%s' without args\n",yytext);
2500  if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
2501  {
2502  yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
2503  }
2504  yyextra->current->bodyLine = yyextra->yyLineNr;
2505  yyextra->current->bodyColumn = yyextra->yyColNr;
2506  yyextra->current->name = yytext;
2507  BEGIN(DefineEnd);
2508  }
2509 <DefineEnd>\n {
2510  //printf("End define: doc=%s docFile=%s docLine=%d\n",qPrint(yyextra->current->doc),qPrint(yyextra->current->docFile),yyextra->current->docLine);
2511  yyextra->current->fileName = yyextra->yyFileName;
2512  yyextra->current->startLine = yyextra->yyLineNr;
2513  yyextra->current->startColumn = yyextra->yyColNr;
2514  yyextra->current->type.resize(0);
2515  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
2516  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2517  yyextra->current->section = Entry::DEFINE_SEC;
2518  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2519  lineCount(yyscanner);
2520  initEntry(yyscanner);
2521  BEGIN(yyextra->lastDefineContext);
2522  }
2523 <DefinePHPEnd>";" {
2524  //printf("End define\n");
2525  yyextra->current->fileName = yyextra->yyFileName;
2526  yyextra->current->startLine = yyextra->yyLineNr;
2527  yyextra->current->startColumn = yyextra->yyColNr;
2528  yyextra->current->type.resize(0);
2529  yyextra->current->type = "const";
2530  QCString init = yyextra->current->initializer.str();
2531  init = init.simplifyWhiteSpace();
2532  init = init.left(init.length()-1);
2533  yyextra->current->initializer.str(init.str());
2534  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2535  yyextra->current->section = Entry::VARIABLE_SEC;
2536  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2537  initEntry(yyscanner);
2538  BEGIN(FindMembers);
2539  }
2540 <DefinePHPEnd>.
2541 <DefineEnd>\\[\r]?\n {
2542  lineCount(yyscanner);
2543  }
2544 <DefineEnd>\" {
2545  if (yyextra->insideIDL && yyextra->insideCppQuote)
2546  {
2547  BEGIN(EndCppQuote);
2548  }
2549  else
2550  {
2551  yyextra->lastStringContext=DefineEnd;
2552  BEGIN(SkipString);
2553  }
2554  }
2555 <DefineEnd>.
2556 <DefinePHP>{ID}["']{BN}*","{BN}* {
2557  yyextra->current->name = yytext;
2558  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2559  yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
2560  yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1);
2561  yyextra->current->bodyLine = yyextra->yyLineNr;
2562  yyextra->current->bodyColumn = yyextra->yyColNr;
2563  yyextra->lastRoundContext = DefinePHPEnd;
2564  yyextra->pCopyRoundGString = &yyextra->current->initializer;
2565  yyextra->roundCount = 0;
2566  BEGIN( GCopyRound );
2567  }
2568 
2569 <FindMembers>[\^%] { // ^ and % are C++/CLI extensions
2570  if (yyextra->insideCli)
2571  {
2572  addType(yyscanner);
2573  yyextra->current->name = yytext ;
2574  }
2575  else
2576  {
2577  REJECT;
2578  }
2579  }
2580 <FindMembers>[*&]+ {
2581  yyextra->current->name += yytext ;
2582  addType(yyscanner);
2583  }
2584 <FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,ReadInitializerPtr,OldStyleArgs,DefinePHPEnd>";"{BN}*{DCOMM}"<" {
2585  if (yyextra->current->bodyLine==-1)
2586  {
2587  yyextra->current->bodyLine=yyextra->yyLineNr;
2588  yyextra->current->bodyColumn = yyextra->yyColNr;
2589  }
2590  yyextra->docBlockContext = YY_START;
2591  yyextra->docBlockInBody = FALSE;
2592  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2593  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2594 
2595  QCString indent;
2596  indent.fill(' ',computeIndent(yytext,yyextra->column));
2597  yyextra->docBlock.str(indent.str());
2598  //printf("indent=%d\n",computeIndent(yytext+1,yyextra->column));
2599  lineCount(yyscanner);
2600 
2601  yyextra->docBlockTerm = ';';
2602  if (YY_START==EnumBaseType && yyextra->current->section==Entry::ENUM_SEC)
2603  {
2604  yyextra->current->bitfields = ":"+yyextra->current->args;
2605  yyextra->current->args.resize(0);
2606  yyextra->current->section=Entry::VARIABLE_SEC;
2607  }
2608  if (yytext[yyleng-3]=='/')
2609  {
2610  startCommentBlock(yyscanner,TRUE);
2611  BEGIN( DocLine );
2612  }
2613  else
2614  {
2615  startCommentBlock(yyscanner,FALSE);
2616  BEGIN( DocBlock );
2617  }
2618  }
2619 <MemberSpec,FindFields,FindMembers,NextSemi,EnumBaseType,BitFields,ReadInitializer,ReadInitializerPtr,OldStyleArgs>","{BN}*{DCOMM}"<" {
2620  yyextra->docBlockContext = YY_START;
2621  yyextra->docBlockInBody = FALSE;
2622  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2623  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2624 
2625  QCString indent;
2626  indent.fill(' ',computeIndent(yytext,yyextra->column));
2627  yyextra->docBlock.str(indent.str());
2628  lineCount(yyscanner);
2629 
2630  yyextra->docBlockTerm = ',';
2631  if (YY_START==EnumBaseType && yyextra->current->section==Entry::ENUM_SEC)
2632  {
2633  yyextra->current->bitfields = ":"+yyextra->current->args;
2634  yyextra->current->args.resize(0);
2635  yyextra->current->section=Entry::VARIABLE_SEC;
2636  }
2637  if (yytext[yyleng-3]=='/')
2638  {
2639  startCommentBlock(yyscanner,TRUE);
2640  BEGIN( DocLine );
2641  }
2642  else
2643  {
2644  startCommentBlock(yyscanner,FALSE);
2645  BEGIN( DocBlock );
2646  }
2647  }
2648 <DefineEnd,FindFields,ReadInitializer,ReadInitializerPtr,OldStyleArgs>{BN}*{DCOMM}"<" {
2649  if (yyextra->current->bodyLine==-1)
2650  {
2651  yyextra->current->bodyLine=yyextra->yyLineNr;
2652  yyextra->current->bodyColumn = yyextra->yyColNr;
2653  }
2654  yyextra->docBlockContext = YY_START;
2655  yyextra->docBlockInBody = FALSE;
2656  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2657  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2658  QCString indent;
2659  indent.fill(' ',computeIndent(yytext,yyextra->column));
2660  yyextra->docBlock.str(indent.str());
2661  lineCount(yyscanner);
2662 
2663  yyextra->docBlockTerm = 0;
2664  if (yytext[yyleng-3]=='/')
2665  {
2666  startCommentBlock(yyscanner,TRUE);
2667  BEGIN( DocLine );
2668  }
2669  else
2670  {
2671  startCommentBlock(yyscanner,FALSE);
2672  BEGIN( DocBlock );
2673  }
2674  }
2675 
2676 <FindMembers,FindFields>({CPPC}([!/]){B}*{CMD}"{")|({CCS}([!*]){B}*{CMD}"{") {
2677  //handleGroupStartCommand(yyextra->current->name);
2678  if (yyextra->previous && yyextra->previous->section==Entry::GROUPDOC_SEC)
2679  {
2680  // link open command to the group defined in the yyextra->previous entry
2681  yyextra->commentScanner.open(yyextra->previous.get(),yyextra->yyFileName,yyextra->yyLineNr);
2682  }
2683  else
2684  {
2685  // link open command to the yyextra->current entry
2686  yyextra->commentScanner.open(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr);
2687  }
2688  //yyextra->current = tmp;
2689  initEntry(yyscanner);
2690  if (yytext[1]=='/')
2691  {
2692  if (yytext[2]=='!' || yytext[2]=='/')
2693  {
2694  yyextra->docBlockContext = YY_START;
2695  yyextra->docBlockInBody = FALSE;
2696  yyextra->docBlockAutoBrief = FALSE;
2697  yyextra->docBlock.str(std::string());
2698  yyextra->docBlockTerm = 0;
2699  startCommentBlock(yyscanner,TRUE);
2700  BEGIN(DocLine);
2701  }
2702  else
2703  {
2704  yyextra->lastCContext=YY_START;
2705  BEGIN(SkipCxxComment);
2706  }
2707  }
2708  else
2709  {
2710  if (yytext[2]=='!' || yytext[2]=='*')
2711  {
2712  yyextra->docBlockContext = YY_START;
2713  yyextra->docBlockInBody = FALSE;
2714  yyextra->docBlock.str(std::string());
2715  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2716  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2717  yyextra->docBlockTerm = 0;
2718  startCommentBlock(yyscanner,FALSE);
2719  BEGIN(DocBlock);
2720  }
2721  else
2722  {
2723  yyextra->lastCContext=YY_START;
2724  BEGIN(SkipComment);
2725  }
2726  }
2727  }
2728 <FindMembers,FindFields,ReadInitializer,ReadInitializerPtr>{CPPC}([!/]){B}*{CMD}"}".*|{CCS}([!*]){B}*{CMD}"}"[^*]*{CCE} {
2729  bool insideEnum = YY_START==FindFields || ((YY_START==ReadInitializer || YY_START==ReadInitializerPtr) && yyextra->lastInitializerContext==FindFields); // see bug746226
2730  yyextra->commentScanner.close(yyextra->current.get(),yyextra->yyFileName,yyextra->yyLineNr,insideEnum);
2731  lineCount(yyscanner);
2732  }
2733 <FindMembers>"=>" {
2734  if (!yyextra->insideCS) REJECT;
2735  yyextra->current->bodyLine = yyextra->yyLineNr;
2736  yyextra->current->bodyColumn = yyextra->yyColNr;
2737  yyextra->current->initializer.str(yytext);
2738  yyextra->lastInitializerContext = YY_START;
2739  yyextra->initBracketCount=0;
2740  yyextra->current->mtype = yyextra->mtype = Property;
2741  yyextra->current->spec |= Entry::Gettable;
2742  BEGIN(ReadInitializerPtr);
2743  }
2744 <FindMembers>"=" { // in PHP code this could also be due to "<?="
2745  yyextra->current->bodyLine = yyextra->yyLineNr;
2746  yyextra->current->bodyColumn = yyextra->yyColNr;
2747  yyextra->current->initializer.str(yytext);
2748  yyextra->lastInitializerContext = YY_START;
2749  yyextra->initBracketCount=0;
2750  BEGIN(ReadInitializer);
2751  }
2752 <UNOIDLAttributeBlock>{BN}*[gs]"et"{BN}+"raises"{BN}*"("{BN}*{SCOPENAME}{BN}*(","{BN}*{SCOPENAME}{BN}*)*")"{BN}*";" {
2753  lineCount(yyscanner);
2754  yyextra->current->exception += " ";
2755  yyextra->current->exception += removeRedundantWhiteSpace(yytext);
2756  }
2757 <UNOIDLAttributeBlock>"}" {
2758  yyextra->current->exception += " }";
2759  BEGIN(FindMembers);
2760  }
2761  /* Read initializer rules */
2762 <ReadInitializer,ReadInitializerPtr>"(" {
2763  yyextra->lastRoundContext=YY_START;
2764  yyextra->pCopyRoundGString=&yyextra->current->initializer;
2765  yyextra->roundCount=0;
2766  yyextra->current->initializer << *yytext;
2767  BEGIN(GCopyRound);
2768  }
2769 <ReadInitializer,ReadInitializerPtr>"[" {
2770  if (!yyextra->insidePHP) REJECT;
2771  yyextra->lastSquareContext=YY_START;
2772  yyextra->pCopySquareGString=&yyextra->current->initializer;
2773  yyextra->squareCount=0;
2774  yyextra->current->initializer << *yytext;
2775  BEGIN(GCopySquare);
2776  }
2777 <ReadInitializer,ReadInitializerPtr>"{" {
2778  yyextra->lastCurlyContext=YY_START;
2779  yyextra->pCopyCurlyGString=&yyextra->current->initializer;
2780  yyextra->curlyCount=0;
2781  yyextra->current->initializer << *yytext;
2782  BEGIN(GCopyCurly);
2783  }
2784 <ReadInitializer,ReadInitializerPtr>[;,] {
2785  //printf(">> initializer '%s' <<\n",qPrint(yyextra->current->initializer));
2786  if (*yytext==';' && (yyextra->current_root->spec&Entry::Enum))
2787  {
2788  yyextra->current->fileName = yyextra->yyFileName;
2789  yyextra->current->startLine = yyextra->yyLineNr;
2790  yyextra->current->startColumn = yyextra->yyColNr;
2791  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
2792  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2793  yyextra->current->section = Entry::VARIABLE_SEC;
2794  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2795  initEntry(yyscanner);
2796  BEGIN(FindMembers);
2797  }
2798  else if (*yytext==';' || (yyextra->lastInitializerContext==FindFields && yyextra->initBracketCount==0)) // yyextra->initBracketCount==0 was added for bug 665778
2799  {
2800  unput(*yytext);
2801  if (YY_START == ReadInitializerPtr) yyextra->current->initializer.str(std::string());
2802  BEGIN(yyextra->lastInitializerContext);
2803  }
2804  else if (*yytext==',' && yyextra->initBracketCount==0) // for "int a=0,b=0"
2805  {
2806  unput(*yytext);
2807  if (YY_START == ReadInitializerPtr) yyextra->current->initializer.str(std::string());
2808  BEGIN(yyextra->lastInitializerContext);
2809  }
2810  else
2811  {
2812  yyextra->current->initializer << *yytext;
2813  }
2814  }
2815 <ReadInitializer,ReadInitializerPtr>{RAWBEGIN} { // C++11 raw string
2816  if (!yyextra->insideCpp)
2817  {
2818  REJECT;
2819  }
2820  else
2821  {
2822  QCString text=yytext;
2823  yyextra->current->initializer << text;
2824  int i=text.find('"');
2825  yyextra->delimiter = yytext+i+1;
2826  yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
2827  yyextra->lastRawStringContext = YY_START;
2828  yyextra->pCopyRawGString = &yyextra->current->initializer;
2829  BEGIN(RawGString);
2830  //printf("RawGString delimiter='%s'\n",qPrint(delimiter));
2831  }
2832  }
2833 <RawGString>{RAWEND} {
2834  *yyextra->pCopyRawGString << yytext;
2835  QCString delimiter = yytext+1;
2836  delimiter=delimiter.left(delimiter.length()-1);
2837  if (delimiter==yyextra->delimiter)
2838  {
2839  BEGIN(yyextra->lastRawStringContext);
2840  }
2841  }
2842 <RawGString>[^)\n]+ {
2843  *yyextra->pCopyRawGString << yytext;
2844  }
2845 <RawGString>. {
2846  *yyextra->pCopyRawGString << yytext;
2847  }
2848 <RawGString>\n {
2849  *yyextra->pCopyRawGString << yytext;
2850  lineCount(yyscanner);
2851  }
2852 <RawString>{RAWEND} {
2853  *yyextra->pCopyRawString+=yytext;
2854  yyextra->fullArgString+=yytext;
2855  QCString delimiter = yytext+1;
2856  delimiter=delimiter.left(delimiter.length()-1);
2857  if (delimiter==yyextra->delimiter)
2858  {
2859  BEGIN(yyextra->lastRawStringContext);
2860  }
2861  }
2862 <RawString>[^)]+ {
2863  *yyextra->pCopyRawString += yytext;
2864  yyextra->fullArgString+=yytext;
2865  }
2866 <RawString>. {
2867  *yyextra->pCopyRawString += yytext;
2868  yyextra->fullArgString+=yytext;
2869  }
2870 <RawString>\n {
2871  *yyextra->pCopyRawString += yytext;
2872  yyextra->fullArgString+=yytext;
2873  lineCount(yyscanner);
2874  }
2875 <ReadInitializer,ReadInitializerPtr>\" {
2876  if (yyextra->insideIDL && yyextra->insideCppQuote)
2877  {
2878  BEGIN(EndCppQuote);
2879  }
2880  else
2881  {
2882  yyextra->lastStringContext=YY_START;
2883  yyextra->current->initializer << yytext;
2884  yyextra->pCopyQuotedGString=&yyextra->current->initializer;
2885  BEGIN(CopyGString);
2886  }
2887  }
2888 <ReadInitializer,ReadInitializerPtr>"->" {
2889  yyextra->current->initializer << yytext;
2890  }
2891 <ReadInitializer,ReadInitializerPtr>"<<" {
2892  yyextra->current->initializer << yytext;
2893  }
2894 <ReadInitializer,ReadInitializerPtr>">>" {
2895  yyextra->current->initializer << yytext;
2896  }
2897 <ReadInitializer,ReadInitializerPtr>[<\[{(] {
2898  yyextra->initBracketCount++;
2899  yyextra->current->initializer << *yytext;
2900  }
2901 <ReadInitializer,ReadInitializerPtr>[>\]})] {
2902  yyextra->initBracketCount--;
2903  yyextra->current->initializer << *yytext;
2904  }
2905 <ReadInitializer,ReadInitializerPtr>\' {
2906  if (yyextra->insidePHP)
2907  {
2908  yyextra->current->initializer << yytext;
2909  yyextra->pCopyQuotedGString = &yyextra->current->initializer;
2910  yyextra->lastStringContext=YY_START;
2911  BEGIN(CopyPHPGString);
2912  }
2913  else
2914  {
2915  yyextra->current->initializer << yytext;
2916  }
2917  }
2918 <ReadInitializer,ReadInitializerPtr>{CHARLIT} {
2919  if (yyextra->insidePHP)
2920  {
2921  REJECT;
2922  }
2923  else
2924  {
2925  yyextra->current->initializer << yytext;
2926  }
2927  }
2928 <ReadInitializer,ReadInitializerPtr>\n {
2929  yyextra->current->initializer << *yytext;
2930  lineCount(yyscanner);
2931  }
2932 <ReadInitializer,ReadInitializerPtr>"@\"" {
2933  //printf("yyextra->insideCS=%d\n",yyextra->insideCS);
2934  yyextra->current->initializer << yytext;
2935  if (!yyextra->insideCS && !yyextra->insideObjC)
2936  {
2937  REJECT;
2938  }
2939  else
2940  {
2941  // C#/ObjC verbatim string
2942  yyextra->lastSkipVerbStringContext=YY_START;
2943  yyextra->pSkipVerbString=&yyextra->current->initializer;
2944  BEGIN(SkipVerbString);
2945  }
2946  }
2947 <SkipVerbString>[^\n"]+ {
2948  *yyextra->pSkipVerbString << yytext;
2949  }
2950 <SkipVerbString>"\"\"" { // quote escape
2951  *yyextra->pSkipVerbString << yytext;
2952  }
2953 <SkipVerbString>"\"" {
2954  *yyextra->pSkipVerbString << *yytext;
2955  BEGIN(yyextra->lastSkipVerbStringContext);
2956  }
2957 <SkipVerbString>\n {
2958  *yyextra->pSkipVerbString << *yytext;
2959  lineCount(yyscanner);
2960  }
2961 <SkipVerbString>. {
2962  *yyextra->pSkipVerbString << *yytext;
2963  }
2964 <ReadInitializer,ReadInitializerPtr>"?>" {
2965  if (yyextra->insidePHP)
2966  BEGIN( FindMembersPHP );
2967  else
2968  yyextra->current->initializer << yytext;
2969  }
2970 <ReadInitializer,ReadInitializerPtr>. {
2971  yyextra->current->initializer << *yytext;
2972  }
2973 
2974  /* generic quoted string copy rules */
2975 <CopyString,CopyPHPString>\\. {
2976  *yyextra->pCopyQuotedString+=yytext;
2977  }
2978 <CopyString>\" {
2979  *yyextra->pCopyQuotedString+=*yytext;
2980  BEGIN( yyextra->lastStringContext );
2981  }
2982 <CopyPHPString>\' {
2983  *yyextra->pCopyQuotedString+=*yytext;
2984  BEGIN( yyextra->lastStringContext );
2985  }
2986 <CopyString,CopyPHPString>{CCS}|{CCE}|{CPPC} {
2987  *yyextra->pCopyQuotedString+=yytext;
2988  }
2989 <CopyString,CopyPHPString>\n {
2990  *yyextra->pCopyQuotedString+=*yytext;
2991  lineCount(yyscanner);
2992  }
2993 <CopyString,CopyPHPString>. {
2994  *yyextra->pCopyQuotedString+=*yytext;
2995  }
2996 
2997  /* generic quoted growable string copy rules */
2998 <CopyGString,CopyPHPGString>\\. {
2999  *yyextra->pCopyQuotedGString << yytext;
3000  }
3001 <CopyGString>\" {
3002  *yyextra->pCopyQuotedGString << *yytext;
3003  BEGIN( yyextra->lastStringContext );
3004  }
3005 <CopyPHPGString>\' {
3006  *yyextra->pCopyQuotedGString << *yytext;
3007  BEGIN( yyextra->lastStringContext );
3008  }
3009 <CopyGString,CopyPHPGString>"<?php" { // we had an odd number of quotes.
3010  *yyextra->pCopyQuotedGString << yytext;
3011  BEGIN( yyextra->lastStringContext );
3012  }
3013 <CopyGString,CopyPHPGString>{CCS}|{CCE}|{CPPC} {
3014  *yyextra->pCopyQuotedGString << yytext;
3015  }
3016 <CopyGString,CopyPHPGString>\n {
3017  *yyextra->pCopyQuotedGString << *yytext;
3018  lineCount(yyscanner);
3019  }
3020 <CopyGString,CopyPHPGString>. {
3021  *yyextra->pCopyQuotedGString << *yytext;
3022  }
3023 
3024  /* generic round bracket list copy rules */
3025 <CopyRound>\" {
3026  *yyextra->pCopyRoundString += *yytext;
3027  yyextra->pCopyQuotedString=yyextra->pCopyRoundString;
3028  yyextra->lastStringContext=YY_START;
3029  BEGIN(CopyString);
3030  }
3031 <CopyRound>"(" {
3032  *yyextra->pCopyRoundString += *yytext;
3033  yyextra->roundCount++;
3034  }
3035 <CopyRound>")" {
3036  *yyextra->pCopyRoundString += *yytext;
3037  if (--yyextra->roundCount<0)
3038  BEGIN(yyextra->lastRoundContext);
3039  }
3040 <CopyRound>\n {
3041  lineCount(yyscanner);
3042  *yyextra->pCopyRoundString += *yytext;
3043  }
3044 <CopyRound>\' {
3045  if (yyextra->insidePHP)
3046  {
3047  yyextra->current->initializer << yytext;
3048  yyextra->pCopyQuotedString = yyextra->pCopyRoundString;
3049  yyextra->lastStringContext=YY_START;
3050  BEGIN(CopyPHPString);
3051  }
3052  else
3053  {
3054  *yyextra->pCopyRoundString += yytext;
3055  }
3056  }
3057 <CopyRound>{CHARLIT} {
3058  if (yyextra->insidePHP)
3059  {
3060  REJECT;
3061  }
3062  else
3063  {
3064  *yyextra->pCopyRoundString+=yytext;
3065  }
3066  }
3067 <CopyRound>[^"'()\n,]+ {
3068  *yyextra->pCopyRoundString+=yytext;
3069  }
3070 <CopyRound>. {
3071  *yyextra->pCopyRoundString+=*yytext;
3072  }
3073 
3074  /* generic sharp bracket list copy rules */
3075 <CopySharp>\" {
3076  *yyextra->pCopySharpString += *yytext;
3077  yyextra->pCopyQuotedString=yyextra->pCopySharpString;
3078  yyextra->lastStringContext=YY_START;
3079  BEGIN(CopyString);
3080  }
3081 <CopySharp>"<" {
3082  *yyextra->pCopySharpString += *yytext;
3083  yyextra->sharpCount++;
3084  }
3085 <CopySharp>">" {
3086  *yyextra->pCopySharpString += *yytext;
3087  if (--yyextra->sharpCount<0)
3088  {
3089  BEGIN(yyextra->lastSharpContext);
3090  }
3091  }
3092 <CopySharp>\n {
3093  lineCount(yyscanner);
3094  *yyextra->pCopySharpString += *yytext;
3095  }
3096 <CopySharp>\' {
3097  if (yyextra->insidePHP)
3098  {
3099  yyextra->current->initializer << yytext;
3100  yyextra->pCopyQuotedString = yyextra->pCopySharpString;
3101  yyextra->lastStringContext=YY_START;
3102  BEGIN(CopyPHPString);
3103  }
3104  else
3105  {
3106  *yyextra->pCopySharpString += yytext;
3107  }
3108  }
3109 <CopySharp>{CHARLIT} {
3110  if (yyextra->insidePHP)
3111  {
3112  REJECT;
3113  }
3114  else
3115  {
3116  *yyextra->pCopySharpString+=yytext;
3117  }
3118  }
3119 <CopySharp>[^"'<>\n,]+ {
3120  *yyextra->pCopySharpString+=yytext;
3121  }
3122 <CopySharp>. {
3123  *yyextra->pCopySharpString+=*yytext;
3124  }
3125 
3126 
3127  /* generic round bracket list copy rules for growable strings */
3128 <GCopyRound>\" {
3129  *yyextra->pCopyRoundGString << *yytext;
3130  yyextra->pCopyQuotedGString=yyextra->pCopyRoundGString;
3131  yyextra->lastStringContext=YY_START;
3132  BEGIN(CopyGString);
3133  }
3134 <GCopyRound>"(" {
3135  *yyextra->pCopyRoundGString << *yytext;
3136  yyextra->roundCount++;
3137  }
3138 <GCopyRound>")" {
3139  *yyextra->pCopyRoundGString << *yytext;
3140  if (--yyextra->roundCount<0)
3141  BEGIN(yyextra->lastRoundContext);
3142  }
3143 <GCopyRound>\n {
3144  lineCount(yyscanner);
3145  *yyextra->pCopyRoundGString << *yytext;
3146  }
3147 <GCopyRound>\' {
3148  if (yyextra->insidePHP)
3149  {
3150  yyextra->current->initializer << yytext;
3151  yyextra->pCopyQuotedGString = yyextra->pCopyRoundGString;
3152  yyextra->lastStringContext=YY_START;
3153  BEGIN(CopyPHPGString);
3154  }
3155  else
3156  {
3157  *yyextra->pCopyRoundGString << yytext;
3158  }
3159  }
3160 <GCopyRound>{CHARLIT} {
3161  if (yyextra->insidePHP)
3162  {
3163  REJECT;
3164  }
3165  else
3166  {
3167  *yyextra->pCopyRoundGString << yytext;
3168  }
3169  }
3170 <GCopyRound>[^"'()\n\/,]+ {
3171  *yyextra->pCopyRoundGString << yytext;
3172  }
3173 <GCopyRound>. {
3174  *yyextra->pCopyRoundGString << *yytext;
3175  }
3176 
3177  /* generic square bracket list copy rules for growable strings, we should only enter here in case of php, left the test part as in GCopyRound to keep it compatible with the round bracket version */
3178 <GCopySquare>\" {
3179  *yyextra->pCopySquareGString << *yytext;
3180  yyextra->pCopyQuotedGString=yyextra->pCopySquareGString;
3181  yyextra->lastStringContext=YY_START;
3182  BEGIN(CopyGString);
3183  }
3184 <GCopySquare>"[" {
3185  *yyextra->pCopySquareGString << *yytext;
3186  yyextra->squareCount++;
3187  }
3188 <GCopySquare>"]" {
3189  *yyextra->pCopySquareGString << *yytext;
3190  if (--yyextra->squareCount<0)
3191  BEGIN(yyextra->lastSquareContext);
3192  }
3193 <GCopySquare>\n {
3194  lineCount(yyscanner);
3195  *yyextra->pCopySquareGString << *yytext;
3196  }
3197 <GCopySquare>\' {
3198  if (yyextra->insidePHP)
3199  {
3200  yyextra->current->initializer << yytext;
3201  yyextra->pCopyQuotedGString = yyextra->pCopySquareGString;
3202  yyextra->lastStringContext=YY_START;
3203  BEGIN(CopyPHPGString);
3204  }
3205  else
3206  {
3207  *yyextra->pCopySquareGString << yytext;
3208  }
3209  }
3210 <GCopySquare>{CHARLIT} {
3211  if (yyextra->insidePHP)
3212  {
3213  REJECT;
3214  }
3215  else
3216  {
3217  *yyextra->pCopySquareGString << yytext;
3218  }
3219  }
3220 <GCopySquare>[^"\[\]\n\/,]+ {
3221  *yyextra->pCopySquareGString << yytext;
3222  }
3223 <GCopySquare>. {
3224  *yyextra->pCopySquareGString << *yytext;
3225  }
3226 
3227  /* generic curly bracket list copy rules */
3228 <CopyCurly>\" {
3229  *yyextra->pCopyCurlyString += *yytext;
3230  yyextra->pCopyQuotedString=yyextra->pCopyCurlyString;
3231  yyextra->lastStringContext=YY_START;
3232  BEGIN(CopyString);
3233  }
3234 <CopyCurly>\' {
3235  *yyextra->pCopyCurlyString += *yytext;
3236  if (yyextra->insidePHP)
3237  {
3238  yyextra->pCopyQuotedString=yyextra->pCopyCurlyString;
3239  yyextra->lastStringContext=YY_START;
3240  BEGIN(CopyPHPString);
3241  }
3242  }
3243 <CopyCurly>"{" {
3244  *yyextra->pCopyCurlyString += *yytext;
3245  yyextra->curlyCount++;
3246  }
3247 <CopyCurly>"}" {
3248  *yyextra->pCopyCurlyString += *yytext;
3249  if (--yyextra->curlyCount<0)
3250  BEGIN(yyextra->lastCurlyContext);
3251  }
3252 <CopyCurly>{CHARLIT} { if (yyextra->insidePHP)
3253  {
3254  REJECT;
3255  }
3256  else
3257  {
3258  *yyextra->pCopyCurlyString += yytext;
3259  }
3260  }
3261 <CopyCurly>[^"'{}\/\n,]+ {
3262  *yyextra->pCopyCurlyString += yytext;
3263  }
3264 <CopyCurly>"/" { *yyextra->pCopyCurlyString += yytext; }
3265 <CopyCurly>\n {
3266  lineCount(yyscanner);
3267  *yyextra->pCopyCurlyString += *yytext;
3268  }
3269 <CopyCurly>. {
3270  *yyextra->pCopyCurlyString += *yytext;
3271  }
3272 
3273  /* generic curly bracket list copy rules for growable strings */
3274 <GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker
3275  }
3276 <GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker
3277  QCString line = QCString(yytext);
3278  int s = line.find(' ');
3279  int e = line.find('"',s);
3280  yyextra->yyLineNr = line.mid(s,e-s).toInt();
3281  if (yytext[yyleng-1]=='\n')
3282  {
3283  lineCount(yyscanner);
3284  yyextra->column=0;
3285  }
3286  }
3287 <GCopyCurly>\" {
3288  *yyextra->pCopyCurlyGString << *yytext;
3289  yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString;
3290  yyextra->lastStringContext=YY_START;
3291  BEGIN(CopyGString);
3292  }
3293 <GCopyCurly>\' {
3294  *yyextra->pCopyCurlyGString << *yytext;
3295  if (yyextra->insidePHP)
3296  {
3297  yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString;
3298  yyextra->lastStringContext=YY_START;
3299  BEGIN(CopyPHPGString);
3300  }
3301  }
3302 <GCopyCurly>"{" {
3303  *yyextra->pCopyCurlyGString << *yytext;
3304  yyextra->curlyCount++;
3305  }
3306 <GCopyCurly>"}" {
3307  *yyextra->pCopyCurlyGString << *yytext;
3308  if (--yyextra->curlyCount<0)
3309  BEGIN(yyextra->lastCurlyContext);
3310  }
3311 <GCopyCurly>{CHARLIT} { if (yyextra->insidePHP)
3312  {
3313  REJECT;
3314  }
3315  else
3316  {
3317  *yyextra->pCopyCurlyGString << yytext;
3318  }
3319  }
3320 <GCopyCurly>[^"'{}\/\n,]+ {
3321  *yyextra->pCopyCurlyGString << yytext;
3322  }
3323 <GCopyCurly>[,]+ {
3324  *yyextra->pCopyCurlyGString << yytext;
3325  }
3326 <GCopyCurly>"/" { *yyextra->pCopyCurlyGString << yytext; }
3327 <GCopyCurly>\n {
3328  lineCount(yyscanner);
3329  *yyextra->pCopyCurlyGString << *yytext;
3330  }
3331 <GCopyCurly>. {
3332  *yyextra->pCopyCurlyGString << *yytext;
3333  }
3334 
3335  /* ---------------------- */
3336 
3337 
3338 <FindMembers>":" {
3339  if (yyextra->current->type.isEmpty() &&
3340  yyextra->current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}'
3341  {
3342  yyextra->current->section=Entry::ENUM_SEC;
3343  yyextra->current->name.resize(0);
3344  yyextra->current->args.resize(0);
3345  BEGIN(EnumBaseType);
3346  }
3347  else
3348  {
3349  if (yyextra->current->type.isEmpty()) // anonymous padding field, e.g. "int :7;"
3350  {
3351  addType(yyscanner);
3352  yyextra->current->name.sprintf("__pad%d__",yyextra->padCount++);
3353  }
3354  BEGIN(BitFields);
3355  yyextra->current->bitfields+=":";
3356  }
3357  }
3358 <BitFields>. {
3359  yyextra->current->bitfields+=*yytext;
3360  }
3361 <EnumBaseType>. {
3362  yyextra->current->args+=*yytext;
3363  }
3364 <EnumBaseType>\n {
3365  lineCount(yyscanner);
3366  yyextra->current->args+=' ';
3367  }
3368 <FindMembers>[;,] {
3369  QCString oldType = yyextra->current->type;
3370  if (yyextra->current->bodyLine==-1)
3371  {
3372  yyextra->current->bodyLine = yyextra->yyLineNr;
3373  yyextra->current->bodyColumn = yyextra->yyColNr;
3374  }
3375  if ( yyextra->insidePHP && yyextra->current->type.left(3) == "var" )
3376  {
3377  yyextra->current->type = yyextra->current->type.mid(3);
3378  }
3379  if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ")
3380  {
3381  yyextra->current->type.prepend("typedef ");
3382  }
3383  bool stat = yyextra->current->stat;
3384  Protection prot = yyextra->current->protection;
3385  if (yyextra->current->section==Entry::CONCEPT_SEC) // C++20 concept
3386  {
3387  auto groups = yyextra->current->groups;
3388  yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
3389  yyextra->current->groups = groups;
3390  initEntry(yyscanner);
3391  }
3392  else if (!yyextra->current->name.isEmpty() && yyextra->current->section!=Entry::ENUM_SEC)
3393  {
3394  yyextra->current->type=yyextra->current->type.simplifyWhiteSpace();
3395  yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
3396  yyextra->current->name=yyextra->current->name.stripWhiteSpace();
3397  if (yyextra->current->section==Entry::CLASS_SEC) // remove spec for "struct Bla bla;"
3398  {
3399  yyextra->current->spec = 0;
3400  }
3401  yyextra->current->section = Entry::VARIABLE_SEC ;
3402  yyextra->current->fileName = yyextra->yyFileName;
3403  yyextra->current->startLine = yyextra->yyBegLineNr;
3404  yyextra->current->startColumn = yyextra->yyBegColNr;
3405  yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
3406  initEntry(yyscanner);
3407  }
3408  if ( *yytext == ',')
3409  {
3410  yyextra->current->stat = stat; // the static attribute holds for all variables
3411  yyextra->current->protection = prot;
3412  yyextra->current->name.resize(0);
3413  yyextra->current->args.resize(0);
3414  yyextra->current->brief.resize(0);
3415  yyextra->current->doc.resize(0);
3416  yyextra->current->initializer.str(std::string());
3417  yyextra->current->bitfields.resize(0);
3418  int i=oldType.length();
3419  while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--;
3420  yyextra->current->type = oldType.left(i);
3421  }
3422  else
3423  {
3424  yyextra->mtype = Method;
3425  yyextra->virt = Normal;
3426  initEntry(yyscanner);
3427  }
3428  }
3429 
3430 <FindMembers>"[" {
3431  if (yyextra->insideSlice)
3432  {
3433  yyextra->squareCount=1;
3434  yyextra->lastSquareContext = YY_START;
3435  yyextra->current->metaData += "[";
3436  BEGIN( SliceMetadata );
3437  }
3438  else if (!yyextra->insideCS &&
3439  (yyextra->current->name.isEmpty() ||
3440  yyextra->current->name=="typedef"
3441  )
3442  ) // IDL function property
3443  {
3444  yyextra->squareCount=1;
3445  yyextra->lastSquareContext = YY_START;
3446  yyextra->idlAttr.resize(0);
3447  yyextra->idlProp.resize(0);
3448  yyextra->current->mtype = yyextra->mtype;
3449 
3450  if (Config_getBool(IDL_PROPERTY_SUPPORT) &&
3451  yyextra->current->mtype == Property)
3452  { // we are yyextra->inside the properties section of a dispinterface
3453  yyextra->odlProp = true;
3454  yyextra->current->spec |= Entry::Gettable;
3455  yyextra->current->spec |= Entry::Settable;
3456  }
3457 
3458  BEGIN( IDLAttribute );
3459  }
3460  else if (yyextra->insideCS &&
3461  yyextra->current->name.isEmpty())
3462  {
3463  yyextra->squareCount=1;
3464  yyextra->lastSquareContext = YY_START;
3465  // Skip the C# attribute
3466  // for this member
3467  yyextra->current->args.resize(0);
3468  BEGIN( SkipSquare );
3469  }
3470  else
3471  {
3472  yyextra->current->args += yytext ;
3473  yyextra->squareCount=1;
3474  yyextra->externLinkage=FALSE; // see bug759247
3475  BEGIN( Array ) ;
3476  }
3477  }
3478 <SliceMetadata>"[" { // Global metadata.
3479  yyextra->squareCount++;
3480  yyextra->current->metaData += "[";
3481  }
3482 <SliceMetadata>{BN}* {
3483  lineCount(yyscanner);
3484  }
3485 <SliceMetadata>\"[^\"]*\" {
3486  yyextra->current->metaData += yytext;
3487  }
3488 <SliceMetadata>"," {
3489  yyextra->current->metaData += yytext;
3490  }
3491 <SliceMetadata>"]" {
3492  yyextra->current->metaData += yytext;
3493  if (--yyextra->squareCount<=0)
3494  {
3495  BEGIN (yyextra->lastSquareContext);
3496  }
3497  }
3498 <SliceOptional>"(" {
3499  yyextra->current->type += "(";
3500  yyextra->roundCount++;
3501  }
3502 <SliceOptional>[0-9]+ {
3503  yyextra->current->type += yytext;
3504  }
3505 <SliceOptional>")" {
3506  yyextra->current->type += ")";
3507  if(--yyextra->roundCount<=0)
3508  {
3509  BEGIN (yyextra->lastModifierContext);
3510  }
3511  }
3512 <IDLAttribute>"]" {
3513  // end of IDL function attribute
3514  if (--yyextra->squareCount<=0)
3515  {
3516  lineCount(yyscanner);
3517  if (yyextra->current->mtype == Property)
3518  BEGIN( IDLPropName );
3519  else
3520  BEGIN( yyextra->lastSquareContext );
3521  }
3522  }
3523 <IDLAttribute>"propput" {
3524  if (Config_getBool(IDL_PROPERTY_SUPPORT))
3525  {
3526  yyextra->current->mtype = Property;
3527  }
3528  yyextra->current->spec |= Entry::Settable;
3529  }
3530 <IDLAttribute>"propget" {
3531  if (Config_getBool(IDL_PROPERTY_SUPPORT))
3532  {
3533  yyextra->current->mtype = Property;
3534  }
3535  yyextra->current->spec |= Entry::Gettable;
3536  }
3537 <IDLAttribute>"property" { // UNO IDL property
3538  yyextra->current->spec |= Entry::Property;
3539  }
3540 <IDLAttribute>"attribute" { // UNO IDL attribute
3541  yyextra->current->spec |= Entry::Attribute;
3542  }
3543 <IDLAttribute>"optional" { // on UNO IDL interface/service/attribute/property
3544  yyextra->current->spec |= Entry::Optional;
3545  }
3546 <IDLAttribute>"readonly" { // on UNO IDL attribute or property
3547  if (Config_getBool(IDL_PROPERTY_SUPPORT) && yyextra->odlProp)
3548  {
3549  yyextra->current->spec ^= Entry::Settable;
3550  }
3551  else
3552  {
3553  yyextra->current->spec |= Entry::Readonly;
3554  }
3555  }
3556 <IDLAttribute>"bound" { // on UNO IDL attribute or property
3557  yyextra->current->spec |= Entry::Bound;
3558  }
3559 <IDLAttribute>"removable" { // on UNO IDL property
3560  yyextra->current->spec |= Entry::Removable;
3561  }
3562 <IDLAttribute>"constrained" { // on UNO IDL property
3563  yyextra->current->spec |= Entry::Constrained;
3564  }
3565 <IDLAttribute>"transient" { // on UNO IDL property
3566  yyextra->current->spec |= Entry::Transient;
3567  }
3568 <IDLAttribute>"maybevoid" { // on UNO IDL property
3569  yyextra->current->spec |= Entry::MaybeVoid;
3570  }
3571 <IDLAttribute>"maybedefault" { // on UNO IDL property
3572  yyextra->current->spec |= Entry::MaybeDefault;
3573  }
3574 <IDLAttribute>"maybeambiguous" { // on UNO IDL property
3575  yyextra->current->spec |= Entry::MaybeAmbiguous;
3576  }
3577 <IDLAttribute>. {
3578  }
3579 <IDLPropName>{BN}*{ID}{BN}* {
3580  // return type (probably HRESULT) - skip it
3581 
3582  if (yyextra->odlProp)
3583  { // property type
3584  yyextra->idlProp = yytext;
3585  }
3586  }
3587 <IDLPropName>{ID}{BN}*"(" {
3588  yyextra->current->name = yytext;
3589  yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
3590  yyextra->current->startLine = yyextra->yyLineNr;
3591  yyextra->current->startColumn = yyextra->yyColNr;
3592  BEGIN( IDLProp );
3593  }
3594 <IDLPropName>{BN}*"("{BN}*{ID}{BN}*")"{BN}* {
3595  if (yyextra->odlProp)
3596  {
3597  yyextra->idlProp += yytext;
3598  }
3599  }
3600 <IDLPropName>{ID}{BNopt}/";" {
3601  if (yyextra->odlProp)
3602  {
3603  yyextra->current->name = yytext;
3604  yyextra->idlProp = yyextra->idlProp.stripWhiteSpace();
3605  yyextra->odlProp = false;
3606 
3607  BEGIN( IDLProp );
3608  }
3609  }
3610 <IDLProp>{BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter
3611  yyextra->idlAttr = yytext;
3612  yyextra->idlAttr=yyextra->idlAttr.stripWhiteSpace();
3613  }
3614 <IDLProp>{ID} { // property type
3615  yyextra->idlProp = yytext;
3616  }
3617 <IDLProp>{BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);)
3618  if (yyextra->current->args.isEmpty())
3619  yyextra->current->args = "(";
3620  else
3621  yyextra->current->args += ", ";
3622  yyextra->current->args += yyextra->idlAttr;
3623  yyextra->current->args += " ";
3624  yyextra->current->args += yyextra->idlProp; // prop was actually type of extra parameter
3625  yyextra->current->args += " ";
3626  yyextra->current->args += yytext;
3627  yyextra->current->args = yyextra->current->args.left(yyextra->current->args.length() - 1); // strip comma
3628  yyextra->idlProp.resize(0);
3629  yyextra->idlAttr.resize(0);
3630  BEGIN( IDLProp );
3631  }
3632 <IDLProp>{BN}*{ID}{BN}*")"{BN}* {
3633  // the parameter name for the property - just skip.
3634  }
3635 <IDLProp>";" {
3636  yyextra->current->fileName = yyextra->yyFileName;
3637  yyextra->current->type = yyextra->idlProp;
3638  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
3639  if (!yyextra->current->args.isEmpty())
3640  yyextra->current->args += ")";
3641  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
3642  yyextra->current->section = Entry::VARIABLE_SEC;
3643  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
3644  initEntry(yyscanner);
3645  BEGIN( FindMembers );
3646  }
3647 <IDLProp>. { // spaces, *, or other stuff
3648  //yyextra->idlProp+=yytext;
3649  }
3650 <Array>"]" { yyextra->current->args += *yytext ;
3651  if (--yyextra->squareCount<=0)
3652  BEGIN( FindMembers ) ;
3653  }
3654 <FuncFuncArray>"]" { yyextra->current->args += *yytext ;
3655  if (--yyextra->squareCount<=0)
3656  BEGIN( Function ) ;
3657  }
3658 <Array,FuncFuncArray>"[" { yyextra->current->args += *yytext ;
3659  yyextra->squareCount++;
3660  }
3661 <Array,FuncFuncArray>. { yyextra->current->args += *yytext ; }
3662 <SkipSquare>"[" { yyextra->squareCount++; }
3663 <SkipSquare>"]" {
3664  if (--yyextra->squareCount<=0)
3665  BEGIN( yyextra->lastSquareContext );
3666  }
3667 <SkipSquare>\" {
3668  yyextra->lastStringContext=YY_START;
3669  BEGIN( SkipString );
3670  }
3671 <SkipSquare>[^\n\[\]\"]+
3672 <FindMembers>"<" { addType(yyscanner);
3673  yyextra->current->type += yytext ;
3674  BEGIN( Sharp ) ;
3675  }
3676 <Sharp>">" { yyextra->current->type += *yytext ;
3677  if (--yyextra->sharpCount<=0)
3678  BEGIN( FindMembers ) ;
3679  }
3680 <Sharp>"<" { yyextra->current->type += *yytext ;
3681  yyextra->sharpCount++;
3682  }
3683 <Sharp>{BN}+ {
3684  yyextra->current->type += ' ';
3685  lineCount(yyscanner);
3686  }
3687 <Sharp>. { yyextra->current->type += *yytext ; }
3688 <FindFields>{ID} {
3689  if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
3690  {
3691  yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
3692  }
3693  yyextra->current->bodyLine = yyextra->yyLineNr;
3694  yyextra->current->bodyColumn = yyextra->yyColNr;
3695  yyextra->current->name = yytext;
3696  }
3697 <FindFields>"(" {
3698  // Java enum initializer
3699  unput('(');
3700  yyextra->lastInitializerContext = YY_START;
3701  yyextra->initBracketCount=0;
3702  yyextra->current->initializer.str("=");
3703  BEGIN(ReadInitializer);
3704  }
3705 <FindFields>"=" {
3706  yyextra->lastInitializerContext = YY_START;
3707  yyextra->initBracketCount=0;
3708  yyextra->current->initializer.str(yytext);
3709  BEGIN(ReadInitializer);
3710  }
3711 <FindFields>";" {
3712  if (yyextra->insideJava) // yyextra->last enum field in Java class
3713  {
3714  if (!yyextra->current->name.isEmpty())
3715  {
3716  yyextra->current->fileName = yyextra->yyFileName;
3717  yyextra->current->startLine = yyextra->yyLineNr;
3718  yyextra->current->startColumn = yyextra->yyColNr;
3719  if (!(yyextra->current_root->spec&Entry::Enum))
3720  {
3721  yyextra->current->type = "@"; // enum marker
3722  }
3723  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
3724  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
3725  yyextra->current->section = Entry::VARIABLE_SEC;
3726  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
3727  initEntry(yyscanner);
3728  }
3729 
3730  BEGIN( FindMembers );
3731  }
3732  else
3733  {
3734  REJECT;
3735  }
3736  }
3737 <FindFields>"," {
3738  //printf("adding '%s' '%s' '%s' to enum '%s' (mGrpId=%d)\n",
3739  // qPrint(yyextra->current->type), qPrint(yyextra->current->name),
3740  // qPrint(yyextra->current->args), qPrint(yyextra->current_root->name),yyextra->current->mGrpId);
3741  if (!yyextra->current->name.isEmpty())
3742  {
3743  yyextra->current->fileName = yyextra->yyFileName;
3744  yyextra->current->startLine = yyextra->yyLineNr;
3745  yyextra->current->startColumn = yyextra->yyColNr;
3746  if (!(yyextra->current_root->spec&Entry::Enum))
3747  {
3748  yyextra->current->type = "@"; // enum marker
3749  }
3750  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
3751  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
3752  yyextra->current->section = Entry::VARIABLE_SEC;
3753  // add to the scope of the enum
3754  if (!yyextra->insideCS && !yyextra->insideJava &&
3755  !(yyextra->current_root->spec&Entry::Strong))
3756  // for C# and Java 1.5+ enum values always have to be explicitly qualified,
3757  // same for C++11 style enums (enum class Name {})
3758  {
3759  // add to the scope surrounding the enum (copy!)
3760  // we cannot during it directly as that would invalidate the iterator in parseCompounds.
3761  //printf("*** adding outer scope entry for %s\n",qPrint(yyextra->current->name));
3762  yyextra->outerScopeEntries.emplace_back(yyextra->current_root->parent(), std::make_shared<Entry>(*yyextra->current));
3763  }
3764  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
3765  initEntry(yyscanner);
3766  }
3767  else // probably a redundant ,
3768  {
3769  yyextra->current->reset();
3770  initEntry(yyscanner);
3771  }
3772  }
3773 <FindFields>"[" { // attribute list in IDL
3774  yyextra->squareCount=1;
3775  yyextra->lastSquareContext = YY_START;
3776  BEGIN(SkipSquare);
3777  }
3778 <ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<]* { yyextra->current->program << yytext ; }
3779 <ReadBody,ReadNSBody,ReadBodyIntf>{CPPC}.* { yyextra->current->program << yytext ; }
3780 <ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!yyextra->insidePHP)
3781  REJECT;
3782  // append PHP comment.
3783  yyextra->current->program << yytext ;
3784  }
3785 <ReadBody,ReadNSBody,ReadBodyIntf>@\" { yyextra->current->program << yytext ;
3786  yyextra->pSkipVerbString = &yyextra->current->program;
3787  yyextra->lastSkipVerbStringContext=YY_START;
3788  BEGIN( SkipVerbString );
3789  }
3790 <ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (yyextra->insidePHP)
3791  {
3792  yyextra->current->program << yytext ;
3793  yyextra->pCopyHereDocGString = &yyextra->current->program;
3794  yyextra->lastHereDocContext=YY_START;
3795  BEGIN( CopyHereDoc );
3796  }
3797  else
3798  {
3799  REJECT;
3800  }
3801  }
3802 <ReadBody,ReadNSBody,ReadBodyIntf>\" { yyextra->current->program << yytext ;
3803  yyextra->pCopyQuotedGString = &yyextra->current->program;
3804  yyextra->lastStringContext=YY_START;
3805  BEGIN( CopyGString );
3806  }
3807 <ReadBody,ReadNSBody,ReadBodyIntf>{CCS}{B}* { yyextra->current->program << yytext ;
3808  yyextra->lastContext = YY_START ;
3809  BEGIN( Comment ) ;
3810  }
3811 <ReadBody,ReadNSBody,ReadBodyIntf>{CCS}{BL} { yyextra->current->program << yytext ;
3812  ++yyextra->yyLineNr ;
3813  yyextra->lastContext = YY_START ;
3814  BEGIN( Comment ) ;
3815  }
3816 <ReadBody,ReadNSBody,ReadBodyIntf>"'" {
3817  if (!yyextra->insidePHP)
3818  {
3819  yyextra->current->program << yytext;
3820  }
3821  else
3822  { // begin of single quoted string
3823  yyextra->current->program << yytext;
3824  yyextra->pCopyQuotedGString = &yyextra->current->program;
3825  yyextra->lastStringContext=YY_START;
3826  BEGIN(CopyPHPGString);
3827  }
3828  }
3829 <ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT} {
3830  if (yyextra->insidePHP)
3831  {
3832  REJECT; // for PHP code single quotes
3833  // are used for strings of arbitrary length
3834  }
3835  else
3836  {
3837  yyextra->current->program << yytext;
3838  }
3839  }
3840 <ReadBody,ReadNSBody,ReadBodyIntf>"{" { yyextra->current->program << yytext ;
3841  ++yyextra->curlyCount ;
3842  }
3843 <ReadBodyIntf>"}" {
3844  yyextra->current->program << yytext ;
3845  --yyextra->curlyCount ;
3846  }
3847 <ReadBody,ReadNSBody>"}" { //err("ReadBody count=%d\n",yyextra->curlyCount);
3848  if ( yyextra->curlyCount>0 )
3849  {
3850  yyextra->current->program << yytext ;
3851  --yyextra->curlyCount ;
3852  }
3853  else
3854  {
3855  yyextra->current->endBodyLine = yyextra->yyLineNr;
3856  std::shared_ptr<Entry> original_root = yyextra->current_root; // save root this namespace is in
3857  if (yyextra->current->section == Entry::NAMESPACE_SEC && yyextra->current->type == "namespace")
3858  {
3859  int split_point;
3860  // save documentation values
3861  QCString doc = yyextra->current->doc;
3862  int docLine = yyextra->current->docLine;
3863  QCString docFile = yyextra->current->docFile;
3864  QCString brief = yyextra->current->brief;
3865  int briefLine = yyextra->current->briefLine;
3866  QCString briefFile = yyextra->current->briefFile;
3867  // reset documentation values
3868  yyextra->current->doc = "";
3869  yyextra->current->docLine = 0;
3870  yyextra->current->docFile = "";
3871  yyextra->current->brief = "";
3872  yyextra->current->briefLine = 0;
3873  yyextra->current->briefFile = "";
3874  while ((split_point = yyextra->current->name.find("::")) != -1)
3875  {
3876  std::shared_ptr<Entry> new_current = std::make_shared<Entry>(*yyextra->current);
3877  yyextra->current->program.str(std::string());
3878  new_current->name = yyextra->current->name.mid(split_point + 2);
3879  yyextra->current->name = yyextra->current->name.left(split_point);
3880  if (!yyextra->current_root->name.isEmpty()) yyextra->current->name.prepend(yyextra->current_root->name+"::");
3881 
3882  yyextra->current_root->moveToSubEntryAndKeep(yyextra->current);
3883  yyextra->current_root = yyextra->current;
3884  yyextra->current = new_current;
3885  }
3886  // restore documentation values
3887  yyextra->current->doc = doc;
3888  yyextra->current->docLine = docLine;
3889  yyextra->current->docFile = docFile;
3890  yyextra->current->brief = brief;
3891  yyextra->current->briefLine = briefLine;
3892  yyextra->current->briefFile = briefFile;
3893  }
3894  QCString &cn = yyextra->current->name;
3895  QCString rn = yyextra->current_root->name;
3896  //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
3897  if (!cn.isEmpty() && !rn.isEmpty())
3898  {
3899  prependScope(yyscanner);
3900  }
3901  if (yyextra->isTypedef && cn.isEmpty())
3902  {
3903  //printf("Typedef Name\n");
3904  BEGIN( TypedefName );
3905  }
3906  else
3907  {
3908  if ((yyextra->current->section == Entry::ENUM_SEC) || (yyextra->current->spec&Entry::Enum))
3909  {
3910  yyextra->current->program << ','; // add field terminator
3911  }
3912  // add compound definition to the tree
3913  yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
3914  // was: yyextra->current->args.simplifyWhiteSpace();
3915  yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
3916  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
3917  //printf("adding '%s' '%s' '%s' brief=%s yyextra->insideObjC=%d %x\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args),qPrint(yyextra->current->brief),yyextra->insideObjC,yyextra->current->section);
3918  if (yyextra->insideObjC &&
3919  ((yyextra->current->spec&Entry::Interface) || (yyextra->current->spec==Entry::Category))
3920  ) // method definition follows
3921  {
3922  BEGIN( ReadBodyIntf ) ;
3923  }
3924  else
3925  {
3926  yyextra->memspecEntry = yyextra->current;
3927  yyextra->current_root->moveToSubEntryAndKeep( yyextra->current ) ;
3928  yyextra->current = std::make_shared<Entry>(*yyextra->current);
3929  if (yyextra->current->section==Entry::NAMESPACE_SEC ||
3930  (yyextra->current->spec==Entry::Interface) ||
3931  yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideJS ||
3932  yyextra->insideSlice
3933  )
3934  { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
3935  yyextra->current->reset();
3936  yyextra->current_root = original_root; // restore scope from before namespace descent
3937  initEntry(yyscanner);
3938  yyextra->memspecEntry.reset();
3939  BEGIN( FindMembers ) ;
3940  }
3941  else
3942  {
3943  static const reg::Ex re(R"(@\d+$)");
3944  if (!yyextra->isTypedef && yyextra->memspecEntry &&
3945  !reg::search(yyextra->memspecEntry->name.str(),re)) // not typedef or anonymous type (see bug691071)
3946  {
3947  // enabled the next two lines for bug 623424
3948  yyextra->current->doc.resize(0);
3949  yyextra->current->brief.resize(0);
3950  }
3951  BEGIN( MemberSpec ) ;
3952  }
3953  }
3954  }
3955  }
3956  }
3957 <ReadBody>"}"{BN}+"typedef"{BN}+ { //err("ReadBody count=%d\n",yyextra->curlyCount);
3958  lineCount(yyscanner);
3959  if ( yyextra->curlyCount>0 )
3960  {
3961  yyextra->current->program << yytext ;
3962  --yyextra->curlyCount ;
3963  }
3964  else
3965  {
3966  yyextra->isTypedef = TRUE;
3967  yyextra->current->endBodyLine = yyextra->yyLineNr;
3968  QCString &cn = yyextra->current->name;
3969  QCString rn = yyextra->current_root->name;
3970  if (!cn.isEmpty() && !rn.isEmpty())
3971  {
3972  prependScope(yyscanner);
3973  }
3974  BEGIN( TypedefName );
3975  }
3976  }
3977 <TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
3978  lineCount(yyscanner);
3979  yyextra->current->type.prepend(yytext);
3980  }
3981 <TypedefName>{ID} {
3982  if ((yyextra->current->section == Entry::ENUM_SEC) || (yyextra->current->spec&Entry::Enum))
3983  {
3984  yyextra->current->program << ","; // add field terminator
3985  }
3986  yyextra->current->name=yytext;
3987  prependScope(yyscanner);
3988  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
3989  yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
3990  //printf("Adding compound %s %s %s\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
3991  if (!yyextra->firstTypedefEntry)
3992  {
3993  yyextra->firstTypedefEntry = yyextra->current;
3994  }
3995  yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
3996  initEntry(yyscanner);
3997  yyextra->isTypedef=TRUE; // to undo reset by initEntry(yyscanner)
3998  BEGIN(MemberSpecSkip);
3999  }
4000 <TypedefName>";" { /* typedef of anonymous type */
4001  yyextra->current->name.sprintf("@%d",anonCount++);
4002  if ((yyextra->current->section == Entry::ENUM_SEC) || (yyextra->current->spec&Entry::Enum))
4003  {
4004  yyextra->current->program << ','; // add field terminator
4005  }
4006  // add compound definition to the tree
4007  yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4008  yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4009  yyextra->memspecEntry = yyextra->current;
4010  yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4011  initEntry(yyscanner);
4012  unput(';');
4013  BEGIN( MemberSpec ) ;
4014  }
4015 <MemberSpec>([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved.
4016  lineCount(yyscanner);
4017  int i=0,l=(int)yyleng,j;
4018  while (i<l && (!isId(yytext[i]))) i++;
4019  yyextra->msName = QCString(yytext).right(l-i).stripWhiteSpace();
4020  j=yyextra->msName.find("[");
4021  if (j!=-1)
4022  {
4023  yyextra->msArgs=yyextra->msName.right(yyextra->msName.length()-j);
4024  yyextra->msName=yyextra->msName.left(j);
4025  }
4026  yyextra->msType=QCString(yytext).left(i);
4027 
4028  // handle *pName in: typedef { ... } name, *pName;
4029  if (yyextra->firstTypedefEntry)
4030  {
4031  if (yyextra->firstTypedefEntry->spec&Entry::Struct)
4032  {
4033  yyextra->msType.prepend("struct "+yyextra->firstTypedefEntry->name);
4034  }
4035  else if (yyextra->firstTypedefEntry->spec&Entry::Union)
4036  {
4037  yyextra->msType.prepend("union "+yyextra->firstTypedefEntry->name);
4038  }
4039  else if (yyextra->firstTypedefEntry->section==Entry::ENUM_SEC)
4040  {
4041  yyextra->msType.prepend("enum "+yyextra->firstTypedefEntry->name);
4042  }
4043  else
4044  {
4045  yyextra->msType.prepend(yyextra->firstTypedefEntry->name);
4046  }
4047  }
4048  }
4049 <MemberSpec>"(" { // function with struct return type
4050  addType(yyscanner);
4051  yyextra->current->name = yyextra->msName;
4052  yyextra->current->spec = 0;
4053  unput('(');
4054  BEGIN(FindMembers);
4055  }
4056 <MemberSpec>[,;] {
4057  if (yyextra->msName.isEmpty() && !yyextra->current->name.isEmpty())
4058  {
4059  // see if the compound does not have a name or is yyextra->inside another
4060  // anonymous compound. If so we insert a
4061  // special 'anonymous' variable.
4062  //Entry *p=yyextra->current_root;
4063  const Entry *p=yyextra->current.get();
4064  while (p)
4065  {
4066  // only look for class scopes, not namespace scopes
4067  if ((p->section & Entry::COMPOUND_MASK) && !p->name.isEmpty())
4068  {
4069  //printf("Trying scope '%s'\n",qPrint(p->name));
4070  int i=p->name.findRev("::");
4071  int pi = (i==-1) ? 0 : i+2;
4072  if (p->name.at(pi)=='@')
4073  {
4074  // anonymous compound yyextra->inside -> insert dummy variable name
4075  //printf("Adding anonymous variable for scope %s\n",qPrint(p->name));
4076  yyextra->msName.sprintf("@%d",anonCount++);
4077  break;
4078  }
4079  }
4080  //p=p->parent;
4081  if (p==yyextra->current.get()) p=yyextra->current_root.get(); else p=p->parent();
4082  }
4083  }
4084  //printf("yyextra->msName=%s yyextra->current->name=%s\n",qPrint(yyextra->msName),qPrint(yyextra->current->name));
4085  if (!yyextra->msName.isEmpty()
4086  /*&& yyextra->msName!=yyextra->current->name*/) // skip typedef T {} T;, removed due to bug608493
4087  {
4088  bool typedefHidesStruct = Config_getBool(TYPEDEF_HIDES_STRUCT);
4089  // case 1: typedef struct _S { ... } S_t;
4090  // -> omit typedef and use S_t as the struct name
4091  if (typedefHidesStruct &&
4092  yyextra->isTypedef &&
4093  ((yyextra->current->spec&(Entry::Struct|Entry::Union)) ||
4094  yyextra->current->section==Entry::ENUM_SEC )&&
4095  yyextra->msType.stripWhiteSpace().isEmpty() &&
4096  yyextra->memspecEntry)
4097  {
4098  yyextra->memspecEntry->name=yyextra->msName;
4099  }
4100  else // case 2: create a typedef field
4101  {
4102  std::shared_ptr<Entry> varEntry=std::make_shared<Entry>();
4103  varEntry->lang = yyextra->language;
4104  varEntry->protection = yyextra->current->protection ;
4105  varEntry->mtype = yyextra->current->mtype;
4106  varEntry->virt = yyextra->current->virt;
4107  varEntry->stat = yyextra->current->stat;
4108  varEntry->section = Entry::VARIABLE_SEC;
4109  varEntry->name = yyextra->msName.stripWhiteSpace();
4110  varEntry->type = yyextra->current->type.simplifyWhiteSpace()+" ";
4111  varEntry->args = yyextra->msArgs;
4112  if (yyextra->isTypedef)
4113  {
4114  varEntry->type.prepend("typedef ");
4115  // //printf("yyextra->current->name = %s %s\n",qPrint(yyextra->current->name),qPrint(yyextra->msName));
4116  }
4117  if (typedefHidesStruct &&
4118  yyextra->isTypedef &&
4119  (yyextra->current->spec&(Entry::Struct|Entry::Union)) &&
4120  yyextra->memspecEntry
4121  ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
4122  {
4123  varEntry->type+=yyextra->memspecEntry->name+yyextra->msType;
4124  }
4125  else // case 2: use _S as type for for pS_t
4126  {
4127  varEntry->type+=yyextra->current->name+yyextra->msType;
4128  }
4129  varEntry->fileName = yyextra->yyFileName;
4130  varEntry->startLine = yyextra->yyLineNr;
4131  varEntry->startColumn = yyextra->yyColNr;
4132  varEntry->doc = yyextra->current->doc;
4133  varEntry->brief = yyextra->current->brief;
4134  varEntry->mGrpId = yyextra->current->mGrpId;
4135  varEntry->initializer.str(yyextra->current->initializer.str());
4136  varEntry->groups = yyextra->current->groups;
4137  varEntry->sli = yyextra->current->sli;
4138 
4139  //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n",
4140  // qPrint(varEntry->type),qPrint(varEntry->name),
4141  // qPrint(varEntry->args),qPrint(varEntry->brief),qPrint(varEntry->doc));
4142  yyextra->current_root->moveToSubEntryAndKeep(varEntry);
4143  }
4144  }
4145  if (*yytext==';') // end of a struct/class ...
4146  {
4147  if (!yyextra->isTypedef && yyextra->msName.isEmpty() && yyextra->memspecEntry && (yyextra->current->section&Entry::COMPOUND_MASK))
4148  { // case where a class/struct has a doc block after it
4149  if (!yyextra->current->doc.isEmpty())
4150  {
4151  yyextra->memspecEntry->doc += yyextra->current->doc;
4152  }
4153  if (!yyextra->current->brief.isEmpty())
4154  {
4155  yyextra->memspecEntry->brief += yyextra->current->brief;
4156  }
4157  }
4158  yyextra->msType.resize(0);
4159  yyextra->msName.resize(0);
4160  yyextra->msArgs.resize(0);
4161  yyextra->isTypedef=FALSE;
4162  yyextra->firstTypedefEntry.reset();
4163  yyextra->memspecEntry.reset();
4164  yyextra->current->reset();
4165  initEntry(yyscanner);
4166  BEGIN( FindMembers );
4167  }
4168  else
4169  {
4170  yyextra->current->doc.resize(0);
4171  yyextra->current->brief.resize(0);
4172  }
4173 
4174  }
4175 <MemberSpec>"=" {
4176  yyextra->lastInitializerContext=YY_START;
4177  yyextra->initBracketCount=0;
4178  yyextra->current->initializer.str(yytext);
4179  BEGIN(ReadInitializer);
4180  /* BEGIN(MemberSpecSkip); */
4181  }
4182  /*
4183 <MemberSpecSkip>"{" {
4184  yyextra->curlyCount=0;
4185  yyextra->lastCurlyContext = MemberSpecSkip;
4186  yyextra->previous = yyextra->current;
4187  BEGIN(SkipCurly);
4188  }
4189  */
4190 <MemberSpecSkip>"," { BEGIN(MemberSpec); }
4191 <MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); }
4192 <ReadBody,ReadNSBody,ReadBodyIntf>{BN}{1,80} { yyextra->current->program << yytext ;
4193  lineCount(yyscanner) ;
4194  }
4195 <ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block
4196  yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4197  initEntry(yyscanner);
4198  yyextra->language = yyextra->current->lang = SrcLangExt_Cpp; // see bug746361
4199  yyextra->insideObjC=FALSE;
4200  BEGIN( FindMembers );
4201  }
4202 <ReadBody,ReadNSBody,ReadBodyIntf>. { yyextra->current->program << yytext ; }
4203 
4204 <FindMembers>"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
4205 <FindMembers>("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */
4206  if (yyextra->insidePHP) // reference parameter
4207  {
4208  REJECT
4209  }
4210  else
4211  {
4212  yyextra->current->bodyLine = yyextra->yyLineNr;
4213  yyextra->current->bodyColumn = yyextra->yyColNr;
4214  lineCount(yyscanner);
4215  addType(yyscanner);
4216  yyextra->funcPtrType=yytext;
4217  yyextra->roundCount=0;
4218  //yyextra->current->type += yytext;
4219  BEGIN( FuncPtr );
4220  }
4221  }
4222 <FuncPtr>{SCOPENAME} {
4223  yyextra->current->name = yytext;
4224  if (nameIsOperator(yyextra->current->name))
4225  {
4226  BEGIN( FuncPtrOperator );
4227  }
4228  else
4229  {
4230  if (yyextra->current->name=="const" || yyextra->current->name=="volatile")
4231  {
4232  yyextra->funcPtrType += yyextra->current->name;
4233  }
4234  else
4235  {
4236  BEGIN( EndFuncPtr );
4237  }
4238  }
4239  }
4240 <FuncPtr>. {
4241  //printf("error: FuncPtr '%c' unexpected at line %d of %s\n",*yytext,yyextra->yyLineNr,yyextra->yyFileName);
4242  }
4243 <FuncPtrOperator>"("{BN}*")"{BNopt}/"(" {
4244  yyextra->current->name += yytext;
4245  yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
4246  lineCount(yyscanner);
4247  }
4248 <FuncPtrOperator>\n {
4249  lineCount(yyscanner);
4250  yyextra->current->name += *yytext;
4251  }
4252 <FuncPtrOperator>"(" {
4253  unput(*yytext);
4254  BEGIN( EndFuncPtr );
4255  }
4256 <FuncPtrOperator>. {
4257  yyextra->current->name += *yytext;
4258  }
4259 <EndFuncPtr>")"{BNopt}/";" { // a variable with extra braces
4260  lineCount(yyscanner);
4261  yyextra->current->type+=yyextra->funcPtrType.mid(1);
4262  BEGIN(FindMembers);
4263  }
4264 <EndFuncPtr>")"{BNopt}/"(" { // a function pointer
4265  lineCount(yyscanner);
4266  yyextra->current->type+=yyextra->funcPtrType+")";
4267  BEGIN(FindMembers);
4268  }
4269 <EndFuncPtr>")"{BNopt}/"[" { // an array of variables
4270  lineCount(yyscanner);
4271  yyextra->current->type+=yyextra->funcPtrType;
4272  yyextra->current->args += ")";
4273  BEGIN(FindMembers);
4274  }
4275 <EndFuncPtr>"(" { // a function returning a function or
4276  // a function returning a pointer to an array
4277  yyextra->current->args += *yytext ;
4278  //yyextra->roundCount=0;
4279  //BEGIN( FuncFunc );
4280  yyextra->current->bodyLine = yyextra->yyLineNr;
4281  yyextra->current->bodyColumn = yyextra->yyColNr;
4282  yyextra->currentArgumentContext = FuncFuncEnd;
4283  yyextra->fullArgString=yyextra->current->args;
4284  yyextra->copyArgString=&yyextra->current->args;
4285  BEGIN( ReadFuncArgType ) ;
4286  }
4287 <EndFuncPtr>"["[^\n\]]*"]" {
4288  yyextra->funcPtrType+=yytext;
4289  }
4290 <EndFuncPtr>")" {
4291  BEGIN(FindMembers);
4292  }
4293 <FuncFunc>"(" {
4294  yyextra->current->args += *yytext ;
4295  ++yyextra->roundCount;
4296  }
4297 <FuncFunc>")" {
4298  yyextra->current->args += *yytext ;
4299  if ( yyextra->roundCount )
4300  --yyextra->roundCount;
4301  else
4302  {
4303  BEGIN(FuncFuncEnd);
4304  }
4305  }
4306 <FuncFuncEnd>")"{BN}*"(" {
4307  lineCount(yyscanner);
4308  yyextra->current->type+=yyextra->funcPtrType+")(";
4309  BEGIN(FuncFuncType);
4310  }
4311 <FuncFuncEnd>")"{BNopt}/[;{] {
4312  lineCount(yyscanner);
4313  yyextra->current->type+=yyextra->funcPtrType.mid(1);
4314  BEGIN(Function);
4315  }
4316 <FuncFuncEnd>")"{BNopt}/"[" { // function returning a pointer to an array
4317  lineCount(yyscanner);
4318  yyextra->current->type+=yyextra->funcPtrType;
4319  yyextra->current->args+=")";
4320  BEGIN(FuncFuncArray);
4321  }
4322 <FuncFuncEnd>. {
4323  yyextra->current->args += *yytext;
4324  }
4325 <FuncFuncType>"(" {
4326  yyextra->current->type += *yytext;
4327  yyextra->roundCount++;
4328  }
4329 <FuncFuncType>")" {
4330  yyextra->current->type += *yytext;
4331  if (yyextra->roundCount)
4332  --yyextra->roundCount;
4333  else
4334  BEGIN(Function);
4335  }
4336 <FuncFuncType>{BN}*","{BN}* { lineCount(yyscanner) ; yyextra->current->type += ", " ; }
4337 <FuncFuncType>{BN}+ { lineCount(yyscanner) ; yyextra->current->type += ' ' ; }
4338 <FuncFuncType>. {
4339  yyextra->current->type += *yytext;
4340  }
4341 <FindMembers>"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")"{BN}*"(" { // for catching typedef void (__stdcall *f)() like definitions
4342  if (yyextra->current->type.left(7)=="typedef" && yyextra->current->bodyLine==-1)
4343  // the bodyLine check is to prevent this guard to be true more than once
4344  {
4345  yyextra->current->bodyLine = yyextra->yyLineNr;
4346  yyextra->current->bodyColumn = yyextra->yyColNr;
4347  BEGIN( GetCallType );
4348  }
4349  else if (!yyextra->current->name.isEmpty()) // normal function
4350  {
4351  yyextra->current->args = yytext;
4352  yyextra->current->bodyLine = yyextra->yyLineNr;
4353  yyextra->current->bodyColumn = yyextra->yyColNr;
4354  yyextra->currentArgumentContext = FuncQual;
4355  yyextra->fullArgString=yyextra->current->args;
4356  yyextra->copyArgString=&yyextra->current->args;
4357  BEGIN( ReadFuncArgType ) ;
4358  //printf(">>> Read function arguments!\n");
4359  }
4360  }
4361 <GetCallType>{BN}*{ID}{BN}*"*" {
4362  lineCount(yyscanner);
4363  addType(yyscanner);
4364  yyextra->funcPtrType="(";
4365  yyextra->funcPtrType+=yytext;
4366  yyextra->roundCount=0;
4367  BEGIN( FuncPtr );
4368  }
4369 <FindMembers>"(" {
4370  if (!yyextra->current->name.isEmpty())
4371  {
4372  yyextra->current->args = yytext;
4373  yyextra->current->bodyLine = yyextra->yyLineNr;
4374  yyextra->current->bodyColumn = yyextra->yyColNr;
4375  yyextra->currentArgumentContext = FuncQual;
4376  yyextra->fullArgString=yyextra->current->args;
4377  yyextra->copyArgString=&yyextra->current->args;
4378  BEGIN( ReadFuncArgType ) ;
4379  //printf(">>> Read function arguments yyextra->current->argList.size()=%d\n",yyextra->current->argList.size());
4380  }
4381  }
4382  /*
4383 <FindMembers>"("{BN}*("void"{BN}*)?")" {
4384  lineCount(yyscanner);
4385  yyextra->current->args = "()";
4386  BEGIN( FuncQual );
4387  }
4388  */
4389 
4390  /*- Function argument reading rules ---------------------------------------*/
4391 
4392 <ReadFuncArgType>[^ \/\r\t\n\[\]\)\(\"\'#]+ { *yyextra->copyArgString+=yytext;
4393  yyextra->fullArgString+=yytext;
4394  }
4395 <CopyArgString,CopyArgPHPString>[^\n\\\"\']+ { *yyextra->copyArgString+=yytext;
4396  yyextra->fullArgString+=yytext;
4397  }
4398 <CopyArgRound>[^\/\n\)\(\"\']+ {
4399  *yyextra->copyArgString+=yytext;
4400  yyextra->fullArgString+=yytext;
4401  }
4402 <CopyArgSquare>[^\/\n\]\[\"\']+ {
4403  *yyextra->copyArgString+=yytext;
4404  yyextra->fullArgString+=yytext;
4405  }
4406 <ReadFuncArgType,ReadTempArgs>{BN}* {
4407  *yyextra->copyArgString+=" ";
4408  yyextra->fullArgString+=" ";
4409  lineCount(yyscanner);
4410  }
4411 <ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>{RAWBEGIN} {
4412  yyextra->delimiter = yytext+2;
4413  yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
4414  yyextra->lastRawStringContext = YY_START;
4415  yyextra->pCopyRawString = yyextra->copyArgString;
4416  *yyextra->pCopyRawString+=yytext;
4417  yyextra->fullArgString+=yytext;
4418  BEGIN(RawString);
4419  }
4420 <ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>\" {
4421  *yyextra->copyArgString+=*yytext;
4422  yyextra->fullArgString+=*yytext;
4423  yyextra->lastCopyArgStringContext = YY_START;
4424  BEGIN( CopyArgString );
4425  }
4426 <ReadFuncArgType>"[" {
4427  if (!yyextra->insidePHP) REJECT;
4428  *yyextra->copyArgString+=*yytext;
4429  yyextra->fullArgString+=*yytext;
4430  yyextra->argSquareCount=0;
4431  yyextra->lastCopyArgContext = YY_START;
4432  BEGIN( CopyArgSquare );
4433  }
4434 <ReadFuncArgType,ReadTempArgs>"(" {
4435  *yyextra->copyArgString+=*yytext;
4436  yyextra->fullArgString+=*yytext;
4437  yyextra->argRoundCount=0;
4438  yyextra->lastCopyArgContext = YY_START;
4439  BEGIN( CopyArgRound );
4440  }
4441 <ReadFuncArgType>")" {
4442  *yyextra->copyArgString+=*yytext;
4443  yyextra->fullArgString+=*yytext;
4444  yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4445  if (yyextra->insideJS)
4446  {
4447  fixArgumentListForJavaScript(yyextra->current->argList);
4448  }
4449  handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
4450 
4451  /* remember the yyextra->current documentation block, since
4452  we could overwrite it with the documentation of
4453  a function argument, which we then have to correct later
4454  on
4455  */
4456  yyextra->docBackup = yyextra->current->doc;
4457  yyextra->briefBackup = yyextra->current->brief;
4458 
4459  BEGIN( yyextra->currentArgumentContext );
4460  }
4461  /* a special comment */
4462 <ReadFuncArgType,ReadTempArgs>({CCS}[*!]|{CPPC}[/!])("<"?) {
4463  if (yyextra->currentArgumentContext==DefineEnd)
4464  {
4465  // for defines we interpret a comment
4466  // as documentation for the define
4467  int i;for (i=(int)yyleng-1;i>=0;i--)
4468  {
4469  unput(yytext[i]);
4470  }
4471  yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4472  handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
4473  BEGIN( yyextra->currentArgumentContext );
4474  }
4475  else // not a define
4476  {
4477  // for functions we interpret a comment
4478  // as documentation for the argument
4479  yyextra->fullArgString+=yytext;
4480  yyextra->lastCopyArgChar=0;
4481  yyextra->lastCommentInArgContext=YY_START;
4482  if (yytext[1]=='/')
4483  BEGIN( CopyArgCommentLine );
4484  else
4485  BEGIN( CopyArgComment );
4486  }
4487  }
4488  /* a non-special comment */
4489 <ReadFuncArgType,ReadTempArgs>{CCS}{CCE} { /* empty comment */ }
4490 <ReadFuncArgType,ReadTempArgs>{CCS} {
4491  yyextra->lastCContext = YY_START;
4492  BEGIN( SkipComment );
4493  }
4494 <ReadFuncArgType,ReadTempArgs>{CPPC} {
4495  yyextra->lastCContext = YY_START;
4496  BEGIN( SkipCxxComment );
4497  }
4498  /*
4499 <ReadFuncArgType,ReadTempArgs>"'#" { if (yyextra->insidePHP)
4500  REJECT;
4501  *yyextra->copyArgString+=yytext;
4502  yyextra->fullArgString+=yytext;
4503  }
4504 <ReadFuncArgType,ReadTempArgs>"#" {
4505  if (!yyextra->insidePHP)
4506  REJECT;
4507  yyextra->lastCContext = YY_START;
4508  BEGIN( SkipCxxComment );
4509  }
4510  */
4511  /* ')' followed by a special comment */
4512 <ReadFuncArgType>")"{BN}*({CCS}[*!]|{CPPC}[/!])"<" {
4513  lineCount(yyscanner);
4514  if (yyextra->currentArgumentContext==DefineEnd)
4515  {
4516  // for defines we interpret a comment
4517  // as documentation for the define
4518  int i;for (i=(int)yyleng-1;i>0;i--)
4519  {
4520  unput(yytext[i]);
4521  }
4522  *yyextra->copyArgString+=*yytext;
4523  yyextra->fullArgString+=*yytext;
4524  yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4525  handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
4526  BEGIN( yyextra->currentArgumentContext );
4527  }
4528  else
4529  {
4530  // for functions we interpret a comment
4531  // as documentation for the yyextra->last argument
4532  yyextra->lastCopyArgChar=*yytext;
4533  QCString text=&yytext[1];
4534  text=text.stripWhiteSpace();
4535  yyextra->lastCommentInArgContext=YY_START;
4536  yyextra->fullArgString+=text;
4537  if (text.find("//")!=-1)
4538  BEGIN( CopyArgCommentLine );
4539  else
4540  BEGIN( CopyArgComment );
4541  }
4542  }
4543 <CopyArgComment>^{B}*"*"+/{BN}+
4544 <CopyArgComment>[^\n\\\@\*]+ { yyextra->fullArgString+=yytext; }
4545 <CopyArgComment>{CCE} { yyextra->fullArgString+=yytext;
4546  if (yyextra->lastCopyArgChar!=0)
4547  unput(yyextra->lastCopyArgChar);
4548  BEGIN( yyextra->lastCommentInArgContext );
4549  }
4550 <CopyArgCommentLine>\n { yyextra->fullArgString+=yytext;
4551  lineCount(yyscanner);
4552  if (yyextra->lastCopyArgChar!=0)
4553  unput(yyextra->lastCopyArgChar);
4554  BEGIN( yyextra->lastCommentInArgContext );
4555  }
4556 <CopyArgCommentLine>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
4557  yyextra->docBlockName="uml";
4558  yyextra->fullArgString+=yytext;
4559  BEGIN(CopyArgVerbatim);
4560  }
4561 <CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
4562  yyextra->docBlockName=&yytext[1];
4563  yyextra->fullArgString+=yytext;
4564  BEGIN(CopyArgVerbatim);
4565  }
4566 <CopyArgCommentLine>{CMD}("f$"|"f["|"f{"|"f(") {
4567  yyextra->docBlockName=&yytext[1];
4568  if (yyextra->docBlockName.at(1)=='[')
4569  {
4570  yyextra->docBlockName.at(1)=']';
4571  }
4572  if (yyextra->docBlockName.at(1)=='{')
4573  {
4574  yyextra->docBlockName.at(1)='}';
4575  }
4576  if (yyextra->docBlockName.at(1)=='(')
4577  {
4578  yyextra->docBlockName.at(1)=')';
4579  }
4580  yyextra->fullArgString+=yytext;
4581  BEGIN(CopyArgVerbatim);
4582  }
4583 <CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode"|"f$"|"f]"|"f}"|"f)")/[^a-z_A-Z0-9\-] { // end of verbatim block
4584  yyextra->fullArgString+=yytext;
4585  if (yytext[1]=='f' && yyextra->docBlockName==&yytext[1])
4586  {
4587  BEGIN(CopyArgCommentLine);
4588  }
4589  if (&yytext[4]==yyextra->docBlockName)
4590  {
4591  BEGIN(CopyArgCommentLine);
4592  }
4593  }
4594 <CopyArgCommentLine>[^\\\@\n]+ { yyextra->fullArgString+=yytext; }
4595 <CopyArgCommentLine>. { yyextra->fullArgString+=*yytext; }
4596 <CopyArgComment,CopyArgVerbatim>\n { yyextra->fullArgString+=*yytext; lineCount(yyscanner); }
4597 <CopyArgComment,CopyArgVerbatim>. { yyextra->fullArgString+=*yytext; }
4598 <CopyArgComment>{CMD}("brief"|"short"){B}+ {
4599  warn(yyextra->yyFileName,yyextra->yyLineNr,
4600  "Ignoring %cbrief command inside argument documentation",*yytext
4601  );
4602  yyextra->fullArgString+=' ';
4603  }
4604 <ReadTempArgs>"<" {
4605  *yyextra->copyArgString+=*yytext;
4606  yyextra->fullArgString+=*yytext;
4607  yyextra->argSharpCount=1;
4608  BEGIN( CopyArgSharp );
4609  }
4610 <ReadTempArgs>">" {
4611  *yyextra->copyArgString+=*yytext;
4612  yyextra->fullArgString+=*yytext;
4613  //printf("end template list '%s'\n",qPrint(*yyextra->copyArgString));
4614  *yyextra->currentArgumentList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4615  BEGIN( yyextra->currentArgumentContext );
4616  }
4617 <CopyArgRound>"(" {
4618  yyextra->argRoundCount++;
4619  *yyextra->copyArgString+=*yytext;
4620  yyextra->fullArgString+=*yytext;
4621  }
4622 <CopyArgRound>")" {
4623  *yyextra->copyArgString+=*yytext;
4624  yyextra->fullArgString+=*yytext;
4625  if (yyextra->argRoundCount>0)
4626  yyextra->argRoundCount--;
4627  else
4628  BEGIN( yyextra->lastCopyArgContext );
4629  }
4630 <CopyArgSquare>"[" {
4631  yyextra->argSquareCount++;
4632  *yyextra->copyArgString+=*yytext;
4633  yyextra->fullArgString+=*yytext;
4634  }
4635 <CopyArgSquare>"]" {
4636  *yyextra->copyArgString+=*yytext;
4637  yyextra->fullArgString+=*yytext;
4638  if (yyextra->argSquareCount>0)
4639  yyextra->argSquareCount--;
4640  else
4641  BEGIN( yyextra->lastCopyArgContext );
4642  }
4643 <CopyArgSharp>"(" {
4644  *yyextra->copyArgString+=*yytext;
4645  yyextra->fullArgString+=*yytext;
4646  yyextra->argRoundCount=0;
4647  yyextra->lastCopyArgContext = YY_START;
4648  BEGIN( CopyArgRound );
4649  }
4650 <CopyArgSharp>"<" {
4651  yyextra->argSharpCount++;
4652  //printf("yyextra->argSharpCount++=%d copy\n",yyextra->argSharpCount);
4653  *yyextra->copyArgString+=*yytext;
4654  yyextra->fullArgString+=*yytext;
4655  }
4656 <CopyArgSharp>">" {
4657  *yyextra->copyArgString+=*yytext;
4658  yyextra->fullArgString+=*yytext;
4659  yyextra->argSharpCount--;
4660  if (yyextra->argSharpCount>0)
4661  {
4662  //printf("yyextra->argSharpCount--=%d copy\n",yyextra->argSharpCount);
4663  }
4664  else
4665  {
4666  BEGIN( ReadTempArgs );
4667  //printf("end of yyextra->argSharpCount\n");
4668  }
4669  }
4670 <CopyArgString,CopyArgPHPString>\\. {
4671  *yyextra->copyArgString+=yytext;
4672  yyextra->fullArgString+=yytext;
4673  }
4674 <CopyArgString>\" {
4675  *yyextra->copyArgString+=*yytext;
4676  yyextra->fullArgString+=*yytext;
4677  BEGIN( yyextra->lastCopyArgStringContext );
4678  }
4679 <CopyArgPHPString>\' {
4680  *yyextra->copyArgString+=*yytext;
4681  yyextra->fullArgString+=*yytext;
4682  BEGIN( yyextra->lastCopyArgStringContext );
4683  }
4684 <ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>{CHARLIT} {
4685  if (yyextra->insidePHP)
4686  {
4687  REJECT;
4688  }
4689  else
4690  {
4691  *yyextra->copyArgString+=yytext;
4692  yyextra->fullArgString+=yytext;
4693  }
4694  }
4695 <ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>\' {
4696  *yyextra->copyArgString+=yytext;
4697  yyextra->fullArgString+=yytext;
4698  if (yyextra->insidePHP)
4699  {
4700  yyextra->lastCopyArgStringContext=YY_START;
4701  BEGIN(CopyArgPHPString);
4702  }
4703  }
4704 <ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>\n {
4705  lineCount(yyscanner);
4706  *yyextra->copyArgString+=*yytext;
4707  yyextra->fullArgString+=*yytext;
4708  }
4709 <ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>. {
4710  *yyextra->copyArgString+=*yytext;
4711  yyextra->fullArgString+=*yytext;
4712  }
4713 
4714 
4715 
4716  /*------------------------------------------------------------------------*/
4717 
4718 
4719 <FuncRound>"(" { yyextra->current->args += *yytext ;
4720  ++yyextra->roundCount ;
4721  }
4722 <FuncRound>")" { yyextra->current->args += *yytext ;
4723  if ( yyextra->roundCount )
4724  --yyextra->roundCount ;
4725  else
4726  BEGIN( FuncQual ) ;
4727  }
4728  /*
4729 <FuncQual>"#" { if (yyextra->insidePHP)
4730  REJECT;
4731  yyextra->lastCPPContext = YY_START;
4732  BEGIN(SkipCPP);
4733  }
4734  */
4735 <FuncQual>[{:;,] {
4736  if ( qstrcmp(yytext,";")==0 &&
4737  yyextra->insidePHP &&
4738  !containsWord(yyextra->current->type,"function") )
4739  {
4740  yyextra->current->reset();
4741  initEntry(yyscanner);
4742  BEGIN( FindMembers );
4743  }
4744  else
4745  {
4746  unput(*yytext); BEGIN( Function );
4747  }
4748  }
4749 <FuncQual>{BN}*"abstract"{BN}* { // pure virtual member function
4750  lineCount(yyscanner) ;
4751  yyextra->current->virt = Pure;
4752  yyextra->current->args += " override ";
4753  }
4754 <FuncQual,TrailingReturn>{BN}*"override"{BN}* { // C++11 overridden virtual member function
4755  lineCount(yyscanner) ;
4756  yyextra->current->spec |= Entry::Override;
4757  yyextra->current->args += " override ";
4758  BEGIN(FuncQual);
4759  }
4760 <FuncQual,TrailingReturn>{BN}*"final"{BN}* { // C++11 final method
4761  lineCount(yyscanner) ;
4762  yyextra->current->spec |= Entry::Final;
4763  yyextra->current->args += " final ";
4764  BEGIN(FuncQual);
4765  }
4766 <FuncQual>{BN}*"sealed"{BN}* { // sealed member function
4767  lineCount(yyscanner) ;
4768  yyextra->current->spec |= Entry::Sealed;
4769  yyextra->current->args += " sealed ";
4770  }
4771 <FuncQual>{BN}*"new"{BN}* { // new member function
4772  lineCount(yyscanner) ;
4773  yyextra->current->spec |= Entry::New;
4774  yyextra->current->args += " new ";
4775  }
4776 <FuncQual>{BN}*"const"{BN}* { // const member function
4777  lineCount(yyscanner) ;
4778  yyextra->current->args += " const ";
4779  yyextra->current->argList.setConstSpecifier(TRUE);
4780  }
4781 <FuncQual>{BN}*"volatile"{BN}* { // volatile member function
4782  lineCount(yyscanner) ;
4783  yyextra->current->args += " volatile ";
4784  yyextra->current->argList.setVolatileSpecifier(TRUE);
4785  }
4786 <FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier
4787  lineCount(yyscanner) ;
4788  yyextra->current->args += " noexcept ";
4789  yyextra->current->spec |= Entry::NoExcept;
4790  }
4791 <FuncQual>{BN}*"noexcept"{BN}*"(" { // noexcept expression
4792  lineCount(yyscanner) ;
4793  yyextra->current->args += " noexcept(";
4794  yyextra->current->spec |= Entry::NoExcept;
4795  yyextra->lastRoundContext=FuncQual;
4796  yyextra->pCopyRoundString=&yyextra->current->args;
4797  yyextra->roundCount=0;
4798  BEGIN(CopyRound);
4799  }
4800 <FuncQual>{BN}*"&" {
4801  yyextra->current->args += " &";
4802  yyextra->current->argList.setRefQualifier(RefQualifierLValue);
4803  }
4804 <FuncQual>{BN}*"&&" {
4805  yyextra->current->args += " &&";
4806  yyextra->current->argList.setRefQualifier(RefQualifierRValue);
4807  }
4808 
4809 <FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function
4810  lineCount(yyscanner) ;
4811  yyextra->current->args += " = 0";
4812  yyextra->current->virt = Pure;
4813  yyextra->current->argList.setPureSpecifier(TRUE);
4814  BEGIN(FuncQual);
4815  }
4816 <FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member
4817  lineCount(yyscanner);
4818  yyextra->current->args += " = delete";
4819  yyextra->current->spec |= Entry::Delete;
4820  yyextra->current->argList.setIsDeleted(TRUE);
4821  BEGIN(FuncQual);
4822  }
4823 <FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator
4824  lineCount(yyscanner);
4825  yyextra->current->args += " = default";
4826  yyextra->current->spec |= Entry::Default;
4827  BEGIN(FuncQual);
4828  }
4829 <FuncQual>{BN}*"->"{BN}* {
4830  lineCount(yyscanner);
4831  yyextra->current->argList.setTrailingReturnType(" -> ");
4832  yyextra->current->args += " -> ";
4833  yyextra->roundCount=0;
4834  BEGIN(TrailingReturn);
4835  }
4836 <TrailingReturn>[{;] {
4837  if (yyextra->roundCount>0) REJECT;
4838  unput(*yytext);
4839  BEGIN(FuncQual);
4840  }
4841 <TrailingReturn>"requires"{BN}+ {
4842  yyextra->requiresContext = FuncQual;
4843  yyextra->current->req+=' ';
4844  BEGIN(RequiresClause);
4845  }
4846 <TrailingReturn>"(" {
4847  yyextra->roundCount++;
4848  yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
4849  yyextra->current->args+=yytext;
4850  }
4851 <TrailingReturn>")" {
4852  if (yyextra->roundCount>0)
4853  {
4854  yyextra->roundCount--;
4855  }
4856  else
4857  {
4858  warn(yyextra->yyFileName,yyextra->yyLineNr,
4859  "Found ')' without opening '(' for trailing return type '%s)...'",
4860  qPrint(yyextra->current->argList.trailingReturnType()));
4861  }
4862  yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
4863  yyextra->current->args+=yytext;
4864  }
4865 <TrailingReturn>. {
4866  yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
4867  yyextra->current->args+=yytext;
4868  }
4869 <TrailingReturn>\n {
4870  lineCount(yyscanner);
4871  yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
4872  yyextra->current->args+=' ';
4873  }
4874 <FuncRound,FuncFunc>{BN}*","{BN}* {
4875  lineCount(yyscanner) ;
4876  yyextra->current->args += ", " ;
4877  }
4878 <FuncQual,FuncRound,FuncFunc>{BN}+ {
4879  lineCount(yyscanner) ;
4880  yyextra->current->args += ' ' ;
4881  }
4882 <Function,FuncQual,FuncRound,FuncFunc>"#" { if (yyextra->insidePHP)
4883  REJECT;
4884  yyextra->lastCPPContext = YY_START;
4885  BEGIN(SkipCPP);
4886  }
4887 <FuncQual>"=" {
4888  if (yyextra->insideCli &&
4889  (yyextra->current_root->section&Entry::COMPOUND_MASK)
4890  )
4891  {
4892  BEGIN(CliOverride);
4893  }
4894  else
4895  {
4896  // typically an initialized function pointer
4897  yyextra->lastInitializerContext=YY_START;
4898  yyextra->initBracketCount=0;
4899  yyextra->current->initializer.str(yytext);
4900  BEGIN(ReadInitializer);
4901  }
4902  }
4903 <CliOverride>{ID} {
4904  }
4905 <CliOverride>"{" {
4906  unput(*yytext);
4907  BEGIN(FuncQual);
4908  }
4909 <CliOverride>\n {
4910  lineCount(yyscanner);
4911  }
4912 <CliOverride>. {
4913  }
4914 <FuncQual>{ID} {
4915  if (yyextra->insideCpp && qstrcmp(yytext,"requires")==0)
4916  {
4917  // c++20 trailing requires clause
4918  yyextra->requiresContext = YY_START;
4919  yyextra->current->req+=' ';
4920  BEGIN(RequiresClause);
4921  }
4922  else if (yyextra->insideCS && qstrcmp(yytext,"where")==0)
4923  {
4924  // type constraint for a method
4925  yyextra->current->typeConstr.clear();
4926  yyextra->current->typeConstr.push_back(Argument());
4927  yyextra->lastCSConstraint = YY_START;
4928  BEGIN( CSConstraintName );
4929  }
4930  else if (checkForKnRstyleC(yyscanner)) // K&R style C function
4931  {
4932  yyextra->current->args = yytext;
4933  yyextra->oldStyleArgType.resize(0);
4934  BEGIN(OldStyleArgs);
4935  }
4936  else
4937  {
4938  yyextra->current->args += yytext;
4939  }
4940  }
4941 <OldStyleArgs>[,;] {
4942  QCString oldStyleArgPtr;
4943  QCString oldStyleArgName;
4944  splitKnRArg(yyscanner,oldStyleArgPtr,oldStyleArgName);
4945  QCString doc,brief;
4946  if (yyextra->current->doc!=yyextra->docBackup)
4947  {
4948  doc=yyextra->current->doc;
4949  yyextra->current->doc=yyextra->docBackup;
4950  }
4951  if (yyextra->current->brief!=yyextra->briefBackup)
4952  {
4953  brief=yyextra->current->brief;
4954  yyextra->current->brief=yyextra->briefBackup;
4955  }
4956  addKnRArgInfo(yyscanner,yyextra->oldStyleArgType+oldStyleArgPtr,
4957  oldStyleArgName,brief,doc);
4958  yyextra->current->args.resize(0);
4959  if (*yytext==';') yyextra->oldStyleArgType.resize(0);
4960  }
4961 <OldStyleArgs>{ID} { yyextra->current->args += yytext; }
4962 <OldStyleArgs>"{" {
4963  if (yyextra->current->argList.empty())
4964  {
4965  yyextra->current->argList.setNoParameters(TRUE);
4966  }
4967  yyextra->current->args = argListToString(yyextra->current->argList);
4968  unput('{');
4969  BEGIN(FuncQual);
4970  }
4971 <OldStyleArgs>. { yyextra->current->args += *yytext; }
4972 <FuncQual,FuncRound,FuncFunc>. { yyextra->current->args += *yytext; }
4973 <FuncQual>{BN}*"try:" |
4974 <FuncQual>{BN}*"try"{BN}+ { /* try-function-block */
4975  yyextra->insideTryBlock=TRUE;
4976  lineCount(yyscanner);
4977  if (yytext[yyleng-1]==':')
4978  {
4979  unput(':');
4980  BEGIN( Function );
4981  }
4982  }
4983 <FuncQual>{BN}*"throw"{BN}*"(" { // C++ style throw clause
4984  yyextra->current->exception = " throw (" ;
4985  yyextra->roundCount=0;
4986  lineCount(yyscanner) ;
4987  BEGIN( ExcpRound ) ;
4988  }
4989 <FuncQual>{BN}*"raises"{BN}*"(" {
4990  yyextra->current->exception = " raises (" ;
4991  lineCount(yyscanner) ;
4992  yyextra->roundCount=0;
4993  BEGIN( ExcpRound ) ;
4994  }
4995 <FuncQual>{BN}*"throws"{BN}+ { // Java style throw clause
4996  yyextra->current->exception = " throws " ;
4997  lineCount(yyscanner) ;
4998  BEGIN( ExcpList );
4999  }
5000 <ExcpRound>"(" { yyextra->current->exception += *yytext ;
5001  ++yyextra->roundCount ;
5002  }
5003 <ExcpRound>")" { yyextra->current->exception += *yytext ;
5004  if ( yyextra->roundCount )
5005  --yyextra->roundCount ;
5006  else
5007  BEGIN( FuncQual ) ;
5008  }
5009 <ExcpRound>. {
5010  yyextra->current->exception += *yytext;
5011  }
5012 <ExcpList>"{" {
5013  unput('{'); BEGIN( FuncQual );
5014  }
5015 <ExcpList>";" {
5016  unput(';'); BEGIN( FuncQual );
5017  }
5018 <ExcpList>"\n" {
5019  yyextra->current->exception += ' ';
5020  lineCount(yyscanner);
5021  }
5022 <ExcpList>. {
5023  yyextra->current->exception += *yytext;
5024  }
5025 <Function>"(" { yyextra->current->type += yyextra->current->name ;
5026  yyextra->current->name = yyextra->current->args ;
5027  yyextra->current->args = yytext ;
5028  yyextra->roundCount=0;
5029  BEGIN( FuncRound ) ;
5030  }
5031 <Function>":" {
5032  if (!yyextra->insidePHP) BEGIN(SkipInits);
5033  }
5034 <Function>[;{,] {
5035  yyextra->current->name=removeRedundantWhiteSpace(yyextra->current->name);
5036  yyextra->current->type=removeRedundantWhiteSpace(yyextra->current->type);
5037  yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
5038  yyextra->current->fileName = yyextra->yyFileName;
5039  yyextra->current->startLine = yyextra->yyBegLineNr;
5040  yyextra->current->startColumn = yyextra->yyBegColNr;
5041  static const reg::Ex re(R"(\([^)]*[*&][^)]*\))");
5042  reg::Match match;
5043  std::string type = yyextra->current->type.str();
5044  int ti=-1;
5045  if (reg::search(type,match,re))
5046  {
5047  ti = (int)match.position();
5048  }
5049  int ts=yyextra->current->type.find('<');
5050  int te=yyextra->current->type.findRev('>');
5051 
5052  // bug677315: A<int(void *, char *)> get(); is not a function pointer
5053  bool isFunction = ti==-1 || // not a (...*...) pattern
5054  (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list
5055  bool isVariable = (!yyextra->current->type.isEmpty() &&
5056  (!isFunction || yyextra->current->type.left(8)=="typedef "));
5057 
5058  //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n",
5059  // qPrint(yyextra->current->type),ts,te,ti,isFunction);
5060 
5061  if (*yytext!=';' || (yyextra->current_root->section&Entry::COMPOUND_MASK) )
5062  {
5063  int tempArg=yyextra->current->name.find('<');
5064  QCString tempName;
5065  if (tempArg==-1) tempName=yyextra->current->name; else tempName=yyextra->current->name.left(tempArg);
5066  if (isVariable)
5067  {
5068  //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5069  if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ")
5070  {
5071  yyextra->current->type.prepend("typedef ");
5072  }
5073  yyextra->current->section = Entry::VARIABLE_SEC ;
5074  }
5075  else
5076  {
5077  //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5078  yyextra->current->section = Entry::FUNCTION_SEC ;
5079  yyextra->current->proto = *yytext==';';
5080  }
5081  }
5082  else // a global function prototype or function variable
5083  {
5084  //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5085  if (isVariable)
5086  {
5087  if (yyextra->isTypedef && yyextra->current->type.left(8)!="typedef ")
5088  {
5089  yyextra->current->type.prepend("typedef ");
5090  }
5091  //printf("Scanner.l: found function variable!\n");
5092  yyextra->current->section = Entry::VARIABLE_SEC;
5093  }
5094  else
5095  {
5096  //printf("Scanner.l: found prototype\n");
5097  yyextra->current->section = Entry::FUNCTION_SEC;
5098  yyextra->current->proto = TRUE;
5099  }
5100  }
5101  //printf("Adding entry '%s'\n",qPrint(yyextra->current->name));
5102  if ( yyextra->insidePHP)
5103  {
5104  if (findAndRemoveWord(yyextra->current->type,"final"))
5105  {
5106  yyextra->current->spec |= Entry::Final;
5107  }
5108  if (findAndRemoveWord(yyextra->current->type,"abstract"))
5109  {
5110  yyextra->current->spec |= Entry::Abstract;
5111  }
5112  }
5113  if ( yyextra->insidePHP && !containsWord(yyextra->current->type,"function"))
5114  {
5115  initEntry(yyscanner);
5116  if ( *yytext == '{' )
5117  {
5118  yyextra->lastCurlyContext = FindMembers;
5119  yyextra->curlyCount=0;
5120  BEGIN( SkipCurly );
5121  }
5122  else
5123  {
5124  BEGIN( FindMembers );
5125  }
5126  }
5127  else
5128  {
5129  if ( yyextra->insidePHP)
5130  {
5131  findAndRemoveWord(yyextra->current->type,"function");
5132  }
5133  yyextra->previous = yyextra->current;
5134  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
5135  initEntry(yyscanner);
5136  // Objective C 2.0: Required/Optional section
5137  if (yyextra->previous->spec & (Entry::Optional | Entry::Required))
5138  {
5139  yyextra->current->spec |= yyextra->previous->spec & (Entry::Optional|Entry::Required);
5140  }
5141  yyextra->lastCurlyContext = FindMembers;
5142  if ( *yytext == ',' )
5143  {
5144  yyextra->current->type = yyextra->previous->type;
5145  // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
5146  int i=yyextra->current->type.length();
5147  while (i>0 && (yyextra->current->type[i-1]=='*' || yyextra->current->type[i-1]=='&' || yyextra->current->type[i-1]==' ')) i--;
5148  yyextra->current->type = yyextra->current->type.left(i);
5149  }
5150  if ( *yytext == '{' )
5151  {
5152  if ( !yyextra->insidePHP && (yyextra->current_root->section & Entry::COMPOUND_MASK) )
5153  {
5154  yyextra->previous->spec |= Entry::Inline;
5155  }
5156  //addToBody(yytext);
5157  yyextra->curlyCount=0;
5158  BEGIN( SkipCurly ) ;
5159  }
5160  else
5161  {
5162  if (yyextra->previous->section!=Entry::VARIABLE_SEC)
5163  yyextra->previous->bodyLine=-1; // a function/member declaration
5164  BEGIN( FindMembers ) ;
5165  }
5166  }
5167  }
5168 <SkipInits>">"{BN}*"{" { // C++11 style initializer (see bug 790788)
5169  lineCount(yyscanner);
5170  yyextra->curlyCount=1;
5171  BEGIN(SkipC11Inits);
5172  }
5173 <SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647)
5174  lineCount(yyscanner);
5175  yyextra->curlyCount=1;
5176  BEGIN(SkipC11Inits);
5177  }
5178 <SkipC11Inits>"{" {
5179  ++yyextra->curlyCount;
5180  }
5181 <SkipC11Inits>"}" {
5182  if ( --yyextra->curlyCount<=0 )
5183  {
5184  BEGIN(SkipInits);
5185  }
5186  }
5187 <SkipC11Attribute>"]]" {
5188  BEGIN(yyextra->lastC11AttributeContext);
5189  }
5190 <SkipInits>"{" { // C++11 style initializer
5191  unput('{');
5192  BEGIN( Function );
5193  }
5194 <SkipCurly>"{" {
5195  //addToBody(yytext);
5196  ++yyextra->curlyCount ;
5197  }
5198 <SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */)
5199 <SkipCurly>"}" {
5200  //addToBody(yytext);
5201  if( yyextra->curlyCount )
5202  {
5203  --yyextra->curlyCount ;
5204  }
5205  else
5206  {
5207  if (!yyextra->current->sli.empty() && yyextra->previous) // copy special list items
5208  {
5209  yyextra->previous->sli = yyextra->current->sli;
5210  yyextra->current->sli.clear();
5211  }
5212  if (yyextra->previous) yyextra->previous->endBodyLine=yyextra->yyLineNr;
5213  BEGIN( yyextra->lastCurlyContext ) ;
5214  }
5215  }
5216 <SkipCurly>"}"{BN}*{DCOMM}"<" {
5217  lineCount(yyscanner);
5218  if ( yyextra->curlyCount )
5219  {
5220  //addToBody(yytext);
5221  --yyextra->curlyCount ;
5222  }
5223  else
5224  {
5225  yyextra->current->endBodyLine=yyextra->yyLineNr;
5226  yyextra->tempEntry = yyextra->current; // temporarily switch to the previous entry
5227  yyextra->current = yyextra->previous;
5228 
5229  yyextra->docBlockContext = SkipCurlyEndDoc;
5230  yyextra->docBlockInBody = FALSE;
5231  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
5232  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
5233  yyextra->docBlock.str(std::string());
5234  yyextra->docBlockTerm = '}';
5235  if (yytext[yyleng-3]=='/')
5236  {
5237  startCommentBlock(yyscanner,TRUE);
5238  BEGIN( DocLine );
5239  }
5240  else
5241  {
5242  startCommentBlock(yyscanner,FALSE);
5243  BEGIN( DocBlock );
5244  }
5245  }
5246  }
5247 <SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
5248  yyextra->docBlockContext = SkipCurlyEndDoc;
5249  yyextra->docBlockInBody = FALSE;
5250  yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
5251  ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
5252  yyextra->docBlock.str(std::string());
5253  yyextra->docBlockTerm = '}';
5254  if (yytext[yyleng-3]=='/')
5255  {
5256  startCommentBlock(yyscanner,TRUE);
5257  BEGIN( DocLine );
5258  }
5259  else
5260  {
5261  startCommentBlock(yyscanner,FALSE);
5262  BEGIN( DocBlock );
5263  }
5264  }
5265 <SkipCurlyEndDoc>"}" {
5266  //addToBody("}");
5267  if (yyextra->tempEntry) // we can only switch back to yyextra->current if no new item was created
5268  {
5269  yyextra->current = yyextra->tempEntry;
5270  yyextra->tempEntry.reset();
5271  }
5272  BEGIN( yyextra->lastCurlyContext );
5273  }
5274 <SkipCurly>\" {
5275  //addToBody(yytext);
5276  yyextra->lastStringContext=SkipCurly;
5277  BEGIN( SkipString );
5278  }
5279 <SkipCurly>^{B}*"#" {
5280  if (yyextra->insidePHP)
5281  REJECT;
5282  //addToBody(yytext);
5283  BEGIN( SkipCurlyCpp );
5284  }
5285 <SkipCurly,SkipC11Inits,SkipInits,SkipC11Attribute>\n {
5286  lineCount(yyscanner);
5287  //addToBody(yytext);
5288  }
5289 <SkipCurly,SkipCurlyCpp,ReadInitializer,ReadInitializerPtr>"<<<" {
5290  if (!yyextra->insidePHP)
5291  {
5292  REJECT;
5293  }
5294  else
5295  {
5296  yyextra->lastHereDocContext = YY_START;
5297  BEGIN(HereDoc);
5298  }
5299  }
5300 <SkipCurly,SkipCurlyCpp>{B}*{RAWBEGIN} {
5301  QCString raw=QCString(yytext).stripWhiteSpace();
5302  yyextra->delimiter = raw.mid(2);
5303  yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
5304  yyextra->lastRawStringContext = YY_START;
5305  yyextra->dummyRawString.resize(0);
5306  yyextra->pCopyRawString = &yyextra->dummyRawString;
5307  *yyextra->pCopyRawString += yytext;
5308  BEGIN(RawString);
5309  }
5310 <SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<]+ {
5311  lineCount(yyscanner); // for yyextra->column updates
5312  //addToBody(yytext);
5313  }
5314 <SkipCurlyCpp>\n {
5315  //addToBody(yytext);
5316  lineCount(yyscanner);
5317  yyextra->lastCurlyContext = FindMembers;
5318  BEGIN( SkipCurly );
5319  }
5320 <SkipCurlyCpp>\\[\r]*"\n"[\r]* {
5321  //addToBody(yytext);
5322  lineCount(yyscanner);
5323  }
5324 <SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,SkipC11Attribute>{CCS} {
5325  //addToBody(yytext);
5326  yyextra->lastCContext = YY_START;
5327  BEGIN(SkipComment);
5328  }
5329 <SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,SkipC11Attribute>{CPPC} {
5330  //addToBody(yytext);
5331  yyextra->lastCContext = YY_START;
5332  BEGIN(SkipCxxComment);
5333  }
5334 <SkipInits,SkipC11Inits,SkipC11Attribute>"(" {
5335  yyextra->roundCount=0;
5336  yyextra->lastSkipRoundContext=YY_START;
5337  BEGIN(SkipRound);
5338  }
5339 <SkipInits,SkipC11Inits,SkipC11Attribute>\" {
5340  yyextra->lastStringContext=YY_START;
5341  BEGIN( SkipString );
5342  }
5343 <SkipInits>; {
5344  warn(yyextra->yyFileName,yyextra->yyLineNr,
5345  "Found ';' while parsing initializer list! "
5346  "(doxygen could be confused by a macro call without semicolon)"
5347  );
5348  BEGIN( FindMembers );
5349  }
5350 <SkipInits,SkipCurly,SkipCurlyCpp>"#" {
5351  if (!yyextra->insidePHP)
5352  REJECT;
5353  //addToBody(yytext);
5354  yyextra->lastCContext = YY_START;
5355  BEGIN(SkipCxxComment);
5356  }
5357 <SkipInits,SkipCurly,SkipCurlyCpp>@\" {
5358  if (!yyextra->insideCS) REJECT;
5359  // C# verbatim string
5360  yyextra->lastSkipVerbStringContext=YY_START;
5361  yyextra->pSkipVerbString=&yyextra->current->initializer;
5362  BEGIN(SkipVerbString);
5363  }
5364 <SkipInits,SkipCurly,SkipCurlyCpp>{CHARLIT} {
5365  if (yyextra->insidePHP) REJECT;
5366  }
5367 <SkipInits,SkipCurly,SkipCurlyCpp>\' {
5368  if (yyextra->insidePHP)
5369  {
5370  yyextra->lastStringContext=YY_START;
5371  BEGIN(SkipPHPString);
5372  }
5373  }
5374 <SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,SkipC11Attribute>. { }
5375 <SkipString,SkipPHPString>\\. { }
5376 <SkipString>\" {
5377  BEGIN( yyextra->lastStringContext );
5378  }
5379 <SkipPHPString>\' {
5380  BEGIN( yyextra->lastStringContext );
5381  }
5382 <SkipString,SkipPHPString>{CCS}|{CCE}|{CPPC} { }
5383 <SkipString,SkipPHPString>\n {
5384  lineCount(yyscanner);
5385  }
5386 <SkipString,SkipPHPString>. { }
5387 <CompoundName>":" { // for "class : public base {} var;" construct, see bug 608359
5388  unput(':');
5389  BEGIN(ClassVar);
5390  }
5391 <CompoundName>";" {
5392  yyextra->current->section = Entry::EMPTY_SEC ;
5393  yyextra->current->type.resize(0) ;
5394  yyextra->current->name.resize(0) ;
5395  yyextra->current->args.resize(0) ;
5396  yyextra->current->argList.clear();
5397  BEGIN( FindMembers ) ;
5398  }
5399 <Bases>";" {
5400  if (yyextra->insideIDL && (yyextra->current->spec & (Entry::Singleton |
5401  Entry::Service)))
5402  {
5403  // in UNO IDL a service or singleton may be defined
5404  // completely like this: "service Foo : XFoo;"
5405  if (!yyextra->current->name.isEmpty() && !yyextra->current_root->name.isEmpty())
5406  {
5407  prependScope(yyscanner);
5408  }
5409  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
5410  // there can be only one base class here
5411  if (!yyextra->baseName.isEmpty())
5412  {
5413  yyextra->current->extends.push_back(
5414  BaseInfo(yyextra->baseName,Public,Normal));
5415  yyextra->baseName.resize(0);
5416  }
5417  yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
5418  initEntry(yyscanner);
5419  }
5420  else
5421  {
5422  yyextra->current->section = Entry::EMPTY_SEC ;
5423  yyextra->current->type.resize(0) ;
5424  yyextra->current->name.resize(0) ;
5425  yyextra->current->args.resize(0) ;
5426  yyextra->current->argList.clear();
5427  }
5428  BEGIN( FindMembers ) ;
5429  }
5430 <CompoundName>{SCOPENAME}/{BN}*"<" {
5431  yyextra->sharpCount = 0;
5432  yyextra->current->name = yytext ;
5433  if (yyextra->current->spec & Entry::Protocol)
5434  {
5435  yyextra->current->name+="-p";
5436  }
5437  lineCount(yyscanner);
5438  yyextra->lastClassTemplSpecContext = ClassVar;
5439  if (yyextra->insideObjC) // protocol list
5440  {
5441  BEGIN( ObjCProtocolList );
5442  }
5443  else if (yyextra->insideCS) // C# generic class
5444  {
5445  //yyextra->current->name+="-g";
5446  BEGIN( CSGeneric );
5447  }
5448  else // C++ template specialization
5449  {
5450  yyextra->roundCount=0;
5451  BEGIN( ClassTemplSpec );
5452  }
5453  }
5454 <CSGeneric>"<" {
5455  ArgumentList al;
5456  // check bug 612858 before enabling the next line
5457  //yyextra->current->spec |= Entry::Template;
5458  yyextra->current->tArgLists.push_back(al);
5459  yyextra->currentArgumentList = &yyextra->current->tArgLists.back();
5460  yyextra->templateStr="<";
5461  yyextra->current->name += "<";
5462  yyextra->fullArgString = yyextra->templateStr;
5463  yyextra->copyArgString = &yyextra->current->name;
5464  //yyextra->copyArgString = &yyextra->templateStr;
5465  yyextra->currentArgumentContext = ClassVar;
5466  BEGIN( ReadTempArgs );
5467  }
5468 <ObjCProtocolList>"<" {
5469  yyextra->insideProtocolList=TRUE;
5470  BEGIN( Bases );
5471  }
5472 <ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
5473  yyextra->current->name += yytext;
5474  lineCount(yyscanner);
5475  if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
5476  {
5477  yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
5478  if (yyextra->current->spec & Entry::Protocol)
5479  { // Objective-C protocol
5480  unput('{'); // fake start of body
5481  BEGIN( ClassVar );
5482  }
5483  else
5484  {
5485  BEGIN( yyextra->lastClassTemplSpecContext );
5486  }
5487  }
5488  }
5489 <ClassTemplSpec>"<" {
5490  yyextra->current->name += yytext;
5491  if (yyextra->roundCount==0) yyextra->sharpCount++;
5492  }
5493 <ClassTemplSpec>. {
5494  yyextra->current->name += yytext;
5495  }
5496 <CompoundName>{SCOPENAME}{BN}*";" { // forward declaration
5497  if (!yyextra->current->tArgLists.empty())
5498  {
5499  // found a forward template declaration, this has
5500  // a purpose of its own
5501  yyextra->current->name = yytext;
5502  yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
5503  //printf("template class declaration for %s!\n",qPrint(yyextra->current->name));
5504  QCString rn = yyextra->current_root->name;
5505  //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
5506  if (!yyextra->current->name.isEmpty() && !rn.isEmpty())
5507  {
5508  prependScope(yyscanner);
5509  }
5510  yyextra->current->spec|=Entry::ForwardDecl;
5511  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
5512  }
5513  else if (yyextra->insideIDL &&
5514  (((yyextra->current_root->spec & (Entry::Interface |
5515  Entry::Service)) &&
5516  (yyextra->current->spec & Entry::Interface)) ||
5517  ((yyextra->current_root->spec & (Entry::Service |
5518  Entry::Singleton)) &&
5519  (yyextra->current->spec & Entry::Service))))
5520  {
5521  // interface yyextra->inside of UNO IDL service or interface
5522  // service yyextra->inside of UNO IDL service or singleton
5523  // there may be documentation on the member,
5524  // so do not throw it away...
5525  yyextra->current->name = yytext;
5526  yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
5527  yyextra->current->section = (yyextra->current->spec & Entry::Interface)
5528  ? Entry::EXPORTED_INTERFACE_SEC
5529  : Entry::INCLUDED_SERVICE_SEC;
5530 // yyextra->current->section = Entry::MEMBERDOC_SEC;
5531  yyextra->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...
5532  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
5533  }
5534 
5535  unput(';');
5536  yyextra->current->reset();
5537  initEntry(yyscanner);
5538  if (yyextra->insideObjC) // see bug746361
5539  {
5540  yyextra->language = yyextra->current->lang = SrcLangExt_Cpp;
5541  yyextra->insideObjC = FALSE;
5542  }
5543  if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
5544  {
5545  yyextra->current->type.prepend("typedef");
5546  }
5547  BEGIN( FindMembers );
5548  }
5549 <CompoundName>{SCOPENAME}/{BN}*"(" {
5550  yyextra->current->name = yytext ;
5551  lineCount(yyscanner);
5552  if (yyextra->insideCpp && yyextra->current->name=="alignas") // C++11
5553  {
5554  yyextra->lastAlignAsContext = YY_START;
5555  BEGIN( AlignAs );
5556  }
5557  else
5558  {
5559  if (yyextra->current->spec & Entry::Protocol)
5560  {
5561  yyextra->current->name += "-p";
5562  }
5563  BEGIN( ClassVar );
5564  }
5565  }
5566 <AlignAs>"(" { yyextra->roundCount=0;
5567  BEGIN( AlignAsEnd );
5568  }
5569 <AlignAs>\n { lineCount(yyscanner); }
5570 <AlignAs>.
5571 <AlignAsEnd>"(" { yyextra->roundCount++; }
5572 <AlignAsEnd>")" { if (--yyextra->roundCount<0)
5573  {
5574  BEGIN( yyextra->lastAlignAsContext );
5575  }
5576  }
5577 <AlignAsEnd>\n { lineCount(yyscanner); }
5578 <AlignAsEnd>.
5579 <ConceptName>{ID} {
5580  yyextra->current->name = yytext ;
5581  }
5582 <ConceptName>"=" {
5583  yyextra->current->bodyLine = yyextra->yyLineNr;
5584  yyextra->current->bodyColumn = yyextra->yyColNr;
5585  yyextra->current->initializer.str(std::string());
5586  yyextra->lastInitializerContext = FindMembers;
5587  yyextra->initBracketCount=0;
5588  BEGIN(ReadInitializer);
5589  }
5590 <CompoundName>{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line
5591  // e.g. @protocol A,B;
5592  yyextra->current->reset();
5593  initEntry(yyscanner);
5594  }
5595 <CompoundName>{SCOPENAME} {
5596  yyextra->current->name = yytext ;
5597  if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
5598  {
5599  yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
5600  }
5601  lineCount(yyscanner);
5602  if (yyextra->current->spec & Entry::Protocol)
5603  {
5604  yyextra->current->name += "-p";
5605  }
5606  if ((yyextra->current->spec & Entry::Protocol) ||
5607  yyextra->current->section == Entry::OBJCIMPL_SEC)
5608  {
5609  unput('{'); // fake start of body
5610  }
5611  BEGIN( ClassVar );
5612  }
5613 <CompoundName>{CSSCOPENAME} { // C# style scope
5614  yyextra->current->name = substitute(yytext,".","::");
5615  lineCount(yyscanner);
5616  BEGIN( ClassVar );
5617  }
5618 <ClassVar>{SCOPENAME}{BNopt}/"(" {
5619  if (yyextra->insideIDL && qstrncmp(yytext,"switch",6)==0 && !isId(yytext[6]))
5620  {
5621  // Corba IDL style union
5622  yyextra->roundCount=0;
5623  BEGIN(SkipUnionSwitch);
5624  }
5625  else
5626  {
5627  addType(yyscanner);
5628  yyextra->yyBegColNr=yyextra->yyColNr;
5629  yyextra->yyBegLineNr=yyextra->yyLineNr;
5630  yyextra->current->name = yytext;
5631  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
5632  lineCount(yyscanner);
5633  BEGIN( FindMembers );
5634  }
5635  }
5636 <ClassVar>"," {
5637  if (yyextra->isTypedef)
5638  {
5639  // multiple types in one typedef
5640  unput(',');
5641  yyextra->current->type.prepend("typedef ");
5642  BEGIN(FindMembers);
5643  }
5644  else
5645  {
5646  // Multiple class forward declaration
5647  }
5648  }
5649 <ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
5650  if (yyextra->insideCli)
5651  {
5652  if (yytext[0]=='s') // sealed
5653  yyextra->current->spec |= Entry::SealedClass;
5654  else // abstract
5655  yyextra->current->spec |= Entry::AbstractClass;
5656  BEGIN( ClassVar );
5657  }
5658  else
5659  {
5660  REJECT;
5661  }
5662  }
5663 <ClassVar>{ID} {
5664  yyextra->yyBegColNr=yyextra->yyColNr;
5665  yyextra->yyBegLineNr=yyextra->yyLineNr;
5666 
5667  if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
5668  {
5669  yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
5670  }
5671  if (yyextra->insideIDL && qstrcmp(yytext,"switch")==0)
5672  {
5673  // Corba IDL style union
5674  yyextra->roundCount=0;
5675  BEGIN(SkipUnionSwitch);
5676  }
5677  else if ((yyextra->insideJava || yyextra->insidePHP || yyextra->insideJS || yyextra->insideSlice) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0))
5678  {
5679  yyextra->current->type.resize(0);
5680  yyextra->baseProt=Public;
5681  yyextra->baseVirt=Normal;
5682  yyextra->baseName.resize(0);
5683  BEGIN( BasesProt ) ;
5684  }
5685  else if (yyextra->insideCS && qstrcmp(yytext,"where")==0) // C# type constraint
5686  {
5687  yyextra->current->typeConstr.clear();
5688  yyextra->current->typeConstr.push_back(Argument());
5689  yyextra->lastCSConstraint = YY_START;
5690  BEGIN( CSConstraintName );
5691  }
5692  else if (yyextra->insideCli && qstrcmp(yytext,"abstract")==0)
5693  {
5694  yyextra->current->spec|=Entry::Abstract;
5695  }
5696  else if (yyextra->insideCli && qstrcmp(yytext,"sealed")==0)
5697  {
5698  yyextra->current->spec|=Entry::Sealed;
5699  }
5700  else if (qstrcmp(yytext,"final")==0)
5701  {
5702  yyextra->current->spec|=Entry::Final;
5703  }
5704  else
5705  {
5706  if (yyextra->current->section == Entry::ENUM_SEC)
5707  { // found "enum a b" -> variable
5708  yyextra->current->section = Entry::VARIABLE_SEC ;
5709  }
5710  yyextra->current->type += ' ' ;
5711  yyextra->current->type += yyextra->current->name ;
5712  yyextra->current->name = yytext ;
5713 
5714  if (nameIsOperator(yyextra->current->name))
5715  {
5716  BEGIN( Operator );
5717  }
5718  }
5719  }
5720 <ClassVar>[(\[] {
5721  if (yyextra->insideObjC && *yytext=='(') // class category
5722  {
5723  yyextra->current->name+='(';
5724  //if (yyextra->current->section!=Entry::OBJCIMPL_SEC)
5725  //{
5726  yyextra->current->spec|=Entry::Category;
5727  //}
5728  BEGIN( ClassCategory );
5729  }
5730  else
5731  {
5732  // probably a function anyway
5733  unput(*yytext);
5734  BEGIN( FindMembers );
5735  }
5736  }
5737 <CSConstraintType,CSConstraintName>{CCS}{CCE} { /* empty comment */ }
5738 <CSConstraintType,CSConstraintName>({CCS}[*!]|{CPPC}[/!])("<"?) { // special comment
5739  yyextra->fullArgString.resize(0);
5740  yyextra->lastCopyArgChar='#'; // end marker
5741  yyextra->lastCommentInArgContext=YY_START;
5742  if (yytext[1]=='/')
5743  BEGIN( CopyArgCommentLine );
5744  else
5745  BEGIN( CopyArgComment );
5746  }
5747 <CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block
5748  yyextra->current->typeConstr.back().docs = yyextra->fullArgString;
5749  }
5750 <CSConstraintType>"{" { // end of type constraint reached
5751  // parse documentation of the constraints
5752  handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
5753  unput('{');
5754  BEGIN( yyextra->lastCSConstraint );
5755  }
5756 <CSConstraintType,CSConstraintName>";" {
5757  handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
5758  unput(';');
5759  BEGIN( yyextra->lastCSConstraint );
5760  }
5761 <CSConstraintName>":" {
5762  BEGIN( CSConstraintType );
5763  }
5764 <CSConstraintName>{ID} {
5765  // parameter name
5766  yyextra->current->typeConstr.back().name=yytext;
5767  }
5768 <CSConstraintType>"where" { // another constraint for a different param
5769  yyextra->current->typeConstr.push_back(Argument());
5770  BEGIN( CSConstraintName );
5771  }
5772 <CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
5773  if (yyextra->current->typeConstr.back().type.isEmpty())
5774  // first type constraint for this parameter
5775  {
5776  yyextra->current->typeConstr.back().type=yytext;
5777  }
5778  else // new type constraint for same parameter
5779  {
5780  QCString name = yyextra->current->typeConstr.back().name;
5781  yyextra->current->typeConstr.push_back(Argument());
5782  yyextra->current->typeConstr.back().name=name;
5783  yyextra->current->typeConstr.back().type=yytext;
5784  }
5785  }
5786 <CSConstraintName,CSConstraintType>\n {
5787  lineCount(yyscanner);
5788  }
5789 <CSConstraintName,CSConstraintType>. {
5790  }
5791 <ClassCategory>{ID} {
5792  yyextra->current->name+=yytext;
5793  }
5794 <ClassCategory>")"/{BN}*"{" {
5795  yyextra->current->name+=')';
5796  BEGIN( ClassVar );
5797  }
5798 <ClassCategory>")"/{BN}*"<" {
5799  yyextra->current->name+=')';
5800  BEGIN( ObjCProtocolList );
5801  }
5802 <ClassCategory>")" {
5803  yyextra->current->name+=')';
5804  if ((yyextra->current->section & Entry::Protocol) ||
5805  yyextra->current->section == Entry::OBJCIMPL_SEC)
5806  {
5807  unput('{'); // fake start of body
5808  }
5809  else // category has no variables so push back an empty body
5810  {
5811  unput('}');
5812  unput('{');
5813  }
5814  BEGIN( ClassVar );
5815  }
5816 <ClassVar>":" {
5817  if (yyextra->current->section==Entry::VARIABLE_SEC) // enum A B:2, see bug 748208
5818  {
5819  yyextra->current->bitfields+=":";
5820  yyextra->current->args.resize(0);
5821  BEGIN(BitFields);
5822  }
5823  else if (yyextra->current->section==Entry::ENUM_SEC) // enum E:2, see bug 313527,
5824  // or C++11 style enum: 'E : unsigned int {...}'
5825  {
5826  yyextra->current->args.resize(0);
5827  BEGIN(EnumBaseType);
5828  }
5829  else
5830  {
5831  yyextra->current->type.resize(0);
5832  if ((yyextra->current->spec & Entry::Interface) ||
5833  (yyextra->current->spec & Entry::Struct) ||
5834  (yyextra->current->spec & Entry::Ref) ||
5835  (yyextra->current->spec & Entry::Value) ||
5836  yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL
5837  )
5838  yyextra->baseProt=Public;
5839  else
5840  yyextra->baseProt=Private;
5841  yyextra->baseVirt=Normal;
5842  yyextra->baseName.resize(0);
5843  BEGIN( BasesProt ) ;
5844  }
5845  }
5846 <ClassVar>[;=*&] {
5847  unput(*yytext);
5848  if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
5849  {
5850  yyextra->current->type.prepend("typedef");
5851  }
5852  if ((yytext[0]=='*' || yytext[0]=='&') &&
5853  yyextra->current->section == Entry::ENUM_SEC)
5854  { // found "enum a *b" -> variable
5855  yyextra->current->section = Entry::VARIABLE_SEC ;
5856  }
5857  BEGIN( FindMembers );
5858  }
5859 <Bases,ClassVar>{CPPC}"/"/[^/] {
5860  if (!yyextra->insideObjC)
5861  {
5862  REJECT;
5863  }
5864  else
5865  {
5866  lineCount(yyscanner);
5867  yyextra->current->program << yytext;
5868  yyextra->current->fileName = yyextra->yyFileName ;
5869  yyextra->current->startLine = yyextra->yyLineNr ;
5870  yyextra->current->startColumn = yyextra->yyColNr;
5871  yyextra->curlyCount=0;
5872  BEGIN( ReadBodyIntf );
5873  }
5874  }
5875 <Bases,ClassVar>({CPPC}{B}*)?{CCS}"*"/{NCOMM} |
5876 <Bases,ClassVar>({CPPC}{B}*)?{CCS}"!" |
5877 <Bases,ClassVar>{CPPC}"!" |
5878 <Bases,ClassVar>[\-+]{BN}* {
5879  if (!yyextra->insideObjC)
5880  {
5881  REJECT;
5882  }
5883  else
5884  {
5885  lineCount(yyscanner);
5886  yyextra->current->program << yytext;
5887  yyextra->current->fileName = yyextra->yyFileName ;
5888  yyextra->current->startLine = yyextra->yyLineNr ;
5889  yyextra->current->startColumn = yyextra->yyColNr;
5890  yyextra->curlyCount=0;
5891  BEGIN( ReadBodyIntf );
5892  }
5893  }
5894 <CompoundName,ClassVar>{B}*"{"{B}* {
5895  yyextra->current->program.str(std::string());
5896  yyextra->current->fileName = yyextra->yyFileName ;
5897  yyextra->current->bodyLine = yyextra->yyLineNr;
5898  yyextra->current->bodyColumn = yyextra->yyColNr;
5899  yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
5900  if (yyextra->current->name.isEmpty() && !yyextra->isTypedef) // anonymous compound
5901  {
5902  if (yyextra->current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces
5903  {
5904  if (Config_getBool(EXTRACT_ANON_NSPACES)) // use visible name
5905  {
5906  yyextra->current->name="anonymous_namespace{"+stripPath(yyextra->current->fileName)+"}";
5907  }
5908  else // use invisible name
5909  {
5910  yyextra->current->name.sprintf("@%d",anonNSCount.load());
5911  }
5912  }
5913  else
5914  {
5915  yyextra->current->name.sprintf("@%d",anonCount++);
5916  }
5917  }
5918  yyextra->curlyCount=0;
5919  if (yyextra->current_root && // not a nested struct yyextra->inside an @interface section
5920  !(yyextra->current_root->spec & Entry::Interface) &&
5921  ((yyextra->current->spec & (Entry::Interface | Entry::Protocol | Entry::Category) ||
5922  yyextra->current->section==Entry::OBJCIMPL_SEC)
5923  ) &&
5924  yyextra->insideObjC
5925  )
5926  { // ObjC body that ends with @end
5927  BEGIN( ReadBodyIntf );
5928  }
5929  else if (yyextra->current->section==Entry::NAMESPACE_SEC)
5930  { // namespace body
5931  BEGIN( ReadNSBody );
5932  }
5933  else
5934  { // class body
5935  BEGIN( ReadBody ) ;
5936  }
5937  }
5938 <BasesProt>"virtual"{BN}+ { lineCount(yyscanner); yyextra->baseVirt = Virtual; }
5939 <BasesProt>"public"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Public; }
5940 <BasesProt>"protected"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protected; }
5941 <BasesProt>"internal"{BN}+ { if (!yyextra->insideCli) REJECT ; lineCount(yyscanner); yyextra->baseProt = Package; }
5942 <BasesProt>"private"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Private; }
5943 <BasesProt>{BN} { lineCount(yyscanner); }
5944 <BasesProt>. { unput(*yytext); BEGIN(Bases); }
5945 <Bases>("\\")?({ID}"\\")*{ID} { // PHP namespace token, not sure if interspacing is allowed but it gives problems (see bug 640847)
5946  if (!yyextra->insidePHP)
5947  {
5948  REJECT;
5949  }
5950  else // PHP base class of the form \Ns\Cl or Ns\Cl
5951  {
5952  lineCount(yyscanner);
5953  QCString bn=yytext;
5954  bn = substitute(bn,"\\","::");
5955  yyextra->baseName += bn;
5956  yyextra->current->args += ' ';
5957  yyextra->current->args += yytext;
5958  }
5959  }
5960 <Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} {
5961  lineCount(yyscanner);
5962  QCString baseScope = yytext;
5963  if (yyextra->insideCS && baseScope.stripWhiteSpace()=="where")
5964  {
5965  // type constraint for a class
5966  yyextra->current->typeConstr.clear();
5967  yyextra->current->typeConstr.push_back(Argument());
5968  yyextra->lastCSConstraint = YY_START;
5969  BEGIN( CSConstraintName );
5970  }
5971  else
5972  {
5973  yyextra->baseName+=yytext;
5974  yyextra->current->args += ' ';
5975  yyextra->current->args += yytext;
5976  }
5977  }
5978 <Bases>{BN}*{ID}("."{ID})* { // Java style class
5979  QCString name = substitute(yytext,".","::");
5980  yyextra->baseName += name;
5981  yyextra->current->args += ' ';
5982  yyextra->current->args += name;
5983  }
5984 <ClassVar,Bases>\n/{BN}*[^{, \t\n] {
5985  if (!yyextra->insideObjC)
5986  {
5987  REJECT;
5988  }
5989  else
5990  {
5991  lineCount(yyscanner);
5992  unput('{');
5993  }
5994  }
5995 <ClassVar,Bases>"@end" { // empty ObjC interface
5996  unput('d'); // insert fake body: {}@end
5997  unput('n');
5998  unput('e');
5999  unput('@');
6000  unput('}');
6001  unput('{');
6002  }
6003 <ClassVar>"<" { yyextra->current->name += *yytext;
6004  yyextra->sharpCount=1;
6005  yyextra->roundCount=0;
6006  yyextra->lastSkipSharpContext = YY_START;
6007  yyextra->specName = &yyextra->current->name;
6008  BEGIN ( Specialization );
6009  }
6010 <Bases>{BN}*"<" {
6011  lineCount(yyscanner);
6012  yyextra->sharpCount=1;
6013  yyextra->roundCount=0;
6014  yyextra->lastSkipSharpContext = YY_START;
6015  if (yyextra->insideObjC) // start of protocol list
6016  {
6017  unput(',');
6018  }
6019  else // template specialization
6020  {
6021  //if (yyextra->insideCS) // generic
6022  //{
6023  // yyextra->baseName+="-g";
6024  //}
6025  yyextra->templateStr = yytext;
6026  yyextra->specName = &yyextra->templateStr;
6027  BEGIN ( Specialization );
6028  }
6029  }
6030 <Specialization>"<" { *yyextra->specName += *yytext;
6031  if (yyextra->roundCount==0) yyextra->sharpCount++;
6032  }
6033 <Specialization>">" {
6034  *yyextra->specName += *yytext;
6035  if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
6036  {
6037  yyextra->baseName+=removeRedundantWhiteSpace(*yyextra->specName);
6038  BEGIN(yyextra->lastSkipSharpContext);
6039  }
6040  }
6041 <Specialization>{BN}+ { lineCount(yyscanner); *yyextra->specName +=' '; }
6042 <Specialization>"<<" { *yyextra->specName += yytext; }
6043 <Specialization>">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template...
6044  unput('>');
6045  unput(' ');
6046  unput('>');
6047  }
6048 <Specialization>">>" {
6049  if (yyextra->insideCS) // for C# >> ends a nested template
6050  {
6051  REJECT;
6052  }
6053  else // for C++ >> is a bitshift
6054  // operator and > > would end
6055  // a nested template.
6056  // We require the bitshift to be enclosed in braces.
6057  // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
6058  {
6059  if (yyextra->roundCount>0)
6060  {
6061  *yyextra->specName += yytext;
6062  }
6063  else
6064  {
6065  unput('>');
6066  unput(' ');
6067  unput('>');
6068  }
6069  }
6070  }
6071 <Specialization>"typename"{BN}+ { lineCount(yyscanner); }
6072 <Specialization>"(" { *yyextra->specName += *yytext; yyextra->roundCount++; }
6073 <Specialization>")" { *yyextra->specName += *yytext; yyextra->roundCount--; }
6074 
6075 <Specialization>"\\\\" { *yyextra->specName += *yytext;}
6076 <Specialization>"\\'" { *yyextra->specName += *yytext;}
6077 <Specialization>"\\\"" { *yyextra->specName += *yytext;}
6078 <Specialization>"'" { *yyextra->specName += *yytext;BEGIN(SpecializationSingleQuote);}
6079 <Specialization>"\"" { *yyextra->specName += *yytext;BEGIN(SpecializationDoubleQuote);}
6080 <SpecializationSingleQuote,SpecializationDoubleQuote>"\\\\" { *yyextra->specName += *yytext;}
6081 <SpecializationSingleQuote>"\\'" { *yyextra->specName += *yytext;}
6082 <SpecializationSingleQuote>"'" { *yyextra->specName += *yytext; BEGIN(Specialization);}
6083 <SpecializationDoubleQuote>"\\\"" { *yyextra->specName += *yytext;}
6084 <SpecializationDoubleQuote>"\"" { *yyextra->specName += *yytext; BEGIN(Specialization);}
6085 <SpecializationSingleQuote,SpecializationDoubleQuote>. { *yyextra->specName += *yytext;}
6086 
6087 <Specialization>. {
6088  *yyextra->specName += *yytext;
6089  }
6090 <SkipRound>"(" { ++yyextra->roundCount; }
6091 <SkipRound>")" { if (--yyextra->roundCount<0)
6092  BEGIN ( yyextra->lastSkipRoundContext );
6093  }
6094 <SkipRound>\" {
6095  yyextra->lastStringContext=SkipRound;
6096  BEGIN(SkipString);
6097  }
6098 <Bases>","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount(yyscanner);
6099  if (yyextra->insideProtocolList)
6100  {
6101  yyextra->baseName+="-p";
6102  }
6103  else
6104  {
6105  yyextra->current->args += ',' ;
6106  }
6107  yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6108  if (!yyextra->baseName.isEmpty())
6109  {
6110  yyextra->current->extends.push_back(
6111  BaseInfo(yyextra->baseName,yyextra->baseProt,yyextra->baseVirt)
6112  );
6113  }
6114  if ((yyextra->current->spec & (Entry::Interface|Entry::Struct)) ||
6115  yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS ||
6116  yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL || yyextra->insideSlice)
6117  {
6118  yyextra->baseProt=Public;
6119  }
6120  else
6121  {
6122  yyextra->baseProt=Private;
6123  }
6124  yyextra->baseVirt=Normal;
6125  yyextra->baseName.resize(0);
6126  if (*yytext=='>')
6127  { // end of a ObjC protocol list
6128  yyextra->insideProtocolList=FALSE;
6129  if (yyleng==1)
6130  {
6131  unput('{'); // dummy start body
6132  }
6133  else
6134  {
6135  yyless(1);
6136  }
6137  }
6138  else
6139  {
6140  if (*yytext==',' && yyextra->insideObjC) // Begin of protocol list
6141  {
6142  yyextra->insideProtocolList=TRUE;
6143  }
6144  BEGIN(BasesProt);
6145  }
6146  }
6147 <Bases>{B}*"{"{B}* {
6148  yyextra->current->program.str(std::string());
6149  yyextra->current->fileName = yyextra->yyFileName ;
6150  yyextra->current->bodyLine = yyextra->yyLineNr;
6151  yyextra->current->bodyColumn = yyextra->yyColNr;
6152  yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6153  if (!yyextra->baseName.isEmpty())
6154  yyextra->current->extends.push_back(
6155  BaseInfo(yyextra->baseName,yyextra->baseProt,yyextra->baseVirt)
6156  );
6157  yyextra->curlyCount=0;
6158  if (yyextra->insideObjC)
6159  {
6160  BEGIN( ReadBodyIntf );
6161  }
6162  else
6163  {
6164  BEGIN( ReadBody ) ;
6165  }
6166  }
6167 <SkipUnionSwitch>{B}*"(" {
6168  yyextra->roundCount++;
6169  }
6170 <SkipUnionSwitch>")" {
6171  if (--yyextra->roundCount==0)
6172  {
6173  BEGIN(ClassVar);
6174  }
6175  }
6176 <SkipUnionSwitch>\n { lineCount(yyscanner); }
6177 <SkipUnionSwitch>.
6178 <Comment>{BN}+ { yyextra->current->program << yytext ;
6179  lineCount(yyscanner) ;
6180  }
6181 <Comment>{CCS} { yyextra->current->program << yytext ; }
6182 <Comment>{CPPC} { yyextra->current->program << yytext ; }
6183 <Comment>{CMD}("code"|"verbatim") {
6184  yyextra->insideCode=TRUE;
6185  yyextra->current->program << yytext ;
6186  }
6187 <Comment>{CMD}("endcode"|"endverbatim") {
6188  yyextra->insideCode=FALSE;
6189  yyextra->current->program << yytext ;
6190  }
6191 <Comment>[^ \.\t\r\n\/\*]+ { yyextra->current->program << yytext ; }
6192 <Comment>{CCE} { yyextra->current->program << yytext ;
6193  if (!yyextra->insideCode) BEGIN( yyextra->lastContext ) ;
6194  }
6195 <Comment>. { yyextra->current->program << *yytext ; }
6196 
6197 <FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,SkipC11Inits,SkipC11Attribute,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"!" {
6198  //printf("Start doc block at %d\n",yyextra->yyLineNr);
6199  if (!yyextra->current->doc.isEmpty())
6200  {
6201  yyextra->current->doc+="\n\n";
6202  }
6203  else
6204  {
6205  yyextra->current->docLine = yyextra->yyLineNr;
6206  yyextra->current->docFile = yyextra->yyFileName;
6207  }
6208 
6209  yyextra->lastDocContext = YY_START;
6210  if (yyextra->current_root->section & Entry::SCOPE_MASK)
6211  {
6212  yyextra->current->inside = yyextra->current_root->name+"::";
6213  }
6214  yyextra->docBlockContext = YY_START;
6215  yyextra->docBlockInBody = YY_START==SkipCurly;
6216  yyextra->docBlockAutoBrief = Config_getBool(QT_AUTOBRIEF);
6217 
6218  QCString indent;
6219  indent.fill(' ',computeIndent(yytext,yyextra->column));
6220  yyextra->docBlock.str(indent.str());
6221 
6222  if (yyextra->docBlockAutoBrief)
6223  {
6224  yyextra->current->briefLine = yyextra->yyLineNr;
6225  yyextra->current->briefFile = yyextra->yyFileName;
6226  }
6227  startCommentBlock(yyscanner,FALSE);
6228  BEGIN( DocBlock );
6229  }
6230 <FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>{CCS}"*"[*]+{BL} {
6231  bool javadocBanner = Config_getBool(JAVADOC_BANNER);
6232  lineCount(yyscanner);
6233 
6234  if( javadocBanner )
6235  {
6236  yyextra->lastDocContext = YY_START;
6237 
6238  //printf("Found comment banner at %s:%d\n",yyextra->yyFileName,yyextra->yyLineNr);
6239  if (yyextra->current_root->section & Entry::SCOPE_MASK)
6240  {
6241  yyextra->current->inside = yyextra->current_root->name+"::";
6242  }
6243  yyextra->current->docLine = yyextra->yyLineNr;
6244  yyextra->current->docFile = yyextra->yyFileName;
6245  yyextra->docBlockContext = YY_START;
6246  yyextra->docBlockInBody = YY_START==SkipCurly;
6247  bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
6248  yyextra->docBlockAutoBrief = javadocAutoBrief;
6249 
6250  QCString indent;
6251  indent.fill(' ',computeIndent(yytext,yyextra->column));
6252  yyextra->docBlock.str(indent.str());
6253 
6254  if (yyextra->docBlockAutoBrief)
6255  {
6256  yyextra->current->briefLine = yyextra->yyLineNr;
6257  yyextra->current->briefFile = yyextra->yyFileName;
6258  }
6259  startCommentBlock(yyscanner,FALSE);
6260  BEGIN( DocBlock );
6261  }
6262  else
6263  {
6264  yyextra->current->program << yytext ;
6265  yyextra->lastContext = YY_START ;
6266  BEGIN( Comment ) ;
6267  }
6268  }
6269 <FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
6270  yyextra->lastDocContext = YY_START;
6271 
6272  //printf("Found comment block at %s:%d\n",yyextra->yyFileName,yyextra->yyLineNr);
6273  if (yyextra->current_root->section & Entry::SCOPE_MASK)
6274  {
6275  yyextra->current->inside = yyextra->current_root->name+"::";
6276  }
6277  yyextra->current->docLine = yyextra->yyLineNr;
6278  yyextra->current->docFile = yyextra->yyFileName;
6279  yyextra->docBlockContext = YY_START;
6280  yyextra->docBlockInBody = YY_START==SkipCurly;
6281  bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
6282  yyextra->docBlockAutoBrief = javadocAutoBrief;
6283 
6284  QCString indent;
6285  indent.fill(' ',computeIndent(yytext,yyextra->column));
6286  yyextra->docBlock.str(indent.str());
6287 
6288  if (yyextra->docBlockAutoBrief)
6289  {
6290  yyextra->current->briefLine = yyextra->yyLineNr;
6291  yyextra->current->briefFile = yyextra->yyFileName;
6292  }
6293  startCommentBlock(yyscanner,FALSE);
6294  BEGIN( DocBlock );
6295  }
6296 <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"!" {
6297  yyextra->lastDocContext = YY_START;
6298  if (yyextra->current_root->section & Entry::SCOPE_MASK)
6299  {
6300  yyextra->current->inside = yyextra->current_root->name+"::";
6301  }
6302  yyextra->docBlockContext = YY_START;
6303  yyextra->docBlockInBody = YY_START==SkipCurly;
6304  yyextra->docBlockAutoBrief = FALSE;
6305 
6306  QCString indent;
6307  indent.fill(' ',computeIndent(yytext,yyextra->column));
6308  yyextra->docBlock.str(indent.str());
6309 
6310  startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
6311  BEGIN( DocLine );
6312  }
6313 <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"/"/[^/] {
6314  yyextra->lastDocContext = YY_START;
6315  if (yyextra->current_root->section & Entry::SCOPE_MASK)
6316  {
6317  yyextra->current->inside = yyextra->current_root->name+"::";
6318  }
6319  yyextra->docBlockContext = YY_START;
6320  yyextra->docBlockInBody = YY_START==SkipCurly;
6321  yyextra->docBlockAutoBrief = FALSE;
6322  QCString indent;
6323  indent.fill(' ',computeIndent(yytext,yyextra->column));
6324  yyextra->docBlock.str(indent.str());
6325  startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
6326  BEGIN( DocLine );
6327  }
6328 <FindMembers>"extern"{BN}*"\""[^\"]+"\""{BN}*("{")? {
6329  lineCount(yyscanner);
6330  yyextra->externLinkage=TRUE;
6331  }
6332 <FindMembers>"{" {
6333  if (yyextra->externLinkage)
6334  {
6335  yyextra->externLinkage=FALSE;
6336  }
6337  else if (yyextra->insideCS &&
6338  !yyextra->current->name.isEmpty() &&
6339  !yyextra->current->type.isEmpty())
6340  {
6341  if (containsWord(yyextra->current->type,"event")) // event
6342  {
6343  yyextra->current->mtype = yyextra->mtype = Event;
6344  }
6345  else // property
6346  {
6347  yyextra->current->mtype = yyextra->mtype = Property;
6348  }
6349  yyextra->current->bodyLine = yyextra->yyLineNr;
6350  yyextra->current->bodyColumn = yyextra->yyColNr;
6351  yyextra->curlyCount=0;
6352  BEGIN( CSAccessorDecl );
6353  }
6354  else if (yyextra->insideIDL && (yyextra->current->spec & Entry::Attribute))
6355  {
6356  // UNO IDL: attributes may have setter and getter
6357  // exception specifications
6358  yyextra->current->exception = " {";
6359  BEGIN(UNOIDLAttributeBlock);
6360  }
6361  else
6362  {
6363  if ((yyextra->insideJava || yyextra->insideCS || yyextra->insideD) &&
6364  yyextra->current->name.isEmpty()
6365  )
6366  {
6367  // static Java initializer
6368  yyextra->needsSemi = FALSE;
6369  if (yyextra->current->stat)
6370  {
6371  yyextra->current->name="[static initializer]";
6372  yyextra->current->type.resize(0);
6373  }
6374  else
6375  {
6376  yyextra->current->name="[instance initializer]";
6377  }
6378  unput(*yytext);
6379  BEGIN( Function );
6380  }
6381  else
6382  {
6383  // pre C++11 code -> ignore the initializer
6384  //yyextra->needsSemi = TRUE;
6385  //yyextra->current->type.resize(0);
6386  //yyextra->current->name.resize(0);
6387  //yyextra->current->args.resize(0);
6388  //yyextra->current->argList.clear();
6389  //yyextra->curlyCount=0;
6390  //BEGIN( SkipCurlyBlock );
6391 
6392  // C++11 style initializer list
6393  yyextra->current->bodyLine = yyextra->yyLineNr;
6394  yyextra->current->bodyColumn = yyextra->yyColNr;
6395  yyextra->current->initializer.str(yytext);
6396  yyextra->lastInitializerContext = YY_START;
6397  yyextra->initBracketCount=1;
6398  BEGIN(ReadInitializer);
6399  }
6400  }
6401  }
6402 <CSAccessorDecl>"{" { yyextra->curlyCount++; }
6403 <CSAccessorDecl>"}"{B}*"=" {
6404  // fall back to next rule if it's not the right bracket
6405  if (yyextra->curlyCount != 0) REJECT;
6406  yyextra->current->initializer.str("=");
6407  yyextra->current->endBodyLine=yyextra->yyLineNr;
6408  yyextra->lastInitializerContext = FindMembers;
6409  BEGIN(ReadInitializer);
6410  }
6411 <CSAccessorDecl>"}" {
6412  if (yyextra->curlyCount)
6413  {
6414  yyextra->curlyCount--;
6415  }
6416  else
6417  {
6418  yyextra->mtype = Method;
6419  yyextra->virt = Normal;
6420  // not really important, but while we are at it
6421  yyextra->current->endBodyLine=yyextra->yyLineNr;
6422  unput(';');
6423  BEGIN(FindMembers);
6424  }
6425  }
6426 <CSAccessorDecl>"private "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::PrivateSettable; }
6427 <CSAccessorDecl>"protected "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::ProtectedSettable; }
6428 <CSAccessorDecl>"private "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::PrivateGettable; }
6429 <CSAccessorDecl>"protected "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::ProtectedGettable; }
6430 <CSAccessorDecl>"set" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::Settable; }
6431 <CSAccessorDecl>"get" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::Gettable; }
6432 <CSAccessorDecl>"add" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::Addable; }
6433 <CSAccessorDecl>"remove" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::Removable; }
6434 <CSAccessorDecl>"raise" { if (yyextra->curlyCount==0) yyextra->current->spec |= Entry::Raisable; }
6435 <CSAccessorDecl>"\"" { BEGIN(CSString);}
6436 <CSAccessorDecl>"." {}
6437 <CSAccessorDecl>\n { lineCount(yyscanner); }
6438 <CSString>"\"" { BEGIN(CSAccessorDecl);}
6439 <CSString>{CPPC} {} // Otherwise the rule <*>"//" will kick in
6440 <CSString>{CCS} {} // Otherwise the rule <*>"/*" will kick in
6441 <CSString>\n { lineCount(yyscanner); }
6442 <CSString>"." {}
6443 
6444  /* ---- Slice-specific rules ------ */
6445 
6446 <SliceSequence>{SCOPENAME} {
6447  if (yyextra->current->spec&Entry::Local)
6448  {
6449  yyextra->current->type = "local ";
6450  }
6451  yyextra->current->type += "sequence<";
6452  yyextra->current->type += yytext;
6453  yyextra->current->type += ">";
6454  }
6455 
6456 <SliceSequence>{BN}*">"{BN}* {
6457  lineCount(yyscanner);
6458  BEGIN(SliceSequenceName);
6459  }
6460 
6461 <SliceSequenceName>{ID}{BN}* {
6462  lineCount(yyscanner);
6463  yyextra->current->name = yytext ;
6464  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6465  }
6466 
6467 <SliceSequenceName>";" {
6468  yyextra->current->section = Entry::VARIABLE_SEC;
6469  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6470  initEntry(yyscanner);
6471  BEGIN(FindMembers);
6472  }
6473 
6474 <SliceDictionary>{SCOPENAME}{BN}*","{BN}*{SCOPENAME} {
6475  lineCount(yyscanner);
6476  if (yyextra->current->spec&Entry::Local)
6477  {
6478  yyextra->current->type = "local ";
6479  }
6480  yyextra->current->type += "dictionary<";
6481  yyextra->current->type += yytext;
6482  yyextra->current->type += ">";
6483  yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
6484  }
6485 
6486 <SliceDictionary>{BN}*">"{BN}* {
6487  lineCount(yyscanner);
6488  BEGIN(SliceDictionaryName);
6489  }
6490 
6491 <SliceDictionaryName>{ID}{BN}* {
6492  lineCount(yyscanner);
6493  yyextra->current->name = yytext ;
6494  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6495  }
6496 
6497 <SliceDictionaryName>";" {
6498  yyextra->current->section = Entry::VARIABLE_SEC;
6499  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6500  initEntry(yyscanner);
6501  BEGIN(FindMembers);
6502  }
6503 
6504  /**********************************************************************************/
6505  /******************** Documentation block related rules ***************************/
6506  /**********************************************************************************/
6507 
6508  /* ---- Single line comments ------ */
6509 <DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
6510  int markerLen = yytext[yyleng-1]=='<' ? 4 : 3;
6511  yyextra->docBlock << std::string(yytext).substr(0,yyleng-markerLen);
6512  lineCount(yyscanner);
6513  }
6514 <DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
6515  handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
6516  BEGIN( yyextra->docBlockContext );
6517  }
6518 <DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
6519  yyextra->docBlock << yytext;
6520  handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
6521  BEGIN( yyextra->docBlockContext );
6522  }
6523 <DocLine>{NONLopt}/"\n" { // whole line
6524  yyextra->docBlock << yytext;
6525  handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
6526  BEGIN( yyextra->docBlockContext );
6527  }
6528 
6529  /* ---- Comments blocks ------ */
6530 
6531 <DocBlock>"*"*{CCE} { // end of comment block
6532  handleCommentBlock(yyscanner,yyextra->docBlock.str(),FALSE);
6533  BEGIN(yyextra->docBlockContext);
6534  }
6535 <DocBlock>^{B}*"*"+/[^/] {
6536 
6537  QCString indent;
6538  indent.fill(' ',computeIndent(yytext,yyextra->column));
6539  yyextra->docBlock << indent;
6540  }
6541 <DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
6542  QCString indent;
6543  indent.fill(' ',computeIndent(yytext,yyextra->column));
6544  yyextra->docBlock << indent;
6545  }
6546 <DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
6547  }
6548 <DocBlock>{CPPC} { // slashes in the middle of a comment block
6549  yyextra->docBlock << yytext;
6550  }
6551 <DocBlock>{CCS} { // start of a new comment in the
6552  // middle of a comment block
6553  yyextra->docBlock << yytext;
6554  }
6555 <DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
6556  yyextra->docBlock << yytext;
6557  }
6558 <DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
6559  yyextra->docBlock << yytext;
6560  yyextra->docBlockName=&yytext[1];
6561  if (yyextra->docBlockName.at(1)=='[')
6562  {
6563  yyextra->docBlockName.at(1)=']';
6564  }
6565  if (yyextra->docBlockName.at(1)=='{')
6566  {
6567  yyextra->docBlockName.at(1)='}';
6568  }
6569  if (yyextra->docBlockName.at(1)=='(')
6570  {
6571  yyextra->docBlockName.at(1)=')';
6572  }
6573  yyextra->fencedSize=0;
6574  yyextra->nestedComment=FALSE;
6575  BEGIN(DocCopyBlock);
6576  }
6577 <DocBlock>{B}*"<"{PRE}">" {
6578  yyextra->docBlock << yytext;
6579  yyextra->docBlockName="<pre>";
6580  yyextra->fencedSize=0;
6581  yyextra->nestedComment=FALSE;
6582  BEGIN(DocCopyBlock);
6583  }
6584 <DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
6585  yyextra->docBlock << yytext;
6586  yyextra->docBlockName="uml";
6587  yyextra->fencedSize=0;
6588  yyextra->nestedComment=FALSE;
6589  BEGIN(DocCopyBlock);
6590  }
6591 <DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
6592  yyextra->docBlock << yytext;
6593  yyextra->docBlockName=&yytext[1];
6594  yyextra->fencedSize=0;
6595  yyextra->nestedComment=FALSE;
6596  BEGIN(DocCopyBlock);
6597  }
6598 <DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
6599 
6600  QCString pat = substitute(yytext,"*"," ");
6601  yyextra->docBlock << pat;
6602  yyextra->docBlockName="~~~";
6603  yyextra->fencedSize=pat.stripWhiteSpace().length();
6604  yyextra->nestedComment=FALSE;
6605  BEGIN(DocCopyBlock);
6606  }
6607 <DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
6608 <DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
6609 <DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
6610  QCString pat = substitute(yytext,"*"," ");
6611  yyextra->docBlock << pat;
6612  yyextra->docBlockName="```";
6613  yyextra->fencedSize=pat.stripWhiteSpace().length();
6614  yyextra->nestedComment=FALSE;
6615  BEGIN(DocCopyBlock);
6616  }
6617 <DocBlock>{B}*"<code>" {
6618  if (yyextra->insideCS)
6619  {
6620  yyextra->docBlock << yytext;
6621  yyextra->docBlockName="<code>";
6622  yyextra->nestedComment=FALSE;
6623  BEGIN(DocCopyBlock);
6624  }
6625  else
6626  {
6627  REJECT;
6628  }
6629  }
6630 <DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
6631  yyextra->docBlock << yytext;
6632  }
6633 <DocBlock>\n { // newline
6634  lineCount(yyscanner);
6635  yyextra->docBlock << *yytext;
6636  }
6637 <DocBlock>. { // command block
6638  yyextra->docBlock << *yytext;
6639  }
6640 
6641  /* ---- Copy verbatim sections ------ */
6642 
6643 <DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
6644  yyextra->docBlock << yytext;
6645  if (yyextra->docBlockName=="<pre>")
6646  {
6647  BEGIN(DocBlock);
6648  }
6649  }
6650 <DocCopyBlock>"</"{CODE}">" { // end of a <code> block
6651  yyextra->docBlock << yytext;
6652  if (yyextra->docBlockName=="<code>")
6653  {
6654  BEGIN(DocBlock);
6655  }
6656  }
6657 <DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
6658  yyextra->docBlock << yytext;
6659  if (yyextra->docBlockName==&yytext[1])
6660  {
6661  BEGIN(DocBlock);
6662  }
6663  }
6664 <DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
6665  yyextra->docBlock << yytext;
6666  if (&yytext[4]==yyextra->docBlockName)
6667  {
6668  BEGIN(DocBlock);
6669  }
6670  }
6671 <DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
6672  if (yyextra->docBlockName=="verbatim")
6673  {
6674  REJECT;
6675  }
6676  else if (yyextra->docBlockName=="code")
6677  {
6678  REJECT;
6679  }
6680  else
6681  {
6682  QCString indent;
6683  indent.fill(' ',computeIndent(yytext,0));
6684  yyextra->docBlock << indent;
6685  }
6686  }
6687 <DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
6688  if (yyextra->docBlockName=="code")
6689  {
6690  QCString indent;
6691  indent.fill(' ',computeIndent(yytext,0));
6692  yyextra->docBlock << indent;
6693  }
6694  else
6695  {
6696  REJECT;
6697  }
6698  }
6699 <DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
6700  if (yyextra->docBlockName=="code")
6701  {
6702  QCString indent;
6703  indent.fill(' ',computeIndent(yytext,-1));
6704  yyextra->docBlock << indent+"*";
6705  }
6706  else
6707  {
6708  REJECT;
6709  }
6710  }
6711 <DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
6712  if (yyextra->docBlockName=="code")
6713  {
6714  QCString indent;
6715  if (yyextra->nestedComment) // keep * it is part of the code
6716  {
6717  indent.fill(' ',computeIndent(yytext,-1));
6718  yyextra->docBlock << indent+"*";
6719  }
6720  else // remove * it is part of the comment block
6721  {
6722  indent.fill(' ',computeIndent(yytext,0));
6723  yyextra->docBlock << indent;
6724  }
6725  }
6726  else
6727  {
6728  REJECT;
6729  }
6730  }
6731 <DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
6732  QCString pat = substitute(yytext,"*"," ");
6733  yyextra->docBlock << pat;
6734  if (yyextra->fencedSize==pat.stripWhiteSpace().length())
6735  {
6736  BEGIN(DocBlock);
6737  }
6738  }
6739 <DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
6740  QCString pat = substitute(yytext,"*"," ");
6741  yyextra->docBlock << pat;
6742  if (yyextra->fencedSize==pat.stripWhiteSpace().length())
6743  {
6744  BEGIN(DocBlock);
6745  }
6746  }
6747 <DocCopyBlock>[^<@/\*\]~\$\\\n]+ { // any character that is not special
6748  yyextra->docBlock << yytext;
6749  }
6750 <DocCopyBlock>{CCS}|{CCE}|{CPPC} {
6751  if (yytext[1]=='*')
6752  {
6753  yyextra->nestedComment=TRUE;
6754  }
6755  else if (yytext[0]=='*')
6756  {
6757  yyextra->nestedComment=FALSE;
6758  }
6759  yyextra->docBlock << yytext;
6760  }
6761 <DocCopyBlock>\n { // newline
6762  yyextra->docBlock << *yytext;
6763  lineCount(yyscanner);
6764  }
6765 <DocCopyBlock>. { // any other character
6766  yyextra->docBlock << *yytext;
6767  }
6768 <DocCopyBlock><<EOF>> {
6769  warn(yyextra->yyFileName,yyextra->yyLineNr,
6770  "reached end of file while inside a '%s' block!\n"
6771  "The command that should end the block seems to be missing!\n",
6772  qPrint(yyextra->docBlockName));
6773  yyterminate();
6774  }
6775 
6776 
6777  /* ------------- Prototype parser -------------- */
6778 
6779 <Prototype>"operator"{B}*"("{B}*")" {
6780  yyextra->current->name+=yytext;
6781  }
6782 <Prototype>"(" {
6783  yyextra->current->args+=*yytext;
6784  yyextra->currentArgumentContext = PrototypeQual;
6785  yyextra->fullArgString = yyextra->current->args;
6786  yyextra->copyArgString = &yyextra->current->args;
6787  BEGIN( ReadFuncArgType ) ;
6788  }
6789 <Prototype>"("({ID}"::")*({B}*[&*])+ {
6790  if (yyextra->insidePHP) // reference parameter
6791  {
6792  REJECT;
6793  }
6794  else
6795  {
6796  yyextra->current->type+=yyextra->current->name+yytext;
6797  yyextra->current->name.resize(0);
6798  BEGIN( PrototypePtr );
6799  }
6800  }
6801 <PrototypePtr>{SCOPENAME} {
6802  yyextra->current->name+=yytext;
6803  }
6804 <PrototypePtr>"(" {
6805  yyextra->current->args+=*yytext;
6806  yyextra->currentArgumentContext = PrototypeQual;
6807  yyextra->fullArgString = yyextra->current->args;
6808  yyextra->copyArgString = &yyextra->current->args;
6809  BEGIN( ReadFuncArgType ) ;
6810  }
6811 <PrototypePtr>")" {
6812  yyextra->current->type+=')';
6813  BEGIN( Prototype );
6814  }
6815 <PrototypePtr>. {
6816  yyextra->current->name+=yytext;
6817  }
6818 <PrototypeQual>"{" {
6819  BEGIN( PrototypeSkipLine);
6820  }
6821 <PrototypeQual>{B}*"const"{B}* {
6822  yyextra->current->args += " const ";
6823  yyextra->current->argList.setConstSpecifier(TRUE);
6824  }
6825 <PrototypeQual>{B}*"volatile"{B}* {
6826  yyextra->current->args += " volatile ";
6827  yyextra->current->argList.setVolatileSpecifier(TRUE);
6828  }
6829 <PrototypeQual>{B}*"="{B}*"0"{B}* {
6830  yyextra->current->args += " = 0";
6831  yyextra->current->virt = Pure;
6832  yyextra->current->argList.setPureSpecifier(TRUE);
6833  }
6834 <PrototypeQual>"throw"{B}*"(" {
6835  yyextra->current->exception = "throw(";
6836  BEGIN(PrototypeExc);
6837  }
6838 <PrototypeExc>")" {
6839  yyextra->current->exception += ')';
6840  BEGIN(PrototypeQual);
6841  }
6842 <PrototypeExc>. {
6843  yyextra->current->exception += *yytext;
6844  }
6845 <PrototypeQual>. {
6846  yyextra->current->args += *yytext;
6847  }
6848 <Prototype>. {
6849  yyextra->current->name += *yytext;
6850  }
6851 <PrototypeSkipLine>. {
6852  }
6853 
6854 
6855 
6856 
6857 <SkipCxxComment>.*"\\\n" { // line continuation
6858  if (yyextra->insideCS)
6859  {
6860  REJECT;
6861  }
6862  else
6863  {
6864  lineCount(yyscanner);
6865  }
6866  }
6867 <SkipCxxComment>{ANYopt}/\n {
6868  BEGIN( yyextra->lastCContext ) ;
6869  }
6870 <SkipComment>[^\*\n]+
6871 
6872  /* ------------ Generic rules -------------- */
6873 
6874 <*>"[[" { // C++11 attribute
6875  if (!yyextra->insideCpp) REJECT;
6876  if (YY_START == CopyGString || YY_START == CopyGString) REJECT;
6877  yyextra->lastC11AttributeContext = YY_START;
6878  BEGIN( SkipC11Attribute );
6879  }
6880 
6881 <*>\n { lineCount(yyscanner); }
6882 <*>\" {
6883  if (yyextra->insideIDL && yyextra->insideCppQuote)
6884  {
6885  BEGIN(EndCppQuote);
6886  }
6887  }
6888 <*>"#" {
6889  if (!yyextra->insidePHP)
6890  REJECT;
6891  yyextra->lastCContext = YY_START ;
6892  BEGIN( SkipCxxComment ) ;
6893  }
6894 <*>\' {
6895  if (yyextra->insidePHP)
6896  {
6897  yyextra->lastStringContext=YY_START;
6898  BEGIN(SkipPHPString);
6899  }
6900  }
6901 <*>\" {
6902  if (yyextra->insidePHP)
6903  {
6904  yyextra->lastStringContext=YY_START;
6905  BEGIN(SkipString);
6906  }
6907  }
6908 <*>\? {
6909  if (yyextra->insideCS && (YY_START != SkipRound))
6910  {
6911  if (yyextra->current->type.isEmpty())
6912  {
6913  if (yyextra->current->name.isEmpty())
6914  yyextra->current->name="?";
6915  else
6916  yyextra->current->name+="?";
6917  }
6918  else
6919  {
6920  yyextra->current->type+="?";
6921  }
6922  }
6923  }
6924 <*>.
6925 <SkipComment>{CPPC}|{CCS}
6926 <*>{CCS} { yyextra->lastCContext = YY_START ;
6927  BEGIN( SkipComment ) ;
6928  }
6929 <SkipComment>{B}*{CCE} { BEGIN( yyextra->lastCContext ) ; }
6930 <*>{CPPC} {
6931  yyextra->lastCContext = YY_START ;
6932  BEGIN( SkipCxxComment ) ;
6933  }
6934 %%
6935 
6936 //----------------------------------------------------------------------------
6937 static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size)
6938 {
6939  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
6940  yy_size_t c=0;
6941  while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
6942  {
6943  *buf = yyextra->inputString[yyextra->inputPosition++] ;
6944  //printf("%d (%c)\n",*buf,*buf);
6945  c++; buf++;
6946  }
6947  return c;
6948 }
6949 
6950 
6951 static void initParser(yyscan_t yyscanner)
6952 {
6953  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
6954  yyextra->outerScopeEntries.clear();
6955  yyextra->baseName.resize(0);
6956  yyextra->protection = Public;
6957  yyextra->baseProt = Public;
6958  yyextra->sharpCount = 0;
6959  yyextra->roundCount = 0;
6960  yyextra->curlyCount = 0;
6961  yyextra->mtype = Method;
6962  yyextra->stat = FALSE;
6963  yyextra->virt = Normal;
6964  yyextra->baseVirt = Normal;
6965  yyextra->isTypedef = FALSE;
6966  yyextra->insideTryBlock = FALSE;
6967  yyextra->insideFormula = FALSE;
6968  yyextra->insideCode=FALSE;
6969  yyextra->insideCli=Config_getBool(CPP_CLI_SUPPORT);
6970  yyextra->previous = 0;
6971  yyextra->firstTypedefEntry.reset();
6972  yyextra->memspecEntry.reset();
6973 }
6974 
6975 static void initEntry(yyscan_t yyscanner)
6976 {
6977  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
6978  if (yyextra->insideJava)
6979  {
6980  yyextra->protection = (yyextra->current_root->spec & (Entry::Interface|Entry::Enum)) ? Public : Package;
6981  }
6982  yyextra->current->protection = yyextra->protection ;
6983  yyextra->current->mtype = yyextra->mtype;
6984  yyextra->current->virt = yyextra->virt;
6985  yyextra->current->stat = yyextra->stat;
6986  yyextra->current->lang = yyextra->language;
6987  //printf("*** initEntry(yyscanner) yyextra->language=%d\n",yyextra->language);
6988  yyextra->commentScanner.initGroupInfo(yyextra->current.get());
6989  yyextra->isTypedef=FALSE;
6990 }
6991 
6992 
6993 //-----------------------------------------------------------------------------
6994 
6995 static void lineCount(yyscan_t yyscanner)
6996 {
6997  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
6998  int tabSize = Config_getInt(TAB_SIZE);
6999  const char *p;
7000  for (p = yytext ; *p ; ++p )
7001  {
7002  if (*p=='\n')
7003  {
7004  yyextra->yyLineNr++,yyextra->column=0,yyextra->yyColNr=1;
7005  }
7006  else if (*p=='\t')
7007  {
7008  yyextra->column+=tabSize - (yyextra->column%tabSize);
7009  }
7010  else
7011  {
7012  yyextra->column++,yyextra->yyColNr++;
7013  }
7014  }
7015  //printf("lineCount()=%d\n",yyextra->column);
7016 }
7017 
7018 static inline int computeIndent(const char *s,int startIndent)
7019 {
7020  int col=startIndent;
7021  int tabSize=Config_getInt(TAB_SIZE);
7022  const char *p=s;
7023  char c;
7024  while ((c=*p++))
7025  {
7026  if (c=='\t') col+=tabSize-(col%tabSize);
7027  else if (c=='\n') col=0;
7028  else col++;
7029  }
7030  return col;
7031 }
7032 
7033 static void addType(yyscan_t yyscanner)
7034 {
7035  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7036  uint tl=yyextra->current->type.length();
7037  if( tl>0 && !yyextra->current->name.isEmpty() && yyextra->current->type.at(tl-1)!='.')
7038  {
7039  yyextra->current->type += ' ' ;
7040  }
7041  yyextra->current->type += yyextra->current->name;
7042  yyextra->current->name.resize(0) ;
7043  tl=yyextra->current->type.length();
7044  if( tl>0 && !yyextra->current->args.isEmpty() && yyextra->current->type.at(tl-1)!='.')
7045  {
7046  yyextra->current->type += ' ' ;
7047  }
7048  yyextra->current->type += yyextra->current->args ;
7049  yyextra->current->args.resize(0) ;
7050  yyextra->current->argList.clear();
7051 }
7052 
7053 
7054 static QCString stripQuotes(const char *s)
7055 {
7056  QCString name;
7057  if (s==0 || *s==0) return name;
7058  name=s;
7059  if (name.at(0)=='"' && name.at(name.length()-1)=='"')
7060  {
7061  name=name.mid(1,name.length()-2);
7062  }
7063  return name;
7064 }
7065 
7066 //-----------------------------------------------------------------
7067 
7068 static bool nameIsOperator(QCString &name)
7069 {
7070  int i=name.find("operator");
7071  if (i==-1) return FALSE;
7072  if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X
7073  if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator
7074  return FALSE; // case TEXToperatorTEXT
7075 }
7076 
7077 //-----------------------------------------------------------------------------
7078 
7079 static void setContext(yyscan_t yyscanner)
7080 {
7081  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7082  yyextra->language = getLanguageFromFileName(yyextra->yyFileName);
7083  yyextra->insideIDL = yyextra->language==SrcLangExt_IDL;
7084  yyextra->insideJava = yyextra->language==SrcLangExt_Java;
7085  yyextra->insideCS = yyextra->language==SrcLangExt_CSharp;
7086  yyextra->insideD = yyextra->language==SrcLangExt_D;
7087  yyextra->insidePHP = yyextra->language==SrcLangExt_PHP;
7088  yyextra->insideObjC = yyextra->language==SrcLangExt_ObjC;
7089  yyextra->insideJS = yyextra->language==SrcLangExt_JS;
7090  yyextra->insideSlice = yyextra->language==SrcLangExt_Slice;
7091  yyextra->insideCpp = (yyextra->language==SrcLangExt_Cpp ||
7092  yyextra->language==SrcLangExt_Lex);
7093  //printf("setContext(%s) yyextra->insideIDL=%d yyextra->insideJava=%d yyextra->insideCS=%d "
7094  // "yyextra->insideD=%d yyextra->insidePHP=%d yyextra->insideObjC=%d\n",
7095  // qPrint(yyextra->yyFileName),yyextra->insideIDL,yyextra->insideJava,yyextra->insideCS,yyextra->insideD,yyextra->insidePHP,yyextra->insideObjC
7096  // );
7097 }
7098 
7099 //-----------------------------------------------------------------------------
7100 
7101 static void prependScope(yyscan_t yyscanner)
7102 {
7103  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7104  if (yyextra->current_root->section & Entry::SCOPE_MASK)
7105  {
7106  //printf("--- prependScope %s to %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
7107  yyextra->current->name.prepend(yyextra->current_root->name+"::");
7108  //printf("prependScope #=%d #yyextra->current=%d\n",yyextra->current_root->tArgLists->count(),yyextra->current->tArgLists->count());
7109  for (const ArgumentList &srcAl : yyextra->current_root->tArgLists)
7110  {
7111  yyextra->current->tArgLists.insert(yyextra->current->tArgLists.begin(),srcAl);
7112  }
7113  }
7114 }
7115 
7116 //-----------------------------------------------------------------------------
7117 
7118 /*! Returns TRUE iff the yyextra->current entry could be a K&R style C function */
7119 static bool checkForKnRstyleC(yyscan_t yyscanner)
7120 {
7121  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7122  if (((QCString)yyextra->yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file
7123  if (yyextra->current->argList.empty()) return FALSE; // must have arguments
7124  for (const Argument &a : yyextra->current->argList)
7125  {
7126  // in K&R style argument do not have a type, but doxygen expects a type
7127  // so it will think the argument has no name
7128  if (a.type.isEmpty() || !a.name.isEmpty()) return FALSE;
7129  }
7130  return TRUE;
7131 }
7132 
7133 //-----------------------------------------------------------------------------
7134 
7135 static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName)
7136 {
7137  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7138  int si = yyextra->current->args.length();
7139  if (yyextra->oldStyleArgType.isEmpty()) // new argument
7140  {
7141  std::string args = yyextra->current->args.str();
7142  static const reg::Ex re(R"(\([^)]*\).*)"); // find first (...)
7143  int bi1=-1;
7144  int bi2=-1;
7145  reg::Match match;
7146  if (reg::search(args,match,re))
7147  {
7148  bi1=(int)match.position();
7149  size_t secondMatchStart = match.position()+match.length(); // search again after first match
7150  if (reg::search(args,match,re,secondMatchStart))
7151  {
7152  bi2=(int)match.position();
7153  }
7154  }
7155  char c;
7156  if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
7157  {
7158  int s=bi2+1; // keep opening (
7159  yyextra->oldStyleArgType = yyextra->current->args.left(s);
7160  int i=s;
7161  while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uchar)c))) i++;
7162  yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
7163  s=i;
7164  while (i<si && isId(yyextra->current->args.at(i))) i++;
7165  oldStyleArgName = yyextra->current->args.mid(s,i-s);
7166  yyextra->oldStyleArgType+=yyextra->current->args.mid(i);
7167  }
7168  else if (bi1!=-1) // redundant braces like in "int (*var)"
7169  {
7170  int s=bi1; // strip opening (
7171  yyextra->oldStyleArgType = yyextra->current->args.left(s);
7172  s++;
7173  int i=s+1;
7174  while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uchar)c))) i++;
7175  yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
7176  s=i;
7177  while (i<si && isId(yyextra->current->args.at(i))) i++;
7178  oldStyleArgName = yyextra->current->args.mid(s,i-s);
7179  }
7180  else // normal "int *var"
7181  {
7182  int l=si,i=l-1,j;
7183  // look for start of name in "type *name"
7184  while (i>=0 && isId(yyextra->current->args.at(i))) i--;
7185  j=i+1;
7186  // look for start of *'s
7187  while (i>=0 && ((c=yyextra->current->args.at(i))=='*' || isspace((uchar)c))) i--;
7188  i++;
7189  if (i!=l)
7190  {
7191  yyextra->oldStyleArgType=yyextra->current->args.left(i);
7192  oldStyleArgPtr=yyextra->current->args.mid(i,j-i);
7193  oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
7194  }
7195  else
7196  {
7197  oldStyleArgName=yyextra->current->args.stripWhiteSpace();
7198  }
7199  }
7200  }
7201  else // continuation like *arg2 in "int *args,*arg2"
7202  {
7203  int l=si,j=0;
7204  char c;
7205  while (j<l && ((c=yyextra->current->args.at(j))=='*' || isspace((uchar)c))) j++;
7206  if (j>0)
7207  {
7208  oldStyleArgPtr=yyextra->current->args.left(j);
7209  oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
7210  }
7211  else
7212  {
7213  oldStyleArgName=yyextra->current->args.stripWhiteSpace();
7214  }
7215  }
7216 }
7217 
7218 //-----------------------------------------------------------------------------
7219 
7220 /*! Update the argument \a name with additional \a type info. For K&R style
7221  * function the type is found \e after the argument list, so this routine
7222  * in needed to fix up.
7223  */
7224 static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name,
7225  const QCString &brief,const QCString &docs)
7226 {
7227  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7228  for (Argument &a : yyextra->current->argList)
7229  {
7230  if (a.type==name)
7231  {
7232  a.type=type.stripWhiteSpace();
7233  if (a.type.left(9)=="register ") // strip keyword
7234  {
7235  a.type=a.type.mid(9);
7236  }
7237  a.name=name.stripWhiteSpace();
7238  if (!brief.isEmpty() && !docs.isEmpty())
7239  {
7240  a.docs=brief+"\n\n"+docs;
7241  }
7242  else if (!brief.isEmpty())
7243  {
7244  a.docs=brief;
7245  }
7246  else
7247  {
7248  a.docs=docs;
7249  }
7250  }
7251  }
7252 }
7253 
7254 //-----------------------------------------------------------------------------
7255 
7256 
7257 void fixArgumentListForJavaScript(ArgumentList &al)
7258 {
7259  for (Argument &a : al)
7260  {
7261  if (!a.type.isEmpty() && a.name.isEmpty())
7262  { // a->type is actually the (typeless) parameter name, so move it
7263  a.name=a.type;
7264  a.type.resize(0);
7265  }
7266  }
7267 }
7268 
7269 
7270 static void startCommentBlock(yyscan_t yyscanner,bool brief)
7271 {
7272  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7273  if (brief)
7274  {
7275  yyextra->current->briefFile = yyextra->yyFileName;
7276  yyextra->current->briefLine = yyextra->yyLineNr;
7277  }
7278  else
7279  {
7280  yyextra->current->docFile = yyextra->yyFileName;
7281  yyextra->current->docLine = yyextra->yyLineNr;
7282  }
7283 }
7284 
7285 //----------------------------------------------------------------------------
7286 
7287 static void newEntry(yyscan_t yyscanner)
7288 {
7289  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7290  if (yyextra->tempEntry==0) // if temp entry is not 0, it holds yyextra->current,
7291  // and yyextra->current is actually replaced by yyextra->previous which was
7292  // already added to yyextra->current_root, so we should not add it again
7293  // (see bug723314)
7294  {
7295  yyextra->previous = yyextra->current;
7296  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7297  }
7298  else
7299  {
7300  yyextra->previous = yyextra->current;
7301  yyextra->current = yyextra->tempEntry;
7302  yyextra->tempEntry.reset();
7303  }
7304  initEntry(yyscanner);
7305 }
7306 
7307 static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief)
7308 {
7309  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7310  bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
7311  if (yyextra->docBlockInBody && hideInBodyDocs) return;
7312  //printf("parseCommentBlock [%s] brief=%d\n",qPrint(doc),brief);
7313  int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; // line of block start
7314 
7315  // fill in inbodyFile && inbodyLine the first time, see bug 633891
7316  std::shared_ptr<Entry> docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current;
7317  if (yyextra->docBlockInBody && docEntry && docEntry->inbodyLine==-1)
7318  {
7319  docEntry->inbodyFile = yyextra->yyFileName;
7320  docEntry->inbodyLine = lineNr;
7321  }
7322 
7323  int position=0;
7324  bool needsEntry=FALSE;
7325  Markdown markdown(yyextra->yyFileName,lineNr);
7326  QCString strippedDoc = stripIndentation(doc);
7327  QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
7328  while (yyextra->commentScanner.parseCommentBlock(
7329  yyextra->thisParser,
7330  yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(),
7331  processedDoc, // text
7332  yyextra->yyFileName, // file
7333  lineNr, // line of block start
7334  yyextra->docBlockInBody ? FALSE : brief, // isBrief
7335  yyextra->docBlockInBody ? FALSE : yyextra->docBlockAutoBrief, // isJavaDocStyle
7336  yyextra->docBlockInBody, // isInBody
7337  yyextra->protection,
7338  position,
7339  needsEntry,
7340  Config_getBool(MARKDOWN_SUPPORT)
7341  )
7342  )
7343  {
7344  //printf("parseCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
7345  if (needsEntry)
7346  {
7347  QCString docFile = yyextra->current->docFile;
7348  newEntry(yyscanner);
7349  yyextra->current->docFile = docFile;
7350  yyextra->current->docLine = lineNr;
7351  }
7352  }
7353  if (needsEntry)
7354  {
7355  newEntry(yyscanner);
7356  }
7357 
7358  if (yyextra->docBlockTerm)
7359  {
7360  unput(yyextra->docBlockTerm);
7361  yyextra->docBlockTerm=0;
7362  }
7363 }
7364 
7365 static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al)
7366 {
7367  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7368  //printf(">>>>>>> handleParametersCommentBlocks()\n");
7369  for (Argument &a : al)
7370  {
7371  //printf(" Param %s docs=%s\n",qPrint(a->name),qPrint(a->docs));
7372  if (!a.docs.isEmpty())
7373  {
7374  if (a.name.isEmpty() && a.type == "...") a.name= "...";
7375  int position=0;
7376  bool needsEntry;
7377 
7378  // save context
7379  QCString orgDoc = yyextra->current->doc;
7380  QCString orgBrief = yyextra->current->brief;
7381  int orgDocLine = yyextra->current->docLine;
7382  int orgBriefLine = yyextra->current->briefLine;
7383 
7384  yyextra->current->doc.resize(0);
7385  yyextra->current->brief.resize(0);
7386 
7387  //printf("handleParametersCommentBlock [%s]\n",qPrint(doc));
7388  while (yyextra->commentScanner.parseCommentBlock(
7389  yyextra->thisParser,
7390  yyextra->current.get(),
7391  a.docs, // text
7392  yyextra->yyFileName, // file
7393  yyextra->current->docLine, // line of block start
7394  FALSE,
7395  FALSE,
7396  FALSE,
7397  yyextra->protection,
7398  position,
7399  needsEntry,
7400  Config_getBool(MARKDOWN_SUPPORT)
7401  )
7402  )
7403  {
7404  //printf("handleParametersCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
7405  if (needsEntry) newEntry(yyscanner);
7406  }
7407  if (needsEntry)
7408  {
7409  newEntry(yyscanner);
7410  }
7411  a.docs = yyextra->current->doc;
7412 
7413  // restore context
7414  yyextra->current->doc = orgDoc;
7415  yyextra->current->brief = orgBrief;
7416  yyextra->current->docLine = orgDocLine;
7417  yyextra->current->briefLine = orgBriefLine;
7418  }
7419  }
7420 }
7421 
7422 
7423 //----------------------------------------------------------------------------
7424 
7425 static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
7426 {
7427  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7428  //printf("parseCompounds(%s)\n",qPrint(rt->name));
7429  for (const auto &ce : rt->children())
7430  {
7431  if (!ce->program.empty())
7432  {
7433  //printf("-- %s ---------\n%s\n---------------\n",
7434  // qPrint(ce->name),qPrint(ce->program));
7435  // init scanner state
7436  yyextra->padCount=0;
7437  //depthIf = 0;
7438  yyextra->column=0;
7439  yyextra->programStr = ce->program.str();
7440  yyextra->inputString = yyextra->programStr.data();
7441  yyextra->inputPosition = 0;
7442  if (ce->section==Entry::ENUM_SEC || (ce->spec&Entry::Enum))
7443  BEGIN( FindFields ) ;
7444  else
7445  BEGIN( FindMembers ) ;
7446  yyextra->current_root = ce;
7447  yyextra->yyFileName = ce->fileName;
7448  //setContext();
7449  yyextra->yyLineNr = ce->bodyLine;
7450  yyextra->yyColNr = ce->bodyColumn;
7451  yyextra->insideObjC = ce->lang==SrcLangExt_ObjC;
7452  //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC);
7453  yyextra->current = std::make_shared<Entry>();
7454  yyextra->stat = FALSE;
7455  initEntry(yyscanner);
7456 
7457  // deep copy group list from parent (see bug 727732)
7458  bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS);
7459  if (autoGroupNested && !rt->groups.empty() && ce->section!=Entry::ENUM_SEC && !(ce->spec&Entry::Enum))
7460  {
7461  ce->groups = rt->groups;
7462  }
7463 
7464  int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
7465  // set default protection based on the compound type
7466  if( ce->section==Entry::CLASS_SEC ) // class
7467  {
7468  if (yyextra->insidePHP || yyextra->insideD || yyextra->insideJS || yyextra->insideIDL || yyextra->insideSlice)
7469  {
7470  yyextra->current->protection = yyextra->protection = Public ;
7471  }
7472  else if (yyextra->insideJava)
7473  {
7474  yyextra->current->protection = yyextra->protection = (ce->spec & (Entry::Interface|Entry::Enum)) ? Public : Package;
7475  }
7476  else if (ce->spec&(Entry::Interface | Entry::Ref | Entry::Value | Entry::Struct | Entry::Union))
7477  {
7478  if (ce->lang==SrcLangExt_ObjC)
7479  {
7480  yyextra->current->protection = yyextra->protection = Protected ;
7481  }
7482  else
7483  {
7484  yyextra->current->protection = yyextra->protection = Public ;
7485  }
7486  }
7487  else
7488  {
7489  yyextra->current->protection = yyextra->protection = Private ;
7490  }
7491  }
7492  else if (ce->section == Entry::ENUM_SEC ) // enum
7493  {
7494  yyextra->current->protection = yyextra->protection = ce->protection;
7495  }
7496  else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
7497  {
7498  if (ce->section == Entry::NAMESPACE_SEC ) // unnamed namespace
7499  {
7500  yyextra->current->stat = yyextra->stat = TRUE;
7501  }
7502  yyextra->current->protection = yyextra->protection = ce->protection;
7503  }
7504  else // named struct, union, protocol, category
7505  {
7506  yyextra->current->protection = yyextra->protection = Public ;
7507  }
7508  yyextra->mtype = Method;
7509  yyextra->virt = Normal;
7510  //printf("name=%s yyextra->current->stat=%d yyextra->stat=%d\n",qPrint(ce->name),yyextra->current->stat,yyextra->stat);
7511 
7512  //memberGroupId = DOX_NOGROUP;
7513  //memberGroupRelates.resize(0);
7514  //memberGroupInside.resize(0);
7515  QCString name = ce->name;
7516  yyextra->commentScanner.enterCompound(yyextra->yyFileName,yyextra->yyLineNr,name);
7517 
7518  scannerYYlex(yyscanner);
7519  yyextra->lexInit=TRUE;
7520  //forceEndGroup();
7521 
7522  yyextra->commentScanner.leaveCompound(yyextra->yyFileName,yyextra->yyLineNr,name);
7523 
7524  yyextra->programStr.resize(0);
7525  ce->program.str(std::string());
7526 
7527 
7528  //if (depthIf>0)
7529  //{
7530  // warn(yyextra->yyFileName,yyextra->yyLineNr,"Documentation block ended in the middle of a conditional section!");
7531  //}
7532  }
7533  parseCompounds(yyscanner,ce);
7534  }
7535 }
7536 
7537 //----------------------------------------------------------------------------
7538 
7539 static void parseMain(yyscan_t yyscanner,
7540  const QCString &fileName,
7541  const char *fileBuf,
7542  const std::shared_ptr<Entry> &rt,
7543  ClangTUParser *clangParser)
7544 {
7545  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7546  initParser(yyscanner);
7547 
7548  yyextra->inputString = fileBuf;
7549  yyextra->inputPosition = 0;
7550  yyextra->column = 0;
7551  scannerYYrestart(0,yyscanner);
7552 
7553  //depthIf = 0;
7554  yyextra->protection = Public;
7555  yyextra->mtype = Method;
7556  yyextra->stat = FALSE;
7557  yyextra->virt = Normal;
7558  yyextra->current_root = rt;
7559  yyextra->yyLineNr = 1 ;
7560  yyextra->yyBegLineNr = 1;
7561  yyextra->yyBegColNr = 0;
7562  yyextra->yyFileName = fileName;
7563  yyextra->clangParser = clangParser;
7564  setContext(yyscanner);
7565  rt->lang = yyextra->language;
7566  msg("Parsing file %s...\n",qPrint(yyextra->yyFileName));
7567 
7568  yyextra->current_root = rt;
7569  initParser(yyscanner);
7570  yyextra->commentScanner.enterFile(yyextra->yyFileName,yyextra->yyLineNr);
7571  yyextra->current = std::make_shared<Entry>();
7572  //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root);
7573  int sec=guessSection(yyextra->yyFileName);
7574  if (sec)
7575  {
7576  yyextra->current->name = yyextra->yyFileName;
7577  yyextra->current->section = sec;
7578  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7579  }
7580  yyextra->current->reset();
7581  initEntry(yyscanner);
7582  if ( yyextra->insidePHP )
7583  {
7584  BEGIN( FindMembersPHP );
7585  }
7586  else if ( yyextra->insideJava ) // add default java.lang package scope
7587  {
7588  yyextra->current->name="java::lang"; // '::' is used in doxygen's internal representation as a scope separator
7589  yyextra->current->fileName = yyextra->yyFileName;
7590  yyextra->current->section=Entry::USINGDIR_SEC;
7591  yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7592  initEntry(yyscanner);
7593  BEGIN( FindMembers );
7594  }
7595  else
7596  {
7597  BEGIN( FindMembers );
7598  }
7599 
7600  scannerYYlex(yyscanner);
7601  yyextra->lexInit=TRUE;
7602 
7603  if (YY_START==Comment)
7604  {
7605  warn(yyextra->yyFileName,yyextra->yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
7606  }
7607 
7608  //forceEndGroup();
7609  yyextra->commentScanner.leaveFile(yyextra->yyFileName,yyextra->yyLineNr);
7610 
7611  yyextra->programStr.resize(0);
7612  rt->program.str(std::string());
7613 
7614  parseCompounds(yyscanner,rt);
7615 
7616  anonNSCount++;
7617 
7618  // add additional entries that were created during processing
7619  for (auto &kv: yyextra->outerScopeEntries)
7620  {
7621  //printf(">>> adding '%s' to scope '%s'\n",qPrint(kv.second->name),qPrint(kv.first->name));
7622  kv.first->moveToSubEntryAndKeep(kv.second);
7623  }
7624  yyextra->outerScopeEntries.clear();
7625 
7626 }
7627 
7628 //----------------------------------------------------------------------------
7629 
7630 static void parsePrototype(yyscan_t yyscanner,const QCString &text)
7631 {
7632  struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7633  //printf("**** parsePrototype(%s) begin\n",qPrint(text));
7634  if (text.isEmpty())
7635  {
7636  warn(yyextra->yyFileName,yyextra->yyLineNr,"Empty prototype found!");
7637  return;
7638  }
7639  if (!yyextra->current) // nothing to store (see bug683516)
7640  {
7641  return;
7642  }
7643 
7644  const char *orgInputString;
7645  int orgInputPosition;
7646  YY_BUFFER_STATE orgState;
7647 
7648  // save scanner state
7649  orgState = YY_CURRENT_BUFFER;
7650  yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE, yyscanner), yyscanner);
7651  orgInputString = yyextra->inputString;
7652  orgInputPosition = yyextra->inputPosition;
7653 
7654  // set new string
7655  yyextra->inputString = text.data();
7656  yyextra->inputPosition = 0;
7657  yyextra->column = 0;
7658  scannerYYrestart(0, yyscanner);
7659  BEGIN(Prototype);
7660  scannerYYlex(yyscanner);
7661  yyextra->lexInit=TRUE;
7662 
7663  yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7664  if (yyextra->current->section == Entry::MEMBERDOC_SEC && yyextra->current->args.isEmpty())
7665  yyextra->current->section = Entry::VARIABLEDOC_SEC;
7666 
7667  // restore original scanner state
7668  yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
7669  yy_switch_to_buffer(orgState, yyscanner);
7670  yyextra->inputString = orgInputString;
7671  yyextra->inputPosition = orgInputPosition;
7672 
7673 
7674  //printf("**** parsePrototype end\n");
7675 }
7676 
7677 //static void handleGroupStartCommand(const char *header)
7678 //{
7679 // memberGroupHeader=header;
7680 // startGroupInDoc();
7681 //}
7682 //
7683 //static void handleGroupEndCommand()
7684 //{
7685 // endGroup();
7686 // g_previous=0;
7687 //}
7688 
7689 //----------------------------------------------------------------------------
7690 
7691 struct COutlineParser::Private
7692 {
7693  yyscan_t yyscanner;
7694  scannerYY_state state;
7695 };
7696 
7697 COutlineParser::COutlineParser() : p(std::make_unique<COutlineParser::Private>())
7698 {
7699  scannerYYlex_init_extra(&p->state,&p->yyscanner);
7700 #ifdef FLEX_DEBUG
7701  scannerYYset_debug(1,p->yyscanner);
7702 #endif
7703 }
7704 
7705 COutlineParser::~COutlineParser()
7706 {
7707  scannerYYlex_destroy(p->yyscanner);
7708 }
7709 
7710 void COutlineParser::parseInput(const QCString &fileName,
7711  const char *fileBuf,
7712  const std::shared_ptr<Entry> &root,
7713  ClangTUParser *clangParser)
7714 {
7715  struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
7716  yyextra->thisParser = this;
7717 
7718  printlex(yy_flex_debug, TRUE, __FILE__, qPrint(fileName));
7719 
7720  ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
7721 
7722  printlex(yy_flex_debug, FALSE, __FILE__, qPrint(fileName));
7723 }
7724 
7725 
7726 bool COutlineParser::needsPreprocessing(const QCString &extension) const
7727 {
7728  QCString fe=extension.lower();
7729  SrcLangExt lang = getLanguageFromFileName(extension);
7730  return (SrcLangExt_Cpp == lang) || (SrcLangExt_Lex == lang) ||
7731  !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
7732  fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5"
7733  );
7734 }
7735 
7736 void COutlineParser::parsePrototype(const QCString &text)
7737 {
7738  ::parsePrototype(p->yyscanner,text);
7739 }
7740 
7741 //----------------------------------------------------------------------------
7742 
7743 #if USE_STATE2STRING
7744 #include "scanner.l.h"
7745 #endif