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:8088
static void storeClangId(yyscan_t yyscanner, const char *id)
Definition scanner.l:7993
static void setContext(yyscan_t yyscanner)
Definition scanner.l:8153
static void addKnRArgInfo(yyscan_t yyscanner, const QCString &type, const QCString &name, const QCString &brief, const QCString &docs)
Definition scanner.l:8313
static bool checkForKnRstyleC(yyscan_t yyscanner)
Definition scanner.l:8193
static void startVerbatimBlock(yyscan_t yyscanner, const QCString &blockName, size_t fencedSize=0, bool codeBlock=false)
Definition scanner.l:8101
static void initMethodProtection(yyscan_t yyscanner, Protection prot)
Definition scanner.l:8043
static bool endVerbatimBlock(yyscan_t yyscanner, const QCString &blockName, size_t fencedSize=0)
Definition scanner.l:8115
void fixArgumentListForJavaScript(ArgumentList &al)
Definition scanner.l:8342
static bool startOfRequiresExpression(const QCString &req)
Definition scanner.l:8134
static void handleParametersCommentBlocks(yyscan_t yyscanner, ArgumentList &al)
Definition scanner.l:8453
static void prependScope(yyscan_t yyscanner)
Definition scanner.l:8175
static bool nameIsOperator(QCString &name)
Definition scanner.l:8142
static void setJavaProtection(yyscan_t yyscanner)
Definition scanner.l:8207
static void splitKnRArg(yyscan_t yyscanner, QCString &oldStyleArgPtr, QCString &oldStyleArgName)
Definition scanner.l:8224
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:1254
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:567
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:2894
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:6957
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:6965
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:3562
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:256
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:4974
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:4990
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:4952
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 if (yyextra->insideObjC && !yyextra->current->spec.isProtocol())
6989 {
6990 BEGIN(ClassVar); // allow parsing of ':' for base class
6991 }
6992 else
6993 {
6994 unput('{'); // dummy start body
6995 }
6996 }
6997 else
6998 {
6999 yyless(1);
7000 }
7001 }
7002 else
7003 {
7004 if (*yytext==',' && yyextra->insideObjC) // Begin of protocol list
7005 {
7006 yyextra->insideProtocolList=TRUE;
7007 }
7008 BEGIN(BasesProt);
7009 }
7010 }
7011<Bases>{B}*"{"{B}* {
7012 yyextra->current->program.str(std::string());
7013 yyextra->current->fileName = yyextra->fileName ;
7014 yyextra->current->bodyLine = yyextra->yyLineNr;
7015 yyextra->current->bodyColumn = yyextra->yyColNr;
7016 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
7017 if (!yyextra->baseName.isEmpty())
7018 {
7019 yyextra->current->extends.emplace_back(
7020 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
7021 );
7022 yyextra->baseName.clear();
7023 }
7024 yyextra->curlyCount=0;
7025 if (yyextra->insideObjC)
7026 {
7027 BEGIN( ReadBodyIntf );
7028 }
7029 else
7030 {
7031 BEGIN( ReadBody ) ;
7032 }
7033 }
7034<SkipUnionSwitch>{B}*"(" {
7035 yyextra->roundCount++;
7036 }
7037<SkipUnionSwitch>")" {
7038 if (--yyextra->roundCount==0)
7039 {
7040 BEGIN(ClassVar);
7041 }
7042 }
7043<SkipUnionSwitch>\n { lineCount(yyscanner); }
7044<SkipUnionSwitch>.
7045<Comment>{BN}+ { yyextra->current->program << yytext ;
7046 lineCount(yyscanner) ;
7047 }
7048<Comment>{CCS} { yyextra->current->program << yytext ; }
7049<Comment>{CPPC} { yyextra->current->program << yytext ; }
7050<Comment>{CMD}("code"|"verbatim"|"iliteral") {
7051 if (yyextra->doxygenComment) yyextra->insideCode=TRUE;
7052 yyextra->current->program << yytext ;
7053 }
7054<Comment>{CMD}("endcode"|"endverbatim"|"endiliteral") {
7055 if (yyextra->doxygenComment) yyextra->insideCode=FALSE;
7056 yyextra->current->program << yytext ;
7057 }
7058<Comment>[^ \.\t\r\n\/\*]+ { yyextra->current->program << yytext ; }
7059<Comment>{CCE} { yyextra->current->program << yytext ;
7060 if (!yyextra->insideCode)
7061 {
7062 yyextra->doxygenComment=false;
7063 BEGIN( yyextra->lastContext );
7064 }
7065 }
7066<Comment>. { yyextra->current->program << *yytext ; }
7067
7068<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,SkipC11Inits,SkipC11Attribute,ReadExpressionBody,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"!" {
7069 //printf("Start doc block at %d\n",yyextra->yyLineNr);
7070 if (!yyextra->current->doc.isEmpty())
7071 {
7072 yyextra->current->doc+="\n\n";
7073 }
7074 else
7075 {
7076 yyextra->current->docLine = yyextra->yyLineNr;
7077 yyextra->current->docFile = yyextra->fileName;
7078 }
7079
7080 yyextra->lastDocContext = YY_START;
7081 if (yyextra->current_root->section.isScope())
7082 {
7083 yyextra->current->inside = yyextra->current_root->name+"::";
7084 }
7085 yyextra->docBlockContext = YY_START;
7086 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7087 yyextra->docBlockAutoBrief = Config_getBool(QT_AUTOBRIEF);
7088
7089 QCString indent;
7090 indent.fill(' ',computeIndent(yytext,yyextra->column));
7091 yyextra->docBlock.str(indent.str());
7092
7093 if (yyextra->docBlockAutoBrief)
7094 {
7095 yyextra->current->briefLine = yyextra->yyLineNr;
7096 yyextra->current->briefFile = yyextra->fileName;
7097 }
7098 startCommentBlock(yyscanner,FALSE);
7099 BEGIN( DocBlock );
7100 }
7101<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,ReadExpressionBody,Bases,OldStyleArgs>{CCS}"*"[*]+{BL} {
7102 bool javadocBanner = Config_getBool(JAVADOC_BANNER);
7103 lineCount(yyscanner);
7104
7105 if( javadocBanner )
7106 {
7107 yyextra->lastDocContext = YY_START;
7108
7109 //printf("Found comment banner at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
7110 if (yyextra->current_root->section.isScope())
7111 {
7112 yyextra->current->inside = yyextra->current_root->name+"::";
7113 }
7114 yyextra->current->docLine = yyextra->yyLineNr;
7115 yyextra->current->docFile = yyextra->fileName;
7116 yyextra->docBlockContext = YY_START;
7117 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7118 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
7119 yyextra->docBlockAutoBrief = javadocAutoBrief;
7120
7121 QCString indent;
7122 indent.fill(' ',computeIndent(yytext,yyextra->column));
7123 yyextra->docBlock.str(indent.str());
7124
7125 if (yyextra->docBlockAutoBrief)
7126 {
7127 yyextra->current->briefLine = yyextra->yyLineNr;
7128 yyextra->current->briefFile = yyextra->fileName;
7129 }
7130 startCommentBlock(yyscanner,FALSE);
7131 BEGIN( DocBlock );
7132 }
7133 else
7134 {
7135 yyextra->current->program << yytext ;
7136 yyextra->lastContext = YY_START ;
7137 yyextra->doxygenComment=true;
7138 BEGIN( Comment ) ;
7139 }
7140 }
7141<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,ReadExpressionBody,SkipInits,Bases,OldStyleArgs>^{B}+({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
7142 lineCount(yyscanner);
7143 yyextra->yyColNr=1;
7144 REJECT;
7145 }
7146<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,ReadExpressionBody,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
7147 yyextra->lastDocContext = YY_START;
7148
7149 //printf("Found comment block at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
7150 if (yyextra->current_root->section.isScope())
7151 {
7152 yyextra->current->inside = yyextra->current_root->name+"::";
7153 }
7154 yyextra->current->docLine = yyextra->yyLineNr;
7155 yyextra->current->docFile = yyextra->fileName;
7156 yyextra->docBlockContext = YY_START;
7157 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7158 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
7159 yyextra->docBlockAutoBrief = javadocAutoBrief;
7160
7161 QCString indent;
7162 indent.fill(' ',computeIndent(yytext,yyextra->column));
7163 yyextra->docBlock.str(indent.str());
7164
7165 if (yyextra->docBlockAutoBrief)
7166 {
7167 yyextra->current->briefLine = yyextra->yyLineNr;
7168 yyextra->current->briefFile = yyextra->fileName;
7169 }
7170 startCommentBlock(yyscanner,FALSE);
7171 BEGIN( DocBlock );
7172 }
7173<FindMembers,FindFields,MemberSpec,SkipCurly,ReadExpressionBody,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"!" {
7174 yyextra->lastDocContext = YY_START;
7175 if (yyextra->current_root->section.isScope())
7176 {
7177 yyextra->current->inside = yyextra->current_root->name+"::";
7178 }
7179 yyextra->docBlockContext = YY_START;
7180 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7181 yyextra->docBlockAutoBrief = FALSE;
7182
7183 QCString indent;
7184 indent.fill(' ',computeIndent(yytext,yyextra->column));
7185 yyextra->docBlock.str(indent.str());
7186
7187 startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
7188 BEGIN( DocLine );
7189 }
7190<FindMembers,FindFields,MemberSpec,SkipCurly,ReadExpressionBody,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"/"/[^/] {
7191 yyextra->lastDocContext = YY_START;
7192 if (yyextra->current_root->section.isScope())
7193 {
7194 yyextra->current->inside = yyextra->current_root->name+"::";
7195 }
7196 yyextra->docBlockContext = YY_START;
7197 yyextra->docBlockInBody = YY_START==SkipCurly || YY_START==ReadExpressionBody;
7198 yyextra->docBlockAutoBrief = FALSE;
7199 QCString indent;
7200 indent.fill(' ',computeIndent(yytext,yyextra->column));
7201 yyextra->docBlock.str(indent.str());
7202 startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
7203 BEGIN( DocLine );
7204 }
7205<FindMembers>"extern"{BN}*"\""[^\"]+"\""{BN}*("{")? {
7206 lineCount(yyscanner);
7207 yyextra->externLinkage=TRUE;
7208 }
7209<FindMembers>"{" {
7210 if (yyextra->externLinkage)
7211 {
7212 yyextra->externLinkage=FALSE;
7213 }
7214 else if (yyextra->insideCS &&
7215 !yyextra->current->name.isEmpty() &&
7216 !yyextra->current->type.isEmpty())
7217 {
7218 if (yyextra->current->mtype == MethodTypes::Event)
7219 {
7220 yyextra->mtype = MethodTypes::Event;
7221 }
7222 else if (containsWord(yyextra->current->type,"event")) // event
7223 {
7224 yyextra->current->mtype = yyextra->mtype = MethodTypes::Event;
7225 }
7226 else // property
7227 {
7228 yyextra->current->mtype = yyextra->mtype = MethodTypes::Property;
7229 }
7230 yyextra->current->bodyLine = yyextra->yyLineNr;
7231 yyextra->current->bodyColumn = yyextra->yyColNr;
7232 yyextra->curlyCount=0;
7233 BEGIN( CSAccessorDecl );
7234 }
7235 else if (yyextra->insideIDL && yyextra->current->spec.isAttribute())
7236 {
7237 // UNO IDL: attributes may have setter and getter
7238 // exception specifications
7239 yyextra->current->exception = " {";
7240 BEGIN(UNOIDLAttributeBlock);
7241 }
7242 else
7243 {
7244 if ((yyextra->insideJava || yyextra->insideCS || yyextra->insideD) &&
7245 yyextra->current->name.isEmpty()
7246 )
7247 {
7248 // static Java initializer
7249 yyextra->needsSemi = FALSE;
7250 if (yyextra->current->isStatic)
7251 {
7252 yyextra->current->name="[static initializer]";
7253 yyextra->current->type.clear();
7254 }
7255 else
7256 {
7257 yyextra->current->name="[instance initializer]";
7258 }
7259 unput(*yytext);
7260 BEGIN( SFunction );
7261 }
7262 else
7263 {
7264 // pre C++11 code -> ignore the initializer
7265 //yyextra->needsSemi = TRUE;
7266 //yyextra->current->type.clear();
7267 //yyextra->current->name.clear();
7268 //yyextra->current->args.clear();
7269 //yyextra->current->argList.clear();
7270 //yyextra->curlyCount=0;
7271 //BEGIN( SkipCurlyBlock );
7272
7273 // C++11 style initializer list
7274 yyextra->current->bodyLine = yyextra->yyLineNr;
7275 yyextra->current->bodyColumn = yyextra->yyColNr;
7276 yyextra->current->initializer.str(yytext);
7277 yyextra->lastInitializerContext = YY_START;
7278 yyextra->sharpCount=0;
7279 yyextra->initBracketCount=1;
7280 BEGIN(ReadInitializer);
7281 }
7282 }
7283 }
7284<CSAccessorDecl>"{" { yyextra->curlyCount++; }
7285<CSAccessorDecl>"}"{B}*"=" {
7286 // fall back to next rule if it's not the right bracket
7287 if (yyextra->curlyCount != 0) REJECT;
7288 yyextra->current->initializer.str("=");
7289 yyextra->current->endBodyLine=yyextra->yyLineNr;
7290 yyextra->lastInitializerContext = FindMembers;
7291 BEGIN(ReadInitializer);
7292 }
7293<CSAccessorDecl>"}" {
7294 if (yyextra->curlyCount)
7295 {
7296 yyextra->curlyCount--;
7297 }
7298 else
7299 {
7300 yyextra->mtype = MethodTypes::Method;
7301 yyextra->virt = Specifier::Normal;
7302 // not really important, but while we are at it
7303 yyextra->current->endBodyLine=yyextra->yyLineNr;
7304 unput(';');
7305 BEGIN(FindMembers);
7306 }
7307 }
7308<CSAccessorDecl>"private "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateSettable(true); }
7309<CSAccessorDecl>"protected "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedSettable(true); }
7310<CSAccessorDecl>"private "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateGettable(true); }
7311<CSAccessorDecl>"protected "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedGettable(true); }
7312<CSAccessorDecl>"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setSettable(true); }
7313<CSAccessorDecl>"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setGettable(true); }
7314<CSAccessorDecl>"add" { if (yyextra->curlyCount==0) yyextra->current->spec.setAddable(true); }
7315<CSAccessorDecl>"remove" { if (yyextra->curlyCount==0) yyextra->current->spec.setRemovable(true); }
7316<CSAccessorDecl>"raise" { if (yyextra->curlyCount==0) yyextra->current->spec.setRaisable(true); }
7317<CSAccessorDecl>{CHARLIT} {}
7318<CSAccessorDecl>"\"" { BEGIN(CSString);}
7319<CSAccessorDecl>"." {}
7320<CSAccessorDecl>\n { lineCount(yyscanner); }
7321<CSString>"\"" { BEGIN(CSAccessorDecl);}
7322<CSString>{CPPC} {} // Otherwise the rule <*>"//" will kick in
7323<CSString>{CCS} {} // Otherwise the rule <*>"/*" will kick in
7324<CSString>\n { lineCount(yyscanner); }
7325<CSString>"." {}
7326
7327 /* ---- Slice-specific rules ------ */
7328
7329<SliceSequence>{SCOPENAME} {
7330 if (yyextra->current->spec.isLocal())
7331 {
7332 yyextra->current->type = "local ";
7333 }
7334 yyextra->current->type += "sequence<";
7335 yyextra->current->type += yytext;
7336 yyextra->current->type += ">";
7337 }
7338
7339<SliceSequence>{BN}*">"{BN}* {
7340 lineCount(yyscanner);
7341 BEGIN(SliceSequenceName);
7342 }
7343
7344<SliceSequenceName>{ID}{BN}* {
7345 lineCount(yyscanner);
7346 yyextra->current->name = yytext ;
7347 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7348 }
7349
7350<SliceSequenceName>";" {
7351 yyextra->current->section = EntryType::makeVariable();
7352 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7353 initEntry(yyscanner);
7354 BEGIN(FindMembers);
7355 }
7356
7357<SliceDictionary>{SCOPENAME}{BN}*","{BN}*{SCOPENAME} {
7358 lineCount(yyscanner);
7359 if (yyextra->current->spec.isLocal())
7360 {
7361 yyextra->current->type = "local ";
7362 }
7363 yyextra->current->type += "dictionary<";
7364 yyextra->current->type += yytext;
7365 yyextra->current->type += ">";
7366 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
7367 }
7368
7369<SliceDictionary>{BN}*">"{BN}* {
7370 lineCount(yyscanner);
7371 BEGIN(SliceDictionaryName);
7372 }
7373
7374<SliceDictionaryName>{ID}{BN}* {
7375 lineCount(yyscanner);
7376 yyextra->current->name = yytext ;
7377 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7378 }
7379
7380<SliceDictionaryName>";" {
7381 yyextra->current->section = EntryType::makeVariable();
7382 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7383 initEntry(yyscanner);
7384 BEGIN(FindMembers);
7385 }
7386
7387 /**********************************************************************************/
7388 /******************** Documentation block related rules ***************************/
7389 /**********************************************************************************/
7390
7391 /* ---- Single line comments ------ */
7392<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
7393 int markerLen = yytext[yyleng-1]=='<' ? 4 : 3;
7394 yyextra->docBlock << std::string(yytext).substr(0,yyleng-markerLen);
7395 lineCount(yyscanner);
7396 }
7397<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
7398 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7399 BEGIN( yyextra->docBlockContext );
7400 }
7401<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
7402 yyextra->docBlock << yytext;
7403 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7404 BEGIN( yyextra->docBlockContext );
7405 }
7406<DocLine>{NONLopt}/"\n" { // whole line
7407 yyextra->docBlock << yytext;
7408 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7409 BEGIN( yyextra->docBlockContext );
7410 }
7411
7412 /* ---- Comments blocks ------ */
7413
7414<DocBlock>"*"*{CCE} { // end of comment block
7415 handleCommentBlock(yyscanner,yyextra->docBlock.str(),FALSE);
7416 BEGIN(yyextra->docBlockContext);
7417 }
7418<DocBlock>"\\ilinebr "{B}*"*"/[^/] {
7419 QCString indent;
7420 indent.fill(' ',computeIndent(yytext+8,yyextra->column));
7421 yyextra->docBlock << "\\ilinebr " << indent;
7422 }
7423<DocBlock>^{B}*"*"+/[^/] {
7424 QCString indent;
7425 indent.fill(' ',computeIndent(yytext,yyextra->column));
7426 yyextra->docBlock << indent;
7427 }
7428<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
7429 QCString indent;
7430 indent.fill(' ',computeIndent(yytext,yyextra->column));
7431 yyextra->docBlock << indent;
7432 }
7433<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
7434 }
7435<DocBlock>{CPPC} { // slashes in the middle of a comment block
7436 yyextra->docBlock << yytext;
7437 }
7438<DocBlock>{CCS} { // start of a new comment in the
7439 // middle of a comment block
7440 yyextra->docBlock << yytext;
7441 }
7442<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
7443 yyextra->docBlock << yytext;
7444 }
7445<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
7446 yyextra->docBlock << yytext;
7447 char blockName[] = "f$";
7448 char c = yytext[2];
7449 if (c=='[') blockName[1]=']';
7450 else if (c=='{') blockName[1]='}';
7451 else if (c=='(') blockName[1]=')';
7452 startVerbatimBlock(yyscanner,blockName);
7453 BEGIN(DocCopyBlock);
7454 }
7455<DocBlock>{CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
7456 yyextra->fileName = &yytext[6];
7457 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7458 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
7459 yyextra->docBlock << yytext;
7460 }
7461<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
7462 yyextra->fileName = &yytext[6];
7463 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7464 yyextra->docBlock << yytext;
7465 }
7466<DocBlock>{CMD}"iline"{LINENR}{B} {
7467 bool ok = false;
7468 int nr = QCString(&yytext[6]).toInt(&ok);
7469 if (!ok)
7470 {
7471 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
7472 }
7473 else
7474 {
7475 yyextra->yyLineNr = nr;
7476 }
7477 yyextra->docBlock << yytext;
7478 }
7479<DocBlock>{B}*"<"{PRE}">" {
7480 yyextra->docBlock << yytext;
7481 startVerbatimBlock(yyscanner,"<pre>");
7482 BEGIN(DocCopyBlock);
7483 }
7484<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7485 yyextra->docBlock << yytext;
7486 startVerbatimBlock(yyscanner,"uml");
7487 BEGIN(DocCopyBlock);
7488 }
7489<DocBlock>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7490 yyextra->docBlock << yytext;
7491 startVerbatimBlock(yyscanner,&yytext[1]);
7492 BEGIN(DocCopyBlock);
7493 }
7494<DocBlock>{CMD}("code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7495 yyextra->docBlock << yytext;
7496 startVerbatimBlock(yyscanner,&yytext[1],0,true);
7497 BEGIN(DocCopyBlock);
7498 }
7499<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7500 QCString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7501 yyextra->docBlock << "\\ilinebr ";
7502 yyextra->docBlock << pat;
7503 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length(),true);
7504 BEGIN(DocCopyBlock);
7505 }
7506<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7507 QCString pat = substitute(yytext,"*"," ");
7508 yyextra->docBlock << pat;
7509 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length(),true);
7510 BEGIN(DocCopyBlock);
7511 }
7512<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7513<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7514<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]* {
7515 QCString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7516 yyextra->docBlock << "\\ilinebr ";
7517 yyextra->docBlock << pat;
7518 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length(),true);
7519 BEGIN(DocCopyBlock);
7520 }
7521<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7522<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7523<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7524 QCString pat = substitute(yytext,"*"," ");
7525 yyextra->docBlock << pat;
7526 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length(),true);
7527 BEGIN(DocCopyBlock);
7528 }
7529<DocBlock>"```" { // skip ``` if not at the start of a line
7530 yyextra->docBlock << "```";
7531 }
7532<DocBlock>"\\`" { // skip escaped backtick
7533 yyextra->docBlock << yytext;
7534 }
7535<DocBlock>"`"{1,2} {
7536 yyextra->docBlock << yytext;
7537 startVerbatimBlock(yyscanner,yytext,yyleng,true);
7538 BEGIN(DocCopyBlock);
7539 }
7540<DocBlock>{B}*"<"{CODE}">" {
7541 if (yyextra->insideCS)
7542 {
7543 yyextra->docBlock << yytext;
7544 startVerbatimBlock(yyscanner,"<code>",0,true);
7545 BEGIN(DocCopyBlock);
7546 }
7547 else
7548 {
7549 REJECT;
7550 }
7551 }
7552<DocBlock>[^@*~`'\/\\\n]+ { // any character that isn't special
7553 yyextra->docBlock << yytext;
7554 }
7555<DocBlock>\n { // newline
7556 lineCount(yyscanner);
7557 yyextra->docBlock << *yytext;
7558 }
7559<DocBlock>. { // command block
7560 yyextra->docBlock << *yytext;
7561 }
7562
7563 /* ---- Copy verbatim sections ------ */
7564
7565<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
7566 if (endVerbatimBlock(yyscanner,"<pre>"))
7567 {
7568 BEGIN(DocBlock);
7569 }
7570 yyextra->docBlock << yytext;
7571 }
7572<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
7573 if (endVerbatimBlock(yyscanner,"<code>"))
7574 {
7575 BEGIN(DocBlock);
7576 }
7577 yyextra->docBlock << yytext;
7578 }
7579<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
7580 if (endVerbatimBlock(yyscanner,&yytext[1]))
7581 {
7582 BEGIN(DocBlock);
7583 }
7584 yyextra->docBlock << yytext;
7585 }
7586<DocCopyBlock>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
7587 if (endVerbatimBlock(yyscanner,&yytext[4]))
7588 {
7589 BEGIN(DocBlock);
7590 }
7591 yyextra->docBlock << yytext;
7592 }
7593<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
7594 if ((yyextra->docBlockName=="verbatim") || (yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7595 {
7596 REJECT;
7597 }
7598 else
7599 {
7600 QCString indent;
7601 indent.fill(' ',computeIndent(yytext,0));
7602 yyextra->docBlock << indent;
7603 }
7604 }
7605<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
7606 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7607 {
7608 QCString indent;
7609 indent.fill(' ',computeIndent(yytext,0));
7610 yyextra->docBlock << indent;
7611 }
7612 else
7613 {
7614 REJECT;
7615 }
7616 }
7617<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
7618 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7619 {
7620 QCString indent;
7621 indent.fill(' ',computeIndent(yytext,-1));
7622 yyextra->docBlock << indent+"*";
7623 }
7624 else
7625 {
7626 REJECT;
7627 }
7628 }
7629<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
7630 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7631 {
7632 QCString indent;
7633 if (yyextra->nestedComment>0) // keep * it is part of the code
7634 {
7635 indent.fill(' ',computeIndent(yytext,-1));
7636 yyextra->docBlock << indent+"*";
7637 }
7638 else // remove * it is part of the comment block
7639 {
7640 indent.fill(' ',computeIndent(yytext,0));
7641 yyextra->docBlock << indent;
7642 }
7643 }
7644 else
7645 {
7646 REJECT;
7647 }
7648 }
7649<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7650 QCString pat = substitute(yytext,"*"," ");
7651 if (endVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length()))
7652 {
7653 BEGIN(DocBlock);
7654 }
7655 yyextra->docBlock << pat;
7656 }
7657<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7658 QCString pat = substitute(yytext,"*"," ");
7659 if (endVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length()))
7660 {
7661 BEGIN(DocBlock);
7662 }
7663 yyextra->docBlock << pat;
7664 }
7665<DocCopyBlock>"```" { // backtick + end marker
7666 if (yyextra->docBlockName=="``")
7667 {
7668 yyextra->docBlock << "`";
7669 endVerbatimBlock(yyscanner,"``",2);
7670 yyextra->docBlock << "``";
7671 BEGIN(DocBlock);
7672 }
7673 else
7674 {
7675 yyextra->docBlock << yytext;
7676 }
7677 }
7678<DocCopyBlock>"''"/[^a-z_A-Z0-9-] {
7679 if (!Config_getBool(MARKDOWN_STRICT) && endVerbatimBlock(yyscanner,"``",2))
7680 {
7681 BEGIN(DocBlock);
7682 }
7683 yyextra->docBlock << yytext;
7684 }
7685<DocCopyBlock>"'"/[^'a-z_A-Z0-9-] {
7686 if (!Config_getBool(MARKDOWN_STRICT) && endVerbatimBlock(yyscanner,"`",1))
7687 {
7688 BEGIN(DocBlock);
7689 }
7690 yyextra->docBlock << yytext;
7691 }
7692<DocCopyBlock>"`"{1,2} {
7693 if (endVerbatimBlock(yyscanner,yytext,yyleng))
7694 {
7695 BEGIN(DocBlock);
7696 }
7697 yyextra->docBlock << yytext;
7698 }
7699<DocCopyBlock>[^<@/\*\‍]`'~"\$\\\n]+ { // any character that is not special
7700 yyextra->docBlock << yytext;
7701 }
7702<DocCopyBlock>\" {
7703 yyextra->docBlock << yytext;
7704 if (yyextra->docBlockName=="code" || yyextra->docBlockName=="iliteral")
7705 // to support end of comment character sequences inside
7706 // a string literal of a code block, see #6737
7707 {
7708 yyextra->lastStringContext=YY_START;
7709 yyextra->pCopyQuotedGString=&yyextra->docBlock;
7710 yyextra->stopAtInvalidString=true;
7711 BEGIN(CopyGString);
7712 }
7713 }
7714<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
7715 if (yytext[1]=='*') // start comment
7716 {
7717 yyextra->nestedComment++;
7718 }
7719 else if (yytext[0]=='*' && yyextra->nestedComment>0) // end comment
7720 {
7721 yyextra->nestedComment--;
7722 }
7723 else if (yytext[0]=='*' && yyextra->nestedComment==0 && yyextra->isCodeBlock) // end comment without start
7724 {
7725 warn(yyextra->fileName,yyextra->yyLineNr,
7726 "Found end of C comment inside a '{}' block without matching start of the comment!"
7727 " Maybe the end marker for the block is missing?",
7728 yyextra->docBlockName);
7729 BEGIN(DocBlock);
7730 }
7731 yyextra->docBlock << yytext;
7732 }
7733<DocCopyBlock>\n { // newline
7734 yyextra->docBlock << *yytext;
7735 lineCount(yyscanner);
7736 }
7737<DocCopyBlock>. { // any other character
7738 yyextra->docBlock << *yytext;
7739 }
7740<DocCopyBlock><<EOF>> {
7741 warn(yyextra->fileName,yyextra->yyLineNr,
7742 "reached end of file while inside a '{}' block!"
7743 " The command that should end the block seems to be missing!",
7744 yyextra->docBlockName);
7745 yyterminate();
7746 }
7747
7748
7749 /* ------------- Prototype parser -------------- */
7750
7751<Prototype>"operator"{B}*"("{B}*")" {
7752 yyextra->current->name+=yytext;
7753 }
7754<Prototype>"(" {
7755 yyextra->current->args+=*yytext;
7756 yyextra->currentArgumentContext = PrototypeQual;
7757 yyextra->fullArgString = yyextra->current->args;
7758 yyextra->copyArgString = &yyextra->current->args;
7759 BEGIN( ReadFuncArgType ) ;
7760 }
7761<Prototype>"("({ID}"::")*({B}*[&*])+ {
7762 if (yyextra->insidePHP) // reference parameter
7763 {
7764 REJECT;
7765 }
7766 else
7767 {
7768 yyextra->current->type+=yyextra->current->name+yytext;
7769 yyextra->current->name.clear();
7770 BEGIN( PrototypePtr );
7771 }
7772 }
7773<PrototypePtr>{SCOPENAME} {
7774 yyextra->current->name+=yytext;
7775 }
7776<PrototypePtr>"(" {
7777 yyextra->current->args+=*yytext;
7778 yyextra->currentArgumentContext = PrototypeQual;
7779 yyextra->fullArgString = yyextra->current->args;
7780 yyextra->copyArgString = &yyextra->current->args;
7781 BEGIN( ReadFuncArgType ) ;
7782 }
7783<PrototypePtr>")" {
7784 yyextra->current->type+=')';
7785 BEGIN( Prototype );
7786 }
7787<PrototypePtr>. {
7788 yyextra->current->name+=yytext;
7789 }
7790<PrototypeQual>"{" {
7791 BEGIN( PrototypeSkipLine);
7792 }
7793<PrototypeQual>{B}*"const"{B}* {
7794 yyextra->current->args += " const ";
7795 yyextra->current->argList.setConstSpecifier(TRUE);
7796 }
7797<PrototypeQual>{B}*"volatile"{B}* {
7798 yyextra->current->args += " volatile ";
7799 yyextra->current->argList.setVolatileSpecifier(TRUE);
7800 }
7801<PrototypeQual>{B}*"="{B}*"0"{B}* {
7802 yyextra->current->args += " = 0";
7803 yyextra->current->virt = Specifier::Pure;
7804 yyextra->current->argList.setPureSpecifier(TRUE);
7805 }
7806<PrototypeQual>"throw"{B}*"(" {
7807 yyextra->current->exception = "throw(";
7808 BEGIN(PrototypeExc);
7809 }
7810<PrototypeExc>")" {
7811 yyextra->current->exception += ')';
7812 BEGIN(PrototypeQual);
7813 }
7814<PrototypeExc>. {
7815 yyextra->current->exception += *yytext;
7816 }
7817<PrototypeQual>. {
7818 yyextra->current->args += *yytext;
7819 }
7820<Prototype>. {
7821 yyextra->current->name += *yytext;
7822 }
7823<PrototypeSkipLine>. {
7824 }
7825
7826
7827
7828
7829<SkipCxxComment>.*"\\\n" { // line continuation
7830 if (yyextra->insideCS)
7831 {
7832 REJECT;
7833 }
7834 else
7835 {
7836 lineCount(yyscanner);
7837 }
7838 }
7839<SkipCxxComment>{ANYopt}/\n {
7840 BEGIN( yyextra->lastCContext ) ;
7841 }
7842<SkipComment>[^\*\n]+
7843
7844 /* ------------ Generic rules -------------- */
7845
7846<*>"[[" { // C++11 attribute
7847 if (!yyextra->insideCpp) REJECT;
7848 if (YY_START == CopyGString || YY_START == CopyGString) REJECT;
7849 yyextra->lastC11AttributeContext = YY_START;
7850 BEGIN( SkipC11Attribute );
7851 }
7852
7853<*>\n { lineCount(yyscanner); }
7854<*>\" {
7855 if (yyextra->insideIDL && yyextra->insideCppQuote)
7856 {
7857 BEGIN(EndCppQuote);
7858 }
7859 else if (yyextra->insidePHP)
7860 {
7861 yyextra->lastStringContext=YY_START;
7862 BEGIN(SkipString);
7863 }
7864 }
7865<*>^{B}*"#" {
7866 if (!yyextra->insidePHP)
7867 {
7868 yyextra->lastCPPContext = YY_START;
7869 BEGIN( SkipCPP ) ;
7870 }
7871 else
7872 {
7873 yyextra->lastCContext = YY_START ;
7874 BEGIN( SkipCxxComment ) ;
7875 }
7876 }
7877<*>"#" {
7878 if (!yyextra->insidePHP)
7879 REJECT;
7880 yyextra->lastCContext = YY_START ;
7881 BEGIN( SkipCxxComment ) ;
7882 }
7883<*>\' {
7884 if (yyextra->insidePHP)
7885 {
7886 yyextra->lastStringContext=YY_START;
7887 BEGIN(SkipPHPString);
7888 }
7889 }
7890<*>\? {
7891 if (yyextra->insideCS && (YY_START != SkipRound) && (YY_START != CSAccessorDecl))
7892 {
7893 if (yyextra->current->type.isEmpty())
7894 {
7895 if (yyextra->current->name.isEmpty())
7896 yyextra->current->name="?";
7897 else
7898 yyextra->current->name+="?";
7899 }
7900 else
7901 {
7902 yyextra->current->type+="?";
7903 }
7904 }
7905 }
7906<*>"}" { yyextra->exported=false; }
7907<*>.
7908<SkipComment>{CPPC}|{CCS}
7909<*>{CCS} { yyextra->lastCContext = YY_START ;
7910 BEGIN( SkipComment ) ;
7911 }
7912<SkipComment>{B}*{CCE} { BEGIN( yyextra->lastCContext ) ; }
7913<*>{CPPC} {
7914 yyextra->lastCContext = YY_START ;
7915 BEGIN( SkipCxxComment ) ;
7916 }
7917<<EOF>> {
7918 if (yyextra->insideCS && yyextra->fakeNS)
7919 {
7920 yyextra->fakeNS--;
7921 unput('}');
7922 BEGIN ( ReadNSBody);
7923 }
7924 else
7925 {
7926 yyterminate();
7927 }
7928 }
7929%%
7930
7931//----------------------------------------------------------------------------
7932static int yyread(yyscan_t yyscanner,char *buf,int max_size)
7933{
7934 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7935 int c=0;
7936 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
7937 {
7938 *buf = yyextra->inputString[yyextra->inputPosition++] ;
7939 //printf("%d (%c)\n",*buf,*buf);
7940 c++; buf++;
7941 }
7942 return c;
7943}
7944
7945
7946static void initParser(yyscan_t yyscanner)
7947{
7948 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7949 yyextra->outerScopeEntries.clear();
7950 yyextra->baseName.clear();
7951 yyextra->protection = Protection::Public;
7952 yyextra->baseProt = Protection::Public;
7953 yyextra->sharpCount = 0;
7954 yyextra->roundCount = 0;
7955 yyextra->curlyCount = 0;
7956 yyextra->mtype = MethodTypes::Method;
7957 yyextra->isStatic = FALSE;
7958 yyextra->virt = Specifier::Normal;
7959 yyextra->baseVirt = Specifier::Normal;
7960 yyextra->isTypedef = FALSE;
7961 yyextra->insideTryBlock = FALSE;
7962 yyextra->insideFormula = FALSE;
7963 yyextra->insideCode=FALSE;
7964 yyextra->insideCli=Config_getBool(CPP_CLI_SUPPORT);
7965 yyextra->previous = 0;
7966 yyextra->firstTypedefEntry.reset();
7967 yyextra->memspecEntry.reset();
7968}
7969
7970static void initEntry(yyscan_t yyscanner)
7971{
7972 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7973 if (yyextra->insideJava)
7974 {
7975 yyextra->protection = (yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isEnum()) ? Protection::Public : Protection::Package;
7976 }
7977 yyextra->current->protection = yyextra->protection;
7978 yyextra->current->exported = yyextra->exported ;
7979 yyextra->current->mtype = yyextra->mtype;
7980 yyextra->current->virt = yyextra->virt;
7981 yyextra->current->isStatic = yyextra->isStatic;
7982 yyextra->current->lang = yyextra->language;
7983 //printf("*** initEntry(yyscanner) yyextra->language=%d\n",yyextra->language);
7984 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
7985 yyextra->isTypedef=FALSE;
7986}
7987
7988
7989//-----------------------------------------------------------------------------
7990
7991static void storeClangId(yyscan_t yyscanner,const char *id)
7992{
7993 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7994 if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
7995 {
7996 yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,id);
7997 }
7998}
7999
8000static void lineCount(yyscan_t yyscanner)
8001{
8002 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8003 int tabSize = Config_getInt(TAB_SIZE);
8004 const char *p;
8005 for (p = yytext ; *p ; ++p )
8006 {
8007 if (*p=='\n')
8008 {
8009 yyextra->yyLineNr++;
8010 yyextra->column=0;
8011 yyextra->yyColNr=1;
8012 }
8013 else if (*p=='\t')
8014 {
8015 yyextra->column+=tabSize - (yyextra->column%tabSize);
8016 }
8017 else
8018 {
8019 yyextra->column++;
8020 yyextra->yyColNr++;
8021 }
8022 }
8023 //printf("lineCount()=%d\n",yyextra->column);
8024}
8025
8026static inline int computeIndent(const char *s,int startIndent)
8027{
8028 int col=startIndent;
8029 int tabSize=Config_getInt(TAB_SIZE);
8030 const char *p=s;
8031 char c;
8032 while ((c=*p++))
8033 {
8034 if (c=='\t') col+=tabSize-(col%tabSize);
8035 else if (c=='\n') col=0;
8036 else col++;
8037 }
8038 return col;
8039}
8040
8041static inline void initMethodProtection(yyscan_t yyscanner,Protection prot)
8042{
8043 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8044 yyextra->current->protection = yyextra->protection = prot;
8045 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
8046 yyextra->current->type.clear();
8047 yyextra->current->name.clear();
8048 yyextra->current->args.clear();
8049 yyextra->current->argList.clear();
8050 lineCount(yyscanner) ;
8051}
8052
8053static void addType(yyscan_t yyscanner)
8054{
8055 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8056 size_t tl=yyextra->current->type.length();
8057 if( tl>0 && !yyextra->current->name.isEmpty() && yyextra->current->type.at(tl-1)!='.')
8058 {
8059 yyextra->current->type += ' ' ;
8060 }
8061 yyextra->current->type += yyextra->current->name;
8062 yyextra->current->name.clear() ;
8063 tl=yyextra->current->type.length();
8064 if( tl>0 && !yyextra->current->args.isEmpty() && yyextra->current->type.at(tl-1)!='.')
8065 {
8066 yyextra->current->type += ' ' ;
8067 }
8068 yyextra->current->type += yyextra->current->args ;
8069 yyextra->current->args.clear() ;
8070 yyextra->current->argList.clear();
8071}
8072
8073
8074static QCString stripQuotes(const char *s)
8075{
8077 if (s==nullptr || *s==0) return name;
8078 name=s;
8079 if (name.at(0)=='"' && name.at(name.length()-1)=='"')
8080 {
8081 name=name.mid(1,name.length()-2);
8082 }
8083 return name;
8084}
8085
8086static QCString stripFuncPtr(const QCString &type)
8087{
8088 // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
8089 // also needed to reset the type for 'arr' to 'int' in 'typedef int (&fp)(), arr[2]'
8090 size_t i=type.length();
8091 bool funcPtr = i>0 && type[i-1]==')';
8092 if (funcPtr) i--;
8093 while (i>0 && (type[i-1]=='*' || type[i-1]=='&' || type[i-1]==' ')) i--;
8094 if (funcPtr && i>0 && type[i-1]=='(') i--;
8095 return type.left(i);
8096}
8097
8098//-----------------------------------------------------------------
8099static void startVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize,bool codeBlock)
8100{
8101 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8102 if (Config_getBool(MARKDOWN_SUPPORT))
8103 {
8104 yyextra->docBlock << "\\iskip";
8105 }
8106 yyextra->docBlockName=blockName;
8107 yyextra->fencedSize=fencedSize;
8108 yyextra->isCodeBlock=codeBlock;
8109 yyextra->nestedComment=0;
8110}
8111
8112//-----------------------------------------------------------------
8113static bool endVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize)
8114{
8115 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8116 if (yyextra->docBlockName==blockName && (fencedSize==0 || fencedSize==yyextra->fencedSize))
8117 {
8118 if (Config_getBool(MARKDOWN_SUPPORT))
8119 {
8120 yyextra->docBlock << "\\endiskip";
8121 }
8122 yyextra->docBlockName="";
8123 return true;
8124 }
8125 return false;
8126}
8127
8128//-----------------------------------------------------------------
8129
8130// return TRUE iff req holds the start of a requires expression
8131// or sub-expression without parenthesis, i.e. req is empty or ends with || or &&
8132static bool startOfRequiresExpression(const QCString &req)
8133{
8135 return r.isEmpty() || r.endsWith("&&") || r.endsWith("||") || r.endsWith("and") || r.endsWith("or");
8136}
8137
8138//-----------------------------------------------------------------
8139
8140static bool nameIsOperator(QCString &name)
8141{
8142 int i=name.find("operator");
8143 if (i==-1) return FALSE;
8144 if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X
8145 if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator
8146 return FALSE; // case TEXToperatorTEXT
8147}
8148
8149//-----------------------------------------------------------------------------
8150
8151static void setContext(yyscan_t yyscanner)
8152{
8153 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8154 yyextra->language = getLanguageFromFileName(yyextra->fileName);
8155 yyextra->insideIDL = yyextra->language==SrcLangExt::IDL;
8156 yyextra->insideJava = yyextra->language==SrcLangExt::Java;
8157 yyextra->insideCS = yyextra->language==SrcLangExt::CSharp;
8158 yyextra->insideD = yyextra->language==SrcLangExt::D;
8159 yyextra->insidePHP = yyextra->language==SrcLangExt::PHP;
8160 yyextra->insideObjC = yyextra->language==SrcLangExt::ObjC;
8161 yyextra->insideJS = yyextra->language==SrcLangExt::JS;
8162 yyextra->insideSlice = yyextra->language==SrcLangExt::Slice;
8163 yyextra->insideCpp = (yyextra->language==SrcLangExt::Cpp ||
8164 yyextra->language==SrcLangExt::Lex);
8165 //printf("setContext(%s) yyextra->insideIDL=%d yyextra->insideJava=%d yyextra->insideCS=%d "
8166 // "yyextra->insideD=%d yyextra->insidePHP=%d yyextra->insideObjC=%d\n",
8167 // qPrint(yyextra->fileName),yyextra->insideIDL,yyextra->insideJava,yyextra->insideCS,yyextra->insideD,yyextra->insidePHP,yyextra->insideObjC
8168 // );
8169}
8170
8171//-----------------------------------------------------------------------------
8172
8173static void prependScope(yyscan_t yyscanner)
8174{
8175 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8176 if (yyextra->current_root->section.isScope())
8177 {
8178 //printf("--- prependScope %s to %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
8179 yyextra->current->name.prepend(yyextra->current_root->name+"::");
8180 //printf("prependScope #=%d #yyextra->current=%d\n",yyextra->current_root->tArgLists->count(),yyextra->current->tArgLists->count());
8181 for (const ArgumentList &srcAl : yyextra->current_root->tArgLists)
8182 {
8183 yyextra->current->tArgLists.insert(yyextra->current->tArgLists.begin(),srcAl);
8184 }
8185 }
8186}
8187
8188//-----------------------------------------------------------------------------
8189
8190/*! Returns TRUE iff the yyextra->current entry could be a K&R style C function */
8191static bool checkForKnRstyleC(yyscan_t yyscanner)
8192{
8193 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8194 if (!yyextra->fileName.lower().endsWith(".c")) return FALSE; // must be a C file
8195 if (yyextra->current->argList.empty()) return FALSE; // must have arguments
8196 for (const Argument &a : yyextra->current->argList)
8197 {
8198 // in K&R style argument do not have a type, but doxygen expects a type
8199 // so it will think the argument has no name
8200 if (a.type.isEmpty() || !a.name.isEmpty()) return FALSE;
8201 }
8202 return TRUE;
8203}
8204
8205static void setJavaProtection(yyscan_t yyscanner)
8206{
8207 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8208 if (yyextra->insideJava)
8209 {
8210 QCString text=yytext;
8211 yyextra->current->protection = Protection::Public;
8212 if (text.find("protected")!=-1)
8213 yyextra->current->protection = Protection::Protected;
8214 else if (text.find("private")!=-1)
8215 yyextra->current->protection = Protection::Private;
8216 else if (text.find("package")!=-1)
8217 yyextra->current->protection = Protection::Package;
8218 }
8219}
8220//-----------------------------------------------------------------------------
8221
8222static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName)
8223{
8224 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8225 int si = static_cast<int>(yyextra->current->args.length());
8226 if (yyextra->oldStyleArgType.isEmpty()) // new argument
8227 {
8228 std::string args = yyextra->current->args.str();
8229 static const reg::Ex re(R"(\‍([^)]*\).*)"); // find first (...)
8230 int bi1=-1;
8231 int bi2=-1;
8232 reg::Match match;
8233 if (reg::search(args,match,re))
8234 {
8235 bi1=(int)match.position();
8236 size_t secondMatchStart = match.position()+match.length(); // search again after first match
8237 if (reg::search(args,match,re,secondMatchStart))
8238 {
8239 bi2=(int)match.position();
8240 }
8241 }
8242 char c;
8243 if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
8244 {
8245 int s=bi2+1; // keep opening (
8246 yyextra->oldStyleArgType = yyextra->current->args.left(s);
8247 int i=s;
8248 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
8249 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
8250 s=i;
8251 while (i<si && isId(yyextra->current->args.at(i))) i++;
8252 oldStyleArgName = yyextra->current->args.mid(s,i-s);
8253 yyextra->oldStyleArgType+=yyextra->current->args.mid(i);
8254 }
8255 else if (bi1!=-1) // redundant braces like in "int (*var)"
8256 {
8257 int s=bi1; // strip opening (
8258 yyextra->oldStyleArgType = yyextra->current->args.left(s);
8259 s++;
8260 int i=s+1;
8261 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
8262 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
8263 s=i;
8264 while (i<si && isId(yyextra->current->args.at(i))) i++;
8265 oldStyleArgName = yyextra->current->args.mid(s,i-s);
8266 }
8267 else // normal "int *var"
8268 {
8269 int l=si,i=l-1,j;
8270 // look for start of name in "type *name"
8271 while (i>=0 && isId(yyextra->current->args.at(i))) i--;
8272 j=i+1;
8273 // look for start of *'s
8274 while (i>=0 && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i--;
8275 i++;
8276 if (i!=l)
8277 {
8278 yyextra->oldStyleArgType=yyextra->current->args.left(i);
8279 oldStyleArgPtr=yyextra->current->args.mid(i,j-i);
8280 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
8281 }
8282 else
8283 {
8284 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
8285 }
8286 }
8287 }
8288 else // continuation like *arg2 in "int *args,*arg2"
8289 {
8290 int l=si,j=0;
8291 char c;
8292 while (j<l && ((c=yyextra->current->args.at(j))=='*' || isspace((uint8_t)c))) j++;
8293 if (j>0)
8294 {
8295 oldStyleArgPtr=yyextra->current->args.left(j);
8296 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
8297 }
8298 else
8299 {
8300 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
8301 }
8302 }
8303}
8304
8305//-----------------------------------------------------------------------------
8306
8307/*! Update the argument \a name with additional \a type info. For K&R style
8308 * function the type is found \e after the argument list, so this routine
8309 * in needed to fix up.
8310 */
8311static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name,
8312 const QCString &brief,const QCString &docs)
8314 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8315 for (Argument &a : yyextra->current->argList)
8316 {
8317 if (a.type==name)
8318 {
8319 a.type=type.stripWhiteSpace();
8320 a.type.stripPrefix("register ");
8321 a.name=name.stripWhiteSpace();
8322 if (!brief.isEmpty() && !docs.isEmpty())
8323 {
8324 a.docs=brief+"\n\n"+docs;
8325 }
8326 else if (!brief.isEmpty())
8327 {
8328 a.docs=brief;
8329 }
8330 else
8331 {
8332 a.docs=docs;
8333 }
8334 }
8335 }
8336}
8337
8338//-----------------------------------------------------------------------------
8339
8341{
8342 for (Argument &a : al)
8343 {
8344 if (!a.type.isEmpty() && a.name.isEmpty())
8345 { // a->type is actually the (typeless) parameter name, so move it
8346 a.name=a.type;
8347 a.type.clear();
8348 }
8349 }
8350}
8351
8352//-----------------------------------------------------------------------------
8353
8354static void startCommentBlock(yyscan_t yyscanner,bool brief)
8355{
8356 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8357 if (brief)
8358 {
8359 yyextra->current->briefFile = yyextra->fileName;
8360 yyextra->current->briefLine = yyextra->yyLineNr;
8361 }
8362 else
8363 {
8364 yyextra->current->docFile = yyextra->fileName;
8365 yyextra->current->docLine = yyextra->yyLineNr;
8366 }
8367}
8368
8369//----------------------------------------------------------------------------
8370
8371static void newEntry(yyscan_t yyscanner)
8372{
8373 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8374 if (yyextra->tempEntry==0) // if temp entry is not 0, it holds yyextra->current,
8375 // and yyextra->current is actually replaced by yyextra->previous which was
8376 // already added to yyextra->current_root, so we should not add it again
8377 // (see bug723314)
8378 {
8379 yyextra->previous = yyextra->current;
8380 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8381 }
8382 else
8383 {
8384 yyextra->previous = yyextra->current;
8385 yyextra->current = yyextra->tempEntry;
8386 yyextra->tempEntry.reset();
8387 }
8388 initEntry(yyscanner);
8389}
8390
8391static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief)
8392{
8393 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8394 AUTO_TRACE("doc='{}' is_brief={}",Trace::trunc(doc),brief);
8395 bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
8396 if (yyextra->docBlockInBody && hideInBodyDocs) return;
8397 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; // line of block start
8398
8399 // fill in inbodyFile && inbodyLine the first time, see bug 633891
8400 std::shared_ptr<Entry> docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current;
8401 if (yyextra->docBlockInBody && docEntry && docEntry->inbodyLine==-1)
8402 {
8403 docEntry->inbodyFile = yyextra->fileName;
8404 docEntry->inbodyLine = lineNr;
8405 }
8406
8407 int position=0;
8408 bool needsEntry=FALSE;
8409 GuardedSectionStack guards;
8410 Markdown markdown(yyextra->fileName,lineNr);
8411 QCString strippedDoc = stripIndentation(doc);
8412 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8413 while (yyextra->commentScanner.parseCommentBlock(
8414 yyextra->thisParser,
8415 yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(),
8416 processedDoc, // text
8417 yyextra->fileName, // file
8418 lineNr, // line of block start
8419 yyextra->docBlockInBody ? FALSE : brief, // isBrief
8420 yyextra->docBlockInBody ? FALSE : yyextra->docBlockAutoBrief, // isJavaDocStyle
8421 yyextra->docBlockInBody, // isInBody
8422 yyextra->protection,
8423 position,
8424 needsEntry,
8425 Config_getBool(MARKDOWN_SUPPORT),
8426 &guards
8427 )
8428 )
8429 {
8430 //printf("parseCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8431 if (needsEntry)
8432 {
8433 QCString docFile = yyextra->current->docFile;
8434 newEntry(yyscanner);
8435 yyextra->current->docFile = docFile;
8436 yyextra->current->docLine = lineNr;
8437 }
8438 }
8439 if (needsEntry)
8440 {
8441 newEntry(yyscanner);
8442 }
8443
8444 if (yyextra->docBlockTerm)
8445 {
8446 unput(yyextra->docBlockTerm);
8447 yyextra->docBlockTerm=0;
8448 }
8449}
8450
8451static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al)
8452{
8454 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8455 for (Argument &a : al)
8456 {
8457 AUTO_TRACE_ADD("Param '{}' docs='{}'",a.name,Trace::trunc(a.docs));
8458 if (!a.docs.isEmpty())
8459 {
8460 if (a.name.isEmpty() && a.type == "...") a.name= "...";
8461 int position=0;
8462 bool needsEntry;
8463
8464 // save context
8465 QCString orgDoc = yyextra->current->doc;
8466 QCString orgBrief = yyextra->current->brief;
8467 int orgDocLine = yyextra->current->docLine;
8468 int orgBriefLine = yyextra->current->briefLine;
8469
8470 yyextra->current->doc.clear();
8471 yyextra->current->brief.clear();
8472
8473 //printf("handleParametersCommentBlock [%s]\n",qPrint(doc));
8474 int lineNr = orgDocLine;
8475 GuardedSectionStack guards;
8476 Markdown markdown(yyextra->fileName,lineNr);
8477 QCString strippedDoc = stripIndentation(a.docs);
8478 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8479 while (yyextra->commentScanner.parseCommentBlock(
8480 yyextra->thisParser,
8481 yyextra->current.get(),
8482 processedDoc, // text
8483 yyextra->fileName, // file
8484 lineNr,
8485 FALSE,
8486 FALSE,
8487 FALSE,
8488 yyextra->protection,
8489 position,
8490 needsEntry,
8491 Config_getBool(MARKDOWN_SUPPORT),
8492 &guards
8493 )
8494 )
8495 {
8496 //printf("handleParametersCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8497 if (needsEntry) newEntry(yyscanner);
8498 }
8499 if (needsEntry)
8500 {
8501 newEntry(yyscanner);
8502 }
8503 a.docs = yyextra->current->doc;
8504
8505 // restore context
8506 yyextra->current->doc = orgDoc;
8507 yyextra->current->brief = orgBrief;
8508 yyextra->current->docLine = orgDocLine;
8509 yyextra->current->briefLine = orgBriefLine;
8510 }
8511 }
8512}
8513
8514
8515//----------------------------------------------------------------------------
8516
8517static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8518{
8519 AUTO_TRACE("name={}",rt->name);
8520 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8521 for (const auto &ce : rt->children())
8522 {
8523 if (!ce->program.empty())
8524 {
8525 AUTO_TRACE_ADD("compound name='{}' program='{}'",Trace::trunc(ce->name),Trace::trunc(ce->program.str()));
8526 // init scanner state
8527 yyextra->padCount=0;
8528 yyextra->column=0;
8529 yyextra->programStr = ce->program.str();
8530 yyextra->inputString = yyextra->programStr.data();
8531 yyextra->inputPosition = 0;
8532 if (ce->section.isEnum() || ce->spec.isEnum())
8533 BEGIN( FindFields ) ;
8534 else
8535 BEGIN( FindMembers ) ;
8536 yyextra->current_root = ce;
8537 yyextra->fileName = ce->fileName;
8538 //setContext();
8539 yyextra->yyLineNr = ce->bodyLine;
8540 yyextra->yyColNr = ce->bodyColumn;
8541 yyextra->insideObjC = ce->lang==SrcLangExt::ObjC;
8542 //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC);
8543 yyextra->current = std::make_shared<Entry>();
8544 yyextra->isStatic = FALSE;
8545 initEntry(yyscanner);
8546
8547 // deep copy group list from parent (see bug 727732)
8548 bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS);
8549 if (autoGroupNested && !rt->groups.empty() && !ce->section.isEnum() && !ce->spec.isEnum())
8550 {
8551 ce->groups = rt->groups;
8552 }
8553
8554 int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
8555 // set default protection based on the compound type
8556 if ( ce->section.isClass() ) // class
8557 {
8558 if (yyextra->insidePHP || yyextra->insideD || yyextra->insideJS || yyextra->insideIDL || yyextra->insideSlice)
8559 {
8560 yyextra->current->protection = yyextra->protection = Protection::Public ;
8561 }
8562 else if (yyextra->insideJava)
8563 {
8564 yyextra->current->protection = yyextra->protection = (ce->spec.isInterface() || ce->spec.isEnum()) ? Protection::Public : Protection::Package;
8565 }
8566 else if (ce->spec.isInterface() || ce->spec.isRef() || ce->spec.isValue() || ce->spec.isStruct() || ce->spec.isUnion())
8567 {
8568 if (ce->lang==SrcLangExt::ObjC)
8569 {
8570 yyextra->current->protection = yyextra->protection = Protection::Protected ;
8571 }
8572 else
8573 {
8574 yyextra->current->protection = yyextra->protection = Protection::Public ;
8575 }
8576 }
8577 else
8578 {
8579 yyextra->current->protection = yyextra->protection = Protection::Private ;
8580 }
8581 }
8582 else if (ce->section.isEnum() ) // enum
8583 {
8584 yyextra->current->protection = yyextra->protection = ce->protection;
8585 }
8586 else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
8587 {
8588 if (ce->section.isNamespace() ) // unnamed namespace
8589 {
8590 yyextra->current->isStatic = yyextra->isStatic = TRUE;
8591 }
8592 yyextra->current->protection = yyextra->protection = ce->protection;
8593 yyextra->current->exported = yyextra->exported = false;
8594 }
8595 else if (ce->section.isNamespace() )
8596 {
8597 yyextra->current->protection = yyextra->protection = Protection::Public ;
8598 yyextra->current->exported = yyextra->exported = ce->exported;
8599 }
8600 else // named struct, union, protocol, category
8601 {
8602 yyextra->current->protection = yyextra->protection = Protection::Public ;
8603 yyextra->current->exported = yyextra->exported = false;
8604 }
8605 yyextra->mtype = MethodTypes::Method;
8606 yyextra->virt = Specifier::Normal;
8607 //printf("name=%s yyextra->current->isStatic=%d yyextra->isStatic=%d\n",qPrint(ce->name),yyextra->current->isStatic,yyextra->isStatic);
8608
8609 //memberGroupId = DOX_NOGROUP;
8610 //memberGroupRelates.clear();
8611 //memberGroupInside.clear();
8612 QCString name = ce->name;
8613 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
8614
8615 scannerYYlex(yyscanner);
8616 //forceEndGroup();
8617
8618 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
8619
8620 yyextra->programStr.clear();
8621 ce->program.str(std::string());
8622
8623
8624 //if (depthIf>0)
8625 //{
8626 // warn(yyextra->fileName,yyextra->yyLineNr,"Documentation block ended in the middle of a conditional section!");
8627 //}
8628 }
8629 parseCompounds(yyscanner,ce);
8630 }
8631}
8632
8633static void parseConcepts(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8634{
8635 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8636 for (const auto &ce : rt->children())
8637 {
8638 if (ce->section.isConcept())
8639 {
8640 //printf("*** found concept '%s' value=[[\n%s\n]] line=%d,col=%d\n",
8641 // qPrint(ce->name),qPrint(ce->initializer.str()),ce->startLine,ce->startColumn);
8642 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,ce->name);
8643 // init scanner state
8644 yyextra->padCount =0;
8645 yyextra->column =0;
8646 yyextra->programStr = ce->initializer.str();
8647 yyextra->inputString = yyextra->programStr.data();
8648 yyextra->inputPosition = 0;
8649 yyextra->current_root = ce;
8650 yyextra->fileName = ce->fileName;
8651 yyextra->yyLineNr = ce->bodyLine;
8652 yyextra->yyColNr = ce->bodyColumn;
8653 yyextra->insideObjC = false;
8654 yyextra->current = std::make_shared<Entry>();
8655
8656 // hack to reconstruct what was in the code before the concept expression
8657 QCString indent;
8658 indent.fill(' ',std::max(0,ce->startColumn-1));
8659 QCString templArgs;
8660 if (!ce->args.isEmpty())
8661 {
8662 templArgs=indent+"template"+ce->args+"\n";
8663 }
8664 yyextra->current->initializer.str(QCString(templArgs+indent+"concept "+ce->name+ " =").str());
8665
8666 yyextra->isStatic = FALSE;
8667 initEntry(yyscanner);
8668 yyextra->current->section = EntryType::makeConceptCodePart();
8669 yyextra->current->startLine = yyextra->yyLineNr;
8670 BEGIN( FindConceptParts );
8671 scannerYYlex(yyscanner);
8672 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,ce->name);
8673
8674 }
8675 parseConcepts(yyscanner,ce);
8676 }
8677}
8678
8679//----------------------------------------------------------------------------
8680
8681static void parseMain(yyscan_t yyscanner,
8682 const QCString &fileName,
8683 const char *fileBuf,
8684 const std::shared_ptr<Entry> &rt,
8685 ClangTUParser *clangParser)
8686{
8687 AUTO_TRACE("fileName={}",fileName);
8688 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8689 initParser(yyscanner);
8690
8691 yyextra->inputString = fileBuf;
8692 yyextra->inputPosition = 0;
8693 yyextra->column = 0;
8694 scannerYYrestart(nullptr,yyscanner);
8695
8696 //depthIf = 0;
8697 yyextra->protection = Protection::Public;
8698 yyextra->mtype = MethodTypes::Method;
8699 yyextra->isStatic = FALSE;
8700 yyextra->exported = false;
8701 yyextra->virt = Specifier::Normal;
8702 yyextra->current_root = rt;
8703 yyextra->yyLineNr = 1 ;
8704 yyextra->yyBegLineNr = 1;
8705 yyextra->yyBegColNr = 0;
8706 yyextra->anonCount = 0;
8707 yyextra->anonNSCount = 0;
8708 yyextra->fileName = fileName;
8709 yyextra->clangParser = clangParser;
8710 setContext(yyscanner);
8711 rt->lang = yyextra->language;
8712 msg("Parsing file {}...\n",yyextra->fileName);
8713
8714 yyextra->current_root = rt;
8715 initParser(yyscanner);
8716 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
8717 yyextra->current = std::make_shared<Entry>();
8718 //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root);
8719 EntryType sec=guessSection(yyextra->fileName);
8720 if (!sec.isEmpty())
8721 {
8722 yyextra->current->name = yyextra->fileName;
8723 yyextra->current->section = sec;
8724 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8725 }
8726 yyextra->current->reset();
8727 initEntry(yyscanner);
8728 if ( yyextra->insidePHP )
8729 {
8730 BEGIN( FindMembersPHP );
8731 }
8732 else if ( yyextra->insideJava ) // add default java.lang package scope
8733 {
8734 yyextra->current->name="java::lang"; // '::' is used in doxygen's internal representation as a scope separator
8735 yyextra->current->fileName = yyextra->fileName;
8736 yyextra->current->section = EntryType::makeUsingDir();
8737 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8738 initEntry(yyscanner);
8739 BEGIN( FindMembers );
8740 }
8741 else
8742 {
8743 BEGIN( FindMembers );
8744 }
8745
8746 scannerYYlex(yyscanner);
8747
8748 if (YY_START==Comment)
8749 {
8750 warn(yyextra->fileName,yyextra->yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
8751 }
8752
8753 //forceEndGroup();
8754 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
8755
8756 yyextra->programStr.clear();
8757 rt->program.str(std::string());
8758
8759 parseCompounds(yyscanner,rt);
8760 parseConcepts(yyscanner,rt);
8761
8762 yyextra->anonNSCount++;
8763
8764 // add additional entries that were created during processing
8765 for (auto &[parent,child]: yyextra->outerScopeEntries)
8766 {
8767 //printf(">>> adding '%s' to scope '%s'\n",qPrint(child->name),qPrint(parent->name));
8768 parent->moveToSubEntryAndKeep(child);
8769 }
8770 yyextra->outerScopeEntries.clear();
8771
8772}
8773
8774//----------------------------------------------------------------------------
8775
8776static void parsePrototype(yyscan_t yyscanner,const QCString &text)
8777{
8778 AUTO_TRACE("text='{}'",Trace::trunc(text));
8779 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8780 if (text.isEmpty())
8781 {
8782 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
8783 return;
8784 }
8785 if (!yyextra->current) // nothing to store (see bug683516)
8786 {
8787 return;
8788 }
8789
8790 const char *orgInputString;
8791 int orgInputPosition;
8792 YY_BUFFER_STATE orgState;
8793
8794 // save scanner state
8795 orgState = YY_CURRENT_BUFFER;
8796 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
8797 orgInputString = yyextra->inputString;
8798 orgInputPosition = yyextra->inputPosition;
8799
8800 // set new string
8801 yyextra->inputString = text.data();
8802 yyextra->inputPosition = 0;
8803 yyextra->column = 0;
8804 scannerYYrestart(nullptr, yyscanner);
8805 BEGIN(Prototype);
8806 scannerYYlex(yyscanner);
8807
8808 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
8809 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.isEmpty())
8810 {
8811 yyextra->current->section = EntryType::makeVariableDoc();
8812 }
8813
8814 // restore original scanner state
8815 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
8816 yy_switch_to_buffer(orgState, yyscanner);
8817 yyextra->inputString = orgInputString;
8818 yyextra->inputPosition = orgInputPosition;
8819
8820
8821 //printf("**** parsePrototype end\n");
8822}
8823
8824//----------------------------------------------------------------------------
8825
8827{
8833{
8834 scannerYYlex_init_extra(&p->state,&p->yyscanner);
8835#ifdef FLEX_DEBUG
8836 scannerYYset_debug(Debug::isFlagSet(Debug::Lex_scanner)?1:0,p->yyscanner);
8837#endif
8838}
8839
8841{
8842 scannerYYlex_destroy(p->yyscanner);
8843}
8844
8845void COutlineParser::parseInput(const QCString &fileName,
8846 const char *fileBuf,
8847 const std::shared_ptr<Entry> &root,
8848 ClangTUParser *clangParser)
8849{
8850 AUTO_TRACE();
8851 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
8852 yyextra->thisParser = this;
8853
8854 DebugLex debugLex(Debug::Lex_scanner, __FILE__, qPrint(fileName));
8855
8856 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
8857}
8858
8859
8860bool COutlineParser::needsPreprocessing(const QCString &extension) const
8861{
8862 QCString fe=extension.lower();
8863 SrcLangExt lang = getLanguageFromFileName(extension);
8864 return (SrcLangExt::Cpp == lang) || (SrcLangExt::Lex == lang) ||
8865 !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
8866 fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5"
8867 );
8868}
8869
8871{
8872 ::parsePrototype(p->yyscanner,text);
8873}
8874
8875//----------------------------------------------------------------------------
8876
8877#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:8847
void parsePrototype(const QCString &text) override
Callback function called by the comment block scanner.
Definition scanner.l:8872
std::unique_ptr< Private > p
Definition scanner.h:46
~COutlineParser() override
Definition scanner.l:8842
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:8862
@ 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:8635
QCString name
Definition arguments.h:44
QCString docs
Definition arguments.h:47
scannerYY_state state
Definition scanner.l:8831
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5214
QCString stripIndentation(const QCString &s, bool skipFirstLine)
Definition util.cpp:5972
EntryType guessSection(const QCString &name)
Definition util.cpp:338