summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralbert-github <albert.tests@gmail.com>2021-02-12 17:02:11 (GMT)
committeralbert-github <albert.tests@gmail.com>2021-02-12 17:02:11 (GMT)
commit77c63397e832a7ad5c618b1aed7fc5de25ff6e89 (patch)
treee885da91ffeb6ab98455c4fd31598f5fd467d047
parent4d8e0f3abdf682e323db79aec176854f2a8aa699 (diff)
downloadDoxygen-77c63397e832a7ad5c618b1aed7fc5de25ff6e89.zip
Doxygen-77c63397e832a7ad5c618b1aed7fc5de25ff6e89.tar.gz
Doxygen-77c63397e832a7ad5c618b1aed7fc5de25ff6e89.tar.bz2
Adding support for lex files
Adding support for lex. The lex files consist of a mixture of lex specific structures, that are handled in the the lexcode.l and lexscanner.l, abd C code that is handled by the C parsers (hence the rules used are partly copied from scanner.l). Special attention has been paid to memberdef.cpp as the initial values should not be handled by the lex parsers but by the C parsers.
-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";
}