diff options
author | Brad King <brad.king@kitware.com> | 2015-07-22 18:03:00 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-07-27 13:45:36 (GMT) |
commit | eebe732bb61bb69f50edae9b7fb171266b216752 (patch) | |
tree | 59d94fa526a28bc0a28bd837eddf5b6a031fc738 /Source/cmDependsFortran.cxx | |
parent | fd1944580266c3c84234b28e2102fc787ed5c00d (diff) | |
download | CMake-eebe732bb61bb69f50edae9b7fb171266b216752.zip CMake-eebe732bb61bb69f50edae9b7fb171266b216752.tar.gz CMake-eebe732bb61bb69f50edae9b7fb171266b216752.tar.bz2 |
cmFortranParser: Factor out of cmDependsFortran
Move the main parser class and method implementations out of
cmDependsFortran.cxx and into separate source files.
Diffstat (limited to 'Source/cmDependsFortran.cxx')
-rw-r--r-- | Source/cmDependsFortran.cxx | 465 |
1 files changed, 0 insertions, 465 deletions
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index a422a98..13c6409 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -19,84 +19,12 @@ #include "cmFortranParser.h" /* Interface to parser object. */ #include <cmsys/FStream.hxx> #include <assert.h> -#include <stack> // TODO: Test compiler for the case of the mod file. Some always // use lower case and some always use upper case. I do not know if any // use the case from the source code. //---------------------------------------------------------------------------- -// Information about a single source file. -class cmFortranSourceInfo -{ -public: - // The name of the source file. - std::string Source; - - // Set of provided and required modules. - std::set<std::string> Provides; - std::set<std::string> Requires; - - // Set of files included in the translation unit. - std::set<std::string> Includes; -}; - -//---------------------------------------------------------------------------- -// Parser methods not included in generated interface. - -// Get the current buffer processed by the lexer. -YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner); - -// The parser entry point. -int cmFortran_yyparse(yyscan_t); - -//---------------------------------------------------------------------------- -// Define parser object internal structure. -struct cmFortranFile -{ - cmFortranFile(FILE* file, YY_BUFFER_STATE buffer, - const std::string& dir): - File(file), Buffer(buffer), Directory(dir) {} - FILE* File; - YY_BUFFER_STATE Buffer; - std::string Directory; -}; - -struct cmFortranParser_s -{ - cmFortranParser_s(std::vector<std::string> const& includes, - std::set<std::string> const& defines, - cmFortranSourceInfo& info); - ~cmFortranParser_s(); - - bool FindIncludeFile(const char* dir, const char* includeName, - std::string& fileName); - - // The include file search path. - std::vector<std::string> IncludePath; - - // Lexical scanner instance. - yyscan_t Scanner; - - // Stack of open files in the translation unit. - std::stack<cmFortranFile> FileStack; - - // Buffer for string literals. - std::string TokenString; - - // Flag for whether lexer is reading from inside an interface. - bool InInterface; - - int OldStartcond; - std::set<std::string> PPDefinitions; - size_t InPPFalseBranch; - std::stack<bool> SkipToEnd; - - // Information about the parsed source. - cmFortranSourceInfo& Info; -}; - -//---------------------------------------------------------------------------- class cmDependsFortranInternals { public: @@ -882,396 +810,3 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile, // The modules are different. return true; } - -//---------------------------------------------------------------------------- -bool cmFortranParser_s::FindIncludeFile(const char* dir, - const char* includeName, - std::string& fileName) -{ - // If the file is a full path, include it directly. - if(cmSystemTools::FileIsFullPath(includeName)) - { - fileName = includeName; - return cmSystemTools::FileExists(fileName.c_str(), true); - } - else - { - // Check for the file in the directory containing the including - // file. - std::string fullName = dir; - fullName += "/"; - fullName += includeName; - if(cmSystemTools::FileExists(fullName.c_str(), true)) - { - fileName = fullName; - return true; - } - - // Search the include path for the file. - for(std::vector<std::string>::const_iterator i = - this->IncludePath.begin(); i != this->IncludePath.end(); ++i) - { - fullName = *i; - fullName += "/"; - fullName += includeName; - if(cmSystemTools::FileExists(fullName.c_str(), true)) - { - fileName = fullName; - return true; - } - } - } - return false; -} - -//---------------------------------------------------------------------------- -cmFortranParser_s -::cmFortranParser_s(std::vector<std::string> const& includes, - std::set<std::string> const& defines, - cmFortranSourceInfo& info): - IncludePath(includes), PPDefinitions(defines), Info(info) -{ - this->InInterface = 0; - this->InPPFalseBranch = 0; - - // Initialize the lexical scanner. - cmFortran_yylex_init(&this->Scanner); - cmFortran_yyset_extra(this, this->Scanner); - - // Create a dummy buffer that is never read but is the fallback - // buffer when the last file is popped off the stack. - YY_BUFFER_STATE buffer = - cmFortran_yy_create_buffer(0, 4, this->Scanner); - cmFortran_yy_switch_to_buffer(buffer, this->Scanner); -} - -//---------------------------------------------------------------------------- -cmFortranParser_s::~cmFortranParser_s() -{ - cmFortran_yylex_destroy(this->Scanner); -} - -//---------------------------------------------------------------------------- -bool cmFortranParser_FilePush(cmFortranParser* parser, - const char* fname) -{ - // Open the new file and push it onto the stack. Save the old - // buffer with it on the stack. - if(FILE* file = cmsys::SystemTools::Fopen(fname, "rb")) - { - YY_BUFFER_STATE current = - cmFortranLexer_GetCurrentBuffer(parser->Scanner); - std::string dir = cmSystemTools::GetParentDirectory(fname); - cmFortranFile f(file, current, dir); - YY_BUFFER_STATE buffer = - cmFortran_yy_create_buffer(0, 16384, parser->Scanner); - cmFortran_yy_switch_to_buffer(buffer, parser->Scanner); - parser->FileStack.push(f); - return 1; - } - else - { - return 0; - } -} - -//---------------------------------------------------------------------------- -bool cmFortranParser_FilePop(cmFortranParser* parser) -{ - // Pop one file off the stack and close it. Switch the lexer back - // to the next one on the stack. - if(parser->FileStack.empty()) - { - return 0; - } - else - { - cmFortranFile f = parser->FileStack.top(); parser->FileStack.pop(); - fclose(f.File); - YY_BUFFER_STATE current = - cmFortranLexer_GetCurrentBuffer(parser->Scanner); - cmFortran_yy_delete_buffer(current, parser->Scanner); - cmFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner); - return 1; - } -} - -//---------------------------------------------------------------------------- -int cmFortranParser_Input(cmFortranParser* parser, - char* buffer, size_t bufferSize) -{ - // Read from the file on top of the stack. If the stack is empty, - // the end of the translation unit has been reached. - if(!parser->FileStack.empty()) - { - FILE* file = parser->FileStack.top().File; - return (int)fread(buffer, 1, bufferSize, file); - } - return 0; -} - -//---------------------------------------------------------------------------- -void cmFortranParser_StringStart(cmFortranParser* parser) -{ - parser->TokenString = ""; -} - -//---------------------------------------------------------------------------- -const char* cmFortranParser_StringEnd(cmFortranParser* parser) -{ - return parser->TokenString.c_str(); -} - -//---------------------------------------------------------------------------- -void cmFortranParser_StringAppend(cmFortranParser* parser, - char c) -{ - parser->TokenString += c; -} - -//---------------------------------------------------------------------------- -void cmFortranParser_SetInInterface(cmFortranParser* parser, - bool in) -{ - if(parser->InPPFalseBranch) - { - return; - } - - parser->InInterface = in; -} - -//---------------------------------------------------------------------------- -bool cmFortranParser_GetInInterface(cmFortranParser* parser) -{ - return parser->InInterface; -} - -//---------------------------------------------------------------------------- -void cmFortranParser_SetOldStartcond(cmFortranParser* parser, - int arg) -{ - parser->OldStartcond = arg; -} - -//---------------------------------------------------------------------------- -int cmFortranParser_GetOldStartcond(cmFortranParser* parser) -{ - return parser->OldStartcond; -} - -//---------------------------------------------------------------------------- -void cmFortranParser_Error(cmFortranParser*, const char*) -{ - // If there is a parser error just ignore it. The source will not - // compile and the user will edit it. Then dependencies will have - // to be regenerated anyway. -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleUse(cmFortranParser* parser, - const char* name) -{ - if(!parser->InPPFalseBranch) - { - parser->Info.Requires.insert(cmSystemTools::LowerCase(name) ); - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleInclude(cmFortranParser* parser, - const char* name) -{ - if(parser->InPPFalseBranch) - { - return; - } - - // If processing an include statement there must be an open file. - assert(!parser->FileStack.empty()); - - // Get the directory containing the source in which the include - // statement appears. This is always the first search location for - // Fortran include files. - std::string dir = parser->FileStack.top().Directory; - - // Find the included file. If it cannot be found just ignore the - // problem because either the source will not compile or the user - // does not care about depending on this included source. - std::string fullName; - if(parser->FindIncludeFile(dir.c_str(), name, fullName)) - { - // Found the included file. Save it in the set of included files. - parser->Info.Includes.insert(fullName); - - // Parse it immediately to translate the source inline. - cmFortranParser_FilePush(parser, fullName.c_str()); - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleModule(cmFortranParser* parser, - const char* name) -{ - if(!parser->InPPFalseBranch && !parser->InInterface) - { - parser->Info.Provides.insert(cmSystemTools::LowerCase(name)); - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleDefine(cmFortranParser* parser, - const char* macro) -{ - if(!parser->InPPFalseBranch) - { - parser->PPDefinitions.insert(macro); - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleUndef(cmFortranParser* parser, - const char* macro) -{ - if(!parser->InPPFalseBranch) - { - std::set<std::string>::iterator match; - match = parser->PPDefinitions.find(macro); - if(match != parser->PPDefinitions.end()) - { - parser->PPDefinitions.erase(match); - } - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleIfdef(cmFortranParser* parser, - const char* macro) -{ - // A new PP branch has been opened - parser->SkipToEnd.push(false); - - if (parser->InPPFalseBranch) - { - parser->InPPFalseBranch++; - } - else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end()) - { - parser->InPPFalseBranch=1; - } - else - { - parser->SkipToEnd.top() = true; - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleIfndef(cmFortranParser* parser, - const char* macro) -{ - // A new PP branch has been opened - parser->SkipToEnd.push(false); - - if (parser->InPPFalseBranch) - { - parser->InPPFalseBranch++; - } - else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end()) - { - parser->InPPFalseBranch = 1; - } - else - { - // ignore other branches - parser->SkipToEnd.top() = true; - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleIf(cmFortranParser* parser) -{ - /* Note: The current parser is _not_ able to get statements like - * #if 0 - * #if 1 - * #if MYSMBOL - * #if defined(MYSYMBOL) - * #if defined(MYSYMBOL) && ... - * right. The same for #elif. Thus in - * #if SYMBOL_1 - * .. - * #elif SYMBOL_2 - * ... - * ... - * #elif SYMBOL_N - * .. - * #else - * .. - * #endif - * _all_ N+1 branches are considered. If you got something like this - * #if defined(MYSYMBOL) - * #if !defined(MYSYMBOL) - * use - * #ifdef MYSYMBOL - * #ifndef MYSYMBOL - * instead. - */ - - // A new PP branch has been opened - // Never skip! See note above. - parser->SkipToEnd.push(false); -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleElif(cmFortranParser* parser) -{ - /* Note: There are parser limitations. See the note at - * cmFortranParser_RuleIf(..) - */ - - // Always taken unless an #ifdef or #ifndef-branch has been taken - // already. If the second condition isn't meet already - // (parser->InPPFalseBranch == 0) correct it. - if(!parser->SkipToEnd.empty() && - parser->SkipToEnd.top() && !parser->InPPFalseBranch) - { - parser->InPPFalseBranch = 1; - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleElse(cmFortranParser* parser) -{ - // if the parent branch is false do nothing! - if(parser->InPPFalseBranch > 1) - { - return; - } - - // parser->InPPFalseBranch is either 0 or 1. We change it depending on - // parser->SkipToEnd.top() - if(!parser->SkipToEnd.empty() && - parser->SkipToEnd.top()) - { - parser->InPPFalseBranch = 1; - } - else - { - parser->InPPFalseBranch = 0; - } -} - -//---------------------------------------------------------------------------- -void cmFortranParser_RuleEndif(cmFortranParser* parser) -{ - if(!parser->SkipToEnd.empty()) - { - parser->SkipToEnd.pop(); - } - - // #endif doesn't know if there was a "#else" in before, so it - // always decreases InPPFalseBranch - if(parser->InPPFalseBranch) - { - parser->InPPFalseBranch--; - } -} |