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

issue#70
Houtan Bastani 2019-10-02 17:08:57 +02:00
parent db52e02158
commit 310f3936fe
No known key found for this signature in database
GPG Key ID: 000094FB955BE169
5 changed files with 15 additions and 25 deletions

View File

@ -61,15 +61,15 @@ Include::interpretAndGetName() const
return ""; return "";
} }
string void
IncludePath::interpretAndGetPath() const IncludePath::interpret(ostream &output, bool no_line_macro)
{ {
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; paths.emplace_back(*msp);
} }
catch (StackTrace &ex) catch (StackTrace &ex)
{ {
@ -80,7 +80,6 @@ IncludePath::interpretAndGetPath() const
{ {
error(StackTrace("@#includepath", e.what(), location)); error(StackTrace("@#includepath", e.what(), location));
} }
return "";
} }
void void

View File

@ -84,17 +84,11 @@ namespace macro
{ {
private: private:
const ExpressionPtr expr; const ExpressionPtr expr;
vector<string> &paths;
public: public:
IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : IncludePath(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("@#includepath", "should never be interpreted", location));
}
string interpretAndGetPath() const;
}; };

View File

@ -55,7 +55,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
else else
command_line_defines_with_endl << "@#define " << define.first << " = \"" << define.second << "\"" << endl; command_line_defines_with_endl << "@#define " << define.first << " = \"" << define.second << "\"" << endl;
} }
Driver m(env, true); Driver m(env, paths, true);
istream is(command_line_defines_with_endl.rdbuf()); istream is(command_line_defines_with_endl.rdbuf());
m.parse("command_line_defines", "command_line_defines", is, output, debug, vector<pair<string, string>>{}, paths); m.parse("command_line_defines", "command_line_defines", is, output, debug, vector<pair<string, string>>{}, paths);
} }
@ -82,10 +82,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
} }
auto ip = dynamic_pointer_cast<Include>(statement); auto ip = dynamic_pointer_cast<Include>(statement);
auto ipp = dynamic_pointer_cast<IncludePath>(statement); if (ip)
if (ipp)
paths.emplace_back(ipp->interpretAndGetPath());
else if (ip)
{ {
string filename = ip->interpretAndGetName(); string filename = ip->interpretAndGetName();
ifstream incfile(filename, ios::binary); ifstream incfile(filename, ios::binary);
@ -111,7 +108,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
if (pos != string::npos) if (pos != string::npos)
basename.erase(pos); basename.erase(pos);
Driver m(env, no_line_macro); Driver m(env, paths, no_line_macro);
m.parse(filename, basename, incfile, output, debug, vector<pair<string, string>>{}, paths); m.parse(filename, basename, incfile, output, debug, vector<pair<string, string>>{}, paths);
} }
else else

View File

@ -63,15 +63,15 @@ namespace macro
{ {
public: public:
Environment &env; Environment &env;
//! The paths to search when looking for .mod files
vector<string> &paths;
private: private:
bool no_line_macro; bool no_line_macro;
vector<DirectivePtr> statements; vector<DirectivePtr> statements;
stack<vector<DirectivePtr>> directive_stack; stack<vector<DirectivePtr>> directive_stack;
//! The paths to search when looking for .mod files
vector<string> paths;
public: public:
Driver(Environment &env_arg, bool no_line_macro_arg) : Driver(Environment &env_arg, vector<string> &paths_arg, bool no_line_macro_arg) :
env{env_arg}, no_line_macro(no_line_macro_arg) { } env{env_arg}, paths{paths_arg}, no_line_macro(no_line_macro_arg) { }
Driver(const Driver &) = delete; Driver(const Driver &) = delete;
Driver(Driver &&) = delete; Driver(Driver &&) = delete;
Driver & operator=(const Driver &) = delete; Driver & operator=(const Driver &) = delete;

View File

@ -128,7 +128,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, @$); }
| INCLUDEPATH expr | INCLUDEPATH expr
{ $$ = make_shared<IncludePath>($2, driver.env, @$); } { $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); }
| DEFINE symbol EQUAL expr | DEFINE symbol EQUAL expr
{ $$ = make_shared<Define>($2, $4, driver.env, @$); } { $$ = make_shared<Define>($2, $4, driver.env, @$); }
| DEFINE function EQUAL expr | DEFINE function EQUAL expr