aboutsummaryrefslogtreecommitdiff
path: root/sim/common
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2016-01-03 21:40:34 -0500
committerMike Frysinger <vapier@gentoo.org>2016-01-03 22:07:39 -0500
commit77cf2ef5dc9099501529151921a73be904757466 (patch)
treeafe55fc45fb53886d73ed81e984f83222ab759a7 /sim/common
parent3726f72c654ab357be5b79c78f238da7a869f9a3 (diff)
downloadgdb-77cf2ef5dc9099501529151921a73be904757466.zip
gdb-77cf2ef5dc9099501529151921a73be904757466.tar.gz
gdb-77cf2ef5dc9099501529151921a73be904757466.tar.bz2
sim: parse_args: display getopt error ourselves
Fix a long standing todo where we let getopt write directly to stderr when an invalid option is passed. Use the sim io funcs instead as they go through the filtered callbacks that gdb wants.
Diffstat (limited to 'sim/common')
-rw-r--r--sim/common/ChangeLog6
-rw-r--r--sim/common/sim-options.c28
2 files changed, 33 insertions, 1 deletions
diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog
index d358491..9de5238 100644
--- a/sim/common/ChangeLog
+++ b/sim/common/ChangeLog
@@ -1,5 +1,11 @@
2016-01-03 Mike Frysinger <vapier@gentoo.org>
+ * sim-options.c (sim_parse_args): Declare local save_opterr. Save
+ opterr state to it before calling getopt_long and restore afterwards.
+ Set opterr to 0. When optc is '?', call sim_io_eprintf.
+
+2016-01-03 Mike Frysinger <vapier@gentoo.org>
+
* hw-device.h (device): Delete commented typedef.
* sim-basics.h (device): Delete typedef.
diff --git a/sim/common/sim-options.c b/sim/common/sim-options.c
index 88663f7..f662b73 100644
--- a/sim/common/sim-options.c
+++ b/sim/common/sim-options.c
@@ -460,7 +460,7 @@ dup_arg_p (const char *arg)
SIM_RC
sim_parse_args (SIM_DESC sd, char **argv)
{
- int c, i, argc, num_opts;
+ int c, i, argc, num_opts, save_opterr;
char *p, *short_options;
/* The `val' option struct entry is dynamically assigned for options that
only come in the long form. ORIG_VAL is used to get the original value
@@ -583,6 +583,11 @@ sim_parse_args (SIM_DESC sd, char **argv)
/* Ensure getopt is initialized. */
optind = 0;
+ /* Do not lot getopt throw errors for us. But don't mess with the state for
+ any callers higher up by saving/restoring it. */
+ save_opterr = opterr;
+ opterr = 0;
+
while (1)
{
int longind, optc;
@@ -596,6 +601,25 @@ sim_parse_args (SIM_DESC sd, char **argv)
}
if (optc == '?')
{
+ /* If getopt rejects a short option, optopt is set to the bad char.
+ If it rejects a long option, we have to look at optind. In the
+ short option case, argv could be multiple short options. */
+ const char *badopt;
+ char optbuf[3];
+
+ if (optopt)
+ {
+ sprintf (optbuf, "-%c", optopt);
+ badopt = optbuf;
+ }
+ else
+ badopt = argv[optind - 1];
+
+ sim_io_eprintf (sd,
+ "%s: unrecognized option: %s\n"
+ "Use --help for a complete list of options.\n",
+ STATE_MY_NAME (sd), badopt);
+
result = SIM_RC_FAIL;
break;
}
@@ -607,6 +631,8 @@ sim_parse_args (SIM_DESC sd, char **argv)
}
}
+ opterr = save_opterr;
+
free (long_options);
free (short_options);
free (handlers);