mirror of https://github.com/YosysHQ/yosys.git
Added support for here documents
This commit is contained in:
parent
3f4e3ca8ad
commit
267c615640
|
@ -28,6 +28,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/register.h"
|
||||
|
@ -116,25 +117,36 @@ static void run_frontend(std::string filename, std::string command, RTLIL::Desig
|
|||
if (f == NULL)
|
||||
log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
|
||||
|
||||
std::string command;
|
||||
while (fgetline(f, command)) {
|
||||
while (!command.empty() && command[command.size()-1] == '\\') {
|
||||
std::string next_line;
|
||||
if (!fgetline(f, next_line))
|
||||
break;
|
||||
command.resize(command.size()-1);
|
||||
command += next_line;
|
||||
FILE *backup_script_file = Frontend::current_script_file;
|
||||
Frontend::current_script_file = f;
|
||||
|
||||
try {
|
||||
std::string command;
|
||||
while (fgetline(f, command)) {
|
||||
while (!command.empty() && command[command.size()-1] == '\\') {
|
||||
std::string next_line;
|
||||
if (!fgetline(f, next_line))
|
||||
break;
|
||||
command.resize(command.size()-1);
|
||||
command += next_line;
|
||||
}
|
||||
handle_label(command, from_to_active, run_from, run_to);
|
||||
if (from_to_active)
|
||||
Pass::call(design, command);
|
||||
}
|
||||
handle_label(command, from_to_active, run_from, run_to);
|
||||
if (from_to_active)
|
||||
Pass::call(design, command);
|
||||
|
||||
if (!command.empty()) {
|
||||
handle_label(command, from_to_active, run_from, run_to);
|
||||
if (from_to_active)
|
||||
Pass::call(design, command);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
Frontend::current_script_file = backup_script_file;
|
||||
std::rethrow_exception(std::current_exception());
|
||||
}
|
||||
|
||||
if (!command.empty()) {
|
||||
handle_label(command, from_to_active, run_from, run_to);
|
||||
if (from_to_active)
|
||||
Pass::call(design, command);
|
||||
}
|
||||
Frontend::current_script_file = backup_script_file;
|
||||
|
||||
if (filename != "-")
|
||||
fclose(f);
|
||||
|
|
|
@ -276,6 +276,9 @@ void Frontend::execute(std::vector<std::string> args, RTLIL::Design *design)
|
|||
} while (!args.empty());
|
||||
}
|
||||
|
||||
FILE *Frontend::current_script_file = NULL;
|
||||
std::string Frontend::last_here_document;
|
||||
|
||||
void Frontend::extra_args(FILE *&f, std::string &filename, std::vector<std::string> args, size_t argidx)
|
||||
{
|
||||
bool called_with_fp = f != NULL;
|
||||
|
@ -291,7 +294,33 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector<std::stri
|
|||
cmd_error(args, argidx, "Extra filename argument in direct file mode.");
|
||||
|
||||
filename = arg;
|
||||
f = fopen(filename.c_str(), "r");
|
||||
if (filename == "<<" && argidx+1 < args.size())
|
||||
filename += args[++argidx];
|
||||
if (filename.substr(0, 2) == "<<") {
|
||||
if (Frontend::current_script_file == NULL)
|
||||
log_error("Unexpected here document '%s' outside of script!\n", filename.c_str());
|
||||
if (filename.size() <= 2)
|
||||
log_error("Missing EOT marker in here document!\n");
|
||||
std::string eot_marker = filename.substr(2);
|
||||
last_here_document.clear();
|
||||
while (1) {
|
||||
std::string buffer;
|
||||
char block[4096];
|
||||
while (1) {
|
||||
if (fgets(block, 4096, Frontend::current_script_file) == NULL)
|
||||
log_error("Unexpected end of file in here document '%s'!\n", filename.c_str());
|
||||
buffer += block;
|
||||
if (buffer.size() > 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r'))
|
||||
break;
|
||||
}
|
||||
int indent = buffer.find_first_not_of(" \t\r\n");
|
||||
if (buffer.substr(indent, eot_marker.size()) == eot_marker)
|
||||
break;
|
||||
last_here_document += buffer;
|
||||
}
|
||||
f = fmemopen((void*)last_here_document.c_str(), last_here_document.size(), "r");
|
||||
} else
|
||||
f = fopen(filename.c_str(), "r");
|
||||
if (f == NULL)
|
||||
log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ extern const char *yosys_version_str;
|
|||
extern RTLIL::Design *yosys_get_design();
|
||||
extern std::string proc_self_dirname();
|
||||
extern std::string proc_share_dirname();
|
||||
const char *create_prompt(RTLIL::Design *design, int recursion_counter);
|
||||
extern const char *create_prompt(RTLIL::Design *design, int recursion_counter);
|
||||
|
||||
// from passes/cmds/design.cc
|
||||
extern std::map<std::string, RTLIL::Design*> saved_designs;
|
||||
|
@ -76,6 +76,10 @@ struct Pass
|
|||
|
||||
struct Frontend : Pass
|
||||
{
|
||||
// for reading of here documents
|
||||
static FILE *current_script_file;
|
||||
static std::string last_here_document;
|
||||
|
||||
std::string frontend_name;
|
||||
Frontend(std::string name, std::string short_help = "** document me **");
|
||||
virtual void run_register();
|
||||
|
|
Loading…
Reference in New Issue