Merge some fixes from NetBSD's getopt.c v1.26:

cleanups, handling 'ls -l-', handling '--*'

Note this is in the same time back out of our v1.3
"Don't print an error message if the bad option is '?'"
because it directly violates POSIX.
This commit is contained in:
Andrey A. Chernov 2004-03-06 17:05:45 +00:00
parent 0d8ed52ea5
commit 9109761318

View File

@ -1,3 +1,5 @@
/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
@ -41,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "un-namespace.h"
#include "libc_private.h"
@ -62,48 +65,64 @@ char *optarg; /* argument associated with option */
int
getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
char * const nargv[];
const char *ostr;
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
if (optreset || *place == 0) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = nargv[optind];
if (optind >= nargc || *place++ != '-') {
/* Argument is absent or is not an option */
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
optopt = *place++;
if (optopt == '-' && *place == 0) {
/* "--" => end of options */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
if (optopt == 0) {
/* Solitary '-', treat as a '-' option
if the program (eg su) is looking for it. */
place = EMSG;
if (strchr(ostr, '-') == NULL)
return (-1);
optopt = '-';
}
} else
optopt = *place++;
/* See if option letter is one the caller wanted... */
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
if (*place == 0)
++optind;
if (opterr && *ostr != ':' && optopt != BADCH)
(void)fprintf(stderr, "%s: illegal option -- %c\n",
_getprogname(), optopt);
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", _getprogname(),
optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
/* Does this option need an argument? */
if (oli[1] != ':') {
/* don't need argument */
optarg = NULL;
if (!*place)
if (*place == 0)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
} else {
/* Option-argument is either the rest of this argument or the
entire next argument. */
if (*place)
optarg = place;
else if (nargc <= ++optind) { /* no arg */
else if (nargc > ++optind)
optarg = nargv[optind];
else {
/* option-argument absent */
place = EMSG;
if (*ostr == ':')
return (BADARG);
@ -113,10 +132,8 @@ getopt(nargc, nargv, ostr)
_getprogname(), optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
return (optopt); /* return option letter */
}