diff options
-rw-r--r-- | gdb/guile/guile-internal.h | 9 | ||||
-rw-r--r-- | gdb/guile/scm-cmd.c | 30 | ||||
-rw-r--r-- | gdb/python/py-cmd.c | 30 | ||||
-rw-r--r-- | gdb/python/python-internal.h | 3 | ||||
-rw-r--r-- | gdb/testsuite/gdb.guile/scm-parameter.exp | 10 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-parameter-prefix.exp | 46 |
6 files changed, 105 insertions, 23 deletions
diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h index 3101882..60a8bf3 100644 --- a/gdb/guile/guile-internal.h +++ b/gdb/guile/guile-internal.h @@ -449,10 +449,11 @@ extern const struct block *bkscm_scm_to_block /* scm-cmd.c */ -extern char *gdbscm_parse_command_name (const char *name, - const char *func_name, int arg_pos, - struct cmd_list_element ***base_list, - struct cmd_list_element **start_list); +extern char *gdbscm_parse_command_name + (const char *name, const char *func_name, int arg_pos, + struct cmd_list_element ***base_list, + struct cmd_list_element **start_list, + struct cmd_list_element **prefix_cmd = nullptr); extern int gdbscm_valid_command_class_p (int command_class); diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c index 565d588..74646f3 100644 --- a/gdb/guile/scm-cmd.c +++ b/gdb/guile/scm-cmd.c @@ -457,11 +457,13 @@ cmdscm_completer (struct cmd_list_element *command, name of the new command. All earlier words must be existing prefix commands. - *BASE_LIST is set to the final prefix command's list of - *sub-commands. + *BASE_LIST is set to the final prefix command's list of sub-commands. START_LIST is the list in which the search starts. + When PREFIX_CMD is not NULL then *PREFIX_CMD is set to the prefix + command itself, or NULL, if there is no prefix command. + This function returns the xmalloc()d name of the new command. On error a Scheme exception is thrown. */ @@ -469,13 +471,17 @@ char * gdbscm_parse_command_name (const char *name, const char *func_name, int arg_pos, struct cmd_list_element ***base_list, - struct cmd_list_element **start_list) + struct cmd_list_element **start_list, + struct cmd_list_element **prefix_cmd) { struct cmd_list_element *elt; int len = strlen (name); int i, lastchar; char *msg; + if (prefix_cmd != nullptr) + *prefix_cmd = nullptr; + /* Skip trailing whitespace. */ for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i) ; @@ -522,6 +528,8 @@ gdbscm_parse_command_name (const char *name, if (elt->is_prefix ()) { *base_list = elt->subcommands; + if (prefix_cmd != nullptr) + *prefix_cmd = elt; return result.release (); } @@ -743,8 +751,9 @@ gdbscm_register_command_x (SCM self) if (cmdscm_is_valid (c_smob)) scm_misc_error (FUNC_NAME, _("command is already registered"), SCM_EOL); + struct cmd_list_element *prefix_cmd = nullptr; cmd_name = gdbscm_parse_command_name (c_smob->name, FUNC_NAME, SCM_ARG1, - &cmd_list, &cmdlist); + &cmd_list, &cmdlist, &prefix_cmd); c_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name); xfree (cmd_name); @@ -769,11 +778,14 @@ gdbscm_register_command_x (SCM self) 'set prefix' the user will get the help text listing all of the sub-commands, and for 'show prefix', the user will see all of the sub-command values. */ - cmd_list_element *first = *cmd_list; - while (first->prefix != nullptr) - first = first->prefix; - - bool is_show = first->subcommands == &showlist; + if (prefix_cmd != nullptr) + { + while (prefix_cmd->prefix != nullptr) + prefix_cmd = prefix_cmd->prefix; + } + + bool is_show = (prefix_cmd != nullptr + && prefix_cmd->subcommands == &showlist); if (is_show) cmd = add_show_prefix_cmd (c_smob->cmd_name, diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 5b4f813..e8c2904 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -334,24 +334,30 @@ cmdpy_completer (struct cmd_list_element *command, name of the new command. All earlier words must be existing prefix commands. - *BASE_LIST is set to the final prefix command's list of - *sub-commands. + *BASE_LIST is set to the final prefix command's list of sub-commands. START_LIST is the list in which the search starts. + When PREFIX_CMD is not NULL then *PREFIX_CMD is set to the prefix + command itself, or NULL, if there is no prefix command. + This function returns the name of the new command. On error sets the Python error and returns NULL. */ gdb::unique_xmalloc_ptr<char> gdbpy_parse_command_name (const char *name, struct cmd_list_element ***base_list, - struct cmd_list_element **start_list) + struct cmd_list_element **start_list, + struct cmd_list_element **prefix_cmd) { struct cmd_list_element *elt; int len = strlen (name); int i, lastchar; const char *prefix_text2; + if (prefix_cmd != nullptr) + *prefix_cmd = nullptr; + /* Skip trailing whitespace. */ for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i) ; @@ -393,6 +399,8 @@ gdbpy_parse_command_name (const char *name, if (elt->is_prefix ()) { *base_list = elt->subcommands; + if (prefix_cmd != nullptr) + *prefix_cmd = elt; return result; } @@ -467,8 +475,9 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw) return -1; } + cmd_list_element *prefix_cmd = nullptr; gdb::unique_xmalloc_ptr<char> cmd_name - = gdbpy_parse_command_name (name, &cmd_list, &cmdlist); + = gdbpy_parse_command_name (name, &cmd_list, &cmdlist, &prefix_cmd); if (cmd_name == nullptr) return -1; @@ -525,11 +534,14 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw) 'set prefix' the user will get the help text listing all of the sub-commands, and for 'show prefix', the user will see all of the sub-command values. */ - cmd_list_element *first = *cmd_list; - while (first->prefix != nullptr) - first = first->prefix; - - bool is_show = first->subcommands == &showlist; + if (prefix_cmd != nullptr) + { + while (prefix_cmd->prefix != nullptr) + prefix_cmd = prefix_cmd->prefix; + } + + bool is_show = (prefix_cmd != nullptr + && prefix_cmd->subcommands == &showlist); if (is_show) cmd = add_show_prefix_cmd (cmd_name.get (), diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index bdccb26..7f4237e 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -510,7 +510,8 @@ PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args); PyObject *gdbpy_parameter_value (const setting &var); gdb::unique_xmalloc_ptr<char> gdbpy_parse_command_name (const char *name, struct cmd_list_element ***base_list, - struct cmd_list_element **start_list); + struct cmd_list_element **start_list, + struct cmd_list_element **prefix_cmd = nullptr); PyObject *gdbpy_register_tui_window (PyObject *self, PyObject *args, PyObject *kw); diff --git a/gdb/testsuite/gdb.guile/scm-parameter.exp b/gdb/testsuite/gdb.guile/scm-parameter.exp index bf0d7df..e35428a 100644 --- a/gdb/testsuite/gdb.guile/scm-parameter.exp +++ b/gdb/testsuite/gdb.guile/scm-parameter.exp @@ -428,6 +428,16 @@ gdb_test_multiline "create set/show foo1 prefix commands" \ " #:prefix? #t))" "" \ "end" +gdb_test_multiline "create set/show foo1 baz1 prefix commands" \ + "guile" "" \ + "(register-command! (make-command \"set foo1 baz1\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "(register-command! (make-command \"show foo1 baz1\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "end" + gdb_test_multiline "create 'foo bar' parameter" \ "guile" "" \ "(register-parameter! (make-parameter \"foo bar\"" "" \ diff --git a/gdb/testsuite/gdb.python/py-parameter-prefix.exp b/gdb/testsuite/gdb.python/py-parameter-prefix.exp index 69cbb90..eb09fe7 100644 --- a/gdb/testsuite/gdb.python/py-parameter-prefix.exp +++ b/gdb/testsuite/gdb.python/py-parameter-prefix.exp @@ -330,7 +330,53 @@ proc_with_prefix test_dont_repeat {} { "repeat show prefix-12 xxx yyy" } +# Create a parameter prefixm, and immediately add another prefix under +# the first. The important thing here is that the second prefix is +# created into an otherwise empty prefix as this triggered a bug at +# one point. +proc_with_prefix test_nested {} { + gdb_test_multiline "Create nested parameter prefixes" \ + "python" "" \ + "gdb.ParameterPrefix('prefix-13', gdb.COMMAND_NONE)" "" \ + "gdb.ParameterPrefix('prefix-13 prefix-14', gdb.COMMAND_NONE)" "" \ + "gdb.Parameter('prefix-13 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-13 param-2', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-13 prefix-14 param-3', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-13 prefix-14 param-4', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "end" "" + + gdb_test "show prefix-13 prefix-14" \ + [multi_line \ + "^prefix-13 prefix-14 param-3: The current value of 'prefix-13 prefix-14 param-3' is \"off\"\\." \ + "prefix-13 prefix-14 param-4: The current value of 'prefix-13 prefix-14 param-4' is \"off\"\\."] + + gdb_test "show prefix-13" \ + [multi_line \ + "^prefix-13 param-1: The current value of 'prefix-13 param-1' is \"off\"\\." \ + "prefix-13 param-2: The current value of 'prefix-13 param-2' is \"off\"\\." \ + "prefix-13 prefix-14 param-3: The current value of 'prefix-13 prefix-14 param-3' is \"off\"\\." \ + "prefix-13 prefix-14 param-4: The current value of 'prefix-13 prefix-14 param-4' is \"off\"\\."] + + gdb_test "set prefix-13 prefix-14" \ + [multi_line \ + "" \ + "set prefix-13 prefix-14 param-3 -- Set the current value of 'prefix-13 prefix-14 param-3'\\." \ + "set prefix-13 prefix-14 param-4 -- Set the current value of 'prefix-13 prefix-14 param-4'\\." \ + "" \ + ".*"] + + gdb_test "set prefix-13" \ + [multi_line \ + "" \ + "set prefix-13 param-1 -- Set the current value of 'prefix-13 param-1'\\." \ + "set prefix-13 param-2 -- Set the current value of 'prefix-13 param-2'\\." \ + "set prefix-13 prefix-14 -- This command is not documented\\." \ + "" \ + ".*"] +} + test_basic_usage test_simple_sub_class test_prefix_with_invoke test_dont_repeat +test_nested |