+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.
{
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;
}
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);
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
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'. */
/* 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);
static void
exec_file_command (char *args, int from_tty)
{
- char **argv;
char *filename;
if (from_tty && target_has_execution
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++)
{;
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);
gdbscm_string_to_argv (SCM string_scm)
{
char *string;
- char **c_argv;
int i;
SCM result = SCM_EOL;
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);
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 == '-')
{
++argv;
if (!*argv)
error (_("No argument to -exec"));
- exec = tilde_expand (*argv);
- make_cleanup (xfree, exec);
+ exec.reset (tilde_expand (*argv));
}
}
else
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] */
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 == '-')
switch_to_thread (null_ptid);
clone_program_space (pspace, orginf->pspace);
}
-
- do_cleanups (old_chain);
}
/* Print notices when new inferiors are created and die. */
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)
{
/* 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. */
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);
}
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)
{
}
else
{
- oursig = gdb_signal_from_name (*argv);
+ oursig = gdb_signal_from_name (arg);
if (oursig != GDB_SIGNAL_UNKNOWN)
{
sigfirst = siglast = (int) oursig;
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);
}
}
break;
}
}
-
- argv++;
}
for (signum = 0; signum < nsigs; signum++)
break;
}
-
- do_cleanups (old_chain);
}
/* Complete the "handle" command. */
{
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> ... ]"));
}
interp_set (old_interp, 0);
-
- do_cleanups (cleanup);
}
/* See interps.h. */
struct cleanup *old_chain;
procinfo *process = NULL;
procinfo *thread = NULL;
- char **argv = NULL;
char *tmp = NULL;
int pid = 0;
int tid = 0;
}
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);
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;
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)
{
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 ();
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]);
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)
remove_breakpoints ();
init_wait_for_inferior ();
+ gdb_argv built_argv;
if (exec_file != NULL)
{
len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10;
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."));
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;
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 ())
len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len,
strlen (argv[i]));
}
- do_cleanups (back_to);
}
rs->buf[len++] = '\0';
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
{
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)
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)
scb->state = (void *) ps;
+ argv.release ();
discard_cleanups (back_to);
return 0;
const char *gfile = NULL;
const char *function = NULL;
const char *rfunction = NULL;
- char **argv;
- struct cleanup *cleanups;
struct skiplist_entry *e;
int i;
return;
}
- argv = buildargv (arg);
- cleanups = make_cleanup_freeargv (argv);
+ gdb_argv argv (arg);
for (i = 0; argv[i] != NULL; ++i)
{
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;
}
lower_file_text, file_to_print);
}
}
-
- do_cleanups (cleanups);
}
static void
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));
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. */
printf_filtered (" `%s' -> `%s'.\n", rule->from, rule->to);
rule = rule->next;
}
-
- do_cleanups (cleanup);
}
/* Implement the "unset substitute-path" command. */
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"));
error (_("No substitution rule defined for `%s'"), from);
forget_cached_source_info ();
-
- do_cleanups (cleanup);
}
/* Add a new source path substitution rule. */
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"));
add_substitute_path_rule (argv[0], argv[1]);
forget_cached_source_info ();
-
- do_cleanups (cleanup);
}
\f
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++)
{
}
else
{
- char **argv = gdb_buildargv (args);
objfile_flags flags = OBJF_USERLOADED;
symfile_add_flags add_flags = 0;
struct cleanup *cleanups;
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);
}
}
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);
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;
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])
{
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;
my_cleanups = make_cleanup (null_cleanup, NULL);
- argv = gdb_buildargv (args);
+ gdb_argv argv (args);
if (strcmp (argv[0], "-a") == 0)
{
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;
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)
{
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;
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)
{
{
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)
{
ALL_DOMAIN);
}
}
-
- do_cleanups (cleanups);
}
\f
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>"));
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");
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)
{
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);
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? ")))
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 ();
}
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,
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. */