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