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