diff options
author | Thomas Kindler <mail+newlib@t-kindler.de> | 2018-05-29 14:04:56 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2018-06-18 18:45:44 +0200 |
commit | 9dd3c3b0ad176683e2c004cb1c734588b63e59d7 (patch) | |
tree | 22ad79c162a19065d1beeeb52432ff62280181b5 /newlib/libc/stdlib | |
parent | ebc9171ede5dac2e28ce2c83f8bc550693981394 (diff) | |
download | newlib-9dd3c3b0ad176683e2c004cb1c734588b63e59d7.zip newlib-9dd3c3b0ad176683e2c004cb1c734588b63e59d7.tar.gz newlib-9dd3c3b0ad176683e2c004cb1c734588b63e59d7.tar.bz2 |
newlib: getopt now permutes multi-flag options correctly
Previously, "test 1 2 3 -a -b -c" was permuted to "test -a -b -c 1 2 3",
but "test 1 2 3 -abc" was left as "test 1 2 3 -abc".
Signed-off-by: Thomas Kindler <mail+newlib@t-kindler.de>
Diffstat (limited to 'newlib/libc/stdlib')
-rw-r--r-- | newlib/libc/stdlib/getopt.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/newlib/libc/stdlib/getopt.c b/newlib/libc/stdlib/getopt.c index 1094747..d4f225a 100644 --- a/newlib/libc/stdlib/getopt.c +++ b/newlib/libc/stdlib/getopt.c @@ -118,6 +118,8 @@ int optopt = '?'; /* static variables */ static int optwhere = 0; +static int permute_from = 0; +static int num_nonopts = 0; /* functions */ @@ -163,6 +165,8 @@ read_globals (struct getopt_data *data) data->opterr = opterr; data->optopt = optopt; data->optwhere = optwhere; + data->permute_from = permute_from; + data->num_nonopts = num_nonopts; } /* write_globals: write the values into the globals from a getopt_data @@ -175,6 +179,8 @@ write_globals (struct getopt_data *data) opterr = data->opterr; optopt = data->optopt; optwhere = data->optwhere; + permute_from = data->permute_from; + num_nonopts = data->num_nonopts; } /* getopt_internal: the function that does all the dirty work @@ -186,8 +192,6 @@ getopt_internal (int argc, char *const argv[], const char *shortopts, struct getopt_data *data) { GETOPT_ORDERING_T ordering = PERMUTE; - size_t permute_from = 0; - int num_nonopts = 0; int optindex = 0; size_t match_chars = 0; char *possible_arg = 0; @@ -209,7 +213,12 @@ getopt_internal (int argc, char *const argv[], const char *shortopts, /* if this is our first time through */ if (data->optind == 0) - data->optind = data->optwhere = 1; + { + data->optind = 1; + data->optwhere = 1; + data->permute_from = 0; + data->num_nonopts = 0; + } /* define ordering */ if (shortopts != 0 && (*shortopts == '-' || *shortopts == '+')) @@ -237,24 +246,24 @@ getopt_internal (int argc, char *const argv[], const char *shortopts, { default: /* shouldn't happen */ case PERMUTE: - permute_from = data->optind; - num_nonopts = 0; + data->permute_from = data->optind; + data->num_nonopts = 0; while (!is_option (argv[data->optind], only)) { data->optind++; - num_nonopts++; + data->num_nonopts++; } if (argv[data->optind] == 0) { /* no more options */ - data->optind = permute_from; + data->optind = data->permute_from; return EOF; } else if (strcmp (argv[data->optind], "--") == 0) { /* no more options, but have to get `--' out of the way */ - permute (argv + permute_from, num_nonopts, 1); - data->optind = permute_from + 1; + permute (argv + data->permute_from, data->num_nonopts, 1); + data->optind = data->permute_from + 1; return EOF; } break; @@ -426,10 +435,10 @@ getopt_internal (int argc, char *const argv[], const char *shortopts, } /* do we have to permute or otherwise modify data->optind? */ - if (ordering == PERMUTE && data->optwhere == 1 && num_nonopts != 0) + if (ordering == PERMUTE && data->optwhere == 1 && data->num_nonopts != 0) { - permute (argv + permute_from, num_nonopts, 1 + arg_next); - data->optind = permute_from + 1 + arg_next; + permute (argv + data->permute_from, data->num_nonopts, 1 + arg_next); + data->optind = data->permute_from + 1 + arg_next; } else if (data->optwhere == 1) data->optind = data->optind + 1 + arg_next; |