aboutsummaryrefslogtreecommitdiff
path: root/gdb/cli/cli-cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/cli/cli-cmds.c')
-rw-r--r--gdb/cli/cli-cmds.c134
1 files changed, 128 insertions, 6 deletions
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 5124ab3..d1ecd62 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -211,6 +211,116 @@ show_command (const char *arg, int from_tty)
cmd_show_list (showlist, from_tty, "");
}
+/* See cli/cli-cmds.h. */
+
+void
+with_command_1 (const char *set_cmd_prefix,
+ cmd_list_element *setlist, const char *args, int from_tty)
+{
+ const char *delim = strstr (args, "--");
+ const char *nested_cmd = nullptr;
+
+ if (delim == args)
+ error (_("Missing setting before '--' delimiter"));
+
+ if (delim == nullptr || *skip_spaces (&delim[2]) == '\0')
+ nested_cmd = repeat_previous ();
+
+ cmd_list_element *set_cmd = lookup_cmd (&args, setlist, set_cmd_prefix,
+ /*allow_unknown=*/ 0,
+ /*ignore_help_classes=*/ 1);
+ gdb_assert (set_cmd != nullptr);
+
+ if (set_cmd->var == nullptr)
+ error (_("Cannot use this setting with the \"with\" command"));
+
+ std::string temp_value
+ = (delim == nullptr ? args : std::string (args, delim - args));
+
+ if (nested_cmd == nullptr)
+ nested_cmd = skip_spaces (delim + 2);
+
+ std::string org_value = get_setshow_command_value_string (set_cmd);
+
+ /* Tweak the setting to the new temporary value. */
+ do_set_command (temp_value.c_str (), from_tty, set_cmd);
+
+ try
+ {
+ scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
+
+ /* Execute the nested command. */
+ execute_command (nested_cmd, from_tty);
+ }
+ catch (const gdb_exception &ex)
+ {
+ /* Restore the setting and rethrow. If restoring the setting
+ throws, swallow the new exception and warn. There's nothing
+ else we can reasonably do. */
+ try
+ {
+ do_set_command (org_value.c_str (), from_tty, set_cmd);
+ }
+ catch (const gdb_exception &ex2)
+ {
+ warning (_("Couldn't restore setting: %s"), ex2.what ());
+ }
+
+ throw;
+ }
+
+ /* Restore the setting. */
+ do_set_command (org_value.c_str (), from_tty, set_cmd);
+}
+
+/* See cli/cli-cmds.h. */
+
+void
+with_command_completer_1 (const char *set_cmd_prefix,
+ completion_tracker &tracker,
+ const char *text)
+{
+ tracker.set_use_custom_word_point (true);
+
+ const char *delim = strstr (text, "--");
+
+ /* If we're still not past the "--" delimiter, complete the "with"
+ command as if it was a "set" command. */
+ if (delim == text
+ || delim == nullptr
+ || !isspace (delim[-1])
+ || !(isspace (delim[2]) || delim[2] == '\0'))
+ {
+ std::string new_text = std::string (set_cmd_prefix) + text;
+ tracker.advance_custom_word_point_by (-(int) strlen (set_cmd_prefix));
+ complete_nested_command_line (tracker, new_text.c_str ());
+ return;
+ }
+
+ /* We're past the "--" delimiter. Complete on the sub command. */
+ const char *nested_cmd = skip_spaces (delim + 2);
+ tracker.advance_custom_word_point_by (nested_cmd - text);
+ complete_nested_command_line (tracker, nested_cmd);
+}
+
+/* The "with" command. */
+
+static void
+with_command (const char *args, int from_tty)
+{
+ with_command_1 ("set ", setlist, args, from_tty);
+}
+
+/* "with" command completer. */
+
+static void
+with_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /*word*/)
+{
+ with_command_completer_1 ("set ", tracker, text);
+}
+
/* Provide documentation on command or list given by COMMAND. FROM_TTY
is ignored. */
@@ -878,12 +988,7 @@ pipe_command (const char *arg, int from_tty)
arg += delim.length (); /* Skip the delimiter. */
if (gdb_cmd.empty ())
- {
- repeat_previous ();
- gdb_cmd = skip_spaces (get_saved_command_line ());
- if (gdb_cmd.empty ())
- error (_("No previous command to relaunch"));
- }
+ gdb_cmd = repeat_previous ();
const char *shell_command = skip_spaces (arg);
if (*shell_command == '\0')
@@ -1850,6 +1955,23 @@ Generic command for showing things about the debugger."),
/* Another way to get at the same thing. */
add_info ("set", show_command, _("Show all GDB settings."));
+ c = add_com ("with", class_vars, with_command, _("\
+Temporarily set SETTING to VALUE, run COMMAND, and restore SETTING.\n\
+Usage: with SETTING [VALUE] [-- COMMAND]\n\
+Usage: w SETTING [VALUE] [-- COMMAND]\n\
+With no COMMAND, repeats the last executed command.\n\
+\n\
+SETTING is any setting you can change with the \"set\" subcommands.\n\
+E.g.:\n\
+ with language pascal -- print obj\n\
+ with print elements unlimited -- print obj\n\
+\n\
+You can change multiple settings using nested with, and use\n\
+abbreviations for commands and/or values. E.g.:\n\
+ w la p -- w p el u -- p obj"));
+ set_cmd_completer_handle_brkchars (c, with_command_completer);
+ add_com_alias ("w", "with", class_vars, 1);
+
add_cmd ("commands", no_set_class, show_commands, _("\
Show the history of commands you typed.\n\
You can supply a command number to start with, or a `+' to start after\n\