[lib] now openfpga shell supports a new type of executive functions

This commit is contained in:
tangxifan 2023-01-07 11:17:02 -08:00
parent 9b5b1b0da7
commit 7028c1ec72
2 changed files with 48 additions and 21 deletions

View File

@ -65,13 +65,14 @@ class Shell {
* Built-in commands have their own execute functions inside the shell
*/
enum e_exec_func_type {
CONST_STANDARD,
STANDARD,
CONST_SHORT,
SHORT,
BUILTIN,
MACRO,
WRAPPER,
CONST_STANDARD, /* A standard function requires to read data from the command context, need the shell to provide command parsing */
STANDARD, /* A standard function requires to write data to the command context, need the shell to provide command parsing */
CONST_SHORT, /* A short function requries to read data from the common context without any command-line options */
SHORT, /* A short function requries to write data to the common context without any command-line options */
BUILTIN, /* A built-in function which requires no input arguments at all */
FLOATING, /* A floating function which does not need to write/read any data from the common context. Need shell to provide command parsing */
MACRO, /* A black-box function which has its own command-line parser/interface. No need for shell to provide command parsing */
PLUGIN, /* A plug-in function which is based on other commands, require shell methods */
NUM_EXEC_FUNC_TYPES
};
@ -99,7 +100,7 @@ class Shell {
public: /* Public mutators */
void set_name(const char* name);
void add_title(const char* title);
ShellCommandId add_command(const Command& cmd, const char* descr);
ShellCommandId add_command(const Command& cmd, const char* descr, const bool& hidden = false);
void set_command_class(const ShellCommandId& cmd_id,
const ShellCommandClassId& cmd_class_id);
/* Link the execute function to a command
@ -150,12 +151,19 @@ class Shell {
void set_command_execute_function(const ShellCommandId& cmd_id,
std::function<void()> exec_func);
/* Floating function, including the only commands
* This is designed for implementing functions which is totally independent from <T>
*/
void set_command_execute_function(
const ShellCommandId& cmd_id,
std::function<int(const Command&, const CommandContext&)> exec_func);
/* Marco function, which directly call a macro function without command
* parsing */
void set_command_execute_function(const ShellCommandId& cmd_id,
std::function<int(int, char**)> exec_func);
/* Wrapper function, which calls other command thru shell's APIs */
/* Plug-in function, which calls other command thru shell's APIs */
void set_command_execute_function(
const ShellCommandId& cmd_id,
std::function<int(Shell<T>*, T&, const Command&, const CommandContext&)>
@ -178,7 +186,7 @@ class Shell {
void run_script_mode(const char* script_file_name, T& context,
const bool& batch_mode = false);
/* Print all the commands by their classes. This is actually the help desk */
void print_commands() const;
void print_commands(const bool& show_hidden = false) const;
/* Find the exit code (assume quit shell now) */
int exit_code() const;
/* Show statistics of errors during command execution */
@ -207,6 +215,9 @@ class Shell {
/* Unique ids for each command */
vtr::vector<ShellCommandId, ShellCommandId> command_ids_;
/* If this is a hidden command which will not appear in help desk */
vtr::vector<ShellCommandId, bool> command_hidden_;
/* Objects for each command */
vtr::vector<ShellCommandId, Command> commands_;
@ -238,13 +249,16 @@ class Shell {
command_short_const_execute_functions_;
vtr::vector<ShellCommandId, std::function<int(T&)>>
command_short_execute_functions_;
vtr::vector<ShellCommandId,
std::function<int(const Command&, const CommandContext&)>>
command_floating_execute_functions_;
vtr::vector<ShellCommandId, std::function<void()>>
command_builtin_execute_functions_;
vtr::vector<ShellCommandId, std::function<int(int, char**)>>
command_macro_execute_functions_;
vtr::vector<ShellCommandId, std::function<int(Shell<T>*, T&, const Command&,
const CommandContext&)>>
command_wrapper_execute_functions_;
command_plugin_execute_functions_;
/* Type of execute functions for each command.
* This is supposed to be an internal data ONLY

View File

@ -116,7 +116,7 @@ void Shell<T>::add_title(const char* title) {
/* Add a command with it description */
template<class T>
ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr) {
ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr, const bool& hidden) {
/* Ensure that the name is unique in the command list */
std::map<std::string, ShellCommandId>::const_iterator name_it = command_name2ids_.find(std::string(cmd.name()));
if (name_it != command_name2ids_.end()) {
@ -126,6 +126,7 @@ ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr) {
/* This is a legal name. we can create a new id */
ShellCommandId shell_cmd = ShellCommandId(command_ids_.size());
command_ids_.push_back(shell_cmd);
command_hidden_.push_back(hidden);
commands_.emplace_back(cmd);
command_contexts_.push_back(CommandContext(cmd));
command_description_.push_back(descr);
@ -136,7 +137,8 @@ ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr) {
command_short_const_execute_functions_.emplace_back();
command_short_execute_functions_.emplace_back();
command_builtin_execute_functions_.emplace_back();
command_wrapper_execute_functions_.emplace_back();
command_plugin_execute_functions_.emplace_back();
command_floating_execute_functions_.emplace_back();
command_macro_execute_functions_.emplace_back();
command_status_.push_back(CMD_EXEC_NONE); /* By default, the command should be marked as fatal error as it has been never executed */
command_dependencies_.emplace_back();
@ -212,8 +214,16 @@ template<class T>
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
std::function<int(Shell<T>*, T&, const Command&, const CommandContext&)> exec_func) {
VTR_ASSERT(true == valid_command_id(cmd_id));
command_execute_function_types_[cmd_id] = WRAPPER;
command_wrapper_execute_functions_[cmd_id] = exec_func;
command_execute_function_types_[cmd_id] = PLUGIN;
command_plugin_execute_functions_[cmd_id] = exec_func;
}
template<class T>
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
std::function<int(const Command&, const CommandContext&)> exec_func) {
VTR_ASSERT(true == valid_command_id(cmd_id));
command_execute_function_types_[cmd_id] = FLOATING;
command_floating_execute_functions_[cmd_id] = exec_func;
}
template<class T>
@ -397,16 +407,16 @@ void Shell<T>::run_script_mode(const char* script_file_name,
}
template <class T>
void Shell<T>::print_commands() const {
void Shell<T>::print_commands(const bool& show_hidden) const {
/* Print the commands by their classes */
for (const ShellCommandClassId& cmd_class : command_class_ids_) {
/* Print the class name */
VTR_LOG("%s:\n", command_class_names_[cmd_class].c_str());
for (const ShellCommandId& cmd : commands_by_classes_[cmd_class]) {
/* Print the command names in this class
* but limited4 command per line for a clean layout
*/
if (!show_hidden && command_hidden_[cmd]) {
continue;
}
VTR_LOG("\t%s\n", commands_[cmd].name().c_str());
}
@ -568,8 +578,8 @@ int Shell<T>::execute_command(const char* cmd_line,
/* Execute the command depending on the type of function ! */
switch (command_execute_function_types_[cmd_id]) {
case WRAPPER:
command_status_[cmd_id] = command_wrapper_execute_functions_[cmd_id](this, common_context, commands_[cmd_id], command_contexts_[cmd_id]);
case PLUGIN:
command_status_[cmd_id] = command_plugin_execute_functions_[cmd_id](this, common_context, commands_[cmd_id], command_contexts_[cmd_id]);
break;
case CONST_STANDARD:
command_status_[cmd_id] = command_const_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]);
@ -577,6 +587,9 @@ int Shell<T>::execute_command(const char* cmd_line,
case STANDARD:
command_status_[cmd_id] = command_standard_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]);
break;
case FLOATING:
command_status_[cmd_id] = command_floating_execute_functions_[cmd_id](commands_[cmd_id], command_contexts_[cmd_id]);
break;
case CONST_SHORT:
command_status_[cmd_id] = command_short_const_execute_functions_[cmd_id](common_context);
break;