diff --git a/lib/libc/stdlib/getopt_long.3 b/lib/libc/stdlib/getopt_long.3 index ffe5d0034c83..88738b020bd4 100644 --- a/lib/libc/stdlib/getopt_long.3 +++ b/lib/libc/stdlib/getopt_long.3 @@ -294,23 +294,23 @@ that use as an option flag. This practice is wrong, and should not be used in any current development. .El -.It -Handling of -.Ql :: -in options string in presence of -.Ev POSIXLY_CORRECT : -.Bl -tag -width ".Bx" -.It Both -.Tn GNU -and -.Bx -ignore -.Ev POSIXLY_CORRECT -here and take -.Ql :: -to -mean the preceding option takes an optional argument. -.El +.\" .It +.\" Handling of +.\" .Ql :: +.\" in options string in presence of +.\" .Ev POSIXLY_CORRECT : +.\" .Bl -tag -width ".Bx" +.\" .It Both +.\" .Tn GNU +.\" and +.\" .Bx +.\" ignore +.\" .Ev POSIXLY_CORRECT +.\" here and take +.\" .Ql :: +.\" to +.\" mean the preceding option takes an optional argument. +.\" .El .It Return value in case of missing argument if first character (after @@ -435,8 +435,8 @@ set to .Tn GNU Ns 's man page documents). .El -.It -The error messages are different. +.\" .It +.\" The error messages are different. .It .Bx does not permute the argument vector at the same points in diff --git a/lib/libc/stdlib/getopt_long.c b/lib/libc/stdlib/getopt_long.c index 92cffab9ba3a..689503eba4be 100644 --- a/lib/libc/stdlib/getopt_long.c +++ b/lib/libc/stdlib/getopt_long.c @@ -70,7 +70,9 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef notyet +#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ + +#ifndef GNU_COMPATIBLE #define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ #endif @@ -110,11 +112,21 @@ static int nonopt_end = -1; /* first option after non options (for permute) */ /* Error messages */ static const char recargchar[] = "option requires an argument -- %c"; +/* From P1003.2 */ +static const char illoptchar[] = "illegal option -- %c"; +#ifdef GNU_COMPATIBLE +static const char gnuoptchar[] = "invalid option -- %c"; + +static const char recargstring[] = "option `--%s' requires an argument"; +static const char ambig[] = "option `--%.*s' is ambiguous"; +static const char noarg[] = "option `--%.*s' doesn't allow an argument"; +static const char illoptstring[] = "unrecognized option `--%s'"; +#else static const char recargstring[] = "option requires an argument -- %s"; static const char ambig[] = "ambiguous option -- %.*s"; static const char noarg[] = "option doesn't take an argument -- %.*s"; -static const char illoptchar[] = "unknown option -- %c"; static const char illoptstring[] = "unknown option -- %s"; +#endif /* * Compute the greatest common divisor of a and b. @@ -300,7 +312,7 @@ getopt_internal(int nargc, char * const *nargv, const char *options, { char *oli; /* option letter list index */ int optchar, short_too; - static int posixly_correct = -1; + int posixly_correct; if (options == NULL) return (-1); @@ -309,16 +321,18 @@ getopt_internal(int nargc, char * const *nargv, const char *options, * Disable GNU extensions if POSIXLY_CORRECT is set or options * string begins with a '+'. */ - if (posixly_correct == -1) - posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - /* - * Code "else if (*options == '-')" was here. - * Try to be more GNU compatible, configure's use us! - */ + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); +#ifdef GNU_COMPATIBLE if (*options == '-') flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; +#else + if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + else if (*options == '-') + flags |= FLAG_ALLARGS; +#endif if (*options == '+' || *options == '-') options++; @@ -442,8 +456,14 @@ getopt_internal(int nargc, char * const *nargv, const char *options, return (-1); if (!*place) ++optind; +#ifdef GNU_COMPATIBLE + if (PRINT_ERROR) + warnx(posixly_correct ? illoptchar : gnuoptchar, + optchar); +#else if (PRINT_ERROR) warnx(illoptchar, optchar); +#endif optopt = optchar; return (BADCH); }