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