ENH: Added Fortran dependency scanner implementation.
This commit is contained in:
parent
aaac6f2c3a
commit
19f977bad7
|
@ -0,0 +1,384 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#include "cmDependsFortran.h"
|
||||||
|
|
||||||
|
#include "cmSystemTools.h"
|
||||||
|
|
||||||
|
#include "cmDependsFortranLexer.h" /* Interface to lexer object. */
|
||||||
|
#include "cmDependsFortranParser.h" /* Interface to parser object. */
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Parser methods not included in generated interface.
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
// Get the current buffer processed by the lexer.
|
||||||
|
YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
|
||||||
|
|
||||||
|
// The parser entry point.
|
||||||
|
int cmDependsFortranParser_yyparse(yyscan_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define parser object internal structure.
|
||||||
|
struct cmDependsFortranFile
|
||||||
|
{
|
||||||
|
FILE* File;
|
||||||
|
YY_BUFFER_STATE Buffer;
|
||||||
|
std::string Directory;
|
||||||
|
};
|
||||||
|
struct cmDependsFortranParser_s
|
||||||
|
{
|
||||||
|
cmDependsFortranParser_s(cmDependsFortran* self);
|
||||||
|
~cmDependsFortranParser_s();
|
||||||
|
|
||||||
|
// Pointer back to the main class.
|
||||||
|
cmDependsFortran* Self;
|
||||||
|
|
||||||
|
// Lexical scanner instance.
|
||||||
|
yyscan_t Scanner;
|
||||||
|
|
||||||
|
// Stack of open files in the translation unit.
|
||||||
|
std::stack<cmDependsFortranFile> FileStack;
|
||||||
|
|
||||||
|
// Buffer for string literals.
|
||||||
|
std::string TokenString;
|
||||||
|
|
||||||
|
// Flag for whether lexer is reading from inside an interface.
|
||||||
|
int InInterface;
|
||||||
|
|
||||||
|
// Set of provided and required modules.
|
||||||
|
std::set<cmStdString> Provides;
|
||||||
|
std::set<cmStdString> Requires;
|
||||||
|
|
||||||
|
// Set of files included in the translation unit.
|
||||||
|
std::set<cmStdString> Includes;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmDependsFortran::cmDependsFortran(const char* dir, const char* targetFile):
|
||||||
|
cmDepends(dir, targetFile),
|
||||||
|
m_SourceFile(),
|
||||||
|
m_IncludePath(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmDependsFortran::cmDependsFortran(const char* dir, const char* targetFile,
|
||||||
|
const char* sourceFile,
|
||||||
|
std::vector<std::string> const& includes):
|
||||||
|
cmDepends(dir, targetFile),
|
||||||
|
m_SourceFile(sourceFile),
|
||||||
|
m_IncludePath(&includes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmDependsFortran::~cmDependsFortran()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmDependsFortran::WriteDependencies(std::ostream& os)
|
||||||
|
{
|
||||||
|
// Make sure this is a scanning instance.
|
||||||
|
if(m_SourceFile == "")
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("Cannot scan dependencies without an source file.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!m_IncludePath)
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("Cannot scan dependencies without an include path.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the parser object.
|
||||||
|
cmDependsFortranParser parser(this);
|
||||||
|
|
||||||
|
// Push on the starting file.
|
||||||
|
cmDependsFortranParser_FilePush(&parser, m_SourceFile.c_str());
|
||||||
|
|
||||||
|
// Parse the translation unit.
|
||||||
|
if(cmDependsFortranParser_yyparse(parser.Scanner) != 0)
|
||||||
|
{
|
||||||
|
// Failed to parse the file. Report failure to write dependencies.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the dependencies to the output stream.
|
||||||
|
const std::set<cmStdString>& dependencies = parser.Includes;
|
||||||
|
for(std::set<cmStdString>::const_iterator i=dependencies.begin();
|
||||||
|
i != dependencies.end(); ++i)
|
||||||
|
{
|
||||||
|
os << m_TargetFile.c_str() << ": "
|
||||||
|
<< cmSystemTools::ConvertToOutputPath(i->c_str()).c_str()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
os << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmDependsFortran::CheckDependencies(std::istream&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmDependsFortran::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());
|
||||||
|
}
|
||||||
|
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()))
|
||||||
|
{
|
||||||
|
fileName = fullName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search the include path for the file.
|
||||||
|
for(std::vector<std::string>::const_iterator i = m_IncludePath->begin();
|
||||||
|
i != m_IncludePath->end(); ++i)
|
||||||
|
{
|
||||||
|
fullName = *i;
|
||||||
|
fullName += "/";
|
||||||
|
fullName += includeName;
|
||||||
|
if(cmSystemTools::FileExists(fullName.c_str()))
|
||||||
|
{
|
||||||
|
fileName = fullName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmDependsFortranParser_s::cmDependsFortranParser_s(cmDependsFortran* self):
|
||||||
|
Self(self)
|
||||||
|
{
|
||||||
|
this->InInterface = 0;
|
||||||
|
|
||||||
|
// Initialize the lexical scanner.
|
||||||
|
cmDependsFortranLexer_yylex_init(&this->Scanner);
|
||||||
|
cmDependsFortranLexer_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 =
|
||||||
|
cmDependsFortranLexer_yy_create_buffer(0, 4, this->Scanner);
|
||||||
|
cmDependsFortranLexer_yy_switch_to_buffer(buffer, this->Scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmDependsFortranParser_s::~cmDependsFortranParser_s()
|
||||||
|
{
|
||||||
|
cmDependsFortranLexer_yylex_destroy(this->Scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int cmDependsFortranParser_FilePush(cmDependsFortranParser* 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 = fopen(fname, "rb"))
|
||||||
|
{
|
||||||
|
YY_BUFFER_STATE current =
|
||||||
|
cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
|
||||||
|
std::string dir = cmSystemTools::GetParentDirectory(fname);
|
||||||
|
cmDependsFortranFile f = {file, current, dir};
|
||||||
|
YY_BUFFER_STATE buffer =
|
||||||
|
cmDependsFortranLexer_yy_create_buffer(0, 16384, parser->Scanner);
|
||||||
|
cmDependsFortranLexer_yy_switch_to_buffer(buffer, parser->Scanner);
|
||||||
|
parser->FileStack.push(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int cmDependsFortranParser_FilePop(cmDependsFortranParser* 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
|
||||||
|
{
|
||||||
|
cmDependsFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
|
||||||
|
fclose(f.File);
|
||||||
|
YY_BUFFER_STATE current =
|
||||||
|
cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
|
||||||
|
cmDependsFortranLexer_yy_delete_buffer(current, parser->Scanner);
|
||||||
|
cmDependsFortranLexer_yy_switch_to_buffer(f.Buffer, parser->Scanner);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int cmDependsFortranParser_Input(cmDependsFortranParser* 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 cmDependsFortranParser_StringStart(cmDependsFortranParser* parser)
|
||||||
|
{
|
||||||
|
parser->TokenString = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser)
|
||||||
|
{
|
||||||
|
return parser->TokenString.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
|
||||||
|
char c)
|
||||||
|
{
|
||||||
|
parser->TokenString += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
|
||||||
|
int in)
|
||||||
|
{
|
||||||
|
parser->InInterface = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser)
|
||||||
|
{
|
||||||
|
return parser->InInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_Error(cmDependsFortranParser*, 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 cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
parser->Requires.insert(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
// 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->Self->FindIncludeFile(dir.c_str(), name, fullName))
|
||||||
|
{
|
||||||
|
// Found the included file. Save it in the set of included files.
|
||||||
|
parser->Includes.insert(fullName);
|
||||||
|
|
||||||
|
// Parse it immediately to translate the source inline.
|
||||||
|
cmDependsFortranParser_FilePush(parser, fullName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
parser->Provides.insert(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleDefine(cmDependsFortranParser*, const char*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleUndef(cmDependsFortranParser*, const char*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser*, const char*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser*, const char*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleIf(cmDependsFortranParser*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleElif(cmDependsFortranParser*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleElse(cmDependsFortranParser*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDependsFortranParser_RuleEndif(cmDependsFortranParser*)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmDependsFortran_h
|
||||||
|
#define cmDependsFortran_h
|
||||||
|
|
||||||
|
#include "cmDepends.h"
|
||||||
|
|
||||||
|
/** \class cmDependsFortran
|
||||||
|
* \brief Dependency scanner for Fortran object files.
|
||||||
|
*/
|
||||||
|
class cmDependsFortran: public cmDepends
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Checking instances need to know the build directory name and the
|
||||||
|
relative path from the build directory to the target file. */
|
||||||
|
cmDependsFortran(const char* dir, const char* targetFile);
|
||||||
|
|
||||||
|
/** Scanning need to know the build directory name, the relative
|
||||||
|
path from the build directory to the target file, the source
|
||||||
|
file from which to start scanning, and the include file search
|
||||||
|
path. */
|
||||||
|
cmDependsFortran(const char* dir, const char* targetFile,
|
||||||
|
const char* sourceFile, std::vector<std::string> const& includes);
|
||||||
|
|
||||||
|
/** Virtual destructor to cleanup subclasses properly. */
|
||||||
|
virtual ~cmDependsFortran();
|
||||||
|
|
||||||
|
/** Method to find an included file in the include path. Fortran
|
||||||
|
always searches the directory containing the including source
|
||||||
|
first. */
|
||||||
|
bool FindIncludeFile(const char* dir, const char* includeName,
|
||||||
|
std::string& fileName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Implement writing/checking methods required by superclass.
|
||||||
|
virtual bool WriteDependencies(std::ostream& os);
|
||||||
|
virtual bool CheckDependencies(std::istream& is);
|
||||||
|
|
||||||
|
// The source file from which to start scanning.
|
||||||
|
std::string m_SourceFile;
|
||||||
|
|
||||||
|
// The include file search path.
|
||||||
|
std::vector<std::string> const* m_IncludePath;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cmDependsFortran(cmDependsFortran const&); // Purposely not implemented.
|
||||||
|
void operator=(cmDependsFortran const&); // Purposely not implemented.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,203 @@
|
||||||
|
%{
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
Portions of this source have been derived from makefdep90 version 2.6.2,
|
||||||
|
|
||||||
|
Copyright (C) 2000,2001 Erik Edelmann <eedelman@beam.helsinki.fi>.
|
||||||
|
|
||||||
|
The code was originally distributed under the GPL but permission
|
||||||
|
from the copyright holder has been obtained to distribute this
|
||||||
|
derived work under the CMake license.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This file must be translated to C and modified to build everywhere.
|
||||||
|
|
||||||
|
Run flex like this:
|
||||||
|
|
||||||
|
flex --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.c cmDependsFortranLexer.in.l
|
||||||
|
|
||||||
|
Modify cmDependsFortranLexer.c:
|
||||||
|
- remove TABs
|
||||||
|
- add a statement "(void)yyscanner;" to the top of these methods:
|
||||||
|
yy_fatal_error, yyalloc, yyrealloc, yyfree
|
||||||
|
- remove all YY_BREAK lines occurring right after return statements
|
||||||
|
|
||||||
|
Modify cmDependsFortranLexer.h:
|
||||||
|
- remove TABs
|
||||||
|
- remove the yy_init_globals function
|
||||||
|
- add these lines around all function declarations:
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
...
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cmDependsFortranParser.h" /* Interface to parser object. */
|
||||||
|
|
||||||
|
/* Disable some warnings. */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning ( disable : 4127 )
|
||||||
|
# pragma warning ( disable : 4131 )
|
||||||
|
# pragma warning ( disable : 4244 )
|
||||||
|
# pragma warning ( disable : 4251 )
|
||||||
|
# pragma warning ( disable : 4267 )
|
||||||
|
# pragma warning ( disable : 4305 )
|
||||||
|
# pragma warning ( disable : 4309 )
|
||||||
|
# pragma warning ( disable : 4706 )
|
||||||
|
# pragma warning ( disable : 4786 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Disable features we do not need. */
|
||||||
|
#define YY_NEVER_INTERACTIVE 1
|
||||||
|
#define YY_NO_UNISTD_H 1
|
||||||
|
#define ECHO
|
||||||
|
|
||||||
|
/* Setup the proper yylex declaration. */
|
||||||
|
#define YY_EXTRA_TYPE cmDependsFortranParser*
|
||||||
|
#define YY_DECL int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
|
||||||
|
|
||||||
|
/* Replace the lexer input function. */
|
||||||
|
#undef YY_INPUT
|
||||||
|
#define YY_INPUT(buf, result, max_size) \
|
||||||
|
{ result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
|
||||||
|
|
||||||
|
/* Include the set of tokens from the parser. */
|
||||||
|
#include "cmDependsFortranParserTokens.h"
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
%}
|
||||||
|
|
||||||
|
%option reentrant
|
||||||
|
%option noyywrap
|
||||||
|
%pointer
|
||||||
|
|
||||||
|
%s free_fmt fixed_fmt
|
||||||
|
%x str_sq str_dq
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
\" {
|
||||||
|
cmDependsFortranParser_StringStart(yyextra);
|
||||||
|
BEGIN(str_dq);
|
||||||
|
}
|
||||||
|
|
||||||
|
' {
|
||||||
|
cmDependsFortranParser_StringStart(yyextra);
|
||||||
|
BEGIN(str_sq);
|
||||||
|
}
|
||||||
|
|
||||||
|
<str_dq>\" |
|
||||||
|
<str_sq>' {
|
||||||
|
yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
<str_dq,str_sq>&[ \t]*\n |
|
||||||
|
<str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */
|
||||||
|
|
||||||
|
<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] /*Ignore (cont. strings, fixed fmt) */
|
||||||
|
|
||||||
|
<str_dq,str_sq>\n {
|
||||||
|
unput ('\n');
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return UNTERMINATED_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
<str_sq,str_dq>. {
|
||||||
|
cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
!.*\n { return EOSTMT; } /* Treat comments like */
|
||||||
|
<fixed_fmt>^[cC*dD].*\n { return EOSTMT; } /* empty lines */
|
||||||
|
|
||||||
|
#[ \t]*include { return CPP_INCLUDE; }
|
||||||
|
\$[ \t]*include { return F90PPR_INCLUDE; }
|
||||||
|
\?\?[ \t]*include { return COCO_INCLUDE; }
|
||||||
|
INCLUDE { return F_INCLUDE; }
|
||||||
|
USE { return USE; }
|
||||||
|
|
||||||
|
END" "*INTERFACE {
|
||||||
|
cmDependsFortranParser_SetInInterface(yyextra, 0);
|
||||||
|
}
|
||||||
|
INTERFACE {
|
||||||
|
cmDependsFortranParser_SetInInterface(yyextra, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
END" "*MODULE /* Ignore */
|
||||||
|
MODULE {
|
||||||
|
if(!cmDependsFortranParser_GetInInterface(yyextra))
|
||||||
|
{
|
||||||
|
return MODULE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ \t]*define { return CPP_DEFINE; }
|
||||||
|
\$[ \t]*DEFINE { return F90PPR_DEFINE; }
|
||||||
|
|
||||||
|
#[ \t]*undef { return CPP_UNDEF; }
|
||||||
|
\$[ \t]*UNDEF { return F90PPR_UNDEF; }
|
||||||
|
|
||||||
|
#[ \t]*ifdef { return CPP_IFDEF; }
|
||||||
|
#[ \t]*ifndef { return CPP_IFNDEF; }
|
||||||
|
#[ \t]*if { return CPP_IF; }
|
||||||
|
#[ \t]*elif { return CPP_ELIF; }
|
||||||
|
#[ \t]*else { return CPP_ELSE; }
|
||||||
|
#[ \t]*endif { return CPP_ENDIF; }
|
||||||
|
|
||||||
|
$[ \t]*ifdef { return F90PPR_IFDEF; }
|
||||||
|
$[ \t]*ifndef { return F90PPR_IFNDEF; }
|
||||||
|
$[ \t]*if { return F90PPR_IF; }
|
||||||
|
$[ \t]*elif { return F90PPR_ELIF; }
|
||||||
|
$[ \t]*else { return F90PPR_ELSE; }
|
||||||
|
$[ \t]*endif { return F90PPR_ENDIF; }
|
||||||
|
|
||||||
|
&[ \t]*\n |
|
||||||
|
&[ \t]*\n[ \t]*& /* Ignore */
|
||||||
|
|
||||||
|
|
||||||
|
[^ \t\n\r;,!'""']+ { yylvalp->string = strdup(yytext); return WORD; }
|
||||||
|
|
||||||
|
;|\n { return EOSTMT; }
|
||||||
|
|
||||||
|
[ \t\r,] /* Ignore */
|
||||||
|
|
||||||
|
. { return *yytext; }
|
||||||
|
|
||||||
|
<<EOF>> {
|
||||||
|
if(!cmDependsFortranParser_FilePop(yyextra))
|
||||||
|
{
|
||||||
|
return YY_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
|
||||||
|
{
|
||||||
|
/* Hack into the internal flex-generated scanner to get the buffer. */
|
||||||
|
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||||
|
return YY_CURRENT_BUFFER;
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmDependsFortranParser_h
|
||||||
|
#define cmDependsFortranParser_h
|
||||||
|
|
||||||
|
/* Forward declare parser object type. */
|
||||||
|
typedef struct cmDependsFortranParser_s cmDependsFortranParser;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Functions to enter/exit #include'd files in order. */
|
||||||
|
int cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
|
||||||
|
const char* fname);
|
||||||
|
int cmDependsFortranParser_FilePop(cmDependsFortranParser* parser);
|
||||||
|
|
||||||
|
/* Callbacks for lexer. */
|
||||||
|
int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
|
||||||
|
char* buffer, size_t bufferSize);
|
||||||
|
void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser);
|
||||||
|
const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser);
|
||||||
|
void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
|
||||||
|
char c);
|
||||||
|
void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
|
||||||
|
int in);
|
||||||
|
int cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser);
|
||||||
|
|
||||||
|
/* Callbacks for parser. */
|
||||||
|
void cmDependsFortranParser_Error(cmDependsFortranParser* parser,
|
||||||
|
const char* message);
|
||||||
|
void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
|
||||||
|
const char* name);
|
||||||
|
void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser);
|
||||||
|
void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser);
|
||||||
|
void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser);
|
||||||
|
void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,165 @@
|
||||||
|
%{
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
Portions of this source have been derived from makefdep90 version 2.6.2,
|
||||||
|
|
||||||
|
Copyright (C) 2000,2001 Erik Edelmann <eedelman@beam.helsinki.fi>.
|
||||||
|
|
||||||
|
The code was originally distributed under the GPL but permission
|
||||||
|
from the copyright holder has been obtained to distribute this
|
||||||
|
derived work under the CMake license.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This file must be translated to C and modified to build everywhere.
|
||||||
|
|
||||||
|
Run bison like this:
|
||||||
|
|
||||||
|
bison --yacc --name-prefix=cmDependsFortran_yy --defines=cmDependsFortranParserTokens.h -ocmDependsFortranParser.c cmDependsFortranParser.y
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Configure the parser to use a lexer object. */
|
||||||
|
#define YYPARSE_PARAM yyscanner
|
||||||
|
#define YYLEX_PARAM yyscanner
|
||||||
|
#define YY_DECL int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
|
||||||
|
#define YYERROR_VERBOSE 1
|
||||||
|
#define cmDependsFortran_yyerror(x) \
|
||||||
|
cmDependsFortranError(yyscanner, x)
|
||||||
|
|
||||||
|
#include "cmDependsFortranLexer.h" /* Interface to lexer object. */
|
||||||
|
#include "cmDependsFortranParser.h" /* Interface to parser object. */
|
||||||
|
|
||||||
|
/* Internal utility functions. */
|
||||||
|
static void cmDependsFortranError(yyscan_t yyscanner, const char* message);
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Generate a reentrant parser object. */
|
||||||
|
%pure_parser
|
||||||
|
|
||||||
|
%union {
|
||||||
|
char* string;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token USE F_INCLUDE MODULE EOSTMT
|
||||||
|
%token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE
|
||||||
|
%token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF
|
||||||
|
%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
|
||||||
|
%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
|
||||||
|
%token UNTERMINATED_STRING
|
||||||
|
%token <string> CPP_TOENDL STRING WORD
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
code: /* empty */ | code stmt ;
|
||||||
|
|
||||||
|
stmt:
|
||||||
|
USE WORD other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleUse(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| include STRING other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleInclude(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| CPP_INCLUDE WORD other eostmt /* Ignore */
|
||||||
|
| MODULE WORD eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleModule(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| define WORD other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleDefine(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| undef WORD other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleUndef(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| ifdef WORD other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleIfdef(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| ifndef WORD other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleIfndef(parser, $2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| if other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleIf(parser);
|
||||||
|
}
|
||||||
|
| elif other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleElif(parser);
|
||||||
|
}
|
||||||
|
| else other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleElse(parser);
|
||||||
|
}
|
||||||
|
| endif other eostmt
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_RuleEndif(parser);
|
||||||
|
}
|
||||||
|
| other eostmt /* Ignore */
|
||||||
|
;
|
||||||
|
|
||||||
|
eostmt: /* empty */ | EOSTMT ;
|
||||||
|
include: F_INCLUDE | CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
|
||||||
|
define: CPP_DEFINE | F90PPR_DEFINE ;
|
||||||
|
undef: CPP_UNDEF | F90PPR_UNDEF ;
|
||||||
|
ifdef: CPP_IFDEF | F90PPR_IFDEF ;
|
||||||
|
ifndef: CPP_IFNDEF | F90PPR_IFNDEF ;
|
||||||
|
if: CPP_IF | F90PPR_IF ;
|
||||||
|
elif: CPP_ELIF | F90PPR_ELIF ;
|
||||||
|
else: CPP_ELSE | F90PPR_ELSE ;
|
||||||
|
endif: CPP_ENDIF | F90PPR_ENDIF ;
|
||||||
|
other: /* empty */ | other misc_code ;
|
||||||
|
|
||||||
|
misc_code:
|
||||||
|
WORD { free ($1); }
|
||||||
|
| STRING { free ($1); }
|
||||||
|
| UNTERMINATED_STRING
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void cmDependsFortranError(yyscan_t yyscanner, const char* message)
|
||||||
|
{
|
||||||
|
cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
|
||||||
|
cmDependsFortranParser_Error(parser, message);
|
||||||
|
}
|
Loading…
Reference in New Issue