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