Doxygen
Loading...
Searching...
No Matches
doctokenizer.l File Reference
#include <stdint.h>
#include <ctype.h>
#include <stack>
#include <string>
#include <cassert>
#include "doctokenizer.h"
#include "cmdmapper.h"
#include "config.h"
#include "message.h"
#include "section.h"
#include "membergroup.h"
#include "definition.h"
#include "doxygen.h"
#include "portable.h"
#include "cite.h"
#include "regex.h"
#include "debug.h"
#include "docnode.h"
#include "stringutil.h"
#include "doxygen_lex.h"
#include "doctokenizer.l.h"
Include dependency graph for doctokenizer.l:

Go to the source code of this file.

Classes

struct  DocLexerContext
struct  doctokenizerYY_state
struct  DocTokenizer::Private

Macros

#define YY_TYPEDEF_YY_SCANNER_T
#define YY_NO_INPUT   1
#define YY_NO_UNISTD_H   1
#define lineCount(s, len)
#define unput_string(yytext, yyleng)
#define YY_INPUT(buf, result, max_size)
#define YY_DECL   static Token doctokenizerYYlex(yyscan_t yyscanner)
#define yyterminate()

Typedefs

typedef yyguts_t * yyscan_t

Functions

static const char * stateToString (int state)
static int yyread (yyscan_t yyscanner, char *buf, int max_size)
static void handleHtmlTag (yyscan_t yyscanner, const char *text)
static void processSection (yyscan_t yyscanner)
QCString extractPartAfterNewLine (const QCString &text)
static int computeIndent (const char *str, size_t length)
static const char * getLexerFILE ()
int yylex (yyscan_t yyscanner)

Macro Definition Documentation

◆ lineCount

#define lineCount ( s,
len )
Value:
do { for(int i=0;i<(int)len;i++) if (s[i]=='\n') yyextra->yyLineNr++; } while(0)

Definition at line 98 of file doctokenizer.l.

Referenced by endBrief(), initMethodProtection(), and CitationManager::insertCrossReferencesForBibFile().

◆ unput_string

#define unput_string ( yytext,
yyleng )
Value:
do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)

Definition at line 160 of file doctokenizer.l.

◆ YY_DECL

#define YY_DECL   static Token doctokenizerYYlex(yyscan_t yyscanner)

Definition at line 171 of file doctokenizer.l.

◆ YY_INPUT

#define YY_INPUT ( buf,
result,
max_size )
Value:
result=yyread(yyscanner,buf,max_size);
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3982

Definition at line 164 of file doctokenizer.l.

◆ YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 53 of file doctokenizer.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 54 of file doctokenizer.l.

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T

Definition at line 26 of file doctokenizer.l.

◆ yyterminate

#define yyterminate ( )
Value:
return Token::make_TK_EOF()

Definition at line 174 of file doctokenizer.l.

Typedef Documentation

◆ yyscan_t

typedef yyguts_t* yyscan_t

Definition at line 28 of file doctokenizer.l.

Function Documentation

◆ computeIndent()

int computeIndent ( const char * str,
size_t length )
static

Definition at line 127 of file doctokenizer.l.

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;
#define Config_getInt(name)
Definition config.h:34
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
156}

References Config_getInt, and literal_at().

◆ extractPartAfterNewLine()

QCString extractPartAfterNewLine ( const QCString & text)

Definition at line 109 of file doctokenizer.l.

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;
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
123}

References QCString::at(), QCString::find(), and QCString::mid().

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 167 of file doctokenizer.l.

167{return __FILE__;}

◆ handleHtmlTag()

void handleHtmlTag ( yyscan_t yyscanner,
const char * text )
static

Definition at line 1661 of file doctokenizer.l.

1662{
1663 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1664
1665 QCString tagText(text);
1666 yyextra->token.text = tagText;
1667 yyextra->token.attribs.clear();
1668 yyextra->token.endTag = FALSE;
1669 yyextra->token.emptyTag = FALSE;
This is an alternative implementation of QCString.
Definition qcstring.h:101
#define FALSE
Definition qcstring.h:34
1670
1671 // Check for end tag
1672 int startNamePos=1;
1673 if (tagText.at(1)=='/')
1674 {
1675 yyextra->token.endTag = TRUE;
1676 startNamePos++;
1677 }
#define TRUE
Definition qcstring.h:37
1678
1679 // Parse the name portion
1680 int i = startNamePos;
1681 for (i=startNamePos; i < (int)yyleng; i++)
1682 {
1683 // Check for valid HTML/XML name chars (including namespaces)
1684 char c = tagText.at(i);
1685 if (!(isalnum(c) || c=='-' || c=='_' || c==':')) break;
1686 }
1687 yyextra->token.name = tagText.mid(startNamePos,i-startNamePos);
1688
1689 // Parse the attributes. Each attribute is a name, value pair
1690 // The result is stored in yyextra->token.attribs.
1691 int startAttribList = i;
1692 while (i<(int)yyleng)
1693 {
1694 char c=tagText.at(i);
1695 // skip spaces
1696 while (i<(int)yyleng && isspace((uint8_t)c)) { c=tagText.at(++i); }
1697 // check for end of the tag
1698 if (c == '>') break;
1699 // Check for XML style "empty" tag.
1700 if (c == '/')
1701 {
1702 yyextra->token.emptyTag = TRUE;
1703 break;
1704 }
1705 int startName=i;
1706 // search for end of name
1707 while (i<(int)yyleng && !isspace((uint8_t)c) && c!='=' && c!= '>') { c=tagText.at(++i); }
1708 int endName=i;
1709 QCString optName,optValue;
1710 optName = tagText.mid(startName,endName-startName).lower();
1711 // skip spaces
1712 while (i<(int)yyleng && isspace((uint8_t)c)) { c=tagText.at(++i); }
1713 if (tagText.at(i)=='=') // option has value
1714 {
1715 int startAttrib=0, endAttrib=0;
1716 c=tagText.at(++i);
1717 // skip spaces
1718 while (i<(int)yyleng && isspace((uint8_t)c)) { c=tagText.at(++i); }
1719 if (tagText.at(i)=='\'') // option '...'
1720 {
1721 c=tagText.at(++i);
1722 startAttrib=i;
QCString lower() const
Definition qcstring.h:249
1723
1724 // search for matching quote
1725 while (i<(int)yyleng && c!='\'') { c=tagText.at(++i); }
1726 endAttrib=i;
1727 if (i<(int)yyleng) { c=tagText.at(++i);}
1728 }
1729 else if (tagText.at(i)=='"') // option "..."
1730 {
1731 c=tagText.at(++i);
1732 startAttrib=i;
1733 // search for matching quote
1734 while (i<(int)yyleng && c!='"') { c=tagText.at(++i); }
1735 endAttrib=i;
1736 if (i<(int)yyleng) { c=tagText.at(++i);}
1737 }
1738 else // value without any quotes
1739 {
1740 startAttrib=i;
1741 // search for separator or end symbol
1742 while (i<(int)yyleng && !isspace((uint8_t)c) && c!='>') { c=tagText.at(++i); }
1743 endAttrib=i;
1744 if (i<(int)yyleng) { c=tagText.at(++i);}
1745 }
1746 optValue = tagText.mid(startAttrib,endAttrib-startAttrib);
1747 if (optName == "align") optValue = optValue.lower();
1748 else if (optName == "valign")
1749 {
1750 optValue = optValue.lower();
1751 if (optValue == "center") optValue="middle";
1752 }
1753 }
1754 else // start next option
1755 {
1756 }
1757 //printf("=====> Adding option name=<%s> value=<%s>\n",
1758 // qPrint(optName),qPrint(optValue));
1759 yyextra->token.attribs.emplace_back(optName,optValue);
1760 }
1761 yyextra->token.attribsStr = tagText.mid(startAttribList,i-startAttribList);
1762}

References QCString::at(), QCString::clear(), FALSE, QCString::lower(), QCString::mid(), and TRUE.

◆ processSection()

void processSection ( yyscan_t yyscanner)
static

Definition at line 1640 of file doctokenizer.l.

1641{
1642 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1643 //printf("%s: found section/anchor with name '%s'\n",qPrint(yyextra->fileName),qPrint(yyextra->secLabel));
1644 QCString file;
1645 if (yyextra->definition)
1646 {
1647 file = yyextra->definition->getOutputFileBase();
1648 }
1649 else
1650 {
1651 warn(yyextra->fileName,yyextra->yyLineNr,"Found section/anchor {} without context",yyextra->secLabel);
1652 }
1653 SectionInfo *si = SectionManager::instance().find(yyextra->secLabel);
1654 if (si)
1655 {
1656 si->setFileName(file);
1657 si->setType(yyextra->secType);
1658 }
const T * find(const std::string &key) const
Definition linkedmap.h:47
class that provide information about a section.
Definition section.h:58
void setType(SectionType t)
Definition section.h:81
void setFileName(const QCString &fn)
Definition section.h:80
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:179
#define warn(file, line, fmt,...)
Definition message.h:97
1659}

References LinkedMap< T, Hash, KeyEqual, Map >::find(), SectionManager::instance(), SectionInfo::setFileName(), SectionInfo::setType(), and warn.

◆ stateToString()

const char * stateToString ( int state)
static

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 340 of file doctokenizer.l.

342 {LISTITEM} { /* list item */
343 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
344 lineCount(yytext,yyleng);
345 QCString text(yytext);
346 uint32_t dashPos = static_cast<uint32_t>(text.findRev('-'));
347 assert(dashPos!=static_cast<uint32_t>(-1));
348 yyextra->token.isEnumList = text.at(dashPos+1)=='#';
349 yyextra->token.isCheckedList = false;
350 yyextra->token.id = -1;
351 yyextra->token.indent = computeIndent(yytext,dashPos);
352 return Token::make_TK_LISTITEM();
353 }
#define lineCount(s, len)
static int computeIndent(const char *str, size_t length)
354<St_Para>^{CLISTITEM} { /* checkbox item */
355 QCString text=yytext;
356 int dashPos = text.findRev('-');
357 yyextra->token.isEnumList = false;
358 yyextra->token.isCheckedList = true;
359 if (text.find('x') != -1) yyextra->token.id = DocAutoList::Checked_x;
360 else if (text.find('X') != -1) yyextra->token.id = DocAutoList::Checked_X;
361 else yyextra->token.id = DocAutoList::Unchecked;
362 yyextra->token.indent = computeIndent(yytext,dashPos);
363 return Token::make_TK_LISTITEM();
364 }
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
365<St_Para>^{MLISTITEM} { /* list item */
366 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
367 {
368 REJECT;
369 }
370 else
371 {
372 lineCount(yytext,yyleng);
373 std::string text(yytext);
374 static const reg::Ex re(R"([*+][^*+]*$)"); // find last + or *
376 reg::search(text,match,re);
377 size_t listPos = match.position();
378 assert(listPos!=std::string::npos);
379 yyextra->token.isEnumList = false;
380 yyextra->token.isCheckedList = false;
381 yyextra->token.id = -1;
382 yyextra->token.indent = computeIndent(yytext,listPos);
383 return Token::make_TK_LISTITEM();
384 }
385 }
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
386<St_Para>^{OLISTITEM} { /* numbered list item */
387 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
388 {
389 REJECT;
390 }
391 else
392 {
393 std::string text(yytext);
394 static const reg::Ex re(R"(\d+)");
396 reg::search(text,match,re);
397 size_t markPos = match.position();
398 assert(markPos!=std::string::npos);
399 yyextra->token.isEnumList = true;
400 yyextra->token.isCheckedList = false;
401 bool ok = false;
402 int id = QCString(match.str()).toInt(&ok);
403 yyextra->token.id = ok ? id : -1;
404 if (!ok)
405 {
406 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid number for list item '{}' ",match.str());
407 }
408 yyextra->token.indent = computeIndent(yytext,markPos);
409 return Token::make_TK_LISTITEM();
410 }
411 }
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:254
412<St_Para>{BLANK}*(\n|"\\ilinebr"){LISTITEM} { /* list item on next line */
413 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
414 lineCount(yytext,yyleng);
416 uint32_t dashPos = static_cast<uint32_t>(text.findRev('-'));
417 assert(dashPos!=static_cast<uint32_t>(-1));
418 yyextra->token.isEnumList = text.at(dashPos+1)=='#';
419 yyextra->token.isCheckedList = false;
420 yyextra->token.id = -1;
421 yyextra->token.indent = computeIndent(text.data(),dashPos);
422 return Token::make_TK_LISTITEM();
423 }
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
QCString extractPartAfterNewLine(const QCString &text)
424<St_Para>{BLANK}*\n{CLISTITEM} { /* checkbox item on next line */
425 QCString text=yytext;
426 text=text.right(text.length()-text.find('\n')-1);
427 int dashPos = text.findRev('-');
428 yyextra->token.isEnumList = false;
429 yyextra->token.isCheckedList = true;
430 if (text.find('x') != -1) yyextra->token.id = DocAutoList::Checked_x;
431 else if (text.find('X') != -1) yyextra->token.id = DocAutoList::Checked_X;
432 else yyextra->token.id = DocAutoList::Unchecked;
433 yyextra->token.indent = computeIndent(text.data(),dashPos);
434 return Token::make_TK_LISTITEM();
435 }
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
436<St_Para>{BLANK}*(\n|"\\ilinebr"){MLISTITEM} { /* list item on next line */
437 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
438 {
439 REJECT;
440 }
441 else
442 {
443 lineCount(yytext,yyleng);
444 std::string text=extractPartAfterNewLine(yytext).str();
445 static const reg::Ex re(R"([*+][^*+]*$)"); // find last + or *
447 reg::search(text,match,re);
448 size_t markPos = match.position();
449 assert(markPos!=std::string::npos);
450 yyextra->token.isEnumList = FALSE;
451 yyextra->token.isCheckedList = false;
452 yyextra->token.id = -1;
453 yyextra->token.indent = computeIndent(text.c_str(),markPos);
454 return Token::make_TK_LISTITEM();
455 }
456 }
const std::string & str() const
Definition qcstring.h:552
457<St_Para>{BLANK}*(\n|"\\ilinebr"){OLISTITEM} { /* list item on next line */
458 if (yyextra->insideHtmlLink || !yyextra->markdownSupport || yyextra->insidePre)
459 {
460 REJECT;
461 }
462 else
463 {
464 lineCount(yytext,yyleng);
465 std::string text=extractPartAfterNewLine(yytext).str();
466 static const reg::Ex re(R"(\d+)");
468 reg::search(text,match,re);
469 size_t markPos = match.position();
470 assert(markPos!=std::string::npos);
471 yyextra->token.isEnumList = true;
472 yyextra->token.isCheckedList = false;
473 bool ok = false;
474 int id = QCString(match.str()).toInt(&ok);
475 yyextra->token.id = ok ? id : -1;
476 if (!ok)
477 {
478 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid number for list item '{}' ",match.str());
479 }
480 yyextra->token.indent = computeIndent(text.c_str(),markPos);
481 return Token::make_TK_LISTITEM();
482 }
483 }
484<St_Para>^{ENDLIST} { /* end list */
485 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
486 lineCount(yytext,yyleng);
487 size_t dotPos = static_cast<size_t>(QCString(yytext).findRev('.'));
488 yyextra->token.indent = computeIndent(yytext,dotPos);
489 return Token::make_TK_ENDLIST();
490 }
491<St_Para>{BLANK}*(\n|"\\ilinebr"){ENDLIST} { /* end list on next line */
492 if (yyextra->insideHtmlLink || yyextra->insidePre) REJECT;
493 lineCount(yytext,yyleng);
495 size_t dotPos = static_cast<size_t>(text.findRev('.'));
496 yyextra->token.indent = computeIndent(text.data(),dotPos);
497 return Token::make_TK_ENDLIST();
498 }
499<St_Para>"{"{BLANK}*"@linkplain"/{WS}+ {
500 yyextra->token.name = "javalinkplain";
501 return Token::make_TK_COMMAND_AT();
502 }
503<St_Para>"{"{BLANK}*"@link"/{WS}+ {
504 yyextra->token.name = "javalink";
505 return Token::make_TK_COMMAND_AT();
506 }
507<St_Para>"{"{BLANK}*"@inheritDoc"{BLANK}*"}" {
508 yyextra->token.name = "inheritdoc";
509 return Token::make_TK_COMMAND_AT();
510 }
511<St_Para>"@_fakenl" { // artificial new line
512 //yyextra->yyLineNr++;
513 }
514<St_Para>{SPCMD3} {
515 yyextra->token.name = "_form";
516 bool ok;
517 yyextra->token.id = QCString(yytext).right((int)yyleng-7).toInt(&ok);
518 ASSERT(ok);
519 return Token::char_to_command(yytext[0]);
520 }
static Token char_to_command(char c)
#define ASSERT(x)
Definition qcstring.h:39
521<St_Para>{CMD}"n"\n { /* \n followed by real newline */
522 lineCount(yytext,yyleng);
523 //yyextra->yyLineNr++;
524 yyextra->token.name = yytext+1;
525 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
526 yyextra->token.paramDir=TokenInfo::Unspecified;
527 return Token::char_to_command(yytext[0]);
528 }
529<St_Para>"\\ilinebr" {
530 }
531<St_Para>{SPCMD1} |
532<St_Para>{SPCMD2} |
533<St_Para>{SPCMD5} |
534<St_Para>{SPCMD4} { /* special command */
535 yyextra->token.name = yytext+1;
536 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
537 yyextra->token.paramDir=TokenInfo::Unspecified;
538 return Token::char_to_command(yytext[0]);
539 }
540<St_Para>{PARAMIO} { /* param [in,out] command */
541 yyextra->token.name = "param";
542 QCString s(yytext);
543 bool isIn = s.find("in")!=-1;
544 bool isOut = s.find("out")!=-1;
545 if (isIn)
546 {
547 if (isOut)
548 {
549 yyextra->token.paramDir=TokenInfo::InOut;
550 }
551 else
552 {
553 yyextra->token.paramDir=TokenInfo::In;
554 }
555 }
556 else if (isOut)
557 {
558 yyextra->token.paramDir=TokenInfo::Out;
559 }
560 else
561 {
562 yyextra->token.paramDir=TokenInfo::Unspecified;
563 }
564 return Token::char_to_command(yytext[0]);
565 }
566<St_Para>{URLPROTOCOL}{URLMASK}/[,\.] { // URL, or 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.isEMailAddr=FALSE;
574 return Token::make_TK_URL();
575 }
576<St_Para>"<"{URLPROTOCOL}{URLMASK}">" { // URL
577 yyextra->token.name=yytext;
578 yyextra->token.name = yyextra->token.name.mid(1,yyextra->token.name.length()-2);
579 yyextra->token.isEMailAddr=FALSE;
580 return Token::make_TK_URL();
581 }
582<St_Para>{MAILADDR} { // Mail address
583 yyextra->token.name=yytext;
584 yyextra->token.name.stripPrefix("mailto:");
585 yyextra->token.isEMailAddr=TRUE;
586 return Token::make_TK_URL();
587 }
588<St_Para>"<"{MAILADDR}">" { // Mail address
589 yyextra->token.name=yytext;
590 yyextra->token.name = yyextra->token.name.mid(1,yyextra->token.name.length()-2);
591 yyextra->token.name.stripPrefix("mailto:");
592 yyextra->token.isEMailAddr=TRUE;
593 return Token::make_TK_URL();
594 }
595<St_Para>"<"{MAILADDR2}">" { // anti spam mail address
596 yyextra->token.name=yytext;
597 return Token::make_TK_WORD();
598 }
599<St_Para>{RCSID} { /* RCS tag */
600 QCString tagName(yytext+1);
601 int index=tagName.find(':');
602 if (index<0) index=0; // should never happen
603 yyextra->token.name = tagName.left(index);
604 int text_begin = index+2;
605 int text_end = static_cast<int>(tagName.length())-1;
606 if (tagName[text_begin-1]==':') /* check for Subversion fixed-length keyword */
607 {
608 ++text_begin;
609 if (tagName[text_end-1]=='#')
610 {
611 --text_end;
612 }
613 }
614 yyextra->token.text = tagName.mid(text_begin,text_end-text_begin);
615 return Token::make_TK_RCSTAG();
616 }
617<St_Para,St_HtmlOnly,St_ManOnly,St_LatexOnly,St_RtfOnly,St_XmlOnly,St_DbOnly>"$("{ID}")" | /* environment variable */
618<St_Para,St_HtmlOnly,St_ManOnly,St_LatexOnly,St_RtfOnly,St_XmlOnly,St_DbOnly>"$("{ID}"("{ID}"))" { /* environment variable */
619 QCString name(&yytext[2]);
620 name = name.left(static_cast<int>(name.length())-1);
621 QCString value = Portable::getenv(name);
622 for (int i=static_cast<int>(value.length())-1;i>=0;i--) unput(value.at(i));
623 }
QCString getenv(const QCString &variable)
Definition portable.cpp:321
624<St_Para>"<blockquote>&zwj;" {
625 // for a markdown inserted block quote,
626 // tell flex that after putting the last indent
627 // back we are at the beginning of the line, see issue #11309
628 YY_CURRENT_BUFFER->yy_at_bol=1;
629 lineCount(yytext,yyleng);
630 handleHtmlTag(yyscanner,yytext);
631 return Token::make_TK_HTMLTAG();
632 }
static void handleHtmlTag(yyscan_t yyscanner, const char *text)
633<St_Para>{HTMLTAG} { /* html tag */
634 lineCount(yytext,yyleng);
635 handleHtmlTag(yyscanner,yytext);
636 return Token::make_TK_HTMLTAG();
637 }
638<St_Para,St_Text>"&"{ID}";" { /* special symbol */
639 yyextra->token.name = yytext;
640 return Token::make_TK_SYMBOL();
641 }
642
643 /********* patterns for linkable words ******************/
644
645<St_Para>{ID}/"<"{HTMLKEYW}">"+ { /* this rule is to prevent opening html
646 * tag to be recognized as a templated classes
647 */
648 yyextra->token.name = yytext;
649 return Token::make_TK_LNKWORD();
650 }
651<St_Para>{LNKWORDN}/("<"{HTMLKEYW}">")+ { // prevent <br> html tag to be parsed as template arguments
652 yyextra->token.name = yytext;
653 return Token::make_TK_LNKWORD();
654 }
655<St_Para>{LNKWORD1} |
656<St_Para>{LNKWORD1}{FUNCARG} |
657<St_Para>{LNKWORD2} |
658<St_Para>{LNKWORD3} |
659<St_Para>{LNKWORD4} {
660 yyextra->token.name = yytext;
661 return Token::make_TK_LNKWORD();
662 }
663<St_Para>{LNKWORD1}{FUNCARG}{CVSPEC}[^a-z_A-Z0-9] {
664 yyextra->token.name = yytext;
665 yyextra->token.name = yyextra->token.name.left(yyextra->token.name.length()-1);
666 unput(yytext[(int)yyleng-1]);
667 return Token::make_TK_LNKWORD();
668 }
669 /********* patterns for normal words ******************/
670
671<St_Para,St_Text>[\-+0-9] |
672<St_Para,St_Text>{WORD1} |
673<St_Para,St_Text>{WORD2} { /* function call */
674 if (QCString(yytext).find("\\ilinebr")!=-1) REJECT; // see issue #8311
675 lineCount(yytext,yyleng);
676 if (yytext[0]=='%') // strip % if present
677 yyextra->token.name = &yytext[1];
678 else
679 yyextra->token.name = yytext;
680 return Token::make_TK_WORD();
681 }
682<St_Text>({ID}".")+{ID} {
683 yyextra->token.name = yytext;
684 return Token::make_TK_WORD();
685 }
686<St_Para,St_Text>"operator"/{BLANK}*"<"[a-zA-Z_0-9]+">" { // Special case: word "operator" followed by a HTML command
687 // avoid interpretation as "operator <"
688 yyextra->token.name = yytext;
689 return Token::make_TK_WORD();
690 }
691
692 /*******************************************************/
693
694<St_Para,St_Text>{BLANK}+ |
695<St_Para,St_Text>{BLANK}*\n{BLANK}* { /* white space */
696 lineCount(yytext,yyleng);
697 yyextra->token.chars=yytext;
698 return Token::make_TK_WHITESPACE();
699 }
700<St_Text>[\\@<>&$#%~] {
701 yyextra->token.name = yytext;
702 return Token::char_to_command(yytext[0]);
703 }
704<St_Para>({BLANK}*\n)+{BLANK}*\n/{LISTITEM} { /* skip trailing paragraph followed by new list item */
705 if (yyextra->insidePre || yyextra->autoListLevel==0)
706 {
707 REJECT;
708 }
709 lineCount(yytext,yyleng);
710 }
711<St_Para>({BLANK}*\n)+{BLANK}*\n/{CLISTITEM} { /* skip trailing paragraph followed by new checkbox item */
712 if (yyextra->insidePre || yyextra->autoListLevel==0)
713 {
714 REJECT;
715 }
716 }
717<St_Para>({BLANK}*\n)+{BLANK}*\n/{MLISTITEM} { /* skip trailing paragraph followed by new list item */
718 if (!yyextra->markdownSupport || yyextra->insidePre || yyextra->autoListLevel==0)
719 {
720 REJECT;
721 }
722 lineCount(yytext,yyleng);
723 }
724<St_Para>({BLANK}*\n)+{BLANK}*\n/{OLISTITEM} { /* skip trailing paragraph followed by new list item */
725 if (!yyextra->markdownSupport || yyextra->insidePre || yyextra->autoListLevel==0)
726 {
727 REJECT;
728 }
729 lineCount(yytext,yyleng);
730 }
731<St_Para,St_Param>({BLANK}*(\n|"\\ilinebr"))+{BLANK}*(\n|"\\ilinebr"){BLANK}*/" \\ifile" | // we don't want to count the space before \ifile
732<St_Para,St_Param>({BLANK}*(\n|"\\ilinebr"))+{BLANK}*(\n|"\\ilinebr"){BLANK}* {
733 lineCount(yytext,yyleng);
734 if (yyextra->insidePre)
735 {
736 yyextra->token.chars=yytext;
737 return Token::make_TK_WHITESPACE();
738 }
739 else
740 {
741 yyextra->token.indent=computeIndent(yytext,yyleng);
742 int i;
743 // put back the indentation (needed for list items)
744 //printf("token.indent=%d\n",yyextra->token.indent);
745 for (i=0;i<yyextra->token.indent;i++)
746 {
747 unput(' ');
748 }
749 // tell flex that after putting the last indent
750 // back we are at the beginning of the line
751 YY_CURRENT_BUFFER->yy_at_bol=1;
752 // start of a new paragraph
753 return Token::make_TK_NEWPARA();
754 }
755 }
756<St_CodeOpt>{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_Code);
761 }
762<St_iCodeOpt>{BLANK}*"{"(".")?{CODEID}"}" {
763 yyextra->token.name = yytext;
764 int i=yyextra->token.name.find('{'); /* } to keep vi happy */
765 yyextra->token.name = yyextra->token.name.mid(i+1,yyextra->token.name.length()-i-2);
766 BEGIN(St_iCode);
767 }
768<St_CodeOpt>"\\ilinebr" |
769<St_CodeOpt>\n |
770<St_CodeOpt>. {
771 unput_string(yytext,yyleng);
772 BEGIN(St_Code);
773 }
#define unput_string(yytext, yyleng)
774<St_iCodeOpt>"\\ilinebr" |
775<St_iCodeOpt>\n |
776<St_iCodeOpt>. {
777 unput_string(yytext,yyleng);
778 BEGIN(St_iCode);
779 }
780<St_Code>{WS}*{CMD}"endcode" {
781 lineCount(yytext,yyleng);
782 return Token::make_RetVal_OK();
783 }
784<St_iCode>{WS}*{CMD}"endicode" {
785 lineCount(yytext,yyleng);
786 return Token::make_RetVal_OK();
787 }
788<St_XmlCode>{WS}*"</code>" {
789 lineCount(yytext,yyleng);
790 return Token::make_RetVal_OK();
791 }
792<St_Code,St_iCode,St_XmlCode>[^\\@\n<]+ |
793<St_Code,St_iCode,St_XmlCode>\n |
794<St_Code,St_iCode,St_XmlCode>. {
795 lineCount(yytext,yyleng);
796 yyextra->token.verb+=yytext;
797 }
798<St_HtmlOnlyOption>" [block]" { // the space is added in commentscan.l
799 yyextra->token.name="block";
800 BEGIN(St_HtmlOnly);
801 }
802<St_HtmlOnlyOption>.|\n {
803 unput(*yytext);
804 BEGIN(St_HtmlOnly);
805 }
806<St_HtmlOnlyOption>"\\ilinebr" {
807 unput_string(yytext,yyleng);
808 BEGIN(St_HtmlOnly);
809 }
810<St_HtmlOnly>{CMD}"endhtmlonly" {
811 return Token::make_RetVal_OK();
812 }
813<St_HtmlOnly>[^\\@\n$]+ |
814<St_HtmlOnly>\n |
815<St_HtmlOnly>. {
816 lineCount(yytext,yyleng);
817 yyextra->token.verb+=yytext;
818 }
819<St_ManOnly>{CMD}"endmanonly" {
820 return Token::make_RetVal_OK();
821 }
822<St_ManOnly>[^\\@\n$]+ |
823<St_ManOnly>\n |
824<St_ManOnly>. {
825 lineCount(yytext,yyleng);
826 yyextra->token.verb+=yytext;
827 }
828<St_RtfOnly>{CMD}"endrtfonly" {
829 return Token::make_RetVal_OK();
830 }
831<St_RtfOnly>[^\\@\n$]+ |
832<St_RtfOnly>\n |
833<St_RtfOnly>. {
834 lineCount(yytext,yyleng);
835 yyextra->token.verb+=yytext;
836 }
837<St_LatexOnly>{CMD}"endlatexonly" {
838 return Token::make_RetVal_OK();
839 }
840<St_LatexOnly>[^\\@\n]+ |
841<St_LatexOnly>\n |
842<St_LatexOnly>. {
843 lineCount(yytext,yyleng);
844 yyextra->token.verb+=yytext;
845 }
846<St_XmlOnly>{CMD}"endxmlonly" {
847 return Token::make_RetVal_OK();
848 }
849<St_XmlOnly>[^\\@\n]+ |
850<St_XmlOnly>\n |
851<St_XmlOnly>. {
852 lineCount(yytext,yyleng);
853 yyextra->token.verb+=yytext;
854 }
855<St_DbOnly>{CMD}"enddocbookonly" {
856 return Token::make_RetVal_OK();
857 }
858<St_DbOnly>[^\\@\n]+ |
859<St_DbOnly>\n |
860<St_DbOnly>. {
861 lineCount(yytext,yyleng);
862 yyextra->token.verb+=yytext;
863 }
864<St_Verbatim>{CMD}"endverbatim" {
865 yyextra->token.verb = yyextra->token.verb.stripLeadingAndTrailingEmptyLines();
866 return Token::make_RetVal_OK();
867 }
868<St_ILiteral>{CMD}"endiliteral " { // note extra space as this is artificially added
869 // remove spaces that have been added
870 yyextra->token.verb = yyextra->token.verb.mid(1,yyextra->token.verb.length()-2);
871 return Token::make_RetVal_OK();
872 }
873<St_iVerbatim>{CMD}"endiverbatim" {
874 yyextra->token.verb = yyextra->token.verb.stripLeadingAndTrailingEmptyLines();
875 return Token::make_RetVal_OK();
876 }
877<St_Verbatim,St_iVerbatim,St_ILiteral>[^\\@\n]+ |
878<St_Verbatim,St_iVerbatim,St_ILiteral>\n |
879<St_Verbatim,St_iVerbatim,St_ILiteral>. { /* Verbatim text */
880 lineCount(yytext,yyleng);
881 yyextra->token.verb+=yytext;
882 }
883<St_ILiteralOpt>{BLANK}*"{"[a-zA-Z_,:0-9\. ]*"}" { // option(s) present
884 yyextra->token.verb = QCString(yytext).stripWhiteSpace();
885 return Token::make_RetVal_OK();
886 }
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:260
887<St_ILiteralOpt>"\\ilinebr" |
888<St_ILiteralOpt>"\n" |
889<St_ILiteralOpt>. {
890 yyextra->token.sectionId = "";
891 unput_string(yytext,yyleng);
892 return Token::make_RetVal_OK();
893 }
894<St_Dot>{CMD}"enddot" {
895 return Token::make_RetVal_OK();
896 }
897<St_Dot>[^\\@\n]+ |
898<St_Dot>\n |
899<St_Dot>. { /* dot text */
900 lineCount(yytext,yyleng);
901 yyextra->token.verb+=yytext;
902 }
903<St_Msc>{CMD}("endmsc") {
904 return Token::make_RetVal_OK();
905 }
906<St_Msc>[^\\@\n]+ |
907<St_Msc>\n |
908<St_Msc>. { /* msc text */
909 lineCount(yytext,yyleng);
910 yyextra->token.verb+=yytext;
911 }
912<St_PlantUMLOpt>{BLANK}*"{"[a-zA-Z_,:0-9\. ]*"}" { // case 1: options present
913 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
914 return Token::make_RetVal_OK();
915 }
916<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}+/{ID}"=" { // case 2: plain file name specified followed by an attribute
917 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
918 return Token::make_RetVal_OK();
919 }
920<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}+/"\"" { // case 3: plain file name specified followed by a quoted title
921 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
922 return Token::make_RetVal_OK();
923 }
924<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANKopt}/\n { // case 4: plain file name specified without title or attributes
925 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
926 return Token::make_RetVal_OK();
927 }
928<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANKopt}/"\\ilinebr" { // case 5: plain file name specified without title or attributes
929 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
930 return Token::make_RetVal_OK();
931 }
932<St_PlantUMLOpt>"\\ilinebr" |
933<St_PlantUMLOpt>"\n" |
934<St_PlantUMLOpt>. {
935 yyextra->token.sectionId = "";
936 unput_string(yytext,yyleng);
937 return Token::make_RetVal_OK();
938 }
939<St_PlantUML>{CMD}"enduml" {
940 return Token::make_RetVal_OK();
941 }
942<St_PlantUML>[^\\@\n]+ |
943<St_PlantUML>\n |
944<St_PlantUML>. { /* plantuml text */
945 lineCount(yytext,yyleng);
946 yyextra->token.verb+=yytext;
947 }
948<St_MermaidOpt>{BLANK}*"{"[a-zA-Z_,:0-9\. ]*"}" { // case 1: options present
949 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
950 return Token::make_RetVal_OK();
951 }
952<St_MermaidOpt>{BLANK}*{FILEMASK}{BLANK}+/{ID}"=" { // case 2: plain file name specified followed by an attribute
953 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
954 return Token::make_RetVal_OK();
955 }
956<St_MermaidOpt>{BLANK}*{FILEMASK}{BLANK}+/"\"" { // case 3: plain file name specified followed by a quoted title
957 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
958 return Token::make_RetVal_OK();
959 }
960<St_MermaidOpt>{BLANK}*{FILEMASK}{BLANKopt}/\n { // case 4: plain file name specified without title or attributes
961 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
962 return Token::make_RetVal_OK();
963 }
964<St_MermaidOpt>{BLANK}*{FILEMASK}{BLANKopt}/"\\ilinebr" { // case 5: plain file name specified without title or attributes
965 yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
966 return Token::make_RetVal_OK();
967 }
968<St_MermaidOpt>"\\ilinebr" |
969<St_MermaidOpt>"\n" |
970<St_MermaidOpt>. {
971 yyextra->token.sectionId = "";
972 unput_string(yytext,yyleng);
973 return Token::make_RetVal_OK();
974 }
975<St_Mermaid>{CMD}"endmermaid" {
976 return Token::make_RetVal_OK();
977 }
978<St_Mermaid>[^\\@\n]+ |
979<St_Mermaid>\n |
980<St_Mermaid>. { /* mermaid text */
981 lineCount(yytext,yyleng);
982 yyextra->token.verb+=yytext;
983 }
984<St_Title>"\"" { // quoted title
985 BEGIN(St_TitleQ);
986 }
987<St_Title>[ \t]+ {
988 yyextra->token.chars=yytext;
989 return Token::make_TK_WHITESPACE();
990 }
991<St_Title>. { // non-quoted title
992 unput(*yytext);
993 BEGIN(St_TitleN);
994 }
995<St_Title>\n {
996 unput(*yytext);
997 return Token::make_TK_NONE();
998 }
999<St_Title>"\\ilinebr" {
1000 unput_string(yytext,yyleng);
1001 return Token::make_TK_NONE();
1002 }
1003<St_TitleN>"&"{ID}";" { /* symbol */
1004 yyextra->token.name = yytext;
1005 return Token::make_TK_SYMBOL();
1006 }
1007<St_TitleN>{HTMLTAG} {
1008 yyextra->token.name = yytext;
1009 handleHtmlTag(yyscanner,yytext);
1010 return Token::make_TK_HTMLTAG();
1011 }
1012<St_TitleN>\n { /* new line => end of title */
1013 unput(*yytext);
1014 return Token::make_TK_NONE();
1015 }
1016<St_TitleN>"\\ilinebr" { /* new line => end of title */
1017 unput_string(yytext,yyleng);
1018 return Token::make_TK_NONE();
1019 }
1020<St_TitleN>{SPCMD1} |
1021<St_TitleN>{SPCMD2} { /* special command */
1022 yyextra->token.name = yytext+1;
1023 yyextra->token.paramDir=TokenInfo::Unspecified;
1024 return Token::char_to_command(yytext[0]);
1025 }
1026<St_TitleN>{ID}"=" { /* attribute */
1027 if (yytext[0]=='%') // strip % if present
1028 yyextra->token.name = &yytext[1];
1029 else
1030 yyextra->token.name = yytext;
1031 return Token::make_TK_WORD();
1032 }
1033<St_TitleN>[\-+0-9] |
1034<St_TitleN>{WORD1} |
1035<St_TitleN>{WORD2} { /* word */
1036 if (QCString(yytext).find("\\ilinebr")!=-1) REJECT; // see issue #8311
1037 lineCount(yytext,yyleng);
1038 if (yytext[0]=='%') // strip % if present
1039 yyextra->token.name = &yytext[1];
1040 else
1041 yyextra->token.name = yytext;
1042 return Token::make_TK_WORD();
1043 }
1044<St_TitleN>[ \t]+ {
1045 yyextra->token.chars=yytext;
1046 return Token::make_TK_WHITESPACE();
1047 }
1048<St_TitleQ>"&"{ID}";" { /* symbol */
1049 yyextra->token.name = yytext;
1050 return Token::make_TK_SYMBOL();
1051 }
1052<St_TitleQ>(\n|"\\ilinebr") { /* new line => end of title */
1053 unput_string(yytext,yyleng);
1054 return Token::make_TK_NONE();
1055 }
1056<St_TitleQ>{SPCMD1} |
1057<St_TitleQ>{SPCMD2} { /* special command */
1058 yyextra->token.name = yytext+1;
1059 yyextra->token.paramDir=TokenInfo::Unspecified;
1060 return Token::char_to_command(yytext[0]);
1061 }
1062<St_TitleQ>{WORD1NQ} |
1063<St_TitleQ>{WORD2NQ} { /* word */
1064 yyextra->token.name = yytext;
1065 return Token::make_TK_WORD();
1066 }
1067<St_TitleQ>[ \t]+ {
1068 yyextra->token.chars=yytext;
1069 return Token::make_TK_WHITESPACE();
1070 }
1071<St_TitleQ>"\"" { /* closing quote => end of title */
1072 BEGIN(St_TitleA);
1073 return Token::make_TK_NONE();
1074 }
1075<St_TitleA>{BLANK}*{ID}{BLANK}*"="{BLANK}* { // title attribute
1076 yyextra->token.name = yytext;
1077 int pos = yyextra->token.name.find('=');
1078 if (pos<0) pos=0; // should never happen
1079 yyextra->token.name = yyextra->token.name.left(pos).stripWhiteSpace();
1080 BEGIN(St_TitleV);
1081 }
1082<St_TitleV>[^ \t\r\n]+ { // attribute value
1083 lineCount(yytext,yyleng);
1084 yyextra->token.chars = yytext;
1085 BEGIN(St_TitleN);
1086 return Token::make_TK_WORD();
1087 }
1088<St_TitleV,St_TitleA>. {
1089 unput(*yytext);
1090 return Token::make_TK_NONE();
1091 }
1092<St_TitleV,St_TitleA>(\n|"\\ilinebr") {
1093 unput_string(yytext,yyleng);
1094 return Token::make_TK_NONE();
1095 }
1096
1097<St_Anchor>({REQID}|{LABELID}){WS}? { // anchor
1098 lineCount(yytext,yyleng);
1099 yyextra->token.name = QCString(yytext).stripWhiteSpace();
1100 return Token::make_TK_WORD();
1101 }
1102<St_Anchor>. {
1103 unput(*yytext);
1104 return Token::make_TK_NONE();
1105 }
1106<St_Cite>{CITEID} { // label to cite
1107 if (yytext[0] =='"')
1108 {
1109 yyextra->token.name=yytext+1;
1110 yyextra->token.name=yyextra->token.name.left(static_cast<uint32_t>(yyleng)-2);
1111 }
1112 else
1113 {
1114 yyextra->token.name=yytext;
1115 }
1116 return Token::make_TK_WORD();
1117 }
1118<St_Cite>{BLANK} { // white space
1119 unput(' ');
1120 return Token::make_TK_NONE();
1121 }
1122<St_Cite>(\n|"\\ilinebr") { // new line
1123 unput_string(yytext,yyleng);
1124 return Token::make_TK_NONE();
1125 }
1126<St_Cite>. { // any other character
1127 unput(*yytext);
1128 return Token::make_TK_NONE();
1129 }
1130<St_DoxyConfig>{DOXYCFG} { // config option
1131 yyextra->token.name=yytext;
1132 return Token::make_TK_WORD();
1133 }
1134<St_DoxyConfig>{BLANK} { // white space
1135 unput(' ');
1136 return Token::make_TK_NONE();
1137 }
1138<St_DoxyConfig>(\n|"\\ilinebr") { // new line
1139 unput_string(yytext,yyleng);
1140 return Token::make_TK_NONE();
1141 }
1142<St_DoxyConfig>. { // any other character
1143 unput(*yytext);
1144 return Token::make_TK_NONE();
1145 }
1146<St_Ref>{REFWORD_NOCV}/{BLANK}("const")[a-z_A-Z0-9] { // see bug776988
1147 yyextra->token.name=yytext;
1148 return Token::make_TK_WORD();
1149 }
1150<St_Ref>{REFWORD_NOCV}/{BLANK}("volatile")[a-z_A-Z0-9] { // see bug776988
1151 yyextra->token.name=yytext;
1152 return Token::make_TK_WORD();
1153 }
1154<St_Ref>{REFWORD} { // label to refer to
1155 yyextra->token.name=yytext;
1156 return Token::make_TK_WORD();
1157 }
1158<St_Ref>{BLANK} { // white space
1159 unput(' ');
1160 return Token::make_TK_NONE();
1161 }
1162<St_Ref>{WS}+"\""{WS}* { // white space following by quoted string
1163 yyextra->expectQuote=true;
1164 lineCount(yytext,yyleng);
1165 BEGIN(St_Ref2);
1166 }
1167<St_Ref>(\n|"\\ilinebr") { // new line
1168 unput_string(yytext,yyleng);
1169 return Token::make_TK_NONE();
1170 }
1171<St_Ref>"\""[^"\n]+"\"" { // quoted first argument -> return without quotes
1172 yyextra->token.name=QCString(yytext).mid(1,yyleng-2);
1173 return Token::make_TK_WORD();
1174 }
1175<St_Ref>. { // any other character
1176 unput(*yytext);
1177 return Token::make_TK_NONE();
1178 }
1179<St_IntRef>[A-Z_a-z0-9.:/#\-\+\‍(\‍)]+ {
1180 yyextra->token.name = yytext;
1181 return Token::make_TK_WORD();
1182 }
1183<St_IntRef>{BLANK}+"\"" {
1184 BEGIN(St_Ref2);
1185 }
1186<St_SetScope>({SCOPEMASK}|{ANONNS}){BLANK}|{FILEMASK} {
1187 yyextra->token.name = yytext;
1188 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1189 return Token::make_TK_WORD();
1190 }
1191<St_SetScope>{SCOPEMASK}"<" {
1192 yyextra->token.name = yytext;
1193 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1194 yyextra->sharpCount=1;
1195 BEGIN(St_SetScopeEnd);
1196 }
1197<St_SetScope>{BLANK} {
1198 }
1199<St_SetScopeEnd>"<" {
1200 yyextra->token.name += yytext;
1201 yyextra->sharpCount++;
1202 }
1203<St_SetScopeEnd>">" {
1204 yyextra->token.name += yytext;
1205 yyextra->sharpCount--;
1206 if (yyextra->sharpCount<=0)
1207 {
1208 return Token::make_TK_WORD();
1209 }
1210 }
1211<St_SetScopeEnd>. {
1212 yyextra->token.name += yytext;
1213 }
1214<St_Ref2>"&"{ID}";" { /* symbol */
1215 yyextra->token.name = yytext;
1216 return Token::make_TK_SYMBOL();
1217 }
1218<St_Ref2>"\""|\n|"\\ilinebr" { /* " or \n => end of title? */
1219 lineCount(yytext,yyleng);
1220 if (!yyextra->expectQuote || yytext[0]=='"')
1221 {
1222 return Token::make_TK_NONE();
1223 }
1224 else
1225 {
1226 yyextra->token.name += yytext;
1227 }
1228 }
1229<St_Ref2>{HTMLTAG_STRICT} { /* html tag */
1230 lineCount(yytext,yyleng);
1231 handleHtmlTag(yyscanner,yytext);
1232 return Token::make_TK_HTMLTAG();
1233 }
1234<St_Ref2>{SPCMD1} |
1235<St_Ref2>{SPCMD2} { /* special command */
1236 yyextra->token.name = yytext+1;
1237 yyextra->token.paramDir=TokenInfo::Unspecified;
1238 return Token::char_to_command(yytext[0]);
1239 }
1240<St_Ref2>{WORD1NQ} |
1241<St_Ref2>{WORD2NQ} {
1242 /* word */
1243 yyextra->token.name = yytext;
1244 return Token::make_TK_WORD();
1245 }
1246<St_Ref2>[ \t]+ {
1247 yyextra->token.chars=yytext;
1248 return Token::make_TK_WHITESPACE();
1249 }
1250<St_XRefItem>{LABELID} {
1251 yyextra->token.name=yytext;
1252 }
1253<St_XRefItem>" " {
1254 BEGIN(St_XRefItem2);
1255 }
1256<St_XRefItem2>[0-9]+"." {
1257 QCString numStr(yytext);
1258 numStr=numStr.left((int)yyleng-1);
1259 yyextra->token.id=numStr.toInt();
1260 return Token::make_RetVal_OK();
1261 }
1262<St_Para,St_Title,St_Ref2>"<!--" { /* html style comment block */
1263 yyextra->commentState = YY_START;
1264 BEGIN(St_Comment);
1265 }
1266<St_Param>"\""[^\n\"]+"\"" {
1267 yyextra->token.name = yytext+1;
1268 yyextra->token.name = yyextra->token.name.left((int)yyleng-2);
1269 return Token::make_TK_WORD();
1270 }
1271<St_Param>({PHPTYPE}{BLANK}*("["{BLANK}*"]")*{BLANK}*"|"{BLANK}*)*{PHPTYPE}{BLANK}*("["{BLANK}*"]")*{WS}+("&")?"$"{LABELID} {
1272 lineCount(yytext,yyleng);
1273 QCString params(yytext);
1274 int j = params.find('&');
1275 int i = params.find('$');
1276 if (i<0) i=0; // should never happen
1277 if (j<i && j>=0) i=j;
1278 QCString types = params.left(i).stripWhiteSpace();
1279 yyextra->token.name = types+"#"+params.mid(i);
1280 return Token::make_TK_WORD();
1281 }
QCString left(size_t len) const
Definition qcstring.h:229
1282<St_Param>[^ \t\n,@\\‍]+ {
1283 yyextra->token.name = yytext;
1284 if (yyextra->token.name.at(static_cast<uint32_t>(yyleng)-1)==':')
1285 {
1286 yyextra->token.name=yyextra->token.name.left(static_cast<uint32_t>(yyleng)-1);
1287 }
1288 return Token::make_TK_WORD();
1289 }
1290<St_Param>{WS}*","{WS}* /* param separator */
1291<St_Param>{WS} {
1292 lineCount(yytext,yyleng);
1293 yyextra->token.chars=yytext;
1294 return Token::make_TK_WHITESPACE();
1295 }
1296<St_Prefix>"\""[^\n\"]*"\"" {
1297 yyextra->token.name = yytext+1;
1298 yyextra->token.name = yyextra->token.name.left((int)yyleng-2);
1299 return Token::make_TK_WORD();
1300 }
1301<St_Prefix>. {
1302 unput(*yytext);
1303 return Token::make_TK_NONE();
1304 }
1305<St_Options>{ID} {
1306 yyextra->token.name+=yytext;
1307 }
1308<St_Options>{WS}*":"{WS}* {
1309 lineCount(yytext,yyleng);
1310 yyextra->token.name+=":";
1311 }
1312<St_Options>{WS}*","{WS}* |
1313<St_Options>{WS} { /* option separator */
1314 lineCount(yytext,yyleng);
1315 yyextra->token.name+=",";
1316 }
1317<St_Options>"}" {
1318 return Token::make_TK_WORD();
1319 }
1320<St_Block>{ID} {
1321 yyextra->token.name+=yytext;
1322 }
1323<St_Block>"]" {
1324 return Token::make_TK_WORD();
1325 }
1326<St_Emoji>[:0-9_a-z+-]+ {
1327 yyextra->token.name=yytext;
1328 return Token::make_TK_WORD();
1329 }
1330<St_Emoji>. {
1331 unput(*yytext);
1332 return Token::make_TK_NONE();
1333 }
1334<St_QuotedString>"\"" {
1335 yyextra->token.name="";
1336 BEGIN(St_QuotedContent);
1337 }
1338<St_QuotedString>(\n|"\\ilinebr") {
1339 unput_string(yytext,yyleng);
1340 return Token::make_TK_NONE();
1341 }
1342<St_QuotedString>. {
1343 unput(*yytext);
1344 return Token::make_TK_NONE();
1345 }
1346<St_QuotedContent>"\"" {
1347 return Token::make_TK_WORD();
1348 }
1349<St_QuotedContent>. {
1350 yyextra->token.name+=yytext;
1351 }
1352<St_ShowDate>{WS}+{SHOWDATE} {
1353 lineCount(yytext,yyleng);
1354 yyextra->token.name=yytext;
1355 return Token::make_TK_WORD();
1356 }
1357<St_ShowDate>(\n|"\\ilinebr") {
1358 unput_string(yytext,yyleng);
1359 return Token::make_TK_NONE();
1360 }
1361<St_ShowDate>. {
1362 unput(*yytext);
1363 return Token::make_TK_NONE();
1364 }
1365<St_ILine>{LINENR}/[\\@\n\.] |
1366<St_ILine>{LINENR}{BLANK} {
1367 bool ok = false;
1368 int nr = QCString(yytext).toInt(&ok);
1369 if (!ok)
1370 {
1371 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
1372 }
1373 else
1374 {
1375 yyextra->yyLineNr = nr;
1376 }
1377 return Token::make_TK_WORD();
1378 }
1379<St_ILine>. {
1380 return Token::make_TK_NONE();
1381 }
1382<St_IFile>{BLANK}*{FILEMASK} {
1383 yyextra->fileName = QCString(yytext).stripWhiteSpace();
1384 return Token::make_TK_WORD();
1385 }
1386<St_IFile>{BLANK}*"\""[^\n\"]+"\"" {
1387 QCString text(yytext);
1388 text = text.stripWhiteSpace();
1389 yyextra->fileName = text.mid(1,text.length()-2);
1390 return Token::make_TK_WORD();
1391 }
1392<St_File>{FILEMASK} {
1393 yyextra->token.name = yytext;
1394 if (yyextra->token.name.endsWith("\\ilinebr") ||yyextra->token.name.endsWith("@ilinebr"))
1395 {
1396 unput_string("\\ilinebr",8);
1397 yyextra->token.name = yyextra->token.name.left(yyleng-8);
1398 }
1399 return Token::make_TK_WORD();
1400 }
1401<St_File>"\""[^\n\"]+"\"" {
1402 QCString text(yytext);
1403 yyextra->token.name = text.mid(1,text.length()-2);
1404 return Token::make_TK_WORD();
1405 }
1406<St_Pattern>[^\\\r\n]+ {
1407 yyextra->token.name += yytext;
1408 }
1409<St_Pattern>"\\ilinebr" {
1410 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1411 return Token::make_TK_WORD();
1412 }
1413<St_Pattern>\n {
1414 lineCount(yytext,yyleng);
1415 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1416 return Token::make_TK_WORD();
1417 }
1418<St_Pattern>. {
1419 yyextra->token.name += yytext;
1420 }
1421<St_Link>{LINKMASK}|{REFWORD} {
1422 yyextra->token.name = yytext;
1423 return Token::make_TK_WORD();
1424 }
1425<St_Comment>"-->" { /* end of html comment */
1426 BEGIN(yyextra->commentState);
1427 }
1428<St_Comment>[^-]+ /* inside html comment */
1429<St_Comment>. /* inside html comment */
1430
1431 /* State for skipping title (all chars until the end of the line) */
1432
1433<St_SkipTitle>.
1434<St_SkipTitle>(\n|"\\ilinebr") {
1435 if (*yytext == '\n') unput('\n');
1436 return Token::make_TK_NONE();
1437 }
1438
1439 /* State for the pass used to find the anchors and sections */
1440
1441<St_Sections>[^\n@\<]+
1442<St_Sections>{CMD}("<"|{CMD})
1443<St_Sections>"<"{CAPTION}({WS}+{ATTRIB})*">" {
1444 lineCount(yytext,yyleng);
1445 QCString tag(yytext);
1446 int s=tag.find("id=");
1447 if (s!=-1) // command has id attribute
1448 {
1449 char c=tag[s+3];
1450 if (c=='\'' || c=='"') // valid start
1451 {
1452 int e=tag.find(c,s+4);
1453 if (e!=-1) // found matching end
1454 {
1455 yyextra->secType = SectionType::Table;
1456 yyextra->secLabel=tag.mid(s+4,e-s-4); // extract id
1457 processSection(yyscanner);
1458 }
1459 }
1460 }
1461 }
static constexpr int Table
Definition section.h:41
static void processSection(yyscan_t yyscanner)
1462<St_Sections>{CMD}"anchor"{BLANK}+ {
1463 yyextra->secType = SectionType::Anchor;
1464 BEGIN(St_SecLabel1);
1465 }
static constexpr int Anchor
Definition section.h:40
1466<St_Sections>{CMD}"ianchor"{BLANK}+ {
1467 yyextra->secType = SectionType::Anchor;
1468 BEGIN(St_SecLabel1);
1469 }
1470<St_Sections>{CMD}"section"{BLANK}+ {
1471 yyextra->secType = SectionType::Section;
1472 BEGIN(St_SecLabel2);
1473 }
static constexpr int Section
Definition section.h:33
1474<St_Sections>{CMD}"subsection"{BLANK}+ {
1475 yyextra->secType = SectionType::Subsection;
1476 BEGIN(St_SecLabel2);
1477 }
static constexpr int Subsection
Definition section.h:34
1478<St_Sections>{CMD}"subsubsection"{BLANK}+ {
1479 yyextra->secType = SectionType::Subsubsection;
1480 BEGIN(St_SecLabel2);
1481 }
static constexpr int Subsubsection
Definition section.h:35
1482<St_Sections>{CMD}"paragraph"{BLANK}+ {
1483 yyextra->secType = SectionType::Paragraph;
1484 BEGIN(St_SecLabel2);
1485 }
static constexpr int Paragraph
Definition section.h:36
1486<St_Sections>{CMD}"subparagraph"{BLANK}+ {
1487 yyextra->secType = SectionType::Subparagraph;
1488 BEGIN(St_SecLabel2);
1489 }
static constexpr int Subparagraph
Definition section.h:37
1490<St_Sections>{CMD}"subsubparagraph"{BLANK}+ {
1491 yyextra->secType = SectionType::Subsubparagraph;
1492 BEGIN(St_SecLabel2);
1493 }
static constexpr int Subsubparagraph
Definition section.h:38
1494<St_Sections>{CMD}"verbatim"/[^a-z_A-Z0-9] {
1495 yyextra->endMarker="endverbatim";
1496 BEGIN(St_SecSkip);
1497 }
1498<St_Sections>{CMD}"iverbatim"/[^a-z_A-Z0-9] {
1499 yyextra->endMarker="endiverbatim";
1500 BEGIN(St_SecSkip);
1501 }
1502<St_Sections>{CMD}"iliteral"/[^a-z_A-Z0-9] {
1503 yyextra->endMarker="endiliteral";
1504 BEGIN(St_SecSkip);
1505 }
1506<St_Sections>{CMD}"dot"/[^a-z_A-Z0-9] {
1507 yyextra->endMarker="enddot";
1508 BEGIN(St_SecSkip);
1509 }
1510<St_Sections>{CMD}"msc"/[^a-z_A-Z0-9] {
1511 yyextra->endMarker="endmsc";
1512 BEGIN(St_SecSkip);
1513 }
1514<St_Sections>{CMD}"startuml"/[^a-z_A-Z0-9] {
1515 yyextra->endMarker="enduml";
1516 BEGIN(St_SecSkip);
1517 }
1518<St_Sections>{CMD}"htmlonly"/[^a-z_A-Z0-9] {
1519 yyextra->endMarker="endhtmlonly";
1520 BEGIN(St_SecSkip);
1521 }
1522<St_Sections>{CMD}"latexonly"/[^a-z_A-Z0-9] {
1523 yyextra->endMarker="endlatexonly";
1524 BEGIN(St_SecSkip);
1525 }
1526<St_Sections>{CMD}"manonly"/[^a-z_A-Z0-9] {
1527 yyextra->endMarker="endmanonly";
1528 BEGIN(St_SecSkip);
1529 }
1530<St_Sections>{CMD}"rtfonly"/[^a-z_A-Z0-9] {
1531 yyextra->endMarker="endrtfonly";
1532 BEGIN(St_SecSkip);
1533 }
1534<St_Sections>{CMD}"xmlonly"/[^a-z_A-Z0-9] {
1535 yyextra->endMarker="endxmlonly";
1536 BEGIN(St_SecSkip);
1537 }
1538<St_Sections>{CMD}"docbookonly"/[^a-z_A-Z0-9] {
1539 yyextra->endMarker="enddocbookonly";
1540 BEGIN(St_SecSkip);
1541 }
1542<St_Sections>{CMD}"code"/[^a-z_A-Z0-9] {
1543 yyextra->endMarker="endcode";
1544 BEGIN(St_SecSkip);
1545 }
1546<St_Sections>{CMD}"icode"/[^a-z_A-Z0-9] {
1547 yyextra->endMarker="endicode";
1548 BEGIN(St_SecSkip);
1549 }
1550<St_Sections>"<!--" {
1551 yyextra->endMarker="-->";
1552 BEGIN(St_SecSkip);
1553 }
1554<St_SecSkip>{CMD}{ID} {
1555 if (yyextra->endMarker==yytext+1)
1556 {
1557 BEGIN(St_Sections);
1558 }
1559 }
1560<St_SecSkip>"-->" {
1561 if (yyextra->endMarker==yytext)
1562 {
1563 BEGIN(St_Sections);
1564 }
1565 }
1566<St_SecSkip>[^a-z_A-Z0-9\-\\\@]+
1567<St_SecSkip>.
1568<St_SecSkip>(\n|"\\ilinebr")
1569<St_Sections>.
1570<St_Sections>(\n|"\\ilinebr")
1571<St_SecLabel1>({REQID}|{LABELID}) {
1572 lineCount(yytext,yyleng);
1573 yyextra->secLabel = yytext;
1574 processSection(yyscanner);
1575 BEGIN(St_Sections);
1576 }
1577<St_SecLabel2>({REQID}|{LABELID}){BLANK}+ |
1578<St_SecLabel2>({REQID}|{LABELID}) {
1579 yyextra->secLabel = yytext;
1580 yyextra->secLabel = yyextra->secLabel.stripWhiteSpace();
1581 BEGIN(St_SecTitle);
1582 }
1583<St_SecTitle>[^\n]+ |
1584<St_SecTitle>[^\n]*\n {
1585 lineCount(yytext,yyleng);
1586 yyextra->secTitle = yytext;
1587 yyextra->secTitle = yyextra->secTitle.stripWhiteSpace();
1588 if (yyextra->secTitle.endsWith("\\ilinebr"))
1589 {
1590 yyextra->secTitle.left(yyextra->secTitle.length()-8);
1591 }
1592 processSection(yyscanner);
1593 BEGIN(St_Sections);
1594 }
1595<St_SecTitle,St_SecLabel1,St_SecLabel2>. {
1596 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected character '{}' while looking for section label or title",yytext);
1597 }
1598
1599<St_Snippet>[^\\\n]+ {
1600 yyextra->token.name += yytext;
1601 }
1602<St_Snippet>"\\" {
1603 yyextra->token.name += yytext;
1604 }
1605<St_Snippet>(\n|"\\ilinebr") {
1606 unput_string(yytext,yyleng);
1607 yyextra->token.name = yyextra->token.name.stripWhiteSpace();
1608 return Token::make_TK_WORD();
1609 }
1610
1611 /* Generic rules that work for all states */
1612<*>\n {
1613 lineCount(yytext,yyleng);
1614 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected new line character");
1615 }
1616<*>"\\ilinebr" {
1617 }
1618<*>[\\@<>&$#%~"=] { /* unescaped special character */
1619 //warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected character '{}', assuming command \\{} was meant.",yytext,yytext);
1620 yyextra->token.name = yytext;
1621 return Token::char_to_command(yytext[0]);
1622 }
1623<*>. {
1624 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected character '{}'",yytext);
1625 }
1626%%

◆ yyread()

int yyread ( yyscan_t yyscanner,
char * buf,
int max_size )
static

Definition at line 1630 of file doctokenizer.l.

1631{
1632 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1633 int c=0;
1634 const char *p = yyextra->inputString + yyextra->inputPos;
1635 while ( c < max_size && *p ) { *buf++ = *p++; c++; }
1636 yyextra->inputPos+=c;
1637 return c;
1638}