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