summaryrefslogtreecommitdiffstats
path: root/src/lexscanner.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/lexscanner.l')
-rw-r--r--src/lexscanner.l1016
1 files changed, 1016 insertions, 0 deletions
diff --git a/src/lexscanner.l b/src/lexscanner.l
new file mode 100644
index 0000000..2b6b3a0
--- /dev/null
+++ b/src/lexscanner.l
@@ -0,0 +1,1016 @@
+/*****************************************************************************
+ *
+ * Copyright (C) 1997-2021 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+%option never-interactive
+%option prefix="lexscannerYY"
+%option reentrant
+%option extra-type="struct lexscannerYY_state *"
+%option noyywrap
+
+%top{
+#include <stdint.h>
+}
+
+%{
+
+/*
+ * includes
+ */
+
+#include <algorithm>
+#include <vector>
+#include <utility>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "config.h"
+#include "lexscanner.h"
+#include "entry.h"
+#include "message.h"
+#include "util.h"
+#include "scanner.h"
+
+#define YY_NO_INPUT 1
+#define YY_NO_UNISTD_H 1
+
+#define USE_STATE2STRING 0
+
+#define repeatChar(chr, cnt) std::string(cnt, chr).c_str()
+
+struct lexscannerYY_state
+{
+ COutlineParser cOutlineParser;
+ const char * inputString = 0;
+ int inputPosition = 0;
+
+ int lastContext = 0;
+ int lastCContext = 0;
+ int lastStringContext = 0;
+ int docBlockContext = 0;
+ int lastPreLineCtrlContext = 0;
+ int lastRawStringContext = 0;
+ int curlyCount = 0;
+
+ bool insideCode = FALSE;
+ QCString delimiter;
+ QCString docBlockName;
+ uint fencedSize = 0;
+ bool nestedComment = false;
+
+ QCString prefix = "yy";
+ bool reentrant = false;
+ bool bison_bridge = false;
+ bool bison_locations = false;
+ QCString cCodeBuffer;
+ int roundCount = 0;
+
+ QCString yyFileName;
+ ClangTUParser *clangParser = 0;
+
+ std::shared_ptr<Entry> current;
+ std::shared_ptr<Entry> current_root;
+ SrcLangExt language;
+};
+
+#if USE_STATE2STRING
+static const char *stateToString(int state);
+#endif
+//-----------------------------------------------------------------------------
+
+// forward declarations for statefull functions
+static void handleCCode(yyscan_t yyscanner);
+static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
+
+/* ----------------------------------------------------------------- */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
+
+%}
+
+nl (\r\n|\r|\n)
+ws [ \t]
+nws [^ \t\n]
+TopStart "%top{"{nl}
+TopEnd "}"{nl}
+LiteralStart "%{"{nl}
+LiteralEnd "%}"{nl}
+Option "%option"
+RulesStart "%%"{nl}
+RulesEnd "%%"{nl}
+RulesSharp "<"[^>\n]*">"
+RulesCurly "{"[^{}\n]*"}"
+StartSquare "["
+StartDouble "\""
+StartRound "("
+StartRoundQuest "(?"
+EscapeRulesCharOpen "\\["|"\\<"|"\\{"|"\\("|"\\\""|"\\ "|"\\\\"
+EscapeRulesCharClose "\\]"|"\\>"|"\\}"|"\\)"
+EscapeRulesChar {EscapeRulesCharOpen}|{EscapeRulesCharClose}
+
+CMD ("\\"|"@")
+BN [ \t\n\r]
+BL [ \t\r]*"\n"
+B [ \t]
+Bopt {B}*
+ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+PRE [pP][rR][eE]
+CODE [cC][oO][dD][eE]
+RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
+RAWEND ")"[^ \t\(\)\\]{0,16}\"
+CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
+CHARCE "[:"[^:]*":]"
+ /* no comment start / end signs inside square brackets */
+NCOMM [^/\*]
+ // C start comment
+CCS "/\*"
+ // C end comment
+CCE "*\/"
+ // Cpp comment
+CPPC "/\/"
+ // doxygen start comment
+DCOMM ("/\*!"|"/\**"|"/\/!"|"/\/\/")
+
+ // Optional any character
+ANYopt .*
+ // Optional all but newline
+NONLopt [^\n]*
+
+%x DefSection
+%x Option
+%x OptPrefix
+%x DefSectionLine
+%x RulesSectionInit
+%x RulesPattern
+%x RulesDouble
+%x RulesRoundDouble
+%x RulesSquare
+%x RulesRoundSquare
+%x RulesRound
+%x RulesRoundQuest
+%x UserSection
+
+%x TopSection
+%x LiteralSection
+
+%x COMMENT
+
+%x SkipCurly
+%x SkipCurlyEndDoc
+%x PreLineCtrl
+%x DocLine
+%x DocBlock
+%x DocCopyBlock
+%x SkipString
+%x RawString
+%x SkipComment
+%x SkipCxxComment
+%x Comment
+
+%%
+
+<*>\x0d
+<DefSection>{Option} {
+ BEGIN (Option);
+ }
+<Option>"prefix"{ws}*"="{ws}* {
+ BEGIN (OptPrefix);
+ }
+<OptPrefix>"\""[^\"]*"\"" {
+ yyextra->prefix = yytext;
+ yyextra->prefix = yyextra->prefix.mid(1,yyleng-2);
+ BEGIN (Option);
+ }
+<Option>"reentrant" {
+ yyextra-> reentrant = true;
+ }
+<Option>"bison-bridge" {
+ yyextra-> bison_bridge = true;
+ }
+<Option>"bison-locations" {
+ yyextra-> bison_bridge = true;
+ yyextra-> bison_locations = true;
+ }
+<Option>{nws}+
+<Option>{ws}+
+<Option>{nl} {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN (DefSection);
+ }
+<DefSection>^{RulesStart} {
+ {
+ bool fill = false;
+ yyextra->cCodeBuffer += "int " + yyextra->prefix + "lex (";
+ if (yyextra->bison_bridge )
+ {
+ if (fill) yyextra->cCodeBuffer += ",";
+ yyextra->cCodeBuffer += "YYSTYPE * yylval_param";
+ fill = true;
+ }
+ if (yyextra->bison_locations)
+ {
+ if (fill) yyextra->cCodeBuffer += ",";
+ yyextra->cCodeBuffer += "YYLTYPE * yylloc_param";
+ fill = true;
+ }
+ if (yyextra->reentrant)
+ {
+ if (fill) yyextra->cCodeBuffer += ",";
+ yyextra->cCodeBuffer += "yyscan_t yyscanner";
+ fill = true;
+ }
+ if (!yyextra->bison_bridge && !yyextra->bison_locations && !yyextra->reentrant)
+ {
+ yyextra->cCodeBuffer += "void";
+ }
+ yyextra->cCodeBuffer += ") {\n";
+ }
+ BEGIN (RulesSectionInit);
+ }
+<DefSection>^{TopStart} {
+ yyextra->cCodeBuffer += "\n";
+ yyextra->lastContext = YY_START;
+ BEGIN (TopSection);
+ }
+<DefSection>^{LiteralStart} {
+ yyextra->cCodeBuffer += "\n";
+ yyextra->lastContext = YY_START;
+ BEGIN (LiteralSection);
+ }
+<TopSection>^{TopEnd} {
+ yyextra->cCodeBuffer += "\n";
+ BEGIN( yyextra->lastContext ) ;
+ }
+<TopSection>.*{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<LiteralSection>^{LiteralEnd} {
+ yyextra->cCodeBuffer += "\n";
+ BEGIN( yyextra->lastContext ) ;
+ }
+<LiteralSection>.*{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<DefSection>^{nws} {
+ BEGIN(DefSectionLine);
+ }
+<DefSection>{CPPC}.*{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<DefSection>^{ws}*{CCS} {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(COMMENT);
+ }
+<COMMENT>{CCE}{ws}*{nl} {
+ yyextra->cCodeBuffer+=yytext;
+ BEGIN(yyextra->lastContext);
+ }
+<COMMENT>{CCE} {
+ yyextra->cCodeBuffer+=yytext;
+ BEGIN(yyextra->lastContext);
+ }
+<COMMENT>[^*\n]+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+<COMMENT>{CPPC}|{CCS} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<COMMENT>{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<COMMENT>. {
+ yyextra->cCodeBuffer += yytext;
+ }
+<DefSection>^{nl} {
+ yyextra->cCodeBuffer += "\n";
+ }
+<DefSection>^{ws}.*{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<DefSectionLine>.*{nl} {
+ yyextra->cCodeBuffer += "\n";
+ BEGIN(DefSection);
+ }
+<RulesSectionInit,RulesPattern>^{RulesEnd} {
+ yyextra->cCodeBuffer += "}\n";
+ BEGIN (UserSection);
+ }
+<RulesSectionInit>^{nws} {
+ unput(*yytext);
+ BEGIN(RulesPattern);
+ }
+<RulesSectionInit>^{ws}.*{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<RulesSectionInit>^{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<RulesPattern>"<<EOF>>" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{EscapeRulesChar} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{RulesSharp} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{RulesCurly} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{StartDouble} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesDouble);
+ }
+<RulesDouble,RulesRoundDouble>"\\\\" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesDouble,RulesRoundDouble>"\\\"" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesDouble>"\"" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN( yyextra->lastContext ) ;
+ }
+<RulesRoundDouble>"\"" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesRound) ;
+ }
+<RulesDouble,RulesRoundDouble>. {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{StartSquare} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesSquare);
+ }
+<RulesSquare,RulesRoundSquare>{CHARCE} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesSquare,RulesRoundSquare>"\\[" |
+<RulesSquare,RulesRoundSquare>"\\]" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesSquare>"]" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesPattern);
+ }
+<RulesRoundSquare>"]" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesRound) ;
+ }
+<RulesSquare,RulesRoundSquare>"\\\\" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesSquare,RulesRoundSquare>. {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{StartRoundQuest} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesRoundQuest);
+ }
+<RulesRoundQuest>{nl} {
+ yyextra->cCodeBuffer += "\n";
+ }
+<RulesRoundQuest>[^)] {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesRoundQuest>")" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(yyextra->lastContext);
+ }
+<RulesPattern>{StartRound} {
+ yyextra->roundCount++;
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesRound);
+ }
+<RulesRound>{RulesCurly} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesRound>{StartSquare} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesRoundSquare);
+ }
+<RulesRound>{StartDouble} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesRoundDouble);
+ }
+<RulesRound>{EscapeRulesChar} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesRound>"(" {
+ yyextra->roundCount++;
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesRound>")" {
+ yyextra->roundCount--;
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ if (!yyextra->roundCount) BEGIN( yyextra->lastContext ) ;
+ }
+<RulesRound>{nl} {
+ yyextra->cCodeBuffer += "\n";
+ }
+<RulesRound>{ws} {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesRound>. {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{ws}+"|" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->curlyCount = 0;
+ BEGIN(SkipCurly);
+ }
+<RulesPattern>^{ws}*{nl} {
+ yyextra->cCodeBuffer += "\n";
+ }
+<RulesPattern>^{ws}+ {
+ }
+
+<RulesPattern>({ws}|{nl}) {
+ unput(*yytext);
+ yyextra->curlyCount = 0;
+ BEGIN(SkipCurly);
+ }
+<RulesPattern>"\\\\" {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{CCS} {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(COMMENT);
+ }
+<RulesPattern>. {
+ yyextra->cCodeBuffer += repeatChar(' ', yyleng);
+ }
+<SkipCurly>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastPreLineCtrlContext = YY_START;
+ BEGIN( PreLineCtrl );
+ }
+<PreLineCtrl>"\""[^\n\"]*"\"" {
+ yyextra->cCodeBuffer += yytext;
+ }
+<PreLineCtrl>. {
+ yyextra->cCodeBuffer += yytext;
+ }
+<PreLineCtrl>\n {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->lastPreLineCtrlContext );
+ }
+<SkipCurly>"{" {
+ yyextra->cCodeBuffer += yytext;
+ ++yyextra->curlyCount ;
+ }
+<SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */
+<SkipCurly>"}" {
+ yyextra->cCodeBuffer += yytext;
+ if( yyextra->curlyCount )
+ {
+ --yyextra->curlyCount ;
+ }
+ }
+<SkipCurly>"}"{BN}*{DCOMM}"<" {
+ yyextra->cCodeBuffer += yytext;
+ if ( yyextra->curlyCount )
+ {
+ --yyextra->curlyCount ;
+ }
+ else
+ {
+ yyextra->docBlockContext = SkipCurlyEndDoc;
+ if (yytext[yyleng-3]=='/')
+ {
+ BEGIN( DocLine );
+ }
+ else
+ {
+ BEGIN( DocBlock );
+ }
+ }
+ }
+<SkipCurly>\" {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastStringContext=SkipCurly;
+ BEGIN( SkipString );
+ }
+<SkipCurly>^{B}*"#" {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastPreLineCtrlContext = YY_START;
+ BEGIN( PreLineCtrl );
+ }
+<SkipCurly>{B}*{RAWBEGIN} {
+ QCString raw=QCString(yytext).stripWhiteSpace();
+ yyextra->delimiter = raw.mid(2);
+ yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
+ yyextra->lastRawStringContext = YY_START;
+ yyextra->cCodeBuffer += yytext;
+ BEGIN(RawString);
+ }
+<SkipCurly>[^\n#"'@\\/{}<]+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCurly>{CCS} {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastCContext = YY_START;
+ BEGIN(SkipComment);
+ }
+<SkipCurly>{CPPC} {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->lastCContext = YY_START;
+ BEGIN(SkipCxxComment);
+ }
+<SkipCurly>{CHARLIT} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCurly>\' {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCurly>. {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCurly>({CPPC}{B}*)?{CCS}"!" {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+<SkipCurly>{CCS}"*"[*]+{BL} {
+ bool javadocBanner = Config_getBool(JAVADOC_BANNER);
+ yyextra->cCodeBuffer += yytext;
+ if( javadocBanner )
+ {
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+ else
+ {
+ BEGIN( Comment ) ;
+ }
+ }
+<SkipCurly>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+<SkipCurly>{CPPC}"!" {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocLine );
+ }
+<SkipCurly>{CPPC}"/"/[^/] {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocLine );
+ }
+
+<SkipCurly>\n {
+ yyextra->cCodeBuffer += yytext;
+ if (yyextra->curlyCount<=0)
+ {
+ BEGIN(RulesPattern);
+ }
+ }
+<SkipString>\\. {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipString>\" {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->lastStringContext );
+ }
+<SkipString>{CCS}|{CCE}|{CPPC} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipString>\n {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipString>. {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCxxComment>.*"\\\n" { // line continuation
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCxxComment>{ANYopt}/\n {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->lastCContext ) ;
+ }
+<Comment>{BN}+ {
+ yyextra->cCodeBuffer += yytext ;
+ }
+<Comment>{CCS} { yyextra->cCodeBuffer += yytext ; }
+<Comment>{CPPC} { yyextra->cCodeBuffer += yytext ; }
+<Comment>{CMD}("code"|"verbatim") {
+ yyextra->insideCode=TRUE;
+ yyextra->cCodeBuffer += yytext ;
+ }
+<Comment>{CMD}("endcode"|"endverbatim") {
+ yyextra->insideCode=FALSE;
+ yyextra->cCodeBuffer += yytext ;
+ }
+<Comment>[^ \.\t\r\n\/\*]+ { yyextra->cCodeBuffer += yytext ; }
+<Comment>{CCE} { yyextra->cCodeBuffer += yytext ;
+ if (!yyextra->insideCode) BEGIN( yyextra->lastContext ) ;
+ }
+<Comment>. { yyextra->cCodeBuffer += *yytext ; }
+
+<SkipComment>{CPPC}|{CCS} {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipComment>[^\*\n]+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipComment>\n {
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipComment>{B}*{CCE} {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->lastCContext );
+ }
+<SkipComment>"*" {
+ yyextra->cCodeBuffer += yytext;
+ }
+<RawString>{RAWEND} {
+ yyextra->cCodeBuffer += yytext;
+ QCString delimiter = yytext+1;
+ delimiter=delimiter.left(delimiter.length()-1);
+ if (delimiter==yyextra->delimiter)
+ {
+ BEGIN(yyextra->lastRawStringContext);
+ }
+ }
+<RawString>[^)\n]+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+<RawString>. {
+ yyextra->cCodeBuffer += yytext;
+ }
+<RawString>\n {
+ yyextra->cCodeBuffer += yytext;
+ }
+
+
+ /* ---- Single line comments ------ */
+<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+<DocLine>{NONLopt}/"\n" { // whole line
+ yyextra->cCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+
+ /* ---- Comments blocks ------ */
+
+<DocBlock>"*"*{CCE} { // end of comment block
+ yyextra->cCodeBuffer += yytext;
+ BEGIN(yyextra->docBlockContext);
+ }
+<DocBlock>^{B}*"*"+/[^/] {
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>{CPPC} { // slashes in the middle of a comment block
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>{CCS} { // start of a new comment in the
+ // middle of a comment block
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockName=&yytext[1];
+ if (yyextra->docBlockName.at(1)=='{')
+ {
+ yyextra->docBlockName.at(1)='}';
+ }
+ yyextra->fencedSize=0;
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{B}*"<"{PRE}">" {
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockName="<pre>";
+ yyextra->fencedSize=0;
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
+ yyextra->cCodeBuffer += yytext;
+ yyextra->docBlockName=&yytext[1];
+ yyextra->fencedSize=0;
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
+ yyextra->cCodeBuffer += yytext;
+ QCString pat = substitute(yytext,"*"," ");
+ yyextra->docBlockName="~~~";
+ yyextra->fencedSize=pat.stripWhiteSpace().length();
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
+ yyextra->cCodeBuffer += yytext;
+ QCString pat = substitute(yytext,"*"," ");
+ yyextra->docBlockName="```";
+ yyextra->fencedSize=pat.stripWhiteSpace().length();
+ yyextra->nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{B}*"<code>" {
+ REJECT;
+ }
+<DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>\n { // newline
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocBlock>. { // command block
+ yyextra->cCodeBuffer += yytext;
+ }
+ /* ---- Copy verbatim sections ------ */
+
+<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
+ yyextra->cCodeBuffer += yytext;
+ if (yyextra->docBlockName=="<pre>")
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
+ yyextra->cCodeBuffer += yytext;
+ if (yyextra->docBlockName=="<code>")
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN(DocBlock);
+ }
+<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+ yyextra->cCodeBuffer += yytext;
+ if (&yytext[4]==yyextra->docBlockName)
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
+ yyextra->cCodeBuffer += yytext;
+ if (yyextra->docBlockName=="verbatim")
+ {
+ REJECT;
+ }
+ else if (yyextra->docBlockName=="code")
+ {
+ REJECT;
+ }
+ else
+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
+ if (yyextra->docBlockName=="code")
+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
+ if (yyextra->docBlockName=="code")
+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
+ if (yyextra->docBlockName=="code")
+ {
+ if (yyextra->nestedComment) // keep * it is part of the code
+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+ else // remove * it is part of the comment block
+ {
+ yyextra->cCodeBuffer += yytext;
+ }
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
+ yyextra->cCodeBuffer += yytext;
+ QCString pat = substitute(yytext,"*"," ");
+ if (yyextra->fencedSize==pat.stripWhiteSpace().length())
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
+ yyextra->cCodeBuffer += yytext;
+ QCString pat = substitute(yytext,"*"," ");
+ if (yyextra->fencedSize==pat.stripWhiteSpace().length())
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>[^\<@/\*\]~\$\\\n]+ { // any character that is not special
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
+ if (yytext[1]=='*')
+ {
+ yyextra->nestedComment=TRUE;
+ }
+ else if (yytext[0]=='*')
+ {
+ yyextra->nestedComment=FALSE;
+ }
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocCopyBlock>\n { // newline
+ yyextra->cCodeBuffer += yytext;
+ }
+<DocCopyBlock>. { // any other character
+ yyextra->cCodeBuffer += yytext;
+ }
+<SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
+ yyextra->docBlockContext = SkipCurlyEndDoc;
+ yyextra->cCodeBuffer += yytext;
+ if (yytext[yyleng-3]=='/')
+ {
+ BEGIN( DocLine );
+ }
+ else
+ {
+ BEGIN( DocBlock );
+ }
+ }
+<SkipCurlyEndDoc>"}" {
+ yyextra->cCodeBuffer += yytext;
+ BEGIN(SkipCurly);
+ }
+
+<UserSection>.*{nl} {
+ yyextra->cCodeBuffer += yytext;
+ }
+
+
+ /*
+<*>. { fprintf(stderr,"Lex scanner Def rule for %s: #%s#\n",stateToString(YY_START),yytext);}
+<*>{nl} { fprintf(stderr,"Lex scanner Def rule for newline %s: #%s#\n",stateToString(YY_START),yytext);}
+ */
+<*><<EOF>> {
+ handleCCode(yyscanner);
+ yyterminate();
+ }
+%%
+
+//----------------------------------------------------------------------------
+static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ yy_size_t c=0;
+ while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
+ {
+ *buf = yyextra->inputString[yyextra->inputPosition++] ;
+ //printf("%d (%c)\n",*buf,*buf);
+ c++; buf++;
+ }
+ return c;
+}
+
+//-----------------------------------------------------------------------------
+
+static void parseMain(yyscan_t yyscanner,
+ const QCString &fileName,
+ const char *fileBuf,
+ const std::shared_ptr<Entry> &rt,
+ ClangTUParser *clangParser)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+
+ yyextra->inputString = fileBuf;
+ yyextra->inputPosition = 0;
+ lexscannerYYrestart(0,yyscanner);
+
+ yyextra->current_root = rt;
+ yyextra->yyFileName = fileName;
+ yyextra->clangParser = clangParser;
+ yyextra->language = getLanguageFromFileName(yyextra->yyFileName);
+ rt->lang = yyextra->language;
+ msg("Parsing file %s...\n",qPrint(yyextra->yyFileName));
+
+ yyextra->current_root = rt;
+ yyextra->current = std::make_shared<Entry>();
+ int sec=guessSection(yyextra->yyFileName);
+ if (sec)
+ {
+ yyextra->current->name = yyextra->yyFileName;
+ yyextra->current->section = sec;
+ yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
+ }
+ yyextra->current->reset();
+ BEGIN( DefSection );
+
+ lexscannerYYlex(yyscanner);
+
+ rt->program.str(std::string());
+}
+
+//----------------------------------------------------------------------------
+
+
+static void handleCCode(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+
+ if (yyextra->cCodeBuffer.isEmpty()) return;
+ yyextra->cOutlineParser.parseInput(yyextra->yyFileName,
+ yyextra->cCodeBuffer.data(),
+ yyextra->current_root,
+ yyextra->clangParser);
+ yyextra->cCodeBuffer.resize(0);
+ return;
+}
+//----------------------------------------------------------------------------
+
+struct LexOutlineParser::Private
+{
+ yyscan_t yyscanner;
+ lexscannerYY_state state;
+};
+
+LexOutlineParser::LexOutlineParser() : p(std::make_unique<LexOutlineParser::Private>())
+{
+ lexscannerYYlex_init_extra(&p->state,&p->yyscanner);
+#ifdef FLEX_DEBUG
+ lexscannerYYset_debug(1,p->yyscanner);
+#endif
+}
+
+LexOutlineParser::~LexOutlineParser()
+{
+ lexscannerYYlex_destroy(p->yyscanner);
+}
+
+void LexOutlineParser::parseInput(const QCString &fileName,
+ const char *fileBuf,
+ const std::shared_ptr<Entry> &root,
+ ClangTUParser *clangParser)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
+
+ printlex(yy_flex_debug, TRUE, __FILE__, qPrint(fileName));
+
+ ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
+
+ printlex(yy_flex_debug, FALSE, __FILE__, qPrint(fileName));
+}
+
+
+//----------------------------------------------------------------------------
+
+#if USE_STATE2STRING
+#include "lexscanner.l.h"
+#endif