From 2ca237e08665e4307da5bf40b7f3e17ca3e640db Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 20 Dec 2018 07:29:46 +0000 Subject: [PATCH] tcl: add support for passing arguments to scripts. --- kernel/yosys.cc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index f002955ad..6884305d9 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -166,7 +166,7 @@ std::string vstringf(const char *fmt, va_list ap) std::string string; char *str = NULL; -#if defined(_WIN32 )|| defined(__CYGWIN__) +#if defined(_WIN32 )|| defined(__CYGWIN__) int sz = 64, rc; while (1) { va_list apc; @@ -637,8 +637,9 @@ extern Tcl_Interp *yosys_get_tcl_interp() struct TclPass : public Pass { TclPass() : Pass("tcl", "execute a TCL script file") { } void help() YS_OVERRIDE { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" tcl \n"); + log(" tcl [args]\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"); @@ -648,14 +649,24 @@ struct TclPass : public Pass { log("'proc' and 'rename' are wrapped to tcl commands 'procs' and 'renames'\n"); log("in order to avoid a name collision with the built in commands.\n"); log("\n"); + log("If any arguments are specified, these arguments are provided to the script via\n"); + log("the standard $argc and $argv variables.\n"); + log("\n"); } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector args, RTLIL::Design *) YS_OVERRIDE { 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_get_tcl_interp(), args[1].c_str()) != TCL_OK) - log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); + + std::vector script_args; + for (auto it = args.begin() + 2; it != args.end(); ++it) + script_args.push_back(Tcl_NewStringObj((*it).c_str(), (*it).size())); + + Tcl_Interp *interp = yosys_get_tcl_interp(); + Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argc", 4), NULL, Tcl_NewIntObj(script_args.size()), 0); + Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv", 4), NULL, Tcl_NewListObj(script_args.size(), script_args.data()), 0); + Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv0", 5), NULL, Tcl_NewStringObj(args[1].c_str(), args[1].size()), 0); + if (Tcl_EvalFile(interp, args[1].c_str()) != TCL_OK) + log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp)); } } TclPass; #endif -- 2.30.2