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 stateful functions
233static void initParser(yyscan_t yyscanner);
234static void initEntry(yyscan_t yyscanner);
235static void lineCount(yyscan_t yyscanner);
236static void addType(yyscan_t yyscanner);
237static void setContext(yyscan_t yyscanner);
238static void prependScope(yyscan_t yyscanner);
239static void startCommentBlock(yyscan_t yyscanner,bool);
240static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief);
241static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al);
242static bool checkForKnRstyleC(yyscan_t yyscanner);
243static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName);
244static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name,
245 const QCString &brief,const QCString &docs);
246static int yyread(yyscan_t yyscanner,char *buf,int max_size);
247static void setJavaProtection(yyscan_t yyscanner);
248static void storeClangId(yyscan_t yyscanner,const char *id);
249static void startVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize=0);
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:7701
static void storeClangId(yyscan_t yyscanner, const char *id)
Definition scanner.l:7595
static QCString extractBeginRawStringDelimiter(const char *str)
Definition scanner.l:7642
static void startCommentBlock(yyscan_t yyscanner, bool)
Definition scanner.l:7968
static void setContext(yyscan_t yyscanner)
Definition scanner.l:7765
static QCString stripQuotes(const char *s)
Definition scanner.l:7689
static void addKnRArgInfo(yyscan_t yyscanner, const QCString &type, const QCString &name, const QCString &brief, const QCString &docs)
Definition scanner.l:7925
static void initParser(yyscan_t yyscanner)
Definition scanner.l:7550
static bool checkForKnRstyleC(yyscan_t yyscanner)
Definition scanner.l:7805
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition scanner.l:7536
static void initMethodProtection(yyscan_t yyscanner, Protection prot)
Definition scanner.l:7656
static const char * stateToString(int state)
static bool endVerbatimBlock(yyscan_t yyscanner, const QCString &blockName, size_t fencedSize=0)
Definition scanner.l:7727
static QCString extractEndRawStringDelimiter(const char *str)
Definition scanner.l:7650
void fixArgumentListForJavaScript(ArgumentList &al)
Definition scanner.l:7954
static void startVerbatimBlock(yyscan_t yyscanner, const QCString &blockName, size_t fencedSize=0)
Definition scanner.l:7714
static int computeIndent(const char *s, int startIndent)
Definition scanner.l:7627
static bool startOfRequiresExpression(const QCString &req)
Definition scanner.l:7746
static void handleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
Definition scanner.l:8005
static void handleParametersCommentBlocks(yyscan_t yyscanner, ArgumentList &al)
Definition scanner.l:8065
static void prependScope(yyscan_t yyscanner)
Definition scanner.l:7787
static const char * getLexerFILE()
Definition scanner.l:258
static bool nameIsOperator(QCString &name)
Definition scanner.l:7754
static void setJavaProtection(yyscan_t yyscanner)
Definition scanner.l:7819
static void splitKnRArg(yyscan_t yyscanner, QCString &oldStyleArgPtr, QCString &oldStyleArgName)
Definition scanner.l:7836
static void addType(yyscan_t yyscanner)
Definition scanner.l:7668
static void initEntry(yyscan_t yyscanner)
Definition scanner.l:7574
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:3415
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->sharpCount=0;
2067 yyextra->initBracketCount=0;
2068 storeClangId(yyscanner,yyextra->current->name.data());
2069 BEGIN(ReadInitializer);
2070 }
2071<UsingAlias>";" {
2072 yyextra->current->section = EntryType::makeVariable();
2073 QCString init = yyextra->current->initializer.str();
2074 init.stripPrefix("class ");
2075 init.stripPrefix("struct ");
2076 init = init.stripWhiteSpace();
2077 yyextra->current->type = "typedef "+init;
2078 yyextra->current->args.clear();
2079 yyextra->current->spec.setAlias(true);
2080 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2081 initEntry(yyscanner);
2082 BEGIN(FindMembers);
2083 }
void init()
2084<UsingAlias>. {
2085 yyextra->current->initializer << yytext;
2086 }
2087<UsingAlias>\n {
2088 yyextra->current->initializer << yytext;
2089 lineCount(yyscanner);
2090 }
2091<UsingDirective>{SCOPENAME} { yyextra->current->name=removeRedundantWhiteSpace(yytext);
2092 yyextra->current->fileName = yyextra->fileName;
2093 yyextra->current->section = EntryType::makeUsingDir();
2094 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2095 initEntry(yyscanner);
2096 BEGIN(Using);
2097 }
2098<Using>";" { BEGIN(FindMembers); }
2099<FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl
2100 QCString n=yytext;
2101 addType(yyscanner);
2102 yyextra->current->name=n.left(n.length()-2);
2103 }
2104<FindMembers>{SCOPENAME}{BNopt}/"<" { // Note: this could be a return type!
2105 QCString name = QCString(yytext).stripWhiteSpace();
2106 if (yyextra->insideCpp && name=="import") REJECT; // C++20 module header import
2107 yyextra->roundCount=0;
2108 yyextra->sharpCount=0;
2109 lineCount(yyscanner);
2110 addType(yyscanner);
2111 yyextra->current->name=name;
2112 //yyextra->current->scopeSpec.clear();
2113 // yyextra->currentTemplateSpec = &yyextra->current->scopeSpec;
2114 if (nameIsOperator(yyextra->current->name))
2115 BEGIN( Operator );
2116 else
2117 BEGIN( EndTemplate );
2118 }
2119<FindMemberName>{SCOPENAME}{BNopt}/"<" {
2120 yyextra->sharpCount=0;
2121 yyextra->roundCount=0;
2122 lineCount(yyscanner);
2123 yyextra->current->name+=((QCString)yytext).stripWhiteSpace();
2124 //yyextra->current->memberSpec.clear();
2125 // yyextra->currentTemplateSpec = &yyextra->current->memberSpec;
2126 if (nameIsOperator(yyextra->current->name))
2127 BEGIN( Operator );
2128 else
2129 BEGIN( EndTemplate );
2130 }
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
2131<EndTemplate>"<<<" {
2132 if (!yyextra->insidePHP)
2133 {
2134 REJECT;
2135 }
2136 else
2137 {
2138 yyextra->lastHereDocContext = YY_START;
2139 BEGIN(HereDoc);
2140 }
2141 }
2142<ClassTemplSpec,EndTemplate>("<<"|"<=") {
2143 yyextra->current->name+=yytext;
2144 // *yyextra->currentTemplateSpec+=yytext;
2145 }
2146<EndTemplate>"<" {
2147 if (yyextra->roundCount==0)
2148 {
2149 // *yyextra->currentTemplateSpec+='<';
2150 yyextra->sharpCount++;
2151 }
2152 yyextra->current->name+=yytext;
2153 }
2154<ClassTemplSpec,EndTemplate>">=" {
2155 yyextra->current->name+=yytext;
2156 }
2157<ClassTemplSpec,EndTemplate>(">>") {
2158 if (yyextra->insideJava || yyextra->insideCS || yyextra->insideCli || yyextra->roundCount==0)
2159 {
2160 unput('>');
2161 unput(' ');
2162 unput('>');
2163 }
2164 else
2165 {
2166 yyextra->current->name+=yytext;
2167 }
2168 // *yyextra->currentTemplateSpec+=yytext;
2169 }
2170<EndTemplate>">" {
2171 yyextra->current->name+='>';
2172 // *yyextra->currentTemplateSpec+='>';
2173 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
2174 {
2175 yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
2176 //printf("Found %s\n",qPrint(yyextra->current->name));
2177 BEGIN(FindMembers);
2178 }
2179 }
2180<EndTemplate>">"{BN}*"(" {
2181 lineCount(yyscanner);
2182 yyextra->current->name+='>';
2183 // *yyextra->currentTemplateSpec+='>';
2184 if (yyextra->roundCount==0)
2185 {
2186 --yyextra->sharpCount;
2187 }
2188 if (yyextra->roundCount==0 && yyextra->sharpCount<=0)
2189 {
2190 yyextra->current->bodyLine = yyextra->yyLineNr;
2191 yyextra->current->bodyColumn = yyextra->yyColNr;
2192 yyextra->current->args = "(";
2193 yyextra->currentArgumentContext = FuncQual;
2194 yyextra->fullArgString = yyextra->current->args;
2195 yyextra->copyArgString = &yyextra->current->args;
2196 //printf("Found %s\n",qPrint(yyextra->current->name));
2197 BEGIN( ReadFuncArgType ) ;
2198 }
2199 else
2200 {
2201 yyextra->current->name+="(";
2202 yyextra->roundCount++;
2203 }
2204 }
2205<EndTemplate>">"{BNopt}/"("({BN}*{TSCOPE}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance
2206 lineCount(yyscanner);
2207 yyextra->current->name+='>';
2208 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
2209 {
2210 BEGIN(FindMembers);
2211 }
2212 }
2213<EndTemplate>">"{BNopt}/"::" {
2214 lineCount(yyscanner);
2215 yyextra->current->name+='>';
2216 // *yyextra->currentTemplateSpec+='>';
2217 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
2218 {
2219 BEGIN(FindMemberName);
2220 }
2221 }
2222<ClassTemplSpec,EndTemplate>"(" { yyextra->current->name+=*yytext;
2223 yyextra->roundCount++;
2224 }
2225<ClassTemplSpec,EndTemplate>")" { yyextra->current->name+=*yytext;
2226 if (yyextra->roundCount>0) yyextra->roundCount--;
2227 }
2228<EndTemplate>. {
2229 yyextra->current->name+=*yytext;
2230 // *yyextra->currentTemplateSpec+=*yytext;
2231 }
2232<FindMembers>"define"{BN}*"("{BN}*["'] {
2233 if (yyextra->insidePHP)
2234 {
2235 yyextra->current->bodyLine = yyextra->yyLineNr;
2236 yyextra->current->bodyColumn = yyextra->yyColNr;
2237 BEGIN( DefinePHP );
2238 }
2239 else
2240 REJECT;
2241 }
2242<CopyHereDoc>{ID} { // PHP heredoc
2243 yyextra->delimiter = yytext;
2244 *yyextra->pCopyHereDocGString << yytext;
2245 BEGIN(CopyHereDocEnd);
2246 }
2247<CopyHereDoc>"\""{ID}/"\"" { // PHP quoted heredoc
2248 yyextra->delimiter = &yytext[1];
2249 *yyextra->pCopyHereDocGString << yytext;
2250 BEGIN(CopyHereDocEnd);
2251 }
2252<CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc
2253 yyextra->delimiter = &yytext[1];
2254 *yyextra->pCopyHereDocGString << yytext;
2255 BEGIN(CopyHereDocEnd);
2256 }
2257<HereDoc>{ID} { // PHP heredoc
2258 yyextra->delimiter = yytext;
2259 BEGIN(HereDocEnd);
2260 }
2261<HereDoc>"\""{ID}/"\"" { // PHP quoted heredoc
2262 yyextra->delimiter = &yytext[1];
2263 BEGIN(HereDocEnd);
2264 }
2265<HereDoc>"'"{ID}/"'" { // PHP nowdoc
2266 yyextra->delimiter = &yytext[1];
2267 BEGIN(HereDocEnd);
2268 }
2269<HereDocEnd>^{ID} { // id at start of the line could mark the end of the block
2270 if (yyextra->delimiter==yytext) // it is the end marker
2271 {
2272 BEGIN(yyextra->lastHereDocContext);
2273 }
2274 }
2275<HereDocEnd>. { }
2276<CopyHereDocEnd>^{Bopt}{ID} { // id at start of the line could mark the end of the block
2277 *yyextra->pCopyHereDocGString << yytext;
2278 if (yyextra->delimiter==QCString(yytext).stripWhiteSpace()) // it is the end marker
2279 {
2280 BEGIN(yyextra->lastHereDocContext);
2281 }
2282 }
2283<CopyHereDocEnd>\n {
2284 lineCount(yyscanner);
2285 *yyextra->pCopyHereDocGString << yytext;
2286 }
2287<CopyHereDocEnd>{ID} {
2288 *yyextra->pCopyHereDocGString << yytext;
2289 }
2290<CopyHereDocEnd>. {
2291 *yyextra->pCopyHereDocGString << yytext;
2292 }
2293<FindMembers>"Q_OBJECT"|"Q_GADGET" { // Qt object / gadget macro
2294 }
2295<FindMembers>"Q_PROPERTY" { // Qt property declaration
2296 yyextra->yyBegLineNr = yyextra->yyLineNr;
2297 yyextra->yyBegColNr = yyextra->yyColNr;
2298 yyextra->current->protection = Protection::Public ; // see bug734245 & bug735462
2299 yyextra->current->mtype = yyextra->mtype = MethodTypes::Property;
2300 yyextra->current->type.clear();
2301 BEGIN(QtPropType);
2302 }
2303<QtPropType>"(" { // start of property arguments
2304 }
2305<QtPropAttr>")" { // end of property arguments
2306 unput(';');
2307 BEGIN(FindMembers);
2308 }
2309<QtPropType>{B}+ {
2310 yyextra->current->name+=yytext;
2311 }
2312<QtPropType>"*" {
2313 yyextra->current->type+= yyextra->current->name;
2314 yyextra->current->type+= yytext;
2315 yyextra->current->name="";
2316 }
2317<QtPropType>({TSCOPE}"::")*{TSCOPE} {
2318 yyextra->current->type+= yyextra->current->name;
2319 yyextra->current->name=yytext;
2320 }
2321<QtPropType,QtPropAttr>{B}+"READ"{B}+ {
2322 yyextra->current->spec.setReadable(true);
2323 BEGIN(QtPropRead);
2324 }
2325<QtPropType,QtPropAttr>{B}+"WRITE"{B}+ {
2326 yyextra->current->spec.setWritable(true);
2327 BEGIN(QtPropWrite);
2328 }
2329<QtPropType,QtPropAttr>{B}+"MEMBER"{B}+{ID} | // member property => not supported yet
2330<QtPropType,QtPropAttr>{B}+"RESET"{B}+{ID} | // reset method => not supported yet
2331<QtPropType,QtPropAttr>{B}+"SCRIPTABLE"{B}+{ID} | // scriptable property => not supported yet
2332<QtPropType,QtPropAttr>{B}+"DESIGNABLE"{B}+{ID} | // designable property => not supported yet
2333<QtPropType,QtPropAttr>{B}+"NOTIFY"{B}+{ID} | // notify property => not supported yet
2334<QtPropType,QtPropAttr>{B}+"REVISION"{B}+{ID} | // revision property => not supported yet
2335<QtPropType,QtPropAttr>{B}+"STORED"{B}+{ID} | // stored property => not supported yet
2336<QtPropType,QtPropAttr>{B}+"USER"{B}+{ID} | // user property => not supported yet
2337<QtPropType,QtPropAttr>{B}+"CONSTANT"{B} | // constant property => not supported yet
2338<QtPropType,QtPropAttr>{B}+"FINAL"{B} { // final property => not supported yet
2339 BEGIN(QtPropAttr);
2340 }
2341<QtPropRead>{ID} {
2342 yyextra->current->read = yytext;
2343 BEGIN(QtPropAttr);
2344 }
2345<QtPropWrite>{ID} {
2346 yyextra->current->write = yytext;
2347 BEGIN(QtPropAttr);
2348 }
2349<FindMembers>"friend"{BN}+("class"|"union"|"struct"){BN}+ {
2350 yyextra->current->name=yytext;
2351 lineCount(yyscanner) ;
2352 BEGIN(FindMembers);
2353 }
2354<FindMembers>"requires" { // C++20 requires clause
2355 if (yyextra->insideJava) REJECT;
2356 yyextra->current->req.clear();
2357 yyextra->requiresContext = YY_START;
2358 BEGIN(RequiresClause);
2359 }
2360<RequiresClause>"requires"{BN}*/"{" { // requires requires { ... }
2361 if (yyextra->insideJava) REJECT;
2362 lineCount(yyscanner) ;
2363 yyextra->current->req+=yytext;
2364 BEGIN( RequiresExpression ) ;
2365 }
2366<RequiresClause>"requires"{BN}*"(" { // requires requires(T x) { ... }
2367 if (yyextra->insideJava) REJECT;
2368 lineCount(yyscanner) ;
2369 yyextra->current->req+=yytext;
2370 yyextra->lastRoundContext=RequiresExpression;
2371 yyextra->pCopyRoundString=&yyextra->current->req;
2372 yyextra->roundCount=0;
2373 BEGIN( CopyRound ) ;
2374 }
2375<RequiresExpression>"{" {
2376 yyextra->current->req+=yytext;
2377 yyextra->lastCurlyContext=RequiresClause;
2378 yyextra->pCopyCurlyString=&yyextra->current->req;
2379 yyextra->curlyCount=0;
2380 BEGIN( CopyCurly ) ;
2381 }
2382<RequiresExpression>\n {
2383 yyextra->current->req+=' ';
2384 lineCount(yyscanner);
2385 }
2386<RequiresExpression>. {
2387 yyextra->current->req+=yytext;
2388 }
2389<RequiresClause>"(" { // requires "(A && B)"
2390 yyextra->current->req+=yytext;
2391 yyextra->lastRoundContext=RequiresClause;
2392 yyextra->pCopyRoundString=&yyextra->current->req;
2393 yyextra->roundCount=0;
2394 BEGIN( CopyRound ) ;
2395 }
2396<RequiresClause>{NOTopt}{SCOPENAME}{BNopt}"(" { // "requires func(x)"
2397 if (startOfRequiresExpression(yyextra->current->req))
2398 {
2399 lineCount(yyscanner);
2400 yyextra->current->req+=yytext;
2401 yyextra->lastRoundContext=RequiresClause;
2402 yyextra->pCopyRoundString=&yyextra->current->req;
2403 yyextra->roundCount=0;
2404 BEGIN( CopyRound );
2405 }
2406 else
2407 {
2408 REJECT;
2409 }
2410 }
2411<RequiresClause>{NOTopt}{SCOPENAME}{BNopt}"<" { // "requires C<S,T>"
2412 if (startOfRequiresExpression(yyextra->current->req))
2413 {
2414 lineCount(yyscanner);
2415 yyextra->current->req+=yytext;
2416 yyextra->lastSharpContext=RequiresClause;
2417 yyextra->pCopySharpString=&yyextra->current->req;
2418 yyextra->sharpCount=0;
2419 BEGIN( CopySharp );
2420 }
2421 else
2422 {
2423 REJECT
2424 }
2425 }
2426<RequiresClause>{NOTopt}{SCOPENAME} { // something like "requires true" or "requires !my::value"
2427 if (startOfRequiresExpression(yyextra->current->req))
2428 {
2429 lineCount(yyscanner);
2430 yyextra->current->req=yytext;
2431 BEGIN(yyextra->requiresContext);
2432 }
2433 else
2434 {
2435 REJECT;
2436 }
2437 }
2438<RequiresClause>{NOTopt}"::"{ID} {
2439 lineCount(yyscanner);
2440 yyextra->current->req+=yytext;
2441 }
2442<RequiresClause>"||"|"&&"|"!"|("or"{BN}+)|("and"{BN}+)|("not"{BN}+) { // "requires A || B" or "requires A && B"
2443 lineCount(yyscanner);
2444 yyextra->current->req+=yytext;
2445 }
2446<RequiresClause>{BN}+ {
2447 yyextra->current->req+=' ';
2448 lineCount(yyscanner) ;
2449 }
2450<RequiresClause>. {
2451 unput(*yytext);
2452 yyextra->current->req=yyextra->current->req.simplifyWhiteSpace();
2453 BEGIN(yyextra->requiresContext);
2454 }
2455<FindMembers,FindMemberName>{SCOPENAME} {
2456 storeClangId(yyscanner,yytext);
2457 yyextra->yyBegColNr=yyextra->yyColNr;
2458 yyextra->yyBegLineNr=yyextra->yyLineNr;
2459 lineCount(yyscanner);
2460 if (yyextra->insideIDL && yyleng==9 && qstrcmp(yytext,"cpp_quote")==0)
2461 {
2462 BEGIN(CppQuote);
2463 }
2464 else if ((yyextra->insideIDL || yyextra->insideJava || yyextra->insideD) && yyleng==6 && qstrcmp(yytext,"import")==0)
2465 {
2466 if (yyextra->insideIDL)
2467 BEGIN(IDLImport);
2468 else // yyextra->insideJava or yyextra->insideD
2469 BEGIN(JavaImport);
2470 }
2471 else if (yyextra->insidePHP && qstrcmp(yytext,"use")==0)
2472 {
2473 BEGIN(PHPUse);
2474 }
2475 else if (yyextra->insideJava && qstrcmp(yytext,"package")==0)
2476 {
2477 lineCount(yyscanner);
2478 BEGIN(PackageName);
2479 }
2480 else if (yyextra->insideIDL && qstrcmp(yytext,"case")==0)
2481 {
2482 BEGIN(IDLUnionCase);
2483 }
2484 else if (yyextra->insideTryBlock && qstrcmp(yytext,"catch")==0)
2485 {
2486 yyextra->insideTryBlock=FALSE;
2487 BEGIN(TryFunctionBlock);
2488 }
2489 else if (yyextra->insideCpp && qstrcmp(yytext,"alignas")==0)
2490 {
2491 yyextra->lastAlignAsContext = YY_START;
2492 BEGIN(AlignAs);
2493 }
2494 else if (yyextra->insideJS && qstrcmp(yytext,"var")==0)
2495 { // javascript variable
2496 yyextra->current->type="var";
2497 }
2498 else if (yyextra->insideJS && qstrcmp(yytext,"function")==0)
2499 { // javascript function
2500 yyextra->current->type="function";
2501 }
2502 else if (yyextra->insideCS && qstrcmp(yytext,"this")==0)
2503 {
2504 // C# indexer
2505 addType(yyscanner);
2506 yyextra->current->name="this";
2507 BEGIN(CSIndexer);
2508 }
2509 else if (yyextra->insideCpp && (qstrcmp(yytext,"static_assert")==0 || qstrcmp(yytext,"_Static_assert")==0))
2510 {
2511 // C/C++11 static_assert
2512 BEGIN(StaticAssert);
2513 }
2514 else if (yyextra->insideCpp && qstrcmp(yytext,"decltype")==0)
2515 {
2516 // C++11 decltype(x)
2517 addType(yyscanner);
2518 if (!yyextra->current->type.isEmpty()) yyextra->current->type+=' ';
2519 yyextra->current->type+=yytext;
2520 BEGIN(DeclType);
2521 }
2522 else if (yyextra->insideSlice && qstrcmp(yytext,"optional")==0)
2523 {
2524 if (yyextra->current->type.isEmpty())
2525 {
2526 yyextra->current->type = "optional";
2527 }
2528 else
2529 {
2530 yyextra->current->type += " optional";
2531 }
2532 yyextra->lastModifierContext = YY_START;
2533 BEGIN(SliceOptional);
2534 }
2535 else
2536 {
2537 if (YY_START==FindMembers)
2538 {
2539 addType(yyscanner);
2540 }
2541 bool javaLike = yyextra->insideJava || yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideJS;
2542 if (javaLike && qstrcmp(yytext,"public")==0)
2543 {
2544 yyextra->current->protection = Protection::Public;
2545 }
2546 else if (javaLike && qstrcmp(yytext,"protected")==0)
2547 {
2548 yyextra->current->protection = Protection::Protected;
2549 }
2550 else if ((yyextra->insideCS || yyextra->insideD || yyextra->insidePHP || yyextra->insideJS) && qstrcmp(yytext,"internal")==0)
2551 {
2552 yyextra->current->protection = Protection::Package;
2553 }
2554 else if (javaLike && qstrcmp(yytext,"private")==0)
2555 {
2556 yyextra->current->protection = Protection::Private;
2557 }
2558 else if (javaLike && qstrcmp(yytext,"static")==0)
2559 {
2560 if (YY_START==FindMembers)
2561 yyextra->current->name = yytext;
2562 else
2563 yyextra->current->name += yytext;
2564 yyextra->current->isStatic = TRUE;
2565 }
2566 else
2567 {
2568 if (YY_START==FindMembers)
2569 yyextra->current->name = yytext;
2570 else
2571 yyextra->current->name += yytext;
2572 if (yyextra->current->name.startsWith("static "))
2573 {
2574 yyextra->current->isStatic = TRUE;
2575 yyextra->current->name= yyextra->current->name.mid(7);
2576 }
2577 else if (yyextra->current->name.startsWith("inline "))
2578 {
2579 if (yyextra->current->type.isEmpty())
2580 {
2581 yyextra->current->type="inline";
2582 }
2583 else
2584 {
2585 yyextra->current->type+="inline ";
2586 }
2587 yyextra->current->name= yyextra->current->name.mid(7);
2588 }
2589 else if (yyextra->current->name.startsWith("constexpr "))
2590 {
2591 if (yyextra->current->type.isEmpty())
2592 {
2593 yyextra->current->type="constexpr";
2594 }
2595 else
2596 {
2597 yyextra->current->type+="constexpr ";
2598 }
2599 yyextra->current->name=yyextra->current->name.mid(10);
2600 }
2601 else if (yyextra->current->name.startsWith("consteval "))
2602 {
2603 if (yyextra->current->type.isEmpty())
2604 {
2605 yyextra->current->type="consteval";
2606 }
2607 else
2608 {
2609 yyextra->current->type+="consteval ";
2610 }
2611 yyextra->current->name=yyextra->current->name.mid(10);
2612 }
2613 else if (yyextra->current->name.startsWith("constinit "))
2614 {
2615 if (yyextra->current->type.isEmpty())
2616 {
2617 yyextra->current->type="constinit";
2618 }
2619 else
2620 {
2621 yyextra->current->type+="constinit ";
2622 }
2623 yyextra->current->name=yyextra->current->name.mid(10);
2624 }
2625 else if (yyextra->current->name.startsWith("const "))
2626 {
2627 if (yyextra->current->type.isEmpty())
2628 {
2629 yyextra->current->type="const";
2630 }
2631 else
2632 {
2633 yyextra->current->type+="const ";
2634 }
2635 yyextra->current->name=yyextra->current->name.mid(6);
2636 }
2637 else if (yyextra->current->name.startsWith("volatile "))
2638 {
2639 if (yyextra->current->type.isEmpty())
2640 {
2641 yyextra->current->type="volatile";
2642 }
2643 else
2644 {
2645 yyextra->current->type+="volatile ";
2646 }
2647 yyextra->current->name=yyextra->current->name.mid(9);
2648 }
2649 else if (yyextra->current->name.startsWith("typedef "))
2650 {
2651 if (yyextra->current->type.isEmpty())
2652 {
2653 yyextra->current->type="typedef";
2654 }
2655 else
2656 {
2657 yyextra->current->type+="typedef ";
2658 }
2659 yyextra->current->name=yyextra->current->name.mid(8);
2660 }
2661 }
2662 QCString tmp=yytext;
2663 if (nameIsOperator(tmp))
2664 {
2665 BEGIN( Operator );
2666 }
2667 else
2668 {
2669 yyextra->externLinkage=FALSE; // see bug759247
2670 BEGIN(FindMembers);
2671 }
2672 }
2673 yyextra->current->name = yyextra->current->name.removeWhiteSpace();
2674 }
2675<StaticAssert>"(" {
2676 yyextra->lastSkipRoundContext = FindMembers;
2677 yyextra->roundCount=0;
2678 BEGIN(SkipRound);
2679 }
2680<StaticAssert>{BN}+ { lineCount(yyscanner); }
2681<StaticAssert>. { // variable with static_assert as name?
2682 unput(*yytext);
2683 BEGIN(FindMembers);
2684 }
2685<DeclType>"(" {
2686 yyextra->current->type+=yytext;
2687 yyextra->lastRoundContext=FindMembers;
2688 yyextra->pCopyRoundString=&yyextra->current->type;
2689 yyextra->roundCount=0;
2690 BEGIN(CopyRound);
2691 }
2692<DeclType>{BN}+ { lineCount(yyscanner); }
2693<DeclType>. {
2694 unput(*yytext);
2695 BEGIN(FindMembers);
2696 }
2697<CSIndexer>"["[^\n\]]*"]" {
2698 yyextra->current->name+=removeRedundantWhiteSpace(yytext);
2699 BEGIN(FindMembers);
2700 }
2701<FindMembers>[0-9]{ID} { // some number where we did not expect one
2702 }
2703<FindMembers>"." {
2704 if (yyextra->insideJava || yyextra->insideCS || yyextra->insideD)
2705 {
2706 yyextra->current->name+=".";
2707 }
2708 }
2709<FindMembers>"::" {
2710 yyextra->current->name+=yytext;
2711 }
2712<CppQuote>"("{B}*"\"" {
2713 yyextra->insideCppQuote=TRUE;
2714 BEGIN(FindMembers);
2715 }
2716<IDLUnionCase>"::"
2717<IDLUnionCase>":" { BEGIN(FindMembers); }
2718<IDLUnionCase>\n { lineCount(yyscanner); }
2719<IDLUnionCase>.
2720<TryFunctionBlock>\n { lineCount(yyscanner); }
2721<TryFunctionBlock>"{" {
2722 yyextra->curlyCount=0;
2723 yyextra->lastCurlyContext = TryFunctionBlockEnd ;
2724 BEGIN( SkipCurly );
2725 }
2726<TryFunctionBlock>.
2727<TryFunctionBlockEnd>{BN}*"catch" { lineCount(yyscanner); BEGIN(TryFunctionBlock); // {BN}* added to fix bug 611193
2728 }
2729<TryFunctionBlockEnd>\n { unput(*yytext); // rule added to fix bug id 601138
2730 BEGIN( FindMembers );
2731 }
2732<TryFunctionBlockEnd>. { unput(*yytext);
2733 BEGIN( FindMembers );
2734 }
2735<EndCppQuote>")" {
2736 yyextra->insideCppQuote=FALSE;
2737 BEGIN(FindMembers);
2738 }
2739<FindMembers,FindFields>{B}*"#" { if (yyextra->insidePHP)
2740 REJECT;
2741 yyextra->lastCPPContext = YY_START;
2742 BEGIN( SkipCPP ) ;
2743 }
2744<FindMembers,FindFields>{B}*"#"{B}*"cmakedefine01" |
2745<FindMembers,FindFields>{B}*"#"{B}*("cmake")?"define" {
2746 if (yyextra->insidePHP)
2747 REJECT;
2748 yyextra->current->bodyLine = yyextra->yyLineNr;
2749 yyextra->current->bodyColumn = yyextra->yyColNr;
2750 yyextra->current->fileName = yyextra->fileName;
2751 yyextra->current->startLine = yyextra->yyLineNr;
2752 yyextra->current->startColumn = yyextra->yyColNr;
2753 yyextra->current->type.clear();
2754 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
2755 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2756 yyextra->current->section = EntryType::makeDefine();
2757 yyextra->lastDefineContext = YY_START;
2758 BEGIN( SDefine );
2759 }
2760<FindMembers,ReadBody,ReadNSBody,ReadBodyIntf,SkipCurly,SkipCurlyCpp>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
2761 yyextra->yyLineNr = atoi(&yytext[1]);
2762 //printf("setting line number to %d\n",yyextra->yyLineNr);
2763 yyextra->lastPreLineCtrlContext = YY_START;
2764 if (YY_START==ReadBody ||
2765 YY_START==ReadNSBody ||
2766 YY_START==ReadBodyIntf)
2767 {
2768 yyextra->current->program << yytext;
2769 }
2770 BEGIN( PreLineCtrl );
2771 }
2772<PreLineCtrl>"\""[^\n\"]*"\"" {
2773 yyextra->fileName = stripQuotes(yytext);
2774 if (yyextra->lastPreLineCtrlContext==ReadBody ||
2775 yyextra->lastPreLineCtrlContext==ReadNSBody ||
2776 yyextra->lastPreLineCtrlContext==ReadBodyIntf)
2777 {
2778 yyextra->current->program << yytext;
2779 }
2780 }
static QCString stripQuotes(const char *s)
2781<PreLineCtrl>. {
2782 if (yyextra->lastPreLineCtrlContext==ReadBody ||
2783 yyextra->lastPreLineCtrlContext==ReadNSBody ||
2784 yyextra->lastPreLineCtrlContext==ReadBodyIntf)
2785 {
2786 yyextra->current->program << yytext;
2787 }
2788 }
2789<PreLineCtrl>\n {
2790 if (yyextra->lastPreLineCtrlContext==ReadBody ||
2791 yyextra->lastPreLineCtrlContext==ReadNSBody ||
2792 yyextra->lastPreLineCtrlContext==ReadBodyIntf)
2793 {
2794 yyextra->current->program << yytext;
2795 }
2796 lineCount(yyscanner);
2797 BEGIN( yyextra->lastPreLineCtrlContext );
2798 }
2799<SkipCPP>.
2800<SkipCPP>\\[\r]*"\n"[\r]* { lineCount(yyscanner); }
2801<SkipCPP>[\r]*\n[\r]* { lineCount(yyscanner);
2802 BEGIN( yyextra->lastCPPContext) ;
2803 }
2804<SDefine>{ID}{B}*"(" {
2805 yyextra->current->name = yytext;
2806 yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
2807 yyextra->current->args = "(";
2808 yyextra->current->bodyLine = yyextra->yyLineNr;
2809 yyextra->current->bodyColumn = yyextra->yyColNr;
2810 yyextra->currentArgumentContext = DefineEnd;
2811 yyextra->fullArgString=yyextra->current->args;
2812 yyextra->copyArgString=&yyextra->current->args;
2813 BEGIN( ReadFuncArgType ) ;
2814 }
2815 /*
2816<DefineArg>")" {
2817 //printf("Define with args\n");
2818 yyextra->current->args += ')';
2819 BEGIN( DefineEnd );
2820 }
2821<DefineArg>. {
2822 yyextra->current->args += *yytext;
2823 }
2824 */
2825<SDefine>{ID} {
2826 //printf("Define '%s' without args\n",yytext);
2827 storeClangId(yyscanner,yytext);
2828 yyextra->current->bodyLine = yyextra->yyLineNr;
2829 yyextra->current->bodyColumn = yyextra->yyColNr;
2830 yyextra->current->name = yytext;
2831 BEGIN(DefineEnd);
2832 }
2833<DefineEnd><<EOF>> |
2834<DefineEnd>\n {
2835 //printf("End define: doc=%s docFile=%s docLine=%d\n",qPrint(yyextra->current->doc),qPrint(yyextra->current->docFile),yyextra->current->docLine);
2836 lineCount(yyscanner);
2837 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2838 initEntry(yyscanner);
2839 BEGIN(yyextra->lastDefineContext);
2840 }
2841<DefinePHPEnd>";" {
2842 //printf("End define\n");
2843 yyextra->current->fileName = yyextra->fileName;
2844 yyextra->current->startLine = yyextra->yyLineNr;
2845 yyextra->current->startColumn = yyextra->yyColNr;
2846 yyextra->current->type.clear();
2847 yyextra->current->type = "const";
2848 QCString init = yyextra->current->initializer.str();
2849 init = init.simplifyWhiteSpace();
2850 init = init.left(init.length()-1);
2851 yyextra->current->initializer.str(init.str());
2852 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2853 yyextra->current->section = EntryType::makeVariable();
2854 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2855 initEntry(yyscanner);
2856 BEGIN(FindMembers);
2857 }
2858<DefinePHPEnd>.
2859<DefineEnd>\\[\r]?\n {
2860 lineCount(yyscanner);
2861 yyextra->current->endBodyLine = yyextra->yyLineNr;
2862 }
2863<DefineEnd>\" {
2864 if (yyextra->insideIDL && yyextra->insideCppQuote)
2865 {
2866 BEGIN(EndCppQuote);
2867 }
2868 else
2869 {
2870 yyextra->lastStringContext=DefineEnd;
2871 BEGIN(SkipString);
2872 }
2873 }
2874<DefineEnd>.
2875<DefinePHP>{ID}["']{BN}*","{BN}* {
2876 yyextra->current->name = yytext;
2877 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2878 yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
2879 yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1);
2880 yyextra->current->bodyLine = yyextra->yyLineNr;
2881 yyextra->current->bodyColumn = yyextra->yyColNr;
2882 yyextra->lastRoundContext = DefinePHPEnd;
2883 yyextra->pCopyRoundGString = &yyextra->current->initializer;
2884 yyextra->roundCount = 0;
2885 BEGIN( GCopyRound );
2886 }
2887
2888<FindMembers>[\^%] { // ^ and % are C++/CLI extensions
2889 if (yyextra->insideCli)
2890 {
2891 addType(yyscanner);
2892 yyextra->current->name = yytext ;
2893 }
2894 else
2895 {
2896 REJECT;
2897 }
2898 }
2899<FindMembers>[*&]+ {
2900 yyextra->current->name += yytext ;
2901 addType(yyscanner);
2902 }
2903<FindMembers,MemberSpec,SFunction,NextSemi,EnumBaseType,BitFields,ReadInitializer,ReadInitializerPtr,OldStyleArgs,DefinePHPEnd>";"{BN}*{DCOMM}"<" {
2904 if (yyextra->current->bodyLine==-1)
2905 {
2906 yyextra->current->bodyLine=yyextra->yyLineNr;
2907 yyextra->current->bodyColumn = yyextra->yyColNr;
2908 }
2909 yyextra->docBlockContext = YY_START;
2910 yyextra->docBlockInBody = FALSE;
2911 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2912 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2913
2914 QCString indent;
2915 indent.fill(' ',computeIndent(yytext,yyextra->column));
2916 yyextra->docBlock.str(indent.str());
2917 //printf("indent=%d\n",computeIndent(yytext+1,yyextra->column));
2918 lineCount(yyscanner);
2919
2920 yyextra->docBlockTerm = ';';
2921 if (YY_START==EnumBaseType && yyextra->current->section.isEnum())
2922 {
2923 yyextra->current->bitfields = ":"+yyextra->current->args;
2924 yyextra->current->args.clear();
2925 yyextra->current->section = EntryType::makeVariable();
2926 }
2927 if (yytext[yyleng-3]=='/')
2928 {
2929 startCommentBlock(yyscanner,TRUE);
2930 BEGIN( DocLine );
2931 }
2932 else
2933 {
2934 startCommentBlock(yyscanner,FALSE);
2935 BEGIN( DocBlock );
2936 }
2937 }
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)
2938<MemberSpec,FindFields,FindMembers,NextSemi,EnumBaseType,BitFields,ReadInitializer,ReadInitializerPtr,OldStyleArgs>","{BN}*{DCOMM}"<" {
2939 yyextra->docBlockContext = YY_START;
2940 yyextra->docBlockInBody = FALSE;
2941 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2942 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2943
2944 QCString indent;
2945 indent.fill(' ',computeIndent(yytext,yyextra->column));
2946 yyextra->docBlock.str(indent.str());
2947 lineCount(yyscanner);
2948
2949 yyextra->docBlockTerm = ',';
2950 if (YY_START==EnumBaseType && yyextra->current->section.isEnum())
2951 {
2952 yyextra->current->bitfields = ":"+yyextra->current->args;
2953 yyextra->current->args.clear();
2954 yyextra->current->section = EntryType::makeVariable();
2955 }
2956 if (yytext[yyleng-3]=='/')
2957 {
2958 startCommentBlock(yyscanner,TRUE);
2959 BEGIN( DocLine );
2960 }
2961 else
2962 {
2963 startCommentBlock(yyscanner,FALSE);
2964 BEGIN( DocBlock );
2965 }
2966 }
2967<DefineEnd,FindFields,ReadInitializer,ReadInitializerPtr,OldStyleArgs>{BN}*{DCOMM}"<" {
2968 if (yyextra->current->bodyLine==-1)
2969 {
2970 yyextra->current->bodyLine=yyextra->yyLineNr;
2971 yyextra->current->bodyColumn = yyextra->yyColNr;
2972 }
2973 yyextra->docBlockContext = YY_START;
2974 yyextra->docBlockInBody = FALSE;
2975 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
2976 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
2977 QCString indent;
2978 indent.fill(' ',computeIndent(yytext,yyextra->column));
2979 yyextra->docBlock.str(indent.str());
2980 lineCount(yyscanner);
2981
2982 yyextra->docBlockTerm = 0;
2983 if (yytext[yyleng-3]=='/')
2984 {
2985 startCommentBlock(yyscanner,TRUE);
2986 BEGIN( DocLine );
2987 }
2988 else
2989 {
2990 startCommentBlock(yyscanner,FALSE);
2991 BEGIN( DocBlock );
2992 }
2993 }
2994
2995<FindMembers,FindFields>({CPPC}([!/]){B}*{CMD}"{")|({CCS}([!*]){B}*{CMD}"{") {
2996 //handleGroupStartCommand(yyextra->current->name);
2997 if (yyextra->previous && yyextra->previous->section.isGroupDoc())
2998 {
2999 // link open command to the group defined in the yyextra->previous entry
3000 yyextra->commentScanner.open(yyextra->previous.get(),yyextra->fileName,yyextra->yyLineNr);
3001 }
3002 else
3003 {
3004 // link open command to the yyextra->current entry
3005 yyextra->commentScanner.open(yyextra->current.get(),yyextra->fileName,yyextra->yyLineNr);
3006 }
3007 //yyextra->current = tmp;
3008 initEntry(yyscanner);
3009 if (yytext[1]=='/')
3010 {
3011 if (yytext[2]=='!' || yytext[2]=='/')
3012 {
3013 yyextra->docBlockContext = YY_START;
3014 yyextra->docBlockInBody = FALSE;
3015 yyextra->docBlockAutoBrief = FALSE;
3016 yyextra->docBlock.str(std::string());
3017 yyextra->docBlockTerm = 0;
3018 startCommentBlock(yyscanner,TRUE);
3019 BEGIN(DocLine);
3020 }
3021 else
3022 {
3023 yyextra->lastCContext=YY_START;
3024 BEGIN(SkipCxxComment);
3025 }
3026 }
3027 else
3028 {
3029 if (yytext[2]=='!' || yytext[2]=='*')
3030 {
3031 yyextra->docBlockContext = YY_START;
3032 yyextra->docBlockInBody = FALSE;
3033 yyextra->docBlock.str(std::string());
3034 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
3035 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
3036 yyextra->docBlockTerm = 0;
3037 startCommentBlock(yyscanner,FALSE);
3038 BEGIN(DocBlock);
3039 }
3040 else
3041 {
3042 yyextra->lastCContext=YY_START;
3043 BEGIN(SkipComment);
3044 }
3045 }
3046 }
3047<FindMembers,FindFields,ReadInitializer,ReadInitializerPtr>{CPPC}([!/]){B}*{CMD}"}".*|{CCS}([!*]){B}*{CMD}"}"[^*]*{CCE} {
3048 bool insideEnum = YY_START==FindFields || ((YY_START==ReadInitializer || YY_START==ReadInitializerPtr) && yyextra->lastInitializerContext==FindFields); // see bug746226
3049 yyextra->commentScanner.close(yyextra->current.get(),yyextra->fileName,yyextra->yyLineNr,insideEnum);
3050 lineCount(yyscanner);
3051 }
3052<FindMembers>"=>" {
3053 if (!yyextra->insideCS) REJECT;
3054 yyextra->current->bodyLine = yyextra->yyLineNr;
3055 yyextra->current->bodyColumn = yyextra->yyColNr;
3056 yyextra->current->initializer.str(yytext);
3057 yyextra->lastInitializerContext = YY_START;
3058 yyextra->sharpCount=0;
3059 yyextra->initBracketCount=0;
3060 yyextra->current->mtype = yyextra->mtype = MethodTypes::Property;
3061 yyextra->current->spec.setGettable(true);
3062 BEGIN(ReadInitializerPtr);
3063 }
3064<FindMembers>"=" { // in PHP code this could also be due to "<?="
3065 yyextra->current->bodyLine = yyextra->yyLineNr;
3066 yyextra->current->bodyColumn = yyextra->yyColNr;
3067 yyextra->current->initializer.str(yytext);
3068 yyextra->lastInitializerContext = YY_START;
3069 yyextra->sharpCount=0;
3070 yyextra->initBracketCount=0;
3071 BEGIN(ReadInitializer);
3072 }
3073<UNOIDLAttributeBlock>{BN}*[gs]"et"{BN}+"raises"{BN}*"("{BN}*{SCOPENAME}{BN}*(","{BN}*{SCOPENAME}{BN}*)*")"{BN}*";" {
3074 lineCount(yyscanner);
3075 yyextra->current->exception += " ";
3076 yyextra->current->exception += removeRedundantWhiteSpace(yytext);
3077 }
3078<UNOIDLAttributeBlock>"}" {
3079 yyextra->current->exception += " }";
3080 BEGIN(FindMembers);
3081 }
3082 /* Read initializer rules */
3083<ReadInitializer,ReadInitializerPtr>"(" {
3084 yyextra->lastRoundContext=YY_START;
3085 yyextra->pCopyRoundGString=&yyextra->current->initializer;
3086 yyextra->roundCount=0;
3087 yyextra->current->initializer << *yytext;
3088 BEGIN(GCopyRound);
3089 }
3090<ReadInitializer,ReadInitializerPtr>"[" {
3091 if (!yyextra->insidePHP) REJECT;
3092 yyextra->lastSquareContext=YY_START;
3093 yyextra->pCopySquareGString=&yyextra->current->initializer;
3094 yyextra->squareCount=0;
3095 yyextra->current->initializer << *yytext;
3096 BEGIN(GCopySquare);
3097 }
3098<ReadInitializer,ReadInitializerPtr>"{" {
3099 yyextra->lastCurlyContext=YY_START;
3100 yyextra->pCopyCurlyGString=&yyextra->current->initializer;
3101 yyextra->curlyCount=0;
3102 yyextra->current->initializer << *yytext;
3103 BEGIN(GCopyCurly);
3104 }
3105<ReadInitializer,ReadInitializerPtr>[;,] {
3106 //printf(">> initializer '%s' <<\n",qPrint(yyextra->current->initializer));
3107 if (*yytext==';' && yyextra->current_root->spec.isEnum())
3108 {
3109 yyextra->current->fileName = yyextra->fileName;
3110 yyextra->current->startLine = yyextra->yyLineNr;
3111 yyextra->current->startColumn = yyextra->yyColNr;
3112 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
3113 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
3114 yyextra->current->section = EntryType::makeVariable();
3115 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
3116 initEntry(yyscanner);
3117 BEGIN(FindMembers);
3118 }
3119 else if (*yytext==';' || (yyextra->lastInitializerContext==FindFields && yyextra->initBracketCount==0)) // yyextra->initBracketCount==0 was added for bug 665778
3120 {
3121 unput(*yytext);
3122 if (YY_START == ReadInitializerPtr) yyextra->current->initializer.str(std::string());
3123 BEGIN(yyextra->lastInitializerContext);
3124 }
3125 else if (*yytext==',' && yyextra->initBracketCount==0) // for "int a=0,b=0"
3126 {
3127 unput(*yytext);
3128 if (YY_START == ReadInitializerPtr) yyextra->current->initializer.str(std::string());
3129 BEGIN(yyextra->lastInitializerContext);
3130 }
3131 else
3132 {
3133 yyextra->current->initializer << *yytext;
3134 }
3135 }
3136<ReadInitializer,ReadInitializerPtr>{RAWBEGIN} { // C++11 raw string
3137 if (!yyextra->insideCpp)
3138 {
3139 REJECT;
3140 }
3141 else
3142 {
3143 yyextra->current->initializer << yytext;
3144 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
3145 yyextra->lastRawStringContext = YY_START;
3146 yyextra->pCopyRawGString = &yyextra->current->initializer;
3147 BEGIN(RawGString);
3148 //printf("RawGString delimiter='%s'\n",qPrint(delimiter));
3149 }
3150 }
3151<RawGString>{RAWEND} {
3152 if (extractEndRawStringDelimiter(yytext)==yyextra->delimiter)
3153 {
3154 *yyextra->pCopyRawGString << yytext;
3155 BEGIN(yyextra->lastRawStringContext);
3156 }
3157 else
3158 {
3159 REJECT;
3160 }
3161 }
3162<RawGString>[^)\n]+ {
3163 *yyextra->pCopyRawGString << yytext;
3164 }
3165<RawGString>. {
3166 *yyextra->pCopyRawGString << yytext;
3167 }
3168<RawGString>\n {
3169 *yyextra->pCopyRawGString << yytext;
3170 lineCount(yyscanner);
3171 }
3172<RawString>{RAWEND} {
3173 *yyextra->pCopyRawString+=yytext;
3174 yyextra->fullArgString+=yytext;
3175 if (extractEndRawStringDelimiter(yytext)==yyextra->delimiter)
3176 {
3177 BEGIN(yyextra->lastRawStringContext);
3178 }
3179 }
3180<RawString>[^)]+ {
3181 *yyextra->pCopyRawString += yytext;
3182 yyextra->fullArgString+=yytext;
3183 }
3184<RawString>. {
3185 *yyextra->pCopyRawString += yytext;
3186 yyextra->fullArgString+=yytext;
3187 }
3188<RawString>\n {
3189 *yyextra->pCopyRawString += yytext;
3190 yyextra->fullArgString+=yytext;
3191 lineCount(yyscanner);
3192 }
3193<ReadInitializer,ReadInitializerPtr>\" {
3194 if (yyextra->insideIDL && yyextra->insideCppQuote)
3195 {
3196 BEGIN(EndCppQuote);
3197 }
3198 else
3199 {
3200 yyextra->lastStringContext=YY_START;
3201 yyextra->current->initializer << yytext;
3202 yyextra->pCopyQuotedGString=&yyextra->current->initializer;
3203 yyextra->stopAtInvalidString=false;
3204 BEGIN(CopyGString);
3205 }
3206 }
3207<ReadInitializer,ReadInitializerPtr>"->" {
3208 yyextra->current->initializer << yytext;
3209 }
3210<ReadInitializer,ReadInitializerPtr>("<<"|"<=") {
3211 yyextra->current->initializer << yytext;
3212 }
3213<ReadInitializer,ReadInitializerPtr>(">>") {
3214 if (yyextra->initBracketCount<=yyextra->sharpCount && yyextra->sharpCount>=2)
3215 {
3216 // heuristic to detect '>>' in A<B<C>>::D as '> >', but not e.g. 'A>>B' or A<B<(C>>2)>::D>
3217 yyextra->initBracketCount-=2;
3218 yyextra->sharpCount-=2;
3219 }
3220 yyextra->current->initializer << yytext;
3221 }
3222<ReadInitializer,ReadInitializerPtr>(">=") {
3223 yyextra->current->initializer << yytext;
3224 }
3225<ReadInitializer,ReadInitializerPtr>[<\[{(] {
3226 yyextra->initBracketCount++;
3227 yyextra->sharpCount++;
3228 yyextra->current->initializer << *yytext;
3229 }
3230<ReadInitializer,ReadInitializerPtr>[>\]})] {
3231 yyextra->initBracketCount--;
3232 yyextra->sharpCount--;
3233 if (*yytext=='}')
3234 {
3235 yyextra->current->endBodyLine=yyextra->yyLineNr;
3236 }
3237 yyextra->current->initializer << *yytext;
3238 }
3239<ReadInitializer,ReadInitializerPtr>\' {
3240 if (yyextra->insidePHP)
3241 {
3242 yyextra->current->initializer << yytext;
3243 yyextra->pCopyQuotedGString = &yyextra->current->initializer;
3244 yyextra->lastStringContext=YY_START;
3245 BEGIN(CopyPHPGString);
3246 }
3247 else
3248 {
3249 yyextra->current->initializer << yytext;
3250 }
3251 }
3252<ReadInitializer,ReadInitializerPtr>{CHARLIT} {
3253 if (yyextra->insidePHP)
3254 {
3255 REJECT;
3256 }
3257 else
3258 {
3259 yyextra->current->initializer << yytext;
3260 }
3261 }
3262<ReadInitializer,ReadInitializerPtr>\n {
3263 yyextra->current->initializer << *yytext;
3264 lineCount(yyscanner);
3265 }
3266<ReadInitializer,ReadInitializerPtr>"@\"" {
3267 //printf("yyextra->insideCS=%d\n",yyextra->insideCS);
3268 yyextra->current->initializer << yytext;
3269 if (!yyextra->insideCS && !yyextra->insideObjC)
3270 {
3271 REJECT;
3272 }
3273 else
3274 {
3275 // C#/ObjC verbatim string
3276 yyextra->lastSkipVerbStringContext=YY_START;
3277 yyextra->pSkipVerbString=&yyextra->current->initializer;
3278 BEGIN(SkipVerbString);
3279 }
3280 }
3281<SkipVerbString>[^\n"\\]+ {
3282 *yyextra->pSkipVerbString << yytext;
3283 }
3284<SkipVerbString>"\\\\" { // escaped backslash
3285 if (yyextra->insideCS) REJECT
3286 *yyextra->pSkipVerbString << yytext;
3287 }
3288<SkipVerbString>"\\\"" { // backslash escaped quote
3289 if (yyextra->insideCS) REJECT
3290 *yyextra->pSkipVerbString << yytext;
3291 }
3292<SkipVerbString>"\"\"" { // quote escape
3293 *yyextra->pSkipVerbString << yytext;
3294 }
3295<SkipVerbString>"\"" {
3296 *yyextra->pSkipVerbString << *yytext;
3297 BEGIN(yyextra->lastSkipVerbStringContext);
3298 }
3299<SkipVerbString>\n {
3300 *yyextra->pSkipVerbString << *yytext;
3301 lineCount(yyscanner);
3302 }
3303<SkipVerbString>. {
3304 *yyextra->pSkipVerbString << *yytext;
3305 }
3306<ReadInitializer,ReadInitializerPtr>"?>" {
3307 if (yyextra->insidePHP)
3308 BEGIN( FindMembersPHP );
3309 else
3310 yyextra->current->initializer << yytext;
3311 }
3312<ReadInitializer,ReadInitializerPtr>. {
3313 yyextra->current->initializer << *yytext;
3314 }
3315
3316 /* generic quoted string copy rules */
3317<CopyString,CopyPHPString>\\. {
3318 *yyextra->pCopyQuotedString+=yytext;
3319 }
3320<CopyString>\" {
3321 *yyextra->pCopyQuotedString+=*yytext;
3322 BEGIN( yyextra->lastStringContext );
3323 }
3324<CopyPHPString>\' {
3325 *yyextra->pCopyQuotedString+=*yytext;
3326 BEGIN( yyextra->lastStringContext );
3327 }
3328<CopyString,CopyPHPString>{CCS}|{CCE}|{CPPC} {
3329 *yyextra->pCopyQuotedString+=yytext;
3330 }
3331<CopyString,CopyPHPString>\n {
3332 *yyextra->pCopyQuotedString+=*yytext;
3333 lineCount(yyscanner);
3334 }
3335<CopyString,CopyPHPString>. {
3336 *yyextra->pCopyQuotedString+=*yytext;
3337 }
3338
3339 /* generic quoted growable string copy rules */
3340<CopyGString,CopyPHPGString>\\. {
3341 *yyextra->pCopyQuotedGString << yytext;
3342 }
3343<CopyGString>\" {
3344 *yyextra->pCopyQuotedGString << *yytext;
3345 BEGIN( yyextra->lastStringContext );
3346 }
3347<CopyPHPGString>\' {
3348 *yyextra->pCopyQuotedGString << *yytext;
3349 BEGIN( yyextra->lastStringContext );
3350 }
3351<CopyGString,CopyPHPGString>"<?php" { // we had an odd number of quotes.
3352 *yyextra->pCopyQuotedGString << yytext;
3353 BEGIN( yyextra->lastStringContext );
3354 }
3355<CopyGString,CopyPHPGString>{CCS}|{CCE}|{CPPC} {
3356 *yyextra->pCopyQuotedGString << yytext;
3357 }
3358<CopyGString,CopyPHPGString>\n {
3359 *yyextra->pCopyQuotedGString << *yytext;
3360 if (yyextra->stopAtInvalidString)
3361 {
3362 BEGIN( yyextra->lastStringContext );
3363 }
3364 else
3365 {
3366 lineCount(yyscanner);
3367 }
3368 }
3369<CopyGString,CopyPHPGString>. {
3370 *yyextra->pCopyQuotedGString << *yytext;
3371 }
3372
3373 /* generic round bracket list copy rules */
3374<CopyRound>\" {
3375 *yyextra->pCopyRoundString += *yytext;
3376 yyextra->pCopyQuotedString=yyextra->pCopyRoundString;
3377 yyextra->lastStringContext=YY_START;
3378 BEGIN(CopyString);
3379 }
3380<CopyRound>"(" {
3381 *yyextra->pCopyRoundString += *yytext;
3382 yyextra->roundCount++;
3383 }
3384<CopyRound>")" {
3385 *yyextra->pCopyRoundString += *yytext;
3386 if (--yyextra->roundCount<0)
3387 BEGIN(yyextra->lastRoundContext);
3388 }
3389<CopyRound>\n {
3390 lineCount(yyscanner);
3391 *yyextra->pCopyRoundString += *yytext;
3392 }
3393<CopyRound>\' {
3394 if (yyextra->insidePHP)
3395 {
3396 yyextra->current->initializer << yytext;
3397 yyextra->pCopyQuotedString = yyextra->pCopyRoundString;
3398 yyextra->lastStringContext=YY_START;
3399 BEGIN(CopyPHPString);
3400 }
3401 else
3402 {
3403 *yyextra->pCopyRoundString += yytext;
3404 }
3405 }
3406<CopyRound>{CHARLIT} {
3407 if (yyextra->insidePHP)
3408 {
3409 REJECT;
3410 }
3411 else
3412 {
3413 *yyextra->pCopyRoundString+=yytext;
3414 }
3415 }
3416<CopyRound>[^"'()\n,]+ {
3417 *yyextra->pCopyRoundString+=yytext;
3418 }
3419<CopyRound>. {
3420 *yyextra->pCopyRoundString+=*yytext;
3421 }
3422
3423 /* generic sharp bracket list copy rules */
3424<CopySharp>\" {
3425 *yyextra->pCopySharpString += *yytext;
3426 yyextra->pCopyQuotedString=yyextra->pCopySharpString;
3427 yyextra->lastStringContext=YY_START;
3428 BEGIN(CopyString);
3429 }
3430<CopySharp>"<" {
3431 *yyextra->pCopySharpString += *yytext;
3432 yyextra->sharpCount++;
3433 }
3434<CopySharp>">" {
3435 *yyextra->pCopySharpString += *yytext;
3436 if (--yyextra->sharpCount<0)
3437 {
3438 BEGIN(yyextra->lastSharpContext);
3439 }
3440 }
3441<CopySharp>\n {
3442 lineCount(yyscanner);
3443 *yyextra->pCopySharpString += *yytext;
3444 }
3445<CopySharp>\' {
3446 if (yyextra->insidePHP)
3447 {
3448 yyextra->current->initializer << yytext;
3449 yyextra->pCopyQuotedString = yyextra->pCopySharpString;
3450 yyextra->lastStringContext=YY_START;
3451 BEGIN(CopyPHPString);
3452 }
3453 else
3454 {
3455 *yyextra->pCopySharpString += yytext;
3456 }
3457 }
3458<CopySharp>{CHARLIT} {
3459 if (yyextra->insidePHP)
3460 {
3461 REJECT;
3462 }
3463 else
3464 {
3465 *yyextra->pCopySharpString+=yytext;
3466 }
3467 }
3468<CopySharp>[^"'<>\n,]+ {
3469 *yyextra->pCopySharpString+=yytext;
3470 }
3471<CopySharp>. {
3472 *yyextra->pCopySharpString+=*yytext;
3473 }
3474
3475
3476 /* generic round bracket list copy rules for growable strings */
3477<GCopyRound>\" {
3478 *yyextra->pCopyRoundGString << *yytext;
3479 yyextra->pCopyQuotedGString=yyextra->pCopyRoundGString;
3480 yyextra->lastStringContext=YY_START;
3481 BEGIN(CopyGString);
3482 }
3483<GCopyRound>"(" {
3484 *yyextra->pCopyRoundGString << *yytext;
3485 yyextra->roundCount++;
3486 }
3487<GCopyRound>")" {
3488 *yyextra->pCopyRoundGString << *yytext;
3489 if (--yyextra->roundCount<0)
3490 BEGIN(yyextra->lastRoundContext);
3491 }
3492<GCopyRound>\n {
3493 lineCount(yyscanner);
3494 *yyextra->pCopyRoundGString << *yytext;
3495 }
3496<GCopyRound>\' {
3497 if (yyextra->insidePHP)
3498 {
3499 yyextra->current->initializer << yytext;
3500 yyextra->pCopyQuotedGString = yyextra->pCopyRoundGString;
3501 yyextra->lastStringContext=YY_START;
3502 BEGIN(CopyPHPGString);
3503 }
3504 else
3505 {
3506 *yyextra->pCopyRoundGString << yytext;
3507 }
3508 }
3509<GCopyRound>{CHARLIT} {
3510 if (yyextra->insidePHP)
3511 {
3512 REJECT;
3513 }
3514 else
3515 {
3516 *yyextra->pCopyRoundGString << yytext;
3517 }
3518 }
3519<GCopyRound>"@\"" {
3520 if (!yyextra->insideCS) REJECT;
3521 *yyextra->pCopyRoundGString << yytext;
3522 yyextra->lastSkipVerbStringContext=YY_START;
3523 yyextra->pSkipVerbString=yyextra->pCopyRoundGString;
3524 BEGIN(SkipVerbString);
3525 }
3526<GCopyRound>[^"'()\n\/,R]+ { // R because of raw string start
3527 *yyextra->pCopyRoundGString << yytext;
3528 }
3529<GCopyRound>{RAWBEGIN} {
3530 *yyextra->pCopyRoundGString << yytext;
3531 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
3532 yyextra->lastRawStringContext = YY_START;
3533 yyextra->pCopyRawGString = yyextra->pCopyRoundGString;
3534 BEGIN(RawGString);
3535 }
3536<GCopyRound>. {
3537 *yyextra->pCopyRoundGString << *yytext;
3538 }
3539
3540 /* 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 */
3541<GCopySquare>\" {
3542 *yyextra->pCopySquareGString << *yytext;
3543 yyextra->pCopyQuotedGString=yyextra->pCopySquareGString;
3544 yyextra->lastStringContext=YY_START;
3545 BEGIN(CopyGString);
3546 }
3547<GCopySquare>\' {
3548 *yyextra->pCopySquareGString << *yytext;
3549 if (yyextra->insidePHP)
3550 {
3551 yyextra->pCopyQuotedGString=yyextra->pCopySquareGString;
3552 yyextra->lastStringContext=YY_START;
3553 BEGIN(CopyPHPGString);
3554 }
3555 }
3556<GCopySquare>"[" {
3557 *yyextra->pCopySquareGString << *yytext;
3558 yyextra->squareCount++;
3559 }
3560<GCopySquare>"]" {
3561 *yyextra->pCopySquareGString << *yytext;
3562 if (--yyextra->squareCount<0)
3563 BEGIN(yyextra->lastSquareContext);
3564 }
3565<GCopySquare>\n {
3566 lineCount(yyscanner);
3567 *yyextra->pCopySquareGString << *yytext;
3568 }
3569<GCopySquare>\' {
3570 if (yyextra->insidePHP)
3571 {
3572 yyextra->current->initializer << yytext;
3573 yyextra->pCopyQuotedGString = yyextra->pCopySquareGString;
3574 yyextra->lastStringContext=YY_START;
3575 BEGIN(CopyPHPGString);
3576 }
3577 else
3578 {
3579 *yyextra->pCopySquareGString << yytext;
3580 }
3581 }
3582<GCopySquare>{CHARLIT} {
3583 if (yyextra->insidePHP)
3584 {
3585 REJECT;
3586 }
3587 else
3588 {
3589 *yyextra->pCopySquareGString << yytext;
3590 }
3591 }
3592<GCopySquare>[^"'\[\]\n\/,]+ {
3593 *yyextra->pCopySquareGString << yytext;
3594 }
3595<GCopySquare>. {
3596 *yyextra->pCopySquareGString << *yytext;
3597 }
3598
3599 /* generic curly bracket list copy rules */
3600<CopyCurly>\" {
3601 *yyextra->pCopyCurlyString += *yytext;
3602 yyextra->pCopyQuotedString=yyextra->pCopyCurlyString;
3603 yyextra->lastStringContext=YY_START;
3604 BEGIN(CopyString);
3605 }
3606<CopyCurly>\' {
3607 *yyextra->pCopyCurlyString += *yytext;
3608 if (yyextra->insidePHP)
3609 {
3610 yyextra->pCopyQuotedString=yyextra->pCopyCurlyString;
3611 yyextra->lastStringContext=YY_START;
3612 BEGIN(CopyPHPString);
3613 }
3614 }
3615<CopyCurly>"{" {
3616 *yyextra->pCopyCurlyString += *yytext;
3617 yyextra->curlyCount++;
3618 }
3619<CopyCurly>"}" {
3620 *yyextra->pCopyCurlyString += *yytext;
3621 if (--yyextra->curlyCount<0)
3622 BEGIN(yyextra->lastCurlyContext);
3623 }
3624<CopyCurly>{CHARLIT} { if (yyextra->insidePHP)
3625 {
3626 REJECT;
3627 }
3628 else
3629 {
3630 *yyextra->pCopyCurlyString += yytext;
3631 }
3632 }
3633<CopyCurly>[^"'{}\/\n,]+ {
3634 *yyextra->pCopyCurlyString += yytext;
3635 }
3636<CopyCurly>"/" { *yyextra->pCopyCurlyString += yytext; }
3637<CopyCurly>\n {
3638 lineCount(yyscanner);
3639 *yyextra->pCopyCurlyString += *yytext;
3640 }
3641<CopyCurly>. {
3642 *yyextra->pCopyCurlyString += *yytext;
3643 }
3644
3645 /* generic curly bracket list copy rules for growable strings */
3646<GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker
3647 }
3648<GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker
3649 QCString line = QCString(yytext);
3650 int s = line.find(' ');
3651 int e = line.find('"',s);
3652 yyextra->yyLineNr = line.mid(s,e-s).toInt();
3653 if (yytext[yyleng-1]=='\n')
3654 {
3655 lineCount(yyscanner);
3656 yyextra->column=0;
3657 }
3658 }
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:249
3659<GCopyCurly>\" {
3660 *yyextra->pCopyCurlyGString << *yytext;
3661 yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString;
3662 yyextra->lastStringContext=YY_START;
3663 BEGIN(CopyGString);
3664 }
3665<GCopyCurly>\' {
3666 *yyextra->pCopyCurlyGString << *yytext;
3667 if (yyextra->insidePHP)
3668 {
3669 yyextra->pCopyQuotedGString=yyextra->pCopyCurlyGString;
3670 yyextra->lastStringContext=YY_START;
3671 BEGIN(CopyPHPGString);
3672 }
3673 }
3674<GCopyCurly>"{" {
3675 *yyextra->pCopyCurlyGString << *yytext;
3676 yyextra->curlyCount++;
3677 }
3678<GCopyCurly>"}" {
3679 *yyextra->pCopyCurlyGString << *yytext;
3680 if (--yyextra->curlyCount<0)
3681 {
3682 yyextra->current->endBodyLine = yyextra->yyLineNr;
3683 BEGIN(yyextra->lastCurlyContext);
3684 }
3685 }
3686<GCopyCurly>{CHARLIT} { if (yyextra->insidePHP)
3687 {
3688 REJECT;
3689 }
3690 else
3691 {
3692 *yyextra->pCopyCurlyGString << yytext;
3693 }
3694 }
3695<GCopyCurly>[^"'{}\/\n,]+ {
3696 *yyextra->pCopyCurlyGString << yytext;
3697 }
3698<GCopyCurly>[,]+ {
3699 *yyextra->pCopyCurlyGString << yytext;
3700 }
3701<GCopyCurly>"/" { *yyextra->pCopyCurlyGString << yytext; }
3702<GCopyCurly>\n {
3703 lineCount(yyscanner);
3704 *yyextra->pCopyCurlyGString << *yytext;
3705 }
3706<GCopyCurly>. {
3707 *yyextra->pCopyCurlyGString << *yytext;
3708 }
3709
3710 /* ---------------------- */
3711
3712
3713<FindMembers>":" {
3714 if (yyextra->current->type.isEmpty() &&
3715 yyextra->current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}'
3716 {
3717 yyextra->current->section = EntryType::makeEnum();
3718 yyextra->current->name.clear();
3719 yyextra->current->args.clear();
3720 BEGIN(EnumBaseType);
3721 }
3722 else
3723 {
3724 if (yyextra->current->type.isEmpty()) // anonymous padding field, e.g. "int :7;"
3725 {
3726 addType(yyscanner);
3727 yyextra->current->name.sprintf("__pad%d__",yyextra->padCount++);
3728 }
3729 BEGIN(BitFields);
3730 yyextra->current->bitfields+=":";
3731 }
3732 }
3733<BitFields>. {
3734 yyextra->current->bitfields+=*yytext;
3735 }
3736<EnumBaseType>. {
3737 yyextra->current->args+=*yytext;
3738 }
3739<EnumBaseType>\n {
3740 lineCount(yyscanner);
3741 yyextra->current->args+=' ';
3742 }
3743<FindMembers>[;,] {
3744 QCString oldType = yyextra->current->type;
3745 if (yyextra->current->bodyLine==-1)
3746 {
3747 yyextra->current->bodyLine = yyextra->yyLineNr;
3748 yyextra->current->bodyColumn = yyextra->yyColNr;
3749 }
3750 if ( yyextra->insidePHP && yyextra->current->type.startsWith("var"))
3751 {
3752 yyextra->current->type = yyextra->current->type.mid(3);
3753 }
3754 if (yyextra->isTypedef && !yyextra->current->type.startsWith("typedef "))
3755 {
3756 yyextra->current->type.prepend("typedef ");
3757 }
3758 bool isStatic = yyextra->current->isStatic;
3759 Protection prot = yyextra->current->protection;
3760 bool isConcept = yyextra->current->section.isConcept();
3761 bool isModule = yyextra->current->section.isModuleDoc();
3762 if (isConcept) // C++20 concept
3763 {
3764 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
3765 initEntry(yyscanner);
3766 }
3767 else if (isModule) // C++20 module
3768 {
3769 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
3770 initEntry(yyscanner);
3771 }
3772 else if (!yyextra->current->name.isEmpty() && !yyextra->current->section.isEnum())
3773 {
3774 yyextra->current->type=yyextra->current->type.simplifyWhiteSpace();
3775 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
3776 yyextra->current->name=yyextra->current->name.stripWhiteSpace();
3777 if (yyextra->current->section.isClass()) // remove spec for "struct Bla bla;"
3778 {
3779 yyextra->current->spec = TypeSpecifier();
3780 }
3781 yyextra->current->section = EntryType::makeVariable() ;
3782 yyextra->current->fileName = yyextra->fileName;
3783 yyextra->current->startLine = yyextra->yyBegLineNr;
3784 yyextra->current->startColumn = yyextra->yyBegColNr;
3785 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
3786 initEntry(yyscanner);
3787 }
3788 if ( *yytext == ',')
3789 {
3790 yyextra->current->isStatic = isStatic; // the static attribute holds for all variables
3791 yyextra->current->protection = prot;
3792 yyextra->current->name.clear();
3793 yyextra->current->args.clear();
3794 yyextra->current->brief.clear();
3795 yyextra->current->doc.clear();
3796 yyextra->current->initializer.str(std::string());
3797 yyextra->current->bitfields.clear();
3798 yyextra->current->type = stripFuncPtr(oldType);
3799 }
3800 else
3801 {
3802 yyextra->mtype = MethodTypes::Method;
3803 yyextra->virt = Specifier::Normal;
3804 yyextra->current->bodyLine = -1;
3805 yyextra->current->bodyColumn = 1;
3806 yyextra->current->groups.clear();
3807 initEntry(yyscanner);
3808 }
3809 }
3810
3811<FindMembers>"[" {
3812 if (yyextra->insideSlice)
3813 {
3814 yyextra->squareCount=1;
3815 yyextra->lastSquareContext = YY_START;
3816 yyextra->current->metaData += "[";
3817 BEGIN( SliceMetadata );
3818 }
3819 else if (!yyextra->insideCS &&
3820 (yyextra->current->name.isEmpty() ||
3821 yyextra->current->name=="typedef"
3822 )
3823 ) // IDL function property
3824 {
3825 yyextra->squareCount=1;
3826 yyextra->lastSquareContext = YY_START;
3827 yyextra->idlAttr.clear();
3828 yyextra->idlProp.clear();
3829 yyextra->current->mtype = yyextra->mtype;
3830
3831 if (Config_getBool(IDL_PROPERTY_SUPPORT) &&
3832 yyextra->current->mtype == MethodTypes::Property)
3833 { // we are yyextra->inside the properties section of a dispinterface
3834 yyextra->odlProp = true;
3835 yyextra->current->spec.setGettable(true).setSettable(true);
3836 }
3837
3838 BEGIN( IDLAttribute );
3839 }
3840 else if (yyextra->insideCS &&
3841 yyextra->current->name.isEmpty())
3842 {
3843 yyextra->squareCount=1;
3844 yyextra->lastSquareContext = YY_START;
3845 // Skip the C# attribute
3846 // for this member
3847 yyextra->current->args.clear();
3848 BEGIN( SkipSquare );
3849 }
3850 else
3851 {
3852 yyextra->current->args += yytext ;
3853 yyextra->squareCount=1;
3854 yyextra->externLinkage=FALSE; // see bug759247
3855 BEGIN( Array ) ;
3856 }
3857 }
3858<SliceMetadata>"[" { // Global metadata.
3859 yyextra->squareCount++;
3860 yyextra->current->metaData += "[";
3861 }
3862<SliceMetadata>{BN}* {
3863 lineCount(yyscanner);
3864 }
3865<SliceMetadata>\"[^\"]*\" {
3866 yyextra->current->metaData += yytext;
3867 }
3868<SliceMetadata>"," {
3869 yyextra->current->metaData += yytext;
3870 }
3871<SliceMetadata>"]" {
3872 yyextra->current->metaData += yytext;
3873 if (--yyextra->squareCount<=0)
3874 {
3875 BEGIN (yyextra->lastSquareContext);
3876 }
3877 }
3878<SliceOptional>"(" {
3879 yyextra->current->type += "(";
3880 yyextra->roundCount++;
3881 }
3882<SliceOptional>[0-9]+ {
3883 yyextra->current->type += yytext;
3884 }
3885<SliceOptional>")" {
3886 yyextra->current->type += ")";
3887 if(--yyextra->roundCount<=0)
3888 {
3889 BEGIN (yyextra->lastModifierContext);
3890 }
3891 }
3892<IDLAttribute>"]" {
3893 // end of IDL function attribute
3894 if (--yyextra->squareCount<=0)
3895 {
3896 lineCount(yyscanner);
3897 if (yyextra->current->mtype == MethodTypes::Property)
3898 BEGIN( IDLPropName );
3899 else
3900 BEGIN( yyextra->lastSquareContext );
3901 }
3902 }
3903<IDLAttribute>"propput" {
3904 if (Config_getBool(IDL_PROPERTY_SUPPORT))
3905 {
3906 yyextra->current->mtype = MethodTypes::Property;
3907 }
3908 yyextra->current->spec.setSettable(true);
3909 }
3910<IDLAttribute>"propget" {
3911 if (Config_getBool(IDL_PROPERTY_SUPPORT))
3912 {
3913 yyextra->current->mtype = MethodTypes::Property;
3914 }
3915 yyextra->current->spec.setGettable(true);
3916 }
3917<IDLAttribute>"property" { // UNO IDL property
3918 yyextra->current->spec.setProperty(true);
3919 }
3920<IDLAttribute>"attribute" { // UNO IDL attribute
3921 yyextra->current->spec.setAttribute(true);
3922 }
3923<IDLAttribute>"optional" { // on UNO IDL interface/service/attribute/property
3924 yyextra->current->spec.setOptional(true);
3925 }
3926<IDLAttribute>"readonly" { // on UNO IDL attribute or property
3927 if (Config_getBool(IDL_PROPERTY_SUPPORT) && yyextra->odlProp)
3928 {
3929 yyextra->current->spec.setSettable(false);
3930 }
3931 else
3932 {
3933 yyextra->current->spec.setReadonly(true);
3934 }
3935 }
3936<IDLAttribute>"bound" { // on UNO IDL attribute or property
3937 yyextra->current->spec.setBound(true);
3938 }
3939<IDLAttribute>"removable" { // on UNO IDL property
3940 yyextra->current->spec.setRemovable(true);
3941 }
3942<IDLAttribute>"constrained" { // on UNO IDL property
3943 yyextra->current->spec.setConstrained(true);
3944 }
3945<IDLAttribute>"transient" { // on UNO IDL property
3946 yyextra->current->spec.setTransient(true);
3947 }
3948<IDLAttribute>"maybevoid" { // on UNO IDL property
3949 yyextra->current->spec.setMaybeVoid(true);
3950 }
3951<IDLAttribute>"maybedefault" { // on UNO IDL property
3952 yyextra->current->spec.setMaybeDefault(true);
3953 }
3954<IDLAttribute>"maybeambiguous" { // on UNO IDL property
3955 yyextra->current->spec.setMaybeAmbiguous(true);
3956 }
3957<IDLAttribute>. {
3958 }
3959<IDLPropName>{BN}*{ID}({BN}*[*]*{BN}*)? {
3960 // return type (probably HRESULT) - skip it
3961
3962 if (yyextra->odlProp)
3963 { // property type
3964 yyextra->idlProp = yytext;
3965 }
3966 }
3967<IDLPropName>{ID}{BN}*"(" {
3968 yyextra->current->name = yytext;
3969 yyextra->current->name = yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
3970 yyextra->current->startLine = yyextra->yyLineNr;
3971 yyextra->current->startColumn = yyextra->yyColNr;
3972 BEGIN( IDLProp );
3973 }
3974<IDLPropName>{BN}*"("{BN}*{ID}{BN}*")"{BN}* {
3975 if (yyextra->odlProp)
3976 {
3977 yyextra->idlProp += yytext;
3978 }
3979 }
3980<IDLPropName>{ID}{BNopt}/";" {
3981 if (yyextra->odlProp)
3982 {
3983 yyextra->current->name = yytext;
3984 yyextra->idlProp = yyextra->idlProp.stripWhiteSpace();
3985 yyextra->odlProp = false;
3986
3987 BEGIN( IDLProp );
3988 }
3989 }
3990<IDLProp>{BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter
3991 yyextra->idlAttr = yytext;
3992 yyextra->idlAttr=yyextra->idlAttr.stripWhiteSpace();
3993 }
3994<IDLProp>{ID} { // property type
3995 yyextra->idlProp = yytext;
3996 }
3997<IDLProp>{BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);)
3998 if (yyextra->current->args.isEmpty())
3999 yyextra->current->args = "(";
4000 else
4001 yyextra->current->args += ", ";
4002 yyextra->current->args += yyextra->idlAttr;
4003 yyextra->current->args += " ";
4004 yyextra->current->args += yyextra->idlProp; // prop was actually type of extra parameter
4005 yyextra->current->args += " ";
4006 yyextra->current->args += yytext;
4007 yyextra->current->args = yyextra->current->args.left(yyextra->current->args.length() - 1); // strip comma
4008 yyextra->idlProp.clear();
4009 yyextra->idlAttr.clear();
4010 BEGIN( IDLProp );
4011 }
4012<IDLProp>{BN}*{ID}{BN}*")"{BN}* {
4013 // the parameter name for the property - just skip.
4014 }
4015<IDLProp>";" {
4016 yyextra->current->fileName = yyextra->fileName;
4017 yyextra->current->type = yyextra->idlProp;
4018 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4019 if (!yyextra->current->args.isEmpty())
4020 yyextra->current->args += ")";
4021 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4022 yyextra->current->section = EntryType::makeVariable();
4023 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
4024 initEntry(yyscanner);
4025 BEGIN( FindMembers );
4026 }
4027<IDLProp>. { // spaces, *, or other stuff
4028 //yyextra->idlProp+=yytext;
4029 }
4030<Array>"]" { yyextra->current->args += *yytext ;
4031 if (--yyextra->squareCount<=0)
4032 BEGIN( FindMembers ) ;
4033 }
4034<FuncFuncArray>"]" { yyextra->current->args += *yytext ;
4035 if (--yyextra->squareCount<=0)
4036 BEGIN( SFunction ) ;
4037 }
4038<Array,FuncFuncArray>"[" { yyextra->current->args += *yytext ;
4039 yyextra->squareCount++;
4040 }
4041<Array,FuncFuncArray>. { yyextra->current->args += *yytext ; }
4042<SkipSquare>"[" { yyextra->squareCount++; }
4043<SkipSquare>"]" {
4044 if (--yyextra->squareCount<=0)
4045 BEGIN( yyextra->lastSquareContext );
4046 }
4047<SkipSquare>\" {
4048 yyextra->lastStringContext=YY_START;
4049 BEGIN( SkipString );
4050 }
4051<SkipSquare>[^\n\[\]\"]+
4052<FindMembers>"<" { addType(yyscanner);
4053 yyextra->current->type += yytext ;
4054 BEGIN( Sharp ) ;
4055 }
4056<Sharp>">" { yyextra->current->type += *yytext ;
4057 if (--yyextra->sharpCount<=0)
4058 BEGIN( FindMembers ) ;
4059 }
4060<Sharp>"<" { yyextra->current->type += *yytext ;
4061 yyextra->sharpCount++;
4062 }
4063<Sharp>{BN}+ {
4064 yyextra->current->type += ' ';
4065 lineCount(yyscanner);
4066 }
4067<Sharp>. { yyextra->current->type += *yytext ; }
4068<FindFields>{ID} {
4069 storeClangId(yyscanner,yytext);
4070 yyextra->current->bodyLine = yyextra->yyLineNr;
4071 yyextra->current->bodyColumn = yyextra->yyColNr;
4072 yyextra->current->name = yytext;
4073 }
4074<FindFields>[({] {
4075 // Java enum initializer
4076 unput(*yytext);
4077 yyextra->lastInitializerContext = YY_START;
4078 yyextra->sharpCount=0;
4079 yyextra->initBracketCount=0;
4080 yyextra->current->initializer.str("=");
4081 BEGIN(ReadInitializer);
4082 }
4083<FindFields>"=" {
4084 yyextra->lastInitializerContext = YY_START;
4085 yyextra->sharpCount=0;
4086 yyextra->initBracketCount=0;
4087 yyextra->current->initializer.str(yytext);
4088 BEGIN(ReadInitializer);
4089 }
4090<FindFields>";" {
4091 if (yyextra->insideJava) // yyextra->last enum field in Java class
4092 {
4093 if (!yyextra->current->name.isEmpty())
4094 {
4095 yyextra->current->fileName = yyextra->fileName;
4096 yyextra->current->startLine = yyextra->yyLineNr;
4097 yyextra->current->startColumn = yyextra->yyColNr;
4098 if (!yyextra->current_root->spec.isEnum())
4099 {
4100 yyextra->current->type = "@"; // enum marker
4101 }
4102 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4103 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4104 yyextra->current->section = EntryType::makeVariable();
4105 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
4106 initEntry(yyscanner);
4107 }
4108
4109 BEGIN( FindMembers );
4110 }
4111 else
4112 {
4113 REJECT;
4114 }
4115 }
4116<FindFields>"," {
4117 //printf("adding '%s' '%s' '%s' to enum '%s' (mGrpId=%d)\n",
4118 // qPrint(yyextra->current->type), qPrint(yyextra->current->name),
4119 // qPrint(yyextra->current->args), qPrint(yyextra->current_root->name),yyextra->current->mGrpId);
4120 if (!yyextra->current->name.isEmpty())
4121 {
4122 yyextra->current->fileName = yyextra->fileName;
4123 if (yyextra->current_root->section.isEnum() || yyextra->current_root->spec.isEnum())
4124 {
4125 yyextra->current->startLine = yyextra->current->bodyLine;
4126 yyextra->current->startColumn = yyextra->current->bodyColumn;
4127 }
4128 else
4129 {
4130 yyextra->current->startLine = yyextra->yyLineNr;
4131 yyextra->current->startColumn = yyextra->yyColNr;
4132 }
4133 if (!yyextra->current_root->spec.isEnum())
4134 {
4135 yyextra->current->type = "@"; // enum marker
4136 }
4137 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4138 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4139 yyextra->current->section = EntryType::makeVariable();
4140 // add to the scope of the enum
4141 if (!yyextra->insideCS && !yyextra->insideJava &&
4142 !yyextra->current_root->spec.isStrong())
4143 // for C# and Java 1.5+ enum values always have to be explicitly qualified,
4144 // same for C++11 style enums (enum class Name {})
4145 {
4146 // add to the scope surrounding the enum (copy!)
4147 // we cannot during it directly as that would invalidate the iterator in parseCompounds.
4148 //printf("*** adding outer scope entry for %s\n",qPrint(yyextra->current->name));
4149 yyextra->outerScopeEntries.emplace_back(yyextra->current_root->parent(), std::make_shared<Entry>(*yyextra->current));
4150 }
4151 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
4152 initEntry(yyscanner);
4153 }
4154 else // probably a redundant ,
4155 {
4156 yyextra->current->reset();
4157 initEntry(yyscanner);
4158 }
4159 }
4160<FindFields>"[" { // attribute list in IDL
4161 yyextra->squareCount=1;
4162 yyextra->lastSquareContext = YY_START;
4163 BEGIN(SkipSquare);
4164 }
4165<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<\\\$R]* { yyextra->current->program << yytext ; } // R because of raw string start
4166<ReadBody,ReadNSBody,ReadBodyIntf>{CPPC}.* { yyextra->current->program << yytext ; }
4167<ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!yyextra->insidePHP)
4168 REJECT;
4169 // append PHP comment.
4170 yyextra->current->program << yytext ;
4171 }
4172 /* Interpolated string C# */
4173<SkipCurly,ReadBody,ReadNSBody,ReadBodyIntf,FindMembers,FindMemberName>$\" { if (!yyextra->insideCS) REJECT
4174 yyextra->current->program << yytext ;
4175 yyextra->pSkipInterpString = &yyextra->current->program;
4176 yyextra->lastSkipInterpStringContext=YY_START;
4177 BEGIN( SkipInterpString );
4178 }
4179<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})* {
4180 *yyextra->pSkipInterpString << yytext;
4181 }
4182<SkipInterpString>\" {
4183 *yyextra->pSkipInterpString << *yytext;
4184 BEGIN( yyextra->lastSkipInterpStringContext );
4185 }
4186 /* Verbatim Interpolated string C# */
4187<SkipCurly,ReadBody,ReadNSBody,ReadBodyIntf,FindMembers,FindMemberName>$@\" { if (!yyextra->insideCS) REJECT
4188 yyextra->current->program << yytext ;
4189 yyextra->pSkipInterpVerbString = &yyextra->current->program;
4190 yyextra->lastSkipInterpVerbStringContext=YY_START;
4191 BEGIN( SkipInterpVerbString );
4192 }
4193<SkipInterpVerbString>([^\"{}]|"{{"|"}}"|"\"\"")* {
4194 *yyextra->pSkipInterpVerbString << yytext;
4195 }
4196<SkipInterpString>"{"[^}]*"}" {
4197 *yyextra->pSkipInterpString << yytext;
4198 }
4199<SkipInterpVerbString>"{"[^}]*"}" {
4200 *yyextra->pSkipInterpVerbString << yytext;
4201 }
4202<SkipInterpVerbString>\" {
4203 *yyextra->pSkipInterpVerbString << *yytext;
4204 BEGIN( yyextra->lastSkipInterpVerbStringContext );
4205 }
4206<ReadBody,ReadNSBody,ReadBodyIntf>"\$" { yyextra->current->program << yytext ; }
4207<ReadBody,ReadNSBody,ReadBodyIntf>@\" { yyextra->current->program << yytext ;
4208 yyextra->pSkipVerbString = &yyextra->current->program;
4209 yyextra->lastSkipVerbStringContext=YY_START;
4210 BEGIN( SkipVerbString );
4211 }
4212<ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (yyextra->insidePHP)
4213 {
4214 yyextra->current->program << yytext ;
4215 yyextra->pCopyHereDocGString = &yyextra->current->program;
4216 yyextra->lastHereDocContext=YY_START;
4217 BEGIN( CopyHereDoc );
4218 }
4219 else
4220 {
4221 REJECT;
4222 }
4223 }
4224<ReadBody,ReadNSBody,ReadBodyIntf>{RAWBEGIN} {
4225 yyextra->current->program << yytext;
4226 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
4227 yyextra->lastRawStringContext = YY_START;
4228 yyextra->pCopyRawGString = &yyextra->current->program;
4229 BEGIN(RawGString);
4230 }
4231<ReadBody,ReadNSBody,ReadBodyIntf>\" { yyextra->current->program << yytext ;
4232 yyextra->pCopyQuotedGString = &yyextra->current->program;
4233 yyextra->lastStringContext=YY_START;
4234 yyextra->stopAtInvalidString=false;
4235 BEGIN( CopyGString );
4236 }
4237<ReadBody,ReadNSBody,ReadBodyIntf>{DCOMMC} { yyextra->doxygenComment=true; REJECT;}
4238<ReadBody,ReadNSBody,ReadBodyIntf>{CCS}{B}* { yyextra->current->program << yytext ;
4239 yyextra->lastContext = YY_START ;
4240 BEGIN( Comment ) ;
4241 }
4242<ReadBody,ReadNSBody,ReadBodyIntf>{CCS}{BL} { yyextra->current->program << yytext ;
4243 ++yyextra->yyLineNr ;
4244 yyextra->lastContext = YY_START ;
4245 BEGIN( Comment ) ;
4246 }
4247<ReadBody,ReadNSBody,ReadBodyIntf>"'" {
4248 if (!yyextra->insidePHP)
4249 {
4250 yyextra->current->program << yytext;
4251 }
4252 else
4253 { // begin of single quoted string
4254 yyextra->current->program << yytext;
4255 yyextra->pCopyQuotedGString = &yyextra->current->program;
4256 yyextra->lastStringContext=YY_START;
4257 BEGIN(CopyPHPGString);
4258 }
4259 }
4260<ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT} {
4261 if (yyextra->insidePHP)
4262 {
4263 REJECT; // for PHP code single quotes
4264 // are used for strings of arbitrary length
4265 }
4266 else
4267 {
4268 yyextra->current->program << yytext;
4269 }
4270 }
4271<ReadBody,ReadNSBody,ReadBodyIntf>"{" { yyextra->current->program << yytext ;
4272 ++yyextra->curlyCount ;
4273 }
4274<ReadBodyIntf>"}" {
4275 yyextra->current->program << yytext ;
4276 --yyextra->curlyCount ;
4277 }
4278<ReadBody,ReadNSBody>"}" {
4279 if ( yyextra->curlyCount>0 )
4280 {
4281 yyextra->current->program << yytext ;
4282 --yyextra->curlyCount ;
4283 }
4284 else
4285 {
4286 yyextra->current->endBodyLine = yyextra->yyLineNr;
4287 std::shared_ptr<Entry> original_root = yyextra->current_root; // save root this namespace is in
4288 if (yyextra->current->section.isNamespace() && yyextra->current->type == "namespace")
4289 {
4290 int split_point;
4291 // save documentation values
4292 QCString doc = yyextra->current->doc;
4293 int docLine = yyextra->current->docLine;
4294 QCString docFile = yyextra->current->docFile;
4295 QCString brief = yyextra->current->brief;
4296 int briefLine = yyextra->current->briefLine;
4297 QCString briefFile = yyextra->current->briefFile;
4298 // reset documentation values
4299 yyextra->current->doc = "";
4300 yyextra->current->docLine = 0;
4301 yyextra->current->docFile = "";
4302 yyextra->current->brief = "";
4303 yyextra->current->briefLine = 0;
4304 yyextra->current->briefFile = "";
4305 while ((split_point = yyextra->current->name.find("::")) != -1)
4306 {
4307 std::shared_ptr<Entry> new_current = std::make_shared<Entry>(*yyextra->current);
4308 yyextra->current->program.str(std::string());
4309 new_current->name = yyextra->current->name.mid(split_point + 2);
4310 yyextra->current->name = yyextra->current->name.left(split_point);
4311 if (!yyextra->current_root->name.isEmpty()) yyextra->current->name.prepend(yyextra->current_root->name+"::");
4312
4313 yyextra->current_root->moveToSubEntryAndKeep(yyextra->current);
4314 yyextra->current_root = yyextra->current;
4315 yyextra->current = new_current;
4316 }
4317 // restore documentation values
4318 yyextra->current->doc = doc;
4319 yyextra->current->docLine = docLine;
4320 yyextra->current->docFile = docFile;
4321 yyextra->current->brief = brief;
4322 yyextra->current->briefLine = briefLine;
4323 yyextra->current->briefFile = briefFile;
4324 }
4325 QCString &cn = yyextra->current->name;
4326 QCString rn = yyextra->current_root->name;
4327 //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
4328 if (!cn.isEmpty() && !rn.isEmpty())
4329 {
4330 prependScope(yyscanner);
4331 }
4332 if (yyextra->isTypedef && cn.isEmpty())
4333 {
4334 //printf("Typedef Name\n");
4335 BEGIN( TypedefName );
4336 }
4337 else
4338 {
4339 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4340 {
4341 yyextra->current->program << ','; // add field terminator
4342 }
4343 // add compound definition to the tree
4344 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
4345 // was: yyextra->current->args.simplifyWhiteSpace();
4346 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4347 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
4348 //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);
4349 if (yyextra->insideObjC &&
4350 (yyextra->current->spec.isInterface() || yyextra->current->spec.isCategory())
4351 ) // method definition follows
4352 {
4353 BEGIN( ReadBodyIntf ) ;
4354 }
4355 else
4356 {
4357 yyextra->memspecEntry = yyextra->current;
4358 yyextra->current_root->moveToSubEntryAndKeep( yyextra->current ) ;
4359 yyextra->current = std::make_shared<Entry>(*yyextra->current);
4360 if (yyextra->current->section.isNamespace() ||
4361 yyextra->current->spec.isInterface() ||
4362 yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideJS ||
4363 yyextra->insideSlice
4364 )
4365 { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
4366 yyextra->current->reset();
4367 yyextra->current_root = std::move(original_root); // restore scope from before namespace descent
4368 initEntry(yyscanner);
4369 yyextra->memspecEntry.reset();
4370 BEGIN( FindMembers ) ;
4371 }
4372 else
4373 {
4374 static const reg::Ex re(R"(@\d+$)");
4375 if (!yyextra->isTypedef && yyextra->memspecEntry &&
4376 !reg::search(yyextra->memspecEntry->name.str(),re)) // not typedef or anonymous type (see bug691071)
4377 {
4378 // enabled the next two lines for bug 623424
4379 yyextra->current->doc.clear();
4380 yyextra->current->brief.clear();
4381 }
4382 BEGIN( MemberSpec ) ;
4383 }
4384 }
4385 }
4386 }
4387 }
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
4388<ReadBody>"}"{BN}+"typedef"{BN}+ {
4389 lineCount(yyscanner);
4390 if ( yyextra->curlyCount>0 )
4391 {
4392 yyextra->current->program << yytext ;
4393 --yyextra->curlyCount ;
4394 }
4395 else
4396 {
4397 yyextra->isTypedef = TRUE;
4398 yyextra->current->endBodyLine = yyextra->yyLineNr;
4399 QCString &cn = yyextra->current->name;
4400 QCString rn = yyextra->current_root->name;
4401 if (!cn.isEmpty() && !rn.isEmpty())
4402 {
4403 prependScope(yyscanner);
4404 }
4405 BEGIN( TypedefName );
4406 }
4407 }
4408<TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
4409 lineCount(yyscanner);
4410 yyextra->current->type.prepend(yytext);
4411 }
4412<TypedefName>{ID} {
4413 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4414 {
4415 yyextra->current->program << ","; // add field terminator
4416 }
4417 yyextra->current->name=yytext;
4418 prependScope(yyscanner);
4419 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4420 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4421 //printf("Adding compound %s %s %s\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
4422 if (!yyextra->firstTypedefEntry)
4423 {
4424 yyextra->firstTypedefEntry = yyextra->current;
4425 }
4426 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4427 initEntry(yyscanner);
4428 yyextra->isTypedef=TRUE; // to undo reset by initEntry(yyscanner)
4429 BEGIN(MemberSpecSkip);
4430 }
4431<TypedefName>";" { /* typedef of anonymous type */
4432 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
4433 if (yyextra->current->section.isEnum() || yyextra->current->spec.isEnum())
4434 {
4435 yyextra->current->program << ','; // add field terminator
4436 }
4437 // add compound definition to the tree
4438 yyextra->current->args = yyextra->current->args.simplifyWhiteSpace();
4439 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
4440 yyextra->memspecEntry = yyextra->current;
4441 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4442 initEntry(yyscanner);
4443 unput(';');
4444 BEGIN( MemberSpec ) ;
4445 }
QCString generateAnonymousAnchor(const QCString &fileName, int count)
Definition util.cpp:4074
4446<MemberSpec>([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved.
4447 lineCount(yyscanner);
4448 int i=0,l=(int)yyleng,j;
4449 while (i<l && (!isId(yytext[i]))) i++;
4450 yyextra->msName = QCString(yytext).right(l-i).stripWhiteSpace();
4451 j=yyextra->msName.find("[");
4452 if (j!=-1)
4453 {
4454 yyextra->msArgs=yyextra->msName.right(yyextra->msName.length()-j);
4455 yyextra->msName=yyextra->msName.left(j);
4456 }
4457 yyextra->msType=QCString(yytext).left(i);
4458
4459 // handle *pName in: typedef { ... } name, *pName;
4460 if (yyextra->firstTypedefEntry)
4461 {
4462 if (yyextra->firstTypedefEntry->spec.isStruct())
4463 {
4464 yyextra->msType.prepend("struct "+yyextra->firstTypedefEntry->name);
4465 }
4466 else if (yyextra->firstTypedefEntry->spec.isUnion())
4467 {
4468 yyextra->msType.prepend("union "+yyextra->firstTypedefEntry->name);
4469 }
4470 else if (yyextra->firstTypedefEntry->section.isEnum())
4471 {
4472 yyextra->msType.prepend("enum "+yyextra->firstTypedefEntry->name);
4473 }
4474 else
4475 {
4476 yyextra->msType.prepend(yyextra->firstTypedefEntry->name);
4477 }
4478 }
4479 }
QCString right(size_t len) const
Definition qcstring.h:219
bool isId(int c)
Definition util.h:208
4480<MemberSpec>"(" { // function with struct return type
4481 addType(yyscanner);
4482 yyextra->current->name = yyextra->msName;
4483 yyextra->current->spec = TypeSpecifier();
4484 unput('(');
4485 BEGIN(FindMembers);
4486 }
4487<MemberSpec>[,;] {
4488 if (yyextra->msName.isEmpty() && !yyextra->current->name.isEmpty())
4489 {
4490 // see if the compound does not have a name or is yyextra->inside another
4491 // anonymous compound. If so we insert a
4492 // special 'anonymous' variable.
4493 //Entry *p=yyextra->current_root;
4494 const Entry *p=yyextra->current.get();
4495 while (p)
4496 {
4497 // only look for class scopes, not namespace scopes
4498 if (p->section.isCompound() && !p->name.isEmpty())
4499 {
4500 //printf("Trying scope '%s'\n",qPrint(p->name));
4501 int i=p->name.findRev("::");
4502 int pi = (i==-1) ? 0 : i+2;
4503 if (p->name.at(pi)=='@')
4504 {
4505 // anonymous compound yyextra->inside -> insert dummy variable name
4506 //printf("Adding anonymous variable for scope %s\n",qPrint(p->name));
4507 yyextra->msName = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
4508 break;
4509 }
4510 }
4511 //p=p->parent;
4512 if (p==yyextra->current.get()) p=yyextra->current_root.get(); else p=p->parent();
4513 }
4514 }
4515 //printf("yyextra->msName=%s yyextra->current->name=%s\n",qPrint(yyextra->msName),qPrint(yyextra->current->name));
4516 if (!yyextra->msName.isEmpty()
4517 /*&& yyextra->msName!=yyextra->current->name*/) // skip typedef T {} T;, removed due to bug608493
4518 {
4519 bool typedefHidesStruct = Config_getBool(TYPEDEF_HIDES_STRUCT);
4520 // case 1: typedef struct _S { ... } S_t;
4521 // -> omit typedef and use S_t as the struct name
4522 if (typedefHidesStruct &&
4523 yyextra->isTypedef &&
4524 ((yyextra->current->spec.isStruct() || yyextra->current->spec.isUnion()) || yyextra->current->section.isEnum()) &&
4525 yyextra->msType.stripWhiteSpace().isEmpty() &&
4526 yyextra->memspecEntry)
4527 {
4528 yyextra->memspecEntry->name=yyextra->msName;
4529 }
4530 else // case 2: create a typedef field
4531 {
4532 std::shared_ptr<Entry> varEntry=std::make_shared<Entry>();
4533 varEntry->lang = yyextra->language;
4534 varEntry->protection = yyextra->current->protection ;
4535 varEntry->mtype = yyextra->current->mtype;
4536 varEntry->virt = yyextra->current->virt;
4537 varEntry->isStatic = yyextra->current->isStatic;
4538 varEntry->section = EntryType::makeVariable();
4539 varEntry->name = yyextra->msName.stripWhiteSpace();
4540 varEntry->type = yyextra->current->type.simplifyWhiteSpace()+" ";
4541 varEntry->args = yyextra->msArgs;
4542 if (yyextra->isTypedef)
4543 {
4544 varEntry->type.prepend("typedef ");
4545 // //printf("yyextra->current->name = %s %s\n",qPrint(yyextra->current->name),qPrint(yyextra->msName));
4546 }
4547 if (typedefHidesStruct &&
4548 yyextra->isTypedef &&
4549 (yyextra->current->spec.isStruct() || yyextra->current->spec.isUnion()) &&
4550 yyextra->memspecEntry
4551 ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
4552 {
4553 varEntry->type+=yyextra->memspecEntry->name+yyextra->msType;
4554 }
4555 else // case 2: use _S as type for for pS_t
4556 {
4557 varEntry->type+=yyextra->current->name+yyextra->msType;
4558 }
4559 varEntry->fileName = yyextra->fileName;
4560 varEntry->startLine = yyextra->yyLineNr;
4561 varEntry->startColumn = yyextra->yyColNr;
4562 varEntry->doc = yyextra->current->doc;
4563 varEntry->brief = yyextra->current->brief;
4564 varEntry->mGrpId = yyextra->current->mGrpId;
4565 varEntry->initializer.str(yyextra->current->initializer.str());
4566 varEntry->groups = yyextra->current->groups;
4567 varEntry->sli = yyextra->current->sli;
4568
4569 //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n",
4570 // qPrint(varEntry->type),qPrint(varEntry->name),
4571 // qPrint(varEntry->args),qPrint(varEntry->brief),qPrint(varEntry->doc));
4572 yyextra->current_root->moveToSubEntryAndKeep(varEntry);
4573 }
4574 }
4575 if (*yytext==';') // end of a struct/class ...
4576 {
4577 if (!yyextra->isTypedef && yyextra->msName.isEmpty() && yyextra->memspecEntry && yyextra->current->section.isCompound())
4578 { // case where a class/struct has a doc block after it
4579 if (!yyextra->current->doc.isEmpty())
4580 {
4581 yyextra->memspecEntry->doc += yyextra->current->doc;
4582 }
4583 if (!yyextra->current->brief.isEmpty())
4584 {
4585 yyextra->memspecEntry->brief += yyextra->current->brief;
4586 }
4587 }
4588 yyextra->msType.clear();
4589 yyextra->msName.clear();
4590 yyextra->msArgs.clear();
4591 yyextra->isTypedef=FALSE;
4592 yyextra->firstTypedefEntry.reset();
4593 yyextra->memspecEntry.reset();
4594 yyextra->current->reset();
4595 initEntry(yyscanner);
4596 BEGIN( FindMembers );
4597 }
4598 else
4599 {
4600 yyextra->current->doc.clear();
4601 yyextra->current->brief.clear();
4602 }
4603
4604 }
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
4605<MemberSpec>"=" {
4606 yyextra->lastInitializerContext=YY_START;
4607 yyextra->sharpCount=0;
4608 yyextra->initBracketCount=0;
4609 yyextra->current->initializer.str(yytext);
4610 BEGIN(ReadInitializer);
4611 /* BEGIN(MemberSpecSkip); */
4612 }
4613 /*
4614<MemberSpecSkip>"{" {
4615 yyextra->curlyCount=0;
4616 yyextra->lastCurlyContext = MemberSpecSkip;
4617 yyextra->previous = yyextra->current;
4618 BEGIN(SkipCurly);
4619 }
4620 */
4621<MemberSpecSkip>"," { BEGIN(MemberSpec); }
4622<MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); }
4623<ReadBody,ReadNSBody,ReadBodyIntf>{BN}{1,80} { yyextra->current->program << yytext ;
4624 lineCount(yyscanner) ;
4625 }
4626<ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block
4627 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
4628 initEntry(yyscanner);
4629 yyextra->language = yyextra->current->lang = SrcLangExt::Cpp; // see bug746361
4630 yyextra->insideObjC=FALSE;
4631 BEGIN( FindMembers );
4632 }
4633<ReadBody,ReadNSBody,ReadBodyIntf>\\. { yyextra->current->program << yytext ; }
4634<ReadBody,ReadNSBody,ReadBodyIntf>. { yyextra->current->program << yytext ; }
4635
4636<FindMembers>"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
4637<FindMembers>("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */
4638 if (yyextra->insidePHP) // reference parameter
4639 {
4640 REJECT
4641 }
4642 else
4643 {
4644 yyextra->current->bodyLine = yyextra->yyLineNr;
4645 yyextra->current->bodyColumn = yyextra->yyColNr;
4646 lineCount(yyscanner);
4647 addType(yyscanner);
4648 yyextra->funcPtrType=yytext;
4649 yyextra->roundCount=0;
4650 //yyextra->current->type += yytext;
4651 BEGIN( FuncPtr );
4652 }
4653 }
4654<FuncPtr>{SCOPENAME} {
4655 yyextra->current->name = yytext;
4656 if (nameIsOperator(yyextra->current->name))
4657 {
4658 BEGIN( FuncPtrOperator );
4659 }
4660 else
4661 {
4662 if (yyextra->current->name=="const" || yyextra->current->name=="volatile")
4663 {
4664 yyextra->funcPtrType += yyextra->current->name;
4665 }
4666 else
4667 {
4668 BEGIN( EndFuncPtr );
4669 }
4670 }
4671 }
4672<FuncPtr>. {
4673 //printf("error: FuncPtr '%c' unexpected at line %d of %s\n",*yytext,yyextra->yyLineNr,yyextra->fileName);
4674 }
4675<FuncPtrOperator>"("{BN}*")"{BNopt}/"(" {
4676 yyextra->current->name += yytext;
4677 yyextra->current->name = yyextra->current->name.simplifyWhiteSpace();
4678 lineCount(yyscanner);
4679 }
4680<FuncPtrOperator>\n {
4681 lineCount(yyscanner);
4682 yyextra->current->name += *yytext;
4683 }
4684<FuncPtrOperator>"(" {
4685 unput(*yytext);
4686 BEGIN( EndFuncPtr );
4687 }
4688<FuncPtrOperator>. {
4689 yyextra->current->name += *yytext;
4690 }
4691<EndFuncPtr>")"{BNopt}/";" { // a variable with extra braces
4692 lineCount(yyscanner);
4693 yyextra->current->type+=yyextra->funcPtrType.mid(1);
4694 BEGIN(FindMembers);
4695 }
4696<EndFuncPtr>")"{BNopt}/"(" { // a function pointer
4697 lineCount(yyscanner);
4698 if (yyextra->funcPtrType!="(") // not just redundant braces
4699 {
4700 yyextra->current->type+=yyextra->funcPtrType+")";
4701 }
4702 BEGIN(FindMembers);
4703 }
4704<EndFuncPtr>")"{BNopt}/"[" { // an array of variables
4705 lineCount(yyscanner);
4706 yyextra->current->type+=yyextra->funcPtrType;
4707 yyextra->current->args += ")";
4708 BEGIN(FindMembers);
4709 }
4710<EndFuncPtr>"(" { // a function returning a function or
4711 // a function returning a pointer to an array
4712 yyextra->current->args += *yytext ;
4713 //yyextra->roundCount=0;
4714 //BEGIN( FuncFunc );
4715 yyextra->current->bodyLine = yyextra->yyLineNr;
4716 yyextra->current->bodyColumn = yyextra->yyColNr;
4717 yyextra->currentArgumentContext = FuncFuncEnd;
4718 yyextra->fullArgString=yyextra->current->args;
4719 yyextra->copyArgString=&yyextra->current->args;
4720 BEGIN( ReadFuncArgType ) ;
4721 }
4722<EndFuncPtr>"["[^\n\]]*"]" {
4723 yyextra->funcPtrType+=yytext;
4724 }
4725<EndFuncPtr>")" {
4726 BEGIN(FindMembers);
4727 }
4728<FuncFunc>"(" {
4729 yyextra->current->args += *yytext ;
4730 ++yyextra->roundCount;
4731 }
4732<FuncFunc>")" {
4733 yyextra->current->args += *yytext ;
4734 if ( yyextra->roundCount )
4735 --yyextra->roundCount;
4736 else
4737 {
4738 BEGIN(FuncFuncEnd);
4739 }
4740 }
4741<FuncFuncEnd>")"{BN}*"(" {
4742 lineCount(yyscanner);
4743 yyextra->current->type+=yyextra->funcPtrType+")(";
4744 BEGIN(FuncFuncType);
4745 }
4746<FuncFuncEnd>")"{BNopt}/[;{] {
4747 lineCount(yyscanner);
4748 yyextra->current->type+=yyextra->funcPtrType.mid(1);
4749 BEGIN(SFunction);
4750 }
4751<FuncFuncEnd>")"{BNopt}/"[" { // function returning a pointer to an array
4752 lineCount(yyscanner);
4753 yyextra->current->type+=yyextra->funcPtrType;
4754 yyextra->current->args+=")";
4755 BEGIN(FuncFuncArray);
4756 }
4757<FuncFuncEnd>. {
4758 yyextra->current->args += *yytext;
4759 }
4760<FuncFuncType>"(" {
4761 yyextra->current->type += *yytext;
4762 yyextra->roundCount++;
4763 }
4764<FuncFuncType>")" {
4765 yyextra->current->type += *yytext;
4766 if (yyextra->roundCount)
4767 --yyextra->roundCount;
4768 else
4769 BEGIN(SFunction);
4770 }
4771<FuncFuncType>{BN}*","{BN}* { lineCount(yyscanner) ; yyextra->current->type += ", " ; }
4772<FuncFuncType>{BN}+ { lineCount(yyscanner) ; yyextra->current->type += ' ' ; }
4773<FuncFuncType>. {
4774 yyextra->current->type += *yytext;
4775 }
4776<FindMembers>"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")"{BN}*"(" { // for catching typedef void (__stdcall *f)() like definitions
4777 if (yyextra->current->type.startsWith("typedef") &&
4778 yyextra->current->bodyLine==-1)
4779 // the bodyLine check is to prevent this guard to be true more than once
4780 {
4781 yyextra->current->bodyLine = yyextra->yyLineNr;
4782 yyextra->current->bodyColumn = yyextra->yyColNr;
4783 BEGIN( GetCallType );
4784 }
4785 else if (!yyextra->current->name.isEmpty()) // normal function
4786 {
4787 yyextra->current->args = yytext;
4788 yyextra->current->bodyLine = yyextra->yyLineNr;
4789 yyextra->current->bodyColumn = yyextra->yyColNr;
4790 yyextra->currentArgumentContext = FuncQual;
4791 yyextra->fullArgString=yyextra->current->args;
4792 yyextra->copyArgString=&yyextra->current->args;
4793 BEGIN( ReadFuncArgType ) ;
4794 //printf(">>> Read function arguments!\n");
4795 }
4796 }
4797<GetCallType>{BN}*{ID}{BN}*"*" {
4798 lineCount(yyscanner);
4799 addType(yyscanner);
4800 yyextra->funcPtrType="(";
4801 yyextra->funcPtrType+=yytext;
4802 yyextra->roundCount=0;
4803 BEGIN( FuncPtr );
4804 }
4805<FindMembers>"(" {
4806 if (!yyextra->current->name.isEmpty())
4807 {
4808 yyextra->current->args = yytext;
4809 yyextra->current->bodyLine = yyextra->yyLineNr;
4810 yyextra->current->bodyColumn = yyextra->yyColNr;
4811 yyextra->currentArgumentContext = FuncQual;
4812 yyextra->fullArgString=yyextra->current->args;
4813 yyextra->copyArgString=&yyextra->current->args;
4814 BEGIN( ReadFuncArgType ) ;
4815 //printf(">>> Read function arguments yyextra->current->argList.size()=%d\n",yyextra->current->argList.size());
4816 }
4817 }
4818 /*
4819<FindMembers>"("{BN}*("void"{BN}*)?")" {
4820 lineCount(yyscanner);
4821 yyextra->current->args = "()";
4822 BEGIN( FuncQual );
4823 }
4824 */
4825
4826 /*- Function argument reading rules ---------------------------------------*/
4827
4828<ReadFuncArgType>[^ \/\r\t\n\[\]\‍)\‍(\"\'#]+ { *yyextra->copyArgString+=yytext;
4829 if (yyextra->insideCS) yyextra->fullArgString+=substitute(yytext,".","::");
4830 else yyextra->fullArgString+=yytext;
4831 }
4832<CopyArgString,CopyArgPHPString>[^\n\\\"\']+ { *yyextra->copyArgString+=yytext;
4833 yyextra->fullArgString+=yytext;
4834 }
4835<CopyArgRound>[^\/\n\‍)\‍(\"\']+ {
4836 *yyextra->copyArgString+=yytext;
4837 yyextra->fullArgString+=yytext;
4838 }
4839<CopyArgSquare>[^\/\n\]\[\"\']+ {
4840 *yyextra->copyArgString+=yytext;
4841 yyextra->fullArgString+=yytext;
4842 }
4843<ReadFuncArgType,ReadTempArgs>{BN}* {
4844 *yyextra->copyArgString+=" ";
4845 yyextra->fullArgString+=" ";
4846 lineCount(yyscanner);
4847 }
4848<ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>{RAWBEGIN} {
4849 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
4850 yyextra->lastRawStringContext = YY_START;
4851 yyextra->pCopyRawString = yyextra->copyArgString;
4852 *yyextra->pCopyRawString+=yytext;
4853 yyextra->fullArgString+=yytext;
4854 BEGIN(RawString);
4855 }
4856<ReadFuncArgType,CopyArgRound,CopyArgSquare,CopyArgSharp,ReadTempArgs>\" {
4857 *yyextra->copyArgString+=*yytext;
4858 yyextra->fullArgString+=*yytext;
4859 yyextra->lastCopyArgStringContext = YY_START;
4860 BEGIN( CopyArgString );
4861 }
4862<ReadFuncArgType>"[" {
4863 if (!yyextra->insidePHP) REJECT;
4864 *yyextra->copyArgString+=*yytext;
4865 yyextra->fullArgString+=*yytext;
4866 yyextra->argSquareCount=0;
4867 yyextra->lastCopyArgContext = YY_START;
4868 BEGIN( CopyArgSquare );
4869 }
4870<ReadFuncArgType,ReadTempArgs>"(" {
4871 *yyextra->copyArgString+=*yytext;
4872 yyextra->fullArgString+=*yytext;
4873 yyextra->argRoundCount=0;
4874 yyextra->lastCopyArgContext = YY_START;
4875 BEGIN( CopyArgRound );
4876 }
4877<ReadFuncArgType>")" {
4878 *yyextra->copyArgString+=*yytext;
4879 yyextra->fullArgString+=*yytext;
4880 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4881 if (yyextra->insideJS)
4882 {
4883 fixArgumentListForJavaScript(yyextra->current->argList);
4884 }
4885 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
4886
4887 /* remember the yyextra->current documentation block, since
4888 we could overwrite it with the documentation of
4889 a function argument, which we then have to correct later
4890 on
4891 */
4892 yyextra->docBackup = yyextra->current->doc;
4893 yyextra->briefBackup = yyextra->current->brief;
4894
4895 BEGIN( yyextra->currentArgumentContext );
4896 }
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:814
4897 /* a special comment */
4898<ReadFuncArgType,ReadTempArgs>({CCS}[*!]|{CPPC}[/!])("<"?) {
4899 if (yyextra->currentArgumentContext==DefineEnd)
4900 {
4901 // for defines we interpret a comment
4902 // as documentation for the define
4903 int i;for (i=(int)yyleng-1;i>=0;i--)
4904 {
4905 unput(yytext[i]);
4906 }
4907 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4908 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
4909 BEGIN( yyextra->currentArgumentContext );
4910 }
4911 else // not a define
4912 {
4913 // for functions we interpret a comment
4914 // as documentation for the argument
4915 yyextra->fullArgString+=yytext;
4916 yyextra->lastCopyArgChar=0;
4917 yyextra->lastCommentInArgContext=YY_START;
4918 if (yytext[1]=='/')
4919 BEGIN( CopyArgCommentLine );
4920 else
4921 BEGIN( CopyArgComment );
4922 }
4923 }
4924 /* a non-special comment */
4925<ReadFuncArgType,ReadTempArgs>{CCS}{CCE} { /* empty comment */ }
4926<ReadFuncArgType,ReadTempArgs>{CCS} {
4927 yyextra->lastCContext = YY_START;
4928 BEGIN( SkipComment );
4929 }
4930<ReadFuncArgType,ReadTempArgs>{CPPC} {
4931 yyextra->lastCContext = YY_START;
4932 BEGIN( SkipCxxComment );
4933 }
4934 /*
4935<ReadFuncArgType,ReadTempArgs>"'#" { if (yyextra->insidePHP)
4936 REJECT;
4937 *yyextra->copyArgString+=yytext;
4938 yyextra->fullArgString+=yytext;
4939 }
4940<ReadFuncArgType,ReadTempArgs>"#" {
4941 if (!yyextra->insidePHP)
4942 REJECT;
4943 yyextra->lastCContext = YY_START;
4944 BEGIN( SkipCxxComment );
4945 }
4946 */
4947 /* ')' followed by a special comment */
4948<ReadFuncArgType>")"{BN}*({CCS}[*!]|{CPPC}[/!])"<" {
4949 lineCount(yyscanner);
4950 if (yyextra->currentArgumentContext==DefineEnd)
4951 {
4952 // for defines we interpret a comment
4953 // as documentation for the define
4954 int i;for (i=(int)yyleng-1;i>0;i--)
4955 {
4956 unput(yytext[i]);
4957 }
4958 *yyextra->copyArgString+=*yytext;
4959 yyextra->fullArgString+=*yytext;
4960 yyextra->current->argList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
4961 handleParametersCommentBlocks(yyscanner,yyextra->current->argList);
4962 BEGIN( yyextra->currentArgumentContext );
4963 }
4964 else
4965 {
4966 // for functions we interpret a comment
4967 // as documentation for the yyextra->last argument
4968 yyextra->lastCopyArgChar=*yytext;
4969 QCString text=&yytext[1];
4970 text=text.stripWhiteSpace();
4971 yyextra->lastCommentInArgContext=YY_START;
4972 yyextra->fullArgString+=text;
4973 if (text.find("//")!=-1)
4974 BEGIN( CopyArgCommentLine );
4975 else
4976 BEGIN( CopyArgComment );
4977 }
4978 }
4979<CopyArgComment>^{B}*"*"+/{BN}+
4980<CopyArgComment>[^\n\\\@\*]+ { yyextra->fullArgString+=yytext; }
4981<CopyArgComment>{CCE} { yyextra->fullArgString+=yytext;
4982 if (yyextra->lastCopyArgChar!=0)
4983 unput(yyextra->lastCopyArgChar);
4984 BEGIN( yyextra->lastCommentInArgContext );
4985 }
4986<CopyArgCommentLine>\n { yyextra->fullArgString+=yytext;
4987 lineCount(yyscanner);
4988 if (yyextra->lastCopyArgChar!=0)
4989 unput(yyextra->lastCopyArgChar);
4990 BEGIN( yyextra->lastCommentInArgContext );
4991 }
4992<CopyArgCommentLine>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
4993 yyextra->docBlockName="uml";
4994 yyextra->fullArgString+=yytext;
4995 BEGIN(CopyArgVerbatim);
4996 }
4997<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!)
4998 yyextra->docBlockName=&yytext[1];
4999 yyextra->fullArgString+=yytext;
5000 BEGIN(CopyArgVerbatim);
5001 }
5002<CopyArgCommentLine>{CMD}("f$"|"f["|"f{"|"f(") {
5003 yyextra->docBlockName=&yytext[1];
5004 if (yyextra->docBlockName.at(1)=='[')
5005 {
5006 yyextra->docBlockName.at(1)=']';
5007 }
5008 if (yyextra->docBlockName.at(1)=='{')
5009 {
5010 yyextra->docBlockName.at(1)='}';
5011 }
5012 if (yyextra->docBlockName.at(1)=='(')
5013 {
5014 yyextra->docBlockName.at(1)=')';
5015 }
5016 yyextra->fullArgString+=yytext;
5017 BEGIN(CopyArgVerbatim);
5018 }
5019<CopyArgVerbatim>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9\-] { // end of verbatim block
5020 yyextra->fullArgString+=yytext;
5021 if (&yytext[4]==yyextra->docBlockName)
5022 {
5023 yyextra->docBlockName="";
5024 BEGIN(CopyArgCommentLine);
5025 }
5026 }
5027<CopyArgVerbatim>[\\@]("f$"|"f]"|"f}"|"f)") { // end of verbatim block
5028 yyextra->fullArgString+=yytext;
5029 if (yyextra->docBlockName==&yytext[1])
5030 {
5031 yyextra->docBlockName="";
5032 BEGIN(CopyArgCommentLine);
5033 }
5034 }
5035<CopyArgCommentLine>[^\\\@\n]+ { yyextra->fullArgString+=yytext; }
5036<CopyArgCommentLine>. { yyextra->fullArgString+=*yytext; }
5037<CopyArgComment,CopyArgVerbatim>\n { yyextra->fullArgString+=*yytext; lineCount(yyscanner); }
5038<CopyArgComment,CopyArgVerbatim>. { yyextra->fullArgString+=*yytext; }
5039<CopyArgComment>{CMD}("brief"|"short"){B}+ {
5040 warn(yyextra->fileName,yyextra->yyLineNr,
5041 "Ignoring {:c}brief command inside argument documentation",*yytext
5042 );
5043 yyextra->fullArgString+=' ';
5044 }
#define warn(file, line, fmt,...)
Definition message.h:97
5045<ReadTempArgs>"<" {
5046 *yyextra->copyArgString+=*yytext;
5047 yyextra->fullArgString+=*yytext;
5048 yyextra->argSharpCount=1;
5049 BEGIN( CopyArgSharp );
5050 }
5051<ReadTempArgs>">" {
5052 *yyextra->copyArgString+=*yytext;
5053 yyextra->fullArgString+=*yytext;
5054 //printf("end template list '%s'\n",qPrint(*yyextra->copyArgString));
5055 *yyextra->currentArgumentList = *stringToArgumentList(yyextra->language, yyextra->fullArgString);
5056 handleParametersCommentBlocks(yyscanner,yyextra->current->tArgLists.back());
5057 BEGIN( yyextra->currentArgumentContext );
5058 }
5059<CopyArgRound>"(" {
5060 yyextra->argRoundCount++;
5061 *yyextra->copyArgString+=*yytext;
5062 yyextra->fullArgString+=*yytext;
5063 }
5064<CopyArgRound>")" {
5065 *yyextra->copyArgString+=*yytext;
5066 yyextra->fullArgString+=*yytext;
5067 if (yyextra->argRoundCount>0)
5068 yyextra->argRoundCount--;
5069 else
5070 BEGIN( yyextra->lastCopyArgContext );
5071 }
5072<CopyArgSquare>"[" {
5073 yyextra->argSquareCount++;
5074 *yyextra->copyArgString+=*yytext;
5075 yyextra->fullArgString+=*yytext;
5076 }
5077<CopyArgSquare>"]" {
5078 *yyextra->copyArgString+=*yytext;
5079 yyextra->fullArgString+=*yytext;
5080 if (yyextra->argSquareCount>0)
5081 yyextra->argSquareCount--;
5082 else
5083 BEGIN( yyextra->lastCopyArgContext );
5084 }
5085<CopyArgSharp>"(" {
5086 *yyextra->copyArgString+=*yytext;
5087 yyextra->fullArgString+=*yytext;
5088 yyextra->argRoundCount=0;
5089 yyextra->lastCopyArgContext = YY_START;
5090 BEGIN( CopyArgRound );
5091 }
5092<CopyArgSharp>"<" {
5093 yyextra->argSharpCount++;
5094 //printf("yyextra->argSharpCount++=%d copy\n",yyextra->argSharpCount);
5095 *yyextra->copyArgString+=*yytext;
5096 yyextra->fullArgString+=*yytext;
5097 }
5098<CopyArgSharp>">" {
5099 *yyextra->copyArgString+=*yytext;
5100 yyextra->fullArgString+=*yytext;
5101 yyextra->argSharpCount--;
5102 if (yyextra->argSharpCount>0)
5103 {
5104 //printf("yyextra->argSharpCount--=%d copy\n",yyextra->argSharpCount);
5105 }
5106 else
5107 {
5108 BEGIN( ReadTempArgs );
5109 //printf("end of yyextra->argSharpCount\n");
5110 }
5111 }
5112<CopyArgString,CopyArgPHPString>\\. {
5113 *yyextra->copyArgString+=yytext;
5114 yyextra->fullArgString+=yytext;
5115 }
5116<CopyArgString>\" {
5117 *yyextra->copyArgString+=*yytext;
5118 yyextra->fullArgString+=*yytext;
5119 BEGIN( yyextra->lastCopyArgStringContext );
5120 }
5121<CopyArgPHPString>\' {
5122 *yyextra->copyArgString+=*yytext;
5123 yyextra->fullArgString+=*yytext;
5124 BEGIN( yyextra->lastCopyArgStringContext );
5125 }
5126<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>{CHARLIT} {
5127 if (yyextra->insidePHP)
5128 {
5129 REJECT;
5130 }
5131 else
5132 {
5133 *yyextra->copyArgString+=yytext;
5134 yyextra->fullArgString+=yytext;
5135 }
5136 }
5137<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSquare,CopyArgSharp>\' {
5138 *yyextra->copyArgString+=yytext;
5139 yyextra->fullArgString+=yytext;
5140 if (yyextra->insidePHP)
5141 {
5142 yyextra->lastCopyArgStringContext=YY_START;
5143 BEGIN(CopyArgPHPString);
5144 }
5145 }
5146<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>"<="|">="|"<=>" {
5147 *yyextra->copyArgString+=yytext;
5148 yyextra->fullArgString+=yytext;
5149 }
5150<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>\n {
5151 lineCount(yyscanner);
5152 *yyextra->copyArgString+=*yytext;
5153 yyextra->fullArgString+=*yytext;
5154 }
5155<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>{ID} {
5156 *yyextra->copyArgString+=yytext;
5157 yyextra->fullArgString+=yytext;
5158 }
5159<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSquare,CopyArgSharp>. {
5160 *yyextra->copyArgString+=*yytext;
5161 yyextra->fullArgString+=*yytext;
5162 }
5163
5164
5165
5166 /*------------------------------------------------------------------------*/
5167
5168
5169<FuncRound>"(" { yyextra->current->args += *yytext ;
5170 ++yyextra->roundCount ;
5171 }
5172<FuncRound>")" { yyextra->current->args += *yytext ;
5173 if ( yyextra->roundCount )
5174 --yyextra->roundCount ;
5175 else
5176 BEGIN( FuncQual ) ;
5177 }
5178 /*
5179<FuncQual>"#" { if (yyextra->insidePHP)
5180 REJECT;
5181 yyextra->lastCPPContext = YY_START;
5182 BEGIN(SkipCPP);
5183 }
5184 */
5185<FuncQual>[{:;,] {
5186 if ( qstrcmp(yytext,";")==0 &&
5187 ((yyextra->insideJS || yyextra->insidePHP) &&
5188 !containsWord(yyextra->current->type,"function")) )
5189 {
5190 yyextra->current->reset();
5191 initEntry(yyscanner);
5192 BEGIN( FindMembers );
5193 }
5194 else
5195 {
5196 unput(*yytext); BEGIN( SFunction );
5197 }
5198 }
bool containsWord(const QCString &str, const char *word)
returns TRUE iff string s contains word w
Definition util.cpp:5481
5199<FuncQual>{BN}*"abstract"{BN}* { // pure virtual member function
5200 lineCount(yyscanner) ;
5201 yyextra->current->virt = Specifier::Pure;
5202 yyextra->current->args += " override ";
5203 }
5204<FuncQual,TrailingReturn>{BN}*"override"{BN}* { // C++11 overridden virtual member function
5205 lineCount(yyscanner) ;
5206 yyextra->current->spec.setOverride(true);
5207 yyextra->current->args += " override ";
5208 BEGIN(FuncQual);
5209 }
5210<FuncQual,TrailingReturn>{BN}*"final"{BN}* { // C++11 final method
5211 lineCount(yyscanner) ;
5212 yyextra->current->spec.setFinal(true);
5213 yyextra->current->args += " final ";
5214 BEGIN(FuncQual);
5215 }
5216<FuncQual>{BN}*"sealed"{BN}* { // sealed member function
5217 lineCount(yyscanner) ;
5218 yyextra->current->spec.setSealed(true);
5219 yyextra->current->args += " sealed ";
5220 }
5221<FuncQual>{BN}*"new"{BN}* { // new member function
5222 lineCount(yyscanner) ;
5223 yyextra->current->spec.setNew(true);
5224 yyextra->current->args += " new ";
5225 }
5226<FuncQual>{BN}*"const"{BN}* { // const member function
5227 lineCount(yyscanner) ;
5228 yyextra->current->args += " const ";
5229 yyextra->current->argList.setConstSpecifier(TRUE);
5230 }
5231<FuncQual>{BN}*"volatile"{BN}* { // volatile member function
5232 lineCount(yyscanner) ;
5233 yyextra->current->args += " volatile ";
5234 yyextra->current->argList.setVolatileSpecifier(TRUE);
5235 }
5236<FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier
5237 lineCount(yyscanner) ;
5238 yyextra->current->args += " noexcept ";
5239 yyextra->current->spec.setNoExcept(true);
5240 }
5241<FuncQual>{BN}*"noexcept"{BN}*"("{B}*false{B}*")"{BN}* { // noexcept(false) expression
5242 lineCount(yyscanner) ;
5243 yyextra->current->args += " noexcept(false)";
5244 }
5245<FuncQual>{BN}*"noexcept"{BN}*"(" { // noexcept expression
5246 lineCount(yyscanner) ;
5247 yyextra->current->args += " noexcept(";
5248 yyextra->current->spec.setNoExcept(true);
5249 yyextra->lastRoundContext=FuncQual;
5250 yyextra->pCopyRoundString=&yyextra->current->args;
5251 yyextra->roundCount=0;
5252 BEGIN(CopyRound);
5253 }
5254<FuncQual>{BN}*"&" {
5255 yyextra->current->args += " &";
5256 yyextra->current->argList.setRefQualifier(RefQualifierType::LValue);
5257 }
5258<FuncQual>{BN}*"&&" {
5259 yyextra->current->args += " &&";
5260 yyextra->current->argList.setRefQualifier(RefQualifierType::RValue);
5261 }
5262
5263<FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function
5264 lineCount(yyscanner) ;
5265 yyextra->current->args += " = 0";
5266 yyextra->current->virt = Specifier::Pure;
5267 yyextra->current->argList.setPureSpecifier(TRUE);
5268 BEGIN(FuncQual);
5269 }
5270<FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member
5271 lineCount(yyscanner);
5272 yyextra->current->args += " = delete";
5273 yyextra->current->spec.setDelete(true);
5274 yyextra->current->argList.setIsDeleted(TRUE);
5275 BEGIN(FuncQual);
5276 }
5277<FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator
5278 lineCount(yyscanner);
5279 yyextra->current->args += " = default";
5280 yyextra->current->spec.setDefault(true);
5281 BEGIN(FuncQual);
5282 }
5283<FuncQual>{BN}*"->"{BN}* {
5284 lineCount(yyscanner);
5285 yyextra->current->argList.setTrailingReturnType(" -> ");
5286 yyextra->current->args += " -> ";
5287 yyextra->roundCount=0;
5288 BEGIN(TrailingReturn);
5289 }
5290<TrailingReturn>[{;] {
5291 if (yyextra->roundCount>0) REJECT;
5292 unput(*yytext);
5293 BEGIN(FuncQual);
5294 }
5295<TrailingReturn>"requires"{BN}+ {
5296 if (yyextra->insideJava) REJECT;
5297 yyextra->requiresContext = FuncQual;
5298 yyextra->current->req+=' ';
5299 BEGIN(RequiresClause);
5300 }
5301<TrailingReturn>"(" {
5302 yyextra->roundCount++;
5303 yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
5304 yyextra->current->args+=yytext;
5305 }
5306<TrailingReturn>")" {
5307 if (yyextra->roundCount>0)
5308 {
5309 yyextra->roundCount--;
5310 }
5311 else
5312 {
5313 warn(yyextra->fileName,yyextra->yyLineNr,
5314 "Found ')' without opening '(' for trailing return type '{})...'",
5315 yyextra->current->argList.trailingReturnType());
5316 }
5317 yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
5318 yyextra->current->args+=yytext;
5319 }
5320<TrailingReturn>. {
5321 yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
5322 yyextra->current->args+=yytext;
5323 }
5324<TrailingReturn>\n {
5325 lineCount(yyscanner);
5326 yyextra->current->argList.setTrailingReturnType(yyextra->current->argList.trailingReturnType()+yytext);
5327 yyextra->current->args+=' ';
5328 }
5329<FuncRound,FuncFunc>{BN}*","{BN}* {
5330 lineCount(yyscanner) ;
5331 yyextra->current->args += ", " ;
5332 }
5333<FuncQual,FuncRound,FuncFunc>{BN}+ {
5334 lineCount(yyscanner) ;
5335 yyextra->current->args += ' ' ;
5336 }
5337<SFunction,FuncQual,FuncRound,FuncFunc>"#" { if (yyextra->insidePHP)
5338 REJECT;
5339 yyextra->lastCPPContext = YY_START;
5340 BEGIN(SkipCPP);
5341 }
5342<FuncQual>"=" {
5343 if (yyextra->insideCli && yyextra->current_root->section.isCompound())
5344 {
5345 BEGIN(CliOverride);
5346 }
5347 else
5348 {
5349 // typically an initialized function pointer
5350 yyextra->lastInitializerContext=YY_START;
5351 yyextra->sharpCount=0;
5352 yyextra->initBracketCount=0;
5353 yyextra->current->initializer.str(yytext);
5354 BEGIN(ReadInitializer);
5355 }
5356 }
5357<CliOverride>{ID} {
5358 }
5359<CliOverride>"{" {
5360 unput(*yytext);
5361 BEGIN(FuncQual);
5362 }
5363<CliOverride>\n {
5364 lineCount(yyscanner);
5365 }
5366<CliOverride>. {
5367 }
5368<FuncQual>{ID} {
5369 if (yyextra->insideCpp && qstrcmp(yytext,"requires")==0)
5370 {
5371 // c++20 trailing requires clause
5372 yyextra->requiresContext = YY_START;
5373 yyextra->current->req+=' ';
5374 BEGIN(RequiresClause);
5375 }
5376 else if (yyextra->insideCS && qstrcmp(yytext,"where")==0)
5377 {
5378 // type constraint for a method
5379 yyextra->current->typeConstr.clear();
5380 yyextra->current->typeConstr.push_back(Argument());
5381 yyextra->lastCSConstraint = YY_START;
5382 BEGIN( CSConstraintName );
5383 }
5384 else if (checkForKnRstyleC(yyscanner)) // K&R style C function
5385 {
5386 yyextra->current->args = yytext;
5387 yyextra->oldStyleArgType.clear();
5388 BEGIN(OldStyleArgs);
5389 }
5390 else
5391 {
5392 yyextra->current->args += yytext;
5393 }
5394 }
5395<OldStyleArgs>[,;] {
5396 QCString oldStyleArgPtr;
5397 QCString oldStyleArgName;
5398 splitKnRArg(yyscanner,oldStyleArgPtr,oldStyleArgName);
5399 QCString doc,brief;
5400 if (yyextra->current->doc!=yyextra->docBackup)
5401 {
5402 doc=yyextra->current->doc;
5403 yyextra->current->doc=yyextra->docBackup;
5404 }
5405 if (yyextra->current->brief!=yyextra->briefBackup)
5406 {
5407 brief=yyextra->current->brief;
5408 yyextra->current->brief=yyextra->briefBackup;
5409 }
5410 addKnRArgInfo(yyscanner,yyextra->oldStyleArgType+oldStyleArgPtr,
5411 oldStyleArgName,brief,doc);
5412 yyextra->current->args.clear();
5413 if (*yytext==';') yyextra->oldStyleArgType.clear();
5414 }
5415<OldStyleArgs>{ID} { yyextra->current->args += yytext; }
5416<OldStyleArgs>"{" {
5417 if (yyextra->current->argList.empty())
5418 {
5419 yyextra->current->argList.setNoParameters(TRUE);
5420 }
5421 yyextra->current->args = argListToString(yyextra->current->argList);
5422 unput('{');
5423 BEGIN(FuncQual);
5424 }
5425<OldStyleArgs>. { yyextra->current->args += *yytext; }
5426<FuncQual,FuncRound,FuncFunc>\" {
5427 if (yyextra->insideIDL && yyextra->insideCppQuote)
5428 {
5429 BEGIN(EndCppQuote);
5430 }
5431 else
5432 {
5433 yyextra->current->args += *yytext;
5434 }
5435 }
5436<FuncQual,FuncRound,FuncFunc>. { yyextra->current->args += *yytext; }
5437<FuncQual>{BN}*"try:" |
5438<FuncQual>{BN}*"try"{BN}+ { /* try-function-block */
5439 yyextra->insideTryBlock=TRUE;
5440 lineCount(yyscanner);
5441 if (yytext[yyleng-1]==':')
5442 {
5443 unput(':');
5444 BEGIN( SFunction );
5445 }
5446 }
5447<FuncQual>{BN}*"throw"{BN}*"(" { // C++ style throw clause
5448 yyextra->current->exception = " throw (" ;
5449 yyextra->roundCount=0;
5450 lineCount(yyscanner) ;
5451 BEGIN( ExcpRound ) ;
5452 }
5453<FuncQual>{BN}*"raises"{BN}*"(" {
5454 yyextra->current->exception = " raises (" ;
5455 lineCount(yyscanner) ;
5456 yyextra->roundCount=0;
5457 BEGIN( ExcpRound ) ;
5458 }
5459<FuncQual>{BN}*"throws"{BN}+ { // Java style throw clause
5460 yyextra->current->exception = " throws " ;
5461 lineCount(yyscanner) ;
5462 BEGIN( ExcpList );
5463 }
5464<ExcpRound>"(" { yyextra->current->exception += *yytext ;
5465 ++yyextra->roundCount ;
5466 }
5467<ExcpRound>")" { yyextra->current->exception += *yytext ;
5468 if ( yyextra->roundCount )
5469 --yyextra->roundCount ;
5470 else
5471 BEGIN( FuncQual ) ;
5472 }
5473<ExcpRound>. {
5474 yyextra->current->exception += *yytext;
5475 }
5476<ExcpList>"{" {
5477 unput('{'); BEGIN( FuncQual );
5478 }
5479<ExcpList>";" {
5480 unput(';'); BEGIN( FuncQual );
5481 }
5482<ExcpList>"\n" {
5483 yyextra->current->exception += ' ';
5484 lineCount(yyscanner);
5485 }
5486<ExcpList>. {
5487 yyextra->current->exception += *yytext;
5488 }
5489<SFunction>"(" { yyextra->current->type += yyextra->current->name ;
5490 yyextra->current->name = yyextra->current->args ;
5491 yyextra->current->args = yytext ;
5492 yyextra->roundCount=0;
5493 BEGIN( FuncRound ) ;
5494 }
5495<SFunction>":" {
5496 if (!yyextra->insidePHP) BEGIN(SkipInits);
5497 }
5498<SFunction>[;{,] {
5499 yyextra->current->name=removeRedundantWhiteSpace(yyextra->current->name);
5500 yyextra->current->type=removeRedundantWhiteSpace(yyextra->current->type);
5501 yyextra->current->args=removeRedundantWhiteSpace(yyextra->current->args);
5502 yyextra->current->fileName = yyextra->fileName;
5503 yyextra->current->startLine = yyextra->yyBegLineNr;
5504 yyextra->current->startColumn = yyextra->yyBegColNr;
5505 static const reg::Ex re(R"(\‍([^)]*[*&][^)]*\))"); // e.g. (...*...)
5507 std::string type = yyextra->current->type.str();
5508 int ti=-1;
5509 if (reg::search(type,match,re))
5510 {
5511 ti = (int)match.position();
5512 }
5513 if (ti!=-1)
5514 {
5515 int di = yyextra->current->type.find("decltype(");
5516 if (di!=-1 && di<ti) // decltype(...(...*...) -> normal return type
5517 {
5518 ti=-1;
5519 }
5520 }
5521 int ts=yyextra->current->type.find('<');
5522 int te=yyextra->current->type.findRev('>');
5523
5524 // bug677315: A<int(void *, char *)> get(); is not a function pointer
5525 bool startsWithTypedef = yyextra->current->type.startsWith("typedef ");
5526 bool isFunction = ti==-1 || // not a (...*...) pattern
5527 (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list
5528 bool isVariable = !yyextra->current->type.isEmpty() &&
5529 (!isFunction || startsWithTypedef);
5530
5531 //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n",
5532 // qPrint(yyextra->current->type),ts,te,ti,isFunction);
5533
5534 if (*yytext!=';' || yyextra->current_root->section.isCompound())
5535 {
5536 if (isVariable)
5537 {
5538 //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5539 if (yyextra->isTypedef && !startsWithTypedef)
5540 {
5541 yyextra->current->type.prepend("typedef ");
5542 }
5543 yyextra->current->section = EntryType::makeVariable() ;
5544 }
5545 else
5546 {
5547 //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5548 yyextra->current->section = EntryType::makeFunction() ;
5549 yyextra->current->proto = *yytext==';';
5550 }
5551 }
5552 else // a global function prototype or function variable
5553 {
5554 //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(yyextra->current->args));
5555 if (isVariable)
5556 {
5557 if (yyextra->isTypedef && !startsWithTypedef)
5558 {
5559 yyextra->current->type.prepend("typedef ");
5560 }
5561 //printf("Scanner.l: found function variable!\n");
5562 yyextra->current->section = EntryType::makeVariable();
5563 }
5564 else
5565 {
5566 //printf("Scanner.l: found prototype\n");
5567 yyextra->current->section = EntryType::makeFunction();
5568 yyextra->current->proto = TRUE;
5569 }
5570 }
5571 //printf("Adding entry '%s'\n",qPrint(yyextra->current->name));
5572 if ( yyextra->insidePHP)
5573 {
5574 if (findAndRemoveWord(yyextra->current->type,"final"))
5575 {
5576 yyextra->current->spec.setFinal(true);
5577 }
5578 if (findAndRemoveWord(yyextra->current->type,"abstract"))
5579 {
5580 yyextra->current->spec.setAbstract(true);
5581 }
5582 }
5583 if ( yyextra->insidePHP && !containsWord(yyextra->current->type,"function"))
5584 {
5585 initEntry(yyscanner);
5586 if ( *yytext == '{' )
5587 {
5588 yyextra->lastCurlyContext = FindMembers;
5589 yyextra->curlyCount=0;
5590 BEGIN( SkipCurly );
5591 }
5592 else
5593 {
5594 BEGIN( FindMembers );
5595 }
5596 }
5597 else
5598 {
5599 if ( yyextra->insidePHP)
5600 {
5601 findAndRemoveWord(yyextra->current->type,"function");
5602 }
5603 yyextra->previous = yyextra->current;
5604 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
5605 initEntry(yyscanner);
5606 // Objective C 2.0: Required/Optional section
5607 if (yyextra->previous->spec.isOptional() || yyextra->previous->spec.isRequired())
5608 {
5609 yyextra->current->spec.setOptional(true).setRequired(true);
5610 }
5611 yyextra->lastCurlyContext = FindMembers;
5612 if ( *yytext == ',' )
5613 {
5614 yyextra->current->type = stripFuncPtr(yyextra->previous->type);
5615 }
5616 if ( *yytext == '{' )
5617 {
5618 if ( !yyextra->insidePHP && yyextra->current_root->section.isCompound() )
5619 {
5620 yyextra->previous->spec.setInline(true);
5621 }
5622 //addToBody(yytext);
5623 yyextra->curlyCount=0;
5624 BEGIN( SkipCurly ) ;
5625 }
5626 else
5627 {
5628 if (!yyextra->previous->section.isVariable())
5629 yyextra->previous->bodyLine=-1; // a function/member declaration
5630 BEGIN( FindMembers ) ;
5631 }
5632 }
5633 }
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:5497
5634<SkipInits>">"{BN}*"{" { // C++11 style initializer (see bug 790788)
5635 lineCount(yyscanner);
5636 yyextra->curlyCount=1;
5637 BEGIN(SkipC11Inits);
5638 }
5639<SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647)
5640 lineCount(yyscanner);
5641 yyextra->curlyCount=1;
5642 BEGIN(SkipC11Inits);
5643 }
5644<SkipC11Inits>"{" {
5645 ++yyextra->curlyCount;
5646 }
5647<SkipC11Inits>"}" {
5648 if ( --yyextra->curlyCount<=0 )
5649 {
5650 BEGIN(SkipInits);
5651 }
5652 }
5653<SkipC11Attribute>"]]" {
5654 BEGIN(yyextra->lastC11AttributeContext);
5655 }
5656<SkipInits>"{" { // C++11 style initializer
5657 unput('{');
5658 BEGIN( SFunction );
5659 }
5660<SkipCurly>"{" {
5661 //addToBody(yytext);
5662 ++yyextra->curlyCount ;
5663 }
5664<SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */)
5665<SkipCurly>"}" {
5666 //addToBody(yytext);
5667 if( yyextra->curlyCount )
5668 {
5669 --yyextra->curlyCount ;
5670 }
5671 else
5672 {
5673 if (!yyextra->current->sli.empty() && yyextra->previous) // copy special list items
5674 {
5675 yyextra->previous->sli = yyextra->current->sli;
5676 yyextra->current->sli.clear();
5677 }
5678 if (yyextra->previous) yyextra->previous->endBodyLine=yyextra->yyLineNr;
5679 BEGIN( yyextra->lastCurlyContext ) ;
5680 }
5681 }
5682<SkipCurly>"}"{BN}*{DCOMM}"<" {
5683 lineCount(yyscanner);
5684 if ( yyextra->curlyCount )
5685 {
5686 //addToBody(yytext);
5687 --yyextra->curlyCount ;
5688 }
5689 else
5690 {
5691 yyextra->current->endBodyLine=yyextra->yyLineNr;
5692 yyextra->tempEntry = yyextra->current; // temporarily switch to the previous entry
5693 yyextra->current = yyextra->previous;
5694
5695 yyextra->docBlockContext = SkipCurlyEndDoc;
5696 yyextra->docBlockInBody = FALSE;
5697 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
5698 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
5699 yyextra->docBlock.str(std::string());
5700 yyextra->docBlockTerm = '}';
5701 if (yytext[yyleng-3]=='/')
5702 {
5703 startCommentBlock(yyscanner,TRUE);
5704 BEGIN( DocLine );
5705 }
5706 else
5707 {
5708 startCommentBlock(yyscanner,FALSE);
5709 BEGIN( DocBlock );
5710 }
5711 }
5712 }
5713<SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
5714 yyextra->docBlockContext = SkipCurlyEndDoc;
5715 yyextra->docBlockInBody = FALSE;
5716 yyextra->docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool(JAVADOC_AUTOBRIEF) ) ||
5717 ( yytext[yyleng-2]=='!' && Config_getBool(QT_AUTOBRIEF) );
5718 yyextra->docBlock.str(std::string());
5719 yyextra->docBlockTerm = '}';
5720 if (yytext[yyleng-3]=='/')
5721 {
5722 startCommentBlock(yyscanner,TRUE);
5723 BEGIN( DocLine );
5724 }
5725 else
5726 {
5727 startCommentBlock(yyscanner,FALSE);
5728 BEGIN( DocBlock );
5729 }
5730 }
5731<SkipCurlyEndDoc>"}" {
5732 //addToBody("}");
5733 if (yyextra->tempEntry) // we can only switch back to yyextra->current if no new item was created
5734 {
5735 yyextra->current = yyextra->tempEntry;
5736 yyextra->tempEntry.reset();
5737 }
5738 BEGIN( yyextra->lastCurlyContext );
5739 }
5740<SkipCurly>\" {
5741 //addToBody(yytext);
5742 yyextra->lastStringContext=SkipCurly;
5743 BEGIN( SkipString );
5744 }
5745<SkipCurly>^{B}*"#" {
5746 if (yyextra->insidePHP)
5747 REJECT;
5748 //addToBody(yytext);
5749 BEGIN( SkipCurlyCpp );
5750 }
5751<SkipCurly,SkipC11Inits,SkipInits,SkipC11Attribute>\n {
5752 lineCount(yyscanner);
5753 //addToBody(yytext);
5754 }
5755<SkipCurly,SkipCurlyCpp,ReadInitializer,ReadInitializerPtr>"<<<" {
5756 if (!yyextra->insidePHP)
5757 {
5758 REJECT;
5759 }
5760 else
5761 {
5762 yyextra->lastHereDocContext = YY_START;
5763 BEGIN(HereDoc);
5764 }
5765 }
5766<SkipCurly,SkipCurlyCpp>{B}*{RAWBEGIN} {
5767 yyextra->delimiter = extractBeginRawStringDelimiter(yytext);
5768 yyextra->lastRawStringContext = YY_START;
5769 yyextra->dummyRawString.clear();
5770 yyextra->pCopyRawString = &yyextra->dummyRawString;
5771 *yyextra->pCopyRawString += yytext;
5772 BEGIN(RawString);
5773 }
5774<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<\$]+ {
5775 lineCount(yyscanner); // for yyextra->column updates
5776 //addToBody(yytext);
5777 }
5778<SkipCurly,SkipCurlyCpp>"\$" {}
5779<SkipCurlyCpp>\n {
5780 //addToBody(yytext);
5781 lineCount(yyscanner);
5782 yyextra->lastCurlyContext = FindMembers;
5783 BEGIN( SkipCurly );
5784 }
5785<SkipCurlyCpp>\\[\r]*"\n"[\r]* {
5786 //addToBody(yytext);
5787 lineCount(yyscanner);
5788 }
5789<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,SkipC11Attribute>{CCS} {
5790 //addToBody(yytext);
5791 yyextra->lastCContext = YY_START;
5792 BEGIN(SkipComment);
5793 }
5794<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,SkipC11Attribute>{CPPC} {
5795 //addToBody(yytext);
5796 yyextra->lastCContext = YY_START;
5797 BEGIN(SkipCxxComment);
5798 }
5799<SkipInits,SkipC11Inits,SkipC11Attribute>"(" {
5800 yyextra->roundCount=0;
5801 yyextra->lastSkipRoundContext=YY_START;
5802 BEGIN(SkipRound);
5803 }
5804<SkipInits,SkipC11Inits,SkipC11Attribute>\" {
5805 yyextra->lastStringContext=YY_START;
5806 BEGIN( SkipString );
5807 }
5808<SkipInits>; {
5809 warn(yyextra->fileName,yyextra->yyLineNr,
5810 "Found ';' while parsing initializer list! "
5811 "(doxygen could be confused by a macro call without semicolon)"
5812 );
5813 BEGIN( FindMembers );
5814 }
5815<SkipInits,SkipCurly,SkipCurlyCpp>"#" {
5816 if (!yyextra->insidePHP)
5817 REJECT;
5818 //addToBody(yytext);
5819 yyextra->lastCContext = YY_START;
5820 BEGIN(SkipCxxComment);
5821 }
5822<SkipInits,SkipCurly,SkipCurlyCpp>@\" {
5823 if (!yyextra->insideCS) REJECT;
5824 // C# verbatim string
5825 // we want to discard the string, due to reuse of states we need a dummy stream
5826 yyextra->lastSkipVerbStringContext=YY_START;
5827 yyextra->pSkipVerbString=&yyextra->dummyTextStream;
5828 yyextra->dummyTextStream.clear(); // remove old data so it won't grow too much
5829 BEGIN(SkipVerbString);
5830 }
5831<SkipInits,SkipCurly,SkipCurlyCpp>{CHARLIT} {
5832 if (yyextra->insidePHP) REJECT;
5833 }
5834<SkipInits,SkipCurly,SkipCurlyCpp>\' {
5835 if (yyextra->insidePHP)
5836 {
5837 yyextra->lastStringContext=YY_START;
5838 BEGIN(SkipPHPString);
5839 }
5840 }
5841<SkipC11Attribute>{ID} {
5842 if (QCString(yytext)=="nodiscard")
5843 {
5844 yyextra->current->spec.setNoDiscard(true);
5845 }
5846 }
5847<SkipInits,SkipC11Inits,SkipCurly,SkipCurlyCpp,SkipC11Attribute>. { }
5848<SkipString,SkipPHPString>\\. { }
5849<SkipString>\" {
5850 BEGIN( yyextra->lastStringContext );
5851 }
5852<SkipPHPString>\' {
5853 BEGIN( yyextra->lastStringContext );
5854 }
5855<SkipString,SkipPHPString>{CCS}|{CCE}|{CPPC} { }
5856<SkipString,SkipPHPString>\n {
5857 lineCount(yyscanner);
5858 }
5859<SkipString>"[[" { }
5860<SkipString,SkipPHPString>. { }
5861<CompoundName>":" { // for "class : public base {} var;" construct, see bug 608359
5862 unput(':');
5863 BEGIN(ClassVar);
5864 }
5865<CompoundName>";" {
5866 yyextra->current->section = EntryType::makeEmpty() ;
5867 yyextra->current->type.clear() ;
5868 yyextra->current->name.clear() ;
5869 yyextra->current->args.clear() ;
5870 yyextra->current->argList.clear();
5871 BEGIN( FindMembers ) ;
5872 }
5873<Bases>";" {
5874 if (yyextra->insideIDL && (yyextra->current->spec.isSingleton() || yyextra->current->spec.isService()))
5875 {
5876 // in UNO IDL a service or singleton may be defined
5877 // completely like this: "service Foo : XFoo;"
5878 if (!yyextra->current->name.isEmpty() && !yyextra->current_root->name.isEmpty())
5879 {
5880 prependScope(yyscanner);
5881 }
5882 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
5883 // there can be only one base class here
5884 if (!yyextra->baseName.isEmpty())
5885 {
5886 yyextra->current->extends.emplace_back(
5887 yyextra->baseName,Protection::Public,Specifier::Normal);
5888 yyextra->baseName.clear();
5889 }
5890 yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ;
5891 initEntry(yyscanner);
5892 }
5893 else
5894 {
5895 yyextra->current->section = EntryType::makeEmpty() ;
5896 yyextra->current->type.clear() ;
5897 yyextra->current->name.clear() ;
5898 yyextra->current->args.clear() ;
5899 yyextra->current->argList.clear();
5900 }
5901 BEGIN( FindMembers ) ;
5902 }
5903<CompoundName>{SCOPENAME}/{BN}*"<" {
5904 yyextra->sharpCount = 0;
5905 yyextra->current->name = yytext ;
5906 storeClangId(yyscanner,yytext);
5907 if (yyextra->current->spec.isProtocol())
5908 {
5909 yyextra->current->name+="-p";
5910 }
5911 lineCount(yyscanner);
5912 yyextra->lastClassTemplSpecContext = ClassVar;
5913 if (yyextra->insideObjC) // protocol list
5914 {
5915 BEGIN( ObjCProtocolList );
5916 }
5917 else if (yyextra->insideCS) // C# generic class
5918 {
5919 //yyextra->current->name+="-g";
5920 BEGIN( CSGeneric );
5921 }
5922 else // C++ template specialization
5923 {
5924 yyextra->roundCount=0;
5925 BEGIN( ClassTemplSpec );
5926 }
5927 }
5928<CSGeneric>"<" {
5929 ArgumentList al;
5930 // check bug 612858 before enabling the next line
5931 //yyextra->current->spec |= Entry::Template;
5932 yyextra->current->tArgLists.push_back(al);
5933 yyextra->currentArgumentList = &yyextra->current->tArgLists.back();
5934 yyextra->templateStr="<";
5935 yyextra->current->name += "<";
5936 yyextra->fullArgString = yyextra->templateStr;
5937 yyextra->copyArgString = &yyextra->current->name;
5938 //yyextra->copyArgString = &yyextra->templateStr;
5939 yyextra->currentArgumentContext = ClassVar;
5940 BEGIN( ReadTempArgs );
5941 }
5942<ObjCProtocolList>"<" {
5943 yyextra->insideProtocolList=TRUE;
5944 BEGIN( Bases );
5945 }
5946<ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
5947 yyextra->current->name += yytext;
5948 lineCount(yyscanner);
5949 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
5950 {
5951 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
5952 if (yyextra->current->spec.isProtocol())
5953 { // Objective-C protocol
5954 unput('{'); // fake start of body
5955 BEGIN( ClassVar );
5956 }
5957 else
5958 {
5959 BEGIN( yyextra->lastClassTemplSpecContext );
5960 }
5961 }
5962 }
5963<ClassTemplSpec>"<" {
5964 yyextra->current->name += yytext;
5965 if (yyextra->roundCount==0) yyextra->sharpCount++;
5966 }
5967<ClassTemplSpec>. {
5968 yyextra->current->name += yytext;
5969 }
5970<CompoundName>({SCOPENAME}|{CSSCOPENAME}){BN}*";" { // forward declaration?
5971 if (yyextra->insideCS && yyextra->current->type == "namespace")
5972 {
5973 // file scoped CSharp namespace
5974 lineCount(yyscanner);
5975 yyextra->current->name = substitute(yytext,".","::");
5976 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
5977 yyextra->fakeNS++;
5978 unput('{'); // fake start of body
5979 BEGIN( ClassVar );
5980 }
5981 else if (!yyextra->current->tArgLists.empty())
5982 {
5983 // found a forward template declaration, this has
5984 // a purpose of its own
5985 yyextra->current->name = yytext;
5986 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
5987 storeClangId(yyscanner,yyextra->current->name.data());
5988 //printf("template class declaration for %s!\n",qPrint(yyextra->current->name));
5989 QCString rn = yyextra->current_root->name;
5990 //printf("cn='%s' rn='%s' yyextra->isTypedef=%d\n",qPrint(cn),qPrint(rn),yyextra->isTypedef);
5991 if (!yyextra->current->name.isEmpty() && !rn.isEmpty())
5992 {
5993 prependScope(yyscanner);
5994 }
5995 yyextra->current->spec.setForwardDecl(true);
5996 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
5997 }
5998 else if (yyextra->insideIDL &&
5999 (((yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isService()) &&
6000 yyextra->current->spec.isInterface()) ||
6001 ((yyextra->current_root->spec.isService() || yyextra->current_root->spec.isSingleton()) &&
6002 yyextra->current->spec.isService())
6003 )
6004 )
6005 {
6006 // interface yyextra->inside of UNO IDL service or interface
6007 // service yyextra->inside of UNO IDL service or singleton
6008 // there may be documentation on the member,
6009 // so do not throw it away...
6010 yyextra->current->name = yytext;
6011 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-1).stripWhiteSpace();
6012 yyextra->current->section = yyextra->current->spec.isInterface() ? EntryType::makeExportedInterface()
6013 : EntryType::makeIncludedService();
6014// yyextra->current->section = EntryType::makeMemberDoc();
6015 yyextra->current->spec.setInterface(false).setService(false);
6016 // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from
6017 // different enums in this case...
6018 // granted only Optional and Interface are actually valid in this context but urgh...
6019 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
6020 }
6021
6022 if (!(yyextra->insideCS && yyextra->current->type == "namespace"))
6023 {
6024 unput(';');
6025 yyextra->current->reset();
6026 initEntry(yyscanner);
6027 if (yyextra->insideObjC) // see bug746361
6028 {
6029 yyextra->language = yyextra->current->lang = SrcLangExt::Cpp;
6030 yyextra->insideObjC = FALSE;
6031 }
6032 if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
6033 {
6034 yyextra->current->type.prepend("typedef");
6035 }
6036 BEGIN( FindMembers );
6037 }
6038 }
Wrapper class for the Entry type.
Definition types.h:793
6039<CompoundName>{SCOPENAME}/{BN}*"(" {
6040 yyextra->current->name = yytext ;
6041 storeClangId(yyscanner,yytext);
6042 lineCount(yyscanner);
6043 if (yyextra->insideCpp && yyextra->current->name=="alignas") // C++11
6044 {
6045 yyextra->lastAlignAsContext = YY_START;
6046 BEGIN( AlignAs );
6047 }
6048 else
6049 {
6050 if (yyextra->current->spec.isProtocol())
6051 {
6052 yyextra->current->name += "-p";
6053 }
6054 BEGIN( ClassVar );
6055 }
6056 }
6057<AlignAs>"(" { yyextra->roundCount=0;
6058 BEGIN( AlignAsEnd );
6059 }
6060<AlignAs>\n { lineCount(yyscanner); }
6061<AlignAs>.
6062<AlignAsEnd>"(" { yyextra->roundCount++; }
6063<AlignAsEnd>")" { if (--yyextra->roundCount<0)
6064 {
6065 BEGIN( yyextra->lastAlignAsContext );
6066 }
6067 }
6068<AlignAsEnd>\n { lineCount(yyscanner); }
6069<AlignAsEnd>.
6070<ConceptName>{ID} {
6071 yyextra->current->name = yytext ;
6072 storeClangId(yyscanner,yytext);
6073 }
6074<ConceptName>"=" {
6075 yyextra->current->bodyLine = yyextra->yyLineNr;
6076 yyextra->current->bodyColumn = yyextra->yyColNr;
6077 yyextra->current->initializer.str(std::string());
6078 yyextra->lastInitializerContext = FindMembers;
6079 yyextra->sharpCount=0;
6080 yyextra->initBracketCount=0;
6081 BEGIN(ReadInitializer);
6082 }
6083<CompoundName>{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line
6084 // e.g. @protocol A,B;
6085 yyextra->current->reset();
6086 initEntry(yyscanner);
6087 }
6088<CompoundName>{SCOPENAME} {
6089 yyextra->current->name = yytext ;
6090 storeClangId(yyscanner,yytext);
6091 lineCount(yyscanner);
6092 if (yyextra->current->spec.isProtocol())
6093 {
6094 yyextra->current->name += "-p";
6095 }
6096 if (yyextra->current->spec.isProtocol() || yyextra->current->section.isObjcImpl())
6097 {
6098 unput('{'); // fake start of body
6099 }
6100 BEGIN( ClassVar );
6101 }
6102<CompoundName>{CSSCOPENAME} { // C# style scope
6103 yyextra->current->name = substitute(yytext,".","::");
6104 lineCount(yyscanner);
6105 BEGIN( ClassVar );
6106 }
6107<ClassVar>{SCOPENAME}{BNopt}/"(" {
6108 if (yyextra->insideIDL && literal_at(yytext,"switch") && !isId(yytext[6]))
6109 {
6110 // Corba IDL style union
6111 yyextra->roundCount=0;
6112 BEGIN(SkipUnionSwitch);
6113 }
6114 else
6115 {
6116 addType(yyscanner);
6117 yyextra->yyBegColNr=yyextra->yyColNr;
6118 yyextra->yyBegLineNr=yyextra->yyLineNr;
6119 yyextra->current->name = yytext;
6120 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
6121 storeClangId(yyscanner,yyextra->current->name.data());
6122 lineCount(yyscanner);
6123 BEGIN( FindMembers );
6124 }
6125 }
6126<ClassVar>"," {
6127 if (yyextra->isTypedef)
6128 {
6129 // multiple types in one typedef
6130 unput(',');
6131 yyextra->current->type.prepend("typedef ");
6132 BEGIN(FindMembers);
6133 }
6134 else
6135 {
6136 // Multiple class forward declaration
6137 }
6138 }
6139<ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
6140 if (yyextra->insideCli)
6141 {
6142 if (yytext[0]=='s') // sealed
6143 yyextra->current->spec.setSealedClass(true);
6144 else // abstract
6145 yyextra->current->spec.setAbstractClass(true);
6146 BEGIN( ClassVar );
6147 }
6148 else
6149 {
6150 REJECT;
6151 }
6152 }
6153<ClassVar>({ID}{BN}*"::"{BN}*)+{ID} {
6154 yyextra->yyBegColNr=yyextra->yyColNr;
6155 yyextra->yyBegLineNr=yyextra->yyLineNr;
6156 storeClangId(yyscanner,yytext);
6157 lineCount(yyscanner);
6158 if (yyextra->current->section.isEnum())
6159 { // found "enum a N::b" -> variable
6160 yyextra->current->section = EntryType::makeVariable() ;
6161 }
6162 yyextra->current->type += ' ' ;
6163 yyextra->current->type += yyextra->current->name ;
6164 yyextra->current->name = QCString(yytext).simplifyWhiteSpace();
6165
6166 if (nameIsOperator(yyextra->current->name))
6167 {
6168 BEGIN( Operator );
6169 }
6170 }
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:185
6171<ClassVar>{ID} {
6172 yyextra->yyBegColNr=yyextra->yyColNr;
6173 yyextra->yyBegLineNr=yyextra->yyLineNr;
6174 storeClangId(yyscanner,yytext);
6175 if (yyextra->insideIDL && qstrcmp(yytext,"switch")==0)
6176 {
6177 // Corba IDL style union
6178 yyextra->roundCount=0;
6179 BEGIN(SkipUnionSwitch);
6180 }
6181 else if ((yyextra->insideJava || yyextra->insidePHP || yyextra->insideJS || yyextra->insideSlice) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0))
6182 {
6183 yyextra->current->type.clear();
6184 yyextra->baseProt = Protection::Public;
6185 yyextra->baseVirt = Specifier::Normal;
6186 yyextra->baseName.clear();
6187 BEGIN( BasesProt ) ;
6188 }
6189 else if (yyextra->insideCS && qstrcmp(yytext,"where")==0) // C# type constraint
6190 {
6191 yyextra->current->typeConstr.clear();
6192 yyextra->current->typeConstr.push_back(Argument());
6193 yyextra->lastCSConstraint = YY_START;
6194 BEGIN( CSConstraintName );
6195 }
6196 else if (yyextra->insideCli && qstrcmp(yytext,"abstract")==0)
6197 {
6198 yyextra->current->spec.setAbstract(true);
6199 }
6200 else if (yyextra->insideCli && qstrcmp(yytext,"sealed")==0)
6201 {
6202 yyextra->current->spec.setSealed(true);
6203 }
6204 else if (qstrcmp(yytext,"final")==0)
6205 {
6206 yyextra->current->spec.setFinal(true);
6207 }
6208 else
6209 {
6210 if (yyextra->current->section.isEnum())
6211 { // found "enum a b" -> variable
6212 yyextra->current->section = EntryType::makeVariable() ;
6213 }
6214 yyextra->current->type += ' ' ;
6215 yyextra->current->type += yyextra->current->name ;
6216 yyextra->current->name = yytext ;
6217
6218 if (nameIsOperator(yyextra->current->name))
6219 {
6220 BEGIN( Operator );
6221 }
6222 }
6223 }
6224<ClassVar>[(\[] {
6225 if (yyextra->insideObjC && *yytext=='(') // class category
6226 {
6227 yyextra->current->name+='(';
6228 //if (yyextra->current->section!=Entry::OBJCIMPL_SEC)
6229 //{
6230 yyextra->current->spec.setCategory(true);
6231 //}
6232 BEGIN( ClassCategory );
6233 }
6234 else
6235 {
6236 // probably a function anyway
6237 unput(*yytext);
6238 BEGIN( FindMembers );
6239 }
6240 }
6241<CSConstraintType,CSConstraintName>{CCS}{CCE} { /* empty comment */ }
6242<CSConstraintType,CSConstraintName>({CCS}[*!]|{CPPC}[/!])("<"?) { // special comment
6243 yyextra->fullArgString.clear();
6244 yyextra->lastCopyArgChar='#'; // end marker
6245 yyextra->lastCommentInArgContext=YY_START;
6246 if (yytext[1]=='/')
6247 BEGIN( CopyArgCommentLine );
6248 else
6249 BEGIN( CopyArgComment );
6250 }
6251<CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block
6252 yyextra->current->typeConstr.back().docs = yyextra->fullArgString;
6253 }
6254<CSConstraintType>"=>" { // end of type constraint reached
6255 // parse documentation of the constraints
6256 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6257 unput('>');
6258 unput('=');
6259 BEGIN( yyextra->lastCSConstraint );
6260 }
6261<CSConstraintType>"{" { // end of type constraint reached
6262 // parse documentation of the constraints
6263 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6264 unput('{');
6265 BEGIN( yyextra->lastCSConstraint );
6266 }
6267<CSConstraintType,CSConstraintName>";" {
6268 handleParametersCommentBlocks(yyscanner,yyextra->current->typeConstr);
6269 unput(';');
6270 BEGIN( yyextra->lastCSConstraint );
6271 }
6272<CSConstraintName>":" {
6273 BEGIN( CSConstraintType );
6274 }
6275<CSConstraintName>{ID} {
6276 // parameter name
6277 yyextra->current->typeConstr.back().name=yytext;
6278 }
6279<CSConstraintType>"where" { // another constraint for a different param
6280 yyextra->current->typeConstr.push_back(Argument());
6281 BEGIN( CSConstraintName );
6282 }
6283<CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
6284 if (yyextra->current->typeConstr.back().type.isEmpty())
6285 // first type constraint for this parameter
6286 {
6287 yyextra->current->typeConstr.back().type=yytext;
6288 }
6289 else // new type constraint for same parameter
6290 {
6291 QCString name = yyextra->current->typeConstr.back().name;
6292 yyextra->current->typeConstr.push_back(Argument());
6293 yyextra->current->typeConstr.back().name=name;
6294 yyextra->current->typeConstr.back().type=yytext;
6295 }
6296 }
6297<CSConstraintName,CSConstraintType>\n {
6298 lineCount(yyscanner);
6299 }
6300<CSConstraintName,CSConstraintType>. {
6301 }
6302<ClassCategory>{ID} {
6303 yyextra->current->name+=yytext;
6304 }
6305<ClassCategory>")"/{BN}*"{" {
6306 yyextra->current->name+=')';
6307 BEGIN( ClassVar );
6308 }
6309<ClassCategory>")"/{BN}*"<" {
6310 yyextra->current->name+=')';
6311 BEGIN( ObjCProtocolList );
6312 }
6313<ClassCategory>")" {
6314 yyextra->current->name+=')';
6315 if (yyextra->current->spec.isProtocol() || yyextra->current->section.isObjcImpl())
6316 {
6317 unput('{'); // fake start of body
6318 }
6319 else // category has no variables so push back an empty body
6320 {
6321 unput('}');
6322 unput('{');
6323 }
6324 BEGIN( ClassVar );
6325 }
6326<ClassVar>":" {
6327 if (yyextra->current->section.isVariable()) // enum A B:2, see bug 748208
6328 {
6329 yyextra->current->bitfields+=":";
6330 yyextra->current->args.clear();
6331 BEGIN(BitFields);
6332 }
6333 else if (yyextra->current->section.isEnum()) // enum E:2, see bug 313527,
6334 // or C++11 style enum: 'E : unsigned int {...}'
6335 {
6336 yyextra->current->args.clear();
6337 BEGIN(EnumBaseType);
6338 }
6339 else
6340 {
6341 yyextra->current->type.clear();
6342 if (yyextra->current->spec.isInterface() ||
6343 yyextra->current->spec.isStruct() ||
6344 yyextra->current->spec.isRef() ||
6345 yyextra->current->spec.isValue() ||
6346 yyextra->insidePHP || yyextra->insideCS || yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL
6347 )
6348 {
6349 yyextra->baseProt = Protection::Public;
6350 }
6351 else
6352 {
6353 yyextra->baseProt = Protection::Private;
6354 }
6355 yyextra->baseVirt = Specifier::Normal;
6356 yyextra->baseName.clear();
6357 BEGIN( BasesProt ) ;
6358 }
6359 }
6360<ClassVar>[;=*&] {
6361 if (yyextra->isTypedef) // typedef of a class, put typedef keyword back
6362 {
6363 yyextra->current->type.prepend("typedef");
6364 }
6365 if ((yytext[0]=='*' || yytext[0]=='&') && yyextra->current->section.isEnum())
6366 { // found "enum a *b" -> variable
6367 yyextra->current->section = EntryType::makeVariable() ;
6368 }
6369 if (yytext[0]==';' && yyextra->current->section.isEnum())
6370 {
6371 yyextra->current->reset();
6372 initEntry(yyscanner);
6373 }
6374 else
6375 {
6376 unput(*yytext);
6377 }
6378 BEGIN( FindMembers );
6379 }
6380<Bases,ClassVar>{CPPC}"/"/[^/] {
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<Bases,ClassVar>({CPPC}{B}*)?{CCS}"*"/{NCOMM} |
6397<Bases,ClassVar>({CPPC}{B}*)?{CCS}"!" |
6398<Bases,ClassVar>{CPPC}"!" |
6399<Bases,ClassVar>[\-+]{BN}* {
6400 if (!yyextra->insideObjC)
6401 {
6402 REJECT;
6403 }
6404 else
6405 {
6406 lineCount(yyscanner);
6407 yyextra->current->program << yytext;
6408 yyextra->current->fileName = yyextra->fileName ;
6409 yyextra->current->startLine = yyextra->yyLineNr ;
6410 yyextra->current->startColumn = yyextra->yyColNr;
6411 yyextra->curlyCount=0;
6412 BEGIN( ReadBodyIntf );
6413 }
6414 }
6415<CompoundName,ClassVar>{B}*"{"{B}* {
6416 yyextra->current->program.str(std::string());
6417 yyextra->current->fileName = yyextra->fileName ;
6418 yyextra->current->bodyLine = yyextra->yyLineNr;
6419 yyextra->current->bodyColumn = yyextra->yyColNr;
6420 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6421 if (yyextra->current->name.isEmpty() && !yyextra->isTypedef) // anonymous compound
6422 {
6423 if (yyextra->current->section.isNamespace()) // allow reopening of anonymous namespaces
6424 {
6425 if (Config_getBool(EXTRACT_ANON_NSPACES)) // use visible name
6426 {
6427 yyextra->current->name="anonymous_namespace{"+stripPath(yyextra->current->fileName)+"}";
6428 }
6429 else // use invisible name
6430 {
6431 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonNSCount);
6432 }
6433 }
6434 else
6435 {
6436 yyextra->current->name = generateAnonymousAnchor(yyextra->fileName,yyextra->anonCount++);
6437 }
6438 }
6439 yyextra->curlyCount=0;
6440 if (yyextra->current_root && // not a nested struct yyextra->inside an @interface section
6441 !yyextra->current_root->spec.isInterface() &&
6442 (yyextra->current->spec.isInterface() ||
6443 yyextra->current->spec.isProtocol() ||
6444 yyextra->current->spec.isCategory() ||
6445 yyextra->current->section.isObjcImpl()
6446 ) &&
6447 yyextra->insideObjC
6448 )
6449 { // ObjC body that ends with @end
6450 BEGIN( ReadBodyIntf );
6451 }
6452 else if (yyextra->current->section.isNamespace())
6453 { // namespace body
6454 BEGIN( ReadNSBody );
6455 }
6456 else
6457 { // class body
6458 BEGIN( ReadBody ) ;
6459 }
6460 }
QCString stripPath(const QCString &s)
Definition util.cpp:5464
6461<BasesProt>"virtual"{BN}+ { lineCount(yyscanner); yyextra->baseVirt = Specifier::Virtual; }
6462<BasesProt>"public"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Public; }
6463<BasesProt>"protected"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Protected; }
6464<BasesProt>"internal"{BN}+ { if (!yyextra->insideCli) REJECT ; lineCount(yyscanner); yyextra->baseProt = Protection::Package; }
6465<BasesProt>"private"{BN}+ { lineCount(yyscanner); yyextra->baseProt = Protection::Private; }
6466<BasesProt>{BN} { lineCount(yyscanner); }
6467<BasesProt>. { unput(*yytext); BEGIN(Bases); }
6468<Bases>"decltype"{BN}*"(" {
6469 lineCount(yyscanner);
6470 yyextra->roundCount=0;
6471 yyextra->lastSkipRoundContext=YY_START;
6472 BEGIN(SkipRound);
6473 }
6474<Bases>("\\")?({ID}"\\")*{ID} { // PHP namespace token, not sure if interspacing is allowed but it gives problems (see bug 640847)
6475 if (!yyextra->insidePHP)
6476 {
6477 REJECT;
6478 }
6479 else // PHP base class of the form \Ns\Cl or Ns\Cl
6480 {
6481 lineCount(yyscanner);
6482 QCString bn=yytext;
6483 bn = substitute(bn,"\\","::");
6484 yyextra->baseName += bn;
6485 yyextra->current->args += ' ';
6486 yyextra->current->args += yytext;
6487 }
6488 }
6489<Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID}("...")? {
6490 lineCount(yyscanner);
6491 QCString baseScope = yytext;
6492 if (yyextra->insideCS && baseScope.stripWhiteSpace()=="where")
6493 {
6494 // type constraint for a class
6495 yyextra->current->typeConstr.clear();
6496 yyextra->current->typeConstr.push_back(Argument());
6497 yyextra->lastCSConstraint = YY_START;
6498 BEGIN( CSConstraintName );
6499 }
6500 else
6501 {
6502 yyextra->baseName+=yytext;
6503 yyextra->current->args += ' ';
6504 yyextra->current->args += yytext;
6505 }
6506 }
6507<Bases>{BN}*{ID}("."{ID})* { // Java style class
6508 QCString name = substitute(yytext,".","::");
6509 yyextra->baseName += name;
6510 yyextra->current->args += ' ';
6511 yyextra->current->args += name;
6512 }
6513<ClassVar,Bases>\n/{BN}*[^{, \t\n] {
6514 if (!yyextra->insideObjC)
6515 {
6516 REJECT;
6517 }
6518 else
6519 {
6520 lineCount(yyscanner);
6521 unput('{');
6522 }
6523 }
6524<ClassVar,Bases>"@end" { // empty ObjC interface
6525 unput('d'); // insert fake body: {}@end
6526 unput('n');
6527 unput('e');
6528 unput('@');
6529 unput('}');
6530 unput('{');
6531 }
6532<ClassVar>"<" { yyextra->current->name += *yytext;
6533 yyextra->sharpCount=1;
6534 yyextra->roundCount=0;
6535 yyextra->lastSkipSharpContext = YY_START;
6536 yyextra->specName = &yyextra->current->name;
6537 BEGIN ( Specialization );
6538 }
6539<Bases>{BN}*"<" {
6540 lineCount(yyscanner);
6541 yyextra->sharpCount=1;
6542 yyextra->roundCount=0;
6543 yyextra->lastSkipSharpContext = YY_START;
6544 if (yyextra->insideObjC) // start of protocol list
6545 {
6546 unput(',');
6547 }
6548 else // template specialization
6549 {
6550 //if (yyextra->insideCS) // generic
6551 //{
6552 // yyextra->baseName+="-g";
6553 //}
6554 yyextra->templateStr = yytext;
6555 yyextra->specName = &yyextra->templateStr;
6556 BEGIN ( Specialization );
6557 }
6558 }
6559<Specialization>"<" { *yyextra->specName += *yytext;
6560 if (yyextra->roundCount==0) yyextra->sharpCount++;
6561 }
6562<Specialization>">" {
6563 *yyextra->specName += *yytext;
6564 if (yyextra->roundCount==0 && --yyextra->sharpCount<=0)
6565 {
6566 yyextra->baseName+=removeRedundantWhiteSpace(*yyextra->specName);
6567 BEGIN(yyextra->lastSkipSharpContext);
6568 }
6569 }
6570<Specialization>{BN}+ { lineCount(yyscanner); *yyextra->specName +=' '; }
6571<Specialization>"<<" { *yyextra->specName += yytext; }
6572<Specialization>">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template...
6573 unput('>');
6574 unput(' ');
6575 unput('>');
6576 }
6577<Specialization>">>" {
6578 if (yyextra->insideCS) // for C# >> ends a nested template
6579 {
6580 REJECT;
6581 }
6582 else // for C++ >> is a bitshift
6583 // operator and > > would end
6584 // a nested template.
6585 // We require the bitshift to be enclosed in braces.
6586 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
6587 {
6588 if (yyextra->roundCount>0)
6589 {
6590 *yyextra->specName += yytext;
6591 }
6592 else
6593 {
6594 unput('>');
6595 unput(' ');
6596 unput('>');
6597 }
6598 }
6599 }
6600<Specialization>"typename"{BN}+ { lineCount(yyscanner); }
6601<Specialization>"(" { *yyextra->specName += *yytext; yyextra->roundCount++; }
6602<Specialization>")" { *yyextra->specName += *yytext; yyextra->roundCount--; }
6603
6604<Specialization>"\\\\" { *yyextra->specName += *yytext;}
6605<Specialization>"\\'" { *yyextra->specName += *yytext;}
6606<Specialization>"\\\"" { *yyextra->specName += *yytext;}
6607<Specialization>"'" { *yyextra->specName += *yytext;BEGIN(SpecializationSingleQuote);}
6608<Specialization>"\"" { *yyextra->specName += *yytext;BEGIN(SpecializationDoubleQuote);}
6609<SpecializationSingleQuote,SpecializationDoubleQuote>"\\\\" { *yyextra->specName += *yytext;}
6610<SpecializationSingleQuote>"\\'" { *yyextra->specName += *yytext;}
6611<SpecializationSingleQuote>"'" { *yyextra->specName += *yytext; BEGIN(Specialization);}
6612<SpecializationDoubleQuote>"\\\"" { *yyextra->specName += *yytext;}
6613<SpecializationDoubleQuote>"\"" { *yyextra->specName += *yytext; BEGIN(Specialization);}
6614<SpecializationSingleQuote,SpecializationDoubleQuote>. { *yyextra->specName += *yytext;}
6615
6616<Specialization>. {
6617 *yyextra->specName += *yytext;
6618 }
6619<SkipRound>"(" { ++yyextra->roundCount; }
6620<SkipRound>")" { if (--yyextra->roundCount<0)
6621 BEGIN ( yyextra->lastSkipRoundContext );
6622 }
6623<SkipRound>\" {
6624 yyextra->lastStringContext=SkipRound;
6625 BEGIN(SkipString);
6626 }
6627<Bases>","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount(yyscanner);
6628 if (yyextra->insideProtocolList)
6629 {
6630 yyextra->baseName+="-p";
6631 }
6632 else
6633 {
6634 yyextra->current->args += ',' ;
6635 }
6636 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6637 if (!yyextra->baseName.isEmpty())
6638 {
6639 yyextra->current->extends.emplace_back(
6640 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
6641 );
6642 }
6643 if (yyextra->current->spec.isInterface() || yyextra->current->spec.isStruct() ||
6644 yyextra->insideJava || yyextra->insidePHP || yyextra->insideCS ||
6645 yyextra->insideD || yyextra->insideObjC || yyextra->insideIDL || yyextra->insideSlice)
6646 {
6647 yyextra->baseProt=Protection::Public;
6648 }
6649 else
6650 {
6651 yyextra->baseProt=Protection::Private;
6652 }
6653 yyextra->baseVirt=Specifier::Normal;
6654 yyextra->baseName.clear();
6655 if (*yytext=='>')
6656 { // end of a ObjC protocol list
6657 yyextra->insideProtocolList=FALSE;
6658 if (yyleng==1)
6659 {
6660 unput('{'); // dummy start body
6661 }
6662 else
6663 {
6664 yyless(1);
6665 }
6666 }
6667 else
6668 {
6669 if (*yytext==',' && yyextra->insideObjC) // Begin of protocol list
6670 {
6671 yyextra->insideProtocolList=TRUE;
6672 }
6673 BEGIN(BasesProt);
6674 }
6675 }
6676<Bases>{B}*"{"{B}* {
6677 yyextra->current->program.str(std::string());
6678 yyextra->current->fileName = yyextra->fileName ;
6679 yyextra->current->bodyLine = yyextra->yyLineNr;
6680 yyextra->current->bodyColumn = yyextra->yyColNr;
6681 yyextra->current->name = removeRedundantWhiteSpace(yyextra->current->name);
6682 if (!yyextra->baseName.isEmpty())
6683 yyextra->current->extends.emplace_back(
6684 yyextra->baseName,yyextra->baseProt,yyextra->baseVirt
6685 );
6686 yyextra->curlyCount=0;
6687 if (yyextra->insideObjC)
6688 {
6689 BEGIN( ReadBodyIntf );
6690 }
6691 else
6692 {
6693 BEGIN( ReadBody ) ;
6694 }
6695 }
6696<SkipUnionSwitch>{B}*"(" {
6697 yyextra->roundCount++;
6698 }
6699<SkipUnionSwitch>")" {
6700 if (--yyextra->roundCount==0)
6701 {
6702 BEGIN(ClassVar);
6703 }
6704 }
6705<SkipUnionSwitch>\n { lineCount(yyscanner); }
6706<SkipUnionSwitch>.
6707<Comment>{BN}+ { yyextra->current->program << yytext ;
6708 lineCount(yyscanner) ;
6709 }
6710<Comment>{CCS} { yyextra->current->program << yytext ; }
6711<Comment>{CPPC} { yyextra->current->program << yytext ; }
6712<Comment>{CMD}("code"|"verbatim"|"iliteral") {
6713 if (yyextra->doxygenComment) yyextra->insideCode=TRUE;
6714 yyextra->current->program << yytext ;
6715 }
6716<Comment>{CMD}("endcode"|"endverbatim"|"endiliteral") {
6717 if (yyextra->doxygenComment) yyextra->insideCode=FALSE;
6718 yyextra->current->program << yytext ;
6719 }
6720<Comment>[^ \.\t\r\n\/\*]+ { yyextra->current->program << yytext ; }
6721<Comment>{CCE} { yyextra->current->program << yytext ;
6722 if (!yyextra->insideCode)
6723 {
6724 yyextra->doxygenComment=false;
6725 BEGIN( yyextra->lastContext );
6726 }
6727 }
6728<Comment>. { yyextra->current->program << *yytext ; }
6729
6730<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,SkipC11Inits,SkipC11Attribute,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"!" {
6731 //printf("Start doc block at %d\n",yyextra->yyLineNr);
6732 if (!yyextra->current->doc.isEmpty())
6733 {
6734 yyextra->current->doc+="\n\n";
6735 }
6736 else
6737 {
6738 yyextra->current->docLine = yyextra->yyLineNr;
6739 yyextra->current->docFile = yyextra->fileName;
6740 }
6741
6742 yyextra->lastDocContext = YY_START;
6743 if (yyextra->current_root->section.isScope())
6744 {
6745 yyextra->current->inside = yyextra->current_root->name+"::";
6746 }
6747 yyextra->docBlockContext = YY_START;
6748 yyextra->docBlockInBody = YY_START==SkipCurly;
6749 yyextra->docBlockAutoBrief = Config_getBool(QT_AUTOBRIEF);
6750
6751 QCString indent;
6752 indent.fill(' ',computeIndent(yytext,yyextra->column));
6753 yyextra->docBlock.str(indent.str());
6754
6755 if (yyextra->docBlockAutoBrief)
6756 {
6757 yyextra->current->briefLine = yyextra->yyLineNr;
6758 yyextra->current->briefFile = yyextra->fileName;
6759 }
6760 startCommentBlock(yyscanner,FALSE);
6761 BEGIN( DocBlock );
6762 }
6763<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>{CCS}"*"[*]+{BL} {
6764 bool javadocBanner = Config_getBool(JAVADOC_BANNER);
6765 lineCount(yyscanner);
6766
6767 if( javadocBanner )
6768 {
6769 yyextra->lastDocContext = YY_START;
6770
6771 //printf("Found comment banner at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
6772 if (yyextra->current_root->section.isScope())
6773 {
6774 yyextra->current->inside = yyextra->current_root->name+"::";
6775 }
6776 yyextra->current->docLine = yyextra->yyLineNr;
6777 yyextra->current->docFile = yyextra->fileName;
6778 yyextra->docBlockContext = YY_START;
6779 yyextra->docBlockInBody = YY_START==SkipCurly;
6780 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
6781 yyextra->docBlockAutoBrief = javadocAutoBrief;
6782
6783 QCString indent;
6784 indent.fill(' ',computeIndent(yytext,yyextra->column));
6785 yyextra->docBlock.str(indent.str());
6786
6787 if (yyextra->docBlockAutoBrief)
6788 {
6789 yyextra->current->briefLine = yyextra->yyLineNr;
6790 yyextra->current->briefFile = yyextra->fileName;
6791 }
6792 startCommentBlock(yyscanner,FALSE);
6793 BEGIN( DocBlock );
6794 }
6795 else
6796 {
6797 yyextra->current->program << yytext ;
6798 yyextra->lastContext = YY_START ;
6799 yyextra->doxygenComment=true;
6800 BEGIN( Comment ) ;
6801 }
6802 }
6803<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>^{B}+({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
6804 lineCount(yyscanner);
6805 yyextra->yyColNr=1;
6806 REJECT;
6807 }
6808<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
6809 yyextra->lastDocContext = YY_START;
6810
6811 //printf("Found comment block at %s:%d\n",yyextra->fileName,yyextra->yyLineNr);
6812 if (yyextra->current_root->section.isScope())
6813 {
6814 yyextra->current->inside = yyextra->current_root->name+"::";
6815 }
6816 yyextra->current->docLine = yyextra->yyLineNr;
6817 yyextra->current->docFile = yyextra->fileName;
6818 yyextra->docBlockContext = YY_START;
6819 yyextra->docBlockInBody = YY_START==SkipCurly;
6820 bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF);
6821 yyextra->docBlockAutoBrief = javadocAutoBrief;
6822
6823 QCString indent;
6824 indent.fill(' ',computeIndent(yytext,yyextra->column));
6825 yyextra->docBlock.str(indent.str());
6826
6827 if (yyextra->docBlockAutoBrief)
6828 {
6829 yyextra->current->briefLine = yyextra->yyLineNr;
6830 yyextra->current->briefFile = yyextra->fileName;
6831 }
6832 startCommentBlock(yyscanner,FALSE);
6833 BEGIN( DocBlock );
6834 }
6835<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"!" {
6836 yyextra->lastDocContext = YY_START;
6837 if (yyextra->current_root->section.isScope())
6838 {
6839 yyextra->current->inside = yyextra->current_root->name+"::";
6840 }
6841 yyextra->docBlockContext = YY_START;
6842 yyextra->docBlockInBody = YY_START==SkipCurly;
6843 yyextra->docBlockAutoBrief = FALSE;
6844
6845 QCString indent;
6846 indent.fill(' ',computeIndent(yytext,yyextra->column));
6847 yyextra->docBlock.str(indent.str());
6848
6849 startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
6850 BEGIN( DocLine );
6851 }
6852<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>{CPPC}"/"/[^/] {
6853 yyextra->lastDocContext = YY_START;
6854 if (yyextra->current_root->section.isScope())
6855 {
6856 yyextra->current->inside = yyextra->current_root->name+"::";
6857 }
6858 yyextra->docBlockContext = YY_START;
6859 yyextra->docBlockInBody = YY_START==SkipCurly;
6860 yyextra->docBlockAutoBrief = FALSE;
6861 QCString indent;
6862 indent.fill(' ',computeIndent(yytext,yyextra->column));
6863 yyextra->docBlock.str(indent.str());
6864 startCommentBlock(yyscanner,yyextra->current->brief.isEmpty());
6865 BEGIN( DocLine );
6866 }
6867<FindMembers>"extern"{BN}*"\""[^\"]+"\""{BN}*("{")? {
6868 lineCount(yyscanner);
6869 yyextra->externLinkage=TRUE;
6870 }
6871<FindMembers>"{" {
6872 if (yyextra->externLinkage)
6873 {
6874 yyextra->externLinkage=FALSE;
6875 }
6876 else if (yyextra->insideCS &&
6877 !yyextra->current->name.isEmpty() &&
6878 !yyextra->current->type.isEmpty())
6879 {
6880 if (yyextra->current->mtype == MethodTypes::Event)
6881 {
6882 yyextra->mtype = MethodTypes::Event;
6883 }
6884 else if (containsWord(yyextra->current->type,"event")) // event
6885 {
6886 yyextra->current->mtype = yyextra->mtype = MethodTypes::Event;
6887 }
6888 else // property
6889 {
6890 yyextra->current->mtype = yyextra->mtype = MethodTypes::Property;
6891 }
6892 yyextra->current->bodyLine = yyextra->yyLineNr;
6893 yyextra->current->bodyColumn = yyextra->yyColNr;
6894 yyextra->curlyCount=0;
6895 BEGIN( CSAccessorDecl );
6896 }
6897 else if (yyextra->insideIDL && yyextra->current->spec.isAttribute())
6898 {
6899 // UNO IDL: attributes may have setter and getter
6900 // exception specifications
6901 yyextra->current->exception = " {";
6902 BEGIN(UNOIDLAttributeBlock);
6903 }
6904 else
6905 {
6906 if ((yyextra->insideJava || yyextra->insideCS || yyextra->insideD) &&
6907 yyextra->current->name.isEmpty()
6908 )
6909 {
6910 // static Java initializer
6911 yyextra->needsSemi = FALSE;
6912 if (yyextra->current->isStatic)
6913 {
6914 yyextra->current->name="[static initializer]";
6915 yyextra->current->type.clear();
6916 }
6917 else
6918 {
6919 yyextra->current->name="[instance initializer]";
6920 }
6921 unput(*yytext);
6922 BEGIN( SFunction );
6923 }
6924 else
6925 {
6926 // pre C++11 code -> ignore the initializer
6927 //yyextra->needsSemi = TRUE;
6928 //yyextra->current->type.clear();
6929 //yyextra->current->name.clear();
6930 //yyextra->current->args.clear();
6931 //yyextra->current->argList.clear();
6932 //yyextra->curlyCount=0;
6933 //BEGIN( SkipCurlyBlock );
6934
6935 // C++11 style initializer list
6936 yyextra->current->bodyLine = yyextra->yyLineNr;
6937 yyextra->current->bodyColumn = yyextra->yyColNr;
6938 yyextra->current->initializer.str(yytext);
6939 yyextra->lastInitializerContext = YY_START;
6940 yyextra->sharpCount=0;
6941 yyextra->initBracketCount=1;
6942 BEGIN(ReadInitializer);
6943 }
6944 }
6945 }
6946<CSAccessorDecl>"{" { yyextra->curlyCount++; }
6947<CSAccessorDecl>"}"{B}*"=" {
6948 // fall back to next rule if it's not the right bracket
6949 if (yyextra->curlyCount != 0) REJECT;
6950 yyextra->current->initializer.str("=");
6951 yyextra->current->endBodyLine=yyextra->yyLineNr;
6952 yyextra->lastInitializerContext = FindMembers;
6953 BEGIN(ReadInitializer);
6954 }
6955<CSAccessorDecl>"}" {
6956 if (yyextra->curlyCount)
6957 {
6958 yyextra->curlyCount--;
6959 }
6960 else
6961 {
6962 yyextra->mtype = MethodTypes::Method;
6963 yyextra->virt = Specifier::Normal;
6964 // not really important, but while we are at it
6965 yyextra->current->endBodyLine=yyextra->yyLineNr;
6966 unput(';');
6967 BEGIN(FindMembers);
6968 }
6969 }
6970<CSAccessorDecl>"private "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateSettable(true); }
6971<CSAccessorDecl>"protected "{BN}*"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedSettable(true); }
6972<CSAccessorDecl>"private "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setPrivateGettable(true); }
6973<CSAccessorDecl>"protected "{BN}*"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setProtectedGettable(true); }
6974<CSAccessorDecl>"set" { if (yyextra->curlyCount==0) yyextra->current->spec.setSettable(true); }
6975<CSAccessorDecl>"get" { if (yyextra->curlyCount==0) yyextra->current->spec.setGettable(true); }
6976<CSAccessorDecl>"add" { if (yyextra->curlyCount==0) yyextra->current->spec.setAddable(true); }
6977<CSAccessorDecl>"remove" { if (yyextra->curlyCount==0) yyextra->current->spec.setRemovable(true); }
6978<CSAccessorDecl>"raise" { if (yyextra->curlyCount==0) yyextra->current->spec.setRaisable(true); }
6979<CSAccessorDecl>{CHARLIT} {}
6980<CSAccessorDecl>"\"" { BEGIN(CSString);}
6981<CSAccessorDecl>"." {}
6982<CSAccessorDecl>\n { lineCount(yyscanner); }
6983<CSString>"\"" { BEGIN(CSAccessorDecl);}
6984<CSString>{CPPC} {} // Otherwise the rule <*>"//" will kick in
6985<CSString>{CCS} {} // Otherwise the rule <*>"/*" will kick in
6986<CSString>\n { lineCount(yyscanner); }
6987<CSString>"." {}
6988
6989 /* ---- Slice-specific rules ------ */
6990
6991<SliceSequence>{SCOPENAME} {
6992 if (yyextra->current->spec.isLocal())
6993 {
6994 yyextra->current->type = "local ";
6995 }
6996 yyextra->current->type += "sequence<";
6997 yyextra->current->type += yytext;
6998 yyextra->current->type += ">";
6999 }
7000
7001<SliceSequence>{BN}*">"{BN}* {
7002 lineCount(yyscanner);
7003 BEGIN(SliceSequenceName);
7004 }
7005
7006<SliceSequenceName>{ID}{BN}* {
7007 lineCount(yyscanner);
7008 yyextra->current->name = yytext ;
7009 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7010 }
7011
7012<SliceSequenceName>";" {
7013 yyextra->current->section = EntryType::makeVariable();
7014 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7015 initEntry(yyscanner);
7016 BEGIN(FindMembers);
7017 }
7018
7019<SliceDictionary>{SCOPENAME}{BN}*","{BN}*{SCOPENAME} {
7020 lineCount(yyscanner);
7021 if (yyextra->current->spec.isLocal())
7022 {
7023 yyextra->current->type = "local ";
7024 }
7025 yyextra->current->type += "dictionary<";
7026 yyextra->current->type += yytext;
7027 yyextra->current->type += ">";
7028 yyextra->current->type = yyextra->current->type.simplifyWhiteSpace();
7029 }
7030
7031<SliceDictionary>{BN}*">"{BN}* {
7032 lineCount(yyscanner);
7033 BEGIN(SliceDictionaryName);
7034 }
7035
7036<SliceDictionaryName>{ID}{BN}* {
7037 lineCount(yyscanner);
7038 yyextra->current->name = yytext ;
7039 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
7040 }
7041
7042<SliceDictionaryName>";" {
7043 yyextra->current->section = EntryType::makeVariable();
7044 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7045 initEntry(yyscanner);
7046 BEGIN(FindMembers);
7047 }
7048
7049 /**********************************************************************************/
7050 /******************** Documentation block related rules ***************************/
7051 /**********************************************************************************/
7052
7053 /* ---- Single line comments ------ */
7054<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
7055 int markerLen = yytext[yyleng-1]=='<' ? 4 : 3;
7056 yyextra->docBlock << std::string(yytext).substr(0,yyleng-markerLen);
7057 lineCount(yyscanner);
7058 }
7059<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
7060 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7061 BEGIN( yyextra->docBlockContext );
7062 }
static void handleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
7063<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
7064 yyextra->docBlock << yytext;
7065 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7066 BEGIN( yyextra->docBlockContext );
7067 }
7068<DocLine>{NONLopt}/"\n" { // whole line
7069 yyextra->docBlock << yytext;
7070 handleCommentBlock(yyscanner,yyextra->docBlock.str(),yyextra->current->brief.isEmpty());
7071 BEGIN( yyextra->docBlockContext );
7072 }
7073
7074 /* ---- Comments blocks ------ */
7075
7076<DocBlock>"*"*{CCE} { // end of comment block
7077 handleCommentBlock(yyscanner,yyextra->docBlock.str(),FALSE);
7078 BEGIN(yyextra->docBlockContext);
7079 }
7080<DocBlock>"\\ilinebr "{B}*"*"/[^/] {
7081 QCString indent;
7082 indent.fill(' ',computeIndent(yytext+8,yyextra->column));
7083 yyextra->docBlock << "\\ilinebr " << indent;
7084 }
7085<DocBlock>^{B}*"*"+/[^/] {
7086 QCString indent;
7087 indent.fill(' ',computeIndent(yytext,yyextra->column));
7088 yyextra->docBlock << indent;
7089 }
7090<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
7091 QCString indent;
7092 indent.fill(' ',computeIndent(yytext,yyextra->column));
7093 yyextra->docBlock << indent;
7094 }
7095<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
7096 }
7097<DocBlock>{CPPC} { // slashes in the middle of a comment block
7098 yyextra->docBlock << yytext;
7099 }
7100<DocBlock>{CCS} { // start of a new comment in the
7101 // middle of a comment block
7102 yyextra->docBlock << yytext;
7103 }
7104<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
7105 yyextra->docBlock << yytext;
7106 }
7107<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
7108 yyextra->docBlock << yytext;
7109 char blockName[] = "f$";
7110 char c = yytext[2];
7111 if (c=='[') blockName[1]=']';
7112 else if (c=='{') blockName[1]='}';
7113 else if (c=='(') blockName[1]=')';
7114 startVerbatimBlock(yyscanner,blockName);
7115 BEGIN(DocCopyBlock);
7116 }
7117<DocBlock>{CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
7118 yyextra->fileName = &yytext[6];
7119 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7120 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
7121 yyextra->docBlock << yytext;
7122 }
7123<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
7124 yyextra->fileName = &yytext[6];
7125 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7126 yyextra->docBlock << yytext;
7127 }
7128<DocBlock>{CMD}"iline"{LINENR}{B} {
7129 bool ok = false;
7130 int nr = QCString(&yytext[6]).toInt(&ok);
7131 if (!ok)
7132 {
7133 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
7134 }
7135 else
7136 {
7137 yyextra->yyLineNr = nr;
7138 }
7139 yyextra->docBlock << yytext;
7140 }
7141<DocBlock>{B}*"<"{PRE}">" {
7142 yyextra->docBlock << yytext;
7143 startVerbatimBlock(yyscanner,"<pre>");
7144 BEGIN(DocCopyBlock);
7145 }
7146<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
7147 yyextra->docBlock << yytext;
7148 startVerbatimBlock(yyscanner,"uml");
7149 BEGIN(DocCopyBlock);
7150 }
7151<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!)
7152 yyextra->docBlock << yytext;
7153 startVerbatimBlock(yyscanner,&yytext[1]);
7154 BEGIN(DocCopyBlock);
7155 }
7156<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7157 QCString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7158 yyextra->docBlock << "\\ilinebr ";
7159 yyextra->docBlock << pat;
7160 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length());
7161 BEGIN(DocCopyBlock);
7162 }
7163<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7164 QCString pat = substitute(yytext,"*"," ");
7165 yyextra->docBlock << pat;
7166 startVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length());
7167 BEGIN(DocCopyBlock);
7168 }
7169<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7170<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7171<DocBlock>"\\ilinebr "({B}*"*"+)?{B}{0,3}"```"[`]* {
7172 QCString pat = substitute(yytext+9,"*"," "); // skip over "\ilinebr " part
7173 yyextra->docBlock << "\\ilinebr ";
7174 yyextra->docBlock << pat;
7175 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length());
7176 BEGIN(DocCopyBlock);
7177 }
7178<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
7179<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]*/"{"[^}]+"}" |
7180<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7181 QCString pat = substitute(yytext,"*"," ");
7182 yyextra->docBlock << pat;
7183 startVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length());
7184 BEGIN(DocCopyBlock);
7185 }
7186<DocBlock>{B}*"<"{CODE}">" {
7187 if (yyextra->insideCS)
7188 {
7189 yyextra->docBlock << yytext;
7190 startVerbatimBlock(yyscanner,"<code>");
7191 BEGIN(DocCopyBlock);
7192 }
7193 else
7194 {
7195 REJECT;
7196 }
7197 }
7198<DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
7199 yyextra->docBlock << yytext;
7200 }
7201<DocBlock>\n { // newline
7202 lineCount(yyscanner);
7203 yyextra->docBlock << *yytext;
7204 }
7205<DocBlock>. { // command block
7206 yyextra->docBlock << *yytext;
7207 }
7208
7209 /* ---- Copy verbatim sections ------ */
7210
7211<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
7212 if (endVerbatimBlock(yyscanner,"<pre>"))
7213 {
7214 BEGIN(DocBlock);
7215 }
7216 yyextra->docBlock << yytext;
7217 }
7218<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
7219 if (endVerbatimBlock(yyscanner,"<code>"))
7220 {
7221 BEGIN(DocBlock);
7222 }
7223 yyextra->docBlock << yytext;
7224 }
7225<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
7226 if (endVerbatimBlock(yyscanner,&yytext[1]))
7227 {
7228 BEGIN(DocBlock);
7229 }
7230 yyextra->docBlock << yytext;
7231 }
7232<DocCopyBlock>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
7233 if (endVerbatimBlock(yyscanner,&yytext[4]))
7234 {
7235 BEGIN(DocBlock);
7236 }
7237 yyextra->docBlock << yytext;
7238 }
7239<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
7240 if ((yyextra->docBlockName=="verbatim") || (yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7241 {
7242 REJECT;
7243 }
7244 else
7245 {
7246 QCString indent;
7247 indent.fill(' ',computeIndent(yytext,0));
7248 yyextra->docBlock << indent;
7249 }
7250 }
7251<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
7252 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7253 {
7254 QCString indent;
7255 indent.fill(' ',computeIndent(yytext,0));
7256 yyextra->docBlock << indent;
7257 }
7258 else
7259 {
7260 REJECT;
7261 }
7262 }
7263<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
7264 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7265 {
7266 QCString indent;
7267 indent.fill(' ',computeIndent(yytext,-1));
7268 yyextra->docBlock << indent+"*";
7269 }
7270 else
7271 {
7272 REJECT;
7273 }
7274 }
7275<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
7276 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
7277 {
7278 QCString indent;
7279 if (yyextra->nestedComment>0) // keep * it is part of the code
7280 {
7281 indent.fill(' ',computeIndent(yytext,-1));
7282 yyextra->docBlock << indent+"*";
7283 }
7284 else // remove * it is part of the comment block
7285 {
7286 indent.fill(' ',computeIndent(yytext,0));
7287 yyextra->docBlock << indent;
7288 }
7289 }
7290 else
7291 {
7292 REJECT;
7293 }
7294 }
7295<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
7296 QCString pat = substitute(yytext,"*"," ");
7297 if (endVerbatimBlock(yyscanner,"~~~",pat.stripWhiteSpace().length()))
7298 {
7299 BEGIN(DocBlock);
7300 }
7301 yyextra->docBlock << pat;
7302 }
7303<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
7304 QCString pat = substitute(yytext,"*"," ");
7305 if (endVerbatimBlock(yyscanner,"```",pat.stripWhiteSpace().length()))
7306 {
7307 BEGIN(DocBlock);
7308 }
7309 yyextra->docBlock << pat;
7310 }
7311<DocCopyBlock>[^<@/\*\]~"\$\\\n]+ { // any character that is not special
7312 yyextra->docBlock << yytext;
7313 }
7314<DocCopyBlock>\" {
7315 yyextra->docBlock << yytext;
7316 if (yyextra->docBlockName=="code" || yyextra->docBlockName=="iliteral")
7317 // to support end of comment character sequences inside
7318 // a string literal of a code block, see #6737
7319 {
7320 yyextra->lastStringContext=YY_START;
7321 yyextra->pCopyQuotedGString=&yyextra->docBlock;
7322 yyextra->stopAtInvalidString=true;
7323 BEGIN(CopyGString);
7324 }
7325 }
7326<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
7327 if (yytext[1]=='*')
7328 {
7329 yyextra->nestedComment++;
7330 }
7331 else if (yytext[0]=='*' && yyextra->nestedComment>0)
7332 {
7333 yyextra->nestedComment--;
7334 }
7335 yyextra->docBlock << yytext;
7336 }
7337<DocCopyBlock>\n { // newline
7338 yyextra->docBlock << *yytext;
7339 lineCount(yyscanner);
7340 }
7341<DocCopyBlock>. { // any other character
7342 yyextra->docBlock << *yytext;
7343 }
7344<DocCopyBlock><<EOF>> {
7345 warn(yyextra->fileName,yyextra->yyLineNr,
7346 "reached end of file while inside a '{}' block!"
7347 " The command that should end the block seems to be missing!",
7348 yyextra->docBlockName);
7349 yyterminate();
7350 }
#define yyterminate()
7351
7352
7353 /* ------------- Prototype parser -------------- */
7354
7355<Prototype>"operator"{B}*"("{B}*")" {
7356 yyextra->current->name+=yytext;
7357 }
7358<Prototype>"(" {
7359 yyextra->current->args+=*yytext;
7360 yyextra->currentArgumentContext = PrototypeQual;
7361 yyextra->fullArgString = yyextra->current->args;
7362 yyextra->copyArgString = &yyextra->current->args;
7363 BEGIN( ReadFuncArgType ) ;
7364 }
7365<Prototype>"("({ID}"::")*({B}*[&*])+ {
7366 if (yyextra->insidePHP) // reference parameter
7367 {
7368 REJECT;
7369 }
7370 else
7371 {
7372 yyextra->current->type+=yyextra->current->name+yytext;
7373 yyextra->current->name.clear();
7374 BEGIN( PrototypePtr );
7375 }
7376 }
7377<PrototypePtr>{SCOPENAME} {
7378 yyextra->current->name+=yytext;
7379 }
7380<PrototypePtr>"(" {
7381 yyextra->current->args+=*yytext;
7382 yyextra->currentArgumentContext = PrototypeQual;
7383 yyextra->fullArgString = yyextra->current->args;
7384 yyextra->copyArgString = &yyextra->current->args;
7385 BEGIN( ReadFuncArgType ) ;
7386 }
7387<PrototypePtr>")" {
7388 yyextra->current->type+=')';
7389 BEGIN( Prototype );
7390 }
7391<PrototypePtr>. {
7392 yyextra->current->name+=yytext;
7393 }
7394<PrototypeQual>"{" {
7395 BEGIN( PrototypeSkipLine);
7396 }
7397<PrototypeQual>{B}*"const"{B}* {
7398 yyextra->current->args += " const ";
7399 yyextra->current->argList.setConstSpecifier(TRUE);
7400 }
7401<PrototypeQual>{B}*"volatile"{B}* {
7402 yyextra->current->args += " volatile ";
7403 yyextra->current->argList.setVolatileSpecifier(TRUE);
7404 }
7405<PrototypeQual>{B}*"="{B}*"0"{B}* {
7406 yyextra->current->args += " = 0";
7407 yyextra->current->virt = Specifier::Pure;
7408 yyextra->current->argList.setPureSpecifier(TRUE);
7409 }
7410<PrototypeQual>"throw"{B}*"(" {
7411 yyextra->current->exception = "throw(";
7412 BEGIN(PrototypeExc);
7413 }
7414<PrototypeExc>")" {
7415 yyextra->current->exception += ')';
7416 BEGIN(PrototypeQual);
7417 }
7418<PrototypeExc>. {
7419 yyextra->current->exception += *yytext;
7420 }
7421<PrototypeQual>. {
7422 yyextra->current->args += *yytext;
7423 }
7424<Prototype>. {
7425 yyextra->current->name += *yytext;
7426 }
7427<PrototypeSkipLine>. {
7428 }
7429
7430
7431
7432
7433<SkipCxxComment>.*"\\\n" { // line continuation
7434 if (yyextra->insideCS)
7435 {
7436 REJECT;
7437 }
7438 else
7439 {
7440 lineCount(yyscanner);
7441 }
7442 }
7443<SkipCxxComment>{ANYopt}/\n {
7444 BEGIN( yyextra->lastCContext ) ;
7445 }
7446<SkipComment>[^\*\n]+
7447
7448 /* ------------ Generic rules -------------- */
7449
7450<*>"[[" { // C++11 attribute
7451 if (!yyextra->insideCpp) REJECT;
7452 if (YY_START == CopyGString || YY_START == CopyGString) REJECT;
7453 yyextra->lastC11AttributeContext = YY_START;
7454 BEGIN( SkipC11Attribute );
7455 }
7456
7457<*>\n { lineCount(yyscanner); }
7458<*>\" {
7459 if (yyextra->insideIDL && yyextra->insideCppQuote)
7460 {
7461 BEGIN(EndCppQuote);
7462 }
7463 else if (yyextra->insidePHP)
7464 {
7465 yyextra->lastStringContext=YY_START;
7466 BEGIN(SkipString);
7467 }
7468 }
7469<*>^{B}*"#" {
7470 if (!yyextra->insidePHP)
7471 {
7472 yyextra->lastCPPContext = YY_START;
7473 BEGIN( SkipCPP ) ;
7474 }
7475 else
7476 {
7477 yyextra->lastCContext = YY_START ;
7478 BEGIN( SkipCxxComment ) ;
7479 }
7480 }
7481<*>"#" {
7482 if (!yyextra->insidePHP)
7483 REJECT;
7484 yyextra->lastCContext = YY_START ;
7485 BEGIN( SkipCxxComment ) ;
7486 }
7487<*>\' {
7488 if (yyextra->insidePHP)
7489 {
7490 yyextra->lastStringContext=YY_START;
7491 BEGIN(SkipPHPString);
7492 }
7493 }
7494<*>\? {
7495 if (yyextra->insideCS && (YY_START != SkipRound) && (YY_START != CSAccessorDecl))
7496 {
7497 if (yyextra->current->type.isEmpty())
7498 {
7499 if (yyextra->current->name.isEmpty())
7500 yyextra->current->name="?";
7501 else
7502 yyextra->current->name+="?";
7503 }
7504 else
7505 {
7506 yyextra->current->type+="?";
7507 }
7508 }
7509 }
7510<*>"}" { yyextra->exported=false; }
7511<*>.
7512<SkipComment>{CPPC}|{CCS}
7513<*>{CCS} { yyextra->lastCContext = YY_START ;
7514 BEGIN( SkipComment ) ;
7515 }
7516<SkipComment>{B}*{CCE} { BEGIN( yyextra->lastCContext ) ; }
7517<*>{CPPC} {
7518 yyextra->lastCContext = YY_START ;
7519 BEGIN( SkipCxxComment ) ;
7520 }
7521<<EOF>> {
7522 if (yyextra->insideCS && yyextra->fakeNS)
7523 {
7524 yyextra->fakeNS--;
7525 unput('}');
7526 BEGIN ( ReadNSBody);
7527 }
7528 else
7529 {
7530 yyterminate();
7531 }
7532 }
7533%%
7534
7535//----------------------------------------------------------------------------
7536static int yyread(yyscan_t yyscanner,char *buf,int max_size)
7537{
7538 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7539 int c=0;
7540 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
7541 {
7542 *buf = yyextra->inputString[yyextra->inputPosition++] ;
7543 //printf("%d (%c)\n",*buf,*buf);
7544 c++; buf++;
7545 }
7546 return c;
7547}
7548
7549
7550static void initParser(yyscan_t yyscanner)
7551{
7552 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7553 yyextra->outerScopeEntries.clear();
7554 yyextra->baseName.clear();
7555 yyextra->protection = Protection::Public;
7556 yyextra->baseProt = Protection::Public;
7557 yyextra->sharpCount = 0;
7558 yyextra->roundCount = 0;
7559 yyextra->curlyCount = 0;
7560 yyextra->mtype = MethodTypes::Method;
7561 yyextra->isStatic = FALSE;
7562 yyextra->virt = Specifier::Normal;
7563 yyextra->baseVirt = Specifier::Normal;
7564 yyextra->isTypedef = FALSE;
7565 yyextra->insideTryBlock = FALSE;
7566 yyextra->insideFormula = FALSE;
7567 yyextra->insideCode=FALSE;
7568 yyextra->insideCli=Config_getBool(CPP_CLI_SUPPORT);
7569 yyextra->previous = 0;
7570 yyextra->firstTypedefEntry.reset();
7571 yyextra->memspecEntry.reset();
7572}
7573
7574static void initEntry(yyscan_t yyscanner)
7575{
7576 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7577 if (yyextra->insideJava)
7578 {
7579 yyextra->protection = (yyextra->current_root->spec.isInterface() || yyextra->current_root->spec.isEnum()) ? Protection::Public : Protection::Package;
7580 }
7581 yyextra->current->protection = yyextra->protection;
7582 yyextra->current->exported = yyextra->exported ;
7583 yyextra->current->mtype = yyextra->mtype;
7584 yyextra->current->virt = yyextra->virt;
7585 yyextra->current->isStatic = yyextra->isStatic;
7586 yyextra->current->lang = yyextra->language;
7587 //printf("*** initEntry(yyscanner) yyextra->language=%d\n",yyextra->language);
7588 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
7589 yyextra->isTypedef=FALSE;
7590}
7591
7592
7593//-----------------------------------------------------------------------------
7594
7595static void storeClangId(yyscan_t yyscanner,const char *id)
7596{
7597 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7598 if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
7599 {
7600 yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,id);
7601 }
7602}
7603
7604static void lineCount(yyscan_t yyscanner)
7605{
7606 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7607 int tabSize = Config_getInt(TAB_SIZE);
7608 const char *p;
7609 for (p = yytext ; *p ; ++p )
7610 {
7611 if (*p=='\n')
7612 {
7613 yyextra->yyLineNr++,yyextra->column=0,yyextra->yyColNr=1;
7614 }
7615 else if (*p=='\t')
7616 {
7617 yyextra->column+=tabSize - (yyextra->column%tabSize);
7618 }
7619 else
7620 {
7621 yyextra->column++,yyextra->yyColNr++;
7622 }
7623 }
7624 //printf("lineCount()=%d\n",yyextra->column);
7625}
7626
7627static inline int computeIndent(const char *s,int startIndent)
7628{
7629 int col=startIndent;
7630 int tabSize=Config_getInt(TAB_SIZE);
7631 const char *p=s;
7632 char c;
7633 while ((c=*p++))
7634 {
7635 if (c=='\t') col+=tabSize-(col%tabSize);
7636 else if (c=='\n') col=0;
7637 else col++;
7638 }
7639 return col;
7640}
7641
7642static QCString extractBeginRawStringDelimiter(const char *rawStart)
7643{
7644 QCString text=rawStart;
7645 int i = text.find('"');
7646 assert(i!=-1);
7647 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
7648}
7649
7650static QCString extractEndRawStringDelimiter(const char *rawEnd)
7651{
7652 QCString text=rawEnd;
7653 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
7654}
7655
7656static inline void initMethodProtection(yyscan_t yyscanner,Protection prot)
7657{
7658 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7659 yyextra->current->protection = yyextra->protection = prot;
7660 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
7661 yyextra->current->type.clear();
7662 yyextra->current->name.clear();
7663 yyextra->current->args.clear();
7664 yyextra->current->argList.clear();
7665 lineCount(yyscanner) ;
7666}
7667
7668static void addType(yyscan_t yyscanner)
7669{
7670 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7671 size_t tl=yyextra->current->type.length();
7672 if( tl>0 && !yyextra->current->name.isEmpty() && yyextra->current->type.at(tl-1)!='.')
7673 {
7674 yyextra->current->type += ' ' ;
7675 }
7676 yyextra->current->type += yyextra->current->name;
7677 yyextra->current->name.clear() ;
7678 tl=yyextra->current->type.length();
7679 if( tl>0 && !yyextra->current->args.isEmpty() && yyextra->current->type.at(tl-1)!='.')
7680 {
7681 yyextra->current->type += ' ' ;
7682 }
7683 yyextra->current->type += yyextra->current->args ;
7684 yyextra->current->args.clear() ;
7685 yyextra->current->argList.clear();
7686}
7687
7688
7689static QCString stripQuotes(const char *s)
7690{
7691 QCString name;
7692 if (s==nullptr || *s==0) return name;
7693 name=s;
7694 if (name.at(0)=='"' && name.at(name.length()-1)=='"')
7695 {
7696 name=name.mid(1,name.length()-2);
7697 }
7698 return name;
7699}
7700
7701static QCString stripFuncPtr(const QCString &type)
7702{
7703 // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
7704 // also needed to reset the type for 'arr' to 'int' in 'typedef int (&fp)(), arr[2]'
7705 size_t i=type.length();
7706 bool funcPtr = i>0 && type[i-1]==')';
7707 if (funcPtr) i--;
7708 while (i>0 && (type[i-1]=='*' || type[i-1]=='&' || type[i-1]==' ')) i--;
7709 if (funcPtr && i>0 && type[i-1]=='(') i--;
7710 return type.left(i);
7711}
7712
7713//-----------------------------------------------------------------
7714static void startVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize)
7715{
7716 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7717 if (Config_getBool(MARKDOWN_SUPPORT))
7718 {
7719 yyextra->docBlock << "\\iskip";
7720 }
7721 yyextra->docBlockName=blockName;
7722 yyextra->fencedSize=fencedSize;
7723 yyextra->nestedComment=0;
7724}
7725
7726//-----------------------------------------------------------------
7727static bool endVerbatimBlock(yyscan_t yyscanner,const QCString &blockName,size_t fencedSize)
7728{
7729 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7730 if (yyextra->docBlockName==blockName && (fencedSize==0 || fencedSize==yyextra->fencedSize))
7731 {
7732 if (Config_getBool(MARKDOWN_SUPPORT))
7733 {
7734 yyextra->docBlock << "\\endiskip";
7735 }
7736 yyextra->docBlockName="";
7737 return true;
7738 }
7739 return false;
7740}
7741
7742//-----------------------------------------------------------------
7743
7744// return TRUE iff req holds the start of a requires expression
7745// or sub-expression without parenthesis, i.e. req is empty or ends with || or &&
7747{
7748 QCString r = req.stripWhiteSpace();
7749 return r.isEmpty() || r.endsWith("&&") || r.endsWith("||") || r.endsWith("and") || r.endsWith("or");
7750}
7751
7752//-----------------------------------------------------------------
7753
7754static bool nameIsOperator(QCString &name)
7755{
7756 int i=name.find("operator");
7757 if (i==-1) return FALSE;
7758 if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X
7759 if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator
7760 return FALSE; // case TEXToperatorTEXT
7761}
7762
7763//-----------------------------------------------------------------------------
7764
7765static void setContext(yyscan_t yyscanner)
7766{
7767 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7768 yyextra->language = getLanguageFromFileName(yyextra->fileName);
7769 yyextra->insideIDL = yyextra->language==SrcLangExt::IDL;
7770 yyextra->insideJava = yyextra->language==SrcLangExt::Java;
7771 yyextra->insideCS = yyextra->language==SrcLangExt::CSharp;
7772 yyextra->insideD = yyextra->language==SrcLangExt::D;
7773 yyextra->insidePHP = yyextra->language==SrcLangExt::PHP;
7774 yyextra->insideObjC = yyextra->language==SrcLangExt::ObjC;
7775 yyextra->insideJS = yyextra->language==SrcLangExt::JS;
7776 yyextra->insideSlice = yyextra->language==SrcLangExt::Slice;
7777 yyextra->insideCpp = (yyextra->language==SrcLangExt::Cpp ||
7778 yyextra->language==SrcLangExt::Lex);
7779 //printf("setContext(%s) yyextra->insideIDL=%d yyextra->insideJava=%d yyextra->insideCS=%d "
7780 // "yyextra->insideD=%d yyextra->insidePHP=%d yyextra->insideObjC=%d\n",
7781 // qPrint(yyextra->fileName),yyextra->insideIDL,yyextra->insideJava,yyextra->insideCS,yyextra->insideD,yyextra->insidePHP,yyextra->insideObjC
7782 // );
7783}
7784
7785//-----------------------------------------------------------------------------
7786
7787static void prependScope(yyscan_t yyscanner)
7788{
7789 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7790 if (yyextra->current_root->section.isScope())
7791 {
7792 //printf("--- prependScope %s to %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
7793 yyextra->current->name.prepend(yyextra->current_root->name+"::");
7794 //printf("prependScope #=%d #yyextra->current=%d\n",yyextra->current_root->tArgLists->count(),yyextra->current->tArgLists->count());
7795 for (const ArgumentList &srcAl : yyextra->current_root->tArgLists)
7796 {
7797 yyextra->current->tArgLists.insert(yyextra->current->tArgLists.begin(),srcAl);
7798 }
7799 }
7800}
7801
7802//-----------------------------------------------------------------------------
7803
7804/*! Returns TRUE iff the yyextra->current entry could be a K&R style C function */
7805static bool checkForKnRstyleC(yyscan_t yyscanner)
7806{
7807 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7808 if (!yyextra->fileName.lower().endsWith(".c")) return FALSE; // must be a C file
7809 if (yyextra->current->argList.empty()) return FALSE; // must have arguments
7810 for (const Argument &a : yyextra->current->argList)
7811 {
7812 // in K&R style argument do not have a type, but doxygen expects a type
7813 // so it will think the argument has no name
7814 if (a.type.isEmpty() || !a.name.isEmpty()) return FALSE;
7815 }
7816 return TRUE;
7817}
7818
7819static void setJavaProtection(yyscan_t yyscanner)
7820{
7821 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7822 if (yyextra->insideJava)
7823 {
7824 QCString text=yytext;
7825 yyextra->current->protection = Protection::Public;
7826 if (text.find("protected")!=-1)
7827 yyextra->current->protection = Protection::Protected;
7828 else if (text.find("private")!=-1)
7829 yyextra->current->protection = Protection::Private;
7830 else if (text.find("package")!=-1)
7831 yyextra->current->protection = Protection::Package;
7832 }
7833}
7834//-----------------------------------------------------------------------------
7835
7836static void splitKnRArg(yyscan_t yyscanner,QCString &oldStyleArgPtr,QCString &oldStyleArgName)
7837{
7838 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7839 int si = static_cast<int>(yyextra->current->args.length());
7840 if (yyextra->oldStyleArgType.isEmpty()) // new argument
7841 {
7842 std::string args = yyextra->current->args.str();
7843 static const reg::Ex re(R"(\‍([^)]*\).*)"); // find first (...)
7844 int bi1=-1;
7845 int bi2=-1;
7846 reg::Match match;
7847 if (reg::search(args,match,re))
7848 {
7849 bi1=(int)match.position();
7850 size_t secondMatchStart = match.position()+match.length(); // search again after first match
7851 if (reg::search(args,match,re,secondMatchStart))
7852 {
7853 bi2=(int)match.position();
7854 }
7855 }
7856 char c;
7857 if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
7858 {
7859 int s=bi2+1; // keep opening (
7860 yyextra->oldStyleArgType = yyextra->current->args.left(s);
7861 int i=s;
7862 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
7863 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
7864 s=i;
7865 while (i<si && isId(yyextra->current->args.at(i))) i++;
7866 oldStyleArgName = yyextra->current->args.mid(s,i-s);
7867 yyextra->oldStyleArgType+=yyextra->current->args.mid(i);
7868 }
7869 else if (bi1!=-1) // redundant braces like in "int (*var)"
7870 {
7871 int s=bi1; // strip opening (
7872 yyextra->oldStyleArgType = yyextra->current->args.left(s);
7873 s++;
7874 int i=s+1;
7875 while (i<si && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i++;
7876 yyextra->oldStyleArgType += yyextra->current->args.mid(s,i-s);
7877 s=i;
7878 while (i<si && isId(yyextra->current->args.at(i))) i++;
7879 oldStyleArgName = yyextra->current->args.mid(s,i-s);
7880 }
7881 else // normal "int *var"
7882 {
7883 int l=si,i=l-1,j;
7884 // look for start of name in "type *name"
7885 while (i>=0 && isId(yyextra->current->args.at(i))) i--;
7886 j=i+1;
7887 // look for start of *'s
7888 while (i>=0 && ((c=yyextra->current->args.at(i))=='*' || isspace((uint8_t)c))) i--;
7889 i++;
7890 if (i!=l)
7891 {
7892 yyextra->oldStyleArgType=yyextra->current->args.left(i);
7893 oldStyleArgPtr=yyextra->current->args.mid(i,j-i);
7894 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
7895 }
7896 else
7897 {
7898 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
7899 }
7900 }
7901 }
7902 else // continuation like *arg2 in "int *args,*arg2"
7903 {
7904 int l=si,j=0;
7905 char c;
7906 while (j<l && ((c=yyextra->current->args.at(j))=='*' || isspace((uint8_t)c))) j++;
7907 if (j>0)
7908 {
7909 oldStyleArgPtr=yyextra->current->args.left(j);
7910 oldStyleArgName=yyextra->current->args.mid(j).stripWhiteSpace();
7911 }
7912 else
7913 {
7914 oldStyleArgName=yyextra->current->args.stripWhiteSpace();
7915 }
7916 }
7917}
7918
7919//-----------------------------------------------------------------------------
7920
7921/*! Update the argument \a name with additional \a type info. For K&R style
7922 * function the type is found \e after the argument list, so this routine
7923 * in needed to fix up.
7924 */
7925static void addKnRArgInfo(yyscan_t yyscanner,const QCString &type,const QCString &name,
7926 const QCString &brief,const QCString &docs)
7927{
7928 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7929 for (Argument &a : yyextra->current->argList)
7930 {
7931 if (a.type==name)
7932 {
7933 a.type=type.stripWhiteSpace();
7934 a.type.stripPrefix("register ");
7935 a.name=name.stripWhiteSpace();
7936 if (!brief.isEmpty() && !docs.isEmpty())
7937 {
7938 a.docs=brief+"\n\n"+docs;
7939 }
7940 else if (!brief.isEmpty())
7941 {
7942 a.docs=brief;
7943 }
7944 else
7945 {
7946 a.docs=docs;
7947 }
7948 }
7949 }
7950}
7951
7952//-----------------------------------------------------------------------------
7953
7955{
7956 for (Argument &a : al)
7957 {
7958 if (!a.type.isEmpty() && a.name.isEmpty())
7959 { // a->type is actually the (typeless) parameter name, so move it
7960 a.name=a.type;
7961 a.type.clear();
7962 }
7963 }
7964}
7965
7966//-----------------------------------------------------------------------------
7967
7968static void startCommentBlock(yyscan_t yyscanner,bool brief)
7969{
7970 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7971 if (brief)
7972 {
7973 yyextra->current->briefFile = yyextra->fileName;
7974 yyextra->current->briefLine = yyextra->yyLineNr;
7975 }
7976 else
7977 {
7978 yyextra->current->docFile = yyextra->fileName;
7979 yyextra->current->docLine = yyextra->yyLineNr;
7980 }
7981}
7982
7983//----------------------------------------------------------------------------
7984
7985static void newEntry(yyscan_t yyscanner)
7986{
7987 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
7988 if (yyextra->tempEntry==0) // if temp entry is not 0, it holds yyextra->current,
7989 // and yyextra->current is actually replaced by yyextra->previous which was
7990 // already added to yyextra->current_root, so we should not add it again
7991 // (see bug723314)
7992 {
7993 yyextra->previous = yyextra->current;
7994 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
7995 }
7996 else
7997 {
7998 yyextra->previous = yyextra->current;
7999 yyextra->current = yyextra->tempEntry;
8000 yyextra->tempEntry.reset();
8001 }
8002 initEntry(yyscanner);
8003}
8004
8005static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief)
8006{
8007 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8008 AUTO_TRACE("doc='{}' is_brief={}",Trace::trunc(doc),brief);
8009 bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
8010 if (yyextra->docBlockInBody && hideInBodyDocs) return;
8011 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; // line of block start
8012
8013 // fill in inbodyFile && inbodyLine the first time, see bug 633891
8014 std::shared_ptr<Entry> docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current;
8015 if (yyextra->docBlockInBody && docEntry && docEntry->inbodyLine==-1)
8016 {
8017 docEntry->inbodyFile = yyextra->fileName;
8018 docEntry->inbodyLine = lineNr;
8019 }
8020
8021 int position=0;
8022 bool needsEntry=FALSE;
8023 GuardedSectionStack guards;
8024 Markdown markdown(yyextra->fileName,lineNr);
8025 QCString strippedDoc = stripIndentation(doc);
8026 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8027 while (yyextra->commentScanner.parseCommentBlock(
8028 yyextra->thisParser,
8029 yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(),
8030 processedDoc, // text
8031 yyextra->fileName, // file
8032 lineNr, // line of block start
8033 yyextra->docBlockInBody ? FALSE : brief, // isBrief
8034 yyextra->docBlockInBody ? FALSE : yyextra->docBlockAutoBrief, // isJavaDocStyle
8035 yyextra->docBlockInBody, // isInBody
8036 yyextra->protection,
8037 position,
8038 needsEntry,
8039 Config_getBool(MARKDOWN_SUPPORT),
8040 &guards
8041 )
8042 )
8043 {
8044 //printf("parseCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8045 if (needsEntry)
8046 {
8047 QCString docFile = yyextra->current->docFile;
8048 newEntry(yyscanner);
8049 yyextra->current->docFile = docFile;
8050 yyextra->current->docLine = lineNr;
8051 }
8052 }
8053 if (needsEntry)
8054 {
8055 newEntry(yyscanner);
8056 }
8057
8058 if (yyextra->docBlockTerm)
8059 {
8060 unput(yyextra->docBlockTerm);
8061 yyextra->docBlockTerm=0;
8062 }
8063}
8064
8066{
8067 AUTO_TRACE();
8068 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8069 for (Argument &a : al)
8070 {
8071 AUTO_TRACE_ADD("Param '{}' docs='{}'",a.name,Trace::trunc(a.docs));
8072 if (!a.docs.isEmpty())
8073 {
8074 if (a.name.isEmpty() && a.type == "...") a.name= "...";
8075 int position=0;
8076 bool needsEntry;
8077
8078 // save context
8079 QCString orgDoc = yyextra->current->doc;
8080 QCString orgBrief = yyextra->current->brief;
8081 int orgDocLine = yyextra->current->docLine;
8082 int orgBriefLine = yyextra->current->briefLine;
8083
8084 yyextra->current->doc.clear();
8085 yyextra->current->brief.clear();
8086
8087 //printf("handleParametersCommentBlock [%s]\n",qPrint(doc));
8088 int lineNr = orgDocLine;
8089 GuardedSectionStack guards;
8090 Markdown markdown(yyextra->fileName,lineNr);
8091 QCString strippedDoc = stripIndentation(a.docs);
8092 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
8093 while (yyextra->commentScanner.parseCommentBlock(
8094 yyextra->thisParser,
8095 yyextra->current.get(),
8096 processedDoc, // text
8097 yyextra->fileName, // file
8098 lineNr,
8099 FALSE,
8100 FALSE,
8101 FALSE,
8102 yyextra->protection,
8103 position,
8104 needsEntry,
8105 Config_getBool(MARKDOWN_SUPPORT),
8106 &guards
8107 )
8108 )
8109 {
8110 //printf("handleParametersCommentBlock position=%d [%s]\n",position,qPrint(doc)+position);
8111 if (needsEntry) newEntry(yyscanner);
8112 }
8113 if (needsEntry)
8114 {
8115 newEntry(yyscanner);
8116 }
8117 a.docs = yyextra->current->doc;
8118
8119 // restore context
8120 yyextra->current->doc = orgDoc;
8121 yyextra->current->brief = orgBrief;
8122 yyextra->current->docLine = orgDocLine;
8123 yyextra->current->briefLine = orgBriefLine;
8124 }
8125 }
8126}
8127
8128
8129//----------------------------------------------------------------------------
8130
8131static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt)
8132{
8133 AUTO_TRACE("name={}",rt->name);
8134 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8135 for (const auto &ce : rt->children())
8136 {
8137 if (!ce->program.empty())
8138 {
8139 AUTO_TRACE_ADD("compound name='{}' program='{}'",Trace::trunc(ce->name),Trace::trunc(ce->program.str()));
8140 // init scanner state
8141 yyextra->padCount=0;
8142 //depthIf = 0;
8143 yyextra->column=0;
8144 yyextra->programStr = ce->program.str();
8145 yyextra->inputString = yyextra->programStr.data();
8146 yyextra->inputPosition = 0;
8147 if (ce->section.isEnum() || ce->spec.isEnum())
8148 BEGIN( FindFields ) ;
8149 else
8150 BEGIN( FindMembers ) ;
8151 yyextra->current_root = ce;
8152 yyextra->fileName = ce->fileName;
8153 //setContext();
8154 yyextra->yyLineNr = ce->bodyLine;
8155 yyextra->yyColNr = ce->bodyColumn;
8156 yyextra->insideObjC = ce->lang==SrcLangExt::ObjC;
8157 //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC);
8158 yyextra->current = std::make_shared<Entry>();
8159 yyextra->isStatic = FALSE;
8160 initEntry(yyscanner);
8161
8162 // deep copy group list from parent (see bug 727732)
8163 bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS);
8164 if (autoGroupNested && !rt->groups.empty() && !ce->section.isEnum() && !ce->spec.isEnum())
8165 {
8166 ce->groups = rt->groups;
8167 }
8168
8169 int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
8170 // set default protection based on the compound type
8171 if ( ce->section.isClass() ) // class
8172 {
8173 if (yyextra->insidePHP || yyextra->insideD || yyextra->insideJS || yyextra->insideIDL || yyextra->insideSlice)
8174 {
8175 yyextra->current->protection = yyextra->protection = Protection::Public ;
8176 }
8177 else if (yyextra->insideJava)
8178 {
8179 yyextra->current->protection = yyextra->protection = (ce->spec.isInterface() || ce->spec.isEnum()) ? Protection::Public : Protection::Package;
8180 }
8181 else if (ce->spec.isInterface() || ce->spec.isRef() || ce->spec.isValue() || ce->spec.isStruct() || ce->spec.isUnion())
8182 {
8183 if (ce->lang==SrcLangExt::ObjC)
8184 {
8185 yyextra->current->protection = yyextra->protection = Protection::Protected ;
8186 }
8187 else
8188 {
8189 yyextra->current->protection = yyextra->protection = Protection::Public ;
8190 }
8191 }
8192 else
8193 {
8194 yyextra->current->protection = yyextra->protection = Protection::Private ;
8195 }
8196 }
8197 else if (ce->section.isEnum() ) // enum
8198 {
8199 yyextra->current->protection = yyextra->protection = ce->protection;
8200 }
8201 else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
8202 {
8203 if (ce->section.isNamespace() ) // unnamed namespace
8204 {
8205 yyextra->current->isStatic = yyextra->isStatic = TRUE;
8206 }
8207 yyextra->current->protection = yyextra->protection = ce->protection;
8208 yyextra->current->exported = yyextra->exported = false;
8209 }
8210 else if (ce->section.isNamespace() )
8211 {
8212 yyextra->current->protection = yyextra->protection = Protection::Public ;
8213 yyextra->current->exported = yyextra->exported = ce->exported;
8214 }
8215 else // named struct, union, protocol, category
8216 {
8217 yyextra->current->protection = yyextra->protection = Protection::Public ;
8218 yyextra->current->exported = yyextra->exported = false;
8219 }
8220 yyextra->mtype = MethodTypes::Method;
8221 yyextra->virt = Specifier::Normal;
8222 //printf("name=%s yyextra->current->isStatic=%d yyextra->isStatic=%d\n",qPrint(ce->name),yyextra->current->isStatic,yyextra->isStatic);
8223
8224 //memberGroupId = DOX_NOGROUP;
8225 //memberGroupRelates.clear();
8226 //memberGroupInside.clear();
8227 QCString name = ce->name;
8228 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
8229
8230 scannerYYlex(yyscanner);
8231 yyextra->lexInit=TRUE;
8232 //forceEndGroup();
8233
8234 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
8235
8236 yyextra->programStr.clear();
8237 ce->program.str(std::string());
8238
8239
8240 //if (depthIf>0)
8241 //{
8242 // warn(yyextra->fileName,yyextra->yyLineNr,"Documentation block ended in the middle of a conditional section!");
8243 //}
8244 }
8245 parseCompounds(yyscanner,ce);
8246 }
8247}
8248
8249//----------------------------------------------------------------------------
8250
8251static void parseMain(yyscan_t yyscanner,
8252 const QCString &fileName,
8253 const char *fileBuf,
8254 const std::shared_ptr<Entry> &rt,
8255 ClangTUParser *clangParser)
8256{
8257 AUTO_TRACE("fileName={}",fileName);
8258 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8259 initParser(yyscanner);
8260
8261 yyextra->inputString = fileBuf;
8262 yyextra->inputPosition = 0;
8263 yyextra->column = 0;
8264 scannerYYrestart(nullptr,yyscanner);
8265
8266 //depthIf = 0;
8267 yyextra->protection = Protection::Public;
8268 yyextra->mtype = MethodTypes::Method;
8269 yyextra->isStatic = FALSE;
8270 yyextra->exported = false;
8271 yyextra->virt = Specifier::Normal;
8272 yyextra->current_root = rt;
8273 yyextra->yyLineNr = 1 ;
8274 yyextra->yyBegLineNr = 1;
8275 yyextra->yyBegColNr = 0;
8276 yyextra->anonCount = 0;
8277 yyextra->anonNSCount = 0;
8278 yyextra->fileName = fileName;
8279 yyextra->clangParser = clangParser;
8280 setContext(yyscanner);
8281 rt->lang = yyextra->language;
8282 msg("Parsing file {}...\n",yyextra->fileName);
8283
8284 yyextra->current_root = rt;
8285 initParser(yyscanner);
8286 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
8287 yyextra->current = std::make_shared<Entry>();
8288 //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root);
8289 EntryType sec=guessSection(yyextra->fileName);
8290 if (!sec.isEmpty())
8291 {
8292 yyextra->current->name = yyextra->fileName;
8293 yyextra->current->section = sec;
8294 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8295 }
8296 yyextra->current->reset();
8297 initEntry(yyscanner);
8298 if ( yyextra->insidePHP )
8299 {
8300 BEGIN( FindMembersPHP );
8301 }
8302 else if ( yyextra->insideJava ) // add default java.lang package scope
8303 {
8304 yyextra->current->name="java::lang"; // '::' is used in doxygen's internal representation as a scope separator
8305 yyextra->current->fileName = yyextra->fileName;
8306 yyextra->current->section = EntryType::makeUsingDir();
8307 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
8308 initEntry(yyscanner);
8309 BEGIN( FindMembers );
8310 }
8311 else
8312 {
8313 BEGIN( FindMembers );
8314 }
8315
8316 scannerYYlex(yyscanner);
8317 yyextra->lexInit=TRUE;
8318
8319 if (YY_START==Comment)
8320 {
8321 warn(yyextra->fileName,yyextra->yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
8322 }
8323
8324 //forceEndGroup();
8325 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
8326
8327 yyextra->programStr.clear();
8328 rt->program.str(std::string());
8329
8330 parseCompounds(yyscanner,rt);
8331
8332 yyextra->anonNSCount++;
8333
8334 // add additional entries that were created during processing
8335 for (auto &[parent,child]: yyextra->outerScopeEntries)
8336 {
8337 //printf(">>> adding '%s' to scope '%s'\n",qPrint(child->name),qPrint(parent->name));
8338 parent->moveToSubEntryAndKeep(child);
8339 }
8340 yyextra->outerScopeEntries.clear();
8341
8342}
8343
8344//----------------------------------------------------------------------------
8345
8346static void parsePrototype(yyscan_t yyscanner,const QCString &text)
8347{
8348 AUTO_TRACE("text='{}'",Trace::trunc(text));
8349 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
8350 if (text.isEmpty())
8351 {
8352 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
8353 return;
8354 }
8355 if (!yyextra->current) // nothing to store (see bug683516)
8356 {
8357 return;
8358 }
8359
8360 const char *orgInputString;
8361 int orgInputPosition;
8362 YY_BUFFER_STATE orgState;
8363
8364 // save scanner state
8365 orgState = YY_CURRENT_BUFFER;
8366 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
8367 orgInputString = yyextra->inputString;
8368 orgInputPosition = yyextra->inputPosition;
8369
8370 // set new string
8371 yyextra->inputString = text.data();
8372 yyextra->inputPosition = 0;
8373 yyextra->column = 0;
8374 scannerYYrestart(nullptr, yyscanner);
8375 BEGIN(Prototype);
8376 scannerYYlex(yyscanner);
8377 yyextra->lexInit=TRUE;
8378
8379 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
8380 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.isEmpty())
8381 {
8382 yyextra->current->section = EntryType::makeVariableDoc();
8383 }
8384
8385 // restore original scanner state
8386 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
8387 yy_switch_to_buffer(orgState, yyscanner);
8388 yyextra->inputString = orgInputString;
8389 yyextra->inputPosition = orgInputPosition;
8390
8391
8392 //printf("**** parsePrototype end\n");
8393}
8394
8395//----------------------------------------------------------------------------
8396
8402
8404{
8405 scannerYYlex_init_extra(&p->state,&p->yyscanner);
8406#ifdef FLEX_DEBUG
8407 scannerYYset_debug(Debug::isFlagSet(Debug::Lex_scanner)?1:0,p->yyscanner);
8408#endif
8409}
8410
8412{
8413 scannerYYlex_destroy(p->yyscanner);
8414}
8415
8417 const char *fileBuf,
8418 const std::shared_ptr<Entry> &root,
8419 ClangTUParser *clangParser)
8420{
8421 AUTO_TRACE();
8422 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
8423 yyextra->thisParser = this;
8424
8425 DebugLex debugLex(Debug::Lex_scanner, __FILE__, qPrint(fileName));
8426
8427 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
8428}
8429
8430
8432{
8433 QCString fe=extension.lower();
8434 SrcLangExt lang = getLanguageFromFileName(extension);
8435 return (SrcLangExt::Cpp == lang) || (SrcLangExt::Lex == lang) ||
8436 !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
8437 fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5"
8438 );
8439}
8440
8442{
8443 ::parsePrototype(p->yyscanner,text);
8444}
8445
8446//----------------------------------------------------------------------------
8447
8448#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:8416
void parsePrototype(const QCString &text) override
Callback function called by the comment block scanner.
Definition scanner.l:8441
std::unique_ptr< Private > p
Definition scanner.h:46
~COutlineParser() override
Definition scanner.l:8411
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:8431
@ 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:1325
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:8400
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5721
QCString stripIndentation(const QCString &s, bool skipFirstLine)
Definition util.cpp:6428
EntryType guessSection(const QCString &name)
Definition util.cpp:349