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