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