Introduce gdb_argv, a class wrapper for buildargv
authorTom Tromey <tom@tromey.com>
Mon, 1 May 2017 05:02:30 +0000 (23:02 -0600)
committerTom Tromey <tom@tromey.com>
Thu, 3 Aug 2017 13:59:08 +0000 (07:59 -0600)
This introduces gdb_argv, a class 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 most users of gdb_buildargv to use gdb_argv
instead.

ChangeLog
2017-08-03  Tom Tromey  <tom@tromey.com>

* utils.h (struct gdb_argv_deleter): New.
(gdb_argv): New class.
* utils.c (gdb_argv::reset): New method.
* tracepoint.c (delete_trace_variable_command): Use gdb_argv.
* tracefile.c (tsave_command): Use gdb_argv.
* top.c (new_ui_command): Use gdb_argv.
* symmisc.c (maintenance_print_symbols)
(maintenance_print_msymbols, maintenance_expand_symtabs): Use gdb_argv.
* symfile.c (symbol_file_command, generic_load)
(remove_symbol_file_command): Use gdb_argv.
* stack.c (backtrace_command): Use gdb_argv.
* source.c (add_path, show_substitute_path_command)
(unset_substitute_path_command, set_substitute_path_command):
Use gdb_argv.
* skip.c (skip_command): Use gdb_argv.  Use gdb_buildargv.
* ser-mingw.c (pipe_windows_open): Use gdb_argv.
* remote.c (extended_remote_run, remote_put_command)
(remote_get_command, remote_delete_command): Use gdb_argv.
* remote-sim.c (gdbsim_load, gdbsim_create_inferior)
(gdbsim_open): Use gdb_argv.
* python/py-cmd.c (gdbpy_string_to_argv): Use gdb_argv.
* psymtab.c (maintenance_print_psymbols): Use gdb_argv.
* procfs.c (procfs_info_proc): Use gdb_argv.
* interps.c (interpreter_exec_cmd): Use gdb_argv.
* infrun.c (handle_command): Use gdb_argv.
* inferior.c (add_inferior_command, clone_inferior_command):
Use gdb_argv.
* guile/scm-string.c (gdbscm_string_to_argv): Use gdb_argv.
* exec.c (exec_file_command): Use gdb_argv.
* cli/cli-cmds.c (alias_command): Use gdb_argv.
* compile/compile.c (build_argc_argv): Use gdb_argv.

24 files changed:
gdb/ChangeLog
gdb/cli/cli-cmds.c
gdb/compile/compile.c
gdb/exec.c
gdb/guile/scm-string.c
gdb/inferior.c
gdb/infrun.c
gdb/interps.c
gdb/procfs.c
gdb/psymtab.c
gdb/python/py-cmd.c
gdb/remote-sim.c
gdb/remote.c
gdb/ser-mingw.c
gdb/skip.c
gdb/source.c
gdb/stack.c
gdb/symfile.c
gdb/symmisc.c
gdb/top.c
gdb/tracefile.c
gdb/tracepoint.c
gdb/utils.c
gdb/utils.h

index 3136f495e3094b9c80e7235e7e4d7ca60316d0f0..392f58a67d26ea4c838cf94ce34e27e91e183689 100644 (file)
@@ -1,3 +1,37 @@
+2017-08-03  Tom Tromey  <tom@tromey.com>
+
+       * utils.h (struct gdb_argv_deleter): New.
+       (gdb_argv): New class.
+       * utils.c (gdb_argv::reset): New method.
+       * tracepoint.c (delete_trace_variable_command): Use gdb_argv.
+       * tracefile.c (tsave_command): Use gdb_argv.
+       * top.c (new_ui_command): Use gdb_argv.
+       * symmisc.c (maintenance_print_symbols)
+       (maintenance_print_msymbols, maintenance_expand_symtabs): Use gdb_argv.
+       * symfile.c (symbol_file_command, generic_load)
+       (remove_symbol_file_command): Use gdb_argv.
+       * stack.c (backtrace_command): Use gdb_argv.
+       * source.c (add_path, show_substitute_path_command)
+       (unset_substitute_path_command, set_substitute_path_command):
+       Use gdb_argv.
+       * skip.c (skip_command): Use gdb_argv.  Use gdb_buildargv.
+       * ser-mingw.c (pipe_windows_open): Use gdb_argv.
+       * remote.c (extended_remote_run, remote_put_command)
+       (remote_get_command, remote_delete_command): Use gdb_argv.
+       * remote-sim.c (gdbsim_load, gdbsim_create_inferior)
+       (gdbsim_open): Use gdb_argv.
+       * python/py-cmd.c (gdbpy_string_to_argv): Use gdb_argv.
+       * psymtab.c (maintenance_print_psymbols): Use gdb_argv.
+       * procfs.c (procfs_info_proc): Use gdb_argv.
+       * interps.c (interpreter_exec_cmd): Use gdb_argv.
+       * infrun.c (handle_command): Use gdb_argv.
+       * inferior.c (add_inferior_command, clone_inferior_command):
+       Use gdb_argv.
+       * guile/scm-string.c (gdbscm_string_to_argv): Use gdb_argv.
+       * exec.c (exec_file_command): Use gdb_argv.
+       * cli/cli-cmds.c (alias_command): Use gdb_argv.
+       * compile/compile.c (build_argc_argv): Use gdb_argv.
+
 2017-08-03  Tom Tromey  <tom@tromey.com>
 
        * python/python.c (gdbpy_decode_line): Use unique_xmalloc_ptr.
index a0d566bafcd830b4b608e99f65081197fcc528c4..036a2f0c03d51b8953167180646d2ef83f05840d 100644 (file)
@@ -1400,31 +1400,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 built_alias_argv (args2.c_str ());
+  gdb_argv command_argv (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;
@@ -1449,12 +1445,13 @@ alias_command (char *args, int from_tty)
     }
 
   alias_argc = countargv (alias_argv);
-  command_argc = countargv (command_argv);
+  command_argc = command_argv.count ();
 
   /* 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);
@@ -1511,8 +1508,6 @@ alias_command (char *args, int from_tty)
                     command_argv[command_argc - 1],
                     class_alias, abbrev_flag, c_command->prefixlist);
     }
-
-  do_cleanups (cleanup);
 }
 \f
 /* Print a list of files and line numbers which a user may choose from
index 5269aaf613beaec834a86604b801c528969f3382..bca7b57ea2e9b95c284f1770751a77a938f0937d 100644 (file)
@@ -285,15 +285,17 @@ get_expr_block_and_pc (CORE_ADDR *pc)
   return block;
 }
 
-/* Call gdb_buildargv, set its result for S into *ARGVP but calculate also the
-   number of parsed arguments into *ARGCP.  If gdb_buildargv has returned NULL
-   then *ARGCP is set to zero.  */
+/* Call buildargv (via gdb_argv), set its result for S into *ARGVP but
+   calculate also the number of parsed arguments into *ARGCP.  If
+   buildargv has returned NULL then *ARGCP is set to zero.  */
 
 static void
 build_argc_argv (const char *s, int *argcp, char ***argvp)
 {
-  *argvp = gdb_buildargv (s);
-  *argcp = countargv (*argvp);
+  gdb_argv args (s);
+
+  *argcp = args.count ();
+  *argvp = args.release ();
 }
 
 /* String for 'set compile-args' and 'show compile-args'.  */
@@ -517,7 +519,7 @@ compile_to_object (struct command_line *cmd, const char *cmd_string,
 
   /* Set compiler command-line arguments.  */
   get_args (compiler, gdbarch, &argc, &argv);
-  make_cleanup_freeargv (argv);
+  gdb_argv argv_holder (argv);
 
   error_message = compiler->fe->ops->set_arguments (compiler->fe, triplet_rx,
                                                    argc, argv);
index 05ecb1bd827e2a1379c8f35d5a2333e7dda49319..6980b07f69abc7118021a33828bb85d424e534d1 100644 (file)
@@ -407,7 +407,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
@@ -417,13 +416,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 built_argv (args);
+      char **argv = built_argv.get ();
 
       for (; (*argv != NULL) && (**argv == '-'); argv++)
         {;
@@ -431,11 +428,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);
index d97f58321c20762812ba5469d52833c817bf9c58..4e495ebd5c9cdd762fa3405d9f8e8a5ea5836374 100644 (file)
@@ -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);
-  for (i = 0; c_argv[i] != NULL; ++i)
-    result = scm_cons (gdbscm_scm_from_c_string (c_argv[i]), result);
+  gdb_argv c_argv (string);
+  for (char *arg : c_argv)
+    result = scm_cons (gdbscm_scm_from_c_string (arg), result);
 
-  freeargv (c_argv);
   xfree (string);
 
   return scm_reverse_x (result, SCM_EOL);
index 8e8e13a00960e6030ec2259080dd159b1ba3dc1b..a20c6c5b9baf6e09b2c24d8c091dd0a902689799 100644 (file)
@@ -795,20 +795,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 built_argv (args);
 
-      for (; *argv != NULL; argv++)
+      for (char **argv = built_argv.get (); *argv != NULL; argv++)
        {
          if (**argv == '-')
            {
@@ -824,8 +821,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
@@ -849,12 +845,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] */
@@ -863,15 +857,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 built_argv (args);
 
+      char **argv = built_argv.get ();
       for (; *argv != NULL; argv++)
        {
          if (**argv == '-')
@@ -942,8 +934,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.  */
index 37ff0157ffb0a2a131b61aa66d964f230e3d32ca..8f966e2c4491aac663b2866d5e23287eeaa80c1a 100644 (file)
@@ -8512,14 +8512,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)
     {
@@ -8534,24 +8532,23 @@ 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 built_argv (args);
 
   /* Walk through the args, looking for signal oursigs, signal names, and
      actions.  Signal numbers and signal names may be interspersed with
      actions, with the actions being performed for all signals cumulatively
      specified.  Signal ranges can be specified as <LOW>-<HIGH>.  */
 
-  while (*argv != NULL)
+  for (char *arg : built_argv)
     {
-      wordlen = strlen (*argv);
-      for (digits = 0; isdigit ((*argv)[digits]); digits++)
+      wordlen = strlen (arg);
+      for (digits = 0; isdigit (arg[digits]); digits++)
        {;
        }
       allsigs = 0;
       sigfirst = siglast = -1;
 
-      if (wordlen >= 1 && !strncmp (*argv, "all", wordlen))
+      if (wordlen >= 1 && !strncmp (arg, "all", wordlen))
        {
          /* Apply action to all signals except those used by the
             debugger.  Silently skip those.  */
@@ -8559,37 +8556,37 @@ handle_command (char *args, int from_tty)
          sigfirst = 0;
          siglast = nsigs - 1;
        }
-      else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen))
+      else if (wordlen >= 1 && !strncmp (arg, "stop", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_stop);
          SET_SIGS (nsigs, sigs, signal_print);
        }
-      else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen))
+      else if (wordlen >= 1 && !strncmp (arg, "ignore", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_program);
        }
-      else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen))
+      else if (wordlen >= 2 && !strncmp (arg, "print", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_print);
        }
-      else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen))
+      else if (wordlen >= 2 && !strncmp (arg, "pass", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_program);
        }
-      else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen))
+      else if (wordlen >= 3 && !strncmp (arg, "nostop", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_stop);
        }
-      else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen))
+      else if (wordlen >= 3 && !strncmp (arg, "noignore", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_program);
        }
-      else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen))
+      else if (wordlen >= 4 && !strncmp (arg, "noprint", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_print);
          UNSET_SIGS (nsigs, sigs, signal_stop);
        }
-      else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen))
+      else if (wordlen >= 4 && !strncmp (arg, "nopass", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_program);
        }
@@ -8602,11 +8599,11 @@ handle_command (char *args, int from_tty)
             SIGHUP, SIGINT, SIGALRM, etc. will work right anyway.  */
 
          sigfirst = siglast = (int)
-           gdb_signal_from_command (atoi (*argv));
-         if ((*argv)[digits] == '-')
+           gdb_signal_from_command (atoi (arg));
+         if (arg[digits] == '-')
            {
              siglast = (int)
-               gdb_signal_from_command (atoi ((*argv) + digits + 1));
+               gdb_signal_from_command (atoi (arg + digits + 1));
            }
          if (sigfirst > siglast)
            {
@@ -8618,7 +8615,7 @@ handle_command (char *args, int from_tty)
        }
       else
        {
-         oursig = gdb_signal_from_name (*argv);
+         oursig = gdb_signal_from_name (arg);
          if (oursig != GDB_SIGNAL_UNKNOWN)
            {
              sigfirst = siglast = (int) oursig;
@@ -8626,7 +8623,7 @@ handle_command (char *args, int from_tty)
          else
            {
              /* Not a number and not a recognized flag word => complain.  */
-             error (_("Unrecognized or ambiguous flag word: \"%s\"."), *argv);
+             error (_("Unrecognized or ambiguous flag word: \"%s\"."), arg);
            }
        }
 
@@ -8664,8 +8661,6 @@ Are you sure you want to change it? "),
              break;
            }
        }
-
-      argv++;
     }
 
   for (signum = 0; signum < nsigs; signum++)
@@ -8686,8 +8681,6 @@ Are you sure you want to change it? "),
 
        break;
       }
-
-  do_cleanups (old_chain);
 }
 
 /* Complete the "handle" command.  */
index 4de7c4e8be6c48d4b266943e06f4ba90c3babaf5..1e59034a5e87b052bdd1007ea0019ca10e5455fb 100644 (file)
@@ -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 prules (args);
+  nrules = prules.count ();
 
   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.  */
index b03809c7b7154b190f63768b78aa72b71a627956..4b965ea987abdde774fcb720c1acefe663722ccf 100644 (file)
@@ -5100,7 +5100,6 @@ procfs_info_proc (struct target_ops *ops, const char *args,
   struct cleanup *old_chain;
   procinfo *process  = NULL;
   procinfo *thread   = NULL;
-  char    **argv     = NULL;
   char     *tmp      = NULL;
   int       pid      = 0;
   int       tid      = 0;
@@ -5121,24 +5120,19 @@ procfs_info_proc (struct target_ops *ops, const char *args,
     }
 
   old_chain = make_cleanup (null_cleanup, 0);
-  if (args)
-    {
-      argv = gdb_buildargv (args);
-      make_cleanup_freeargv (argv);
-    }
-  while (argv != NULL && *argv != NULL)
+  gdb_argv built_argv (args);
+  for (char *arg : argv)
     {
-      if (isdigit (argv[0][0]))
+      if (isdigit (arg[0]))
        {
-         pid = strtoul (argv[0], &tmp, 10);
+         pid = strtoul (arg, &tmp, 10);
          if (*tmp == '/')
            tid = strtoul (++tmp, NULL, 10);
        }
-      else if (argv[0][0] == '/')
+      else if (arg[0] == '/')
        {
-         tid = strtoul (argv[0] + 1, NULL, 10);
+         tid = strtoul (arg + 1, NULL, 10);
        }
-      argv++;
     }
   if (pid == 0)
     pid = ptid_get_pid (inferior_ptid);
index 4077fb37f57b9952843cff5c0f0f50a338f12a00..a3762b54498b310aee873efd80f0439d190694dc 100644 (file)
@@ -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 argv (args);
+  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
index b9f60377bd60218547968f30ae737b6d8322d11e..2a7c613f18fc0d218f7bf4647b1912053107ff7c 100644 (file)
@@ -775,22 +775,16 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args)
 
   if (*input != '\0')
     {
-      char **c_argv = gdb_buildargv (input);
-      int i;
+      gdb_argv c_argv (input);
 
-      for (i = 0; c_argv[i] != NULL; ++i)
+      for (char *arg : c_argv)
        {
-         gdbpy_ref<> argp (PyString_FromString (c_argv[i]));
+         gdbpy_ref<> argp (PyString_FromString (arg));
 
          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 ();
index 508e2c22b698453dc1260fe66aa33859f4d9e3a5..75b1f56cb3411faaa74615857c732ffffa2c2731 100644 (file)
@@ -570,8 +570,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 argv (args);
 
   prog = tilde_expand (argv[0]);
 
@@ -609,7 +608,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
   int len;
-  char *arg_buf, **argv;
+  char *arg_buf;
   const char *args = allargs.c_str ();
 
   if (exec_file == 0 || exec_bfd == 0)
@@ -628,6 +627,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
   remove_breakpoints ();
   init_wait_for_inferior ();
 
+  gdb_argv built_argv;
   if (exec_file != NULL)
     {
       len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10;
@@ -636,16 +636,14 @@ 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 (arg_buf);
     }
-  else
-    argv = NULL;
 
   if (!have_inferiors ())
     init_thread_list ();
 
-  if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd, argv, env)
+  if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd,
+                          built_argv.get (), env)
       != SIM_RC_OK)
     error (_("Unable to create sim inferior."));
 
@@ -728,18 +726,21 @@ gdbsim_open (const char *args, int from_tty)
       strcat (arg_buf, " ");   /* 1 */
       strcat (arg_buf, args);
     }
-  sim_argv = gdb_buildargv (arg_buf);
+
+  gdb_argv args (arg_buf);
+  sim_argv = args.get ();
 
   init_callbacks ();
   gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv);
 
   if (gdbsim_desc == 0)
     {
-      freeargv (sim_argv);
       sim_argv = NULL;
       error (_("unable to create simulator instance"));
     }
 
+  args.release ();
+
   /* Reset the pid numberings for this batch of sim instances.  */
   next_pid = INITIAL_PID;
 
index 5adf5eb03077c9a13b6a8c7417a012ffec83cf21..ff59a0f81f4d5385d68c2a2fe75fa5d6fd5b973a 100644 (file)
@@ -9519,12 +9519,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 argv (args.c_str ());
       for (i = 0; argv[i] != NULL; i++)
        {
          if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ())
@@ -9533,7 +9530,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';
@@ -12043,58 +12039,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 argv (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 argv (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 argv (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
index 3f124582a8529c9bbb90cc8bb22c4104532a297a..0b78ba18e0fafc29c71db997f125eeccb040242e 100644 (file)
@@ -863,20 +863,18 @@ pipe_windows_open (struct serial *scb, const char *name)
 {
   struct pipe_state *ps;
   FILE *pex_stderr;
-  char **argv;
   struct cleanup *back_to;
 
   if (name == NULL)
     error_no_arg (_("child command"));
 
-  argv = gdb_buildargv (name);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv argv (name);
 
   if (! argv[0] || argv[0][0] == '\0')
     error (_("missing child command"));
 
   ps = make_pipe_state ();
-  make_cleanup (cleanup_pipe_state, ps);
+  back_to = make_cleanup (cleanup_pipe_state, ps);
 
   ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
   if (! ps->pex)
@@ -890,7 +888,7 @@ pipe_windows_open (struct serial *scb, const char *name)
     const char *err_msg
       = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
                 | PEX_STDERR_TO_PIPE,
-                 argv[0], argv, NULL, NULL,
+                 argv[0], argv.get (), NULL, NULL,
                  &err);
 
     if (err_msg)
@@ -920,6 +918,7 @@ pipe_windows_open (struct serial *scb, const char *name)
 
   scb->state = (void *) ps;
 
+  argv.release ();
   discard_cleanups (back_to);
   return 0;
 
index afa81ecbe3ecb205acc146b32f83c262558a7178..bf4491381df1348a87e083d56470423b860e65f6 100644 (file)
@@ -217,8 +217,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;
 
@@ -228,8 +226,7 @@ skip_command (char *arg, int from_tty)
       return;
     }
 
-  argv = buildargv (arg);
-  cleanups = make_cleanup_freeargv (argv);
+  gdb_argv argv (arg);
 
   for (i = 0; argv[i] != NULL; ++i)
     {
@@ -276,7 +273,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;
        }
@@ -336,8 +332,6 @@ skip_command (char *arg, int from_tty)
                         lower_file_text, file_to_print);
       }
   }
-
-  do_cleanups (cleanups);
 }
 
 static void
index 4cc862c156f545443d4485f1912edba8abb46382..5473103b3fd6ff4765d9759537aae2362c1f1552 100644 (file)
@@ -484,16 +484,12 @@ add_path (char *dirname, char **which_path, int parse_separators)
 
   if (parse_separators)
     {
-      char **argv, **argvp;
-
       /* This will properly parse the space and tab separators
         and any quotes that may exist.  */
-      argv = gdb_buildargv (dirname);
-
-      for (argvp = argv; *argvp; argvp++)
-       dirnames_to_char_ptr_vec_append (&dir_vec, *argvp);
+      gdb_argv argv (dirname);
 
-      freeargv (argv);
+      for (char *arg : argv)
+       dirnames_to_char_ptr_vec_append (&dir_vec, arg);
     }
   else
     VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname));
@@ -1883,12 +1879,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 argv (args);
 
   /* We expect zero or one argument.  */
 
@@ -1912,8 +1905,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.  */
@@ -1922,14 +1913,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 argv (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"));
 
@@ -1967,8 +1956,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.  */
@@ -1976,12 +1963,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 argv (args);
 
   if (argv == NULL || argv[0] == NULL || argv [1] == NULL)
     error (_("Incorrect usage, too few arguments in command"));
@@ -2008,8 +1992,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);
 }
 
 \f
index 7f8a51caa5602417172bc27f39bc40063bb5e2fd..3e9dca2d5c55844beeec2584f26fca0c48205e39 100644 (file)
@@ -1877,8 +1877,8 @@ backtrace_command (char *arg, int from_tty)
       char **argv;
       int i;
 
-      argv = gdb_buildargv (arg);
-      make_cleanup_freeargv (argv);
+      gdb_argv built_argv (arg);
+      argv = built_argv.get ();
       argc = 0;
       for (i = 0; argv[i]; i++)
        {
index 9cbd6e52138ee9728301340a32da22bb19f40b27..67a39769aa297d0137fd92c547a567b84d87fc6f 100644 (file)
@@ -1639,7 +1639,6 @@ symbol_file_command (char *args, int from_tty)
     }
   else
     {
-      char **argv = gdb_buildargv (args);
       objfile_flags flags = OBJF_USERLOADED;
       symfile_add_flags add_flags = 0;
       struct cleanup *cleanups;
@@ -1648,26 +1647,22 @@ symbol_file_command (char *args, int from_tty)
       if (from_tty)
        add_flags |= SYMFILE_VERBOSE;
 
-      cleanups = make_cleanup_freeargv (argv);
-      while (*argv != NULL)
+      gdb_argv built_argv (args);
+      for (char *arg : built_argv)
        {
-         if (strcmp (*argv, "-readnow") == 0)
+         if (strcmp (arg, "-readnow") == 0)
            flags |= OBJF_READNOW;
-         else if (**argv == '-')
-           error (_("unknown option `%s'"), *argv);
+         else if (*arg == '-')
+           error (_("unknown option `%s'"), arg);
          else
            {
-             symbol_file_add_main_1 (*argv, add_flags, flags);
-             name = *argv;
+             symbol_file_add_main_1 (arg, add_flags, flags);
+             name = arg;
            }
-
-         argv++;
        }
 
       if (name == NULL)
        error (_("no symbol file name was specified"));
-
-      do_cleanups (cleanups);
     }
 }
 
@@ -2061,25 +2056,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 argv (args);
 
   filename = tilde_expand (argv[0]);
   make_cleanup (xfree, filename);
@@ -2227,7 +2220,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;
@@ -2254,8 +2246,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 argv (args);
 
   for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
     {
@@ -2375,7 +2366,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;
@@ -2387,7 +2377,7 @@ remove_symbol_file_command (char *args, int from_tty)
 
   my_cleanups = make_cleanup (null_cleanup, NULL);
 
-  argv = gdb_buildargv (args);
+  gdb_argv argv (args);
 
   if (strcmp (argv[0], "-a") == 0)
     {
index 32a53318a8c46d9e78522ab3cafcd5a6802db639..cfdd5d940bdf6c1107b255525a835a0d2b99d4a7 100644 (file)
@@ -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 argv (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 argv (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 argv (args);
 
   if (argv != NULL)
     {
@@ -988,8 +983,6 @@ maintenance_expand_symtabs (char *args, int from_tty)
             ALL_DOMAIN);
        }
     }
-
-  do_cleanups (cleanups);
 }
 \f
 
index 6b00c6e7c2cee0e9cd3441af65ac91e5b3bca415..a4fd262d294d4947976639c411a285e7132fbeb1 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -365,17 +365,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 argv (args);
+  argc = argv.count ();
 
   if (argc < 2)
     error (_("usage: new-ui <interpreter> <tty>"));
@@ -408,9 +405,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");
index e208fc6d2b900e2f81c1c0358c9bf1e61963804e..8dde605b0e78ad8552a1456debb52110291e7eca 100644 (file)
@@ -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 built_argv (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);
 
index 6721e22773007bebe9479fbf0f48eb6018f0cc87..86acdbe5cc88032b847e1d3bca088d6066f090a2 100644 (file)
@@ -447,10 +447,6 @@ trace_variable_command (char *args, int from_tty)
 static void
 delete_trace_variable_command (char *args, int from_tty)
 {
-  int ix;
-  char **argv;
-  struct cleanup *back_to;
-
   if (args == NULL)
     {
       if (query (_("Delete all trace state variables? ")))
@@ -460,19 +456,16 @@ delete_trace_variable_command (char *args, int from_tty)
       return;
     }
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv argv (args);
 
-  for (ix = 0; argv[ix] != NULL; ix++)
+  for (char *arg : argv)
     {
-      if (*argv[ix] == '$')
-       delete_trace_state_variable (argv[ix] + 1);
+      if (*arg == '$')
+       delete_trace_state_variable (arg + 1);
       else
-       warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]);
+       warning (_("Name \"%s\" not prefixed with '$', ignoring"), arg);
     }
 
-  do_cleanups (back_to);
-
   dont_repeat ();
 }
 
index 06f4168e6e619b3586bc65ca424c8929401cec80..e7e176da8ca39f1692e645a7114c87482bafe35c 100644 (file)
@@ -2863,6 +2863,20 @@ ldirname (const char *filename)
   return dirname;
 }
 
+/* See utils.h.  */
+
+void
+gdb_argv::reset (const char *s)
+{
+  char **argv = buildargv (s);
+
+  if (s != NULL && argv == NULL)
+    malloc_failure (0);
+
+  freeargv (m_argv);
+  m_argv = argv;
+}
+
 /* Call libiberty's buildargv, and return the result.
    If buildargv fails due to out-of-memory, call nomem.
    Therefore, the returned value is guaranteed to be non-NULL,
index b9bd6d9b80ef7ac4613749f778a53c65d70c6580..88cab4b93072a61af8ab1f723af4cd11c307e346 100644 (file)
@@ -86,6 +86,124 @@ extern int parse_pid_to_attach (const char *args);
 extern int parse_escape (struct gdbarch *, const char **);
 
 char **gdb_buildargv (const char *);
+
+/* A wrapper for an array of char* that was allocated in the way that
+   'buildargv' does, and should be freed with 'freeargv'.  */
+
+class gdb_argv
+{
+public:
+
+  /* A constructor that initializes to NULL.  */
+
+  gdb_argv ()
+    : m_argv (NULL)
+  {
+  }
+
+  /* A constructor that calls buildargv on STR.  STR may be NULL, in
+     which case this object is initialized with a NULL array.  If
+     buildargv fails due to out-of-memory, call malloc_failure.
+     Therefore, the value is guaranteed to be non-NULL, unless the
+     parameter itself is NULL.  */
+
+  explicit gdb_argv (const char *str)
+    : m_argv (NULL)
+  {
+    reset (str);
+  }
+
+  /* A constructor that takes ownership of an existing array.  */
+
+  explicit gdb_argv (char **array)
+    : m_argv (array)
+  {
+  }
+
+  gdb_argv (const gdb_argv &) = delete;
+  gdb_argv &operator= (const gdb_argv &) = delete;
+
+  ~gdb_argv ()
+  {
+    freeargv (m_argv);
+  }
+
+  /* Call buildargv on STR, storing the result in this object.  Any
+     previous state is freed.  STR may be NULL, in which case this
+     object is reset with a NULL array.  If buildargv fails due to
+     out-of-memory, call malloc_failure.  Therefore, the value is
+     guaranteed to be non-NULL, unless the parameter itself is
+     NULL.  */
+
+  void reset (const char *str);
+
+  /* Return the underlying array.  */
+
+  char **get ()
+  {
+    return m_argv;
+  }
+
+  /* Return the underlying array, transferring ownership to the
+     caller.  */
+
+  char **release ()
+  {
+    char **result = m_argv;
+    m_argv = NULL;
+    return result;
+  }
+
+  /* Return the number of items in the array.  */
+
+  int count () const
+  {
+    return countargv (m_argv);
+  }
+
+  /* Index into the array.  */
+
+  char *operator[] (int arg)
+  {
+    gdb_assert (m_argv != NULL);
+    return m_argv[arg];
+  }
+
+  /* The iterator type.  */
+
+  typedef char **iterator;
+
+  /* Return an iterator pointing to the start of the array.  */
+
+  iterator begin ()
+  {
+    return m_argv;
+  }
+
+  /* Return an iterator pointing to the end of the array.  */
+
+  iterator end ()
+  {
+    return m_argv + count ();
+  }
+
+  bool operator!= (nullptr_t)
+  {
+    return m_argv != NULL;
+  }
+
+  bool operator== (nullptr_t)
+  {
+    return m_argv == NULL;
+  }
+
+private:
+
+  /* The wrapped array.  */
+
+  char **m_argv;
+};
+
 \f
 /* Cleanup utilities.  */