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