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:103
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:8196
static void storeClangId(yyscan_t yyscanner, const char *id)
Definition scanner.l:8101
static void startCommentBlock(yyscan_t yyscanner, bool)
Definition scanner.l:8464
static void setContext(yyscan_t yyscanner)
Definition scanner.l:8261
static QCString stripQuotes(const char *s)
Definition scanner.l:8184
static void addKnRArgInfo(yyscan_t yyscanner, const QCString &type, const QCString &name, const QCString &brief, const QCString &docs)
Definition scanner.l:8421
static void initParser(yyscan_t yyscanner)
Definition scanner.l:8056
static bool checkForKnRstyleC(yyscan_t yyscanner)
Definition scanner.l:8301
static void startVerbatimBlock(yyscan_t yyscanner, const QCString &blockName, size_t fencedSize=0, bool codeBlock=false)
Definition scanner.l:8209
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition scanner.l:8042
static void initMethodProtection(yyscan_t yyscanner, Protection prot)
Definition scanner.l:8151
static const char * stateToString(int state)
static bool endVerbatimBlock(yyscan_t yyscanner, const QCString &blockName, size_t fencedSize=0)
Definition scanner.l:8223
void fixArgumentListForJavaScript(ArgumentList &al)
Definition scanner.l:8450
static int computeIndent(const char *s, int startIndent)
Definition scanner.l:8136
static bool startOfRequiresExpression(const QCString &req)
Definition scanner.l:8242
static void handleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
Definition scanner.l:8501
static void handleParametersCommentBlocks(yyscan_t yyscanner, ArgumentList &al)
Definition scanner.l:8561
static void prependScope(yyscan_t yyscanner)
Definition scanner.l:8283
static const char * getLexerFILE()
Definition scanner.l:264
static bool nameIsOperator(QCString &name)
Definition scanner.l:8250
static void setJavaProtection(yyscan_t yyscanner)
Definition scanner.l:8315
static void splitKnRArg(yyscan_t yyscanner, QCString &oldStyleArgPtr, QCString &oldStyleArgName)
Definition scanner.l:8332
static void addType(yyscan_t yyscanner)
Definition scanner.l:8163
static void initEntry(yyscan_t yyscanner)
Definition scanner.l:8080
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 }
#define TRUE
Definition qcstring.h:37
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 }
static void addType(yyscan_t yyscanner)
Definition code.l:2599
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:170
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:167
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:264
QCString left(size_t len) const
Definition qcstring.h:233
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:69
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
#define FALSE
Definition qcstring.h:34
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 }
static void initEntry(yyscan_t yyscanner)
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())
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:245
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:556
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 }
static void handleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
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:197
static int computeIndent(const char *s)
#define Config_getBool(name)
Definition config.h:33
static void startCommentBlock(yyscan_t yyscanner, bool)
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 CommentScanner::addDeprecatedDocs(yyextra->current.get(), yyextra->yyLineNr);
3647 BEGIN(yyextra->lastC11AttributeContext);
3648 }
static void addDeprecatedDocs(Entry *current, int lineNr)
3649
3650
3651 /* generic round bracket list copy rules */
3652<CopyRound>\" {
3653 *yyextra->pCopyRoundString += *yytext;
3654 yyextra->pCopyQuotedString=yyextra->pCopyRoundString;
3655 yyextra->lastStringContext=YY_START;
3656 BEGIN(CopyString);
3657 }
3658<CopyRound>"(" {
3659 *yyextra->pCopyRoundString += *yytext;
3660 yyextra->roundCount++;
3661 }
3662<CopyRound>")" {
3663 *yyextra->pCopyRoundString += *yytext;
3664 if (--yyextra->roundCount<0)
3665 BEGIN(yyextra->lastRoundContext);
3666 }
3667<CopyRound>\n {
3668 lineCount(yyscanner);
3669 *yyextra->pCopyRoundString += *yytext;
3670 }
3671<CopyRound>\' {
3672 if (yyextra->insidePHP)
3673 {
3674 yyextra->current->initializer << yytext;
3675 yyextra->pCopyQuotedString = yyextra->pCopyRoundString;
3676 yyextra->lastStringContext=YY_START;
3677 BEGIN(CopyPHPString);
3678 }
3679 else
3680 {
3681 *yyextra->pCopyRoundString += yytext;
3682 }
3683 }
3684<CopyRound>{CHARLIT} {
3685 if (yyextra->insidePHP)
3686 {
3687 REJECT;
3688 }
3689 else
3690 {
3691 *yyextra->pCopyRoundString+=yytext;
3692 }
3693 }
3694<CopyRound>[^"'()\n,]+ {
3695 *yyextra->pCopyRoundString+=yytext;
3696 }
3697<CopyRound>. {
3698 *yyextra->pCopyRoundString+=*yytext;
3699 }
3700
3701 /* generic sharp bracket list copy rules */
3702<CopySharp>\" {
3703 *yyextra->pCopySharpString += *yytext;
3704 yyextra->pCopyQuotedString=yyextra->pCopySharpString;
3705 yyextra->lastStringContext=YY_START;
3706 BEGIN(CopyString);
3707 }
3708<CopySharp>"<" {
3709 *yyextra->pCopySharpString += *yytext;
3710 yyextra->sharpCount++;
3711 }
3712<CopySharp>">" {
3713 *yyextra->pCopySharpString += *yytext;
3714 if (--yyextra->sharpCount<0)
3715 {
3716 BEGIN(yyextra->lastSharpContext);
3717 }
3718 }
3719<CopySharp>\n {
3720 lineCount(yyscanner);
3721 *yyextra->pCopySharpString += *yytext;
3722 }
3723<CopySharp>\' {
3724 if (yyextra->insidePHP)
3725 {
3726 yyextra->current->initializer << yytext;
3727 yyextra->pCopyQuotedString = yyextra->pCopySharpString;
3728 yyextra->lastStringContext=YY_START;
3729 BEGIN(CopyPHPString);
3730 }
3731 else
3732 {
3733 *yyextra->pCopySharpString += yytext;
3734 }
3735 }
3736<CopySharp>{CHARLIT} {
3737 if (yyextra->insidePHP)
3738 {
3739 REJECT;
3740 }
3741 else
3742 {
3743 *yyextra->pCopySharpString+=yytext;
3744 }
3745 }
3746<CopySharp>[^"'<>\n,]+ {
3747 *yyextra->pCopySharpString+=yytext;
3748 }
3749<CopySharp>. {
3750 *yyextra->pCopySharpString+=*yytext;
3751 }
3752
3753
3754 /* generic round bracket list copy rules for growable strings */
3755<GCopyRound>\" {
3756 *yyextra->pCopyRoundGString << *yytext;
3757 yyextra->pCopyQuotedGString=yyextra->pCopyRoundGString;
3758 yyextra->lastStringContext=YY_START;
3759 BEGIN(CopyGString);
3760 }
3761<GCopyRound>"(" {
3762 *yyextra->pCopyRoundGString << *yytext;
3763 yyextra->roundCount++;
3764 }
3765<GCopyRound>")" {
3766 *yyextra->pCopyRoundGString << *yytext;
3767 if (--yyextra->roundCount<0)
3768 BEGIN(yyextra->lastRoundContext);
3769 }
3770<GCopyRound>\n {
3771 lineCount(yyscanner);
3772 *yyextra->pCopyRoundGString << *yytext;
3773 }
3774<GCopyRound>\' {
3775 if (yyextra->insidePHP)
3776 {
3777 yyextra->current->initializer << yytext;
3778 yyextra->pCopyQuotedGString = yyextra->pCopyRoundGString;
3779 yyextra->lastStringContext=YY_START;
3780 BEGIN(CopyPHPGString);
3781 }
3782 else
3783 {
3784 *yyextra->pCopyRoundGString << yytext;
3785 }
3786 }
3787<GCopyRound>{CHARLIT} {
3788 if (yyextra->insidePHP)
3789 {
3790 REJECT;
3791 }
3792 else
3793 {
3794 *yyextra->pCopyRoundGString << yytext;
3795 }
3796 }
3797<GCopyRound>"@\"" {
3798 if (!yyextra->insideCS) REJECT;
3799 *yyextra->pCopyRoundGString << yytext;
3800 yyextra->lastSkipVerbStringContext=YY_START;
3801 yyextra->pSkipVerbString=yyextra->pCopyRoundGString;
3802 BEGIN(SkipVerbString);
3803 }
3804<GCopyRound>[^"'()\n\/,R]+ { // R because of raw string start
3805 *yyextra->pCopyRoundGString << yytext;
3806 }
3807<GCopyRound>{RAWBEGIN} {
3808 *yyextra->pCopyRoundGString << yytext;
3809 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
3810 yyextra->lastRawStringContext = YY_START;
3811 yyextra->pCopyRawGString = yyextra->pCopyRoundGString;
3812 BEGIN(RawGString);
3813 }
3814<GCopyRound>. {
3815 *yyextra->pCopyRoundGString << *yytext;
3816 }
3817
3818 /* 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 */
3819<GCopySquare>\" {
3820 *yyextra->pCopySquareGString << *yytext;
3821 yyextra->pCopyQuotedGString=yyextra->pCopySquareGString;
3822 yyextra->lastStringContext=YY_START;
3823 BEGIN(CopyGString);
3824 }
3825<GCopySquare>\' {
3826 *yyextra->pCopySquareGString << *yytext;
3827 if (yyextra->insidePHP)
3828 {
3829 yyextra->pCopyQuotedGString=yyextra->pCopySquareGString;
3830 yyextra->lastStringContext=YY_START;
3831 BEGIN(CopyPHPGString);
3832 }
3833 }
3834<GCopySquare>"[" {
3835 *yyextra->pCopySquareGString << *yytext;
3836 yyextra->squareCount++;
3837 }
3838<GCopySquare>"]" {
3839 *yyextra->pCopySquareGString << *yytext;
3840 if (--yyextra->squareCount<0)
3841 BEGIN(yyextra->lastSquareContext);
3842 }
3843<GCopySquare>\n {
3844 lineCount(yyscanner);
3845 *yyextra->pCopySquareGString << *yytext;
3846 }
3847<GCopySquare>\' {
3848 if (yyextra->insidePHP)
3849 {
3850 yyextra->current->initializer << yytext;
3851 yyextra->pCopyQuotedGString = yyextra->pCopySquareGString;
3852 yyextra->lastStringContext=YY_START;
3853 BEGIN(CopyPHPGString);
3854 }
3855 else
3856 {
3857 *yyextra->pCopySquareGString << yytext;
3858 }
3859 }
3860<GCopySquare>{CHARLIT} {
3861 if (yyextra->insidePHP)
3862 {
3863 REJECT;
3864 }
3865 else
3866 {
3867 *yyextra->pCopySquareGString << yytext;
3868 }
3869 }
3870<GCopySquare>[^"'\‍[\‍]\n\/,]+ {
3871 *yyextra->pCopySquareGString << yytext;
3872 }
3873<GCopySquare>. {
3874 *yyextra->pCopySquareGString << *yytext;
3875 }
3876
3877 /* generic curly bracket list copy rules */
3878<CopyCurly>\" {
3879 *yyextra->pCopyCurlyString += *yytext;
3880 yyextra->pCopyQuotedString=yyextra->pCopyCurlyString;
3881 yyextra->lastStringContext=YY_START;
3882 yyextra->keepComment=false;
3883 BEGIN(CopyString);
3884 }
3885<CopyCurly>\' {
3886 *yyextra->pCopyCurlyString += *yytext;
3887 if (yyextra->insidePHP)
3888 {
3889 yyextra->pCopyQuotedString=yyextra->pCopyCurlyString;
3890 yyextra->lastStringContext=YY_START;
3891 yyextra->keepComment=false;
3892 BEGIN(CopyPHPString);
3893 }
3894 }
3895<CopyCurly>"{" {
3896 *yyextra->pCopyCurlyString += *yytext;
3897 yyextra->curlyCount++;
3898 }
3899<CopyCurly>"}" {
3900 *yyextra->pCopyCurlyString += *yytext;
3901 if (--yyextra->curlyCount<0)
3902 {
3903 yyextra->keepComment=false;
3904 BEGIN(yyextra->lastCurlyContext);
3905 }
3906 }
3907<CopyCurly>{CHARLIT} { if (yyextra->insidePHP)
3908 {
3909 REJECT;
3910 }
3911 else
3912 {
3913 *yyextra->pCopyCurlyString += yytext;
3914 }
3915 }
3916<CopyCurly>[^"'{}\/\n,]+ {
3917 *yyextra->pCopyCurlyString += yytext;
3918 }
3919<CopyCurly>"/" { *yyextra->pCopyCurlyString += yytext; }
3920<CopyCurly>\n {
3921 lineCount(yyscanner);
3922 *yyextra->pCopyCurlyString += *yytext;
3923 }
3924<CopyCurly>. {
3925 *yyextra->pCopyCurlyString += *yytext;
3926 }
3927<CopyCurly>{CPPC}[^\n]* {
3928 if (yyextra->keepComment)
3929 {
3930 *yyextra->pCopyCurlyString += yytext;
3931 }
3932 else
3933 {
3934 REJECT;
3935 }
3936 }
3937<CopyCurly>{CCS} {
3938 if (yyextra->keepComment)
3939 {
3940 *yyextra->pCopyCurlyString += yytext;
3941 BEGIN(CopyComment);
3942 }
3943 else
3944 {
3945 REJECT;
3946 }
3947 }
3948<CopyComment>{CCE} {
3949 *yyextra->pCopyCurlyString += yytext;
3950 BEGIN(CopyCurly);
3951 }
3952<CopyComment>\n {
3953 lineCount(yyscanner);
3954 *yyextra->pCopyCurlyString += *yytext;
3955 }
3956<CopyComment>. {
3957 *yyextra->pCopyCurlyString += *yytext;
3958 }
3959<CopyComment><<EOF>> {
3960 warn(yyextra->fileName,yyextra->yyLineNr,
3961 "reached end of file while inside a C style comment block!");
3962 yyterminate();
3963 }
3964
3965 /* generic curly bracket list copy rules for growable strings */
3966<GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker
3967 }
3968<GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker
3969 QCString line = yytext;
3970 int s = line.find(' ');
3971 int e = line.find('"',s);
3972 yyextra->yyLineNr = line.mid(s,e-s).toInt();
3973 if (yytext[yyleng-1]=='\n')
3974 {
3975 lineCount(yyscanner);
3976 yyextra->column=0;
3977 }
3978 }
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:254
3979<GCopyCurly>\" {
3980 *yyextra->pCopyCurlyGString << *yytext;
3981 yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString;
3982 yyextra->lastStringContext=YY_START;
3983 yyextra->keepComment = false;
3984 BEGIN(CopyGString);
3985 }
3986<GCopyCurly>\' {
3987 *yyextra->pCopyCurlyGString << *yytext;
3988 if (yyextra->insidePHP)
3989 {
3990 yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString;
3991 yyextra->lastStringContext=YY_START;
3992 yyextra->keepComment = false;
3993 BEGIN(CopyPHPGString);
3994 }
3995 }
3996<GCopyCurly>"{" {
3997 *yyextra->pCopyCurlyGString << *yytext;
3998 yyextra->curlyCount++;
3999 }
4000<GCopyCurly>"}" {
4001 *yyextra->pCopyCurlyGString << *yytext;
4002 if (--yyextra->curlyCount<0)
4003 {
4004 yyextra->current->endBodyLine = yyextra->yyLineNr;
4005 yyextra->keepComment = false;
4006 BEGIN(yyextra->lastCurlyContext);
4007 }
4008 }
4009<GCopyCurly>{CHARLIT} { if (yyextra->insidePHP)
4010 {
4011 REJECT;
4012 }
4013 else
4014 {
4015 *yyextra->pCopyCurlyGString << yytext;
4016 }
4017 }
4018<GCopyCurly>[^"'{}\/\n,]+ {
4019 *yyextra->pCopyCurlyGString << yytext;
4020 }
4021<GCopyCurly>[,]+ {
4022 *yyextra->pCopyCurlyGString << yytext;
4023 }
4024<GCopyCurly>"/" { *yyextra->pCopyCurlyGString << yytext; }
4025<GCopyCurly>\n {
4026 lineCount(yyscanner);
4027 *yyextra->pCopyCurlyGString << *yytext;
4028 }
4029<GCopyCurly>. {
4030 *yyextra->pCopyCurlyGString << *yytext;
4031 }
4032<GCopyCurly>{CPPC}[^\n]* {
4033 if (yyextra->keepComment)
4034 {
4035 *yyextra->pCopyCurlyGString << yytext;
4036 }
4037 else
4038 {
4039 REJECT;
4040 }
4041 }
4042<GCopyCurly>{CCS} {
4043 if (yyextra->keepComment)
4044 {
4045 *yyextra->pCopyCurlyGString << yytext;
4046 BEGIN(GCopyComment);
4047 }
4048 else
4049 {
4050 REJECT;
4051 }
4052 }
4053<GCopyComment>{CCE} {
4054 *yyextra->pCopyCurlyGString << yytext;
4055 BEGIN(GCopyCurly);
4056 }
4057<GCopyComment>\n {
4058 lineCount(yyscanner);
4059 *yyextra->pCopyCurlyGString << *yytext;
4060 }
4061<GCopyComment>. {
4062 *yyextra->pCopyCurlyGString << *yytext;
4063 }
4064<GCopyComment><<EOF>> {
4065 warn(yyextra->fileName,yyextra->yyLineNr,
4066 "reached end of file while inside a C style comment block!");
4067 yyterminate();
4068 }
4069
4070 /* ---------------------- */
4071
4072
4073<FindMembers>":" {
4074 if (yyextra->current->type.isEmpty() &&
4075 yyextra->current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}'
4076 {
4077 yyextra->current->section = EntryType::makeEnum();
4078 yyextra->current->name.clear();
4079 yyextra->current->args.clear();
4080 BEGIN(EnumBaseType);
4081 }
4082 else
4083 {
4084 if (yyextra->current->type.isEmpty()) // anonymous padding field, e.g. "int :7;"
4085 {
4086 addType(yyscanner);
4087 yyextra->current->name.sprintf("__pad%d__",yyextra->padCount++);
4088 }
4089 BEGIN(BitFields);
4090 yyextra->current->bitfields+=":";
4091 }
4092 }
4093<BitFields>. {
4094 yyextra->current->bitfields+=*yytext;
4095 }
4096<EnumBaseType>. {
4097 yyextra->current->args+=*yytext;
4098 }
4099<EnumBaseType>\n {
4100 lineCount(yyscanner);
4101 yyextra->current->args+=' ';
4102 }
4103<FindMembers>[;,] {
4104 QCString oldType = yyextra->current->type;
4105 if (yyextra->current->bodyLine==-1)
4106 {
4107 yyextra->current->bodyLine = yyextra->yyLineNr;
4108 yyextra->current->bodyColumn = yyextra->yyColNr;
4109 }
4110 if ( yyextra->insidePHP && yyextra->current->type.startsWith("var"))
4111 {
4112 yyextra->current->type = yyextra->current->type.mid(3);
4113 }
4114 if (yyextra->isTypedef && !yyextra->current->type.startsWith("typedef "))
4115 {
4116 yyextra->current->type.prepend("typedef ");
4117 }
4118 bool isStatic = yyextra->current->isStatic;
4119 Protection prot = yyextra->current->protection;
4120 bool isConcept = yyextra->current->section.isConcept();
4121 bool isModule = yyextra->current->section.isModuleDoc();
4122 if (isConcept) // C++20 concept
4123 {
4124 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4125 initEntry(yyscanner);
4126 }
4127 else if (isModule) // C++20 module
4128 {
4129 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4130 initEntry(yyscanner);
4131 }
4132 else if (!yyextra->current->name.isEmpty() && !yyextra->current->section.isEnum())
4133 {
4134 yyextra->current->type=yyextra->current->type.simplifyWhiteSpace();
4135 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
4136 yyextra->current->name=yyextra->current->name.stripWhiteSpace();
4137 if (yyextra->current->section.isClass()) // remove spec for "struct Bla bla;"
4138 {
4139 yyextra->current->spec = TypeSpecifier();
4140 }
4141 yyextra->current->section = EntryType::makeVariable() ;
4142 yyextra->current->fileName = yyextra->fileName;
4143 yyextra->current->startLine = yyextra->yyBegLineNr;
4144 yyextra->current->startColumn = yyextra->yyBegColNr;
4145 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4146 initEntry(yyscanner);
4147 }
4148 if ( *yytext == ',')
4149 {
4150 yyextra->current->isStatic = isStatic; // the static attribute holds for all variables
4151 yyextra->current->protection = prot;
4152 yyextra->current->name.clear();
4153 yyextra->current->args.clear();
4154 yyextra->current->brief.clear();
4155 yyextra->current->doc.clear();
4156 yyextra->current->initializer.str(std::string());
4157 yyextra->current->bitfields.clear();
4158 yyextra->current->type = stripFuncPtr(oldType);
4159 }
4160 else
4161 {
4162 yyextra->mtype = MethodTypes::Method;
4163 yyextra->virt = Specifier::Normal;
4164 yyextra->current->bodyLine = -1;
4165 yyextra->current->bodyColumn = 1;
4166 yyextra->current->groups.clear();
4167 initEntry(yyscanner);
4168 }
4169 }
4170
4171<FindMembers>"[" {
4172 if (yyextra->insideSlice)
4173 {
4174 yyextra->squareCount=1;
4175 yyextra->lastSquareContext = YY_START;
4176 yyextra->current->metaData += "[";
4177 BEGIN( SliceMetadata );
4178 }
4179 else if (!yyextra->insideCS &&
4180 (yyextra->current->name.isEmpty() ||
4181 yyextra->current->name=="typedef"
4182 )
4183 ) // IDL function property
4184 {
4185 yyextra->squareCount=1;
4186 yyextra->lastSquareContext = YY_START;
4187 yyextra->idlAttr.clear();
4188 yyextra->idlProp.clear();
4189 yyextra->current->mtype = yyextra->mtype;
4190
4191 if (Config_getBool(IDL_PROPERTY_SUPPORT) &&
4192 yyextra->current->mtype == MethodTypes::Property)
4193 { // we are yyextra->inside the properties section of a dispinterface
4194 yyextra->odlProp = true;
4195 yyextra->current->spec.setGettable(true).setSettable(true);
4196 }
4197
4198 BEGIN( IDLAttribute );
4199 }
4200 else if (yyextra->insideCS &&
4201 yyextra->current->name.isEmpty())
4202 {
4203 yyextra->squareCount=1;
4204 yyextra->lastSquareContext = YY_START;
4205 // Skip the C# attribute
4206 // for this member
4207 yyextra->current->args.clear();
4208 BEGIN( SkipSquare );
4209 }
4210 else
4211 {
4212 yyextra->current->args += yytext ;
4213 yyextra->squareCount=1;
4214 yyextra->externLinkage=FALSE; // see bug759247
4215 BEGIN( Array ) ;
4216 }
4217 }
4218<SliceMetadata>"[" { // Global metadata.
4219 yyextra->squareCount++;
4220 yyextra->current->metaData += "[";
4221 }
4222<SliceMetadata>{BN}* {
4223 lineCount(yyscanner);
4224 }
4225<SliceMetadata>\"[^\"]*\" {
4226 yyextra->current->metaData += yytext;
4227 }
4228<SliceMetadata>"," {
4229 yyextra->current->metaData += yytext;
4230 }
4231<SliceMetadata>"]" {
4232 yyextra->current->metaData += yytext;
4233 if (--yyextra->squareCount<=0)
4234 {
4235 BEGIN (yyextra->lastSquareContext);
4236 }
4237 }
4238<SliceOptional>"(" {
4239 yyextra->current->type += "(";
4240 yyextra->roundCount++;
4241 }
4242<SliceOptional>[0-9]+ {
4243 yyextra->current->type += yytext;
4244 }
4245<SliceOptional>")" {
4246 yyextra->current->type += ")";
4247 if(--yyextra->roundCount<=0)
4248 {
4249 BEGIN (yyextra->lastModifierContext);
4250 }
4251 }
4252<IDLAttribute>"]" {
4253 // end of IDL function attribute
4254 if (--yyextra->squareCount<=0)
4255 {
4256 lineCount(yyscanner);
4257 if (yyextra->current->mtype == MethodTypes::Property)
4258 BEGIN( IDLPropName );
4259 else
4260 BEGIN( yyextra->lastSquareContext );
4261 }
4262 }
4263<IDLAttribute>"propput" {
4264 if (Config_getBool(IDL_PROPERTY_SUPPORT))
4265 {
4266 yyextra->current->mtype = MethodTypes::Property;
4267 }
4268 yyextra->current->spec.setSettable(true);
4269 }
4270<IDLAttribute>"propget" {
4271 if (Config_getBool(IDL_PROPERTY_SUPPORT))
4272 {
4273 yyextra->current->mtype = MethodTypes::Property;
4274 }
4275 yyextra->current->spec.setGettable(true);
4276 }
4277<IDLAttribute>"property" { // UNO IDL property
4278 yyextra->current->spec.setProperty(true);
4279 }
4280<IDLAttribute>"attribute" { // UNO IDL attribute
4281 yyextra->current->spec.setAttribute(true);
4282 }
4283<IDLAttribute>"optional" { // on UNO IDL interface/service/attribute/property
4284 yyextra->current->spec.setOptional(true);
4285 }
4286<IDLAttribute>"readonly" { // on UNO IDL attribute or property
4287 if (Config_getBool(IDL_PROPERTY_SUPPORT) && yyextra->odlProp)
4288 {
4289 yyextra->current->spec.setSettable(false);
4290 }
4291 else
4292 {
4293 yyextra->current->spec.setReadonly(true);
4294 }
4295 }
4296<IDLAttribute>"bound" { // on UNO IDL attribute or property
4297 yyextra->current->spec.setBound(true);
4298 }
4299<IDLAttribute>"removable" { // on UNO IDL property
4300 yyextra->current->spec.setRemovable(true);
4301 }
4302<IDLAttribute>"constrained" { // on UNO IDL property
4303 yyextra->current->spec.setConstrained(true);
4304 }
4305<IDLAttribute>"transient" { // on UNO IDL property
4306 yyextra->current->spec.setTransient(true);
4307 }
4308<IDLAttribute>"maybevoid" { // on UNO IDL property
4309 yyextra->current->spec.setMaybeVoid(true);
4310 }
4311<IDLAttribute>"maybedefault" { // on UNO IDL property
4312 yyextra->current->spec.setMaybeDefault(true);
4313 }
4314<IDLAttribute>"maybeambiguous" { // on UNO IDL property
4315 yyextra->current->spec.setMaybeAmbiguous(true);
4316 }
4317<IDLAttribute>. {
4318 }
4319<IDLPropName>{BN}*{ID}({BN}*[*]*{BN}*)? {
4320 // return type (probably HRESULT) - skip it
4321
4322 if (yyextra->odlProp)
4323 { // property type
4324 yyextra->idlProp = yytext;
4325 }
4326 }
4327<IDLPropName>{ID}{BN}*"(" {
4328 yyextra->current->name = yytext;
4329 yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
4330 yyextra->current->startLine = yyextra->yyLineNr;
4331 yyextra->current->startColumn = yyextra->yyColNr;
4332 BEGIN( IDLProp );
4333 }
4334<IDLPropName>{BN}*"("{BN}*{ID}{BN}*")"{BN}* {
4335 if (yyextra->odlProp)
4336 {
4337 yyextra->idlProp += yytext;
4338 }
4339 }
4340<IDLPropName>{ID}{BNopt}/";" {
4341 if (yyextra->odlProp)
4342 {
4343 yyextra->current->name = yytext;
4344 yyextra->idlProp = yyextra->idlProp.stripWhiteSpace();
4345 yyextra->odlProp = false;
4346
4347 BEGIN( IDLProp );
4348 }
4349 }
4350<IDLProp>{BN}*"["[^\‍]]*"]"{BN}* { // attribute of a parameter
4351 yyextra->idlAttr = yytext;
4352 yyextra->idlAttr=yyextra->idlAttr.stripWhiteSpace();
4353 }
4354<IDLProp>{ID} { // property type
4355 yyextra->idlProp = yytext;
4356 }
4357<IDLProp>{BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);)
4358 if (yyextra->current->args.isEmpty())
4359 yyextra->current->args = "(";
4360 else
4361 yyextra->current->args += ", ";
4362 yyextra->current->args += yyextra->idlAttr;
4363 yyextra->current->args += " ";
4364 yyextra->current->args += yyextra->idlProp; // prop was actually type of extra parameter
4365 yyextra->current->args += " ";
4366 yyextra->current->args += yytext;
4367 yyextra->current->args = yyextra->current->args.left(yyextra->current->args.length() - 1); // strip comma
4368 yyextra->idlProp.clear();
4369 yyextra->idlAttr.clear();
4370 BEGIN( IDLProp );
4371 }
4372<IDLProp>{BN}*{ID}{BN}*")"{BN}* {
4373 // the parameter name for the property - just skip.
4374 }
4375<IDLProp>";" {
4376 yyextra->current->fileName = yyextra->fileName;
4377 yyextra->current->type = yyextra->idlProp;
4378 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4379 if (!yyextra->current->args.isEmpty())
4380 yyextra->current->args += ")";
4381 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4382 yyextra->current->section = EntryType::makeVariable();
4383 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
4384 initEntry(yyscanner);
4385 BEGIN( FindMembers );
4386 }
4387<IDLProp>. { // spaces, *, or other stuff
4388 //yyextra->idlProp+=yytext;
4389 }
4390<Array>"]" { yyextra->current->args += *yytext ;
4391 if (--yyextra->squareCount<=0)
4392 BEGIN( FindMembers ) ;
4393 }
4394<FuncFuncArray>"]" { yyextra->current->args += *yytext ;
4395 if (--yyextra->squareCount<=0)
4396 BEGIN( SFunction ) ;
4397 }
4398<Array,FuncFuncArray>"[" { yyextra->current->args += *yytext ;
4399 yyextra->squareCount++;
4400 }
4401<Array,FuncFuncArray>. { yyextra->current->args += *yytext ; }
4402<SkipSquare>"[" { yyextra->squareCount++; }
4403<SkipSquare>"]" {
4404 if (--yyextra->squareCount<=0)
4405 BEGIN( yyextra->lastSquareContext );
4406 }
4407<SkipSquare>\" {
4408 yyextra->lastStringContext=YY_START;
4409 BEGIN( SkipString );
4410 }
4411<SkipSquare>[^\n\‍[\‍]\"]+
4412<FindMembers>"<" { addType(yyscanner);
4413 yyextra->current->type += yytext ;
4414 BEGIN( Sharp ) ;
4415 }
4416<Sharp>">" { yyextra->current->type += *yytext ;
4417 if (--yyextra->sharpCount<=0)
4418 BEGIN( FindMembers ) ;
4419 }
4420<Sharp>"<" { yyextra->current->type += *yytext ;
4421 yyextra->sharpCount++;
4422 }
4423<Sharp>{BN}+ {
4424 yyextra->current->type += ' ';
4425 lineCount(yyscanner);
4426 }
4427<Sharp>. { yyextra->current->type += *yytext ; }
4428<FindFields>{ID} {
4429 storeClangId(yyscanner,yytext);
4430 yyextra->current->bodyLine = yyextra->yyLineNr;
4431 yyextra->current->bodyColumn = yyextra->yyColNr;
4432 yyextra->current->name = yytext;
4433 }
4434<FindFields>[({] {
4435 // Java enum initializer
4436 unput(*yytext);
4437 yyextra->lastInitializerContext = YY_START;
4438 yyextra->sharpCount=0;
4439 yyextra->initBracketCount=0;
4440 yyextra->current->initializer.str("=");
4441 BEGIN(ReadInitializer);
4442 }
4443<FindFields>"=" {
4444 yyextra->lastInitializerContext = YY_START;
4445 yyextra->sharpCount=0;
4446 yyextra->initBracketCount=0;
4447 yyextra->current->initializer.str(yytext);
4448 BEGIN(ReadInitializer);
4449 }
4450<FindFields>";" {
4451 if (yyextra->insideJava) // yyextra->last enum field in Java class
4452 {
4453 if (!yyextra->current->name.isEmpty())
4454 {
4455 yyextra->current->fileName = yyextra->fileName;
4456 yyextra->current->startLine = yyextra->yyLineNr;
4457 yyextra->current->startColumn = yyextra->yyColNr;
4458 if (!yyextra->current_root->spec.isEnum())
4459 {
4460 yyextra->current->type = "@"; // enum marker
4461 }
4462 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4463 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4464 yyextra->current->section = EntryType::makeVariable();
4465 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
4466 initEntry(yyscanner);
4467 }
4468
4469 BEGIN( FindMembers );
4470 }
4471 else
4472 {
4473 REJECT;
4474 }
4475 }
4476<FindFields>"," {
4477 //printf("adding '%s' '%s' '%s' to enum '%s' (mGrpId=%d)\n",
4478 // qPrint(yyextra->current->type), qPrint(yyextra->current->name),
4479 // qPrint(yyextra->current->args), qPrint(yyextra->current_root->name),yyextra->current->mGrpId);
4480 if (!yyextra->current->name.isEmpty())
4481 {
4482 yyextra->current->fileName = yyextra->fileName;
4483 if (yyextra->current_root->section.isEnum() || yyextra->current_root->spec.isEnum())
4484 {
4485 yyextra->current->startLine = yyextra->current->bodyLine;
4486 yyextra->current->startColumn = yyextra->current->bodyColumn;
4487 }
4488 else
4489 {
4490 yyextra->current->startLine = yyextra->yyLineNr;
4491 yyextra->current->startColumn = yyextra->yyColNr;
4492 }
4493 if (!yyextra->current_root->spec.isEnum())
4494 {
4495 yyextra->current->type = "@"; // enum marker
4496 }
4497 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4498 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4499 yyextra->current->section = EntryType::makeVariable();
4500 // add to the scope of the enum
4501 if (!yyextra->insideCS && !yyextra->insideJava &&
4502 !yyextra->current_root->spec.isStrong())
4503 // for C# and Java 1.5+ enum values always have to be explicitly qualified,
4504 // same for C++11 style enums (enum class Name {})
4505 {
4506 // add to the scope surrounding the enum (copy!)
4507 // we cannot add it directly as that would invalidate the iterator in parseCompounds.
4508 //printf("*** adding outer scope entry for %s\n",qPrint(yyextra->current->name));
4509 yyextra->outerScopeEntries.emplace_back(yyextra->current_root->parent(), std::make_shared<Entry>(*yyextra->current));
4510 }
4511 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
4512 initEntry(yyscanner);
4513 }
4514 else // probably a redundant ,
4515 {
4516 yyextra->current->reset();
4517 initEntry(yyscanner);
4518 }
4519 }
4520<FindFields>"[" { // attribute list in IDL
4521 yyextra->squareCount=1;
4522 yyextra->lastSquareContext = YY_START;
4523 BEGIN(SkipSquare);
4524 }
4525<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<\\\$R]* { yyextra->current->program << yytext ; } // R because of raw string start
4526<ReadBody,ReadNSBody,ReadBodyIntf>{CPPC}.* { yyextra->current->program << yytext ; }
4527<ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!yyextra->insidePHP)
4528 REJECT;
4529 // append PHP comment.
4530 yyextra->current->program << yytext ;
4531 }
4532 /* Interpolated string C# */
4533<SkipCurly,ReadBody,ReadNSBody,ReadBodyIntf,ReadExpressionBody,FindMembers,FindMemberName>$\" { if (!yyextra->insideCS) REJECT
4534 yyextra->current->program << yytext ;
4535 yyextra->pSkipInterpString = &yyextra->current->program;
4536 yyextra->lastSkipInterpStringContext=YY_START;
4537 yyextra->strCurlyCount = 0;
4538 BEGIN( SkipInterpString );
4539 }
4540<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})* {
4541 *yyextra->pSkipInterpString << yytext;
4542 }
4543<SkipInterpString>"{" {
4544 *yyextra->pSkipInterpString << *yytext;
4545 yyextra->strCurlyCount++;
4546 }
4547<SkipInterpString>"}" {
4548 *yyextra->pSkipInterpString << *yytext;
4549 yyextra->strCurlyCount--;
4550 }
4551<SkipInterpString>\" {
4552 *yyextra->pSkipInterpString << *yytext;
4553 if (yyextra->strCurlyCount==0)
4554 {
4555 BEGIN( yyextra->lastSkipInterpStringContext );
4556 }
4557 }
4558<SkipInterpString>. {
4559 *yyextra->pSkipInterpString << *yytext;
4560 }
4561 /* Verbatim Interpolated string C# */
4562<SkipCurly,ReadBody,ReadNSBody,ReadBodyIntf,ReadExpressionBody,FindMembers,FindMemberName>$@\" { if (!yyextra->insideCS) REJECT
4563 yyextra->current->program << yytext ;
4564 yyextra->pSkipInterpVerbString = &yyextra->current->program;
4565 yyextra->lastSkipInterpVerbStringContext=YY_START;
4566 yyextra->strCurlyCount = 0;
4567 BEGIN( SkipInterpVerbString );
4568 }
4569<SkipInterpVerbString>([^\"{}]|"{{"|"}}"|"\"\"")* {
4570 *yyextra->pSkipInterpVerbString << yytext;
4571 }
4572<SkipInterpVerbString>"{" {
4573 *yyextra->pSkipInterpVerbString << *yytext;
4574 yyextra->strCurlyCount++;
4575 }
4576<SkipInterpVerbString>"}" {
4577 *yyextra->pSkipInterpVerbString << *yytext;
4578 yyextra->strCurlyCount--;
4579 }
4580<SkipInterpVerbString>\" {
4581 *yyextra->pSkipInterpVerbString << *yytext;
4582 if (yyextra->strCurlyCount==0)
4583 {
4584 BEGIN( yyextra->lastSkipInterpVerbStringContext );
4585 }
4586 }
4587<SkipInterpVerbString>. {
4588 *yyextra->pSkipInterpVerbString << *yytext;
4589 }
4590<ReadBody,ReadNSBody,ReadBodyIntf>"\$" { yyextra->current->program << yytext ; }
4591<ReadBody,ReadNSBody,ReadBodyIntf>@\" { yyextra->current->program << yytext ;
4592 yyextra->pSkipVerbString = &yyextra->current->program;
4593 yyextra->lastSkipVerbStringContext=YY_START;
4594 BEGIN( SkipVerbString );
4595 }
4596<ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (yyextra->insidePHP)
4597 {
4598 yyextra->current->program << yytext ;
4599 yyextra->pCopyHereDocGString = &yyextra->current->program;
4600 yyextra->lastHereDocContext=YY_START;
4601 BEGIN( CopyHereDoc );
4602 }
4603 else
4604 {
4605 REJECT;
4606 }
4607 }
4608<ReadBody,ReadNSBody,ReadBodyIntf>{RAWBEGIN} {
4609 yyextra->current->program << yytext;
4610 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
4611 yyextra->lastRawStringContext = YY_START;
4612 yyextra->pCopyRawGString = &yyextra->current->program;
4613 BEGIN(RawGString);
4614 }
4615<ReadBody,ReadNSBody,ReadBodyIntf>\" { yyextra->current->program << yytext ;
4616 yyextra->pCopyQuotedGString = &yyextra->current->program;
4617 yyextra->lastStringContext=YY_START;
4618 yyextra->stopAtInvalidString=false;
4619 BEGIN( CopyGString );
4620 }
4621<ReadBody,ReadNSBody,ReadBodyIntf>{DCOMMC} { yyextra->doxygenComment=true; REJECT;}
4622<ReadBody,ReadNSBody,ReadBodyIntf>{CCS}{B}* { yyextra->current->program << yytext ;
4623 yyextra->lastContext = YY_START ;
4624 BEGIN( Comment ) ;
4625 }
4626<ReadBody,ReadNSBody,ReadBodyIntf>{CCS}{BL} { yyextra->current->program << yytext ;
4627 ++yyextra->yyLineNr ;
4628 yyextra->lastContext = YY_START ;
4629 BEGIN( Comment ) ;
4630 }
4631<ReadBody,ReadNSBody,ReadBodyIntf>"'" {
4632 if (!yyextra->insidePHP)
4633 {
4634 yyextra->current->program << yytext;
4635 }
4636 else
4637 { // begin of single quoted string
4638 yyextra->current->program << yytext;
4639 yyextra->pCopyQuotedGString = &yyextra->current->program;
4640 yyextra->lastStringContext=YY_START;
4641 BEGIN(CopyPHPGString);
4642 }
4643 }
4644<ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT} {
4645 if (yyextra->insidePHP)
4646 {
4647 REJECT; // for PHP code single quotes
4648 // are used for strings of arbitrary length
4649 }
4650 else
4651 {
4652 yyextra->current->program << yytext;
4653 }
4654 }
4655<ReadBody,ReadNSBody,ReadBodyIntf>"{" { yyextra->current->program << yytext ;
4656 ++yyextra->curlyCount ;
4657 }
4658<ReadBodyIntf>"}" {
4659 yyextra->current->program << yytext ;
4660 --yyextra->curlyCount ;
4661 }
4662<ReadBody,ReadNSBody>"}" {
4663 if ( yyextra->curlyCount>0 )
4664 {
4665 yyextra->current->program << yytext ;
4666 --yyextra->curlyCount ;
4667 }
4668 else
4669 {
4670 yyextra->current->endBodyLine = yyextra->yyLineNr;
4671 std::shared_ptr<Entry> original_root = yyextra->current_root; // save root this namespace is in
4672 if (yyextra->current->section.isNamespace() && yyextra->current->type == "namespace")
4673 {
4674 //printf("namespace %s\n",qPrint(yyextra->current->name));
4675 int split_point;
4676 // save documentation values
4677 QCString doc = yyextra->current->doc;
4678 int docLine = yyextra->current->docLine;
4679 QCString docFile = yyextra->current->docFile;
4680 QCString brief = yyextra->current->brief;
4681 int briefLine = yyextra->current->briefLine;
4682 QCString briefFile = yyextra->current->briefFile;
4683 auto groups = yyextra->current->groups;
4684 auto anchors = yyextra->current->anchors;
4685 auto sli = yyextra->current->sli;
4686 auto rqli = yyextra->current->rqli;
4687 // reset documentation values
4688 yyextra->current->doc = "";
4689 yyextra->current->docLine = 0;
4690 yyextra->current->docFile = "";
4691 yyextra->current->brief = "";
4692 yyextra->current->briefLine = 0;
4693 yyextra->current->briefFile = "";
4694 yyextra->current->groups.clear();
4695 yyextra->current->anchors.clear();
4696 yyextra->current->sli.clear();
4697 yyextra->current->rqli.clear();
4698 while ((split_point = yyextra->current->name.find("::")) != -1)
4699 {
4700 std::shared_ptr<Entry> new_current = std::make_shared<Entry>(*yyextra->current);
4701 yyextra->current->program.str(std::string());
4702 new_current->name = yyextra->current->name.mid(split_point + 2);
4703 yyextra->current->name = yyextra->current->name.left(split_point);
4704 if (yyextra->current->name.startsWith("inline ")) // C++20 style nested inline namespace syntax
4705 {
4706 yyextra->current->name = yyextra->current->name.mid(7);
4707 yyextra->current->spec.setInline(true);
4708 }
4709 if (!yyextra->current_root->name.isEmpty()) yyextra->current->name.prepend(yyextra->current_root->name+"::");
4710
4711 yyextra->current_root->moveToSubEntryAndKeep(yyextra->current);
4712 yyextra->current_root = yyextra->current;
4713 yyextra->current = new_current;
4714 }
4715 // restore documentation values
4716 yyextra->current->doc = doc;
4717 yyextra->current->docLine = docLine;
4718 yyextra->current->docFile = docFile;
4719 yyextra->current->brief = brief;
4720 yyextra->current->briefLine = briefLine;
4721 yyextra->current->briefFile = briefFile;
4722 yyextra->current->groups = groups;
4723 yyextra->current->anchors = anchors;
4724 yyextra->current->sli = sli;
4725 yyextra->current->rqli = rqli;
4726 }
4727 QCString &cn = yyextra->current->name;
4728 if (cn.startsWith("inline ")) // C++20 style nested inline namespace syntax
4729 {
4730 cn = cn.mid(7);
4731 yyextra->current->spec.setInline(true);
4732 }
4733 QCString rn = yyextra->current_root->name;
4734 //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
4735 if (!cn.isEmpty() && !rn.isEmpty())
4736 {
4737 prependScope(yyscanner);
4738 }
4739 if (yyextra->isTypedef && cn.isEmpty())
4740 {
4741 //printf("Typedef Name\n");
4742 BEGIN( TypedefName );
4743 }
4744 else
4745 {
4746 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4747 {
4748 yyextra->current->program << ','; // add field terminator
4749 }
4750 // add compound definition to the tree
4751 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
4752 // was: yyextra->current->args.simplifyWhiteSpace();
4753 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4754 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4755 //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);
4756 if (yyextra->insideObjC &&
4757 (yyextra->current->spec.isInterface() || yyextra->current->spec.isCategory())
4758 ) // method definition follows
4759 {
4760 BEGIN( ReadBodyIntf ) ;
4761 }
4762 else
4763 {
4764 yyextra->memspecEntry = yyextra->current;
4765 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4766 yyextra->current = std::make_shared<Entry>(*yyextra->memspecEntry);
4767 if (yyextra->current->section.isNamespace() ||
4768 yyextra->current->spec.isInterface() ||
4769 yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideJS ||
4770 yyextra->insideSlice
4771 )
4772 { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
4773 yyextra->current->reset();
4774 yyextra->current_root = std::move(original_root); // restore scope from before namespace descent
4775 initEntry(yyscanner);
4776 yyextra->memspecEntry.reset();
4777 BEGIN( FindMembers ) ;
4778 }
4779 else
4780 {
4781 // enabled the next two lines for bug 623424
4782 yyextra->current->doc.clear();
4783 yyextra->current->brief.clear();
4784 BEGIN( MemberSpec ) ;
4785 }
4786 }
4787 }
4788 }
4789 }
bool startsWith(const char *s) const
Definition qcstring.h:511
void clear()
Definition qcstring.h:186
4790<ReadBody>"}"{BN}+"typedef"{BN}+ {
4791 lineCount(yyscanner);
4792 if ( yyextra->curlyCount>0 )
4793 {
4794 yyextra->current->program << yytext ;
4795 --yyextra->curlyCount ;
4796 }
4797 else
4798 {
4799 yyextra->isTypedef = TRUE;
4800 yyextra->current->endBodyLine = yyextra->yyLineNr;
4801 QCString &cn = yyextra->current->name;
4802 QCString rn = yyextra->current_root->name;
4803 if (!cn.isEmpty() && !rn.isEmpty())
4804 {
4805 prependScope(yyscanner);
4806 }
4807 BEGIN( TypedefName );
4808 }
4809 }
4810<TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
4811 lineCount(yyscanner);
4812 yyextra->current->type.prepend(yytext);
4813 }
4814<TypedefName>{ID} {
4815 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4816 {
4817 yyextra->current->program << ","; // add field terminator
4818 }
4819 yyextra->current->name=yytext;
4820 prependScope(yyscanner);
4821 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4822 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4823 //printf("Adding compound %s %s %s\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
4824 if (!yyextra->firstTypedefEntry)
4825 {
4826 yyextra->firstTypedefEntry = yyextra->current;
4827 }
4828 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4829 initEntry(yyscanner);
4830 yyextra->isTypedef=TRUE; // to undo reset by initEntry(yyscanner)
4831 BEGIN(MemberSpecSkip);
4832 }
4833<TypedefName>";" { /* typedef of anonymous type */
4834 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
4835 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4836 {
4837 yyextra->current->program << ','; // add field terminator
4838 }
4839 // add compound definition to the tree
4840 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4841 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4842 yyextra->memspecEntry = yyextra->current;
4843 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4844 initEntry(yyscanner);
4845 unput(';');
4846 BEGIN( MemberSpec ) ;
4847 }
QCString generateAnonymousAnchor(const QCString &fileName, int count)
Definition util.cpp:3597
4848<MemberSpec>([*&]*{BN}*)*{ID}{BN}*("["[^\‍]\n]*"]")* { // the [] part could be improved.
4849 lineCount(yyscanner);
4850 int i=0,l=(int)yyleng,j;
4851 while (i<l && (!isId(yytext[i]))) i++;
4852 yyextra->msName = QCString(yytext).right(l-i).stripWhiteSpace();
4853 j=yyextra->msName.find("[");
4854 if (j!=-1)
4855 {
4856 yyextra->msArgs=yyextra->msName.right(yyextra->msName.length()-j);
4857 yyextra->msName=yyextra->msName.left(j);
4858 }
4859 yyextra->msType=QCString(yytext).left(i);
4860
4861 // handle *pName in: typedef { ... } name, *pName;
4862 if (yyextra->firstTypedefEntry)
4863 {
4864 if (yyextra->firstTypedefEntry->spec.isStruct())
4865 {
4866 yyextra->msType.prepend("struct "+yyextra->firstTypedefEntry->name);
4867 }
4868 else if (yyextra->firstTypedefEntry->spec.isUnion())
4869 {
4870 yyextra->msType.prepend("union "+yyextra->firstTypedefEntry->name);
4871 }
4872 else if (yyextra->firstTypedefEntry->section.isEnum())
4873 {
4874 yyextra->msType.prepend("enum "+yyextra->firstTypedefEntry->name);
4875 }
4876 else
4877 {
4878 yyextra->msType.prepend(yyextra->firstTypedefEntry->name);
4879 }
4880 }
4881 }
QCString right(size_t len) const
Definition qcstring.h:238
bool isId(int c)
Definition util.h:257
4882<MemberSpec>"(" { // function with struct return type
4883 addType(yyscanner);
4884 yyextra->current->name = yyextra->msName;
4885 yyextra->current->spec = TypeSpecifier();
4886 unput('(');
4887 BEGIN(FindMembers);
4888 }
4889<MemberSpec>[,;] {
4890 //printf("msName=%s\n",qPrint(yyextra->msName));
4891 if (yyextra->msName.isEmpty() && !yyextra->current->name.isEmpty())
4892 {
4893 // see if the compound does not have a name or is yyextra->inside another
4894 // anonymous compound. If so we insert a
4895 // special 'anonymous' variable.
4896 //Entry *p=yyextra->current_root;
4897 const Entry *p=yyextra->current.get();
4898 while (p)
4899 {
4900 // only look for class scopes, not namespace scopes
4901 if (p->section.isCompound() && !p->name.isEmpty())
4902 {
4903 //printf("Trying scope '%s'\n",qPrint(p->name));
4904 int i=p->name.findRev("::");
4905 int pi = (i==-1) ? 0 : i+2;
4906 if (p->name.at(pi)=='@')
4907 {
4908 // anonymous compound yyextra->inside -> insert dummy variable name
4909 //printf("Adding anonymous variable for scope %s\n",qPrint(p->name));
4910 yyextra->msName = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
4911 break;
4912 }
4913 }
4914 //p=p->parent;
4915 if (p==yyextra->current.get()) p=yyextra->current_root.get(); else p=p->parent();
4916 }
4917 }
4918 //printf("yyextra->msName=%s yyextra->current->name=%s\n",qPrint(yyextra->msName),qPrint(yyextra->current->name));
4919 if (!yyextra->msName.isEmpty()
4920 /*&& yyextra->msName!=yyextra->current->name*/) // skip typedef T {} T;, removed due to bug608493
4921 {
4922 bool typedefHidesStruct = Config_getBool(TYPEDEF_HIDES_STRUCT);
4923 // case 1: typedef struct _S { ... } S_t;
4924 // -> omit typedef and use S_t as the struct name
4925 if (typedefHidesStruct &&
4926 yyextra->isTypedef &&
4927 ((yyextra->current->spec.isStruct() || yyextra->current->spec.isUnion()) || yyextra->current->section.isEnum()) &&
4928 yyextra->msType.stripWhiteSpace().isEmpty() &&
4929 yyextra->memspecEntry)
4930 {
4931 yyextra->memspecEntry->name=yyextra->msName;
4932 }
4933 else // case 2: create a typedef field
4934 {
4935 std::shared_ptr<Entry> varEntry=std::make_shared<Entry>();
4936 varEntry->lang = yyextra->language;
4937 varEntry->protection = yyextra->current->protection ;
4938 varEntry->mtype = yyextra->current->mtype;
4939 varEntry->virt = yyextra->current->virt;
4940 varEntry->isStatic = yyextra->current->isStatic;
4941 varEntry->section = EntryType::makeVariable();
4942 varEntry->name = yyextra->msName.stripWhiteSpace();
4943 varEntry->type = yyextra->current->type.simplifyWhiteSpace()+" ";
4944 varEntry->args = yyextra->msArgs;
4945 if (yyextra->isTypedef)
4946 {
4947 varEntry->type.prepend("typedef ");
4948 // //printf("yyextra->current->name = %s %s\n",qPrint(yyextra->current->name),qPrint(yyextra->msName));
4949 }
4950 if (typedefHidesStruct &&
4951 yyextra->isTypedef &&
4952 (yyextra->current->spec.isStruct() || yyextra->current->spec.isUnion()) &&
4953 yyextra->memspecEntry
4954 ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
4955 {
4956 varEntry->type+=yyextra->memspecEntry->name+yyextra->msType;
4957 }
4958 else // case 2: use _S as type for for pS_t
4959 {
4960 varEntry->type+=yyextra->current->name+yyextra->msType;
4961 }
4962 varEntry->fileName = yyextra->fileName;
4963 varEntry->startLine = yyextra->yyLineNr;
4964 varEntry->startColumn = yyextra->yyColNr;
4965 varEntry->doc = yyextra->current->doc;
4966 varEntry->brief = yyextra->current->brief;
4967 varEntry->mGrpId = yyextra->current->mGrpId;
4968 varEntry->initializer.str(yyextra->current->initializer.str());
4969 varEntry->groups = yyextra->current->groups;
4970 varEntry->sli = yyextra->current->sli;
4971
4972 //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n",
4973 // qPrint(varEntry->type),qPrint(varEntry->name),
4974 // qPrint(varEntry->args),qPrint(varEntry->brief),qPrint(varEntry->doc));
4975 yyextra->current_root->moveToSubEntryAndKeep(varEntry);
4976 }
4977 }
4978 if (*yytext==';') // end of a struct/class ...
4979 {
4980 if (!yyextra->isTypedef && yyextra->msName.isEmpty() &&
4981 yyextra->memspecEntry && yyextra->current->section.isCompound())
4982 { // case where a class/struct has a doc block after it
4983 if (!yyextra->current->doc.isEmpty())
4984 {
4985 yyextra->memspecEntry->doc += yyextra->current->doc;
4986 }
4987 if (!yyextra->current->brief.isEmpty())
4988 {
4989 yyextra->memspecEntry->brief += yyextra->current->brief;
4990 }
4991 }
4992 yyextra->msType.clear();
4993 yyextra->msName.clear();
4994 yyextra->msArgs.clear();
4995 yyextra->isTypedef=FALSE;
4996 yyextra->firstTypedefEntry.reset();
4997 yyextra->memspecEntry.reset();
4998 yyextra->current->reset();
4999 initEntry(yyscanner);
5000 BEGIN( FindMembers );
5001 }
5002 else
5003 {
5004 yyextra->current->doc.clear();
5005 yyextra->current->brief.clear();
5006 }
5007
5008 }
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:597
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
5009<MemberSpec>"=" {
5010 yyextra->lastInitializerContext=YY_START;
5011 yyextra->sharpCount=0;
5012 yyextra->initBracketCount=0;
5013 yyextra->current->initializer.str(yytext);
5014 BEGIN(ReadInitializer);
5015 /* BEGIN(MemberSpecSkip); */
5016 }
5017 /*
5018<MemberSpecSkip>"{" {
5019 yyextra->curlyCount=0;
5020 yyextra->lastCurlyContext = MemberSpecSkip;
5021 yyextra->previous = yyextra->current;
5022 BEGIN(SkipCurly);
5023 }
5024 */
5025<MemberSpecSkip>"," { BEGIN(MemberSpec); }
5026<MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); }
5027<ReadBody,ReadNSBody,ReadBodyIntf>{BN}{1,80} { yyextra->current->program << yytext ;
5028 lineCount(yyscanner) ;
5029 }
5030<ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block
5031 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
5032 initEntry(yyscanner);
5033 yyextra->language = yyextra->current->lang = SrcLangExt::Cpp; // see bug746361
5034 yyextra->insideObjC=FALSE;
5035 BEGIN( FindMembers );
5036 }
5037<ReadBody,ReadNSBody,ReadBodyIntf>\\. { yyextra->current->program << yytext ; }
5038<ReadBody,ReadNSBody,ReadBodyIntf>. { yyextra->current->program << yytext ; }
5039
5040<FindMembers>"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
5041<FindMembers>("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */
5042 if (yyextra->insidePHP) // reference parameter
5043 {
5044 REJECT
5045 }
5046 else
5047 {
5048 yyextra->current->bodyLine = yyextra->yyLineNr;
5049 yyextra->current->bodyColumn = yyextra->yyColNr;
5050 lineCount(yyscanner);
5051 addType(yyscanner);
5052 yyextra->funcPtrType=yytext;
5053 yyextra->roundCount=0;
5054 //yyextra->current->type += yytext;
5055 BEGIN( FuncPtr );
5056 }
5057 }
5058<FuncPtr>{SCOPENAME} {
5059 yyextra->current->name = yytext;
5060 if (nameIsOperator(yyextra->current->name))
5061 {
5062 BEGIN( FuncPtrOperator );
5063 }
5064 else
5065 {
5066 if (yyextra->current->name=="const" || yyextra->current->name=="volatile")
5067 {
5068 yyextra->funcPtrType += yyextra->current->name;
5069 }
5070 else
5071 {
5072 BEGIN( EndFuncPtr );
5073 }
5074 }
5075 }
5076<FuncPtr>. {
5077 //printf("error: FuncPtr '%c' unexpected at line %d of %s\n",*yytext,yyextra->yyLineNr,yyextra->fileName);
5078 }
5079<FuncPtrOperator>"("{BN}*")"{BNopt}/"(" {
5080 yyextra->current->name += yytext;
5081 yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
5082 lineCount(yyscanner);
5083 }
5084<FuncPtrOperator>\n {
5085 lineCount(yyscanner);
5086 yyextra->current->name += *yytext;
5087 }
5088<FuncPtrOperator>"(" {
5089 unput(*yytext);
5090 BEGIN( EndFuncPtr );
5091 }
5092<FuncPtrOperator>. {
5093 yyextra->current->name += *yytext;
5094 }
5095<EndFuncPtr>")"{BNopt}/";" { // a variable with extra braces
5096 lineCount(yyscanner);
5097 yyextra->current->type+=yyextra->funcPtrType.mid(1);
5098 BEGIN(FindMembers);
5099 }
5100<EndFuncPtr>")"{BNopt}/"(" { // a function pointer
5101 lineCount(yyscanner);
5102 if (yyextra->funcPtrType!="(") // not just redundant braces
5103 {
5104 yyextra->current->type+=yyextra->funcPtrType+")";
5105 }
5106 BEGIN(FindMembers);
5107 }
5108<EndFuncPtr>")"{BNopt}/"[" { // an array of variables
5109 lineCount(yyscanner);
5110 yyextra->current->type+=yyextra->funcPtrType;
5111 yyextra->current->args += ")";
5112 BEGIN(FindMembers);
5113 }
5114<EndFuncPtr>"(" { // a function returning a function or
5115 // a function returning a pointer to an array
5116 yyextra->current->args += *yytext ;
5117 //yyextra->roundCount=0;
5118 //BEGIN( FuncFunc );
5119 yyextra->current->bodyLine = yyextra->yyLineNr;
5120 yyextra->current->bodyColumn = yyextra->yyColNr;
5121 yyextra->currentArgumentContext = FuncFuncEnd;
5122 yyextra->fullArgString=yyextra->current->args;
5123 yyextra->copyArgString=&yyextra->current->args;
5124 BEGIN( ReadFuncArgType ) ;
5125 }
5126<EndFuncPtr>"["[^\n\‍]]*"]" {
5127 yyextra->funcPtrType+=yytext;
5128 }
5129<EndFuncPtr>")" {
5130 BEGIN(FindMembers);
5131 }
5132<FuncFunc>"(" {
5133 yyextra->current->args += *yytext ;
5134 ++yyextra->roundCount;
5135 }
5136<FuncFunc>")" {
5137 yyextra->current->args += *yytext ;
5138 if ( yyextra->roundCount )
5139 --yyextra->roundCount;
5140 else
5141 {
5142 BEGIN(FuncFuncEnd);
5143 }
5144 }
5145<FuncFuncEnd>")"{BN}*"(" {
5146 lineCount(yyscanner);
5147 yyextra->current->type+=yyextra->funcPtrType+")(";
5148 BEGIN(FuncFuncType);
5149 }
5150<FuncFuncEnd>")"{BNopt}/[;{] {
5151 lineCount(yyscanner);
5152 yyextra->current->type+=yyextra->funcPtrType.mid(1);
5153 BEGIN(SFunction);
5154 }
5155<FuncFuncEnd>")"{BNopt}/"[" { // function returning a pointer to an array
5156 lineCount(yyscanner);
5157 yyextra->current->type+=yyextra->funcPtrType;
5158 yyextra->current->args+=")";
5159 BEGIN(FuncFuncArray);
5160 }
5161<FuncFuncEnd>. {
5162 yyextra->current->args += *yytext;
5163 }
5164<FuncFuncType>"(" {
5165 yyextra->current->type += *yytext;
5166 yyextra->roundCount++;
5167 }
5168<FuncFuncType>")" {
5169 yyextra->current->type += *yytext;
5170 if (yyextra->roundCount)
5171 --yyextra->roundCount;
5172 else
5173 BEGIN(SFunction);
5174 }
5175<FuncFuncType>{BN}*","{BN}* { lineCount(yyscanner) ; yyextra->current->type += ", " ; }
5176<FuncFuncType>{BN}+ { lineCount(yyscanner) ; yyextra->current->type += ' ' ; }
5177<FuncFuncType>. {
5178 yyextra->current->type += *yytext;
5179 }
5180<FindMembers>"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")"{BN}*"(" { // for catching typedef void (__stdcall *f)() like definitions
5181 if (yyextra->current->type.startsWith("typedef") &&
5182 yyextra->current->bodyLine==-1)
5183 // the bodyLine check is to prevent this guard to be true more than once
5184 {
5185 yyextra->current->bodyLine = yyextra->yyLineNr;
5186 yyextra->current->bodyColumn = yyextra->yyColNr;
5187 BEGIN( GetCallType );
5188 }
5189 else if (!yyextra->current->name.isEmpty()) // normal function
5190 {
5191 yyextra->current->args = yytext;
5192 yyextra->current->bodyLine = yyextra->yyLineNr;
5193 yyextra->current->bodyColumn = yyextra->yyColNr;
5194 yyextra->currentArgumentContext = FuncQual;
5195 yyextra->fullArgString=yyextra->current->args;
5196 yyextra->copyArgString=&yyextra->current->args;
5197 BEGIN( ReadFuncArgType ) ;
5198 //printf(">>> Read function arguments!\n");
5199 }
5200 }
5201<GetCallType>{BN}*{ID}{BN}*"*" {
5202 lineCount(yyscanner);
5203 addType(yyscanner);
5204 yyextra->funcPtrType="(";
5205 yyextra->funcPtrType+=yytext;
5206 yyextra->roundCount=0;
5207 BEGIN( FuncPtr );
5208 }
5209<FindMembers>"(" {
5210 if (!yyextra->current->name.isEmpty())
5211 {
5212 yyextra->current->args = yytext;
5213 yyextra->current->bodyLine = yyextra->yyLineNr;
5214 yyextra->current->bodyColumn = yyextra->yyColNr;
5215 yyextra->currentArgumentContext = FuncQual;
5216 yyextra->fullArgString=yyextra->current->args;
5217 yyextra->copyArgString=&yyextra->current->args;
5218 BEGIN( ReadFuncArgType ) ;
5219 //printf(">>> Read function arguments yyextra->current->argList.size()=%d\n",yyextra->current->argList.size());
5220 }
5221 }
5222
5223 /*- Function argument reading rules ---------------------------------------*/
5224
5225<ReadFuncArgType>[^ \/\r\t\n\‍[\‍]\‍)\‍(\"\'#]+ { *yyextra->copyArgString+=yytext;
5226 if (yyextra->insideCS) yyextra->fullArgString+=substitute(yytext,".","::");
5227 else yyextra->fullArgString+=yytext;
5228 }
5229<CopyArgString,CopyArgPHPString>[^\n\\\"\']+ { *yyextra->copyArgString+=yytext;
5230 yyextra->fullArgString+=yytext;
5231 }
5232<CopyArgRound>[^\/\n\‍)\‍(\"\']+ {
5233 *yyextra->copyArgString+=yytext;
5234 yyextra->fullArgString+=yytext;
5235 }
5236<CopyArgSquare>[^\/\n\‍]\‍[\"\']+ {
5237 *yyextra->copyArgString+=yytext;
5238 yyextra->fullArgString+=yytext;
5239 }
5240<ReadFuncArgType,ReadTempArgs>{BN}* {
5241 *yyextra->copyArgString+=" ";
5242 yyextra->fullArgString+=" ";
5243 lineCount(yyscanner);
5244 }
5245<ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>{RAWBEGIN} {
5246 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
5247 yyextra->lastRawStringContext = YY_START;
5248 yyextra->pCopyRawString = yyextra->copyArgString;
5249 *yyextra->pCopyRawString+=yytext;
5250 yyextra->fullArgString+=yytext;
5251 BEGIN(RawString);
5252 }
5253<ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>\" {
5254 *yyextra->copyArgString+=*yytext;
5255 yyextra->fullArgString+=*yytext;
5256 yyextra->lastCopyArgStringContext = YY_START;
5257 BEGIN( CopyArgString );
5258 }
5259<ReadFuncArgType>"[" {
5260 if (!yyextra->insidePHP) REJECT;
5261 *yyextra->copyArgString+=*yytext;
5262 yyextra->fullArgString+=*yytext;
5263 yyextra->argSquareCount=0;
5264 yyextra->lastCopyArgContext = YY_START;
5265 BEGIN( CopyArgSquare );
5266 }
5267<ReadFuncArgType,ReadTempArgs>"(" {
5268 *yyextra->copyArgString+=*yytext;
5269 yyextra->fullArgString+=*yytext;
5270 yyextra->argRoundCount=0;
5271 yyextra->lastCopyArgContext = YY_START;
5272 BEGIN( CopyArgRound );
5273 }
5274<ReadFuncArgType>")" {
5275 *yyextra->copyArgString+=*yytext;
5276 yyextra->fullArgString+=*yytext;
5277 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5278 if (yyextra->insideJS)
5279 {
5280 fixArgumentListForJavaScript(yyextra->current->argList);
5281 }
5282 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
5283
5284 /* remember the yyextra->current documentation block, since
5285 we could overwrite it with the documentation of
5286 a function argument, which we then have to correct later
5287 on
5288 */
5289 yyextra->docBackup = yyextra->current->doc;
5290 yyextra->briefBackup = yyextra->current->brief;
5291
5292 BEGIN( yyextra->currentArgumentContext );
5293 }
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:826
5294 /* a special comment */
5295<ReadFuncArgType,ReadTempArgs>({CCS}[*!]|{CPPC}[/!])("<"?) {
5296 if (yyextra->currentArgumentContext==DefineEnd)
5297 {
5298 // for defines we interpret a comment
5299 // as documentation for the define
5300 int i;for (i=(int)yyleng-1;i>=0;i--)
5301 {
5302 unput(yytext[i]);
5303 }
5304 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5305 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
5306 BEGIN( yyextra->currentArgumentContext );
5307 }
5308 else // not a define
5309 {
5310 // for functions we interpret a comment
5311 // as documentation for the argument
5312 yyextra->fullArgString+=yytext;
5313 yyextra->lastCopyArgChar=0;
5314 yyextra->lastCommentInArgContext=YY_START;
5315 if (yytext[1]=='/')
5316 BEGIN( CopyArgCommentLine );
5317 else
5318 BEGIN( CopyArgComment );
5319 }
5320 }
5321 /* a non-special comment */
5322<ReadFuncArgType,ReadTempArgs>{CCS}{CCE} { /* empty comment */ }
5323<ReadFuncArgType,ReadTempArgs>{CCS} {
5324 yyextra->lastCContext = YY_START;
5325 BEGIN( SkipComment );
5326 }
5327<ReadFuncArgType,ReadTempArgs>{CPPC} {
5328 yyextra->lastCContext = YY_START;
5329 BEGIN( SkipCxxComment );
5330 }
5331 /*
5332<ReadFuncArgType,ReadTempArgs>"'#" { if (yyextra->insidePHP)
5333 REJECT;
5334 *yyextra->copyArgString+=yytext;
5335 yyextra->fullArgString+=yytext;
5336 }
5337<ReadFuncArgType,ReadTempArgs>"#" {
5338 if (!yyextra->insidePHP)
5339 REJECT;
5340 yyextra->lastCContext = YY_START;
5341 BEGIN( SkipCxxComment );
5342 }
5343 */
5344 /* ')' followed by a special comment */
5345<ReadFuncArgType>")"{BN}*({CCS}[*!]|{CPPC}[/!])"<" {
5346 lineCount(yyscanner);
5347 if (yyextra->currentArgumentContext==DefineEnd)
5348 {
5349 // for defines we interpret a comment
5350 // as documentation for the define
5351 int i;for (i=(int)yyleng-1;i>0;i--)
5352 {
5353 unput(yytext[i]);
5354 }
5355 *yyextra->copyArgString+=*yytext;
5356 yyextra->fullArgString+=*yytext;
5357 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5358 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
5359 BEGIN( yyextra->currentArgumentContext );
5360 }
5361 else
5362 {
5363 // for functions we interpret a comment
5364 // as documentation for the yyextra->last argument
5365 yyextra->lastCopyArgChar=*yytext;
5366 QCString text=&yytext[1];
5367 text=text.stripWhiteSpace();
5368 yyextra->lastCommentInArgContext=YY_START;
5369 yyextra->fullArgString+=text;
5370 if (text.find("//")!=-1)
5371 BEGIN( CopyArgCommentLine );
5372 else
5373 BEGIN( CopyArgComment );
5374 }
5375 }
5376<CopyArgComment>^{B}*"*"+/{BN}+
5377<CopyArgComment>[^\n\\\@\*]+ { yyextra->fullArgString+=yytext; }
5378<CopyArgComment>{CCE} { yyextra->fullArgString+=yytext;
5379 if (yyextra->lastCopyArgChar!=0)
5380 unput(yyextra->lastCopyArgChar);
5381 BEGIN( yyextra->lastCommentInArgContext );
5382 }
5383<CopyArgCommentLine>\n { yyextra->fullArgString+=yytext;
5384 lineCount(yyscanner);
5385 if (yyextra->lastCopyArgChar!=0)
5386 unput(yyextra->lastCopyArgChar);
5387 BEGIN( yyextra->lastCommentInArgContext );
5388 }
5389<CopyArgCommentLine>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
5390 yyextra->docBlockName="uml";
5391 yyextra->fullArgString+=yytext;
5392 BEGIN(CopyArgVerbatim);
5393 }
5394<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!)
5395 yyextra->docBlockName=&yytext[1];
5396 yyextra->fullArgString+=yytext;
5397 BEGIN(CopyArgVerbatim);
5398 }
5399<CopyArgCommentLine>{CMD}("f$"|"f["|"f{"|"f(") {
5400 yyextra->docBlockName=&yytext[1];
5401 if (yyextra->docBlockName.at(1)=='[')
5402 {
5403 yyextra->docBlockName.at(1)=']';
5404 }
5405 if (yyextra->docBlockName.at(1)=='{')
5406 {
5407 yyextra->docBlockName.at(1)='}';
5408 }
5409 if (yyextra->docBlockName.at(1)=='(')
5410 {
5411 yyextra->docBlockName.at(1)=')';
5412 }
5413 yyextra->fullArgString+=yytext;
5414 BEGIN(CopyArgVerbatim);
5415 }
5416<CopyArgVerbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"endmermaid"|"enduml"|"endcode")/[^a-z_A-Z0-9\-] { // end of verbatim block
5417 yyextra->fullArgString+=yytext;
5418 if (&yytext[4]==yyextra->docBlockName)
5419 {
5420 yyextra->docBlockName="";
5421 BEGIN(CopyArgCommentLine);
5422 }
5423 }
5424<CopyArgVerbatim>{CMD}("f$"|"f]"|"f}"|"f)") { // end of verbatim block
5425 yyextra->fullArgString+=yytext;
5426 if (yyextra->docBlockName==&yytext[1])
5427 {
5428 yyextra->docBlockName="";
5429 BEGIN(CopyArgCommentLine);
5430 }
5431 }
5432<CopyArgCommentLine>[^\\\@\n]+ { yyextra->fullArgString+=yytext; }
5433<CopyArgCommentLine>. { yyextra->fullArgString+=*yytext; }
5434<CopyArgComment,CopyArgVerbatim>\n { yyextra->fullArgString+=*yytext; lineCount(yyscanner); }
5435<CopyArgComment,CopyArgVerbatim>. { yyextra->fullArgString+=*yytext; }
5436<CopyArgComment>{CMD}("brief"|"short"){B}+ {
5437 warn(yyextra->fileName,yyextra->yyLineNr,
5438 "Ignoring {:c}brief command inside argument documentation",*yytext
5439 );
5440 yyextra->fullArgString+=' ';
5441 }
5442<ReadTempArgs>"<" {
5443 *yyextra->copyArgString+=*yytext;
5444 yyextra->fullArgString+=*yytext;
5445 yyextra->argSharpCount=1;
5446 BEGIN( CopyArgSharp );
5447 }
5448<ReadTempArgs>">" {
5449 *yyextra->copyArgString+=*yytext;
5450 yyextra->fullArgString+=*yytext;
5451 //printf("end template list '%s'\n",qPrint(*yyextra->copyArgString));
5452 *yyextra->currentArgumentList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5453 handleParametersCommentBlocks(yyscanner,yyextra->current->tArgLists.back());
5454 BEGIN( yyextra->currentArgumentContext );
5455 }
5456<CopyArgRound>"(" {
5457 yyextra->argRoundCount++;
5458 *yyextra->copyArgString+=*yytext;
5459 yyextra->fullArgString+=*yytext;
5460 }
5461<CopyArgRound>")" {
5462 *yyextra->copyArgString+=*yytext;
5463 yyextra->fullArgString+=*yytext;
5464 if (yyextra->argRoundCount>0)
5465 yyextra->argRoundCount--;
5466 else
5467 BEGIN( yyextra->lastCopyArgContext );
5468 }
5469<CopyArgSquare>"[" {
5470 yyextra->argSquareCount++;
5471 *yyextra->copyArgString+=*yytext;
5472 yyextra->fullArgString+=*yytext;
5473 }
5474<CopyArgSquare>"]" {
5475 *yyextra->copyArgString+=*yytext;
5476 yyextra->fullArgString+=*yytext;
5477 if (yyextra->argSquareCount>0)
5478 yyextra->argSquareCount--;
5479 else
5480 BEGIN( yyextra->lastCopyArgContext );
5481 }
5482<CopyArgSharp>"(" {
5483 *yyextra->copyArgString+=*yytext;
5484 yyextra->fullArgString+=*yytext;
5485 yyextra->argRoundCount=0;
5486 yyextra->lastCopyArgContext = YY_START;
5487 BEGIN( CopyArgRound );
5488 }
5489<CopyArgSharp>"<" {
5490 yyextra->argSharpCount++;
5491 //printf("yyextra->argSharpCount++=%d copy\n",yyextra->argSharpCount);
5492 *yyextra->copyArgString+=*yytext;
5493 yyextra->fullArgString+=*yytext;
5494 }
5495<CopyArgSharp>">" {
5496 *yyextra->copyArgString+=*yytext;
5497 yyextra->fullArgString+=*yytext;
5498 yyextra->argSharpCount--;
5499 if (yyextra->argSharpCount>0)
5500 {
5501 //printf("yyextra->argSharpCount--=%d copy\n",yyextra->argSharpCount);
5502 }
5503 else
5504 {
5505 BEGIN( ReadTempArgs );
5506 //printf("end of yyextra->argSharpCount\n");
5507 }
5508 }
5509<CopyArgString,CopyArgPHPString>\\. {
5510 *yyextra->copyArgString+=yytext;
5511 yyextra->fullArgString+=yytext;
5512 }
5513<CopyArgString>\" {
5514 *yyextra->copyArgString+=*yytext;
5515 yyextra->fullArgString+=*yytext;
5516 BEGIN( yyextra->lastCopyArgStringContext );
5517 }
5518<CopyArgPHPString>\' {
5519 *yyextra->copyArgString+=*yytext;
5520 yyextra->fullArgString+=*yytext;
5521 BEGIN( yyextra->lastCopyArgStringContext );
5522 }
5523<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>{CHARLIT} {
5524 if (yyextra->insidePHP)
5525 {
5526 REJECT;
5527 }
5528 else
5529 {
5530 *yyextra->copyArgString+=yytext;
5531 yyextra->fullArgString+=yytext;
5532 }
5533 }
5534<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>\' {
5535 *yyextra->copyArgString+=yytext;
5536 yyextra->fullArgString+=yytext;
5537 if (yyextra->insidePHP)
5538 {
5539 yyextra->lastCopyArgStringContext=YY_START;
5540 BEGIN(CopyArgPHPString);
5541 }
5542 }
5543<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>"<="|">="|"<=>" {
5544 *yyextra->copyArgString+=yytext;
5545 yyextra->fullArgString+=yytext;
5546 }
5547<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>\n {
5548 lineCount(yyscanner);
5549 *yyextra->copyArgString+=*yytext;
5550 yyextra->fullArgString+=*yytext;
5551 }
5552<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>{ID} {
5553 *yyextra->copyArgString+=yytext;
5554 yyextra->fullArgString+=yytext;
5555 }
5556<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>. {
5557 *yyextra->copyArgString+=*yytext;
5558 yyextra->fullArgString+=*yytext;
5559 }
5560
5561
5562
5563 /*------------------------------------------------------------------------*/
5564
5565
5566<FuncRound>"(" { yyextra->current->args += *yytext ;
5567 ++yyextra->roundCount ;
5568 }
5569<FuncRound>")" { yyextra->current->args += *yytext ;
5570 if ( yyextra->roundCount )
5571 --yyextra->roundCount ;
5572 else
5573 BEGIN( FuncQual ) ;
5574 }
5575 /*
5576<FuncQual>"#" { if (yyextra->insidePHP)
5577 REJECT;
5578 yyextra->lastCPPContext = YY_START;
5579 BEGIN(SkipCPP);
5580 }
5581 */
5582<FuncQual>[{:;,] {
5583 if ( qstrcmp(yytext,";")==0 &&
5584 ((yyextra->insideJS || yyextra->insidePHP) &&
5585 !containsWord(yyextra->current->type,"function")) )
5586 {
5587 yyextra->current->reset();
5588 initEntry(yyscanner);
5589 BEGIN( FindMembers );
5590 }
5591 else
5592 {
5593 unput(*yytext); BEGIN( SFunction );
5594 }
5595 }
bool containsWord(const QCString &str, const char *word)
returns TRUE iff string s contains word w
Definition util.cpp:5013
5596<FuncQual>{BN}*"abstract"{BN}* { // pure virtual member function
5597 lineCount(yyscanner) ;
5598 yyextra->current->virt = Specifier::Pure;
5599 yyextra->current->args += " override ";
5600 }
5601<FuncQual,TrailingReturn>{BN}*"override"{BN}* { // C++11 overridden virtual member function
5602 lineCount(yyscanner) ;
5603 yyextra->current->spec.setOverride(true);
5604 yyextra->current->args += " override ";
5605 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5606 BEGIN(FuncQual);
5607 }
5608<FuncQual,TrailingReturn>{BN}*"final"{BN}* { // C++11 final method
5609 lineCount(yyscanner) ;
5610 yyextra->current->spec.setFinal(true);
5611 yyextra->current->args += " final ";
5612 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5613 BEGIN(FuncQual);
5614 }
5615<FuncQual>{BN}*"sealed"{BN}* { // sealed member function
5616 lineCount(yyscanner) ;
5617 yyextra->current->spec.setSealed(true);
5618 yyextra->current->args += " sealed ";
5619 }
5620<FuncQual>{BN}*"new"{BN}* { // new member function
5621 lineCount(yyscanner) ;
5622 yyextra->current->spec.setNew(true);
5623 yyextra->current->args += " new ";
5624 }
5625<FuncQual>{BN}*"const"{BN}* { // const member function
5626 lineCount(yyscanner) ;
5627 yyextra->current->args += " const ";
5628 yyextra->current->argList.setConstSpecifier(TRUE);
5629 }
5630<FuncQual>{BN}*"volatile"{BN}* { // volatile member function
5631 lineCount(yyscanner) ;
5632 yyextra->current->args += " volatile ";
5633 yyextra->current->argList.setVolatileSpecifier(TRUE);
5634 }
5635<FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier
5636 lineCount(yyscanner) ;
5637 yyextra->current->args += " noexcept ";
5638 yyextra->current->spec.setNoExcept(true);
5639 }
5640<FuncQual>{BN}*"noexcept"{BN}*"("{B}*false{B}*")"{BN}* { // noexcept(false) expression
5641 lineCount(yyscanner) ;
5642 yyextra->current->args += " noexcept(false)";
5643 }
5644<FuncQual>{BN}*"noexcept"{BN}*"(" { // noexcept expression
5645 lineCount(yyscanner) ;
5646 yyextra->current->args += " noexcept(";
5647 yyextra->current->spec.setNoExcept(true);
5648 yyextra->lastRoundContext=FuncQual;
5649 yyextra->pCopyRoundString=&yyextra->current->args;
5650 yyextra->roundCount=0;
5651 BEGIN(CopyRound);
5652 }
5653<FuncQual>{BN}*"&" {
5654 yyextra->current->args += " &";
5655 yyextra->current->argList.setRefQualifier(RefQualifierType::LValue);
5656 }
5657<FuncQual>{BN}*"&&" {
5658 yyextra->current->args += " &&";
5659 yyextra->current->argList.setRefQualifier(RefQualifierType::RValue);
5660 }
5661
5662<FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function
5663 lineCount(yyscanner) ;
5664 yyextra->current->args += " = 0";
5665 yyextra->current->virt = Specifier::Pure;
5666 yyextra->current->argList.setPureSpecifier(TRUE);
5667 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5668 BEGIN(FuncQual);
5669 }
5670<FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member
5671 lineCount(yyscanner);
5672 yyextra->current->args += " = delete";
5673 yyextra->current->spec.setDelete(true);
5674 yyextra->current->argList.setIsDeleted(TRUE);
5675 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5676 BEGIN(FuncQual);
5677 }
5678<FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator
5679 lineCount(yyscanner);
5680 yyextra->current->args += " = default";
5681 yyextra->current->spec.setDefault(true);
5682 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5683 BEGIN(FuncQual);
5684 }
5685<FuncQual>{BN}*"->"{BN}* {
5686 lineCount(yyscanner);
5687 yyextra->current->argList.setTrailingReturnType(" -> ");
5688 yyextra->current->args += " -> ";
5689 yyextra->roundCount=0;
5690 BEGIN(TrailingReturn);
5691 }
5692<TrailingReturn>[{;] {
5693 if (yyextra->roundCount>0) REJECT;
5694 unput(*yytext);
5695 yyextra->current->argList.finishTrailingReturnType();
5696 BEGIN(FuncQual);
5697 }
5698<TrailingReturn>"requires"{BN}+ {
5699 if (yyextra->insideJava) REJECT;
5700 yyextra->requiresContext = FuncQual;
5701 yyextra->current->req+=' ';
5702 yyextra->current->argList.finishTrailingReturnType();
5703 BEGIN(RequiresClause);
5704 }
5705<TrailingReturn>"(" {
5706 yyextra->roundCount++;
5707 yyextra->current->argList.appendTrailingReturnType(yytext);
5708 yyextra->current->args+=yytext;
5709 }
5710<TrailingReturn>")" {
5711 if (yyextra->roundCount>0)
5712 {
5713 yyextra->roundCount--;
5714 }
5715 else
5716 {
5717 warn(yyextra->fileName,yyextra->yyLineNr,
5718 "Found ')' without opening '(' for trailing return type '{})...'",
5719 yyextra->current->argList.trailingReturnType());
5720 }
5721 yyextra->current->argList.appendTrailingReturnType(yytext);
5722 yyextra->current->args+=yytext;
5723 }
5724<TrailingReturn>. {
5725 yyextra->current->argList.appendTrailingReturnType(yytext);
5726 yyextra->current->args+=yytext;
5727 }
5728<TrailingReturn>\n {
5729 lineCount(yyscanner);
5730 yyextra->current->argList.appendTrailingReturnType(yytext);
5731 yyextra->current->args+=' ';
5732 }
5733<FuncRound,FuncFunc>{BN}*","{BN}* {
5734 lineCount(yyscanner) ;
5735 yyextra->current->args += ", " ;
5736 }
5737<FuncQual,FuncRound,FuncFunc>{BN}+ {
5738 lineCount(yyscanner) ;
5739 yyextra->current->args += ' ' ;
5740 }
5741<SFunction,FuncQual,FuncRound,FuncFunc>"#" { if (yyextra->insidePHP)
5742 REJECT;
5743 yyextra->lastCPPContext = YY_START;
5744 BEGIN(SkipCPP);
5745 }
5746<FuncQual>"=>" {
5747 if (!yyextra->insideCS)
5748 REJECT;
5749 // Expression body function
5750 unput('=');
5751 BEGIN(SFunction);
5752 }
5753<FuncQual>"=" {
5754 if (yyextra->insideCli && yyextra->current_root->section.isCompound())
5755 {
5756 BEGIN(CliOverride);
5757 }
5758 else
5759 {
5760 // typically an initialized function pointer
5761 yyextra->lastInitializerContext=YY_START;
5762 yyextra->sharpCount=0;
5763 yyextra->initBracketCount=0;
5764 yyextra->current->initializer.str(yytext);
5765 BEGIN(ReadInitializer);
5766 }
5767 }
5768<ReadExpressionBody>";" {
5769 if (!yyextra->current->sli.empty() && yyextra->previous) // copy special list items
5770 {
5771 yyextra->previous->sli = yyextra->current->sli;
5772 yyextra->current->sli.clear();
5773 }
5774 if (yyextra->previous) yyextra->previous->endBodyLine=yyextra->yyLineNr;
5775 BEGIN(FindMembers);
5776 }
5777<CliOverride>{ID} {
5778 }
5779<CliOverride>"{" {
5780 unput(*yytext);
5781 BEGIN(FuncQual);
5782 }
5783<CliOverride>\n {
5784 lineCount(yyscanner);
5785 }
5786<CliOverride>. {
5787 }
5788<FuncQual>{ID} {
5789 if (yyextra->insideCpp && qstrcmp(yytext,"requires")==0)
5790 {
5791 // c++20 trailing requires clause
5792 yyextra->requiresContext = YY_START;
5793 if (!yyextra->current->req.isEmpty())
5794 {
5795 yyextra->current->req+=" && ";
5796 }
5797 BEGIN(RequiresClause);
5798 }
5799 else if (yyextra->insideCS && qstrcmp(yytext,"where")==0)
5800 {
5801 // type constraint for a method
5802 yyextra->current->typeConstr.clear();
5803 yyextra->current->typeConstr.push_back(Argument());
5804 yyextra->lastCSConstraint = YY_START;
5805 BEGIN( CSConstraintName );
5806 }
5807 else if (checkForKnRstyleC(yyscanner)) // K&R style C function
5808 {
5809 yyextra->current->args = yytext;
5810 yyextra->oldStyleArgType.clear();
5811 BEGIN(OldStyleArgs);
5812 }
5813 else
5814 {
5815 yyextra->current->args += yytext;
5816 }
5817 }
5818<OldStyleArgs>[,;] {
5819 QCString oldStyleArgPtr;
5820 QCString oldStyleArgName;
5821 splitKnRArg(yyscanner,oldStyleArgPtr,oldStyleArgName);
5822 QCString doc,brief;
5823 if (yyextra->current->doc!=yyextra->docBackup)
5824 {
5825 doc=yyextra->current->doc;
5826 yyextra->current->doc=yyextra->docBackup;
5827 }
5828 if (yyextra->current->brief!=yyextra->briefBackup)
5829 {
5830 brief=yyextra->current->brief;
5831 yyextra->current->brief=yyextra->briefBackup;
5832 }
5833 addKnRArgInfo(yyscanner,yyextra->oldStyleArgType+oldStyleArgPtr,
5834 oldStyleArgName,brief,doc);
5835 yyextra->current->args.clear();
5836 if (*yytext==';') yyextra->oldStyleArgType.clear();
5837 }
5838<OldStyleArgs>{ID} { yyextra->current->args += yytext; }
5839<OldStyleArgs>"{" {
5840 if (yyextra->current->argList.empty())
5841 {
5842 yyextra->current->argList.setNoParameters(TRUE);
5843 }
5844 yyextra->current->args = argListToString(yyextra->current->argList);
5845 unput('{');
5846 BEGIN(FuncQual);
5847 }
5848<OldStyleArgs>. { yyextra->current->args += *yytext; }
5849<FuncQual,FuncRound,FuncFunc>\" {
5850 if (yyextra->insideIDL && yyextra->insideCppQuote)
5851 {
5852 BEGIN(EndCppQuote);
5853 }
5854 else
5855 {
5856 yyextra->current->args += *yytext;
5857 }
5858 }
5859<FuncQual,FuncRound,FuncFunc>. { yyextra->current->args += *yytext; }
5860<FuncQual>{BN}*"try:" |
5861<FuncQual>{BN}*"try"{BN}+ { /* try-function-block */
5862 yyextra->insideTryBlock=TRUE;
5863 lineCount(yyscanner);
5864 if (yytext[yyleng-1]==':')
5865 {
5866 unput(':');
5867 BEGIN( SFunction );
5868 }
5869 }
5870<FuncQual>{BN}*"throw"{BN}*"(" { // C++ style throw clause
5871 yyextra->current->exception = " throw (" ;
5872 yyextra->roundCount=0;
5873 lineCount(yyscanner) ;
5874 BEGIN( ExcpRound ) ;
5875 }
5876<FuncQual>{BN}*"raises"{BN}*"(" {
5877 yyextra->current->exception = " raises (" ;
5878 lineCount(yyscanner) ;
5879 yyextra->roundCount=0;
5880 BEGIN( ExcpRound ) ;
5881 }
5882<FuncQual>{BN}*"throws"{BN}+ { // Java style throw clause
5883 yyextra->current->exception = " throws " ;
5884 lineCount(yyscanner) ;
5885 BEGIN( ExcpList );
5886 }
5887<ExcpRound>"(" { yyextra->current->exception += *yytext ;
5888 ++yyextra->roundCount ;
5889 }
5890<ExcpRound>")" { yyextra->current->exception += *yytext ;
5891 if ( yyextra->roundCount )
5892 --yyextra->roundCount ;
5893 else
5894 BEGIN( FuncQual ) ;
5895 }
5896<ExcpRound>. {
5897 yyextra->current->exception += *yytext;
5898 }
5899<ExcpList>"{" {
5900 unput('{'); BEGIN( FuncQual );
5901 }
5902<ExcpList>";" {
5903 unput(';'); BEGIN( FuncQual );
5904 }
5905<ExcpList>"\n" {
5906 yyextra->current->exception += ' ';
5907 lineCount(yyscanner);
5908 }
5909<ExcpList>. {
5910 yyextra->current->exception += *yytext;
5911 }
5912<SFunction>"(" { yyextra->current->type += yyextra->current->name ;
5913 yyextra->current->name = yyextra->current->args ;
5914 yyextra->current->args = yytext ;
5915 yyextra->roundCount=0;
5916 BEGIN( FuncRound ) ;
5917 }
5918<SFunction>":" {
5919 if (!yyextra->insidePHP) BEGIN(SkipInits);
5920 }
5921<SFunction>[=;{,] {
5922 yyextra->current->name=removeRedundantWhiteSpace(yyextra->current->name);
5923 yyextra->current->type=removeRedundantWhiteSpace(yyextra->current->type);
5924 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
5925 yyextra->current->fileName = yyextra->fileName;
5926 yyextra->current->startLine = yyextra->yyBegLineNr;
5927 yyextra->current->startColumn = yyextra->yyBegColNr;
5928 static const reg::Ex re(R"(\‍([^)]*[*&][^)]*\))"); // e.g. (...*...)
5930 std::string type = yyextra->current->type.str();
5931 int ti=-1;
5932 if (reg::search(type,match,re))
5933 {
5934 ti = (int)match.position();
5935 }
5936 if (ti!=-1)
5937 {
5938 int di = yyextra->current->type.find("decltype(");
5939 if (di!=-1 && di<ti) // decltype(...(...*...) -> normal return type
5940 {
5941 ti=-1;
5942 }
5943 }
5944 int ts=yyextra->current->type.find('<');
5945 int te=yyextra->current->type.findRev('>');
5946
5947 // bug677315: A<int(void *, char *)> get(); is not a function pointer
5948 bool startsWithTypedef = yyextra->current->type.startsWith("typedef ");
5949 bool isFunction = ti==-1 || // not a (...*...) pattern
5950 (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list
5951 bool isVariable = !yyextra->current->type.isEmpty() &&
5952 (!isFunction || startsWithTypedef);
5953
5954 //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n",
5955 // qPrint(yyextra->current->type),ts,te,ti,isFunction);
5956
5957 if (*yytext!=';' || yyextra->current_root->section.isCompound())
5958 {
5959 if (isVariable)
5960 {
5961 //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5962 if (yyextra->isTypedef && !startsWithTypedef)
5963 {
5964 yyextra->current->type.prepend("typedef ");
5965 }
5966 yyextra->current->section = EntryType::makeVariable() ;
5967 }
5968 else
5969 {
5970 //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5971 yyextra->current->section = EntryType::makeFunction() ;
5972 yyextra->current->proto = *yytext==';';
5973 }
5974 }
5975 else // a global function prototype or function variable
5976 {
5977 //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5978 if (isVariable)
5979 {
5980 if (yyextra->isTypedef && !startsWithTypedef)
5981 {
5982 yyextra->current->type.prepend("typedef ");
5983 }
5984 //printf("Scanner.l: found function variable!\n");
5985 yyextra->current->section = EntryType::makeVariable();
5986 }
5987 else
5988 {
5989 //printf("Scanner.l: found prototype\n");
5990 yyextra->current->section = EntryType::makeFunction();
5991 yyextra->current->proto = TRUE;
5992 }
5993 }
5994 //printf("Adding entry '%s'\n",qPrint(yyextra->current->name));
5995 if ( yyextra->insidePHP)
5996 {
5997 if (findAndRemoveWord(yyextra->current->type,"final"))
5998 {
5999 yyextra->current->spec.setFinal(true);
6000 }
6001 if (findAndRemoveWord(yyextra->current->type,"abstract"))
6002 {
6003 yyextra->current->spec.setAbstract(true);
6004 }
6005 }
6006 if ( yyextra->insidePHP && !containsWord(yyextra->current->type,"function"))
6007 {
6008 initEntry(yyscanner);
6009 if ( *yytext == '{' )
6010 {
6011 yyextra->lastCurlyContext = FindMembers;
6012 yyextra->curlyCount=0;
6013 BEGIN( SkipCurly );
6014 }
6015 else
6016 {
6017 BEGIN( FindMembers );
6018 }
6019 }
6020 else
6021 {
6022 if ( yyextra->insidePHP)
6023 {
6024 findAndRemoveWord(yyextra->current->type,"function");
6025 }
6026 yyextra->previous = yyextra->current;
6027 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6028 initEntry(yyscanner);
6029 // Objective C 2.0: Required/Optional section
6030 if (yyextra->previous->spec.isOptional() || yyextra->previous->spec.isRequired())
6031 {
6032 yyextra->current->spec.setOptional(true).setRequired(true);
6033 }
6034 yyextra->lastCurlyContext = FindMembers;
6035 if ( *yytext == ',' )
6036 {
6037 yyextra->current->type = stripFuncPtr(yyextra->previous->type);
6038 }
6039 if ( *yytext == '{' )
6040 {
6041 if ( !yyextra->insidePHP && yyextra->current_root->section.isCompound() )
6042 {
6043 yyextra->previous->spec.setInline(true);
6044 }
6045 yyextra->curlyCount=0;
6046 BEGIN( SkipCurly ) ;
6047 }
6048 else if ( *yytext == '=' ) // C# Expression Body
6049 {
6050 yyextra->previous->spec.setInline(true);
6051 yyextra->curlyCount=0;
6052 BEGIN( ReadExpressionBody );
6053 }
6054 else
6055 {
6056 if (!yyextra->previous->section.isVariable())
6057 yyextra->previous->bodyLine=-1; // a function/member declaration
6058 BEGIN( FindMembers ) ;
6059 }
6060 }
6061 }
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
6062<SkipInits>">"{BN}*"{" { // C++11 style initializer (see bug 790788)
6063 lineCount(yyscanner);
6064 yyextra->curlyCount=1;
6065 BEGIN(SkipC11Inits);
6066 }
6067<SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647)
6068 lineCount(yyscanner);
6069 yyextra->curlyCount=1;
6070 BEGIN(SkipC11Inits);
6071 }
6072<SkipC11Inits>"{" {
6073 ++yyextra->curlyCount;
6074 }
6075<SkipC11Inits>"}" {
6076 if ( --yyextra->curlyCount<=0 )
6077 {
6078 BEGIN(SkipInits);
6079 }
6080 }
6081<SkipInits>"{" { // C++11 style initializer
6082 unput('{');
6083 BEGIN( SFunction );
6084 }
6085<SkipCurly>"{" {
6086 //addToBody(yytext);
6087 ++yyextra->curlyCount ;
6088 }
6089<SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */)
6090<SkipCurly>"}" {
6091 //addToBody(yytext);
6092 if( yyextra->curlyCount )
6093 {
6094 --yyextra->curlyCount ;
6095 }
6096 else
6097 {
6098 if (!yyextra->current->sli.empty() && yyextra->previous) // copy special list items
6099 {
6100 yyextra->previous->sli = yyextra->current->sli;
6101 yyextra->current->sli.clear();
6102 }
6103 if (yyextra->previous) yyextra->previous->endBodyLine=yyextra->yyLineNr;
6104 BEGIN( yyextra->lastCurlyContext ) ;
6105 }
6106 }
6107<SkipCurly>"}"{BN}*{DCOMM}"<" {
6108 lineCount(yyscanner);
6109 if ( yyextra->curlyCount )
6110 {
6111 //addToBody(yytext);
6112 --yyextra->curlyCount ;
6113 }
6114 else
6115 {
6116 yyextra->current->endBodyLine=yyextra->yyLineNr;
6117 yyextra->tempEntry = yyextra->current; // temporarily switch to the previous entry
6118 yyextra->current = yyextra->previous;
6119
6120 yyextra->docBlockContext = SkipCurlyEndDoc;
6121 yyextra->docBlockInBody = FALSE;
6122 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
6123 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
6124 yyextra->docBlock.str(std::string());
6125 yyextra->docBlockTerm = '}';
6126 if (yytext[yyleng-3]=='/')
6127 {
6128 startCommentBlock(yyscanner,TRUE);
6129 BEGIN( DocLine );
6130 }
6131 else
6132 {
6133 startCommentBlock(yyscanner,FALSE);
6134 BEGIN( DocBlock );
6135 }
6136 }
6137 }
6138<SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
6139 yyextra->docBlockContext = SkipCurlyEndDoc;
6140 yyextra->docBlockInBody = FALSE;
6141 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
6142 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
6143 yyextra->docBlock.str(std::string());
6144 yyextra->docBlockTerm = '}';
6145 if (yytext[yyleng-3]=='/')
6146 {
6147 startCommentBlock(yyscanner,TRUE);
6148 BEGIN( DocLine );
6149 }
6150 else
6151 {
6152 startCommentBlock(yyscanner,FALSE);
6153 BEGIN( DocBlock );
6154 }
6155 }
6156<SkipCurlyEndDoc>"}" {
6157 //addToBody("}");
6158 if (yyextra->tempEntry) // we can only switch back to yyextra->current if no new item was created
6159 {
6160 yyextra->current = yyextra->tempEntry;
6161 yyextra->tempEntry.reset();
6162 }
6163 BEGIN( yyextra->lastCurlyContext );
6164 }
6165<SkipCurly,ReadExpressionBody>\" {
6166 //addToBody(yytext);
6167 yyextra->lastStringContext=YY_START;
6168 BEGIN( SkipString );
6169 }
6170<SkipCurly>^{B}*"#" {
6171 if (yyextra->insidePHP)
6172 REJECT;
6173 //addToBody(yytext);
6174 BEGIN( SkipCurlyCpp );
6175 }
6176<SkipCurly,SkipC11Inits,SkipInits,ReadExpressionBody>\n {
6177 lineCount(yyscanner);
6178 //addToBody(yytext);
6179 }
6180<SkipCurly,SkipCurlyCpp,ReadInitializer,ReadInitializerPtr>"<<<" {
6181 if (!yyextra->insidePHP)
6182 {
6183 REJECT;
6184 }
6185 else
6186 {
6187 yyextra->lastHereDocContext = YY_START;
6188 BEGIN(HereDoc);
6189 }
6190 }
6191<SkipCurly,SkipCurlyCpp>{B}*{RAWBEGIN} {
6192 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
6193 yyextra->lastRawStringContext = YY_START;
6194 yyextra->dummyRawString.clear();
6195 yyextra->pCopyRawString = &yyextra->dummyRawString;
6196 *yyextra->pCopyRawString += yytext;
6197 BEGIN(RawString);
6198 }
6199<SkipCurly,SkipCurlyCpp>[^\n#"R'@\\/{}<\$]+ {
6200 lineCount(yyscanner); // for yyextra->column updates
6201 //addToBody(yytext);
6202 }
6203<SkipCurly,SkipCurlyCpp>"\$" {}
6204<SkipCurlyCpp>\n {
6205 //addToBody(yytext);
6206 lineCount(yyscanner);
6207 yyextra->lastCurlyContext = FindMembers;
6208 BEGIN( SkipCurly );
6209 }
6210<SkipCurlyCpp>\\‍[\r]*"\n"[\r]* {
6211 //addToBody(yytext);
6212 lineCount(yyscanner);
6213 }
6214<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,CopyC11Attribute,ReadExpressionBody>{CCS} {
6215 //addToBody(yytext);
6216 yyextra->lastCContext = YY_START;
6217 BEGIN(SkipComment);
6218 }
6219<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,CopyC11Attribute,ReadExpressionBody>{CPPC} {
6220 //addToBody(yytext);
6221 yyextra->lastCContext = YY_START;
6222 BEGIN(SkipCxxComment);
6223 }
6224<SkipInits,SkipC11Inits>"(" {
6225 yyextra->roundCount=0;
6226 yyextra->lastSkipRoundContext=YY_START;
6227 BEGIN(SkipRound);
6228 }
6229<SkipInits,SkipC11Inits>\" {
6230 yyextra->lastStringContext=YY_START;
6231 BEGIN( SkipString );
6232 }
6233<SkipInits>; {
6234 warn(yyextra->fileName,yyextra->yyLineNr,
6235 "Found ';' while parsing initializer list! "
6236 "(doxygen could be confused by a macro call without semicolon)"
6237 );
6238 BEGIN( FindMembers );
6239 }
6240<SkipInits,SkipCurly,SkipCurlyCpp>"#" {
6241 if (!yyextra->insidePHP)
6242 REJECT;
6243 //addToBody(yytext);
6244 yyextra->lastCContext = YY_START;
6245 BEGIN(SkipCxxComment);
6246 }
6247<SkipInits,SkipCurly,SkipCurlyCpp,ReadExpressionBody>@\" {
6248 if (!yyextra->insideCS) REJECT;
6249 // C# verbatim string
6250 // we want to discard the string, due to reuse of states we need a dummy stream
6251 yyextra->lastSkipVerbStringContext=YY_START;
6252 yyextra->pSkipVerbString=&yyextra->dummyTextStream;
6253 yyextra->dummyTextStream.clear(); // remove old data so it won't grow too much
6254 BEGIN(SkipVerbString);
6255 }
6256<SkipInits,SkipCurly,SkipCurlyCpp,ReadExpressionBody>{CHARLIT} {
6257 if (yyextra->insidePHP) REJECT;
6258 }
6259<SkipInits,SkipCurly,SkipCurlyCpp>\' {
6260 if (yyextra->insidePHP)
6261 {
6262 yyextra->lastStringContext=YY_START;
6263 BEGIN(SkipPHPString);
6264 }
6265 }
6266<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,ReadExpressionBody>. { }
6267<SkipString,SkipPHPString>\\. { }
6268<SkipString>\" {
6269 BEGIN( yyextra->lastStringContext );
6270 }
6271<SkipPHPString>\' {
6272 BEGIN( yyextra->lastStringContext );
6273 }
6274<SkipString,SkipPHPString>{CCS}|{CCE}|{CPPC} { }
6275<SkipString,SkipPHPString>\n {
6276 lineCount(yyscanner);
6277 }
6278<SkipString>"[[" { }
6279<SkipString,SkipPHPString>. { }
6280<CompoundName>":" { // for "class : public base {} var;" construct, see bug 608359
6281 unput(':');
6282 BEGIN(ClassVar);
6283 }
6284<CompoundName>";" {
6285 yyextra->current->section = EntryType::makeEmpty() ;
6286 yyextra->current->type.clear() ;
6287 yyextra->current->name.clear() ;
6288 yyextra->current->args.clear() ;
6289 yyextra->current->argList.clear();
6290 BEGIN( FindMembers ) ;
6291 }
6292<Bases>";" {
6293 if (yyextra->insideIDL && (yyextra->current->spec.isSingleton() || yyextra->current->spec.isService()))
6294 {
6295 // in UNO IDL a service or singleton may be defined
6296 // completely like this: "service Foo : XFoo;"
6297 if (!yyextra->current->name.isEmpty() && !yyextra->current_root->name.isEmpty())
6298 {
6299 prependScope(yyscanner);
6300 }
6301 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6302 // there can be only one base class here
6303 if (!yyextra->baseName.isEmpty())
6304 {
6305 yyextra->current->extends.emplace_back(
6306 yyextra->baseName,Protection::Public,Specifier::Normal);
6307 yyextra->baseName.clear();
6308 }
6309 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
6310 initEntry(yyscanner);
6311 }
6312 else
6313 {
6314 yyextra->current->section = EntryType::makeEmpty() ;
6315 yyextra->current->type.clear() ;
6316 yyextra->current->name.clear() ;
6317 yyextra->current->args.clear() ;
6318 yyextra->current->argList.clear();
6319 }
6320 BEGIN( FindMembers ) ;
6321 }
6322<CompoundName>{SCOPENAME}/{BN}*"<" {
6323 yyextra->sharpCount = 0;
6324 yyextra->current->name = yytext ;
6325 storeClangId(yyscanner,yytext);
6326 if (yyextra->current->spec.isProtocol())
6327 {
6328 yyextra->current->name+="-p";
6329 }
6330 lineCount(yyscanner);
6331 yyextra->lastClassTemplSpecContext = ClassVar;
6332 if (yyextra->insideObjC) // protocol list
6333 {
6334 BEGIN( ObjCProtocolList );
6335 }
6336 else if (yyextra->insideCS) // C# generic class
6337 {
6338 //yyextra->current->name+="-g";
6339 BEGIN( CSGeneric );
6340 }
6341 else // C++ template specialization
6342 {
6343 yyextra->roundCount=0;
6344 BEGIN( ClassTemplSpec );
6345 }
6346 }
6347<CSGeneric>"<" {
6348 ArgumentList al;
6349 // check bug 612858 before enabling the next line
6350 //yyextra->current->spec |= Entry::Template;
6351 yyextra->current->tArgLists.push_back(al);
6352 yyextra->currentArgumentList = &yyextra->current->tArgLists.back();
6353 yyextra->templateStr="<";
6354 yyextra->current->name += "<";
6355 yyextra->fullArgString = yyextra->templateStr;
6356 yyextra->copyArgString = &yyextra->current->name;
6357 //yyextra->copyArgString = &yyextra->templateStr;
6358 yyextra->currentArgumentContext = ClassVar;
6359 BEGIN( ReadTempArgs );
6360 }
6361<ObjCProtocolList>"<" {
6362 yyextra->insideProtocolList=TRUE;
6363 BEGIN( Bases );
6364 }
6365<ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
6366 yyextra->current->name += yytext;
6367 lineCount(yyscanner);
6368 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
6369 {
6370 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6371 if (yyextra->current->spec.isProtocol())
6372 { // Objective-C protocol
6373 unput('{'); // fake start of body
6374 BEGIN( ClassVar );
6375 }
6376 else
6377 {
6378 BEGIN( yyextra->lastClassTemplSpecContext );
6379 }
6380 }
6381 }
6382<ClassTemplSpec>"<" {
6383 yyextra->current->name += yytext;
6384 if (yyextra->roundCount==0) yyextra->sharpCount++;
6385 }
6386<ClassTemplSpec>. {
6387 yyextra->current->name += yytext;
6388 }
6389<CompoundName>({SCOPENAME}|{CSSCOPENAME}){BN}*";" { // forward declaration?
6390 if (yyextra->insideCS && yyextra->current->type == "namespace")
6391 {
6392 // file scoped CSharp namespace
6393 lineCount(yyscanner);
6394 yyextra->current->name = substitute(yytext,".","::");
6395 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6396 yyextra->fakeNS++;
6397 unput('{'); // fake start of body
6398 BEGIN( ClassVar );
6399 }
6400 else if (!yyextra->current->tArgLists.empty())
6401 {
6402 // found a forward template declaration, this has
6403 // a purpose of its own
6404 yyextra->current->name = yytext;
6405 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6406 storeClangId(yyscanner,yyextra->current->name.data());
6407 //printf("template class declaration for %s!\n",qPrint(yyextra->current->name));
6408 QCString rn = yyextra->current_root->name;
6409 //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
6410 if (!yyextra->current->name.isEmpty() && !rn.isEmpty())
6411 {
6412 prependScope(yyscanner);
6413 }
6414 yyextra->current->spec.setForwardDecl(true);
6415 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6416 }
6417 else if (yyextra->insideIDL &&
6418 (((yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isService()) &&
6419 yyextra->current->spec.isInterface()) ||
6420 ((yyextra->current_root->spec.isService() || yyextra->current_root->spec.isSingleton()) &&
6421 yyextra->current->spec.isService())
6422 )
6423 )
6424 {
6425 // interface yyextra->inside of UNO IDL service or interface
6426 // service yyextra->inside of UNO IDL service or singleton
6427 // there may be documentation on the member,
6428 // so do not throw it away...
6429 yyextra->current->name = yytext;
6430 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6431 yyextra->current->section = yyextra->current->spec.isInterface() ? EntryType::makeExportedInterface()
6432 : EntryType::makeIncludedService();
6433// yyextra->current->section = EntryType::makeMemberDoc();
6434 yyextra->current->spec.setInterface(false).setService(false);
6435 // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from
6436 // different enums in this case...
6437 // granted only Optional and Interface are actually valid in this context but urgh...
6438 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6439 }
6440
6441 if (!(yyextra->insideCS && yyextra->current->type == "namespace"))
6442 {
6443 unput(';');
6444 yyextra->current->reset();
6445 initEntry(yyscanner);
6446 if (yyextra->insideObjC) // see bug746361
6447 {
6448 yyextra->language = yyextra->current->lang = SrcLangExt::Cpp;
6449 yyextra->insideObjC = FALSE;
6450 }
6451 if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
6452 {
6453 yyextra->current->type.prepend("typedef");
6454 }
6455 BEGIN( FindMembers );
6456 }
6457 }
Wrapper class for the Entry type.
Definition types.h:856
6458<CompoundName>{SCOPENAME}/{BN}*"(" {
6459 yyextra->current->name = yytext ;
6460 storeClangId(yyscanner,yytext);
6461 lineCount(yyscanner);
6462 if (yyextra->insideCpp && yyextra->current->name=="alignas") // C++11
6463 {
6464 yyextra->lastAlignAsContext = YY_START;
6465 BEGIN( AlignAs );
6466 }
6467 else
6468 {
6469 if (yyextra->current->spec.isProtocol())
6470 {
6471 yyextra->current->name += "-p";
6472 }
6473 BEGIN( ClassVar );
6474 }
6475 }
6476<AlignAs>"(" { yyextra->roundCount=0;
6477 BEGIN( AlignAsEnd );
6478 }
6479<AlignAs>\n { lineCount(yyscanner); }
6480<AlignAs>.
6481<AlignAsEnd>"(" { yyextra->roundCount++; }
6482<AlignAsEnd>")" { if (--yyextra->roundCount<0)
6483 {
6484 BEGIN( yyextra->lastAlignAsContext );
6485 }
6486 }
6487<AlignAsEnd>\n { lineCount(yyscanner); }
6488<AlignAsEnd>.
6489<ConceptName>{ID} {
6490 yyextra->current->name = yytext ;
6491 storeClangId(yyscanner,yytext);
6492 }
6493<ConceptName>"=" {
6494 yyextra->current->bodyLine = yyextra->yyLineNr;
6495 yyextra->current->bodyColumn = yyextra->yyColNr;
6496 yyextra->current->initializer.str(std::string());
6497 yyextra->lastInitializerContext = FindMembers;
6498 yyextra->sharpCount=0;
6499 yyextra->initBracketCount=0;
6500 BEGIN(ReadInitializer);
6501 }
6502<CompoundName>{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line
6503 // e.g. @protocol A,B;
6504 yyextra->current->reset();
6505 initEntry(yyscanner);
6506 }
6507<CompoundName>{SCOPENAME} {
6508 yyextra->current->name = yytext ;
6509 storeClangId(yyscanner,yytext);
6510 lineCount(yyscanner);
6511 if (yyextra->current->spec.isProtocol())
6512 {
6513 yyextra->current->name += "-p";
6514 }
6515 if (yyextra->current->spec.isProtocol() || yyextra->current->section.isObjcImpl())
6516 {
6517 unput('{'); // fake start of body
6518 }
6519 BEGIN( ClassVar );
6520 }
6521<CompoundName>({ID}{BN}*"::"{BN}*)+("inline"{BN}+({ID}{BN}*"::"{BN}*)*)+{ID} { // C++20 style nested inline namespace syntax
6522 if (yyextra->current->section.isNamespace())
6523 {
6524 yyextra->current->name = QCString(yytext).simplifyWhiteSpace();
6525 storeClangId(yyscanner,yyextra->current->name.data());
6526 lineCount(yyscanner);
6527 BEGIN( ClassVar );
6528 }
6529 else
6530 {
6531 REJECT;
6532 }
6533 }
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:190
6534<CompoundName>{CSSCOPENAME} { // C# style scope
6535 yyextra->current->name = substitute(yytext,".","::");
6536 lineCount(yyscanner);
6537 BEGIN( ClassVar );
6538 }
6539<ClassVar>{SCOPENAME}{BNopt}/"(" {
6540 if (yyextra->insideIDL && literal_at(yytext,"switch") && !isId(yytext[6]))
6541 {
6542 // Corba IDL style union
6543 yyextra->roundCount=0;
6544 BEGIN(SkipUnionSwitch);
6545 }
6546 else
6547 {
6548 addType(yyscanner);
6549 yyextra->yyBegColNr=yyextra->yyColNr;
6550 yyextra->yyBegLineNr=yyextra->yyLineNr;
6551 yyextra->current->name = yytext;
6552 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6553 storeClangId(yyscanner,yyextra->current->name.data());
6554 lineCount(yyscanner);
6555 BEGIN( FindMembers );
6556 }
6557 }
6558<ClassVar>"," {
6559 if (yyextra->isTypedef)
6560 {
6561 // multiple types in one typedef
6562 unput(',');
6563 yyextra->current->type.prepend("typedef ");
6564 BEGIN(FindMembers);
6565 }
6566 else
6567 {
6568 // Multiple class forward declaration
6569 }
6570 }
6571<ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
6572 if (yyextra->insideCli)
6573 {
6574 if (yytext[0]=='s') // sealed
6575 yyextra->current->spec.setSealedClass(true);
6576 else // abstract
6577 yyextra->current->spec.setAbstractClass(true);
6578 BEGIN( ClassVar );
6579 }
6580 else
6581 {
6582 REJECT;
6583 }
6584 }
6585<ClassVar>({ID}{BN}*"::"{BN}*)+{ID} {
6586 yyextra->yyBegColNr=yyextra->yyColNr;
6587 yyextra->yyBegLineNr=yyextra->yyLineNr;
6588 storeClangId(yyscanner,yytext);
6589 lineCount(yyscanner);
6590 if (yyextra->current->section.isEnum())
6591 { // found "enum a N::b" -> variable
6592 yyextra->current->section = EntryType::makeVariable() ;
6593 }
6594 yyextra->current->type += ' ' ;
6595 yyextra->current->type += yyextra->current->name ;
6596 yyextra->current->name = QCString(yytext).simplifyWhiteSpace();
6597
6598 if (nameIsOperator(yyextra->current->name))
6599 {
6600 BEGIN( Operator );
6601 }
6602 }
6603<ClassVar>{ID} {
6604 yyextra->yyBegColNr=yyextra->yyColNr;
6605 yyextra->yyBegLineNr=yyextra->yyLineNr;
6606 storeClangId(yyscanner,yytext);
6607 if (yyextra->insideIDL && qstrcmp(yytext,"switch")==0)
6608 {
6609 // Corba IDL style union
6610 yyextra->roundCount=0;
6611 BEGIN(SkipUnionSwitch);
6612 }
6613 else if ((yyextra->insideJava || yyextra->insidePHP || yyextra->insideJS || yyextra->insideSlice) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0))
6614 {
6615 yyextra->current->type.clear();
6616 yyextra->baseProt = Protection::Public;
6617 yyextra->baseVirt = Specifier::Normal;
6618 yyextra->baseName.clear();
6619 BEGIN( BasesProt ) ;
6620 }
6621 else if (yyextra->insideCS && qstrcmp(yytext,"where")==0) // C# type constraint
6622 {
6623 yyextra->current->typeConstr.clear();
6624 yyextra->current->typeConstr.push_back(Argument());
6625 yyextra->lastCSConstraint = YY_START;
6626 BEGIN( CSConstraintName );
6627 }
6628 else if (yyextra->insideCli && qstrcmp(yytext,"abstract")==0)
6629 {
6630 yyextra->current->spec.setAbstract(true);
6631 }
6632 else if (yyextra->insideCli && qstrcmp(yytext,"sealed")==0)
6633 {
6634 yyextra->current->spec.setSealed(true);
6635 }
6636 else if (qstrcmp(yytext,"final")==0)
6637 {
6638 yyextra->current->spec.setFinal(true);
6639 }
6640 else
6641 {
6642 if (yyextra->current->section.isEnum())
6643 { // found "enum a b" -> variable
6644 yyextra->current->section = EntryType::makeVariable() ;
6645 }
6646 yyextra->current->type += ' ' ;
6647 yyextra->current->type += yyextra->current->name ;
6648 yyextra->current->name = yytext ;
6649
6650 if (nameIsOperator(yyextra->current->name))
6651 {
6652 BEGIN( Operator );
6653 }
6654 }
6655 }
6656<ClassVar>[(\‍[] {
6657 if (yyextra->insideObjC && *yytext=='(') // class category
6658 {
6659 yyextra->current->name+='(';
6660 yyextra->current->spec.setCategory(true);
6661 BEGIN( ClassCategory );
6662 }
6663 else if (yyextra->insideCS && *yytext=='(') // C# 12 primary constructor
6664 {
6665 yyextra->current->args=yytext;
6666 yyextra->currentArgumentContext = ClassVar;
6667 yyextra->fullArgString = yyextra->current->args;
6668 yyextra->copyArgString = &yyextra->current->args;
6669 BEGIN( ReadFuncArgType ) ;
6670 }
6671 else
6672 {
6673 // probably a function anyway
6674 unput(*yytext);
6675 BEGIN( FindMembers );
6676 }
6677 }
6678<CSConstraintType,CSConstraintName>{CCS}{CCE} { /* empty comment */ }
6679<CSConstraintType,CSConstraintName>({CCS}[*!]|{CPPC}[/!])("<"?) { // special comment
6680 yyextra->fullArgString.clear();
6681 yyextra->lastCopyArgChar='#'; // end marker
6682 yyextra->lastCommentInArgContext=YY_START;
6683 if (yytext[1]=='/')
6684 BEGIN( CopyArgCommentLine );
6685 else
6686 BEGIN( CopyArgComment );
6687 }
6688<CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block
6689 yyextra->current->typeConstr.back().docs = yyextra->fullArgString;
6690 }
6691<CSConstraintType>"=>" { // end of type constraint reached
6692 // parse documentation of the constraints
6693 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6694 unput('>');
6695 unput('=');
6696 BEGIN( yyextra->lastCSConstraint );
6697 }
6698<CSConstraintType>"{" { // end of type constraint reached
6699 // parse documentation of the constraints
6700 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6701 unput('{');
6702 BEGIN( yyextra->lastCSConstraint );
6703 }
6704<CSConstraintType,CSConstraintName>";" {
6705 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6706 unput(';');
6707 BEGIN( yyextra->lastCSConstraint );
6708 }
6709<CSConstraintName>":" {
6710 BEGIN( CSConstraintType );
6711 }
6712<CSConstraintName>{ID} {
6713 // parameter name
6714 yyextra->current->typeConstr.back().name=yytext;
6715 }
6716<CSConstraintType>"where" { // another constraint for a different param
6717 yyextra->current->typeConstr.push_back(Argument());
6718 BEGIN( CSConstraintName );
6719 }
6720<CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
6721 if (yyextra->current->typeConstr.back().type.isEmpty())
6722 // first type constraint for this parameter
6723 {
6724 yyextra->current->typeConstr.back().type=yytext;
6725 }
6726 else // new type constraint for same parameter
6727 {
6728 QCString name = yyextra->current->typeConstr.back().name;
6729 yyextra->current->typeConstr.push_back(Argument());
6730 yyextra->current->typeConstr.back().name=name;
6731 yyextra->current->typeConstr.back().type=yytext;
6732 }
6733 }
6734<CSConstraintName,CSConstraintType>\n {
6735 lineCount(yyscanner);
6736 }
6737<CSConstraintName,CSConstraintType>. {
6738 }
6739<ClassCategory>{ID} {
6740 yyextra->current->name+=yytext;
6741 }
6742<ClassCategory>")"/{BN}*"{" {
6743 yyextra->current->name+=')';
6744 BEGIN( ClassVar );
6745 }
6746<ClassCategory>")"/{BN}*"<" {
6747 yyextra->current->name+=')';
6748 BEGIN( ObjCProtocolList );
6749 }
6750<ClassCategory>")" {
6751 yyextra->current->name+=')';
6752 if (yyextra->current->spec.isProtocol() || yyextra->current->section.isObjcImpl())
6753 {
6754 unput('{'); // fake start of body
6755 }
6756 else // category has no variables so push back an empty body
6757 {
6758 unput('}');
6759 unput('{');
6760 }
6761 BEGIN( ClassVar );
6762 }
6763<ClassVar>":" {
6764 if (yyextra->current->section.isVariable()) // enum A B:2, see bug 748208
6765 {
6766 yyextra->current->bitfields+=":";
6767 yyextra->current->args.clear();
6768 BEGIN(BitFields);
6769 }
6770 else if (yyextra->current->section.isEnum()) // enum E:2, see bug 313527,
6771 // or C++11 style enum: 'E : unsigned int {...}'
6772 {
6773 yyextra->current->args.clear();
6774 BEGIN(EnumBaseType);
6775 }
6776 else
6777 {
6778 yyextra->current->type.clear();
6779 if (yyextra->current->spec.isInterface() ||
6780 yyextra->current->spec.isStruct() ||
6781 yyextra->current->spec.isRef() ||
6782 yyextra->current->spec.isValue() ||
6783 yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL
6784 )
6785 {
6786 yyextra->baseProt = Protection::Public;
6787 }
6788 else
6789 {
6790 yyextra->baseProt = Protection::Private;
6791 }
6792 yyextra->baseVirt = Specifier::Normal;
6793 yyextra->baseName.clear();
6794 BEGIN( BasesProt ) ;
6795 }
6796 }
6797<ClassVar>[;=*&] {
6798 if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
6799 {
6800 yyextra->current->type.prepend("typedef");
6801 }
6802 if ((yytext[0]=='*' || yytext[0]=='&') && yyextra->current->section.isEnum())
6803 { // found "enum a *b" -> variable
6804 yyextra->current->section = EntryType::makeVariable() ;
6805 }
6806 if (yytext[0]==';' && yyextra->current->section.isEnum())
6807 {
6808 yyextra->current->reset();
6809 initEntry(yyscanner);
6810 }
6811 else
6812 {
6813 unput(*yytext);
6814 }
6815 BEGIN( FindMembers );
6816 }
6817<Bases,ClassVar>{CPPC}"/"/[^/] {
6818 if (!yyextra->insideObjC)
6819 {
6820 REJECT;
6821 }
6822 else
6823 {
6824 lineCount(yyscanner);
6825 yyextra->current->program << yytext;
6826 yyextra->current->fileName = yyextra->fileName ;
6827 yyextra->current->startLine = yyextra->yyLineNr ;
6828 yyextra->current->startColumn = yyextra->yyColNr;
6829 yyextra->curlyCount=0;
6830 BEGIN( ReadBodyIntf );
6831 }
6832 }
6833<Bases,ClassVar>({CPPC}{B}*)?{CCS}"*"/{NCOMM} |
6834<Bases,ClassVar>({CPPC}{B}*)?{CCS}"!" |
6835<Bases,ClassVar>{CPPC}"!" |
6836<Bases,ClassVar>[\-+]{BN}* {
6837 if (!yyextra->insideObjC)
6838 {
6839 REJECT;
6840 }
6841 else
6842 {
6843 lineCount(yyscanner);
6844 yyextra->current->program << yytext;
6845 yyextra->current->fileName = yyextra->fileName ;
6846 yyextra->current->startLine = yyextra->yyLineNr ;
6847 yyextra->current->startColumn = yyextra->yyColNr;
6848 yyextra->curlyCount=0;
6849 BEGIN( ReadBodyIntf );
6850 }
6851 }
6852<CompoundName,ClassVar>{B}*"{"{B}* {
6853 yyextra->current->program.str(std::string());
6854 yyextra->current->fileName = yyextra->fileName ;
6855 yyextra->current->bodyLine = yyextra->yyLineNr;
6856 yyextra->current->bodyColumn = yyextra->yyColNr;
6857 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6858 if (yyextra->current->name.isEmpty() && !yyextra->isTypedef) // anonymous compound
6859 {
6860 if (yyextra->current->section.isNamespace()) // allow reopening of anonymous namespaces
6861 {
6862 if (Config_getBool(EXTRACT_ANON_NSPACES)) // use visible name
6863 {
6864 yyextra->current->name="anonymous_namespace{"+stripPath(yyextra->current->fileName)+"}";
6865 }
6866 else // use invisible name
6867 {
6868 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonNSCount);
6869 }
6870 }
6871 else
6872 {
6873 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
6874 }
6875 }
6876 yyextra->curlyCount=0;
6877 if (yyextra->current_root && // not a nested struct yyextra->inside an @interface section
6878 !yyextra->current_root->spec.isInterface() &&
6879 (yyextra->current->spec.isInterface() ||
6880 yyextra->current->spec.isProtocol() ||
6881 yyextra->current->spec.isCategory() ||
6882 yyextra->current->section.isObjcImpl()
6883 ) &&
6884 yyextra->insideObjC
6885 )
6886 { // ObjC body that ends with @end
6887 BEGIN( ReadBodyIntf );
6888 }
6889 else if (yyextra->current->section.isNamespace())
6890 { // namespace body
6891 BEGIN( ReadNSBody );
6892 }
6893 else
6894 { // class body
6895 BEGIN( ReadBody ) ;
6896 }
6897 }
QCString stripPath(const QCString &s)
Definition util.cpp:4991
6898<BasesProt>"virtual"{BN}+ { lineCount(yyscanner); yyextra->baseVirt = Specifier::Virtual; }
6899<BasesProt>"public"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Public; }
6900<BasesProt>"protected"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Protected; }
6901<BasesProt>"internal"{BN}+ { if (!yyextra->insideCli) REJECT ; lineCount(yyscanner); yyextra->baseProt = Protection::Package; }
6902<BasesProt>"private"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Private; }
6903<BasesProt>{BN} { lineCount(yyscanner); }
6904<BasesProt>. { unput(*yytext); BEGIN(Bases); }
6905<Bases>"decltype"{BN}*"(" {
6906 lineCount(yyscanner);
6907 yyextra->roundCount=0;
6908 yyextra->lastSkipRoundContext=YY_START;
6909 BEGIN(SkipRound);
6910 }
6911<Bases>("\\")?({ID}"\\")*{ID} { // PHP namespace token, not sure if interspacing is allowed but it gives problems (see bug 640847)
6912 if (!yyextra->insidePHP)
6913 {
6914 REJECT;
6915 }
6916 else // PHP base class of the form \Ns\Cl or Ns\Cl
6917 {
6918 lineCount(yyscanner);
6919 QCString bn=yytext;
6920 bn = substitute(bn,"\\","::");
6921 yyextra->baseName += bn;
6922 yyextra->current->args += ' ';
6923 yyextra->current->args += yytext;
6924 }
6925 }
6926<Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID}("...")? {
6927 lineCount(yyscanner);
6928 QCString baseScope = yytext;
6929 if (yyextra->insideCS && baseScope.stripWhiteSpace()=="where")
6930 {
6931 // type constraint for a class
6932 yyextra->current->typeConstr.clear();
6933 yyextra->current->typeConstr.push_back(Argument());
6934 yyextra->lastCSConstraint = YY_START;
6935 BEGIN( CSConstraintName );
6936 }
6937 else
6938 {
6939 yyextra->baseName+=yytext;
6940 yyextra->current->args += ' ';
6941 yyextra->current->args += yytext;
6942 }
6943 }
6944<Bases>{BN}*{ID}("."{ID})* { // Java style class
6945 QCString name = substitute(yytext,".","::");
6946 yyextra->baseName += name;
6947 yyextra->current->args += ' ';
6948 yyextra->current->args += name;
6949 }
6950<ClassVar,Bases>\n/{BN}*[^{, \t\n:] {
6951 if (!yyextra->insideObjC)
6952 {
6953 REJECT;
6954 }
6955 else
6956 {
6957 lineCount(yyscanner);
6958 unput('{');
6959 }
6960 }
6961<ClassVar,Bases>"@end" { // empty ObjC interface
6962 unput('d'); // insert fake body: {}@end
6963 unput('n');
6964 unput('e');
6965 unput('@');
6966 unput('}');
6967 unput('{');
6968 }
6969<ClassVar>"<" { yyextra->current->name += *yytext;
6970 yyextra->sharpCount=1;
6971 yyextra->roundCount=0;
6972 yyextra->lastSkipSharpContext = YY_START;
6973 yyextra->specName = &yyextra->current->name;
6974 BEGIN ( Specialization );
6975 }
6976<Bases>{BN}*"<" {
6977 lineCount(yyscanner);
6978 yyextra->sharpCount=1;
6979 yyextra->roundCount=0;
6980 yyextra->lastSkipSharpContext = YY_START;
6981 if (yyextra->insideObjC) // start of protocol list
6982 {
6983 unput(',');
6984 }
6985 else // template specialization
6986 {
6987 //if (yyextra->insideCS) // generic
6988 //{
6989 // yyextra->baseName+="-g";
6990 //}
6991 yyextra->templateStr = yytext;
6992 yyextra->specName = &yyextra->templateStr;
6993 BEGIN ( Specialization );
6994 }
6995 }
6996<Specialization>"<" { *yyextra->specName += *yytext;
6997 if (yyextra->roundCount==0) yyextra->sharpCount++;
6998 }
6999<Specialization>">" {
7000 *yyextra->specName += *yytext;
7001 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
7002 {
7003 yyextra->baseName+=removeRedundantWhiteSpace(*yyextra->specName);
7004 BEGIN(yyextra->lastSkipSharpContext);
7005 }
7006 }
7007<Specialization>{BN}+ { lineCount(yyscanner); *yyextra->specName +=' '; }
7008<Specialization>"<<" { *yyextra->specName += yytext; }
7009<Specialization>">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template...
7010 unput('>');
7011 unput(' ');
7012 unput('>');
7013 }
7014<Specialization>">>" {
7015 if (yyextra->insideCS) // for C# >> ends a nested template
7016 {
7017 REJECT;
7018 }
7019 else // for C++ >> is a bitshift
7020 // operator and > > would end
7021 // a nested template.
7022 // We require the bitshift to be enclosed in braces.
7023 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
7024 {
7025 if (yyextra->roundCount>0)
7026 {
7027 *yyextra->specName += yytext;
7028 }
7029 else
7030 {
7031 unput('>');
7032 unput(' ');
7033 unput('>');
7034 }
7035 }
7036 }
7037<Specialization>"typename"{BN}+ { lineCount(yyscanner); }
7038<Specialization>"(" { *yyextra->specName += *yytext; yyextra->roundCount++; }
7039<Specialization>")" { *yyextra->specName += *yytext; yyextra->roundCount--; }
7040
7041<Specialization>"\\\\" { *yyextra->specName += *yytext;}
7042<Specialization>"\\'" { *yyextra->specName += *yytext;}
7043<Specialization>"\\\"" { *yyextra->specName += *yytext;}
7044<Specialization>"'" { *yyextra->specName += *yytext;BEGIN(SpecializationSingleQuote);}
7045<Specialization>"\"" { *yyextra->specName += *yytext;BEGIN(SpecializationDoubleQuote);}
7046<SpecializationSingleQuote,SpecializationDoubleQuote>"\\\\" { *yyextra->specName += *yytext;}
7047<SpecializationSingleQuote>"\\'" { *yyextra->specName += *yytext;}
7048<SpecializationSingleQuote>"'" { *yyextra->specName += *yytext; BEGIN(Specialization);}
7049<SpecializationDoubleQuote>"\\\"" { *yyextra->specName += *yytext;}
7050<SpecializationDoubleQuote>"\"" { *yyextra->specName += *yytext; BEGIN(Specialization);}
7051<SpecializationSingleQuote,SpecializationDoubleQuote>. { *yyextra->specName += *yytext;}
7052
7053<Specialization>. {
7054 *yyextra->specName += *yytext;
7055 }
7056<SkipRound>"(" { ++yyextra->roundCount; }
7057<SkipRound>")" { if (--yyextra->roundCount<0)
7058 BEGIN ( yyextra->lastSkipRoundContext );
7059 }
7060<SkipRound>\" {
7061 yyextra->lastStringContext=SkipRound;
7062 BEGIN(SkipString);
7063 }
7064<Bases>","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount(yyscanner);
7065 if (yyextra->insideProtocolList)
7066 {
7067 yyextra->baseName+="-p";
7068 }
7069 else
7070 {
7071 yyextra->current->args += ',' ;
7072 }
7073 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
7074 if (!yyextra->baseName.isEmpty())
7075 {
7076 yyextra->current->extends.emplace_back(
7077 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
7078 );
7079 }
7080 if (yyextra->current->spec.isInterface() || yyextra->current->spec.isStruct() ||
7081 yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS ||
7082 yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL || yyextra->insideSlice)
7083 {
7084 yyextra->baseProt=Protection::Public;
7085 }
7086 else
7087 {
7088 yyextra->baseProt=Protection::Private;
7089 }
7090 yyextra->baseVirt=Specifier::Normal;
7091 yyextra->baseName.clear();
7092 if (*yytext=='>')
7093 { // end of a ObjC protocol list
7094 yyextra->insideProtocolList=FALSE;
7095 if (yyleng==1)
7096 {
7097 if (yyextra->insideObjC && !yyextra->current->spec.isProtocol())
7098 {
7099 BEGIN(ClassVar); // allow parsing of ':' for base class
7100 }
7101 else
7102 {
7103 unput('{'); // dummy start body
7104 }
7105 }
7106 else
7107 {
7108 yyless(1);
7109 }
7110 }
7111 else
7112 {
7113 if (*yytext==',' && yyextra->insideObjC) // Begin of protocol list
7114 {
7115 yyextra->insideProtocolList=TRUE;
7116 }
7117 BEGIN(BasesProt);
7118 }
7119 }
7120<Bases>{B}*"{"{B}* {
7121 yyextra->current->program.str(std::string());
7122 yyextra->current->fileName = yyextra->fileName ;
7123 yyextra->current->bodyLine = yyextra->yyLineNr;
7124 yyextra->current->bodyColumn = yyextra->yyColNr;
7125 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
7126 if (!yyextra->baseName.isEmpty())
7127 {
7128 yyextra->current->extends.emplace_back(
7129 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
7130 );
7131 yyextra->baseName.clear();
7132 }
7133 yyextra->curlyCount=0;
7134 if (yyextra->insideObjC)
7135 {
7136 BEGIN( ReadBodyIntf );
7137 }
7138 else
7139 {
7140 BEGIN( ReadBody ) ;
7141 }
7142 }
7143<SkipUnionSwitch>{B}*"(" {
7144 yyextra->roundCount++;
7145 }
7146<SkipUnionSwitch>")" {
7147 if (--yyextra->roundCount==0)
7148 {
7149 BEGIN(ClassVar);
7150 }
7151 }
7152<SkipUnionSwitch>\n { lineCount(yyscanner); }
7153<SkipUnionSwitch>.
7154<Comment>{BN}+ { yyextra->current->program << yytext ;
7155 lineCount(yyscanner) ;
7156 }
7157<Comment>{CCS} { yyextra->current->program << yytext ; }
7158<Comment>{CPPC} { yyextra->current->program << yytext ; }
7159<Comment>{CMD}("code"|"verbatim"|"iliteral") {
7160 if (yyextra->doxygenComment) yyextra->insideCode=TRUE;
7161 yyextra->current->program << yytext ;
7162 }
7163<Comment>{CMD}("endcode"|"endverbatim"|"endiliteral") {
7164 if (yyextra->doxygenComment) yyextra->insideCode=FALSE;
7165 yyextra->current->program << yytext ;
7166 }
7167<Comment>[^ \.\t\r\n\/\*]+ { yyextra->current->program << yytext ; }
7168<Comment>{CCE} { yyextra->current->program << yytext ;
7169 if (!yyextra->insideCode)
7170 {
7171 yyextra->doxygenComment=false;
7172 BEGIN( yyextra->lastContext );
7173 }
7174 }
7175<Comment>. { yyextra->current->program << *yytext ; }
7176
7177<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,SkipC11Inits,ReadExpressionBody,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"!" {
7178 //printf("Start doc block at %d\n",yyextra->yyLineNr);
7179 if (!yyextra->current->doc.isEmpty())
7180 {
7181 yyextra->current->doc+="\n\n";
7182 }
7183 else
7184 {
7185 yyextra->current->docLine = yyextra->yyLineNr;
7186 yyextra->current->docFile = yyextra->fileName;
7187 }
7188
7189 yyextra->lastDocContext = YY_START;
7190 if (yyextra->current_root->section.isScope())
7191 {
7192 yyextra->current->inside = yyextra->current_root->name+"::";
7193 }
7194 yyextra->docBlockContext = YY_START;
7195 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7196 yyextra->docBlockAutoBrief = Config_getBool(QT_AUTOBRIEF);
7197
7198 QCString indent;
7199 indent.fill(' ',computeIndent(yytext,yyextra->column));
7200 yyextra->docBlock.str(indent.str());
7201
7202 if (yyextra->docBlockAutoBrief)
7203 {
7204 yyextra->current->briefLine = yyextra->yyLineNr;
7205 yyextra->current->briefFile = yyextra->fileName;
7206 }
7207 startCommentBlock(yyscanner,FALSE);
7208 BEGIN( DocBlock );
7209 }
7210<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,ReadExpressionBody,Bases,OldStyleArgs>{CCS}"*"[*]+{BL} {
7211 bool javadocBanner = Config_getBool(JAVADOC_BANNER);
7212 lineCount(yyscanner);
7213
7214 if( javadocBanner )
7215 {
7216 yyextra->lastDocContext = YY_START;
7217
7218 //printf("Found comment banner at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
7219 if (yyextra->current_root->section.isScope())
7220 {
7221 yyextra->current->inside = yyextra->current_root->name+"::";
7222 }
7223 yyextra->current->docLine = yyextra->yyLineNr;
7224 yyextra->current->docFile = yyextra->fileName;
7225 yyextra->docBlockContext = YY_START;
7226 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7227 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
7228 yyextra->docBlockAutoBrief = javadocAutoBrief;
7229
7230 QCString indent;
7231 indent.fill(' ',computeIndent(yytext,yyextra->column));
7232 yyextra->docBlock.str(indent.str());
7233
7234 if (yyextra->docBlockAutoBrief)
7235 {
7236 yyextra->current->briefLine = yyextra->yyLineNr;
7237 yyextra->current->briefFile = yyextra->fileName;
7238 }
7239 startCommentBlock(yyscanner,FALSE);
7240 BEGIN( DocBlock );
7241 }
7242 else
7243 {
7244 yyextra->current->program << yytext ;
7245 yyextra->lastContext = YY_START ;
7246 yyextra->doxygenComment=true;
7247 BEGIN( Comment ) ;
7248 }
7249 }
7250<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,ReadExpressionBody,SkipInits,Bases,OldStyleArgs>^{B}+({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
7251 lineCount(yyscanner);
7252 yyextra->yyColNr=1;
7253 REJECT;
7254 }
7255<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,ReadExpressionBody,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
7256 yyextra->lastDocContext = YY_START;
7257
7258 //printf("Found comment block at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
7259 if (yyextra->current_root->section.isScope())
7260 {
7261 yyextra->current->inside = yyextra->current_root->name+"::";
7262 }
7263 yyextra->current->docLine = yyextra->yyLineNr;
7264 yyextra->current->docFile = yyextra->fileName;
7265 yyextra->docBlockContext = YY_START;
7266 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7267 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
7268 yyextra->docBlockAutoBrief = javadocAutoBrief;
7269
7270 QCString indent;
7271 indent.fill(' ',computeIndent(yytext,yyextra->column));
7272 yyextra->docBlock.str(indent.str());
7273
7274 if (yyextra->docBlockAutoBrief)
7275 {
7276 yyextra->current->briefLine = yyextra->yyLineNr;
7277 yyextra->current->briefFile = yyextra->fileName;
7278 }
7279 startCommentBlock(yyscanner,FALSE);
7280 BEGIN( DocBlock );
7281 }
7282<FindMembers,FindFields,MemberSpec,SkipCurly,ReadExpressionBody,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"!" {
7283 yyextra->lastDocContext = YY_START;
7284 if (yyextra->current_root->section.isScope())
7285 {
7286 yyextra->current->inside = yyextra->current_root->name+"::";
7287 }
7288 yyextra->docBlockContext = YY_START;
7289 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7290 yyextra->docBlockAutoBrief = FALSE;
7291
7292 QCString indent;
7293 indent.fill(' ',computeIndent(yytext,yyextra->column));
7294 yyextra->docBlock.str(indent.str());
7295
7296 startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
7297 BEGIN( DocLine );
7298 }
7299<FindMembers,FindFields,MemberSpec,SkipCurly,ReadExpressionBody,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"/"/[^/] {
7300 yyextra->lastDocContext = YY_START;
7301 if (yyextra->current_root->section.isScope())
7302 {
7303 yyextra->current->inside = yyextra->current_root->name+"::";
7304 }
7305 yyextra->docBlockContext = YY_START;
7306 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7307 yyextra->docBlockAutoBrief = FALSE;
7308 QCString indent;
7309 indent.fill(' ',computeIndent(yytext,yyextra->column));
7310 yyextra->docBlock.str(indent.str());
7311 startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
7312 BEGIN( DocLine );
7313 }
7314<FindMembers>"extern"{BN}*"\""[^\"]+"\""{BN}*("{")? {
7315 lineCount(yyscanner);
7316 yyextra->externLinkage=TRUE;
7317 }
7318<FindMembers>"{" {
7319 if (yyextra->externLinkage)
7320 {
7321 yyextra->externLinkage=FALSE;
7322 }
7323 else if (yyextra->insideCS &&
7324 !yyextra->current->name.isEmpty() &&
7325 !yyextra->current->type.isEmpty())
7326 {
7327 if (yyextra->current->mtype == MethodTypes::Event)
7328 {
7329 yyextra->mtype = MethodTypes::Event;
7330 }
7331 else if (containsWord(yyextra->current->type,"event")) // event
7332 {
7333 yyextra->current->mtype = yyextra->mtype = MethodTypes::Event;
7334 }
7335 else // property
7336 {
7337 yyextra->current->mtype = yyextra->mtype = MethodTypes::Property;
7338 }
7339 yyextra->current->bodyLine = yyextra->yyLineNr;
7340 yyextra->current->bodyColumn = yyextra->yyColNr;
7341 yyextra->curlyCount=0;
7342 BEGIN( CSAccessorDecl );
7343 }
7344 else if (yyextra->insideIDL && yyextra->current->spec.isAttribute())
7345 {
7346 // UNO IDL: attributes may have setter and getter
7347 // exception specifications
7348 yyextra->current->exception = " {";
7349 BEGIN(UNOIDLAttributeBlock);
7350 }
7351 else
7352 {
7353 if ((yyextra->insideJava || yyextra->insideCS || yyextra->insideD) &&
7354 yyextra->current->name.isEmpty()
7355 )
7356 {
7357 // static Java initializer
7358 yyextra->needsSemi = FALSE;
7359 if (yyextra->current->isStatic)
7360 {
7361 yyextra->current->name="[static initializer]";
7362 yyextra->current->type.clear();
7363 }
7364 else
7365 {
7366 yyextra->current->name="[instance initializer]";
7367 }
7368 unput(*yytext);
7369 BEGIN( SFunction );
7370 }
7371 else
7372 {
7373 // pre C++11 code -> ignore the initializer
7374 //yyextra->needsSemi = TRUE;
7375 //yyextra->current->type.clear();
7376 //yyextra->current->name.clear();
7377 //yyextra->current->args.clear();
7378 //yyextra->current->argList.clear();
7379 //yyextra->curlyCount=0;
7380 //BEGIN( SkipCurlyBlock );
7381
7382 // C++11 style initializer list
7383 yyextra->current->bodyLine = yyextra->yyLineNr;
7384 yyextra->current->bodyColumn = yyextra->yyColNr;
7385 yyextra->current->initializer.str(yytext);
7386 yyextra->lastInitializerContext = YY_START;
7387 yyextra->sharpCount=0;
7388 yyextra->initBracketCount=1;
7389 BEGIN(ReadInitializer);
7390 }
7391 }
7392 }
7393<CSAccessorDecl>"{" { yyextra->curlyCount++; }
7394<CSAccessorDecl>"}"{B}*"=" {
7395 // fall back to next rule if it's not the right bracket
7396 if (yyextra->curlyCount != 0) REJECT;
7397 yyextra->current->initializer.str("=");
7398 yyextra->current->endBodyLine=yyextra->yyLineNr;
7399 yyextra->lastInitializerContext = FindMembers;
7400 BEGIN(ReadInitializer);
7401 }
7402<CSAccessorDecl>"}" {
7403 if (yyextra->curlyCount)
7404 {
7405 yyextra->curlyCount--;
7406 }
7407 else
7408 {
7409 yyextra->mtype = MethodTypes::Method;
7410 yyextra->virt = Specifier::Normal;
7411 // not really important, but while we are at it
7412 yyextra->current->endBodyLine=yyextra->yyLineNr;
7413 unput(';');
7414 BEGIN(FindMembers);
7415 }
7416 }
7417<CSAccessorDecl>"private "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateSettable(true); }
7418<CSAccessorDecl>"protected "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedSettable(true); }
7419<CSAccessorDecl>"private "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateGettable(true); }
7420<CSAccessorDecl>"protected "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedGettable(true); }
7421<CSAccessorDecl>"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setSettable(true); }
7422<CSAccessorDecl>"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setGettable(true); }
7423<CSAccessorDecl>"add" { if (yyextra->curlyCount==0) yyextra->current->spec.setAddable(true); }
7424<CSAccessorDecl>"remove" { if (yyextra->curlyCount==0) yyextra->current->spec.setRemovable(true); }
7425<CSAccessorDecl>"raise" { if (yyextra->curlyCount==0) yyextra->current->spec.setRaisable(true); }
7426<CSAccessorDecl>{CHARLIT} {}
7427<CSAccessorDecl>"\"" { BEGIN(CSString);}
7428<CSAccessorDecl>"." {}
7429<CSAccessorDecl>\n { lineCount(yyscanner); }
7430<CSString>"\"" { BEGIN(CSAccessorDecl);}
7431<CSString>{CPPC} {} // Otherwise the rule <*>"//" will kick in
7432<CSString>{CCS} {} // Otherwise the rule <*>"/*" will kick in
7433<CSString>\n { lineCount(yyscanner); }
7434<CSString>"." {}
7435
7436 /* ---- Slice-specific rules ------ */
7437
7438<SliceSequence>{SCOPENAME} {
7439 if (yyextra->current->spec.isLocal())
7440 {
7441 yyextra->current->type = "local ";
7442 }
7443 yyextra->current->type += "sequence<";
7444 yyextra->current->type += yytext;
7445 yyextra->current->type += ">";
7446 }
7447
7448<SliceSequence>{BN}*">"{BN}* {
7449 lineCount(yyscanner);
7450 BEGIN(SliceSequenceName);
7451 }
7452
7453<SliceSequenceName>{ID}{BN}* {
7454 lineCount(yyscanner);
7455 yyextra->current->name = yytext ;
7456 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7457 }
7458
7459<SliceSequenceName>";" {
7460 yyextra->current->section = EntryType::makeVariable();
7461 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7462 initEntry(yyscanner);
7463 BEGIN(FindMembers);
7464 }
7465
7466<SliceDictionary>{SCOPENAME}{BN}*","{BN}*{SCOPENAME} {
7467 lineCount(yyscanner);
7468 if (yyextra->current->spec.isLocal())
7469 {
7470 yyextra->current->type = "local ";
7471 }
7472 yyextra->current->type += "dictionary<";
7473 yyextra->current->type += yytext;
7474 yyextra->current->type += ">";
7475 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
7476 }
7477
7478<SliceDictionary>{BN}*">"{BN}* {
7479 lineCount(yyscanner);
7480 BEGIN(SliceDictionaryName);
7481 }
7482
7483<SliceDictionaryName>{ID}{BN}* {
7484 lineCount(yyscanner);
7485 yyextra->current->name = yytext ;
7486 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7487 }
7488
7489<SliceDictionaryName>";" {
7490 yyextra->current->section = EntryType::makeVariable();
7491 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7492 initEntry(yyscanner);
7493 BEGIN(FindMembers);
7494 }
7495
7496 /**********************************************************************************/
7497 /******************** Documentation block related rules ***************************/
7498 /**********************************************************************************/
7499
7500 /* ---- Single line comments ------ */
7501<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
7502 int markerLen = yytext[yyleng-1]=='<' ? 4 : 3;
7503 yyextra->docBlock << std::string(yytext).substr(0,yyleng-markerLen);
7504 lineCount(yyscanner);
7505 }
7506<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
7507 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7508 BEGIN( yyextra->docBlockContext );
7509 }
7510<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
7511 yyextra->docBlock << yytext;
7512 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7513 BEGIN( yyextra->docBlockContext );
7514 }
7515<DocLine>{NONLopt}/"\n" { // whole line
7516 yyextra->docBlock << yytext;
7517 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7518 BEGIN( yyextra->docBlockContext );
7519 }
7520
7521 /* ---- Comments blocks ------ */
7522
7523<DocBlock>"*"*{CCE} { // end of comment block
7524 handleCommentBlock(yyscanner,yyextra->docBlock.str(),FALSE);
7525 BEGIN(yyextra->docBlockContext);
7526 }
7527<DocBlock>"\\ilinebr "{B}*"*"/[^/] {
7528 QCString indent;
7529 indent.fill(' ',computeIndent(yytext+8,yyextra->column));
7530 yyextra->docBlock << "\\ilinebr " << indent;
7531 }
7532<DocBlock>^{B}*"*"+/[^/] {
7533 QCString indent;
7534 indent.fill(' ',computeIndent(yytext,yyextra->column));
7535 yyextra->docBlock << indent;
7536 }
7537<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
7538 QCString indent;
7539 indent.fill(' ',computeIndent(yytext,yyextra->column));
7540 yyextra->docBlock << indent;
7541 }
7542<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
7543 }
7544<DocBlock>{CPPC} { // slashes in the middle of a comment block
7545 yyextra->docBlock << yytext;
7546 }
7547<DocBlock>{CCS} { // start of a new comment in the
7548 // middle of a comment block
7549 yyextra->docBlock << yytext;
7550 }
7551<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
7552 yyextra->docBlock << yytext;
7553 }
7554<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
7555 yyextra->docBlock << yytext;
7556 char blockName[] = "f$";
7557 char c = yytext[2];
7558 if (c=='[') blockName[1]=']';
7559 else if (c=='{') blockName[1]='}';
7560 else if (c=='(') blockName[1]=')';
7561 startVerbatimBlock(yyscanner,blockName);
7562 BEGIN(DocCopyBlock);
7563 }
7564<DocBlock>{CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
7565 yyextra->fileName = &yytext[6];
7566 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7567 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
7568 yyextra->docBlock << yytext;
7569 }
7570<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
7571 yyextra->fileName = &yytext[6];
7572 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7573 yyextra->docBlock << yytext;
7574 }
7575<DocBlock>{CMD}"iline"{LINENR}{B} {
7576 bool ok = false;
7577 int nr = QCString(&yytext[6]).toInt(&ok);
7578 if (!ok)
7579 {
7580 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
7581 }
7582 else
7583 {
7584 yyextra->yyLineNr = nr;
7585 }
7586 yyextra->docBlock << yytext;
7587 }
7588<DocBlock>{B}*"<"{PRE}">" {
7589 yyextra->docBlock << yytext;
7590 startVerbatimBlock(yyscanner,"<pre>");
7591 BEGIN(DocCopyBlock);
7592 }
7593<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7594 yyextra->docBlock << yytext;
7595 startVerbatimBlock(yyscanner,"uml");
7596 BEGIN(DocCopyBlock);
7597 }
7598<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!)
7599 yyextra->docBlock << yytext;
7600 startVerbatimBlock(yyscanner,&yytext[1]);
7601 BEGIN(DocCopyBlock);
7602 }
7603<DocBlock>{CMD}("code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7604 yyextra->docBlock << yytext;
7605 startVerbatimBlock(yyscanner,&yytext[1],0,true);
7606 BEGIN(DocCopyBlock);
7607 }
7608<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7609 QCString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7610 yyextra->docBlock << "\\ilinebr ";
7611 yyextra->docBlock << pat;
7612 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length(),true);
7613 BEGIN(DocCopyBlock);
7614 }
7615<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7616 QCString pat = substitute(yytext,"*"," ");
7617 yyextra->docBlock << pat;
7618 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length(),true);
7619 BEGIN(DocCopyBlock);
7620 }
7621<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7622<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7623<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]* {
7624 QCString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7625 yyextra->docBlock << "\\ilinebr ";
7626 yyextra->docBlock << pat;
7627 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length(),true);
7628 BEGIN(DocCopyBlock);
7629 }
7630<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7631<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7632<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7633 QCString pat = substitute(yytext,"*"," ");
7634 yyextra->docBlock << pat;
7635 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length(),true);
7636 BEGIN(DocCopyBlock);
7637 }
7638<DocBlock>"```" { // skip ``` if not at the start of a line
7639 yyextra->docBlock << "```";
7640 }
7641<DocBlock>"\\`" { // skip escaped backtick
7642 yyextra->docBlock << yytext;
7643 }
7644<DocBlock>"`"{1,2} {
7645 yyextra->docBlock << yytext;
7646 startVerbatimBlock(yyscanner,yytext,yyleng,true);
7647 BEGIN(DocCopyBlock);
7648 }
7649<DocBlock>{B}*"<"{CODE}">" {
7650 if (yyextra->insideCS)
7651 {
7652 yyextra->docBlock << yytext;
7653 startVerbatimBlock(yyscanner,"<code>",0,true);
7654 BEGIN(DocCopyBlock);
7655 }
7656 else
7657 {
7658 REJECT;
7659 }
7660 }
7661<DocBlock>[^@*~`'\/\\\n]+ { // any character that isn't special
7662 yyextra->docBlock << yytext;
7663 }
7664<DocBlock>\n { // newline
7665 lineCount(yyscanner);
7666 yyextra->docBlock << *yytext;
7667 }
7668<DocBlock>. { // command block
7669 yyextra->docBlock << *yytext;
7670 }
7671
7672 /* ---- Copy verbatim sections ------ */
7673
7674<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
7675 if (endVerbatimBlock(yyscanner,"<pre>"))
7676 {
7677 BEGIN(DocBlock);
7678 }
7679 yyextra->docBlock << yytext;
7680 }
7681<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
7682 if (endVerbatimBlock(yyscanner,"<code>"))
7683 {
7684 BEGIN(DocBlock);
7685 }
7686 yyextra->docBlock << yytext;
7687 }
7688<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
7689 if (endVerbatimBlock(yyscanner,&yytext[1]))
7690 {
7691 BEGIN(DocBlock);
7692 }
7693 yyextra->docBlock << yytext;
7694 }
7695<DocCopyBlock>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"endmermaid"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
7696 if (endVerbatimBlock(yyscanner,&yytext[4]))
7697 {
7698 BEGIN(DocBlock);
7699 }
7700 yyextra->docBlock << yytext;
7701 }
7702<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
7703 if ((yyextra->docBlockName=="verbatim") || (yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7704 {
7705 REJECT;
7706 }
7707 else
7708 {
7709 QCString indent;
7710 indent.fill(' ',computeIndent(yytext,0));
7711 yyextra->docBlock << indent;
7712 }
7713 }
7714<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
7715 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7716 {
7717 QCString indent;
7718 indent.fill(' ',computeIndent(yytext,0));
7719 yyextra->docBlock << indent;
7720 }
7721 else
7722 {
7723 REJECT;
7724 }
7725 }
7726<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
7727 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7728 {
7729 QCString indent;
7730 indent.fill(' ',computeIndent(yytext,-1));
7731 yyextra->docBlock << indent+"*";
7732 }
7733 else
7734 {
7735 REJECT;
7736 }
7737 }
7738<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
7739 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7740 {
7741 QCString indent;
7742 if (yyextra->nestedComment>0) // keep * it is part of the code
7743 {
7744 indent.fill(' ',computeIndent(yytext,-1));
7745 yyextra->docBlock << indent+"*";
7746 }
7747 else // remove * it is part of the comment block
7748 {
7749 indent.fill(' ',computeIndent(yytext,0));
7750 yyextra->docBlock << indent;
7751 }
7752 }
7753 else
7754 {
7755 REJECT;
7756 }
7757 }
7758<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7759 QCString pat = substitute(yytext,"*"," ");
7760 if (endVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length()))
7761 {
7762 BEGIN(DocBlock);
7763 }
7764 yyextra->docBlock << pat;
7765 }
7766<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7767 QCString pat = substitute(yytext,"*"," ");
7768 if (endVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length()))
7769 {
7770 BEGIN(DocBlock);
7771 }
7772 yyextra->docBlock << pat;
7773 }
7774<DocCopyBlock>"```" { // backtick + end marker
7775 if (yyextra->docBlockName=="``")
7776 {
7777 yyextra->docBlock << "`";
7778 endVerbatimBlock(yyscanner,"``",2);
7779 yyextra->docBlock << "``";
7780 BEGIN(DocBlock);
7781 }
7782 else
7783 {
7784 yyextra->docBlock << yytext;
7785 }
7786 }
7787<DocCopyBlock>"''"/[^a-z_A-Z0-9-] {
7788 if (!Config_getBool(MARKDOWN_STRICT) && endVerbatimBlock(yyscanner,"``",2))
7789 {
7790 BEGIN(DocBlock);
7791 }
7792 yyextra->docBlock << yytext;
7793 }
7794<DocCopyBlock>"'"/[^'a-z_A-Z0-9-] {
7795 if (!Config_getBool(MARKDOWN_STRICT) && endVerbatimBlock(yyscanner,"`",1))
7796 {
7797 BEGIN(DocBlock);
7798 }
7799 yyextra->docBlock << yytext;
7800 }
7801<DocCopyBlock>"`"{1,2} {
7802 if (endVerbatimBlock(yyscanner,yytext,yyleng))
7803 {
7804 BEGIN(DocBlock);
7805 }
7806 yyextra->docBlock << yytext;
7807 }
7808<DocCopyBlock>[^<@/\*\‍]`'~"\$\\\n]+ { // any character that is not special
7809 yyextra->docBlock << yytext;
7810 }
7811<DocCopyBlock>\" {
7812 yyextra->docBlock << yytext;
7813 if (yyextra->docBlockName=="code" || yyextra->docBlockName=="iliteral")
7814 // to support end of comment character sequences inside
7815 // a string literal of a code block, see #6737
7816 {
7817 yyextra->lastStringContext=YY_START;
7818 yyextra->pCopyQuotedGString=&yyextra->docBlock;
7819 yyextra->stopAtInvalidString=true;
7820 BEGIN(CopyGString);
7821 }
7822 }
7823<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
7824 if (yytext[1]=='*') // start comment
7825 {
7826 yyextra->nestedComment++;
7827 }
7828 else if (yytext[0]=='*' && yyextra->nestedComment>0) // end comment
7829 {
7830 yyextra->nestedComment--;
7831 }
7832 else if (yytext[0]=='*' && yyextra->nestedComment==0 && yyextra->isCodeBlock) // end comment without start
7833 {
7834 warn(yyextra->fileName,yyextra->yyLineNr,
7835 "Found end of C comment inside a '{}' block without matching start of the comment!"
7836 " Maybe the end marker for the block is missing?",
7837 yyextra->docBlockName);
7838 BEGIN(DocBlock);
7839 }
7840 yyextra->docBlock << yytext;
7841 }
7842<DocCopyBlock>\n { // newline
7843 yyextra->docBlock << *yytext;
7844 lineCount(yyscanner);
7845 }
7846<DocCopyBlock>. { // any other character
7847 yyextra->docBlock << *yytext;
7848 }
7849<DocCopyBlock><<EOF>> {
7850 warn(yyextra->fileName,yyextra->yyLineNr,
7851 "reached end of file while inside a '{}' block!"
7852 " The command that should end the block seems to be missing!",
7853 yyextra->docBlockName);
7854 yyterminate();
7855 }
7856
7857
7858 /* ------------- Prototype parser -------------- */
7859
7860<Prototype>"operator"{B}*"("{B}*")" {
7861 yyextra->current->name+=yytext;
7862 }
7863<Prototype>"(" {
7864 yyextra->current->args+=*yytext;
7865 yyextra->currentArgumentContext = PrototypeQual;
7866 yyextra->fullArgString = yyextra->current->args;
7867 yyextra->copyArgString = &yyextra->current->args;
7868 BEGIN( ReadFuncArgType ) ;
7869 }
7870<Prototype>"("({ID}"::")*({B}*[&*])+ {
7871 if (yyextra->insidePHP) // reference parameter
7872 {
7873 REJECT;
7874 }
7875 else
7876 {
7877 yyextra->current->type+=yyextra->current->name+yytext;
7878 yyextra->current->name.clear();
7879 BEGIN( PrototypePtr );
7880 }
7881 }
7882<PrototypePtr>{SCOPENAME} {
7883 yyextra->current->name+=yytext;
7884 }
7885<PrototypePtr>"(" {
7886 yyextra->current->args+=*yytext;
7887 yyextra->currentArgumentContext = PrototypeQual;
7888 yyextra->fullArgString = yyextra->current->args;
7889 yyextra->copyArgString = &yyextra->current->args;
7890 BEGIN( ReadFuncArgType ) ;
7891 }
7892<PrototypePtr>")" {
7893 yyextra->current->type+=')';
7894 BEGIN( Prototype );
7895 }
7896<PrototypePtr>. {
7897 yyextra->current->name+=yytext;
7898 }
7899<PrototypeQual>"{" {
7900 BEGIN( PrototypeSkipLine);
7901 }
7902<PrototypeQual>{B}*"const"{B}* {
7903 yyextra->current->args += " const ";
7904 yyextra->current->argList.setConstSpecifier(TRUE);
7905 }
7906<PrototypeQual>{B}*"volatile"{B}* {
7907 yyextra->current->args += " volatile ";
7908 yyextra->current->argList.setVolatileSpecifier(TRUE);
7909 }
7910<PrototypeQual>{B}*"="{B}*"0"{B}* {
7911 yyextra->current->args += " = 0";
7912 yyextra->current->virt = Specifier::Pure;
7913 yyextra->current->argList.setPureSpecifier(TRUE);
7914 }
7915<PrototypeQual>"throw"{B}*"(" {
7916 yyextra->current->exception = "throw(";
7917 BEGIN(PrototypeExc);
7918 }
7919<PrototypeExc>")" {
7920 yyextra->current->exception += ')';
7921 BEGIN(PrototypeQual);
7922 }
7923<PrototypeExc>. {
7924 yyextra->current->exception += *yytext;
7925 }
7926<PrototypeQual>. {
7927 yyextra->current->args += *yytext;
7928 }
7929<Prototype>. {
7930 yyextra->current->name += *yytext;
7931 }
7932<PrototypeSkipLine>. {
7933 }
7934
7935
7936
7937
7938<SkipCxxComment>.*"\\\n" { // line continuation
7939 if (yyextra->insideCS)
7940 {
7941 REJECT;
7942 }
7943 else
7944 {
7945 lineCount(yyscanner);
7946 }
7947 }
7948<SkipCxxComment>{ANYopt}/\n {
7949 BEGIN( yyextra->lastCContext ) ;
7950 }
7951<SkipComment>[^\*\n]+
7952
7953 /* ------------ Generic rules -------------- */
7954
7955<*>"[[" { // C++11 attribute
7956 if (!yyextra->insideCpp) REJECT;
7957 if (YY_START == CopyGString || YY_START == CopyGString) REJECT;
7958 yyextra->lastC11AttributeContext = YY_START;
7959 yyextra->pCopyC11AttributeString = &yyextra->current->attributes;
7960 BEGIN( CopyC11Attribute );
7961 }
7962
7963<*>\n { lineCount(yyscanner); }
7964<*>\" {
7965 if (yyextra->insideIDL && yyextra->insideCppQuote)
7966 {
7967 BEGIN(EndCppQuote);
7968 }
7969 else if (yyextra->insidePHP)
7970 {
7971 yyextra->lastStringContext=YY_START;
7972 BEGIN(SkipString);
7973 }
7974 }
7975<*>^{B}*"#" {
7976 if (!yyextra->insidePHP)
7977 {
7978 yyextra->lastCPPContext = YY_START;
7979 BEGIN( SkipCPP ) ;
7980 }
7981 else
7982 {
7983 yyextra->lastCContext = YY_START ;
7984 BEGIN( SkipCxxComment ) ;
7985 }
7986 }
7987<*>"#" {
7988 if (!yyextra->insidePHP)
7989 REJECT;
7990 yyextra->lastCContext = YY_START ;
7991 BEGIN( SkipCxxComment ) ;
7992 }
7993<*>\' {
7994 if (yyextra->insidePHP)
7995 {
7996 yyextra->lastStringContext=YY_START;
7997 BEGIN(SkipPHPString);
7998 }
7999 }
8000<*>\? {
8001 if (yyextra->insideCS && (YY_START != SkipRound) && (YY_START != CSAccessorDecl))
8002 {
8003 if (yyextra->current->type.isEmpty())
8004 {
8005 if (yyextra->current->name.isEmpty())
8006 yyextra->current->name="?";
8007 else
8008 yyextra->current->name+="?";
8009 }
8010 else
8011 {
8012 yyextra->current->type+="?";
8013 }
8014 }
8015 }
8016<*>"}" { yyextra->exported=false; }
8017<*>.
8018<SkipComment>{CPPC}|{CCS}
8019<*>{CCS} { yyextra->lastCContext = YY_START ;
8020 BEGIN( SkipComment ) ;
8021 }
8022<SkipComment>{B}*{CCE} { BEGIN( yyextra->lastCContext ) ; }
8023<*>{CPPC} {
8024 yyextra->lastCContext = YY_START ;
8025 BEGIN( SkipCxxComment ) ;
8026 }
8027<<EOF>> {
8028 if (yyextra->insideCS && yyextra->fakeNS)
8029 {
8030 yyextra->fakeNS--;
8031 unput('}');
8032 BEGIN ( ReadNSBody);
8033 }
8034 else
8035 {
8036 yyterminate();
8037 }
8038 }
8039%%
8040
8041//----------------------------------------------------------------------------
8042static int yyread(yyscan_t yyscanner,char *buf,int max_size)
8043{
8044 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8045 int c=0;
8046 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
8047 {
8048 *buf = yyextra->inputString[yyextra->inputPosition++] ;
8049 //printf("%d (%c)\n",*buf,*buf);
8050 c++; buf++;
8051 }
8052 return c;
8053}
8054
8055
8056static void initParser(yyscan_t yyscanner)
8057{
8058 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8059 yyextra->outerScopeEntries.clear();
8060 yyextra->baseName.clear();
8061 yyextra->protection = Protection::Public;
8062 yyextra->baseProt = Protection::Public;
8063 yyextra->sharpCount = 0;
8064 yyextra->roundCount = 0;
8065 yyextra->curlyCount = 0;
8066 yyextra->mtype = MethodTypes::Method;
8067 yyextra->isStatic = FALSE;
8068 yyextra->virt = Specifier::Normal;
8069 yyextra->baseVirt = Specifier::Normal;
8070 yyextra->isTypedef = FALSE;
8071 yyextra->insideTryBlock = FALSE;
8072 yyextra->insideFormula = FALSE;
8073 yyextra->insideCode=FALSE;
8074 yyextra->insideCli=Config_getBool(CPP_CLI_SUPPORT);
8075 yyextra->previous = 0;
8076 yyextra->firstTypedefEntry.reset();
8077 yyextra->memspecEntry.reset();
8078}
8079
8080static void initEntry(yyscan_t yyscanner)
8081{
8082 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8083 if (yyextra->insideJava)
8084 {
8085 yyextra->protection = (yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isEnum()) ? Protection::Public : Protection::Package;
8086 }
8087 yyextra->current->protection = yyextra->protection;
8088 yyextra->current->exported = yyextra->exported ;
8089 yyextra->current->mtype = yyextra->mtype;
8090 yyextra->current->virt = yyextra->virt;
8091 yyextra->current->isStatic = yyextra->isStatic;
8092 yyextra->current->lang = yyextra->language;
8093 //printf("*** initEntry(yyscanner) yyextra->language=%d\n",yyextra->language);
8094 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
8095 yyextra->isTypedef=FALSE;
8096}
8097
8098
8099//-----------------------------------------------------------------------------
8100
8101static void storeClangId(yyscan_t yyscanner,const char *id)
8102{
8103 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8104 if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
8105 {
8106 yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,id);
8107 }
8108}
8109
8110static void lineCount(yyscan_t yyscanner)
8111{
8112 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8113 int tabSize = Config_getInt(TAB_SIZE);
8114 const char *p;
8115 for (p = yytext ; *p ; ++p )
8116 {
8117 if (*p=='\n')
8118 {
8119 yyextra->yyLineNr++;
8120 yyextra->column=0;
8121 yyextra->yyColNr=1;
8122 }
8123 else if (*p=='\t')
8124 {
8125 yyextra->column+=tabSize - (yyextra->column%tabSize);
8126 }
8127 else
8128 {
8129 yyextra->column++;
8130 yyextra->yyColNr++;
8131 }
8132 }
8133 //printf("lineCount()=%d\n",yyextra->column);
8134}
8135
8136static inline int computeIndent(const char *s,int startIndent)
8137{
8138 int col=startIndent;
8139 int tabSize=Config_getInt(TAB_SIZE);
8140 const char *p=s;
8141 char c;
8142 while ((c=*p++))
8143 {
8144 if (c=='\t') col+=tabSize-(col%tabSize);
8145 else if (c=='\n') col=0;
8146 else col++;
8147 }
8148 return col;
8149}
8150
8151static inline void initMethodProtection(yyscan_t yyscanner,Protection prot)
8152{
8153 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8154 yyextra->current->protection = yyextra->protection = prot;
8155 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
8156 yyextra->current->type.clear();
8157 yyextra->current->name.clear();
8158 yyextra->current->args.clear();
8159 yyextra->current->argList.clear();
8160 lineCount(yyscanner) ;
8161}
8162
8163static void addType(yyscan_t yyscanner)
8164{
8165 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8166 size_t tl=yyextra->current->type.length();
8167 if( tl>0 && !yyextra->current->name.isEmpty() && yyextra->current->type.at(tl-1)!='.')
8168 {
8169 yyextra->current->type += ' ' ;
8170 }
8171 yyextra->current->type += yyextra->current->name;
8172 yyextra->current->name.clear() ;
8173 tl=yyextra->current->type.length();
8174 if( tl>0 && !yyextra->current->args.isEmpty() && yyextra->current->type.at(tl-1)!='.')
8175 {
8176 yyextra->current->type += ' ' ;
8177 }
8178 yyextra->current->type += yyextra->current->args ;
8179 yyextra->current->args.clear() ;
8180 yyextra->current->argList.clear();
8181}
8182
8183
8184static QCString stripQuotes(const char *s)
8185{
8186 QCString name;
8187 if (s==nullptr || *s==0) return name;
8188 name=s;
8189 if (name.at(0)=='"' && name.at(name.length()-1)=='"')
8190 {
8191 name=name.mid(1,name.length()-2);
8192 }
8193 return name;
8194}
8195
8196static QCString stripFuncPtr(const QCString &type)
8197{
8198 // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
8199 // also needed to reset the type for 'arr' to 'int' in 'typedef int (&fp)(), arr[2]'
8200 size_t i=type.length();
8201 bool funcPtr = i>0 && type[i-1]==')';
8202 if (funcPtr) i--;
8203 while (i>0 && (type[i-1]=='*' || type[i-1]=='&' || type[i-1]==' ')) i--;
8204 if (funcPtr && i>0 && type[i-1]=='(') i--;
8205 return type.left(i);
8206}
8207
8208//-----------------------------------------------------------------
8209static void startVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize,bool codeBlock)
8210{
8211 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8212 if (Config_getBool(MARKDOWN_SUPPORT))
8213 {
8214 yyextra->docBlock << "\\iskip";
8215 }
8216 yyextra->docBlockName=blockName;
8217 yyextra->fencedSize=fencedSize;
8218 yyextra->isCodeBlock=codeBlock;
8219 yyextra->nestedComment=0;
8220}
8221
8222//-----------------------------------------------------------------
8223static bool endVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize)
8224{
8225 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8226 if (yyextra->docBlockName==blockName && (fencedSize==0 || fencedSize==yyextra->fencedSize))
8227 {
8228 if (Config_getBool(MARKDOWN_SUPPORT))
8229 {
8230 yyextra->docBlock << "\\endiskip";
8231 }
8232 yyextra->docBlockName="";
8233 return true;
8234 }
8235 return false;
8236}
8237
8238//-----------------------------------------------------------------
8239
8240// return TRUE iff req holds the start of a requires expression
8241// or sub-expression without parenthesis, i.e. req is empty or ends with || or &&
8243{
8244 QCString r = req.stripWhiteSpace();
8245 return r.isEmpty() || r.endsWith("&&") || r.endsWith("||") || r.endsWith("and") || r.endsWith("or");
8246}
8247
8248//-----------------------------------------------------------------
8249
8250static bool nameIsOperator(QCString &name)
8251{
8252 int i=name.find("operator");
8253 if (i==-1) return FALSE;
8254 if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X
8255 if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator
8256 return FALSE; // case TEXToperatorTEXT
8257}
8258
8259//-----------------------------------------------------------------------------
8260
8261static void setContext(yyscan_t yyscanner)
8262{
8263 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8264 yyextra->language = getLanguageFromFileName(yyextra->fileName);
8265 yyextra->insideIDL = yyextra->language==SrcLangExt::IDL;
8266 yyextra->insideJava = yyextra->language==SrcLangExt::Java;
8267 yyextra->insideCS = yyextra->language==SrcLangExt::CSharp;
8268 yyextra->insideD = yyextra->language==SrcLangExt::D;
8269 yyextra->insidePHP = yyextra->language==SrcLangExt::PHP;
8270 yyextra->insideObjC = yyextra->language==SrcLangExt::ObjC;
8271 yyextra->insideJS = yyextra->language==SrcLangExt::JS;
8272 yyextra->insideSlice = yyextra->language==SrcLangExt::Slice;
8273 yyextra->insideCpp = (yyextra->language==SrcLangExt::Cpp ||
8274 yyextra->language==SrcLangExt::Lex);
8275 //printf("setContext(%s) yyextra->insideIDL=%d yyextra->insideJava=%d yyextra->insideCS=%d "
8276 // "yyextra->insideD=%d yyextra->insidePHP=%d yyextra->insideObjC=%d\n",
8277 // qPrint(yyextra->fileName),yyextra->insideIDL,yyextra->insideJava,yyextra->insideCS,yyextra->insideD,yyextra->insidePHP,yyextra->insideObjC
8278 // );
8279}
8280
8281//-----------------------------------------------------------------------------
8282
8283static void prependScope(yyscan_t yyscanner)
8284{
8285 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8286 if (yyextra->current_root->section.isScope())
8287 {
8288 //printf("--- prependScope %s to %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
8289 yyextra->current->name.prepend(yyextra->current_root->name+"::");
8290 //printf("prependScope #=%d #yyextra->current=%d\n",yyextra->current_root->tArgLists->count(),yyextra->current->tArgLists->count());
8291 for (const ArgumentList &srcAl : yyextra->current_root->tArgLists)
8292 {
8293 yyextra->current->tArgLists.insert(yyextra->current->tArgLists.begin(),srcAl);
8294 }
8295 }
8296}
8297
8298//-----------------------------------------------------------------------------
8299
8300/*! Returns TRUE iff the yyextra->current entry could be a K&R style C function */
8301static bool checkForKnRstyleC(yyscan_t yyscanner)
8302{
8303 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8304 if (!yyextra->fileName.lower().endsWith(".c")) return FALSE; // must be a C file
8305 if (yyextra->current->argList.empty()) return FALSE; // must have arguments
8306 for (const Argument &a : yyextra->current->argList)
8307 {
8308 // in K&R style argument do not have a type, but doxygen expects a type
8309 // so it will think the argument has no name
8310 if (a.type.isEmpty() || !a.name.isEmpty()) return FALSE;
8311 }
8312 return TRUE;
8313}
8314
8315static void setJavaProtection(yyscan_t yyscanner)
8316{
8317 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8318 if (yyextra->insideJava)
8319 {
8320 QCString text=yytext;
8321 yyextra->current->protection = Protection::Public;
8322 if (text.find("protected")!=-1)
8323 yyextra->current->protection = Protection::Protected;
8324 else if (text.find("private")!=-1)
8325 yyextra->current->protection = Protection::Private;
8326 else if (text.find("package")!=-1)
8327 yyextra->current->protection = Protection::Package;
8328 }
8329}
8330//-----------------------------------------------------------------------------
8331
8332static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName)
8333{
8334 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8335 int si = static_cast<int>(yyextra->current->args.length());
8336 if (yyextra->oldStyleArgType.isEmpty()) // new argument
8337 {
8338 std::string args = yyextra->current->args.str();
8339 static const reg::Ex re(R"(\‍([^)]*\).*)"); // find first (...)
8340 int bi1=-1;
8341 int bi2=-1;
8342 reg::Match match;
8343 if (reg::search(args,match,re))
8344 {
8345 bi1=(int)match.position();
8346 size_t secondMatchStart = match.position()+match.length(); // search again after first match
8347 if (reg::search(args,match,re,secondMatchStart))
8348 {
8349 bi2=(int)match.position();
8350 }
8351 }
8352 char c;
8353 if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
8354 {
8355 int s=bi2+1; // keep opening (
8356 yyextra->oldStyleArgType = yyextra->current->args.left(s);
8357 int i=s;
8358 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
8359 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
8360 s=i;
8361 while (i<si && isId(yyextra->current->args.at(i))) i++;
8362 oldStyleArgName = yyextra->current->args.mid(s,i-s);
8363 yyextra->oldStyleArgType+=yyextra->current->args.mid(i);
8364 }
8365 else if (bi1!=-1) // redundant braces like in "int (*var)"
8366 {
8367 int s=bi1; // strip opening (
8368 yyextra->oldStyleArgType = yyextra->current->args.left(s);
8369 s++;
8370 int i=s+1;
8371 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
8372 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
8373 s=i;
8374 while (i<si && isId(yyextra->current->args.at(i))) i++;
8375 oldStyleArgName = yyextra->current->args.mid(s,i-s);
8376 }
8377 else // normal "int *var"
8378 {
8379 int l=si,i=l-1,j;
8380 // look for start of name in "type *name"
8381 while (i>=0 && isId(yyextra->current->args.at(i))) i--;
8382 j=i+1;
8383 // look for start of *'s
8384 while (i>=0 && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i--;
8385 i++;
8386 if (i!=l)
8387 {
8388 yyextra->oldStyleArgType=yyextra->current->args.left(i);
8389 oldStyleArgPtr=yyextra->current->args.mid(i,j-i);
8390 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
8391 }
8392 else
8393 {
8394 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
8395 }
8396 }
8397 }
8398 else // continuation like *arg2 in "int *args,*arg2"
8399 {
8400 int l=si,j=0;
8401 char c;
8402 while (j<l && ((c=yyextra->current->args.at(j))=='*' || isspace((uint8_t)c))) j++;
8403 if (j>0)
8404 {
8405 oldStyleArgPtr=yyextra->current->args.left(j);
8406 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
8407 }
8408 else
8409 {
8410 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
8411 }
8412 }
8413}
8414
8415//-----------------------------------------------------------------------------
8416
8417/*! Update the argument \a name with additional \a type info. For K&R style
8418 * function the type is found \e after the argument list, so this routine
8419 * in needed to fix up.
8420 */
8421static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name,
8422 const QCString &brief,const QCString &docs)
8423{
8424 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8425 for (Argument &a : yyextra->current->argList)
8426 {
8427 if (a.type==name)
8428 {
8429 a.type=type.stripWhiteSpace();
8430 a.type.stripPrefix("register ");
8431 a.name=name.stripWhiteSpace();
8432 if (!brief.isEmpty() && !docs.isEmpty())
8433 {
8434 a.docs=brief+"\n\n"+docs;
8435 }
8436 else if (!brief.isEmpty())
8437 {
8438 a.docs=brief;
8439 }
8440 else
8441 {
8442 a.docs=docs;
8443 }
8444 }
8445 }
8446}
8447
8448//-----------------------------------------------------------------------------
8449
8451{
8452 for (Argument &a : al)
8453 {
8454 if (!a.type.isEmpty() && a.name.isEmpty())
8455 { // a->type is actually the (typeless) parameter name, so move it
8456 a.name=a.type;
8457 a.type.clear();
8458 }
8459 }
8460}
8461
8462//-----------------------------------------------------------------------------
8463
8464static void startCommentBlock(yyscan_t yyscanner,bool brief)
8465{
8466 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8467 if (brief)
8468 {
8469 yyextra->current->briefFile = yyextra->fileName;
8470 yyextra->current->briefLine = yyextra->yyLineNr;
8471 }
8472 else
8473 {
8474 yyextra->current->docFile = yyextra->fileName;
8475 yyextra->current->docLine = yyextra->yyLineNr;
8476 }
8477}
8478
8479//----------------------------------------------------------------------------
8480
8481static void newEntry(yyscan_t yyscanner)
8482{
8483 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8484 if (yyextra->tempEntry==0) // if temp entry is not 0, it holds yyextra->current,
8485 // and yyextra->current is actually replaced by yyextra->previous which was
8486 // already added to yyextra->current_root, so we should not add it again
8487 // (see bug723314)
8488 {
8489 yyextra->previous = yyextra->current;
8490 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8491 }
8492 else
8493 {
8494 yyextra->previous = yyextra->current;
8495 yyextra->current = yyextra->tempEntry;
8496 yyextra->tempEntry.reset();
8497 }
8498 initEntry(yyscanner);
8499}
8500
8501static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief)
8502{
8503 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8504 AUTO_TRACE("doc='{}' is_brief={}",Trace::trunc(doc),brief);
8505 bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
8506 if (yyextra->docBlockInBody && hideInBodyDocs) return;
8507 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; // line of block start
8508
8509 // fill in inbodyFile && inbodyLine the first time, see bug 633891
8510 std::shared_ptr<Entry> docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current;
8511 if (yyextra->docBlockInBody && docEntry && docEntry->inbodyLine==-1)
8512 {
8513 docEntry->inbodyFile = yyextra->fileName;
8514 docEntry->inbodyLine = lineNr;
8515 }
8516
8517 int position=0;
8518 bool needsEntry=FALSE;
8519 GuardedSectionStack guards;
8520 Markdown markdown(yyextra->fileName,lineNr);
8521 QCString strippedDoc = stripIndentation(doc);
8522 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8523 while (yyextra->commentScanner.parseCommentBlock(
8524 yyextra->thisParser,
8525 yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(),
8526 processedDoc, // text
8527 yyextra->fileName, // file
8528 lineNr, // line of block start
8529 yyextra->docBlockInBody ? FALSE : brief, // isBrief
8530 yyextra->docBlockInBody ? FALSE : yyextra->docBlockAutoBrief, // isJavaDocStyle
8531 yyextra->docBlockInBody, // isInBody
8532 yyextra->protection,
8533 position,
8534 needsEntry,
8535 Config_getBool(MARKDOWN_SUPPORT),
8536 &guards
8537 )
8538 )
8539 {
8540 //printf("parseCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8541 if (needsEntry)
8542 {
8543 QCString docFile = yyextra->current->docFile;
8544 newEntry(yyscanner);
8545 yyextra->current->docFile = docFile;
8546 yyextra->current->docLine = lineNr;
8547 }
8548 }
8549 if (needsEntry)
8550 {
8551 newEntry(yyscanner);
8552 }
8553
8554 if (yyextra->docBlockTerm)
8555 {
8556 unput(yyextra->docBlockTerm);
8557 yyextra->docBlockTerm=0;
8558 }
8559}
8560
8562{
8563 AUTO_TRACE();
8564 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8565 for (Argument &a : al)
8566 {
8567 AUTO_TRACE_ADD("Param '{}' docs='{}'",a.name,Trace::trunc(a.docs));
8568 if (!a.docs.isEmpty())
8569 {
8570 if (a.name.isEmpty() && a.type == "...") a.name= "...";
8571 int position=0;
8572 bool needsEntry;
8573
8574 // save context
8575 QCString orgDoc = yyextra->current->doc;
8576 QCString orgBrief = yyextra->current->brief;
8577 int orgDocLine = yyextra->current->docLine;
8578 int orgBriefLine = yyextra->current->briefLine;
8579
8580 yyextra->current->doc.clear();
8581 yyextra->current->brief.clear();
8582
8583 //printf("handleParametersCommentBlock [%s]\n",qPrint(doc));
8584 int lineNr = orgDocLine;
8585 GuardedSectionStack guards;
8586 Markdown markdown(yyextra->fileName,lineNr);
8587 QCString strippedDoc = stripIndentation(a.docs);
8588 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8589 while (yyextra->commentScanner.parseCommentBlock(
8590 yyextra->thisParser,
8591 yyextra->current.get(),
8592 processedDoc, // text
8593 yyextra->fileName, // file
8594 lineNr,
8595 FALSE,
8596 FALSE,
8597 FALSE,
8598 yyextra->protection,
8599 position,
8600 needsEntry,
8601 Config_getBool(MARKDOWN_SUPPORT),
8602 &guards
8603 )
8604 )
8605 {
8606 //printf("handleParametersCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8607 if (needsEntry) newEntry(yyscanner);
8608 }
8609 if (needsEntry)
8610 {
8611 newEntry(yyscanner);
8612 }
8613 a.docs = yyextra->current->doc;
8614
8615 // restore context
8616 yyextra->current->doc = orgDoc;
8617 yyextra->current->brief = orgBrief;
8618 yyextra->current->docLine = orgDocLine;
8619 yyextra->current->briefLine = orgBriefLine;
8620 }
8621 }
8622}
8623
8624
8625//----------------------------------------------------------------------------
8626
8627static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8628{
8629 AUTO_TRACE("name={}",rt->name);
8630 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8631 for (const auto &ce : rt->children())
8632 {
8633 if (!ce->program.empty())
8634 {
8635 AUTO_TRACE_ADD("compound name='{}' program='{}'",Trace::trunc(ce->name),Trace::trunc(ce->program.str()));
8636 // init scanner state
8637 yyextra->padCount=0;
8638 yyextra->column=0;
8639 yyextra->programStr = ce->program.str();
8640 yyextra->inputString = yyextra->programStr.data();
8641 yyextra->inputPosition = 0;
8642 if (ce->section.isEnum() || ce->spec.isEnum())
8643 BEGIN( FindFields ) ;
8644 else
8645 BEGIN( FindMembers ) ;
8646 yyextra->current_root = ce;
8647 yyextra->fileName = ce->fileName;
8648 //setContext();
8649 yyextra->yyLineNr = ce->bodyLine;
8650 yyextra->yyColNr = ce->bodyColumn;
8651 yyextra->insideObjC = ce->lang==SrcLangExt::ObjC;
8652 //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC);
8653 yyextra->current = std::make_shared<Entry>();
8654 yyextra->isStatic = FALSE;
8655 initEntry(yyscanner);
8656
8657 // deep copy group list from parent (see bug 727732)
8658 bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS);
8659 if (autoGroupNested && !rt->groups.empty() && !ce->section.isEnum() && !ce->spec.isEnum())
8660 {
8661 ce->groups = rt->groups;
8662 }
8663
8664 int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
8665 // set default protection based on the compound type
8666 if ( ce->section.isClass() ) // class
8667 {
8668 if (yyextra->insidePHP || yyextra->insideD || yyextra->insideJS || yyextra->insideIDL || yyextra->insideSlice)
8669 {
8670 yyextra->current->protection = yyextra->protection = Protection::Public ;
8671 }
8672 else if (yyextra->insideJava)
8673 {
8674 yyextra->current->protection = yyextra->protection = (ce->spec.isInterface() || ce->spec.isEnum()) ? Protection::Public : Protection::Package;
8675 }
8676 else if (ce->spec.isInterface() || ce->spec.isRef() || ce->spec.isValue() || ce->spec.isStruct() || ce->spec.isUnion())
8677 {
8678 if (ce->lang==SrcLangExt::ObjC)
8679 {
8680 yyextra->current->protection = yyextra->protection = Protection::Protected ;
8681 }
8682 else
8683 {
8684 yyextra->current->protection = yyextra->protection = Protection::Public ;
8685 }
8686 }
8687 else
8688 {
8689 yyextra->current->protection = yyextra->protection = Protection::Private ;
8690 }
8691 }
8692 else if (ce->section.isEnum() ) // enum
8693 {
8694 yyextra->current->protection = yyextra->protection = ce->protection;
8695 }
8696 else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
8697 {
8698 if (ce->section.isNamespace() ) // unnamed namespace
8699 {
8700 yyextra->current->isStatic = yyextra->isStatic = TRUE;
8701 }
8702 yyextra->current->protection = yyextra->protection = ce->protection;
8703 yyextra->current->exported = yyextra->exported = false;
8704 }
8705 else if (ce->section.isNamespace() )
8706 {
8707 yyextra->current->protection = yyextra->protection = Protection::Public ;
8708 yyextra->current->exported = yyextra->exported = ce->exported;
8709 }
8710 else // named struct, union, protocol, category
8711 {
8712 yyextra->current->protection = yyextra->protection = Protection::Public ;
8713 yyextra->current->exported = yyextra->exported = false;
8714 }
8715 yyextra->mtype = MethodTypes::Method;
8716 yyextra->virt = Specifier::Normal;
8717 //printf("name=%s yyextra->current->isStatic=%d yyextra->isStatic=%d\n",qPrint(ce->name),yyextra->current->isStatic,yyextra->isStatic);
8718
8719 //memberGroupId = DOX_NOGROUP;
8720 //memberGroupRelates.clear();
8721 //memberGroupInside.clear();
8722 QCString name = ce->name;
8723 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
8724
8725 scannerYYlex(yyscanner);
8726 //forceEndGroup();
8727
8728 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
8729
8730 yyextra->programStr.clear();
8731 ce->program.str(std::string());
8732
8733
8734 //if (depthIf>0)
8735 //{
8736 // warn(yyextra->fileName,yyextra->yyLineNr,"Documentation block ended in the middle of a conditional section!");
8737 //}
8738 }
8739 parseCompounds(yyscanner,ce);
8740 }
8741}
8742
8743static void parseConcepts(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8744{
8745 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8746 for (const auto &ce : rt->children())
8747 {
8748 if (ce->section.isConcept())
8749 {
8750 //printf("*** found concept '%s' value=[[\n%s\n]] line=%d,col=%d\n",
8751 // qPrint(ce->name),qPrint(ce->initializer.str()),ce->startLine,ce->startColumn);
8752 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,ce->name);
8753 // init scanner state
8754 yyextra->padCount =0;
8755 yyextra->column =0;
8756 yyextra->programStr = ce->initializer.str();
8757 yyextra->inputString = yyextra->programStr.data();
8758 yyextra->inputPosition = 0;
8759 yyextra->current_root = ce;
8760 yyextra->fileName = ce->fileName;
8761 yyextra->yyLineNr = ce->bodyLine;
8762 yyextra->yyColNr = ce->bodyColumn;
8763 yyextra->insideObjC = false;
8764 yyextra->current = std::make_shared<Entry>();
8765
8766 // hack to reconstruct what was in the code before the concept expression
8767 QCString indent;
8768 indent.fill(' ',std::max(0,ce->startColumn-1));
8769 QCString templArgs;
8770 if (!ce->args.isEmpty())
8771 {
8772 templArgs=indent+"template"+ce->args+"\n";
8773 }
8774 yyextra->current->initializer.str(QCString(templArgs+indent+"concept "+ce->name+ " =").str());
8775
8776 yyextra->isStatic = FALSE;
8777 initEntry(yyscanner);
8778 yyextra->current->section = EntryType::makeConceptCodePart();
8779 yyextra->current->startLine = yyextra->yyLineNr;
8780 BEGIN( FindConceptParts );
8781 scannerYYlex(yyscanner);
8782 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,ce->name);
8783
8784 }
8785 parseConcepts(yyscanner,ce);
8786 }
8787}
8788
8789//----------------------------------------------------------------------------
8790
8791static void parseMain(yyscan_t yyscanner,
8792 const QCString &fileName,
8793 const char *fileBuf,
8794 const std::shared_ptr<Entry> &rt,
8795 ClangTUParser *clangParser)
8796{
8797 AUTO_TRACE("fileName={}",fileName);
8798 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8799 initParser(yyscanner);
8800
8801 yyextra->inputString = fileBuf;
8802 yyextra->inputPosition = 0;
8803 yyextra->column = 0;
8804 scannerYYrestart(nullptr,yyscanner);
8805
8806 //depthIf = 0;
8807 yyextra->protection = Protection::Public;
8808 yyextra->mtype = MethodTypes::Method;
8809 yyextra->isStatic = FALSE;
8810 yyextra->exported = false;
8811 yyextra->virt = Specifier::Normal;
8812 yyextra->current_root = rt;
8813 yyextra->yyLineNr = 1 ;
8814 yyextra->yyBegLineNr = 1;
8815 yyextra->yyBegColNr = 0;
8816 yyextra->anonCount = 0;
8817 yyextra->anonNSCount = 0;
8818 yyextra->fileName = fileName;
8819 yyextra->clangParser = clangParser;
8820 setContext(yyscanner);
8821 rt->lang = yyextra->language;
8822 msg("Parsing file {}...\n",yyextra->fileName);
8823
8824 yyextra->current_root = rt;
8825 initParser(yyscanner);
8826 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
8827 yyextra->current = std::make_shared<Entry>();
8828 //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root);
8829 EntryType sec=guessSection(yyextra->fileName);
8830 if (!sec.isEmpty())
8831 {
8832 yyextra->current->name = yyextra->fileName;
8833 yyextra->current->section = sec;
8834 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8835 }
8836 yyextra->current->reset();
8837 initEntry(yyscanner);
8838 if ( yyextra->insidePHP )
8839 {
8840 BEGIN( FindMembersPHP );
8841 }
8842 else if ( yyextra->insideJava ) // add default java.lang package scope
8843 {
8844 yyextra->current->name="java::lang"; // '::' is used in doxygen's internal representation as a scope separator
8845 yyextra->current->fileName = yyextra->fileName;
8846 yyextra->current->section = EntryType::makeUsingDir();
8847 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8848 initEntry(yyscanner);
8849 BEGIN( FindMembers );
8850 }
8851 else
8852 {
8853 BEGIN( FindMembers );
8854 }
8855
8856 scannerYYlex(yyscanner);
8857
8858 if (YY_START==Comment)
8859 {
8860 warn(yyextra->fileName,yyextra->yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
8861 }
8862
8863 //forceEndGroup();
8864 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
8865
8866 yyextra->programStr.clear();
8867 rt->program.str(std::string());
8868
8869 parseCompounds(yyscanner,rt);
8870 parseConcepts(yyscanner,rt);
8871
8872 yyextra->anonNSCount++;
8873
8874 // add additional entries that were created during processing
8875 for (auto &[parent,child]: yyextra->outerScopeEntries)
8876 {
8877 //printf(">>> adding '%s' to scope '%s'\n",qPrint(child->name),qPrint(parent->name));
8878 parent->moveToSubEntryAndKeep(child);
8879 }
8880 yyextra->outerScopeEntries.clear();
8881
8882}
8883
8884//----------------------------------------------------------------------------
8885
8886static void parsePrototype(yyscan_t yyscanner,const QCString &text)
8887{
8888 AUTO_TRACE("text='{}'",Trace::trunc(text));
8889 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8890 if (text.isEmpty())
8891 {
8892 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
8893 return;
8894 }
8895 if (!yyextra->current) // nothing to store (see bug683516)
8896 {
8897 return;
8898 }
8899
8900 const char *orgInputString;
8901 int orgInputPosition;
8902 YY_BUFFER_STATE orgState;
8903
8904 // save scanner state
8905 orgState = YY_CURRENT_BUFFER;
8906 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
8907 orgInputString = yyextra->inputString;
8908 orgInputPosition = yyextra->inputPosition;
8909
8910 // set new string
8911 yyextra->inputString = text.data();
8912 yyextra->inputPosition = 0;
8913 yyextra->column = 0;
8914 scannerYYrestart(nullptr, yyscanner);
8915 BEGIN(Prototype);
8916 scannerYYlex(yyscanner);
8917
8918 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
8919 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.isEmpty())
8920 {
8921 yyextra->current->section = EntryType::makeVariableDoc();
8922 }
8923
8924 // restore original scanner state
8925 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
8926 yy_switch_to_buffer(orgState, yyscanner);
8927 yyextra->inputString = orgInputString;
8928 yyextra->inputPosition = orgInputPosition;
8929
8930
8931 //printf("**** parsePrototype end\n");
8932}
8933
8934//----------------------------------------------------------------------------
8935
8941
8943{
8944 scannerYYlex_init_extra(&p->state,&p->yyscanner);
8945#ifdef FLEX_DEBUG
8946 scannerYYset_debug(Debug::isFlagSet(Debug::Lex_scanner)?1:0,p->yyscanner);
8947#endif
8948}
8949
8951{
8952 scannerYYlex_destroy(p->yyscanner);
8953}
8954
8956 const char *fileBuf,
8957 const std::shared_ptr<Entry> &root,
8958 ClangTUParser *clangParser)
8959{
8960 AUTO_TRACE();
8961 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
8962 yyextra->thisParser = this;
8963
8964 DebugLex debugLex(Debug::Lex_scanner, __FILE__, qPrint(fileName));
8965
8966 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
8967}
8968
8969
8971{
8972 QCString fe=extension.lower();
8973 SrcLangExt lang = getLanguageFromFileName(extension);
8974 return (SrcLangExt::Cpp == lang) || (SrcLangExt::Lex == lang) ||
8975 !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
8976 fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5"
8977 );
8978}
8979
8981{
8982 ::parsePrototype(p->yyscanner,text);
8983}
8984
8985//----------------------------------------------------------------------------
8986
8987#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:8955
void parsePrototype(const QCString &text) override
Callback function called by the comment block scanner.
Definition scanner.l:8980
std::unique_ptr< Private > p
Definition scanner.h:46
~COutlineParser() override
Definition scanner.l:8950
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:8970
@ 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:253
bool endsWith(const char *s) const
Definition qcstring.h:528
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:176
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:217
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3982
#define YY_BUF_SIZE
Definition commentcnv.l:19
std::stack< GuardedSection > GuardedSectionStack
Definition commentscan.h:48
static void initParser(yyscan_t yyscanner)
#define Config_getInt(name)
Definition config.h:34
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp: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
static void parseMain(yyscan_t yyscanner, const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt, FortranFormat format)
#define msg(fmt,...)
Definition message.h:94
QCString trunc(const QCString &s, size_t numChars=15)
Definition trace.h:56
static void newEntry(yyscan_t yyscanner)
Definition pyscanner.l:1869
static void parsePrototype(yyscan_t yyscanner, const QCString &text)
Definition pyscanner.l:2399
static void parseCompounds(yyscan_t yyscanner, std::shared_ptr< Entry > rt)
Definition pyscanner.l:2265
const char * qPrint(const char *s)
Definition qcstring.h:691
static void parseConcepts(yyscan_t yyscanner, const std::shared_ptr< Entry > &rt)
Definition scanner.l:8743
QCString name
Definition arguments.h:44
QCString docs
Definition arguments.h:47
scannerYY_state state
Definition scanner.l:8939
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