From: Clifford Wolf Date: Wed, 1 May 2013 12:21:03 +0000 (+0200) Subject: Improved/simplified TCL bindings X-Git-Tag: yosys-0.2.0~640 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=97f783e668015065069fa2b2f85e4cbe518abc26;p=yosys.git Improved/simplified TCL bindings --- diff --git a/kernel/driver.cc b/kernel/driver.cc index a397a16cc..f06c784d8 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -149,10 +149,13 @@ static char **readline_completion(const char *text, int start, int) return NULL; } -static const char *create_prompt(RTLIL::Design *design) +static const char *create_prompt(RTLIL::Design *design, int recursion_counter) { static char buffer[100]; - std::string str = "\nyosys"; + std::string str = "\n"; + if (recursion_counter > 1) + str += stringf("(%d) ", recursion_counter); + str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", design->selected_active_module.c_str()); if (!design->selection_stack.back().full_selection) { @@ -168,26 +171,29 @@ static const char *create_prompt(RTLIL::Design *design) static void shell(RTLIL::Design *design) { - static bool recursion_detect = false; + static int recursion_counter = 0; - if (recursion_detect) { - log("Already in interactive shell.\n"); - return; - } - - recursion_detect = true; + recursion_counter++; log_cmd_error_throw = true; rl_readline_name = "yosys"; rl_attempted_completion_function = readline_completion; char *command = NULL; - while ((command = readline(create_prompt(design))) != NULL) + while ((command = readline(create_prompt(design, recursion_counter))) != NULL) { if (command[strspn(command, " \t\r\n")] == 0) continue; add_history(command); + char *p = command + strspn(command, " \t\r\n"); + if (!strncmp(p, "exit", 4)) { + p += 4; + p += strspn(p, " \t\r\n"); + if (*p == 0) + break; + } + try { assert(design->selection_stack.size() == 1); Pass::call(design, command); @@ -197,8 +203,10 @@ static void shell(RTLIL::Design *design) log_reset_stack(); } } + if (command == NULL) + printf("exit\n"); - recursion_detect = false; + recursion_counter--; log_cmd_error_throw = false; } @@ -233,7 +241,7 @@ struct ShellPass : public Pass { log("This command is the default action if nothing else has been specified\n"); log("on the command line.\n"); log("\n"); - log("Press Ctrl-D to leave the interactive shell.\n"); + log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { @@ -243,7 +251,7 @@ struct ShellPass : public Pass { } ShellPass; struct ScriptPass : public Pass { - ScriptPass() : Pass("script", "execute files from script file") { } + ScriptPass() : Pass("script", "execute commands from script file") { } virtual void help() { log("\n"); log(" script \n"); @@ -252,12 +260,45 @@ struct ScriptPass : public Pass { log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() != 2) + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + if (args.size() > 2) extra_args(args, 1, design, false); run_frontend(args[1], "script", design, NULL); } } ScriptPass; +#ifdef YOSYS_ENABLE_TCL +struct TclPass : public Pass { + TclPass() : Pass("tcl", "execute a TCL script file") { } + virtual void help() { + log("\n"); + log(" tcl \n"); + log("\n"); + log("This command executes the tcl commands in the specified file.\n"); + log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + if (args.size() > 2) + extra_args(args, 1, design, false); + if (Tcl_EvalFile(yosys_tcl, args[1].c_str()) != TCL_OK) + log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_tcl)); + } +} TclPass; + +static int tcl_yosys_cmd(ClientData, Tcl_Interp*, int argc, const char *argv[]) +{ + std::vector args; + for (int i = 1; i < argc; i++) + args.push_back(argv[i]); + Pass::call(yosys_tcl_design, args); + return TCL_OK; +} +#endif + int main(int argc, char **argv) { std::string frontend_command = "auto"; @@ -271,6 +312,7 @@ int main(int argc, char **argv) #ifdef YOSYS_ENABLE_TCL yosys_tcl = Tcl_CreateInterp(); + Tcl_CreateCommand(yosys_tcl, "yosys", tcl_yosys_cmd, NULL, NULL); #endif int opt; @@ -356,6 +398,7 @@ int main(int argc, char **argv) fprintf(stderr, "\n"); fprintf(stderr, " -c tcl_scriptfile\n"); fprintf(stderr, " execute the commands in the tcl script file\n"); + fprintf(stderr, " (use 'yosys cmd' to run the yosys command 'cmd' from tcl)\n"); fprintf(stderr, "\n"); fprintf(stderr, " -p command\n"); fprintf(stderr, " execute the commands\n"); diff --git a/kernel/register.cc b/kernel/register.cc index 0579dbc43..bfd51feb1 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -56,8 +56,6 @@ void Pass::run_register() { assert(pass_register.count(pass_name) == 0); pass_register[pass_name] = this; - - register_tcl(); } void Pass::init_register() @@ -77,25 +75,6 @@ void Pass::done_register() raw_register_done = false; } -#ifdef YOSYS_ENABLE_TCL -static int tcl_pass(ClientData that_vp, Tcl_Interp*, int argc, const char *argv[]) -{ - Pass *that = (Pass*)that_vp; - std::vector args; - for (int i = 0; i < argc; i++) - args.push_back(argv[i]); - that->call(yosys_tcl_design, args); - return TCL_OK; -} -#endif - -void Pass::register_tcl() -{ -#ifdef YOSYS_ENABLE_TCL - Tcl_CreateCommand(yosys_tcl, pass_name.c_str(), tcl_pass, (ClientData)this, NULL); -#endif -} - Pass::~Pass() { } @@ -212,8 +191,6 @@ void Frontend::run_register() assert(frontend_register.count(frontend_name) == 0); frontend_register[frontend_name] = this; - - register_tcl(); } Frontend::~Frontend() @@ -306,8 +283,6 @@ void Backend::run_register() assert(backend_register.count(backend_name) == 0); backend_register[backend_name] = this; - - register_tcl(); } Backend::~Backend() diff --git a/kernel/register.h b/kernel/register.h index 4823125d5..2f664e7c1 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -50,7 +50,6 @@ struct Pass static void init_register(); static void done_register(); - void register_tcl(); }; struct Frontend : Pass