summaryrefslogtreecommitdiff
path: root/src/xmlcode.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmlcode.l')
-rw-r--r--src/xmlcode.l608
1 files changed, 321 insertions, 287 deletions
diff --git a/src/xmlcode.l b/src/xmlcode.l
index b583bf5..c7322cb 100644
--- a/src/xmlcode.l
+++ b/src/xmlcode.l
@@ -1,10 +1,10 @@
/******************************************************************************
*
- * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ * Copyright (C) 1997-2020 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
+ * 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.
*
@@ -19,6 +19,11 @@
%option never-interactive
%option prefix="xmlcodeYY"
+%option reentrant
+%option extra-type="struct xmlcodeYY_state *"
+%option noyy_top_state
+%option nounput
+%option noyywrap
%top{
#include <stdint.h>
}
@@ -44,401 +49,430 @@
#define YY_NO_INPUT 1
#define YY_NO_UNISTD_H 1
-static CodeOutputInterface * g_code;
-static QCString g_curClassName;
-static QCString g_parmType;
-static QCString g_parmName;
-static const char * g_inputString; //!< the code fragment as text
-static int g_inputPosition; //!< read offset during parsing
-static int g_inputLines; //!< number of line in the code fragment
-static int g_yyLineNr; //!< current line number
-static bool g_needsTermination;
-static const Definition *g_searchCtx;
-
-static bool g_exampleBlock;
-static QCString g_exampleName;
-static QCString g_exampleFile;
-
-static QCString g_type;
-static QCString g_name;
-static QCString g_args;
-static QCString g_classScope;
-
-static QCString g_CurrScope;
-
-static FileDef * g_sourceFileDef;
-static Definition * g_currentDefinition;
-static MemberDef * g_currentMemberDef;
-static bool g_includeCodeFragment;
-static const char * g_currentFontClass;
+struct xmlcodeYY_state
+{
+ CodeOutputInterface * code;
+ QCString curClassName;
+ QCString parmType;
+ QCString parmName;
+ const char * inputString = 0; //!< the code fragment as text
+ yy_size_t inputPosition = 0; //!< read offset during parsing
+ int inputLines = 0; //!< number of line in the code fragment
+ int yyLineNr = 0; //!< current line number
+ bool needsTermination = false;
+ const Definition *searchCtx = 0;
+
+ bool exampleBlock = false;
+ QCString exampleName;
+ QCString exampleFile;
+
+ QCString type;
+ QCString name;
+ QCString args;
+ QCString classScope;
+
+ QCString CurrScope;
+
+ const FileDef * sourceFileDef = 0;
+ const Definition * currentDefinition = 0;
+ const MemberDef * currentMemberDef = 0;
+ bool includeCodeFragment = false;
+ const char * currentFontClass = 0;
+};
#if USE_STATE2STRING
static const char *stateToString(int state);
#endif
-static void codify(const char* text)
-{
- g_code->codify(text);
+static void codify(yyscan_t yyscanner,const char* text);
+static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor);
+static void startCodeLine(yyscan_t yyscanner);
+static void endFontClass(yyscan_t yyscanner);
+static void endCodeLine(yyscan_t yyscanner);
+static void nextCodeLine(yyscan_t yyscanner);
+static void codifyLines(yyscan_t yyscanner,const char *text);
+static void startFontClass(yyscan_t yyscanner,const char *s);
+static int countLines(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]+
+open "<"
+close ">"
+namestart [A-Za-z\200-\377_]
+namechar [:A-Za-z\200-\377_0-9.-]
+esc "&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";"
+name {namestart}{namechar}*
+comment {open}"!--"([^-]|"-"[^-])*"--"{close}
+data "random string"
+string \"([^"&]|{esc})*\"|\'([^'&]|{esc})*\'
+
+%option noyywrap
+%option nounput
+
+%%
+
+<INITIAL>{ws} {
+ codifyLines(yyscanner,yytext);
+ }
+<INITIAL>"/" {
+ endFontClass(yyscanner);
+ codify(yyscanner,yytext);
+ }
+<INITIAL>"=" {
+ endFontClass(yyscanner);
+ codify(yyscanner,yytext);
+ }
+<INITIAL>{close} {
+ endFontClass(yyscanner);
+ codify(yyscanner,yytext);
+ }
+<INITIAL>{name} {
+ startFontClass(yyscanner,"keyword");
+ codify(yyscanner,yytext);
+ endFontClass(yyscanner);
+ }
+<INITIAL>{string} {
+ startFontClass(yyscanner,"stringliteral");
+ codifyLines(yyscanner,yytext);
+ endFontClass(yyscanner);
+ }
+
+{open}{ws}?{name} {
+ // Write the < in a different color
+ char openBracket[] = { yytext[0], '\0' };
+ codify(yyscanner,openBracket);
+
+ // Then write the rest
+ yytext++;
+ startFontClass(yyscanner,"keywordtype");
+ codify(yyscanner,yytext);
+ endFontClass(yyscanner);
+
+ BEGIN(INITIAL);
+ }
+{open}{ws}?"/"{name} {
+ // Write the "</" in a different color
+ char closeBracket[] = { yytext[0], yytext[1], '\0' };
+ endFontClass(yyscanner);
+ codify(yyscanner,closeBracket);
+
+ // Then write the rest
+ yytext++; // skip the '<'
+ yytext++; // skip the '/'
+ startFontClass(yyscanner,"keywordtype");
+ codify(yyscanner,yytext);
+ endFontClass(yyscanner);
+
+ BEGIN(INITIAL);
+ }
+{comment} {
+ // Strip off the extra '!'
+ // yytext++; // <
+ // *yytext = '<'; // replace '!' with '<'
+
+ startFontClass(yyscanner,"comment");
+ codifyLines(yyscanner,yytext);
+ endFontClass(yyscanner);
+ }
+{nl} {
+ codifyLines(yyscanner,yytext);
+ }
+
+. {
+ //printf("!ERROR(%c)\n", *yytext);
+ codifyLines(yyscanner,yytext);
+ }
+
+%%
+
+//----------------------------------------------------------------------------------------
+
+static yy_size_t yyread(yyscan_t yyscanner,char *buf,size_t max_size)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ yy_size_t inputPosition = yyextra->inputPosition;
+ const char *s = yyextra->inputString + inputPosition;
+ yy_size_t c=0;
+ while( c < max_size && *s)
+ {
+ *buf++ = *s++;
+ c++;
+ }
+ yyextra->inputPosition += c;
+ return c;
+}
+
+static void codify(yyscan_t yyscanner,const char* text)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ yyextra->code->codify(text);
}
-static void setCurrentDoc(const QCString &anchor)
+static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (Doxygen::searchIndex)
{
- if (g_searchCtx)
+ if (yyextra->searchCtx)
{
- Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
+ yyextra->code->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),false);
}
else
{
- Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
+ yyextra->code->setCurrentDoc(yyextra->sourceFileDef,anchor,true);
}
}
}
-/*! start a new line of code, inserting a line number if g_sourceFileDef
- * is TRUE. If a definition starts at the current line, then the line
+/*! start a new line of code, inserting a line number if yyextra->sourceFileDef
+ * is true. If a definition starts at the current line, then the line
* number is linked to the documentation of that definition.
*/
-static void startCodeLine()
+static void startCodeLine(yyscan_t yyscanner)
{
- if (g_sourceFileDef)
- {
- Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
-
- if (!g_includeCodeFragment && d && d->isLinkableInProject())
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->sourceFileDef)
+ {
+ Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+
+ if (!yyextra->includeCodeFragment && d && d->isLinkableInProject())
{
- g_currentDefinition = d;
- g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
- //g_insideBody = FALSE;
- g_classScope = d->name().copy();
+ yyextra->currentDefinition = d;
+ yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
+ //yyextra->insideBody = false;
+ yyextra->classScope = d->name().copy();
QCString lineAnchor;
- lineAnchor.sprintf("l%05d",g_yyLineNr);
- if (g_currentMemberDef)
+ lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
+ if (yyextra->currentMemberDef)
{
- g_code->writeLineNumber(g_currentMemberDef->getReference(),
- g_currentMemberDef->getOutputFileBase(),
- g_currentMemberDef->anchor(),g_yyLineNr);
- setCurrentDoc(lineAnchor);
+ yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
+ yyextra->currentMemberDef->getOutputFileBase(),
+ yyextra->currentMemberDef->anchor(),yyextra->yyLineNr);
+ setCurrentDoc(yyscanner,lineAnchor);
}
else
{
- g_code->writeLineNumber(d->getReference(),
+ yyextra->code->writeLineNumber(d->getReference(),
d->getOutputFileBase(),
- 0,g_yyLineNr);
- setCurrentDoc(lineAnchor);
+ 0,yyextra->yyLineNr);
+ setCurrentDoc(yyscanner,lineAnchor);
}
}
else
{
- g_code->writeLineNumber(0,0,0,g_yyLineNr);
+ yyextra->code->writeLineNumber(0,0,0,yyextra->yyLineNr);
}
}
-
- g_code->startCodeLine(g_sourceFileDef);
-
- if (g_currentFontClass)
+
+ yyextra->code->startCodeLine(yyextra->sourceFileDef);
+
+ if (yyextra->currentFontClass)
{
- g_code->startFontClass(g_currentFontClass);
+ yyextra->code->startFontClass(yyextra->currentFontClass);
}
}
-static void endFontClass()
+static void endFontClass(yyscan_t yyscanner)
{
- if (g_currentFontClass)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->currentFontClass)
{
- g_code->endFontClass();
- g_currentFontClass=0;
+ yyextra->code->endFontClass();
+ yyextra->currentFontClass=0;
}
}
-static void endCodeLine()
+static void endCodeLine(yyscan_t yyscanner)
{
- endFontClass();
- g_code->endCodeLine();
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ endFontClass(yyscanner);
+ yyextra->code->endCodeLine();
}
-static void nextCodeLine()
+static void nextCodeLine(yyscan_t yyscanner)
{
- const char *fc = g_currentFontClass;
- endCodeLine();
- if (g_yyLineNr<g_inputLines)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ const char *fc = yyextra->currentFontClass;
+ endCodeLine(yyscanner);
+ if (yyextra->yyLineNr<yyextra->inputLines)
{
- g_currentFontClass = fc;
- startCodeLine();
+ yyextra->currentFontClass = fc;
+ startCodeLine(yyscanner);
}
}
-static void codifyLines(char *text)
+static void codifyLines(yyscan_t yyscanner,const char *text)
{
- char *p=text,*sp=p;
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ const char *p=text,*sp=p;
char c;
- bool done=FALSE;
-
+ bool done=false;
while (!done)
{
sp=p;
-
while ((c=*p++) && c!='\n') { }
-
if (c=='\n')
{
- g_yyLineNr++;
- *(p-1)='\0';
- g_code->codify(sp);
- nextCodeLine();
+ yyextra->yyLineNr++;
+ int l = (int)(p-sp-1);
+ char *tmp = (char*)malloc(l+1);
+ tmp[l]='\0';
+ yyextra->code->codify(tmp);
+ free(tmp);
+ nextCodeLine(yyscanner);
}
else
{
- g_code->codify(sp);
- done=TRUE;
+ yyextra->code->codify(sp);
+ done=true;
}
}
}
-static void startFontClass(const char *s)
+static void startFontClass(yyscan_t yyscanner,const char *s)
{
- endFontClass();
- g_code->startFontClass(s);
- g_currentFontClass=s;
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ endFontClass(yyscanner);
+ yyextra->code->startFontClass(s);
+ yyextra->currentFontClass=s;
}
/*! counts the number of lines in the input */
-static int countLines()
+static int countLines(yyscan_t yyscanner)
{
- const char *p=g_inputString;
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ const char *p=yyextra->inputString;
char c;
int count=1;
- while ((c=*p))
- {
- p++ ;
- if (c=='\n') count++;
+ while ((c=*p))
+ {
+ p++ ;
+ if (c=='\n') count++;
}
- if (p>g_inputString && *(p-1)!='\n')
+ if (p>yyextra->inputString && *(p-1)!='\n')
{ // last line does not end with a \n, so we add an extra
// line and explicitly terminate the line after parsing.
- count++,
- g_needsTermination=TRUE;
- }
+ count++,
+ yyextra->needsTermination=true;
+ }
return count;
}
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+//----------------------------------------------------------------------------------------
-static int yyread(char *buf,int max_size)
+struct XMLCodeParser::Private
{
- int c=0;
- while( c < max_size && g_inputString[g_inputPosition] )
- {
- *buf = g_inputString[g_inputPosition++] ;
- c++; buf++;
- }
- return c;
-}
-
-%}
+ yyscan_t yyscanner;
+ xmlcodeYY_state state;
+};
-nl (\r\n|\r|\n)
-ws [ \t]+
-open "<"
-close ">"
-namestart [A-Za-z\200-\377_]
-namechar [:A-Za-z\200-\377_0-9.-]
-esc "&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";"
-name {namestart}{namechar}*
-comment {open}"!--"([^-]|"-"[^-])*"--"{close}
-data "random string"
-string \"([^"&]|{esc})*\"|\'([^'&]|{esc})*\'
-
-%option noyywrap
-%option nounput
+XMLCodeParser::XMLCodeParser() : p(std::make_unique<Private>())
+{
+ xmlcodeYYlex_init_extra(&p->state,&p->yyscanner);
+#ifdef FLEX_DEBUG
+ xmlcodeYYset_debug(1,yyscanner);
+#endif
+ resetCodeParserState();
+}
-%%
+XMLCodeParser::~XMLCodeParser()
+{
+ xmlcodeYYlex_destroy(p->yyscanner);
+}
-<INITIAL>{ws} {
- codifyLines(yytext);
- }
-<INITIAL>"/" {
- endFontClass();
- codify(yytext);
- }
-<INITIAL>"=" {
- endFontClass();
- codify(yytext);
- }
-<INITIAL>{close} {
- endFontClass();
- codify(yytext);
- }
-<INITIAL>{name} {
- startFontClass("keyword");
- codify(yytext);
- endFontClass();
- }
-<INITIAL>{string} {
- startFontClass("stringliteral");
- codifyLines(yytext);
- endFontClass();
- }
-
-{open}{ws}?{name} {
- // Write the < in a different color
- char openBracket[] = { yytext[0], '\0' };
- codify(openBracket);
-
- // Then write the rest
- yytext++;
- startFontClass("keywordtype");
- codify(yytext);
- endFontClass();
-
- BEGIN(INITIAL);
- }
-{open}{ws}?"/"{name} {
- // Write the "</" in a different color
- char closeBracket[] = { yytext[0], yytext[1], '\0' };
- endFontClass();
- codify(closeBracket);
-
- // Then write the rest
- yytext++; // skip the '<'
- yytext++; // skip the '/'
- startFontClass("keywordtype");
- codify(yytext);
- endFontClass();
+void XMLCodeParser::resetCodeParserState()
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
+ yyextra->currentDefinition = 0;
+ yyextra->currentMemberDef = 0;
+}
- BEGIN(INITIAL);
- }
-{comment} {
- // Strip off the extra '!'
- // yytext++; // <
- // *yytext = '<'; // replace '!' with '<'
+void XMLCodeParser::parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt,
+ bool isExampleBlock,
+ const char *exampleName,
+ FileDef *fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ const MemberDef *memberDef,
+ bool showLineNumbers,
+ const Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+ yyscan_t yyscanner = p->yyscanner;
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- startFontClass("comment");
- codifyLines(yytext);
- endFontClass();
- }
-{nl} {
- codifyLines(yytext);
- }
+ if (input.isEmpty()) return;
-. {
- //printf("!ERROR(%c)\n", *yytext);
- codifyLines(yytext);
- }
+ printlex(yy_flex_debug, true, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
-%%
+ yyextra->code = &codeOutIntf;
+ yyextra->inputString = input;
+ yyextra->inputPosition = 0;
+ yyextra->currentFontClass = 0;
+ yyextra->needsTermination = false;
+ yyextra->searchCtx = searchCtx;
-void parseXmlCode(
- CodeOutputInterface &od,
- const char * /*className*/,
- const QCString &s,
- bool exBlock,
- const char *exName,
- FileDef *fd,
- int startLine,
- int endLine,
- bool inlineFragment,
- const MemberDef *,
- bool,const Definition *searchCtx,
- bool /*collectXRefs*/
- )
-{
- if (s.isEmpty()) return;
- printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
-
- g_code = &od;
- g_inputString = s;
- g_inputPosition = 0;
- g_currentFontClass = 0;
- g_needsTermination = FALSE;
- g_searchCtx=searchCtx;
-
if (startLine!=-1)
- g_yyLineNr = startLine;
+ yyextra->yyLineNr = startLine;
else
- g_yyLineNr = 1;
-
+ yyextra->yyLineNr = 1;
+
if (endLine!=-1)
- g_inputLines = endLine+1;
+ yyextra->inputLines = endLine+1;
else
- g_inputLines = g_yyLineNr + countLines() - 1;
-
- g_exampleBlock = exBlock;
- g_exampleName = exName;
- g_sourceFileDef = fd;
-
- bool cleanupSourceDef = FALSE;
-
- if (exBlock && fd==0)
+ yyextra->inputLines = yyextra->yyLineNr + countLines(yyscanner) - 1;
+
+ yyextra->exampleBlock = isExampleBlock;
+ yyextra->exampleName = exampleName;
+ yyextra->sourceFileDef = fileDef;
+
+ bool cleanupSourceDef = false;
+
+ if (isExampleBlock && fileDef==0)
{
// create a dummy filedef for the example
- g_sourceFileDef = createFileDef("",(exName?exName:"generated"));
- cleanupSourceDef = TRUE;
+ yyextra->sourceFileDef = createFileDef("",(exampleName?exampleName:"generated"));
+ cleanupSourceDef = true;
}
-
- if (g_sourceFileDef)
+
+ if (yyextra->sourceFileDef)
{
- setCurrentDoc("l00001");
+ setCurrentDoc(yyscanner,"l00001");
}
- g_includeCodeFragment = inlineFragment;
- // Starts line 1 on the output
- startCodeLine();
+ yyextra->includeCodeFragment = inlineFragment;
+ // Starts line 1 on the output
+ startCodeLine(yyscanner);
- xmlcodeYYrestart( xmlcodeYYin );
+ xmlcodeYYrestart( 0, yyscanner );
- xmlcodeYYlex();
+ xmlcodeYYlex(yyscanner);
- if (g_needsTermination)
+ if (yyextra->needsTermination)
{
- endCodeLine();
+ endCodeLine(yyscanner);
}
if (cleanupSourceDef)
{
// delete the temporary file definition used for this example
- delete g_sourceFileDef;
- g_sourceFileDef=0;
+ delete yyextra->sourceFileDef;
+ yyextra->sourceFileDef=0;
}
-
- printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
- return;
-}
-
-void resetXmlCodeParserState()
-{
- g_currentDefinition = 0;
- g_currentMemberDef = 0;
-}
-
-//----------------------------------------------------------------------------
-void XMLCodeParser::parseCode(CodeOutputInterface &codeOutIntf,
- const char *scopeName,
- const QCString &input,
- SrcLangExt,
- bool isExampleBlock,
- const char *exampleName,
- FileDef *fileDef,
- int startLine,
- int endLine,
- bool inlineFragment,
- const MemberDef *memberDef,
- bool showLineNumbers,
- const Definition *searchCtx,
- bool collectXRefs
- )
-{
- parseXmlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,
- fileDef,startLine,endLine,inlineFragment,memberDef,
- showLineNumbers,searchCtx,collectXRefs);
+ printlex(yy_flex_debug, false, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
}
-void XMLCodeParser::resetCodeParserState()
-{
- resetXmlCodeParserState();
-}
#if USE_STATE2STRING
#include "xmlcode.l.h"