add macro function support to openfpga shell and update unit test
This commit is contained in:
parent
558f0bb1bd
commit
e983966a08
|
@ -61,6 +61,7 @@ class Shell {
|
|||
STANDARD,
|
||||
SHORT,
|
||||
BUILTIN,
|
||||
MACRO,
|
||||
NUM_EXEC_FUNC_TYPES
|
||||
};
|
||||
public: /* Constructor */
|
||||
|
@ -89,6 +90,7 @@ class Shell {
|
|||
* 1. Standard function, including the data exchange <T> and commands
|
||||
* 2. Short function, including only the data exchange <T>
|
||||
* 3. Built-in function, including only the shell envoriment variables
|
||||
* 4. Marco function, which directly call a macro function without command parsing
|
||||
* Users just need to specify the function object and its type will be automatically inferred
|
||||
*/
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
|
@ -97,6 +99,8 @@ class Shell {
|
|||
std::function<void(T&)> exec_func);
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void()> exec_func);
|
||||
void set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(int, char**)> exec_func);
|
||||
void set_command_dependency(const ShellCommandId& cmd_id,
|
||||
const std::vector<ShellCommandId> cmd_dependency);
|
||||
ShellCommandClassId add_command_class(const char* name);
|
||||
|
@ -150,10 +154,12 @@ class Shell {
|
|||
* 1. Standard function, including the data exchange <T> and commands
|
||||
* 2. Short function, including only the data exchange <T>
|
||||
* 3. Built-in function, including only the shell envoriment variables
|
||||
* 4. Marco function, which directly call a macro function without command parsing
|
||||
*/
|
||||
vtr::vector<ShellCommandId, std::function<void(T&, const Command&, const CommandContext&)>> command_standard_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void(T&)>> command_short_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void()>> command_builtin_execute_functions_;
|
||||
vtr::vector<ShellCommandId, std::function<void(int, char**)>> command_macro_execute_functions_;
|
||||
|
||||
/* Type of execute functions for each command.
|
||||
* This is supposed to be an internal data ONLY
|
||||
|
|
|
@ -128,6 +128,7 @@ ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr) {
|
|||
command_standard_execute_functions_.emplace_back();
|
||||
command_short_execute_functions_.emplace_back();
|
||||
command_builtin_execute_functions_.emplace_back();
|
||||
command_macro_execute_functions_.emplace_back();
|
||||
command_dependencies_.emplace_back();
|
||||
|
||||
/* Register the name in the name2id map */
|
||||
|
@ -173,6 +174,14 @@ void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
|
|||
command_builtin_execute_functions_[cmd_id] = exec_func;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
|
||||
std::function<void(int, char**)> exec_func) {
|
||||
VTR_ASSERT(true == valid_command_id(cmd_id));
|
||||
command_execute_function_types_[cmd_id] = MACRO;
|
||||
command_macro_execute_functions_[cmd_id] = exec_func;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Shell<T>::set_command_dependency(const ShellCommandId& cmd_id,
|
||||
const std::vector<ShellCommandId> dependent_cmds) {
|
||||
|
@ -337,7 +346,28 @@ void Shell<T>::execute_command(const char* cmd_line,
|
|||
|
||||
/* TODO: Check the dependency graph to see if all the prequistics have been met */
|
||||
|
||||
/* Find the command! Parse the options */
|
||||
/* Find the command! Parse the options
|
||||
* Note:
|
||||
* Macro command will not be parsed! It will be directly executed
|
||||
*/
|
||||
if (MACRO == command_execute_function_types_[cmd_id]) {
|
||||
/* Convert the tokens from string to char */
|
||||
char** argv = (char**)malloc(tokens.size() * sizeof(char*));
|
||||
for (size_t itok = 0; itok < tokens.size(); ++itok) {
|
||||
argv[itok] = (char*)malloc((tokens[itok].length() + 1) * sizeof(char));
|
||||
strcpy(argv[itok], tokens[itok].c_str());
|
||||
}
|
||||
/* Execute the marco function */
|
||||
command_macro_execute_functions_[cmd_id](tokens.size(), argv);
|
||||
/* Free the argv */
|
||||
for (size_t itok = 0; itok < tokens.size(); ++itok) {
|
||||
free(argv[itok]);
|
||||
}
|
||||
free(argv);
|
||||
/* Finish for macro command, return */
|
||||
return;
|
||||
}
|
||||
|
||||
if (false == parse_command(tokens, commands_[cmd_id], command_contexts_[cmd_id])) {
|
||||
/* Echo the command */
|
||||
print_command_options(commands_[cmd_id]);
|
||||
|
@ -358,6 +388,7 @@ void Shell<T>::execute_command(const char* cmd_line,
|
|||
case BUILTIN:
|
||||
command_builtin_execute_functions_[cmd_id]();
|
||||
break;
|
||||
/* MACRO should be executed eariler in this function. It should not appear here */
|
||||
default:
|
||||
/* This is not allowed! Error out */
|
||||
VTR_LOG("Invalid type of execute function for command '%s'!\n",
|
||||
|
|
|
@ -27,6 +27,15 @@ void shell_execute_print(ShellContext& context) {
|
|||
VTR_LOG("a=%d\n", context.a);
|
||||
}
|
||||
|
||||
static
|
||||
void shell_execute_print_macro(int argc, char** argv) {
|
||||
VTR_LOG("Number of arguments: %d\n", argc);
|
||||
VTR_LOG("Detailed arguments:\n");
|
||||
for (int iarg = 0; iarg < argc; ++iarg) {
|
||||
VTR_LOG("\t[%d]: %s\n", iarg, argv[iarg]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
/* Create the command to launch shell in different modes */
|
||||
Command start_cmd("test_shell");
|
||||
|
@ -97,6 +106,15 @@ int main(int argc, char** argv) {
|
|||
shell.set_command_class(shell_cmd_print_id, arith_cmd_class);
|
||||
shell.set_command_execute_function(shell_cmd_print_id, shell_execute_print);
|
||||
|
||||
/* Create a macro command of 'print_macro'
|
||||
* This function will print the value of an internal variable of ShellContext
|
||||
*/
|
||||
Command shell_cmd_print_macro("print_macro");
|
||||
ShellCommandId shell_cmd_print_macro_id = shell.add_command(shell_cmd_print_macro, "A macro function to print arguments");
|
||||
shell.set_command_class(shell_cmd_print_macro_id, arith_cmd_class);
|
||||
shell.set_command_execute_function(shell_cmd_print_macro_id, shell_execute_print_macro);
|
||||
|
||||
|
||||
/* Add a new class of commands */
|
||||
ShellCommandClassId basic_cmd_class = shell.add_command_class("Basic");
|
||||
|
||||
|
|
|
@ -6,4 +6,7 @@ set --value 5
|
|||
|
||||
print # Print out the value
|
||||
|
||||
# Test macro arguments
|
||||
print_macro arch blif
|
||||
|
||||
exit # Finish
|
||||
|
|
Loading…
Reference in New Issue