Skip to content
Snippets Groups Projects
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
Branches
Tags
No related merge requests found
...@@ -33,7 +33,8 @@ main1(const string &filename, const string &basename, istream &modfile, bool deb ...@@ -33,7 +33,8 @@ main1(const string &filename, const string &basename, istream &modfile, bool deb
{ {
// Do macro processing // Do macro processing
macro::Environment env = macro::Environment(); 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); m.parse(filename, basename, modfile, macro_output, debug, defines, path);
if (save_macro) if (save_macro)
{ {
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
*/ */
#include "Directives.hh" #include "Directives.hh"
#include "Driver.hh"
#include <fstream>
using namespace macro; using namespace macro;
...@@ -39,15 +42,45 @@ Eval::interpret(ostream &output, bool no_line_macro) ...@@ -39,15 +42,45 @@ Eval::interpret(ostream &output, bool no_line_macro)
} }
} }
string void
Include::interpretAndGetName() const Include::interpret(ostream &output, bool no_line_macro)
{ {
#ifdef _WIN32
string FILESEP = "\\";
#else
string FILESEP = "/";
#endif
try try
{ {
StringPtr msp = dynamic_pointer_cast<String>(expr->eval()); StringPtr msp = dynamic_pointer_cast<String>(expr->eval());
if (!msp) if (!msp)
throw StackTrace("File name does not evaluate to a string"); 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) catch (StackTrace &ex)
{ {
...@@ -58,7 +91,6 @@ Include::interpretAndGetName() const ...@@ -58,7 +91,6 @@ Include::interpretAndGetName() const
{ {
error(StackTrace("@#include", e.what(), location)); error(StackTrace("@#include", e.what(), location));
} }
return "";
} }
void void
......
...@@ -66,17 +66,11 @@ namespace macro ...@@ -66,17 +66,11 @@ namespace macro
{ {
private: private:
const ExpressionPtr expr; const ExpressionPtr expr;
vector<string> &paths;
public: public:
Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : 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)} { } Directive(env_arg, move(location_arg)), expr{move(expr_arg)}, paths{paths_arg} { }
// Not interpretable because we want the class to be immutable (for use with shared_ptr) void interpret(ostream &output, bool no_line_macro) override;
// 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;
}; };
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
#include "Driver.hh" #include "Driver.hh"
#include <fstream>
using namespace macro; using namespace macro;
void void
...@@ -28,12 +26,6 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi ...@@ -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, ostream &output, bool debug, const vector<pair<string, string>> &defines,
vector<string> paths_arg) vector<string> paths_arg)
{ {
#ifdef _WIN32
string FILESEP = "\\";
#else
string FILESEP = "/";
#endif
file = file_arg; file = file_arg;
basename = basename_arg; basename = basename_arg;
paths = move(paths_arg); paths = move(paths_arg);
...@@ -80,39 +72,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi ...@@ -80,39 +72,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
statement->printLineInfo(output, no_line_macro); statement->printLineInfo(output, no_line_macro);
printLine = false; printLine = false;
} }
statement->interpret(output, no_line_macro);
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);
} }
} }
......
...@@ -56,6 +56,9 @@ namespace macro ...@@ -56,6 +56,9 @@ namespace macro
class Eval; class Eval;
using EvalPtr = shared_ptr<Eval>; using EvalPtr = shared_ptr<Eval>;
// For Directives.cc
class Driver;
namespace codes namespace codes
{ {
enum class BaseType enum class BaseType
......
...@@ -126,7 +126,7 @@ directive : directive_one_line EOL ...@@ -126,7 +126,7 @@ directive : directive_one_line EOL
; ;
directive_one_line : INCLUDE expr directive_one_line : INCLUDE expr
{ $$ = make_shared<Include>($2, driver.env, @$); } { $$ = make_shared<Include>($2, driver.env, driver.paths, @$); }
| INCLUDEPATH expr | INCLUDEPATH expr
{ $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); } { $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); }
| DEFINE symbol EQUAL expr | DEFINE symbol EQUAL expr
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment