public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
                   ` (6 preceding siblings ...)
  2017-10-13 21:00 ` [RFA 5/8] Constify add_path and friends Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-14  4:49   ` Tom Tromey
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

The "x" and "list" commands have special repetition behavior:
repeating the command doesn't re-run it with the same arguments, but
rather advances (through memory or the program listing).

This is currenty implemented by modifying the passed-in argument; but
that won't work properly with const arguments (and seems pretty
obscure besides).

This patch adds a new "truncate_repeat_arguments" function and changes
the relevant places to call it.

2017-10-13  Tom Tromey  <tom@tromey.com>

	* printcmd.c (x_command): Call truncate_repeat_arguments.
	* cli/cli-cmds.c (list_command): Call truncate_repeat_arguments.
	* top.c (should_truncate_repeat_arguments): New global.
	(truncate_repeat_arguments): New function.
	(execute_command): Handle should_truncate_repeat_arguments.
	* command.h (truncate_repeat_arguments): Declare.
---
 gdb/ChangeLog      |  9 +++++++++
 gdb/cli/cli-cmds.c |  2 +-
 gdb/command.h      |  5 +++++
 gdb/printcmd.c     |  2 +-
 gdb/top.c          | 19 +++++++++++++++++++
 5 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index a1c308a38d..d45a7353db 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1082,7 +1082,7 @@ list_command (char *arg, int from_tty)
      turn it into the no-arg variant.  */
 
   if (from_tty)
-    *arg = 0;
+    truncate_repeat_arguments ();
 
   if (dummy_beg && sal_end.symtab == 0)
     error (_("No default source file yet.  Do \"help list\"."));
diff --git a/gdb/command.h b/gdb/command.h
index a99544563c..b590e897ed 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -445,6 +445,11 @@ extern void dont_repeat (void);
 
 extern scoped_restore_tmpl<int> prevent_dont_repeat (void);
 
+/* Truncate the arguments to the last command, so that a repetition of
+   the command sees no arguments.  */
+
+extern void truncate_repeat_arguments ();
+
 /* Used to mark commands that don't do anything.  If we just leave the
    function field NULL, the command is interpreted as a help topic, or
    as a class of commands.  */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 77a05e5d9f..3218b5ab51 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1636,7 +1636,7 @@ x_command (char *exp, int from_tty)
          repeated with Newline.  But don't clobber a user-defined
          command's definition.  */
       if (from_tty)
-	*exp = 0;
+	truncate_repeat_arguments ();
       val = evaluate_expression (expr.get ());
       if (TYPE_IS_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
diff --git a/gdb/top.c b/gdb/top.c
index 3b3bbee4ac..be90ed6e30 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -528,6 +528,19 @@ maybe_wait_sync_command_done (int was_sync)
     wait_sync_command_done ();
 }
 
+/* True if execute_command should truncate the arguments to the last
+   command, so that a repetition of the command sees no arguments.  */
+
+static int should_truncate_repeat_arguments;
+
+/* See command.h.  */
+
+void
+truncate_repeat_arguments ()
+{
+  should_truncate_repeat_arguments = 1;
+}
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -571,6 +584,10 @@ execute_command (char *p, int from_tty)
       c = lookup_cmd (&cmd, cmdlist, "", 0, 1);
       p = (char *) cmd;
 
+      scoped_restore save_truncation
+	= make_scoped_restore (&should_truncate_repeat_arguments, 0);
+      char *args_pointer = p;
+
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;
 
@@ -619,6 +636,8 @@ execute_command (char *p, int from_tty)
       /* If this command has been post-hooked, run the hook last.  */
       execute_cmd_post_hook (c);
 
+      if (should_truncate_repeat_arguments)
+	*args_pointer = '\0';
     }
 
   check_frame_language_change ();
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 8/8] Constify add_com
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
  2017-10-13 21:00 ` [RFA 1/8] Constify add_abbrev_prefix_cmd Tom Tromey
  2017-10-13 21:00 ` [RFA 6/8] Remove cleanup from backtrace_command Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:59   ` Yao Qi
  2017-10-13 21:00 ` [RFA 2/8] Constify add_com_suppress_notification Tom Tromey
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes add_com to take a cmd_const_cfunc_ftype, and then fixes
up all the command implementations.

In most cases this is trivial.

In a couple of places I had to again introduce a temporary non-const
overload.  These overloads will be removed when add_info is
constified.

2017-10-13  Tom Tromey  <tom@tromey.com>

	* solib.h (no_shared_libraries): Constify.
	* frame.h (return_command): Constify.
	* cli/cli-cmds.h (quit_command): Constify.
	* top.h (quit_command, execute_command): Constify.
	* target.h (flash_erase_command): Constify.
	* inferior.h (set_inferior_args, attach_command): Constify.
	* tracepoint.h (start_tracing, stop_tracing): Constify.
	* breakpoint.h (break_command, tbreak_command)
	(hbreak_command_wrapper, thbreak_command_wrapper)
	(rbreak_command_wrapper, watch_command_wrapper)
	(awatch_command_wrapper, rwatch_command_wrapper)
	(get_tracepoint_by_number): Constify.
	* symtab.c (info_variables_command, rbreak_command)
	(symtab_symbol_info): Constify.
	(info_variables_command): Add non-const overload.
	* top.c (dont_repeat_command): Constify.
	* breakpoint.c (ignore_command, commands_command)
	(condition_command, tbreak_command, hbreak_command)
	(thbreak_command, clear_command, break_command)
	(info_breakpoints_command, watch_command, rwatch_command)
	(awatch_command, trace_command, ftrace_command, strace_command)
	(trace_pass_command, break_range_command, dprintf_command)
	(agent_printf_command, get_tracepoint_by_number)
	(watch_maybe_just_location, trace_pass_command): Constify.
	(info_breakpoints_command): Add non-const overload.
	* tracefile.c (tsave_command): Constify.
	* infcmd.c (attach_command, disconnect_command, signal_command)
	(queue_signal_command, stepi_command, nexti_command)
	(finish_command, next_command, step_command, until_command)
	(advance_command, jump_command, continue_command, run_command)
	(start_command, starti_command, interrupt_command)
	(run_command_1, set_inferior_args, step_1): Constify.
	* inferior.c (add_inferior_command, remove_inferior_command)
	(clone_inferior_command): Constify.
	* linux-fork.c (checkpoint_command, restart_command): Constify.
	* windows-nat.c (signal_event_command): Constify.
	* guile/guile.c (guile_repl_command, guile_command): Constify.
	* printcmd.c (x_command, display_command, printf_command)
	(output_command, set_command, call_command, print_command)
	(eval_command): Constify.
	(non_const_set_command): Remove.
	(_initialize_printcmd): Update.
	* source.c (forward_search_command, reverse_search_command):
	Constify.
	* jit.c (jit_reader_load_command, jit_reader_unload_command):
	Constify.
	* infrun.c (handle_command): Constify.
	* memattr.c (mem_command): Constify.
	* stack.c (return_command, up_command, up_silently_command)
	(down_command, down_silently_command, frame_command)
	(backtrace_command, func_command, backtrace_command_1): Constify.
	(backtrace_command): Add non-const overload.
	* remote-sim.c (simulator_command): Constify.
	* exec.c (set_section_command): Constify.
	* tracepoint.c (tdump_command, trace_variable_command)
	(tstatus_command, tstop_command, tstart_command)
	(end_actions_pseudocommand, while_stepping_pseudocommand)
	(collect_pseudocommand, teval_pseudocommand, actions_command)
	(start_tracing, stop_tracing): Constify.
	* value.c (init_if_undefined_command): Constify.
	* tui/tui-stack.c (tui_update_command): Constify.
	* tui/tui-win.c (tui_refresh_all_command)
	(tui_set_tab_width_command, tui_set_win_height_command)
	(tui_set_focus_command, tui_scroll_forward_command)
	(tui_scroll_backward_command, tui_scroll_left_command)
	(tui_scroll_right_command, parse_scrolling_args, tui_set_focus)
	(tui_set_win_height): Constify.
	* tui/tui-layout.c (tui_layout_command): Constify.
	* procfs.c (proc_trace_syscalls, proc_trace_sysentry_cmd)
	(proc_trace_sysexit_cmd, proc_untrace_sysentry_cmd)
	(proc_untrace_sysexit_cmd): Constify.
	* remote.c (threadlist_test_cmd, threadinfo_test_cmd)
	(threadset_test_cmd, threadlist_update_test_cmd)
	(threadalive_test): Constify.
	* objc-lang.c (print_object_command): Constify.
	* command.h (add_com): Constify.
	* cli/cli-dump.c (restore_command): Constify.
	* cli/cli-cmds.c (pwd_command, echo_command, quit_command)
	(help_command, complete_command, shell_command, edit_command)
	(list_command, disassemble_command, make_command)
	(apropos_command, alias_command): Constify.
	* cli/cli-script.c (document_command, define_command)
	(while_command, if_command, validate_comname): Constify.
	* cli/cli-decode.c (struct cmd_list_element): Change type of
	"fun".
	* target.c (do_monitor_command, flash_erase_command): Constify.
	* regcache.c (reg_flush_command): Constify.
	* reverse.c (reverse_step, reverse_next, reverse_stepi)
	(reverse_nexti, reverse_continue, reverse_finish)
	(save_bookmark_command, goto_bookmark_command)
	(exec_reverse_once): Constify.
	* python/python.c (python_interactive_command, python_command):
	Constify.
	* typeprint.c (ptype_command, whatis_command, whatis_exp):
	Constify.
	* solib.c (sharedlibrary_command, no_shared_libraries): Constify.
	* gcore.c (gcore_command): Constify.
---
 gdb/ChangeLog        | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/breakpoint.c     |  81 ++++++++++++++++++-----------------------
 gdb/breakpoint.h     |  12 +++----
 gdb/cli/cli-cmds.c   |  48 ++++++++-----------------
 gdb/cli/cli-cmds.h   |   2 +-
 gdb/cli/cli-decode.c |   3 +-
 gdb/cli/cli-dump.c   |   3 +-
 gdb/cli/cli-script.c |  34 ++++++++----------
 gdb/command.h        |   2 +-
 gdb/exec.c           |   6 ++--
 gdb/frame.h          |   2 +-
 gdb/gcore.c          |   2 +-
 gdb/guile/guile.c    |   8 ++---
 gdb/infcmd.c         |  62 ++++++++++++--------------------
 gdb/inferior.c       |   6 ++--
 gdb/inferior.h       |   4 +--
 gdb/infrun.c         |   4 +--
 gdb/jit.c            |   4 +--
 gdb/linux-fork.c     |   4 +--
 gdb/memattr.c        |  45 ++++++++++++-----------
 gdb/objc-lang.c      |   2 +-
 gdb/printcmd.c       |  24 +++++--------
 gdb/procfs.c         |  10 +++---
 gdb/python/python.c  |   8 ++---
 gdb/regcache.c       |   2 +-
 gdb/remote-sim.c     |   2 +-
 gdb/remote.c         |  10 +++---
 gdb/reverse.c        |  20 +++++------
 gdb/solib.c          |   4 +--
 gdb/solib.h          |   2 +-
 gdb/source.c         |   8 ++---
 gdb/stack.c          |  25 ++++++++-----
 gdb/symtab.c         |  16 ++++++---
 gdb/target.c         |   5 ++-
 gdb/target.h         |   2 +-
 gdb/top.c            |   2 +-
 gdb/top.h            |   2 +-
 gdb/tracefile.c      |   2 +-
 gdb/tracepoint.c     |  26 +++++++-------
 gdb/tracepoint.h     |   4 +--
 gdb/tui/tui-layout.c |   5 ++-
 gdb/tui/tui-stack.c  |   4 +--
 gdb/tui/tui-win.c    |  40 ++++++++++-----------
 gdb/typeprint.c      |  12 ++-----
 gdb/value.c          |   2 +-
 gdb/windows-nat.c    |   2 +-
 46 files changed, 355 insertions(+), 318 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 3e7957f223..c05a2960ac 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -96,8 +96,6 @@ enum exception_event_kind
 static void map_breakpoint_numbers (const char *,
 				    gdb::function_view<void (breakpoint *)>);
 
-static void ignore_command (char *, int);
-
 static void breakpoint_re_set_default (struct breakpoint *);
 
 static void
@@ -119,8 +117,6 @@ static std::vector<symtab_and_line> decode_location_default
   (struct breakpoint *b, const struct event_location *location,
    struct program_space *search_pspace);
 
-static void clear_command (char *, int);
-
 static int can_use_hardware_watchpoint (struct value *);
 
 static void mention (struct breakpoint *);
@@ -165,14 +161,8 @@ static int breakpoint_location_address_range_overlap (struct bp_location *,
 						      struct address_space *,
 						      CORE_ADDR, int);
 
-static void info_breakpoints_command (char *, int);
-
 static void info_watchpoints_command (char *, int);
 
-static void commands_command (char *, int);
-
-static void condition_command (char *, int);
-
 static int remove_breakpoint (struct bp_location *);
 static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
 
@@ -186,10 +176,6 @@ static int hw_watchpoint_used_count_others (struct breakpoint *except,
 					    enum bptype type,
 					    int *other_type_used);
 
-static void hbreak_command (char *, int);
-
-static void thbreak_command (char *, int);
-
 static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
 				    int count);
 
@@ -248,7 +234,7 @@ static void enable_trace_command (char *, int);
 
 static void disable_trace_command (char *, int);
 
-static void trace_pass_command (char *, int);
+static void trace_pass_command (const char *, int);
 
 static void set_tracepoint_count (int num);
 
@@ -982,10 +968,10 @@ condition_completer (struct cmd_list_element *cmd,
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
-condition_command (char *arg, int from_tty)
+condition_command (const char *arg, int from_tty)
 {
   struct breakpoint *b;
-  char *p;
+  const char *p;
   int bnum;
 
   if (arg == 0)
@@ -1303,7 +1289,7 @@ commands_command_1 (const char *arg, int from_tty,
 }
 
 static void
-commands_command (char *arg, int from_tty)
+commands_command (const char *arg, int from_tty)
 {
   commands_command_1 (arg, from_tty, NULL);
 }
@@ -6730,13 +6716,21 @@ default_collect_info (void)
 }
   
 static void
-info_breakpoints_command (char *args, int from_tty)
+info_breakpoints_command (const char *args, int from_tty)
 {
   breakpoint_1 (args, 0, NULL);
 
   default_collect_info ();
 }
 
+/* Temporary non-const overload.  */
+
+static void
+info_breakpoints_command (char *args, int from_tty)
+{
+  info_breakpoints_command ((const char *) args, from_tty);
+}
+
 static void
 info_watchpoints_command (char *args, int from_tty)
 {
@@ -9648,25 +9642,25 @@ resolve_sal_pc (struct symtab_and_line *sal)
 }
 
 void
-break_command (char *arg, int from_tty)
+break_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, 0, from_tty);
 }
 
 void
-tbreak_command (char *arg, int from_tty)
+tbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, BP_TEMPFLAG, from_tty);
 }
 
 static void
-hbreak_command (char *arg, int from_tty)
+hbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
 }
 
 static void
-thbreak_command (char *arg, int from_tty)
+thbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
 }
@@ -9750,9 +9744,8 @@ stopat_command (const char *arg, int from_tty)
    line.  */
 
 static void
-dprintf_command (char *arg_in, int from_tty)
+dprintf_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   event_location_up location = string_to_event_location (&arg, current_language);
 
   /* If non-NULL, ARG should have been advanced past the location;
@@ -9782,7 +9775,7 @@ dprintf_command (char *arg_in, int from_tty)
 }
 
 static void
-agent_printf_command (char *arg, int from_tty)
+agent_printf_command (const char *arg, int from_tty)
 {
   error (_("May only run agent-printf on the target"));
 }
@@ -9966,9 +9959,8 @@ find_breakpoint_range_end (struct symtab_and_line sal)
 /* Implement the "break-range" CLI command.  */
 
 static void
-break_range_command (char *arg_in, int from_tty)
+break_range_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   const char *arg_start;
   struct linespec_result canonical_start, canonical_end;
   int bp_count, can_use_bp, length;
@@ -11073,7 +11065,7 @@ watch_command_wrapper (const char *arg, int from_tty, int internal)
    calls watch_command_1.  */
 
 static void
-watch_maybe_just_location (char *arg, int accessflag, int from_tty)
+watch_maybe_just_location (const char *arg, int accessflag, int from_tty)
 {
   int just_location = 0;
 
@@ -11089,7 +11081,7 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty)
 }
 
 static void
-watch_command (char *arg, int from_tty)
+watch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_write, from_tty);
 }
@@ -11101,7 +11093,7 @@ rwatch_command_wrapper (const char *arg, int from_tty, int internal)
 }
 
 static void
-rwatch_command (char *arg, int from_tty)
+rwatch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_read, from_tty);
 }
@@ -11113,7 +11105,7 @@ awatch_command_wrapper (const char *arg, int from_tty, int internal)
 }
 
 static void
-awatch_command (char *arg, int from_tty)
+awatch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_access, from_tty);
 }
@@ -11521,7 +11513,7 @@ compare_breakpoints (const breakpoint *a, const breakpoint *b)
 /* Delete breakpoints by address or line.  */
 
 static void
-clear_command (char *arg, int from_tty)
+clear_command (const char *arg, int from_tty)
 {
   struct breakpoint *b;
   int default_match;
@@ -14138,9 +14130,9 @@ set_ignore_count (int bptnum, int count, int from_tty)
 /* Command to set ignore-count of breakpoint N to COUNT.  */
 
 static void
-ignore_command (char *args, int from_tty)
+ignore_command (const char *args, int from_tty)
 {
-  char *p = args;
+  const char *p = args;
   int num;
 
   if (p == 0)
@@ -14627,9 +14619,8 @@ set_tracepoint_count (int num)
 }
 
 static void
-trace_command (char *arg_in, int from_tty)
+trace_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   struct breakpoint_ops *ops;
 
   event_location_up location = string_to_event_location (&arg,
@@ -14654,9 +14645,8 @@ trace_command (char *arg_in, int from_tty)
 }
 
 static void
-ftrace_command (char *arg_in, int from_tty)
+ftrace_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   event_location_up location = string_to_event_location (&arg,
 							 current_language);
   create_breakpoint (get_current_arch (),
@@ -14675,9 +14665,8 @@ ftrace_command (char *arg_in, int from_tty)
 /* strace command implementation.  Creates a static tracepoint.  */
 
 static void
-strace_command (char *arg_in, int from_tty)
+strace_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   struct breakpoint_ops *ops;
   event_location_up location;
 
@@ -14913,16 +14902,16 @@ trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
    Also accepts special argument "all".  */
 
 static void
-trace_pass_command (char *args, int from_tty)
+trace_pass_command (const char *args, int from_tty)
 {
   struct tracepoint *t1;
-  unsigned int count;
+  ULONGEST count;
 
   if (args == 0 || *args == 0)
     error (_("passcount command requires an "
 	     "argument (count + optional TP num)"));
 
-  count = strtoul (args, &args, 10);	/* Count comes first, then TP num.  */
+  count = strtoulst (args, &args, 10);	/* Count comes first, then TP num.  */
 
   args = skip_spaces (args);
   if (*args && strncasecmp (args, "all", 3) == 0)
@@ -14995,12 +14984,12 @@ get_tracepoint_by_number_on_target (int num)
    (tracepoint_count) is returned.  */
 
 struct tracepoint *
-get_tracepoint_by_number (char **arg,
+get_tracepoint_by_number (const char **arg,
 			  number_or_range_parser *parser)
 {
   struct breakpoint *t;
   int tpnum;
-  char *instring = arg == NULL ? NULL : *arg;
+  const char *instring = arg == NULL ? NULL : *arg;
 
   if (parser != NULL)
     {
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 2b80ed9f46..c75d5b5b1b 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -1250,15 +1250,15 @@ extern struct command_line *breakpoint_commands (struct breakpoint *b);
    NOT be deallocated after use.  */
 const char *bpdisp_text (enum bpdisp disp);
 
-extern void break_command (char *, int);
+extern void break_command (const char *, int);
 
-extern void hbreak_command_wrapper (char *, int);
-extern void thbreak_command_wrapper (char *, int);
-extern void rbreak_command_wrapper (char *, int);
+extern void hbreak_command_wrapper (const char *, int);
+extern void thbreak_command_wrapper (const char *, int);
+extern void rbreak_command_wrapper (const char *, int);
 extern void watch_command_wrapper (const char *, int, int);
 extern void awatch_command_wrapper (const char *, int, int);
 extern void rwatch_command_wrapper (const char *, int, int);
-extern void tbreak_command (char *, int);
+extern void tbreak_command (const char *, int);
 
 extern struct breakpoint_ops base_breakpoint_ops;
 extern struct breakpoint_ops bkpt_breakpoint_ops;
@@ -1580,7 +1580,7 @@ extern struct tracepoint *get_tracepoint_by_number_on_target (int num);
 
 /* Find a tracepoint by parsing a number in the supplied string.  */
 extern struct tracepoint *
-  get_tracepoint_by_number (char **arg,
+  get_tracepoint_by_number (const char **arg,
 			    number_or_range_parser *parser);
 
 /* Return a vector of all tracepoints currently defined.  The vector
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index d45a7353db..e35ab8a233 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -58,24 +58,6 @@
 #include <algorithm>
 #include <string>
 
-/* Prototypes for local command functions */
-
-static void complete_command (char *, int);
-
-static void echo_command (char *, int);
-
-static void pwd_command (char *, int);
-
-static void help_command (char *, int);
-
-static void make_command (char *, int);
-
-static void shell_escape (const char *, int);
-
-static void edit_command (char *, int);
-
-static void list_command (char *, int);
-
 /* Prototypes for local utility functions */
 
 static void print_sal_location (const symtab_and_line &sal);
@@ -238,7 +220,7 @@ show_command (char *arg, int from_tty)
    is ignored.  */
 
 static void
-help_command (char *command, int from_tty)
+help_command (const char *command, int from_tty)
 {
   help_cmd (command, gdb_stdout);
 }
@@ -248,10 +230,8 @@ help_command (char *command, int from_tty)
    [Is that why this function writes output with *_unfiltered?]  */
 
 static void
-complete_command (char *arg_entry, int from_tty)
+complete_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_entry;
-
   dont_repeat ();
 
   if (max_completions == 0)
@@ -356,7 +336,7 @@ show_configuration (const char *args, int from_tty)
 /* Handle the quit command.  */
 
 void
-quit_command (char *args, int from_tty)
+quit_command (const char *args, int from_tty)
 {
   int exit_code = 0;
 
@@ -378,7 +358,7 @@ quit_command (char *args, int from_tty)
 }
 
 static void
-pwd_command (char *args, int from_tty)
+pwd_command (const char *args, int from_tty)
 {
   if (args)
     error (_("The \"pwd\" command does not take an argument: %s"), args);
@@ -693,7 +673,7 @@ source_command (const char *args, int from_tty)
 
 
 static void
-echo_command (char *text, int from_tty)
+echo_command (const char *text, int from_tty)
 {
   const char *p = text;
   int c;
@@ -785,13 +765,13 @@ shell_escape (const char *arg, int from_tty)
 /* Implementation of the "shell" command.  */
 
 static void
-shell_command (char *arg, int from_tty)
+shell_command (const char *arg, int from_tty)
 {
   shell_escape (arg, from_tty);
 }
 
 static void
-edit_command (char *arg, int from_tty)
+edit_command (const char *arg, int from_tty)
 {
   struct symtab_and_line sal;
   struct symbol *sym;
@@ -891,7 +871,7 @@ edit_command (char *arg, int from_tty)
 }
 
 static void
-list_command (char *arg, int from_tty)
+list_command (const char *arg, int from_tty)
 {
   struct symbol *sym;
   const char *arg1;
@@ -899,7 +879,7 @@ list_command (char *arg, int from_tty)
   int dummy_end = 0;
   int dummy_beg = 0;
   int linenum_beg = 0;
-  char *p;
+  const char *p;
 
   /* Pull in the current default source line if necessary.  */
   if (arg == NULL || ((arg[0] == '+' || arg[0] == '-') && arg[1] == '\0'))
@@ -1205,7 +1185,7 @@ disassemble_current_function (gdb_disassembly_flags flags)
    2) File names and contents for all relevant source files are displayed.  */
 
 static void
-disassemble_command (char *arg, int from_tty)
+disassemble_command (const char *arg, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR low, high;
@@ -1295,7 +1275,7 @@ disassemble_command (char *arg, int from_tty)
 }
 
 static void
-make_command (char *arg, int from_tty)
+make_command (const char *arg, int from_tty)
 {
   if (arg == 0)
     shell_escape ("make", from_tty);
@@ -1336,7 +1316,7 @@ show_user (const char *args, int from_tty)
    regular expression.  */
 
 static void 
-apropos_command (char *searchstr, int from_tty)
+apropos_command (const char *searchstr, int from_tty)
 {
   if (searchstr == NULL)
     error (_("REGEXP string is empty"));
@@ -1405,11 +1385,11 @@ alias_usage_error (void)
 /* Make an alias of an existing command.  */
 
 static void
-alias_command (char *args, int from_tty)
+alias_command (const char *args, int from_tty)
 {
   int i, alias_argc, command_argc;
   int abbrev_flag = 0;
-  char *equals;
+  const char *equals;
   const char *alias, *command;
 
   if (args == NULL || strchr (args, '=') == NULL)
diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h
index 34d19f50c6..14fc93136b 100644
--- a/gdb/cli/cli-cmds.h
+++ b/gdb/cli/cli-cmds.h
@@ -114,7 +114,7 @@ extern void cd_command (const char *, int);
 
 /* Exported to gdb/top.c and gdb/main.c */
 
-extern void quit_command (char *, int);
+extern void quit_command (const char *, int);
 
 extern void source_script (const char *, int);
 
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 76be7d33f4..e9baf38d13 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -931,7 +931,8 @@ add_info_alias (const char *name, const char *oldname, int abbrev_flag)
 /* Add an element to the list of commands.  */
 
 struct cmd_list_element *
-add_com (const char *name, enum command_class theclass, cmd_cfunc_ftype *fun,
+add_com (const char *name, enum command_class theclass,
+	 cmd_const_cfunc_ftype *fun,
 	 const char *doc)
 {
   return add_cmd (name, theclass, fun, doc, &cmdlist);
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index 4eafffac90..3443299e9a 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -513,12 +513,11 @@ restore_binary_file (const char *filename, struct callback_data *data)
 }
 
 static void
-restore_command (char *args_in, int from_tty)
+restore_command (const char *args, int from_tty)
 {
   struct callback_data data;
   bfd *ibfd;
   int binary_flag = 0;
-  const char *args = args_in;
 
   if (!target_has_execution)
     noprocess ();
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 0a93e8b54f..4a66db80d8 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -659,7 +659,7 @@ execute_control_command_untraced (struct command_line *cmd)
    loop condition is nonzero.  */
 
 static void
-while_command (char *arg, int from_tty)
+while_command (const char *arg, int from_tty)
 {
   control_level = 1;
   command_line_up command = get_command_line (while_control, arg);
@@ -676,7 +676,7 @@ while_command (char *arg, int from_tty)
    on the value of the if conditional.  */
 
 static void
-if_command (char *arg, int from_tty)
+if_command (const char *arg, int from_tty)
 {
   control_level = 1;
   command_line_up command = get_command_line (if_control, arg);
@@ -1352,10 +1352,10 @@ copy_command_lines (struct command_line *cmds)
    prefix.  */
 
 static struct cmd_list_element **
-validate_comname (char **comname)
+validate_comname (const char **comname)
 {
   struct cmd_list_element **list = &cmdlist;
-  char *p, *last_word;
+  const char *p, *last_word;
 
   if (*comname == 0)
     error_no_arg (_("name of command to define"));
@@ -1372,19 +1372,16 @@ validate_comname (char **comname)
   if (last_word != *comname)
     {
       struct cmd_list_element *c;
-      char saved_char;
-      const char *tem = *comname;
 
       /* Separate the prefix and the command.  */
-      saved_char = last_word[-1];
-      last_word[-1] = '\0';
+      std::string prefix (*comname, last_word - 1);
+      const char *tem = prefix.c_str ();
 
       c = lookup_cmd (&tem, cmdlist, "", 0, 1);
       if (c->prefixlist == NULL)
-	error (_("\"%s\" is not a prefix command."), *comname);
+	error (_("\"%s\" is not a prefix command."), prefix.c_str ());
 
       list = c->prefixlist;
-      last_word[-1] = saved_char;
       *comname = last_word;
     }
 
@@ -1406,7 +1403,7 @@ user_defined_command (const char *ignore, int from_tty)
 }
 
 static void
-define_command (char *comname, int from_tty)
+define_command (const char *comname, int from_tty)
 {
 #define MAX_TMPBUF 128   
   enum cmd_hook_type
@@ -1416,8 +1413,7 @@ define_command (char *comname, int from_tty)
       CMD_POST_HOOK
     };
   struct cmd_list_element *c, *newc, *hookc = 0, **list;
-  char *tem, *comfull;
-  const char *tem_c;
+  const char *tem, *comfull;
   char tmpbuf[MAX_TMPBUF];
   int  hook_type      = CMD_NO_HOOK;
   int  hook_name_size = 0;
@@ -1431,8 +1427,8 @@ define_command (char *comname, int from_tty)
   list = validate_comname (&comname);
 
   /* Look it up, and verify that we got an exact match.  */
-  tem_c = comname;
-  c = lookup_cmd (&tem_c, *list, "", -1, 1);
+  tem = comname;
+  c = lookup_cmd (&tem, *list, "", -1, 1);
   if (c && strcmp (comname, c->name) != 0)
     c = 0;
 
@@ -1466,8 +1462,8 @@ define_command (char *comname, int from_tty)
   if (hook_type != CMD_NO_HOOK)
     {
       /* Look up cmd it hooks, and verify that we got an exact match.  */
-      tem_c = comname + hook_name_size;
-      hookc = lookup_cmd (&tem_c, *list, "", -1, 0);
+      tem = comname + hook_name_size;
+      hookc = lookup_cmd (&tem, *list, "", -1, 0);
       if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
 	hookc = 0;
       if (!hookc)
@@ -1517,11 +1513,11 @@ define_command (char *comname, int from_tty)
 }
 
 static void
-document_command (char *comname, int from_tty)
+document_command (const char *comname, int from_tty)
 {
   struct cmd_list_element *c, **list;
   const char *tem;
-  char *comfull;
+  const char *comfull;
   char tmpbuf[128];
 
   comfull = comname;
diff --git a/gdb/command.h b/gdb/command.h
index b590e897ed..852f1817e4 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -256,7 +256,7 @@ extern int lookup_cmd_composition (const char *text,
 				   struct cmd_list_element **cmd);
 
 extern struct cmd_list_element *add_com (const char *, enum command_class,
-					 cmd_cfunc_ftype *fun,
+					 cmd_const_cfunc_ftype *fun,
 					 const char *);
 
 extern struct cmd_list_element *add_com_alias (const char *, const char *,
diff --git a/gdb/exec.c b/gdb/exec.c
index 6eda9b2a61..73d3655b1f 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -49,8 +49,6 @@ void (*deprecated_file_changed_hook) (const char *);
 
 /* Prototypes for local functions */
 
-static void set_section_command (char *, int);
-
 static void exec_files_info (struct target_ops *);
 
 static void init_exec_ops (void);
@@ -975,10 +973,10 @@ exec_files_info (struct target_ops *t)
 }
 
 static void
-set_section_command (char *args, int from_tty)
+set_section_command (const char *args, int from_tty)
 {
   struct target_section *p;
-  char *secname;
+  const char *secname;
   unsigned seclen;
   unsigned long secaddr;
   char secprint[100];
diff --git a/gdb/frame.h b/gdb/frame.h
index 190ce7623f..ce9d0bbefe 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -788,7 +788,7 @@ extern void info_args_command (char *, int);
 
 extern void info_locals_command (char *, int);
 
-extern void return_command (char *, int);
+extern void return_command (const char *, int);
 
 /* Set FRAME's unwinder temporarily, so that we can call a sniffer.
    If sniffing fails, the caller should be sure to call
diff --git a/gdb/gcore.c b/gdb/gcore.c
index 69e5eb9575..0d5dccab61 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -141,7 +141,7 @@ write_gcore_file (bfd *obfd)
    Generate a core file from the inferior process.  */
 
 static void
-gcore_command (char *args, int from_tty)
+gcore_command (const char *args, int from_tty)
 {
   gdb::unique_xmalloc_ptr<char> corefilename;
 
diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c
index 5c514f6ace..bc3c45f368 100644
--- a/gdb/guile/guile.c
+++ b/gdb/guile/guile.c
@@ -161,7 +161,7 @@ const struct extension_language_ops guile_extension_ops =
 /* Implementation of the gdb "guile-repl" command.  */
 
 static void
-guile_repl_command (char *arg, int from_tty)
+guile_repl_command (const char *arg, int from_tty)
 {
   scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
@@ -189,7 +189,7 @@ guile_repl_command (char *arg, int from_tty)
    TODO: Add the result to Guile's history?  */
 
 static void
-guile_command (char *arg, int from_tty)
+guile_command (const char *arg, int from_tty)
 {
   scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
@@ -390,7 +390,7 @@ gdbscm_target_config (void)
    commands. */
 
 static void
-guile_repl_command (char *arg, int from_tty)
+guile_repl_command (const char *arg, int from_tty)
 {
   arg = skip_spaces (arg);
   if (arg && *arg)
@@ -399,7 +399,7 @@ guile_repl_command (char *arg, int from_tty)
 }
 
 static void
-guile_command (char *arg, int from_tty)
+guile_command (const char *arg, int from_tty)
 {
   arg = skip_spaces (arg);
   if (arg && *arg)
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 125051fa63..f042ec2b8b 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -66,29 +66,11 @@ static void info_registers_command (char *, int);
 
 static void until_next_command (int);
 
-static void until_command (char *, int);
-
-static void path_command (char *, int);
-
 static void info_float_command (char *, int);
 
-static void disconnect_command (char *, int);
-
 static void info_program_command (char *, int);
 
-static void finish_command (char *, int);
-
-static void signal_command (char *, int);
-
-static void jump_command (char *, int);
-
-static void step_1 (int, int, char *);
-
-static void next_command (char *, int);
-
-static void step_command (char *, int);
-
-static void run_command (char *, int);
+static void step_1 (int, int, const char *);
 
 #define ERROR_NO_INFERIOR \
    if (!target_has_execution) error (_("The program is not being run."));
@@ -204,7 +186,7 @@ get_inferior_args (void)
    NEWARGS is not transferred.  */
 
 void
-set_inferior_args (char *newargs)
+set_inferior_args (const char *newargs)
 {
   xfree (current_inferior ()->args);
   current_inferior ()->args = newargs ? xstrdup (newargs) : NULL;
@@ -585,7 +567,7 @@ enum run_how
    requested by RUN_HOW.  */
 
 static void
-run_command_1 (char *args, int from_tty, enum run_how run_how)
+run_command_1 (const char *args, int from_tty, enum run_how run_how)
 {
   const char *exec_file;
   struct cleanup *old_chain;
@@ -708,7 +690,7 @@ run_command_1 (char *args, int from_tty, enum run_how run_how)
 }
 
 static void
-run_command (char *args, int from_tty)
+run_command (const char *args, int from_tty)
 {
   run_command_1 (args, from_tty, RUN_NORMAL);
 }
@@ -717,7 +699,7 @@ run_command (char *args, int from_tty)
    program.  */
 
 static void
-start_command (char *args, int from_tty)
+start_command (const char *args, int from_tty)
 {
   /* Some languages such as Ada need to search inside the program
      minimal symbols for the location where to put the temporary
@@ -733,7 +715,7 @@ start_command (char *args, int from_tty)
    instruction.  */
 
 static void
-starti_command (char *args, int from_tty)
+starti_command (const char *args, int from_tty)
 {
   run_command_1 (args, from_tty, RUN_STOP_AT_FIRST_INSN);
 } 
@@ -843,7 +825,7 @@ continue_1 (int all_threads)
 /* continue [-a] [proceed-count] [&]  */
 
 static void
-continue_command (char *args, int from_tty)
+continue_command (const char *args, int from_tty)
 {
   int async_exec;
   int all_threads = 0;
@@ -949,7 +931,7 @@ set_step_frame (void)
 /* Step until outside of current statement.  */
 
 static void
-step_command (char *count_string, int from_tty)
+step_command (const char *count_string, int from_tty)
 {
   step_1 (0, 0, count_string);
 }
@@ -957,7 +939,7 @@ step_command (char *count_string, int from_tty)
 /* Likewise, but skip over subroutine calls as if single instructions.  */
 
 static void
-next_command (char *count_string, int from_tty)
+next_command (const char *count_string, int from_tty)
 {
   step_1 (1, 0, count_string);
 }
@@ -965,13 +947,13 @@ next_command (char *count_string, int from_tty)
 /* Likewise, but step only one instruction.  */
 
 static void
-stepi_command (char *count_string, int from_tty)
+stepi_command (const char *count_string, int from_tty)
 {
   step_1 (0, 1, count_string);
 }
 
 static void
-nexti_command (char *count_string, int from_tty)
+nexti_command (const char *count_string, int from_tty)
 {
   step_1 (1, 1, count_string);
 }
@@ -1054,7 +1036,7 @@ step_command_fsm_prepare (struct step_command_fsm *sm,
 static int prepare_one_step (struct step_command_fsm *sm);
 
 static void
-step_1 (int skip_subroutines, int single_inst, char *count_string)
+step_1 (int skip_subroutines, int single_inst, const char *count_string)
 {
   int count;
   int async_exec;
@@ -1242,7 +1224,7 @@ prepare_one_step (struct step_command_fsm *sm)
 /* Continue program at specified address.  */
 
 static void
-jump_command (char *arg, int from_tty)
+jump_command (const char *arg, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR addr;
@@ -1323,7 +1305,7 @@ jump_command (char *arg, int from_tty)
 /* Continue program giving it specified signal.  */
 
 static void
-signal_command (char *signum_exp, int from_tty)
+signal_command (const char *signum_exp, int from_tty)
 {
   enum gdb_signal oursig;
   int async_exec;
@@ -1420,7 +1402,7 @@ signal_command (char *signum_exp, int from_tty)
 /* Queue a signal to be delivered to the current thread.  */
 
 static void
-queue_signal_command (char *signum_exp, int from_tty)
+queue_signal_command (const char *signum_exp, int from_tty)
 {
   enum gdb_signal oursig;
   struct thread_info *tp;
@@ -1601,7 +1583,7 @@ until_next_command (int from_tty)
 }
 
 static void
-until_command (char *arg, int from_tty)
+until_command (const char *arg, int from_tty)
 {
   int async_exec;
 
@@ -1623,7 +1605,7 @@ until_command (char *arg, int from_tty)
 }
 
 static void
-advance_command (char *arg, int from_tty)
+advance_command (const char *arg, int from_tty)
 {
   int async_exec;
 
@@ -2003,7 +1985,7 @@ skip_finish_frames (struct frame_info *frame)
    frame will return to, then continue.  */
 
 static void
-finish_command (char *arg, int from_tty)
+finish_command (const char *arg, int from_tty)
 {
   struct frame_info *frame;
   int async_exec;
@@ -2291,7 +2273,7 @@ path_info (const char *args, int from_tty)
 /* Add zero or more directories to the front of the execution path.  */
 
 static void
-path_command (char *dirname, int from_tty)
+path_command (const char *dirname, int from_tty)
 {
   char *exec_path;
   const char *env;
@@ -2815,7 +2797,7 @@ attach_command_continuation_free_args (void *args)
    and allows us to start debugging it.  */
 
 void
-attach_command (char *args, int from_tty)
+attach_command (const char *args, int from_tty)
 {
   int async_exec;
   struct target_ops *attach_target;
@@ -3035,7 +3017,7 @@ detach_command (const char *args, int from_tty)
    stopped processes on some native platforms (e.g. GNU/Linux).  */
 
 static void
-disconnect_command (char *args, int from_tty)
+disconnect_command (const char *args, int from_tty)
 {
   dont_repeat ();		/* Not for the faint of heart.  */
   query_if_trace_running (from_tty);
@@ -3079,7 +3061,7 @@ interrupt_target_1 (int all_threads)
    if the `-a' switch is used.  */
 
 static void
-interrupt_command (char *args, int from_tty)
+interrupt_command (const char *args, int from_tty)
 {
   if (target_can_async_p ())
     {
diff --git a/gdb/inferior.c b/gdb/inferior.c
index ba8efe2342..0c60d30fa2 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -726,7 +726,7 @@ info_inferiors_command (char *args, int from_tty)
 /* remove-inferior ID */
 
 static void
-remove_inferior_command (char *args, int from_tty)
+remove_inferior_command (const char *args, int from_tty)
 {
   if (args == NULL || *args == '\0')
     error (_("Requires an argument (inferior id(s) to remove)"));
@@ -790,7 +790,7 @@ add_inferior_with_spaces (void)
 /* add-inferior [-copies N] [-exec FILENAME]  */
 
 static void
-add_inferior_command (char *args, int from_tty)
+add_inferior_command (const char *args, int from_tty)
 {
   int i, copies = 1;
   gdb::unique_xmalloc_ptr<char> exec;
@@ -852,7 +852,7 @@ add_inferior_command (char *args, int from_tty)
 /* clone-inferior [-copies N] [ID] */
 
 static void
-clone_inferior_command (char *args, int from_tty)
+clone_inferior_command (const char *args, int from_tty)
 {
   int i, copies = 1;
   struct inferior *orginf = NULL;
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 39a8877b22..f70c0accc5 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -152,11 +152,11 @@ extern void setup_inferior (int from_tty);
 
 extern void post_create_inferior (struct target_ops *, int);
 
-extern void attach_command (char *, int);
+extern void attach_command (const char *, int);
 
 extern char *get_inferior_args (void);
 
-extern void set_inferior_args (char *);
+extern void set_inferior_args (const char *);
 
 extern void set_inferior_args_vector (int, char **);
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d00c5f6ee0..98a11a3957 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -72,8 +72,6 @@
 
 static void info_signals_command (char *, int);
 
-static void handle_command (char *, int);
-
 static void sig_print_info (enum gdb_signal);
 
 static void sig_print_header (void);
@@ -8467,7 +8465,7 @@ sig_print_info (enum gdb_signal oursig)
 /* Specify how various signals in the inferior should be handled.  */
 
 static void
-handle_command (char *args, int from_tty)
+handle_command (const char *args, int from_tty)
 {
   int digits, wordlen;
   int sigfirst, signum, siglast;
diff --git a/gdb/jit.c b/gdb/jit.c
index 556bcb6749..8ce14e7e01 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -208,7 +208,7 @@ jit_reader_load (const char *file_name)
 /* Provides the jit-reader-load command.  */
 
 static void
-jit_reader_load_command (char *args, int from_tty)
+jit_reader_load_command (const char *args, int from_tty)
 {
   if (args == NULL)
     error (_("No reader name provided."));
@@ -229,7 +229,7 @@ jit_reader_load_command (char *args, int from_tty)
 /* Provides the jit-reader-unload command.  */
 
 static void
-jit_reader_unload_command (char *args, int from_tty)
+jit_reader_unload_command (const char *args, int from_tty)
 {
   if (!loaded_jit_reader)
     error (_("No JIT reader loaded."));
diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c
index 554cfae772..c60d90c3e5 100644
--- a/gdb/linux-fork.c
+++ b/gdb/linux-fork.c
@@ -668,7 +668,7 @@ inf_has_multiple_threads (void)
 }
 
 static void
-checkpoint_command (char *args, int from_tty)
+checkpoint_command (const char *args, int from_tty)
 {
   struct objfile *fork_objf;
   struct gdbarch *gdbarch;
@@ -761,7 +761,7 @@ linux_fork_context (struct fork_info *newfp, int from_tty)
 
 /* Switch inferior process (checkpoint) context, by checkpoint id.  */
 static void
-restart_command (char *args, int from_tty)
+restart_command (const char *args, int from_tty)
 {
   struct fork_info *fp;
 
diff --git a/gdb/memattr.c b/gdb/memattr.c
index 6ed126b75b..89adce85f4 100644
--- a/gdb/memattr.c
+++ b/gdb/memattr.c
@@ -313,10 +313,9 @@ mem_clear (void)
 \f
 
 static void
-mem_command (char *args, int from_tty)
+mem_command (const char *args, int from_tty)
 {
   CORE_ADDR lo, hi;
-  char *tok;
   struct mem_attrib attrib;
 
   if (!args)
@@ -340,41 +339,41 @@ mem_command (char *args, int from_tty)
 
   require_user_regions (from_tty);
 
-  tok = strtok (args, " \t");
-  if (!tok)
+  std::string tok = extract_arg (&args);
+  if (tok == "")
     error (_("no lo address"));
-  lo = parse_and_eval_address (tok);
+  lo = parse_and_eval_address (tok.c_str ());
 
-  tok = strtok (NULL, " \t");
-  if (!tok)
+  tok = extract_arg (&args);
+  if (tok == "")
     error (_("no hi address"));
-  hi = parse_and_eval_address (tok);
+  hi = parse_and_eval_address (tok.c_str ());
 
   attrib = default_mem_attrib;
-  while ((tok = strtok (NULL, " \t")) != NULL)
+  while ((tok = extract_arg (&args)) != "")
     {
-      if (strcmp (tok, "rw") == 0)
+      if (tok == "rw")
 	attrib.mode = MEM_RW;
-      else if (strcmp (tok, "ro") == 0)
+      else if (tok == "ro")
 	attrib.mode = MEM_RO;
-      else if (strcmp (tok, "wo") == 0)
+      else if (tok == "wo")
 	attrib.mode = MEM_WO;
 
-      else if (strcmp (tok, "8") == 0)
+      else if (tok == "8")
 	attrib.width = MEM_WIDTH_8;
-      else if (strcmp (tok, "16") == 0)
+      else if (tok == "16")
 	{
 	  if ((lo % 2 != 0) || (hi % 2 != 0))
 	    error (_("region bounds not 16 bit aligned"));
 	  attrib.width = MEM_WIDTH_16;
 	}
-      else if (strcmp (tok, "32") == 0)
+      else if (tok == "32")
 	{
 	  if ((lo % 4 != 0) || (hi % 4 != 0))
 	    error (_("region bounds not 32 bit aligned"));
 	  attrib.width = MEM_WIDTH_32;
 	}
-      else if (strcmp (tok, "64") == 0)
+      else if (tok == "64")
 	{
 	  if ((lo % 8 != 0) || (hi % 8 != 0))
 	    error (_("region bounds not 64 bit aligned"));
@@ -382,26 +381,26 @@ mem_command (char *args, int from_tty)
 	}
 
 #if 0
-      else if (strcmp (tok, "hwbreak") == 0)
+      else if (tok == "hwbreak")
 	attrib.hwbreak = 1;
-      else if (strcmp (tok, "swbreak") == 0)
+      else if (tok == "swbreak")
 	attrib.hwbreak = 0;
 #endif
 
-      else if (strcmp (tok, "cache") == 0)
+      else if (tok == "cache")
 	attrib.cache = 1;
-      else if (strcmp (tok, "nocache") == 0)
+      else if (tok == "nocache")
 	attrib.cache = 0;
 
 #if 0
-      else if (strcmp (tok, "verify") == 0)
+      else if (tok == "verify")
 	attrib.verify = 1;
-      else if (strcmp (tok, "noverify") == 0)
+      else if (tok == "noverify")
 	attrib.verify = 0;
 #endif
 
       else
-	error (_("unknown attribute: %s"), tok);
+	error (_("unknown attribute: %s"), tok.c_str ());
     }
 
   create_mem_region (lo, hi, &attrib);
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 0423832d5f..43abf13bc3 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -1184,7 +1184,7 @@ find_imps (const char *method, VEC (const_char_ptr) **symbol_names)
 }
 
 static void 
-print_object_command (char *args, int from_tty)
+print_object_command (const char *args, int from_tty)
 {
   struct value *object, *function, *description;
   CORE_ADDR string_addr, object_addr;
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 3218b5ab51..2e0d5180cb 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1204,14 +1204,14 @@ print_command_1 (const char *exp, int voidprint)
 }
 
 static void
-print_command (char *exp, int from_tty)
+print_command (const char *exp, int from_tty)
 {
   print_command_1 (exp, 1);
 }
 
 /* Same as print, except it doesn't print void results.  */
 static void
-call_command (char *exp, int from_tty)
+call_command (const char *exp, int from_tty)
 {
   print_command_1 (exp, 0);
 }
@@ -1219,7 +1219,7 @@ call_command (char *exp, int from_tty)
 /* Implementation of the "output" command.  */
 
 static void
-output_command (char *exp, int from_tty)
+output_command (const char *exp, int from_tty)
 {
   output_command_const (exp, from_tty);
 }
@@ -1285,14 +1285,6 @@ set_command (const char *exp, int from_tty)
   evaluate_expression (expr.get ());
 }
 
-/* Temporary non-const version of set_command.  */
-
-static void
-non_const_set_command (char *exp, int from_tty)
-{
-  set_command (exp, from_tty);
-}
-
 static void
 info_symbol_command (char *arg, int from_tty)
 {
@@ -1609,7 +1601,7 @@ info_address_command (char *exp, int from_tty)
 \f
 
 static void
-x_command (char *exp, int from_tty)
+x_command (const char *exp, int from_tty)
 {
   struct format_data fmt;
   struct value *val;
@@ -1692,7 +1684,7 @@ x_command (char *exp, int from_tty)
    Specify the expression.  */
 
 static void
-display_command (char *arg, int from_tty)
+display_command (const char *arg, int from_tty)
 {
   struct format_data fmt;
   struct display *newobj;
@@ -2643,7 +2635,7 @@ ui_printf (const char *arg, struct ui_file *stream)
 /* Implement the "printf" command.  */
 
 static void
-printf_command (char *arg, int from_tty)
+printf_command (const char *arg, int from_tty)
 {
   ui_printf (arg, gdb_stdout);
   gdb_flush (gdb_stdout);
@@ -2652,7 +2644,7 @@ printf_command (char *arg, int from_tty)
 /* Implement the "eval" command.  */
 
 static void
-eval_command (char *arg, int from_tty)
+eval_command (const char *arg, int from_tty)
 {
   string_file stb;
 
@@ -2757,7 +2749,7 @@ With a subcommand, this command modifies parts of the gdb environment.\n\
 You can see these environment settings with the \"show\" command."),
 		  &setlist, "set ", 1, &cmdlist);
   if (dbx_commands)
-    add_com ("assign", class_vars, non_const_set_command, _("\
+    add_com ("assign", class_vars, set_command, _("\
 Evaluate expression EXP and assign result to variable VAR, using assignment\n\
 syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
 example).  VAR may be a debugger \"convenience\" variable (names starting\n\
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 34515a0f58..2bcc64723f 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -5224,7 +5224,7 @@ proc_trace_syscalls_1 (procinfo *pi, int syscallnum, int entry_or_exit,
 }
 
 static void
-proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
+proc_trace_syscalls (const char *args, int from_tty, int entry_or_exit, int mode)
 {
   procinfo *pi;
 
@@ -5244,25 +5244,25 @@ proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
 }
 
 static void
-proc_trace_sysentry_cmd (char *args, int from_tty)
+proc_trace_sysentry_cmd (const char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET);
 }
 
 static void
-proc_trace_sysexit_cmd (char *args, int from_tty)
+proc_trace_sysexit_cmd (const char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET);
 }
 
 static void
-proc_untrace_sysentry_cmd (char *args, int from_tty)
+proc_untrace_sysentry_cmd (const char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET);
 }
 
 static void
-proc_untrace_sysexit_cmd (char *args, int from_tty)
+proc_untrace_sysexit_cmd (const char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
 }
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 5bb642a50a..88a31b0c99 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -289,7 +289,7 @@ eval_python_command (const char *command)
 /* Implementation of the gdb "python-interactive" command.  */
 
 static void
-python_interactive_command (char *arg, int from_tty)
+python_interactive_command (const char *arg, int from_tty)
 {
   struct ui *ui = current_ui;
   int err;
@@ -404,7 +404,7 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
 /* Implementation of the gdb "python" command.  */
 
 static void
-python_command (char *arg, int from_tty)
+python_command (const char *arg, int from_tty)
 {
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
@@ -1397,7 +1397,7 @@ gdbpy_free_type_printers (const struct extension_language_defn *extlang,
    command. */
 
 static void
-python_interactive_command (char *arg, int from_tty)
+python_interactive_command (const char *arg, int from_tty)
 {
   arg = skip_spaces (arg);
   if (arg && *arg)
@@ -1411,7 +1411,7 @@ python_interactive_command (char *arg, int from_tty)
 }
 
 static void
-python_command (char *arg, int from_tty)
+python_command (const char *arg, int from_tty)
 {
   python_interactive_command (arg, from_tty);
 }
diff --git a/gdb/regcache.c b/gdb/regcache.c
index bf448ef123..2a0a613f2b 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1329,7 +1329,7 @@ regcache::debug_print_register (const char *func,  int regno)
 }
 
 static void
-reg_flush_command (char *command, int from_tty)
+reg_flush_command (const char *command, int from_tty)
 {
   /* Force-flush the register cache.  */
   registers_changed ();
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index 48fa503cf4..553aee8aad 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -1179,7 +1179,7 @@ gdbsim_mourn_inferior (struct target_ops *target)
    simulator must do any command interpretation work.  */
 
 void
-simulator_command (char *args, int from_tty)
+simulator_command (const char *args, int from_tty)
 {
   struct sim_inferior_data *sim_data;
 
diff --git a/gdb/remote.c b/gdb/remote.c
index e06e807712..043c74eba8 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -10977,7 +10977,7 @@ static void init_remote_threadtests (void);
 #define SAMPLE_THREAD  0x05060708	/* Truncated 64 bit threadid.  */
 
 static void
-threadset_test_cmd (char *cmd, int tty)
+threadset_test_cmd (const char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
 
@@ -10987,7 +10987,7 @@ threadset_test_cmd (char *cmd, int tty)
 
 
 static void
-threadalive_test (char *cmd, int tty)
+threadalive_test (const char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
   int pid = ptid_get_pid (inferior_ptid);
@@ -11012,7 +11012,7 @@ output_threadid (char *title, threadref *ref)
 }
 
 static void
-threadlist_test_cmd (char *cmd, int tty)
+threadlist_test_cmd (const char *cmd, int tty)
 {
   int startflag = 1;
   threadref nextthread;
@@ -11057,7 +11057,7 @@ get_and_display_threadinfo (threadref *ref)
 }
 
 static void
-threadinfo_test_cmd (char *cmd, int tty)
+threadinfo_test_cmd (const char *cmd, int tty)
 {
   int athread = SAMPLE_THREAD;
   threadref thread;
@@ -11077,7 +11077,7 @@ thread_display_step (threadref *ref, void *context)
 }
 
 static void
-threadlist_update_test_cmd (char *cmd, int tty)
+threadlist_update_test_cmd (const char *cmd, int tty)
 {
   printf_filtered ("Remote Threadlist update test\n");
   remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
diff --git a/gdb/reverse.c b/gdb/reverse.c
index e7ef5c3792..0d1c6e6549 100644
--- a/gdb/reverse.c
+++ b/gdb/reverse.c
@@ -36,7 +36,7 @@
    Used to implement reverse-next etc. commands.  */
 
 static void
-exec_reverse_once (const char *cmd, char *args, int from_tty)
+exec_reverse_once (const char *cmd, const char *args, int from_tty)
 {
   enum exec_direction_kind dir = execution_direction;
 
@@ -54,37 +54,37 @@ exec_reverse_once (const char *cmd, char *args, int from_tty)
 }
 
 static void
-reverse_step (char *args, int from_tty)
+reverse_step (const char *args, int from_tty)
 {
   exec_reverse_once ("step", args, from_tty);
 }
 
 static void
-reverse_stepi (char *args, int from_tty)
+reverse_stepi (const char *args, int from_tty)
 {
   exec_reverse_once ("stepi", args, from_tty);
 }
 
 static void
-reverse_next (char *args, int from_tty)
+reverse_next (const char *args, int from_tty)
 {
   exec_reverse_once ("next", args, from_tty);
 }
 
 static void
-reverse_nexti (char *args, int from_tty)
+reverse_nexti (const char *args, int from_tty)
 {
   exec_reverse_once ("nexti", args, from_tty);
 }
 
 static void
-reverse_continue (char *args, int from_tty)
+reverse_continue (const char *args, int from_tty)
 {
   exec_reverse_once ("continue", args, from_tty);
 }
 
 static void
-reverse_finish (char *args, int from_tty)
+reverse_finish (const char *args, int from_tty)
 {
   exec_reverse_once ("finish", args, from_tty);
 }
@@ -117,7 +117,7 @@ static int bookmark_count;
    Up to us to free it as required.  */
 
 static void
-save_bookmark_command (char *args, int from_tty)
+save_bookmark_command (const char *args, int from_tty)
 {
   /* Get target's idea of a bookmark.  */
   gdb_byte *bookmark_id = target_get_bookmark (args, from_tty);
@@ -230,11 +230,11 @@ delete_bookmark_command (const char *args, int from_tty)
 /* Implement "goto-bookmark" command.  */
 
 static void
-goto_bookmark_command (char *args, int from_tty)
+goto_bookmark_command (const char *args, int from_tty)
 {
   struct bookmark *b;
   unsigned long num;
-  char *p = args;
+  const char *p = args;
 
   if (args == NULL || args[0] == '\0')
     error (_("Command requires an argument."));
diff --git a/gdb/solib.c b/gdb/solib.c
index f9f7217b7d..c70b9d8193 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1246,7 +1246,7 @@ in_solib_dynsym_resolve_code (CORE_ADDR pc)
 /* Implements the "sharedlibrary" command.  */
 
 static void
-sharedlibrary_command (char *args, int from_tty)
+sharedlibrary_command (const char *args, int from_tty)
 {
   dont_repeat ();
   solib_add (args, from_tty, 1);
@@ -1258,7 +1258,7 @@ sharedlibrary_command (char *args, int from_tty)
    are not discarded.  Also called from remote.c.  */
 
 void
-no_shared_libraries (char *ignored, int from_tty)
+no_shared_libraries (const char *ignored, int from_tty)
 {
   /* The order of the two routines below is important: clear_solib notifies
      the solib_unloaded observers, and some of these observers might need
diff --git a/gdb/solib.h b/gdb/solib.h
index e91fb75d3d..35f956b08d 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -71,7 +71,7 @@ extern int in_solib_dynsym_resolve_code (CORE_ADDR);
 
 /* Discard symbols that were auto-loaded from shared libraries.  */
 
-extern void no_shared_libraries (char *ignored, int from_tty);
+extern void no_shared_libraries (const char *ignored, int from_tty);
 
 /* Set the solib operations for GDBARCH to NEW_OPS.  */
 
diff --git a/gdb/source.c b/gdb/source.c
index 4ae2ba251b..e67209e201 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -52,10 +52,6 @@
 
 static int get_filename_and_charpos (struct symtab *, char **);
 
-static void reverse_search_command (char *, int);
-
-static void forward_search_command (char *, int);
-
 static void info_line_command (char *, int);
 
 static void info_source_command (char *, int);
@@ -1591,7 +1587,7 @@ info_line_command (char *arg, int from_tty)
 /* Commands to search the source file for a regexp.  */
 
 static void
-forward_search_command (char *regex, int from_tty)
+forward_search_command (const char *regex, int from_tty)
 {
   int c;
   int desc;
@@ -1676,7 +1672,7 @@ forward_search_command (char *regex, int from_tty)
 }
 
 static void
-reverse_search_command (char *regex, int from_tty)
+reverse_search_command (const char *regex, int from_tty)
 {
   int c;
   int desc;
diff --git a/gdb/stack.c b/gdb/stack.c
index 63c3d837de..946a2e243b 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1844,11 +1844,10 @@ backtrace_command_1 (const char *count_exp, int show_locals, int no_filters,
 }
 
 static void
-backtrace_command (char *arg_in, int from_tty)
+backtrace_command (const char *arg, int from_tty)
 {
   int fulltrace_arg = -1, arglen = 0, argc = 0, no_filters  = -1;
   int user_arg = 0;
-  const char *arg = arg_in;
 
   std::string reconstructed_arg;
   if (arg)
@@ -1904,6 +1903,14 @@ backtrace_command (char *arg_in, int from_tty)
 		       no_filters >= 0 /* no frame-filters */, from_tty);
 }
 
+/* Temporary non-const overload.  */
+
+static void
+backtrace_command (char *arg, int from_tty)
+{
+  backtrace_command ((const char *) arg, from_tty);
+}
+
 /* Iterate over the local variables of a block B, calling CB with
    CB_DATA.  */
 
@@ -2281,7 +2288,7 @@ select_frame_command (const char *level_exp, int from_tty)
    the selected frame.  */
 
 static void
-frame_command (char *level_exp, int from_tty)
+frame_command (const char *level_exp, int from_tty)
 {
   struct frame_info *prev_frame = get_selected_frame_if_set ();
 
@@ -2311,13 +2318,13 @@ up_silently_base (const char *count_exp)
 }
 
 static void
-up_silently_command (char *count_exp, int from_tty)
+up_silently_command (const char *count_exp, int from_tty)
 {
   up_silently_base (count_exp);
 }
 
 static void
-up_command (char *count_exp, int from_tty)
+up_command (const char *count_exp, int from_tty)
 {
   up_silently_base (count_exp);
   observer_notify_user_selected_context_changed (USER_SELECTED_FRAME);
@@ -2350,20 +2357,20 @@ down_silently_base (const char *count_exp)
 }
 
 static void
-down_silently_command (char *count_exp, int from_tty)
+down_silently_command (const char *count_exp, int from_tty)
 {
   down_silently_base (count_exp);
 }
 
 static void
-down_command (char *count_exp, int from_tty)
+down_command (const char *count_exp, int from_tty)
 {
   down_silently_base (count_exp);
   observer_notify_user_selected_context_changed (USER_SELECTED_FRAME);
 }
 
 void
-return_command (char *retval_exp, int from_tty)
+return_command (const char *retval_exp, int from_tty)
 {
   /* Initialize it just to avoid a GCC false warning.  */
   enum return_value_convention rv_conv = RETURN_VALUE_STRUCT_CONVENTION;
@@ -2498,7 +2505,7 @@ struct function_bounds
 };
 
 static void
-func_command (char *arg, int from_tty)
+func_command (const char *arg, int from_tty)
 {
   struct frame_info *frame;
   int found = 0;
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 16a6b2eb6f..f4deace2fd 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -69,7 +69,7 @@
 
 /* Forward declarations for local functions.  */
 
-static void rbreak_command (char *, int);
+static void rbreak_command (const char *, int);
 
 static int find_line_common (struct linetable *, int, int *, int);
 
@@ -4436,7 +4436,7 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
    matches.  */
 
 static void
-symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty)
+symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
 {
   static const char * const classnames[] =
     {"variable", "function", "type"};
@@ -4480,6 +4480,14 @@ symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty)
 }
 
 static void
+info_variables_command (const char *regexp, int from_tty)
+{
+  symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
+}
+
+/* Temporary non-const overload.  */
+
+static void
 info_variables_command (char *regexp, int from_tty)
 {
   symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
@@ -4515,7 +4523,7 @@ do_end_rbreak_breakpoints (void *ignore)
 }
 
 static void
-rbreak_command (char *regexp, int from_tty)
+rbreak_command (const char *regexp, int from_tty)
 {
   struct cleanup *old_chain;
   char *string = NULL;
@@ -4526,7 +4534,7 @@ rbreak_command (char *regexp, int from_tty)
 
   if (regexp)
     {
-      char *colon = strchr (regexp, ':');
+      const char *colon = strchr (regexp, ':');
 
       if (colon && *(colon + 1) != ':')
 	{
diff --git a/gdb/target.c b/gdb/target.c
index 4a7589d445..d89d0558ec 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3803,8 +3803,7 @@ default_rcmd (struct target_ops *self, const char *command,
 }
 
 static void
-do_monitor_command (char *cmd,
-		 int from_tty)
+do_monitor_command (const char *cmd, int from_tty)
 {
   target_rcmd (cmd, gdb_stdtarg);
 }
@@ -3813,7 +3812,7 @@ do_monitor_command (char *cmd,
    ignored.  */
 
 void
-flash_erase_command (char *cmd, int from_tty)
+flash_erase_command (const char *cmd, int from_tty)
 {
   /* Used to communicate termination of flash operations to the target.  */
   bool found_flash_region = false;
diff --git a/gdb/target.h b/gdb/target.h
index f5ad1e5ca8..3077351aed 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1476,7 +1476,7 @@ extern int target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr,
 VEC(mem_region_s) *target_memory_map (void);
 
 /* Erases all flash memory regions on the target.  */
-void flash_erase_command (char *cmd, int from_tty);
+void flash_erase_command (const char *cmd, int from_tty);
 
 /* Erase the specified flash region.  */
 void target_flash_erase (ULONGEST address, LONGEST length);
diff --git a/gdb/top.c b/gdb/top.c
index be90ed6e30..c50afa870b 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1682,7 +1682,7 @@ input_interactive_p (struct ui *ui)
 }
 \f
 static void
-dont_repeat_command (char *ignored, int from_tty)
+dont_repeat_command (const char *ignored, int from_tty)
 {
   /* Can't call dont_repeat here because we're not necessarily reading
      from stdin.  */
diff --git a/gdb/top.h b/gdb/top.h
index ab21e5e013..7a8ffc82df 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -229,7 +229,7 @@ extern void init_history (void);
 extern void command_loop (void);
 extern int quit_confirm (void);
 extern void quit_force (int *, int);
-extern void quit_command (char *, int);
+extern void quit_command (const char *, int);
 extern void quit_cover (void);
 extern void execute_command (char *, int);
 
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index b6a800cf7d..447e63211c 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -306,7 +306,7 @@ trace_save (const char *filename, struct trace_file_writer *writer,
 }
 
 static void
-tsave_command (char *args, int from_tty)
+tsave_command (const char *args, int from_tty)
 {
   int target_does_save = 0;
   char **argv;
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index c66a4b39c5..570c29ad92 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -369,11 +369,11 @@ validate_trace_state_variable_name (const char *name)
    evaluate into an initial value.  */
 
 static void
-trace_variable_command (char *args, int from_tty)
+trace_variable_command (const char *args, int from_tty)
 {
   LONGEST initval = 0;
   struct trace_state_variable *tsv;
-  char *name_start, *p;
+  const char *name_start, *p;
 
   if (!args || !*args)
     error_no_arg (_("Syntax is $NAME [ = EXPR ]"));
@@ -541,25 +541,25 @@ save_trace_state_variables (struct ui_file *fp)
    which is always an error.  */
 
 static void
-end_actions_pseudocommand (char *args, int from_tty)
+end_actions_pseudocommand (const char *args, int from_tty)
 {
   error (_("This command cannot be used at the top level."));
 }
 
 static void
-while_stepping_pseudocommand (char *args, int from_tty)
+while_stepping_pseudocommand (const char *args, int from_tty)
 {
   error (_("This command can only be used in a tracepoint actions list."));
 }
 
 static void
-collect_pseudocommand (char *args, int from_tty)
+collect_pseudocommand (const char *args, int from_tty)
 {
   error (_("This command can only be used in a tracepoint actions list."));
 }
 
 static void
-teval_pseudocommand (char *args, int from_tty)
+teval_pseudocommand (const char *args, int from_tty)
 {
   error (_("This command can only be used in a tracepoint actions list."));
 }
@@ -608,7 +608,7 @@ decode_agent_options (const char *exp, int *trace_string)
 
 /* Enter a list of actions for a tracepoint.  */
 static void
-actions_command (char *args, int from_tty)
+actions_command (const char *args, int from_tty)
 {
   struct tracepoint *t;
 
@@ -1602,7 +1602,7 @@ trace_reset_local_state (void)
 }
 
 void
-start_tracing (char *notes)
+start_tracing (const char *notes)
 {
   VEC(breakpoint_p) *tp_vec = NULL;
   int ix;
@@ -1733,7 +1733,7 @@ start_tracing (char *notes)
    anybody else messing with the target.  */
 
 static void
-tstart_command (char *args, int from_tty)
+tstart_command (const char *args, int from_tty)
 {
   dont_repeat ();	/* Like "run", dangerous to repeat accidentally.  */
 
@@ -1753,7 +1753,7 @@ tstart_command (char *args, int from_tty)
    of the trace run's status.  */
 
 static void
-tstop_command (char *args, int from_tty)
+tstop_command (const char *args, int from_tty)
 {
   if (!current_trace_status ()->running)
     error (_("Trace is not running."));
@@ -1762,7 +1762,7 @@ tstop_command (char *args, int from_tty)
 }
 
 void
-stop_tracing (char *note)
+stop_tracing (const char *note)
 {
   int ret;
   VEC(breakpoint_p) *tp_vec = NULL;
@@ -1810,7 +1810,7 @@ stop_tracing (char *note)
 
 /* tstatus command */
 static void
-tstatus_command (char *args, int from_tty)
+tstatus_command (const char *args, int from_tty)
 {
   struct trace_status *ts = current_trace_status ();
   int status, ix;
@@ -2880,7 +2880,7 @@ all_tracepoint_actions_and_cleanup (struct breakpoint *t)
 /* The tdump command.  */
 
 static void
-tdump_command (char *args, int from_tty)
+tdump_command (const char *args, int from_tty)
 {
   int stepping_frame = 0;
   struct bp_location *loc;
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index ffa645bacb..0c5b4e5ae8 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -368,8 +368,8 @@ extern void trace_reset_local_state (void);
 
 extern void check_trace_running (struct trace_status *);
 
-extern void start_tracing (char *notes);
-extern void stop_tracing (char *notes);
+extern void start_tracing (const char *notes);
+extern void stop_tracing (const char *notes);
 
 extern void trace_status_mi (int on_stop);
 
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index fe68331b5b..8b94ddf6ce 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -62,7 +62,7 @@ static void show_source_disasm_command (void);
 static void show_data (enum tui_layout_type);
 static enum tui_layout_type next_layout (void);
 static enum tui_layout_type prev_layout (void);
-static void tui_layout_command (char *, int);
+static void tui_layout_command (const char *, int);
 static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);
 
 
@@ -492,12 +492,11 @@ extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
 
 
 static void
-tui_layout_command (char *arg, int from_tty)
+tui_layout_command (const char *arg, int from_tty)
 {
   /* Switch to the selected layout.  */
   if (tui_set_layout_by_name (arg) != TUI_SUCCESS)
     warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE);
-
 }
 
 /* Answer the previous layout to cycle to.  */
diff --git a/gdb/tui/tui-stack.c b/gdb/tui/tui-stack.c
index ce7c5ee732..4a69b97b9d 100644
--- a/gdb/tui/tui-stack.c
+++ b/gdb/tui/tui-stack.c
@@ -53,7 +53,7 @@ static int tui_set_locator_info (struct gdbarch *gdbarch,
 				 const char *procname,
                                  int lineno, CORE_ADDR addr);
 
-static void tui_update_command (char *, int);
+static void tui_update_command (const char *, int);
 \f
 
 /* Create the status line to display as much information as we can on
@@ -497,7 +497,7 @@ _initialize_tui_stack (void)
 
 /* Command to update the display with the current execution point.  */
 static void
-tui_update_command (char *arg, int from_tty)
+tui_update_command (const char *arg, int from_tty)
 {
   char cmd[sizeof("frame 0")];
 
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index 26b6b5e8f5..9482646c95 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -61,16 +61,16 @@ static void make_invisible_and_set_new_height (struct tui_win_info *,
 static enum tui_status tui_adjust_win_heights (struct tui_win_info *, 
 					       int);
 static int new_height_ok (struct tui_win_info *, int);
-static void tui_set_tab_width_command (char *, int);
-static void tui_refresh_all_command (char *, int);
-static void tui_set_win_height_command (char *, int);
+static void tui_set_tab_width_command (const char *, int);
+static void tui_refresh_all_command (const char *, int);
+static void tui_set_win_height_command (const char *, int);
 static void tui_all_windows_info (char *, int);
-static void tui_set_focus_command (char *, int);
-static void tui_scroll_forward_command (char *, int);
-static void tui_scroll_backward_command (char *, int);
-static void tui_scroll_left_command (char *, int);
-static void tui_scroll_right_command (char *, int);
-static void parse_scrolling_args (char *, 
+static void tui_set_focus_command (const char *, int);
+static void tui_scroll_forward_command (const char *, int);
+static void tui_scroll_backward_command (const char *, int);
+static void tui_scroll_left_command (const char *, int);
+static void tui_scroll_right_command (const char *, int);
+static void parse_scrolling_args (const char *, 
 				  struct tui_win_info **, 
 				  int *);
 
@@ -980,7 +980,7 @@ tui_initialize_win (void)
 
 
 static void
-tui_scroll_forward_command (char *arg, int from_tty)
+tui_scroll_forward_command (const char *arg, int from_tty)
 {
   int num_to_scroll = 1;
   struct tui_win_info *win_to_scroll;
@@ -996,7 +996,7 @@ tui_scroll_forward_command (char *arg, int from_tty)
 
 
 static void
-tui_scroll_backward_command (char *arg, int from_tty)
+tui_scroll_backward_command (const char *arg, int from_tty)
 {
   int num_to_scroll = 1;
   struct tui_win_info *win_to_scroll;
@@ -1012,7 +1012,7 @@ tui_scroll_backward_command (char *arg, int from_tty)
 
 
 static void
-tui_scroll_left_command (char *arg, int from_tty)
+tui_scroll_left_command (const char *arg, int from_tty)
 {
   int num_to_scroll;
   struct tui_win_info *win_to_scroll;
@@ -1025,7 +1025,7 @@ tui_scroll_left_command (char *arg, int from_tty)
 
 
 static void
-tui_scroll_right_command (char *arg, int from_tty)
+tui_scroll_right_command (const char *arg, int from_tty)
 {
   int num_to_scroll;
   struct tui_win_info *win_to_scroll;
@@ -1039,7 +1039,7 @@ tui_scroll_right_command (char *arg, int from_tty)
 
 /* Set focus to the window named by 'arg'.  */
 static void
-tui_set_focus (char *arg, int from_tty)
+tui_set_focus (const char *arg, int from_tty)
 {
   if (arg != (char *) NULL)
     {
@@ -1078,7 +1078,7 @@ The window name specified must be valid and visible.\n"));
 }
 
 static void
-tui_set_focus_command (char *arg, int from_tty)
+tui_set_focus_command (const char *arg, int from_tty)
 {
   /* Make sure the curses mode is enabled.  */
   tui_enable ();
@@ -1109,7 +1109,7 @@ tui_all_windows_info (char *arg, int from_tty)
 
 
 static void
-tui_refresh_all_command (char *arg, int from_tty)
+tui_refresh_all_command (const char *arg, int from_tty)
 {
   /* Make sure the curses mode is enabled.  */
   tui_enable ();
@@ -1120,7 +1120,7 @@ tui_refresh_all_command (char *arg, int from_tty)
 
 /* Set the tab width of the specified window.  */
 static void
-tui_set_tab_width_command (char *arg, int from_tty)
+tui_set_tab_width_command (const char *arg, int from_tty)
 {
   /* Make sure the curses mode is enabled.  */
   tui_enable ();
@@ -1159,7 +1159,7 @@ tui_set_tab_width_command (char *arg, int from_tty)
 
 /* Set the height of the specified window.  */
 static void
-tui_set_win_height (char *arg, int from_tty)
+tui_set_win_height (const char *arg, int from_tty)
 {
   /* Make sure the curses mode is enabled.  */
   tui_enable ();
@@ -1240,7 +1240,7 @@ The window name specified must be valid and visible.\n"));
 
 /* Set the height of the specified window, with va_list.  */
 static void
-tui_set_win_height_command (char *arg, int from_tty)
+tui_set_win_height_command (const char *arg, int from_tty)
 {
   /* Make sure the curses mode is enabled.  */
   tui_enable ();
@@ -1646,7 +1646,7 @@ new_height_ok (struct tui_win_info *primary_win_info,
 
 
 static void
-parse_scrolling_args (char *arg, 
+parse_scrolling_args (const char *arg, 
 		      struct tui_win_info **win_to_scroll,
 		      int *num_to_scroll)
 {
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 441cbb8742..15810e4555 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -37,12 +37,6 @@
 #include "extension.h"
 #include "completer.h"
 
-static void ptype_command (char *, int);
-
-static void whatis_command (char *, int);
-
-static void whatis_exp (char *, int);
-
 const struct type_print_options type_print_raw_options =
 {
   1,				/* raw */
@@ -405,7 +399,7 @@ error_unknown_type (const char *sym_print_name)
    show is passed to type_print.  */
 
 static void
-whatis_exp (char *exp, int show)
+whatis_exp (const char *exp, int show)
 {
   struct value *val;
   struct cleanup *old_chain;
@@ -524,7 +518,7 @@ whatis_exp (char *exp, int show)
 }
 
 static void
-whatis_command (char *exp, int from_tty)
+whatis_command (const char *exp, int from_tty)
 {
   /* Most of the time users do not want to see all the fields
      in a structure.  If they do they can use the "ptype" command.
@@ -535,7 +529,7 @@ whatis_command (char *exp, int from_tty)
 /* TYPENAME is either the name of a type, or an expression.  */
 
 static void
-ptype_command (char *type_name, int from_tty)
+ptype_command (const char *type_name, int from_tty)
 {
   whatis_exp (type_name, 1);
 }
diff --git a/gdb/value.c b/gdb/value.c
index 7d0966c8fe..b2510200ec 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -2095,7 +2095,7 @@ static struct internalvar *internalvars;
 /* If the variable does not already exist create it and give it the
    value given.  If no value is given then the default is zero.  */
 static void
-init_if_undefined_command (char* args, int from_tty)
+init_if_undefined_command (const char* args, int from_tty)
 {
   struct internalvar* intvar;
 
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 58d7e11537..57cf909beb 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -859,7 +859,7 @@ windows_clear_solib (void)
 }
 
 static void
-signal_event_command (char *args, int from_tty)
+signal_event_command (const char *args, int from_tty)
 {
   uintptr_t event_id = 0;
   char *endargs = NULL;
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 3/8] Make set_cmd_cfunc private
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
                   ` (3 preceding siblings ...)
  2017-10-13 21:00 ` [RFA 2/8] Constify add_com_suppress_notification Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:20   ` Yao Qi
  2017-10-13 21:00 ` [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr Tom Tromey
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

set_cmd_cfunc is only used in cli-decode.c, and I don't think there is
a good reason to expose it directly.  So, this patch makes it private.

gdb/ChangeLog
2017-10-13  Tom Tromey  <tom@tromey.com>

	* command.h (set_cmd_cfunc): Don't declare.
	* cli/cli-decode.c (set_cmd_cfunc): Now static.
---
 gdb/ChangeLog        |  5 +++++
 gdb/cli/cli-decode.c |  4 ++--
 gdb/command.h        | 10 ----------
 3 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index f66bb2a3d8..76be7d33f4 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -106,7 +106,7 @@ do_cfunc (struct cmd_list_element *c, char *args, int from_tty)
   c->function.cfunc (args, from_tty);
 }
 
-void
+static void
 set_cmd_cfunc (struct cmd_list_element *cmd, cmd_cfunc_ftype *cfunc)
 {
   if (cfunc == NULL)
@@ -122,7 +122,7 @@ do_const_cfunc (struct cmd_list_element *c, char *args, int from_tty)
   c->function.const_cfunc (args, from_tty);
 }
 
-void
+static void
 set_cmd_cfunc (struct cmd_list_element *cmd, cmd_const_cfunc_ftype *cfunc)
 {
   if (cfunc == NULL)
diff --git a/gdb/command.h b/gdb/command.h
index c7922a0c3a..a99544563c 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -180,16 +180,6 @@ extern struct cmd_list_element *add_abbrev_prefix_cmd (const char *,
 						       struct cmd_list_element
 						       **);
 
-/* Set the commands corresponding callback.  */
-
-extern void set_cmd_cfunc (struct cmd_list_element *cmd,
-			   cmd_cfunc_ftype *cfunc);
-
-/* Const-correct variant of the above.  */
-
-extern void set_cmd_cfunc (struct cmd_list_element *cmd,
-			   cmd_const_cfunc_ftype *cfunc);
-
 typedef void cmd_sfunc_ftype (char *args, int from_tty,
 			      struct cmd_list_element *c);
 extern void set_cmd_sfunc (struct cmd_list_element *cmd,
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 1/8] Constify add_abbrev_prefix_cmd
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:02   ` Yao Qi
  2017-10-13 21:00 ` [RFA 6/8] Remove cleanup from backtrace_command Tom Tromey
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes add_abbrev_prefix_cmd to take a const-taking callback
function and then fixes the one caller.

gdb/ChangeLog
2017-10-13  Tom Tromey  <tom@tromey.com>

	* breakpoint.c (stop_command): Constify.
	* cli/cli-decode.c (struct cmd_list_element): Constify.
	* command.h (add_abbrev_prefix_cmd): Constify.
---
 gdb/ChangeLog        | 6 ++++++
 gdb/breakpoint.c     | 4 +---
 gdb/cli/cli-decode.c | 2 +-
 gdb/command.h        | 2 +-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 32ceea7c9b..3e7957f223 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -193,8 +193,6 @@ static void thbreak_command (char *, int);
 static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
 				    int count);
 
-static void stop_command (char *arg, int from_tty);
-
 static void free_bp_location (struct bp_location *loc);
 static void incref_bp_location (struct bp_location *loc);
 static void decref_bp_location (struct bp_location **loc);
@@ -9674,7 +9672,7 @@ thbreak_command (char *arg, int from_tty)
 }
 
 static void
-stop_command (char *arg, int from_tty)
+stop_command (const char *arg, int from_tty)
 {
   printf_filtered (_("Specify the type of breakpoint to set.\n\
 Usage: stop in <function | address>\n\
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 87ebed5f6e..5fc3187001 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -424,7 +424,7 @@ add_prefix_cmd (const char *name, enum command_class theclass,
 
 struct cmd_list_element *
 add_abbrev_prefix_cmd (const char *name, enum command_class theclass,
-		       cmd_cfunc_ftype *fun, const char *doc,
+		       cmd_const_cfunc_ftype *fun, const char *doc,
 		       struct cmd_list_element **prefixlist,
 		       const char *prefixname,
 		       int allow_unknown, struct cmd_list_element **list)
diff --git a/gdb/command.h b/gdb/command.h
index 32ee73af62..71ad71d953 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -173,7 +173,7 @@ extern struct cmd_list_element *add_prefix_cmd (const char *, enum command_class
 
 extern struct cmd_list_element *add_abbrev_prefix_cmd (const char *,
 						       enum command_class,
-						       cmd_cfunc_ftype *fun,
+						       cmd_const_cfunc_ftype *fun,
 						       const char *,
 						       struct cmd_list_element
 						       **, const char *, int,
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 5/8] Constify add_path and friends
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
                   ` (5 preceding siblings ...)
  2017-10-13 21:00 ` [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:35   ` Yao Qi
  2017-10-13 21:00 ` [RFA 7/8] Add truncate_repeat_arguments function Tom Tromey
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This constifies add_path, mod_path, and directory_switch.

gdb/ChangeLog
2017-10-13  Tom Tromey  <tom@tromey.com>

	* source.c (directory_switch, mod_path, add_path): Constify.
	* defs.h (add_path, mod_path, directory_switch): Constify.
	* mi/mi-cmd-env.c (env_mod_path): Constify.
---
 gdb/ChangeLog       | 6 ++++++
 gdb/defs.h          | 6 +++---
 gdb/mi/mi-cmd-env.c | 4 +---
 gdb/source.c        | 6 +++---
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/gdb/defs.h b/gdb/defs.h
index cf59602857..675c239af2 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -350,11 +350,11 @@ extern int openp (const char *, int, const char *, int, char **);
 
 extern int source_full_path_of (const char *, char **);
 
-extern void mod_path (char *, char **);
+extern void mod_path (const char *, char **);
 
-extern void add_path (char *, char **, int);
+extern void add_path (const char *, char **, int);
 
-extern void directory_switch (char *, int);
+extern void directory_switch (const char *, int);
 
 extern char *source_path;
 
diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c
index 0d08bb89a9..436462ac5f 100644
--- a/gdb/mi/mi-cmd-env.c
+++ b/gdb/mi/mi-cmd-env.c
@@ -32,8 +32,6 @@
 #include "top.h"
 #include <sys/stat.h>
 
-static void env_mod_path (char *dirname, char **which_path);
-
 static const char path_var_name[] = "PATH";
 static char *orig_path = NULL;
 
@@ -94,7 +92,7 @@ mi_cmd_env_cd (const char *command, char **argv, int argc)
 }
 
 static void
-env_mod_path (char *dirname, char **which_path)
+env_mod_path (const char *dirname, char **which_path)
 {
   if (dirname == 0 || dirname[0] == '\0')
     return;
diff --git a/gdb/source.c b/gdb/source.c
index aa672fde45..4ae2ba251b 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -444,7 +444,7 @@ directory_command (char *dirname, int from_tty)
    This will not be quoted so we must not treat spaces as separators.  */
 
 void
-directory_switch (char *dirname, int from_tty)
+directory_switch (const char *dirname, int from_tty)
 {
   add_path (dirname, &source_path, 0);
 }
@@ -452,7 +452,7 @@ directory_switch (char *dirname, int from_tty)
 /* Add zero or more directories to the front of an arbitrary path.  */
 
 void
-mod_path (char *dirname, char **which_path)
+mod_path (const char *dirname, char **which_path)
 {
   add_path (dirname, which_path, 1);
 }
@@ -464,7 +464,7 @@ mod_path (char *dirname, char **which_path)
    as space or tab.  */
 
 void
-add_path (char *dirname, char **which_path, int parse_separators)
+add_path (const char *dirname, char **which_path, int parse_separators)
 {
   char *old = *which_path;
   int prefix = 0;
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
                   ` (4 preceding siblings ...)
  2017-10-13 21:00 ` [RFA 3/8] Make set_cmd_cfunc private Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:33   ` Yao Qi
  2017-10-13 21:00 ` [RFA 5/8] Constify add_path and friends Tom Tromey
  2017-10-13 21:00 ` [RFA 7/8] Add truncate_repeat_arguments function Tom Tromey
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes strip_bg_char to return a unique_xmalloc_ptr and removes
several cleanups.

gdb/ChangeLog
2017-10-13  Tom Tromey  <tom@tromey.com>

	* infcmd.c (strip_bg_char): Return gdb::unique_xmalloc_ptr.
	(run_command_1, continue_command, step_1, jump_command)
	(signal_command, until_command, advance_command, finish_command)
	(attach_command): Update.
---
 gdb/ChangeLog |  7 +++++
 gdb/infcmd.c  | 84 ++++++++++++++++++-----------------------------------------
 2 files changed, 32 insertions(+), 59 deletions(-)

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 669631bdb4..125051fa63 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -421,7 +421,7 @@ construct_inferior_arguments (int argc, char **argv)
    NULL is returned.  *BG_CHAR_P is an output boolean that indicates
    whether the '&' character was found.  */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 strip_bg_char (const char *args, int *bg_char_p)
 {
   const char *p;
@@ -441,13 +441,14 @@ strip_bg_char (const char *args, int *bg_char_p)
 
       *bg_char_p = 1;
       if (p != args)
-	return savestring (args, p - args);
+	return gdb::unique_xmalloc_ptr<char>
+	  (savestring (args, p - args));
       else
-	return NULL;
+	return gdb::unique_xmalloc_ptr<char> (nullptr);
     }
 
   *bg_char_p = 0;
-  return xstrdup (args);
+  return gdb::unique_xmalloc_ptr<char> (xstrdup (args));
 }
 
 /* Common actions to take after creating any sort of inferior, by any
@@ -592,7 +593,6 @@ run_command_1 (char *args, int from_tty, enum run_how run_how)
   struct ui_out *uiout = current_uiout;
   struct target_ops *run_target;
   int async_exec;
-  struct cleanup *args_chain;
   CORE_ADDR pc;
 
   dont_repeat ();
@@ -616,8 +616,8 @@ run_command_1 (char *args, int from_tty, enum run_how run_how)
   reopen_exec_file ();
   reread_symbols ();
 
-  args = strip_bg_char (args, &async_exec);
-  args_chain = make_cleanup (xfree, args);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
+  args = stripped.get ();
 
   /* Do validation and preparation before possibly changing anything
      in the inferior.  */
@@ -663,9 +663,6 @@ run_command_1 (char *args, int from_tty, enum run_how run_how)
       uiout->flush ();
     }
 
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
-
   /* We call get_inferior_args() because we might need to compute
      the value now.  */
   run_target->to_create_inferior (run_target, exec_file,
@@ -850,13 +847,12 @@ continue_command (char *args, int from_tty)
 {
   int async_exec;
   int all_threads = 0;
-  struct cleanup *args_chain;
 
   ERROR_NO_INFERIOR;
 
   /* Find out whether we must run in the background.  */
-  args = strip_bg_char (args, &async_exec);
-  args_chain = make_cleanup (xfree, args);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
+  args = stripped.get ();
 
   if (args != NULL)
     {
@@ -918,9 +914,6 @@ continue_command (char *args, int from_tty)
 	}
     }
 
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
-
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
 
@@ -1065,7 +1058,6 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
 {
   int count;
   int async_exec;
-  struct cleanup *args_chain;
   struct thread_info *thr;
   struct step_command_fsm *step_sm;
 
@@ -1074,16 +1066,14 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
   ensure_valid_thread ();
   ensure_not_running ();
 
-  count_string = strip_bg_char (count_string, &async_exec);
-  args_chain = make_cleanup (xfree, count_string);
+  gdb::unique_xmalloc_ptr<char> stripped =
+    strip_bg_char (count_string, &async_exec);
+  count_string = stripped.get ();
 
   prepare_execution_command (&current_target, async_exec);
 
   count = count_string ? parse_and_eval_long (count_string) : 1;
 
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
-
   clear_proceed_status (1);
 
   /* Setup the execution command state machine to handle all the COUNT
@@ -1259,7 +1249,6 @@ jump_command (char *arg, int from_tty)
   struct symbol *fn;
   struct symbol *sfn;
   int async_exec;
-  struct cleanup *args_chain;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1267,8 +1256,8 @@ jump_command (char *arg, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  arg = strip_bg_char (arg, &async_exec);
-  args_chain = make_cleanup (xfree, arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
   prepare_execution_command (&current_target, async_exec);
 
@@ -1280,9 +1269,6 @@ jump_command (char *arg, int from_tty)
   if (sals.size () != 1)
     error (_("Unreasonable jump request"));
 
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
-
   symtab_and_line &sal = sals[0];
 
   if (sal.symtab == 0 && sal.pc == 0)
@@ -1341,7 +1327,6 @@ signal_command (char *signum_exp, int from_tty)
 {
   enum gdb_signal oursig;
   int async_exec;
-  struct cleanup *args_chain;
 
   dont_repeat ();		/* Too dangerous.  */
   ERROR_NO_INFERIOR;
@@ -1350,8 +1335,9 @@ signal_command (char *signum_exp, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  signum_exp = strip_bg_char (signum_exp, &async_exec);
-  args_chain = make_cleanup (xfree, signum_exp);
+  gdb::unique_xmalloc_ptr<char> stripped
+    = strip_bg_char (signum_exp, &async_exec);
+  signum_exp = stripped.get ();
 
   prepare_execution_command (&current_target, async_exec);
 
@@ -1374,8 +1360,6 @@ signal_command (char *signum_exp, int from_tty)
 	oursig = gdb_signal_from_command (num);
     }
 
-  do_cleanups (args_chain);
-
   /* Look for threads other than the current that this command ends up
      resuming too (due to schedlock off), and warn if they'll get a
      signal delivered.  "signal 0" is used to suppress a previous
@@ -1620,7 +1604,6 @@ static void
 until_command (char *arg, int from_tty)
 {
   int async_exec;
-  struct cleanup *args_chain;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1628,8 +1611,8 @@ until_command (char *arg, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  arg = strip_bg_char (arg, &async_exec);
-  args_chain = make_cleanup (xfree, arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
   prepare_execution_command (&current_target, async_exec);
 
@@ -1637,16 +1620,12 @@ until_command (char *arg, int from_tty)
     until_break_command (arg, from_tty, 0);
   else
     until_next_command (from_tty);
-
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
 }
 
 static void
 advance_command (char *arg, int from_tty)
 {
   int async_exec;
-  struct cleanup *args_chain;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1657,15 +1636,12 @@ advance_command (char *arg, int from_tty)
     error_no_arg (_("a location"));
 
   /* Find out whether we must run in the background.  */
-  arg = strip_bg_char (arg, &async_exec);
-  args_chain = make_cleanup (xfree, arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
   prepare_execution_command (&current_target, async_exec);
 
   until_break_command (arg, from_tty, 1);
-
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
 }
 \f
 /* Return the value of the result of a function at the end of a 'finish'
@@ -2031,7 +2007,6 @@ finish_command (char *arg, int from_tty)
 {
   struct frame_info *frame;
   int async_exec;
-  struct cleanup *args_chain;
   struct finish_command_fsm *sm;
   struct thread_info *tp;
 
@@ -2041,17 +2016,14 @@ finish_command (char *arg, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  arg = strip_bg_char (arg, &async_exec);
-  args_chain = make_cleanup (xfree, arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
   prepare_execution_command (&current_target, async_exec);
 
   if (arg)
     error (_("The \"finish\" command does not take any arguments."));
 
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
-
   frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
   if (frame == 0)
     error (_("\"finish\" not meaningful in the outermost frame."));
@@ -2846,7 +2818,6 @@ void
 attach_command (char *args, int from_tty)
 {
   int async_exec;
-  struct cleanup *args_chain;
   struct target_ops *attach_target;
   struct inferior *inferior = current_inferior ();
   enum attach_post_wait_mode mode;
@@ -2869,8 +2840,8 @@ attach_command (char *args, int from_tty)
      this function should probably be moved into target_pre_inferior.  */
   target_pre_inferior (from_tty);
 
-  args = strip_bg_char (args, &async_exec);
-  args_chain = make_cleanup (xfree, args);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
+  args = stripped.get ();
 
   attach_target = find_attach_target ();
 
@@ -2948,17 +2919,12 @@ attach_command (char *args, int from_tty)
       a->mode = mode;
       add_inferior_continuation (attach_command_continuation, a,
 				 attach_command_continuation_free_args);
-      /* Done with ARGS.  */
-      do_cleanups (args_chain);
 
       if (!target_is_async_p ())
 	mark_infrun_async_event_handler ();
       return;
     }
 
-  /* Done with ARGS.  */
-  do_cleanups (args_chain);
-
   attach_post_wait (args, from_tty, mode);
 }
 
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 2/8] Constify add_com_suppress_notification
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
                   ` (2 preceding siblings ...)
  2017-10-13 21:00 ` [RFA 8/8] Constify add_com Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:03   ` Yao Qi
  2017-10-13 21:00 ` [RFA 3/8] Make set_cmd_cfunc private Tom Tromey
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This constifies add_com_suppress_notification and fixes the one
caller.

gdb/ChangeLog
2017-10-13  Tom Tromey  <tom@tromey.com>

	* stack.c (select_frame_command): Constify.
	* cli/cli-decode.c (struct cmd_list_element): Constify.
	* command.h (add_com_suppress_notification): Constify.
---
 gdb/ChangeLog        | 6 ++++++
 gdb/cli/cli-decode.c | 2 +-
 gdb/command.h        | 2 +-
 gdb/stack.c          | 2 +-
 gdb/stack.h          | 2 +-
 5 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 5fc3187001..f66bb2a3d8 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -950,7 +950,7 @@ add_com_alias (const char *name, const char *oldname, enum command_class theclas
 
 struct cmd_list_element *
 add_com_suppress_notification (const char *name, enum command_class theclass,
-			       cmd_cfunc_ftype *fun, const char *doc,
+			       cmd_const_cfunc_ftype *fun, const char *doc,
 			       int *suppress_notification)
 {
   struct cmd_list_element *element;
diff --git a/gdb/command.h b/gdb/command.h
index 71ad71d953..c7922a0c3a 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -274,7 +274,7 @@ extern struct cmd_list_element *add_com_alias (const char *, const char *,
 
 extern struct cmd_list_element *add_com_suppress_notification
 		       (const char *name, enum command_class theclass,
-			cmd_cfunc_ftype *fun, const char *doc,
+			cmd_const_cfunc_ftype *fun, const char *doc,
 			int *supress_notification);
 
 extern struct cmd_list_element *add_info (const char *,
diff --git a/gdb/stack.c b/gdb/stack.c
index 4e40e32283..4de3675bc5 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2270,7 +2270,7 @@ find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
    expressions.  */
 
 void
-select_frame_command (char *level_exp, int from_tty)
+select_frame_command (const char *level_exp, int from_tty)
 {
   struct frame_info *prev_frame = get_selected_frame_if_set ();
 
diff --git a/gdb/stack.h b/gdb/stack.h
index 3379318cca..563229fea4 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -20,7 +20,7 @@
 #ifndef STACK_H
 #define STACK_H
 
-void select_frame_command (char *level_exp, int from_tty);
+void select_frame_command (const char *level_exp, int from_tty);
 
 gdb::unique_xmalloc_ptr<char> find_frame_funname (struct frame_info *frame,
 						  enum language *funlang,
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 0/8] Constify many commands
@ 2017-10-13 21:00 Tom Tromey
  2017-10-13 21:00 ` [RFA 1/8] Constify add_abbrev_prefix_cmd Tom Tromey
                   ` (7 more replies)
  0 siblings, 8 replies; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches

This series changes add_abbrev_prefix_cmd,
add_com_suppress_notification, and add_com to take
cmd_const_cfunc_ftype rather than cmd_cfunc_ttype; then cleans up all
the users.

Some cleanups are removed as well, because changes were already needed
in some areas where moving to the cleanup-free style was more
convenient.

This probably overlaps a bit with some of my other breakpoint patches.
Those are still waiting for feedback.

Most of the patches are straightforward.

Patch #7 adds a new function to deal with how "list" and "x" work.

Patch #8 removes some non-const overloads that were added in a
previous series; but also adds some new ones.  The eventual conversion
of add_info should remove these.

Regression tested by the buildbot.  I also built (but did not regtest)
each patch (that is, each spot in the series at least compiles).

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFA 6/8] Remove cleanup from backtrace_command
  2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
  2017-10-13 21:00 ` [RFA 1/8] Constify add_abbrev_prefix_cmd Tom Tromey
@ 2017-10-13 21:00 ` Tom Tromey
  2017-10-16  9:46   ` Yao Qi
  2017-10-13 21:00 ` [RFA 8/8] Constify add_com Tom Tromey
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-13 21:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This removes a cleanup from backtrace_command, replacing it with
std::string.  This patch temporarily changes backtrace_command so that
the parameter is named "args_in" and is immediately constified; this
is fixed again in the constification patch.

gdb/ChangeLog
2017-10-13  Tom Tromey  <tom@tromey.com>

	* stack.c (backtrace_command): Use std::string.
	(backtrace_command_1): Make "count_exp" const.
---
 gdb/ChangeLog |  5 +++++
 gdb/stack.c   | 17 +++++++----------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/gdb/stack.c b/gdb/stack.c
index 4de3675bc5..63c3d837de 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1692,7 +1692,7 @@ info_frame_command (char *addr_exp, int from_tty)
    frames.  */
 
 static void
-backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
+backtrace_command_1 (const char *count_exp, int show_locals, int no_filters,
 		     int from_tty)
 {
   struct frame_info *fi;
@@ -1844,12 +1844,13 @@ backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
 }
 
 static void
-backtrace_command (char *arg, int from_tty)
+backtrace_command (char *arg_in, int from_tty)
 {
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   int fulltrace_arg = -1, arglen = 0, argc = 0, no_filters  = -1;
   int user_arg = 0;
+  const char *arg = arg_in;
 
+  std::string reconstructed_arg;
   if (arg)
     {
       char **argv;
@@ -1884,17 +1885,15 @@ backtrace_command (char *arg, int from_tty)
 	{
 	  if (arglen > 0)
 	    {
-	      arg = (char *) xmalloc (arglen + 1);
-	      make_cleanup (xfree, arg);
-	      arg[0] = 0;
 	      for (i = 0; i < argc; i++)
 		{
 		  if (i != fulltrace_arg && i != no_filters)
 		    {
-		      strcat (arg, argv[i]);
-		      strcat (arg, " ");
+		      reconstructed_arg += argv[i];
+		      reconstructed_arg += " ";
 		    }
 		}
+	      arg = reconstructed_arg.c_str ();
 	    }
 	  else
 	    arg = NULL;
@@ -1903,8 +1902,6 @@ backtrace_command (char *arg, int from_tty)
 
   backtrace_command_1 (arg, fulltrace_arg >= 0 /* show_locals */,
 		       no_filters >= 0 /* no frame-filters */, from_tty);
-
-  do_cleanups (old_chain);
 }
 
 /* Iterate over the local variables of a block B, calling CB with
-- 
2.13.6

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-13 21:00 ` [RFA 7/8] Add truncate_repeat_arguments function Tom Tromey
@ 2017-10-14  4:49   ` Tom Tromey
  2017-10-16  3:07     ` Tom Tromey
  0 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-14  4:49 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

Tom> The "x" and "list" commands have special repetition behavior:
Tom> repeating the command doesn't re-run it with the same arguments, but
Tom> rather advances (through memory or the program listing).

I found a couple more functions that do something similar, but not
purely truncating their arguments.  Both show_commands and show_values
do:

  if (from_tty && num_exp)
    {
      num_exp[0] = '+';
      num_exp[1] = '\0';
    }

I'm rewriting this patch to allow those uses as well... so you might as
well skip this patch if you're reviewing.  However, I think the other
patches in the series are still ok to read.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-14  4:49   ` Tom Tromey
@ 2017-10-16  3:07     ` Tom Tromey
  2017-10-16  9:53       ` Yao Qi
  0 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-16  3:07 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

Tom> I'm rewriting this patch to allow those uses as well... so you might as
Tom> well skip this patch if you're reviewing.  However, I think the other
Tom> patches in the series are still ok to read.

Here is a new version of this patch, that addresses the additional
commands I ran across.

Tom

commit 323b5cdc6429d865ddf091913c8b78bb521e20f3
Author: Tom Tromey <tom@tromey.com>
Date:   Thu Oct 12 08:27:21 2017 -0600

    Add set_repeat_arguments function
    
    The "x", "list", and "show commands" commands have special repetition
    behavior: repeating the command doesn't re-run it with the same
    arguments
    
    This is currently implemented by modifying the passed-in argument; but
    that won't work properly with const arguments (and seems pretty
    obscure besides).
    
    This patch adds a new "set_repeat_arguments" function and changes the
    relevant places to call it.
    
    ChangeLog
    2017-10-15  Tom Tromey  <tom@tromey.com>
    
            * printcmd.c (x_command): Call set_repeat_arguments.
            * cli/cli-cmds.c (list_command): Call set_repeat_arguments.
            * top.c (repeat_arguments): New global.
            (set_repeat_arguments): New function.
            (execute_command): Handle repeat_arguments.
            (show_commands): Calls set_repeat_arguments.
            * command.h (set_repeat_arguments): Declare.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 91f30ae683..15e8984544 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
 2017-10-15  Tom Tromey  <tom@tromey.com>
 
+	* printcmd.c (x_command): Call set_repeat_arguments.
+	* cli/cli-cmds.c (list_command): Call set_repeat_arguments.
+	* top.c (repeat_arguments): New global.
+	(set_repeat_arguments): New function.
+	(execute_command): Handle repeat_arguments.
+	(show_commands): Calls set_repeat_arguments.
+	* command.h (set_repeat_arguments): Declare.
+
+2017-10-15  Tom Tromey  <tom@tromey.com>
+
 	* stack.c (backtrace_command): Use std::string.
 	(backtrace_command_1): Make "count_exp" const.
 
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index a1c308a38d..a8edb1341f 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1082,7 +1082,7 @@ list_command (char *arg, int from_tty)
      turn it into the no-arg variant.  */
 
   if (from_tty)
-    *arg = 0;
+    set_repeat_arguments ("");
 
   if (dummy_beg && sal_end.symtab == 0)
     error (_("No default source file yet.  Do \"help list\"."));
diff --git a/gdb/command.h b/gdb/command.h
index a99544563c..63c76589c8 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -445,6 +445,11 @@ extern void dont_repeat (void);
 
 extern scoped_restore_tmpl<int> prevent_dont_repeat (void);
 
+/* Set the arguments that will be passed if the current command is
+   repeated.  Note that the passed-in string must be a constant.  */
+
+extern void set_repeat_arguments (const char *args);
+
 /* Used to mark commands that don't do anything.  If we just leave the
    function field NULL, the command is interpreted as a help topic, or
    as a class of commands.  */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 77a05e5d9f..343c9049c5 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1636,7 +1636,7 @@ x_command (char *exp, int from_tty)
          repeated with Newline.  But don't clobber a user-defined
          command's definition.  */
       if (from_tty)
-	*exp = 0;
+	set_repeat_arguments ("");
       val = evaluate_expression (expr.get ());
       if (TYPE_IS_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
diff --git a/gdb/top.c b/gdb/top.c
index 3b3bbee4ac..5a6f99995a 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -528,6 +528,19 @@ maybe_wait_sync_command_done (int was_sync)
     wait_sync_command_done ();
 }
 
+/* If not NULL, the arguments that should be passed if the current
+   command is repeated.  */
+
+static const char *repeat_arguments;
+
+/* See command.h.  */
+
+void
+set_repeat_arguments (const char *args)
+{
+  repeat_arguments = args;
+}
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -571,6 +584,10 @@ execute_command (char *p, int from_tty)
       c = lookup_cmd (&cmd, cmdlist, "", 0, 1);
       p = (char *) cmd;
 
+      scoped_restore save_repeat_args
+	= make_scoped_restore (&repeat_arguments, nullptr);
+      char *args_pointer = p;
+
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;
 
@@ -619,6 +636,11 @@ execute_command (char *p, int from_tty)
       /* If this command has been post-hooked, run the hook last.  */
       execute_cmd_post_hook (c);
 
+      if (repeat_arguments != NULL)
+	{
+	  gdb_assert (strlen (args_pointer) >= strlen (repeat_arguments));
+	  strcpy (args_pointer, repeat_arguments);
+	}
     }
 
   check_frame_language_change ();
@@ -1675,7 +1697,7 @@ dont_repeat_command (char *ignored, int from_tty)
 /* Number of commands to print in each call to show_commands.  */
 #define Hist_print 10
 void
-show_commands (char *args, int from_tty)
+show_commands (const char *args, int from_tty)
 {
   /* Index for history commands.  Relative to history_base.  */
   int offset;
@@ -1729,10 +1751,7 @@ show_commands (char *args, int from_tty)
      "show commands +" does.  This is unnecessary if arg is null,
      because "show commands +" is not useful after "show commands".  */
   if (from_tty && args)
-    {
-      args[0] = '+';
-      args[1] = '\0';
-    }
+    set_repeat_arguments ("+");
 }
 
 /* Update the size of our command history file to HISTORY_SIZE.
diff --git a/gdb/value.c b/gdb/value.c
index 7d0966c8fe..6af9458f43 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -2005,10 +2005,7 @@ show_values (char *num_exp, int from_tty)
      "show values +".  If num_exp is null, this is unnecessary, since
      "show values +" is not useful after "show values".  */
   if (from_tty && num_exp)
-    {
-      num_exp[0] = '+';
-      num_exp[1] = '\0';
-    }
+    set_repeat_arguments ("+");
 }
 \f
 enum internalvar_kind

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 1/8] Constify add_abbrev_prefix_cmd
  2017-10-13 21:00 ` [RFA 1/8] Constify add_abbrev_prefix_cmd Tom Tromey
@ 2017-10-16  9:02   ` Yao Qi
  2017-10-16 15:54     ` Tom Tromey
  0 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:02 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> This changes add_abbrev_prefix_cmd to take a const-taking callback
> function and then fixes the one caller.
>
> gdb/ChangeLog
> 2017-10-13  Tom Tromey  <tom@tromey.com>
>
> 	* breakpoint.c (stop_command): Constify.
> 	* cli/cli-decode.c (struct cmd_list_element): Constify.
> 	* command.h (add_abbrev_prefix_cmd): Constify.

As you said in cover letter, breakpoint.c:stop_command needs update as
well.  You can pull the stop_command change in this patch, and it looks
good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 2/8] Constify add_com_suppress_notification
  2017-10-13 21:00 ` [RFA 2/8] Constify add_com_suppress_notification Tom Tromey
@ 2017-10-16  9:03   ` Yao Qi
  2017-10-16 15:55     ` Tom Tromey
  0 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:03 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> gdb/ChangeLog
> 2017-10-13  Tom Tromey  <tom@tromey.com>
>
> 	* stack.c (select_frame_command): Constify.
> 	* cli/cli-decode.c (struct cmd_list_element): Constify.

s/struct cmd_list_element/add_com_suppress_notification/ ?

> 	* command.h (add_com_suppress_notification): Constify.

Patch is good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 3/8] Make set_cmd_cfunc private
  2017-10-13 21:00 ` [RFA 3/8] Make set_cmd_cfunc private Tom Tromey
@ 2017-10-16  9:20   ` Yao Qi
  0 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:20 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> gdb/ChangeLog
> 2017-10-13  Tom Tromey  <tom@tromey.com>
>
> 	* command.h (set_cmd_cfunc): Don't declare.
> 	* cli/cli-decode.c (set_cmd_cfunc): Now static.

Patch is good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-13 21:00 ` [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr Tom Tromey
@ 2017-10-16  9:33   ` Yao Qi
  2017-10-16 18:37     ` Simon Marchi
  2017-10-18  9:37     ` Pedro Alves
  0 siblings, 2 replies; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:33 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> -  args = strip_bg_char (args, &async_exec);
> -  args_chain = make_cleanup (xfree, args);
> +  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
> +  args = stripped.get ();
>  
>    /* Do validation and preparation before possibly changing anything
>       in the inferior.  */
> @@ -663,9 +663,6 @@ run_command_1 (char *args, int from_tty, enum run_how run_how)
>        uiout->flush ();
>      }
>  
> -  /* Done with ARGS.  */
> -  do_cleanups (args_chain);
> -

My concern is that we may leak something if some cleanups are registered
to the cleanup chain in the callees between make_cleanup and do_cleanups
here.  However, I am not sure how to detect that.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 5/8] Constify add_path and friends
  2017-10-13 21:00 ` [RFA 5/8] Constify add_path and friends Tom Tromey
@ 2017-10-16  9:35   ` Yao Qi
  0 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:35 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> This constifies add_path, mod_path, and directory_switch.
>
> gdb/ChangeLog
> 2017-10-13  Tom Tromey  <tom@tromey.com>
>
> 	* source.c (directory_switch, mod_path, add_path): Constify.
> 	* defs.h (add_path, mod_path, directory_switch): Constify.
> 	* mi/mi-cmd-env.c (env_mod_path): Constify.

Looks good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 6/8] Remove cleanup from backtrace_command
  2017-10-13 21:00 ` [RFA 6/8] Remove cleanup from backtrace_command Tom Tromey
@ 2017-10-16  9:46   ` Yao Qi
  0 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:46 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> gdb/ChangeLog
> 2017-10-13  Tom Tromey  <tom@tromey.com>
>
> 	* stack.c (backtrace_command): Use std::string.
> 	(backtrace_command_1): Make "count_exp" const.

Patch is good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-16  3:07     ` Tom Tromey
@ 2017-10-16  9:53       ` Yao Qi
  2017-10-18  3:48         ` Tom Tromey
  0 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:53 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> +/* If not NULL, the arguments that should be passed if the current
> +   command is repeated.  */
> +
> +static const char *repeat_arguments;
> +
> +/* See command.h.  */
> +
> +void
> +set_repeat_arguments (const char *args)
> +{
> +  repeat_arguments = args;
> +}

This global variable worries me a little bit.  Is it possible that
different part of GDB request to execute the repeatable commands?  For
example, CLI and MI issues command, or different UIs issue command.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 8/8] Constify add_com
  2017-10-13 21:00 ` [RFA 8/8] Constify add_com Tom Tromey
@ 2017-10-16  9:59   ` Yao Qi
  0 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2017-10-16  9:59 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey <tom@tromey.com> writes:

> 2017-10-13  Tom Tromey  <tom@tromey.com>
>
> 	* solib.h (no_shared_libraries): Constify.
> 	* frame.h (return_command): Constify.
> 	* cli/cli-cmds.h (quit_command): Constify.
> 	* top.h (quit_command, execute_command): Constify.
> 	* target.h (flash_erase_command): Constify.
> 	* inferior.h (set_inferior_args, attach_command): Constify.
> 	* tracepoint.h (start_tracing, stop_tracing): Constify.
> 	* breakpoint.h (break_command, tbreak_command)
> 	(hbreak_command_wrapper, thbreak_command_wrapper)
> 	(rbreak_command_wrapper, watch_command_wrapper)
> 	(awatch_command_wrapper, rwatch_command_wrapper)
> 	(get_tracepoint_by_number): Constify.
> 	* symtab.c (info_variables_command, rbreak_command)
> 	(symtab_symbol_info): Constify.
> 	(info_variables_command): Add non-const overload.
> 	* top.c (dont_repeat_command): Constify.
> 	* breakpoint.c (ignore_command, commands_command)
> 	(condition_command, tbreak_command, hbreak_command)
> 	(thbreak_command, clear_command, break_command)
> 	(info_breakpoints_command, watch_command, rwatch_command)
> 	(awatch_command, trace_command, ftrace_command, strace_command)
> 	(trace_pass_command, break_range_command, dprintf_command)
> 	(agent_printf_command, get_tracepoint_by_number)
> 	(watch_maybe_just_location, trace_pass_command): Constify.
> 	(info_breakpoints_command): Add non-const overload.
> 	* tracefile.c (tsave_command): Constify.
> 	* infcmd.c (attach_command, disconnect_command, signal_command)
> 	(queue_signal_command, stepi_command, nexti_command)
> 	(finish_command, next_command, step_command, until_command)
> 	(advance_command, jump_command, continue_command, run_command)
> 	(start_command, starti_command, interrupt_command)
> 	(run_command_1, set_inferior_args, step_1): Constify.
> 	* inferior.c (add_inferior_command, remove_inferior_command)
> 	(clone_inferior_command): Constify.
> 	* linux-fork.c (checkpoint_command, restart_command): Constify.
> 	* windows-nat.c (signal_event_command): Constify.
> 	* guile/guile.c (guile_repl_command, guile_command): Constify.
> 	* printcmd.c (x_command, display_command, printf_command)
> 	(output_command, set_command, call_command, print_command)
> 	(eval_command): Constify.
> 	(non_const_set_command): Remove.
> 	(_initialize_printcmd): Update.
> 	* source.c (forward_search_command, reverse_search_command):
> 	Constify.
> 	* jit.c (jit_reader_load_command, jit_reader_unload_command):
> 	Constify.
> 	* infrun.c (handle_command): Constify.
> 	* memattr.c (mem_command): Constify.
> 	* stack.c (return_command, up_command, up_silently_command)
> 	(down_command, down_silently_command, frame_command)
> 	(backtrace_command, func_command, backtrace_command_1): Constify.
> 	(backtrace_command): Add non-const overload.
> 	* remote-sim.c (simulator_command): Constify.
> 	* exec.c (set_section_command): Constify.
> 	* tracepoint.c (tdump_command, trace_variable_command)
> 	(tstatus_command, tstop_command, tstart_command)
> 	(end_actions_pseudocommand, while_stepping_pseudocommand)
> 	(collect_pseudocommand, teval_pseudocommand, actions_command)
> 	(start_tracing, stop_tracing): Constify.
> 	* value.c (init_if_undefined_command): Constify.
> 	* tui/tui-stack.c (tui_update_command): Constify.
> 	* tui/tui-win.c (tui_refresh_all_command)
> 	(tui_set_tab_width_command, tui_set_win_height_command)
> 	(tui_set_focus_command, tui_scroll_forward_command)
> 	(tui_scroll_backward_command, tui_scroll_left_command)
> 	(tui_scroll_right_command, parse_scrolling_args, tui_set_focus)
> 	(tui_set_win_height): Constify.
> 	* tui/tui-layout.c (tui_layout_command): Constify.
> 	* procfs.c (proc_trace_syscalls, proc_trace_sysentry_cmd)
> 	(proc_trace_sysexit_cmd, proc_untrace_sysentry_cmd)
> 	(proc_untrace_sysexit_cmd): Constify.
> 	* remote.c (threadlist_test_cmd, threadinfo_test_cmd)
> 	(threadset_test_cmd, threadlist_update_test_cmd)
> 	(threadalive_test): Constify.
> 	* objc-lang.c (print_object_command): Constify.
> 	* command.h (add_com): Constify.
> 	* cli/cli-dump.c (restore_command): Constify.
> 	* cli/cli-cmds.c (pwd_command, echo_command, quit_command)
> 	(help_command, complete_command, shell_command, edit_command)
> 	(list_command, disassemble_command, make_command)
> 	(apropos_command, alias_command): Constify.
> 	* cli/cli-script.c (document_command, define_command)
> 	(while_command, if_command, validate_comname): Constify.
> 	* cli/cli-decode.c (struct cmd_list_element): Change type of
> 	"fun".
> 	* target.c (do_monitor_command, flash_erase_command): Constify.
> 	* regcache.c (reg_flush_command): Constify.
> 	* reverse.c (reverse_step, reverse_next, reverse_stepi)
> 	(reverse_nexti, reverse_continue, reverse_finish)
> 	(save_bookmark_command, goto_bookmark_command)
> 	(exec_reverse_once): Constify.
> 	* python/python.c (python_interactive_command, python_command):
> 	Constify.
> 	* typeprint.c (ptype_command, whatis_command, whatis_exp):
> 	Constify.
> 	* solib.c (sharedlibrary_command, no_shared_libraries): Constify.
> 	* gcore.c (gcore_command): Constify.

Hi Tom,
thanks for doing this.  Patch is good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 1/8] Constify add_abbrev_prefix_cmd
  2017-10-16  9:02   ` Yao Qi
@ 2017-10-16 15:54     ` Tom Tromey
  2017-10-16 20:23       ` Yao Qi
  0 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2017-10-16 15:54 UTC (permalink / raw)
  To: Yao Qi; +Cc: Tom Tromey, gdb-patches

>>>>> "Yao" == Yao Qi <qiyaoltc@gmail.com> writes:

Yao> Tom Tromey <tom@tromey.com> writes:
>> This changes add_abbrev_prefix_cmd to take a const-taking callback
>> function and then fixes the one caller.
>> 
>> gdb/ChangeLog
>> 2017-10-13  Tom Tromey  <tom@tromey.com>
>> 
>> * breakpoint.c (stop_command): Constify.
>> * cli/cli-decode.c (struct cmd_list_element): Constify.
>> * command.h (add_abbrev_prefix_cmd): Constify.

Yao> As you said in cover letter, breakpoint.c:stop_command needs update as
Yao> well.  You can pull the stop_command change in this patch, and it looks
Yao> good to me.

I'm sorry -- I don't understand what I ought to do here.
I think this patch does include a change to stop_command.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 2/8] Constify add_com_suppress_notification
  2017-10-16  9:03   ` Yao Qi
@ 2017-10-16 15:55     ` Tom Tromey
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Tromey @ 2017-10-16 15:55 UTC (permalink / raw)
  To: Yao Qi; +Cc: Tom Tromey, gdb-patches

>>>>> "Yao" == Yao Qi <qiyaoltc@gmail.com> writes:

Yao> Tom Tromey <tom@tromey.com> writes:
>> gdb/ChangeLog
>> 2017-10-13  Tom Tromey  <tom@tromey.com>
>> 
>> * stack.c (select_frame_command): Constify.
>> * cli/cli-decode.c (struct cmd_list_element): Constify.

Yao> s/struct cmd_list_element/add_com_suppress_notification/ ?

Yes, thanks.  I've fixed this locally.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-16  9:33   ` Yao Qi
@ 2017-10-16 18:37     ` Simon Marchi
  2017-10-17 11:05       ` Yao Qi
  2017-10-18  9:37     ` Pedro Alves
  1 sibling, 1 reply; 30+ messages in thread
From: Simon Marchi @ 2017-10-16 18:37 UTC (permalink / raw)
  To: Yao Qi; +Cc: Tom Tromey, gdb-patches

On 2017-10-16 05:33, Yao Qi wrote:
> Tom Tromey <tom@tromey.com> writes:
> 
>> -  args = strip_bg_char (args, &async_exec);
>> -  args_chain = make_cleanup (xfree, args);
>> +  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, 
>> &async_exec);
>> +  args = stripped.get ();
>> 
>>    /* Do validation and preparation before possibly changing anything
>>       in the inferior.  */
>> @@ -663,9 +663,6 @@ run_command_1 (char *args, int from_tty, enum 
>> run_how run_how)
>>        uiout->flush ();
>>      }
>> 
>> -  /* Done with ARGS.  */
>> -  do_cleanups (args_chain);
>> -
> 
> My concern is that we may leak something if some cleanups are 
> registered
> to the cleanup chain in the callees between make_cleanup and 
> do_cleanups
> here.  However, I am not sure how to detect that.

When reviewing previous cleanup-removal patches, I tried to look for 
something that hinted like it would install and return a cleanup, but 
it's obviously not a 100% reliable method.  What you could do is 
temporarily add

   struct cleanup *before = cleanup_chain;

at the beginning of the function, and

   gdb_assert (cleanup_chain == before);

at the end.

Simon

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 1/8] Constify add_abbrev_prefix_cmd
  2017-10-16 15:54     ` Tom Tromey
@ 2017-10-16 20:23       ` Yao Qi
  0 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2017-10-16 20:23 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On Mon, Oct 16, 2017 at 4:54 PM, Tom Tromey <tom@tromey.com> wrote:
>>>>>> "Yao" == Yao Qi <qiyaoltc@gmail.com> writes:
>
> I'm sorry -- I don't understand what I ought to do here.
> I think this patch does include a change to stop_command.
>

Oh, yes, a change to stop_command was there.  I wonder why I didn't
see it in gnus.  Sorry about the confusion.  Patch is good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-16 18:37     ` Simon Marchi
@ 2017-10-17 11:05       ` Yao Qi
  2017-10-18  3:32         ` Tom Tromey
  0 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2017-10-17 11:05 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

Simon Marchi <simon.marchi@polymtl.ca> writes:

> When reviewing previous cleanup-removal patches, I tried to look for
> something that hinted like it would install and return a cleanup, but
> it's obviously not a 100% reliable method.  What you could do is
> temporarily add
>
>   struct cleanup *before = cleanup_chain;
>
> at the beginning of the function, and
>
>   gdb_assert (cleanup_chain == before);
>
> at the end.

Yes, that is one approach I though of, but it needs changing code.  I am
looking at running gdb testsuite with valgrind, but there are too many
warnings on leak, so it is not that useful to find new leaks.

The patch is the good direction to go, so I don't want to block it.
Meanwhile, I am still looking at memory leaks reported by valgrind.

Tom, if you don't hear me by Friday this week, feel free to commit it.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-17 11:05       ` Yao Qi
@ 2017-10-18  3:32         ` Tom Tromey
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Tromey @ 2017-10-18  3:32 UTC (permalink / raw)
  To: Yao Qi; +Cc: Simon Marchi, Tom Tromey, gdb-patches

>>>>> "Yao" == Yao Qi <qiyaoltc@gmail.com> writes:

Yao> Yes, that is one approach I though of, but it needs changing code.  I am
Yao> looking at running gdb testsuite with valgrind, but there are too many
Yao> warnings on leak, so it is not that useful to find new leaks.

That sounds pretty bad.
A valgrind or ASAN buildbot would be good...

Yao> The patch is the good direction to go, so I don't want to block it.
Yao> Meanwhile, I am still looking at memory leaks reported by valgrind.

I don't know if the cleanup checker still works, but that would be one
route.  I don't believe there are all that many dangling cleanups any
more, but I do agree that it's hard to know.

It's maybe worth pointing out that, at least in the past (I didn't look
recently), commands were always run with a cleanup installed, and this
cleanup was run after the command returned.  So, before the cleanup
checker work, it was normal to see dangling cleanups in command
implementations.  If this still exists then I think it would reduce the
risk of changing strip_bg_char.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-16  9:53       ` Yao Qi
@ 2017-10-18  3:48         ` Tom Tromey
  2017-11-06 16:38           ` Tom Tromey
  2017-11-07 14:35           ` Pedro Alves
  0 siblings, 2 replies; 30+ messages in thread
From: Tom Tromey @ 2017-10-18  3:48 UTC (permalink / raw)
  To: Yao Qi; +Cc: Tom Tromey, gdb-patches

>>>>> "Yao" == Yao Qi <qiyaoltc@gmail.com> writes:

Yao> This global variable worries me a little bit.  Is it possible that
Yao> different part of GDB request to execute the repeatable commands?  For
Yao> example, CLI and MI issues command, or different UIs issue command.

It's hard to reason about, I agree.

I think commands can either be run via "cmd_func", or by calling the
command function directly.

Direct calls can be directly audited -- and none of the callers of the
new set_repeat_arguments function are called this way.

There are also not many calls to cmd_func; and at least when I look at
these (I encourage you to check my work), I think only execute_command
can possibly call a command that calls set_repeat_arguments.

Since execute_command uses a scoped_restore to save and restore this
global, I think this must be ok.

It does seem a bit fragile.  For example, I'd recommend not adding new
callers of set_repeat_arguments.  I'm open to suggestions for another
way to approach this.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-16  9:33   ` Yao Qi
  2017-10-16 18:37     ` Simon Marchi
@ 2017-10-18  9:37     ` Pedro Alves
  2017-11-06 16:33       ` Tom Tromey
  1 sibling, 1 reply; 30+ messages in thread
From: Pedro Alves @ 2017-10-18  9:37 UTC (permalink / raw)
  To: Yao Qi, Tom Tromey; +Cc: gdb-patches

On 10/16/2017 10:33 AM, Yao Qi wrote:
> Tom Tromey <tom@tromey.com> writes:
> 
>> -  args = strip_bg_char (args, &async_exec);
>> -  args_chain = make_cleanup (xfree, args);
>> +  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
>> +  args = stripped.get ();
>>  
>>    /* Do validation and preparation before possibly changing anything
>>       in the inferior.  */
>> @@ -663,9 +663,6 @@ run_command_1 (char *args, int from_tty, enum run_how run_how)
>>        uiout->flush ();
>>      }
>>  
>> -  /* Done with ARGS.  */
>> -  do_cleanups (args_chain);
>> -
> 
> My concern is that we may leak something if some cleanups are registered
> to the cleanup chain in the callees between make_cleanup and do_cleanups
> here.  However, I am not sure how to detect that.

Personally, I'm not as much worried about cleanup leaks (because there's
a TRY/CATCH at the top of the event loop, and TRY detects dangling
cleanups via restore_my_cleanups), as about some cleanup installed in
that chain, whose do_cleanups call must be run at the particular point
it's being run.

I've touched and moved around these cleanups in the past, and what
thought might be worth a second look was whether prepare_execute_command
or something around it was installing a cleanup.  It isn't, and when I went
looking a bit deeper I found 8bc2fe488957, where I had written:

~~~
    attach_command installs a cleanup to re-enable stdin, but that's not
    necessary, as per the comment in prepare_execution_command.  In any
    case, if someday it turns out necessary, we have a single place to
    install it now.
~~~

I think we're good.  Found one nit:

> @@ -1074,16 +1066,14 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
...
> -  count_string = strip_bg_char (count_string, &async_exec);
> -  args_chain = make_cleanup (xfree, count_string);
> +  gdb::unique_xmalloc_ptr<char> stripped =
> +    strip_bg_char (count_string, &async_exec);

= on next line.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr
  2017-10-18  9:37     ` Pedro Alves
@ 2017-11-06 16:33       ` Tom Tromey
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Tromey @ 2017-11-06 16:33 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

[...]
Pedro> I think we're good.  Found one nit:

Thanks.

>> +  gdb::unique_xmalloc_ptr<char> stripped =
>> +    strip_bg_char (count_string, &async_exec);

Pedro> = on next line.

I finally got around to fixing this locally.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-18  3:48         ` Tom Tromey
@ 2017-11-06 16:38           ` Tom Tromey
  2017-11-07 14:35           ` Pedro Alves
  1 sibling, 0 replies; 30+ messages in thread
From: Tom Tromey @ 2017-11-06 16:38 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Yao Qi, gdb-patches

Yao> This global variable worries me a little bit.  Is it possible that
Yao> different part of GDB request to execute the repeatable commands?  For
Yao> example, CLI and MI issues command, or different UIs issue command.

Tom> It's hard to reason about, I agree.
[...]

I think this is the last remaining constification patch of mine that
requires approval.  There weren't any concrete suggestions coming from
this exchange; but if you have one I am happy to try to implement it.

thanks,
Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFA 7/8] Add truncate_repeat_arguments function
  2017-10-18  3:48         ` Tom Tromey
  2017-11-06 16:38           ` Tom Tromey
@ 2017-11-07 14:35           ` Pedro Alves
  1 sibling, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2017-11-07 14:35 UTC (permalink / raw)
  To: Tom Tromey, Yao Qi; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 3879 bytes --]

On 10/18/2017 04:47 AM, Tom Tromey wrote:
>>>>>> "Yao" == Yao Qi <qiyaoltc@gmail.com> writes:
> 
> Yao> This global variable worries me a little bit.  Is it possible that
> Yao> different part of GDB request to execute the repeatable commands?  For
> Yao> example, CLI and MI issues command, or different UIs issue command.
> 
> It's hard to reason about, I agree.
> 
> I think commands can either be run via "cmd_func", or by calling the
> command function directly.
> 
> Direct calls can be directly audited -- and none of the callers of the
> new set_repeat_arguments function are called this way.
> 
> There are also not many calls to cmd_func; and at least when I look at
> these (I encourage you to check my work), I think only execute_command
> can possibly call a command that calls set_repeat_arguments.
> 
> Since execute_command uses a scoped_restore to save and restore this
> global, I think this must be ok.
> 
> It does seem a bit fragile.  For example, I'd recommend not adding new
> callers of set_repeat_arguments.  I'm open to suggestions for another
> way to approach this.

I think an unanswered question is whether the cases of two different
UIs or interpreters running a command that calls set_repeat_arguments
are handled correctly (for some definition of correctly).

Two UIs means doing something like:
  gdb -ex "new-ui console /dev/pts/56"
or:
  gdb -ex "new-ui mi /dev/pts/56"

and then typing "list foo" in main UI and then just "<ret>"
in the extra UI.

while two interpreters means something like:

  $ gdb -i=mi
  (gdb)
  -interpreter-exec console "CLI COMMAND"
  -equivalent-mi-command

I'm not sure there's any MI command that calls into
the commands that set repeat arguments.

For for different UIs: currently, while each UI has its own line buffer,
saved_command_line is still global.  I.e., the variable that holds the
command line that is passed to the command functions.  That means that if you
type a command in one UI, and then type "<ret>" in a second UI, the
second UI repeats the command typed in the first UI.  I don't recall a
good reason for that, other than "we can improve things incrementally on
top of the initial support for multiple UIs" and "one console and one
MI is the main use case".

I think this patch doesn't affect things here.  Even if we make
saved_command_line per-UI, it seems like repeat_arguments can still be
a global, since it's only used within the scope of a single execute_command
call.   It could be made per-UI too, though it wouldn't make much of a
difference, I think.

To expand a bit: It's entirely possible that execute_command ends up doing
another execute_command inside.  For example when running a GDB script.
And it's plausible that the nested execute_command runs in a different UI from
the one that started the script.  E.g., if a breakpoint is hit, and that
breakpoint has commands -- currently all run control events are always run with
the main UI as current UI, while the script that started the target running
could have been invoked from a different UI.   Actually, I noticed that
breakpoint commands aren't (they're run in inferior_event_handler, while
it's fetch_inferior_event that sets the current UI to the main UI right
at the top), which seems like a bug to me.  But in any case,
breakpoint commands run with from_tty == 0, so shouldn't be affected.

So I think the patch is OK.

BTW, while writing the above, I spent a bit playing with actually 
making saved_command_line be per-UI, and then also the
"list", "x", and "show command" global state.  Playing with 

  gdb -ex "new-ui console TTY" --args ./gdb

it seems to work nicely and intuitively.  See attached
(untested) patch.  I've pushed it to the 
users/palves/per_ui_repeat branch on sourceware too.
(And what I was trying to determine: ) it doesn't look
like your patch would affect doing this.

Thanks,
Pedro Alves


[-- Attachment #2: per-ui-info --]
[-- Type: text/plain, Size: 38766 bytes --]

diff --git a/gdb/event-top.c b/gdb/event-top.c
index 7377189..1e84fdf 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -634,8 +634,8 @@ command_line_append_input_line (struct buffer *cmd_line_buffer, char *rl)
    If REPEAT, handle command repetitions:
 
      - If the input command line is NOT empty, the command returned is
-       copied into the global 'saved_command_line' var so that it can
-       be repeated later.
+       copied into the 'ui->saved_command_line' var so that it can be
+       repeated later.
 
      - OTOH, if the input command line IS empty, return the previously
        saved command instead of the empty input line.
@@ -671,9 +671,9 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
 #define SERVER_COMMAND_PREFIX "server "
   if (startswith (cmd, SERVER_COMMAND_PREFIX))
     {
-      /* Note that we don't set `saved_command_line'.  Between this
-         and the check in dont_repeat, this insures that repeating
-         will still do the right thing.  */
+      /* Note that we don't set `ui->saved_command_line'.  Between
+         this and the check in dont_repeat, this insures that
+         repeating will still do the right thing.  */
       return cmd + strlen (SERVER_COMMAND_PREFIX);
     }
 
@@ -713,7 +713,7 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
   for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
     ;
   if (repeat && *p1 == '\0')
-    return saved_command_line;
+    return ui->saved_command_line;
 
   /* Add command to history if appropriate.  Note: lines consisting
      solely of comments are also added to the command history.  This
@@ -728,9 +728,9 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
   /* Save into global buffer if appropriate.  */
   if (repeat)
     {
-      xfree (saved_command_line);
-      saved_command_line = xstrdup (cmd);
-      return saved_command_line;
+      xfree (ui->saved_command_line);
+      ui->saved_command_line = xstrdup (cmd);
+      return ui->saved_command_line;
     }
   else
     return cmd;
diff --git a/gdb/main.c b/gdb/main.c
index 835ae24..8fae552 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -522,8 +522,6 @@ captured_main_1 (struct captured_main_args *context)
   notice_open_fds ();
   save_original_signals_state ();
 
-  saved_command_line = (char *) xstrdup ("");
-
 #ifdef __MINGW32__
   /* Ensure stderr is unbuffered.  A Cygwin pty or pipe is implemented
      as a Windows pipe, and Windows buffers on pipes.  */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 017c7be..ec54658 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -49,37 +49,50 @@
 #include "format.h"
 #include "source.h"
 #include "common/byte-vector.h"
+#include "top.h"
 
 #ifdef TUI
 #include "tui/tui.h"		/* For tui_active et al.   */
 #endif
 
-/* Last specified output format.  */
+struct current_printcmd_info
+{
+  /* Last specified output format.  */
+  char last_format = 0;
 
-static char last_format = 0;
+  /* Last specified examination size.  'b', 'h', 'w' or `q'.  */
+  char last_size = 'w';
 
-/* Last specified examination size.  'b', 'h', 'w' or `q'.  */
+  /* Default address to examine next, and associated architecture.  */
+  struct gdbarch *next_gdbarch;
+  CORE_ADDR next_address;
 
-static char last_size = 'w';
+  /* Last address examined.  */
+  CORE_ADDR last_examine_address;
 
-/* Default address to examine next, and associated architecture.  */
+  /* Contents of last address examined.  This is not valid past the
+     end of the `x' command!  */
+  struct value *last_examine_value;
+};
 
-static struct gdbarch *next_gdbarch;
-static CORE_ADDR next_address;
+static current_printcmd_info &
+get_current_printcmd_info ()
+{
+  if (current_ui->curr_printcmd_info == NULL)
+    current_ui->curr_printcmd_info = new current_printcmd_info ();
+  return *current_ui->curr_printcmd_info;
+}
+
+void
+delete_current_printcmd_info (struct ui *ui)
+{
+  delete ui->curr_printcmd_info;
+}
 
 /* Number of delay instructions following current disassembled insn.  */
 
 static int branch_delay_insns;
 
-/* Last address examined.  */
-
-static CORE_ADDR last_examine_address;
-
-/* Contents of last address examined.
-   This is not valid past the end of the `x' command!  */
-
-static struct value *last_examine_value;
-
 /* Largest offset between a symbolic value and an address, that will be
    printed as `0x1234 <symbol+offset>'.  */
 
@@ -279,8 +292,10 @@ print_formatted (struct value *val, int size,
   struct type *type = check_typedef (value_type (val));
   int len = TYPE_LENGTH (type);
 
+  current_printcmd_info &ci = get_current_printcmd_info ();
+
   if (VALUE_LVAL (val) == lval_memory)
-    next_address = value_address (val) + len;
+    ci.next_address = value_address (val) + len;
 
   if (size)
     {
@@ -290,20 +305,20 @@ print_formatted (struct value *val, int size,
 	  {
 	    struct type *elttype = value_type (val);
 
-	    next_address = (value_address (val)
-			    + val_print_string (elttype, NULL,
-						value_address (val), -1,
-						stream, options) * len);
+	    ci.next_address = (value_address (val)
+			       + val_print_string (elttype, NULL,
+						   value_address (val), -1,
+						   stream, options) * len);
 	  }
 	  return;
 
 	case 'i':
 	  /* We often wrap here if there are long symbolic names.  */
 	  wrap_here ("    ");
-	  next_address = (value_address (val)
-			  + gdb_print_insn (get_type_arch (type),
-					    value_address (val), stream,
-					    &branch_delay_insns));
+	  ci.next_address = (value_address (val)
+			     + gdb_print_insn (get_type_arch (type),
+					       value_address (val), stream,
+					       &branch_delay_insns));
 	  return;
 	}
     }
@@ -500,10 +515,13 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
-  next_gdbarch = gdbarch;
-  next_address = addr;
+  current_printcmd_info &ci = get_current_printcmd_info ();
 
-  /* Make address available to the user as $_.  */
+  ci.next_gdbarch = gdbarch;
+  ci.next_address = addr;
+
+  /* Make address available to the user as $_.  FIXME: should instead
+     be a computed val, so that it works Per-UI.  */
   set_internalvar (lookup_internalvar ("_"),
 		   value_from_pointer (ptr_type, addr));
 }
@@ -976,8 +994,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
   format = fmt.format;
   size = fmt.size;
   count = fmt.count;
-  next_gdbarch = gdbarch;
-  next_address = addr;
+
+  current_printcmd_info &ci = get_current_printcmd_info ();
+
+  ci.next_gdbarch = gdbarch;
+  ci.next_address = addr;
 
   /* Instruction format implies fetch single bytes
      regardless of the specified size.
@@ -989,11 +1010,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
   if (size == 'a')
     {
       /* Pick the appropriate size for an address.  */
-      if (gdbarch_ptr_bit (next_gdbarch) == 64)
+      if (gdbarch_ptr_bit (ci.next_gdbarch) == 64)
 	size = 'g';
-      else if (gdbarch_ptr_bit (next_gdbarch) == 32)
+      else if (gdbarch_ptr_bit (ci.next_gdbarch) == 32)
 	size = 'w';
-      else if (gdbarch_ptr_bit (next_gdbarch) == 16)
+      else if (gdbarch_ptr_bit (ci.next_gdbarch) == 16)
 	size = 'h';
       else
 	/* Bad value for gdbarch_ptr_bit.  */
@@ -1002,13 +1023,13 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     }
 
   if (size == 'b')
-    val_type = builtin_type (next_gdbarch)->builtin_int8;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int8;
   else if (size == 'h')
-    val_type = builtin_type (next_gdbarch)->builtin_int16;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int16;
   else if (size == 'w')
-    val_type = builtin_type (next_gdbarch)->builtin_int32;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int32;
   else if (size == 'g')
-    val_type = builtin_type (next_gdbarch)->builtin_int64;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int64;
 
   if (format == 's')
     {
@@ -1017,9 +1038,9 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
       /* Search for "char16_t"  or "char32_t" types or fall back to 8-bit char
 	 if type is not found.  */
       if (size == 'h')
-	char_type = builtin_type (next_gdbarch)->builtin_char16;
+	char_type = builtin_type (ci.next_gdbarch)->builtin_char16;
       else if (size == 'w')
-	char_type = builtin_type (next_gdbarch)->builtin_char32;
+	char_type = builtin_type (ci.next_gdbarch)->builtin_char32;
       if (char_type)
         val_type = char_type;
       else
@@ -1028,7 +1049,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 	    warning (_("Unable to display strings with "
 		       "size '%c', using 'b' instead."), size);
 	  size = 'b';
-	  val_type = builtin_type (next_gdbarch)->builtin_int8;
+	  val_type = builtin_type (ci.next_gdbarch)->builtin_int8;
         }
     }
 
@@ -1051,26 +1072,26 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
       count = -count;
       if (format == 'i')
         {
-          next_address = find_instruction_backward (gdbarch, addr, count,
-                                                    &count);
+          ci.next_address = find_instruction_backward (gdbarch, addr, count,
+						       &count);
         }
       else if (format == 's')
         {
-          next_address = find_string_backward (gdbarch, addr, count,
-                                               TYPE_LENGTH (val_type),
-                                               &opts, &count);
+          ci.next_address = find_string_backward (gdbarch, addr, count,
+						  TYPE_LENGTH (val_type),
+						  &opts, &count);
         }
       else
         {
-          next_address = addr - count * TYPE_LENGTH (val_type);
+          ci.next_address = addr - count * TYPE_LENGTH (val_type);
         }
 
       /* The following call to print_formatted updates next_address in every
          iteration.  In backward case, we store the start address here
          and update next_address with it before exiting the function.  */
       addr_rewound = (format == 's'
-                      ? next_address - TYPE_LENGTH (val_type)
-                      : next_address);
+                      ? ci.next_address - TYPE_LENGTH (val_type)
+                      : ci.next_address);
       need_to_update_next_address = 1;
     }
 
@@ -1081,8 +1102,8 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     {
       QUIT;
       if (format == 'i')
-	fputs_filtered (pc_prefix (next_address), gdb_stdout);
-      print_address (next_gdbarch, next_address, gdb_stdout);
+	fputs_filtered (pc_prefix (ci.next_address), gdb_stdout);
+      print_address (ci.next_gdbarch, ci.next_address, gdb_stdout);
       printf_filtered (":");
       for (i = maxelts;
 	   i > 0 && count > 0;
@@ -1091,10 +1112,10 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 	  printf_filtered ("\t");
 	  /* Note that print_formatted sets next_address for the next
 	     object.  */
-	  last_examine_address = next_address;
+	  ci.last_examine_address = ci.next_address;
 
-	  if (last_examine_value)
-	    value_free (last_examine_value);
+	  if (ci.last_examine_value)
+	    value_free (ci.last_examine_value);
 
 	  /* The value to be displayed is not fetched greedily.
 	     Instead, to avoid the possibility of a fetched value not
@@ -1105,12 +1126,12 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 	     the disassembler be modified so that LAST_EXAMINE_VALUE
 	     is left with the byte sequence from the last complete
 	     instruction fetched from memory?  */
-	  last_examine_value = value_at_lazy (val_type, next_address);
+	  ci.last_examine_value = value_at_lazy (val_type, ci.next_address);
 
-	  if (last_examine_value)
-	    release_value (last_examine_value);
+	  if (ci.last_examine_value)
+	    release_value (ci.last_examine_value);
 
-	  print_formatted (last_examine_value, size, &opts, gdb_stdout);
+	  print_formatted (ci.last_examine_value, size, &opts, gdb_stdout);
 
 	  /* Display any branch delay slots following the final insn.  */
 	  if (format == 'i' && count == 1)
@@ -1121,7 +1142,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     }
 
   if (need_to_update_next_address)
-    next_address = addr_rewound;
+    ci.next_address = addr_rewound;
 }
 \f
 static void
@@ -1149,9 +1170,12 @@ print_command_parse_format (const char **expp, const char *cmdname,
   if (exp && *exp == '/')
     {
       exp++;
-      *fmtp = decode_format (&exp, last_format, 0);
+
+      current_printcmd_info &ci = get_current_printcmd_info ();
+
+      *fmtp = decode_format (&exp, ci.last_format, 0);
       validate_format (*fmtp, cmdname);
-      last_format = fmtp->format;
+      ci.last_format = fmtp->format;
     }
   else
     {
@@ -1624,8 +1648,10 @@ x_command (char *exp, int from_tty)
   struct format_data fmt;
   struct value *val;
 
-  fmt.format = last_format ? last_format : 'x';
-  fmt.size = last_size;
+  current_printcmd_info &ci = get_current_printcmd_info ();
+
+  fmt.format = ci.last_format ? ci.last_format : 'x';
+  fmt.size = ci.last_size;
   fmt.count = 1;
   fmt.raw = 0;
 
@@ -1633,7 +1659,7 @@ x_command (char *exp, int from_tty)
     {
       const char *tmp = exp + 1;
 
-      fmt = decode_format (&tmp, last_format, last_size);
+      fmt = decode_format (&tmp, ci.last_format, ci.last_size);
       exp = (char *) tmp;
     }
 
@@ -1655,45 +1681,45 @@ x_command (char *exp, int from_tty)
       if (/* last_format == 'i'  && */ 
 	  TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
 	   && VALUE_LVAL (val) == lval_memory)
-	next_address = value_address (val);
+	ci.next_address = value_address (val);
       else
-	next_address = value_as_address (val);
+	ci.next_address = value_as_address (val);
 
-      next_gdbarch = expr->gdbarch;
+      ci.next_gdbarch = expr->gdbarch;
     }
 
-  if (!next_gdbarch)
+  if (!ci.next_gdbarch)
     error_no_arg (_("starting display address"));
 
-  do_examine (fmt, next_gdbarch, next_address);
+  do_examine (fmt, ci.next_gdbarch, ci.next_address);
 
   /* If the examine succeeds, we remember its size and format for next
      time.  Set last_size to 'b' for strings.  */
   if (fmt.format == 's')
-    last_size = 'b';
+    ci.last_size = 'b';
   else
-    last_size = fmt.size;
-  last_format = fmt.format;
+    ci.last_size = fmt.size;
+  ci.last_format = fmt.format;
 
   /* Set a couple of internal variables if appropriate.  */
-  if (last_examine_value)
+  if (ci.last_examine_value)
     {
       /* Make last address examined available to the user as $_.  Use
          the correct pointer type.  */
       struct type *pointer_type
-	= lookup_pointer_type (value_type (last_examine_value));
+	= lookup_pointer_type (value_type (ci.last_examine_value));
       set_internalvar (lookup_internalvar ("_"),
 		       value_from_pointer (pointer_type,
-					   last_examine_address));
+					   ci.last_examine_address));
 
       /* Make contents of last address examined available to the user
 	 as $__.  If the last value has not been fetched from memory
 	 then don't fetch it now; instead mark it by voiding the $__
 	 variable.  */
-      if (value_lazy (last_examine_value))
+      if (value_lazy (ci.last_examine_value))
 	clear_internalvar (lookup_internalvar ("__"));
       else
-	set_internalvar (lookup_internalvar ("__"), last_examine_value);
+	set_internalvar (lookup_internalvar ("__"), ci.last_examine_value);
     }
 }
 \f
diff --git a/gdb/source.c b/gdb/source.c
index aa672fd..61a3634 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -44,6 +44,7 @@
 #include "readline/readline.h"
 #include "common/enum-flags.h"
 #include <algorithm>
+#include "top.h"
 
 #define OPEN_MODE (O_RDONLY | O_BINARY)
 #define FDOPEN_MODE FOPEN_RB
@@ -76,15 +77,45 @@ struct substitute_path_rule
 
 static struct substitute_path_rule *substitute_path_rules = NULL;
 
-/* Symtab of default file for listing lines of.  */
+struct current_source_info
+{
+  /* Symtab of default file for listing lines of.  */
+  symtab *current_source_symtab = NULL;
+
+  /* Default next line to list.  */
+  int current_source_line = 0;
 
-static struct symtab *current_source_symtab;
+  program_space *current_source_pspace = NULL;
 
-/* Default next line to list.  */
+  /* Line number of last line printed.  Default for various commands.
+     source_line is usually, but not always, the same as this.  */
+  int last_line_listed;
 
-static int current_source_line;
+  /* First line number listed by last listing command.  If 0, then no
+     source lines have yet been listed since the last time the current
+     source line was changed.  */
+  int first_line_listed;
 
-static struct program_space *current_source_pspace;
+  /* Saves the name of the last source file visited and a possible
+     error code.  Used to prevent repeating annoying "No such file or
+     directories" msgs.  */
+  struct symtab *last_source_visited = NULL;
+  int last_source_error = 0;
+};
+
+static current_source_info &
+get_current_source_info ()
+{
+  if (current_ui->curr_source_info == NULL)
+    current_ui->curr_source_info = new current_source_info ();
+  return *current_ui->curr_source_info;
+}
+
+void
+delete_current_source_info (struct ui *ui)
+{
+  delete ui->curr_source_info;
+}
 
 /* Default number of lines to print with commands like "list".
    This is based on guessing how many long (i.e. more than chars_per_line
@@ -123,23 +154,8 @@ show_filename_display_string (struct ui_file *file, int from_tty,
 {
   fprintf_filtered (file, _("Filenames are displayed as \"%s\".\n"), value);
 }
- 
-/* Line number of last line printed.  Default for various commands.
-   current_source_line is usually, but not always, the same as this.  */
-
-static int last_line_listed;
-
-/* First line number listed by last listing command.  If 0, then no
-   source lines have yet been listed since the last time the current
-   source line was changed.  */
-
-static int first_line_listed;
 
-/* Saves the name of the last source file visited and a possible error code.
-   Used to prevent repeating annoying "No such file or directories" msgs.  */
 
-static struct symtab *last_source_visited = NULL;
-static int last_source_error = 0;
 \f
 /* Return the first line listed by print_source_lines.
    Used by command interpreters to request listing from
@@ -148,7 +164,9 @@ static int last_source_error = 0;
 int
 get_first_line_listed (void)
 {
-  return first_line_listed;
+  current_source_info &si = get_current_source_info ();
+
+  return si.first_line_listed;
 }
 
 /* Clear line listed range.  This makes the next "list" center the
@@ -157,8 +175,10 @@ get_first_line_listed (void)
 static void
 clear_lines_listed_range (void)
 {
-  first_line_listed = 0;
-  last_line_listed = 0;
+  current_source_info &si = get_current_source_info ();
+
+  si.first_line_listed = 0;
+  si.last_line_listed = 0;
 }
 
 /* Return the default number of lines to print with commands like the
@@ -180,12 +200,14 @@ get_current_source_symtab_and_line (void)
 {
   symtab_and_line cursal;
 
-  cursal.pspace = current_source_pspace;
-  cursal.symtab = current_source_symtab;
-  cursal.line = current_source_line;
+  current_source_info &si = get_current_source_info ();
+
+  cursal.pspace = si.current_source_pspace;
+  cursal.symtab = si.current_source_symtab;
+  cursal.line = si.current_source_line;
   cursal.pc = 0;
   cursal.end = 0;
-  
+
   return cursal;
 }
 
@@ -203,8 +225,9 @@ set_default_source_symtab_and_line (void)
   if (!have_full_symbols () && !have_partial_symbols ())
     error (_("No symbol table is loaded.  Use the \"file\" command."));
 
+  current_source_info &si = get_current_source_info ();
   /* Pull in a current source symtab if necessary.  */
-  if (current_source_symtab == 0)
+  if (si.current_source_symtab == NULL)
     select_source_symtab (0);
 }
 
@@ -218,15 +241,17 @@ set_current_source_symtab_and_line (const symtab_and_line &sal)
 {
   symtab_and_line cursal;
 
-  cursal.pspace = current_source_pspace;
-  cursal.symtab = current_source_symtab;
-  cursal.line = current_source_line;
+  current_source_info &si = get_current_source_info ();
+
+  cursal.pspace = si.current_source_pspace;
+  cursal.symtab = si.current_source_symtab;
+  cursal.line = si.current_source_line;
   cursal.pc = 0;
   cursal.end = 0;
 
-  current_source_pspace = sal.pspace;
-  current_source_symtab = sal.symtab;
-  current_source_line = sal.line;
+  si.current_source_pspace = sal.pspace;
+  si.current_source_symtab = sal.symtab;
+  si.current_source_line = sal.line;
 
   /* Force the next "list" to center around the current line.  */
   clear_lines_listed_range ();
@@ -239,8 +264,10 @@ set_current_source_symtab_and_line (const symtab_and_line &sal)
 void
 clear_current_source_symtab_and_line (void)
 {
-  current_source_symtab = 0;
-  current_source_line = 0;
+  current_source_info &si = get_current_source_info ();
+
+  si.current_source_symtab = NULL;
+  si.current_source_line = 0;
 }
 
 /* Set the source file default for the "list" command to be S.
@@ -257,15 +284,17 @@ select_source_symtab (struct symtab *s)
   struct objfile *ofp;
   struct compunit_symtab *cu;
 
+  current_source_info &si = get_current_source_info ();
+
   if (s)
     {
-      current_source_symtab = s;
-      current_source_line = 1;
-      current_source_pspace = SYMTAB_PSPACE (s);
+      si.current_source_symtab = s;
+      si.current_source_line = 1;
+      si.current_source_pspace = SYMTAB_PSPACE (s);
       return;
     }
 
-  if (current_source_symtab)
+  if (si.current_source_symtab != NULL)
     return;
 
   /* Make the default place to list be the function `main'
@@ -276,17 +305,17 @@ select_source_symtab (struct symtab *s)
 	= decode_line_with_current_source (main_name (),
 					   DECODE_LINE_FUNFIRSTLINE);
       const symtab_and_line &sal = sals[0];
-      current_source_pspace = sal.pspace;
-      current_source_symtab = sal.symtab;
-      current_source_line = std::max (sal.line - (lines_to_list - 1), 1);
-      if (current_source_symtab)
+      si.current_source_pspace = sal.pspace;
+      si.current_source_symtab = sal.symtab;
+      si.current_source_line = std::max (sal.line - (lines_to_list - 1), 1);
+      if (si.current_source_symtab != NULL)
 	return;
     }
 
   /* Alright; find the last file in the symtab list (ignoring .h's
      and namespace symtabs).  */
 
-  current_source_line = 1;
+  si.current_source_line = 1;
 
   ALL_FILETABS (ofp, cu, s)
     {
@@ -296,12 +325,12 @@ select_source_symtab (struct symtab *s)
       if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
 			|| strcmp (name, "<<C++-namespaces>>") == 0)))
 	{
-	  current_source_pspace = current_program_space;
-	  current_source_symtab = s;
+	  si.current_source_pspace = current_program_space;
+	  si.current_source_symtab = s;
 	}
     }
 
-  if (current_source_symtab)
+  if (si.current_source_symtab != NULL)
     return;
 
   ALL_OBJFILES (ofp)
@@ -309,9 +338,9 @@ select_source_symtab (struct symtab *s)
     if (ofp->sf)
       s = ofp->sf->qf->find_last_source_symtab (ofp);
     if (s)
-      current_source_symtab = s;
+      si.current_source_symtab = s;
   }
-  if (current_source_symtab)
+  if (si.current_source_symtab != NULL)
     return;
 
   error (_("Can't find a default source file"));
@@ -403,7 +432,12 @@ forget_cached_source_info (void)
       forget_cached_source_info_for_objfile (objfile);
     }
 
-  last_source_visited = NULL;
+  struct ui *ui;
+  ALL_UIS (ui)
+    {
+      if (ui->curr_source_info != NULL)
+	ui->curr_source_info->last_source_visited = NULL;
+    }
 }
 
 void
@@ -645,7 +679,8 @@ add_path (char *dirname, char **which_path, int parse_separators)
 static void
 info_source_command (char *ignore, int from_tty)
 {
-  struct symtab *s = current_source_symtab;
+  current_source_info &si = get_current_source_info ();
+  struct symtab *s = si.current_source_symtab;
   struct compunit_symtab *cust;
 
   if (!s)
@@ -1312,8 +1347,9 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
   annotate_source (s->fullname, line, s->line_charpos[line - 1],
 		   mid_statement, get_objfile_arch (SYMTAB_OBJFILE (s)), pc);
 
-  current_source_line = line;
-  current_source_symtab = s;
+  current_source_info &si = get_current_source_info ();
+  si.current_source_line = line;
+  si.current_source_symtab = s;
   clear_lines_listed_range ();
   return 1;
 }
@@ -1333,36 +1369,37 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
   struct ui_out *uiout = current_uiout;
 
   /* Regardless of whether we can open the file, set current_source_symtab.  */
-  current_source_symtab = s;
-  current_source_line = line;
-  first_line_listed = line;
+  current_source_info &si = get_current_source_info ();
+  si.current_source_symtab = s;
+  si.current_source_line = line;
+  si.first_line_listed = line;
 
   /* If printing of source lines is disabled, just print file and line
      number.  */
   if (uiout->test_flags (ui_source_list))
     {
       /* Only prints "No such file or directory" once.  */
-      if ((s != last_source_visited) || (!last_source_error))
+      if ((s != si.last_source_visited) || (!si.last_source_error))
 	{
-	  last_source_visited = s;
+	  si.last_source_visited = s;
 	  desc = open_source_file (s);
 	}
       else
 	{
-	  desc = last_source_error;
+	  desc = si.last_source_error;
 	  flags |= PRINT_SOURCE_LINES_NOERROR;
 	}
     }
   else
     {
-      desc = last_source_error;
+      desc = si.last_source_error;
       flags |= PRINT_SOURCE_LINES_NOERROR;
       noprint = 1;
     }
 
   if (desc < 0 || noprint)
     {
-      last_source_error = desc;
+      si.last_source_error = desc;
 
       if (!(flags & PRINT_SOURCE_LINES_NOERROR))
 	{
@@ -1404,7 +1441,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
       return;
     }
 
-  last_source_error = 0;
+  si.last_source_error = 0;
 
   if (s->line_charpos == 0)
     find_source_lines (s, desc);
@@ -1432,13 +1469,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
       c = fgetc (stream.get ());
       if (c == EOF)
 	break;
-      last_line_listed = current_source_line;
+      si.last_line_listed = si.current_source_line;
       if (flags & PRINT_SOURCE_LINES_FILENAME)
         {
           uiout->text (symtab_to_filename_for_display (s));
           uiout->text (":");
         }
-      xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++);
+      xsnprintf (buf, sizeof (buf), "%d\t", si.current_source_line++);
       uiout->text (buf);
       do
 	{
@@ -1492,14 +1529,16 @@ info_line_command (char *arg, int from_tty)
   symtab_and_line curr_sal;
   gdb::array_view<symtab_and_line> sals;
 
+  current_source_info &si = get_current_source_info ();
+
   if (arg == 0)
     {
-      curr_sal.symtab = current_source_symtab;
+      curr_sal.symtab = si.current_source_symtab;
       curr_sal.pspace = current_program_space;
-      if (last_line_listed != 0)
-	curr_sal.line = last_line_listed;
+      if (si.last_line_listed != 0)
+	curr_sal.line = si.last_line_listed;
       else
-	curr_sal.line = current_source_line;
+	curr_sal.line = si.current_source_line;
 
       sals = curr_sal;
     }
@@ -1572,7 +1611,7 @@ info_line_command (char *arg, int from_tty)
 	  set_next_address (gdbarch, start_pc);
 
 	  /* Repeating "info line" should do the following line.  */
-	  last_line_listed = sal.line + 1;
+	  si.last_line_listed = sal.line + 1;
 
 	  /* If this is the only line, show the source code.  If it could
 	     not find the file, don't do anything special.  */
@@ -1599,28 +1638,30 @@ forward_search_command (char *regex, int from_tty)
   char *msg;
   struct cleanup *cleanups;
 
-  line = last_line_listed + 1;
+  current_source_info &si = get_current_source_info ();
+
+  line = si.last_line_listed + 1;
 
   msg = (char *) re_comp (regex);
   if (msg)
     error (("%s"), msg);
 
-  if (current_source_symtab == 0)
+  if (si.current_source_symtab == 0)
     select_source_symtab (0);
 
-  desc = open_source_file (current_source_symtab);
+  desc = open_source_file (si.current_source_symtab);
   if (desc < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
   cleanups = make_cleanup_close (desc);
 
-  if (current_source_symtab->line_charpos == 0)
-    find_source_lines (current_source_symtab, desc);
+  if (si.current_source_symtab->line_charpos == 0)
+    find_source_lines (si.current_source_symtab, desc);
 
-  if (line < 1 || line > current_source_symtab->nlines)
+  if (line < 1 || line > si.current_source_symtab->nlines)
     error (_("Expression not found"));
 
-  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+  if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0)
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
 
   discard_cleanups (cleanups);
   gdb_file_up stream (fdopen (desc, FDOPEN_MODE));
@@ -1664,9 +1705,9 @@ forward_search_command (char *regex, int from_tty)
       if (re_exec (buf) > 0)
 	{
 	  /* Match!  */
-	  print_source_lines (current_source_symtab, line, line + 1, 0);
+	  print_source_lines (si.current_source_symtab, line, line + 1, 0);
 	  set_internalvar_integer (lookup_internalvar ("_"), line);
-	  current_source_line = std::max (line - lines_to_list / 2, 1);
+	  si.current_source_line = std::max (line - lines_to_list / 2, 1);
 	  return;
 	}
       line++;
@@ -1684,28 +1725,30 @@ reverse_search_command (char *regex, int from_tty)
   char *msg;
   struct cleanup *cleanups;
 
-  line = last_line_listed - 1;
+  current_source_info &si = get_current_source_info ();
+
+  line = si.last_line_listed - 1;
 
   msg = (char *) re_comp (regex);
   if (msg)
     error (("%s"), msg);
 
-  if (current_source_symtab == 0)
+  if (si.current_source_symtab == 0)
     select_source_symtab (0);
 
-  desc = open_source_file (current_source_symtab);
+  desc = open_source_file (si.current_source_symtab);
   if (desc < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
   cleanups = make_cleanup_close (desc);
 
-  if (current_source_symtab->line_charpos == 0)
-    find_source_lines (current_source_symtab, desc);
+  if (si.current_source_symtab->line_charpos == 0)
+    find_source_lines (si.current_source_symtab, desc);
 
-  if (line < 1 || line > current_source_symtab->nlines)
+  if (line < 1 || line > si.current_source_symtab->nlines)
     error (_("Expression not found"));
 
-  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+  if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0)
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
 
   discard_cleanups (cleanups);
   gdb_file_up stream (fdopen (desc, FDOPEN_MODE));
@@ -1738,18 +1781,18 @@ reverse_search_command (char *regex, int from_tty)
       if (re_exec (buf) > 0)
 	{
 	  /* Match!  */
-	  print_source_lines (current_source_symtab, line, line + 1, 0);
+	  print_source_lines (si.current_source_symtab, line, line + 1, 0);
 	  set_internalvar_integer (lookup_internalvar ("_"), line);
-	  current_source_line = std::max (line - lines_to_list / 2, 1);
+	  si.current_source_line = std::max (line - lines_to_list / 2, 1);
 	  return;
 	}
       line--;
       if (fseek (stream.get (),
-		 current_source_symtab->line_charpos[line - 1], 0) < 0)
+		 si.current_source_symtab->line_charpos[line - 1], 0) < 0)
 	{
 	  const char *filename;
 
-	  filename = symtab_to_filename_for_display (current_source_symtab);
+	  filename = symtab_to_filename_for_display (si.current_source_symtab);
 	  perror_with_name (filename);
 	}
     }
@@ -1974,7 +2017,6 @@ _initialize_source (void)
 {
   struct cmd_list_element *c;
 
-  current_source_symtab = 0;
   init_source_path ();
 
   /* The intention is to use POSIX Basic Regular Expressions.
diff --git a/gdb/top.c b/gdb/top.c
index f006c66..3919203 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -132,10 +132,6 @@ show_confirm (struct ui_file *file, int from_tty,
 
 char *current_directory;
 
-/* The last command line executed on the console.  Used for command
-   repetitions.  */
-char *saved_command_line;
-
 /* Nonzero if the current command is modified by "server ".  This
    affects things like recording into the command history, commands
    repeating on RETURN, etc.  This is so a user interface (emacs, GUI,
@@ -251,6 +247,7 @@ static int highest_ui_num;
 ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_)
   : next (nullptr),
     num (++highest_ui_num),
+    saved_command_line (xstrdup ("")),
     call_readline (nullptr),
     input_handler (nullptr),
     command_editing (0),
@@ -301,6 +298,10 @@ ui::~ui ()
   else
     ui_list = next;
 
+  delete_current_printcmd_info (this);
+  delete_current_source_info (this);
+  delete_current_top_info (this);
+
   delete m_gdb_stdin;
   delete m_gdb_stdout;
   delete m_gdb_stderr;
@@ -675,7 +676,10 @@ dont_repeat (void)
      thing read from stdin in line and don't want to delete it.  Null
      lines won't repeat here in any case.  */
   if (ui->instream == ui->stdin_stream)
-    *saved_command_line = 0;
+    {
+      xfree (ui->saved_command_line);
+      ui->saved_command_line = NULL;
+    }
 }
 
 /* Prevent dont_repeat from working, and return a cleanup that
@@ -1659,11 +1663,33 @@ dont_repeat_command (char *ignored, int from_tty)
 {
   /* Can't call dont_repeat here because we're not necessarily reading
      from stdin.  */
-  *saved_command_line = 0;
+  xfree (current_ui->saved_command_line);
+  current_ui->saved_command_line = NULL;
 }
 \f
 /* Functions to manipulate command line editing control variables.  */
 
+struct current_top_info
+{
+  /* Number of the history entry which we are planning to display
+     next in "show commands".  Relative to history_base.  */
+  int num = 0;
+};
+
+static current_top_info &
+get_current_top_info ()
+{
+  if (current_ui->curr_top_info == NULL)
+    current_ui->curr_top_info = new current_top_info ();
+  return *current_ui->curr_top_info;
+}
+
+void
+delete_current_top_info (struct ui *ui)
+{
+  delete ui->curr_top_info;
+}
+
 /* Number of commands to print in each call to show_commands.  */
 #define Hist_print 10
 void
@@ -1672,9 +1698,7 @@ show_commands (char *args, int from_tty)
   /* Index for history commands.  Relative to history_base.  */
   int offset;
 
-  /* Number of the history entry which we are planning to display next.
-     Relative to history_base.  */
-  static int num = 0;
+  current_top_info &ci = get_current_top_info ();
 
   /* Print out some of the commands from the command history.  */
 
@@ -1685,28 +1709,28 @@ show_commands (char *args, int from_tty)
 	;
       else
 	/* "info editing <exp>" should print around command number <exp>.  */
-	num = (parse_and_eval_long (args) - history_base) - Hist_print / 2;
+	ci.num = (parse_and_eval_long (args) - history_base) - Hist_print / 2;
     }
   /* "show commands" means print the last Hist_print commands.  */
   else
     {
-      num = history_length - Hist_print;
+      ci.num = history_length - Hist_print;
     }
 
-  if (num < 0)
-    num = 0;
+  if (ci.num < 0)
+    ci.num = 0;
 
   /* If there are at least Hist_print commands, we want to display the last
      Hist_print rather than, say, the last 6.  */
-  if (history_length - num < Hist_print)
+  if (history_length - ci.num < Hist_print)
     {
-      num = history_length - Hist_print;
-      if (num < 0)
-	num = 0;
+      ci.num = history_length - Hist_print;
+      if (ci.num < 0)
+	ci.num = 0;
     }
 
-  for (offset = num;
-       offset < num + Hist_print && offset < history_length;
+  for (offset = ci.num;
+       offset < ci.num + Hist_print && offset < history_length;
        offset++)
     {
       printf_filtered ("%5d  %s\n", history_base + offset,
@@ -1715,7 +1739,7 @@ show_commands (char *args, int from_tty)
 
   /* The next command we want to display is the next one that we haven't
      displayed yet.  */
-  num += Hist_print;
+  ci.num += Hist_print;
 
   /* If the user repeats this command with return, it should do what
      "show commands +" does.  This is unnecessary if arg is null,
diff --git a/gdb/top.h b/gdb/top.h
index ab65ddb..94822772 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -71,6 +71,10 @@ struct ui
      input until we have a whole command line.  */
   struct buffer line_buffer;
 
+  /* The last command line executed on the console.  Used for command
+     repetitions.  */
+  char *saved_command_line;
+
   /* The callback used by the event loop whenever an event is detected
      on the UI's input file descriptor.  This function incrementally
      builds a buffer where it accumulates the line read up to the
@@ -130,6 +134,15 @@ struct ui
   /* See enum prompt_state's description.  */
   enum prompt_state prompt_state;
 
+  /* Per-UI info for printcmd.c.  Initialized on demand.  */
+  struct current_printcmd_info *curr_printcmd_info = NULL;
+
+  /* Per-UI info for source.c.  Initialized on demand.  */
+  struct current_source_info *curr_source_info = NULL;
+
+  /* Per-UI info for top.c.  Initialized on demand.  */
+  struct current_top_info *curr_top_info = NULL;
+
   /* The fields below that start with "m_" are "private".  They're
      meant to be accessed through wrapper macros that make them look
      like globals.  */
@@ -217,7 +230,6 @@ extern void ui_register_input_event_handler (struct ui *ui);
 extern void ui_unregister_input_event_handler (struct ui *ui);
 
 /* From top.c.  */
-extern char *saved_command_line;
 extern int confirm;
 extern int inhibit_gdbinit;
 extern const char gdbinit[];
@@ -234,6 +246,11 @@ extern void quit_command (char *, int);
 extern void quit_cover (void);
 extern void execute_command (char *, int);
 
+/* Delete the per-UI info of UI.  */
+extern void delete_current_printcmd_info (struct ui *ui);
+extern void delete_current_source_info (struct ui *ui);
+extern void delete_current_top_info (struct ui *ui);
+
 /* If the interpreter is in sync mode (we're running a user command's
    list, running command hooks or similars), and we just ran a
    synchronous command that started the target, wait for that command

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2017-11-07 14:35 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-13 21:00 [RFA 0/8] Constify many commands Tom Tromey
2017-10-13 21:00 ` [RFA 1/8] Constify add_abbrev_prefix_cmd Tom Tromey
2017-10-16  9:02   ` Yao Qi
2017-10-16 15:54     ` Tom Tromey
2017-10-16 20:23       ` Yao Qi
2017-10-13 21:00 ` [RFA 6/8] Remove cleanup from backtrace_command Tom Tromey
2017-10-16  9:46   ` Yao Qi
2017-10-13 21:00 ` [RFA 8/8] Constify add_com Tom Tromey
2017-10-16  9:59   ` Yao Qi
2017-10-13 21:00 ` [RFA 2/8] Constify add_com_suppress_notification Tom Tromey
2017-10-16  9:03   ` Yao Qi
2017-10-16 15:55     ` Tom Tromey
2017-10-13 21:00 ` [RFA 3/8] Make set_cmd_cfunc private Tom Tromey
2017-10-16  9:20   ` Yao Qi
2017-10-13 21:00 ` [RFA 4/8] Make strip_bg_char return a unique_xmalloc_ptr Tom Tromey
2017-10-16  9:33   ` Yao Qi
2017-10-16 18:37     ` Simon Marchi
2017-10-17 11:05       ` Yao Qi
2017-10-18  3:32         ` Tom Tromey
2017-10-18  9:37     ` Pedro Alves
2017-11-06 16:33       ` Tom Tromey
2017-10-13 21:00 ` [RFA 5/8] Constify add_path and friends Tom Tromey
2017-10-16  9:35   ` Yao Qi
2017-10-13 21:00 ` [RFA 7/8] Add truncate_repeat_arguments function Tom Tromey
2017-10-14  4:49   ` Tom Tromey
2017-10-16  3:07     ` Tom Tromey
2017-10-16  9:53       ` Yao Qi
2017-10-18  3:48         ` Tom Tromey
2017-11-06 16:38           ` Tom Tromey
2017-11-07 14:35           ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).