aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc/stdlib/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/stdlib/getopt.c')
-rw-r--r--newlib/libc/stdlib/getopt.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/newlib/libc/stdlib/getopt.c b/newlib/libc/stdlib/getopt.c
index 944214d..2bea694 100644
--- a/newlib/libc/stdlib/getopt.c
+++ b/newlib/libc/stdlib/getopt.c
@@ -71,6 +71,14 @@ The special argument `--' forces an end of option-scanning regardless of the
value of ordering. In the case of RETURN_IN_ORDER, only `--' can cause
getopt() and friends to return EOF with optind != argc.
+2012-08-26: Tried to make the error handling more sus4-like. The functions
+return a colon if getopt() and friends detect a missing argument and the
+first character of shortopts/optstring starts with a colon (`:'). If getopt()
+and friends detect a missing argument and shortopts/optstring does not start
+with a colon, the function returns a question mark (`?'). If it was a missing
+argument to a short option, optopt is set to the character in question. The
+colon goes after the ordering character (`+' or `-').
+
COPYRIGHT NOTICE AND DISCLAIMER:
Copyright (C) 1997 Gregory Pietsch
@@ -185,6 +193,7 @@ getopt_internal (int argc, char *const argv[], const char *shortopts,
int has_arg = -1;
char *cp = 0;
int arg_next = 0;
+ int initial_colon = 0;
/* first, deal with silly parameters and easy stuff */
if (argc == 0 || argv == 0 || (shortopts == 0 && longopts == 0)
@@ -209,6 +218,13 @@ getopt_internal (int argc, char *const argv[], const char *shortopts,
else
ordering = (getenv ("POSIXLY_CORRECT") != 0) ? REQUIRE_ORDER : PERMUTE;
+ /* check for initial colon in shortopts */
+ if (shortopts != 0 && *shortopts == ':')
+ {
+ ++shortopts;
+ initial_colon = 1;
+ }
+
/*
* based on ordering, find our next option, if we're at the beginning of
* one
@@ -359,12 +375,18 @@ getopt_internal (int argc, char *const argv[], const char *shortopts,
{
fprintf (stderr, "%s: argument required for option `", argv[0]);
if (longopt_match >= 0)
- fprintf (stderr, "--%s'\n", longopts[longopt_match].name);
+ {
+ fprintf (stderr, "--%s'\n", longopts[longopt_match].name);
+ data->optopt = initial_colon ? ':' : '\?';
+ }
else
- fprintf (stderr, "-%c'\n", *cp);
+ {
+ fprintf (stderr, "-%c'\n", *cp);
+ data->optopt = *cp;
+ }
}
data->optind++;
- return (data->optopt = ':');
+ return initial_colon ? ':' : '\?';
}
else
{
@@ -460,8 +482,8 @@ __getopt_r (int argc, char *const argv[], const char *optstring,
int
__getopt_long_r (int argc, char *const argv[], const char *shortopts,
- const struct option *longopts, int *longind,
- struct getopt_data *data)
+ const struct option *longopts, int *longind,
+ struct getopt_data *data)
{
return getopt_internal (argc, argv, shortopts, longopts, longind, 0, data);
}