From 3595a9c789947fe9f3ba804ccbb1af72186e404c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 16 Oct 2012 19:11:48 +0000 Subject: [PATCH] * libc/stdlib/getopt.c (getopt_internal): Align handling of colon to SUSv4 requirements. (__getopt_long_r): Fix formatting. --- newlib/ChangeLog | 6 ++++++ newlib/libc/stdlib/getopt.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 45e2d73d9..ce3a390e9 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,9 @@ +2012-10-16 Gregory Pietsch + + * libc/stdlib/getopt.c (getopt_internal): Align handling of colon to + SUSv4 requirements. + (__getopt_long_r): Fix formatting. + 2012-10-16 Corinna Vinschen * libc/stdio/vfprintf.c (__sbprintf): Fix comment. diff --git a/newlib/libc/stdlib/getopt.c b/newlib/libc/stdlib/getopt.c index 944214d5f..2bea694e8 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); }