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
static int computeIndent(const char *s)
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
static const char * stateToString(int state)
static const char * getLexerFILE()
Definition commentcnv.l:168
Interface for the comment block scanner.
#define lineCount(s, len)
static void initParser(yyscan_t yyscanner)
Definition pyscanner.l:1842
static void startCommentBlock(yyscan_t yyscanner, bool brief)
Definition pyscanner.l:2091
static void handleCommentBlock(yyscan_t yyscanner, const DString &doc, bool brief)
Definition pyscanner.l:2106
static void initEntry(yyscan_t yyscanner)
Definition pyscanner.l:1853
static void startVerbatimBlock(yyscan_t yyscanner, const DString &blockName, size_t fencedSize=0, bool codeBlock=false)
Definition scanner.l:8211
static void storeClangId(yyscan_t yyscanner, const char *id)
Definition scanner.l:8103
static bool endVerbatimBlock(yyscan_t yyscanner, const DString &blockName, size_t fencedSize=0)
Definition scanner.l:8225
static void setContext(yyscan_t yyscanner)
Definition scanner.l:8263
static bool startOfRequiresExpression(const DString &req)
Definition scanner.l:8244
static DString stripFuncPtr(const DString &type)
Definition scanner.l:8198
static bool checkForKnRstyleC(yyscan_t yyscanner)
Definition scanner.l:8303
static void addKnRArgInfo(yyscan_t yyscanner, const DString &type, const DString &name, const DString &brief, const DString &docs)
Definition scanner.l:8423
static void initMethodProtection(yyscan_t yyscanner, Protection prot)
Definition scanner.l:8153
void fixArgumentListForJavaScript(ArgumentList &al)
Definition scanner.l:8452
static void splitKnRArg(yyscan_t yyscanner, DString &oldStyleArgPtr, DString &oldStyleArgName)
Definition scanner.l:8334
static bool nameIsOperator(DString &name)
Definition scanner.l:8252
static void handleParametersCommentBlocks(yyscan_t yyscanner, ArgumentList &al)
Definition scanner.l:8563
static void prependScope(yyscan_t yyscanner)
Definition scanner.l:8285
static void setJavaProtection(yyscan_t yyscanner)
Definition scanner.l:8317
static void addType(yyscan_t yyscanner)
Definition scanner.l:8165
static DString stripQuotes(const char *s)
Definition scanner.l:8186
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:1253
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:98
1014<ObjCPropAttr>"getter="{ID} {
1015 yyextra->current->read = yytext+7;
1016 }
1017<ObjCPropAttr>"setter="{ID} {
1018 yyextra->current->write = yytext+7;
1019 }
1020<ObjCPropAttr>"readonly" {
1021 yyextra->current->spec.setWritable(false);
1022 }
1023<ObjCPropAttr>"readwrite" { // default
1024 }
1025<ObjCPropAttr>"assign" { // default
1026 }
1027<ObjCPropAttr>"unsafe_unretained" {
1028 yyextra->current->spec.setAssign(false);
1029 yyextra->current->spec.setUnretained(true);
1030 }
1031<ObjCPropAttr>"retain" {
1032 yyextra->current->spec.setAssign(false);
1033 yyextra->current->spec.setRetain(true);
1034 }
1035<ObjCPropAttr>"copy" {
1036 yyextra->current->spec.setAssign(false);
1037 yyextra->current->spec.setCopy(true);
1038 }
1039<ObjCPropAttr>"weak" {
1040 yyextra->current->spec.setAssign(false);
1041 yyextra->current->spec.setWeak(true);
1042 }
1043<ObjCPropAttr>"strong" {
1044 yyextra->current->spec.setAssign(false);
1045 yyextra->current->spec.setStrong(true);
1046 }
1047<ObjCPropAttr>"nonatomic" {
1048 yyextra->current->spec.setNonAtomic(true);
1049 }
1050<ObjCPropAttr>")" {
1051 BEGIN(FindMembers);
1052 }
1053<FindMembers>"@"{ID}("."{ID})+ {
1054 if (yyextra->insideJava) // Java annotation
1055 {
1056 // skip annotation
1057 }
1058 else
1059 {
1060 REJECT;
1061 }
1062 }
1063<FindMembers>"@"{ID} {
1064 if (yyextra->insideJava) // Java annotation
1065 {
1066 // skip annotation
1067 }
1068 else if (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:567
1964<PHPUseAs>{BN}+"as"{BN}+ {
1965 lineCount(yyscanner);
1966 }
1967<PHPUseAs>{PHPUSEKW} {
1968 }
1969<PHPUseAs>{ID} {
1970 //printf("PHP: adding use as relation: %s->%s\n",yytext,qPrint(yyextra->aliasName));
1971 if (!yyextra->aliasName.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:2917
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:72
2190<EndTemplate>"<<<" {
2191 if (!yyextra->insidePHP)
2192 {
2193 REJECT;
2194 }
2195 else
2196 {
2197 yyextra->lastHereDocContext = YY_START;
2198 BEGIN(HereDoc);
2199 }
2200 }
2201<ClassTemplSpec,EndTemplate>("<<"|"<=") {
2202 yyextra->current->name+=yytext;
2203 // *yyextra->currentTemplateSpec+=yytext;
2204 }
2205<EndTemplate>"<" {
2206 if (yyextra->roundCount==0)
2207 {
2208 // *yyextra->currentTemplateSpec+='<';
2209 yyextra->sharpCount++;
2210 }
2211 yyextra->current->name+=yytext;
2212 }
2213<ClassTemplSpec,EndTemplate>">=" {
2214 yyextra->current->name+=yytext;
2215 }
2216<ClassTemplSpec,EndTemplate>(">>") {
2217 if (yyextra->insideJava || yyextra->insideCS || yyextra->insideCli || yyextra->roundCount==0)
2218 {
2219 unput('>');
2220 unput(' ');
2221 unput('>');
2222 }
2223 else
2224 {
2225 yyextra->current->name+=yytext;
2226 }
2227 // *yyextra->currentTemplateSpec+=yytext;
2228 }
2229<EndTemplate>">" {
2230 yyextra->current->name+='>';
2231 // *yyextra->currentTemplateSpec+='>';
2232 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
2233 {
2234 yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
2235 //printf("Found %s\n",qPrint(yyextra->current->name));
2236 BEGIN(FindMembers);
2237 }
2238 }
2239<EndTemplate>">"{BN}*"(" {
2240 lineCount(yyscanner);
2241 yyextra->current->name+='>';
2242 // *yyextra->currentTemplateSpec+='>';
2243 if (yyextra->roundCount==0)
2244 {
2245 --yyextra->sharpCount;
2246 }
2247 if (yyextra->roundCount==0 && yyextra->sharpCount<=0)
2248 {
2249 yyextra->current->bodyLine = yyextra->yyLineNr;
2250 yyextra->current->bodyColumn = yyextra->yyColNr;
2251 yyextra->current->args = "(";
2252 yyextra->currentArgumentContext = FuncQual;
2253 yyextra->fullArgString = yyextra->current->args;
2254 yyextra->copyArgString = &yyextra->current->args;
2255 //printf("Found %s\n",qPrint(yyextra->current->name));
2256 BEGIN( ReadFuncArgType ) ;
2257 }
2258 else
2259 {
2260 yyextra->current->name+="(";
2261 yyextra->roundCount++;
2262 }
2263 }
2264<EndTemplate>">"{BNopt}/"("({BN}*{TSCOPE}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance
2265 lineCount(yyscanner);
2266 yyextra->current->name+='>';
2267 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
2268 {
2269 BEGIN(FindMembers);
2270 }
2271 }
2272<EndTemplate>">"{BNopt}/"::" {
2273 lineCount(yyscanner);
2274 yyextra->current->name+='>';
2275 // *yyextra->currentTemplateSpec+='>';
2276 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
2277 {
2278 BEGIN(FindMemberName);
2279 }
2280 }
2281<ClassTemplSpec,EndTemplate>"(" { yyextra->current->name+=*yytext;
2282 yyextra->roundCount++;
2283 }
2284<ClassTemplSpec,EndTemplate>")" { yyextra->current->name+=*yytext;
2285 if (yyextra->roundCount>0) yyextra->roundCount--;
2286 }
2287<EndTemplate>. {
2288 yyextra->current->name+=*yytext;
2289 // *yyextra->currentTemplateSpec+=*yytext;
2290 }
2291<FindMembers>"define"{BN}*"("{BN}*["'] {
2292 if (yyextra->insidePHP)
2293 {
2294 yyextra->current->bodyLine = yyextra->yyLineNr;
2295 yyextra->current->bodyColumn = yyextra->yyColNr;
2296 BEGIN( DefinePHP );
2297 }
2298 else
2299 REJECT;
2300 }
2301<CopyHereDoc>{ID} { // PHP heredoc
2302 yyextra->delimiter = yytext;
2303 *yyextra->pCopyHereDocGString << yytext;
2304 BEGIN(CopyHereDocEnd);
2305 }
2306<CopyHereDoc>"\""{ID}/"\"" { // PHP quoted heredoc
2307 yyextra->delimiter = &yytext[1];
2308 *yyextra->pCopyHereDocGString << yytext;
2309 BEGIN(CopyHereDocEnd);
2310 }
2311<CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc
2312 yyextra->delimiter = &yytext[1];
2313 *yyextra->pCopyHereDocGString << yytext;
2314 BEGIN(CopyHereDocEnd);
2315 }
2316<HereDoc>{ID} { // PHP heredoc
2317 yyextra->delimiter = yytext;
2318 BEGIN(HereDocEnd);
2319 }
2320<HereDoc>"\""{ID}/"\"" { // PHP quoted heredoc
2321 yyextra->delimiter = &yytext[1];
2322 BEGIN(HereDocEnd);
2323 }
2324<HereDoc>"'"{ID}/"'" { // PHP nowdoc
2325 yyextra->delimiter = &yytext[1];
2326 BEGIN(HereDocEnd);
2327 }
2328<HereDocEnd>^{Bopt}{ID} { // id at start of the line could mark the end of the block
2329 if (yyextra->delimiter==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
static void startCommentBlock(yyscan_t yyscanner, bool)
Definition scanner.l:8466
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:6971
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:6979
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 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4769 yyextra->current = std::make_shared<Entry>(*yyextra->memspecEntry);
4770 if (yyextra->current->section.isNamespace() ||
4771 yyextra->current->spec.isInterface() ||
4772 yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideJS ||
4773 yyextra->insideSlice
4774 )
4775 { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
4776 yyextra->current->reset();
4777 yyextra->current_root = std::move(original_root); // restore scope from before namespace descent
4778 initEntry(yyscanner);
4779 yyextra->memspecEntry.reset();
4780 BEGIN( FindMembers ) ;
4781 }
4782 else
4783 {
4784 // enabled the next two lines for bug 623424
4785 yyextra->current->doc.clear();
4786 yyextra->current->brief.clear();
4787 BEGIN( MemberSpec ) ;
4788 }
4789 }
4790 }
4791 }
4792 }
void clear()
Definition dstring.h:219
bool startsWith(const char *s) const
Definition dstring.h:589
4793<ReadBody>"}"{BN}+"typedef"{BN}+ {
4794 lineCount(yyscanner);
4795 if ( yyextra->curlyCount>0 )
4796 {
4797 yyextra->current->program << yytext ;
4798 --yyextra->curlyCount ;
4799 }
4800 else
4801 {
4802 yyextra->isTypedef = true;
4803 yyextra->current->endBodyLine = yyextra->yyLineNr;
4804 DString &cn = yyextra->current->name;
4805 DString rn = yyextra->current_root->name;
4806 if (!cn.empty() && !rn.empty())
4807 {
4808 prependScope(yyscanner);
4809 }
4810 BEGIN( TypedefName );
4811 }
4812 }
4813<TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
4814 lineCount(yyscanner);
4815 yyextra->current->type.prepend(yytext);
4816 }
4817<TypedefName>{ID} {
4818 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4819 {
4820 yyextra->current->program << ","; // add field terminator
4821 }
4822 yyextra->current->name=yytext;
4823 prependScope(yyscanner);
4824 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4825 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4826 //printf("Adding compound %s %s %s\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
4827 if (!yyextra->firstTypedefEntry)
4828 {
4829 yyextra->firstTypedefEntry = yyextra->current;
4830 }
4831 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4832 initEntry(yyscanner);
4833 yyextra->isTypedef=true; // to undo reset by initEntry(yyscanner)
4834 BEGIN(MemberSpecSkip);
4835 }
4836<TypedefName>";" { /* typedef of anonymous type */
4837 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
4838 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4839 {
4840 yyextra->current->program << ','; // add field terminator
4841 }
4842 // add compound definition to the tree
4843 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4844 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4845 yyextra->memspecEntry = yyextra->current;
4846 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4847 initEntry(yyscanner);
4848 unput(';');
4849 BEGIN( MemberSpec ) ;
4850 }
DString generateAnonymousAnchor(const DString &fileName, int count)
Definition util.cpp:3599
4851<MemberSpec>([*&]*{BN}*)*{ID}{BN}*("["[^\‍]\n]*"]")* { // the [] part could be improved.
4852 lineCount(yyscanner);
4853 int i=0,l=(int)yyleng;
4854 while (i<l && (!isId(yytext[i]))) i++;
4855 yyextra->msName = DString(yytext).right(l-i).stripWhiteSpace();
4856 if (size_t j=yyextra->msName.find("[") ; j!=DString::npos)
4857 {
4858 yyextra->msArgs=yyextra->msName.mid(j);
4859 yyextra->msName=yyextra->msName.left(j);
4860 }
4861 yyextra->msType=DString(yytext).left(i);
4862
4863 // handle *pName in: typedef { ... } name, *pName;
4864 if (yyextra->firstTypedefEntry)
4865 {
4866 if (yyextra->firstTypedefEntry->spec.isStruct())
4867 {
4868 yyextra->msType.prepend("struct "+yyextra->firstTypedefEntry->name);
4869 }
4870 else if (yyextra->firstTypedefEntry->spec.isUnion())
4871 {
4872 yyextra->msType.prepend("union "+yyextra->firstTypedefEntry->name);
4873 }
4874 else if (yyextra->firstTypedefEntry->section.isEnum())
4875 {
4876 yyextra->msType.prepend("enum "+yyextra->firstTypedefEntry->name);
4877 }
4878 else
4879 {
4880 yyextra->msType.prepend(yyextra->firstTypedefEntry->name);
4881 }
4882 }
4883 }
bool isId(int c)
Definition util.h:257
4884<MemberSpec>"(" { // function with struct return type
4885 addType(yyscanner);
4886 yyextra->current->name = yyextra->msName;
4887 yyextra->current->spec = TypeSpecifier();
4888 unput('(');
4889 BEGIN(FindMembers);
4890 }
4891<MemberSpec>[,;] {
4892 //printf("msName=%s\n",qPrint(yyextra->msName));
4893 if (yyextra->msName.empty() && !yyextra->current->name.empty())
4894 {
4895 // see if the compound does not have a name or is yyextra->inside another
4896 // anonymous compound. If so we insert a
4897 // special 'anonymous' variable.
4898 //Entry *p=yyextra->current_root;
4899 const Entry *p=yyextra->current.get();
4900 while (p)
4901 {
4902 // only look for class scopes, not namespace scopes
4903 if (p->section.isCompound() && !p->name.empty())
4904 {
4905 //printf("Trying scope '%s'\n",qPrint(p->name));
4906 size_t i=p->name.rfind("::");
4907 int pi = i==DString::npos ? 0 : i+2;
4908 if (p->name.at(pi)=='@')
4909 {
4910 // anonymous compound yyextra->inside -> insert dummy variable name
4911 //printf("Adding anonymous variable for scope %s\n",qPrint(p->name));
4912 yyextra->msName = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
4913 break;
4914 }
4915 }
4916 //p=p->parent;
4917 if (p==yyextra->current.get()) p=yyextra->current_root.get(); else p=p->parent();
4918 }
4919 }
4920 //printf("yyextra->msName=%s yyextra->current->name=%s\n",qPrint(yyextra->msName),qPrint(yyextra->current->name));
4921 if (!yyextra->msName.empty()
4922 /*&& yyextra->msName!=yyextra->current->name*/) // skip typedef T {} T;, removed due to bug608493
4923 {
4924 bool typedefHidesStruct = Config_getBool(TYPEDEF_HIDES_STRUCT);
4925 // case 1: typedef struct _S { ... } S_t;
4926 // -> omit typedef and use S_t as the struct name
4927 if (typedefHidesStruct &&
4928 yyextra->isTypedef &&
4929 ((yyextra->current->spec.isStruct() || yyextra->current->spec.isUnion()) || yyextra->current->section.isEnum()) &&
4930 yyextra->msType.stripWhiteSpace().empty() &&
4931 yyextra->memspecEntry)
4932 {
4933 yyextra->memspecEntry->name=yyextra->msName;
4934 }
4935 else // case 2: create a typedef field
4936 {
4937 std::shared_ptr<Entry> varEntry=std::make_shared<Entry>();
4938 varEntry->lang = yyextra->language;
4939 varEntry->protection = yyextra->current->protection ;
4940 varEntry->mtype = yyextra->current->mtype;
4941 varEntry->virt = yyextra->current->virt;
4942 varEntry->isStatic = yyextra->current->isStatic;
4943 varEntry->section = EntryType::makeVariable();
4944 varEntry->name = yyextra->msName.stripWhiteSpace();
4945 varEntry->type = yyextra->current->type.simplifyWhiteSpace()+" ";
4946 varEntry->args = yyextra->msArgs;
4947 if (yyextra->isTypedef)
4948 {
4949 varEntry->type.prepend("typedef ");
4950 // //printf("yyextra->current->name = %s %s\n",qPrint(yyextra->current->name),qPrint(yyextra->msName));
4951 }
4952 if (typedefHidesStruct &&
4953 yyextra->isTypedef &&
4954 (yyextra->current->spec.isStruct() || yyextra->current->spec.isUnion()) &&
4955 yyextra->memspecEntry
4956 ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
4957 {
4958 varEntry->type+=yyextra->memspecEntry->name+yyextra->msType;
4959 }
4960 else // case 2: use _S as type for for pS_t
4961 {
4962 varEntry->type+=yyextra->current->name+yyextra->msType;
4963 }
4964 varEntry->fileName = yyextra->fileName;
4965 varEntry->startLine = yyextra->yyLineNr;
4966 varEntry->startColumn = yyextra->yyColNr;
4967 varEntry->doc = yyextra->current->doc;
4968 varEntry->brief = yyextra->current->brief;
4969 varEntry->mGrpId = yyextra->current->mGrpId;
4970 varEntry->initializer.str(yyextra->current->initializer.str());
4971 varEntry->groups = yyextra->current->groups;
4972 varEntry->sli = yyextra->current->sli;
4973
4974 //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n",
4975 // qPrint(varEntry->type),qPrint(varEntry->name),
4976 // qPrint(varEntry->args),qPrint(varEntry->brief),qPrint(varEntry->doc));
4977 yyextra->current_root->moveToSubEntryAndKeep(varEntry);
4978 }
4979 }
4980 if (*yytext==';') // end of a struct/class ...
4981 {
4982 if (!yyextra->isTypedef && yyextra->msName.empty() &&
4983 yyextra->memspecEntry && yyextra->current->section.isCompound())
4984 { // case where a class/struct has a doc block after it
4985 if (!yyextra->current->doc.empty())
4986 {
4987 yyextra->memspecEntry->doc += yyextra->current->doc;
4988 }
4989 if (!yyextra->current->brief.empty())
4990 {
4991 yyextra->memspecEntry->brief += yyextra->current->brief;
4992 }
4993 }
4994 yyextra->msType.clear();
4995 yyextra->msName.clear();
4996 yyextra->msArgs.clear();
4997 yyextra->isTypedef=false;
4998 yyextra->firstTypedefEntry.reset();
4999 yyextra->memspecEntry.reset();
5000 yyextra->current->reset();
5001 initEntry(yyscanner);
5002 BEGIN( FindMembers );
5003 }
5004 else
5005 {
5006 yyextra->current->doc.clear();
5007 yyextra->current->brief.clear();
5008 }
5009
5010 }
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
5011<MemberSpec>"=" {
5012 yyextra->lastInitializerContext=YY_START;
5013 yyextra->sharpCount=0;
5014 yyextra->initBracketCount=0;
5015 yyextra->current->initializer.str(yytext);
5016 BEGIN(ReadInitializer);
5017 /* BEGIN(MemberSpecSkip); */
5018 }
5019 /*
5020<MemberSpecSkip>"{" {
5021 yyextra->curlyCount=0;
5022 yyextra->lastCurlyContext = MemberSpecSkip;
5023 yyextra->previous = yyextra->current;
5024 BEGIN(SkipCurly);
5025 }
5026 */
5027<MemberSpecSkip>"," { BEGIN(MemberSpec); }
5028<MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); }
5029<ReadBody,ReadNSBody,ReadBodyIntf>{BN}{1,80} { yyextra->current->program << yytext ;
5030 lineCount(yyscanner) ;
5031 }
5032<ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block
5033 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
5034 initEntry(yyscanner);
5035 yyextra->language = yyextra->current->lang = SrcLangExt::Cpp; // see bug746361
5036 yyextra->insideObjC=false;
5037 BEGIN( FindMembers );
5038 }
5039<ReadBody,ReadNSBody,ReadBodyIntf>\\. { yyextra->current->program << yytext ; }
5040<ReadBody,ReadNSBody,ReadBodyIntf>. { yyextra->current->program << yytext ; }
5041
5042<FindMembers>"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
5043<FindMembers>("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */
5044 if (yyextra->insidePHP) // reference parameter
5045 {
5046 REJECT
5047 }
5048 else
5049 {
5050 yyextra->current->bodyLine = yyextra->yyLineNr;
5051 yyextra->current->bodyColumn = yyextra->yyColNr;
5052 lineCount(yyscanner);
5053 addType(yyscanner);
5054 yyextra->funcPtrType=yytext;
5055 yyextra->roundCount=0;
5056 //yyextra->current->type += yytext;
5057 BEGIN( FuncPtr );
5058 }
5059 }
5060<FuncPtr>{SCOPENAME} {
5061 yyextra->current->name = yytext;
5062 if (nameIsOperator(yyextra->current->name))
5063 {
5064 BEGIN( FuncPtrOperator );
5065 }
5066 else
5067 {
5068 if (yyextra->current->name=="const" || yyextra->current->name=="volatile")
5069 {
5070 yyextra->funcPtrType += yyextra->current->name;
5071 }
5072 else
5073 {
5074 BEGIN( EndFuncPtr );
5075 }
5076 }
5077 }
5078<FuncPtr>. {
5079 //printf("error: FuncPtr '%c' unexpected at line %d of %s\n",*yytext,yyextra->yyLineNr,yyextra->fileName);
5080 }
5081<FuncPtrOperator>"("{BN}*")"{BNopt}/"(" {
5082 yyextra->current->name += yytext;
5083 yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
5084 lineCount(yyscanner);
5085 }
5086<FuncPtrOperator>\n {
5087 lineCount(yyscanner);
5088 yyextra->current->name += *yytext;
5089 }
5090<FuncPtrOperator>"(" {
5091 unput(*yytext);
5092 BEGIN( EndFuncPtr );
5093 }
5094<FuncPtrOperator>. {
5095 yyextra->current->name += *yytext;
5096 }
5097<EndFuncPtr>")"{BNopt}/";" { // a variable with extra braces
5098 lineCount(yyscanner);
5099 yyextra->current->type+=yyextra->funcPtrType.mid(1);
5100 BEGIN(FindMembers);
5101 }
5102<EndFuncPtr>")"{BNopt}/"(" { // a function pointer
5103 lineCount(yyscanner);
5104 if (yyextra->funcPtrType!="(") // not just redundant braces
5105 {
5106 yyextra->current->type+=yyextra->funcPtrType+")";
5107 }
5108 BEGIN(FindMembers);
5109 }
5110<EndFuncPtr>")"{BNopt}/"[" { // an array of variables
5111 lineCount(yyscanner);
5112 yyextra->current->type+=yyextra->funcPtrType;
5113 yyextra->current->args += ")";
5114 BEGIN(FindMembers);
5115 }
5116<EndFuncPtr>"(" { // a function returning a function or
5117 // a function returning a pointer to an array
5118 yyextra->current->args += *yytext ;
5119 //yyextra->roundCount=0;
5120 //BEGIN( FuncFunc );
5121 yyextra->current->bodyLine = yyextra->yyLineNr;
5122 yyextra->current->bodyColumn = yyextra->yyColNr;
5123 yyextra->currentArgumentContext = FuncFuncEnd;
5124 yyextra->fullArgString=yyextra->current->args;
5125 yyextra->copyArgString=&yyextra->current->args;
5126 BEGIN( ReadFuncArgType ) ;
5127 }
5128<EndFuncPtr>"["[^\n\‍]]*"]" {
5129 yyextra->funcPtrType+=yytext;
5130 }
5131<EndFuncPtr>")" {
5132 BEGIN(FindMembers);
5133 }
5134<FuncFunc>"(" {
5135 yyextra->current->args += *yytext ;
5136 ++yyextra->roundCount;
5137 }
5138<FuncFunc>")" {
5139 yyextra->current->args += *yytext ;
5140 if ( yyextra->roundCount )
5141 --yyextra->roundCount;
5142 else
5143 {
5144 BEGIN(FuncFuncEnd);
5145 }
5146 }
5147<FuncFuncEnd>")"{BN}*"(" {
5148 lineCount(yyscanner);
5149 yyextra->current->type+=yyextra->funcPtrType+")(";
5150 BEGIN(FuncFuncType);
5151 }
5152<FuncFuncEnd>")"{BNopt}/[;{] {
5153 lineCount(yyscanner);
5154 yyextra->current->type+=yyextra->funcPtrType.mid(1);
5155 BEGIN(SFunction);
5156 }
5157<FuncFuncEnd>")"{BNopt}/"[" { // function returning a pointer to an array
5158 lineCount(yyscanner);
5159 yyextra->current->type+=yyextra->funcPtrType;
5160 yyextra->current->args+=")";
5161 BEGIN(FuncFuncArray);
5162 }
5163<FuncFuncEnd>. {
5164 yyextra->current->args += *yytext;
5165 }
5166<FuncFuncType>"(" {
5167 yyextra->current->type += *yytext;
5168 yyextra->roundCount++;
5169 }
5170<FuncFuncType>")" {
5171 yyextra->current->type += *yytext;
5172 if (yyextra->roundCount)
5173 --yyextra->roundCount;
5174 else
5175 BEGIN(SFunction);
5176 }
5177<FuncFuncType>{BN}*","{BN}* { lineCount(yyscanner) ; yyextra->current->type += ", " ; }
5178<FuncFuncType>{BN}+ { lineCount(yyscanner) ; yyextra->current->type += ' ' ; }
5179<FuncFuncType>. {
5180 yyextra->current->type += *yytext;
5181 }
5182<FindMembers>"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")"{BN}*"(" { // for catching typedef void (__stdcall *f)() like definitions
5183 if (yyextra->current->type.startsWith("typedef") &&
5184 yyextra->current->bodyLine==-1)
5185 // the bodyLine check is to prevent this guard to be true more than once
5186 {
5187 yyextra->current->bodyLine = yyextra->yyLineNr;
5188 yyextra->current->bodyColumn = yyextra->yyColNr;
5189 BEGIN( GetCallType );
5190 }
5191 else if (!yyextra->current->name.empty()) // normal function
5192 {
5193 yyextra->current->args = yytext;
5194 yyextra->current->bodyLine = yyextra->yyLineNr;
5195 yyextra->current->bodyColumn = yyextra->yyColNr;
5196 yyextra->currentArgumentContext = FuncQual;
5197 yyextra->fullArgString=yyextra->current->args;
5198 yyextra->copyArgString=&yyextra->current->args;
5199 BEGIN( ReadFuncArgType ) ;
5200 //printf(">>> Read function arguments!\n");
5201 }
5202 }
5203<GetCallType>{BN}*{ID}{BN}*"*" {
5204 lineCount(yyscanner);
5205 addType(yyscanner);
5206 yyextra->funcPtrType="(";
5207 yyextra->funcPtrType+=yytext;
5208 yyextra->roundCount=0;
5209 BEGIN( FuncPtr );
5210 }
5211<FindMembers>"(" {
5212 if (!yyextra->current->name.empty())
5213 {
5214 yyextra->current->args = yytext;
5215 yyextra->current->bodyLine = yyextra->yyLineNr;
5216 yyextra->current->bodyColumn = yyextra->yyColNr;
5217 yyextra->currentArgumentContext = FuncQual;
5218 yyextra->fullArgString=yyextra->current->args;
5219 yyextra->copyArgString=&yyextra->current->args;
5220 BEGIN( ReadFuncArgType ) ;
5221 //printf(">>> Read function arguments yyextra->current->argList.size()=%d\n",yyextra->current->argList.size());
5222 }
5223 }
5224
5225 /*- Function argument reading rules ---------------------------------------*/
5226
5227<ReadFuncArgType>[^ \/\r\t\n\‍[\‍]\‍)\‍(\"\'#]+ { *yyextra->copyArgString+=yytext;
5228 if (yyextra->insideCS) yyextra->fullArgString+=substitute(yytext,".","::");
5229 else yyextra->fullArgString+=yytext;
5230 }
5231<CopyArgString,CopyArgPHPString>[^\n\\\"\']+ { *yyextra->copyArgString+=yytext;
5232 yyextra->fullArgString+=yytext;
5233 }
5234<CopyArgRound>[^\/\n\‍)\‍(\"\']+ {
5235 *yyextra->copyArgString+=yytext;
5236 yyextra->fullArgString+=yytext;
5237 }
5238<CopyArgSquare>[^\/\n\‍]\‍[\"\']+ {
5239 *yyextra->copyArgString+=yytext;
5240 yyextra->fullArgString+=yytext;
5241 }
5242<ReadFuncArgType,ReadTempArgs>{BN}* {
5243 *yyextra->copyArgString+=" ";
5244 yyextra->fullArgString+=" ";
5245 lineCount(yyscanner);
5246 }
5247<ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>{RAWBEGIN} {
5248 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
5249 yyextra->lastRawStringContext = YY_START;
5250 yyextra->pCopyRawString = yyextra->copyArgString;
5251 *yyextra->pCopyRawString+=yytext;
5252 yyextra->fullArgString+=yytext;
5253 BEGIN(RawString);
5254 }
5255<ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>\" {
5256 *yyextra->copyArgString+=*yytext;
5257 yyextra->fullArgString+=*yytext;
5258 yyextra->lastCopyArgStringContext = YY_START;
5259 BEGIN( CopyArgString );
5260 }
5261<ReadFuncArgType>"[" {
5262 if (!yyextra->insidePHP) REJECT;
5263 *yyextra->copyArgString+=*yytext;
5264 yyextra->fullArgString+=*yytext;
5265 yyextra->argSquareCount=0;
5266 yyextra->lastCopyArgContext = YY_START;
5267 BEGIN( CopyArgSquare );
5268 }
5269<ReadFuncArgType,ReadTempArgs>"(" {
5270 *yyextra->copyArgString+=*yytext;
5271 yyextra->fullArgString+=*yytext;
5272 yyextra->argRoundCount=0;
5273 yyextra->lastCopyArgContext = YY_START;
5274 BEGIN( CopyArgRound );
5275 }
5276<ReadFuncArgType>")" {
5277 *yyextra->copyArgString+=*yytext;
5278 yyextra->fullArgString+=*yytext;
5279 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5280 if (yyextra->insideJS)
5281 {
5282 fixArgumentListForJavaScript(yyextra->current->argList);
5283 }
5284 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
5285
5286 /* remember the yyextra->current documentation block, since
5287 we could overwrite it with the documentation of
5288 a function argument, which we then have to correct later
5289 on
5290 */
5291 yyextra->docBackup = yyextra->current->doc;
5292 yyextra->briefBackup = yyextra->current->brief;
5293
5294 BEGIN( yyextra->currentArgumentContext );
5295 }
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const DString &argsString, DString *extraTypeChars=nullptr)
Definition defargs.l:828
5296 /* a special comment */
5297<ReadFuncArgType,ReadTempArgs>({CCS}[*!]|{CPPC}[/!])("<"?) {
5298 if (yyextra->currentArgumentContext==DefineEnd)
5299 {
5300 // for defines we interpret a comment
5301 // as documentation for the define
5302 int i;for (i=(int)yyleng-1;i>=0;i--)
5303 {
5304 unput(yytext[i]);
5305 }
5306 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5307 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
5308 BEGIN( yyextra->currentArgumentContext );
5309 }
5310 else // not a define
5311 {
5312 // for functions we interpret a comment
5313 // as documentation for the argument
5314 yyextra->fullArgString+=yytext;
5315 yyextra->lastCopyArgChar=0;
5316 yyextra->lastCommentInArgContext=YY_START;
5317 if (yytext[1]=='/')
5318 BEGIN( CopyArgCommentLine );
5319 else
5320 BEGIN( CopyArgComment );
5321 }
5322 }
5323 /* a non-special comment */
5324<ReadFuncArgType,ReadTempArgs>{CCS}{CCE} { /* empty comment */ }
5325<ReadFuncArgType,ReadTempArgs>{CCS} {
5326 yyextra->lastCContext = YY_START;
5327 BEGIN( SkipComment );
5328 }
5329<ReadFuncArgType,ReadTempArgs>{CPPC} {
5330 yyextra->lastCContext = YY_START;
5331 BEGIN( SkipCxxComment );
5332 }
5333 /*
5334<ReadFuncArgType,ReadTempArgs>"'#" { if (yyextra->insidePHP)
5335 REJECT;
5336 *yyextra->copyArgString+=yytext;
5337 yyextra->fullArgString+=yytext;
5338 }
5339<ReadFuncArgType,ReadTempArgs>"#" {
5340 if (!yyextra->insidePHP)
5341 REJECT;
5342 yyextra->lastCContext = YY_START;
5343 BEGIN( SkipCxxComment );
5344 }
5345 */
5346 /* ')' followed by a special comment */
5347<ReadFuncArgType>")"{BN}*({CCS}[*!]|{CPPC}[/!])"<" {
5348 lineCount(yyscanner);
5349 if (yyextra->currentArgumentContext==DefineEnd)
5350 {
5351 // for defines we interpret a comment
5352 // as documentation for the define
5353 int i;for (i=(int)yyleng-1;i>0;i--)
5354 {
5355 unput(yytext[i]);
5356 }
5357 *yyextra->copyArgString+=*yytext;
5358 yyextra->fullArgString+=*yytext;
5359 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5360 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
5361 BEGIN( yyextra->currentArgumentContext );
5362 }
5363 else
5364 {
5365 // for functions we interpret a comment
5366 // as documentation for the yyextra->last argument
5367 yyextra->lastCopyArgChar=*yytext;
5368 DString text=&yytext[1];
5369 text=text.stripWhiteSpace();
5370 yyextra->lastCommentInArgContext=YY_START;
5371 yyextra->fullArgString+=text;
5372 if (text.find("//")!=DString::npos)
5373 BEGIN( CopyArgCommentLine );
5374 else
5375 BEGIN( CopyArgComment );
5376 }
5377 }
5378<CopyArgComment>^{B}*"*"+/{BN}+
5379<CopyArgComment>[^\n\\\@\*]+ { yyextra->fullArgString+=yytext; }
5380<CopyArgComment>{CCE} { yyextra->fullArgString+=yytext;
5381 if (yyextra->lastCopyArgChar!=0)
5382 unput(yyextra->lastCopyArgChar);
5383 BEGIN( yyextra->lastCommentInArgContext );
5384 }
5385<CopyArgCommentLine>\n { yyextra->fullArgString+=yytext;
5386 lineCount(yyscanner);
5387 if (yyextra->lastCopyArgChar!=0)
5388 unput(yyextra->lastCopyArgChar);
5389 BEGIN( yyextra->lastCommentInArgContext );
5390 }
5391<CopyArgCommentLine>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
5392 yyextra->docBlockName="uml";
5393 yyextra->fullArgString+=yytext;
5394 BEGIN(CopyArgVerbatim);
5395 }
5396<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!)
5397 yyextra->docBlockName=&yytext[1];
5398 yyextra->fullArgString+=yytext;
5399 BEGIN(CopyArgVerbatim);
5400 }
5401<CopyArgCommentLine>{CMD}("f$"|"f["|"f{"|"f(") {
5402 yyextra->docBlockName=&yytext[1];
5403 if (yyextra->docBlockName.at(1)=='[')
5404 {
5405 yyextra->docBlockName.at(1)=']';
5406 }
5407 if (yyextra->docBlockName.at(1)=='{')
5408 {
5409 yyextra->docBlockName.at(1)='}';
5410 }
5411 if (yyextra->docBlockName.at(1)=='(')
5412 {
5413 yyextra->docBlockName.at(1)=')';
5414 }
5415 yyextra->fullArgString+=yytext;
5416 BEGIN(CopyArgVerbatim);
5417 }
5418<CopyArgVerbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"endmermaid"|"enduml"|"endcode")/[^a-z_A-Z0-9\-] { // end of verbatim block
5419 yyextra->fullArgString+=yytext;
5420 if (&yytext[4]==yyextra->docBlockName)
5421 {
5422 yyextra->docBlockName="";
5423 BEGIN(CopyArgCommentLine);
5424 }
5425 }
5426<CopyArgVerbatim>{CMD}("f$"|"f]"|"f}"|"f)") { // end of verbatim block
5427 yyextra->fullArgString+=yytext;
5428 if (yyextra->docBlockName==&yytext[1])
5429 {
5430 yyextra->docBlockName="";
5431 BEGIN(CopyArgCommentLine);
5432 }
5433 }
5434<CopyArgCommentLine>[^\\\@\n]+ { yyextra->fullArgString+=yytext; }
5435<CopyArgCommentLine>. { yyextra->fullArgString+=*yytext; }
5436<CopyArgComment,CopyArgVerbatim>\n { yyextra->fullArgString+=*yytext; lineCount(yyscanner); }
5437<CopyArgComment,CopyArgVerbatim>. { yyextra->fullArgString+=*yytext; }
5438<CopyArgComment>{CMD}("brief"|"short"){B}+ {
5439 warn(yyextra->fileName,yyextra->yyLineNr,
5440 "Ignoring {:c}brief command inside argument documentation",*yytext
5441 );
5442 yyextra->fullArgString+=' ';
5443 }
5444<ReadTempArgs>"<" {
5445 *yyextra->copyArgString+=*yytext;
5446 yyextra->fullArgString+=*yytext;
5447 yyextra->argSharpCount=1;
5448 BEGIN( CopyArgSharp );
5449 }
5450<ReadTempArgs>">" {
5451 *yyextra->copyArgString+=*yytext;
5452 yyextra->fullArgString+=*yytext;
5453 //printf("end template list '%s'\n",qPrint(*yyextra->copyArgString));
5454 *yyextra->currentArgumentList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5455 handleParametersCommentBlocks(yyscanner,yyextra->current->tArgLists.back());
5456 BEGIN( yyextra->currentArgumentContext );
5457 }
5458<CopyArgRound>"(" {
5459 yyextra->argRoundCount++;
5460 *yyextra->copyArgString+=*yytext;
5461 yyextra->fullArgString+=*yytext;
5462 }
5463<CopyArgRound>")" {
5464 *yyextra->copyArgString+=*yytext;
5465 yyextra->fullArgString+=*yytext;
5466 if (yyextra->argRoundCount>0)
5467 yyextra->argRoundCount--;
5468 else
5469 BEGIN( yyextra->lastCopyArgContext );
5470 }
5471<CopyArgSquare>"[" {
5472 yyextra->argSquareCount++;
5473 *yyextra->copyArgString+=*yytext;
5474 yyextra->fullArgString+=*yytext;
5475 }
5476<CopyArgSquare>"]" {
5477 *yyextra->copyArgString+=*yytext;
5478 yyextra->fullArgString+=*yytext;
5479 if (yyextra->argSquareCount>0)
5480 yyextra->argSquareCount--;
5481 else
5482 BEGIN( yyextra->lastCopyArgContext );
5483 }
5484<CopyArgSharp>"(" {
5485 *yyextra->copyArgString+=*yytext;
5486 yyextra->fullArgString+=*yytext;
5487 yyextra->argRoundCount=0;
5488 yyextra->lastCopyArgContext = YY_START;
5489 BEGIN( CopyArgRound );
5490 }
5491<CopyArgSharp>"<" {
5492 yyextra->argSharpCount++;
5493 //printf("yyextra->argSharpCount++=%d copy\n",yyextra->argSharpCount);
5494 *yyextra->copyArgString+=*yytext;
5495 yyextra->fullArgString+=*yytext;
5496 }
5497<CopyArgSharp>">" {
5498 *yyextra->copyArgString+=*yytext;
5499 yyextra->fullArgString+=*yytext;
5500 yyextra->argSharpCount--;
5501 if (yyextra->argSharpCount>0)
5502 {
5503 //printf("yyextra->argSharpCount--=%d copy\n",yyextra->argSharpCount);
5504 }
5505 else
5506 {
5507 BEGIN( ReadTempArgs );
5508 //printf("end of yyextra->argSharpCount\n");
5509 }
5510 }
5511<CopyArgString,CopyArgPHPString>\\. {
5512 *yyextra->copyArgString+=yytext;
5513 yyextra->fullArgString+=yytext;
5514 }
5515<CopyArgString>\" {
5516 *yyextra->copyArgString+=*yytext;
5517 yyextra->fullArgString+=*yytext;
5518 BEGIN( yyextra->lastCopyArgStringContext );
5519 }
5520<CopyArgPHPString>\' {
5521 *yyextra->copyArgString+=*yytext;
5522 yyextra->fullArgString+=*yytext;
5523 BEGIN( yyextra->lastCopyArgStringContext );
5524 }
5525<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>{CHARLIT} {
5526 if (yyextra->insidePHP)
5527 {
5528 REJECT;
5529 }
5530 else
5531 {
5532 *yyextra->copyArgString+=yytext;
5533 yyextra->fullArgString+=yytext;
5534 }
5535 }
5536<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>\' {
5537 *yyextra->copyArgString+=yytext;
5538 yyextra->fullArgString+=yytext;
5539 if (yyextra->insidePHP)
5540 {
5541 yyextra->lastCopyArgStringContext=YY_START;
5542 BEGIN(CopyArgPHPString);
5543 }
5544 }
5545<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>"<="|">="|"<=>" {
5546 *yyextra->copyArgString+=yytext;
5547 yyextra->fullArgString+=yytext;
5548 }
5549<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>\n {
5550 lineCount(yyscanner);
5551 *yyextra->copyArgString+=*yytext;
5552 yyextra->fullArgString+=*yytext;
5553 }
5554<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>{ID} {
5555 *yyextra->copyArgString+=yytext;
5556 yyextra->fullArgString+=yytext;
5557 }
5558<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>. {
5559 *yyextra->copyArgString+=*yytext;
5560 yyextra->fullArgString+=*yytext;
5561 }
5562
5563
5564
5565 /*------------------------------------------------------------------------*/
5566
5567
5568<FuncRound>"(" { yyextra->current->args += *yytext ;
5569 ++yyextra->roundCount ;
5570 }
5571<FuncRound>")" { yyextra->current->args += *yytext ;
5572 if ( yyextra->roundCount )
5573 --yyextra->roundCount ;
5574 else
5575 BEGIN( FuncQual ) ;
5576 }
5577 /*
5578<FuncQual>"#" { if (yyextra->insidePHP)
5579 REJECT;
5580 yyextra->lastCPPContext = YY_START;
5581 BEGIN(SkipCPP);
5582 }
5583 */
5584<FuncQual>[{:;,] {
5585 if ( dstrcmp(yytext,";")==0 &&
5586 ((yyextra->insideJS || yyextra->insidePHP) &&
5587 !containsWord(yyextra->current->type,"function")) )
5588 {
5589 yyextra->current->reset();
5590 initEntry(yyscanner);
5591 BEGIN( FindMembers );
5592 }
5593 else
5594 {
5595 unput(*yytext); BEGIN( SFunction );
5596 }
5597 }
bool containsWord(const DString &str, const char *word)
returns true iff string s contains word w
Definition util.cpp:5012
5598<FuncQual>{BN}*"abstract"{BN}* { // pure virtual member function
5599 lineCount(yyscanner) ;
5600 yyextra->current->virt = Specifier::Pure;
5601 yyextra->current->args += " override ";
5602 }
5603<FuncQual,TrailingReturn>{BN}*"override"{BN}* { // C++11 overridden virtual member function
5604 lineCount(yyscanner) ;
5605 yyextra->current->spec.setOverride(true);
5606 yyextra->current->args += " override ";
5607 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5608 BEGIN(FuncQual);
5609 }
5610<FuncQual,TrailingReturn>{BN}*"final"{BN}* { // C++11 final method
5611 lineCount(yyscanner) ;
5612 yyextra->current->spec.setFinal(true);
5613 yyextra->current->args += " final ";
5614 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5615 BEGIN(FuncQual);
5616 }
5617<FuncQual>{BN}*"sealed"{BN}* { // sealed member function
5618 lineCount(yyscanner) ;
5619 yyextra->current->spec.setSealed(true);
5620 yyextra->current->args += " sealed ";
5621 }
5622<FuncQual>{BN}*"new"{BN}* { // new member function
5623 lineCount(yyscanner) ;
5624 yyextra->current->spec.setNew(true);
5625 yyextra->current->args += " new ";
5626 }
5627<FuncQual>{BN}*"const"{BN}* { // const member function
5628 lineCount(yyscanner) ;
5629 yyextra->current->args += " const ";
5630 yyextra->current->argList.setConstSpecifier(true);
5631 }
5632<FuncQual>{BN}*"volatile"{BN}* { // volatile member function
5633 lineCount(yyscanner) ;
5634 yyextra->current->args += " volatile ";
5635 yyextra->current->argList.setVolatileSpecifier(true);
5636 }
5637<FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier
5638 lineCount(yyscanner) ;
5639 yyextra->current->args += " noexcept ";
5640 yyextra->current->spec.setNoExcept(true);
5641 }
5642<FuncQual>{BN}*"noexcept"{BN}*"("{B}*false{B}*")"{BN}* { // noexcept(false) expression
5643 lineCount(yyscanner) ;
5644 yyextra->current->args += " noexcept(false)";
5645 }
5646<FuncQual>{BN}*"noexcept"{BN}*"(" { // noexcept expression
5647 lineCount(yyscanner) ;
5648 yyextra->current->args += " noexcept(";
5649 yyextra->current->spec.setNoExcept(true);
5650 yyextra->lastRoundContext=FuncQual;
5651 yyextra->pCopyRoundString=&yyextra->current->args;
5652 yyextra->roundCount=0;
5653 BEGIN(CopyRound);
5654 }
5655<FuncQual>{BN}*"&" {
5656 yyextra->current->args += " &";
5657 yyextra->current->argList.setRefQualifier(RefQualifierType::LValue);
5658 }
5659<FuncQual>{BN}*"&&" {
5660 yyextra->current->args += " &&";
5661 yyextra->current->argList.setRefQualifier(RefQualifierType::RValue);
5662 }
5663
5664<FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function
5665 lineCount(yyscanner) ;
5666 yyextra->current->args += " = 0";
5667 yyextra->current->virt = Specifier::Pure;
5668 yyextra->current->argList.setPureSpecifier(true);
5669 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5670 BEGIN(FuncQual);
5671 }
5672<FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member
5673 lineCount(yyscanner);
5674 yyextra->current->args += " = delete";
5675 yyextra->current->spec.setDelete(true);
5676 yyextra->current->argList.setIsDeleted(true);
5677 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5678 BEGIN(FuncQual);
5679 }
5680<FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator
5681 lineCount(yyscanner);
5682 yyextra->current->args += " = default";
5683 yyextra->current->spec.setDefault(true);
5684 if (YY_START==TrailingReturn) yyextra->current->argList.finishTrailingReturnType();
5685 BEGIN(FuncQual);
5686 }
5687<FuncQual>{BN}*"->"{BN}* {
5688 lineCount(yyscanner);
5689 yyextra->current->argList.setTrailingReturnType(" -> ");
5690 yyextra->current->args += " -> ";
5691 yyextra->roundCount=0;
5692 BEGIN(TrailingReturn);
5693 }
5694<TrailingReturn>[{;] {
5695 if (yyextra->roundCount>0) REJECT;
5696 unput(*yytext);
5697 yyextra->current->argList.finishTrailingReturnType();
5698 BEGIN(FuncQual);
5699 }
5700<TrailingReturn>"requires"{BN}+ {
5701 if (yyextra->insideJava) REJECT;
5702 yyextra->requiresContext = FuncQual;
5703 yyextra->current->req+=' ';
5704 yyextra->current->argList.finishTrailingReturnType();
5705 BEGIN(RequiresClause);
5706 }
5707<TrailingReturn>"(" {
5708 yyextra->roundCount++;
5709 yyextra->current->argList.appendTrailingReturnType(yytext);
5710 yyextra->current->args+=yytext;
5711 }
5712<TrailingReturn>")" {
5713 if (yyextra->roundCount>0)
5714 {
5715 yyextra->roundCount--;
5716 }
5717 else
5718 {
5719 warn(yyextra->fileName,yyextra->yyLineNr,
5720 "Found ')' without opening '(' for trailing return type '{})...'",
5721 yyextra->current->argList.trailingReturnType());
5722 }
5723 yyextra->current->argList.appendTrailingReturnType(yytext);
5724 yyextra->current->args+=yytext;
5725 }
5726<TrailingReturn>. {
5727 yyextra->current->argList.appendTrailingReturnType(yytext);
5728 yyextra->current->args+=yytext;
5729 }
5730<TrailingReturn>\n {
5731 lineCount(yyscanner);
5732 yyextra->current->argList.appendTrailingReturnType(yytext);
5733 yyextra->current->args+=' ';
5734 }
5735<FuncRound,FuncFunc>{BN}*","{BN}* {
5736 lineCount(yyscanner) ;
5737 yyextra->current->args += ", " ;
5738 }
5739<FuncQual,FuncRound,FuncFunc>{BN}+ {
5740 lineCount(yyscanner) ;
5741 yyextra->current->args += ' ' ;
5742 }
5743<SFunction,FuncQual,FuncRound,FuncFunc>"#" { if (yyextra->insidePHP)
5744 REJECT;
5745 yyextra->lastCPPContext = YY_START;
5746 BEGIN(SkipCPP);
5747 }
5748<FuncQual>"=>" {
5749 if (!yyextra->insideCS)
5750 REJECT;
5751 // Expression body function
5752 unput('=');
5753 BEGIN(SFunction);
5754 }
5755<FuncQual>"=" {
5756 if (yyextra->insideCli && yyextra->current_root->section.isCompound())
5757 {
5758 BEGIN(CliOverride);
5759 }
5760 else
5761 {
5762 // typically an initialized function pointer
5763 yyextra->lastInitializerContext=YY_START;
5764 yyextra->sharpCount=0;
5765 yyextra->initBracketCount=0;
5766 yyextra->current->initializer.str(yytext);
5767 BEGIN(ReadInitializer);
5768 }
5769 }
5770<ReadExpressionBody>";" {
5771 if (!yyextra->current->sli.empty() && yyextra->previous) // copy special list items
5772 {
5773 yyextra->previous->sli = yyextra->current->sli;
5774 yyextra->current->sli.clear();
5775 }
5776 if (yyextra->previous) yyextra->previous->endBodyLine=yyextra->yyLineNr;
5777 BEGIN(FindMembers);
5778 }
5779<CliOverride>{ID} {
5780 }
5781<CliOverride>"{" {
5782 unput(*yytext);
5783 BEGIN(FuncQual);
5784 }
5785<CliOverride>\n {
5786 lineCount(yyscanner);
5787 }
5788<CliOverride>. {
5789 }
5790<FuncQual>{ID} {
5791 if (yyextra->insideCpp && dstrcmp(yytext,"requires")==0)
5792 {
5793 // c++20 trailing requires clause
5794 yyextra->requiresContext = YY_START;
5795 if (!yyextra->current->req.empty())
5796 {
5797 yyextra->current->req+=" && ";
5798 }
5799 BEGIN(RequiresClause);
5800 }
5801 else if (yyextra->insideCS && dstrcmp(yytext,"where")==0)
5802 {
5803 // type constraint for a method
5804 yyextra->current->typeConstr.clear();
5805 yyextra->current->typeConstr.push_back(Argument());
5806 yyextra->lastCSConstraint = YY_START;
5807 BEGIN( CSConstraintName );
5808 }
5809 else if (checkForKnRstyleC(yyscanner)) // K&R style C function
5810 {
5811 yyextra->current->args = yytext;
5812 yyextra->oldStyleArgType.clear();
5813 BEGIN(OldStyleArgs);
5814 }
5815 else
5816 {
5817 yyextra->current->args += yytext;
5818 }
5819 }
5820<OldStyleArgs>[,;] {
5821 DString oldStyleArgPtr;
5822 DString oldStyleArgName;
5823 splitKnRArg(yyscanner,oldStyleArgPtr,oldStyleArgName);
5824 DString doc,brief;
5825 if (yyextra->current->doc!=yyextra->docBackup)
5826 {
5827 doc=yyextra->current->doc;
5828 yyextra->current->doc=yyextra->docBackup;
5829 }
5830 if (yyextra->current->brief!=yyextra->briefBackup)
5831 {
5832 brief=yyextra->current->brief;
5833 yyextra->current->brief=yyextra->briefBackup;
5834 }
5835 addKnRArgInfo(yyscanner,yyextra->oldStyleArgType+oldStyleArgPtr,
5836 oldStyleArgName,brief,doc);
5837 yyextra->current->args.clear();
5838 if (*yytext==';') yyextra->oldStyleArgType.clear();
5839 }
5840<OldStyleArgs>{ID} { yyextra->current->args += yytext; }
5841<OldStyleArgs>"{" {
5842 if (yyextra->current->argList.empty())
5843 {
5844 yyextra->current->argList.setNoParameters(true);
5845 }
5846 yyextra->current->args = argListToString(yyextra->current->argList);
5847 unput('{');
5848 BEGIN(FuncQual);
5849 }
5850<OldStyleArgs>. { yyextra->current->args += *yytext; }
5851<FuncQual,FuncRound,FuncFunc>\" {
5852 if (yyextra->insideIDL && yyextra->insideCppQuote)
5853 {
5854 BEGIN(EndCppQuote);
5855 }
5856 else
5857 {
5858 yyextra->current->args += *yytext;
5859 }
5860 }
5861<FuncQual,FuncRound,FuncFunc>. { yyextra->current->args += *yytext; }
5862<FuncQual>{BN}*"try:" |
5863<FuncQual>{BN}*"try"{BN}+ { /* try-function-block */
5864 yyextra->insideTryBlock=true;
5865 lineCount(yyscanner);
5866 if (yytext[yyleng-1]==':')
5867 {
5868 unput(':');
5869 BEGIN( SFunction );
5870 }
5871 }
5872<FuncQual>{BN}*"throw"{BN}*"(" { // C++ style throw clause
5873 yyextra->current->exception = " throw (" ;
5874 yyextra->roundCount=0;
5875 lineCount(yyscanner) ;
5876 BEGIN( ExcpRound ) ;
5877 }
5878<FuncQual>{BN}*"raises"{BN}*"(" {
5879 yyextra->current->exception = " raises (" ;
5880 lineCount(yyscanner) ;
5881 yyextra->roundCount=0;
5882 BEGIN( ExcpRound ) ;
5883 }
5884<FuncQual>{BN}*"throws"{BN}+ { // Java style throw clause
5885 yyextra->current->exception = " throws " ;
5886 lineCount(yyscanner) ;
5887 BEGIN( ExcpList );
5888 }
5889<ExcpRound>"(" { yyextra->current->exception += *yytext ;
5890 ++yyextra->roundCount ;
5891 }
5892<ExcpRound>")" { yyextra->current->exception += *yytext ;
5893 if ( yyextra->roundCount )
5894 --yyextra->roundCount ;
5895 else
5896 BEGIN( FuncQual ) ;
5897 }
5898<ExcpRound>. {
5899 yyextra->current->exception += *yytext;
5900 }
5901<ExcpList>"{" {
5902 unput('{'); BEGIN( FuncQual );
5903 }
5904<ExcpList>";" {
5905 unput(';'); BEGIN( FuncQual );
5906 }
5907<ExcpList>"\n" {
5908 yyextra->current->exception += ' ';
5909 lineCount(yyscanner);
5910 }
5911<ExcpList>. {
5912 yyextra->current->exception += *yytext;
5913 }
5914<SFunction>"(" { yyextra->current->type += yyextra->current->name ;
5915 yyextra->current->name = yyextra->current->args ;
5916 yyextra->current->args = yytext ;
5917 yyextra->roundCount=0;
5918 BEGIN( FuncRound ) ;
5919 }
5920<SFunction>":" {
5921 if (!yyextra->insidePHP) BEGIN(SkipInits);
5922 }
5923<SFunction>[=;{,] {
5924 yyextra->current->name=removeRedundantWhiteSpace(yyextra->current->name);
5925 yyextra->current->type=removeRedundantWhiteSpace(yyextra->current->type);
5926 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
5927 yyextra->current->fileName = yyextra->fileName;
5928 yyextra->current->startLine = yyextra->yyBegLineNr;
5929 yyextra->current->startColumn = yyextra->yyBegColNr;
5930 static const reg::Ex re(R"(\‍([^)]*[*&][^)]*\))"); // e.g. (...*...)
5932 std::string type = yyextra->current->type.str();
5933 size_t ti=DString::npos;
5934 if (reg::search(type,match,re))
5935 {
5936 ti = match.position();
5937 }
5938 if (ti!=DString::npos)
5939 {
5940 if (size_t di = yyextra->current->type.find("decltype(");
5941 di!=DString::npos && di<ti) // decltype(...(...*...) -> normal return type
5942 {
5943 ti = DString::npos;
5944 }
5945 }
5946 size_t ts=yyextra->current->type.find('<');
5947 size_t te=yyextra->current->type.rfind('>');
5948
5949 // bug677315: A<int(void *, char *)> get(); is not a function pointer
5950 bool startsWithTypedef = yyextra->current->type.startsWith("typedef ");
5951 bool isFunction = ti==DString::npos || // not a (...*...) pattern
5952 (ts!=DString::npos && te!=DString::npos && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list
5953 bool isVariable = !yyextra->current->type.empty() &&
5954 (!isFunction || startsWithTypedef);
5955
5956 //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n",
5957 // qPrint(yyextra->current->type),ts,te,ti,isFunction);
5958
5959 if (*yytext!=';' || yyextra->current_root->section.isCompound())
5960 {
5961 if (isVariable)
5962 {
5963 //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5964 if (yyextra->isTypedef && !startsWithTypedef)
5965 {
5966 yyextra->current->type.prepend("typedef ");
5967 }
5968 yyextra->current->section = EntryType::makeVariable() ;
5969 }
5970 else
5971 {
5972 //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5973 yyextra->current->section = EntryType::makeFunction() ;
5974 yyextra->current->proto = *yytext==';';
5975 }
5976 }
5977 else // a global function prototype or function variable
5978 {
5979 //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5980 if (isVariable)
5981 {
5982 if (yyextra->isTypedef && !startsWithTypedef)
5983 {
5984 yyextra->current->type.prepend("typedef ");
5985 }
5986 //printf("Scanner.l: found function variable!\n");
5987 yyextra->current->section = EntryType::makeVariable();
5988 }
5989 else
5990 {
5991 //printf("Scanner.l: found prototype\n");
5992 yyextra->current->section = EntryType::makeFunction();
5993 yyextra->current->proto = true;
5994 }
5995 }
5996 //printf("Adding entry '%s'\n",qPrint(yyextra->current->name));
5997 if ( yyextra->insidePHP)
5998 {
5999 if (findAndRemoveWord(yyextra->current->type,"final"))
6000 {
6001 yyextra->current->spec.setFinal(true);
6002 }
6003 if (findAndRemoveWord(yyextra->current->type,"abstract"))
6004 {
6005 yyextra->current->spec.setAbstract(true);
6006 }
6007 }
6008 if ( yyextra->insidePHP && !containsWord(yyextra->current->type,"function"))
6009 {
6010 initEntry(yyscanner);
6011 if ( *yytext == '{' )
6012 {
6013 yyextra->lastCurlyContext = FindMembers;
6014 yyextra->curlyCount=0;
6015 BEGIN( SkipCurly );
6016 }
6017 else
6018 {
6019 BEGIN( FindMembers );
6020 }
6021 }
6022 else
6023 {
6024 if ( yyextra->insidePHP)
6025 {
6026 findAndRemoveWord(yyextra->current->type,"function");
6027 }
6028 yyextra->previous = yyextra->current;
6029 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6030 initEntry(yyscanner);
6031 // Objective C 2.0: Required/Optional section
6032 if (yyextra->previous->spec.isOptional() || yyextra->previous->spec.isRequired())
6033 {
6034 yyextra->current->spec.setOptional(true).setRequired(true);
6035 }
6036 yyextra->lastCurlyContext = FindMembers;
6037 if ( *yytext == ',' )
6038 {
6039 yyextra->current->type = stripFuncPtr(yyextra->previous->type);
6040 }
6041 if ( *yytext == '{' )
6042 {
6043 if ( !yyextra->insidePHP && yyextra->current_root->section.isCompound() )
6044 {
6045 yyextra->previous->spec.setInline(true);
6046 }
6047 yyextra->curlyCount=0;
6048 BEGIN( SkipCurly ) ;
6049 }
6050 else if ( *yytext == '=' ) // C# Expression Body
6051 {
6052 yyextra->previous->spec.setInline(true);
6053 yyextra->curlyCount=0;
6054 BEGIN( ReadExpressionBody );
6055 }
6056 else
6057 {
6058 if (!yyextra->previous->section.isVariable())
6059 yyextra->previous->bodyLine=-1; // a function/member declaration
6060 BEGIN( FindMembers ) ;
6061 }
6062 }
6063 }
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:5028
6064<SkipInits>">"{BN}*"{" { // C++11 style initializer (see bug 790788)
6065 lineCount(yyscanner);
6066 yyextra->curlyCount=1;
6067 BEGIN(SkipC11Inits);
6068 }
6069<SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647)
6070 lineCount(yyscanner);
6071 yyextra->curlyCount=1;
6072 BEGIN(SkipC11Inits);
6073 }
6074<SkipC11Inits>"{" {
6075 ++yyextra->curlyCount;
6076 }
6077<SkipC11Inits>"}" {
6078 if ( --yyextra->curlyCount<=0 )
6079 {
6080 BEGIN(SkipInits);
6081 }
6082 }
6083<SkipInits>"{" { // C++11 style initializer
6084 unput('{');
6085 BEGIN( SFunction );
6086 }
6087<SkipCurly>"{" {
6088 //addToBody(yytext);
6089 ++yyextra->curlyCount ;
6090 }
6091<SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */)
6092<SkipCurly>"}" {
6093 //addToBody(yytext);
6094 if( yyextra->curlyCount )
6095 {
6096 --yyextra->curlyCount ;
6097 }
6098 else
6099 {
6100 if (!yyextra->current->sli.empty() && yyextra->previous) // copy special list items
6101 {
6102 yyextra->previous->sli = yyextra->current->sli;
6103 yyextra->current->sli.clear();
6104 }
6105 if (yyextra->previous) yyextra->previous->endBodyLine=yyextra->yyLineNr;
6106 BEGIN( yyextra->lastCurlyContext ) ;
6107 }
6108 }
6109<SkipCurly>"}"{BN}*{DCOMM}"<" {
6110 lineCount(yyscanner);
6111 if ( yyextra->curlyCount )
6112 {
6113 //addToBody(yytext);
6114 --yyextra->curlyCount ;
6115 }
6116 else
6117 {
6118 yyextra->current->endBodyLine=yyextra->yyLineNr;
6119 yyextra->tempEntry = yyextra->current; // temporarily switch to the previous entry
6120 yyextra->current = yyextra->previous;
6121
6122 yyextra->docBlockContext = SkipCurlyEndDoc;
6123 yyextra->docBlockInBody = false;
6124 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
6125 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
6126 yyextra->docBlock.str(std::string());
6127 yyextra->docBlockTerm = '}';
6128 if (yytext[yyleng-3]=='/')
6129 {
6130 startCommentBlock(yyscanner,true);
6131 BEGIN( DocLine );
6132 }
6133 else
6134 {
6135 startCommentBlock(yyscanner,false);
6136 BEGIN( DocBlock );
6137 }
6138 }
6139 }
6140<SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
6141 yyextra->docBlockContext = SkipCurlyEndDoc;
6142 yyextra->docBlockInBody = false;
6143 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
6144 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
6145 yyextra->docBlock.str(std::string());
6146 yyextra->docBlockTerm = '}';
6147 if (yytext[yyleng-3]=='/')
6148 {
6149 startCommentBlock(yyscanner,true);
6150 BEGIN( DocLine );
6151 }
6152 else
6153 {
6154 startCommentBlock(yyscanner,false);
6155 BEGIN( DocBlock );
6156 }
6157 }
6158<SkipCurlyEndDoc>"}" {
6159 //addToBody("}");
6160 if (yyextra->tempEntry) // we can only switch back to yyextra->current if no new item was created
6161 {
6162 yyextra->current = yyextra->tempEntry;
6163 yyextra->tempEntry.reset();
6164 }
6165 BEGIN( yyextra->lastCurlyContext );
6166 }
6167<SkipCurly,ReadExpressionBody>\" {
6168 //addToBody(yytext);
6169 yyextra->lastStringContext=YY_START;
6170 BEGIN( SkipString );
6171 }
6172<SkipCurly>^{B}*"#" {
6173 if (yyextra->insidePHP)
6174 REJECT;
6175 //addToBody(yytext);
6176 BEGIN( SkipCurlyCpp );
6177 }
6178<SkipCurly,SkipC11Inits,SkipInits,ReadExpressionBody>\n {
6179 lineCount(yyscanner);
6180 //addToBody(yytext);
6181 }
6182<SkipCurly,SkipCurlyCpp,ReadInitializer,ReadInitializerPtr>"<<<" {
6183 if (!yyextra->insidePHP)
6184 {
6185 REJECT;
6186 }
6187 else
6188 {
6189 yyextra->lastHereDocContext = YY_START;
6190 BEGIN(HereDoc);
6191 }
6192 }
6193<SkipCurly,SkipCurlyCpp>{B}*{RAWBEGIN} {
6194 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
6195 yyextra->lastRawStringContext = YY_START;
6196 yyextra->dummyRawString.clear();
6197 yyextra->pCopyRawString = &yyextra->dummyRawString;
6198 *yyextra->pCopyRawString += yytext;
6199 BEGIN(RawString);
6200 }
6201<SkipCurly,SkipCurlyCpp>[^\n#"R'@\\/{}<\$]+ {
6202 lineCount(yyscanner); // for yyextra->column updates
6203 //addToBody(yytext);
6204 }
6205<SkipCurly,SkipCurlyCpp>"\$" {}
6206<SkipCurlyCpp>\n {
6207 //addToBody(yytext);
6208 lineCount(yyscanner);
6209 yyextra->lastCurlyContext = FindMembers;
6210 BEGIN( SkipCurly );
6211 }
6212<SkipCurlyCpp>\\‍[\r]*"\n"[\r]* {
6213 //addToBody(yytext);
6214 lineCount(yyscanner);
6215 }
6216<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,CopyC11Attribute,ReadExpressionBody>{CCS} {
6217 //addToBody(yytext);
6218 yyextra->lastCContext = YY_START;
6219 BEGIN(SkipComment);
6220 }
6221<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,CopyC11Attribute,ReadExpressionBody>{CPPC} {
6222 //addToBody(yytext);
6223 yyextra->lastCContext = YY_START;
6224 BEGIN(SkipCxxComment);
6225 }
6226<SkipInits,SkipC11Inits>"(" {
6227 yyextra->roundCount=0;
6228 yyextra->lastSkipRoundContext=YY_START;
6229 BEGIN(SkipRound);
6230 }
6231<SkipInits,SkipC11Inits>\" {
6232 yyextra->lastStringContext=YY_START;
6233 BEGIN( SkipString );
6234 }
6235<SkipInits>; {
6236 warn(yyextra->fileName,yyextra->yyLineNr,
6237 "Found ';' while parsing initializer list! "
6238 "(doxygen could be confused by a macro call without semicolon)"
6239 );
6240 BEGIN( FindMembers );
6241 }
6242<SkipInits,SkipCurly,SkipCurlyCpp>"#" {
6243 if (!yyextra->insidePHP)
6244 REJECT;
6245 //addToBody(yytext);
6246 yyextra->lastCContext = YY_START;
6247 BEGIN(SkipCxxComment);
6248 }
6249<SkipInits,SkipCurly,SkipCurlyCpp,ReadExpressionBody>@\" {
6250 if (!yyextra->insideCS) REJECT;
6251 // C# verbatim string
6252 // we want to discard the string, due to reuse of states we need a dummy stream
6253 yyextra->lastSkipVerbStringContext=YY_START;
6254 yyextra->pSkipVerbString=&yyextra->dummyTextStream;
6255 yyextra->dummyTextStream.clear(); // remove old data so it won't grow too much
6256 BEGIN(SkipVerbString);
6257 }
6258<SkipInits,SkipCurly,SkipCurlyCpp,ReadExpressionBody>{CHARLIT} {
6259 if (yyextra->insidePHP) REJECT;
6260 }
6261<SkipInits,SkipCurly,SkipCurlyCpp>\' {
6262 if (yyextra->insidePHP)
6263 {
6264 yyextra->lastStringContext=YY_START;
6265 BEGIN(SkipPHPString);
6266 }
6267 }
6268<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,ReadExpressionBody>. { }
6269<SkipString,SkipPHPString>\\. { }
6270<SkipString>\" {
6271 BEGIN( yyextra->lastStringContext );
6272 }
6273<SkipPHPString>\' {
6274 BEGIN( yyextra->lastStringContext );
6275 }
6276<SkipString,SkipPHPString>{CCS}|{CCE}|{CPPC} { }
6277<SkipString,SkipPHPString>\n {
6278 lineCount(yyscanner);
6279 }
6280<SkipString>"[[" { }
6281<SkipString,SkipPHPString>. { }
6282<CompoundName>":" { // for "class : public base {} var;" construct, see bug 608359
6283 unput(':');
6284 BEGIN(ClassVar);
6285 }
6286<CompoundName>";" {
6287 yyextra->current->section = EntryType::makeEmpty() ;
6288 yyextra->current->type.clear() ;
6289 yyextra->current->name.clear() ;
6290 yyextra->current->args.clear() ;
6291 yyextra->current->argList.clear();
6292 BEGIN( FindMembers ) ;
6293 }
6294<Bases>";" {
6295 if (yyextra->insideIDL && (yyextra->current->spec.isSingleton() || yyextra->current->spec.isService()))
6296 {
6297 // in UNO IDL a service or singleton may be defined
6298 // completely like this: "service Foo : XFoo;"
6299 if (!yyextra->current->name.empty() && !yyextra->current_root->name.empty())
6300 {
6301 prependScope(yyscanner);
6302 }
6303 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6304 // there can be only one base class here
6305 if (!yyextra->baseName.empty())
6306 {
6307 yyextra->current->extends.emplace_back(
6308 yyextra->baseName,Protection::Public,Specifier::Normal);
6309 yyextra->baseName.clear();
6310 }
6311 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
6312 initEntry(yyscanner);
6313 }
6314 else
6315 {
6316 yyextra->current->section = EntryType::makeEmpty() ;
6317 yyextra->current->type.clear() ;
6318 yyextra->current->name.clear() ;
6319 yyextra->current->args.clear() ;
6320 yyextra->current->argList.clear();
6321 }
6322 BEGIN( FindMembers ) ;
6323 }
6324<CompoundName>{SCOPENAME}/{BN}*"<" {
6325 yyextra->sharpCount = 0;
6326 yyextra->current->name = yytext ;
6327 storeClangId(yyscanner,yytext);
6328 if (yyextra->current->spec.isProtocol())
6329 {
6330 yyextra->current->name+="-p";
6331 }
6332 lineCount(yyscanner);
6333 yyextra->lastClassTemplSpecContext = ClassVar;
6334 if (yyextra->insideObjC) // protocol list
6335 {
6336 BEGIN( ObjCProtocolList );
6337 }
6338 else if (yyextra->insideCS) // C# generic class
6339 {
6340 //yyextra->current->name+="-g";
6341 BEGIN( CSGeneric );
6342 }
6343 else // C++ template specialization
6344 {
6345 yyextra->roundCount=0;
6346 BEGIN( ClassTemplSpec );
6347 }
6348 }
6349<CSGeneric>"<" {
6350 ArgumentList al;
6351 // check bug 612858 before enabling the next line
6352 //yyextra->current->spec |= Entry::Template;
6353 yyextra->current->tArgLists.push_back(al);
6354 yyextra->currentArgumentList = &yyextra->current->tArgLists.back();
6355 yyextra->templateStr="<";
6356 yyextra->current->name += "<";
6357 yyextra->fullArgString = yyextra->templateStr;
6358 yyextra->copyArgString = &yyextra->current->name;
6359 //yyextra->copyArgString = &yyextra->templateStr;
6360 yyextra->currentArgumentContext = ClassVar;
6361 BEGIN( ReadTempArgs );
6362 }
6363<ObjCProtocolList>"<" {
6364 yyextra->insideProtocolList=true;
6365 BEGIN( Bases );
6366 }
6367<ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
6368 yyextra->current->name += yytext;
6369 lineCount(yyscanner);
6370 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
6371 {
6372 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6373 if (yyextra->current->spec.isProtocol())
6374 { // Objective-C protocol
6375 unput('{'); // fake start of body
6376 BEGIN( ClassVar );
6377 }
6378 else
6379 {
6380 BEGIN( yyextra->lastClassTemplSpecContext );
6381 }
6382 }
6383 }
6384<ClassTemplSpec>"<" {
6385 yyextra->current->name += yytext;
6386 if (yyextra->roundCount==0) yyextra->sharpCount++;
6387 }
6388<ClassTemplSpec>. {
6389 yyextra->current->name += yytext;
6390 }
6391<CompoundName>({SCOPENAME}|{CSSCOPENAME}){BN}*";" { // forward declaration?
6392 if (yyextra->insideCS && yyextra->current->type == "namespace")
6393 {
6394 // file scoped CSharp namespace
6395 lineCount(yyscanner);
6396 yyextra->current->name = substitute(yytext,".","::");
6397 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6398 yyextra->fakeNS++;
6399 unput('{'); // fake start of body
6400 BEGIN( ClassVar );
6401 }
6402 else if (!yyextra->current->tArgLists.empty())
6403 {
6404 // found a forward template declaration, this has
6405 // a purpose of its own
6406 yyextra->current->name = yytext;
6407 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6408 storeClangId(yyscanner,yyextra->current->name.data());
6409 //printf("template class declaration for %s!\n",qPrint(yyextra->current->name));
6410 DString rn = yyextra->current_root->name;
6411 //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
6412 if (!yyextra->current->name.empty() && !rn.empty())
6413 {
6414 prependScope(yyscanner);
6415 }
6416 yyextra->current->spec.setForwardDecl(true);
6417 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6418 }
6419 else if (yyextra->insideIDL &&
6420 (((yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isService()) &&
6421 yyextra->current->spec.isInterface()) ||
6422 ((yyextra->current_root->spec.isService() || yyextra->current_root->spec.isSingleton()) &&
6423 yyextra->current->spec.isService())
6424 )
6425 )
6426 {
6427 // interface yyextra->inside of UNO IDL service or interface
6428 // service yyextra->inside of UNO IDL service or singleton
6429 // there may be documentation on the member,
6430 // so do not throw it away...
6431 yyextra->current->name = yytext;
6432 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6433 yyextra->current->section = yyextra->current->spec.isInterface() ? EntryType::makeExportedInterface()
6434 : EntryType::makeIncludedService();
6435// yyextra->current->section = EntryType::makeMemberDoc();
6436 yyextra->current->spec.setInterface(false).setService(false);
6437 // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from
6438 // different enums in this case...
6439 // granted only Optional and Interface are actually valid in this context but urgh...
6440 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6441 }
6442
6443 if (!(yyextra->insideCS && yyextra->current->type == "namespace"))
6444 {
6445 unput(';');
6446 yyextra->current->reset();
6447 initEntry(yyscanner);
6448 if (yyextra->insideObjC) // see bug746361
6449 {
6450 yyextra->language = yyextra->current->lang = SrcLangExt::Cpp;
6451 yyextra->insideObjC = false;
6452 }
6453 if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
6454 {
6455 yyextra->current->type.prepend("typedef");
6456 }
6457 BEGIN( FindMembers );
6458 }
6459 }
Wrapper class for the Entry type.
Definition types.h:856
6460<CompoundName>{SCOPENAME}/{BN}*"(" {
6461 yyextra->current->name = yytext ;
6462 storeClangId(yyscanner,yytext);
6463 lineCount(yyscanner);
6464 if (yyextra->insideCpp && yyextra->current->name=="alignas") // C++11
6465 {
6466 yyextra->lastAlignAsContext = YY_START;
6467 BEGIN( AlignAs );
6468 }
6469 else
6470 {
6471 if (yyextra->current->spec.isProtocol())
6472 {
6473 yyextra->current->name += "-p";
6474 }
6475 BEGIN( ClassVar );
6476 }
6477 }
6478<AlignAs>"(" { yyextra->roundCount=0;
6479 BEGIN( AlignAsEnd );
6480 }
6481<AlignAs>\n { lineCount(yyscanner); }
6482<AlignAs>.
6483<AlignAsEnd>"(" { yyextra->roundCount++; }
6484<AlignAsEnd>")" { if (--yyextra->roundCount<0)
6485 {
6486 BEGIN( yyextra->lastAlignAsContext );
6487 }
6488 }
6489<AlignAsEnd>\n { lineCount(yyscanner); }
6490<AlignAsEnd>.
6491<ConceptName>{ID} {
6492 yyextra->current->name = yytext ;
6493 storeClangId(yyscanner,yytext);
6494 }
6495<ConceptName>"=" {
6496 yyextra->current->bodyLine = yyextra->yyLineNr;
6497 yyextra->current->bodyColumn = yyextra->yyColNr;
6498 yyextra->current->initializer.str(std::string());
6499 yyextra->lastInitializerContext = FindMembers;
6500 yyextra->sharpCount=0;
6501 yyextra->initBracketCount=0;
6502 BEGIN(ReadInitializer);
6503 }
6504<CompoundName>{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line
6505 // e.g. @protocol A,B;
6506 yyextra->current->reset();
6507 initEntry(yyscanner);
6508 }
6509<CompoundName>{SCOPENAME} {
6510 yyextra->current->name = yytext ;
6511 storeClangId(yyscanner,yytext);
6512 lineCount(yyscanner);
6513 if (yyextra->current->spec.isProtocol())
6514 {
6515 yyextra->current->name += "-p";
6516 }
6517 if (yyextra->current->spec.isProtocol() || yyextra->current->section.isObjcImpl())
6518 {
6519 unput('{'); // fake start of body
6520 }
6521 BEGIN( ClassVar );
6522 }
6523<CompoundName>({ID}{BN}*"::"{BN}*)+("inline"{BN}+({ID}{BN}*"::"{BN}*)*)+{ID} { // C++20 style nested inline namespace syntax
6524 if (yyextra->current->section.isNamespace())
6525 {
6526 yyextra->current->name = DString(yytext).simplifyWhiteSpace();
6527 storeClangId(yyscanner,yyextra->current->name.data());
6528 lineCount(yyscanner);
6529 BEGIN( ClassVar );
6530 }
6531 else
6532 {
6533 REJECT;
6534 }
6535 }
6536<CompoundName>{CSSCOPENAME} { // C# style scope
6537 yyextra->current->name = substitute(yytext,".","::");
6538 lineCount(yyscanner);
6539 BEGIN( ClassVar );
6540 }
6541<ClassVar>{SCOPENAME}{BNopt}/"(" {
6542 if (yyextra->insideIDL && literal_at(yytext,"switch") && !isId(yytext[6]))
6543 {
6544 // Corba IDL style union
6545 yyextra->roundCount=0;
6546 BEGIN(SkipUnionSwitch);
6547 }
6548 else
6549 {
6550 addType(yyscanner);
6551 yyextra->yyBegColNr=yyextra->yyColNr;
6552 yyextra->yyBegLineNr=yyextra->yyLineNr;
6553 yyextra->current->name = yytext;
6554 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6555 storeClangId(yyscanner,yyextra->current->name.data());
6556 lineCount(yyscanner);
6557 BEGIN( FindMembers );
6558 }
6559 }
6560<ClassVar>"," {
6561 if (yyextra->isTypedef)
6562 {
6563 // multiple types in one typedef
6564 unput(',');
6565 yyextra->current->type.prepend("typedef ");
6566 BEGIN(FindMembers);
6567 }
6568 else
6569 {
6570 // Multiple class forward declaration
6571 }
6572 }
6573<ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
6574 if (yyextra->insideCli)
6575 {
6576 if (yytext[0]=='s') // sealed
6577 yyextra->current->spec.setSealedClass(true);
6578 else // abstract
6579 yyextra->current->spec.setAbstractClass(true);
6580 BEGIN( ClassVar );
6581 }
6582 else
6583 {
6584 REJECT;
6585 }
6586 }
6587<ClassVar>({ID}{BN}*"::"{BN}*)+{ID} {
6588 yyextra->yyBegColNr=yyextra->yyColNr;
6589 yyextra->yyBegLineNr=yyextra->yyLineNr;
6590 storeClangId(yyscanner,yytext);
6591 lineCount(yyscanner);
6592 if (yyextra->current->section.isEnum())
6593 { // found "enum a N::b" -> variable
6594 yyextra->current->section = EntryType::makeVariable() ;
6595 }
6596 yyextra->current->type += ' ' ;
6597 yyextra->current->type += yyextra->current->name ;
6598 yyextra->current->name = DString(yytext).simplifyWhiteSpace();
6599
6600 if (nameIsOperator(yyextra->current->name))
6601 {
6602 BEGIN( Operator );
6603 }
6604 }
6605<ClassVar>{ID} {
6606 yyextra->yyBegColNr=yyextra->yyColNr;
6607 yyextra->yyBegLineNr=yyextra->yyLineNr;
6608 storeClangId(yyscanner,yytext);
6609 if (yyextra->insideIDL && dstrcmp(yytext,"switch")==0)
6610 {
6611 // Corba IDL style union
6612 yyextra->roundCount=0;
6613 BEGIN(SkipUnionSwitch);
6614 }
6615 else if ((yyextra->insideJava || yyextra->insidePHP || yyextra->insideJS || yyextra->insideSlice) && (dstrcmp(yytext,"implements")==0 || dstrcmp(yytext,"extends")==0))
6616 {
6617 yyextra->current->type.clear();
6618 yyextra->baseProt = Protection::Public;
6619 yyextra->baseVirt = Specifier::Normal;
6620 yyextra->baseName.clear();
6621 BEGIN( BasesProt ) ;
6622 }
6623 else if (yyextra->insideCS && dstrcmp(yytext,"where")==0) // C# type constraint
6624 {
6625 yyextra->current->typeConstr.clear();
6626 yyextra->current->typeConstr.push_back(Argument());
6627 yyextra->lastCSConstraint = YY_START;
6628 BEGIN( CSConstraintName );
6629 }
6630 else if (yyextra->insideCli && dstrcmp(yytext,"abstract")==0)
6631 {
6632 yyextra->current->spec.setAbstract(true);
6633 }
6634 else if (yyextra->insideCli && dstrcmp(yytext,"sealed")==0)
6635 {
6636 yyextra->current->spec.setSealed(true);
6637 }
6638 else if (dstrcmp(yytext,"final")==0)
6639 {
6640 yyextra->current->spec.setFinal(true);
6641 }
6642 else
6643 {
6644 if (yyextra->current->section.isEnum())
6645 { // found "enum a b" -> variable
6646 yyextra->current->section = EntryType::makeVariable() ;
6647 }
6648 yyextra->current->type += ' ' ;
6649 yyextra->current->type += yyextra->current->name ;
6650 yyextra->current->name = yytext ;
6651
6652 if (nameIsOperator(yyextra->current->name))
6653 {
6654 BEGIN( Operator );
6655 }
6656 }
6657 }
6658<ClassVar>[(\‍[] {
6659 if (yyextra->insideObjC && *yytext=='(') // class category
6660 {
6661 yyextra->current->name+='(';
6662 yyextra->current->spec.setCategory(true);
6663 BEGIN( ClassCategory );
6664 }
6665 else if (yyextra->insideCS && *yytext=='(') // C# 12 primary constructor
6666 {
6667 yyextra->current->args=yytext;
6668 yyextra->currentArgumentContext = ClassVar;
6669 yyextra->fullArgString = yyextra->current->args;
6670 yyextra->copyArgString = &yyextra->current->args;
6671 BEGIN( ReadFuncArgType ) ;
6672 }
6673 else
6674 {
6675 // probably a function anyway
6676 unput(*yytext);
6677 BEGIN( FindMembers );
6678 }
6679 }
6680<CSConstraintType,CSConstraintName>{CCS}{CCE} { /* empty comment */ }
6681<CSConstraintType,CSConstraintName>({CCS}[*!]|{CPPC}[/!])("<"?) { // special comment
6682 yyextra->fullArgString.clear();
6683 yyextra->lastCopyArgChar='#'; // end marker
6684 yyextra->lastCommentInArgContext=YY_START;
6685 if (yytext[1]=='/')
6686 BEGIN( CopyArgCommentLine );
6687 else
6688 BEGIN( CopyArgComment );
6689 }
6690<CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block
6691 yyextra->current->typeConstr.back().docs = yyextra->fullArgString;
6692 }
6693<CSConstraintType>"=>" { // end of type constraint reached
6694 // parse documentation of the constraints
6695 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6696 unput('>');
6697 unput('=');
6698 BEGIN( yyextra->lastCSConstraint );
6699 }
6700<CSConstraintType>"{" { // end of type constraint reached
6701 // parse documentation of the constraints
6702 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6703 unput('{');
6704 BEGIN( yyextra->lastCSConstraint );
6705 }
6706<CSConstraintType,CSConstraintName>";" {
6707 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6708 unput(';');
6709 BEGIN( yyextra->lastCSConstraint );
6710 }
6711<CSConstraintName>":" {
6712 BEGIN( CSConstraintType );
6713 }
6714<CSConstraintName>{ID} {
6715 // parameter name
6716 yyextra->current->typeConstr.back().name=yytext;
6717 }
6718<CSConstraintType>"where" { // another constraint for a different param
6719 yyextra->current->typeConstr.push_back(Argument());
6720 BEGIN( CSConstraintName );
6721 }
6722<CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
6723 if (yyextra->current->typeConstr.back().type.empty())
6724 // first type constraint for this parameter
6725 {
6726 yyextra->current->typeConstr.back().type=yytext;
6727 }
6728 else // new type constraint for same parameter
6729 {
6730 DString name = yyextra->current->typeConstr.back().name;
6731 yyextra->current->typeConstr.push_back(Argument());
6732 yyextra->current->typeConstr.back().name=name;
6733 yyextra->current->typeConstr.back().type=yytext;
6734 }
6735 }
char & back()
Returns a reference to the last character.
Definition dstring.h:204
6736<CSConstraintName,CSConstraintType>\n {
6737 lineCount(yyscanner);
6738 }
6739<CSConstraintName,CSConstraintType>. {
6740 }
6741<ClassCategory>{ID} {
6742 yyextra->current->name+=yytext;
6743 }
6744<ClassCategory>")"/{BN}*"{" {
6745 yyextra->current->name+=')';
6746 BEGIN( ClassVar );
6747 }
6748<ClassCategory>")"/{BN}*"<" {
6749 yyextra->current->name+=')';
6750 BEGIN( ObjCProtocolList );
6751 }
6752<ClassCategory>")" {
6753 yyextra->current->name+=')';
6754 if (yyextra->current->spec.isProtocol() || yyextra->current->section.isObjcImpl())
6755 {
6756 unput('{'); // fake start of body
6757 }
6758 else // category has no variables so push back an empty body
6759 {
6760 unput('}');
6761 unput('{');
6762 }
6763 BEGIN( ClassVar );
6764 }
6765<ClassVar>":" {
6766 if (yyextra->current->section.isVariable()) // enum A B:2, see bug 748208
6767 {
6768 yyextra->current->bitfields+=":";
6769 yyextra->current->args.clear();
6770 BEGIN(BitFields);
6771 }
6772 else if (yyextra->current->section.isEnum()) // enum E:2, see bug 313527,
6773 // or C++11 style enum: 'E : unsigned int {...}'
6774 {
6775 yyextra->current->args.clear();
6776 BEGIN(EnumBaseType);
6777 }
6778 else
6779 {
6780 yyextra->current->type.clear();
6781 if (yyextra->current->spec.isInterface() ||
6782 yyextra->current->spec.isStruct() ||
6783 yyextra->current->spec.isRef() ||
6784 yyextra->current->spec.isValue() ||
6785 yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL
6786 )
6787 {
6788 yyextra->baseProt = Protection::Public;
6789 }
6790 else
6791 {
6792 yyextra->baseProt = Protection::Private;
6793 }
6794 yyextra->baseVirt = Specifier::Normal;
6795 yyextra->baseName.clear();
6796 BEGIN( BasesProt ) ;
6797 }
6798 }
6799<ClassVar>[;=*&] {
6800 if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
6801 {
6802 yyextra->current->type.prepend("typedef");
6803 }
6804 if ((yytext[0]=='*' || yytext[0]=='&') && yyextra->current->section.isEnum())
6805 { // found "enum a *b" -> variable
6806 yyextra->current->section = EntryType::makeVariable() ;
6807 }
6808 if (yytext[0]==';' && yyextra->current->section.isEnum())
6809 {
6810 yyextra->current->reset();
6811 initEntry(yyscanner);
6812 }
6813 else
6814 {
6815 unput(*yytext);
6816 }
6817 BEGIN( FindMembers );
6818 }
6819<Bases,ClassVar>{CPPC}"/"/[^/] {
6820 if (!yyextra->insideObjC)
6821 {
6822 REJECT;
6823 }
6824 else
6825 {
6826 lineCount(yyscanner);
6827 yyextra->current->program << yytext;
6828 yyextra->current->fileName = yyextra->fileName ;
6829 yyextra->current->startLine = yyextra->yyLineNr ;
6830 yyextra->current->startColumn = yyextra->yyColNr;
6831 yyextra->curlyCount=0;
6832 BEGIN( ReadBodyIntf );
6833 }
6834 }
6835<Bases,ClassVar>({CPPC}{B}*)?{CCS}"*"/{NCOMM} |
6836<Bases,ClassVar>({CPPC}{B}*)?{CCS}"!" |
6837<Bases,ClassVar>{CPPC}"!" |
6838<Bases,ClassVar>[\-+]{BN}* {
6839 if (!yyextra->insideObjC)
6840 {
6841 REJECT;
6842 }
6843 else
6844 {
6845 lineCount(yyscanner);
6846 yyextra->current->program << yytext;
6847 yyextra->current->fileName = yyextra->fileName ;
6848 yyextra->current->startLine = yyextra->yyLineNr ;
6849 yyextra->current->startColumn = yyextra->yyColNr;
6850 yyextra->curlyCount=0;
6851 BEGIN( ReadBodyIntf );
6852 }
6853 }
6854<CompoundName,ClassVar>{B}*"{"{B}* {
6855 yyextra->current->program.str(std::string());
6856 yyextra->current->fileName = yyextra->fileName ;
6857 yyextra->current->bodyLine = yyextra->yyLineNr;
6858 yyextra->current->bodyColumn = yyextra->yyColNr;
6859 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6860 if (yyextra->current->name.empty() && !yyextra->isTypedef) // anonymous compound
6861 {
6862 if (yyextra->current->section.isNamespace()) // allow reopening of anonymous namespaces
6863 {
6864 if (Config_getBool(EXTRACT_ANON_NSPACES)) // use visible name
6865 {
6866 yyextra->current->name="anonymous_namespace{"+stripPath(yyextra->current->fileName)+"}";
6867 }
6868 else // use invisible name
6869 {
6870 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonNSCount);
6871 }
6872 }
6873 else
6874 {
6875 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
6876 }
6877 }
6878 yyextra->curlyCount=0;
6879 if (yyextra->current_root && // not a nested struct yyextra->inside an @interface section
6880 !yyextra->current_root->spec.isInterface() &&
6881 (yyextra->current->spec.isInterface() ||
6882 yyextra->current->spec.isProtocol() ||
6883 yyextra->current->spec.isCategory() ||
6884 yyextra->current->section.isObjcImpl()
6885 ) &&
6886 yyextra->insideObjC
6887 )
6888 { // ObjC body that ends with @end
6889 BEGIN( ReadBodyIntf );
6890 }
6891 else if (yyextra->current->section.isNamespace())
6892 { // namespace body
6893 BEGIN( ReadNSBody );
6894 }
6895 else
6896 { // class body
6897 BEGIN( ReadBody ) ;
6898 }
6899 }
DString stripPath(const DString &s)
Definition util.cpp:4992
6900<BasesProt>"virtual"{BN}+ { lineCount(yyscanner); yyextra->baseVirt = Specifier::Virtual; }
6901<BasesProt>"public"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Public; }
6902<BasesProt>"protected"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Protected; }
6903<BasesProt>"internal"{BN}+ { if (!yyextra->insideCli) REJECT ; lineCount(yyscanner); yyextra->baseProt = Protection::Package; }
6904<BasesProt>"private"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Private; }
6905<BasesProt>{BN} { lineCount(yyscanner); }
6906<BasesProt>. { unput(*yytext); BEGIN(Bases); }
6907<Bases>"decltype"{BN}*"(" {
6908 lineCount(yyscanner);
6909 yyextra->roundCount=0;
6910 yyextra->lastSkipRoundContext=YY_START;
6911 BEGIN(SkipRound);
6912 }
6913<Bases>("\\")?({ID}"\\")*{ID} { // PHP namespace token, not sure if interspacing is allowed but it gives problems (see bug 640847)
6914 if (!yyextra->insidePHP)
6915 {
6916 REJECT;
6917 }
6918 else // PHP base class of the form \Ns\Cl or Ns\Cl
6919 {
6920 lineCount(yyscanner);
6921 DString bn=yytext;
6922 bn = substitute(bn,"\\","::");
6923 yyextra->baseName += bn;
6924 yyextra->current->args += ' ';
6925 yyextra->current->args += yytext;
6926 }
6927 }
6928<Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID}("...")? {
6929 lineCount(yyscanner);
6930 DString baseScope = yytext;
6931 if (yyextra->insideCS && baseScope.stripWhiteSpace()=="where")
6932 {
6933 // type constraint for a class
6934 yyextra->current->typeConstr.clear();
6935 yyextra->current->typeConstr.push_back(Argument());
6936 yyextra->lastCSConstraint = YY_START;
6937 BEGIN( CSConstraintName );
6938 }
6939 else
6940 {
6941 yyextra->baseName+=yytext;
6942 yyextra->current->args += ' ';
6943 yyextra->current->args += yytext;
6944 }
6945 }
6946<Bases>{BN}*{ID}("."{ID})* { // Java style class
6947 DString name = substitute(yytext,".","::");
6948 yyextra->baseName += name;
6949 yyextra->current->args += ' ';
6950 yyextra->current->args += name;
6951 }
6952<ClassVar,Bases>\n/{BN}*[^{, \t\n:] {
6953 if (!yyextra->insideObjC)
6954 {
6955 REJECT;
6956 }
6957 else
6958 {
6959 lineCount(yyscanner);
6960 unput('{');
6961 }
6962 }
6963<ClassVar,Bases>"@end" { // empty ObjC interface
6964 unput('d'); // insert fake body: {}@end
6965 unput('n');
6966 unput('e');
6967 unput('@');
6968 unput('}');
6969 unput('{');
6970 }
6971<ClassVar>"<" { yyextra->current->name += *yytext;
6972 yyextra->sharpCount=1;
6973 yyextra->roundCount=0;
6974 yyextra->lastSkipSharpContext = YY_START;
6975 yyextra->specName = &yyextra->current->name;
6976 BEGIN ( Specialization );
6977 }
6978<Bases>{BN}*"<" {
6979 lineCount(yyscanner);
6980 yyextra->sharpCount=1;
6981 yyextra->roundCount=0;
6982 yyextra->lastSkipSharpContext = YY_START;
6983 if (yyextra->insideObjC) // start of protocol list
6984 {
6985 unput(',');
6986 }
6987 else // template specialization
6988 {
6989 //if (yyextra->insideCS) // generic
6990 //{
6991 // yyextra->baseName+="-g";
6992 //}
6993 yyextra->templateStr = yytext;
6994 yyextra->specName = &yyextra->templateStr;
6995 BEGIN ( Specialization );
6996 }
6997 }
6998<Specialization>"<" { *yyextra->specName += *yytext;
6999 if (yyextra->roundCount==0) yyextra->sharpCount++;
7000 }
7001<Specialization>">" {
7002 *yyextra->specName += *yytext;
7003 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
7004 {
7005 yyextra->baseName+=removeRedundantWhiteSpace(*yyextra->specName);
7006 BEGIN(yyextra->lastSkipSharpContext);
7007 }
7008 }
7009<Specialization>{BN}+ { lineCount(yyscanner); *yyextra->specName +=' '; }
7010<Specialization>"<<" { *yyextra->specName += yytext; }
7011<Specialization>">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template...
7012 unput('>');
7013 unput(' ');
7014 unput('>');
7015 }
7016<Specialization>">>" {
7017 if (yyextra->insideCS) // for C# >> ends a nested template
7018 {
7019 REJECT;
7020 }
7021 else // for C++ >> is a bitshift
7022 // operator and > > would end
7023 // a nested template.
7024 // We require the bitshift to be enclosed in braces.
7025 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
7026 {
7027 if (yyextra->roundCount>0)
7028 {
7029 *yyextra->specName += yytext;
7030 }
7031 else
7032 {
7033 unput('>');
7034 unput(' ');
7035 unput('>');
7036 }
7037 }
7038 }
7039<Specialization>"typename"{BN}+ { lineCount(yyscanner); }
7040<Specialization>"(" { *yyextra->specName += *yytext; yyextra->roundCount++; }
7041<Specialization>")" { *yyextra->specName += *yytext; yyextra->roundCount--; }
7042
7043<Specialization>"\\\\" { *yyextra->specName += *yytext;}
7044<Specialization>"\\'" { *yyextra->specName += *yytext;}
7045<Specialization>"\\\"" { *yyextra->specName += *yytext;}
7046<Specialization>"'" { *yyextra->specName += *yytext;BEGIN(SpecializationSingleQuote);}
7047<Specialization>"\"" { *yyextra->specName += *yytext;BEGIN(SpecializationDoubleQuote);}
7048<SpecializationSingleQuote,SpecializationDoubleQuote>"\\\\" { *yyextra->specName += *yytext;}
7049<SpecializationSingleQuote>"\\'" { *yyextra->specName += *yytext;}
7050<SpecializationSingleQuote>"'" { *yyextra->specName += *yytext; BEGIN(Specialization);}
7051<SpecializationDoubleQuote>"\\\"" { *yyextra->specName += *yytext;}
7052<SpecializationDoubleQuote>"\"" { *yyextra->specName += *yytext; BEGIN(Specialization);}
7053<SpecializationSingleQuote,SpecializationDoubleQuote>. { *yyextra->specName += *yytext;}
7054
7055<Specialization>. {
7056 *yyextra->specName += *yytext;
7057 }
7058<SkipRound>"(" { ++yyextra->roundCount; }
7059<SkipRound>")" { if (--yyextra->roundCount<0)
7060 BEGIN ( yyextra->lastSkipRoundContext );
7061 }
7062<SkipRound>\" {
7063 yyextra->lastStringContext=SkipRound;
7064 BEGIN(SkipString);
7065 }
7066<Bases>","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount(yyscanner);
7067 if (yyextra->insideProtocolList)
7068 {
7069 yyextra->baseName+="-p";
7070 }
7071 else
7072 {
7073 yyextra->current->args += ',' ;
7074 }
7075 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
7076 if (!yyextra->baseName.empty())
7077 {
7078 yyextra->current->extends.emplace_back(
7079 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
7080 );
7081 }
7082 if (yyextra->current->spec.isInterface() || yyextra->current->spec.isStruct() ||
7083 yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS ||
7084 yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL || yyextra->insideSlice)
7085 {
7086 yyextra->baseProt=Protection::Public;
7087 }
7088 else
7089 {
7090 yyextra->baseProt=Protection::Private;
7091 }
7092 yyextra->baseVirt=Specifier::Normal;
7093 yyextra->baseName.clear();
7094 if (*yytext=='>')
7095 { // end of a ObjC protocol list
7096 yyextra->insideProtocolList=false;
7097 if (yyleng==1)
7098 {
7099 if (yyextra->insideObjC && !yyextra->current->spec.isProtocol())
7100 {
7101 BEGIN(ClassVar); // allow parsing of ':' for base class
7102 }
7103 else
7104 {
7105 unput('{'); // dummy start body
7106 }
7107 }
7108 else
7109 {
7110 yyless(1);
7111 }
7112 }
7113 else
7114 {
7115 if (*yytext==',' && yyextra->insideObjC) // Begin of protocol list
7116 {
7117 yyextra->insideProtocolList=true;
7118 }
7119 BEGIN(BasesProt);
7120 }
7121 }
7122<Bases>{B}*"{"{B}* {
7123 yyextra->current->program.str(std::string());
7124 yyextra->current->fileName = yyextra->fileName ;
7125 yyextra->current->bodyLine = yyextra->yyLineNr;
7126 yyextra->current->bodyColumn = yyextra->yyColNr;
7127 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
7128 if (!yyextra->baseName.empty())
7129 {
7130 yyextra->current->extends.emplace_back(
7131 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
7132 );
7133 yyextra->baseName.clear();
7134 }
7135 yyextra->curlyCount=0;
7136 if (yyextra->insideObjC)
7137 {
7138 BEGIN( ReadBodyIntf );
7139 }
7140 else
7141 {
7142 BEGIN( ReadBody ) ;
7143 }
7144 }
7145<SkipUnionSwitch>{B}*"(" {
7146 yyextra->roundCount++;
7147 }
7148<SkipUnionSwitch>")" {
7149 if (--yyextra->roundCount==0)
7150 {
7151 BEGIN(ClassVar);
7152 }
7153 }
7154<SkipUnionSwitch>\n { lineCount(yyscanner); }
7155<SkipUnionSwitch>.
7156<Comment>{BN}+ { yyextra->current->program << yytext ;
7157 lineCount(yyscanner) ;
7158 }
7159<Comment>{CCS} { yyextra->current->program << yytext ; }
7160<Comment>{CPPC} { yyextra->current->program << yytext ; }
7161<Comment>{CMD}("code"|"verbatim"|"iliteral") {
7162 if (yyextra->doxygenComment) yyextra->insideCode=true;
7163 yyextra->current->program << yytext ;
7164 }
7165<Comment>{CMD}("endcode"|"endverbatim"|"endiliteral") {
7166 if (yyextra->doxygenComment) yyextra->insideCode=false;
7167 yyextra->current->program << yytext ;
7168 }
7169<Comment>[^ \.\t\r\n\/\*]+ { yyextra->current->program << yytext ; }
7170<Comment>{CCE} { yyextra->current->program << yytext ;
7171 if (!yyextra->insideCode)
7172 {
7173 yyextra->doxygenComment=false;
7174 BEGIN( yyextra->lastContext );
7175 }
7176 }
7177<Comment>. { yyextra->current->program << *yytext ; }
7178
7179<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,SkipC11Inits,ReadExpressionBody,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"!" {
7180 //printf("Start doc block at %d\n",yyextra->yyLineNr);
7181 if (!yyextra->current->doc.empty())
7182 {
7183 yyextra->current->doc+="\n\n";
7184 }
7185 else
7186 {
7187 yyextra->current->docLine = yyextra->yyLineNr;
7188 yyextra->current->docFile = yyextra->fileName;
7189 }
7190
7191 yyextra->lastDocContext = YY_START;
7192 if (yyextra->current_root->section.isScope())
7193 {
7194 yyextra->current->inside = yyextra->current_root->name+"::";
7195 }
7196 yyextra->docBlockContext = YY_START;
7197 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7198 yyextra->docBlockAutoBrief = Config_getBool(QT_AUTOBRIEF);
7199
7200 DString indent;
7201 indent.fill(' ',computeIndent(yytext,yyextra->column));
7202 yyextra->docBlock.str(indent.str());
7203
7204 if (yyextra->docBlockAutoBrief)
7205 {
7206 yyextra->current->briefLine = yyextra->yyLineNr;
7207 yyextra->current->briefFile = yyextra->fileName;
7208 }
7209 startCommentBlock(yyscanner,false);
7210 BEGIN( DocBlock );
7211 }
7212<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,ReadExpressionBody,Bases,OldStyleArgs>{CCS}"*"[*]+{BL} {
7213 bool javadocBanner = Config_getBool(JAVADOC_BANNER);
7214 lineCount(yyscanner);
7215
7216 if( javadocBanner )
7217 {
7218 yyextra->lastDocContext = YY_START;
7219
7220 //printf("Found comment banner at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
7221 if (yyextra->current_root->section.isScope())
7222 {
7223 yyextra->current->inside = yyextra->current_root->name+"::";
7224 }
7225 yyextra->current->docLine = yyextra->yyLineNr;
7226 yyextra->current->docFile = yyextra->fileName;
7227 yyextra->docBlockContext = YY_START;
7228 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7229 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
7230 yyextra->docBlockAutoBrief = javadocAutoBrief;
7231
7232 DString indent;
7233 indent.fill(' ',computeIndent(yytext,yyextra->column));
7234 yyextra->docBlock.str(indent.str());
7235
7236 if (yyextra->docBlockAutoBrief)
7237 {
7238 yyextra->current->briefLine = yyextra->yyLineNr;
7239 yyextra->current->briefFile = yyextra->fileName;
7240 }
7241 startCommentBlock(yyscanner,false);
7242 BEGIN( DocBlock );
7243 }
7244 else
7245 {
7246 yyextra->current->program << yytext ;
7247 yyextra->lastContext = YY_START ;
7248 yyextra->doxygenComment=true;
7249 BEGIN( Comment ) ;
7250 }
7251 }
7252<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,ReadExpressionBody,SkipInits,Bases,OldStyleArgs>^{B}+({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
7253 lineCount(yyscanner);
7254 yyextra->yyColNr=1;
7255 REJECT;
7256 }
7257<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,ReadExpressionBody,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
7258 yyextra->lastDocContext = YY_START;
7259
7260 //printf("Found comment block at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
7261 if (yyextra->current_root->section.isScope())
7262 {
7263 yyextra->current->inside = yyextra->current_root->name+"::";
7264 }
7265 yyextra->current->docLine = yyextra->yyLineNr;
7266 yyextra->current->docFile = yyextra->fileName;
7267 yyextra->docBlockContext = YY_START;
7268 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7269 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
7270 yyextra->docBlockAutoBrief = javadocAutoBrief;
7271
7272 DString indent;
7273 indent.fill(' ',computeIndent(yytext,yyextra->column));
7274 yyextra->docBlock.str(indent.str());
7275
7276 if (yyextra->docBlockAutoBrief)
7277 {
7278 yyextra->current->briefLine = yyextra->yyLineNr;
7279 yyextra->current->briefFile = yyextra->fileName;
7280 }
7281 startCommentBlock(yyscanner,false);
7282 BEGIN( DocBlock );
7283 }
7284<FindMembers,FindFields,MemberSpec,SkipCurly,ReadExpressionBody,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"!" {
7285 yyextra->lastDocContext = YY_START;
7286 if (yyextra->current_root->section.isScope())
7287 {
7288 yyextra->current->inside = yyextra->current_root->name+"::";
7289 }
7290 yyextra->docBlockContext = YY_START;
7291 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7292 yyextra->docBlockAutoBrief = false;
7293
7294 DString indent;
7295 indent.fill(' ',computeIndent(yytext,yyextra->column));
7296 yyextra->docBlock.str(indent.str());
7297
7298 startCommentBlock(yyscanner,yyextra->current->brief.empty());
7299 BEGIN( DocLine );
7300 }
7301<FindMembers,FindFields,MemberSpec,SkipCurly,ReadExpressionBody,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"/"/[^/] {
7302 yyextra->lastDocContext = YY_START;
7303 if (yyextra->current_root->section.isScope())
7304 {
7305 yyextra->current->inside = yyextra->current_root->name+"::";
7306 }
7307 yyextra->docBlockContext = YY_START;
7308 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7309 yyextra->docBlockAutoBrief = false;
7310 DString indent;
7311 indent.fill(' ',computeIndent(yytext,yyextra->column));
7312 yyextra->docBlock.str(indent.str());
7313 startCommentBlock(yyscanner,yyextra->current->brief.empty());
7314 BEGIN( DocLine );
7315 }
7316<FindMembers>"extern"{BN}*"\""[^\"]+"\""{BN}*("{")? {
7317 lineCount(yyscanner);
7318 yyextra->externLinkage=true;
7319 }
7320<FindMembers>"{" {
7321 if (yyextra->externLinkage)
7322 {
7323 yyextra->externLinkage=false;
7324 }
7325 else if (yyextra->insideCS &&
7326 !yyextra->current->name.empty() &&
7327 !yyextra->current->type.empty())
7328 {
7329 if (yyextra->current->mtype == MethodTypes::Event)
7330 {
7331 yyextra->mtype = MethodTypes::Event;
7332 }
7333 else if (containsWord(yyextra->current->type,"event")) // event
7334 {
7335 yyextra->current->mtype = yyextra->mtype = MethodTypes::Event;
7336 }
7337 else // property
7338 {
7339 yyextra->current->mtype = yyextra->mtype = MethodTypes::Property;
7340 }
7341 yyextra->current->bodyLine = yyextra->yyLineNr;
7342 yyextra->current->bodyColumn = yyextra->yyColNr;
7343 yyextra->curlyCount=0;
7344 BEGIN( CSAccessorDecl );
7345 }
7346 else if (yyextra->insideIDL && yyextra->current->spec.isAttribute())
7347 {
7348 // UNO IDL: attributes may have setter and getter
7349 // exception specifications
7350 yyextra->current->exception = " {";
7351 BEGIN(UNOIDLAttributeBlock);
7352 }
7353 else
7354 {
7355 if ((yyextra->insideJava || yyextra->insideCS || yyextra->insideD) &&
7356 yyextra->current->name.empty()
7357 )
7358 {
7359 // static Java initializer
7360 yyextra->needsSemi = false;
7361 if (yyextra->current->isStatic)
7362 {
7363 yyextra->current->name="[static initializer]";
7364 yyextra->current->type.clear();
7365 }
7366 else
7367 {
7368 yyextra->current->name="[instance initializer]";
7369 }
7370 unput(*yytext);
7371 BEGIN( SFunction );
7372 }
7373 else
7374 {
7375 // pre C++11 code -> ignore the initializer
7376 //yyextra->needsSemi = true;
7377 //yyextra->current->type.clear();
7378 //yyextra->current->name.clear();
7379 //yyextra->current->args.clear();
7380 //yyextra->current->argList.clear();
7381 //yyextra->curlyCount=0;
7382 //BEGIN( SkipCurlyBlock );
7383
7384 // C++11 style initializer list
7385 yyextra->current->bodyLine = yyextra->yyLineNr;
7386 yyextra->current->bodyColumn = yyextra->yyColNr;
7387 yyextra->current->initializer.str(yytext);
7388 yyextra->lastInitializerContext = YY_START;
7389 yyextra->sharpCount=0;
7390 yyextra->initBracketCount=1;
7391 BEGIN(ReadInitializer);
7392 }
7393 }
7394 }
7395<CSAccessorDecl>"{" { yyextra->curlyCount++; }
7396<CSAccessorDecl>"}"{B}*"=" {
7397 // fall back to next rule if it's not the right bracket
7398 if (yyextra->curlyCount != 0) REJECT;
7399 yyextra->current->initializer.str("=");
7400 yyextra->current->endBodyLine=yyextra->yyLineNr;
7401 yyextra->lastInitializerContext = FindMembers;
7402 BEGIN(ReadInitializer);
7403 }
7404<CSAccessorDecl>"}" {
7405 if (yyextra->curlyCount)
7406 {
7407 yyextra->curlyCount--;
7408 }
7409 else
7410 {
7411 yyextra->mtype = MethodTypes::Method;
7412 yyextra->virt = Specifier::Normal;
7413 // not really important, but while we are at it
7414 yyextra->current->endBodyLine=yyextra->yyLineNr;
7415 unput(';');
7416 BEGIN(FindMembers);
7417 }
7418 }
7419<CSAccessorDecl>"private "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateSettable(true); }
7420<CSAccessorDecl>"protected "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedSettable(true); }
7421<CSAccessorDecl>"private "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateGettable(true); }
7422<CSAccessorDecl>"protected "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedGettable(true); }
7423<CSAccessorDecl>"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setSettable(true); }
7424<CSAccessorDecl>"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setGettable(true); }
7425<CSAccessorDecl>"add" { if (yyextra->curlyCount==0) yyextra->current->spec.setAddable(true); }
7426<CSAccessorDecl>"remove" { if (yyextra->curlyCount==0) yyextra->current->spec.setRemovable(true); }
7427<CSAccessorDecl>"raise" { if (yyextra->curlyCount==0) yyextra->current->spec.setRaisable(true); }
7428<CSAccessorDecl>{CHARLIT} {}
7429<CSAccessorDecl>"\"" { BEGIN(CSString);}
7430<CSAccessorDecl>"." {}
7431<CSAccessorDecl>\n { lineCount(yyscanner); }
7432<CSString>"\"" { BEGIN(CSAccessorDecl);}
7433<CSString>{CPPC} {} // Otherwise the rule <*>"//" will kick in
7434<CSString>{CCS} {} // Otherwise the rule <*>"/*" will kick in
7435<CSString>\n { lineCount(yyscanner); }
7436<CSString>"." {}
7437
7438 /* ---- Slice-specific rules ------ */
7439
7440<SliceSequence>{SCOPENAME} {
7441 if (yyextra->current->spec.isLocal())
7442 {
7443 yyextra->current->type = "local ";
7444 }
7445 yyextra->current->type += "sequence<";
7446 yyextra->current->type += yytext;
7447 yyextra->current->type += ">";
7448 }
7449
7450<SliceSequence>{BN}*">"{BN}* {
7451 lineCount(yyscanner);
7452 BEGIN(SliceSequenceName);
7453 }
7454
7455<SliceSequenceName>{ID}{BN}* {
7456 lineCount(yyscanner);
7457 yyextra->current->name = yytext ;
7458 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7459 }
7460
7461<SliceSequenceName>";" {
7462 yyextra->current->section = EntryType::makeVariable();
7463 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7464 initEntry(yyscanner);
7465 BEGIN(FindMembers);
7466 }
7467
7468<SliceDictionary>{SCOPENAME}{BN}*","{BN}*{SCOPENAME} {
7469 lineCount(yyscanner);
7470 if (yyextra->current->spec.isLocal())
7471 {
7472 yyextra->current->type = "local ";
7473 }
7474 yyextra->current->type += "dictionary<";
7475 yyextra->current->type += yytext;
7476 yyextra->current->type += ">";
7477 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
7478 }
7479
7480<SliceDictionary>{BN}*">"{BN}* {
7481 lineCount(yyscanner);
7482 BEGIN(SliceDictionaryName);
7483 }
7484
7485<SliceDictionaryName>{ID}{BN}* {
7486 lineCount(yyscanner);
7487 yyextra->current->name = yytext ;
7488 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7489 }
7490
7491<SliceDictionaryName>";" {
7492 yyextra->current->section = EntryType::makeVariable();
7493 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7494 initEntry(yyscanner);
7495 BEGIN(FindMembers);
7496 }
7497
7498 /**********************************************************************************/
7499 /******************** Documentation block related rules ***************************/
7500 /**********************************************************************************/
7501
7502 /* ---- Single line comments ------ */
7503<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
7504 int markerLen = yytext[yyleng-1]=='<' ? 4 : 3;
7505 yyextra->docBlock << std::string(yytext).substr(0,yyleng-markerLen);
7506 lineCount(yyscanner);
7507 }
7508<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
7509 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.empty());
7510 BEGIN( yyextra->docBlockContext );
7511 }
7512<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
7513 yyextra->docBlock << yytext;
7514 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.empty());
7515 BEGIN( yyextra->docBlockContext );
7516 }
7517<DocLine>{NONLopt}/"\n" { // whole line
7518 yyextra->docBlock << yytext;
7519 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.empty());
7520 BEGIN( yyextra->docBlockContext );
7521 }
7522
7523 /* ---- Comments blocks ------ */
7524
7525<DocBlock>"*"*{CCE} { // end of comment block
7526 handleCommentBlock(yyscanner,yyextra->docBlock.str(),false);
7527 BEGIN(yyextra->docBlockContext);
7528 }
7529<DocBlock>"\\ilinebr "{B}*"*"/[^/] {
7530 DString indent;
7531 indent.fill(' ',computeIndent(yytext+8,yyextra->column));
7532 yyextra->docBlock << "\\ilinebr " << indent;
7533 }
7534<DocBlock>^{B}*"*"+/[^/] {
7535 DString indent;
7536 indent.fill(' ',computeIndent(yytext,yyextra->column));
7537 yyextra->docBlock << indent;
7538 }
7539<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
7540 DString indent;
7541 indent.fill(' ',computeIndent(yytext,yyextra->column));
7542 yyextra->docBlock << indent;
7543 }
7544<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
7545 }
7546<DocBlock>{CPPC} { // slashes in the middle of a comment block
7547 yyextra->docBlock << yytext;
7548 }
7549<DocBlock>{CCS} { // start of a new comment in the
7550 // middle of a comment block
7551 yyextra->docBlock << yytext;
7552 }
7553<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
7554 yyextra->docBlock << yytext;
7555 }
7556<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
7557 yyextra->docBlock << yytext;
7558 char blockName[] = "f$";
7559 char c = yytext[2];
7560 if (c=='[') blockName[1]=']';
7561 else if (c=='{') blockName[1]='}';
7562 else if (c=='(') blockName[1]=')';
7563 startVerbatimBlock(yyscanner,blockName);
7564 BEGIN(DocCopyBlock);
7565 }
7566<DocBlock>{CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
7567 yyextra->fileName = &yytext[6];
7568 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7569 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
7570 yyextra->docBlock << yytext;
7571 }
7572<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
7573 yyextra->fileName = &yytext[6];
7574 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7575 yyextra->docBlock << yytext;
7576 }
7577<DocBlock>{CMD}"iline"{LINENR}{B} {
7578 bool ok = false;
7579 int nr = DString(&yytext[6]).toInt(&ok);
7580 if (!ok)
7581 {
7582 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
7583 }
7584 else
7585 {
7586 yyextra->yyLineNr = nr;
7587 }
7588 yyextra->docBlock << yytext;
7589 }
7590<DocBlock>{B}*"<"{PRE}">" {
7591 yyextra->docBlock << yytext;
7592 startVerbatimBlock(yyscanner,"<pre>");
7593 BEGIN(DocCopyBlock);
7594 }
7595<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7596 yyextra->docBlock << yytext;
7597 startVerbatimBlock(yyscanner,"uml");
7598 BEGIN(DocCopyBlock);
7599 }
7600<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!)
7601 yyextra->docBlock << yytext;
7602 startVerbatimBlock(yyscanner,&yytext[1]);
7603 BEGIN(DocCopyBlock);
7604 }
7605<DocBlock>{CMD}("code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7606 yyextra->docBlock << yytext;
7607 startVerbatimBlock(yyscanner,&yytext[1],0,true);
7608 BEGIN(DocCopyBlock);
7609 }
7610<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7611 DString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7612 yyextra->docBlock << "\\ilinebr ";
7613 yyextra->docBlock << pat;
7614 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length(),true);
7615 BEGIN(DocCopyBlock);
7616 }
7617<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7618 DString pat = substitute(yytext,"*"," ");
7619 yyextra->docBlock << pat;
7620 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length(),true);
7621 BEGIN(DocCopyBlock);
7622 }
7623<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7624<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7625<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]* {
7626 DString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7627 yyextra->docBlock << "\\ilinebr ";
7628 yyextra->docBlock << pat;
7629 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length(),true);
7630 BEGIN(DocCopyBlock);
7631 }
7632<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7633<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7634<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7635 DString pat = substitute(yytext,"*"," ");
7636 yyextra->docBlock << pat;
7637 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length(),true);
7638 BEGIN(DocCopyBlock);
7639 }
7640<DocBlock>"```" { // skip ``` if not at the start of a line
7641 yyextra->docBlock << "```";
7642 }
7643<DocBlock>"\\`" { // skip escaped backtick
7644 yyextra->docBlock << yytext;
7645 }
7646<DocBlock>"`"{1,2} {
7647 yyextra->docBlock << yytext;
7648 startVerbatimBlock(yyscanner,yytext,yyleng,true);
7649 BEGIN(DocCopyBlock);
7650 }
7651<DocBlock>{B}*"<"{CODE}">" {
7652 if (yyextra->insideCS)
7653 {
7654 yyextra->docBlock << yytext;
7655 startVerbatimBlock(yyscanner,"<code>",0,true);
7656 BEGIN(DocCopyBlock);
7657 }
7658 else
7659 {
7660 REJECT;
7661 }
7662 }
7663<DocBlock>[^@*~`'\/\\\n]+ { // any character that isn't special
7664 yyextra->docBlock << yytext;
7665 }
7666<DocBlock>\n { // newline
7667 lineCount(yyscanner);
7668 yyextra->docBlock << *yytext;
7669 }
7670<DocBlock>. { // command block
7671 yyextra->docBlock << *yytext;
7672 }
7673
7674 /* ---- Copy verbatim sections ------ */
7675
7676<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
7677 if (endVerbatimBlock(yyscanner,"<pre>"))
7678 {
7679 BEGIN(DocBlock);
7680 }
7681 yyextra->docBlock << yytext;
7682 }
7683<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
7684 if (endVerbatimBlock(yyscanner,"<code>"))
7685 {
7686 BEGIN(DocBlock);
7687 }
7688 yyextra->docBlock << yytext;
7689 }
7690<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
7691 if (endVerbatimBlock(yyscanner,&yytext[1]))
7692 {
7693 BEGIN(DocBlock);
7694 }
7695 yyextra->docBlock << yytext;
7696 }
7697<DocCopyBlock>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"endmermaid"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
7698 if (endVerbatimBlock(yyscanner,&yytext[4]))
7699 {
7700 BEGIN(DocBlock);
7701 }
7702 yyextra->docBlock << yytext;
7703 }
7704<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
7705 if ((yyextra->docBlockName=="verbatim") || (yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7706 {
7707 REJECT;
7708 }
7709 else
7710 {
7711 DString indent;
7712 indent.fill(' ',computeIndent(yytext,0));
7713 yyextra->docBlock << indent;
7714 }
7715 }
7716<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
7717 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7718 {
7719 DString indent;
7720 indent.fill(' ',computeIndent(yytext,0));
7721 yyextra->docBlock << indent;
7722 }
7723 else
7724 {
7725 REJECT;
7726 }
7727 }
7728<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
7729 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7730 {
7731 DString indent;
7732 indent.fill(' ',computeIndent(yytext,-1));
7733 yyextra->docBlock << indent+"*";
7734 }
7735 else
7736 {
7737 REJECT;
7738 }
7739 }
7740<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
7741 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7742 {
7743 DString indent;
7744 if (yyextra->nestedComment>0) // keep * it is part of the code
7745 {
7746 indent.fill(' ',computeIndent(yytext,-1));
7747 yyextra->docBlock << indent+"*";
7748 }
7749 else // remove * it is part of the comment block
7750 {
7751 indent.fill(' ',computeIndent(yytext,0));
7752 yyextra->docBlock << indent;
7753 }
7754 }
7755 else
7756 {
7757 REJECT;
7758 }
7759 }
7760<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7761 DString pat = substitute(yytext,"*"," ");
7762 if (endVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length()))
7763 {
7764 BEGIN(DocBlock);
7765 }
7766 yyextra->docBlock << pat;
7767 }
7768<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7769 DString pat = substitute(yytext,"*"," ");
7770 if (endVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length()))
7771 {
7772 BEGIN(DocBlock);
7773 }
7774 yyextra->docBlock << pat;
7775 }
7776<DocCopyBlock>"```" { // backtick + end marker
7777 if (yyextra->docBlockName=="``")
7778 {
7779 yyextra->docBlock << "`";
7780 endVerbatimBlock(yyscanner,"``",2);
7781 yyextra->docBlock << "``";
7782 BEGIN(DocBlock);
7783 }
7784 else
7785 {
7786 yyextra->docBlock << yytext;
7787 }
7788 }
7789<DocCopyBlock>"''"/[^a-z_A-Z0-9-] {
7790 if (!Config_getBool(MARKDOWN_STRICT) && endVerbatimBlock(yyscanner,"``",2))
7791 {
7792 BEGIN(DocBlock);
7793 }
7794 yyextra->docBlock << yytext;
7795 }
7796<DocCopyBlock>"'"/[^'a-z_A-Z0-9-] {
7797 if (!Config_getBool(MARKDOWN_STRICT) && endVerbatimBlock(yyscanner,"`",1))
7798 {
7799 BEGIN(DocBlock);
7800 }
7801 yyextra->docBlock << yytext;
7802 }
7803<DocCopyBlock>"`"{1,2} {
7804 if (endVerbatimBlock(yyscanner,yytext,yyleng))
7805 {
7806 BEGIN(DocBlock);
7807 }
7808 yyextra->docBlock << yytext;
7809 }
7810<DocCopyBlock>[^<@/\*\‍]`'~"\$\\\n]+ { // any character that is not special
7811 yyextra->docBlock << yytext;
7812 }
7813<DocCopyBlock>\" {
7814 yyextra->docBlock << yytext;
7815 if (yyextra->docBlockName=="code" || yyextra->docBlockName=="iliteral")
7816 // to support end of comment character sequences inside
7817 // a string literal of a code block, see #6737
7818 {
7819 yyextra->lastStringContext=YY_START;
7820 yyextra->pCopyQuotedGString=&yyextra->docBlock;
7821 yyextra->stopAtInvalidString=true;
7822 BEGIN(CopyGString);
7823 }
7824 }
7825<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
7826 if (yytext[1]=='*') // start comment
7827 {
7828 yyextra->nestedComment++;
7829 }
7830 else if (yytext[0]=='*' && yyextra->nestedComment>0) // end comment
7831 {
7832 yyextra->nestedComment--;
7833 }
7834 else if (yytext[0]=='*' && yyextra->nestedComment==0 && yyextra->isCodeBlock) // end comment without start
7835 {
7836 warn(yyextra->fileName,yyextra->yyLineNr,
7837 "Found end of C comment inside a '{}' block without matching start of the comment!"
7838 " Maybe the end marker for the block is missing?",
7839 yyextra->docBlockName);
7840 BEGIN(DocBlock);
7841 }
7842 yyextra->docBlock << yytext;
7843 }
7844<DocCopyBlock>\n { // newline
7845 yyextra->docBlock << *yytext;
7846 lineCount(yyscanner);
7847 }
7848<DocCopyBlock>. { // any other character
7849 yyextra->docBlock << *yytext;
7850 }
7851<DocCopyBlock><<EOF>> {
7852 warn(yyextra->fileName,yyextra->yyLineNr,
7853 "reached end of file while inside a '{}' block!"
7854 " The command that should end the block seems to be missing!",
7855 yyextra->docBlockName);
7856 yyterminate();
7857 }
7858
7859
7860 /* ------------- Prototype parser -------------- */
7861
7862<Prototype>"operator"{B}*"("{B}*")" {
7863 yyextra->current->name+=yytext;
7864 }
7865<Prototype>"(" {
7866 yyextra->current->args+=*yytext;
7867 yyextra->currentArgumentContext = PrototypeQual;
7868 yyextra->fullArgString = yyextra->current->args;
7869 yyextra->copyArgString = &yyextra->current->args;
7870 BEGIN( ReadFuncArgType ) ;
7871 }
7872<Prototype>"("({ID}"::")*({B}*[&*])+ {
7873 if (yyextra->insidePHP) // reference parameter
7874 {
7875 REJECT;
7876 }
7877 else
7878 {
7879 yyextra->current->type+=yyextra->current->name+yytext;
7880 yyextra->current->name.clear();
7881 BEGIN( PrototypePtr );
7882 }
7883 }
7884<PrototypePtr>{SCOPENAME} {
7885 yyextra->current->name+=yytext;
7886 }
7887<PrototypePtr>"(" {
7888 yyextra->current->args+=*yytext;
7889 yyextra->currentArgumentContext = PrototypeQual;
7890 yyextra->fullArgString = yyextra->current->args;
7891 yyextra->copyArgString = &yyextra->current->args;
7892 BEGIN( ReadFuncArgType ) ;
7893 }
7894<PrototypePtr>")" {
7895 yyextra->current->type+=')';
7896 BEGIN( Prototype );
7897 }
7898<PrototypePtr>. {
7899 yyextra->current->name+=yytext;
7900 }
7901<PrototypeQual>"{" {
7902 BEGIN( PrototypeSkipLine);
7903 }
7904<PrototypeQual>{B}*"const"{B}* {
7905 yyextra->current->args += " const ";
7906 yyextra->current->argList.setConstSpecifier(true);
7907 }
7908<PrototypeQual>{B}*"volatile"{B}* {
7909 yyextra->current->args += " volatile ";
7910 yyextra->current->argList.setVolatileSpecifier(true);
7911 }
7912<PrototypeQual>{B}*"="{B}*"0"{B}* {
7913 yyextra->current->args += " = 0";
7914 yyextra->current->virt = Specifier::Pure;
7915 yyextra->current->argList.setPureSpecifier(true);
7916 }
7917<PrototypeQual>"throw"{B}*"(" {
7918 yyextra->current->exception = "throw(";
7919 BEGIN(PrototypeExc);
7920 }
7921<PrototypeExc>")" {
7922 yyextra->current->exception += ')';
7923 BEGIN(PrototypeQual);
7924 }
7925<PrototypeExc>. {
7926 yyextra->current->exception += *yytext;
7927 }
7928<PrototypeQual>. {
7929 yyextra->current->args += *yytext;
7930 }
7931<Prototype>. {
7932 yyextra->current->name += *yytext;
7933 }
7934<PrototypeSkipLine>. {
7935 }
7936
7937
7938
7939
7940<SkipCxxComment>.*"\\\n" { // line continuation
7941 if (yyextra->insideCS)
7942 {
7943 REJECT;
7944 }
7945 else
7946 {
7947 lineCount(yyscanner);
7948 }
7949 }
7950<SkipCxxComment>{ANYopt}/\n {
7951 BEGIN( yyextra->lastCContext ) ;
7952 }
7953<SkipComment>[^\*\n]+
7954
7955 /* ------------ Generic rules -------------- */
7956
7957<*>"[[" { // C++11 attribute
7958 if (!yyextra->insideCpp) REJECT;
7959 if (YY_START == CopyGString || YY_START == CopyGString) REJECT;
7960 yyextra->lastC11AttributeContext = YY_START;
7961 yyextra->pCopyC11AttributeString = &yyextra->current->attributes;
7962 BEGIN( CopyC11Attribute );
7963 }
7964
7965<*>\n { lineCount(yyscanner); }
7966<*>\" {
7967 if (yyextra->insideIDL && yyextra->insideCppQuote)
7968 {
7969 BEGIN(EndCppQuote);
7970 }
7971 else if (yyextra->insidePHP)
7972 {
7973 yyextra->lastStringContext=YY_START;
7974 BEGIN(SkipString);
7975 }
7976 }
7977<*>^{B}*"#" {
7978 if (!yyextra->insidePHP)
7979 {
7980 yyextra->lastCPPContext = YY_START;
7981 BEGIN( SkipCPP ) ;
7982 }
7983 else
7984 {
7985 yyextra->lastCContext = YY_START ;
7986 BEGIN( SkipCxxComment ) ;
7987 }
7988 }
7989<*>"#" {
7990 if (!yyextra->insidePHP)
7991 REJECT;
7992 yyextra->lastCContext = YY_START ;
7993 BEGIN( SkipCxxComment ) ;
7994 }
7995<*>\' {
7996 if (yyextra->insidePHP)
7997 {
7998 yyextra->lastStringContext=YY_START;
7999 BEGIN(SkipPHPString);
8000 }
8001 }
8002<*>\? {
8003 if (yyextra->insideCS && (YY_START != SkipRound) && (YY_START != CSAccessorDecl))
8004 {
8005 if (yyextra->current->type.empty())
8006 {
8007 if (yyextra->current->name.empty())
8008 yyextra->current->name="?";
8009 else
8010 yyextra->current->name+="?";
8011 }
8012 else
8013 {
8014 yyextra->current->type+="?";
8015 }
8016 }
8017 }
8018<*>"}" { yyextra->exported=false; }
8019<*>.
8020<SkipComment>{CPPC}|{CCS}
8021<*>{CCS} { yyextra->lastCContext = YY_START ;
8022 BEGIN( SkipComment ) ;
8023 }
8024<SkipComment>{B}*{CCE} { BEGIN( yyextra->lastCContext ) ; }
8025<*>{CPPC} {
8026 yyextra->lastCContext = YY_START ;
8027 BEGIN( SkipCxxComment ) ;
8028 }
8029<<EOF>> {
8030 if (yyextra->insideCS && yyextra->fakeNS)
8031 {
8032 yyextra->fakeNS--;
8033 unput('}');
8034 BEGIN ( ReadNSBody);
8035 }
8036 else
8037 {
8038 yyterminate();
8039 }
8040 }
8041%%
8042
8043//----------------------------------------------------------------------------
8044static int yyread(yyscan_t yyscanner,char *buf,int max_size)
8045{
8046 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8047 int c=0;
8048 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
8049 {
8050 *buf = yyextra->inputString[yyextra->inputPosition++] ;
8051 //printf("%d (%c)\n",*buf,*buf);
8052 c++; buf++;
8053 }
8054 return c;
8055}
8056
8057
8058static void initParser(yyscan_t yyscanner)
8059{
8060 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8061 yyextra->outerScopeEntries.clear();
8062 yyextra->baseName.clear();
8063 yyextra->protection = Protection::Public;
8064 yyextra->baseProt = Protection::Public;
8065 yyextra->sharpCount = 0;
8066 yyextra->roundCount = 0;
8067 yyextra->curlyCount = 0;
8068 yyextra->mtype = MethodTypes::Method;
8069 yyextra->isStatic = false;
8070 yyextra->virt = Specifier::Normal;
8071 yyextra->baseVirt = Specifier::Normal;
8072 yyextra->isTypedef = false;
8073 yyextra->insideTryBlock = false;
8074 yyextra->insideFormula = false;
8075 yyextra->insideCode=false;
8076 yyextra->insideCli=Config_getBool(CPP_CLI_SUPPORT);
8077 yyextra->previous = 0;
8078 yyextra->firstTypedefEntry.reset();
8079 yyextra->memspecEntry.reset();
8080}
8081
8082static void initEntry(yyscan_t yyscanner)
8083{
8084 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8085 if (yyextra->insideJava)
8086 {
8087 yyextra->protection = (yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isEnum()) ? Protection::Public : Protection::Package;
8088 }
8089 yyextra->current->protection = yyextra->protection;
8090 yyextra->current->exported = yyextra->exported ;
8091 yyextra->current->mtype = yyextra->mtype;
8092 yyextra->current->virt = yyextra->virt;
8093 yyextra->current->isStatic = yyextra->isStatic;
8094 yyextra->current->lang = yyextra->language;
8095 //printf("*** initEntry(yyscanner) yyextra->language=%d\n",yyextra->language);
8096 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
8097 yyextra->isTypedef=false;
8098}
8099
8100
8101//-----------------------------------------------------------------------------
8102
8103static void storeClangId(yyscan_t yyscanner,const char *id)
8104{
8105 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8106 if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
8107 {
8108 yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,id);
8109 }
8110}
8111
8112static void lineCount(yyscan_t yyscanner)
8113{
8114 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8115 int tabSize = Config_getInt(TAB_SIZE);
8116 const char *p;
8117 for (p = yytext ; *p ; ++p )
8118 {
8119 if (*p=='\n')
8120 {
8121 yyextra->yyLineNr++;
8122 yyextra->column=0;
8123 yyextra->yyColNr=1;
8124 }
8125 else if (*p=='\t')
8126 {
8127 yyextra->column+=tabSize - (yyextra->column%tabSize);
8128 }
8129 else
8130 {
8131 yyextra->column++;
8132 yyextra->yyColNr++;
8133 }
8134 }
8135 //printf("lineCount()=%d\n",yyextra->column);
8136}
8137
8138static inline int computeIndent(const char *s,int startIndent)
8139{
8140 int col=startIndent;
8141 int tabSize=Config_getInt(TAB_SIZE);
8142 const char *p=s;
8143 char c;
8144 while ((c=*p++))
8145 {
8146 if (c=='\t') col+=tabSize-(col%tabSize);
8147 else if (c=='\n') col=0;
8148 else col++;
8149 }
8150 return col;
8151}
8152
8153static inline void initMethodProtection(yyscan_t yyscanner,Protection prot)
8154{
8155 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8156 yyextra->current->protection = yyextra->protection = prot;
8157 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
8158 yyextra->current->type.clear();
8159 yyextra->current->name.clear();
8160 yyextra->current->args.clear();
8161 yyextra->current->argList.clear();
8162 lineCount(yyscanner) ;
8163}
8164
8165static void addType(yyscan_t yyscanner)
8166{
8167 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8168 size_t tl=yyextra->current->type.length();
8169 if( tl>0 && !yyextra->current->name.empty() && yyextra->current->type.at(tl-1)!='.')
8170 {
8171 yyextra->current->type += ' ' ;
8172 }
8173 yyextra->current->type += yyextra->current->name;
8174 yyextra->current->name.clear() ;
8175 tl=yyextra->current->type.length();
8176 if( tl>0 && !yyextra->current->args.empty() && yyextra->current->type.at(tl-1)!='.')
8177 {
8178 yyextra->current->type += ' ' ;
8179 }
8180 yyextra->current->type += yyextra->current->args ;
8181 yyextra->current->args.clear() ;
8182 yyextra->current->argList.clear();
8183}
8184
8185
8186static DString stripQuotes(const char *s)
8187{
8188 DString name;
8189 if (s==nullptr || *s==0) return name;
8190 name=s;
8191 if (name.at(0)=='"' && name.at(name.length()-1)=='"')
8192 {
8193 name=name.mid(1,name.length()-2);
8194 }
8195 return name;
8196}
8197
8198static DString stripFuncPtr(const DString &type)
8199{
8200 // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
8201 // also needed to reset the type for 'arr' to 'int' in 'typedef int (&fp)(), arr[2]'
8202 size_t i=type.length();
8203 bool funcPtr = i>0 && type[i-1]==')';
8204 if (funcPtr) i--;
8205 while (i>0 && (type[i-1]=='*' || type[i-1]=='&' || type[i-1]==' ')) i--;
8206 if (funcPtr && i>0 && type[i-1]=='(') i--;
8207 return type.left(i);
8208}
8209
8210//-----------------------------------------------------------------
8211static void startVerbatimBlock(yyscan_t yyscanner,const DString &blockName,size_t fencedSize,bool codeBlock)
8212{
8213 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8214 if (Config_getBool(MARKDOWN_SUPPORT))
8215 {
8216 yyextra->docBlock << "\\iskip";
8217 }
8218 yyextra->docBlockName=blockName;
8219 yyextra->fencedSize=fencedSize;
8220 yyextra->isCodeBlock=codeBlock;
8221 yyextra->nestedComment=0;
8222}
8223
8224//-----------------------------------------------------------------
8225static bool endVerbatimBlock(yyscan_t yyscanner,const DString &blockName,size_t fencedSize)
8226{
8227 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8228 if (yyextra->docBlockName==blockName && (fencedSize==0 || fencedSize==yyextra->fencedSize))
8229 {
8230 if (Config_getBool(MARKDOWN_SUPPORT))
8231 {
8232 yyextra->docBlock << "\\endiskip";
8233 }
8234 yyextra->docBlockName="";
8235 return true;
8236 }
8237 return false;
8238}
8239
8240//-----------------------------------------------------------------
8241
8242// return true iff req holds the start of a requires expression
8243// or sub-expression without parenthesis, i.e. req is empty or ends with || or &&
8244static bool startOfRequiresExpression(const DString &req)
8245{
8246 DString r = req.stripWhiteSpace();
8247 return r.empty() || r.endsWith("&&") || r.endsWith("||") || r.endsWith("and") || r.endsWith("or");
8248}
8249
8250//-----------------------------------------------------------------
8251
8252static bool nameIsOperator(DString &name)
8253{
8254 size_t i=name.find("operator");
8255 if (i==DString::npos) return false;
8256 if (i==0 && !isId(name.at(8))) return true; // case operator ::X
8257 if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return true; // case X::operator
8258 return false; // case TEXToperatorTEXT
8259}
8260
8261//-----------------------------------------------------------------------------
8262
8263static void setContext(yyscan_t yyscanner)
8264{
8265 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8266 yyextra->language = getLanguageFromFileName(yyextra->fileName);
8267 yyextra->insideIDL = yyextra->language==SrcLangExt::IDL;
8268 yyextra->insideJava = yyextra->language==SrcLangExt::Java;
8269 yyextra->insideCS = yyextra->language==SrcLangExt::CSharp;
8270 yyextra->insideD = yyextra->language==SrcLangExt::D;
8271 yyextra->insidePHP = yyextra->language==SrcLangExt::PHP;
8272 yyextra->insideObjC = yyextra->language==SrcLangExt::ObjC;
8273 yyextra->insideJS = yyextra->language==SrcLangExt::JS;
8274 yyextra->insideSlice = yyextra->language==SrcLangExt::Slice;
8275 yyextra->insideCpp = (yyextra->language==SrcLangExt::Cpp ||
8276 yyextra->language==SrcLangExt::Lex);
8277 //printf("setContext(%s) yyextra->insideIDL=%d yyextra->insideJava=%d yyextra->insideCS=%d "
8278 // "yyextra->insideD=%d yyextra->insidePHP=%d yyextra->insideObjC=%d\n",
8279 // qPrint(yyextra->fileName),yyextra->insideIDL,yyextra->insideJava,yyextra->insideCS,yyextra->insideD,yyextra->insidePHP,yyextra->insideObjC
8280 // );
8281}
8282
8283//-----------------------------------------------------------------------------
8284
8285static void prependScope(yyscan_t yyscanner)
8286{
8287 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8288 if (yyextra->current_root->section.isScope())
8289 {
8290 //printf("--- prependScope %s to %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
8291 yyextra->current->name.prepend(yyextra->current_root->name+"::");
8292 //printf("prependScope #=%d #yyextra->current=%d\n",yyextra->current_root->tArgLists->count(),yyextra->current->tArgLists->count());
8293 for (const ArgumentList &srcAl : yyextra->current_root->tArgLists)
8294 {
8295 yyextra->current->tArgLists.insert(yyextra->current->tArgLists.begin(),srcAl);
8296 }
8297 }
8298}
8299
8300//-----------------------------------------------------------------------------
8301
8302/*! Returns true iff the yyextra->current entry could be a K&R style C function */
8303static bool checkForKnRstyleC(yyscan_t yyscanner)
8304{
8305 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8306 if (!yyextra->fileName.lower().endsWith(".c")) return false; // must be a C file
8307 if (yyextra->current->argList.empty()) return false; // must have arguments
8308 for (const Argument &a : yyextra->current->argList)
8309 {
8310 // in K&R style argument do not have a type, but doxygen expects a type
8311 // so it will think the argument has no name
8312 if (a.type.empty() || !a.name.empty()) return false;
8313 }
8314 return true;
8315}
8316
8317static void setJavaProtection(yyscan_t yyscanner)
8318{
8319 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8320 if (yyextra->insideJava)
8321 {
8322 DString text=yytext;
8323 yyextra->current->protection = Protection::Public;
8324 if (text.find("protected")!=DString::npos)
8325 yyextra->current->protection = Protection::Protected;
8326 else if (text.find("private")!=DString::npos)
8327 yyextra->current->protection = Protection::Private;
8328 else if (text.find("package")!=DString::npos)
8329 yyextra->current->protection = Protection::Package;
8330 }
8331}
8332//-----------------------------------------------------------------------------
8333
8334static void splitKnRArg(yyscan_t yyscanner,DString &oldStyleArgPtr,DString &oldStyleArgName)
8335{
8336 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8337 int si = static_cast<int>(yyextra->current->args.length());
8338 if (yyextra->oldStyleArgType.empty()) // new argument
8339 {
8340 std::string args = yyextra->current->args.str();
8341 static const reg::Ex re(R"(\‍([^)]*\).*)"); // find first (...)
8342 int bi1=-1;
8343 int bi2=-1;
8344 reg::Match match;
8345 if (reg::search(args,match,re))
8346 {
8347 bi1=(int)match.position();
8348 size_t secondMatchStart = match.position()+match.length(); // search again after first match
8349 if (reg::search(args,match,re,secondMatchStart))
8350 {
8351 bi2=(int)match.position();
8352 }
8353 }
8354 char c;
8355 if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
8356 {
8357 int s=bi2+1; // keep opening (
8358 yyextra->oldStyleArgType = yyextra->current->args.left(s);
8359 int i=s;
8360 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
8361 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
8362 s=i;
8363 while (i<si && isId(yyextra->current->args.at(i))) i++;
8364 oldStyleArgName = yyextra->current->args.mid(s,i-s);
8365 yyextra->oldStyleArgType+=yyextra->current->args.mid(i);
8366 }
8367 else if (bi1!=-1) // redundant braces like in "int (*var)"
8368 {
8369 int s=bi1; // strip opening (
8370 yyextra->oldStyleArgType = yyextra->current->args.left(s);
8371 s++;
8372 int i=s+1;
8373 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
8374 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
8375 s=i;
8376 while (i<si && isId(yyextra->current->args.at(i))) i++;
8377 oldStyleArgName = yyextra->current->args.mid(s,i-s);
8378 }
8379 else // normal "int *var"
8380 {
8381 int l=si,i=l-1,j;
8382 // look for start of name in "type *name"
8383 while (i>=0 && isId(yyextra->current->args.at(i))) i--;
8384 j=i+1;
8385 // look for start of *'s
8386 while (i>=0 && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i--;
8387 i++;
8388 if (i!=l)
8389 {
8390 yyextra->oldStyleArgType=yyextra->current->args.left(i);
8391 oldStyleArgPtr=yyextra->current->args.mid(i,j-i);
8392 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
8393 }
8394 else
8395 {
8396 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
8397 }
8398 }
8399 }
8400 else // continuation like *arg2 in "int *args,*arg2"
8401 {
8402 int l=si,j=0;
8403 char c;
8404 while (j<l && ((c=yyextra->current->args.at(j))=='*' || isspace((uint8_t)c))) j++;
8405 if (j>0)
8406 {
8407 oldStyleArgPtr=yyextra->current->args.left(j);
8408 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
8409 }
8410 else
8411 {
8412 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
8413 }
8414 }
8415}
8416
8417//-----------------------------------------------------------------------------
8418
8419/*! Update the argument \a name with additional \a type info. For K&R style
8420 * function the type is found \e after the argument list, so this routine
8421 * in needed to fix up.
8422 */
8423static void addKnRArgInfo(yyscan_t yyscanner,const DString &type,const DString &name,
8424 const DString &brief,const DString &docs)
8425{
8426 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8427 for (Argument &a : yyextra->current->argList)
8428 {
8429 if (a.type==name)
8430 {
8431 a.type=type.stripWhiteSpace();
8432 a.type.stripPrefix("register ");
8433 a.name=name.stripWhiteSpace();
8434 if (!brief.empty() && !docs.empty())
8435 {
8436 a.docs=brief+"\n\n"+docs;
8437 }
8438 else if (!brief.empty())
8439 {
8440 a.docs=brief;
8441 }
8442 else
8443 {
8444 a.docs=docs;
8445 }
8446 }
8447 }
8448}
8449
8450//-----------------------------------------------------------------------------
8451
8453{
8454 for (Argument &a : al)
8455 {
8456 if (!a.type.empty() && a.name.empty())
8457 { // a->type is actually the (typeless) parameter name, so move it
8458 a.name=a.type;
8459 a.type.clear();
8460 }
8461 }
8462}
8463
8464//-----------------------------------------------------------------------------
8465
8466static void startCommentBlock(yyscan_t yyscanner,bool brief)
8467{
8468 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8469 if (brief)
8470 {
8471 yyextra->current->briefFile = yyextra->fileName;
8472 yyextra->current->briefLine = yyextra->yyLineNr;
8473 }
8474 else
8475 {
8476 yyextra->current->docFile = yyextra->fileName;
8477 yyextra->current->docLine = yyextra->yyLineNr;
8478 }
8479}
8480
8481//----------------------------------------------------------------------------
8482
8483static void newEntry(yyscan_t yyscanner)
8484{
8485 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8486 if (yyextra->tempEntry==0) // if temp entry is not 0, it holds yyextra->current,
8487 // and yyextra->current is actually replaced by yyextra->previous which was
8488 // already added to yyextra->current_root, so we should not add it again
8489 // (see bug723314)
8490 {
8491 yyextra->previous = yyextra->current;
8492 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8493 }
8494 else
8495 {
8496 yyextra->previous = yyextra->current;
8497 yyextra->current = yyextra->tempEntry;
8498 yyextra->tempEntry.reset();
8499 }
8500 initEntry(yyscanner);
8501}
8502
8503static void handleCommentBlock(yyscan_t yyscanner,const DString &doc,bool brief)
8504{
8505 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8506 AUTO_TRACE("doc='{}' is_brief={}",Trace::trunc(doc),brief);
8507 bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
8508 if (yyextra->docBlockInBody && hideInBodyDocs) return;
8509 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; // line of block start
8510
8511 // fill in inbodyFile && inbodyLine the first time, see bug 633891
8512 std::shared_ptr<Entry> docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current;
8513 if (yyextra->docBlockInBody && docEntry && docEntry->inbodyLine==-1)
8514 {
8515 docEntry->inbodyFile = yyextra->fileName;
8516 docEntry->inbodyLine = lineNr;
8517 }
8518
8519 int position=0;
8520 bool needsEntry=false;
8521 GuardedSectionStack guards;
8522 Markdown markdown(yyextra->fileName,lineNr);
8523 DString strippedDoc = stripIndentation(doc);
8524 DString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8525 while (yyextra->commentScanner.parseCommentBlock(
8526 yyextra->thisParser,
8527 yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(),
8528 processedDoc, // text
8529 yyextra->fileName, // file
8530 lineNr, // line of block start
8531 yyextra->docBlockInBody ? false : brief, // isBrief
8532 yyextra->docBlockInBody ? false : yyextra->docBlockAutoBrief, // isJavaDocStyle
8533 yyextra->docBlockInBody, // isInBody
8534 yyextra->protection,
8535 position,
8536 needsEntry,
8537 Config_getBool(MARKDOWN_SUPPORT),
8538 &guards
8539 )
8540 )
8541 {
8542 //printf("parseCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8543 if (needsEntry)
8544 {
8545 DString docFile = yyextra->current->docFile;
8546 newEntry(yyscanner);
8547 yyextra->current->docFile = docFile;
8548 yyextra->current->docLine = lineNr;
8549 }
8550 }
8551 if (needsEntry)
8552 {
8553 newEntry(yyscanner);
8554 }
8555
8556 if (yyextra->docBlockTerm)
8557 {
8558 unput(yyextra->docBlockTerm);
8559 yyextra->docBlockTerm=0;
8560 }
8561}
8562
8564{
8565 AUTO_TRACE();
8566 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8567 for (Argument &a : al)
8568 {
8569 AUTO_TRACE_ADD("Param '{}' docs='{}'",a.name,Trace::trunc(a.docs));
8570 if (!a.docs.empty())
8571 {
8572 if (a.name.empty() && a.type == "...") a.name= "...";
8573 int position=0;
8574 bool needsEntry;
8575
8576 // save context
8577 DString orgDoc = yyextra->current->doc;
8578 DString orgBrief = yyextra->current->brief;
8579 int orgDocLine = yyextra->current->docLine;
8580 int orgBriefLine = yyextra->current->briefLine;
8581
8582 yyextra->current->doc.clear();
8583 yyextra->current->brief.clear();
8584
8585 //printf("handleParametersCommentBlock [%s]\n",qPrint(doc));
8586 int lineNr = orgDocLine;
8587 GuardedSectionStack guards;
8588 Markdown markdown(yyextra->fileName,lineNr);
8589 DString strippedDoc = stripIndentation(a.docs);
8590 DString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8591 while (yyextra->commentScanner.parseCommentBlock(
8592 yyextra->thisParser,
8593 yyextra->current.get(),
8594 processedDoc, // text
8595 yyextra->fileName, // file
8596 lineNr,
8597 false,
8598 false,
8599 false,
8600 yyextra->protection,
8601 position,
8602 needsEntry,
8603 Config_getBool(MARKDOWN_SUPPORT),
8604 &guards
8605 )
8606 )
8607 {
8608 //printf("handleParametersCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8609 if (needsEntry) newEntry(yyscanner);
8610 }
8611 if (needsEntry)
8612 {
8613 newEntry(yyscanner);
8614 }
8615 a.docs = yyextra->current->doc;
8616
8617 // restore context
8618 yyextra->current->doc = orgDoc;
8619 yyextra->current->brief = orgBrief;
8620 yyextra->current->docLine = orgDocLine;
8621 yyextra->current->briefLine = orgBriefLine;
8622 }
8623 }
8624}
8625
8626
8627//----------------------------------------------------------------------------
8628
8629static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8630{
8631 AUTO_TRACE("name={}",rt->name);
8632 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8633 for (const auto &ce : rt->children())
8634 {
8635 if (!ce->program.empty())
8636 {
8637 AUTO_TRACE_ADD("compound name='{}' program='{}'",Trace::trunc(ce->name),Trace::trunc(ce->program.str()));
8638 // init scanner state
8639 yyextra->padCount=0;
8640 yyextra->column=0;
8641 yyextra->programStr = ce->program.str();
8642 yyextra->inputString = yyextra->programStr.data();
8643 yyextra->inputPosition = 0;
8644 if (ce->section.isEnum() || ce->spec.isEnum())
8645 BEGIN( FindFields ) ;
8646 else
8647 BEGIN( FindMembers ) ;
8648 yyextra->current_root = ce;
8649 yyextra->fileName = ce->fileName;
8650 //setContext();
8651 yyextra->yyLineNr = ce->bodyLine;
8652 yyextra->yyColNr = ce->bodyColumn;
8653 yyextra->insideObjC = ce->lang==SrcLangExt::ObjC;
8654 //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC);
8655 yyextra->current = std::make_shared<Entry>();
8656 yyextra->isStatic = false;
8657 initEntry(yyscanner);
8658
8659 // deep copy group list from parent (see bug 727732)
8660 bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS);
8661 if (autoGroupNested && !rt->groups.empty() && !ce->section.isEnum() && !ce->spec.isEnum())
8662 {
8663 ce->groups = rt->groups;
8664 }
8665
8666 size_t ni=ce->name.rfind("::");
8667 if (ni==DString::npos) ni=0; else ni+=2;
8668 // set default protection based on the compound type
8669 if ( ce->section.isClass() ) // class
8670 {
8671 if (yyextra->insidePHP || yyextra->insideD || yyextra->insideJS || yyextra->insideIDL || yyextra->insideSlice)
8672 {
8673 yyextra->current->protection = yyextra->protection = Protection::Public ;
8674 }
8675 else if (yyextra->insideJava)
8676 {
8677 yyextra->current->protection = yyextra->protection = (ce->spec.isInterface() || ce->spec.isEnum()) ? Protection::Public : Protection::Package;
8678 }
8679 else if (ce->spec.isInterface() || ce->spec.isRef() || ce->spec.isValue() || ce->spec.isStruct() || ce->spec.isUnion())
8680 {
8681 if (ce->lang==SrcLangExt::ObjC)
8682 {
8683 yyextra->current->protection = yyextra->protection = Protection::Protected ;
8684 }
8685 else
8686 {
8687 yyextra->current->protection = yyextra->protection = Protection::Public ;
8688 }
8689 }
8690 else
8691 {
8692 yyextra->current->protection = yyextra->protection = Protection::Private ;
8693 }
8694 }
8695 else if (ce->section.isEnum() ) // enum
8696 {
8697 yyextra->current->protection = yyextra->protection = ce->protection;
8698 }
8699 else if (!ce->name.empty() && ce->name.at(ni)=='@') // unnamed union or namespace
8700 {
8701 if (ce->section.isNamespace() ) // unnamed namespace
8702 {
8703 yyextra->current->isStatic = yyextra->isStatic = true;
8704 }
8705 yyextra->current->protection = yyextra->protection = ce->protection;
8706 yyextra->current->exported = yyextra->exported = false;
8707 }
8708 else if (ce->section.isNamespace() )
8709 {
8710 yyextra->current->protection = yyextra->protection = Protection::Public ;
8711 yyextra->current->exported = yyextra->exported = ce->exported;
8712 }
8713 else // named struct, union, protocol, category
8714 {
8715 yyextra->current->protection = yyextra->protection = Protection::Public ;
8716 yyextra->current->exported = yyextra->exported = false;
8717 }
8718 yyextra->mtype = MethodTypes::Method;
8719 yyextra->virt = Specifier::Normal;
8720 //printf("name=%s yyextra->current->isStatic=%d yyextra->isStatic=%d\n",qPrint(ce->name),yyextra->current->isStatic,yyextra->isStatic);
8721
8722 //memberGroupId = DOX_NOGROUP;
8723 //memberGroupRelates.clear();
8724 //memberGroupInside.clear();
8725 DString name = ce->name;
8726 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
8727
8728 scannerYYlex(yyscanner);
8729 //forceEndGroup();
8730
8731 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
8732
8733 yyextra->programStr.clear();
8734 ce->program.str(std::string());
8735
8736
8737 //if (depthIf>0)
8738 //{
8739 // warn(yyextra->fileName,yyextra->yyLineNr,"Documentation block ended in the middle of a conditional section!");
8740 //}
8741 }
8742 parseCompounds(yyscanner,ce);
8743 }
8744}
8745
8746static void parseConcepts(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8747{
8748 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8749 for (const auto &ce : rt->children())
8750 {
8751 if (ce->section.isConcept())
8752 {
8753 //printf("*** found concept '%s' value=[[\n%s\n]] line=%d,col=%d\n",
8754 // qPrint(ce->name),qPrint(ce->initializer.str()),ce->startLine,ce->startColumn);
8755 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,ce->name);
8756 // init scanner state
8757 yyextra->padCount =0;
8758 yyextra->column =0;
8759 yyextra->programStr = ce->initializer.str();
8760 yyextra->inputString = yyextra->programStr.data();
8761 yyextra->inputPosition = 0;
8762 yyextra->current_root = ce;
8763 yyextra->fileName = ce->fileName;
8764 yyextra->yyLineNr = ce->bodyLine;
8765 yyextra->yyColNr = ce->bodyColumn;
8766 yyextra->insideObjC = false;
8767 yyextra->current = std::make_shared<Entry>();
8768
8769 // hack to reconstruct what was in the code before the concept expression
8770 DString indent;
8771 indent.fill(' ',std::max(0,ce->startColumn-1));
8772 DString templArgs;
8773 if (!ce->args.empty())
8774 {
8775 templArgs=indent+"template"+ce->args+"\n";
8776 }
8777 yyextra->current->initializer.str(DString(templArgs+indent+"concept "+ce->name+ " =").str());
8778
8779 yyextra->isStatic = false;
8780 initEntry(yyscanner);
8781 yyextra->current->section = EntryType::makeConceptCodePart();
8782 yyextra->current->startLine = yyextra->yyLineNr;
8783 BEGIN( FindConceptParts );
8784 scannerYYlex(yyscanner);
8785 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,ce->name);
8786
8787 }
8788 parseConcepts(yyscanner,ce);
8789 }
8790}
8791
8792//----------------------------------------------------------------------------
8793
8794static void parseMain(yyscan_t yyscanner,
8795 const DString &fileName,
8796 const char *fileBuf,
8797 const std::shared_ptr<Entry> &rt,
8798 ClangTUParser *clangParser)
8799{
8800 AUTO_TRACE("fileName={}",fileName);
8801 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8802 initParser(yyscanner);
8803
8804 yyextra->inputString = fileBuf;
8805 yyextra->inputPosition = 0;
8806 yyextra->column = 0;
8807 scannerYYrestart(nullptr,yyscanner);
8808
8809 //depthIf = 0;
8810 yyextra->protection = Protection::Public;
8811 yyextra->mtype = MethodTypes::Method;
8812 yyextra->isStatic = false;
8813 yyextra->exported = false;
8814 yyextra->virt = Specifier::Normal;
8815 yyextra->current_root = rt;
8816 yyextra->yyLineNr = 1 ;
8817 yyextra->yyBegLineNr = 1;
8818 yyextra->yyBegColNr = 0;
8819 yyextra->anonCount = 0;
8820 yyextra->anonNSCount = 0;
8821 yyextra->fileName = fileName;
8822 yyextra->clangParser = clangParser;
8823 setContext(yyscanner);
8824 rt->lang = yyextra->language;
8825 msg("Parsing file {}...\n",yyextra->fileName);
8826
8827 yyextra->current_root = rt;
8828 initParser(yyscanner);
8829 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
8830 yyextra->current = std::make_shared<Entry>();
8831 //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root);
8832 EntryType sec=guessSection(yyextra->fileName);
8833 if (!sec.isEmpty())
8834 {
8835 yyextra->current->name = yyextra->fileName;
8836 yyextra->current->section = sec;
8837 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8838 }
8839 yyextra->current->reset();
8840 initEntry(yyscanner);
8841 if ( yyextra->insidePHP )
8842 {
8843 BEGIN( FindMembersPHP );
8844 }
8845 else if ( yyextra->insideJava ) // add default java.lang package scope
8846 {
8847 yyextra->current->name="java::lang"; // '::' is used in doxygen's internal representation as a scope separator
8848 yyextra->current->fileName = yyextra->fileName;
8849 yyextra->current->section = EntryType::makeUsingDir();
8850 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8851 initEntry(yyscanner);
8852 BEGIN( FindMembers );
8853 }
8854 else
8855 {
8856 BEGIN( FindMembers );
8857 }
8858
8859 scannerYYlex(yyscanner);
8860
8861 if (YY_START==Comment)
8862 {
8863 warn(yyextra->fileName,yyextra->yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
8864 }
8865
8866 //forceEndGroup();
8867 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
8868
8869 yyextra->programStr.clear();
8870 rt->program.str(std::string());
8871
8872 parseCompounds(yyscanner,rt);
8873 parseConcepts(yyscanner,rt);
8874
8875 yyextra->anonNSCount++;
8876
8877 // add additional entries that were created during processing
8878 for (auto &[parent,child]: yyextra->outerScopeEntries)
8879 {
8880 //printf(">>> adding '%s' to scope '%s'\n",qPrint(child->name),qPrint(parent->name));
8881 parent->moveToSubEntryAndKeep(child);
8882 }
8883 yyextra->outerScopeEntries.clear();
8884
8885}
8886
8887//----------------------------------------------------------------------------
8888
8889static void parsePrototype(yyscan_t yyscanner,const DString &text)
8890{
8891 AUTO_TRACE("text='{}'",Trace::trunc(text));
8892 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8893 if (text.empty())
8894 {
8895 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
8896 return;
8897 }
8898 if (!yyextra->current) // nothing to store (see bug683516)
8899 {
8900 return;
8901 }
8902
8903 const char *orgInputString;
8904 int orgInputPosition;
8905 YY_BUFFER_STATE orgState;
8906
8907 // save scanner state
8908 orgState = YY_CURRENT_BUFFER;
8909 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
8910 orgInputString = yyextra->inputString;
8911 orgInputPosition = yyextra->inputPosition;
8912
8913 // set new string
8914 yyextra->inputString = text.data();
8915 yyextra->inputPosition = 0;
8916 yyextra->column = 0;
8917 scannerYYrestart(nullptr, yyscanner);
8918 BEGIN(Prototype);
8919 scannerYYlex(yyscanner);
8920
8921 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
8922 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.empty())
8923 {
8924 yyextra->current->section = EntryType::makeVariableDoc();
8925 }
8926
8927 // restore original scanner state
8928 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
8929 yy_switch_to_buffer(orgState, yyscanner);
8930 yyextra->inputString = orgInputString;
8931 yyextra->inputPosition = orgInputPosition;
8932
8933
8934 //printf("**** parsePrototype end\n");
8935}
8936
8937//----------------------------------------------------------------------------
8938
8944
8946{
8947 scannerYYlex_init_extra(&p->state,&p->yyscanner);
8948#ifdef FLEX_DEBUG
8949 scannerYYset_debug(Debug::isFlagSet(Debug::Lex_scanner)?1:0,p->yyscanner);
8950#endif
8951}
8952
8954{
8955 scannerYYlex_destroy(p->yyscanner);
8956}
8957
8959 const char *fileBuf,
8960 const std::shared_ptr<Entry> &root,
8961 ClangTUParser *clangParser)
8962{
8963 AUTO_TRACE();
8964 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
8965 yyextra->thisParser = this;
8966
8967 DebugLex debugLex(Debug::Lex_scanner, __FILE__, qPrint(fileName));
8968
8969 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
8970}
8971
8972
8974{
8975 DString fe=extension.lower();
8976 SrcLangExt lang = getLanguageFromFileName(extension);
8977 return (SrcLangExt::Cpp == lang) || (SrcLangExt::Lex == lang) ||
8978 !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
8979 fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5"
8980 );
8981}
8982
8984{
8985 ::parsePrototype(p->yyscanner,text);
8986}
8987
8988//----------------------------------------------------------------------------
8989
8990#include "scanner.l.h"
void parsePrototype(const DString &text) override
Callback function called by the comment block scanner.
Definition scanner.l:8983
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:8973
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:8958
std::unique_ptr< Private > p
Definition scanner.h:46
~COutlineParser() override
Definition scanner.l:8953
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:49
#define AUTO_TRACE(...)
Definition docnode.cpp:48
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1335
const char * qPrint(const char *s)
Definition dstring.h:769
#define msg(fmt,...)
Definition message.h:94
DString trunc(const DString &s, size_t numChars=15)
Definition trace.h:56
Definition dstring.h:879
static void newEntry(yyscan_t yyscanner)
Definition pyscanner.l:1869
static void parseMain(yyscan_t yyscanner, const DString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt)
Definition pyscanner.l:2321
static void parsePrototype(yyscan_t yyscanner, const DString &text)
Definition pyscanner.l:2405
static void parseCompounds(yyscan_t yyscanner, std::shared_ptr< Entry > rt)
Definition pyscanner.l:2265
static void parseMain(yyscan_t yyscanner, const DString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt, ClangTUParser *clangParser)
Definition scanner.l:8794
static void parseConcepts(yyscan_t yyscanner, const std::shared_ptr< Entry > &rt)
Definition scanner.l:8746
DString docs
Definition arguments.h:47
DString name
Definition arguments.h:44
scannerYY_state state
Definition scanner.l:8942
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
Definition util.cpp:5252
DString stripIndentation(const DString &s, bool skipFirstLine)
Definition util.cpp:5987
EntryType guessSection(const DString &name)
Definition util.cpp:338