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