Doxygen
Loading...
Searching...
No Matches
doctokenizer.l
Go to the documentation of this file.
-1/******************************************************************************
2 *
3 * $Id: $
4 *
5 *
6 * Copyright (C) 1997-2015 by Dimitri van Heesch.
7 *
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation under the terms of the GNU General Public License is hereby
10 * granted. No representations are made about the suitability of this software
11 * for any purpose. It is provided "as is" without express or implied warranty.
12 * See the GNU General Public License for more details.
13 *
14 * Documents produced by Doxygen are derivative works derived from the
15 * input used in their production; they are not affected by this license.
16 *
17 */
16
17%option never-interactive
18%option prefix="doctokenizerYY"
19%option reentrant
20%option extra-type="struct doctokenizerYY_state *"
21%top{
22#include <stdint.h>
23// forward declare yyscan_t to improve type safety
24#define YY_TYPEDEF_YY_SCANNER_T
25struct yyguts_t;
26typedef yyguts_t *yyscan_t;
yyguts_t * yyscan_t
Definition code.l:24
27}
29%{
30
31#include <ctype.h>
32#include <stack>
33#include <string>
34#include <cassert>
35
36#include "doctokenizer.h"
37#include "cmdmapper.h"
38#include "config.h"
39#include "message.h"
40#include "section.h"
41#include "membergroup.h"
42#include "definition.h"
43#include "doxygen.h"
44#include "portable.h"
45#include "cite.h"
46#include "regex.h"
47#include "debug.h"
48#include "docnode.h"
49#include "stringutil.h"
50
51#define YY_NO_INPUT 1
52#define YY_NO_UNISTD_H 1
54//--------------------------------------------------------------------------
55
56struct DocLexerContext
57{
58 DocLexerContext(const TokenInfo &tk,int r,int lvl,yy_size_t pos,const char *s,YY_BUFFER_STATE bs)
59 : token(tk), rule(r), autoListLevel(lvl), inputPos(pos), inputString(s), state(bs) {}
63 yy_size_t inputPos;
64 const char *inputString;
65 YY_BUFFER_STATE state;
66};
69{
71 // context for tokenizer phase
72 int commentState;
74 yy_size_t inputPos = 0;
75 const char *inputString = nullptr;
77 bool insidePre = false;
79 bool markdownSupport=true;
80 bool insideHtmlLink=false;
81 bool expectQuote=false;
83 // context for section finding phase
84 const Definition *definition = nullptr;
90 std::stack< std::unique_ptr<DocLexerContext> > lexerStack;
91 std::stack<int> stateStack;
93 int yyLineNr = 0;
94};
96#define lineCount(s,len) do { for(int i=0;i<(int)len;i++) if (s[i]=='\n') yyextra->yyLineNr++; } while(0)
97
99[[maybe_unused]] static const char *stateToString(int state);
100
101static int yyread(yyscan_t yyscanner,char *buf,int max_size);
102static void handleHtmlTag(yyscan_t yyscanner,const char *text);
103static void processSection(yyscan_t yyscanner);
104
105//--------------------------------------------------------------------------
106
108{
109 int nl1 = text.find('\n');
110 int nl2 = text.find("\\ilinebr");
111 if (nl1!=-1 && nl1<nl2)
112 {
113 return text.mid(nl1+1);
114 }
115 if (nl2!=-1)
116 {
117 if (text.at(nl2+8)==' ') nl2++; // skip space after \\ilinebr
118 return text.mid(nl2+8);
119 }
120 return text;
121}
122
123//--------------------------------------------------------------------------
124
125static int computeIndent(const char *str,size_t length)
126{
127 if (str==0 || length==std::string::npos) return 0;
128 size_t i;
129 int indent=0;
130 int tabSize=Config_getInt(TAB_SIZE);
131 for (i=0;i<length;i++)
132 {
133 if (str[i]=='\t')
134 {
135 indent+=tabSize - (indent%tabSize);
136 }
137 else if (str[i]=='\n')
138 {
139 indent=0;
140 }
141 else if (literal_at(&str[i],"\\ilinebr"))
142 {
143 indent=0;
144 i+=7;
145 if (str[i+1]==' ') i++; // also eat space after \\ilinebr if present
146 }
147 else
148 {
149 indent++;
150 }
151 }
152 //printf("input('%s')=%d\n",str,indent);
153 return indent;
154}
155
156//--------------------------------------------------------------------------
157
158#define unput_string(yytext,yyleng) do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)
159//--------------------------------------------------------------------------
161#undef YY_INPUT
162#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
163
164// otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
165static inline const char *getLexerFILE() {return __FILE__;}
166#include "doxygen_lex.h"
168//--------------------------------------------------------------------------
169#define YY_DECL static Token doctokenizerYYlex(yyscan_t yyscanner)
170//#define LOCAL_YY_DECL local_doctokenizer(yyscan_t yyscanner)
171#ifndef yyterminate
172#define yyterminate() return Token::make_TK_EOF()
173#endif
The common base class of all entity definitions found in the sources.
Definition definition.h:76
This is an alternative implementation of QCString.
Definition qcstring.h:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:593
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3971
static const char * stateToString(int state)
static const char * getLexerFILE()
Definition code.l:263
static int computeIndent(const char *s)
#define Config_getInt(name)
Definition config.h:34
QCString extractPartAfterNewLine(const QCString &text)
static void processSection(yyscan_t yyscanner)
static void handleHtmlTag(yyscan_t yyscanner, const char *text)
Portable versions of functions that are platform dependent.
Some helper functions for std::string.
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
TokenInfo token
const char * inputString
yy_size_t inputPos
DocLexerContext(const TokenInfo &tk, int r, int lvl, yy_size_t pos, const char *s, YY_BUFFER_STATE bs)
YY_BUFFER_STATE state
Data associated with a token used by the comment block parser.
const Definition * definition
std::stack< int > stateStack
const char * inputString
std::stack< std::unique_ptr< DocLexerContext > > lexerStack
175%}
176
177CMD ("\\"|"@")
178WS [ \t\r\n]
179BLANK [ \t\r]
180BLANKopt {BLANK}*
181ID [$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*
182LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
183CODEID [a-zA-Z][a-zA-Z0-9+]*
184PHPTYPE [?]?[\\:a-z_A-Z0-9\x80-\xFF\-]+
185CITESCHAR [a-z_A-Z0-9\x80-\xFF\-\?]
186CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/\?]
187CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*|"\""{CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*"\""
188DOXYCFG [A-Z][A-Z_0-9]*
189MAILADDR ("mailto:")?[a-z_A-Z0-9\x80-\xFF.+-]+"@"[a-z_A-Z0-9\x80-\xFf-]+("."[a-z_A-Z0-9\x80-\xFf\-]+)+[a-z_A-Z0-9\x80-\xFf\-]+
190MAILWS [\t a-z_A-Z0-9\x80-\xFF+-]
191MAILADDR2 {MAILWS}+{BLANK}+("at"|"AT"|"_at_"|"_AT_"){BLANK}+{MAILWS}+("dot"|"DOT"|"_dot_"|"_DOT_"|"point"|"POINT"|"_point_"|"_POINT_"){BLANK}+{MAILWS}+
192LISTITEM {BLANK}*[-]("#")?{WS}
193MLISTITEM {BLANK}*[+*]{WS}
194OLISTITEM {BLANK}*("0"|[1-9][0-9]*)"."{BLANK}
195CLISTITEM {BLANK}*[-]{BLANK}*"\‍["[ xX]"\‍]"
196ENDLIST {BLANK}*"."{BLANK}*(\n|"\\ilinebr")
197ATTRNAME [a-z_A-Z\x80-\xFF][:a-z_A-Z0-9\x80-\xFF\-]*
198ATTRIB {ATTRNAME}{WS}*("="{WS}*(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'"><]+))?
199URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=\x80-\xFF]
200URLMASK ({URLCHAR}+([({]{URLCHAR}*[)}])?)+
201URLPROTOCOL ("http:"|"https:"|"ftp:"|"ftps:"|"sftp:"|"file:"|"news:"|"irc:"|"ircs:")
202FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@~]
203FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@~]
204FILECHARS {FILEICHAR}*{FILEECHAR}+
205HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
206VFILEMASK {FILECHARS}("."{FILECHARS})*
207FILEMASK {VFILEMASK}|{HFILEMASK}
208LINKMASK [^ \t\n\r\\@<&${}]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"){BLANK}+)?
209VERBATIM "verbatim"{BLANK}*
210SPCMD1 {CMD}([a-z_A-Z][a-z_A-Z0-9]*|{VERBATIM}|"--"|"---")
211SPCMD2 {CMD}[\\@<>&$#%~".+=|!?-]
212SPCMD3 {CMD}_form#[0-9]+
213SPCMD4 {CMD}"::"
214SPCMD5 {CMD}":"
215INOUT "in"|"out"|("in"{BLANK}*","?{BLANK}*"out")|("out"{BLANK}*","?{BLANK}*"in")
216PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]"
217VARARGS "..."
218TEMPCHAR [a-z_A-Z0-9.,: \t\*\&\‍(\‍)\‍[\‍]]
219FUNCCHAR [a-z_A-Z0-9,:<> \t\n\^\*\&\‍[\‍]]|{VARARGS}|"\\ilinebr"
220FUNCPART {FUNCCHAR}*("("{FUNCCHAR}*")"{FUNCCHAR}*)?
221SCOPESEP "::"|"#"|"."
222TEMPLPART "<"{TEMPCHAR}*("<"{TEMPCHAR}*("<"{TEMPCHAR}*">")?">")?">"
223ANONNS "anonymous_namespace{"[^}]*"}"
224SCOPEPRE (({ID}{TEMPLPART}?)|{ANONNS}){SCOPESEP}
225SCOPEKEYS ":"({ID}":")*
226SCOPECPP {SCOPEPRE}*(~)?{ID}{TEMPLPART}?
227SCOPECPPN {SCOPEPRE}*(~)?{ID}
228SCOPEOBJC {SCOPEPRE}?{ID}{SCOPEKEYS}?
229SCOPEMASK {SCOPECPP}|{SCOPEOBJC}
230SCOPEMSKN {SCOPECPPN}|{SCOPEOBJC}
231FUNCARG "("{FUNCPART}")"({BLANK}*("volatile"|"const"){BLANK})?
232FUNCARG2 "("{FUNCPART}")"({BLANK}*("volatile"|"const"))?
233OPNEW {BLANK}+"new"({BLANK}*"[]")?
234OPDEL {BLANK}+"delete"({BLANK}*"[]")?
235OPNORM {OPNEW}|{OPDEL}|"+"|"-"|"*"|"/"|"%"|"^"|"&"|"|"|"~"|"!"|"="|"<"|">"|"+="|"-="|"*="|"/="|"%="|"^="|"&="|"|="|"<<"|">>"|"<<="|">>="|"=="|"!="|"<="|">="|"&&"|"||"|"++"|"--"|","|"->*"|"->"|"[]"|"()"|"<=>"
236OPCAST {BLANK}+[^<(\r\n.,][^(\r\n.,]*
237OPMASK ({BLANK}*{OPNORM}{FUNCARG})
238OPMASKOPT ({BLANK}*{OPNORM}{FUNCARG}?)|({OPCAST}{FUNCARG})
239OPMASKOP2 ({BLANK}*{OPNORM}{FUNCARG2}?)|({OPCAST}{FUNCARG2})
240LNKWORD1 ("::"|"#")?{SCOPEMASK}
241LNKWORDN ("::"|"#")?{SCOPEMSKN}
242CVSPEC {BLANK}*("const"|"volatile")
243LNKWORD2 (({SCOPEPRE}*"operator"{OPMASK})|({SCOPEPRE}"operator"{OPMASKOPT})|(("::"|"#"){SCOPEPRE}*"operator"{OPMASKOPT})){CVSPEC}?
244LNKWORD3 ([0-9a-z_A-Z\-]+("/"|"\\"))*[0-9a-z_A-Z\-]+("."[0-9a-z_A-Z]+)+
245CHARWORDQ [^ \t\n\r\\@<>()\‍[\‍]:;\?{}&%$#,."=']
246ESCWORD ("%"{ID}(("::"|"."){ID})*)|("%'")
247CHARWORDQ1 [^ \-+0-9\t\n\r\\@<>()\‍[\‍]:;\?{}&%$#,."=']
248WORD1 {ESCWORD}|{CHARWORDQ1}{CHARWORDQ}*|"{"|"}"|"'\"'"|("\""([^"\n]*(\\\"|\n)?)*[^"\n]*"\"")
249WORD2 "."|","|"("|")"|"["|"]"|"::"|":"|";"|"\?"|"="|"'"
250WORD1NQ {ESCWORD}|{CHARWORDQ}+|"{"|"}"
251WORD2NQ "."|","|"("|")"|"["|"]"|"::"|":"|";"|"\?"|"="|"'"
252CAPTION [cC][aA][pP][tT][iI][oO][nN]
253HTMLTAG "<"(("/")?){ID}({WS}+{ATTRIB})*{WS}*(("/")?)">"
254HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p"|"strike"|"u"|"del"|"ins"|"s"
255HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P"|"STRIKE"|"U"|"DEL"|"INS"|"S"
256HTMLKEYW {HTMLKEYL}|{HTMLKEYU}
257HTMLTAG_STRICT "<"(("/")?){HTMLKEYW}({WS}+{ATTRIB})*{WS}*(("/")?)">"
258REFWORD2_PRE ("#"|"::")?((({ID}{TEMPLPART}?)|{ANONNS})("."|"#"|"::"|"-"|"/"))*({ID}{TEMPLPART}?(":")?)
259REFWORD2 {REFWORD2_PRE}{FUNCARG2}?
260REFWORD2_NOCV {REFWORD2_PRE}("("{FUNCPART}")")?
261REFWORD3 ({ID}":")*{ID}":"?
262REFWORD4_NOCV (({SCOPEPRE}*"operator"{OPMASKOP2})|(("::"|"#"){SCOPEPRE}*"operator"{OPMASKOP2}))
263REFWORD4 {REFWORD4_NOCV}{CVSPEC}?
264REFWORD {FILEMASK}|{LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4}
265REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
266RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revision"|"Source"|"State")":"[^:\n$][^\n$]*"$"
267LINENR {BLANK}*([1-9][0-9]*|"0"|"-1")
268
269SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[0-9]{1,2})?)?
270
271%option noyywrap
272
273%x St_Para
274%x St_Comment
275%x St_Title
276%x St_TitleN
277%x St_TitleQ
278%x St_TitleA
279%x St_TitleV
280%x St_Code
281%x St_iCode
282%x St_CodeOpt
283%x St_iCodeOpt
284%x St_XmlCode
285%x St_HtmlOnly
286%x St_HtmlOnlyOption
287%x St_ManOnly
288%x St_LatexOnly
289%x St_RtfOnly
290%x St_XmlOnly
291%x St_DbOnly
292%x St_Verbatim
293%x St_iVerbatim
294%x St_ILiteral
295%x St_ILiteralOpt
296%x St_Dot
297%x St_Msc
298%x St_PlantUMLOpt
299%x St_PlantUML
300%x St_Param
301%x St_XRefItem
302%x St_XRefItem2
303%x St_File
304%x St_IFile
305%x St_Pattern
306%x St_Link
307%x St_Cite
308%x St_DoxyConfig
309%x St_Ref
310%x St_Ref2
311%x St_IntRef
312%x St_Text
313%x St_SkipTitle
314%x St_Anchor
315%x St_Prefix
316%x St_Snippet
317%x St_SetScope
318%x St_SetScopeEnd
319%x St_Options
320%x St_Block
321%x St_Emoji
322%x St_ILine
323%x St_ShowDate
324
325%x St_Sections
326%s St_SecLabel1
327%s St_SecLabel2
328%s St_SecTitle
329%x St_SecSkip
330
331%x St_QuotedString
332%x St_QuotedContent
333
334%%
335<St_Para>\r /* skip carriage return */
336<St_Para>^{LISTITEM} { /* list item */
337 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
338 lineCount(yytext,yyleng);
339 QCString text(yytext);
340 uint32_t dashPos = static_cast<uint32_t>(text.findRev('-'));
341 assert(dashPos!=static_cast<uint32_t>(-1));
342 yyextra->token.isEnumList = text.at(dashPos+1)=='#';
343 yyextra->token.isCheckedList = false;
344 yyextra->token.id = -1;
345 yyextra->token.indent = computeIndent(yytext,dashPos);
346 return Token::make_TK_LISTITEM();
347 }
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
#define lineCount(s, len)
348<St_Para>^{CLISTITEM} { /* checkbox item */
349 QCString text=yytext;
350 int dashPos = text.findRev('-');
351 yyextra->token.isEnumList = false;
352 yyextra->token.isCheckedList = true;
353 if (text.find('x') != -1) yyextra->token.id = DocAutoList::Checked_x;
354 else if (text.find('X') != -1) yyextra->token.id = DocAutoList::Checked_X;
355 else yyextra->token.id = DocAutoList::Unchecked;
356 yyextra->token.indent = computeIndent(yytext,dashPos);
357 return Token::make_TK_LISTITEM();
358 }
359<St_Para>^{MLISTITEM} { /* list item */
360 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
361 {
362 REJECT;
363 }
364 else
365 {
366 lineCount(yytext,yyleng);
367 std::string text(yytext);
368 static const reg::Ex re(R"([*+][^*+]*$)"); // find last + or *
370 reg::search(text,match,re);
371 size_t listPos = match.position();
372 assert(listPos!=std::string::npos);
373 yyextra->token.isEnumList = false;
374 yyextra->token.isCheckedList = false;
375 yyextra->token.id = -1;
376 yyextra->token.indent = computeIndent(yytext,listPos);
377 return Token::make_TK_LISTITEM();
378 }
379 }
Class representing a regular expression.
Definition regex.h:39
Object representing the matching results.
Definition regex.h:151
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:844
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:855
380<St_Para>^{OLISTITEM} { /* numbered list item */
381 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
382 {
383 REJECT;
384 }
385 else
386 {
387 std::string text(yytext);
388 static const reg::Ex re(R"(\d+)");
390 reg::search(text,match,re);
391 size_t markPos = match.position();
392 assert(markPos!=std::string::npos);
393 yyextra->token.isEnumList = true;
394 yyextra->token.isCheckedList = false;
395 bool ok = false;
396 int id = QCString(match.str()).toInt(&ok);
397 yyextra->token.id = ok ? id : -1;
398 if (!ok)
399 {
400 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid number for list item '{}' ",match.str());
401 }
402 yyextra->token.indent = computeIndent(yytext,markPos);
403 return Token::make_TK_LISTITEM();
404 }
405 }
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:254
#define warn(file, line, fmt,...)
Definition message.h:97
406<St_Para>{BLANK}*(\n|"\\ilinebr"){LISTITEM} { /* list item on next line */
407 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
408 lineCount(yytext,yyleng);
410 uint32_t dashPos = static_cast<uint32_t>(text.findRev('-'));
411 assert(dashPos!=static_cast<uint32_t>(-1));
412 yyextra->token.isEnumList = text.at(dashPos+1)=='#';
413 yyextra->token.isCheckedList = false;
414 yyextra->token.id = -1;
415 yyextra->token.indent = computeIndent(text.data(),dashPos);
416 return Token::make_TK_LISTITEM();
417 }
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:172
418<St_Para>{BLANK}*\n{CLISTITEM} { /* checkbox item on next line */
419 QCString text=yytext;
420 text=text.right(text.length()-text.find('\n')-1);
421 int dashPos = text.findRev('-');
422 yyextra->token.isEnumList = false;
423 yyextra->token.isCheckedList = true;
424 if (text.find('x') != -1) yyextra->token.id = DocAutoList::Checked_x;
425 else if (text.find('X') != -1) yyextra->token.id = DocAutoList::Checked_X;
426 else yyextra->token.id = DocAutoList::Unchecked;
427 yyextra->token.indent = computeIndent(text.data(),dashPos);
428 return Token::make_TK_LISTITEM();
429 }
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
QCString right(size_t len) const
Definition qcstring.h:234
430<St_Para>{BLANK}*(\n|"\\ilinebr"){MLISTITEM} { /* list item on next line */
431 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
432 {
433 REJECT;
434 }
435 else
436 {
437 lineCount(yytext,yyleng);
438 std::string text=extractPartAfterNewLine(yytext).str();
439 static const reg::Ex re(R"([*+][^*+]*$)"); // find last + or *
441 reg::search(text,match,re);
442 size_t markPos = match.position();
443 assert(markPos!=std::string::npos);
444 yyextra->token.isEnumList = FALSE;
445 yyextra->token.isCheckedList = false;
446 yyextra->token.id = -1;
447 yyextra->token.indent = computeIndent(text.c_str(),markPos);
448 return Token::make_TK_LISTITEM();
449 }
450 }
const std::string & str() const
Definition qcstring.h:552
#define FALSE
Definition qcstring.h:34
451<St_Para>{BLANK}*(\n|"\\ilinebr"){OLISTITEM} { /* list item on next line */
452 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
453 {
454 REJECT;
455 }
456 else
457 {
458 lineCount(yytext,yyleng);
459 std::string text=extractPartAfterNewLine(yytext).str();
460 static const reg::Ex re(R"(\d+)");
462 reg::search(text,match,re);
463 size_t markPos = match.position();
464 assert(markPos!=std::string::npos);
465 yyextra->token.isEnumList = true;
466 yyextra->token.isCheckedList = false;
467 bool ok = false;
468 int id = QCString(match.str()).toInt(&ok);
469 yyextra->token.id = ok ? id : -1;
470 if (!ok)
471 {
472 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid number for list item '{}' ",match.str());
473 }
474 yyextra->token.indent = computeIndent(text.c_str(),markPos);
475 return Token::make_TK_LISTITEM();
476 }
477 }
478<St_Para>^{ENDLIST} { /* end list */
479 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
480 lineCount(yytext,yyleng);
481 size_t dotPos = static_cast<size_t>(QCString(yytext).findRev('.'));
482 yyextra->token.indent = computeIndent(yytext,dotPos);
483 return Token::make_TK_ENDLIST();
484 }
485<St_Para>{BLANK}*(\n|"\\ilinebr"){ENDLIST} { /* end list on next line */
486 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
487 lineCount(yytext,yyleng);
489 size_t dotPos = static_cast<size_t>(text.findRev('.'));
490 yyextra->token.indent = computeIndent(text.data(),dotPos);
491 return Token::make_TK_ENDLIST();
492 }
493<St_Para>"{"{BLANK}*"@linkplain"/{WS}+ {
494 yyextra->token.name = "javalinkplain";
495 return Token::make_TK_COMMAND_AT();
496 }
497<St_Para>"{"{BLANK}*"@link"/{WS}+ {
498 yyextra->token.name = "javalink";
499 return Token::make_TK_COMMAND_AT();
500 }
501<St_Para>"{"{BLANK}*"@inheritDoc"{BLANK}*"}" {
502 yyextra->token.name = "inheritdoc";
503 return Token::make_TK_COMMAND_AT();
504 }
505<St_Para>"@_fakenl" { // artificial new line
506 //yyextra->yyLineNr++;
507 }
508<St_Para>{SPCMD3} {
509 yyextra->token.name = "_form";
510 bool ok;
511 yyextra->token.id = QCString(yytext).right((int)yyleng-7).toInt(&ok);
512 ASSERT(ok);
513 return Token::char_to_command(yytext[0]);
514 }
static Token char_to_command(char c)
#define ASSERT(x)
Definition qcstring.h:39
515<St_Para>{CMD}"n"\n { /* \n followed by real newline */
516 lineCount(yytext,yyleng);
517 //yyextra->yyLineNr++;
518 yyextra->token.name = yytext+1;
519 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
520 yyextra->token.paramDir=TokenInfo::Unspecified;
521 return Token::char_to_command(yytext[0]);
522 }
523<St_Para>"\\ilinebr" {
524 }
525<St_Para>{SPCMD1} |
526<St_Para>{SPCMD2} |
527<St_Para>{SPCMD5} |
528<St_Para>{SPCMD4} { /* special command */
529 yyextra->token.name = yytext+1;
530 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
531 yyextra->token.paramDir=TokenInfo::Unspecified;
532 return Token::char_to_command(yytext[0]);
533 }
534<St_Para>{PARAMIO} { /* param [in,out] command */
535 yyextra->token.name = "param";
536 QCString s(yytext);
537 bool isIn = s.find("in")!=-1;
538 bool isOut = s.find("out")!=-1;
539 if (isIn)
540 {
541 if (isOut)
542 {
543 yyextra->token.paramDir=TokenInfo::InOut;
544 }
545 else
546 {
547 yyextra->token.paramDir=TokenInfo::In;
548 }
549 }
550 else if (isOut)
551 {
552 yyextra->token.paramDir=TokenInfo::Out;
553 }
554 else
555 {
556 yyextra->token.paramDir=TokenInfo::Unspecified;
557 }
558 return Token::char_to_command(yytext[0]);
559 }
560<St_Para>{URLPROTOCOL}{URLMASK}/[,\.] { // URL, or URL.
561 yyextra->token.name=yytext;
562 yyextra->token.isEMailAddr=FALSE;
563 return Token::make_TK_URL();
564 }
565<St_Para>{URLPROTOCOL}{URLMASK} { // URL
566 yyextra->token.name=yytext;
567 yyextra->token.isEMailAddr=FALSE;
568 return Token::make_TK_URL();
569 }
570<St_Para>"<"{URLPROTOCOL}{URLMASK}">" { // URL
571 yyextra->token.name=yytext;
572 yyextra->token.name = yyextra->token.name.mid(1,yyextra->token.name.length()-2);
573 yyextra->token.isEMailAddr=FALSE;
574 return Token::make_TK_URL();
575 }
576<St_Para>{MAILADDR} { // Mail address
577 yyextra->token.name=yytext;
578 yyextra->token.name.stripPrefix("mailto:");
579 yyextra->token.isEMailAddr=TRUE;
580 return Token::make_TK_URL();
581 }
#define TRUE
Definition qcstring.h:37
582<St_Para>"<"{MAILADDR}">" { // Mail address
583 yyextra->token.name=yytext;
584 yyextra->token.name = yyextra->token.name.mid(1,yyextra->token.name.length()-2);
585 yyextra->token.name.stripPrefix("mailto:");
586 yyextra->token.isEMailAddr=TRUE;
587 return Token::make_TK_URL();
588 }
589<St_Para>"<"{MAILADDR2}">" { // anti spam mail address
590 yyextra->token.name=yytext;
591 return Token::make_TK_WORD();
592 }
593<St_Para>{RCSID} { /* RCS tag */
594 QCString tagName(yytext+1);
595 int index=tagName.find(':');
596 if (index<0) index=0; // should never happen
597 yyextra->token.name = tagName.left(index);
598 int text_begin = index+2;
599 int text_end = static_cast<int>(tagName.length())-1;
600 if (tagName[text_begin-1]==':') /* check for Subversion fixed-length keyword */
601 {
602 ++text_begin;
603 if (tagName[text_end-1]=='#')
604 {
605 --text_end;
606 }
607 }
608 yyextra->token.text = tagName.mid(text_begin,text_end-text_begin);
609 return Token::make_TK_RCSTAG();
610 }
611<St_Para,St_HtmlOnly,St_ManOnly,St_LatexOnly,St_RtfOnly,St_XmlOnly,St_DbOnly>"$("{ID}")" | /* environment variable */
612<St_Para,St_HtmlOnly,St_ManOnly,St_LatexOnly,St_RtfOnly,St_XmlOnly,St_DbOnly>"$("{ID}"("{ID}"))" { /* environment variable */
613 QCString name(&yytext[2]);
614 name = name.left(static_cast<int>(name.length())-1);
615 QCString value = Portable::getenv(name);
616 for (int i=static_cast<int>(value.length())-1;i>=0;i--) unput(value.at(i));
617 }
QCString getenv(const QCString &variable)
Definition portable.cpp:322
618<St_Para>"<blockquote>&zwj;" {
619 // for a markdown inserted block quote,
620 // tell flex that after putting the last indent
621 // back we are at the beginning of the line, see issue #11309
622 YY_CURRENT_BUFFER->yy_at_bol=1;
623 lineCount(yytext,yyleng);
624 handleHtmlTag(yyscanner,yytext);
625 return Token::make_TK_HTMLTAG();
626 }
627<St_Para>{HTMLTAG} { /* html tag */
628 lineCount(yytext,yyleng);
629 handleHtmlTag(yyscanner,yytext);
630 return Token::make_TK_HTMLTAG();
631 }
632<St_Para,St_Text>"&"{ID}";" { /* special symbol */
633 yyextra->token.name = yytext;
634 return Token::make_TK_SYMBOL();
635 }
636
637 /********* patterns for linkable words ******************/
638
639<St_Para>{ID}/"<"{HTMLKEYW}">"+ { /* this rule is to prevent opening html
640 * tag to be recognized as a templated classes
641 */
642 yyextra->token.name = yytext;
643 return Token::make_TK_LNKWORD();
644 }
645<St_Para>{LNKWORDN}/("<"{HTMLKEYW}">")+ { // prevent <br> html tag to be parsed as template arguments
646 yyextra->token.name = yytext;
647 return Token::make_TK_LNKWORD();
648 }
649<St_Para>{LNKWORD1} |
650<St_Para>{LNKWORD1}{FUNCARG} |
651<St_Para>{LNKWORD2} |
652<St_Para>{LNKWORD3} {
653 yyextra->token.name = yytext;
654 return Token::make_TK_LNKWORD();
655 }
656<St_Para>{LNKWORD1}{FUNCARG}{CVSPEC}[^a-z_A-Z0-9] {
657 yyextra->token.name = yytext;
658 yyextra->token.name = yyextra->token.name.left(yyextra->token.name.length()-1);
659 unput(yytext[(int)yyleng-1]);
660 return Token::make_TK_LNKWORD();
661 }
662 /********* patterns for normal words ******************/
663
664<St_Para,St_Text>[\-+0-9] |
665<St_Para,St_Text>{WORD1} |
666<St_Para,St_Text>{WORD2} { /* function call */
667 if (QCString(yytext).find("\\ilinebr")!=-1) REJECT; // see issue #8311
668 lineCount(yytext,yyleng);
669 if (yytext[0]=='%') // strip % if present
670 yyextra->token.name = &yytext[1];
671 else
672 yyextra->token.name = yytext;
673 return Token::make_TK_WORD();
674 }
675<St_Text>({ID}".")+{ID} {
676 yyextra->token.name = yytext;
677 return Token::make_TK_WORD();
678 }
679<St_Para,St_Text>"operator"/{BLANK}*"<"[a-zA-Z_0-9]+">" { // Special case: word "operator" followed by a HTML command
680 // avoid interpretation as "operator <"
681 yyextra->token.name = yytext;
682 return Token::make_TK_WORD();
683 }
684
685 /*******************************************************/
686
687<St_Para,St_Text>{BLANK}+ |
688<St_Para,St_Text>{BLANK}*\n{BLANK}* { /* white space */
689 lineCount(yytext,yyleng);
690 yyextra->token.chars=yytext;
691 return Token::make_TK_WHITESPACE();
692 }
693<St_Text>[\\@<>&$#%~] {
694 yyextra->token.name = yytext;
695 return Token::char_to_command(yytext[0]);
696 }
697<St_Para>({BLANK}*\n)+{BLANK}*\n/{LISTITEM} { /* skip trailing paragraph followed by new list item */
698 if (yyextra->insidePre || yyextra->autoListLevel==0)
699 {
700 REJECT;
701 }
702 lineCount(yytext,yyleng);
703 }
704<St_Para>({BLANK}*\n)+{BLANK}*\n/{CLISTITEM} { /* skip trailing paragraph followed by new checkbox item */
705 if (yyextra->insidePre || yyextra->autoListLevel==0)
706 {
707 REJECT;
708 }
709 }
710<St_Para>({BLANK}*\n)+{BLANK}*\n/{MLISTITEM} { /* skip trailing paragraph followed by new list item */
711 if (!yyextra->markdownSupport || yyextra->insidePre || yyextra->autoListLevel==0)
712 {
713 REJECT;
714 }
715 lineCount(yytext,yyleng);
716 }
717<St_Para>({BLANK}*\n)+{BLANK}*\n/{OLISTITEM} { /* skip trailing paragraph followed by new list item */
718 if (!yyextra->markdownSupport || yyextra->insidePre || yyextra->autoListLevel==0)
719 {
720 REJECT;
721 }
722 lineCount(yytext,yyleng);
723 }
724<St_Para,St_Param>({BLANK}*(\n|"\\ilinebr"))+{BLANK}*(\n|"\\ilinebr"){BLANK}*/" \\ifile" | // we don't want to count the space before \ifile
725<St_Para,St_Param>({BLANK}*(\n|"\\ilinebr"))+{BLANK}*(\n|"\\ilinebr"){BLANK}* {
726 lineCount(yytext,yyleng);
727 if (yyextra->insidePre)
728 {
729 yyextra->token.chars=yytext;
730 return Token::make_TK_WHITESPACE();
731 }
732 else
733 {
734 yyextra->token.indent=computeIndent(yytext,yyleng);
735 int i;
736 // put back the indentation (needed for list items)
737 //printf("token.indent=%d\n",yyextra->token.indent);
738 for (i=0;i<yyextra->token.indent;i++)
739 {
740 unput(' ');
741 }
742 // tell flex that after putting the last indent
743 // back we are at the beginning of the line
744 YY_CURRENT_BUFFER->yy_at_bol=1;
745 // start of a new paragraph
746 return Token::make_TK_NEWPARA();
747 }
748 }
749<St_CodeOpt>{BLANK}*"{"(".")?{CODEID}"}" {
750 yyextra->token.name = yytext;
751 int i=yyextra->token.name.find('{'); /* } to keep vi happy */
752 yyextra->token.name = yyextra->token.name.mid(i+1,yyextra->token.name.length()-i-2);
753 BEGIN(St_Code);
754 }
755<St_iCodeOpt>{BLANK}*"{"(".")?{CODEID}"}" {
756 yyextra->token.name = yytext;
757 int i=yyextra->token.name.find('{'); /* } to keep vi happy */
758 yyextra->token.name = yyextra->token.name.mid(i+1,yyextra->token.name.length()-i-2);
759 BEGIN(St_iCode);
760 }
761<St_CodeOpt>"\\ilinebr" |
762<St_CodeOpt>\n |
763<St_CodeOpt>. {
764 unput_string(yytext,yyleng);
765 BEGIN(St_Code);
766 }
#define unput_string(yytext, yyleng)
767<St_iCodeOpt>"\\ilinebr" |
768<St_iCodeOpt>\n |
769<St_iCodeOpt>. {
770 unput_string(yytext,yyleng);
771 BEGIN(St_iCode);
772 }
773<St_Code>{WS}*{CMD}"endcode" {
774 lineCount(yytext,yyleng);
775 return Token::make_RetVal_OK();
776 }
777<St_iCode>{WS}*{CMD}"endicode" {
778 lineCount(yytext,yyleng);
779 return Token::make_RetVal_OK();
780 }
781<St_XmlCode>{WS}*"</code>" {
782 lineCount(yytext,yyleng);
783 return Token::make_RetVal_OK();
784 }
785<St_Code,St_iCode,St_XmlCode>[^\\@\n<]+ |
786<St_Code,St_iCode,St_XmlCode>\n |
787<St_Code,St_iCode,St_XmlCode>. {
788 lineCount(yytext,yyleng);
789 yyextra->token.verb+=yytext;
790 }
791<St_HtmlOnlyOption>" [block]" { // the space is added in commentscan.l
792 yyextra->token.name="block";
793 BEGIN(St_HtmlOnly);
794 }
795<St_HtmlOnlyOption>.|\n {
796 unput(*yytext);
797 BEGIN(St_HtmlOnly);
798 }
799<St_HtmlOnlyOption>"\\ilinebr" {
800 unput_string(yytext,yyleng);
801 BEGIN(St_HtmlOnly);
802 }
803<St_HtmlOnly>{CMD}"endhtmlonly" {
804 return Token::make_RetVal_OK();
805 }
806<St_HtmlOnly>[^\\@\n$]+ |
807<St_HtmlOnly>\n |
808<St_HtmlOnly>. {
809 lineCount(yytext,yyleng);
810 yyextra->token.verb+=yytext;
811 }
812<St_ManOnly>{CMD}"endmanonly" {
813 return Token::make_RetVal_OK();
814 }
815<St_ManOnly>[^\\@\n$]+ |
816<St_ManOnly>\n |
817<St_ManOnly>. {
818 lineCount(yytext,yyleng);
819 yyextra->token.verb+=yytext;
820 }
821<St_RtfOnly>{CMD}"endrtfonly" {
822 return Token::make_RetVal_OK();
823 }
824<St_RtfOnly>[^\\@\n$]+ |
825<St_RtfOnly>\n |
826<St_RtfOnly>. {
827 lineCount(yytext,yyleng);
828 yyextra->token.verb+=yytext;
829 }
830<St_LatexOnly>{CMD}"endlatexonly" {
831 return Token::make_RetVal_OK();
832 }
833<St_LatexOnly>[^\\@\n]+ |
834<St_LatexOnly>\n |
835<St_LatexOnly>. {
836 lineCount(yytext,yyleng);
837 yyextra->token.verb+=yytext;
838 }
839<St_XmlOnly>{CMD}"endxmlonly" {
840 return Token::make_RetVal_OK();
841 }
842<St_XmlOnly>[^\\@\n]+ |
843<St_XmlOnly>\n |
844<St_XmlOnly>. {
845 lineCount(yytext,yyleng);
846 yyextra->token.verb+=yytext;
847 }
848<St_DbOnly>{CMD}"enddocbookonly" {
849 return Token::make_RetVal_OK();
850 }
851<St_DbOnly>[^\\@\n]+ |
852<St_DbOnly>\n |
853<St_DbOnly>. {
854 lineCount(yytext,yyleng);
855 yyextra->token.verb+=yytext;
856 }
857<St_Verbatim>{CMD}"endverbatim" {
858 yyextra->token.verb = yyextra->token.verb.stripLeadingAndTrailingEmptyLines();
859 return Token::make_RetVal_OK();
860 }
861<St_ILiteral>{CMD}"endiliteral " { // note extra space as this is artificially added
862 // remove spaces that have been added
863 yyextra->token.verb = yyextra->token.verb.mid(1,yyextra->token.verb.length()-2);
864 return Token::make_RetVal_OK();
865 }
866<St_iVerbatim>{CMD}"endiverbatim" {
867 yyextra->token.verb = yyextra->token.verb.stripLeadingAndTrailingEmptyLines();
868 return Token::make_RetVal_OK();
869 }
870<St_Verbatim,St_iVerbatim,St_ILiteral>[^\\@\n]+ |
871<St_Verbatim,St_iVerbatim,St_ILiteral>\n |
872<St_Verbatim,St_iVerbatim,St_ILiteral>. { /* Verbatim text */
873 lineCount(yytext,yyleng);
874 yyextra->token.verb+=yytext;
875 }
876<St_ILiteralOpt>{BLANK}*"{"[a-zA-Z_,:0-9\. ]*"}" { // option(s) present
877 yyextra->token.verb = QCString(yytext).stripWhiteSpace();
878 return Token::make_RetVal_OK();
879 }
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:260
880<St_ILiteralOpt>"\\ilinebr" |
881<St_ILiteralOpt>"\n" |
882<St_ILiteralOpt>. {
883 yyextra->token.sectionId = "";
884 unput_string(yytext,yyleng);
885 return Token::make_RetVal_OK();
886 }
887<St_Dot>{CMD}"enddot" {
888 return Token::make_RetVal_OK();
889 }
890<St_Dot>[^\\@\n]+ |
891<St_Dot>\n |
892<St_Dot>. { /* dot text */
893 lineCount(yytext,yyleng);
894 yyextra->token.verb+=yytext;
895 }
896<St_Msc>{CMD}("endmsc") {
897 return Token::make_RetVal_OK();
898 }
899<St_Msc>[^\\@\n]+ |
900<St_Msc>\n |
901<St_Msc>. { /* msc text */
902 lineCount(yytext,yyleng);
903 yyextra->token.verb+=yytext;
904 }
905<St_PlantUMLOpt>{BLANK}*"{"[a-zA-Z_,:0-9\. ]*"}" { // case 1: options present
906 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
907 return Token::make_RetVal_OK();
908 }
909<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}+/{ID}"=" { // case 2: plain file name specified followed by an attribute
910 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
911 return Token::make_RetVal_OK();
912 }
913<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}+/"\"" { // case 3: plain file name specified followed by a quoted title
914 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
915 return Token::make_RetVal_OK();
916 }
917<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANKopt}/\n { // case 4: plain file name specified without title or attributes
918 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
919 return Token::make_RetVal_OK();
920 }
921<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANKopt}/"\\ilinebr" { // case 5: plain file name specified without title or attributes
922 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
923 return Token::make_RetVal_OK();
924 }
925<St_PlantUMLOpt>"\\ilinebr" |
926<St_PlantUMLOpt>"\n" |
927<St_PlantUMLOpt>. {
928 yyextra->token.sectionId = "";
929 unput_string(yytext,yyleng);
930 return Token::make_RetVal_OK();
931 }
932<St_PlantUML>{CMD}"enduml" {
933 return Token::make_RetVal_OK();
934 }
935<St_PlantUML>[^\\@\n]+ |
936<St_PlantUML>\n |
937<St_PlantUML>. { /* plantuml text */
938 lineCount(yytext,yyleng);
939 yyextra->token.verb+=yytext;
940 }
941<St_Title>"\"" { // quoted title
942 BEGIN(St_TitleQ);
943 }
944<St_Title>[ \t]+ {
945 yyextra->token.chars=yytext;
946 return Token::make_TK_WHITESPACE();
947 }
948<St_Title>. { // non-quoted title
949 unput(*yytext);
950 BEGIN(St_TitleN);
951 }
952<St_Title>\n {
953 unput(*yytext);
954 return Token::make_TK_NONE();
955 }
956<St_Title>"\\ilinebr" {
957 unput_string(yytext,yyleng);
958 return Token::make_TK_NONE();
959 }
960<St_TitleN>"&"{ID}";" { /* symbol */
961 yyextra->token.name = yytext;
962 return Token::make_TK_SYMBOL();
963 }
964<St_TitleN>{HTMLTAG} {
965 yyextra->token.name = yytext;
966 handleHtmlTag(yyscanner,yytext);
967 return Token::make_TK_HTMLTAG();
968 }
969<St_TitleN>\n { /* new line => end of title */
970 unput(*yytext);
971 return Token::make_TK_NONE();
972 }
973<St_TitleN>"\\ilinebr" { /* new line => end of title */
974 unput_string(yytext,yyleng);
975 return Token::make_TK_NONE();
976 }
977<St_TitleN>{SPCMD1} |
978<St_TitleN>{SPCMD2} { /* special command */
979 yyextra->token.name = yytext+1;
980 yyextra->token.paramDir=TokenInfo::Unspecified;
981 return Token::char_to_command(yytext[0]);
982 }
983<St_TitleN>{ID}"=" { /* attribute */
984 if (yytext[0]=='%') // strip % if present
985 yyextra->token.name = &yytext[1];
986 else
987 yyextra->token.name = yytext;
988 return Token::make_TK_WORD();
989 }
990<St_TitleN>[\-+0-9] |
991<St_TitleN>{WORD1} |
992<St_TitleN>{WORD2} { /* word */
993 if (QCString(yytext).find("\\ilinebr")!=-1) REJECT; // see issue #8311
994 lineCount(yytext,yyleng);
995 if (yytext[0]=='%') // strip % if present
996 yyextra->token.name = &yytext[1];
997 else
998 yyextra->token.name = yytext;
999 return Token::make_TK_WORD();
1000 }
1001<St_TitleN>[ \t]+ {
1002 yyextra->token.chars=yytext;
1003 return Token::make_TK_WHITESPACE();
1004 }
1005<St_TitleQ>"&"{ID}";" { /* symbol */
1006 yyextra->token.name = yytext;
1007 return Token::make_TK_SYMBOL();
1008 }
1009<St_TitleQ>(\n|"\\ilinebr") { /* new line => end of title */
1010 unput_string(yytext,yyleng);
1011 return Token::make_TK_NONE();
1012 }
1013<St_TitleQ>{SPCMD1} |
1014<St_TitleQ>{SPCMD2} { /* special command */
1015 yyextra->token.name = yytext+1;
1016 yyextra->token.paramDir=TokenInfo::Unspecified;
1017 return Token::char_to_command(yytext[0]);
1018 }
1019<St_TitleQ>{WORD1NQ} |
1020<St_TitleQ>{WORD2NQ} { /* word */
1021 yyextra->token.name = yytext;
1022 return Token::make_TK_WORD();
1023 }
1024<St_TitleQ>[ \t]+ {
1025 yyextra->token.chars=yytext;
1026 return Token::make_TK_WHITESPACE();
1027 }
1028<St_TitleQ>"\"" { /* closing quote => end of title */
1029 BEGIN(St_TitleA);
1030 return Token::make_TK_NONE();
1031 }
1032<St_TitleA>{BLANK}*{ID}{BLANK}*"="{BLANK}* { // title attribute
1033 yyextra->token.name = yytext;
1034 int pos = yyextra->token.name.find('=');
1035 if (pos<0) pos=0; // should never happen
1036 yyextra->token.name = yyextra->token.name.left(pos).stripWhiteSpace();
1037 BEGIN(St_TitleV);
1038 }
1039<St_TitleV>[^ \t\r\n]+ { // attribute value
1040 lineCount(yytext,yyleng);
1041 yyextra->token.chars = yytext;
1042 BEGIN(St_TitleN);
1043 return Token::make_TK_WORD();
1044 }
1045<St_TitleV,St_TitleA>. {
1046 unput(*yytext);
1047 return Token::make_TK_NONE();
1048 }
1049<St_TitleV,St_TitleA>(\n|"\\ilinebr") {
1050 unput_string(yytext,yyleng);
1051 return Token::make_TK_NONE();
1052 }
1053
1054<St_Anchor>{LABELID}{WS}? { // anchor
1055 lineCount(yytext,yyleng);
1056 yyextra->token.name = QCString(yytext).stripWhiteSpace();
1057 return Token::make_TK_WORD();
1058 }
1059<St_Anchor>. {
1060 unput(*yytext);
1061 return Token::make_TK_NONE();
1062 }
1063<St_Cite>{CITEID} { // label to cite
1064 if (yytext[0] =='"')
1065 {
1066 yyextra->token.name=yytext+1;
1067 yyextra->token.name=yyextra->token.name.left(static_cast<uint32_t>(yyleng)-2);
1068 }
1069 else
1070 {
1071 yyextra->token.name=yytext;
1072 }
1073 return Token::make_TK_WORD();
1074 }
1075<St_Cite>{BLANK} { // white space
1076 unput(' ');
1077 return Token::make_TK_NONE();
1078 }
1079<St_Cite>(\n|"\\ilinebr") { // new line
1080 unput_string(yytext,yyleng);
1081 return Token::make_TK_NONE();
1082 }
1083<St_Cite>. { // any other character
1084 unput(*yytext);
1085 return Token::make_TK_NONE();
1086 }
1087<St_DoxyConfig>{DOXYCFG} { // config option
1088 yyextra->token.name=yytext;
1089 return Token::make_TK_WORD();
1090 }
1091<St_DoxyConfig>{BLANK} { // white space
1092 unput(' ');
1093 return Token::make_TK_NONE();
1094 }
1095<St_DoxyConfig>(\n|"\\ilinebr") { // new line
1096 unput_string(yytext,yyleng);
1097 return Token::make_TK_NONE();
1098 }
1099<St_DoxyConfig>. { // any other character
1100 unput(*yytext);
1101 return Token::make_TK_NONE();
1102 }
1103<St_Ref>{REFWORD_NOCV}/{BLANK}("const")[a-z_A-Z0-9] { // see bug776988
1104 yyextra->token.name=yytext;
1105 return Token::make_TK_WORD();
1106 }
1107<St_Ref>{REFWORD_NOCV}/{BLANK}("volatile")[a-z_A-Z0-9] { // see bug776988
1108 yyextra->token.name=yytext;
1109 return Token::make_TK_WORD();
1110 }
1111<St_Ref>{REFWORD} { // label to refer to
1112 yyextra->token.name=yytext;
1113 return Token::make_TK_WORD();
1114 }
1115<St_Ref>{BLANK} { // white space
1116 unput(' ');
1117 return Token::make_TK_NONE();
1118 }
1119<St_Ref>{WS}+"\""{WS}* { // white space following by quoted string
1120 yyextra->expectQuote=true;
1121 lineCount(yytext,yyleng);
1122 BEGIN(St_Ref2);
1123 }
1124<St_Ref>(\n|"\\ilinebr") { // new line
1125 unput_string(yytext,yyleng);
1126 return Token::make_TK_NONE();
1127 }
1128<St_Ref>"\""[^"\n]+"\"" { // quoted first argument -> return without quotes
1129 yyextra->token.name=QCString(yytext).mid(1,yyleng-2);
1130 return Token::make_TK_WORD();
1131 }
1132<St_Ref>. { // any other character
1133 unput(*yytext);
1134 return Token::make_TK_NONE();
1135 }
1136<St_IntRef>[A-Z_a-z0-9.:/#\-\+\‍(\‍)]+ {
1137 yyextra->token.name = yytext;
1138 return Token::make_TK_WORD();
1139 }
1140<St_IntRef>{BLANK}+"\"" {
1141 BEGIN(St_Ref2);
1142 }
1143<St_SetScope>({SCOPEMASK}|{ANONNS}){BLANK}|{FILEMASK} {
1144 yyextra->token.name = yytext;
1145 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1146 return Token::make_TK_WORD();
1147 }
1148<St_SetScope>{SCOPEMASK}"<" {
1149 yyextra->token.name = yytext;
1150 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1151 yyextra->sharpCount=1;
1152 BEGIN(St_SetScopeEnd);
1153 }
1154<St_SetScope>{BLANK} {
1155 }
1156<St_SetScopeEnd>"<" {
1157 yyextra->token.name += yytext;
1158 yyextra->sharpCount++;
1159 }
1160<St_SetScopeEnd>">" {
1161 yyextra->token.name += yytext;
1162 yyextra->sharpCount--;
1163 if (yyextra->sharpCount<=0)
1164 {
1165 return Token::make_TK_WORD();
1166 }
1167 }
1168<St_SetScopeEnd>. {
1169 yyextra->token.name += yytext;
1170 }
1171<St_Ref2>"&"{ID}";" { /* symbol */
1172 yyextra->token.name = yytext;
1173 return Token::make_TK_SYMBOL();
1174 }
1175<St_Ref2>"\""|\n|"\\ilinebr" { /* " or \n => end of title? */
1176 lineCount(yytext,yyleng);
1177 if (!yyextra->expectQuote || yytext[0]=='"')
1178 {
1179 return Token::make_TK_NONE();
1180 }
1181 else
1182 {
1183 yyextra->token.name += yytext;
1184 }
1185 }
1186<St_Ref2>{HTMLTAG_STRICT} { /* html tag */
1187 lineCount(yytext,yyleng);
1188 handleHtmlTag(yyscanner,yytext);
1189 return Token::make_TK_HTMLTAG();
1190 }
1191<St_Ref2>{SPCMD1} |
1192<St_Ref2>{SPCMD2} { /* special command */
1193 yyextra->token.name = yytext+1;
1194 yyextra->token.paramDir=TokenInfo::Unspecified;
1195 return Token::char_to_command(yytext[0]);
1196 }
1197<St_Ref2>{WORD1NQ} |
1198<St_Ref2>{WORD2NQ} {
1199 /* word */
1200 yyextra->token.name = yytext;
1201 return Token::make_TK_WORD();
1202 }
1203<St_Ref2>[ \t]+ {
1204 yyextra->token.chars=yytext;
1205 return Token::make_TK_WHITESPACE();
1206 }
1207<St_XRefItem>{LABELID} {
1208 yyextra->token.name=yytext;
1209 }
1210<St_XRefItem>" " {
1211 BEGIN(St_XRefItem2);
1212 }
1213<St_XRefItem2>[0-9]+"." {
1214 QCString numStr(yytext);
1215 numStr=numStr.left((int)yyleng-1);
1216 yyextra->token.id=numStr.toInt();
1217 return Token::make_RetVal_OK();
1218 }
1219<St_Para,St_Title,St_Ref2>"<!--" { /* html style comment block */
1220 yyextra->commentState = YY_START;
1221 BEGIN(St_Comment);
1222 }
1223<St_Param>"\""[^\n\"]+"\"" {
1224 yyextra->token.name = yytext+1;
1225 yyextra->token.name = yyextra->token.name.left((int)yyleng-2);
1226 return Token::make_TK_WORD();
1227 }
1228<St_Param>({PHPTYPE}{BLANK}*("["{BLANK}*"]")*{BLANK}*"|"{BLANK}*)*{PHPTYPE}{BLANK}*("["{BLANK}*"]")*{WS}+("&")?"$"{LABELID} {
1229 lineCount(yytext,yyleng);
1230 QCString params(yytext);
1231 int j = params.find('&');
1232 int i = params.find('$');
1233 if (i<0) i=0; // should never happen
1234 if (j<i && j>=0) i=j;
1235 QCString types = params.left(i).stripWhiteSpace();
1236 yyextra->token.name = types+"#"+params.mid(i);
1237 return Token::make_TK_WORD();
1238 }
QCString left(size_t len) const
Definition qcstring.h:229
1239<St_Param>[^ \t\n,@\\‍]+ {
1240 yyextra->token.name = yytext;
1241 if (yyextra->token.name.at(static_cast<uint32_t>(yyleng)-1)==':')
1242 {
1243 yyextra->token.name=yyextra->token.name.left(static_cast<uint32_t>(yyleng)-1);
1244 }
1245 return Token::make_TK_WORD();
1246 }
1247<St_Param>{WS}*","{WS}* /* param separator */
1248<St_Param>{WS} {
1249 lineCount(yytext,yyleng);
1250 yyextra->token.chars=yytext;
1251 return Token::make_TK_WHITESPACE();
1252 }
1253<St_Prefix>"\""[^\n\"]*"\"" {
1254 yyextra->token.name = yytext+1;
1255 yyextra->token.name = yyextra->token.name.left((int)yyleng-2);
1256 return Token::make_TK_WORD();
1257 }
1258<St_Prefix>. {
1259 unput(*yytext);
1260 return Token::make_TK_NONE();
1261 }
1262<St_Options>{ID} {
1263 yyextra->token.name+=yytext;
1264 }
1265<St_Options>{WS}*":"{WS}* {
1266 lineCount(yytext,yyleng);
1267 yyextra->token.name+=":";
1268 }
1269<St_Options>{WS}*","{WS}* |
1270<St_Options>{WS} { /* option separator */
1271 lineCount(yytext,yyleng);
1272 yyextra->token.name+=",";
1273 }
1274<St_Options>"}" {
1275 return Token::make_TK_WORD();
1276 }
1277<St_Block>{ID} {
1278 yyextra->token.name+=yytext;
1279 }
1280<St_Block>"]" {
1281 return Token::make_TK_WORD();
1282 }
1283<St_Emoji>[:0-9_a-z+-]+ {
1284 yyextra->token.name=yytext;
1285 return Token::make_TK_WORD();
1286 }
1287<St_Emoji>. {
1288 unput(*yytext);
1289 return Token::make_TK_NONE();
1290 }
1291<St_QuotedString>"\"" {
1292 yyextra->token.name="";
1293 BEGIN(St_QuotedContent);
1294 }
1295<St_QuotedString>(\n|"\\ilinebr") {
1296 unput_string(yytext,yyleng);
1297 return Token::make_TK_NONE();
1298 }
1299<St_QuotedString>. {
1300 unput(*yytext);
1301 return Token::make_TK_NONE();
1302 }
1303<St_QuotedContent>"\"" {
1304 return Token::make_TK_WORD();
1305 }
1306<St_QuotedContent>. {
1307 yyextra->token.name+=yytext;
1308 }
1309<St_ShowDate>{WS}+{SHOWDATE} {
1310 lineCount(yytext,yyleng);
1311 yyextra->token.name=yytext;
1312 return Token::make_TK_WORD();
1313 }
1314<St_ShowDate>(\n|"\\ilinebr") {
1315 unput_string(yytext,yyleng);
1316 return Token::make_TK_NONE();
1317 }
1318<St_ShowDate>. {
1319 unput(*yytext);
1320 return Token::make_TK_NONE();
1321 }
1322<St_ILine>{LINENR}/[\\@\n\.] |
1323<St_ILine>{LINENR}{BLANK} {
1324 bool ok = false;
1325 int nr = QCString(yytext).toInt(&ok);
1326 if (!ok)
1327 {
1328 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
1329 }
1330 else
1331 {
1332 yyextra->yyLineNr = nr;
1333 }
1334 return Token::make_TK_WORD();
1335 }
1336<St_ILine>. {
1337 return Token::make_TK_NONE();
1338 }
1339<St_IFile>{BLANK}*{FILEMASK} {
1340 yyextra->fileName = QCString(yytext).stripWhiteSpace();
1341 return Token::make_TK_WORD();
1342 }
1343<St_IFile>{BLANK}*"\""[^\n\"]+"\"" {
1344 QCString text(yytext);
1345 text = text.stripWhiteSpace();
1346 yyextra->fileName = text.mid(1,text.length()-2);
1347 return Token::make_TK_WORD();
1348 }
1349<St_File>{FILEMASK} {
1350 yyextra->token.name = yytext;
1351 if (yyextra->token.name.endsWith("\\ilinebr") ||yyextra->token.name.endsWith("@ilinebr"))
1352 {
1353 unput_string("\\ilinebr",8);
1354 yyextra->token.name = yyextra->token.name.left(yyleng-8);
1355 }
1356 return Token::make_TK_WORD();
1357 }
1358<St_File>"\""[^\n\"]+"\"" {
1359 QCString text(yytext);
1360 yyextra->token.name = text.mid(1,text.length()-2);
1361 return Token::make_TK_WORD();
1362 }
1363<St_Pattern>[^\\\r\n]+ {
1364 yyextra->token.name += yytext;
1365 }
1366<St_Pattern>"\\ilinebr" {
1367 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1368 return Token::make_TK_WORD();
1369 }
1370<St_Pattern>\n {
1371 lineCount(yytext,yyleng);
1372 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1373 return Token::make_TK_WORD();
1374 }
1375<St_Pattern>. {
1376 yyextra->token.name += yytext;
1377 }
1378<St_Link>{LINKMASK}|{REFWORD} {
1379 yyextra->token.name = yytext;
1380 return Token::make_TK_WORD();
1381 }
1382<St_Comment>"-->" { /* end of html comment */
1383 BEGIN(yyextra->commentState);
1384 }
1385<St_Comment>[^-]+ /* inside html comment */
1386<St_Comment>. /* inside html comment */
1387
1388 /* State for skipping title (all chars until the end of the line) */
1389
1390<St_SkipTitle>.
1391<St_SkipTitle>(\n|"\\ilinebr") {
1392 if (*yytext == '\n') unput('\n');
1393 return Token::make_TK_NONE();
1394 }
1395
1396 /* State for the pass used to find the anchors and sections */
1397
1398<St_Sections>[^\n@\<]+
1399<St_Sections>{CMD}("<"|{CMD})
1400<St_Sections>"<"{CAPTION}({WS}+{ATTRIB})*">" {
1401 lineCount(yytext,yyleng);
1402 QCString tag(yytext);
1403 int s=tag.find("id=");
1404 if (s!=-1) // command has id attribute
1405 {
1406 char c=tag[s+3];
1407 if (c=='\'' || c=='"') // valid start
1408 {
1409 int e=tag.find(c,s+4);
1410 if (e!=-1) // found matching end
1411 {
1412 yyextra->secType = SectionType::Table;
1413 yyextra->secLabel=tag.mid(s+4,e-s-4); // extract id
1414 processSection(yyscanner);
1415 }
1416 }
1417 }
1418 }
static constexpr int Table
Definition section.h:41
1419<St_Sections>{CMD}"anchor"{BLANK}+ {
1420 yyextra->secType = SectionType::Anchor;
1421 BEGIN(St_SecLabel1);
1422 }
static constexpr int Anchor
Definition section.h:40
1423<St_Sections>{CMD}"ianchor"{BLANK}+ {
1424 yyextra->secType = SectionType::Anchor;
1425 BEGIN(St_SecLabel1);
1426 }
1427<St_Sections>{CMD}"section"{BLANK}+ {
1428 yyextra->secType = SectionType::Section;
1429 BEGIN(St_SecLabel2);
1430 }
static constexpr int Section
Definition section.h:33
1431<St_Sections>{CMD}"subsection"{BLANK}+ {
1432 yyextra->secType = SectionType::Subsection;
1433 BEGIN(St_SecLabel2);
1434 }
static constexpr int Subsection
Definition section.h:34
1435<St_Sections>{CMD}"subsubsection"{BLANK}+ {
1436 yyextra->secType = SectionType::Subsubsection;
1437 BEGIN(St_SecLabel2);
1438 }
static constexpr int Subsubsection
Definition section.h:35
1439<St_Sections>{CMD}"paragraph"{BLANK}+ {
1440 yyextra->secType = SectionType::Paragraph;
1441 BEGIN(St_SecLabel2);
1442 }
static constexpr int Paragraph
Definition section.h:36
1443<St_Sections>{CMD}"subparagraph"{BLANK}+ {
1444 yyextra->secType = SectionType::Subparagraph;
1445 BEGIN(St_SecLabel2);
1446 }
static constexpr int Subparagraph
Definition section.h:37
1447<St_Sections>{CMD}"subsubparagraph"{BLANK}+ {
1448 yyextra->secType = SectionType::Subsubparagraph;
1449 BEGIN(St_SecLabel2);
1450 }
static constexpr int Subsubparagraph
Definition section.h:38
1451<St_Sections>{CMD}"verbatim"/[^a-z_A-Z0-9] {
1452 yyextra->endMarker="endverbatim";
1453 BEGIN(St_SecSkip);
1454 }
1455<St_Sections>{CMD}"iverbatim"/[^a-z_A-Z0-9] {
1456 yyextra->endMarker="endiverbatim";
1457 BEGIN(St_SecSkip);
1458 }
1459<St_Sections>{CMD}"iliteral"/[^a-z_A-Z0-9] {
1460 yyextra->endMarker="endiliteral";
1461 BEGIN(St_SecSkip);
1462 }
1463<St_Sections>{CMD}"dot"/[^a-z_A-Z0-9] {
1464 yyextra->endMarker="enddot";
1465 BEGIN(St_SecSkip);
1466 }
1467<St_Sections>{CMD}"msc"/[^a-z_A-Z0-9] {
1468 yyextra->endMarker="endmsc";
1469 BEGIN(St_SecSkip);
1470 }
1471<St_Sections>{CMD}"startuml"/[^a-z_A-Z0-9] {
1472 yyextra->endMarker="enduml";
1473 BEGIN(St_SecSkip);
1474 }
1475<St_Sections>{CMD}"htmlonly"/[^a-z_A-Z0-9] {
1476 yyextra->endMarker="endhtmlonly";
1477 BEGIN(St_SecSkip);
1478 }
1479<St_Sections>{CMD}"latexonly"/[^a-z_A-Z0-9] {
1480 yyextra->endMarker="endlatexonly";
1481 BEGIN(St_SecSkip);
1482 }
1483<St_Sections>{CMD}"manonly"/[^a-z_A-Z0-9] {
1484 yyextra->endMarker="endmanonly";
1485 BEGIN(St_SecSkip);
1486 }
1487<St_Sections>{CMD}"rtfonly"/[^a-z_A-Z0-9] {
1488 yyextra->endMarker="endrtfonly";
1489 BEGIN(St_SecSkip);
1490 }
1491<St_Sections>{CMD}"xmlonly"/[^a-z_A-Z0-9] {
1492 yyextra->endMarker="endxmlonly";
1493 BEGIN(St_SecSkip);
1494 }
1495<St_Sections>{CMD}"docbookonly"/[^a-z_A-Z0-9] {
1496 yyextra->endMarker="enddocbookonly";
1497 BEGIN(St_SecSkip);
1498 }
1499<St_Sections>{CMD}"code"/[^a-z_A-Z0-9] {
1500 yyextra->endMarker="endcode";
1501 BEGIN(St_SecSkip);
1502 }
1503<St_Sections>{CMD}"icode"/[^a-z_A-Z0-9] {
1504 yyextra->endMarker="endicode";
1505 BEGIN(St_SecSkip);
1506 }
1507<St_Sections>"<!--" {
1508 yyextra->endMarker="-->";
1509 BEGIN(St_SecSkip);
1510 }
1511<St_SecSkip>{CMD}{ID} {
1512 if (yyextra->endMarker==yytext+1)
1513 {
1514 BEGIN(St_Sections);
1515 }
1516 }
1517<St_SecSkip>"-->" {
1518 if (yyextra->endMarker==yytext)
1519 {
1520 BEGIN(St_Sections);
1521 }
1522 }
1523<St_SecSkip>[^a-z_A-Z0-9\-\\\@]+
1524<St_SecSkip>.
1525<St_SecSkip>(\n|"\\ilinebr")
1526<St_Sections>.
1527<St_Sections>(\n|"\\ilinebr")
1528<St_SecLabel1>{LABELID} {
1529 lineCount(yytext,yyleng);
1530 yyextra->secLabel = yytext;
1531 processSection(yyscanner);
1532 BEGIN(St_Sections);
1533 }
1534<St_SecLabel2>{LABELID}{BLANK}+ |
1535<St_SecLabel2>{LABELID} {
1536 yyextra->secLabel = yytext;
1537 yyextra->secLabel = yyextra->secLabel.stripWhiteSpace();
1538 BEGIN(St_SecTitle);
1539 }
1540<St_SecTitle>[^\n]+ |
1541<St_SecTitle>[^\n]*\n {
1542 lineCount(yytext,yyleng);
1543 yyextra->secTitle = yytext;
1544 yyextra->secTitle = yyextra->secTitle.stripWhiteSpace();
1545 if (yyextra->secTitle.endsWith("\\ilinebr"))
1546 {
1547 yyextra->secTitle.left(yyextra->secTitle.length()-8);
1548 }
1549 processSection(yyscanner);
1550 BEGIN(St_Sections);
1551 }
1552<St_SecTitle,St_SecLabel1,St_SecLabel2>. {
1553 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected character '{}' while looking for section label or title",yytext);
1554 }
1555
1556<St_Snippet>[^\\\n]+ {
1557 yyextra->token.name += yytext;
1558 }
1559<St_Snippet>"\\" {
1560 yyextra->token.name += yytext;
1561 }
1562<St_Snippet>(\n|"\\ilinebr") {
1563 unput_string(yytext,yyleng);
1564 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1565 return Token::make_TK_WORD();
1566 }
1567
1568 /* Generic rules that work for all states */
1569<*>\n {
1570 lineCount(yytext,yyleng);
1571 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected new line character");
1572 }
1573<*>"\\ilinebr" {
1574 }
1575<*>[\\@<>&$#%~"=] { /* unescaped special character */
1576 //warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected character '{}', assuming command \\{} was meant.",yytext,yytext);
1577 yyextra->token.name = yytext;
1578 return Token::char_to_command(yytext[0]);
1579 }
1580<*>. {
1581 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected character '{}'",yytext);
1582 }
1583%%
1584
1585//--------------------------------------------------------------------------
1586
1587static int yyread(yyscan_t yyscanner,char *buf,int max_size)
1588{
1589 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1590 int c=0;
1591 const char *p = yyextra->inputString + yyextra->inputPos;
1592 while ( c < max_size && *p ) { *buf++ = *p++; c++; }
1593 yyextra->inputPos+=c;
1594 return c;
1595}
1596
1597static void processSection(yyscan_t yyscanner)
1598{
1599 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1600 //printf("%s: found section/anchor with name '%s'\n",qPrint(yyextra->fileName),qPrint(yyextra->secLabel));
1601 QCString file;
1602 if (yyextra->definition)
1603 {
1604 file = yyextra->definition->getOutputFileBase();
1605 }
1606 else
1607 {
1608 warn(yyextra->fileName,yyextra->yyLineNr,"Found section/anchor {} without context",yyextra->secLabel);
1609 }
1610 SectionInfo *si = SectionManager::instance().find(yyextra->secLabel);
1611 if (si)
1612 {
1613 si->setFileName(file);
1614 si->setType(yyextra->secType);
1615 }
1616}
1617
1618static void handleHtmlTag(yyscan_t yyscanner,const char *text)
1619{
1620 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1621
1622 QCString tagText(text);
1623 yyextra->token.text = tagText;
1624 yyextra->token.attribs.clear();
1625 yyextra->token.endTag = FALSE;
1626 yyextra->token.emptyTag = FALSE;
1627
1628 // Check for end tag
1629 int startNamePos=1;
1630 if (tagText.at(1)=='/')
1631 {
1632 yyextra->token.endTag = TRUE;
1633 startNamePos++;
1634 }
1635
1636 // Parse the name portion
1637 int i = startNamePos;
1638 for (i=startNamePos; i < (int)yyleng; i++)
1639 {
1640 // Check for valid HTML/XML name chars (including namespaces)
1641 char c = tagText.at(i);
1642 if (!(isalnum(c) || c=='-' || c=='_' || c==':')) break;
1643 }
1644 yyextra->token.name = tagText.mid(startNamePos,i-startNamePos);
1645
1646 // Parse the attributes. Each attribute is a name, value pair
1647 // The result is stored in yyextra->token.attribs.
1648 int startAttribList = i;
1649 while (i<(int)yyleng)
1650 {
1651 char c=tagText.at(i);
1652 // skip spaces
1653 while (i<(int)yyleng && isspace((uint8_t)c)) { c=tagText.at(++i); }
1654 // check for end of the tag
1655 if (c == '>') break;
1656 // Check for XML style "empty" tag.
1657 if (c == '/')
1658 {
1659 yyextra->token.emptyTag = TRUE;
1660 break;
1661 }
1662 int startName=i;
1663 // search for end of name
1664 while (i<(int)yyleng && !isspace((uint8_t)c) && c!='=' && c!= '>') { c=tagText.at(++i); }
1665 int endName=i;
1666 QCString optName,optValue;
1667 optName = tagText.mid(startName,endName-startName).lower();
1668 // skip spaces
1669 while (i<(int)yyleng && isspace((uint8_t)c)) { c=tagText.at(++i); }
1670 if (tagText.at(i)=='=') // option has value
1671 {
1672 int startAttrib=0, endAttrib=0;
1673 c=tagText.at(++i);
1674 // skip spaces
1675 while (i<(int)yyleng && isspace((uint8_t)c)) { c=tagText.at(++i); }
1676 if (tagText.at(i)=='\'') // option '...'
1677 {
1678 c=tagText.at(++i);
1679 startAttrib=i;
1680
1681 // search for matching quote
1682 while (i<(int)yyleng && c!='\'') { c=tagText.at(++i); }
1683 endAttrib=i;
1684 if (i<(int)yyleng) { c=tagText.at(++i);}
1685 }
1686 else if (tagText.at(i)=='"') // option "..."
1687 {
1688 c=tagText.at(++i);
1689 startAttrib=i;
1690 // search for matching quote
1691 while (i<(int)yyleng && c!='"') { c=tagText.at(++i); }
1692 endAttrib=i;
1693 if (i<(int)yyleng) { c=tagText.at(++i);}
1694 }
1695 else // value without any quotes
1696 {
1697 startAttrib=i;
1698 // search for separator or end symbol
1699 while (i<(int)yyleng && !isspace((uint8_t)c) && c!='>') { c=tagText.at(++i); }
1700 endAttrib=i;
1701 if (i<(int)yyleng) { c=tagText.at(++i);}
1702 }
1703 optValue = tagText.mid(startAttrib,endAttrib-startAttrib);
1704 if (optName == "align") optValue = optValue.lower();
1705 else if (optName == "valign")
1706 {
1707 optValue = optValue.lower();
1708 if (optValue == "center") optValue="middle";
1709 }
1710 }
1711 else // start next option
1712 {
1713 }
1714 //printf("=====> Adding option name=<%s> value=<%s>\n",
1715 // qPrint(optName),qPrint(optValue));
1716 yyextra->token.attribs.emplace_back(optName,optValue);
1717 }
1718 yyextra->token.attribsStr = tagText.mid(startAttribList,i-startAttribList);
1719}
1720
1722{
1729{
1730 yyscan_t yyscanner = p->yyscanner;
1731 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1732 //printf("DocTokenizer::pushContext() stack=%zu\n",yyextra->lexerStack.size());
1733 yyextra->lexerStack.push(
1734 std::make_unique<DocLexerContext>(
1735 yyextra->token,YY_START,
1736 yyextra->autoListLevel,
1737 yyextra->inputPos,
1738 yyextra->inputString,
1739 YY_CURRENT_BUFFER));
1740 yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE, yyscanner), yyscanner);
1741}
1742
1744{
1745 yyscan_t yyscanner = p->yyscanner;
1746 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1747 //printf("DocTokenizer::popContext() stack=%zu\n",yyextra->lexerStack.size());
1748 if (yyextra->lexerStack.empty()) return FALSE;
1749 const auto &ctx = yyextra->lexerStack.top();
1750 yyextra->autoListLevel = ctx->autoListLevel;
1751 yyextra->inputPos = ctx->inputPos;
1752 yyextra->inputString = ctx->inputString;
1753 yyextra->token = ctx->token;
1754
1755 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
1756 yy_switch_to_buffer(ctx->state, yyscanner);
1757
1758 BEGIN(ctx->rule);
1759 yyextra->lexerStack.pop();
1760 return TRUE;
1761}
1762
1763
1764DocTokenizer::DocTokenizer() : p(std::make_unique<Private>())
1765{
1766 //printf("%p:DocTokenizer::DocTokenizer()\n",(void*)this);
1767 doctokenizerYYlex_init_extra(&p->extra,&p->yyscanner);
1768#ifdef FLEX_DEBUG
1769 doctokenizerYYset_debug(Debug::isFlagSet(Debug::Lex_doctokenizer)?1:0,p->yyscanner);
1770#endif
1771}
1772
1774{
1775 //printf("%p:DocTokenizer::~DocTokenizer()\n",(void*)this);
1776 doctokenizerYYlex_destroy(p->yyscanner);
1777}
1778
1780{
1781 return doctokenizerYYlex(p->yyscanner);
1782}
1783
1784void DocTokenizer::unputString(const QCString &tag)
1785{
1786 yyscan_t yyscanner = p->yyscanner;
1787 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1788 unput_string(tag.data(),tag.length());
1789}
1790
1791void DocTokenizer::findSections(const QCString &input,const Definition *d,
1792 const QCString &fileName)
1794 yyscan_t yyscanner = p->yyscanner;
1795 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1796
1797 if (input.isEmpty()) return;
1798 DebugLex debugLex(Debug::Lex_doctokenizer, __FILE__, qPrint(fileName));
1799 yyextra->inputString = input.data();
1800 //printf("parsing --->'%s'<---\n",input);
1801 yyextra->inputPos = 0;
1802 yyextra->definition = d;
1803 yyextra->fileName = fileName;
1804 BEGIN(St_Sections);
1805 yyextra->yyLineNr = 1;
1806 doctokenizerYYlex(yyscanner);
1807}
1808
1809void DocTokenizer::init(const char *input,const QCString &fileName,bool markdownSupport, bool insideHtmlLink)
1810{
1811 yyscan_t yyscanner = p->yyscanner;
1812 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1813 yyextra->autoListLevel = 0;
1814 yyextra->inputString = input;
1815 yyextra->inputPos = 0;
1816 yyextra->fileName = fileName;
1817 yyextra->insidePre = FALSE;
1818 yyextra->markdownSupport = markdownSupport;
1819 yyextra->insideHtmlLink = insideHtmlLink;
1820 BEGIN(St_Para);
1821}
1822
1824{
1825 yyscan_t yyscanner = p->yyscanner;
1826 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1827 return &yyextra->token;
1828}
1829
1831{
1832 yyscan_t yyscanner = p->yyscanner;
1833 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1834 yyextra->token = TokenInfo();
1835 return &yyextra->token;
1836}
1837
1839{
1840 yyscan_t yyscanner = p->yyscanner;
1841 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1842 yyextra->insideHtmlLink = false;
1843 BEGIN(St_Para);
1844}
1845
1847{
1848 yyscan_t yyscanner = p->yyscanner;
1849 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1850 BEGIN(St_Title);
1851}
1852
1854{
1855 yyscan_t yyscanner = p->yyscanner;
1856 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1857 BEGIN(St_TitleV);
1858}
1859
1861{
1862 yyscan_t yyscanner = p->yyscanner;
1863 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1864 yyextra->token.verb="";
1865 yyextra->token.name="";
1866 BEGIN(St_CodeOpt);
1867}
1868
1870{
1871 yyscan_t yyscanner = p->yyscanner;
1872 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1873 yyextra->token.verb="";
1874 yyextra->token.name="";
1875 BEGIN(St_iCodeOpt);
1876}
1877
1879{
1880 yyscan_t yyscanner = p->yyscanner;
1881 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1882 yyextra->token.verb="";
1883 yyextra->token.name="";
1884 BEGIN(St_XmlCode);
1885}
1886
1888{
1889 yyscan_t yyscanner = p->yyscanner;
1890 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1891 yyextra->token.verb="";
1892 yyextra->token.name="";
1893 BEGIN(St_HtmlOnlyOption);
1894}
1895
1897{
1898 yyscan_t yyscanner = p->yyscanner;
1899 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1900 yyextra->token.verb="";
1901 BEGIN(St_ManOnly);
1902}
1903
1905{
1906 yyscan_t yyscanner = p->yyscanner;
1907 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1908 yyextra->token.verb="";
1909 BEGIN(St_RtfOnly);
1910}
1911
1913{
1914 yyscan_t yyscanner = p->yyscanner;
1915 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1916 yyextra->token.verb="";
1917 BEGIN(St_XmlOnly);
1918}
1919
1921{
1922 yyscan_t yyscanner = p->yyscanner;
1923 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1924 yyextra->token.verb="";
1925 BEGIN(St_DbOnly);
1926}
1927
1929{
1930 yyscan_t yyscanner = p->yyscanner;
1931 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1932 yyextra->token.verb="";
1933 BEGIN(St_LatexOnly);
1934}
1935
1937{
1938 yyscan_t yyscanner = p->yyscanner;
1939 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1940 yyextra->token.verb="";
1941 BEGIN(St_ILiteral);
1942}
1943
1945{
1946 yyscan_t yyscanner = p->yyscanner;
1947 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1948 yyextra->token.verb="";
1949 BEGIN(St_ILiteralOpt);
1950}
1951
1953{
1954 yyscan_t yyscanner = p->yyscanner;
1955 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1956 yyextra->token.verb="";
1957 BEGIN(St_Verbatim);
1958}
1959
1961{
1962 yyscan_t yyscanner = p->yyscanner;
1963 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1964 yyextra->token.verb="";
1965 BEGIN(St_iVerbatim);
1966}
1967
1969{
1970 yyscan_t yyscanner = p->yyscanner;
1971 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1972 yyextra->token.verb="";
1973 BEGIN(St_Dot);
1974}
1975
1977{
1978 yyscan_t yyscanner = p->yyscanner;
1979 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1980 yyextra->token.verb="";
1981 BEGIN(St_Msc);
1982}
1983
1985{
1986 yyscan_t yyscanner = p->yyscanner;
1987 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1988 yyextra->token.verb="";
1989 yyextra->token.sectionId="";
1990 BEGIN(St_PlantUMLOpt);
1991}
1992
1994{
1995 yyscan_t yyscanner = p->yyscanner;
1996 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1997 yyextra->token.verb="";
1998 BEGIN(St_PlantUML);
1999}
2000
2002{
2003 yyscan_t yyscanner = p->yyscanner;
2004 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2005 BEGIN(St_Param);
2006}
2007
2009{
2010 yyscan_t yyscanner = p->yyscanner;
2011 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2012 BEGIN(St_XRefItem);
2013}
2014
2016{
2017 yyscan_t yyscanner = p->yyscanner;
2018 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2019 BEGIN(St_File);
2020}
2021
2023{
2024 yyscan_t yyscanner = p->yyscanner;
2025 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2026 BEGIN(St_IFile);
2027}
2028
2030{
2031 yyscan_t yyscanner = p->yyscanner;
2032 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2033 yyextra->token.name = "";
2034 BEGIN(St_Pattern);
2035}
2036
2038{
2039 yyscan_t yyscanner = p->yyscanner;
2040 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2041 BEGIN(St_Link);
2042}
2043
2045{
2046 yyscan_t yyscanner = p->yyscanner;
2047 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2048 BEGIN(St_Cite);
2049}
2050
2052{
2053 yyscan_t yyscanner = p->yyscanner;
2054 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2055 BEGIN(St_DoxyConfig);
2056}
2057
2059{
2060 yyscan_t yyscanner = p->yyscanner;
2061 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2062 yyextra->expectQuote=false;
2063 BEGIN(St_Ref);
2064}
2065
2067{
2068 yyscan_t yyscanner = p->yyscanner;
2069 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2070 BEGIN(St_IntRef);
2071}
2072
2074{
2075 yyscan_t yyscanner = p->yyscanner;
2076 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2077 BEGIN(St_Text);
2078}
2079
2081{
2082 yyscan_t yyscanner = p->yyscanner;
2083 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2084 BEGIN(St_SkipTitle);
2085}
2086
2088{
2089 yyscan_t yyscanner = p->yyscanner;
2090 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2091 BEGIN(St_Anchor);
2092}
2093
2095{
2096 yyscan_t yyscanner = p->yyscanner;
2097 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2098 BEGIN(St_Prefix);
2099}
2100
2102{
2103 yyscan_t yyscanner = p->yyscanner;
2104 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2105 yyextra->token.name="";
2106 BEGIN(St_Snippet);
2107}
2108
2110{
2111 yyscan_t yyscanner = p->yyscanner;
2112 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2113 BEGIN(St_SetScope);
2114}
2115
2117{
2118 yyscan_t yyscanner = p->yyscanner;
2119 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2120 yyextra->token.name="";
2121 BEGIN(St_Options);
2122}
2123
2125{
2126 yyscan_t yyscanner = p->yyscanner;
2127 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2128 yyextra->token.name="";
2129 BEGIN(St_Block);
2130}
2131
2133{
2134 yyscan_t yyscanner = p->yyscanner;
2135 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2136 yyextra->token.name="";
2137 BEGIN(St_Emoji);
2138}
2139
2141{
2142 yyscan_t yyscanner = p->yyscanner;
2143 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2144 BEGIN(St_ILine);
2145}
2146
2148{
2149 yyscan_t yyscanner = p->yyscanner;
2150 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2151 BEGIN(St_QuotedString);
2152}
2153
2155{
2156 yyscan_t yyscanner = p->yyscanner;
2157 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2158 BEGIN(St_ShowDate);
2159}
2160
2162{
2163 yyscan_t yyscanner = p->yyscanner;
2164 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2165 yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
2166}
2167
2168void DocTokenizer::setInsidePre(bool b)
2169{
2170 yyscan_t yyscanner = p->yyscanner;
2171 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2172 yyextra->insidePre = b;
2173}
2174
2176{
2177 yyscan_t yyscanner = p->yyscanner;
2178 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2179 QCString tagName = tag;
2180 int l = static_cast<int>(tagName.length());
2181 unput('>');
2182 for (int i=l-1;i>=0;i--)
2183 {
2184 unput(tag[i]);
2185 }
2186 unput('<');
2187}
2188
2190{
2191 yyscan_t yyscanner = p->yyscanner;
2192 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2193 yyextra->autoListLevel++;
2194}
2195
2197{
2198 yyscan_t yyscanner = p->yyscanner;
2199 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2200 yyextra->autoListLevel--;
2201}
2202
2203void DocTokenizer::setLineNr(int lineno)
2204{
2205 yyscan_t yyscanner = p->yyscanner;
2206 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2207 yyextra->yyLineNr = lineno;
2208}
2209
2211{
2212 yyscan_t yyscanner = p->yyscanner;
2213 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2214 return yyextra->yyLineNr;
2215}
2216
2218{
2219 yyscan_t yyscanner = p->yyscanner;
2220 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2221 yyextra->stateStack.push(YYSTATE);
2222}
2223
2225{
2226 yyscan_t yyscanner = p->yyscanner;
2227 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2228 assert(!yyextra->stateStack.empty());
2229 BEGIN(yyextra->stateStack.top());
2230 yyextra->stateStack.pop();
2231}
2232
2233#include "doctokenizer.l.h"
@ Lex_doctokenizer
Definition debug.h:59
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
TokenInfo * token()
void setStateTitleAttrValue()
void setStateILiteralOpt()
void setStateILiteral()
void setStateCite()
void setStateSnippet()
void setStatePrefix()
void setStateEmoji()
void init(const char *input, const QCString &fileName, bool markdownSupport, bool insideHtmlLink)
void setLineNr(int lineno)
void setStateCode()
void setStatePattern()
void startAutoList()
void setStateIFile()
void setStateSkipTitle()
void setStateParam()
void setStateBlock()
void setStatePlantUMLOpt()
void setStateAnchor()
void findSections(const QCString &input, const Definition *d, const QCString &fileName)
void setStateRtfOnly()
void setStateVerbatim()
void setStateLink()
void setStateTitle()
void setStateFile()
void setStateLatexOnly()
void setStateManOnly()
void setStateShowDate()
void setInsidePre(bool b)
void setStateXRefItem()
void setStateText()
void setStateXmlCode()
void unputString(const QCString &tag)
void setStateDbOnly()
void setStateHtmlOnly()
void setStateInternalRef()
void setStateILine()
void setStateICode()
void setStateOptions()
void setStateDoxyConfig()
void setStateQuotedString()
void setStatePara()
int getLineNr(void)
void setStatePlantUML()
TokenInfo * resetToken()
void setStateIVerbatim()
void setStateXmlOnly()
std::unique_ptr< Private > p
void setStateSetScope()
void pushBackHtmlTag(const QCString &tag)
const T * find(const std::string &key) const
Definition linkedmap.h:47
QCString lower() const
Definition qcstring.h:249
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
class that provide information about a section.
Definition section.h:57
void setType(SectionType t)
Definition section.h:80
void setFileName(const QCString &fn)
Definition section.h:79
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:178
#define YY_BUF_SIZE
Definition commentcnv.l:19
const char * qPrint(const char *s)
Definition qcstring.h:687
doctokenizerYY_state extra