[RFA 11/22] Change command stats reporting to use class

Tom Tromey
2016-09-27T04:52:51Z

This removes make_command_stats_cleanup in favor of an RAII class.
The patch is reasonably straightforward, but keeping the same
semantics required reindenting much of captured_main.

2016-09-26 Tom Tromey <tom@tromey.com>

* maint.h (scoped_command_stats): New class.
(make_command_stats_cleanup): Don't declare.
* maint.c (struct cmd_stats): Remove.
(~scoped_command_stats): Rename from report_command_stats. Now a
destructor.
(scoped_command_stats): Rename from make_command_stats_cleanup.
Now a constructor.
* main.c (captured_main): Use scoped_command_stats.
* event-top.c (command_handler): Use scoped_command_stats.
---
gdb/ChangeLog | 12 +
gdb/event-top.c | 5 +-
gdb/main.c | 1101 +++++++++++++++++++++++++++----------------------------
gdb/maint.c | 112 ++----
gdb/maint.h | 39 +-
5 files changed, 632 insertions(+), 637 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 704de48..66e9236 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
2016-09-26 Tom Tromey <tom@tromey.com>

+ * maint.h (scoped_command_stats): New class.
+ (make_command_stats_cleanup): Don't declare.
+ * maint.c (struct cmd_stats): Remove.
+ (~scoped_command_stats): Rename from report_command_stats. Now a
+ destructor.
+ (scoped_command_stats): Rename from make_command_stats_cleanup.
+ Now a constructor.
+ * main.c (captured_main): Use scoped_command_stats.
+ * event-top.c (command_handler): Use scoped_command_stats.
+
+2016-09-26 Tom Tromey <tom@tromey.com>
+
* mi/mi-main.c (mi_cmd_data_read_memory): Use std::vector. Remove
some cleanups.

diff --git a/gdb/event-top.c b/gdb/event-top.c
index 9b0ccbc..c452501 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -562,13 +562,12 @@ void
command_handler (char *command)
{
struct ui *ui = current_ui;
- struct cleanup *stat_chain;
char *c;

if (ui->instream == ui->stdin_stream)
reinitialize_more_filter ();

- stat_chain = make_command_stats_cleanup (1);
+ scoped_command_stats stat_reporter (1);

/* Do not execute commented lines. */
for (c = command; *c == ' ' || *c == '\t'; c++)
@@ -580,8 +579,6 @@ command_handler (char *command)
/* Do any commands attached to breakpoint we stopped at. */
bpstat_do_actions ();
}
-
- do_cleanups (stat_chain);
}

/* Append RL, an input line returned by readline or one of its
diff --git a/gdb/main.c b/gdb/main.c
index 2ea9466..f081136 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -486,661 +486,658 @@ captured_main (void *data)
int save_auto_load;
struct objfile *objfile;

- struct cleanup *pre_stat_chain;
-
#ifdef HAVE_SBRK
- /* Set this before calling make_command_stats_cleanup. */
+ /* Set this before constructing scoped_command_stats. */
lim_at_start = (char *) sbrk (0);
#endif

- pre_stat_chain = make_command_stats_cleanup (0);
+ {
+ scoped_command_stats stat_reporter (0);

#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
- setlocale (LC_MESSAGES, "");
+ setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
- setlocale (LC_CTYPE, "");
+ setlocale (LC_CTYPE, "");
#endif
#ifdef ENABLE_NLS
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
#endif

- bfd_init ();
- notice_open_fds ();
- save_original_signals_state ();
+ bfd_init ();
+ notice_open_fds ();
+ save_original_signals_state ();

- make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
- dirsize = 1;
- dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
- ndir = 0;
+ make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
+ dirsize = 1;
+ dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
+ ndir = 0;

- saved_command_line = (char *) xstrdup ("");
+ 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. */
- setvbuf (stderr, NULL, _IONBF, BUFSIZ);
+ /* Ensure stderr is unbuffered. A Cygwin pty or pipe is implemented
+ as a Windows pipe, and Windows buffers on pipes. */
+ setvbuf (stderr, NULL, _IONBF, BUFSIZ);
#endif

- main_ui = new_ui (stdin, stdout, stderr);
- current_ui = main_ui;
+ main_ui = new_ui (stdin, stdout, stderr);
+ current_ui = main_ui;

- gdb_stdtargerr = gdb_stderr; /* for moment */
- gdb_stdtargin = gdb_stdin; /* for moment */
+ gdb_stdtargerr = gdb_stderr; /* for moment */
+ gdb_stdtargin = gdb_stdin; /* for moment */

#ifdef __MINGW32__
- /* On Windows, argv[0] is not necessarily set to absolute form when
- GDB is found along PATH, without which relocation doesn't work. */
- gdb_program_name = windows_get_absolute_argv0 (argv[0]);
+ /* On Windows, argv[0] is not necessarily set to absolute form when
+ GDB is found along PATH, without which relocation doesn't work. */
+ gdb_program_name = windows_get_absolute_argv0 (argv[0]);
#else
- gdb_program_name = xstrdup (argv[0]);
+ gdb_program_name = xstrdup (argv[0]);
#endif

- /* Prefix warning messages with the command name. */
- warning_pre_print = xstrprintf ("%s: warning: ", gdb_program_name);
+ /* Prefix warning messages with the command name. */
+ warning_pre_print = xstrprintf ("%s: warning: ", gdb_program_name);

- if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
- perror_warning_with_name (_("error finding working directory"));
+ if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
+ perror_warning_with_name (_("error finding working directory"));

- current_directory = gdb_dirbuf;
+ current_directory = gdb_dirbuf;

- /* Set the sysroot path. */
- gdb_sysroot = relocate_gdb_directory (TARGET_SYSTEM_ROOT,
- TARGET_SYSTEM_ROOT_RELOCATABLE);
+ /* Set the sysroot path. */
+ gdb_sysroot = relocate_gdb_directory (TARGET_SYSTEM_ROOT,
+ TARGET_SYSTEM_ROOT_RELOCATABLE);

- if (gdb_sysroot == NULL || *gdb_sysroot == '\0')
- {
- xfree (gdb_sysroot);
- gdb_sysroot = xstrdup (TARGET_SYSROOT_PREFIX);
- }
+ if (gdb_sysroot == NULL || *gdb_sysroot == '\0')
+ {
+ xfree (gdb_sysroot);
+ gdb_sysroot = xstrdup (TARGET_SYSROOT_PREFIX);
+ }

- debug_file_directory = relocate_gdb_directory (DEBUGDIR,
- DEBUGDIR_RELOCATABLE);
+ debug_file_directory = relocate_gdb_directory (DEBUGDIR,
+ DEBUGDIR_RELOCATABLE);

- gdb_datadir = relocate_gdb_directory (GDB_DATADIR,
- GDB_DATADIR_RELOCATABLE);
+ gdb_datadir = relocate_gdb_directory (GDB_DATADIR,
+ GDB_DATADIR_RELOCATABLE);

#ifdef WITH_PYTHON_PATH
- {
- /* For later use in helping Python find itself. */
- char *tmp = concat (WITH_PYTHON_PATH, SLASH_STRING, "lib", (char *) NULL);
+ {
+ /* For later use in helping Python find itself. */
+ char *tmp = concat (WITH_PYTHON_PATH, SLASH_STRING, "lib", (char *) NULL);

- python_libdir = relocate_gdb_directory (tmp, PYTHON_PATH_RELOCATABLE);
- xfree (tmp);
- }
+ python_libdir = relocate_gdb_directory (tmp, PYTHON_PATH_RELOCATABLE);
+ xfree (tmp);
+ }
#endif

#ifdef RELOC_SRCDIR
- add_substitute_path_rule (RELOC_SRCDIR,
- make_relative_prefix (gdb_program_name, BINDIR,
- RELOC_SRCDIR));
+ add_substitute_path_rule (RELOC_SRCDIR,
+ make_relative_prefix (gdb_program_name, BINDIR,
+ RELOC_SRCDIR));
#endif

- /* There will always be an interpreter. Either the one passed into
- this captured main, or one specified by the user at start up, or
- the console. Initialize the interpreter to the one requested by
- the application. */
- interpreter_p = xstrdup (context->interpreter_p);
+ /* There will always be an interpreter. Either the one passed into
+ this captured main, or one specified by the user at start up, or
+ the console. Initialize the interpreter to the one requested by
+ the application. */
+ interpreter_p = xstrdup (context->interpreter_p);

- /* Parse arguments and options. */
- {
- int c;
- /* When var field is 0, use flag field to record the equivalent
- short option (or arbitrary numbers starting at 10 for those
- with no equivalent). */
- enum {
- OPT_SE = 10,
- OPT_CD,
- OPT_ANNOTATE,
- OPT_STATISTICS,
- OPT_TUI,
- OPT_NOWINDOWS,
- OPT_WINDOWS,
- OPT_IX,
- OPT_IEX
- };
- static struct option long_options[] =
+ /* Parse arguments and options. */
{
- {"tui", no_argument, 0, OPT_TUI},
- {"dbx", no_argument, &dbx_commands, 1},
- {"readnow", no_argument, &readnow_symbol_files, 1},
- {"r", no_argument, &readnow_symbol_files, 1},
- {"quiet", no_argument, &quiet, 1},
- {"q", no_argument, &quiet, 1},
- {"silent", no_argument, &quiet, 1},
- {"nh", no_argument, &inhibit_home_gdbinit, 1},
- {"nx", no_argument, &inhibit_gdbinit, 1},
- {"n", no_argument, &inhibit_gdbinit, 1},
- {"batch-silent", no_argument, 0, 'B'},
- {"batch", no_argument, &batch_flag, 1},
-
- /* This is a synonym for "--annotate=1". --annotate is now
- preferred, but keep this here for a long time because people
- will be running emacses which use --fullname. */
- {"fullname", no_argument, 0, 'f'},
- {"f", no_argument, 0, 'f'},
-
- {"annotate", required_argument, 0, OPT_ANNOTATE},
- {"help", no_argument, &print_help, 1},
- {"se", required_argument, 0, OPT_SE},
- {"symbols", required_argument, 0, 's'},
- {"s", required_argument, 0, 's'},
- {"exec", required_argument, 0, 'e'},
- {"e", required_argument, 0, 'e'},
- {"core", required_argument, 0, 'c'},
- {"c", required_argument, 0, 'c'},
- {"pid", required_argument, 0, 'p'},
- {"p", required_argument, 0, 'p'},
- {"command", required_argument, 0, 'x'},
- {"eval-command", required_argument, 0, 'X'},
- {"version", no_argument, &print_version, 1},
- {"configuration", no_argument, &print_configuration, 1},
- {"x", required_argument, 0, 'x'},
- {"ex", required_argument, 0, 'X'},
- {"init-command", required_argument, 0, OPT_IX},
- {"init-eval-command", required_argument, 0, OPT_IEX},
- {"ix", required_argument, 0, OPT_IX},
- {"iex", required_argument, 0, OPT_IEX},
+ int c;
+ /* When var field is 0, use flag field to record the equivalent
+ short option (or arbitrary numbers starting at 10 for those
+ with no equivalent). */
+ enum {
+ OPT_SE = 10,
+ OPT_CD,
+ OPT_ANNOTATE,
+ OPT_STATISTICS,
+ OPT_TUI,
+ OPT_NOWINDOWS,
+ OPT_WINDOWS,
+ OPT_IX,
+ OPT_IEX
+ };
+ static struct option long_options[] =
+ {
+ {"tui", no_argument, 0, OPT_TUI},
+ {"dbx", no_argument, &dbx_commands, 1},
+ {"readnow", no_argument, &readnow_symbol_files, 1},
+ {"r", no_argument, &readnow_symbol_files, 1},
+ {"quiet", no_argument, &quiet, 1},
+ {"q", no_argument, &quiet, 1},
+ {"silent", no_argument, &quiet, 1},
+ {"nh", no_argument, &inhibit_home_gdbinit, 1},
+ {"nx", no_argument, &inhibit_gdbinit, 1},
+ {"n", no_argument, &inhibit_gdbinit, 1},
+ {"batch-silent", no_argument, 0, 'B'},
+ {"batch", no_argument, &batch_flag, 1},
+
+ /* This is a synonym for "--annotate=1". --annotate is now
+ preferred, but keep this here for a long time because people
+ will be running emacses which use --fullname. */
+ {"fullname", no_argument, 0, 'f'},
+ {"f", no_argument, 0, 'f'},
+
+ {"annotate", required_argument, 0, OPT_ANNOTATE},
+ {"help", no_argument, &print_help, 1},
+ {"se", required_argument, 0, OPT_SE},
+ {"symbols", required_argument, 0, 's'},
+ {"s", required_argument, 0, 's'},
+ {"exec", required_argument, 0, 'e'},
+ {"e", required_argument, 0, 'e'},
+ {"core", required_argument, 0, 'c'},
+ {"c", required_argument, 0, 'c'},
+ {"pid", required_argument, 0, 'p'},
+ {"p", required_argument, 0, 'p'},
+ {"command", required_argument, 0, 'x'},
+ {"eval-command", required_argument, 0, 'X'},
+ {"version", no_argument, &print_version, 1},
+ {"configuration", no_argument, &print_configuration, 1},
+ {"x", required_argument, 0, 'x'},
+ {"ex", required_argument, 0, 'X'},
+ {"init-command", required_argument, 0, OPT_IX},
+ {"init-eval-command", required_argument, 0, OPT_IEX},
+ {"ix", required_argument, 0, OPT_IX},
+ {"iex", required_argument, 0, OPT_IEX},
#ifdef GDBTK
- {"tclcommand", required_argument, 0, 'z'},
- {"enable-external-editor", no_argument, 0, 'y'},
- {"editor-command", required_argument, 0, 'w'},
+ {"tclcommand", required_argument, 0, 'z'},
+ {"enable-external-editor", no_argument, 0, 'y'},
+ {"editor-command", required_argument, 0, 'w'},
#endif
- {"ui", required_argument, 0, 'i'},
- {"interpreter", required_argument, 0, 'i'},
- {"i", required_argument, 0, 'i'},
- {"directory", required_argument, 0, 'd'},
- {"d", required_argument, 0, 'd'},
- {"data-directory", required_argument, 0, 'D'},
- {"D", required_argument, 0, 'D'},
- {"cd", required_argument, 0, OPT_CD},
- {"tty", required_argument, 0, 't'},
- {"baud", required_argument, 0, 'b'},
- {"b", required_argument, 0, 'b'},
- {"nw", no_argument, NULL, OPT_NOWINDOWS},
- {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
- {"w", no_argument, NULL, OPT_WINDOWS},
- {"windows", no_argument, NULL, OPT_WINDOWS},
- {"statistics", no_argument, 0, OPT_STATISTICS},
- {"write", no_argument, &write_files, 1},
- {"args", no_argument, &set_args, 1},
- {"l", required_argument, 0, 'l'},
- {"return-child-result", no_argument, &return_child_result, 1},
- {0, no_argument, 0, 0}
- };
-
- while (1)
- {
- int option_index;
+ {"ui", required_argument, 0, 'i'},
+ {"interpreter", required_argument, 0, 'i'},
+ {"i", required_argument, 0, 'i'},
+ {"directory", required_argument, 0, 'd'},
+ {"d", required_argument, 0, 'd'},
+ {"data-directory", required_argument, 0, 'D'},
+ {"D", required_argument, 0, 'D'},
+ {"cd", required_argument, 0, OPT_CD},
+ {"tty", required_argument, 0, 't'},
+ {"baud", required_argument, 0, 'b'},
+ {"b", required_argument, 0, 'b'},
+ {"nw", no_argument, NULL, OPT_NOWINDOWS},
+ {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
+ {"w", no_argument, NULL, OPT_WINDOWS},
+ {"windows", no_argument, NULL, OPT_WINDOWS},
+ {"statistics", no_argument, 0, OPT_STATISTICS},
+ {"write", no_argument, &write_files, 1},
+ {"args", no_argument, &set_args, 1},
+ {"l", required_argument, 0, 'l'},
+ {"return-child-result", no_argument, &return_child_result, 1},
+ {0, no_argument, 0, 0}
+ };
+
+ while (1)
+ {
+ int option_index;

- c = getopt_long_only (argc, argv, "",
- long_options, &option_index);
- if (c == EOF || set_args)
- break;
+ c = getopt_long_only (argc, argv, "",
+ long_options, &option_index);
+ if (c == EOF || set_args)
+ break;

- /* Long option that takes an argument. */
- if (c == 0 && long_options[option_index].flag == 0)
- c = long_options[option_index].val;
+ /* Long option that takes an argument. */
+ if (c == 0 && long_options[option_index].flag == 0)
+ c = long_options[option_index].val;

- switch (c)
- {
- case 0:
- /* Long option that just sets a flag. */
- break;
- case OPT_SE:
- symarg = optarg;
- execarg = optarg;
- break;
- case OPT_CD:
- cdarg = optarg;
- break;
- case OPT_ANNOTATE:
- /* FIXME: what if the syntax is wrong (e.g. not digits)? */
- annotation_level = atoi (optarg);
- break;
- case OPT_STATISTICS:
- /* Enable the display of both time and space usage. */
- set_per_command_time (1);
- set_per_command_space (1);
- break;
- case OPT_TUI:
- /* --tui is equivalent to -i=tui. */
+ switch (c)
+ {
+ case 0:
+ /* Long option that just sets a flag. */
+ break;
+ case OPT_SE:
+ symarg = optarg;
+ execarg = optarg;
+ break;
+ case OPT_CD:
+ cdarg = optarg;
+ break;
+ case OPT_ANNOTATE:
+ /* FIXME: what if the syntax is wrong (e.g. not digits)? */
+ annotation_level = atoi (optarg);
+ break;
+ case OPT_STATISTICS:
+ /* Enable the display of both time and space usage. */
+ set_per_command_time (1);
+ set_per_command_space (1);
+ break;
+ case OPT_TUI:
+ /* --tui is equivalent to -i=tui. */
#ifdef TUI
- xfree (interpreter_p);
- interpreter_p = xstrdup (INTERP_TUI);
+ xfree (interpreter_p);
+ interpreter_p = xstrdup (INTERP_TUI);
#else
- error (_("%s: TUI mode is not supported"), gdb_program_name);
+ error (_("%s: TUI mode is not supported"), gdb_program_name);
#endif
- break;
- case OPT_WINDOWS:
- /* FIXME: cagney/2003-03-01: Not sure if this option is
- actually useful, and if it is, what it should do. */
+ break;
+ case OPT_WINDOWS:
+ /* FIXME: cagney/2003-03-01: Not sure if this option is
+ actually useful, and if it is, what it should do. */
#ifdef GDBTK
- /* --windows is equivalent to -i=insight. */
- xfree (interpreter_p);
- interpreter_p = xstrdup (INTERP_INSIGHT);
+ /* --windows is equivalent to -i=insight. */
+ xfree (interpreter_p);
+ interpreter_p = xstrdup (INTERP_INSIGHT);
#endif
- break;
- case OPT_NOWINDOWS:
- /* -nw is equivalent to -i=console. */
- xfree (interpreter_p);
- interpreter_p = xstrdup (INTERP_CONSOLE);
- break;
- case 'f':
- annotation_level = 1;
- break;
- case 's':
- symarg = optarg;
- break;
- case 'e':
- execarg = optarg;
- break;
- case 'c':
- corearg = optarg;
- break;
- case 'p':
- pidarg = optarg;
- break;
- case 'x':
- {
- struct cmdarg cmdarg = { CMDARG_FILE, optarg };
+ break;
+ case OPT_NOWINDOWS:
+ /* -nw is equivalent to -i=console. */
+ xfree (interpreter_p);
+ interpreter_p = xstrdup (INTERP_CONSOLE);
+ break;
+ case 'f':
+ annotation_level = 1;
+ break;
+ case 's':
+ symarg = optarg;
+ break;
+ case 'e':
+ execarg = optarg;
+ break;
+ case 'c':
+ corearg = optarg;
+ break;
+ case 'p':
+ pidarg = optarg;
+ break;
+ case 'x':
+ {
+ struct cmdarg cmdarg = { CMDARG_FILE, optarg };

- VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
- }
- break;
- case 'X':
- {
- struct cmdarg cmdarg = { CMDARG_COMMAND, optarg };
+ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+ }
+ break;
+ case 'X':
+ {
+ struct cmdarg cmdarg = { CMDARG_COMMAND, optarg };

- VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
- }
- break;
- case OPT_IX:
- {
- struct cmdarg cmdarg = { CMDARG_INIT_FILE, optarg };
+ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+ }
+ break;
+ case OPT_IX:
+ {
+ struct cmdarg cmdarg = { CMDARG_INIT_FILE, optarg };

- VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
- }
- break;
- case OPT_IEX:
- {
- struct cmdarg cmdarg = { CMDARG_INIT_COMMAND, optarg };
+ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+ }
+ break;
+ case OPT_IEX:
+ {
+ struct cmdarg cmdarg = { CMDARG_INIT_COMMAND, optarg };

- VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
- }
- break;
- case 'B':
- batch_flag = batch_silent = 1;
- gdb_stdout = ui_file_new();
- break;
- case 'D':
- if (optarg[0] == '\0')
- error (_("%s: empty path for `--data-directory'"),
- gdb_program_name);
- set_gdb_data_directory (optarg);
- gdb_datadir_provided = 1;
- break;
+ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+ }
+ break;
+ case 'B':
+ batch_flag = batch_silent = 1;
+ gdb_stdout = ui_file_new();
+ break;
+ case 'D':
+ if (optarg[0] == '\0')
+ error (_("%s: empty path for `--data-directory'"),
+ gdb_program_name);
+ set_gdb_data_directory (optarg);
+ gdb_datadir_provided = 1;
+ break;
#ifdef GDBTK
- case 'z':
- {
- extern int gdbtk_test (char *);
+ case 'z':
+ {
+ extern int gdbtk_test (char *);

- if (!gdbtk_test (optarg))
- error (_("%s: unable to load tclcommand file \"%s\""),
- gdb_program_name, optarg);
+ if (!gdbtk_test (optarg))
+ error (_("%s: unable to load tclcommand file \"%s\""),
+ gdb_program_name, optarg);
+ break;
+ }
+ case 'y':
+ /* Backwards compatibility only. */
break;
- }
- case 'y':
- /* Backwards compatibility only. */
- break;
- case 'w':
- {
- /* Set the external editor commands when gdb is farming out files
- to be edited by another program. */
- extern char *external_editor_command;
+ case 'w':
+ {
+ /* Set the external editor commands when gdb is farming out files
+ to be edited by another program. */
+ extern char *external_editor_command;

- external_editor_command = xstrdup (optarg);
- break;
- }
+ external_editor_command = xstrdup (optarg);
+ break;
+ }
#endif /* GDBTK */
- case 'i':
- xfree (interpreter_p);
- interpreter_p = xstrdup (optarg);
- break;
- case 'd':
- dirarg[ndir++] = optarg;
- if (ndir >= dirsize)
+ case 'i':
+ xfree (interpreter_p);
+ interpreter_p = xstrdup (optarg);
+ break;
+ case 'd':
+ dirarg[ndir++] = optarg;
+ if (ndir >= dirsize)
+ {
+ dirsize *= 2;
+ dirarg = (char **) xrealloc ((char *) dirarg,
+ dirsize * sizeof (*dirarg));
+ }
+ break;
+ case 't':
+ ttyarg = optarg;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 'b':
{
- dirsize *= 2;
- dirarg = (char **) xrealloc ((char *) dirarg,
- dirsize * sizeof (*dirarg));
+ int i;
+ char *p;
+
+ i = strtol (optarg, &p, 0);
+ if (i == 0 && p == optarg)
+ warning (_("could not set baud rate to `%s'."),
+ optarg);
+ else
+ baud_rate = i;
}
- break;
- case 't':
- ttyarg = optarg;
- break;
- case 'q':
- quiet = 1;
- break;
- case 'b':
- {
- int i;
- char *p;
-
- i = strtol (optarg, &p, 0);
- if (i == 0 && p == optarg)
- warning (_("could not set baud rate to `%s'."),
- optarg);
- else
- baud_rate = i;
- }
- break;
- case 'l':
- {
- int i;
- char *p;
+ break;
+ case 'l':
+ {
+ int i;
+ char *p;
+
+ i = strtol (optarg, &p, 0);
+ if (i == 0 && p == optarg)
+ warning (_("could not set timeout limit to `%s'."),
+ optarg);
+ else
+ remote_timeout = i;
+ }
+ break;

- i = strtol (optarg, &p, 0);
- if (i == 0 && p == optarg)
- warning (_("could not set timeout limit to `%s'."),
- optarg);
- else
- remote_timeout = i;
+ case '?':
+ error (_("Use `%s --help' for a complete list of options."),
+ gdb_program_name);
}
- break;
-
- case '?':
- error (_("Use `%s --help' for a complete list of options."),
- gdb_program_name);
- }
- }
+ }

- if (batch_flag)
- quiet = 1;
- }
+ if (batch_flag)
+ quiet = 1;
+ }

- /* Try to set up an alternate signal stack for SIGSEGV handlers. */
- setup_alternate_signal_stack ();
+ /* Try to set up an alternate signal stack for SIGSEGV handlers. */
+ setup_alternate_signal_stack ();

- /* Initialize all files. */
- gdb_init (gdb_program_name);
+ /* Initialize all files. */
+ gdb_init (gdb_program_name);

- /* Now that gdb_init has created the initial inferior, we're in
- position to set args for that inferior. */
- if (set_args)
- {
- /* The remaining options are the command-line options for the
- inferior. The first one is the sym/exec file, and the rest
- are arguments. */
- if (optind >= argc)
- error (_("%s: `--args' specified but no program specified"),
- gdb_program_name);
-
- symarg = argv[optind];
- execarg = argv[optind];
- ++optind;
- set_inferior_args_vector (argc - optind, &argv[optind]);
- }
- else
- {
- /* OK, that's all the options. */
+ /* Now that gdb_init has created the initial inferior, we're in
+ position to set args for that inferior. */
+ if (set_args)
+ {
+ /* The remaining options are the command-line options for the
+ inferior. The first one is the sym/exec file, and the rest
+ are arguments. */
+ if (optind >= argc)
+ error (_("%s: `--args' specified but no program specified"),
+ gdb_program_name);
+
+ symarg = argv[optind];
+ execarg = argv[optind];
+ ++optind;
+ set_inferior_args_vector (argc - optind, &argv[optind]);
+ }
+ else
+ {
+ /* OK, that's all the options. */

- /* The first argument, if specified, is the name of the
- executable. */
- if (optind < argc)
- {
- symarg = argv[optind];
- execarg = argv[optind];
- optind++;
- }
+ /* The first argument, if specified, is the name of the
+ executable. */
+ if (optind < argc)
+ {
+ symarg = argv[optind];
+ execarg = argv[optind];
+ optind++;
+ }

- /* If the user hasn't already specified a PID or the name of a
- core file, then a second optional argument is allowed. If
- present, this argument should be interpreted as either a
- PID or a core file, whichever works. */
- if (pidarg == NULL && corearg == NULL && optind < argc)
- {
- pid_or_core_arg = argv[optind];
- optind++;
- }
+ /* If the user hasn't already specified a PID or the name of a
+ core file, then a second optional argument is allowed. If
+ present, this argument should be interpreted as either a
+ PID or a core file, whichever works. */
+ if (pidarg == NULL && corearg == NULL && optind < argc)
+ {
+ pid_or_core_arg = argv[optind];
+ optind++;
+ }

- /* Any argument left on the command line is unexpected and
- will be ignored. Inform the user. */
- if (optind < argc)
- fprintf_unfiltered (gdb_stderr,
- _("Excess command line "
- "arguments ignored. (%s%s)\n"),
- argv[optind],
- (optind == argc - 1) ? "" : " ...");
- }
+ /* Any argument left on the command line is unexpected and
+ will be ignored. Inform the user. */
+ if (optind < argc)
+ fprintf_unfiltered (gdb_stderr,
+ _("Excess command line "
+ "arguments ignored. (%s%s)\n"),
+ argv[optind],
+ (optind == argc - 1) ? "" : " ...");
+ }

- /* Lookup gdbinit files. Note that the gdbinit file name may be
- overriden during file initialization, so get_init_files should be
- called after gdb_init. */
- get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
+ /* Lookup gdbinit files. Note that the gdbinit file name may be
+ overriden during file initialization, so get_init_files should be
+ called after gdb_init. */
+ get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);

- /* Do these (and anything which might call wrap_here or *_filtered)
- after initialize_all_files() but before the interpreter has been
- installed. Otherwize the help/version messages will be eaten by
- the interpreter's output handler. */
+ /* Do these (and anything which might call wrap_here or *_filtered)
+ after initialize_all_files() but before the interpreter has been
+ installed. Otherwize the help/version messages will be eaten by
+ the interpreter's output handler. */

- if (print_version)
- {
- print_gdb_version (gdb_stdout);
- wrap_here ("");
- printf_filtered ("\n");
- exit (0);
- }
+ if (print_version)
+ {
+ print_gdb_version (gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("\n");
+ exit (0);
+ }

- if (print_help)
- {
- print_gdb_help (gdb_stdout);
- fputs_unfiltered ("\n", gdb_stdout);
- exit (0);
- }
+ if (print_help)
+ {
+ print_gdb_help (gdb_stdout);
+ fputs_unfiltered ("\n", gdb_stdout);
+ exit (0);
+ }

- if (print_configuration)
- {
- print_gdb_configuration (gdb_stdout);
- wrap_here ("");
- printf_filtered ("\n");
- exit (0);
- }
+ if (print_configuration)
+ {
+ print_gdb_configuration (gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("\n");
+ exit (0);
+ }

- /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
- GDB retain the old MI1 interpreter startup behavior. Output the
- copyright message before the interpreter is installed. That way
- it isn't encapsulated in MI output. */
- if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
- {
- /* Print all the junk at the top, with trailing "..." if we are
- about to read a symbol file (possibly slowly). */
- print_gdb_version (gdb_stdout);
- if (symarg)
- printf_filtered ("..");
- wrap_here ("");
- printf_filtered ("\n");
- gdb_flush (gdb_stdout); /* Force to screen during slow
+ /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
+ GDB retain the old MI1 interpreter startup behavior. Output the
+ copyright message before the interpreter is installed. That way
+ it isn't encapsulated in MI output. */
+ if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
+ {
+ /* Print all the junk at the top, with trailing "..." if we are
+ about to read a symbol file (possibly slowly). */
+ print_gdb_version (gdb_stdout);
+ if (symarg)
+ printf_filtered ("..");
+ wrap_here ("");
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout); /* Force to screen during slow
operations. */
- }
+ }

- /* Install the default UI. All the interpreters should have had a
- look at things by now. Initialize the default interpreter. */
- set_top_level_interpreter (interpreter_p);
+ /* Install the default UI. All the interpreters should have had a
+ look at things by now. Initialize the default interpreter. */
+ set_top_level_interpreter (interpreter_p);

- /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
- GDB retain the old MI1 interpreter startup behavior. Output the
- copyright message after the interpreter is installed when it is
- any sane interpreter. */
- if (!quiet && !current_interp_named_p (INTERP_MI1))
- {
- /* Print all the junk at the top, with trailing "..." if we are
- about to read a symbol file (possibly slowly). */
- print_gdb_version (gdb_stdout);
- if (symarg)
- printf_filtered ("..");
- wrap_here ("");
- printf_filtered ("\n");
- gdb_flush (gdb_stdout); /* Force to screen during slow
+ /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
+ GDB retain the old MI1 interpreter startup behavior. Output the
+ copyright message after the interpreter is installed when it is
+ any sane interpreter. */
+ if (!quiet && !current_interp_named_p (INTERP_MI1))
+ {
+ /* Print all the junk at the top, with trailing "..." if we are
+ about to read a symbol file (possibly slowly). */
+ print_gdb_version (gdb_stdout);
+ if (symarg)
+ printf_filtered ("..");
+ wrap_here ("");
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout); /* Force to screen during slow
operations. */
- }
+ }

- /* Set off error and warning messages with a blank line. */
- xfree (warning_pre_print);
- warning_pre_print = _("\nwarning: ");
+ /* Set off error and warning messages with a blank line. */
+ xfree (warning_pre_print);
+ warning_pre_print = _("\nwarning: ");

- /* Read and execute the system-wide gdbinit file, if it exists.
- This is done *before* all the command line arguments are
- processed; it sets global parameters, which are independent of
- what file you are debugging or what directory you are in. */
- if (system_gdbinit && !inhibit_gdbinit)
- catch_command_errors_const (source_script, system_gdbinit, 0);
+ /* Read and execute the system-wide gdbinit file, if it exists.
+ This is done *before* all the command line arguments are
+ processed; it sets global parameters, which are independent of
+ what file you are debugging or what directory you are in. */
+ if (system_gdbinit && !inhibit_gdbinit)
+ catch_command_errors_const (source_script, system_gdbinit, 0);

- /* Read and execute $HOME/.gdbinit file, if it exists. This is done
+ /* Read and execute $HOME/.gdbinit file, if it exists. This is done
*before* all the command line arguments are processed; it sets
global parameters, which are independent of what file you are
debugging or what directory you are in. */

- if (home_gdbinit && !inhibit_gdbinit && !inhibit_home_gdbinit)
- catch_command_errors_const (source_script, home_gdbinit, 0);
-
- /* Process '-ix' and '-iex' options early. */
- for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
- switch (cmdarg_p->type)
- {
- case CMDARG_INIT_FILE:
- catch_command_errors_const (source_script, cmdarg_p->string,
- !batch_flag);
- break;
- case CMDARG_INIT_COMMAND:
- catch_command_errors (execute_command, cmdarg_p->string,
- !batch_flag);
- break;
- }
+ if (home_gdbinit && !inhibit_gdbinit && !inhibit_home_gdbinit)
+ catch_command_errors_const (source_script, home_gdbinit, 0);

- /* Now perform all the actions indicated by the arguments. */
- if (cdarg != NULL)
- {
- catch_command_errors (cd_command, cdarg, 0);
- }
+ /* Process '-ix' and '-iex' options early. */
+ for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
+ switch (cmdarg_p->type)
+ {
+ case CMDARG_INIT_FILE:
+ catch_command_errors_const (source_script, cmdarg_p->string,
+ !batch_flag);
+ break;
+ case CMDARG_INIT_COMMAND:
+ catch_command_errors (execute_command, cmdarg_p->string,
+ !batch_flag);
+ break;
+ }

- for (i = 0; i < ndir; i++)
- catch_command_errors (directory_switch, dirarg[i], 0);
- xfree (dirarg);
+ /* Now perform all the actions indicated by the arguments. */
+ if (cdarg != NULL)
+ {
+ catch_command_errors (cd_command, cdarg, 0);
+ }

- /* Skip auto-loading section-specified scripts until we've sourced
- local_gdbinit (which is often used to augment the source search
- path). */
- save_auto_load = global_auto_load;
- global_auto_load = 0;
+ for (i = 0; i < ndir; i++)
+ catch_command_errors (directory_switch, dirarg[i], 0);
+ xfree (dirarg);

- if (execarg != NULL
- && symarg != NULL
- && strcmp (execarg, symarg) == 0)
- {
- /* The exec file and the symbol-file are the same. If we can't
- open it, better only print one error message.
- catch_command_errors returns non-zero on success! */
- if (catch_command_errors_const (exec_file_attach, execarg,
- !batch_flag))
- catch_command_errors_const (symbol_file_add_main, symarg,
- !batch_flag);
- }
- else
- {
- if (execarg != NULL)
- catch_command_errors_const (exec_file_attach, execarg,
- !batch_flag);
- if (symarg != NULL)
- catch_command_errors_const (symbol_file_add_main, symarg,
- !batch_flag);
- }
+ /* Skip auto-loading section-specified scripts until we've sourced
+ local_gdbinit (which is often used to augment the source search
+ path). */
+ save_auto_load = global_auto_load;
+ global_auto_load = 0;

- if (corearg && pidarg)
- error (_("Can't attach to process and specify "
- "a core file at the same time."));
+ if (execarg != NULL
+ && symarg != NULL
+ && strcmp (execarg, symarg) == 0)
+ {
+ /* The exec file and the symbol-file are the same. If we can't
+ open it, better only print one error message.
+ catch_command_errors returns non-zero on success! */
+ if (catch_command_errors_const (exec_file_attach, execarg,
+ !batch_flag))
+ catch_command_errors_const (symbol_file_add_main, symarg,
+ !batch_flag);
+ }
+ else
+ {
+ if (execarg != NULL)
+ catch_command_errors_const (exec_file_attach, execarg,
+ !batch_flag);
+ if (symarg != NULL)
+ catch_command_errors_const (symbol_file_add_main, symarg,
+ !batch_flag);
+ }

- if (corearg != NULL)
- catch_command_errors (core_file_command, corearg, !batch_flag);
- else if (pidarg != NULL)
- catch_command_errors (attach_command, pidarg, !batch_flag);
- else if (pid_or_core_arg)
- {
- /* The user specified 'gdb program pid' or gdb program core'.
- If pid_or_core_arg's first character is a digit, try attach
- first and then corefile. Otherwise try just corefile. */
+ if (corearg && pidarg)
+ error (_("Can't attach to process and specify "
+ "a core file at the same time."));

- if (isdigit (pid_or_core_arg[0]))
- {
- if (catch_command_errors (attach_command, pid_or_core_arg,
- !batch_flag) == 0)
- catch_command_errors (core_file_command, pid_or_core_arg,
- !batch_flag);
- }
- else /* Can't be a pid, better be a corefile. */
- catch_command_errors (core_file_command, pid_or_core_arg,
- !batch_flag);
- }
+ if (corearg != NULL)
+ catch_command_errors (core_file_command, corearg, !batch_flag);
+ else if (pidarg != NULL)
+ catch_command_errors (attach_command, pidarg, !batch_flag);
+ else if (pid_or_core_arg)
+ {
+ /* The user specified 'gdb program pid' or gdb program core'.
+ If pid_or_core_arg's first character is a digit, try attach
+ first and then corefile. Otherwise try just corefile. */

- if (ttyarg != NULL)
- set_inferior_io_terminal (ttyarg);
+ if (isdigit (pid_or_core_arg[0]))
+ {
+ if (catch_command_errors (attach_command, pid_or_core_arg,
+ !batch_flag) == 0)
+ catch_command_errors (core_file_command, pid_or_core_arg,
+ !batch_flag);
+ }
+ else /* Can't be a pid, better be a corefile. */
+ catch_command_errors (core_file_command, pid_or_core_arg,
+ !batch_flag);
+ }

- /* Error messages should no longer be distinguished with extra output. */
- warning_pre_print = _("warning: ");
+ if (ttyarg != NULL)
+ set_inferior_io_terminal (ttyarg);

- /* Read the .gdbinit file in the current directory, *if* it isn't
- the same as the $HOME/.gdbinit file (it should exist, also). */
- if (local_gdbinit)
- {
- auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit);
+ /* Error messages should no longer be distinguished with extra output. */
+ warning_pre_print = _("warning: ");

- if (!inhibit_gdbinit && auto_load_local_gdbinit
- && file_is_auto_load_safe (local_gdbinit,
- _("auto-load: Loading .gdbinit "
- "file \"%s\".\n"),
- local_gdbinit))
- {
- auto_load_local_gdbinit_loaded = 1;
+ /* Read the .gdbinit file in the current directory, *if* it isn't
+ the same as the $HOME/.gdbinit file (it should exist, also). */
+ if (local_gdbinit)
+ {
+ auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit);

- catch_command_errors_const (source_script, local_gdbinit, 0);
- }
- }
+ if (!inhibit_gdbinit && auto_load_local_gdbinit
+ && file_is_auto_load_safe (local_gdbinit,
+ _("auto-load: Loading .gdbinit "
+ "file \"%s\".\n"),
+ local_gdbinit))
+ {
+ auto_load_local_gdbinit_loaded = 1;

- /* Now that all .gdbinit's have been read and all -d options have been
- processed, we can read any scripts mentioned in SYMARG.
- We wait until now because it is common to add to the source search
- path in local_gdbinit. */
- global_auto_load = save_auto_load;
- ALL_OBJFILES (objfile)
- load_auto_scripts_for_objfile (objfile);
-
- /* Process '-x' and '-ex' options. */
- for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
- switch (cmdarg_p->type)
- {
- case CMDARG_FILE:
- catch_command_errors_const (source_script, cmdarg_p->string,
- !batch_flag);
- break;
- case CMDARG_COMMAND:
- catch_command_errors (execute_command, cmdarg_p->string,
- !batch_flag);
- break;
- }
+ catch_command_errors_const (source_script, local_gdbinit, 0);
+ }
+ }

- /* Read in the old history after all the command files have been
- read. */
- init_history ();
+ /* Now that all .gdbinit's have been read and all -d options have been
+ processed, we can read any scripts mentioned in SYMARG.
+ We wait until now because it is common to add to the source search
+ path in local_gdbinit. */
+ global_auto_load = save_auto_load;
+ ALL_OBJFILES (objfile)
+ load_auto_scripts_for_objfile (objfile);
+
+ /* Process '-x' and '-ex' options. */
+ for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
+ switch (cmdarg_p->type)
+ {
+ case CMDARG_FILE:
+ catch_command_errors_const (source_script, cmdarg_p->string,
+ !batch_flag);
+ break;
+ case CMDARG_COMMAND:
+ catch_command_errors (execute_command, cmdarg_p->string,
+ !batch_flag);
+ break;
+ }

- if (batch_flag)
- {
- /* We have hit the end of the batch file. */
- quit_force (NULL, 0);
- }
+ /* Read in the old history after all the command files have been
+ read. */
+ init_history ();

- /* Show time and/or space usage. */
- do_cleanups (pre_stat_chain);
+ if (batch_flag)
+ {
+ /* We have hit the end of the batch file. */
+ quit_force (NULL, 0);
+ }
+ }

/* NOTE: cagney/1999-11-07: There is probably no reason for not
moving this loop and the code found in captured_command_loop()
diff --git a/gdb/maint.c b/gdb/maint.c
index d2c9346..dad13fa 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -752,31 +752,6 @@ static int per_command_symtab;
static struct cmd_list_element *per_command_setlist;
static struct cmd_list_element *per_command_showlist;

-/* Records a run time and space usage to be used as a base for
- reporting elapsed time or change in space. */
-
-struct cmd_stats
-{
- /* Zero if the saved time is from the beginning of GDB execution.
- One if from the beginning of an individual command execution. */
- int msg_type;
- /* Track whether the stat was enabled at the start of the command
- so that we can avoid printing anything if it gets turned on by
- the current command. */
- int time_enabled : 1;
- int space_enabled : 1;
- int symtab_enabled : 1;
- long start_cpu_time;
- struct timeval start_wall_time;
- long start_space;
- /* Total number of symtabs (over all objfiles). */
- int start_nr_symtabs;
- /* A count of the compunits. */
- int start_nr_compunit_symtabs;
- /* Total number of blocks. */
- int start_nr_blocks;
-};
-
/* Set whether to display time statistics to NEW_VALUE
(non-zero means true). */

@@ -827,25 +802,32 @@ count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
*nr_blocks_ptr = nr_blocks;
}

-/* As indicated by display_time and display_space, report GDB's elapsed time
- and space usage from the base time and space provided in ARG, which
- must be a pointer to a struct cmd_stat. This function is intended
- to be called as a cleanup. */
+/* As indicated by display_time and display_space, report GDB's
+ elapsed time and space usage from the base time and space recorded
+ in this object. */

-static void
-report_command_stats (void *arg)
+scoped_command_stats::~scoped_command_stats ()
{
- struct cmd_stats *start_stats = (struct cmd_stats *) arg;
- int msg_type = start_stats->msg_type;
+ /* Early exit if we're not reporting any stats. It can be expensive to
+ compute the pre-command values so don't collect them at all if we're
+ not reporting stats. Alas this doesn't work in the startup case because
+ we don't know yet whether we will be reporting the stats. For the
+ startup case collect the data anyway (it should be cheap at this point),
+ and leave it to the reporter to decide whether to print them. */
+ if (msg_type != 0
+ && !per_command_time
+ && !per_command_space
+ && !per_command_symtab)
+ return;

- if (start_stats->time_enabled && per_command_time)
+ if (this->time_enabled && per_command_time)
{
- long cmd_time = get_run_time () - start_stats->start_cpu_time;
+ long cmd_time = get_run_time () - this->start_cpu_time;
struct timeval now_wall_time, delta_wall_time, wait_time;

gettimeofday (&now_wall_time, NULL);
timeval_sub (&delta_wall_time,
- &now_wall_time, &start_stats->start_wall_time);
+ &now_wall_time, &this->start_wall_time);

/* Subtract time spend in prompt_for_continue from walltime. */
wait_time = get_prompt_for_continue_wait_time ();
@@ -859,13 +841,13 @@ report_command_stats (void *arg)
(long) delta_wall_time.tv_usec);
}

- if (start_stats->space_enabled && per_command_space)
+ if (this->space_enabled && per_command_space)
{
#ifdef HAVE_SBRK
char *lim = (char *) sbrk (0);

long space_now = lim - lim_at_start;
- long space_diff = space_now - start_stats->start_space;
+ long space_diff = space_now - this->start_space;

printf_unfiltered (msg_type == 0
? _("Space used: %ld (%s%ld during startup)\n")
@@ -876,7 +858,7 @@ report_command_stats (void *arg)
#endif
}

- if (start_stats->symtab_enabled && per_command_symtab)
+ if (this->symtab_enabled && per_command_symtab)
{
int nr_symtabs, nr_compunit_symtabs, nr_blocks;

@@ -885,54 +867,32 @@ report_command_stats (void *arg)
" #compunits: %d (+%d),"
" #blocks: %d (+%d)\n"),
nr_symtabs,
- nr_symtabs - start_stats->start_nr_symtabs,
+ nr_symtabs - this->start_nr_symtabs,
nr_compunit_symtabs,
(nr_compunit_symtabs
- - start_stats->start_nr_compunit_symtabs),
+ - this->start_nr_compunit_symtabs),
nr_blocks,
- nr_blocks - start_stats->start_nr_blocks);
+ nr_blocks - this->start_nr_blocks);
}
}

-/* Create a cleanup that reports time and space used since its creation.
- MSG_TYPE is zero for gdb startup, otherwise it is one(1) to report
- data for individual commands. */
-
-struct cleanup *
-make_command_stats_cleanup (int msg_type)
+scoped_command_stats::scoped_command_stats (int msg_type)
+: msg_type (msg_type)
{
- struct cmd_stats *new_stat;
-
- /* Early exit if we're not reporting any stats. It can be expensive to
- compute the pre-command values so don't collect them at all if we're
- not reporting stats. Alas this doesn't work in the startup case because
- we don't know yet whether we will be reporting the stats. For the
- startup case collect the data anyway (it should be cheap at this point),
- and leave it to the reporter to decide whether to print them. */
- if (msg_type != 0
- && !per_command_time
- && !per_command_space
- && !per_command_symtab)
- return make_cleanup (null_cleanup, 0);
-
- new_stat = XCNEW (struct cmd_stats);
-
- new_stat->msg_type = msg_type;
-
if (msg_type == 0 || per_command_space)
{
#ifdef HAVE_SBRK
char *lim = (char *) sbrk (0);
- new_stat->start_space = lim - lim_at_start;
- new_stat->space_enabled = 1;
+ this->start_space = lim - lim_at_start;
+ this->space_enabled = 1;
#endif
}

if (msg_type == 0 || per_command_time)
{
- new_stat->start_cpu_time = get_run_time ();
- gettimeofday (&new_stat->start_wall_time, NULL);
- new_stat->time_enabled = 1;
+ this->start_cpu_time = get_run_time ();
+ gettimeofday (&this->start_wall_time, NULL);
+ this->time_enabled = 1;
}

if (msg_type == 0 || per_command_symtab)
@@ -940,16 +900,14 @@ make_command_stats_cleanup (int msg_type)
int nr_symtabs, nr_compunit_symtabs, nr_blocks;

count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
- new_stat->start_nr_symtabs = nr_symtabs;
- new_stat->start_nr_compunit_symtabs = nr_compunit_symtabs;
- new_stat->start_nr_blocks = nr_blocks;
- new_stat->symtab_enabled = 1;
+ this->start_nr_symtabs = nr_symtabs;
+ this->start_nr_compunit_symtabs = nr_compunit_symtabs;
+ this->start_nr_blocks = nr_blocks;
+ this->symtab_enabled = 1;
}

/* Initalize timer to keep track of how long we waited for the user. */
reset_prompt_for_continue_wait_time ();
-
- return make_cleanup_dtor (report_command_stats, new_stat, xfree);
}

/* Handle unknown "mt set per-command" arguments.
diff --git a/gdb/maint.h b/gdb/maint.h
index 841e790..f517fa4 100644
--- a/gdb/maint.h
+++ b/gdb/maint.h
@@ -23,9 +23,40 @@ extern void set_per_command_time (int);

extern void set_per_command_space (int);

-/* Note: There's no set_per_command_symtab on purpose.
- Symtab stats aren't yet as useful for --statistics output. */
-
-extern struct cleanup *make_command_stats_cleanup (int);
+/* Records a run time and space usage to be used as a base for
+ reporting elapsed time or change in space. */
+
+class scoped_command_stats
+{
+ public:
+
+ scoped_command_stats (int msg_type);
+ ~scoped_command_stats ();
+
+ private:
+
+ // No need for these. They are intentionally not defined anywhere.
+ scoped_command_stats &operator= (const scoped_command_stats &);
+ scoped_command_stats (const scoped_command_stats &);
+
+ /* Zero if the saved time is from the beginning of GDB execution.
+ One if from the beginning of an individual command execution. */
+ int msg_type;
+ /* Track whether the stat was enabled at the start of the command
+ so that we can avoid printing anything if it gets turned on by
+ the current command. */
+ int time_enabled : 1;
+ int space_enabled : 1;
+ int symtab_enabled : 1;
+ long start_cpu_time;
+ struct timeval start_wall_time;
+ long start_space;
+ /* Total number of symtabs (over all objfiles). */
+ int start_nr_symtabs;
+ /* A count of the compunits. */
+ int start_nr_compunit_symtabs;
+ /* Total number of blocks. */
+ int start_nr_blocks;
+};

#endif /* MAINT_H */
--
2.7.4