summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-06-09 01:04:23 +0200
committerClifford Wolf <clifford@clifford.at>2013-06-09 01:04:23 +0200
commite52c9aff1bda85f87764cf16570c511b9e705b71 (patch)
treebd65907368a956173af7f7e7410b3226627476f7 /kernel
parentbf59a28f80fc321b139772804d52e441194040f7 (diff)
Improved readline tab completion
Diffstat (limited to 'kernel')
-rw-r--r--kernel/driver.cc98
-rw-r--r--kernel/register.h2
2 files changed, 75 insertions, 25 deletions
diff --git a/kernel/driver.cc b/kernel/driver.cc
index c24b293f..1136dc67 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -25,6 +25,8 @@
#include <libgen.h>
#include <dlfcn.h>
+#include <algorithm>
+
#include "kernel/rtlil.h"
#include "kernel/register.h"
#include "kernel/log.h"
@@ -143,10 +145,64 @@ static char *readline_cmd_generator(const char *text, int state)
return NULL;
}
+static char *readline_obj_generator(const char *text, int state)
+{
+ static std::vector<char*> obj_names;
+ static size_t idx;
+
+ if (!state)
+ {
+ idx = 0;
+ obj_names.clear();
+
+ RTLIL::Design *design = yosys_get_design();
+ int len = strlen(text);
+
+ if (design->selected_active_module.empty())
+ {
+ for (auto &it : design->modules)
+ if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str())));
+ }
+ else
+ if (design->modules.count(design->selected_active_module) > 0)
+ {
+ RTLIL::Module *module = design->modules.at(design->selected_active_module);
+
+ for (auto &it : module->wires)
+ if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str())));
+
+ for (auto &it : module->memories)
+ if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str())));
+
+ for (auto &it : module->cells)
+ if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str())));
+
+ for (auto &it : module->processes)
+ if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str())));
+ }
+
+ std::sort(obj_names.begin(), obj_names.end());
+ }
+
+ if (idx < obj_names.size())
+ return strdup(obj_names[idx++]);
+
+ idx = 0;
+ obj_names.clear();
+ return NULL;
+}
+
static char **readline_completion(const char *text, int start, int)
{
if (start == 0)
return rl_completion_matches(text, readline_cmd_generator);
+ if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6))
+ return rl_completion_matches(text, readline_obj_generator);
return NULL;
}
@@ -271,7 +327,6 @@ struct ScriptPass : public Pass {
#ifdef YOSYS_ENABLE_TCL
static Tcl_Interp *yosys_tcl_interp = NULL;
-static RTLIL::Design *yosys_tcl_design = NULL;
static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
{
@@ -296,11 +351,11 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
}
if (args.size() == 1) {
- Pass::call(yosys_tcl_design, args[0]);
+ Pass::call(yosys_get_design(), args[0]);
return TCL_OK;
}
- Pass::call(yosys_tcl_design, args);
+ Pass::call(yosys_get_design(), args);
return TCL_OK;
}
@@ -313,11 +368,6 @@ extern Tcl_Interp *yosys_get_tcl_interp()
return yosys_tcl_interp;
}
-extern RTLIL::Design *yosys_get_tcl_design()
-{
- return yosys_tcl_design;
-}
-
struct TclPass : public Pass {
TclPass() : Pass("tcl", "execute a TCL script file") { }
virtual void help() {
@@ -344,6 +394,13 @@ struct TclPass : public Pass {
} TclPass;
#endif
+static RTLIL::Design *yosys_design = NULL;
+
+extern RTLIL::Design *yosys_get_design()
+{
+ return yosys_design;
+}
+
std::string rewrite_yosys_exe(std::string exe)
{
char buffer[1024];
@@ -506,22 +563,18 @@ int main(int argc, char **argv)
Pass::init_register();
- RTLIL::Design *design = new RTLIL::Design;
- design->selection_stack.push_back(RTLIL::Selection());
+ yosys_design = new RTLIL::Design;
+ yosys_design->selection_stack.push_back(RTLIL::Selection());
log_push();
-#ifdef YOSYS_ENABLE_TCL
- yosys_tcl_design = design;
-#endif
-
if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) {
if (!got_output_filename)
backend_command = "";
- shell(design);
+ shell(yosys_design);
}
while (optind < argc)
- run_frontend(argv[optind++], frontend_command, design, output_filename == "-" ? &backend_command : NULL);
+ run_frontend(argv[optind++], frontend_command, yosys_design, output_filename == "-" ? &backend_command : NULL);
if (!scriptfile.empty()) {
if (scriptfile_tcl) {
@@ -532,20 +585,17 @@ int main(int argc, char **argv)
log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n");
#endif
} else
- run_frontend(scriptfile, "script", design, output_filename == "-" ? &backend_command : NULL);
+ run_frontend(scriptfile, "script", yosys_design, output_filename == "-" ? &backend_command : NULL);
}
for (auto it = passes_commands.begin(); it != passes_commands.end(); it++)
- run_pass(*it, design);
+ run_pass(*it, yosys_design);
if (!backend_command.empty())
- run_backend(output_filename, backend_command, design);
-
- delete design;
+ run_backend(output_filename, backend_command, yosys_design);
-#ifdef YOSYS_ENABLE_TCL
- yosys_tcl_design = NULL;
-#endif
+ delete yosys_design;
+ yosys_design = NULL;
log("\nREADY.\n");
log_pop();
diff --git a/kernel/register.h b/kernel/register.h
index 849549ac..5983211d 100644
--- a/kernel/register.h
+++ b/kernel/register.h
@@ -29,10 +29,10 @@
#ifdef YOSYS_ENABLE_TCL
#include <tcl.h>
extern Tcl_Interp *yosys_get_tcl_interp();
-extern RTLIL::Design *yosys_get_tcl_design();
#endif
// implemented in driver.cc
+extern RTLIL::Design *yosys_get_design();
std::string rewrite_yosys_exe(std::string exe);
struct Pass