summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-01-01 20:36:25 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-01-01 20:36:25 (GMT)
commit79cca781278544a7efc3a5538e2252ab399e08df (patch)
tree7908c341e2892a315b38ae1eef12d7c81308da6a
parenta036d6401cc457f6c80899775a471bb5ac4d5323 (diff)
downloadDoxygen-79cca781278544a7efc3a5538e2252ab399e08df.zip
Doxygen-79cca781278544a7efc3a5538e2252ab399e08df.tar.gz
Doxygen-79cca781278544a7efc3a5538e2252ab399e08df.tar.bz2
Make fortranscanner.l reentrant
-rw-r--r--src/fortranscanner.h6
-rw-r--r--src/fortranscanner.l2409
2 files changed, 1231 insertions, 1184 deletions
diff --git a/src/fortranscanner.h b/src/fortranscanner.h
index 7a13f47..6ffcb1f 100644
--- a/src/fortranscanner.h
+++ b/src/fortranscanner.h
@@ -27,7 +27,8 @@
class FortranOutlineParser : public OutlineParserInterface
{
public:
- FortranOutlineParser(FortranFormat format=FortranFormat_Unknown) : m_format(format) { }
+ FortranOutlineParser(FortranFormat format=FortranFormat_Unknown);
+ ~FortranOutlineParser();
void startTranslationUnit(const char *) {}
void finishTranslationUnit() {}
void parseInput(const char *fileName,
@@ -39,7 +40,8 @@ class FortranOutlineParser : public OutlineParserInterface
void parsePrototype(const char *text);
private:
- FortranFormat m_format;
+ struct Private;
+ std::unique_ptr<Private> p;
};
class FortranOutlineParserFree : public FortranOutlineParser
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index d569763..18cfdcb 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -21,8 +21,8 @@
* - Consider using startScope(), endScope() functions with module, program,
* subroutine or any other scope in fortran program.
*
- * - Symbol modifiers (attributes) are collected using SymbolModifiers |= operator during
- * substructure parsing. When substructure ends all modifiers are applied to actual
+ * - Symbol yyextra->modifiers (attributes) are collected using SymbolModifiers |= operator during
+ * substructure parsing. When substructure ends all yyextra->modifiers are applied to actual
* entries in applyModifiers() functions.
*
* - How case insensitiveness should be handled in code?
@@ -35,11 +35,13 @@
* "functionA" or "MyInterface". So constructs like '(^|[ \t])interface({BS_}{ID})?/[ \t\n]'
* are desired.
*
- * - Must track yyLineNr when using REJECT, unput() or similar commands.
+ * - Must track yyextra->lineNr when using REJECT, unput() or similar commands.
*/
%option never-interactive
%option case-insensitive
%option prefix="fortranscannerYY"
+%option reentrant
+%option extra-type="struct fortranscannerYY_state *"
%{
@@ -80,8 +82,9 @@ enum ScanVar { V_IGNORE, V_VARIABLE, V_PARAMETER, V_RESULT};
enum InterfaceType { IF_NONE, IF_SPECIFIC, IF_GENERIC, IF_ABSTRACT };
// {{{ ----- Helper structs -----
-//! Holds modifiers (ie attributes) for one symbol (variable, function, etc)
-struct SymbolModifiers {
+//! Holds yyextra->modifiers (ie attributes) for one symbol (variable, function, etc)
+struct SymbolModifiers
+{
enum Protection {NONE_P, PUBLIC, PRIVATE};
enum Direction {NONE_D, IN, OUT, INOUT};
@@ -133,116 +136,110 @@ static const char *directionParam[] =
// }}}
-/* -----------------------------------------------------------------
- *
- * statics
- */
-static OutlineParserInterface *g_thisParser;
-static CommentScanner g_commentScanner;
-static const char * inputString;
-static int inputPosition;
-static bool isFixedForm;
-static QCString inputStringPrepass; ///< Input string for prepass of line cont. '&'
-static QCString inputStringSemi; ///< Input string after command separator ';'
-static unsigned int inputPositionPrepass;
-static int lineCountPrepass = 0;
-
-static std::vector< std::shared_ptr<Entry> > subrCurrent;
-
-struct CommentInPrepass {
+struct CommentInPrepass
+{
int column;
QCString str;
CommentInPrepass(int column, QCString str) : column(column), str(str) {}
};
-static QList<CommentInPrepass> comments;
-
-YY_BUFFER_STATE *include_stack = NULL;
-int include_stack_ptr = 0;
-int include_stack_cnt = 0;
-
-static QFile inputFile;
-static QCString yyFileName;
-static int yyLineNr = 1 ;
-static int yyColNr = 0 ;
-static Entry *current_root = 0;
-static Entry *global_scope = 0;
-static std::shared_ptr<Entry> global_root;
-static std::shared_ptr<Entry> file_root;
-static std::shared_ptr<Entry> last_entry;
-static std::shared_ptr<Entry> last_enum;
-static std::shared_ptr<Entry> current;
-static ScanVar v_type = V_IGNORE; // type of parsed variable
-static std::vector<std::shared_ptr<Entry> > moduleProcedures; // list of all interfaces which contain unresolved
- // module procedures
-static QCString docBlock;
-static bool docBlockInBody = FALSE;
-static bool docBlockJavaStyle;
-
-static MethodTypes mtype;
-static bool gstat;
-static Specifier virt;
-
-static QCString debugStr;
-static QCString result; // function result
-static Argument *parameter; // element of parameter list
-static QCString argType; // fortran type of an argument of a parameter list
-static QCString argName; // last identifier name in variable list
-static QCString initializer; // initial value of a variable
-static int initializerArrayScope; // number if nested array scopes in initializer
-static int initializerScope; // number if nested function calls in initializer
-static QCString useModuleName; // name of module in the use statement
-static Protection defaultProtection;
-static Protection typeProtection;
-static int typeMode = false;
-static InterfaceType ifType = IF_NONE;
-static bool functionLine = FALSE;
-
-static char stringStartSymbol; // single or double quote
-static bool parsingPrototype = FALSE; // see parsePrototype()
+
+typedef std::vector< std::shared_ptr<Entry> > EntryList;
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+
+struct fortranscannerYY_state
+{
+ OutlineParserInterface * thisParser;
+ CommentScanner commentScanner;
+ const char * inputString;
+ int inputPosition;
+ bool isFixedForm;
+ QCString inputStringPrepass; ///< Input string for prepass of line cont. '&'
+ QCString inputStringSemi; ///< Input string after command separator ';'
+ unsigned int inputPositionPrepass;
+ int lineCountPrepass = 0;
+ EntryList subrCurrent;
+ QList<CommentInPrepass> comments;
+ YY_BUFFER_STATE * includeStack = NULL;
+ int includeStackPtr = 0;
+ int includeStackCnt = 0;
+ QCString fileName;
+ int lineNr = 1 ;
+ int colNr = 0 ;
+ Entry *current_root = 0;
+ Entry *global_scope = 0;
+ std::shared_ptr<Entry> global_root;
+ std::shared_ptr<Entry> file_root;
+ std::shared_ptr<Entry> last_entry;
+ std::shared_ptr<Entry> last_enum;
+ std::shared_ptr<Entry> current;
+ ScanVar vtype = V_IGNORE; // type of parsed variable
+ EntryList moduleProcedures; // list of all interfaces which contain unresolved module procedures
+ QCString docBlock;
+ bool docBlockInBody = FALSE;
+ bool docBlockJavaStyle;
+ QCString debugStr;
+// Argument *parameter; // element of parameter list
+ QCString argType; // fortran type of an argument of a parameter list
+ QCString argName; // last identifier name in variable list
+ QCString initializer; // initial value of a variable
+ int initializerArrayScope; // number if nested array scopes in initializer
+ int initializerScope; // number if nested function calls in initializer
+ QCString useModuleName; // name of module in the use statement
+ Protection defaultProtection;
+ Protection typeProtection;
+ bool typeMode = false;
+ InterfaceType ifType = IF_NONE;
+ bool functionLine = FALSE;
+ char stringStartSymbol; // single or double quote
+ bool parsingPrototype = FALSE; // see parsePrototype()
//! Accumulated modifiers of current statement, eg variable declaration.
-static SymbolModifiers currentModifiers;
+ SymbolModifiers currentModifiers;
//! Holds program scope->symbol name->symbol modifiers.
-static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers;
+ QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers;
+ int anonCount = 0 ;
+};
-static int anonCount = 0 ;
//-----------------------------------------------------------------------------
-
-static int yyread(char *buf,int max_size);
-static void startCommentBlock(bool);
-static void handleCommentBlock(const QCString &doc,bool brief);
-static void subrHandleCommentBlock(const QCString &doc,bool brief);
-static void subrHandleCommentBlockResult(const QCString &doc,bool brief);
-static void addCurrentEntry(bool case_insens);
-static void addModule(const char *name, bool isModule=FALSE);
-static void addSubprogram(const char *text);
-static void addInterface(QCString name, InterfaceType type);
-static Argument *getParameter(const QCString &name);
-static void scanner_abort();
-
-static void startScope(Entry *scope);
-static bool endScope(Entry *scope, bool isGlobalRoot=FALSE);
-//static bool isTypeName(QCString name);
-static void resolveModuleProcedures(Entry *current_root);
static int getAmpersandAtTheStart(const char *buf, int length);
static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch);
-static void truncatePrepass(int index);
-static void pushBuffer(QCString &buffer);
-static void popBuffer();
-//static void extractPrefix(QCString& text);
static QCString extractFromParens(const QCString name);
static QCString extractBind(const QCString name);
-static CommentInPrepass* locatePrepassComment(int from, int to);
-static void updateVariablePrepassComment(int from, int to);
-static void newLine();
-static void initEntry();
+
+
+static int yyread(yyscan_t yyscanner,char *buf,int max_size);
+static void startCommentBlock(yyscan_t yyscanner,bool);
+static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief);
+static void subrHandleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief);
+static void subrHandleCommentBlockResult(yyscan_t yyscanner,const QCString &doc,bool brief);
+static void addCurrentEntry(yyscan_t yyscanner,bool case_insens);
+static void addModule(yyscan_t yyscanner,const char *name, bool isModule=FALSE);
+static void addSubprogram(yyscan_t yyscanner,const char *text);
+static void addInterface(yyscan_t yyscanner,QCString name, InterfaceType type);
+static Argument *getParameter(yyscan_t yyscanner,const QCString &name);
+static void scanner_abort(yyscan_t yyscanner);
+
+static void startScope(yyscan_t yyscanner,Entry *scope);
+static bool endScope(yyscan_t yyscanner,Entry *scope, bool isGlobalRoot=FALSE);
+static void resolveModuleProcedures(yyscan_t yyscanner,Entry *current_root);
+static void truncatePrepass(yyscan_t yyscanner,int index);
+static void pushBuffer(yyscan_t yyscanner,QCString &buffer);
+static void popBuffer(yyscan_t yyscanner);
+static CommentInPrepass* locatePrepassComment(yyscan_t yyscanner,int from, int to);
+static void updateVariablePrepassComment(yyscan_t yyscanner,int from, int to);
+static void newLine(yyscan_t yyscanner);
+static void initEntry(yyscan_t yyscanner);
static const char *stateToString(int state);
//-----------------------------------------------------------------------------
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
-#define YY_USER_ACTION yyColNr+=(int)yyleng;
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
+#define YY_USER_ACTION yyextra->colNr+=(int)yyleng;
#define INVALID_ENTRY ((Entry*)0x8)
//-----------------------------------------------------------------------------
@@ -250,7 +247,7 @@ static const char *stateToString(int state);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-IDSYM [a-z_A-Z0-9]
+IDSYM [a-z_A-Z0-9]
NOTIDSYM [^a-z_A-Z0-9]
SEPARATE [:, \t]
ID [a-z_A-Z%]+{IDSYM}*
@@ -296,18 +293,18 @@ SCOPENAME ({ID}{BS}"::"{BS})*
//---------------------------------------------------------------------------------
/** fortran parsing states */
-%x Subprog
-%x SubprogPrefix
-%x Parameterlist
-%x SubprogBody
-%x SubprogBodyContains
-%x Start
-%x Comment
+%x Subprog
+%x SubprogPrefix
+%x Parameterlist
+%x SubprogBody
+%x SubprogBodyContains
+%x Start
+%x Comment
%x Module
%x Program
%x ModuleBody
-%x ModuleBodyContains
-%x AttributeList
+%x ModuleBodyContains
+%x AttributeList
%x Variable
%x Initialization
%x ArrayInitializer
@@ -325,289 +322,325 @@ SCOPENAME ({ID}{BS}"::"{BS})*
%x Prepass
/** comment parsing states */
-%x DocBlock
-%x DocBackLine
-%x EndDoc
+%x DocBlock
+%x DocBackLine
+%x EndDoc
%x BlockData
/** prototype parsing */
-%x Prototype
-%x PrototypeSubprog
-%x PrototypeArgs
+%x Prototype
+%x PrototypeSubprog
+%x PrototypeArgs
%%
/*-----------------------------------------------------------------------------------*/
<Prepass>^{BS}[&]*{BS}!.*\n { /* skip lines with just comment. Note code was in free format or has been converted to it */
- lineCountPrepass ++;
+ yyextra->lineCountPrepass ++;
}
<Prepass>^{BS}\n { /* skip empty lines */
- lineCountPrepass ++;
+ yyextra->lineCountPrepass ++;
}
<*>^.*\n { // prepass: look for line continuations
- functionLine = FALSE;
+ yyextra->functionLine = FALSE;
DBG_CTX((stderr, "---%s", yytext));
- int indexStart = getAmpersandAtTheStart(yytext, (int)yyleng);
- int indexEnd = getAmpOrExclAtTheEnd(yytext, (int)yyleng, '\0');
- if (indexEnd>=0 && yytext[indexEnd]!='&') //we are only interested in amp
- indexEnd=-1;
-
- if(indexEnd<0){ // ----- no ampersand as line continuation
- if(YY_START == Prepass) { // last line in "continuation"
+ int indexStart = getAmpersandAtTheStart(yytext, (int)yyleng);
+ int indexEnd = getAmpOrExclAtTheEnd(yytext, (int)yyleng, '\0');
+ if (indexEnd>=0 && yytext[indexEnd]!='&') //we are only interested in amp
+ {
+ indexEnd=-1;
+ }
- // Only take input after initial ampersand
- inputStringPrepass+=(const char*)(yytext+(indexStart+1));
-
- //printf("BUFFER:%s\n", (const char*)inputStringPrepass);
- pushBuffer(inputStringPrepass);
- yyColNr = 0;
- yy_pop_state();
- } else { // simple line
- yyColNr = 0;
- REJECT;
- }
-
- } else { // ----- line with continuation
- if(YY_START != Prepass) {
- comments.setAutoDelete(TRUE);
- comments.clear();
- yy_push_state(Prepass);
- }
+ if (indexEnd<0)
+ { // ----- no ampersand as line continuation
+ if (YY_START == Prepass)
+ { // last line in "continuation"
- int length = inputStringPrepass.length();
+ // Only take input after initial ampersand
+ yyextra->inputStringPrepass+=(const char*)(yytext+(indexStart+1));
+
+ //printf("BUFFER:%s\n", (const char*)yyextra->inputStringPrepass);
+ pushBuffer(yyscanner,yyextra->inputStringPrepass);
+ yyextra->colNr = 0;
+ yy_pop_state(yyscanner);
+ }
+ else
+ { // simple line
+ yyextra->colNr = 0;
+ REJECT;
+ }
+ }
+ else
+ { // ----- line with continuation
+ if (YY_START != Prepass)
+ {
+ yyextra->comments.setAutoDelete(TRUE);
+ yyextra->comments.clear();
+ yy_push_state(Prepass,yyscanner);
+ }
- // Only take input after initial ampersand
- inputStringPrepass+=(const char*)(yytext+(indexStart+1));
- lineCountPrepass ++;
+ int length = yyextra->inputStringPrepass.length();
- // cut off & and remove following comment if present
- truncatePrepass(length+indexEnd-(indexStart+1));
- }
+ // Only take input after initial ampersand
+ yyextra->inputStringPrepass+=(const char*)(yytext+(indexStart+1));
+ yyextra->lineCountPrepass ++;
+ // cut off & and remove following comment if present
+ truncatePrepass(yyscanner,length+indexEnd-(indexStart+1));
+ }
}
/*------ ignore strings that are not initialization strings */
<String>\"|\' { // string ends with next quote without previous backspace
- if (yytext[0]!=stringStartSymbol) { yyColNr -= (int)yyleng; REJECT; } // single vs double quote
- if (yy_top_state() == Initialization
- || yy_top_state() == ArrayInitializer)
- initializer+=yytext;
- yy_pop_state();
- }
-<String>. { if (yy_top_state() == Initialization
- || yy_top_state() == ArrayInitializer)
- initializer+=yytext;
- }
+ if (yytext[0]!=yyextra->stringStartSymbol)
+ {
+ yyextra->colNr -= (int)yyleng;
+ REJECT;
+ } // single vs double quote
+ if (yy_top_state(yyscanner) == Initialization ||
+ yy_top_state(yyscanner) == ArrayInitializer)
+ {
+ yyextra->initializer+=yytext;
+ }
+ yy_pop_state(yyscanner);
+ }
+<String>. { if (yy_top_state(yyscanner) == Initialization ||
+ yy_top_state(yyscanner) == ArrayInitializer)
+ {
+ yyextra->initializer+=yytext;
+ }
+ }
<*>\"|\' { /* string starts */
- if (YY_START == StrIgnore) { yyColNr -= (int)yyleng; REJECT; }; // ignore in simple comments
- yy_push_state(YY_START);
- if (yy_top_state() == Initialization
- || yy_top_state() == ArrayInitializer)
- initializer+=yytext;
- stringStartSymbol=yytext[0]; // single or double quote
+ if (YY_START == StrIgnore)
+ { yyextra->colNr -= (int)yyleng;
+ REJECT;
+ }; // ignore in simple yyextra->comments
+ yy_push_state(YY_START,yyscanner);
+ if (yy_top_state(yyscanner) == Initialization ||
+ yy_top_state(yyscanner) == ArrayInitializer)
+ {
+ yyextra->initializer+=yytext;
+ }
+ yyextra->stringStartSymbol=yytext[0]; // single or double quote
BEGIN(String);
}
- /*------ ignore simple comment (not documentation comments) */
+ /*------ ignore simple comment (not documentation yyextra->comments) */
-<*>"!"/[^<>\n] { if (YY_START == String) { yyColNr -= (int)yyleng; REJECT; } // "!" is ignored in strings
- // skip comment line (without docu comments "!>" "!<" )
- /* ignore further "!" and ignore comments in Strings */
+<*>"!"/[^<>\n] { if (YY_START == String)
+ { yyextra->colNr -= (int)yyleng;
+ REJECT;
+ } // "!" is ignored in strings
+ // skip comment line (without docu yyextra->comments "!>" "!<" )
+ /* ignore further "!" and ignore yyextra->comments in Strings */
if ((YY_START != StrIgnore) && (YY_START != String))
- {
- yy_push_state(YY_START);
+ {
+ yy_push_state(YY_START,yyscanner);
BEGIN(StrIgnore);
- debugStr="*!";
- DBG_CTX((stderr,"start comment %d\n",yyLineNr));
+ yyextra->debugStr="*!";
+ DBG_CTX((stderr,"start comment %d\n",yyextra->lineNr));
}
}
-<StrIgnore>.?/\n { yy_pop_state(); // comment ends with endline character
- DBG_CTX((stderr,"end comment %d %s\n",yyLineNr,debugStr.data()));
+<StrIgnore>.?/\n { yy_pop_state(yyscanner); // comment ends with endline character
+ DBG_CTX((stderr,"end comment %d %s\n",yyextra->lineNr,yyextra->debugStr.data()));
} // comment line ends
-<StrIgnore>. { debugStr+=yytext; }
+<StrIgnore>. { yyextra->debugStr+=yytext; }
/*------ use handling ------------------------------------------------------------*/
<Start,ModuleBody,SubprogBody>"use"{BS_} {
- if(YY_START == Start)
+ if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBody); //anon program
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBody,yyscanner); //anon program
}
- yy_push_state(Use);
+ yy_push_state(Use,yyscanner);
}
<Use>{ID} {
DBG_CTX((stderr,"using dir %s\n",yytext));
- current->name=yytext;
- current->fileName = yyFileName;
- current->section=Entry::USINGDIR_SEC;
- current_root->moveToSubEntryAndRefresh(current);
- current->lang = SrcLangExt_Fortran;
- yy_pop_state();
+ yyextra->current->name=yytext;
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->section=Entry::USINGDIR_SEC;
+ yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
+ yyextra->current->lang = SrcLangExt_Fortran;
+ yy_pop_state(yyscanner);
}
<Use>{ID}/, {
- useModuleName=yytext;
+ yyextra->useModuleName=yytext;
}
<Use>,{BS}"ONLY" { BEGIN(UseOnly);
}
<UseOnly>{BS},{BS} {}
<UseOnly>{ID} {
- current->name= useModuleName+"::"+yytext;
- current->fileName = yyFileName;
- current->section=Entry::USINGDECL_SEC;
- current_root->moveToSubEntryAndRefresh(current);
- current->lang = SrcLangExt_Fortran;
- }
+ yyextra->current->name= yyextra->useModuleName+"::"+yytext;
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->section=Entry::USINGDECL_SEC;
+ yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
+ yyextra->current->lang = SrcLangExt_Fortran;
+ }
<Use,UseOnly>"\n" {
- yyColNr -= 1;
+ yyextra->colNr -= 1;
unput(*yytext);
- yy_pop_state();
+ yy_pop_state(yyscanner);
}
/* INTERFACE definitions */
<Start,ModuleBody,SubprogBody>{
-^{BS}interface{IDSYM}+ { /* variable with interface prefix */ }
-^{BS}interface { ifType = IF_SPECIFIC;
- yy_push_state(InterfaceBody);
+^{BS}interface{IDSYM}+ { /* variable with interface prefix */ }
+^{BS}interface { yyextra->ifType = IF_SPECIFIC;
+ yy_push_state(InterfaceBody,yyscanner);
// do not start a scope here, every
// interface body is a scope of its own
}
-^{BS}abstract{BS_}interface { ifType = IF_ABSTRACT;
- yy_push_state(InterfaceBody);
+^{BS}abstract{BS_}interface { yyextra->ifType = IF_ABSTRACT;
+ yy_push_state(InterfaceBody,yyscanner);
// do not start a scope here, every
// interface body is a scope of its own
}
-^{BS}interface{BS_}{ID}{ARGS}? { ifType = IF_GENERIC;
- current->bodyLine = yyLineNr + lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account.
- yy_push_state(InterfaceBody);
+^{BS}interface{BS_}{ID}{ARGS}? { yyextra->ifType = IF_GENERIC;
+ yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account.
+ yy_push_state(InterfaceBody,yyscanner);
// extract generic name
QCString name = QCString(yytext).stripWhiteSpace();
name = name.right(name.length() - 9).stripWhiteSpace().lower();
- addInterface(name, ifType);
- startScope(last_entry.get());
+ addInterface(yyscanner,name, yyextra->ifType);
+ startScope(yyscanner,yyextra->last_entry.get());
}
}
<InterfaceBody>^{BS}end{BS}interface({BS_}{ID})? {
// end scope only if GENERIC interface
- if (ifType == IF_GENERIC) last_entry->parent()->endBodyLine = yyLineNr - 1;
- if (ifType == IF_GENERIC && !endScope(current_root))
+ if (yyextra->ifType == IF_GENERIC)
+ {
+ yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr - 1;
+ }
+ if (yyextra->ifType == IF_GENERIC && !endScope(yyscanner,yyextra->current_root))
+ {
yyterminate();
-
- ifType = IF_NONE;
- yy_pop_state();
+ }
+ yyextra->ifType = IF_NONE;
+ yy_pop_state(yyscanner);
}
-<InterfaceBody>module{BS}procedure { yy_push_state(YY_START);
+<InterfaceBody>module{BS}procedure { yy_push_state(YY_START,yyscanner);
BEGIN(ModuleProcedure);
}
-<ModuleProcedure>{ID} { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+<ModuleProcedure>{ID} { if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC)
{
- addInterface(yytext, ifType);
- startScope(last_entry.get());
+ addInterface(yyscanner,yytext, yyextra->ifType);
+ startScope(yyscanner,yyextra->last_entry.get());
}
- current->section = Entry::FUNCTION_SEC ;
- current->name = yytext;
- moduleProcedures.push_back(current);
- addCurrentEntry(true);
+ yyextra->current->section = Entry::FUNCTION_SEC ;
+ yyextra->current->name = yytext;
+ yyextra->moduleProcedures.push_back(yyextra->current);
+ addCurrentEntry(yyscanner,true);
}
-<ModuleProcedure>"\n" { yyColNr -= 1;
- unput(*yytext);
- yy_pop_state();
+<ModuleProcedure>"\n" { yyextra->colNr -= 1;
+ unput(*yytext);
+ yy_pop_state(yyscanner);
}
<InterfaceBody>. {}
/*-- Contains handling --*/
-<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) {
- if(YY_START == Start)
+<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) {
+ if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBodyContains); //anon program
- }
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBodyContains,yyscanner); //anon program
+ }
}
<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(ModuleBodyContains); }
<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(SubprogBodyContains); }
<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(TypedefBodyContains); }
/*------ module handling ------------------------------------------------------------*/
-<Start>block{BS}data{BS}{ID_} { //
- v_type = V_IGNORE;
- yy_push_state(BlockData);
- defaultProtection = Public;
- }
-<Start>module|program{BS_} { //
- v_type = V_IGNORE;
- if(yytext[0]=='m' || yytext[0]=='M')
- yy_push_state(Module);
- else
- yy_push_state(Program);
- defaultProtection = Public;
- }
+<Start>block{BS}data{BS}{ID_} { //
+ yyextra->vtype = V_IGNORE;
+ yy_push_state(BlockData,yyscanner);
+ yyextra->defaultProtection = Public;
+ }
+<Start>module|program{BS_} { //
+ yyextra->vtype = V_IGNORE;
+ if (yytext[0]=='m' || yytext[0]=='M')
+ {
+ yy_push_state(Module,yyscanner);
+ }
+ else
+ {
+ yy_push_state(Program,yyscanner);
+ }
+ yyextra->defaultProtection = Public;
+ }
<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!|;) { // end block data
- //if (!endScope(current_root))
- // yyterminate();
- defaultProtection = Public;
- yy_pop_state();
- }
+ //if (!endScope(yyscanner,yyextra->current_root))
+ // yyterminate();
+ yyextra->defaultProtection = Public;
+ yy_pop_state(yyscanner);
+ }
<Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module
- resolveModuleProcedures(current_root);
- if (!endScope(current_root))
- yyterminate();
- defaultProtection = Public;
- if (global_scope)
+ resolveModuleProcedures(yyscanner,yyextra->current_root);
+ if (!endScope(yyscanner,yyextra->current_root))
+ {
+ yyterminate();
+ }
+ yyextra->defaultProtection = Public;
+ if (yyextra->global_scope)
+ {
+ if (yyextra->global_scope != INVALID_ENTRY)
{
- if (global_scope != INVALID_ENTRY)
- yy_push_state(Start);
- else
- yy_pop_state(); // cannot pop artrificial entry
+ yy_push_state(Start,yyscanner);
}
else
{
- yy_push_state(Start);
- global_scope = INVALID_ENTRY; // signal that the global_scope has already been used.
+ yy_pop_state(yyscanner); // cannot pop artrificial entry
}
- }
-<Module>{ID} {
- addModule(yytext, TRUE);
- BEGIN(ModuleBody);
- }
-
+ }
+ else
+ {
+ yy_push_state(Start,yyscanner);
+ yyextra->global_scope = INVALID_ENTRY; // signal that the yyextra->global_scope has already been used.
+ }
+ }
+<Module>{ID} {
+ addModule(yyscanner,yytext, TRUE);
+ BEGIN(ModuleBody);
+ }
<Program>{ID} {
- addModule(yytext, FALSE);
- BEGIN(ModuleBody);
- }
+ addModule(yyscanner,yytext, FALSE);
+ BEGIN(ModuleBody);
+ }
/*------- access specification --------------------------------------------------------------------------*/
-<ModuleBody>private/{BS}(\n|"!") { defaultProtection = Private;
- current->protection = defaultProtection ;
- }
-<ModuleBody>public/{BS}(\n|"!") { defaultProtection = Public;
- current->protection = defaultProtection ;
- }
+<ModuleBody>private/{BS}(\n|"!") { yyextra->defaultProtection = Private;
+ yyextra->current->protection = yyextra->defaultProtection ;
+ }
+<ModuleBody>public/{BS}(\n|"!") { yyextra->defaultProtection = Public;
+ yyextra->current->protection = yyextra->defaultProtection ;
+ }
/*------- type definition -------------------------------------------------------------------------------*/
-<Start,ModuleBody>^{BS}type/[^a-z0-9_] {
- if(YY_START == Start)
+<Start,ModuleBody>^{BS}type/[^a-z0-9_] {
+ if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBody); //anon program
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBody,yyscanner); //anon program
}
- yy_push_state(Typedef);
- current->protection = defaultProtection;
- typeProtection = defaultProtection;
- typeMode = true;
+ yy_push_state(Typedef,yyscanner);
+ yyextra->current->protection = yyextra->defaultProtection;
+ yyextra->typeProtection = yyextra->defaultProtection;
+ yyextra->typeMode = true;
}
<Typedef>{
{COMMA} {}
@@ -615,100 +648,104 @@ SCOPENAME ({ID}{BS}"::"{BS})*
{BS}"::"{BS} {}
abstract {
- current->spec |= Entry::AbstractClass;
+ yyextra->current->spec |= Entry::AbstractClass;
}
extends{ARGS} {
QCString basename = extractFromParens(yytext).lower();
- current->extends.push_back(BaseInfo(basename, Public, Normal));
+ yyextra->current->extends.push_back(BaseInfo(basename, Public, Normal));
}
public {
- current->protection = Public;
- typeProtection = Public;
+ yyextra->current->protection = Public;
+ yyextra->typeProtection = Public;
}
private {
- current->protection = Private;
- typeProtection = Private;
+ yyextra->current->protection = Private;
+ yyextra->typeProtection = Private;
}
{LANGUAGE_BIND_SPEC} {
/* ignored for now */
}
{ID} { /* type name found */
- current->section = Entry::CLASS_SEC;
- current->spec |= Entry::Struct;
- current->name = yytext;
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr;
- current->startLine = yyLineNr;
+ yyextra->current->section = Entry::CLASS_SEC;
+ yyextra->current->spec |= Entry::Struct;
+ yyextra->current->name = yytext;
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->bodyLine = yyextra->lineNr;
+ yyextra->current->startLine = yyextra->lineNr;
/* if type is part of a module, mod name is necessary for output */
- if (current_root &&
- (current_root->section == Entry::CLASS_SEC
- || current_root->section == Entry::NAMESPACE_SEC))
+ if (yyextra->current_root &&
+ (yyextra->current_root->section == Entry::CLASS_SEC ||
+ yyextra->current_root->section == Entry::NAMESPACE_SEC))
{
- current->name = current_root->name + "::" + current->name;
+ yyextra->current->name = yyextra->current_root->name + "::" + yyextra->current->name;
}
- addCurrentEntry(true);
- startScope(last_entry.get());
+ addCurrentEntry(yyscanner,true);
+ startScope(yyscanner,yyextra->last_entry.get());
BEGIN(TypedefBody);
}
}
<TypedefBodyContains>{ /* Type Bound Procedures */
^{BS}PROCEDURE{ARGS}? {
- current->type = QCString(yytext).simplifyWhiteSpace();
+ yyextra->current->type = QCString(yytext).simplifyWhiteSpace();
}
^{BS}final {
- current->spec |= Entry::Final;
- current->type = QCString(yytext).simplifyWhiteSpace();
+ yyextra->current->spec |= Entry::Final;
+ yyextra->current->type = QCString(yytext).simplifyWhiteSpace();
}
^{BS}generic {
- current->type = QCString(yytext).simplifyWhiteSpace();
+ yyextra->current->type = QCString(yytext).simplifyWhiteSpace();
}
{COMMA} {
}
{ATTR_SPEC} {
- currentModifiers |= QCString(yytext);
+ yyextra->currentModifiers |= QCString(yytext);
}
{BS}"::"{BS} {
}
{ID} {
QCString name = yytext;
- modifiers[current_root][name.lower()] |= currentModifiers;
- current->section = Entry::FUNCTION_SEC;
- current->name = name;
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr;
- current->startLine = yyLineNr;
- addCurrentEntry(true);
+ yyextra->modifiers[yyextra->current_root][name.lower()] |= yyextra->currentModifiers;
+ yyextra->current->section = Entry::FUNCTION_SEC;
+ yyextra->current->name = name;
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->bodyLine = yyextra->lineNr;
+ yyextra->current->startLine = yyextra->lineNr;
+ addCurrentEntry(yyscanner,true);
}
{BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */
QCString args = yytext;
- last_entry->args = args.lower();
+ yyextra->last_entry->args = args.lower();
}
"\n" {
- currentModifiers = SymbolModifiers();
- newLine();
- docBlock.resize(0);
+ yyextra->currentModifiers = SymbolModifiers();
+ newLine(yyscanner);
+ yyextra->docBlock.resize(0);
}
}
<TypedefBody,TypedefBodyContains>{
^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!|;) { /* end type definition */
- last_entry->parent()->endBodyLine = yyLineNr;
- if (!endScope(current_root))
+ yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
+ if (!endScope(yyscanner,yyextra->current_root))
+ {
yyterminate();
- typeMode = false;
- yy_pop_state();
+ }
+ yyextra->typeMode = false;
+ yy_pop_state(yyscanner);
}
^{BS}"end"{BS}/(\n|!|;) { /* incorrect end type definition */
- warn(yyFileName,yyLineNr, "Found 'END' instead of 'END TYPE'");
- last_entry->parent()->endBodyLine = yyLineNr;
- if (!endScope(current_root))
+ warn(yyextra->fileName,yyextra->lineNr, "Found 'END' instead of 'END TYPE'");
+ yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
+ if (!endScope(yyscanner,yyextra->current_root))
+ {
yyterminate();
- typeMode = false;
- yy_pop_state();
+ }
+ yyextra->typeMode = false;
+ yy_pop_state(yyscanner);
}
}
@@ -720,603 +757,594 @@ private {
// in a scope of their own, even if multiple
// are group in one INTERFACE/END INTERFACE block.
//
- if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+ if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC)
{
- endScope(current_root);
- last_entry->endBodyLine = yyLineNr - 1;
+ endScope(yyscanner,yyextra->current_root);
+ yyextra->last_entry->endBodyLine = yyextra->lineNr - 1;
}
- current_root->endBodyLine = yyLineNr - 1;
+ yyextra->current_root->endBodyLine = yyextra->lineNr - 1;
- if (!endScope(current_root))
- yyterminate();
- subrCurrent.pop_back();
- yy_pop_state() ;
- }
+ if (!endScope(yyscanner,yyextra->current_root))
+ {
+ yyterminate();
+ }
+ yyextra->subrCurrent.pop_back();
+ yy_pop_state(yyscanner) ;
+ }
<BlockData>{
{ID} {
}
}
<Start,ModuleBody,TypedefBody,SubprogBody,Enum>{
^{BS}{TYPE_SPEC}/{SEPARATE} {
- last_enum.reset();
+ yyextra->last_enum.reset();
if (YY_START == Enum)
{
- argType = "@"; // enum marker
+ yyextra->argType = "@"; // enum marker
}
else
{
- argType = QCString(yytext).simplifyWhiteSpace().lower();
+ yyextra->argType = QCString(yytext).simplifyWhiteSpace().lower();
}
- current->bodyLine = yyLineNr + 1;
- current->endBodyLine = yyLineNr + lineCountPrepass;
+ yyextra->current->bodyLine = yyextra->lineNr + 1;
+ yyextra->current->endBodyLine = yyextra->lineNr + yyextra->lineCountPrepass;
/* variable declaration starts */
- if(YY_START == Start)
+ if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBody); //anon program
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBody,yyscanner); //anon program
}
- yy_push_state(AttributeList);
- }
- /* Dimitri: macro expansion should already be done during preprocessing not here!
-^{BS}{PP_ID}{KIND}? { // check for preprocessor symbol expand to type
- QCString str = yytext;
- str = str.stripWhiteSpace();
- //DefineDict* defines = getGlobalDefineDict();
- QCString name;
- int index = str.find("(");
- if (index != -1)
- name = str.left(index).stripWhiteSpace();
- else
- name = str;
-
- Define *define = 0; //(*defines)[name];
- if (define != 0 && isTypeName(define->definition))
- {
- argType = str;
- yy_push_state(AttributeList);
- }
- else
- {
- yyColNr -= (int)yyleng;
- REJECT;
- }
- }
- */
-{EXTERNAL_STMT}/({BS}"::"|{BS_}{ID}) {
+ yy_push_state(AttributeList,yyscanner);
+ }
+{EXTERNAL_STMT}/({BS}"::"|{BS_}{ID}) {
/* external can be a "type" or an attribute */
- if(YY_START == Start)
+ if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBody); //anon program
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBody,yyscanner); //anon program
}
QCString tmp = yytext;
- currentModifiers |= tmp.stripWhiteSpace();
- argType = QCString(yytext).simplifyWhiteSpace().lower();
- yy_push_state(AttributeList);
- }
-{ATTR_STMT}/{BS_}{ID} |
-{ATTR_STMT}/{BS}"::" {
+ yyextra->currentModifiers |= tmp.stripWhiteSpace();
+ yyextra->argType = QCString(yytext).simplifyWhiteSpace().lower();
+ yy_push_state(AttributeList,yyscanner);
+ }
+{ATTR_STMT}/{BS_}{ID} |
+{ATTR_STMT}/{BS}"::" {
/* attribute statement starts */
DBG_CTX((stderr,"5=========> Attribute statement: %s\n", yytext));
QCString tmp = yytext;
- currentModifiers |= tmp.stripWhiteSpace();
- argType="";
- yy_push_state(YY_START);
- BEGIN( AttributeList ) ;
- }
-{ID} {
- }
-^{BS}"type"{BS_}"is"/{BT_} { }
-^{BS}"type"{BS}"=" { }
-^{BS}"class"{BS_}"is"/{BT_} { }
-^{BS}"class"{BS_}"default" { }
+ yyextra->currentModifiers |= tmp.stripWhiteSpace();
+ yyextra->argType="";
+ yy_push_state(YY_START,yyscanner);
+ BEGIN( AttributeList ) ;
+ }
+{ID} {
+ }
+^{BS}"type"{BS_}"is"/{BT_} {}
+^{BS}"type"{BS}"=" {}
+^{BS}"class"{BS_}"is"/{BT_} {}
+^{BS}"class"{BS_}"default" {}
}
<AttributeList>{
-{COMMA} {}
-{BS} {}
+{COMMA} {}
+{BS} {}
{LANGUAGE_BIND_SPEC} {
- currentModifiers |= yytext;
+ yyextra->currentModifiers |= yytext;
}
-{ATTR_SPEC}. { /* update current modifiers when it is an ATTR_SPEC and not a variable name */
- /* bug_625519 */
+{ATTR_SPEC}. { /* update yyextra->current yyextra->modifiers when it is an ATTR_SPEC and not a variable name */
+ /* buyyextra->625519 */
QChar chr = yytext[(int)yyleng-1];
if (chr.isLetter() || chr.isDigit() || (chr == '_'))
{
- yyColNr -= (int)yyleng;
+ yyextra->colNr -= (int)yyleng;
REJECT;
}
else
{
QCString tmp = yytext;
tmp = tmp.left(tmp.length() - 1);
- yyColNr -= 1;
+ yyextra->colNr -= 1;
unput(yytext[(int)yyleng-1]);
- currentModifiers |= (tmp);
+ yyextra->currentModifiers |= (tmp);
}
- }
-"::" { /* end attribute list */
- BEGIN( Variable );
- }
-. { /* unknown attribute, consider variable name */
- //cout<<"start variables, unput "<<*yytext<<endl;
- yyColNr -= 1;
- unput(*yytext);
- BEGIN( Variable );
- }
+ }
+"::" { /* end attribute list */
+ BEGIN( Variable );
+ }
+. { /* unknown attribute, consider variable name */
+ //cout<<"start variables, unput "<<*yytext<<endl;
+ yyextra->colNr -= 1;
+ unput(*yytext);
+ BEGIN( Variable );
+ }
}
-<Variable>{BS} { }
-<Variable>{ID} { /* parse variable declaration */
- //cout << "5=========> got variable: " << argType << "::" << yytext << endl;
- /* work around for bug in QCString.replace (QCString works) */
- QCString name=yytext;
+<Variable>{BS} {}
+<Variable>{ID} { /* parse variable declaration */
+ //cout << "5=========> got variable: " << yyextra->argType << "::" << yytext << endl;
+ /* work around for bug in QCString.replace (QCString works) */
+ QCString name=yytext;
name = name.lower();
- /* remember attributes for the symbol */
- modifiers[current_root][name.lower()] |= currentModifiers;
- argName= name;
+ /* remember attributes for the symbol */
+ yyextra->modifiers[yyextra->current_root][name.lower()] |= yyextra->currentModifiers;
+ yyextra->argName= name;
- v_type= V_IGNORE;
- if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC)
+ yyextra->vtype= V_IGNORE;
+ if (!yyextra->argType.isEmpty() && yyextra->current_root->section!=Entry::FUNCTION_SEC)
{ // new variable entry
- v_type = V_VARIABLE;
- current->section = Entry::VARIABLE_SEC;
- current->name = argName;
- current->type = argType;
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr; // used for source reference
- current->startLine = yyLineNr;
- if (argType == "@")
+ yyextra->vtype = V_VARIABLE;
+ yyextra->current->section = Entry::VARIABLE_SEC;
+ yyextra->current->name = yyextra->argName;
+ yyextra->current->type = yyextra->argType;
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->bodyLine = yyextra->lineNr; // used for source reference
+ yyextra->current->startLine = yyextra->lineNr;
+ if (yyextra->argType == "@")
{
- current_root->copyToSubEntry(current);
+ yyextra->current_root->copyToSubEntry(yyextra->current);
// add to the scope surrounding the enum (copy!)
- last_enum = current;
- current_root->parent()->moveToSubEntryAndRefresh(current);
- initEntry();
+ yyextra->last_enum = yyextra->current;
+ yyextra->current_root->parent()->moveToSubEntryAndRefresh(yyextra->current);
+ initEntry(yyscanner);
}
else
{
- addCurrentEntry(true);
+ addCurrentEntry(yyscanner,true);
+ }
+ }
+ else if (!yyextra->argType.isEmpty())
+ { // declaration of parameter list: add type for corr. parameter
+ Argument *parameter = getParameter(yyscanner,yyextra->argName);
+ if (parameter)
+ {
+ yyextra->vtype= V_PARAMETER;
+ if (!yyextra->argType.isNull()) parameter->type=yyextra->argType.stripWhiteSpace();
+ if (!yyextra->docBlock.isNull())
+ {
+ subrHandleCommentBlock(yyscanner,yyextra->docBlock,TRUE);
+ }
+ }
+ // save, it may be function return type
+ if (parameter)
+ {
+ yyextra->modifiers[yyextra->current_root][name.lower()].type = yyextra->argType;
+ }
+ else
+ {
+ if ((yyextra->current_root->name.lower() == yyextra->argName.lower()) ||
+ (yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower()].returnName.lower() == yyextra->argName.lower()))
+ {
+ int strt = yyextra->current_root->type.find("function");
+ QCString lft;
+ QCString rght;
+ if (strt != -1)
+ {
+ yyextra->vtype = V_RESULT;
+ lft = "";
+ rght = "";
+ if (strt != 0) lft = yyextra->current_root->type.left(strt).stripWhiteSpace();
+ if ((yyextra->current_root->type.length() - strt - strlen("function"))!= 0)
+ {
+ rght = yyextra->current_root->type.right(yyextra->current_root->type.length() - strt - strlen("function")).stripWhiteSpace();
+ }
+ yyextra->current_root->type = lft;
+ if (rght.length() > 0)
+ {
+ if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " ";
+ yyextra->current_root->type += rght;
+ }
+ if (yyextra->argType.stripWhiteSpace().length() > 0)
+ {
+ if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " ";
+ yyextra->current_root->type += yyextra->argType.stripWhiteSpace();
+ }
+ if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " ";
+ yyextra->current_root->type += "function";
+ if (!yyextra->docBlock.isNull())
+ {
+ subrHandleCommentBlockResult(yyscanner,yyextra->docBlock,TRUE);
+ }
+ }
+ else
+ {
+ yyextra->current_root->type += " " + yyextra->argType.stripWhiteSpace();
+ }
+ yyextra->current_root->type = yyextra->current_root->type.stripWhiteSpace();
+ yyextra->modifiers[yyextra->current_root][name.lower()].type = yyextra->current_root->type;
+ }
+ else
+ {
+ yyextra->modifiers[yyextra->current_root][name.lower()].type = yyextra->argType;
+ }
}
+ // any accumulated doc for argument should be emptied,
+ // because it is handled other way and this doc can be
+ // unexpectedly passed to the next member.
+ yyextra->current->doc.resize(0);
+ yyextra->current->brief.resize(0);
}
- else if (!argType.isEmpty())
- { // declaration of parameter list: add type for corr. parameter
- parameter = getParameter(argName);
- if (parameter)
- {
- v_type= V_PARAMETER;
- if (!argType.isNull()) parameter->type=argType.stripWhiteSpace();
- if (!docBlock.isNull())
- {
- subrHandleCommentBlock(docBlock,TRUE);
- }
- }
- // save, it may be function return type
- if (parameter)
- {
- modifiers[current_root][name.lower()].type = argType;
- }
- else
- {
- if ((current_root->name.lower() == argName.lower()) ||
- (modifiers[current_root->parent()][current_root->name.lower()].returnName.lower() == argName.lower()))
- {
- int strt = current_root->type.find("function");
- QCString lft;
- QCString rght;
- if (strt != -1)
- {
- v_type = V_RESULT;
- lft = "";
- rght = "";
- if (strt != 0) lft = current_root->type.left(strt).stripWhiteSpace();
- if ((current_root->type.length() - strt - strlen("function"))!= 0)
- {
- rght = current_root->type.right(current_root->type.length() - strt - strlen("function")).stripWhiteSpace();
- }
- current_root->type = lft;
- if (rght.length() > 0)
- {
- if (current_root->type.length() > 0) current_root->type += " ";
- current_root->type += rght;
- }
- if (argType.stripWhiteSpace().length() > 0)
- {
- if (current_root->type.length() > 0) current_root->type += " ";
- current_root->type += argType.stripWhiteSpace();
- }
- if (current_root->type.length() > 0) current_root->type += " ";
- current_root->type += "function";
- if (!docBlock.isNull())
- {
- subrHandleCommentBlockResult(docBlock,TRUE);
- }
- }
- else
- {
- current_root->type += " " + argType.stripWhiteSpace();
- }
- current_root->type = current_root->type.stripWhiteSpace();
- modifiers[current_root][name.lower()].type = current_root->type;
- }
- else
- {
- modifiers[current_root][name.lower()].type = argType;
- }
- }
- // any accumulated doc for argument should be emptied,
- // because it is handled other way and this doc can be
- // unexpectedly passed to the next member.
- current->doc.resize(0);
- current->brief.resize(0);
- }
- }
-<Variable>{ARGS} { /* dimension of the previous entry. */
- QCString name(argName);
- QCString attr("dimension");
- attr += yytext;
- modifiers[current_root][name.lower()] |= attr;
- }
-<Variable>{COMMA} { //printf("COMMA: %d<=..<=%d\n", yyColNr-(int)yyleng, yyColNr);
- // locate !< comment
- updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr);
- }
+ }
+<Variable>{ARGS} { /* dimension of the previous entry. */
+ QCString name(yyextra->argName);
+ QCString attr("dimension");
+ attr += yytext;
+ yyextra->modifiers[yyextra->current_root][name.lower()] |= attr;
+ }
+<Variable>{COMMA} { //printf("COMMA: %d<=..<=%d\n", yyextra->colNr-(int)yyleng, yyextra->colNr);
+ // locate !< comment
+ updateVariablePrepassComment(yyscanner,yyextra->colNr-(int)yyleng, yyextra->colNr);
+ }
<Variable>{BS}"=" {
- yy_push_state(YY_START);
- initializer="=";
- initializerScope = initializerArrayScope = 0;
- BEGIN(Initialization);
- }
-<Variable>"\n" { currentModifiers = SymbolModifiers();
- yy_pop_state(); // end variable declaration list
- newLine();
- docBlock.resize(0);
- }
-<Variable>";".*"\n" { currentModifiers = SymbolModifiers();
- yy_pop_state(); // end variable declaration list
- docBlock.resize(0);
- inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data();
- yyLineNr--;
- pushBuffer(inputStringSemi);
+ yy_push_state(YY_START,yyscanner);
+ yyextra->initializer="=";
+ yyextra->initializerScope = yyextra->initializerArrayScope = 0;
+ BEGIN(Initialization);
+ }
+<Variable>"\n" { yyextra->currentModifiers = SymbolModifiers();
+ yy_pop_state(yyscanner); // end variable declaration list
+ newLine(yyscanner);
+ yyextra->docBlock.resize(0);
+ }
+<Variable>";".*"\n" { yyextra->currentModifiers = SymbolModifiers();
+ yy_pop_state(yyscanner); // end variable declaration list
+ yyextra->docBlock.resize(0);
+ yyextra->inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data();
+ yyextra->lineNr--;
+ pushBuffer(yyscanner,yyextra->inputStringSemi);
}
<*>";".*"\n" {
- if (YY_START == Variable) REJECT; // Just be on the safe side
+ if (YY_START == Variable) REJECT; // Just be on the safe side
if (YY_START == String) REJECT; // ";" ignored in strings
- if (YY_START == StrIgnore) REJECT; // ";" ignored in regular comments
- inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data();
- yyLineNr--;
- pushBuffer(inputStringSemi);
+ if (YY_START == StrIgnore) REJECT; // ";" ignored in regular yyextra->comments
+ yyextra->inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data();
+ yyextra->lineNr--;
+ pushBuffer(yyscanner,yyextra->inputStringSemi);
}
<Initialization,ArrayInitializer>"[" |
-<Initialization,ArrayInitializer>"(/" { initializer+=yytext;
- initializerArrayScope++;
- BEGIN(ArrayInitializer); // initializer may contain comma
+<Initialization,ArrayInitializer>"(/" { yyextra->initializer+=yytext;
+ yyextra->initializerArrayScope++;
+ BEGIN(ArrayInitializer); // initializer may contain comma
}
<ArrayInitializer>"]" |
-<ArrayInitializer>"/)" { initializer+=yytext;
- initializerArrayScope--;
- if(initializerArrayScope<=0)
- {
- initializerArrayScope = 0; // just in case
- BEGIN(Initialization);
- }
+<ArrayInitializer>"/)" { yyextra->initializer+=yytext;
+ yyextra->initializerArrayScope--;
+ if (yyextra->initializerArrayScope<=0)
+ {
+ yyextra->initializerArrayScope = 0; // just in case
+ BEGIN(Initialization);
+ }
}
-<ArrayInitializer>. { initializer+=yytext; }
-<Initialization>"(" { initializerScope++;
- initializer+=yytext;
- }
-<Initialization>")" { initializerScope--;
- initializer+=yytext;
- }
-<Initialization>{COMMA} { if (initializerScope == 0)
- {
- updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr);
- yy_pop_state(); // end initialization
- if (last_enum)
+<ArrayInitializer>. { yyextra->initializer+=yytext; }
+<Initialization>"(" { yyextra->initializerScope++;
+ yyextra->initializer+=yytext;
+ }
+<Initialization>")" { yyextra->initializerScope--;
+ yyextra->initializer+=yytext;
+ }
+<Initialization>{COMMA} { if (yyextra->initializerScope == 0)
+ {
+ updateVariablePrepassComment(yyscanner,yyextra->colNr-(int)yyleng, yyextra->colNr);
+ yy_pop_state(yyscanner); // end initialization
+ if (yyextra->last_enum)
{
- last_enum->initializer= initializer;
+ yyextra->last_enum->initializer= yyextra->initializer;
}
else
{
- if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ if (yyextra->vtype == V_VARIABLE) yyextra->last_entry->initializer= yyextra->initializer;
}
- }
- else
- initializer+=", ";
- }
+ }
+ else
+ {
+ yyextra->initializer+=", ";
+ }
+ }
<Initialization>"\n"|"!" { //|
- yy_pop_state(); // end initialization
- if (last_enum)
+ yy_pop_state(yyscanner); // end initialization
+ if (yyextra->last_enum)
{
- last_enum->initializer= initializer;
+ yyextra->last_enum->initializer= yyextra->initializer;
}
else
{
- if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ if (yyextra->vtype == V_VARIABLE) yyextra->last_entry->initializer= yyextra->initializer;
}
- yyColNr -= 1;
- unput(*yytext);
+ yyextra->colNr -= 1;
+ unput(*yytext);
}
-<Initialization>. { initializer+=yytext; }
+<Initialization>. { yyextra->initializer+=yytext; }
<*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} {
- if(YY_START == Start)
+ if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBody); //anon program
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBody,yyscanner); //anon program
}
- yy_push_state(Enum);
- current->protection = defaultProtection;
- typeProtection = defaultProtection;
- typeMode = true;
-
- current->spec |= Entry::Struct;
- current->name.resize(0);
- current->args.resize(0);
- current->name.sprintf("@%d",anonCount++);
-
- current->section = Entry::ENUM_SEC;
- current->fileName = yyFileName;
- current->startLine = yyLineNr;
- current->bodyLine = yyLineNr;
- if ((current_root) &&
- (current_root->section == Entry::CLASS_SEC
- || current_root->section == Entry::NAMESPACE_SEC))
+ yy_push_state(Enum,yyscanner);
+ yyextra->current->protection = yyextra->defaultProtection;
+ yyextra->typeProtection = yyextra->defaultProtection;
+ yyextra->typeMode = true;
+
+ yyextra->current->spec |= Entry::Struct;
+ yyextra->current->name.resize(0);
+ yyextra->current->args.resize(0);
+ yyextra->current->name.sprintf("@%d",yyextra->anonCount++);
+
+ yyextra->current->section = Entry::ENUM_SEC;
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->startLine = yyextra->lineNr;
+ yyextra->current->bodyLine = yyextra->lineNr;
+ if ((yyextra->current_root) &&
+ (yyextra->current_root->section == Entry::CLASS_SEC ||
+ yyextra->current_root->section == Entry::NAMESPACE_SEC))
{
- current->name = current_root->name + "::" + current->name;
+ yyextra->current->name = yyextra->current_root->name + "::" + yyextra->current->name;
}
- addCurrentEntry(true);
- startScope(last_entry.get());
- BEGIN( Enum ) ;
+ addCurrentEntry(yyscanner,true);
+ startScope(yyscanner,yyextra->last_entry.get());
+ BEGIN( Enum ) ;
}
<Enum>"end"{BS}"enum" {
- last_entry->parent()->endBodyLine = yyLineNr;
- if (!endScope(current_root))
+ yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
+ if (!endScope(yyscanner,yyextra->current_root))
+ {
yyterminate();
- typeMode = false;
- yy_pop_state();
+ }
+ yyextra->typeMode = false;
+ yy_pop_state(yyscanner);
}
/*------ fortran subroutine/function handling ------------------------------------------------------------*/
/* Start is initial condition */
<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}({PREFIX}{BS_})?/{SUBPROG}{BS_} {
- if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
- {
- addInterface("$interface$", ifType);
- startScope(last_entry.get());
- }
+ if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC)
+ {
+ addInterface(yyscanner,"$interface$", yyextra->ifType);
+ startScope(yyscanner,yyextra->last_entry.get());
+ }
+
+ // TYPE_SPEC is for old function style function result
+ QCString result = QCString(yytext).stripWhiteSpace().lower();
+ yyextra->current->type = result;
+ yy_push_state(SubprogPrefix,yyscanner);
+ }
- // TYPE_SPEC is for old function style function result
- result = QCString(yytext).stripWhiteSpace().lower();
- current->type = result;
- yy_push_state(SubprogPrefix);
- }
-
-<SubprogPrefix>{BS}{SUBPROG}{BS_} {
- // Fortran subroutine or function found
- v_type = V_IGNORE;
- result=yytext;
- result=result.stripWhiteSpace();
- addSubprogram(result);
- BEGIN(Subprog);
- current->bodyLine = yyLineNr + lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account.
- current->startLine = yyLineNr;
- }
+<SubprogPrefix>{BS}{SUBPROG}{BS_} {
+ // Fortran subroutine or function found
+ yyextra->vtype = V_IGNORE;
+ QCString result=yytext;
+ result=result.stripWhiteSpace();
+ addSubprogram(yyscanner,result);
+ BEGIN(Subprog);
+ yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account.
+ yyextra->current->startLine = yyextra->lineNr;
+ }
<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{SUBPROG}{BS_} {
- // Fortran subroutine or function found
- v_type = V_IGNORE;
- if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
- {
- addInterface("$interface$", ifType);
- startScope(last_entry.get());
- }
+ // Fortran subroutine or function found
+ yyextra->vtype = V_IGNORE;
+ if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC)
+ {
+ addInterface(yyscanner,"$interface$", yyextra->ifType);
+ startScope(yyscanner,yyextra->last_entry.get());
+ }
+
+ QCString result = QCString(yytext).stripWhiteSpace();
+ addSubprogram(yyscanner,result);
+ yy_push_state(Subprog,yyscanner);
+ yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account.
+ yyextra->current->startLine = yyextra->lineNr;
+ }
+
+<Subprog>{BS} { /* ignore white space */ }
+<Subprog>{ID} { yyextra->current->name = yytext;
+ //cout << "1a==========> got " << yyextra->current->type << " " << yytext << " " << yyextra->lineNr << endl;
+ yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower()].returnName = yyextra->current->name.lower();
- result = QCString(yytext).stripWhiteSpace();
- addSubprogram(result);
- yy_push_state(Subprog);
- current->bodyLine = yyLineNr + lineCountPrepass + 1; // we have to be at the line after the definition and we have to take continuation lines into account.
- current->startLine = yyLineNr;
- }
-
-<Subprog>{BS} { /* ignore white space */ }
-<Subprog>{ID} { current->name = yytext;
- //cout << "1a==========> got " << current->type << " " << yytext << " " << yyLineNr << endl;
- modifiers[current_root][current->name.lower()].returnName = current->name.lower();
-
- if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
- {
- current_root->name.replace(QRegExp("\\$interface\\$"), yytext);
+ if (yyextra->ifType == IF_ABSTRACT || yyextra->ifType == IF_SPECIFIC)
+ {
+ yyextra->current_root->name.replace(QRegExp("\\$interface\\$"), yytext);
+ }
+
+ BEGIN(Parameterlist);
+ }
+<Parameterlist>"(" { yyextra->current->args = "("; }
+<Parameterlist>")" {
+ yyextra->current->args += ")";
+ yyextra->current->args = removeRedundantWhiteSpace(yyextra->current->args);
+ addCurrentEntry(yyscanner,true);
+ startScope(yyscanner,yyextra->last_entry.get());
+ BEGIN(SubprogBody);
+ }
+<Parameterlist>{COMMA}|{BS} { yyextra->current->args += yytext;
+ CommentInPrepass *c = locatePrepassComment(yyscanner,yyextra->colNr-(int)yyleng, yyextra->colNr);
+ if (c!=NULL)
+ {
+ if (!yyextra->current->argList.empty())
+ {
+ yyextra->current->argList.back().docs = c->str;
+ }
+ }
+ }
+<Parameterlist>{ID} {
+ //yyextra->current->type not yet available
+ QCString param = yytext;
+ // std::cout << "3=========> got parameter " << param << std::endl;
+ yyextra->current->args += param;
+ Argument arg;
+ arg.name = param;
+ yyextra->current->argList.push_back(arg);
+ }
+<Parameterlist>{NOARGS} {
+ newLine(yyscanner);
+ //printf("3=========> without parameterlist \n");
+ addCurrentEntry(yyscanner,true);
+ startScope(yyscanner,yyextra->last_entry.get());
+ BEGIN(SubprogBody);
+ }
+<SubprogBody>result{BS}\({BS}{ID} {
+ if (yyextra->functionLine)
+ {
+ QCString result= yytext;
+ result= result.right(result.length()-result.find("(")-1);
+ result= result.stripWhiteSpace();
+ yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower()].returnName = result;
+ }
+ //cout << "=====> got result " << result << endl;
}
- BEGIN(Parameterlist);
- }
-<Parameterlist>"(" { current->args = "("; }
-<Parameterlist>")" {
- current->args += ")";
- current->args = removeRedundantWhiteSpace(current->args);
- addCurrentEntry(true);
- startScope(last_entry.get());
- BEGIN(SubprogBody);
- }
-<Parameterlist>{COMMA}|{BS} { current->args += yytext;
- CommentInPrepass *c = locatePrepassComment(yyColNr-(int)yyleng, yyColNr);
- if (c!=NULL)
- {
- if (!current->argList.empty())
- {
- current->argList.back().docs = c->str;
- }
- }
- }
-<Parameterlist>{ID} {
- //current->type not yet available
- QCString param = yytext;
- // std::cout << "3=========> got parameter " << param << std::endl;
- current->args += param;
- Argument arg;
- arg.name = param;
- current->argList.push_back(arg);
- }
-<Parameterlist>{NOARGS} {
- newLine();
- //printf("3=========> without parameterlist \n");
- addCurrentEntry(true);
- startScope(last_entry.get());
- BEGIN(SubprogBody);
-}
-<SubprogBody>result{BS}\({BS}{ID} {
- if (functionLine)
- {
- result= yytext;
- result= result.right(result.length()-result.find("(")-1);
- result= result.stripWhiteSpace();
- modifiers[current_root->parent()][current_root->name.lower()].returnName = result;
- }
- //cout << "=====> got result " << result << endl;
- }
-
- /*---- documentation comments --------------------------------------------------------------------*/
+ /*---- documentation yyextra->comments --------------------------------------------------------------------*/
<Variable,SubprogBody,ModuleBody,TypedefBody,TypedefBodyContains>"!<" { /* backward docu comment */
- if (v_type != V_IGNORE) {
- current->docLine = yyLineNr;
- docBlockJavaStyle = FALSE;
- docBlock.resize(0);
- docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF);
- startCommentBlock(TRUE);
- yy_push_state(DocBackLine);
+ if (yyextra->vtype != V_IGNORE)
+ {
+ yyextra->current->docLine = yyextra->lineNr;
+ yyextra->docBlockJavaStyle = FALSE;
+ yyextra->docBlock.resize(0);
+ yyextra->docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF);
+ startCommentBlock(yyscanner,TRUE);
+ yy_push_state(DocBackLine,yyscanner);
}
else
{
/* handle out of place !< comment as a normal comment */
- if (YY_START == String) { yyColNr -= (int)yyleng; REJECT; } // "!" is ignored in strings
- // skip comment line (without docu comments "!>" "!<" )
- /* ignore further "!" and ignore comments in Strings */
- if ((YY_START != StrIgnore) && (YY_START != String))
- {
- yy_push_state(YY_START);
- BEGIN(StrIgnore);
- debugStr="*!";
- }
+ if (YY_START == String)
+ {
+ yyextra->colNr -= (int)yyleng;
+ REJECT;
+ } // "!" is ignored in strings
+ // skip comment line (without docu yyextra->comments "!>" "!<" )
+ /* ignore further "!" and ignore yyextra->comments in Strings */
+ if ((YY_START != StrIgnore) && (YY_START != String))
+ {
+ yy_push_state(YY_START,yyscanner);
+ BEGIN(StrIgnore);
+ yyextra->debugStr="*!";
+ }
}
- }
-<DocBackLine>.* { // contents of current comment line
- docBlock+=yytext;
- }
-<DocBackLine>"\n"{BS}"!"("<"|"!"+) { // comment block (next line is also comment line)
- docBlock+="\n"; // \n is necessary for lists
- newLine();
- }
-<DocBackLine>"\n" { // comment block ends at the end of this line
- //cout <<"3=========> comment block : "<< docBlock << endl;
- yyColNr -= 1;
- unput(*yytext);
- if (v_type == V_VARIABLE)
- {
- std::shared_ptr<Entry> tmp_entry = current;
+ }
+<DocBackLine>.* { // contents of yyextra->current comment line
+ yyextra->docBlock+=yytext;
+ }
+<DocBackLine>"\n"{BS}"!"("<"|"!"+) { // comment block (next line is also comment line)
+ yyextra->docBlock+="\n"; // \n is necessary for lists
+ newLine(yyscanner);
+ }
+<DocBackLine>"\n" { // comment block ends at the end of this line
+ //cout <<"3=========> comment block : "<< yyextra->docBlock << endl;
+ yyextra->colNr -= 1;
+ unput(*yytext);
+ if (yyextra->vtype == V_VARIABLE)
+ {
+ std::shared_ptr<Entry> tmp_entry = yyextra->current;
// temporarily switch to the previous entry
- if (last_enum)
+ if (yyextra->last_enum)
{
- current = last_enum;
+ yyextra->current = yyextra->last_enum;
}
else
{
- current = last_entry;
+ yyextra->current = yyextra->last_entry;
}
- handleCommentBlock(docBlock,TRUE);
+ handleCommentBlock(yyscanner,yyextra->docBlock,TRUE);
// switch back
- current = tmp_entry;
+ yyextra->current = tmp_entry;
}
- else if (v_type == V_PARAMETER)
- {
- subrHandleCommentBlock(docBlock,TRUE);
+ else if (yyextra->vtype == V_PARAMETER)
+ {
+ subrHandleCommentBlock(yyscanner,yyextra->docBlock,TRUE);
}
- else if (v_type == V_RESULT)
- {
- subrHandleCommentBlockResult(docBlock,TRUE);
+ else if (yyextra->vtype == V_RESULT)
+ {
+ subrHandleCommentBlockResult(yyscanner,yyextra->docBlock,TRUE);
}
- yy_pop_state();
- docBlock.resize(0);
+ yy_pop_state(yyscanner);
+ yyextra->docBlock.resize(0);
}
<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,Enum>"!>" {
- yy_push_state(YY_START);
- current->docLine = yyLineNr;
- docBlockJavaStyle = FALSE;
- if (YY_START==SubprogBody) docBlockInBody = TRUE;
- docBlock.resize(0);
- docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF);
- startCommentBlock(TRUE);
- BEGIN(DocBlock);
+ yy_push_state(YY_START,yyscanner);
+ yyextra->current->docLine = yyextra->lineNr;
+ yyextra->docBlockJavaStyle = FALSE;
+ if (YY_START==SubprogBody) yyextra->docBlockInBody = TRUE;
+ yyextra->docBlock.resize(0);
+ yyextra->docBlockJavaStyle = Config_getBool(JAVADOC_AUTOBRIEF);
+ startCommentBlock(yyscanner,TRUE);
+ BEGIN(DocBlock);
//cout << "start DocBlock " << endl;
- }
-
-<DocBlock>.* { // contents of current comment line
- docBlock+=yytext;
- }
-<DocBlock>"\n"{BS}"!"(">"|"!"+) { // comment block (next line is also comment line)
- docBlock+="\n"; // \n is necessary for lists
- newLine();
- }
-<DocBlock>"\n" { // comment block ends at the end of this line
- //cout <<"3=========> comment block : "<< docBlock << endl;
- yyColNr -= 1;
- unput(*yytext);
- handleCommentBlock(docBlock,TRUE);
- yy_pop_state();
- }
+ }
+
+<DocBlock>.* { // contents of yyextra->current comment line
+ yyextra->docBlock+=yytext;
+ }
+<DocBlock>"\n"{BS}"!"(">"|"!"+) { // comment block (next line is also comment line)
+ yyextra->docBlock+="\n"; // \n is necessary for lists
+ newLine(yyscanner);
+ }
+<DocBlock>"\n" { // comment block ends at the end of this line
+ //cout <<"3=========> comment block : "<< yyextra->docBlock << endl;
+ yyextra->colNr -= 1;
+ unput(*yytext);
+ handleCommentBlock(yyscanner,yyextra->docBlock,TRUE);
+ yy_pop_state(yyscanner);
+ }
/*-----Prototype parsing -------------------------------------------------------------------------*/
-<Prototype>{BS}{SUBPROG}{BS_} {
- BEGIN(PrototypeSubprog);
- }
+<Prototype>{BS}{SUBPROG}{BS_} {
+ BEGIN(PrototypeSubprog);
+ }
<Prototype,PrototypeSubprog>{BS}{SCOPENAME}?{BS}{ID} {
- current->name = QCString(yytext).lower();
- current->name.stripWhiteSpace();
- BEGIN(PrototypeArgs);
- }
+ yyextra->current->name = QCString(yytext).lower();
+ yyextra->current->name.stripWhiteSpace();
+ BEGIN(PrototypeArgs);
+ }
<PrototypeArgs>{
-"("|")"|","|{BS_} { current->args += yytext; }
-{ID} { current->args += yytext;
- Argument a;
- a.name = QCString(yytext).lower();
- current->argList.push_back(a);
- }
+"("|")"|","|{BS_} { yyextra->current->args += yytext; }
+{ID} { yyextra->current->args += yytext;
+ Argument a;
+ a.name = QCString(yytext).lower();
+ yyextra->current->argList.push_back(a);
+ }
}
/*------------------------------------------------------------------------------------------------*/
<*>"\n" {
- newLine();
- //if (debugStr.stripWhiteSpace().length() > 0) cout << "ignored text: " << debugStr << " state: " <<YY_START << endl;
- debugStr="";
+ newLine(yyscanner);
+ //if (yyextra->debugStr.stripWhiteSpace().length() > 0) cout << "ignored text: " << yyextra->debugStr << " state: " <<YY_START << endl;
+ yyextra->debugStr="";
}
/*---- error: EOF in wrong state --------------------------------------------------------------------*/
<*><<EOF>> {
- if (parsingPrototype) {
- yyterminate();
-
- } else if ( include_stack_ptr <= 0 ) {
- if (YY_START!=INITIAL && YY_START!=Start) {
+ if (yyextra->parsingPrototype)
+ {
+ yyterminate();
+ }
+ else if ( yyextra->includeStackPtr <= 0 )
+ {
+ if (YY_START!=INITIAL && YY_START!=Start)
+ {
DBG_CTX((stderr,"==== Error: EOF reached in wrong state (end missing)"));
- scanner_abort();
+ scanner_abort(yyscanner);
}
yyterminate();
- } else {
- popBuffer();
+ }
+ else
+ {
+ popBuffer(yyscanner);
}
}
<*>{LOG_OPER} { // Fortran logical comparison keywords
}
-<*>. {
- //debugStr+=yytext;
- //printf("I:%c\n", *yytext);
+<*>. {
+ //yyextra->debugStr+=yytext;
+ //printf("I:%c\n", *yytext);
} // ignore remaining text
/**********************************************************************************/
@@ -1325,63 +1353,53 @@ private {
%%
//----------------------------------------------------------------------------
-#if 0
-static void extractPrefix(QCString &text)
+static void newLine(yyscan_t yyscanner)
{
- int prefixIndex = 0;
- int curIndex = 0;
- bool cont = TRUE;
- const char* pre[] = {"RECURSIVE","IMPURE","PURE","ELEMENTAL"};
- while(cont)
- {
- cont = FALSE;
- for(unsigned int i=0; i<4; i++)
- {
- if((prefixIndex=text.find(pre[i], curIndex, FALSE))==0)
- {
- text.remove(0,strlen(pre[i]));
- text.stripWhiteSpace();
- cont = TRUE;
- }
- }
- }
-}
-#endif
-
-static void newLine() {
- yyLineNr++;
- yyLineNr+=lineCountPrepass;
- lineCountPrepass=0;
- comments.clear();
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ yyextra->lineNr++;
+ yyextra->lineNr+=yyextra->lineCountPrepass;
+ yyextra->lineCountPrepass=0;
+ yyextra->comments.clear();
}
-static CommentInPrepass* locatePrepassComment(int from, int to) {
+static CommentInPrepass* locatePrepassComment(yyscan_t yyscanner,int from, int to)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
//printf("Locate %d-%d\n", from, to);
- for(uint i=0; i<comments.count(); i++) { // todo: optimize
- int c = comments.at(i)->column;
+ for (uint i=0; i<yyextra->comments.count(); i++)
+ { // todo: optimize
+ int c = yyextra->comments.at(i)->column;
//printf("Candidate %d\n", c);
- if (c>=from && c<=to) {
+ if (c>=from && c<=to)
+ {
// comment for previous variable or parameter
- return comments.at(i);
+ return yyextra->comments.at(i);
}
}
return NULL;
}
-static void updateVariablePrepassComment(int from, int to) {
- CommentInPrepass *c = locatePrepassComment(from, to);
- if (c!=NULL && v_type == V_VARIABLE) {
- last_entry->brief = c->str;
- } else if (c!=NULL && v_type == V_PARAMETER) {
- Argument *parameter = getParameter(argName);
+static void updateVariablePrepassComment(yyscan_t yyscanner,int from, int to)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ CommentInPrepass *c = locatePrepassComment(yyscanner,from, to);
+ if (c!=NULL && yyextra->vtype == V_VARIABLE)
+ {
+ yyextra->last_entry->brief = c->str;
+ }
+ else if (c!=NULL && yyextra->vtype == V_PARAMETER)
+ {
+ Argument *parameter = getParameter(yyscanner,yyextra->argName);
if (parameter) parameter->docs = c->str;
}
}
static int getAmpersandAtTheStart(const char *buf, int length)
{
- for(int i=0; i<length; i++) {
- switch(buf[i]) {
+ for(int i=0; i<length; i++)
+ {
+ switch(buf[i])
+ {
case ' ':
case '\t':
break;
@@ -1397,7 +1415,7 @@ static int getAmpersandAtTheStart(const char *buf, int length)
/* Returns ampersand index, comment start index or -1 if neither exist.*/
static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
{
- // Avoid ampersands in string and comments
+ // Avoid ampersands in string and yyextra->comments
int parseState = Start;
char quoteSymbol = 0;
int ampIndex = -1;
@@ -1409,9 +1427,9 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
{
// When in string, skip backslashes
// Legacy code, not sure whether this is correct?
- if(parseState==String)
+ if (parseState==String)
{
- if(buf[i]=='\\') i++;
+ if (buf[i]=='\\') i++;
}
switch(buf[i])
@@ -1420,13 +1438,13 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
case '"':
// Close string, if quote symbol matches.
// Quote symbol is set iff parseState==String
- if(buf[i]==quoteSymbol)
+ if (buf[i]==quoteSymbol)
{
parseState = Start;
quoteSymbol = 0;
}
// Start new string, if not already in string or comment
- else if(parseState==Start)
+ else if (parseState==Start)
{
parseState = String;
quoteSymbol = buf[i];
@@ -1435,7 +1453,7 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
break;
case '!':
// When in string or comment, ignore exclamation mark
- if(parseState==Start)
+ if (parseState==Start)
{
parseState = Comment;
commentIndex = i;
@@ -1459,19 +1477,20 @@ static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
return commentIndex;
}
-/* Although comments at the end of continuation line are grabbed by this function,
+/* Although yyextra->comments at the end of continuation line are grabbed by this function,
* we still do not know how to use them later in parsing.
*/
-void truncatePrepass(int index)
+void truncatePrepass(yyscan_t yyscanner,int index)
{
- int length = inputStringPrepass.length();
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ int length = yyextra->inputStringPrepass.length();
for (int i=index+1; i<length; i++) {
- if (inputStringPrepass[i]=='!' && i<length-1 && inputStringPrepass[i+1]=='<') { // save comment
- struct CommentInPrepass *c=new CommentInPrepass(index, inputStringPrepass.right(length-i-2));
- comments.append(c);
+ if (yyextra->inputStringPrepass[i]=='!' && i<length-1 && yyextra->inputStringPrepass[i+1]=='<') { // save comment
+ struct CommentInPrepass *c=new CommentInPrepass(index, yyextra->inputStringPrepass.right(length-i-2));
+ yyextra->comments.append(c);
}
}
- inputStringPrepass.truncate(index);
+ yyextra->inputStringPrepass.truncate(index);
}
// simplified way to know if this is fixed form
@@ -1502,16 +1521,16 @@ bool recognizeFixedForm(const char* contents, FortranFormat format)
case 'C':
case 'c':
case '*':
- if(column==1) return TRUE;
- if(skipLine) break;
+ if (column==1) return TRUE;
+ if (skipLine) break;
return FALSE;
case '!':
- if(column>1 && column<7) return FALSE;
+ if (column>1 && column<7) return FALSE;
skipLine=TRUE;
break;
default:
- if(skipLine) break;
- if(column==7) return TRUE;
+ if (skipLine) break;
+ if (column==7) return TRUE;
return FALSE;
}
}
@@ -1528,7 +1547,7 @@ static void insertCharacter(char *contents, int length, int pos, char c)
contents[pos] = c;
}
-/* change comments and bring line continuation character to previous line */
+/* change yyextra->comments and bring line continuation character to previous line */
/* also used to set continuation marks in case of fortran code usage, done here as it is quite complicated code */
const char* prepassFixedForm(const char* contents, int *hasContLine)
{
@@ -1574,7 +1593,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
}
j++;
- if(j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ')
+ if (j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ')
newContents = (char*)realloc(newContents, newContentsSize+1000);
newContentsSize = newContentsSize+1000;
}
@@ -1605,7 +1624,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
spaces=TRUE;
fullCommentLine=TRUE;
column=0;
- emptyLabel=TRUE;
+ emptyLabel=TRUE;
commented=FALSE;
newContents[j]=c;
prevQuote = thisQuote;
@@ -1635,10 +1654,10 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
case '\'':
case '\\':
if ((column <= fixedCommentAfter) && (column!=6) && !commented)
- {
+ {
// we have some special cases in respect to strings and escaped string characters
fullCommentLine=FALSE;
- newContents[j]=c;
+ newContents[j]=c;
if (c == '\\')
{
inBackslash = !inBackslash;
@@ -1673,71 +1692,89 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
case '*':
case '!':
if ((column <= fixedCommentAfter) && (column!=6))
- {
- emptyLabel=FALSE;
- if(column==1)
+ {
+ emptyLabel=FALSE;
+ if (column==1)
{
- newContents[j]='!';
+ newContents[j]='!';
commented = TRUE;
}
- else if ((c == '!') && !inDouble && !inSingle)
+ else if ((c == '!') && !inDouble && !inSingle)
{
- newContents[j]=c;
+ newContents[j]=c;
commented = TRUE;
}
- else
+ else
{
if (!commented) fullCommentLine=FALSE;
- newContents[j]=c;
+ newContents[j]=c;
}
- break;
- }
+ break;
+ }
// fallthrough
default:
- if (!commented && (column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9)) { // remove numbers, i.e. labels from first 5 positions.
+ if (!commented && (column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9))
+ { // remove numbers, i.e. labels from first 5 positions.
newContents[j]=' ';
}
- else if(column==6 && emptyLabel) { // continuation
+ else if (column==6 && emptyLabel)
+ { // continuation
if (!commented) fullCommentLine=FALSE;
- if (c != '0') { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3
+ if (c != '0')
+ { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3
newContents[j]=' ';
- if(prevLineAmpOrExclIndex==-1) { // add & just before end of previous line
+ if (prevLineAmpOrExclIndex==-1)
+ { // add & just before end of previous line
/* first line is not a continuation line in code, just in snippets etc. */
if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-1, '&');
j++;
- } else { // add & just before end of previous line comment
+ }
+ else
+ { // add & just before end of previous line comment
/* first line is not a continuation line in code, just in snippets etc. */
if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex+skipped, '&');
skipped = 0;
j++;
}
- if (hasContLine) hasContLine[curLine - 1] = 1;
- } else {
- newContents[j]=c; // , just handle like space
+ if (hasContLine)
+ {
+ hasContLine[curLine - 1] = 1;
+ }
+ }
+ else
+ {
+ newContents[j]=c; // , just handle like space
}
prevLineLength=0;
- } else if ((column > fixedCommentAfter) && !commented) {
+ }
+ else if ((column > fixedCommentAfter) && !commented)
+ {
// first non commented non blank character after position fixedCommentAfter
- if (c == '&') {
- newContents[j]=' ';
+ if (c == '&')
+ {
+ newContents[j]=' ';
}
- else if (c != '!') {
+ else if (c != '!')
+ {
// I'm not a possible start of doxygen comment
- newContents[j]=' ';
+ newContents[j]=' ';
artificialComment = TRUE;
spaces=TRUE;
skipped = 0;
}
- else {
- newContents[j]=c;
+ else
+ {
+ newContents[j]=c;
commented = TRUE;
}
- } else {
+ }
+ else
+ {
if (!commented) fullCommentLine=FALSE;
- newContents[j]=c;
- emptyLabel=FALSE;
- }
+ newContents[j]=c;
+ emptyLabel=FALSE;
+ }
break;
}
}
@@ -1758,25 +1795,28 @@ const char* prepassFixedForm(const char* contents, int *hasContLine)
return newContents;
}
-static void pushBuffer(QCString& buffer)
+static void pushBuffer(yyscan_t yyscanner,QCString& buffer)
{
- if (include_stack_cnt <= include_stack_ptr)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->includeStackCnt <= yyextra->includeStackPtr)
{
- include_stack_cnt++;
- include_stack = (YY_BUFFER_STATE *)realloc(include_stack, include_stack_cnt * sizeof(YY_BUFFER_STATE));
+ yyextra->includeStackCnt++;
+ yyextra->includeStack = (YY_BUFFER_STATE *)realloc(yyextra->includeStack, yyextra->includeStackCnt * sizeof(YY_BUFFER_STATE));
}
- include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(yy_scan_string(buffer));
+ yyextra->includeStack[yyextra->includeStackPtr++] = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_scan_string(buffer,yyscanner),yyscanner);
DBG_CTX((stderr, "--PUSH--%s", (const char *)buffer));
buffer = NULL;
}
-static void popBuffer() {
+static void popBuffer(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
DBG_CTX((stderr, "--POP--"));
- include_stack_ptr --;
- yy_delete_buffer( YY_CURRENT_BUFFER );
- yy_switch_to_buffer( include_stack[include_stack_ptr] );
+ yyextra->includeStackPtr --;
+ yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
+ yy_switch_to_buffer( yyextra->includeStack[yyextra->includeStackPtr], yyscanner );
}
/** used to copy entry to an interface module procedure */
@@ -1797,9 +1837,10 @@ static void copyEntry(std::shared_ptr<Entry> dest, const std::shared_ptr<Entry>
corresponding module subprogs
@TODO: handle procedures in used modules
*/
-void resolveModuleProcedures(Entry *current_root)
+void resolveModuleProcedures(yyscan_t yyscanner,Entry *current_root)
{
- for (const auto &ce1 : moduleProcedures)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ for (const auto &ce1 : yyextra->moduleProcedures)
{
// check all entries in this module
for (const auto &ce2 : current_root->children())
@@ -1808,19 +1849,10 @@ void resolveModuleProcedures(Entry *current_root)
{
copyEntry(ce1, ce2);
}
- } // for procedures in current module
+ } // for procedures in yyextra->current module
} // for all interface module procedures
- moduleProcedures.clear();
-}
-
-#if 0
-static bool isTypeName(QCString name)
-{
- name = name.lower();
- return name=="integer" || name == "real" ||
- name=="complex" || name == "logical";
+ yyextra->moduleProcedures.clear();
}
-#endif
/*! Extracts string which resides within parentheses of provided string. */
static QCString extractFromParens(const QCString name)
@@ -1865,7 +1897,7 @@ static QCString extractBind(const QCString name)
}
}
-/*! Adds passed modifiers to these modifiers.*/
+/*! Adds passed yyextra->modifiers to these yyextra->modifiers.*/
SymbolModifiers& SymbolModifiers::operator|=(const SymbolModifiers &mdfs)
{
if (mdfs.protection!=NONE_P) protection = mdfs.protection;
@@ -1892,7 +1924,7 @@ SymbolModifiers& SymbolModifiers::operator|=(const SymbolModifiers &mdfs)
return *this;
}
-/*! Extracts and adds passed modifier to these modifiers.*/
+/*! Extracts and adds passed modifier to these yyextra->modifiers.*/
SymbolModifiers& SymbolModifiers::operator|=(QCString mdfStringArg)
{
QCString mdfString = mdfStringArg.lower();
@@ -2014,7 +2046,7 @@ static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = F
for (Argument &arg : subprog->argList)
{
if ((!byTypeName && arg.name.lower() == cname) ||
- (byTypeName && arg.type.lower() == cname)
+ (byTypeName && arg.type.lower() == cname)
)
{
return &arg;
@@ -2024,7 +2056,7 @@ static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = F
}
-/*! Apply modifiers stored in \a mdfs to the \a typeName string. */
+/*! Apply yyextra->modifiers stored in \a mdfs to the \a typeName string. */
static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs)
{
if (!mdfs.dimension.isNull())
@@ -2141,14 +2173,14 @@ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs)
return typeName;
}
-/*! Apply modifiers stored in \a mdfs to the \a arg argument. */
+/*! Apply yyextra->modifiers stored in \a mdfs to the \a arg argument. */
static void applyModifiers(Argument *arg, SymbolModifiers& mdfs)
{
QCString tmp = arg->type;
arg->type = applyModifiers(tmp, mdfs);
}
-/*! Apply modifiers stored in \a mdfs to the \a ent entry. */
+/*! Apply yyextra->modifiers stored in \a mdfs to the \a ent entry. */
static void applyModifiers(Entry *ent, SymbolModifiers& mdfs)
{
QCString tmp = ent->type;
@@ -2164,47 +2196,49 @@ static void applyModifiers(Entry *ent, SymbolModifiers& mdfs)
* starting module, interface, function or other program block.
* \see endScope()
*/
-static void startScope(Entry *scope)
+static void startScope(yyscan_t yyscanner,Entry *scope)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
//cout<<"start scope: "<<scope->name<<endl;
- current_root= scope; /* start substructure */
+ yyextra->current_root= scope; /* start substructure */
QMap<QCString,SymbolModifiers> mdfMap;
- modifiers.insert(scope, mdfMap);
+ yyextra->modifiers.insert(scope, mdfMap);
}
/*! Ends scope in fortran program: may update subprogram arguments or module variable attributes.
* \see startScope()
*/
-static bool endScope(Entry *scope, bool isGlobalRoot)
+static bool endScope(yyscan_t yyscanner,Entry *scope, bool isGlobalRoot)
{
- if (global_scope == scope)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->global_scope == scope)
{
- global_scope = 0;
+ yyextra->global_scope = 0;
return TRUE;
}
- if (global_scope == INVALID_ENTRY)
+ if (yyextra->global_scope == INVALID_ENTRY)
{
return TRUE;
}
//cout<<"end scope: "<<scope->name<<endl;
- if (current_root->parent() || isGlobalRoot)
+ if (yyextra->current_root->parent() || isGlobalRoot)
{
- current_root= current_root->parent(); /* end substructure */
+ yyextra->current_root= yyextra->current_root->parent(); /* end substructure */
}
- else // if (current_root != scope)
+ else // if (yyextra->current_root != scope)
{
fprintf(stderr,"parse error in end <scopename>\n");
- scanner_abort();
+ scanner_abort(yyscanner);
return FALSE;
}
- // update variables or subprogram arguments with modifiers
- QMap<QCString,SymbolModifiers>& mdfsMap = modifiers[scope];
+ // update variables or subprogram arguments with yyextra->modifiers
+ QMap<QCString,SymbolModifiers>& mdfsMap = yyextra->modifiers[scope];
if (scope->section == Entry::FUNCTION_SEC)
{
- // iterate all symbol modifiers of the scope
+ // iterate all symbol yyextra->modifiers of the scope
for (QMap<QCString,SymbolModifiers>::Iterator it=mdfsMap.begin(); it!=mdfsMap.end(); it++)
{
//cout<<it.key()<<": "<<it.data()<<endl;
@@ -2217,12 +2251,12 @@ static bool endScope(Entry *scope, bool isGlobalRoot)
}
// find return type for function
- //cout<<"RETURN NAME "<<modifiers[current_root][scope->name.lower()].returnName<<endl;
- QCString returnName = modifiers[current_root][scope->name.lower()].returnName.lower();
- if (modifiers[scope].contains(returnName))
+ //cout<<"RETURN NAME "<<yyextra->modifiers[yyextra->current_root][scope->name.lower()].returnName<<endl;
+ QCString returnName = yyextra->modifiers[yyextra->current_root][scope->name.lower()].returnName.lower();
+ if (yyextra->modifiers[scope].contains(returnName))
{
- scope->type = modifiers[scope][returnName].type; // returning type works
- applyModifiers(scope, modifiers[scope][returnName]); // returning array works
+ scope->type = yyextra->modifiers[scope][returnName].type; // returning type works
+ applyModifiers(scope, yyextra->modifiers[scope][returnName]); // returning array works
}
}
@@ -2243,17 +2277,17 @@ static bool endScope(Entry *scope, bool isGlobalRoot)
Argument *arg = findArgument(scope->parent(), ce->name, TRUE);
if (arg != 0)
- {
+ {
// set type of dummy procedure argument to interface
- arg->name = arg->type;
+ arg->name = arg->type;
arg->type = scope->name;
}
if (ce->name.lower() == scope->name.lower()) found = TRUE;
}
if ((count == 1) && found)
{
- // clear all modifiers of the scope
- modifiers.remove(scope);
+ // clear all yyextra->modifiers of the scope
+ yyextra->modifiers.remove(scope);
scope->parent()->removeSubEntry(scope);
scope = 0;
return TRUE;
@@ -2262,7 +2296,7 @@ static bool endScope(Entry *scope, bool isGlobalRoot)
}
if (scope->section!=Entry::FUNCTION_SEC)
{ // not function section
- // iterate variables: get and apply modifiers
+ // iterate variables: get and apply yyextra->modifiers
for (const auto &ce : scope->children())
{
if (ce->section != Entry::VARIABLE_SEC && ce->section != Entry::FUNCTION_SEC)
@@ -2274,165 +2308,156 @@ static bool endScope(Entry *scope, bool isGlobalRoot)
}
}
- // clear all modifiers of the scope
- modifiers.remove(scope);
+ // clear all yyextra->modifiers of the scope
+ yyextra->modifiers.remove(scope);
return TRUE;
}
-#if 0
-//! Return full name of the entry. Sometimes we must combine several names recursively.
-static QCString getFullName(Entry *e)
-{
- QCString name = e->name;
- if (e->section == Entry::CLASS_SEC // || e->section == Entry::INTERFACE_SEC
- || !e->parent() || e->parent()->name.isEmpty())
- return name;
-
- return getFullName(e->parent())+"::"+name;
-}
-#endif
-
-static int yyread(char *buf,int max_size)
+static int yyread(yyscan_t yyscanner,char *buf,int max_size)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
int c=0;
-
- while ( c < max_size && inputString[inputPosition] )
+ while ( c < max_size && yyextra->inputString[yyextra->inputPosition] )
{
- *buf = inputString[inputPosition++] ;
+ *buf = yyextra->inputString[yyextra->inputPosition++] ;
c++; buf++;
}
return c;
}
-static void initParser()
+static void initParser(yyscan_t yyscanner)
{
- last_entry.reset();
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ yyextra->last_entry.reset();
}
-static void initEntry()
+static void initEntry(yyscan_t yyscanner)
{
- if (typeMode)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (yyextra->typeMode)
{
- current->protection = typeProtection;
+ yyextra->current->protection = yyextra->typeProtection;
}
else
{
- current->protection = defaultProtection;
+ yyextra->current->protection = yyextra->defaultProtection;
}
- current->mtype = mtype;
- current->virt = virt;
- current->stat = gstat;
- current->lang = SrcLangExt_Fortran;
- Doxygen::docGroup.initGroupInfo(current.get());
+ yyextra->current->mtype = Method;
+ yyextra->current->virt = Normal;
+ yyextra->current->stat = FALSE;
+ yyextra->current->lang = SrcLangExt_Fortran;
+ Doxygen::docGroup.initGroupInfo(yyextra->current.get());
}
/**
- adds current entry to current_root and creates new current
+ adds yyextra->current entry to yyextra->current_root and creates new yyextra->current
*/
-static void addCurrentEntry(bool case_insens)
+static void addCurrentEntry(yyscan_t yyscanner,bool case_insens)
{
- if (case_insens) current->name = current->name.lower();
- //printf("===Adding entry %s to %s\n", current->name.data(), current_root->name.data());
- last_entry = current;
- current_root->moveToSubEntryAndRefresh(current);
- initEntry();
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ if (case_insens) yyextra->current->name = yyextra->current->name.lower();
+ //printf("===Adding entry %s to %s\n", yyextra->current->name.data(), yyextra->current_root->name.data());
+ yyextra->last_entry = yyextra->current;
+ yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
+ initEntry(yyscanner);
}
-static int max(int a, int b) {return a>b?a:b;}
-
-static void addModule(const char *name, bool isModule)
+static void addModule(yyscan_t yyscanner,const char *name, bool isModule)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
DBG_CTX((stderr, "0=========> got module %s\n", name));
if (isModule)
- current->section = Entry::NAMESPACE_SEC;
+ yyextra->current->section = Entry::NAMESPACE_SEC;
else
- current->section = Entry::FUNCTION_SEC;
+ yyextra->current->section = Entry::FUNCTION_SEC;
if (name!=NULL)
{
- current->name = name;
+ yyextra->current->name = name;
}
else
{
- QCString fname = yyFileName;
- int index = max(fname.findRev('/'), fname.findRev('\\'));
+ QCString fname = yyextra->fileName;
+ int index = QMAX(fname.findRev('/'), fname.findRev('\\'));
fname = fname.right(fname.length()-index-1);
fname = fname.prepend("__").append("__");
- current->name = fname;
- }
- current->type = "program";
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr; // used for source reference
- current->startLine = yyLineNr;
- current->protection = Public ;
- addCurrentEntry(true);
- startScope(last_entry.get());
+ yyextra->current->name = fname;
+ }
+ yyextra->current->type = "program";
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->bodyLine = yyextra->lineNr; // used for source reference
+ yyextra->current->startLine = yyextra->lineNr;
+ yyextra->current->protection = Public ;
+ addCurrentEntry(yyscanner,true);
+ startScope(yyscanner,yyextra->last_entry.get());
}
-static void addSubprogram(const char *text)
+static void addSubprogram(yyscan_t yyscanner,const char *text)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
DBG_CTX((stderr,"1=========> got subprog, type: %s\n",text));
- subrCurrent.push_back(current);
- current->section = Entry::FUNCTION_SEC ;
+ yyextra->subrCurrent.push_back(yyextra->current);
+ yyextra->current->section = Entry::FUNCTION_SEC ;
QCString subtype = text; subtype=subtype.lower().stripWhiteSpace();
- functionLine = (subtype.find("function") != -1);
- current->type += " " + subtype;
- current->type = current->type.stripWhiteSpace();
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr; // used for source reference start of body of routine
- current->startLine = yyLineNr; // used for source reference start of definition
- current->args.resize(0);
- current->argList.clear();
- docBlock.resize(0);
+ yyextra->functionLine = (subtype.find("function") != -1);
+ yyextra->current->type += " " + subtype;
+ yyextra->current->type = yyextra->current->type.stripWhiteSpace();
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->bodyLine = yyextra->lineNr; // used for source reference start of body of routine
+ yyextra->current->startLine = yyextra->lineNr; // used for source reference start of definition
+ yyextra->current->args.resize(0);
+ yyextra->current->argList.clear();
+ yyextra->docBlock.resize(0);
}
/*! Adds interface to the root entry.
* \note Code was brought to this procedure from the parser,
* because there was/is idea to use it in several parts of the parser.
*/
-static void addInterface(QCString name, InterfaceType type)
+static void addInterface(yyscan_t yyscanner,QCString name, InterfaceType type)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (YY_START == Start)
{
- addModule(NULL);
- yy_push_state(ModuleBody); //anon program
+ addModule(yyscanner,NULL);
+ yy_push_state(ModuleBody,yyscanner); //anon program
}
- current->section = Entry::CLASS_SEC; // was Entry::INTERFACE_SEC;
- current->spec = Entry::Interface;
- current->name = name;
+ yyextra->current->section = Entry::CLASS_SEC; // was Entry::INTERFACE_SEC;
+ yyextra->current->spec = Entry::Interface;
+ yyextra->current->name = name;
switch (type)
{
case IF_ABSTRACT:
- current->type = "abstract";
+ yyextra->current->type = "abstract";
break;
case IF_GENERIC:
- current->type = "generic";
+ yyextra->current->type = "generic";
break;
case IF_SPECIFIC:
case IF_NONE:
default:
- current->type = "";
+ yyextra->current->type = "";
}
/* if type is part of a module, mod name is necessary for output */
- if ((current_root) &&
- (current_root->section == Entry::CLASS_SEC ||
- current_root->section == Entry::NAMESPACE_SEC))
+ if ((yyextra->current_root) &&
+ (yyextra->current_root->section == Entry::CLASS_SEC ||
+ yyextra->current_root->section == Entry::NAMESPACE_SEC))
{
- current->name= current_root->name + "::" + current->name;
+ yyextra->current->name= yyextra->current_root->name + "::" + yyextra->current->name;
}
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr;
- current->startLine = yyLineNr;
- addCurrentEntry(true);
+ yyextra->current->fileName = yyextra->fileName;
+ yyextra->current->bodyLine = yyextra->lineNr;
+ yyextra->current->startLine = yyextra->lineNr;
+ addCurrentEntry(yyscanner,true);
}
@@ -2440,11 +2465,12 @@ static void addInterface(QCString name, InterfaceType type)
/*! Get the argument \a name.
*/
-static Argument *getParameter(const QCString &name)
+static Argument *getParameter(yyscan_t yyscanner,const QCString &name)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
// std::cout<<"addFortranParameter(): "<<name<<" DOCS:"<<(docs.isNull()?QCString("null"):docs)<<std::endl;
Argument *ret = 0;
- for (Argument &a:current_root->argList)
+ for (Argument &a:yyextra->current_root->argList)
{
if (a.name.lower()==name.lower())
{
@@ -2457,70 +2483,73 @@ static Argument *getParameter(const QCString &name)
}
//----------------------------------------------------------------------------
-static void startCommentBlock(bool brief)
+static void startCommentBlock(yyscan_t yyscanner,bool brief)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (brief)
{
- current->briefFile = yyFileName;
- current->briefLine = yyLineNr;
+ yyextra->current->briefFile = yyextra->fileName;
+ yyextra->current->briefLine = yyextra->lineNr;
}
else
{
- current->docFile = yyFileName;
- current->docLine = yyLineNr;
+ yyextra->current->docFile = yyextra->fileName;
+ yyextra->current->docLine = yyextra->lineNr;
}
}
//----------------------------------------------------------------------------
-static void handleCommentBlock(const QCString &doc,bool brief)
+static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief)
{
- static bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
- if (docBlockInBody && hideInBodyDocs)
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS);
+ if (yyextra->docBlockInBody && hideInBodyDocs)
{
- docBlockInBody = FALSE;
+ yyextra->docBlockInBody = FALSE;
return;
}
DBG_CTX((stderr,"call parseCommentBlock [%s]\n",doc.data()));
- int lineNr = brief ? current->briefLine : current->docLine;
+ int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
int position=0;
bool needsEntry = FALSE;
- QCString processedDoc = processMarkdownForCommentBlock(doc,yyFileName,lineNr);
- while (g_commentScanner.parseCommentBlock(
- g_thisParser,
- docBlockInBody ? subrCurrent.back().get() : current.get(),
- processedDoc, // text
- yyFileName, // file
- lineNr,
- docBlockInBody ? FALSE : brief,
- docBlockInBody ? FALSE : docBlockJavaStyle,
- docBlockInBody,
- defaultProtection,
+ QCString processedDoc = processMarkdownForCommentBlock(doc,yyextra->fileName,lineNr);
+ while (yyextra->commentScanner.parseCommentBlock(
+ yyextra->thisParser,
+ yyextra->docBlockInBody ? yyextra->subrCurrent.back().get() : yyextra->current.get(),
+ processedDoc, // text
+ yyextra->fileName, // file
+ lineNr,
+ yyextra->docBlockInBody ? FALSE : brief,
+ yyextra->docBlockInBody ? FALSE : yyextra->docBlockJavaStyle,
+ yyextra->docBlockInBody,
+ yyextra->defaultProtection,
position,
needsEntry
))
{
- DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry));
- if (needsEntry) addCurrentEntry(false);
+ DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry));
+ if (needsEntry) addCurrentEntry(yyscanner,false);
}
DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry));
- if (needsEntry) addCurrentEntry(false);
- docBlockInBody = FALSE;
+ if (needsEntry) addCurrentEntry(yyscanner,false);
+ yyextra->docBlockInBody = FALSE;
}
//----------------------------------------------------------------------------
/// Handle parameter description as defined after the declaration of the parameter
-static void subrHandleCommentBlock(const QCString &doc,bool brief)
+static void subrHandleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
QCString loc_doc;
loc_doc = doc.stripWhiteSpace();
- std::shared_ptr<Entry> tmp_entry = current;
- current = subrCurrent.back(); // temporarily switch to the entry of the subroutine / function
+ std::shared_ptr<Entry> tmp_entry = yyextra->current;
+ yyextra->current = yyextra->subrCurrent.back(); // temporarily switch to the entry of the subroutine / function
// Still in the specification section so no inbodyDocs yet, but parameter documentation
- current->inbodyDocs = "";
+ yyextra->current->inbodyDocs = "";
// strip \\param or @param, so we can do some extra checking. We will add it later on again.
if (!loc_doc.stripPrefix("\\param") &&
@@ -2529,7 +2558,7 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief)
loc_doc.stripWhiteSpace();
// direction as defined with the declaration of the parameter
- int dir1 = modifiers[current_root][argName.lower()].direction;
+ int dir1 = yyextra->modifiers[yyextra->current_root][yyextra->argName.lower()].direction;
// in description [in] is specified
if (loc_doc.lower().find(directionParam[SymbolModifiers::IN]) == 0)
{
@@ -2541,19 +2570,19 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief)
loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::IN]));
loc_doc.stripWhiteSpace();
// in case of empty documentation or (now) just name, consider it as no documentation
- if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower()))
+ if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower()))
{
- handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " +
- argName + " " + loc_doc,brief);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
}
else
{
// something different specified, give warning and leave error.
- warn(yyFileName,yyLineNr, "Routine: " + current->name + current->args +
- " inconsistency between intent attribute and documentation for parameter: " + argName);
- handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " +
- argName + " " + loc_doc,brief);
+ warn(yyextra->fileName,yyextra->lineNr, "Routine: " + yyextra->current->name + yyextra->current->args +
+ " inconsistency between intent attribute and documentation for parameter: " + yyextra->argName);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
}
// analogous to the [in] case, here [out] direction specified
@@ -2564,20 +2593,20 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief)
{
loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::OUT]));
loc_doc.stripWhiteSpace();
- if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower()))
+ if (loc_doc.isEmpty() || (loc_doc.lower() == yyextra->argName.lower()))
{
- current = tmp_entry;
+ yyextra->current = tmp_entry;
return;
}
- handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " +
- argName + " " + loc_doc,brief);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
else
{
- warn(yyFileName,yyLineNr, "Routine: " + current->name + current->args +
- " inconsistency between intent attribute and documentation for parameter: " + argName);
- handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " +
- argName + " " + loc_doc,brief);
+ warn(yyextra->fileName,yyextra->lineNr, "Routine: " + yyextra->current->name + yyextra->current->args +
+ " inconsistency between intent attribute and documentation for parameter: " + yyextra->argName);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
}
// analogous to the [in] case, here [in,out] direction specified
@@ -2588,42 +2617,43 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief)
{
loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::INOUT]));
loc_doc.stripWhiteSpace();
- if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower()))
+ if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower()))
{
- handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " +
- argName + " " + loc_doc,brief);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
}
else
{
- warn(yyFileName,yyLineNr, "Routine: " + current->name + current->args +
- " inconsistency between intent attribute and documentation for parameter: " + argName);
- handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " +
- argName + " " + loc_doc,brief);
+ warn(yyextra->fileName,yyextra->lineNr, "Routine: " + yyextra->current->name + yyextra->current->args +
+ " inconsistency between intent attribute and documentation for parameter: " + yyextra->argName);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
}
// analogous to the [in] case; here no direction specified
- else if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower()))
+ else if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower()))
{
- handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " +
- argName + " " + loc_doc,brief);
+ handleCommentBlock(yyscanner,QCString("\n\n@param ") + directionParam[dir1] + " " +
+ yyextra->argName + " " + loc_doc,brief);
}
- // reset current back to the part inside the routine
- current = tmp_entry;
+ // reset yyextra->current back to the part inside the routine
+ yyextra->current = tmp_entry;
}
//----------------------------------------------------------------------------
/// Handle result description as defined after the declaration of the parameter
-static void subrHandleCommentBlockResult(const QCString &doc,bool brief)
+static void subrHandleCommentBlockResult(yyscan_t yyscanner,const QCString &doc,bool brief)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
QCString loc_doc;
loc_doc = doc.stripWhiteSpace();
- std::shared_ptr<Entry> tmp_entry = current;
- current = subrCurrent.back(); // temporarily switch to the entry of the subroutine / function
+ std::shared_ptr<Entry> tmp_entry = yyextra->current;
+ yyextra->current = yyextra->subrCurrent.back(); // temporarily switch to the entry of the subroutine / function
// Still in the specification section so no inbodyDocs yet, but parameter documentation
- current->inbodyDocs = "";
+ yyextra->current->inbodyDocs = "";
// strip \\returns or @returns. We will add it later on again.
if (!loc_doc.stripPrefix("\\returns") &&
@@ -2633,140 +2663,152 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief)
) (void)loc_doc; // Do nothing work has been done by stripPrefix; (void)loc_doc: to overcome 'empty controlled statement' warning
loc_doc.stripWhiteSpace();
- if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower()))
+ if (!loc_doc.isEmpty() && (loc_doc.lower() != yyextra->argName.lower()))
{
- handleCommentBlock(QCString("\n\n@returns ") + loc_doc,brief);
+ handleCommentBlock(yyscanner,QCString("\n\n@returns ") + loc_doc,brief);
}
- // reset current back to the part inside the routine
- current = tmp_entry;
+ // reset yyextra->current back to the part inside the routine
+ yyextra->current = tmp_entry;
}
//----------------------------------------------------------------------------
-#if 0
-static int level=0;
-static void debugCompounds(Entry *rt) // print Entry structure (for debugging)
+static void parseMain(yyscan_t yyscanner, const char *fileName,const char *fileBuf,
+ const std::shared_ptr<Entry> &rt, FortranFormat format)
{
- level++;
- printf("%d) debugCompounds(%s) line %d\n",level, rt->name.data(), rt->bodyLine);
- for (const auto &ce : rt->children())
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ char *tmpBuf = NULL;
+ initParser(yyscanner);
+
+ yyextra->defaultProtection = Public;
+ yyextra->inputString = fileBuf;
+ yyextra->inputPosition = 0;
+ yyextra->inputStringPrepass = NULL;
+ yyextra->inputPositionPrepass = 0;
+
+ //yyextra->anonCount = 0; // don't reset per file
+ yyextra->current_root = rt.get();
+ yyextra->global_root = rt;
+
+ yyextra->isFixedForm = recognizeFixedForm(fileBuf,format);
+
+ if (yyextra->isFixedForm)
+ {
+ msg("Prepassing fixed form of %s\n", fileName);
+ //printf("---strlen=%d\n", strlen(fileBuf));
+ //clock_t start=clock();
+
+ //printf("Input fixed form string:\n%s\n", fileBuf);
+ //printf("===========================\n");
+ yyextra->inputString = prepassFixedForm(fileBuf, NULL);
+ Debug::print(Debug::FortranFixed2Free,0,"======== Fixed to Free format =========\n---- Input fixed form string ------- \n%s\n", fileBuf);
+ Debug::print(Debug::FortranFixed2Free,0,"---- Resulting free form string ------- \n%s\n", yyextra->inputString);
+ //printf("Resulting free form string:\n%s\n", yyextra->inputString);
+ //printf("===========================\n");
+
+ //clock_t end=clock();
+ //printf("CPU time used=%f\n", ((double) (end-start))/CLOCKS_PER_SEC);
+ }
+ else if (yyextra->inputString[strlen(fileBuf)-1] != '\n')
{
- debugCompounds(ce.get());
+ tmpBuf = (char *)malloc(strlen(fileBuf)+2);
+ strcpy(tmpBuf,fileBuf);
+ tmpBuf[strlen(fileBuf)]= '\n';
+ tmpBuf[strlen(fileBuf)+1]= '\000';
+ yyextra->inputString = tmpBuf;
}
-level--;
-}
-#endif
+ yyextra->lineNr= 1 ;
+ yyextra->fileName = fileName;
+ msg("Parsing file %s...\n",yyextra->fileName.data());
-static void parseMain(const char *fileName,const char *fileBuf,
- const std::shared_ptr<Entry> &rt, FortranFormat format)
-{
- char *tmpBuf = NULL;
- initParser();
-
- defaultProtection = Public;
- inputString = fileBuf;
- inputPosition = 0;
- inputStringPrepass = NULL;
- inputPositionPrepass = 0;
-
- //anonCount = 0; // don't reset per file
- mtype = Method;
- gstat = FALSE;
- virt = Normal;
- current_root = rt.get();
- global_root = rt;
- inputFile.setName(fileName);
- if (inputFile.open(IO_ReadOnly))
- {
- isFixedForm = recognizeFixedForm(fileBuf,format);
-
- if (isFixedForm)
- {
- msg("Prepassing fixed form of %s\n", fileName);
- //printf("---strlen=%d\n", strlen(fileBuf));
- //clock_t start=clock();
-
- //printf("Input fixed form string:\n%s\n", fileBuf);
- //printf("===========================\n");
- inputString = prepassFixedForm(fileBuf, NULL);
- Debug::print(Debug::FortranFixed2Free,0,"======== Fixed to Free format =========\n---- Input fixed form string ------- \n%s\n", fileBuf);
- Debug::print(Debug::FortranFixed2Free,0,"---- Resulting free form string ------- \n%s\n", inputString);
- //printf("Resulting free form string:\n%s\n", inputString);
- //printf("===========================\n");
-
- //clock_t end=clock();
- //printf("CPU time used=%f\n", ((double) (end-start))/CLOCKS_PER_SEC);
- }
- else if (inputString[strlen(fileBuf)-1] != '\n')
- {
- tmpBuf = (char *)malloc(strlen(fileBuf)+2);
- strcpy(tmpBuf,fileBuf);
- tmpBuf[strlen(fileBuf)]= '\n';
- tmpBuf[strlen(fileBuf)+1]= '\000';
- inputString = tmpBuf;
- }
+ yyextra->global_scope = rt.get();
+ startScope(yyscanner,rt.get()); // implies yyextra->current_root = rt
+ initParser(yyscanner);
+ Doxygen::docGroup.enterFile(yyextra->fileName,yyextra->lineNr);
- yyLineNr= 1 ;
- yyFileName = fileName;
- msg("Parsing file %s...\n",yyFileName.data());
-
- global_scope = rt.get();
- startScope(rt.get()); // implies current_root = rt
- initParser();
- Doxygen::docGroup.enterFile(yyFileName,yyLineNr);
-
- // add entry for the file
- current = std::make_shared<Entry>();
- current->lang = SrcLangExt_Fortran;
- current->name = yyFileName;
- current->section = Entry::SOURCE_SEC;
- file_root = current;
- current_root->moveToSubEntryAndRefresh(current);
- current->lang = SrcLangExt_Fortran;
-
- fortranscannerYYrestart( fortranscannerYYin );
- {
- BEGIN( Start );
- }
+ // add entry for the file
+ yyextra->current = std::make_shared<Entry>();
+ yyextra->current->lang = SrcLangExt_Fortran;
+ yyextra->current->name = yyextra->fileName;
+ yyextra->current->section = Entry::SOURCE_SEC;
+ yyextra->file_root = yyextra->current;
+ yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
+ yyextra->current->lang = SrcLangExt_Fortran;
- fortranscannerYYlex();
- Doxygen::docGroup.leaveFile(yyFileName,yyLineNr);
+ fortranscannerYYrestart( 0, yyscanner );
+ {
+ BEGIN( Start );
+ }
- if (global_scope && global_scope != INVALID_ENTRY) endScope(current_root, TRUE); // TRUE - global root
+ fortranscannerYYlex(yyscanner);
+ Doxygen::docGroup.leaveFile(yyextra->fileName,yyextra->lineNr);
- //debugCompounds(rt); //debug
+ if (yyextra->global_scope && yyextra->global_scope != INVALID_ENTRY)
+ {
+ endScope(yyscanner,yyextra->current_root, TRUE); // TRUE - global root
+ }
- rt->program.resize(0);
- //delete current; current=0;
- moduleProcedures.clear();
- if (tmpBuf) {
- free((char*)tmpBuf);
- inputString=NULL;
- }
- if (isFixedForm) {
- free((char*)inputString);
- inputString=NULL;
- }
+ //debugCompounds(rt); //debug
- inputFile.close();
+ rt->program.resize(0);
+ //delete yyextra->current; yyextra->current=0;
+ yyextra->moduleProcedures.clear();
+ if (tmpBuf)
+ {
+ free((char*)tmpBuf);
+ yyextra->inputString=NULL;
}
+ if (yyextra->isFixedForm)
+ {
+ free((char*)yyextra->inputString);
+ yyextra->inputString=NULL;
+ }
+
}
//----------------------------------------------------------------------------
+struct FortranOutlineParser::Private
+{
+ yyscan_t yyscanner;
+ fortranscannerYY_state extra;
+ FortranFormat format;
+ Private(FortranFormat fmt) : format(fmt)
+ {
+ fortranscannerYYlex_init_extra(&extra,&yyscanner);
+#ifdef FLEX_DEBUG
+ fortranscannerYYset_debug(1,yyscanner);
+#endif
+ }
+ ~Private()
+ {
+ fortranscannerYYlex_destroy(yyscanner);
+ }
+};
+
+FortranOutlineParser::FortranOutlineParser(FortranFormat format)
+ : p(std::make_unique<Private>(format))
+{
+}
+
+FortranOutlineParser::~FortranOutlineParser()
+{
+}
+
void FortranOutlineParser::parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
bool /*sameTranslationUnit*/,
QStrList & /*filesInSameTranslationUnit*/)
{
- g_thisParser = this;
+ struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
+ yyextra->thisParser = this;
printlex(yy_flex_debug, TRUE, __FILE__, fileName);
- ::parseMain(fileName,fileBuf,root,m_format);
+ ::parseMain(p->yyscanner,fileName,fileBuf,root,p->format);
printlex(yy_flex_debug, FALSE, __FILE__, fileName);
}
@@ -2775,35 +2817,38 @@ bool FortranOutlineParser::needsPreprocessing(const QCString &extension) const
{
return extension!=extension.lower(); // use preprocessor only for upper case extensions
}
+
void FortranOutlineParser::parsePrototype(const char *text)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
QCString buffer = QCString(text);
- pushBuffer(buffer);
- parsingPrototype = TRUE;
+ pushBuffer(p->yyscanner,buffer);
+ yyextra->parsingPrototype = TRUE;
BEGIN(Prototype);
- fortranscannerYYlex();
- parsingPrototype = FALSE;
- popBuffer();
+ fortranscannerYYlex(p->yyscanner);
+ yyextra->parsingPrototype = FALSE;
+ popBuffer(p->yyscanner);
}
//----------------------------------------------------------------------------
-static void scanner_abort()
+static void scanner_abort(yyscan_t yyscanner)
{
+ struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
fprintf(stderr,"********************************************************************\n");
- fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyFileName.data(),yyLineNr,YY_START,stateToString(YY_START));
+ fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyextra->fileName.data(),yyextra->lineNr,YY_START,stateToString(YY_START));
fprintf(stderr,"********************************************************************\n");
bool start=FALSE;
- for (const auto &ce : global_root->children())
+ for (const auto &ce : yyextra->global_root->children())
{
- if (ce == file_root) start=TRUE;
+ if (ce == yyextra->file_root) start=TRUE;
if (start) ce->reset();
}
// dummy call to avoid compiler warning
- (void)yy_top_state();
+ (void)yy_top_state(yyscanner);
return;
//exit(-1);