diff options
Diffstat (limited to 'src/fortranscanner.l')
-rw-r--r-- | src/fortranscanner.l | 242 |
1 files changed, 103 insertions, 139 deletions
diff --git a/src/fortranscanner.l b/src/fortranscanner.l index d75134a..d7eefd6 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -165,11 +165,11 @@ static int yyColNr = 0 ; static Entry* current_root = 0 ; static Entry* global_root = 0 ; static Entry* file_root = 0 ; -static Entry* current = 0 ; static Entry* last_entry = 0 ; static Entry* last_enum = 0 ; +static std::unique_ptr<Entry> current; static ScanVar v_type = V_IGNORE; // type of parsed variable -static QList<Entry> moduleProcedures; // list of all interfaces which contain unresolved +static std::vector<Entry*> moduleProcedures; // list of all interfaces which contain unresolved // module procedures static QCString docBlock; static bool docBlockInBody = FALSE; @@ -202,7 +202,7 @@ static SymbolModifiers currentModifiers; //! Holds program scope->symbol name->symbol modifiers. static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers; -static Entry *global_scope = NULL; +static Entry *global_scope = 0; static int anonCount = 0 ; //----------------------------------------------------------------------------- @@ -211,7 +211,7 @@ 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(int case_insens); +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); @@ -221,7 +221,7 @@ 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(QList<Entry> &moduleProcedures, Entry *current_root); +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); @@ -241,6 +241,7 @@ 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; +#define INVALID_ENTRY ((Entry*)0x8) //----------------------------------------------------------------------------- %} @@ -444,8 +445,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* current->name=yytext; current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; yy_pop_state(); } @@ -459,8 +459,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* current->name= useModuleName+"::"+yytext; current->fileName = yyFileName; current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; } <Use,UseOnly>"\n" { @@ -516,8 +515,8 @@ SCOPENAME ({ID}{BS}"::"{BS})* current->section = Entry::FUNCTION_SEC ; current->name = yytext; - moduleProcedures.append(current); - addCurrentEntry(1); + moduleProcedures.push_back(current.get()); + addCurrentEntry(true); } <ModuleProcedure>"\n" { yyColNr -= 1; unput(*yytext); @@ -558,13 +557,13 @@ SCOPENAME ({ID}{BS}"::"{BS})* yy_pop_state(); } <Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module - resolveModuleProcedures(moduleProcedures, current_root); + resolveModuleProcedures(current_root); if (!endScope(current_root)) yyterminate(); defaultProtection = Public; if (global_scope) { - if (global_scope != (Entry *) -1) + if (global_scope != INVALID_ENTRY) yy_push_state(Start); else yy_pop_state(); // cannot pop artrificial entry @@ -572,7 +571,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* else { yy_push_state(Start); - global_scope = (Entry *)-1; // signal that the global_scope has already been used. + global_scope = INVALID_ENTRY; // signal that the global_scope has already been used. } } <Module>{ID} { @@ -647,7 +646,7 @@ private { current->name = current_root->name + "::" + current->name; } - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN(TypedefBody); } @@ -679,7 +678,7 @@ private { current->fileName = yyFileName; current->bodyLine = yyLineNr; current->startLine = yyLineNr; - addCurrentEntry(1); + addCurrentEntry(true); } {BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */ QCString args = yytext; @@ -866,17 +865,15 @@ private { current->startLine = yyLineNr; if (argType == "@") { - current_root->addSubEntry(current); - current = new Entry(*current); + current_root->copyToSubEntry(current); // add to the scope surrounding the enum (copy!) - current_root->parent()->addSubEntry(current); - last_enum = current; - current = new Entry ; + last_enum = current.get(); + current_root->parent()->moveToSubEntryAndRefresh(current); initEntry(); } else { - addCurrentEntry(1); + addCurrentEntry(true); } } else if (!argType.isEmpty()) @@ -889,7 +886,7 @@ private { if (!docBlock.isNull()) { subrHandleCommentBlock(docBlock,TRUE); - } + } } // save, it may be function return type if (parameter) @@ -1068,7 +1065,7 @@ private { current->name = current_root->name + "::" + current->name; } - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN( Enum ) ; } @@ -1138,7 +1135,7 @@ private { <Parameterlist>")" { current->args += ")"; current->args = removeRedundantWhiteSpace(current->args); - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN(SubprogBody); } @@ -1164,7 +1161,7 @@ private { newLine(); //printf("3=========> without parameterlist \n"); //current->argList = ; - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN(SubprogBody); } @@ -1217,11 +1214,20 @@ private { unput(*yytext); if (v_type == V_VARIABLE) { - Entry *tmp_entry = current; - current = last_entry; // temporarily switch to the previous entry - if (last_enum) current = last_enum; + std::unique_ptr<Entry> tmp_entry; + current.swap(tmp_entry); + // temporarily switch to the previous entry + if (last_enum) + { + current.reset(last_enum); + } + else + { + current.reset(last_entry); + } handleCommentBlock(docBlock,TRUE); - current=tmp_entry; + // switch back + tmp_entry.swap(current); } else if (v_type == V_PARAMETER) { @@ -1773,34 +1779,30 @@ static void popBuffer() { } /** used to copy entry to an interface module procedure */ -static void copyEntry(Entry *dest, Entry *src) +static void copyEntry(Entry *dest, const std::unique_ptr<Entry> &src) { - dest->type = src->type; - dest->fileName = src->fileName; - dest->startLine = src->startLine; - dest->bodyLine = src->bodyLine; + dest->type = src->type; + dest->fileName = src->fileName; + dest->startLine = src->startLine; + dest->bodyLine = src->bodyLine; dest->endBodyLine = src->endBodyLine; - dest->args = src->args; - dest->argList = new ArgumentList(*src->argList); - dest->doc = src->doc; - dest->brief = src->brief; + dest->args = src->args; + delete dest->argList; + dest->argList = new ArgumentList(*src->argList); + dest->doc = src->doc; + dest->brief = src->brief; } /** fill empty interface module procedures with info from corresponding module subprogs @TODO: handle procedures in used modules */ -void resolveModuleProcedures(QList<Entry> &moduleProcedures, Entry *current_root) +void resolveModuleProcedures(Entry *current_root) { - if (moduleProcedures.isEmpty()) return; - - EntryListIterator eli1(moduleProcedures); - // for all module procedures - for (Entry *ce1; (ce1=eli1.current()); ++eli1) + for (const auto &ce1 : moduleProcedures) { // check all entries in this module - EntryListIterator eli2(*current_root->children()); - for (Entry *ce2; (ce2=eli2.current()); ++eli2) + for (const auto &ce2 : current_root->children()) { if (ce1->name == ce2->name) { @@ -1840,7 +1842,7 @@ static QCString extractFromParens(const QCString name) return extracted; } -/*! remove non usefull spaces from bind statement */ +/*! remove unuseful spaces from bind statement */ static QCString extractBind(const QCString name) { QCString parensPart = extractFromParens(name); @@ -2022,26 +2024,6 @@ static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = F return 0; } -/*! Find function with given name in \a entry. */ -#if 0 -static Entry *findFunction(Entry* entry, QCString name) -{ - QCString cname(name.lower()); - - EntryListIterator eli(*entry->children()); - Entry *ce; - for (;(ce=eli.current());++eli) - { - if (ce->section != Entry::FUNCTION_SEC) - continue; - - if (ce->name.lower() == cname) - return ce; - } - - return 0; -} -#endif /*! Apply modifiers stored in \a mdfs to the \a typeName string. */ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs) @@ -2199,10 +2181,10 @@ static bool endScope(Entry *scope, bool isGlobalRoot) { if (global_scope == scope) { - global_scope = NULL; + global_scope = 0; return TRUE; } - if (global_scope == (Entry *) -1) + if (global_scope == INVALID_ENTRY) { return TRUE; } @@ -2250,11 +2232,9 @@ static bool endScope(Entry *scope, bool isGlobalRoot) // iterate functions of interface and // try to find types for dummy(ie. argument) procedures. //cout<<"Search in "<<scope->name<<endl; - EntryListIterator eli(*scope->children()); - Entry *ce; int count = 0; int found = FALSE; - for (;(ce=eli.current());++eli) + for (const auto &ce : scope->children()) { count++; if (ce->section != Entry::FUNCTION_SEC) @@ -2273,7 +2253,7 @@ static bool endScope(Entry *scope, bool isGlobalRoot) { // clear all modifiers of the scope modifiers.remove(scope); - delete scope->parent()->removeSubEntry(scope); + scope->parent()->removeSubEntry(scope); scope = 0; return TRUE; } @@ -2282,16 +2262,14 @@ static bool endScope(Entry *scope, bool isGlobalRoot) if (scope->section!=Entry::FUNCTION_SEC) { // not function section // iterate variables: get and apply modifiers - EntryListIterator eli(*scope->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (const auto &ce : scope->children()) { if (ce->section != Entry::VARIABLE_SEC && ce->section != Entry::FUNCTION_SEC) continue; //cout<<ce->name<<", "<<mdfsMap.contains(ce->name.lower())<<mdfsMap.count()<<endl; if (mdfsMap.contains(ce->name.lower())) - applyModifiers(ce, mdfsMap[ce->name.lower()]); + applyModifiers(ce.get(), mdfsMap[ce->name.lower()]); } } @@ -2345,19 +2323,18 @@ static void initEntry() current->virt = virt; current->stat = gstat; current->lang = SrcLangExt_Fortran; - Doxygen::docGroup.initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current.get()); } /** adds current entry to current_root and creates new current */ -static void addCurrentEntry(int case_insens) +static void addCurrentEntry(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()); - current_root->addSubEntry(current); - last_entry = current; - current = new Entry ; + last_entry = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -2375,7 +2352,7 @@ static void addModule(const char *name, bool isModule) if (name!=NULL) { current->name = name; - } + } else { QCString fname = yyFileName; @@ -2389,7 +2366,7 @@ static void addModule(const char *name, bool isModule) current->bodyLine = yyLineNr; // used for source reference current->startLine = yyLineNr; current->protection = Public ; - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); } @@ -2397,7 +2374,7 @@ static void addModule(const char *name, bool isModule) static void addSubprogram(const char *text) { DBG_CTX((stderr,"1=========> got subprog, type: %s\n",text)); - subrCurrent.prepend(current); + subrCurrent.prepend(current.get()); current->section = Entry::FUNCTION_SEC ; QCString subtype = text; subtype=subtype.lower().stripWhiteSpace(); functionLine = (subtype.find("function") != -1); @@ -2454,7 +2431,7 @@ static void addInterface(QCString name, InterfaceType type) current->fileName = yyFileName; current->bodyLine = yyLineNr; current->startLine = yyLineNr; - addCurrentEntry(1); + addCurrentEntry(true); } @@ -2513,7 +2490,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - docBlockInBody ? subrCurrent.getFirst() : current, + docBlockInBody ? subrCurrent.getFirst() : current.get(), processedDoc, // text yyFileName, // file lineNr, @@ -2526,11 +2503,11 @@ static void handleCommentBlock(const QCString &doc,bool brief) )) { DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); - if (needsEntry) addCurrentEntry(0); + if (needsEntry) addCurrentEntry(false); } DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); - if (needsEntry) addCurrentEntry(0); + if (needsEntry) addCurrentEntry(false); docBlockInBody = FALSE; } @@ -2541,8 +2518,9 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - Entry *tmp_entry = current; - current = subrCurrent.getFirst(); // temporarily switch to the entry of the subroutine / function + std::unique_ptr<Entry> tmp_entry; + current.swap(tmp_entry); + current.reset(subrCurrent.getFirst()); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation current->inbodyDocs = ""; @@ -2566,14 +2544,11 @@ 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 documemntation - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) { - // reset current back to the part inside the routine - current=tmp_entry; - return; - } - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " + + handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " + argName + " " + loc_doc,brief); + } } else { @@ -2594,7 +2569,7 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) loc_doc.stripWhiteSpace(); if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) { - current=tmp_entry; + tmp_entry.swap(current); return; } handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " + @@ -2616,13 +2591,11 @@ 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() != argName.lower())) { - current=tmp_entry; - return; + handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " + + argName + " " + loc_doc,brief); } - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " + - argName + " " + loc_doc,brief); } else { @@ -2633,19 +2606,14 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) } } // analogous to the [in] case; here no direction specified - else + else if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) { - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) - { - current=tmp_entry; - return; - } handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " + argName + " " + loc_doc,brief); } // reset current back to the part inside the routine - current=tmp_entry; + tmp_entry.swap(current); } //---------------------------------------------------------------------------- /// Handle result description as defined after the declaration of the parameter @@ -2654,8 +2622,9 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief) QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - Entry *tmp_entry = current; - current = subrCurrent.getFirst(); // temporarily switch to the entry of the subroutine / function + std::unique_ptr<Entry> tmp_entry; + current.swap(tmp_entry); + current.reset(subrCurrent.getFirst()); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation current->inbodyDocs = ""; @@ -2668,15 +2637,13 @@ 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() != argName.lower())) { - current=tmp_entry; - return; + handleCommentBlock(QCString("\n\n@returns ") + loc_doc,brief); } - handleCommentBlock(QCString("\n\n@returns ") + loc_doc,brief); // reset current back to the part inside the routine - current=tmp_entry; + tmp_entry.swap(current); } //---------------------------------------------------------------------------- @@ -2687,18 +2654,17 @@ static void debugCompounds(Entry *rt) // print Entry structure (for debugging) { level++; printf("%d) debugCompounds(%s) line %d\n",level, rt->name.data(), rt->bodyLine); - EntryListIterator eli(*rt->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (const auto &ce : rt->children()) { - debugCompounds(ce); - } + debugCompounds(ce.get()); + } level--; } #endif -static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, FortranFormat format) +static void parseMain(const char *fileName,const char *fileBuf, + const std::unique_ptr<Entry> &rt, FortranFormat format) { char *tmpBuf = NULL; initParser(); @@ -2713,8 +2679,8 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra mtype = Method; gstat = FALSE; virt = Normal; - current_root = rt; - global_root = rt; + current_root = rt.get(); + global_root = rt.get(); inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { @@ -2750,18 +2716,18 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra yyFileName = fileName; msg("Parsing file %s...\n",yyFileName.data()); - global_scope = rt; - startScope(rt); // implies current_root = rt + global_scope = rt.get(); + startScope(rt.get()); // implies current_root = rt initParser(); Doxygen::docGroup.enterFile(yyFileName,yyLineNr); - current = new Entry; + // add entry for the file + current = std::make_unique<Entry>(); current->lang = SrcLangExt_Fortran; current->name = yyFileName; current->section = Entry::SOURCE_SEC; - current_root->addSubEntry(current); - file_root = current; - current = new Entry; + file_root = current.get(); + current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; fortranscannerYYrestart( fortranscannerYYin ); @@ -2772,12 +2738,12 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra fortranscannerYYlex(); Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); - if (global_scope && global_scope != (Entry *) -1) endScope(current_root, TRUE); // TRUE - global root + if (global_scope && global_scope != INVALID_ENTRY) endScope(current_root, TRUE); // TRUE - global root //debugCompounds(rt); //debug rt->program.resize(0); - delete current; current=0; + //delete current; current=0; moduleProcedures.clear(); if (tmpBuf) { free((char*)tmpBuf); @@ -2796,7 +2762,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra void FortranLanguageScanner::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { @@ -2856,13 +2822,11 @@ static void scanner_abort() fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyFileName.data(),yyLineNr,YY_START,stateToString(YY_START)); fprintf(stderr,"********************************************************************\n"); - EntryListIterator eli(*global_root->children()); - Entry *ce; bool start=FALSE; - for (;(ce=eli.current());++eli) + for (const auto &ce : global_root->children()) { - if (ce == file_root) start=TRUE; + if (ce.get() == file_root) start=TRUE; if (start) ce->reset(); } |