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