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