Verified Commit d7e70a40 authored by Houtan Bastani's avatar Houtan Bastani
Browse files

macro processor: fix bug: interpret @#include at node level instead of at the Driver level

parent 310f3936
Pipeline #1981 passed with stage
in 1 minute and 41 seconds
......@@ -33,7 +33,8 @@ main1(const string &filename, const string &basename, istream &modfile, bool deb
{
// Do macro processing
macro::Environment env = macro::Environment();
macro::Driver m(env, no_line_macro_arg);
vector<string> paths;
macro::Driver m(env, paths, no_line_macro_arg);
m.parse(filename, basename, modfile, macro_output, debug, defines, path);
if (save_macro)
{
......
......@@ -18,6 +18,9 @@
*/
#include "Directives.hh"
#include "Driver.hh"
#include <fstream>
using namespace macro;
......@@ -39,15 +42,45 @@ Eval::interpret(ostream &output, bool no_line_macro)
}
}
string
Include::interpretAndGetName() const
void
Include::interpret(ostream &output, bool no_line_macro)
{
#ifdef _WIN32
string FILESEP = "\\";
#else
string FILESEP = "/";
#endif
try
{
StringPtr msp = dynamic_pointer_cast<String>(expr->eval());
if (!msp)
throw StackTrace("File name does not evaluate to a string");
return msp->to_string();
string filename = msp->to_string();
ifstream incfile(filename, ios::binary);
if (incfile.fail())
{
ostringstream dirs;
dirs << "." << FILESEP << endl;
for (const auto & path : paths)
{
string testfile = path + FILESEP + filename;
incfile = ifstream(testfile, ios::binary);
if (incfile.good())
break;
dirs << path << endl;
}
if (incfile.fail())
error(StackTrace("@#includepath", "Could not open " + filename +
". The following directories were searched:\n" + dirs.str(), location));
}
string basename = filename;
size_t pos = basename.find_last_of('.');
if (pos != string::npos)
basename.erase(pos);
Driver m(env, paths, no_line_macro);
m.parse(filename, basename, incfile, output, false, vector<pair<string, string>>{}, paths);
}
catch (StackTrace &ex)
{
......@@ -58,7 +91,6 @@ Include::interpretAndGetName() const
{
error(StackTrace("@#include", e.what(), location));
}
return "";
}
void
......
......@@ -66,17 +66,11 @@ namespace macro
{
private:
const ExpressionPtr expr;
vector<string> &paths;
public:
Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
// Not interpretable because we want the class to be immutable (for use with shared_ptr)
// If it were interpretable, the name would need to be stored in a non-const variable
// rendering the class mutable
inline void interpret(ostream &output, bool no_line_macro) override
{
error(StackTrace("@#include", "should never be interpreted", location));
}
string interpretAndGetName() const;
Include(ExpressionPtr expr_arg, Environment &env_arg, vector<string> &paths_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}, paths{paths_arg} { }
void interpret(ostream &output, bool no_line_macro) override;
};
......
......@@ -19,8 +19,6 @@
#include "Driver.hh"
#include <fstream>
using namespace macro;
void
......@@ -28,12 +26,6 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
ostream &output, bool debug, const vector<pair<string, string>> &defines,
vector<string> paths_arg)
{
#ifdef _WIN32
string FILESEP = "\\";
#else
string FILESEP = "/";
#endif
file = file_arg;
basename = basename_arg;
paths = move(paths_arg);
......@@ -80,39 +72,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
statement->printLineInfo(output, no_line_macro);
printLine = false;
}
auto ip = dynamic_pointer_cast<Include>(statement);
if (ip)
{
string filename = ip->interpretAndGetName();
ifstream incfile(filename, ios::binary);
if (incfile.fail())
{
ostringstream dirs;
dirs << "." << FILESEP << endl;
for (const auto & path : paths)
{
string testfile = path + FILESEP + filename;
incfile = ifstream(testfile, ios::binary);
if (incfile.good())
break;
dirs << path << endl;
}
if (incfile.fail())
error(statement->getLocation(), "Could not open " + filename +
". The following directories were searched:\n" + dirs.str());
}
string basename = filename;
size_t pos = basename.find_last_of('.');
if (pos != string::npos)
basename.erase(pos);
Driver m(env, paths, no_line_macro);
m.parse(filename, basename, incfile, output, debug, vector<pair<string, string>>{}, paths);
}
else
statement->interpret(output, no_line_macro);
statement->interpret(output, no_line_macro);
}
}
......
......@@ -56,6 +56,9 @@ namespace macro
class Eval;
using EvalPtr = shared_ptr<Eval>;
// For Directives.cc
class Driver;
namespace codes
{
enum class BaseType
......
......@@ -126,7 +126,7 @@ directive : directive_one_line EOL
;
directive_one_line : INCLUDE expr
{ $$ = make_shared<Include>($2, driver.env, @$); }
{ $$ = make_shared<Include>($2, driver.env, driver.paths, @$); }
| INCLUDEPATH expr
{ $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); }
| DEFINE symbol EQUAL expr
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment