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