From 267c61564047f8768c29040f898633d9444a5404 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:21:40 +0200 Subject: [PATCH] Added support for here documents --- kernel/driver.cc | 44 ++++++++++++++++++++++++++++---------------- kernel/register.cc | 31 ++++++++++++++++++++++++++++++- kernel/register.h | 6 +++++- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 3c185e44b..97910aa98 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -28,6 +28,7 @@ #include #include +#include #include "kernel/rtlil.h" #include "kernel/register.h" @@ -116,26 +117,37 @@ 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); + 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()); } + Frontend::current_script_file = backup_script_file; + if (filename != "-") fclose(f); diff --git a/kernel/register.cc b/kernel/register.cc index e7ad7ef05..59667ac97 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -276,6 +276,9 @@ void Frontend::execute(std::vector 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 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 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)); diff --git a/kernel/register.h b/kernel/register.h index fd073cbe7..73875e968 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -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 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(); -- 2.30.2