diff options
Diffstat (limited to 'gdb/guile')
-rw-r--r-- | gdb/guile/guile-internal.h | 9 | ||||
-rw-r--r-- | gdb/guile/guile.c | 4 | ||||
-rw-r--r-- | gdb/guile/scm-cmd.c | 83 | ||||
-rw-r--r-- | gdb/guile/scm-color.c | 11 | ||||
-rw-r--r-- | gdb/guile/scm-param.c | 41 | ||||
-rw-r--r-- | gdb/guile/scm-ports.c | 10 |
6 files changed, 122 insertions, 36 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/guile.c b/gdb/guile/guile.c index 1803df0..66a74b3 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -827,9 +827,7 @@ message == an error message without a stack will be printed."), &set_guile_list, &show_guile_list); } -void _initialize_guile (); -void -_initialize_guile () +INIT_GDB_FILE (guile) { install_gdb_commands (); } diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c index 4757872..19fb742 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) ; @@ -490,9 +496,9 @@ gdbscm_parse_command_name (const char *name, /* Find first character of the final word. */ for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i) ; - gdb::unique_xmalloc_ptr<char> result ((char *) xmalloc (lastchar - i + 2)); - memcpy (result.get (), &name[i], lastchar - i + 1); - result.get ()[lastchar - i + 1] = '\0'; + + gdb::unique_xmalloc_ptr<char> result + = make_unique_xstrndup (&name[i], lastchar - i + 1); /* Skip whitespace again. */ for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i) @@ -503,18 +509,21 @@ gdbscm_parse_command_name (const char *name, return result.release (); } - gdb::unique_xmalloc_ptr<char> prefix_text ((char *) xmalloc (i + 2)); - memcpy (prefix_text.get (), name, i + 1); - prefix_text.get ()[i + 1] = '\0'; + gdb::unique_xmalloc_ptr<char> prefix_text + = make_unique_xstrndup (name, i + 1); const char *prefix_text2 = prefix_text.get (); elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1); - if (elt == NULL || elt == CMD_LIST_AMBIGUOUS) + if (elt == nullptr || elt == CMD_LIST_AMBIGUOUS || *prefix_text2 != '\0') { msg = xstrprintf (_("could not find command prefix '%s'"), prefix_text.get ()).release (); scm_dynwind_begin ((scm_t_dynwind_flags) 0); gdbscm_dynwind_xfree (msg); + /* Release memory now as the destructors will not be run when the + guile exception is thrown. */ + result = nullptr; + prefix_text = nullptr; gdbscm_out_of_range_error (func_name, arg_pos, gdbscm_scm_from_c_string (name), msg); } @@ -522,6 +531,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 (); } @@ -529,6 +540,10 @@ gdbscm_parse_command_name (const char *name, prefix_text.get ()).release (); scm_dynwind_begin ((scm_t_dynwind_flags) 0); gdbscm_dynwind_xfree (msg); + /* Release memory now as the destructors will not be run when the guile + exception is thrown. */ + result = nullptr; + prefix_text = nullptr; gdbscm_out_of_range_error (func_name, arg_pos, gdbscm_scm_from_c_string (name), msg); /* NOTREACHED */ @@ -743,8 +758,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); @@ -753,18 +769,50 @@ gdbscm_register_command_x (SCM self) { if (c_smob->is_prefix) { - /* If we have our own "invoke" method, then allow unknown - sub-commands. */ - int allow_unknown = gdbscm_is_true (c_smob->invoke); + bool has_invoke = gdbscm_is_true (c_smob->invoke) == 1; - cmd = add_prefix_cmd (c_smob->cmd_name, c_smob->cmd_class, - NULL, c_smob->doc, &c_smob->sub_list, - allow_unknown, cmd_list); + if (has_invoke) + { + cmd = add_prefix_cmd (c_smob->cmd_name, c_smob->cmd_class, + NULL, c_smob->doc, &c_smob->sub_list, + 1 /* allow_unknown */, cmd_list); + cmd->func = cmdscm_function; + } + else + { + /* If there is no 'invoke' method, then create the prefix + using the standard prefix callbacks. This means that for + '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. */ + 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, + c_smob->cmd_class, + c_smob->doc, + &c_smob->sub_list, + 0 /* allow_unknown */, cmd_list); + else + cmd = add_basic_prefix_cmd (c_smob->cmd_name, + c_smob->cmd_class, + c_smob->doc, + &c_smob->sub_list, + 0 /* allow_unknown */, cmd_list); + } } else { cmd = add_cmd (c_smob->cmd_name, c_smob->cmd_class, c_smob->doc, cmd_list); + cmd->func = cmdscm_function; } } catch (const gdb_exception &except) @@ -777,7 +825,6 @@ gdbscm_register_command_x (SCM self) So no more errors after this point. */ /* There appears to be no API to set this. */ - cmd->func = cmdscm_function; cmd->destroyer = cmdscm_destroyer; c_smob->command = cmd; diff --git a/gdb/guile/scm-color.c b/gdb/guile/scm-color.c index 4850575..cde22e5 100644 --- a/gdb/guile/scm-color.c +++ b/gdb/guile/scm-color.c @@ -24,6 +24,7 @@ #include "language.h" #include "arch-utils.h" #include "guile-internal.h" +#include "cli/cli-style.h" /* A GDB color. */ @@ -354,8 +355,14 @@ gdbscm_color_escape_sequence (SCM self, SCM is_fg_scm) const ui_file_style::color &color = coscm_get_color (self); SCM_ASSERT_TYPE (gdbscm_is_bool (is_fg_scm), is_fg_scm, SCM_ARG2, FUNC_NAME, _("boolean")); - bool is_fg = gdbscm_is_true (is_fg_scm); - std::string s = color.to_ansi (is_fg); + + std::string s; + if (term_cli_styling ()) + { + bool is_fg = gdbscm_is_true (is_fg_scm); + s = color.to_ansi (is_fg); + } + return gdbscm_scm_from_host_string (s.c_str (), s.size ()); } diff --git a/gdb/guile/scm-param.c b/gdb/guile/scm-param.c index 65226ec..5137847 100644 --- a/gdb/guile/scm-param.c +++ b/gdb/guile/scm-param.c @@ -308,13 +308,37 @@ pascm_is_valid (param_smob *p_smob) return p_smob->commands.set != nullptr; } -/* A helper function which return the default documentation string for - a parameter (which is to say that it's undocumented). */ + +/* The different types of documentation string. */ + +enum doc_string_type +{ + doc_string_set, + doc_string_show, + doc_string_description +}; + +/* A helper function which returns the default documentation string for + a parameter CMD_NAME. The DOC_TYPE indicates which type of + documentation string is needed. The returned string is dynamically + allocated. */ static char * -get_doc_string (void) +get_doc_string (doc_string_type doc_type, const char *cmd_name) { - return xstrdup (_("This command is not documented.")); + if (doc_type == doc_string_description) + return xstrdup (_("This command is not documented.")); + else + { + gdb_assert (cmd_name != nullptr); + + if (doc_type == doc_string_show) + return xstrprintf (_("Show the current value of '%s'."), + cmd_name).release (); + else + return xstrprintf (_("Set the current value of '%s'."), + cmd_name).release (); + } } /* Subroutine of pascm_set_func, pascm_show_func to simplify them. @@ -990,11 +1014,14 @@ gdbscm_make_parameter (SCM name_scm, SCM rest) &show_doc_arg_pos, &show_doc, &initial_value_arg_pos, &initial_value_scm); - /* If doc is NULL, leave it NULL. See add_setshow_cmd_full. */ + if (doc == nullptr) + doc = get_doc_string (doc_string_description, nullptr); + else if (*doc == '\0') + doc = nullptr; if (set_doc == NULL) - set_doc = get_doc_string (); + set_doc = get_doc_string (doc_string_set, name); if (show_doc == NULL) - show_doc = get_doc_string (); + show_doc = get_doc_string (doc_string_show, name); s = name; name = gdbscm_canonicalize_command_name (s, 0); diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c index ed43d64..f3e3ec8 100644 --- a/gdb/guile/scm-ports.c +++ b/gdb/guile/scm-ports.c @@ -336,9 +336,15 @@ ioscm_flush (SCM port) return; if (scm_is_eq (port, error_port_scm)) - gdb_flush (gdb_stderr); + { + if (gdb_stderr != nullptr) + gdb_flush (gdb_stderr); + } else - gdb_flush (gdb_stdout); + { + if (gdb_stdout != nullptr) + gdb_flush (gdb_stdout); + } } #else /* !USING_GUILE_BEFORE_2_2 */ |