preprocessor: macroprocessor: add @#includepath macro. #1039

issue#70
Houtan Bastani 2015-08-28 12:38:25 +02:00
parent 38443b0775
commit ee6880bfdb
2 changed files with 66 additions and 2 deletions

View File

@ -79,7 +79,7 @@ private:
//! Should we omit the @#line statements ?
const bool no_line_macro;
//! The paths to search when looking for .mod files
const vector<string> path;
vector<string> path;
//! True iff current context is the body of a loop
bool is_for_context;
//! If current context is the body of a loop, contains the string of the loop body
@ -122,6 +122,10 @@ private:
//! Restore last scanning context
void restore_context(Macro::parser::location_type *yylloc);
//! pushes the colon-separated paths passed to @#includepath onto the path vector
void push_path(string *includepath, Macro::parser::location_type *yylloc,
MacroDriver &driver);
//! Saves current scanning context and create a new context with content of filename
/*! Filename must be a newly allocated string which will be deleted by the lexer */
void create_include_context(string *filename, Macro::parser::location_type *yylloc,
@ -178,7 +182,7 @@ public:
//! Starts parsing a file, returns output in out
/*! \param no_line_macro should we omit the @#line statements ? */
void parse(const string &f, ostream &out, bool debug, bool no_line_macro,
map<string,string> defines, const vector<string> path);
map<string,string> defines, vector<string> path);
//! Name of main file being parsed
string file;

View File

@ -21,6 +21,9 @@
using namespace std;
#include <fstream>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/tokenizer.hpp>
#include "MacroDriver.hh"
@ -68,6 +71,47 @@ CONT \\\\
yylloc->step();
%}
<INITIAL>^{SPC}*@#{SPC}*includepath{SPC}+\"([^\"\r\n:;|<>]*){1}(:[^\"\r\n:;|<>]*)*\"{SPC}*{EOL} {
yylloc->lines(1);
yylloc->step();
// Get path
string *includepath = new string(yytext);
int dblq_idx1 = includepath->find('"');
int dblq_idx2 = includepath->find('"', dblq_idx1 + 1);
includepath->erase(dblq_idx2);
includepath->erase(0, dblq_idx1 + 1);
push_path(includepath, yylloc, driver);
BEGIN(INITIAL);
}
<INITIAL>^{SPC}*@#{SPC}*includepath{SPC}+[^\"\r\n]*{SPC}*{EOL} {
yylloc->lines(1);
yylloc->step();
// Get variable name
string pathvar = string(yytext);
int dblq_idx1 = pathvar.find("includepath");
pathvar.erase(0, dblq_idx1 + 11);
pathvar.erase(0, pathvar.find_first_not_of(" \t"));
size_t p = pathvar.find_last_not_of(" \t\n\r");
if (string::npos != p)
pathvar.erase(p+1);
string *includepath = NULL;
try
{
includepath = new string(driver.get_variable(pathvar)->toString());
}
catch(MacroDriver::UnknownVariable(&e))
{
driver.error(*yylloc, "Unknown variable: " + pathvar);
}
push_path(includepath, yylloc, driver);
BEGIN(INITIAL);
}
<INITIAL>^{SPC}*@#{SPC}*include{SPC}+\"[^\"\r\n]*\"{SPC}*{EOL} {
yylloc->lines(1);
yylloc->step();
@ -383,6 +427,22 @@ MacroFlex::restore_context(Macro::parser::location_type *yylloc)
output_line(yylloc);
}
void
MacroFlex::push_path(string *includepath, Macro::parser::location_type *yylloc,
MacroDriver &driver)
{
using namespace boost;
vector<string> tokenizedPath;
split(tokenizedPath, *includepath, is_any_of(":"), token_compress_on);
for (vector<string>::iterator it = tokenizedPath.begin();
it != tokenizedPath.end(); it++ )
if (!it->empty())
{
trim(*it);
path.push_back(*it);
}
}
void
MacroFlex::create_include_context(string *filename, Macro::parser::location_type *yylloc,
MacroDriver &driver)