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