aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Borneo <borneo.antonio@gmail.com>2021-05-27 15:25:43 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2021-06-04 17:41:09 +0100
commitfad1eaaa42ad5a52d1d9e38b1e94ab027fad5b24 (patch)
treece5fc1020f22bf2b0f6b2e63940d016b6f9a31ff
parent9e7b31479ba7100f41a5b88b32571cf765cdb3ee (diff)
downloadriscv-openocd-fad1eaaa42ad5a52d1d9e38b1e94ab027fad5b24.zip
riscv-openocd-fad1eaaa42ad5a52d1d9e38b1e94ab027fad5b24.tar.gz
riscv-openocd-fad1eaaa42ad5a52d1d9e38b1e94ab027fad5b24.tar.bz2
server/telnet: fix autocomplete for jimtcl commands
Current autocomplete filters-out some command reported by "info commands". One of the filter rule concerns the command's private data. Every command registered by OpenOCD has its 'struct command' as private data. By ignoring commands without private data, we loose several TCL commands registered by jimtcl, e.g. 'foreach', 'llength'. By assuming that every command with non-NULL private data has 'struct command' as private data, we risk at best to access inconsistent data, at worst to trigger a segmentation fault. Export the already available functions: - to check if a command has been registered by OpenOCD and - to get the private data. While there, rename jimcmd_is_ocd_command() as jimcmd_is_oocd_command(). Don't filter-out jimtcl commands with no private data. Check the private data only on OpenOCD commands. Change-Id: Ib5bf8d2bc5c12440c0cfae438f637c38724a79b7 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6282 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
-rw-r--r--src/helper/command.c8
-rw-r--r--src/helper/command.h11
-rw-r--r--src/server/telnet_server.c26
3 files changed, 26 insertions, 19 deletions
diff --git a/src/helper/command.c b/src/helper/command.c
index d4f6a0a..43c5a0f 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -62,12 +62,12 @@ static inline bool jimcmd_is_proc(Jim_Cmd *cmd)
return cmd->isproc;
}
-static inline bool jimcmd_is_ocd_command(Jim_Cmd *cmd)
+bool jimcmd_is_oocd_command(Jim_Cmd *cmd)
{
return !cmd->isproc && cmd->u.native.cmdProc == jim_command_dispatch;
}
-static inline void *jimcmd_privdata(Jim_Cmd *cmd)
+void *jimcmd_privdata(Jim_Cmd *cmd)
{
return cmd->isproc ? NULL : cmd->u.native.privData;
}
@@ -261,7 +261,7 @@ static struct command *command_find_from_name(Jim_Interp *interp, const char *na
Jim_IncrRefCount(jim_name);
Jim_Cmd *cmd = Jim_GetCommand(interp, jim_name, JIM_NONE);
Jim_DecrRefCount(interp, jim_name);
- if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_ocd_command(cmd))
+ if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_oocd_command(cmd))
return NULL;
return jimcmd_privdata(cmd);
@@ -1020,7 +1020,7 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE);
Jim_DecrRefCount(interp, s);
free(full_name);
- if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_ocd_command(cmd))) {
+ if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) {
Jim_SetResultString(interp, "unknown", -1);
return JIM_OK;
}
diff --git a/src/helper/command.h b/src/helper/command.h
index 068df9d..719c94b 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -85,6 +85,17 @@ struct command_invocation {
};
/**
+ * Return true if the command @c cmd is registered by OpenOCD.
+ */
+bool jimcmd_is_oocd_command(Jim_Cmd *cmd);
+
+/**
+ * Return the pointer to the command's private data specified during the
+ * registration of command @a cmd .
+ */
+void *jimcmd_privdata(Jim_Cmd *cmd);
+
+/**
* Command handlers may be defined with more parameters than the base
* set provided by command.c. This macro uses C99 magic to allow
* defining all such derivative types using this macro.
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index acb57ef..2ad3791 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -500,22 +500,18 @@ static void telnet_auto_complete(struct connection *connection)
bool ignore_cmd = false;
Jim_Cmd *jim_cmd = Jim_GetCommand(command_context->interp, elem, JIM_NONE);
- if (!jim_cmd)
+ if (!jim_cmd) {
+ /* Why we are here? Let's ignore it! */
ignore_cmd = true;
- else {
- if (!jim_cmd->isproc) {
- /* ignore commands without handler
- * and those with COMMAND_CONFIG mode */
- /* FIXME it's better to use jimcmd_is_ocd_command(jim_cmd)
- * or command_find_from_name(command_context->interp, name) */
- struct command *cmd = jim_cmd->u.native.privData;
- if (!cmd)
- ignore_cmd = true;
- /* make Valgrind happy by checking that cmd is not NULL */
- else if (cmd != NULL && !cmd->handler && !cmd->jim_handler)
- ignore_cmd = true;
- else if (cmd != NULL && cmd->mode == COMMAND_CONFIG)
- ignore_cmd = true;
+ } else if (jimcmd_is_oocd_command(jim_cmd)) {
+ struct command *cmd = jimcmd_privdata(jim_cmd);
+
+ if (cmd && !cmd->handler && !cmd->jim_handler) {
+ /* Initial part of a multi-word command. Ignore it! */
+ ignore_cmd = true;
+ } else if (cmd && cmd->mode == COMMAND_CONFIG) {
+ /* Not executable after config phase. Ignore it! */
+ ignore_cmd = true;
}
}