summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doxyfile4
-rw-r--r--doc/features.doc2
-rw-r--r--doc/starting.doc4
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/code.h1
-rw-r--r--src/code.l14
-rw-r--r--src/config.xml3
-rw-r--r--src/context.cpp1
-rw-r--r--src/defargs.l4
-rw-r--r--src/docsets.cpp1
-rw-r--r--src/doxygen.cpp4
-rw-r--r--src/lexcode.h57
-rw-r--r--src/lexcode.l1223
-rw-r--r--src/lexscanner.h43
-rw-r--r--src/lexscanner.l938
-rw-r--r--src/memberdef.cpp11
-rw-r--r--src/pre.l275
-rw-r--r--src/scanner.l5
-rw-r--r--src/types.h3
-rw-r--r--src/util.cpp6
20 files changed, 2459 insertions, 146 deletions
diff --git a/Doxyfile b/Doxyfile
index 44eb5b5..100347b 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -106,10 +106,12 @@ WARN_LOGFILE = warnings.log
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = src \
- vhdlparser
+ vhdlparser \
+ xml
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.cpp \
+ *.l \
*.md
RECURSIVE = NO
EXCLUDE =
diff --git a/doc/features.doc b/doc/features.doc
index e746ac3..9c42d5b 100644
--- a/doc/features.doc
+++ b/doc/features.doc
@@ -28,7 +28,7 @@
output even from undocumented code.
<li>Generates structured XML output for parsed sources, which can be
used by external tools.
-<li>Supports C/C++, Java, (Corba and Microsoft) Java, Python, VHDL, PHP
+<li>Supports C/C++, Lex, Java, (Corba and Microsoft) Java, Python, VHDL, PHP
IDL, C#, Fortran, Objective-C 2.0, and to some extent D sources.
<li>Supports documentation of files, namespaces, packages, classes,
structs, unions, templates, variables, functions, typedefs, enums and
diff --git a/doc/starting.doc b/doc/starting.doc
index ad34af3..44f2a92 100644
--- a/doc/starting.doc
+++ b/doc/starting.doc
@@ -37,7 +37,7 @@ tries to be complete):
\section step0 Step 0: Check if doxygen supports your programming language
First, assure that your programming language has a reasonable chance of being
-recognized by doxygen. These languages are supported by default: C, C++, C#,
+recognized by doxygen. These languages are supported by default: C, C++, Lex, C#,
Objective-C, IDL, Java, VHDL, PHP, Python, Fortran and D. It
is possible to configure certain file type extensions to use certain parsers:
see the \ref cfg_extension_mapping "Configuration/ExtensionMappings" for details.
@@ -120,7 +120,7 @@ Extension | Language | Extension | Language | Extension | Language
.ixx |C / C++ | .php5 |PHP | .vhdl |VHDL
.ipp |C / C++ | .inc |PHP | .ucf |VHDL
.i++ |C / C++ | .phtml |PHP | .qsf |VHDL
-.inl |C / C++ | .m |Objective-C | &nbsp; |&nbsp;
+.inl |C / C++ | .m |Objective-C | .l |Lex
.h |C / C++ | .M |Objective-C | .md |Markdown
.H |C / C++ | .py |Python | .markdown |Markdown
.hh |C / C++ | .pyw |Python | .ice |Slice
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c6af813..e85d8f2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -117,6 +117,8 @@ set(LEX_FILES scanner
constexp
xmlcode
sqlcode
+ lexcode
+ lexscanner
configimpl)
# unfortunately ${LEX_FILES_H} and ${LEX_FILES_CPP} don't work in older versions of CMake (like 3.6.2) for add_library
@@ -184,6 +186,8 @@ add_library(doxymain STATIC
${GENERATED_SRC}/doctokenizer.l.h
${GENERATED_SRC}/fortrancode.l.h
${GENERATED_SRC}/fortranscanner.l.h
+ ${GENERATED_SRC}/lexcode.l.h
+ ${GENERATED_SRC}/lexscanner.l.h
${GENERATED_SRC}/pre.l.h
${GENERATED_SRC}/pycode.l.h
${GENERATED_SRC}/pyscanner.l.h
@@ -199,6 +203,8 @@ add_library(doxymain STATIC
${GENERATED_SRC}/doctokenizer.cpp
${GENERATED_SRC}/fortrancode.cpp
${GENERATED_SRC}/fortranscanner.cpp
+ ${GENERATED_SRC}/lexcode.cpp
+ ${GENERATED_SRC}/lexscanner.cpp
${GENERATED_SRC}/pre.cpp
${GENERATED_SRC}/pycode.cpp
${GENERATED_SRC}/pyscanner.cpp
diff --git a/src/code.h b/src/code.h
index 42265ad..ba24242 100644
--- a/src/code.h
+++ b/src/code.h
@@ -46,6 +46,7 @@ class CCodeParser : public CodeParserInterface
bool collectXRefs=TRUE
);
void resetCodeParserState();
+ void setStartCodeLine(const bool inp);
private:
struct Private;
std::unique_ptr<Private> p;
diff --git a/src/code.l b/src/code.l
index 233a4f0..083660b 100644
--- a/src/code.l
+++ b/src/code.l
@@ -98,6 +98,11 @@ struct codeYY_state
QCString parmType;
QCString parmName;
+ bool beginCodeLine = true; //!< signals whether or not we should with the first line
+ //!< write a start line code or not. Essential
+ //!< when this code parser is called from another
+ //!< code parser.
+
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
@@ -3788,6 +3793,12 @@ void CCodeParser::resetCodeParserState()
yyextra->anchorCount = 0;
}
+void CCodeParser::setStartCodeLine(const bool inp)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
+ yyextra->beginCodeLine = inp;
+}
+
void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const QCString &s,
SrcLangExt lang,bool exBlock, const char *exName,FileDef *fd,
int startLine,int endLine,bool inlineFragment,
@@ -3862,7 +3873,8 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const
}
yyextra->includeCodeFragment = inlineFragment;
//printf("** exBlock=%d exName=%s include=%d\n",exBlock,exName,inlineFragment);
- startCodeLine(yyscanner);
+
+ if (yyextra->beginCodeLine) startCodeLine(yyscanner);
yyextra->type.resize(0);
yyextra->name.resize(0);
yyextra->args.resize(0);
diff --git a/src/config.xml b/src/config.xml
index d9b29aa..8526a2b 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -647,7 +647,7 @@ Go to the <a href="commands.html">next</a> section or return to the
With this tag you can assign which parser to use for a given extension.
Doxygen has a built-in mapping, but you can override or extend it using this tag.
The format is <code>ext=language</code>, where \c ext is a file extension, and language is one of
- the parsers supported by doxygen: IDL, Java, JavaScript, Csharp (C#), C, C++, D, PHP,
+ the parsers supported by doxygen: IDL, Java, JavaScript, Csharp (C#), C, C++, Lex, D, PHP,
md (Markdown), Objective-C, Python, Slice, VHDL, Fortran (fixed format Fortran: FortranFixed,
free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In
the later case the parser tries to guess whether the code is fixed or free
@@ -1434,6 +1434,7 @@ FILE_VERSION_FILTER = "cleartool desc -fmt \%Vn"
<value name='*.hxx'/>
<value name='*.hpp'/>
<value name='*.h++'/>
+ <value name='*.l'/>
<value name='*.cs'/>
<value name='*.d'/>
<value name='*.php'/>
diff --git a/src/context.cpp b/src/context.cpp
index d2cfa9e..e0017fb 100644
--- a/src/context.cpp
+++ b/src/context.cpp
@@ -1540,6 +1540,7 @@ class DefinitionContext
case SrcLangExt_SQL: result="sql"; break;
case SrcLangExt_Markdown: result="markdown"; break;
case SrcLangExt_Slice: result="slice"; break;
+ case SrcLangExt_Lex: result="lex"; break;
}
return result;
}
diff --git a/src/defargs.l b/src/defargs.l
index e25c1fe..76d07ec 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -27,12 +27,12 @@
* The Argument list as a whole can be pure, constant or volatile.
*
* Examples of input strings are:
- * \code
+ * \verbatim
* "(int a,int b) const"
* "(const char *s="hello world",int=5) = 0"
* "<class T,class N>"
* "(char c,const char)"
- * \endcode
+ * \endverbatim
*
* Note: It is not always possible to distinguish between the name and
* type of an argument. In case of doubt the name is added to the
diff --git a/src/docsets.cpp b/src/docsets.cpp
index 4f04623..9c29818 100644
--- a/src/docsets.cpp
+++ b/src/docsets.cpp
@@ -328,6 +328,7 @@ void DocSets::addIndexItem(const Definition *context,const MemberDef *md,
case SrcLangExt_SQL: lang="sql"; break; // Sql
case SrcLangExt_Markdown:lang="markdown"; break; // Markdown
case SrcLangExt_Slice: lang="slice"; break; // Slice
+ case SrcLangExt_Lex: lang="lex"; break; // Lex
case SrcLangExt_Unknown: lang="unknown"; break; // should not happen!
}
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index f5a280b..c268f26 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -77,6 +77,8 @@
#include "fortranscanner.h"
#include "xmlcode.h"
#include "sqlcode.h"
+#include "lexcode.h"
+#include "lexscanner.h"
#include "code.h"
#include "portable.h"
#include "vhdljjparser.h"
@@ -10058,6 +10060,8 @@ void initDoxygen()
make_parser_factory<SQLCodeParser>());
Doxygen::parserManager->registerParser("md", make_parser_factory<MarkdownOutlineParser>(),
make_parser_factory<FileCodeParser>());
+ Doxygen::parserManager->registerParser("lex", make_parser_factory<LexOutlineParser>(),
+ make_parser_factory<LexCodeParser>());
// register any additional parsers here...
diff --git a/src/lexcode.h b/src/lexcode.h
new file mode 100644
index 0000000..38aec50
--- /dev/null
+++ b/src/lexcode.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ */
+
+
+#ifndef LEXCODE_H
+#define LEXCODE_H
+
+#include "parserintf.h"
+
+class CodeOutputInterface;
+class FileDef;
+class MemberDef;
+class QCString;
+class Definition;
+
+/** LEX code scanner.
+ */
+class LexCodeParser : public CodeParserInterface
+{
+ public:
+ LexCodeParser();
+ virtual ~LexCodeParser();
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ const MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ const Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ void resetCodeParserState();
+ private:
+ struct Private;
+ std::unique_ptr<Private> p;
+};
+
+
+#endif
diff --git a/src/lexcode.l b/src/lexcode.l
new file mode 100644
index 0000000..d6b41b0
--- /dev/null
+++ b/src/lexcode.l
@@ -0,0 +1,1223 @@
+/******************************************************************************
+ *
+ * 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="lexcodeYY"
+%option noyywrap
+%option reentrant
+%option extra-type="struct lexcodeYY_state *"
+%top{
+#include <stdint.h>
+}
+
+%{
+
+#include <stdio.h>
+
+#include "config.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "code.h"
+#include "lexcode.h"
+#include "filedef.h"
+#include "message.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+#define YY_NO_UNISTD_H 1
+
+#define USE_STATE2STRING 0
+
+struct lexcodeYY_state
+{
+ CodeOutputInterface * code;
+ CCodeParser ccodeParser;
+ const char *inputString; //!< the code fragment as text
+ yy_size_t inputPosition; //!< read offset during parsing
+ int inputLines; //!< number of line in the code fragment
+ int yyLineNr; //!< current line number
+ bool needsTermination;
+
+ bool lineNumbers = FALSE;
+ const Definition *searchCtx;
+ bool collectXRefs = FALSE;
+
+ int lastContext = 0;
+ int lastCContext = 0;
+ int lastStringContext = 0;
+ int docBlockContext = 0;
+ int lastPreLineCtrlContext = 0;
+ int lastRawStringContext = 0;
+ int curlyCount = 0;
+
+ QCString rulesPatternBuffer;
+ QCString CCodeBuffer;
+ int startCCodeLine = -1;
+ int roundCount = 0;
+ int squareCount = 0;
+ bool insideCode = FALSE;
+ QCString delimiter;
+ QCString docBlockName;
+ uint fencedSize = 0;
+ bool nestedComment = false;
+
+ bool exampleBlock;
+ QCString exampleName;
+ QCString classScope;
+
+ FileDef *sourceFileDef;
+ const Definition *currentDefinition;
+ const MemberDef *currentMemberDef;
+ bool includeCodeFragment;
+ const char *currentFontClass;
+};
+
+#if USE_STATE2STRING
+static const char *stateToString(int state);
+#endif
+
+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);
+static void lineCount(yyscan_t yyscanner);
+static void handleCCode(yyscan_t yyscanner);
+
+#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}
+RulesStart "%%"{nl}
+RulesEnd "%%"{nl}
+RulesSharp "<"[^>]*">"
+RulesCurly "{"[^{}\n]*"}"
+StartSquare "["
+StartDouble "\""
+StartRound "("
+EscapeRulesCharOpen "\\["|"\\<"|"\\{"|"\\("|"\\\""|"\\{"|"\\ "
+EscapeRulesCharClose "\\]"|"\\>"|"\\}"|"\\)"
+EscapeRulesChar {EscapeRulesCharOpen}|{EscapeRulesCharClose}
+
+CMD ("\\"|"@")
+BN [ \t\n\r]
+BL [ \t\r]*"\n"
+B [ \t]
+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}"'"))
+
+%x DefSection
+%x DefSectionLine
+%x RulesSectionInit
+%x RulesPattern
+%x RulesDouble
+%x RulesRoundDouble
+%x RulesSquare
+%x RulesRoundSquare
+%x RulesRound
+%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>^{TopStart} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ yyextra->lastContext = YY_START;
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ BEGIN (TopSection);
+ }
+<DefSection>^{LiteralStart} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ yyextra->lastContext = YY_START;
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ BEGIN (LiteralSection);
+ }
+<TopSection>^{TopEnd} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ BEGIN( yyextra->lastContext ) ;
+ }
+<TopSection>.*{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<LiteralSection>^{LiteralEnd} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ BEGIN( yyextra->lastContext ) ;
+ }
+<LiteralSection>.*{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<DefSection>"//".*{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<DefSection>^{ws}*"/*" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(COMMENT);
+ }
+<COMMENT>"*/"{ws}*{nl} {
+ yyextra->CCodeBuffer+=yytext;
+ yyextra->yyLineNr++;
+ handleCCode(yyscanner);
+ BEGIN(yyextra->lastContext);
+ }
+<COMMENT>"*/" {
+ yyextra->CCodeBuffer+=yytext;
+ handleCCode(yyscanner);
+ BEGIN(yyextra->lastContext);
+ }
+<COMMENT>[^*\n]+ {
+ yyextra->CCodeBuffer += yytext;
+ }
+<COMMENT>"//"|"/*" {
+ yyextra->CCodeBuffer += yytext;
+ }
+<COMMENT>{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<COMMENT>. {
+ yyextra->CCodeBuffer += yytext;
+ }
+<DefSection>^{nl} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ }
+<DefSection>^{ws}.*{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<DefSection>^{RulesStart} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ BEGIN (RulesSectionInit);
+ }
+<DefSection>^{nws} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ BEGIN(DefSectionLine);
+ }
+<DefSectionLine>.*{nl} {
+ codifyLines(yyscanner,yytext);
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ BEGIN(DefSection);
+ }
+<RulesSectionInit,RulesPattern>^{RulesEnd} {
+ handleCCode(yyscanner);
+ codifyLines(yyscanner,yytext);
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ BEGIN (UserSection);
+ }
+<RulesSectionInit>^{nws} {
+ handleCCode(yyscanner);
+ unput(*yytext);
+ BEGIN(RulesPattern);
+ }
+<RulesSectionInit>{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<RulesSectionInit>^{ws}.*{nl} {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<RulesPattern>"<<EOF>>" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{EscapeRulesChar} {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{RulesSharp} {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{RulesCurly} {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{StartDouble} {
+ yyextra->rulesPatternBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesDouble);
+ }
+<RulesDouble,RulesRoundDouble>"\\\\" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesDouble,RulesRoundDouble>"\\\"" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesDouble>"\"" {
+ yyextra->rulesPatternBuffer += yytext;
+ BEGIN( yyextra->lastContext ) ;
+ }
+<RulesRoundDouble>"\"" {
+ yyextra->rulesPatternBuffer += yytext;
+ BEGIN(RulesRound) ;
+ }
+<RulesDouble,RulesRoundDouble>. {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{StartSquare} {
+ yyextra->squareCount++;
+ yyextra->rulesPatternBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesSquare);
+ }
+<RulesSquare,RulesRoundSquare>"\\[" |
+<RulesSquare,RulesRoundSquare>"\\]" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesSquare,RulesRoundSquare>"[" {
+ yyextra->squareCount++;
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesSquare>"]" {
+ yyextra->squareCount--;
+ yyextra->rulesPatternBuffer += yytext;
+ if (!yyextra->squareCount) BEGIN(RulesPattern) ;
+ }
+<RulesRoundSquare>"]" {
+ yyextra->squareCount--;
+ yyextra->rulesPatternBuffer += yytext;
+ if (!yyextra->squareCount) BEGIN(RulesRound) ;
+ }
+<RulesSquare,RulesRoundSquare>"\\\\" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesSquare,RulesRoundSquare>. {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{StartRound} {
+ yyextra->roundCount++;
+ yyextra->rulesPatternBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesRound);
+ }
+<RulesRound>{RulesCurly} {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesRound>{StartSquare} {
+ yyextra->squareCount++;
+ yyextra->rulesPatternBuffer += yytext;
+ BEGIN(RulesRoundSquare);
+ }
+<RulesRound>{StartDouble} {
+ yyextra->rulesPatternBuffer += yytext;
+ BEGIN(RulesRoundDouble);
+ }
+<RulesRound>"\\(" |
+<RulesRound>"\\)" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesRound>"(" {
+ yyextra->roundCount++;
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesRound>")" {
+ yyextra->roundCount--;
+ yyextra->rulesPatternBuffer += yytext;
+ if (!yyextra->roundCount) BEGIN( yyextra->lastContext ) ;
+ }
+<RulesRound>. {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>{ws}+"|" {
+ if (!yyextra->rulesPatternBuffer.isEmpty())
+ {
+ startFontClass(yyscanner,"stringliteral");
+ codifyLines(yyscanner,yyextra->rulesPatternBuffer.data());
+ yyextra->rulesPatternBuffer.resize(0);
+ endFontClass(yyscanner);
+ }
+ codifyLines(yyscanner,yytext);
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ yyextra->curlyCount = 0;
+ BEGIN(SkipCurly);
+ }
+<RulesPattern>^{ws}*{nl} {
+ codifyLines(yyscanner,"\n");
+ }
+<RulesPattern>^{ws}+ {
+ codifyLines(yyscanner,yytext);
+ }
+<RulesPattern>({ws}|{nl}) {
+ unput(*yytext);
+ if (!yyextra->rulesPatternBuffer.isEmpty())
+ {
+ startFontClass(yyscanner,"stringliteral");
+ codifyLines(yyscanner,yyextra->rulesPatternBuffer.data());
+ yyextra->rulesPatternBuffer.resize(0);
+ endFontClass(yyscanner);
+ }
+ yyextra->startCCodeLine=yyextra->yyLineNr;
+ yyextra->curlyCount = 0;
+ BEGIN(SkipCurly);
+ }
+<RulesPattern>"\\\\" {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<RulesPattern>"/*" {
+ if (!yyextra->rulesPatternBuffer.isEmpty())
+ {
+ startFontClass(yyscanner,"stringliteral");
+ codifyLines(yyscanner,yyextra->rulesPatternBuffer.data());
+ yyextra->rulesPatternBuffer.resize(0);
+ endFontClass(yyscanner);
+ }
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(COMMENT);
+ }
+<RulesPattern>. {
+ yyextra->rulesPatternBuffer += yytext;
+ }
+<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;
+ yyextra->yyLineNr++;
+ BEGIN( yyextra->lastPreLineCtrlContext );
+ }
+<SkipCurly>"{" {
+ yyextra->CCodeBuffer += yytext;
+ ++yyextra->curlyCount ;
+ }
+<SkipCurly>"}"/{BN}*("/*!"|"/**"|"//!"|"///")"<!--" | /* see bug710917 */
+<SkipCurly>"}" {
+ yyextra->CCodeBuffer += yytext;
+ lineCount(yyscanner);
+ if( yyextra->curlyCount )
+ {
+ --yyextra->curlyCount ;
+ }
+ }
+<SkipCurly>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" {
+ yyextra->CCodeBuffer += yytext;
+ lineCount(yyscanner);
+ 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.data()+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>"/*" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastCContext = YY_START;
+ BEGIN(SkipComment);
+ }
+<SkipCurly>"//" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastCContext = YY_START;
+ BEGIN(SkipCxxComment);
+ }
+<SkipCurly>{CHARLIT} {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurly>\' {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurly>. {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurly>("//"{B}*)?"/*!" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+<SkipCurly>"/**"[*]+{BL} {
+ bool javadocBanner = Config_getBool(JAVADOC_BANNER);
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ if( javadocBanner )
+ {
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+ else
+ {
+ BEGIN( Comment ) ;
+ }
+ }
+<SkipCurly>("//"{B}*)?"/**"/[^/*] {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+<SkipCurly>"//!" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocLine );
+ }
+<SkipCurly>"///"/[^/] {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocLine );
+ }
+
+<SkipCurly>\n {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ if (yyextra->curlyCount<=0)
+ {
+ handleCCode(yyscanner);
+ BEGIN(RulesPattern);
+ }
+ }
+<SkipString>\\. {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipString>\" {
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->lastStringContext );
+ }
+<SkipString>"/*"|"*/"|"//" {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipString>\n {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<SkipString>. {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCxxComment>.*"\\\n" { // line continuation
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<SkipCxxComment>.*/\n {
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->lastCContext ) ;
+ }
+<Comment>{BN}+ {
+ yyextra->CCodeBuffer += yytext ;
+ lineCount(yyscanner);
+ }
+<Comment>"/*" { yyextra->CCodeBuffer += yytext ; }
+<Comment>"//" { 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>"*/" {
+ yyextra->CCodeBuffer += yytext ;
+ if (!yyextra->insideCode) BEGIN( yyextra->lastContext ) ;
+ }
+<Comment>. { yyextra->CCodeBuffer += *yytext ; }
+
+<SkipComment>"//"|"/*" {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipComment>[^\*\n]+ {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipComment>\n {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->yyLineNr++;
+ }
+<SkipComment>{B}*"*/" {
+ 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;
+ yyextra->yyLineNr++;
+ }
+
+
+ /* ---- Single line comments ------ */
+<DocLine>[^\n]*"\n"[ \t]*"//"[/!][<]? { // continuation of multiline C++-style comment
+ yyextra->CCodeBuffer += yytext;
+ lineCount(yyscanner);
+ }
+<DocLine>{B}*"///"[/]+{B}*/"\n" { // ignore marker line (see bug700345)
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+<DocLine>[^\n]*/"\n"{B}*"//"[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+<DocLine>[^\n]*/"\n" { // whole line
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+
+ /* ---- Comments blocks ------ */
+
+<DocBlock>"*"*"*/" { // end of comment block
+ yyextra->CCodeBuffer += yytext;
+ BEGIN(yyextra->docBlockContext);
+ }
+<DocBlock>^{B}*"*"+/[^/] {
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>^{B}*("//")?{B}*"*"+/[^//a-z_A-Z0-9*] { // start of a comment line
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>^{B}*("//"){B}* { // strip embedded C++ comments if at the start of a line
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>"//" { // slashes in the middle of a comment block
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>"/*" { // 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{") {
+ 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;
+ lineCount(yyscanner);
+ }
+<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}") {
+ 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>"/*"|"*/"|"//" {
+ if (yytext[1]=='*')
+ {
+ yyextra->nestedComment=TRUE;
+ }
+ else if (yytext[0]=='*')
+ {
+ yyextra->nestedComment=FALSE;
+ }
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocCopyBlock>\n { // newline
+ yyextra->CCodeBuffer += yytext;
+ lineCount(yyscanner);
+ }
+<DocCopyBlock>. { // any other character
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurlyEndDoc>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { // 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;
+ yyextra->yyLineNr++;
+ }
+ /*
+<*>. { fprintf(stderr,"Lex code scanner Def rule for %s: #%s#\n",stateToString(YY_START),yytext);}
+ */
+<*><<EOF>> {
+ handleCCode(yyscanner);
+ yyterminate();
+ }
+%%
+
+static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (Doxygen::searchIndex)
+ {
+ if (yyextra->searchCtx)
+ {
+ yyextra->code->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),false);
+ }
+ else
+ {
+ yyextra->code->setCurrentDoc(yyextra->sourceFileDef,anchor,true);
+ }
+ }
+}
+
+/*! 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(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->sourceFileDef && yyextra->lineNumbers)
+ {
+ const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+
+ if (!yyextra->includeCodeFragment && d)
+ {
+ yyextra->currentDefinition = d;
+ yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
+ yyextra->classScope = d->name().copy();
+ QCString lineAnchor;
+ lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
+ if (yyextra->currentMemberDef)
+ {
+ yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
+ yyextra->currentMemberDef->getOutputFileBase(),
+ yyextra->currentMemberDef->anchor(),yyextra->yyLineNr);
+ setCurrentDoc(yyscanner,lineAnchor);
+ }
+ else
+ {
+ yyextra->code->writeLineNumber(d->getReference(),
+ d->getOutputFileBase(),
+ 0,yyextra->yyLineNr);
+ setCurrentDoc(yyscanner,lineAnchor);
+ }
+ }
+ else
+ {
+ yyextra->code->writeLineNumber(0,0,0,yyextra->yyLineNr);
+ }
+ }
+
+ yyextra->code->startCodeLine(yyextra->sourceFileDef && yyextra->lineNumbers);
+
+ if (yyextra->currentFontClass)
+ {
+ yyextra->code->startFontClass(yyextra->currentFontClass);
+ }
+}
+
+static void endFontClass(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->currentFontClass)
+ {
+ yyextra->code->endFontClass();
+ yyextra->currentFontClass=0;
+ }
+}
+
+static void endCodeLine(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ endFontClass(yyscanner);
+ yyextra->code->endCodeLine();
+}
+
+static void nextCodeLine(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ const char *fc = yyextra->currentFontClass;
+ endCodeLine(yyscanner);
+ if (yyextra->yyLineNr<yyextra->inputLines)
+ {
+ yyextra->currentFontClass = fc;
+ startCodeLine(yyscanner);
+ }
+}
+
+static void codifyLines(yyscan_t yyscanner,const char *text)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ const char *p=text,*sp=p;
+ char c;
+ bool done=false;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') { }
+ if (c=='\n')
+ {
+ yyextra->yyLineNr++;
+ int l = (int)(p-sp-1);
+ char *tmp = (char*)malloc(l+1);
+ memcpy(tmp,sp,l);
+ tmp[l]='\0';
+ yyextra->code->codify(tmp);
+ if (p)
+ {
+ nextCodeLine(yyscanner);
+ }
+ else
+ {
+ endCodeLine(yyscanner);
+ done=true;
+ }
+ free(tmp);
+ }
+ else
+ {
+ yyextra->code->codify(sp);
+ done=true;
+ }
+ }
+ yyextra->startCCodeLine = yyextra->yyLineNr;
+}
+
+static void startFontClass(yyscan_t yyscanner,const char *s)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ endFontClass(yyscanner);
+ if (!yyextra->currentFontClass || !s || strcmp(yyextra->currentFontClass,s))
+ {
+ endFontClass(yyscanner);
+ yyextra->code->startFontClass(s);
+ yyextra->currentFontClass=s;
+ }
+}
+
+/*! counts the number of lines in the input */
+static int countLines(yyscan_t yyscanner)
+{
+ 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++;
+ }
+ 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++,
+ yyextra->needsTermination=true;
+ }
+ return count;
+}
+
+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 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 lineCount(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ const char *p;
+ for (p = yytext ; *p ; ++p )
+ {
+ if (*p=='\n')
+ {
+ yyextra->yyLineNr++;
+ }
+ }
+}
+
+static void handleCCode(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->CCodeBuffer.isEmpty()) return;
+
+ yyextra->ccodeParser.setStartCodeLine(false);
+ yyextra->ccodeParser.parseCode(*yyextra->code,
+ yyextra->classScope,
+ yyextra->CCodeBuffer,
+ SrcLangExt_Cpp,
+ yyextra->exampleBlock,
+ yyextra->exampleName,
+ yyextra->sourceFileDef,
+ yyextra->startCCodeLine,
+ -1, /* endLine will be calculated in called routine */
+ yyextra->includeCodeFragment,
+ yyextra->currentMemberDef,
+ yyextra->lineNumbers,
+ yyextra->searchCtx,
+ yyextra->collectXRefs
+ );
+ yyextra->CCodeBuffer.resize(0);
+ yyextra->ccodeParser.setStartCodeLine(true);
+ yyextra->yyLineNr--;
+ codifyLines(yyscanner,"\n");
+ return;
+}
+
+// public interface -----------------------------------------------------------
+
+struct LexCodeParser::Private
+{
+ yyscan_t yyscanner;
+ lexcodeYY_state state;
+};
+
+LexCodeParser::LexCodeParser() : p(std::make_unique<Private>())
+{
+ lexcodeYYlex_init_extra(&p->state, &p->yyscanner);
+#ifdef FLEX_DEBUG
+ lexcodeYYset_debug(1,p->yyscanner);
+#endif
+ resetCodeParserState();
+}
+
+LexCodeParser::~LexCodeParser()
+{
+ lexcodeYYlex_destroy(p->yyscanner);
+}
+
+void LexCodeParser::resetCodeParserState()
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
+ yyextra->currentDefinition = 0;
+ yyextra->currentMemberDef = 0;
+}
+
+void LexCodeParser::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;
+
+ if (input.isEmpty()) return;
+
+ 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->classScope=scopeName;
+ yyextra->currentMemberDef=memberDef;
+ yyextra->searchCtx=searchCtx;
+ yyextra->collectXRefs=collectXRefs;
+
+ if (startLine!=-1)
+ yyextra->yyLineNr = startLine;
+ else
+ yyextra->yyLineNr = 1;
+
+ if (endLine!=-1)
+ yyextra->inputLines = endLine+1;
+ else
+ yyextra->inputLines = yyextra->yyLineNr + countLines(yyscanner) - 1;
+
+ yyextra->startCCodeLine = yyextra->yyLineNr;
+ yyextra->exampleBlock = isExampleBlock;
+ yyextra->exampleName = exampleName;
+ yyextra->sourceFileDef = fileDef;
+ yyextra->lineNumbers = fileDef!=0 && showLineNumbers;
+
+ bool cleanupSourceDef = false;
+
+ if (isExampleBlock && fileDef==0)
+ {
+ // create a dummy filedef for the example
+ yyextra->sourceFileDef = createFileDef("",(exampleName?exampleName:"generated"));
+ cleanupSourceDef = true;
+ }
+
+ if (yyextra->sourceFileDef)
+ {
+ setCurrentDoc(yyscanner,"l00001");
+ }
+
+ yyextra->includeCodeFragment = inlineFragment;
+ // Starts line 1 on the output
+ startCodeLine(yyscanner);
+
+ lexcodeYYrestart( 0, yyscanner );
+ BEGIN( DefSection );
+ lexcodeYYlex(yyscanner);
+
+ if (yyextra->needsTermination)
+ {
+ endCodeLine(yyscanner);
+ }
+ if (cleanupSourceDef)
+ {
+ // delete the temporary file definition used for this example
+ delete yyextra->sourceFileDef;
+ yyextra->sourceFileDef=0;
+ }
+
+ printlex(yy_flex_debug, false, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
+}
+
+//---------------------------------------------------------------------------------
+
+#if USE_STATE2STRING
+#include "lexcode.l.h"
+#endif
diff --git a/src/lexscanner.h b/src/lexscanner.h
new file mode 100644
index 0000000..11bf25e
--- /dev/null
+++ b/src/lexscanner.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ *
+ *
+ * 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.
+ *
+ */
+
+#ifndef SCANNER_LEL_H
+#define SCANNER_LEX_H
+
+#include "parserintf.h"
+
+/** \brief Lex language parser using state-based lexical scanning.
+ *
+ * This is the Lex language parser for doxygen.
+ */
+class LexOutlineParser : public OutlineParserInterface
+{
+ public:
+ LexOutlineParser();
+ ~LexOutlineParser();
+ void parseInput(const char *fileName,
+ const char *fileBuf,
+ const std::shared_ptr<Entry> &root,
+ ClangTUParser *clangParser);
+ bool needsPreprocessing(const QCString &extension) const { return TRUE; };
+ void parsePrototype(const char *text){}
+
+ private:
+ struct Private;
+ std::unique_ptr<Private> p;
+};
+#endif
diff --git a/src/lexscanner.l b/src/lexscanner.l
new file mode 100644
index 0000000..e0f3a92
--- /dev/null
+++ b/src/lexscanner.l
@@ -0,0 +1,938 @@
+/*****************************************************************************
+ *
+ *
+ *
+ * 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";
+ QCString CCodeBuffer;
+ int roundCount = 0;
+ int squareCount = 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}
+OptPrefix "%option"{ws}+"prefix"{ws}*"="{ws}*
+RulesStart "%%"{nl}
+RulesEnd "%%"{nl}
+RulesSharp "<"[^>]*">"
+RulesCurly "{"[^{}\n]*"}"
+StartSquare "["
+StartDouble "\""
+StartRound "("
+EscapeRulesCharOpen "\\["|"\\<"|"\\{"|"\\("|"\\\""|"\\{"|"\\ "
+EscapeRulesCharClose "\\]"|"\\>"|"\\}"|"\\)"
+EscapeRulesChar {EscapeRulesCharOpen}|{EscapeRulesCharClose}
+
+CMD ("\\"|"@")
+BN [ \t\n\r]
+BL [ \t\r]*"\n"
+B [ \t]
+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}"'"))
+
+%x DefSection
+%x OptPrefix
+%x DefSectionLine
+%x RulesSectionInit
+%x RulesPattern
+%x RulesDouble
+%x RulesRoundDouble
+%x RulesSquare
+%x RulesRoundSquare
+%x RulesRound
+%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>{OptPrefix} {
+ BEGIN (OptPrefix);
+ }
+<OptPrefix>"\""[^\"]*"\"" {
+ yyextra->prefix = yytext;
+ yyextra->prefix = yyextra->prefix.mid(1,yyleng-2);
+ }
+<OptPrefix>{nl} {
+ yyextra->CCodeBuffer += yytext;
+ BEGIN (DefSection);
+ }
+<DefSection>^{RulesStart} {
+ yyextra->CCodeBuffer += "int " + yyextra->prefix + "lex (yyscan_t yyscanner) {\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>"//".*{nl} {
+ yyextra->CCodeBuffer += yytext;
+ }
+<DefSection>^{ws}*"/*" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastContext = YY_START;
+ BEGIN(COMMENT);
+ }
+<COMMENT>"*/"{ws}*{nl} {
+ yyextra->CCodeBuffer+=yytext;
+ BEGIN(yyextra->lastContext);
+ }
+<COMMENT>"*/" {
+ yyextra->CCodeBuffer+=yytext;
+ BEGIN(yyextra->lastContext);
+ }
+<COMMENT>[^*\n]+ {
+ yyextra->CCodeBuffer += yytext;
+ }
+<COMMENT>"//"|"/*" {
+ 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->squareCount++;
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesSquare);
+ }
+<RulesSquare,RulesRoundSquare>"\\[" |
+<RulesSquare,RulesRoundSquare>"\\]" {
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesSquare,RulesRoundSquare>"[" {
+ yyextra->squareCount++;
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesSquare>"]" {
+ yyextra->squareCount--;
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ if (!yyextra->squareCount) BEGIN(RulesPattern);
+ }
+<RulesRoundSquare>"]" {
+ yyextra->squareCount--;
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ if (!yyextra->squareCount) BEGIN(RulesRound) ;
+ }
+<RulesSquare,RulesRoundSquare>"\\\\" {
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesSquare,RulesRoundSquare>. {
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesPattern>{StartRound} {
+ yyextra->roundCount++;
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ yyextra->lastContext = YY_START;
+ BEGIN(RulesRound);
+ }
+<RulesRound>{RulesCurly} {
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ }
+<RulesRound>{StartSquare} {
+ yyextra->squareCount++;
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesRoundSquare);
+ }
+<RulesRound>{StartDouble} {
+ yyextra->CCodeBuffer += repeatChar(' ', yyleng);
+ BEGIN(RulesRoundDouble);
+ }
+<RulesRound>"\\(" |
+<RulesRound>"\\)" {
+ 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>. {
+ 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>"/*" {
+ 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}*("/*!"|"/**"|"//!"|"///")"<!--" | /* see bug710917 */
+<SkipCurly>"}" {
+ yyextra->CCodeBuffer += yytext;
+ if( yyextra->curlyCount )
+ {
+ --yyextra->curlyCount ;
+ }
+ }
+<SkipCurly>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" {
+ 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.data()+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>"/*" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastCContext = YY_START;
+ BEGIN(SkipComment);
+ }
+<SkipCurly>"//" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->lastCContext = YY_START;
+ BEGIN(SkipCxxComment);
+ }
+<SkipCurly>{CHARLIT} {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurly>\' {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurly>. {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCurly>("//"{B}*)?"/*!" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+<SkipCurly>"/**"[*]+{BL} {
+ bool javadocBanner = Config_getBool(JAVADOC_BANNER);
+ yyextra->CCodeBuffer += yytext;
+ if( javadocBanner )
+ {
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+ else
+ {
+ BEGIN( Comment ) ;
+ }
+ }
+<SkipCurly>("//"{B}*)?"/**"/[^/*] {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocBlock );
+ }
+<SkipCurly>"//!" {
+ yyextra->CCodeBuffer += yytext;
+ yyextra->docBlockContext = YY_START;
+ BEGIN( DocLine );
+ }
+<SkipCurly>"///"/[^/] {
+ 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>"/*"|"*/"|"//" {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipString>\n {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipString>. {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCxxComment>.*"\\\n" { // line continuation
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipCxxComment>.*/\n {
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->lastCContext ) ;
+ }
+<Comment>{BN}+ {
+ yyextra->CCodeBuffer += yytext ;
+ }
+<Comment>"/*" { yyextra->CCodeBuffer += yytext ; }
+<Comment>"//" { 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>"*/" { yyextra->CCodeBuffer += yytext ;
+ if (!yyextra->insideCode) BEGIN( yyextra->lastContext ) ;
+ }
+<Comment>. { yyextra->CCodeBuffer += *yytext ; }
+
+<SkipComment>"//"|"/*" {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipComment>[^\*\n]+ {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipComment>\n {
+ yyextra->CCodeBuffer += yytext;
+ }
+<SkipComment>{B}*"*/" {
+ 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]*"//"[/!][<]? { // continuation of multiline C++-style comment
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocLine>{B}*"///"[/]+{B}*/"\n" { // ignore marker line (see bug700345)
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+<DocLine>[^\n]*/"\n"{B}*"//"[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+<DocLine>[^\n]*/"\n" { // whole line
+ yyextra->CCodeBuffer += yytext;
+ BEGIN( yyextra->docBlockContext );
+ }
+
+ /* ---- Comments blocks ------ */
+
+<DocBlock>"*"*"*/" { // end of comment block
+ yyextra->CCodeBuffer += yytext;
+ BEGIN(yyextra->docBlockContext);
+ }
+<DocBlock>^{B}*"*"+/[^/] {
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>^{B}*("//")?{B}*"*"+/[^//a-z_A-Z0-9*] { // start of a comment line
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>^{B}*("//"){B}* { // strip embedded C++ comments if at the start of a line
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>"//" { // slashes in the middle of a comment block
+ yyextra->CCodeBuffer += yytext;
+ }
+<DocBlock>"/*" { // 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{") {
+ 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}") {
+ 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>"/*"|"*/"|"//" {
+ 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}*("/*!"|"/**"|"//!"|"///")"<" { // 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);}
+ */
+<*><<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 char *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",yyextra->yyFileName.data());
+
+ 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.resize(0);
+}
+
+//----------------------------------------------------------------------------
+
+
+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,
+ yyextra->current_root,
+ yyextra->clangParser);
+ // SrcLangExt_Cpp,
+ 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 char *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__, fileName);
+
+ ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
+
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+
+//----------------------------------------------------------------------------
+
+#if USE_STATE2STRING
+#include "lexscanner.l.h"
+#endif
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 7e58331..4eeacc6 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -3512,10 +3512,17 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml,
else
ol.parseText(theTranslator->trInitialValue());
ol.endBold();
- auto intf = Doxygen::parserManager->getCodeParser(getDefFileExtension());
+ QCString langCorrected = getDefFileExtension();
+ SrcLangExt srcLangExt = getLanguageFromFileName(getDefFileExtension());
+ if (srcLangExt == SrcLangExt_Lex)
+ {
+ langCorrected = ".doxygen_lex_c";
+ srcLangExt = SrcLangExt_Cpp;
+ }
+ auto intf = Doxygen::parserManager->getCodeParser(langCorrected);
intf->resetCodeParserState();
ol.startCodeFragment("DoxyCode");
- intf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()),
+ intf->parseCode(ol,scopeName,m_impl->initializer,srcLangExt,FALSE,0,const_cast<FileDef*>(getFileDef()),
-1,-1,TRUE,this,FALSE,this);
ol.endCodeFragment("DoxyCode");
}
diff --git a/src/pre.l b/src/pre.l
index e817a9d..4e423f9 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -111,8 +111,8 @@ struct PreIncludeInfo
/** A dictionary of managed Define objects. */
typedef std::map< std::string, Define > DefineMap;
-/** @brief Class that manages the defines available while
- * preprocessing files.
+/** @brief Class that manages the defines available while
+ * preprocessing files.
*/
class DefineManager
{
@@ -122,7 +122,7 @@ class DefineManager
{
public:
/** Creates an empty container for defines */
- DefinesPerFile(DefineManager *parent)
+ DefinesPerFile(DefineManager *parent)
: m_parent(parent)
{
}
@@ -353,6 +353,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
%x SkipLine
%x SkipString
%x CopyLine
+%x LexCopyLine
%x CopyString
%x CopyStringCs
%x CopyStringFtn
@@ -396,9 +397,14 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
unput(resolveTrigraph(yytext[2]));
}
<Start>^{B}*"#" { BEGIN(Command); yyextra->yyColNr+=(int)yyleng; yyextra->yyMLines=0;}
+<Start>^("%top{"|"%{") {
+ if (getLanguageFromFileName(yyextra->yyFileName)!=SrcLangExt_Lex) REJECT
+ outputArray(yyscanner,yytext,(int)yyleng);
+ BEGIN(LexCopyLine);
+ }
<Start>^{B}*/[^#] {
outputArray(yyscanner,yytext,(int)yyleng);
- BEGIN(CopyLine);
+ BEGIN(CopyLine);
}
<Start>^{B}*[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]+{B}*"("[^\)\n]*")"/{BN}{1,10}*[:{] { // constructors?
int i;
@@ -439,46 +445,49 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
BEGIN(CopyLine);
}
}
-<CopyLine>"extern"{BN}{0,80}"\"C\""*{BN}{0,80}"{" {
+<CopyLine,LexCopyLine>"extern"{BN}{0,80}"\"C\""*{BN}{0,80}"{" {
QCString text=yytext;
yyextra->yyLineNr+=text.contains('\n');
outputArray(yyscanner,yytext,(int)yyleng);
}
-<CopyLine>{RAWBEGIN} {
+<CopyLine,LexCopyLine>{RAWBEGIN} {
yyextra->delimiter = yytext+2;
yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
outputArray(yyscanner,yytext,(int)yyleng);
BEGIN(CopyRawString);
}
-<CopyLine>"{" { // count brackets inside the main file
- if (yyextra->includeStack.empty())
+<CopyLine,LexCopyLine>"{" { // count brackets inside the main file
+ if (yyextra->includeStack.empty())
{
yyextra->curlyCount++;
}
outputChar(yyscanner,*yytext);
}
-<CopyLine>"}" { // count brackets inside the main file
- if (yyextra->includeStack.empty() && yyextra->curlyCount>0)
+<LexCopyLine>^"%}" {
+ outputArray(yyscanner,yytext,(int)yyleng);
+ }
+<CopyLine,LexCopyLine>"}" { // count brackets inside the main file
+ if (yyextra->includeStack.empty() && yyextra->curlyCount>0)
{
yyextra->curlyCount--;
}
outputChar(yyscanner,*yytext);
}
-<CopyLine>"'"\\[0-7]{1,3}"'" {
+<CopyLine,LexCopyLine>"'"\\[0-7]{1,3}"'" {
outputArray(yyscanner,yytext,(int)yyleng);
}
-<CopyLine>"'"\\."'" {
+<CopyLine,LexCopyLine>"'"\\."'" {
outputArray(yyscanner,yytext,(int)yyleng);
}
-<CopyLine>"'"."'" {
+<CopyLine,LexCopyLine>"'"."'" {
outputArray(yyscanner,yytext,(int)yyleng);
}
-<CopyLine>@\" {
+<CopyLine,LexCopyLine>@\" {
if (getLanguageFromFileName(yyextra->yyFileName)!=SrcLangExt_CSharp) REJECT;
outputArray(yyscanner,yytext,(int)yyleng);
BEGIN( CopyStringCs );
}
-<CopyLine>\" {
+<CopyLine,LexCopyLine>\" {
outputChar(yyscanner,*yytext);
if (getLanguageFromFileName(yyextra->yyFileName)!=SrcLangExt_Fortran)
{
@@ -489,7 +498,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
BEGIN( CopyStringFtnDouble );
}
}
-<CopyLine>\' {
+<CopyLine,LexCopyLine>\' {
if (getLanguageFromFileName(yyextra->yyFileName)!=SrcLangExt_Fortran) REJECT;
outputChar(yyscanner,*yytext);
BEGIN( CopyStringFtn );
@@ -542,7 +551,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<CopyRawString>. {
outputChar(yyscanner,*yytext);
}
-<CopyLine>{ID}/{BN}{0,80}"(" {
+<CopyLine,LexCopyLine>{ID}/{BN}{0,80}"(" {
yyextra->expectGuard = FALSE;
Define *def=0;
//def=yyextra->globalDefineDict->find(yytext);
@@ -579,9 +588,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,yytext,(int)yyleng);
}
}
-<CopyLine>{ID} {
+<CopyLine,LexCopyLine>{ID} {
Define *def=0;
- if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
+ if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
yyextra->macroExpansion &&
(def=isDefined(yyscanner,yytext)) &&
def->nargs==-1 &&
@@ -589,7 +598,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
(!yyextra->expandOnlyPredef || def->isPredefined)
)
{
- QCString result=def->isPredefined ? def->definition : expandMacro(yyscanner,yytext);
+ QCString result=def->isPredefined ? def->definition : expandMacro(yyscanner,yytext);
outputArray(yyscanner,result,result.length());
}
else
@@ -597,13 +606,13 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,yytext,(int)yyleng);
}
}
-<CopyLine>"\\"\r?/\n { // strip line continuation characters
+<CopyLine,LexCopyLine>"\\"\r?/\n { // strip line continuation characters
if (getLanguageFromFileName(yyextra->yyFileName)==SrcLangExt_Fortran) outputChar(yyscanner,*yytext);
}
-<CopyLine>. {
+<CopyLine,LexCopyLine>. {
outputChar(yyscanner,*yytext);
}
-<CopyLine>\n {
+<CopyLine,LexCopyLine>\n {
outputChar(yyscanner,'\n');
BEGIN(Start);
yyextra->yyLineNr++;
@@ -672,12 +681,12 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
yyextra->defArgsStr+=yytext;
BEGIN(FindDefineArgs);
}
-<ArgCopyCComment>\n {
+<ArgCopyCComment>\n {
yyextra->defArgsStr+=' ';
yyextra->yyLineNr++;
outputChar(yyscanner,'\n');
}
-<ArgCopyCComment>. {
+<ArgCopyCComment>. {
yyextra->defArgsStr+=yytext;
}
<ReadString>"\"" {
@@ -703,20 +712,20 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
<Command>("include"|"import"){B}+/{ID} {
yyextra->isImported = yytext[1]=='m';
- if (yyextra->macroExpansion)
+ if (yyextra->macroExpansion)
BEGIN(IncludeID);
}
-<Command>("include"|"import"){B}*[<"] {
+<Command>("include"|"import"){B}*[<"] {
yyextra->isImported = yytext[1]=='m';
char c[2];
c[0]=yytext[yyleng-1];c[1]='\0';
yyextra->incName=c;
- BEGIN(Include);
+ BEGIN(Include);
}
-<Command>("cmake")?"define"{B}+ {
- //printf("!!!DefName\n");
+<Command>("cmake")?"define"{B}+ {
+ //printf("!!!DefName\n");
yyextra->yyColNr+=(int)yyleng;
- BEGIN(DefName);
+ BEGIN(DefName);
}
<Command>"ifdef"/{B}*"(" {
incrLevel(yyscanner);
@@ -748,7 +757,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
if (!otherCaseDone(yyscanner))
{
yyextra->guardExpr.resize(0);
- BEGIN(Guard);
+ BEGIN(Guard);
}
else
{
@@ -765,7 +774,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
else
{
setCaseDone(yyscanner,TRUE);
- }
+ }
}
<Command>"undef"{B}+ {
BEGIN(UndefName);
@@ -800,7 +809,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<Command>. {yyextra->yyColNr+=(int)yyleng;}
<UndefName>{ID} {
Define *def;
- if ((def=isDefined(yyscanner,yytext))
+ if ((def=isDefined(yyscanner,yytext))
/*&& !def->isPredefined*/
&& !def->nonRecursive
)
@@ -833,7 +842,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
if (guard)
{
BEGIN(Start);
- }
+ }
else
{
yyextra->ifcount=0;
@@ -859,7 +868,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<DefinedExpr1,DefinedExpr2>\n { // should not happen, handle anyway
yyextra->yyLineNr++;
yyextra->ifcount=0;
- BEGIN(SkipCPPBlock);
+ BEGIN(SkipCPPBlock);
}
<DefinedExpr2>")" {
BEGIN(Guard);
@@ -869,9 +878,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<SkipCPPBlock>^{B}*/[^#] { BEGIN(SkipLine); }
<SkipCPPBlock>\n { yyextra->yyLineNr++; outputChar(yyscanner,'\n'); }
<SkipCPPBlock>.
-<SkipCommand>"if"(("n")?("def"))?/[ \t(!] {
+<SkipCommand>"if"(("n")?("def"))?/[ \t(!] {
incrLevel(yyscanner);
- yyextra->ifcount++;
+ yyextra->ifcount++;
//printf("#if... depth=%d\n",yyextra->ifcount);
}
<SkipCommand>"else" {
@@ -884,7 +893,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
}
<SkipCommand>("elif"|"else"{B}*"if")/[ \t(!] {
- if (yyextra->ifcount==0)
+ if (yyextra->ifcount==0)
{
if (!otherCaseDone(yyscanner))
{
@@ -898,7 +907,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
}
}
-<SkipCommand>"endif" {
+<SkipCommand>"endif" {
yyextra->expectGuard = FALSE;
decrLevel(yyscanner);
if (--yyextra->ifcount<0)
@@ -907,13 +916,13 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
BEGIN(Start);
}
}
-<SkipCommand>\n {
+<SkipCommand>\n {
outputChar(yyscanner,'\n');
- yyextra->yyLineNr++;
+ yyextra->yyLineNr++;
BEGIN(SkipCPPBlock);
}
-<SkipCommand>{ID} { // unknown directive
- BEGIN(SkipLine);
+<SkipCommand>{ID} { // unknown directive
+ BEGIN(SkipLine);
}
<SkipCommand>.
<SkipLine>[^'"/\n]+
@@ -922,13 +931,13 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
BEGIN(SkipString);
}
<SkipLine>.
-<SkipString>"//"/[^\n]* {
+<SkipString>"//"/[^\n]* {
}
<SkipLine,SkipCommand,SkipCPPBlock>"//"[^\n]* {
yyextra->lastCPPContext=YY_START;
BEGIN(RemoveCPPComment);
}
-<SkipString>"/*"/[^\n]* {
+<SkipString>"/*"/[^\n]* {
}
<SkipLine,SkipCommand,SkipCPPBlock>"/*"/[^\n]* {
yyextra->lastCContext=YY_START;
@@ -936,7 +945,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
<SkipLine>\n {
outputChar(yyscanner,'\n');
- yyextra->yyLineNr++;
+ yyextra->yyLineNr++;
BEGIN(SkipCPPBlock);
}
<SkipString>[^"\\\n]+ { }
@@ -957,7 +966,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
readIncludeFile(yyscanner,expandMacro(yyscanner,yytext));
BEGIN(Start);
}
-<Include>[^\">\n]+[\">] {
+<Include>[^\">\n]+[\">] {
yyextra->incName+=yytext;
readIncludeFile(yyscanner,yyextra->incName);
if (yyextra->isImported)
@@ -972,7 +981,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<EndImport>[^\\\n]*/\n {
BEGIN(Start);
}
-<EndImport>\\[\r]?"\n" {
+<EndImport>\\[\r]?"\n" {
outputChar(yyscanner,'\n');
yyextra->yyLineNr++;
}
@@ -1007,9 +1016,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
yyextra->quoteArg=FALSE;
yyextra->insideComment=FALSE;
yyextra->lastGuardName.resize(0);
- yyextra->defText="1";
- yyextra->defLitText="1";
- BEGIN(DefineText);
+ yyextra->defText="1";
+ yyextra->defLitText="1";
+ BEGIN(DefineText);
}
else // define is a guard => hide
{
@@ -1061,7 +1070,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,tmp.data(),tmp.length());
yyextra->quoteArg=FALSE;
yyextra->insideComment=FALSE;
- BEGIN(DefineText);
+ BEGIN(DefineText);
}
<DefineArg>"\\\n" {
yyextra->defExtraSpacing+="\n";
@@ -1070,7 +1079,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<DefineArg>","{B}* { yyextra->defArgsStr+=yytext; }
<DefineArg>"("{B}* { yyextra->defArgsStr+=yytext; }
<DefineArg>{B}*")"{B}* {
- yyextra->defArgsStr+=yytext;
+ yyextra->defArgsStr+=yytext;
QCString tmp=(QCString)"#define "+yyextra->defName+yyextra->defArgsStr+yyextra->defExtraSpacing;
outputArray(yyscanner,tmp.data(),tmp.length());
yyextra->quoteArg=FALSE;
@@ -1126,13 +1135,13 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputChar(yyscanner,'*');outputChar(yyscanner,'/');
if (--yyextra->commentCount<=0)
{
- if (yyextra->lastCContext==Start)
+ if (yyextra->lastCContext==Start)
// small hack to make sure that ^... rule will
// match when going to Start... Example: "/*...*/ some stuff..."
{
YY_CURRENT_BUFFER->yy_at_bol=1;
}
- BEGIN(yyextra->lastCContext);
+ BEGIN(yyextra->lastCContext);
}
}
<SkipCComment>"//"("/")* {
@@ -1196,12 +1205,12 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,yytext,(int)yyleng);
}
<SkipCPPComment>[\\@]"cond"[ \t]+ { // conditional section
- yyextra->ccomment=TRUE;
+ yyextra->ccomment=TRUE;
yyextra->condCtx=YY_START;
BEGIN(CondLineCpp);
}
<SkipCComment>[\\@]"cond"[ \t]+ { // conditional section
- yyextra->ccomment=FALSE;
+ yyextra->ccomment=FALSE;
yyextra->condCtx=YY_START;
BEGIN(CondLineC);
}
@@ -1274,7 +1283,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,yytext,(int)yyleng);
}
}
-<SkipCond>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
+<SkipCond>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
bool oldSkip = yyextra->skip;
endCondSection(yyscanner);
if (oldSkip && !yyextra->skip)
@@ -1289,7 +1298,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<SkipCComment,SkipCPPComment>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
bool oldSkip = yyextra->skip;
endCondSection(yyscanner);
- if (oldSkip && !yyextra->skip)
+ if (oldSkip && !yyextra->skip)
{
BEGIN(yyextra->condCtx);
}
@@ -1325,7 +1334,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<SkipCComment,SkipVerbatim>[^*\\@\x06~`\n\/]+ {
outputArray(yyscanner,yytext,(int)yyleng);
}
-<SkipCComment,SkipVerbatim>\n {
+<SkipCComment,SkipVerbatim>\n {
yyextra->yyLineNr++;
outputChar(yyscanner,'\n');
}
@@ -1347,7 +1356,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
yyextra->defText+=yytext;
BEGIN(yyextra->lastCContext);
}
-<CopyCComment>\n {
+<CopyCComment>\n {
yyextra->yyLineNr++;
yyextra->defLitText+=yytext;
yyextra->defText+=' ';
@@ -1447,7 +1456,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputChar(yyscanner,'\n');
Define *def=0;
//printf("Define name='%s' text='%s' litTexti='%s'\n",yyextra->defName.data(),yyextra->defText.data(),yyextra->defLitText.data());
- if (yyextra->includeStack.empty() || yyextra->curlyCount>0)
+ if (yyextra->includeStack.empty() || yyextra->curlyCount>0)
{
addMacroDefinition(yyscanner);
}
@@ -1468,7 +1477,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
def->name = yyextra->defName;
def->definition = yyextra->defText.stripWhiteSpace();
def->nargs = yyextra->defArgs;
- def->fileName = yyextra->yyFileName.copy();
+ def->fileName = yyextra->yyFileName.copy();
def->lineNr = yyextra->yyLineNr-yyextra->yyMLines;
def->columnNr = yyextra->yyColNr;
}
@@ -1486,16 +1495,16 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<DefineText>{B}* { yyextra->defText += ' '; yyextra->defLitText+=yytext; }
<DefineText>{B}*"##"{B}* { yyextra->defText += "##"; yyextra->defLitText+=yytext; }
<DefineText>"@" { yyextra->defText += "@@"; yyextra->defLitText+=yytext; }
-<DefineText>\" {
- yyextra->defText += *yytext;
- yyextra->defLitText+=yytext;
+<DefineText>\" {
+ yyextra->defText += *yytext;
+ yyextra->defLitText+=yytext;
if (!yyextra->insideComment)
{
BEGIN(SkipDoubleQuote);
}
}
<DefineText>\' { yyextra->defText += *yytext;
- yyextra->defLitText+=yytext;
+ yyextra->defLitText+=yytext;
if (!yyextra->insideComment)
{
BEGIN(SkipSingleQuote);
@@ -1504,7 +1513,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<SkipDoubleQuote>"//"[/]? { yyextra->defText += yytext; yyextra->defLitText+=yytext; }
<SkipDoubleQuote>"/*"[*]? { yyextra->defText += yytext; yyextra->defLitText+=yytext; }
<SkipDoubleQuote>\" {
- yyextra->defText += *yytext; yyextra->defLitText+=yytext;
+ yyextra->defText += *yytext; yyextra->defLitText+=yytext;
BEGIN(DefineText);
}
<SkipSingleQuote,SkipDoubleQuote>\\. {
@@ -1541,7 +1550,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
setFileName(yyscanner,fs->fileName);
DBG_CTX((stderr,"######## FileName %s\n",yyextra->yyFileName.data()));
- // Deal with file changes due to
+ // Deal with file changes due to
// #include's within { .. } blocks
QCString lineStr(15+yyextra->yyFileName.length());
lineStr.sprintf("# %d \"%s\" 2",yyextra->yyLineNr,yyextra->yyFileName.data());
@@ -1593,7 +1602,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,yytext,(int)yyleng);
yyextra->lastCContext=YY_START;
yyextra->commentCount=1;
- if (yyleng==3)
+ if (yyleng==3)
{
yyextra->isSpecialComment = true;
yyextra->lastGuardName.resize(0); // reset guard in case the #define is documented!
@@ -1626,9 +1635,9 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
BEGIN(SkipCPPComment);
}
}
-<*>\n {
+<*>\n {
outputChar(yyscanner,'\n');
- yyextra->yyLineNr++;
+ yyextra->yyLineNr++;
}
<*>. {
yyextra->expectGuard = FALSE;
@@ -1845,23 +1854,23 @@ static QCString extractTrailingComment(const char *s)
{
i--;
while (i>0 && !(s[i-1]=='/' && s[i]=='*')) i--;
- if (i==0)
+ if (i==0)
{
i++;
}
// only /*!< or /**< are treated as a comment for the macro name,
// otherwise the comment is treated as part of the macro definition
- return ((s[i+1]=='*' || s[i+1]=='!') && s[i+2]=='<') ? &s[i-1] : "";
+ return ((s[i+1]=='*' || s[i+1]=='!') && s[i+2]=='<') ? &s[i-1] : "";
}
else
{
return "";
}
- }
+ }
break;
// whitespace or line-continuation
case ' ':
- case '\t':
+ case '\t':
case '\r':
case '\n':
case '\\':
@@ -1935,7 +1944,7 @@ static QCString stringize(const QCString &s)
while (i<s.length() && inString)
{
c=s.at(i++);
- if (c=='"')
+ if (c=='"')
{
result+="\\\"";
inString= pc=='\\';
@@ -1952,15 +1961,15 @@ static QCString stringize(const QCString &s)
return result;
}
-/*! Execute all ## operators in expr.
- * If the macro name before or after the operator contains a no-rescan
+/*! Execute all ## operators in expr.
+ * If the macro name before or after the operator contains a no-rescan
* marker (@-) then this is removed (before the concatenated macro name
* may be expanded again.
*/
static void processConcatOperators(QCString &expr)
{
//printf("processConcatOperators: in='%s'\n",expr.data());
- QRegExp r("[ \\t\\n]*##[ \\t\\n]*");
+ QRegExp r("[ \\t\\n]*##[ \\t\\n]*");
int l,n,i=0;
if (expr.isEmpty()) return;
while ((n=r.match(expr,i,&l))!=-1)
@@ -1975,7 +1984,7 @@ static void processConcatOperators(QCString &expr)
// remove the ## operator and the surrounding whitespace
expr=expr.left(n)+expr.right(expr.length()-n-l);
int k=n-1;
- while (k>=0 && isId(expr.at(k))) k--;
+ while (k>=0 && isId(expr.at(k))) k--;
if (k>0 && expr.at(k)=='-' && expr.at(k-1)=='@')
{
// remove no-rescan marker before ID
@@ -2006,12 +2015,12 @@ static inline void addTillEndOfString(yyscan_t yyscanner,const QCString &expr,QC
}
/*! replaces the function macro \a def whose argument list starts at
- * \a pos in expression \a expr.
+ * \a pos in expression \a expr.
* Notice that this routine may scan beyond the \a expr string if needed.
* In that case the characters will be read from the input file.
- * The replacement string will be returned in \a result and the
+ * The replacement string will be returned in \a result and the
* length of the (unexpanded) argument list is stored in \a len.
- */
+ */
static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result,int level)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
@@ -2020,15 +2029,15 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
len=0;
result.resize(0);
int cc;
- while ((cc=getCurrentChar(yyscanner,expr,rest,j))!=EOF && isspace(cc))
- {
- len++;
- getNextChar(yyscanner,expr,rest,j);
+ while ((cc=getCurrentChar(yyscanner,expr,rest,j))!=EOF && isspace(cc))
+ {
+ len++;
+ getNextChar(yyscanner,expr,rest,j);
}
- if (cc!='(')
- {
- unputChar(yyscanner,expr,rest,j,(char)cc);
- return FALSE;
+ if (cc!='(')
+ {
+ unputChar(yyscanner,expr,rest,j,(char)cc);
+ return FALSE;
}
getNextChar(yyscanner,expr,rest,j); // eat the '(' character
@@ -2048,7 +2057,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
}
else
{
- while (!done && (argCount<def->nargs || def->varArgs) &&
+ while (!done && (argCount<def->nargs || def->varArgs) &&
((cc=getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
)
{
@@ -2102,21 +2111,21 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
done=TRUE;
}
}
- }
+ }
else if (c=='\"') // append literal strings
{
- arg+=c;
+ arg+=c;
bool found=FALSE;
while (!found && (cc=getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
{
found = cc=='"';
if (cc=='\\')
{
- c=(char)cc;
+ c=(char)cc;
arg+=c;
if ((cc=getNextChar(yyscanner,expr,rest,j))==EOF || cc==0) break;
}
- c=(char)cc;
+ c=(char)cc;
arg+=c;
}
}
@@ -2129,14 +2138,14 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
found = cc=='\'';
if (cc=='\\')
{
- c=(char)cc;
+ c=(char)cc;
arg+=c;
if ((cc=getNextChar(yyscanner,expr,rest,j))==EOF || cc==0) break;
}
c=(char)cc;
arg+=c;
}
- }
+ }
else if (c=='/') // possible start of a comment
{
char prevChar = '\0';
@@ -2196,7 +2205,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
k++;
// scan the number
while (k<d.length() && d.at(k)>='0' && d.at(k)<='9') key+=d.at(k++);
- if (!hash)
+ if (!hash)
{
// search for ## forward
l=k;
@@ -2220,7 +2229,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
{
//printf("'%s'=stringize('%s')\n",stringize(*subst).data(),subst->data());
- // if the marker is inside a string (because a # was put
+ // if the marker is inside a string (because a # was put
// before the macro name) we must escape " and \ characters
resExpr+=stringize(substArg);
}
@@ -2244,7 +2253,7 @@ static bool replaceFunctionMacro(yyscan_t yyscanner,const QCString &expr,QCStrin
}
else // no marker, just copy
{
- if (!inString && d.at(k)=='\"')
+ if (!inString && d.at(k)=='\"')
{
inString=TRUE; // entering a literal string
}
@@ -2284,13 +2293,13 @@ static int getNextId(const QCString &expr,int p,int *l)
n=p-1;
while (p<(int)expr.length() && isId(expr.at(p))) p++;
*l=p-n;
- return n;
+ return n;
}
else if (c=='"') // skip string
{
char ppc=0,pc=c;
if (p<(int)expr.length()) c=expr.at(p);
- while (p<(int)expr.length() && (c!='"' || (pc=='\\' && ppc!='\\')))
+ while (p<(int)expr.length() && (c!='"' || (pc=='\\' && ppc!='\\')))
// continue as long as no " is found, but ignoring \", but not \\"
{
ppc=pc;
@@ -2304,11 +2313,11 @@ static int getNextId(const QCString &expr,int p,int *l)
{
//printf("Found C comment at p=%d\n",p);
char pc=c;
- if (p<(int)expr.length())
+ if (p<(int)expr.length())
{
c=expr.at(p);
if (c=='*') // Start of C comment
- {
+ {
p++;
while (p<(int)expr.length() && !(pc=='*' && c=='/'))
{
@@ -2369,7 +2378,7 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in
//printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data());
definedTest=TRUE;
}
- else if (definedTest) // macro name was found after defined
+ else if (definedTest) // macro name was found after defined
{
if (def) expMacro = " 1 "; else expMacro = " 0 ";
replaced=TRUE;
@@ -2527,7 +2536,7 @@ static QCString removeIdsAndMarkers(const char *s)
{
if (*(p+1)=='@')
{
- result+=c;
+ result+=c;
}
else if (*(p+1)=='E')
{
@@ -2547,7 +2556,7 @@ static QCString removeIdsAndMarkers(const char *s)
}
else if (c=='d' && !inNum) // identifier starting with a 'd'
{
- if (qstrncmp(p,"defined ",8)==0 || qstrncmp(p,"defined(",8)==0)
+ if (qstrncmp(p,"defined ",8)==0 || qstrncmp(p,"defined(",8)==0)
// defined keyword
{
p+=7; // skip defined
@@ -2599,7 +2608,7 @@ static QCString removeIdsAndMarkers(const char *s)
char pc=c;
c=*++p;
if (c=='*') // start of C comment
- {
+ {
while (*p && !(pc=='*' && c=='/')) // search end of comment
{
pc=c;
@@ -2613,7 +2622,7 @@ static QCString removeIdsAndMarkers(const char *s)
goto nextChar;
}
}
- else
+ else
{
nextChar:
result+=c;
@@ -2628,7 +2637,7 @@ nextChar:
}
/*! replaces all occurrences of @@ in \a s by @
- * \par assumption:
+ * \par assumption:
* \a s only contains pairs of @@'s
*/
static QCString removeMarkers(const char *s)
@@ -2646,7 +2655,7 @@ static QCString removeMarkers(const char *s)
{
if (*(p+1)=='@')
{
- result+=c;
+ result+=c;
}
p+=2;
}
@@ -2657,12 +2666,12 @@ static QCString removeMarkers(const char *s)
char pc=c;
c=*++p;
if (c=='*') // start of C comment
- {
+ {
while (*p && !(pc=='*' && c=='/')) // search end of comment
{
- if (*p=='@' && *(p+1)=='@')
+ if (*p=='@' && *(p+1)=='@')
result+=c,p++;
- else
+ else
result+=c;
pc=c;
c=*++p;
@@ -2727,7 +2736,7 @@ static void addDefine(yyscan_t yyscanner)
def.name = state->defName;
def.definition = state->defText.stripWhiteSpace();
def.nargs = state->defArgs;
- def.fileName = state->yyFileName;
+ def.fileName = state->yyFileName;
def.fileDef = state->yyFileDef;
def.lineNr = state->yyLineNr-state->yyMLines;
def.columnNr = state->yyColNr;
@@ -2735,7 +2744,7 @@ static void addDefine(yyscan_t yyscanner)
//printf("newDefine: %s %s file: %s\n",def.name.data(),def.definition.data(),
// def.fileDef ? def.fileDef->name().data() : def.fileName.data());
//printf("newDefine: '%s'->'%s'\n",def.name.data(),def.definition.data());
- if (!def.name.isEmpty() &&
+ if (!def.name.isEmpty() &&
Doxygen::expandAsDefinedSet.find(def.name.str())!=Doxygen::expandAsDefinedSet.end())
{
def.isPredefined=TRUE;
@@ -2751,7 +2760,7 @@ static void addDefine(yyscan_t yyscanner)
static void addMacroDefinition(yyscan_t yyscanner)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
- if (state->skip) return; // do not add this define as it is inside a
+ if (state->skip) return; // do not add this define as it is inside a
// conditional section (cond command) that is disabled.
Define define;
@@ -2892,7 +2901,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
//printf("Found include file!\n");
if (Debug::isFlagSet(Debug::Preprocessor))
{
- for (i=0;i<state->includeStack.size();i++)
+ for (i=0;i<state->includeStack.size();i++)
{
Debug::print(Debug::Preprocessor,0," ");
}
@@ -2927,7 +2936,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
state->includeStack.emplace_back(fs);
// set the scanner to the include file
- // Deal with file changes due to
+ // Deal with file changes due to
// #include's within { .. } blocks
QCString lineStr(state->yyFileName.length()+20);
lineStr.sprintf("# 1 \"%s\" 1\n",state->yyFileName.data());
@@ -2968,7 +2977,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
if (Debug::isFlagSet(Debug::Preprocessor))
{
- for (i=0;i<state->includeStack.size();i++)
+ for (i=0;i<state->includeStack.size();i++)
{
Debug::print(Debug::Preprocessor,0," ");
}
@@ -3089,7 +3098,7 @@ static int getNextChar(yyscan_t yyscanner,const QCString &expr,QCString *rest,ui
return cc;
}
}
-
+
static int getCurrentChar(yyscan_t yyscanner,const QCString &expr,QCString *rest,uint pos)
{
//printf("getCurrentChar(%s,%s,%d)\n",expr.data(),rest ? rest->data() : 0,pos);
@@ -3185,8 +3194,8 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
continue; // no define name
}
- if (i_obrace<i_equals && i_cbrace<i_equals &&
- i_obrace!=-1 && i_cbrace!=-1 &&
+ if (i_obrace<i_equals && i_cbrace<i_equals &&
+ i_obrace!=-1 && i_cbrace!=-1 &&
i_obrace<i_cbrace
) // predefined function macro definition
{
@@ -3205,7 +3214,7 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
{
//printf("predefined function macro '%s'\n",qPrint(ds.mid(i_obrace+1,i_cbrace-i_obrace-1)));
i=i_obrace+1;
- // gather the formal arguments in a dictionary
+ // gather the formal arguments in a dictionary
while (i<i_cbrace && (pi=reId.match(ds,i,&l)))
{
if (l>0) // see bug375037
@@ -3224,7 +3233,7 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
QCString tmp=ds.right(ds.length()-i_equals-1);
QCString definition;
i=0;
- // substitute all occurrences of formal arguments by their
+ // substitute all occurrences of formal arguments by their
// corresponding markers
while ((pi=reId.match(tmp,i,&l))!=-1)
{
@@ -3355,20 +3364,20 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
state->inputFileDef = state->yyFileDef;
//yyextra->defineManager.startContext(state->yyFileName);
-
+
initPredefined(yyscanner,fileName);
-
+
state->yyLineNr = 1;
state->yyColNr = 1;
state->ifcount = 0;
BEGIN( Start );
-
+
state->expectGuard = guessSection(fileName)==Entry::HEADER_SEC;
state->guardName.resize(0);
state->lastGuardName.resize(0);
state->guardExpr.resize(0);
-
+
preYYlex(yyscanner);
while (!state->condStack.empty())
@@ -3391,7 +3400,7 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
Debug::print(Debug::Preprocessor,0,"Preprocessor output of %s (size: %d bytes):\n",fileName,newPos-orgPos);
int line=1;
Debug::print(Debug::Preprocessor,0,"---------\n00001 ");
- while (orgPos<newPos)
+ while (orgPos<newPos)
{
putchar(*orgPos);
if (*orgPos=='\n') Debug::print(Debug::Preprocessor,0,"%05d ",++line);
diff --git a/src/scanner.l b/src/scanner.l
index 6970d3e..7edfc9b 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -6842,7 +6842,8 @@ static void setContext(yyscan_t yyscanner)
yyextra->insideObjC = yyextra->language==SrcLangExt_ObjC;
yyextra->insideJS = yyextra->language==SrcLangExt_JS;
yyextra->insideSlice = yyextra->language==SrcLangExt_Slice;
- yyextra->insideCpp = yyextra->language==SrcLangExt_Cpp;
+ yyextra->insideCpp = (yyextra->language==SrcLangExt_Cpp ||
+ yyextra->language==SrcLangExt_Lex);
//printf("setContext(%s) yyextra->insideIDL=%d yyextra->insideJava=%d yyextra->insideCS=%d "
// "yyextra->insideD=%d yyextra->insidePHP=%d yyextra->insideObjC=%d\n",
// yyextra->yyFileName.data(),yyextra->insideIDL,yyextra->insideJava,yyextra->insideCS,yyextra->insideD,yyextra->insidePHP,yyextra->insideObjC
@@ -7458,7 +7459,7 @@ bool COutlineParser::needsPreprocessing(const QCString &extension) const
{
QCString fe=extension.lower();
SrcLangExt lang = getLanguageFromFileName(extension);
- return (SrcLangExt_Cpp == lang) ||
+ return (SrcLangExt_Cpp == lang) || (SrcLangExt_Lex == lang) ||
!( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5"
);
diff --git a/src/types.h b/src/types.h
index d34444c..3667f3d 100644
--- a/src/types.h
+++ b/src/types.h
@@ -57,7 +57,8 @@ enum SrcLangExt
//SrcLangExt_Tcl = 0x08000, // no longer supported
SrcLangExt_Markdown = 0x10000,
SrcLangExt_SQL = 0x20000,
- SrcLangExt_Slice = 0x40000
+ SrcLangExt_Slice = 0x40000,
+ SrcLangExt_Lex = 0x100000
};
/** Grouping info */
diff --git a/src/util.cpp b/src/util.cpp
index 3bf349a..ad6b208 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -325,6 +325,7 @@ int guessSection(const char *name)
n.right(4)==".i++" ||
n.right(4)==".inl" ||
n.right(4)==".xml" ||
+ n.right(4)==".lex" ||
n.right(4)==".sql"
) return Entry::SOURCE_SEC;
if (n.right(2)==".h" || // header
@@ -5483,6 +5484,7 @@ g_lang2extMap[] =
{ "xml", "xml", SrcLangExt_XML },
{ "sql", "sql", SrcLangExt_SQL },
{ "md", "md", SrcLangExt_Markdown },
+ { "lex", "lex", SrcLangExt_Lex },
{ 0, 0, (SrcLangExt)0 }
};
@@ -5580,6 +5582,9 @@ void initDefaultExtensionMapping()
updateLanguageMapping(".md", "md");
updateLanguageMapping(".markdown", "md");
updateLanguageMapping(".ice", "slice");
+ updateLanguageMapping(".l", "lex");
+ updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
+ // in the lex scanning to cpp
}
void addCodeOnlyMappings()
@@ -6592,6 +6597,7 @@ QCString langToString(SrcLangExt lang)
case SrcLangExt_SQL: return "SQL";
case SrcLangExt_Markdown: return "Markdown";
case SrcLangExt_Slice: return "Slice";
+ case SrcLangExt_Lex: return "Lex";
}
return "Unknown";
}