This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA 22/23] Make gdb_buildargv return a unique pointer


This introduces gdb_argv_up, a unique pointer wrapping an "argv"
pointer; that is, a pointer to a NULL-terminated array of char*, where
both the array and each non-NULL element in the array are xmalloc'd.

This patch then changes gdb_buildargv to return a gdb_argv_up and
fixes all the users.  It also changes skip.c to use gdb_buildargv
(previously it was the only direct caller of buildargv, other than
gdb_buildargv itself).

One future change that might make sense would be to add begin and end
functions, so that an argv could be iterated over.  I didn't look into
this too much; and perhaps replacing some uses with
std::vector<std::string> would be even better.

2017-05-02  Tom Tromey  <tom@tromey.com>

	* utils.h (struct gdb_argv_deleter): New.
	(gdb_argv_up): New typedef.
	(gdb_buildargv): Change return type.
	* utils.c (gdb_buildargv): Return gdb_argv_up.
	* tracepoint.c (delete_trace_variable_command): Update.
	* tracefile.c (tsave_command): Update.
	* top.c (new_ui_command): Update.
	* symmisc.c (maintenance_print_symbols)
	(maintenance_print_msymbols, maintenance_expand_symtabs): Update.
	* symfile.c (symbol_file_command, generic_load)
	(remove_symbol_file_command): Update.
	* stack.c (backtrace_command): Update.
	* source.c (add_path, show_substitute_path_command)
	(unset_substitute_path_command, set_substitute_path_command):
	Update.
	* skip.c (skip_command): Update.  Use gdb_buildargv.
	* ser-mingw.c (pipe_windows_open): Update.
	* remote.c (extended_remote_run, remote_put_command)
	(remote_get_command, remote_delete_command): Update.
	* remote-sim.c (gdbsim_load, gdbsim_create_inferior)
	(gdbsim_open): Update.
	* python/py-cmd.c (gdbpy_string_to_argv): Update.
	* psymtab.c (maintenance_print_psymbols): Update.
	* procfs.c (procfs_info_proc): Update.
	* interps.c (interpreter_exec_cmd): Update.
	* infrun.c (handle_command): Update.
	* inferior.c (add_inferior_command, clone_inferior_command):
	Update.
	* guile/scm-string.c (gdbscm_string_to_argv): Update.
	* exec.c (exec_file_command): Update.
	* compile/compile.c (build_argc_argv): Update.
	* cli/cli-cmds.c (alias_command): Update.
---
 gdb/ChangeLog          | 35 +++++++++++++++++++++++++++++++++++
 gdb/cli/cli-cmds.c     | 31 +++++++++++++------------------
 gdb/compile/compile.c  |  2 +-
 gdb/exec.c             | 14 ++++----------
 gdb/guile/scm-string.c |  4 +---
 gdb/inferior.c         | 26 ++++++++------------------
 gdb/infrun.c           |  8 ++------
 gdb/interps.c          | 13 ++-----------
 gdb/procfs.c           |  5 +++--
 gdb/psymtab.c          |  5 ++---
 gdb/python/py-cmd.c    |  9 ++-------
 gdb/remote-sim.c       | 10 +++++-----
 gdb/remote.c           | 30 ++++--------------------------
 gdb/ser-mingw.c        |  2 +-
 gdb/skip.c             |  8 +-------
 gdb/source.c           | 28 ++++++----------------------
 gdb/stack.c            |  2 +-
 gdb/symfile.c          | 22 ++++++++--------------
 gdb/symmisc.c          | 17 +++++------------
 gdb/top.c              | 10 ++--------
 gdb/tracefile.c        |  6 +++---
 gdb/tracepoint.c       |  7 +------
 gdb/utils.c            |  4 ++--
 gdb/utils.h            | 19 ++++++++++++++++++-
 24 files changed, 130 insertions(+), 187 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 286d414..4dc3bb4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,40 @@
 2017-05-02  Tom Tromey  <tom@tromey.com>
 
+	* utils.h (struct gdb_argv_deleter): New.
+	(gdb_argv_up): New typedef.
+	(gdb_buildargv): Change return type.
+	* utils.c (gdb_buildargv): Return gdb_argv_up.
+	* tracepoint.c (delete_trace_variable_command): Update.
+	* tracefile.c (tsave_command): Update.
+	* top.c (new_ui_command): Update.
+	* symmisc.c (maintenance_print_symbols)
+	(maintenance_print_msymbols, maintenance_expand_symtabs): Update.
+	* symfile.c (symbol_file_command, generic_load)
+	(remove_symbol_file_command): Update.
+	* stack.c (backtrace_command): Update.
+	* source.c (add_path, show_substitute_path_command)
+	(unset_substitute_path_command, set_substitute_path_command):
+	Update.
+	* skip.c (skip_command): Update.  Use gdb_buildargv.
+	* ser-mingw.c (pipe_windows_open): Update.
+	* remote.c (extended_remote_run, remote_put_command)
+	(remote_get_command, remote_delete_command): Update.
+	* remote-sim.c (gdbsim_load, gdbsim_create_inferior)
+	(gdbsim_open): Update.
+	* python/py-cmd.c (gdbpy_string_to_argv): Update.
+	* psymtab.c (maintenance_print_psymbols): Update.
+	* procfs.c (procfs_info_proc): Update.
+	* interps.c (interpreter_exec_cmd): Update.
+	* infrun.c (handle_command): Update.
+	* inferior.c (add_inferior_command, clone_inferior_command):
+	Update.
+	* guile/scm-string.c (gdbscm_string_to_argv): Update.
+	* exec.c (exec_file_command): Update.
+	* compile/compile.c (build_argc_argv): Update.
+	* cli/cli-cmds.c (alias_command): Update.
+
+2017-05-02  Tom Tromey  <tom@tromey.com>
+
 	* python/python.c (gdbpy_decode_line): Use unique_xmalloc_ptr.
 
 2017-05-02  Tom Tromey  <tom@tromey.com>
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 3dc8b9c..5ba0922 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1403,31 +1403,27 @@ alias_command (char *args, int from_tty)
 {
   int i, alias_argc, command_argc;
   int abbrev_flag = 0;
-  char *args2, *equals;
+  char *equals;
   const char *alias, *command;
-  char **alias_argv, **command_argv;
-  struct cleanup *cleanup;
 
   if (args == NULL || strchr (args, '=') == NULL)
     alias_usage_error ();
 
-  args2 = xstrdup (args);
-  cleanup = make_cleanup (xfree, args2);
-  equals = strchr (args2, '=');
-  *equals = '\0';
-  alias_argv = gdb_buildargv (args2);
-  make_cleanup_freeargv (alias_argv);
-  command_argv = gdb_buildargv (equals + 1);
-  make_cleanup_freeargv (command_argv);
+  equals = strchr (args, '=');
+  std::string args2 (args, equals - args);
+
+  gdb_argv_up built_alias_argv = gdb_buildargv (args2.c_str ());
+  gdb_argv_up command_argv = gdb_buildargv (equals + 1);
 
-  for (i = 0; alias_argv[i] != NULL; )
+  char **alias_argv = built_alias_argv.get ();
+  while (alias_argv[0] != NULL)
     {
-      if (strcmp (alias_argv[i], "-a") == 0)
+      if (strcmp (alias_argv[0], "-a") == 0)
 	{
 	  ++alias_argv;
 	  abbrev_flag = 1;
 	}
-      else if (strcmp (alias_argv[i], "--") == 0)
+      else if (strcmp (alias_argv[0], "--") == 0)
 	{
 	  ++alias_argv;
 	  break;
@@ -1452,12 +1448,13 @@ alias_command (char *args, int from_tty)
     }
 
   alias_argc = countargv (alias_argv);
-  command_argc = countargv (command_argv);
+  command_argc = countargv (command_argv.get ());
 
   /* COMMAND must exist.
      Reconstruct the command to remove any extraneous spaces,
      for better error messages.  */
-  std::string command_string (argv_to_string (command_argv, command_argc));
+  std::string command_string (argv_to_string (command_argv.get (),
+					      command_argc));
   command = command_string.c_str ();
   if (! valid_command_p (command))
     error (_("Invalid command to alias to: %s"), command);
@@ -1514,8 +1511,6 @@ alias_command (char *args, int from_tty)
 		     command_argv[command_argc - 1],
 		     class_alias, abbrev_flag, c_command->prefixlist);
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Print a list of files and line numbers which a user may choose from
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 5269aaf..4994219 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -292,7 +292,7 @@ get_expr_block_and_pc (CORE_ADDR *pc)
 static void
 build_argc_argv (const char *s, int *argcp, char ***argvp)
 {
-  *argvp = gdb_buildargv (s);
+  *argvp = gdb_buildargv (s).release ();
   *argcp = countargv (*argvp);
 }
 
diff --git a/gdb/exec.c b/gdb/exec.c
index 2c9a74b..8fba0a1 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -410,7 +410,6 @@ exec_file_attach (const char *filename, int from_tty)
 static void
 exec_file_command (char *args, int from_tty)
 {
-  char **argv;
   char *filename;
 
   if (from_tty && target_has_execution
@@ -420,13 +419,11 @@ exec_file_command (char *args, int from_tty)
 
   if (args)
     {
-      struct cleanup *cleanups;
-
       /* Scan through the args and pick up the first non option arg
          as the filename.  */
 
-      argv = gdb_buildargv (args);
-      cleanups = make_cleanup_freeargv (argv);
+      gdb_argv_up built_argv = gdb_buildargv (args);
+      char **argv = built_argv.get ();
 
       for (; (*argv != NULL) && (**argv == '-'); argv++)
         {;
@@ -434,11 +431,8 @@ exec_file_command (char *args, int from_tty)
       if (*argv == NULL)
         error (_("No executable file name was specified"));
 
-      filename = tilde_expand (*argv);
-      make_cleanup (xfree, filename);
-      exec_file_attach (filename, from_tty);
-
-      do_cleanups (cleanups);
+      gdb::unique_xmalloc_ptr<char> filename (tilde_expand (*argv));
+      exec_file_attach (filename.get (), from_tty);
     }
   else
     exec_file_attach (NULL, from_tty);
diff --git a/gdb/guile/scm-string.c b/gdb/guile/scm-string.c
index d97f583..c6432c1 100644
--- a/gdb/guile/scm-string.c
+++ b/gdb/guile/scm-string.c
@@ -241,7 +241,6 @@ static SCM
 gdbscm_string_to_argv (SCM string_scm)
 {
   char *string;
-  char **c_argv;
   int i;
   SCM result = SCM_EOL;
 
@@ -254,11 +253,10 @@ gdbscm_string_to_argv (SCM string_scm)
       return SCM_EOL;
     }
 
-  c_argv = gdb_buildargv (string);
+  gdb_argv_up c_argv = gdb_buildargv (string);
   for (i = 0; c_argv[i] != NULL; ++i)
     result = scm_cons (gdbscm_scm_from_c_string (c_argv[i]), result);
 
-  freeargv (c_argv);
   xfree (string);
 
   return scm_reverse_x (result, SCM_EOL);
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 002296f..1b467884 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -820,20 +820,17 @@ static void
 add_inferior_command (char *args, int from_tty)
 {
   int i, copies = 1;
-  char *exec = NULL;
-  char **argv;
+  gdb::unique_xmalloc_ptr<char> exec;
   symfile_add_flags add_flags = 0;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
 
   if (from_tty)
     add_flags |= SYMFILE_VERBOSE;
 
   if (args)
     {
-      argv = gdb_buildargv (args);
-      make_cleanup_freeargv (argv);
+      gdb_argv_up built_argv = gdb_buildargv (args);
 
-      for (; *argv != NULL; argv++)
+      for (char **argv = built_argv.get (); *argv != NULL; argv++)
 	{
 	  if (**argv == '-')
 	    {
@@ -849,8 +846,7 @@ add_inferior_command (char *args, int from_tty)
 		  ++argv;
 		  if (!*argv)
 		    error (_("No argument to -exec"));
-		  exec = tilde_expand (*argv);
-		  make_cleanup (xfree, exec);
+		  exec.reset (tilde_expand (*argv));
 		}
 	    }
 	  else
@@ -874,12 +870,10 @@ add_inferior_command (char *args, int from_tty)
 	  set_current_inferior (inf);
 	  switch_to_thread (null_ptid);
 
-	  exec_file_attach (exec, from_tty);
-	  symbol_file_add_main (exec, add_flags);
+	  exec_file_attach (exec.get (), from_tty);
+	  symbol_file_add_main (exec.get (), add_flags);
 	}
     }
-
-  do_cleanups (old_chain);
 }
 
 /* clone-inferior [-copies N] [ID] */
@@ -888,15 +882,13 @@ static void
 clone_inferior_command (char *args, int from_tty)
 {
   int i, copies = 1;
-  char **argv;
   struct inferior *orginf = NULL;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
 
   if (args)
     {
-      argv = gdb_buildargv (args);
-      make_cleanup_freeargv (argv);
+      gdb_argv_up built_argv = gdb_buildargv (args);
 
+      char **argv = built_argv.get ();
       for (; *argv != NULL; argv++)
 	{
 	  if (**argv == '-')
@@ -967,8 +959,6 @@ clone_inferior_command (char *args, int from_tty)
       switch_to_thread (null_ptid);
       clone_program_space (pspace, orginf->pspace);
     }
-
-  do_cleanups (old_chain);
 }
 
 /* Print notices when new inferiors are created and die.  */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index fcafdc1..03aad38 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -8506,14 +8506,12 @@ sig_print_info (enum gdb_signal oursig)
 static void
 handle_command (char *args, int from_tty)
 {
-  char **argv;
   int digits, wordlen;
   int sigfirst, signum, siglast;
   enum gdb_signal oursig;
   int allsigs;
   int nsigs;
   unsigned char *sigs;
-  struct cleanup *old_chain;
 
   if (args == NULL)
     {
@@ -8528,8 +8526,8 @@ handle_command (char *args, int from_tty)
 
   /* Break the command line up into args.  */
 
-  argv = gdb_buildargv (args);
-  old_chain = make_cleanup_freeargv (argv);
+  gdb_argv_up built_argv = gdb_buildargv (args);
+  char **argv = built_argv.get ();
 
   /* Walk through the args, looking for signal oursigs, signal names, and
      actions.  Signal numbers and signal names may be interspersed with
@@ -8680,8 +8678,6 @@ Are you sure you want to change it? "),
 
 	break;
       }
-
-  do_cleanups (old_chain);
 }
 
 /* Complete the "handle" command.  */
diff --git a/gdb/interps.c b/gdb/interps.c
index af86390..0512b38 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -407,21 +407,14 @@ interpreter_exec_cmd (char *args, int from_tty)
 {
   struct ui_interp_info *ui_interp = get_current_interp_info ();
   struct interp *old_interp, *interp_to_use;
-  char **prules = NULL;
-  char **trule = NULL;
   unsigned int nrules;
   unsigned int i;
-  struct cleanup *cleanup;
 
   if (args == NULL)
     error_no_arg (_("interpreter-exec command"));
 
-  prules = gdb_buildargv (args);
-  cleanup = make_cleanup_freeargv (prules);
-
-  nrules = 0;
-  for (trule = prules; *trule != NULL; trule++)
-    nrules++;
+  gdb_argv_up prules = gdb_buildargv (args);
+  nrules = countargv (prules.get ());
 
   if (nrules < 2)
     error (_("usage: interpreter-exec <interpreter> [ <command> ... ]"));
@@ -446,8 +439,6 @@ interpreter_exec_cmd (char *args, int from_tty)
     }
 
   interp_set (old_interp, 0);
-
-  do_cleanups (cleanup);
 }
 
 /* See interps.h.  */
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 2aaee07..fa4fa1a 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -5108,10 +5108,11 @@ procfs_info_proc (struct target_ops *ops, const char *args,
     }
 
   old_chain = make_cleanup (null_cleanup, 0);
+  gdb_argv_up built_argv;
   if (args)
     {
-      argv = gdb_buildargv (args);
-      make_cleanup_freeargv (argv);
+      built_argv.reset (gdb_buildargv (args));
+      argv = built_argv.get ();
     }
   while (argv != NULL && *argv != NULL)
     {
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index bb482ee..a85e512 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1905,7 +1905,6 @@ dump_psymtab_addrmap (struct objfile *objfile, struct partial_symtab *psymtab,
 static void
 maintenance_print_psymbols (char *args, int from_tty)
 {
-  char **argv;
   struct ui_file *outfile = gdb_stdout;
   struct cleanup *cleanups;
   char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
@@ -1917,8 +1916,8 @@ maintenance_print_psymbols (char *args, int from_tty)
 
   dont_repeat ();
 
-  argv = gdb_buildargv (args);
-  cleanups = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
+  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 6203211..7bd25b4 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -763,7 +763,7 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args)
 
   if (*input != '\0')
     {
-      char **c_argv = gdb_buildargv (input);
+      gdb_argv_up c_argv = gdb_buildargv (input);
       int i;
 
       for (i = 0; c_argv[i] != NULL; ++i)
@@ -772,13 +772,8 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args)
 
 	  if (argp == NULL
 	      || PyList_Append (py_argv.get (), argp.get ()) < 0)
-	    {
-	      freeargv (c_argv);
-	      return NULL;
-	    }
+	    return NULL;
 	}
-
-      freeargv (c_argv);
     }
 
   return py_argv.release ();
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index fd1bc66..e932e87 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -574,8 +574,7 @@ gdbsim_load (struct target_ops *self, const char *args, int fromtty)
   if (args == NULL)
       error_no_arg (_("program to load"));
 
-  argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   prog = tilde_expand (argv[0]);
 
@@ -632,6 +631,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
   remove_breakpoints ();
   init_wait_for_inferior ();
 
+  gdb_argv_up built_argv;
   if (exec_file != NULL)
     {
       len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10;
@@ -640,8 +640,8 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
       strcat (arg_buf, exec_file);
       strcat (arg_buf, " ");
       strcat (arg_buf, args);
-      argv = gdb_buildargv (arg_buf);
-      make_cleanup_freeargv (argv);
+      built_argv.reset (gdb_buildargv (arg_buf));
+      argv = built_argv.get ();
     }
   else
     argv = NULL;
@@ -732,7 +732,7 @@ gdbsim_open (const char *args, int from_tty)
       strcat (arg_buf, " ");	/* 1 */
       strcat (arg_buf, args);
     }
-  sim_argv = gdb_buildargv (arg_buf);
+  sim_argv = gdb_buildargv (arg_buf).release ();
 
   init_callbacks ();
   gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv);
diff --git a/gdb/remote.c b/gdb/remote.c
index ecd0ce0..a699387 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -9525,12 +9525,9 @@ extended_remote_run (const std::string &args)
 
   if (!args.empty ())
     {
-      struct cleanup *back_to;
       int i;
-      char **argv;
 
-      argv = gdb_buildargv (args.c_str ());
-      back_to = make_cleanup_freeargv (argv);
+      gdb_argv_up argv = gdb_buildargv (args.c_str ());
       for (i = 0; argv[i] != NULL; i++)
 	{
 	  if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ())
@@ -9539,7 +9536,6 @@ extended_remote_run (const std::string &args)
 	  len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len,
 			      strlen (argv[i]));
 	}
-      do_cleanups (back_to);
     }
 
   rs->buf[len++] = '\0';
@@ -12035,58 +12031,40 @@ remote_file_delete (const char *remote_file, int from_tty)
 static void
 remote_put_command (char *args, int from_tty)
 {
-  struct cleanup *back_to;
-  char **argv;
-
   if (args == NULL)
     error_no_arg (_("file to put"));
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
   if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL)
     error (_("Invalid parameters to remote put"));
 
   remote_file_put (argv[0], argv[1], from_tty);
-
-  do_cleanups (back_to);
 }
 
 static void
 remote_get_command (char *args, int from_tty)
 {
-  struct cleanup *back_to;
-  char **argv;
-
   if (args == NULL)
     error_no_arg (_("file to get"));
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
   if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL)
     error (_("Invalid parameters to remote get"));
 
   remote_file_get (argv[0], argv[1], from_tty);
-
-  do_cleanups (back_to);
 }
 
 static void
 remote_delete_command (char *args, int from_tty)
 {
-  struct cleanup *back_to;
-  char **argv;
-
   if (args == NULL)
     error_no_arg (_("file to delete"));
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
   if (argv[0] == NULL || argv[1] != NULL)
     error (_("Invalid parameters to remote delete"));
 
   remote_file_delete (argv[0], from_tty);
-
-  do_cleanups (back_to);
 }
 
 static void
diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c
index 3f12458..429f89f 100644
--- a/gdb/ser-mingw.c
+++ b/gdb/ser-mingw.c
@@ -869,7 +869,7 @@ pipe_windows_open (struct serial *scb, const char *name)
   if (name == NULL)
     error_no_arg (_("child command"));
 
-  argv = gdb_buildargv (name);
+  argv = gdb_buildargv (name).release ();
   back_to = make_cleanup_freeargv (argv);
 
   if (! argv[0] || argv[0][0] == '\0')
diff --git a/gdb/skip.c b/gdb/skip.c
index 33ed8d8..b830c6f 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -231,8 +231,6 @@ skip_command (char *arg, int from_tty)
   const char *gfile = NULL;
   const char *function = NULL;
   const char *rfunction = NULL;
-  char **argv;
-  struct cleanup *cleanups;
   struct skiplist_entry *e;
   int i;
 
@@ -242,8 +240,7 @@ skip_command (char *arg, int from_tty)
       return;
     }
 
-  argv = buildargv (arg);
-  cleanups = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (arg);
 
   for (i = 0; argv[i] != NULL; ++i)
     {
@@ -290,7 +287,6 @@ skip_command (char *arg, int from_tty)
 	     FUNCTION-NAME may be `foo (int)', and therefore we pass the
 	     complete original arg to skip_function command as if the user
 	     typed "skip function arg".  */
-	  do_cleanups (cleanups);
 	  skip_function_command (arg, from_tty);
 	  return;
 	}
@@ -350,8 +346,6 @@ skip_command (char *arg, int from_tty)
 			 lower_file_text, file_to_print);
       }
   }
-
-  do_cleanups (cleanups);
 }
 
 static void
diff --git a/gdb/source.c b/gdb/source.c
index 3d477ad..7eef86c 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -484,16 +484,14 @@ add_path (char *dirname, char **which_path, int parse_separators)
 
   if (parse_separators)
     {
-      char **argv, **argvp;
+      char **argvp;
 
       /* This will properly parse the space and tab separators
 	 and any quotes that may exist.  */
-      argv = gdb_buildargv (dirname);
+      gdb_argv_up argv = gdb_buildargv (dirname);
 
-      for (argvp = argv; *argvp; argvp++)
+      for (argvp = argv.get (); *argvp; argvp++)
 	dirnames_to_char_ptr_vec_append (&dir_vec, *argvp);
-
-      freeargv (argv);
     }
   else
     VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname));
@@ -1882,12 +1880,9 @@ static void
 show_substitute_path_command (char *args, int from_tty)
 {
   struct substitute_path_rule *rule = substitute_path_rules;
-  char **argv;
   char *from = NULL;
-  struct cleanup *cleanup;
   
-  argv = gdb_buildargv (args);
-  cleanup = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   /* We expect zero or one argument.  */
 
@@ -1911,8 +1906,6 @@ show_substitute_path_command (char *args, int from_tty)
         printf_filtered ("  `%s' -> `%s'.\n", rule->from, rule->to);
       rule = rule->next;
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Implement the "unset substitute-path" command.  */
@@ -1921,14 +1914,12 @@ static void
 unset_substitute_path_command (char *args, int from_tty)
 {
   struct substitute_path_rule *rule = substitute_path_rules;
-  char **argv = gdb_buildargv (args);
+  gdb_argv_up argv = gdb_buildargv (args);
   char *from = NULL;
   int rule_found = 0;
-  struct cleanup *cleanup;
 
   /* This function takes either 0 or 1 argument.  */
 
-  cleanup = make_cleanup_freeargv (argv);
   if (argv != NULL && argv[0] != NULL && argv[1] != NULL)
     error (_("Incorrect usage, too many arguments in command"));
 
@@ -1966,8 +1957,6 @@ unset_substitute_path_command (char *args, int from_tty)
     error (_("No substitution rule defined for `%s'"), from);
 
   forget_cached_source_info ();
-
-  do_cleanups (cleanup);
 }
 
 /* Add a new source path substitution rule.  */
@@ -1975,12 +1964,9 @@ unset_substitute_path_command (char *args, int from_tty)
 static void
 set_substitute_path_command (char *args, int from_tty)
 {
-  char **argv;
   struct substitute_path_rule *rule;
-  struct cleanup *cleanup;
   
-  argv = gdb_buildargv (args);
-  cleanup = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   if (argv == NULL || argv[0] == NULL || argv [1] == NULL)
     error (_("Incorrect usage, too few arguments in command"));
@@ -2007,8 +1993,6 @@ set_substitute_path_command (char *args, int from_tty)
 
   add_substitute_path_rule (argv[0], argv[1]);
   forget_cached_source_info ();
-
-  do_cleanups (cleanup);
 }
 
 
diff --git a/gdb/stack.c b/gdb/stack.c
index 7f8a51c..34e8aa5 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1877,7 +1877,7 @@ backtrace_command (char *arg, int from_tty)
       char **argv;
       int i;
 
-      argv = gdb_buildargv (arg);
+      argv = gdb_buildargv (arg).release ();
       make_cleanup_freeargv (argv);
       argc = 0;
       for (i = 0; argv[i]; i++)
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 846aabe..9482ddc 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1628,7 +1628,7 @@ symbol_file_command (char *args, int from_tty)
     }
   else
     {
-      char **argv = gdb_buildargv (args);
+      char **argv;
       objfile_flags flags = OBJF_USERLOADED;
       symfile_add_flags add_flags = 0;
       struct cleanup *cleanups;
@@ -1637,7 +1637,8 @@ symbol_file_command (char *args, int from_tty)
       if (from_tty)
 	add_flags |= SYMFILE_VERBOSE;
 
-      cleanups = make_cleanup_freeargv (argv);
+      gdb_argv_up built_argv = gdb_buildargv (args);
+      argv = built_argv.get ();
       while (*argv != NULL)
 	{
 	  if (strcmp (*argv, "-readnow") == 0)
@@ -1655,8 +1656,6 @@ symbol_file_command (char *args, int from_tty)
 
       if (name == NULL)
 	error (_("no symbol file name was specified"));
-
-      do_cleanups (cleanups);
     }
 }
 
@@ -2050,25 +2049,23 @@ void
 generic_load (const char *args, int from_tty)
 {
   char *filename;
-  struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
+  struct cleanup *old_cleanups;
   struct load_section_data cbdata;
   struct load_progress_data total_progress;
   struct ui_out *uiout = current_uiout;
 
   CORE_ADDR entry;
-  char **argv;
 
   memset (&cbdata, 0, sizeof (cbdata));
   memset (&total_progress, 0, sizeof (total_progress));
   cbdata.progress_data = &total_progress;
 
-  make_cleanup (clear_memory_write_data, &cbdata.requests);
+  old_cleanups = make_cleanup (clear_memory_write_data, &cbdata.requests);
 
   if (args == NULL)
     error_no_arg (_("file to load"));
 
-  argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   filename = tilde_expand (argv[0]);
   make_cleanup (xfree, filename);
@@ -2216,7 +2213,6 @@ add_symbol_file_command (char *args, int from_tty)
   int i;
   int expecting_sec_name = 0;
   int expecting_sec_addr = 0;
-  char **argv;
   struct objfile *objf;
   objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED;
   symfile_add_flags add_flags = 0;
@@ -2243,8 +2239,7 @@ add_symbol_file_command (char *args, int from_tty)
   if (args == NULL)
     error (_("add-symbol-file takes a file name and an address"));
 
-  argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
     {
@@ -2364,7 +2359,6 @@ add_symbol_file_command (char *args, int from_tty)
 static void
 remove_symbol_file_command (char *args, int from_tty)
 {
-  char **argv;
   struct objfile *objf = NULL;
   struct cleanup *my_cleanups;
   struct program_space *pspace = current_program_space;
@@ -2376,7 +2370,7 @@ remove_symbol_file_command (char *args, int from_tty)
 
   my_cleanups = make_cleanup (null_cleanup, NULL);
 
-  argv = gdb_buildargv (args);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   if (strcmp (argv[0], "-a") == 0)
     {
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 32a5331..e3a512e 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -407,7 +407,6 @@ dump_symtab (struct symtab *symtab, struct ui_file *outfile)
 static void
 maintenance_print_symbols (char *args, int from_tty)
 {
-  char **argv;
   struct ui_file *outfile = gdb_stdout;
   struct cleanup *cleanups;
   char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
@@ -415,8 +414,8 @@ maintenance_print_symbols (char *args, int from_tty)
 
   dont_repeat ();
 
-  argv = gdb_buildargv (args);
-  cleanups = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
+  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
@@ -709,7 +708,6 @@ print_symbol (void *args)
 static void
 maintenance_print_msymbols (char *args, int from_tty)
 {
-  char **argv;
   struct ui_file *outfile = gdb_stdout;
   struct cleanup *cleanups;
   char *objfile_arg = NULL;
@@ -718,8 +716,8 @@ maintenance_print_msymbols (char *args, int from_tty)
 
   dont_repeat ();
 
-  argv = gdb_buildargv (args);
-  cleanups = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
+  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
@@ -944,14 +942,11 @@ maintenance_expand_symtabs (char *args, int from_tty)
 {
   struct program_space *pspace;
   struct objfile *objfile;
-  struct cleanup *cleanups;
-  char **argv;
   char *regexp = NULL;
 
   /* We use buildargv here so that we handle spaces in the regexp
      in a way that allows adding more arguments later.  */
-  argv = gdb_buildargv (args);
-  cleanups = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   if (argv != NULL)
     {
@@ -988,8 +983,6 @@ maintenance_expand_symtabs (char *args, int from_tty)
 	     ALL_DOMAIN);
 	}
     }
-
-  do_cleanups (cleanups);
 }
 
 
diff --git a/gdb/top.c b/gdb/top.c
index 6038366..a51b59f 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -364,17 +364,14 @@ new_ui_command (char *args, int from_tty)
   int i;
   int res;
   int argc;
-  char **argv;
   const char *interpreter_name;
   const char *tty_name;
-  struct cleanup *success_chain;
   struct cleanup *failure_chain;
 
   dont_repeat ();
 
-  argv = gdb_buildargv (args);
-  success_chain = make_cleanup_freeargv (argv);
-  argc = countargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
+  argc = countargv (argv.get ());
 
   if (argc < 2)
     error (_("usage: new-ui <interpreter> <tty>"));
@@ -407,9 +404,6 @@ new_ui_command (char *args, int from_tty)
     stream[2].release ();
 
     discard_cleanups (failure_chain);
-
-    /* This restores the previous UI and frees argv.  */
-    do_cleanups (success_chain);
   }
 
   printf_unfiltered ("New UI allocated\n");
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index cc90945..2dce0d9 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -318,8 +318,8 @@ tsave_command (char *args, int from_tty)
   if (args == NULL)
     error_no_arg (_("file in which to save trace data"));
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv_up built_argv = gdb_buildargv (args);
+  argv = built_argv.get ();
 
   for (; *argv; ++argv)
     {
@@ -341,7 +341,7 @@ tsave_command (char *args, int from_tty)
   else
     writer = tfile_trace_file_writer_new ();
 
-  make_cleanup (trace_file_writer_xfree, writer);
+  back_to = make_cleanup (trace_file_writer_xfree, writer);
 
   trace_save (filename, writer, target_does_save);
 
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 3a39ebc..f569c86 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -448,8 +448,6 @@ static void
 delete_trace_variable_command (char *args, int from_tty)
 {
   int ix;
-  char **argv;
-  struct cleanup *back_to;
 
   if (args == NULL)
     {
@@ -460,8 +458,7 @@ delete_trace_variable_command (char *args, int from_tty)
       return;
     }
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv_up argv = gdb_buildargv (args);
 
   for (ix = 0; argv[ix] != NULL; ix++)
     {
@@ -471,8 +468,6 @@ delete_trace_variable_command (char *args, int from_tty)
 	warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]);
     }
 
-  do_cleanups (back_to);
-
   dont_repeat ();
 }
 
diff --git a/gdb/utils.c b/gdb/utils.c
index 7d0b5f4..b631ed0 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -2914,14 +2914,14 @@ ldirname (const char *filename)
    Therefore, the returned value is guaranteed to be non-NULL,
    unless the parameter itself is NULL.  */
 
-char **
+gdb_argv_up
 gdb_buildargv (const char *s)
 {
   char **argv = buildargv (s);
 
   if (s != NULL && argv == NULL)
     malloc_failure (0);
-  return argv;
+  return gdb_argv_up (argv);
 }
 
 int
diff --git a/gdb/utils.h b/gdb/utils.h
index 8f545c6..dd7c75e7 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -60,7 +60,24 @@ extern int parse_pid_to_attach (const char *args);
 
 extern int parse_escape (struct gdbarch *, const char **);
 
-char **gdb_buildargv (const char *);
+/* A deleter for an argv array.  This is an array where each element,
+   up to the first NULL, is xmalloc'd, and the array itself is
+   xmalloc'd.  */
+struct gdb_argv_deleter
+{
+  void operator() (char **argv) const
+  {
+    freeargv (argv);
+  }
+};
+
+/* A unique pointer to an argv array.  */
+typedef std::unique_ptr<char *[], gdb_argv_deleter> gdb_argv_up;
+
+/* A wrapper for libiberty's buildargv that handles memory allocation
+   failures in the gdb style.  */
+gdb_argv_up gdb_buildargv (const char *);
+
 
 /* Cleanup utilities.  */
 
-- 
2.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]