Make extract_arg return a std::string

Change extract_arg to return a std::string and fix up all the users.
I think string is mildly better than unique_xmalloc_ptr<char>, when
possible, because it provides a more robust API.

I changed the error messages emitted from find_location_by_number to
avoid either writing to a string or an extra allocation; this can be
changed but I thought that the new message was not any less clear.
You can see an example in the testsuite patch.

ChangeLog
2017-09-11  Tom Tromey  <tom@tromey.com>

	* demangle.c (demangle_command): Update.
	* breakpoint.c (disable_command): Update.
	(enable_command): Update.
	(find_location_by_number): Make "number" const.  Use
	get_number_trailer.
	* cli/cli-utils.c (extract_arg): Return std::string.
	* probe.c (parse_probe_linespec): Update.  Change types.
	(collect_probes): Take string arguments.
	(parse_probe_linespec): Likewise.
	(info_probes_for_ops): Update.
	(enable_probes_command): Update.
	(disable_probes_command): Update.
	* break-catch-sig.c (catch_signal_split_args): Update.
	* mi/mi-parse.c (mi_parse): Update.

testsuite/ChangeLog
2017-09-11  Tom Tromey  <tom@tromey.com>

	* gdb.base/ena-dis-br.exp (test_ena_dis_br): Update test.
This commit is contained in:
Tom Tromey 2017-09-10 14:48:30 -06:00
parent 2039bd9f0c
commit cb791d5948
10 changed files with 92 additions and 85 deletions

View file

@ -1,3 +1,20 @@
2017-09-11 Tom Tromey <tom@tromey.com>
* demangle.c (demangle_command): Update.
* breakpoint.c (disable_command): Update.
(enable_command): Update.
(find_location_by_number): Make "number" const. Use
get_number_trailer.
* cli/cli-utils.c (extract_arg): Return std::string.
* probe.c (parse_probe_linespec): Update. Change types.
(collect_probes): Take string arguments.
(parse_probe_linespec): Likewise.
(info_probes_for_ops): Update.
(enable_probes_command): Update.
(disable_probes_command): Update.
* break-catch-sig.c (catch_signal_split_args): Update.
* mi/mi-parse.c (mi_parse): Update.
2017-09-11 Tom Tromey <tom@tromey.com> 2017-09-11 Tom Tromey <tom@tromey.com>
* language.h (language_enum): Make argument const. * language.h (language_enum): Make argument const.

View file

@ -343,12 +343,12 @@ catch_signal_split_args (char *arg, bool *catch_all)
gdb_signal signal_number; gdb_signal signal_number;
char *endptr; char *endptr;
gdb::unique_xmalloc_ptr<char> one_arg (extract_arg (&arg)); std::string one_arg = extract_arg (&arg);
if (one_arg == NULL) if (one_arg.empty ())
break; break;
/* Check for the special flag "all". */ /* Check for the special flag "all". */
if (strcmp (one_arg.get (), "all") == 0) if (one_arg == "all")
{ {
arg = skip_spaces (arg); arg = skip_spaces (arg);
if (*arg != '\0' || !first) if (*arg != '\0' || !first)
@ -361,14 +361,14 @@ catch_signal_split_args (char *arg, bool *catch_all)
first = false; first = false;
/* Check if the user provided a signal name or a number. */ /* Check if the user provided a signal name or a number. */
num = (int) strtol (one_arg.get (), &endptr, 0); num = (int) strtol (one_arg.c_str (), &endptr, 0);
if (*endptr == '\0') if (*endptr == '\0')
signal_number = gdb_signal_from_command (num); signal_number = gdb_signal_from_command (num);
else else
{ {
signal_number = gdb_signal_from_name (one_arg.get ()); signal_number = gdb_signal_from_name (one_arg.c_str ());
if (signal_number == GDB_SIGNAL_UNKNOWN) if (signal_number == GDB_SIGNAL_UNKNOWN)
error (_("Unknown signal name '%s'."), one_arg.get ()); error (_("Unknown signal name '%s'."), one_arg.c_str ());
} }
result.push_back (signal_number); result.push_back (signal_number);

View file

@ -14489,20 +14489,17 @@ map_breakpoint_numbers (const char *args,
} }
static struct bp_location * static struct bp_location *
find_location_by_number (char *number) find_location_by_number (const char *number)
{ {
char *dot = strchr (number, '.'); const char *p1;
char *p1;
int bp_num; int bp_num;
int loc_num; int loc_num;
struct breakpoint *b; struct breakpoint *b;
struct bp_location *loc; struct bp_location *loc;
*dot = '\0';
p1 = number; p1 = number;
bp_num = get_number (&p1); bp_num = get_number_trailer (&p1, '.');
if (bp_num == 0) if (bp_num == 0 || p1[0] != '.')
error (_("Bad breakpoint number '%s'"), number); error (_("Bad breakpoint number '%s'"), number);
ALL_BREAKPOINTS (b) ALL_BREAKPOINTS (b)
@ -14514,7 +14511,9 @@ find_location_by_number (char *number)
if (!b || b->number != bp_num) if (!b || b->number != bp_num)
error (_("Bad breakpoint number '%s'"), number); error (_("Bad breakpoint number '%s'"), number);
p1 = dot+1; /* Skip the dot. */
++p1;
const char *save = p1;
loc_num = get_number (&p1); loc_num = get_number (&p1);
if (loc_num == 0) if (loc_num == 0)
error (_("Bad breakpoint location number '%s'"), number); error (_("Bad breakpoint location number '%s'"), number);
@ -14524,7 +14523,7 @@ find_location_by_number (char *number)
for (;loc_num && loc; --loc_num, loc = loc->next) for (;loc_num && loc; --loc_num, loc = loc->next)
; ;
if (!loc) if (!loc)
error (_("Bad breakpoint location number '%s'"), dot+1); error (_("Bad breakpoint location number '%s'"), save);
return loc; return loc;
} }
@ -14592,13 +14591,13 @@ disable_command (char *args, int from_tty)
} }
else else
{ {
char *num = extract_arg (&args); std::string num = extract_arg (&args);
while (num) while (!num.empty ())
{ {
if (strchr (num, '.')) if (num.find ('.') != std::string::npos)
{ {
struct bp_location *loc = find_location_by_number (num); struct bp_location *loc = find_location_by_number (num.c_str ());
if (loc) if (loc)
{ {
@ -14615,7 +14614,8 @@ disable_command (char *args, int from_tty)
update_global_location_list (UGLL_DONT_INSERT); update_global_location_list (UGLL_DONT_INSERT);
} }
else else
map_breakpoint_numbers (num, do_map_disable_breakpoint, NULL); map_breakpoint_numbers (num.c_str (), do_map_disable_breakpoint,
NULL);
num = extract_arg (&args); num = extract_arg (&args);
} }
} }
@ -14723,13 +14723,13 @@ enable_command (char *args, int from_tty)
} }
else else
{ {
char *num = extract_arg (&args); std::string num = extract_arg (&args);
while (num) while (!num.empty ())
{ {
if (strchr (num, '.')) if (num.find ('.') != std::string::npos)
{ {
struct bp_location *loc = find_location_by_number (num); struct bp_location *loc = find_location_by_number (num.c_str ());
if (loc) if (loc)
{ {
@ -14746,7 +14746,8 @@ enable_command (char *args, int from_tty)
update_global_location_list (UGLL_MAY_INSERT); update_global_location_list (UGLL_MAY_INSERT);
} }
else else
map_breakpoint_numbers (num, do_map_enable_breakpoint, NULL); map_breakpoint_numbers (num.c_str (), do_map_enable_breakpoint,
NULL);
num = extract_arg (&args); num = extract_arg (&args);
} }
} }

View file

@ -249,36 +249,36 @@ remove_trailing_whitespace (const char *start, const char *s)
/* See documentation in cli-utils.h. */ /* See documentation in cli-utils.h. */
char * std::string
extract_arg (const char **arg) extract_arg (const char **arg)
{ {
const char *result; const char *result;
if (!*arg) if (!*arg)
return NULL; return std::string ();
/* Find the start of the argument. */ /* Find the start of the argument. */
*arg = skip_spaces (*arg); *arg = skip_spaces (*arg);
if (!**arg) if (!**arg)
return NULL; return std::string ();
result = *arg; result = *arg;
/* Find the end of the argument. */ /* Find the end of the argument. */
*arg = skip_to_space (*arg + 1); *arg = skip_to_space (*arg + 1);
if (result == *arg) if (result == *arg)
return NULL; return std::string ();
return savestring (result, *arg - result); return std::string (result, *arg - result);
} }
/* See documentation in cli-utils.h. */ /* See documentation in cli-utils.h. */
char * std::string
extract_arg (char **arg) extract_arg (char **arg)
{ {
const char *arg_const = *arg; const char *arg_const = *arg;
char *result; std::string result;
result = extract_arg (&arg_const); result = extract_arg (&arg_const);
*arg += arg_const - *arg; *arg += arg_const - *arg;

View file

@ -149,17 +149,14 @@ remove_trailing_whitespace (const char *start, char *s)
} }
/* A helper function to extract an argument from *ARG. An argument is /* A helper function to extract an argument from *ARG. An argument is
delimited by whitespace. The return value is either NULL if no delimited by whitespace. The return value is empty if no argument
argument was found, or an xmalloc'd string. */ was found. */
extern char *extract_arg (char **arg); extern std::string extract_arg (char **arg);
/* A const-correct version of the above. /* A const-correct version of the above. */
Since the returned value is xmalloc'd, it eventually needs to be extern std::string extract_arg (const char **arg);
xfree'ed, which prevents us from making it const as well. */
extern char *extract_arg (const char **arg);
/* A helper function that looks for an argument at the start of a /* A helper function that looks for an argument at the start of a
string. The argument must also either be at the end of the string, string. The argument must also either be at the end of the string,

View file

@ -170,21 +170,21 @@ demangle_command (char *args, int from_tty)
std::string arg_buf = args != NULL ? args : ""; std::string arg_buf = args != NULL ? args : "";
arg_start = arg_buf.c_str (); arg_start = arg_buf.c_str ();
gdb::unique_xmalloc_ptr<char> lang_name; std::string lang_name;
while (processing_args while (processing_args
&& *arg_start == '-') && *arg_start == '-')
{ {
const char *p = skip_to_space (arg_start); const char *p = skip_to_space (arg_start);
if (strncmp (arg_start, "-l", p - arg_start) == 0) if (strncmp (arg_start, "-l", p - arg_start) == 0)
lang_name.reset (extract_arg (&p)); lang_name = extract_arg (&p);
else if (strncmp (arg_start, "--", p - arg_start) == 0) else if (strncmp (arg_start, "--", p - arg_start) == 0)
processing_args = 0; processing_args = 0;
else else
{ {
gdb::unique_xmalloc_ptr<char> option (extract_arg (&p)); std::string option = extract_arg (&p);
error (_("Unrecognized option '%s' to demangle command. " error (_("Unrecognized option '%s' to demangle command. "
"Try \"help demangle\"."), option.get ()); "Try \"help demangle\"."), option.c_str ());
} }
arg_start = skip_spaces (p); arg_start = skip_spaces (p);
@ -195,13 +195,13 @@ demangle_command (char *args, int from_tty)
if (*name == '\0') if (*name == '\0')
error (_("Usage: demangle [-l language] [--] name")); error (_("Usage: demangle [-l language] [--] name"));
if (lang_name != NULL) if (!lang_name.empty ())
{ {
enum language lang_enum; enum language lang_enum;
lang_enum = language_enum (lang_name.get ()); lang_enum = language_enum (lang_name.c_str ());
if (lang_enum == language_unknown) if (lang_enum == language_unknown)
error (_("Unknown language \"%s\""), lang_name.get ()); error (_("Unknown language \"%s\""), lang_name.c_str ());
lang = language_def (lang_enum); lang = language_def (lang_enum);
} }
else else

View file

@ -347,20 +347,14 @@ mi_parse (const char *cmd, char **token)
} }
else if (strncmp (chp, "--language ", ls) == 0) else if (strncmp (chp, "--language ", ls) == 0)
{ {
char *lang_name;
struct cleanup *old_chain;
option = "--language"; option = "--language";
chp += ls; chp += ls;
lang_name = extract_arg (&chp); std::string lang_name = extract_arg (&chp);
old_chain = make_cleanup (xfree, lang_name);
parse->language = language_enum (lang_name); parse->language = language_enum (lang_name.c_str ());
if (parse->language == language_unknown if (parse->language == language_unknown
|| parse->language == language_auto) || parse->language == language_auto)
error (_("Invalid --language argument: %s"), lang_name); error (_("Invalid --language argument: %s"), lang_name.c_str ());
do_cleanups (old_chain);
} }
else else
break; break;

View file

@ -275,8 +275,8 @@ find_probe_by_pc (CORE_ADDR pc)
Each argument is a regexp, or NULL, which matches anything. */ Each argument is a regexp, or NULL, which matches anything. */
static VEC (bound_probe_s) * static VEC (bound_probe_s) *
collect_probes (char *objname, char *provider, char *probe_name, collect_probes (const std::string &objname, const std::string &provider,
const struct probe_ops *pops) const std::string &probe_name, const struct probe_ops *pops)
{ {
struct objfile *objfile; struct objfile *objfile;
VEC (bound_probe_s) *result = NULL; VEC (bound_probe_s) *result = NULL;
@ -285,12 +285,15 @@ collect_probes (char *objname, char *provider, char *probe_name,
cleanup = make_cleanup (VEC_cleanup (bound_probe_s), &result); cleanup = make_cleanup (VEC_cleanup (bound_probe_s), &result);
if (provider != NULL) if (!provider.empty ())
prov_pat.emplace (provider, REG_NOSUB, _("Invalid provider regexp")); prov_pat.emplace (provider.c_str (), REG_NOSUB,
if (probe_name != NULL) _("Invalid provider regexp"));
probe_pat.emplace (probe_name, REG_NOSUB, _("Invalid probe regexp")); if (!probe_name.empty ())
if (objname != NULL) probe_pat.emplace (probe_name.c_str (), REG_NOSUB,
obj_pat.emplace (objname, REG_NOSUB, _("Invalid object file regexp")); _("Invalid probe regexp"));
if (!objname.empty ())
obj_pat.emplace (objname.c_str (), REG_NOSUB,
_("Invalid object file regexp"));
ALL_OBJFILES (objfile) ALL_OBJFILES (objfile)
{ {
@ -301,7 +304,7 @@ collect_probes (char *objname, char *provider, char *probe_name,
if (! objfile->sf || ! objfile->sf->sym_probe_fns) if (! objfile->sf || ! objfile->sf->sym_probe_fns)
continue; continue;
if (objname) if (obj_pat)
{ {
if (obj_pat->exec (objfile_name (objfile), 0, NULL, 0) != 0) if (obj_pat->exec (objfile_name (objfile), 0, NULL, 0) != 0)
continue; continue;
@ -316,11 +319,11 @@ collect_probes (char *objname, char *provider, char *probe_name,
if (pops != NULL && probe->pops != pops) if (pops != NULL && probe->pops != pops)
continue; continue;
if (provider if (prov_pat
&& prov_pat->exec (probe->provider, 0, NULL, 0) != 0) && prov_pat->exec (probe->provider, 0, NULL, 0) != 0)
continue; continue;
if (probe_name if (probe_pat
&& probe_pat->exec (probe->name, 0, NULL, 0) != 0) && probe_pat->exec (probe->name, 0, NULL, 0) != 0)
continue; continue;
@ -553,16 +556,16 @@ exists_probe_with_pops (VEC (bound_probe_s) *probes,
[PROBE [OBJNAME]]] from the provided string STR. */ [PROBE [OBJNAME]]] from the provided string STR. */
static void static void
parse_probe_linespec (const char *str, char **provider, parse_probe_linespec (const char *str, std::string *provider,
char **probe_name, char **objname) std::string *probe_name, std::string *objname)
{ {
*probe_name = *objname = NULL; *probe_name = *objname = "";
*provider = extract_arg (&str); *provider = extract_arg (&str);
if (*provider != NULL) if (!provider->empty ())
{ {
*probe_name = extract_arg (&str); *probe_name = extract_arg (&str);
if (*probe_name != NULL) if (!probe_name->empty ())
*objname = extract_arg (&str); *objname = extract_arg (&str);
} }
} }
@ -573,7 +576,7 @@ void
info_probes_for_ops (const char *arg, int from_tty, info_probes_for_ops (const char *arg, int from_tty,
const struct probe_ops *pops) const struct probe_ops *pops)
{ {
char *provider, *probe_name = NULL, *objname = NULL; std::string provider, probe_name, objname;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
VEC (bound_probe_s) *probes; VEC (bound_probe_s) *probes;
int i, any_found; int i, any_found;
@ -587,9 +590,6 @@ info_probes_for_ops (const char *arg, int from_tty,
struct gdbarch *gdbarch = get_current_arch (); struct gdbarch *gdbarch = get_current_arch ();
parse_probe_linespec (arg, &provider, &probe_name, &objname); parse_probe_linespec (arg, &provider, &probe_name, &objname);
make_cleanup (xfree, provider);
make_cleanup (xfree, probe_name);
make_cleanup (xfree, objname);
probes = collect_probes (objname, provider, probe_name, pops); probes = collect_probes (objname, provider, probe_name, pops);
make_cleanup (VEC_cleanup (probe_p), &probes); make_cleanup (VEC_cleanup (probe_p), &probes);
@ -721,16 +721,13 @@ info_probes_command (char *arg, int from_tty)
static void static void
enable_probes_command (char *arg, int from_tty) enable_probes_command (char *arg, int from_tty)
{ {
char *provider, *probe_name = NULL, *objname = NULL; std::string provider, probe_name, objname;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
VEC (bound_probe_s) *probes; VEC (bound_probe_s) *probes;
struct bound_probe *probe; struct bound_probe *probe;
int i; int i;
parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname); parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname);
make_cleanup (xfree, provider);
make_cleanup (xfree, probe_name);
make_cleanup (xfree, objname);
probes = collect_probes (objname, provider, probe_name, NULL); probes = collect_probes (objname, provider, probe_name, NULL);
if (VEC_empty (bound_probe_s, probes)) if (VEC_empty (bound_probe_s, probes))
@ -765,16 +762,13 @@ enable_probes_command (char *arg, int from_tty)
static void static void
disable_probes_command (char *arg, int from_tty) disable_probes_command (char *arg, int from_tty)
{ {
char *provider, *probe_name = NULL, *objname = NULL; std::string provider, probe_name, objname;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
VEC (bound_probe_s) *probes; VEC (bound_probe_s) *probes;
struct bound_probe *probe; struct bound_probe *probe;
int i; int i;
parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname); parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname);
make_cleanup (xfree, provider);
make_cleanup (xfree, probe_name);
make_cleanup (xfree, objname);
probes = collect_probes (objname, provider, probe_name, NULL /* pops */); probes = collect_probes (objname, provider, probe_name, NULL /* pops */);
if (VEC_empty (bound_probe_s, probes)) if (VEC_empty (bound_probe_s, probes))

View file

@ -1,3 +1,7 @@
2017-09-11 Tom Tromey <tom@tromey.com>
* gdb.base/ena-dis-br.exp (test_ena_dis_br): Update test.
2017-09-11 Tom Tromey <tom@tromey.com> 2017-09-11 Tom Tromey <tom@tromey.com>
* gdb.python/py-infthread.exp: Add tests for new_thread event. * gdb.python/py-infthread.exp: Add tests for new_thread event.

View file

@ -369,7 +369,7 @@ proc test_ena_dis_br { what } {
# Now enable(disable) $b1 fooo.1, it should give error on fooo. # Now enable(disable) $b1 fooo.1, it should give error on fooo.
gdb_test "$what $b1 fooo.1" \ gdb_test "$what $b1 fooo.1" \
"Bad breakpoint number 'fooo'" \ "Bad breakpoint number 'fooo\\.1'" \
"$what \$b1 fooo.1" "$what \$b1 fooo.1"
# $b1 should be enabled(disabled). # $b1 should be enabled(disabled).