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