From 9dd256d9113af69545873d9f2b429e2c52e3c931 Mon Sep 17 00:00:00 2001 From: Danilo Almeida Date: Fri, 4 Feb 2000 20:14:56 +0000 Subject: [PATCH] * getopt.c, getopt_long.c, getopt.h: Update to latest BSD code found (from NetBSD). * Makefile.in: Build getopt.lib which includes getopt.obj and getopt_long.obj. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11990 dc483132-0cff-0310-8789-dd5450dbe970 --- src/util/windows/ChangeLog | 8 ++ src/util/windows/Makefile.in | 10 +- src/util/windows/getopt.c | 94 ++++++++----- src/util/windows/getopt.h | 33 +++++ src/util/windows/getopt_long.c | 236 +++++++++++++++++++++++++++++++++ 5 files changed, 341 insertions(+), 40 deletions(-) create mode 100644 src/util/windows/getopt.h create mode 100644 src/util/windows/getopt_long.c diff --git a/src/util/windows/ChangeLog b/src/util/windows/ChangeLog index 0b1a112df..96fd0aee4 100644 --- a/src/util/windows/ChangeLog +++ b/src/util/windows/ChangeLog @@ -1,3 +1,11 @@ +2000-02-04 Danilo Almeida + + * getopt.c, getopt_long.c, getopt.h: Update to latest BSD code + found (from NetBSD). + + * Makefile.in: Build getopt.lib which includes getopt.obj and + getopt_long.obj. + Mon May 10 15:27:34 1999 Danilo Almeida * Makefile.in: Do win32 build in subdir. diff --git a/src/util/windows/Makefile.in b/src/util/windows/Makefile.in index a260600d4..be5d4f5d6 100644 --- a/src/util/windows/Makefile.in +++ b/src/util/windows/Makefile.in @@ -1,15 +1,13 @@ BUILDTOP = ..\.. -CFLAGS = $(COPTS) $(INCLUDES) - -##WIN16##LFLAGS = /nologo /nod /nopackcode -##WIN32##LFLAGS = /nologo /nod - -##WIN32##all-windows:: $(OUTPRE)libecho.exe $(OUTPRE)getopt.obj +all-windows:: $(OUTPRE)libecho.exe $(OUTPRE)getopt.lib $(OUTPRE)libecho.exe: $(OUTPRE)libecho.obj link -out:$@ $** +$(OUTPRE)getopt.lib: $(OUTPRE)getopt.obj $(OUTPRE)getopt_long.obj + lib -out:$@ $** + install-windows:: clean-windows:: diff --git a/src/util/windows/getopt.c b/src/util/windows/getopt.c index 081520f55..2b21c7be5 100644 --- a/src/util/windows/getopt.c +++ b/src/util/windows/getopt.c @@ -1,5 +1,7 @@ +/* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */ + /* - * Copyright (c) 1987, 1993 + * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,69 +33,97 @@ * SUCH DAMAGE. */ -/* based on @(#)getopt.c 8.1 (Berkeley) 6/4/93 */ - -#ifndef __STDC__ -#define const +#if 0 +static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; #endif + +#include +#include #include -#include #include -/* - * get option letter from argument vector - */ +#define __P(x) x +#define _DIAGASSERT(x) assert(x) + +#ifdef __weak_alias +__weak_alias(getopt,_getopt); +#endif + + int opterr = 1, /* if error message should be printed */ optind = 1, /* index into parent argv vector */ optopt, /* character checked for validity */ optreset; /* reset getopt */ char *optarg; /* argument associated with option */ +static char * _progname __P((char *)); +int getopt_internal __P((int, char * const *, const char *)); + +static char * +_progname(nargv0) + char * nargv0; +{ + char * tmp; + + _DIAGASSERT(nargv0 != NULL); + + tmp = strrchr(nargv0, '/'); + if (tmp) + tmp++; + else + tmp = nargv0; + return(tmp); +} + #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" +/* + * getopt -- + * Parse argc/argv argument vector. + */ int getopt(nargc, nargv, ostr) int nargc; - char * const *nargv; + char * const nargv[]; const char *ostr; { + static char *__progname = 0; static char *place = EMSG; /* option letter processing */ - register char *oli; /* option letter list index */ - char *p; + char *oli; /* option letter list index */ + __progname = __progname?__progname:_progname(*nargv); + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(ostr != NULL); if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; - return(-1); + return (-1); } - if (place[1] && *++place == '-') { /* found "--" */ + if (place[1] && *++place == '-' /* found "--" */ + && place[1] == '\0') { ++optind; place = EMSG; - return(-1); + 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 EOF. + * assume it means -1. */ if (optopt == (int)'-') - return(-1); + return (-1); if (!*place) ++optind; - if (opterr && *ostr != ':') { - if (!(p = strrchr(*nargv, '/'))) - p = *nargv; - else - ++p; - (void)fprintf(stderr, "%s: illegal option -- %c\n", - p, optopt); - } - return(BADCH); + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; @@ -105,22 +135,18 @@ getopt(nargc, nargv, ostr) optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; - if (!(p = strrchr(*nargv, '/'))) - p = *nargv; - else - ++p; if (*ostr == ':') - return(BADARG); + return (BADARG); if (opterr) (void)fprintf(stderr, "%s: option requires an argument -- %c\n", - p, optopt); - return(BADCH); + __progname, optopt); + return (BADCH); } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } - return(optopt); /* dump back option letter */ + return (optopt); /* dump back option letter */ } diff --git a/src/util/windows/getopt.h b/src/util/windows/getopt.h new file mode 100644 index 000000000..7137f0379 --- /dev/null +++ b/src/util/windows/getopt.h @@ -0,0 +1,33 @@ +#ifndef __GETOPT_H__ +#define __GETOPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +int getopt(int, char**, char*); +int getopt_long(int, char**, char*, struct option*, int*); + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_H__ */ diff --git a/src/util/windows/getopt_long.c b/src/util/windows/getopt_long.c new file mode 100644 index 000000000..bb819628e --- /dev/null +++ b/src/util/windows/getopt_long.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 1987, 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "getopt.h" + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +#define __P(x) x +#define _DIAGASSERT(x) assert(x) + +static char * __progname __P((char *)); +int getopt_internal __P((int, char * const *, const char *)); + +static char * +__progname(nargv0) + char * nargv0; +{ + char * tmp; + + _DIAGASSERT(nargv0 != NULL); + + tmp = strrchr(nargv0, '/'); + if (tmp) + tmp++; + else + tmp = nargv0; + return(tmp); +} + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt_internal(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(ostr != NULL); + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + /* ++optind; */ + place = EMSG; + return (-2); + } + } /* 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) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname(nargv[0]), optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if ((opterr) && (*ostr != ':')) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname(nargv[0]), optopt); + return (BADARG); + } else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} + +#if 0 +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt2(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + int retval; + + if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) { + retval = -1; + ++optind; + } + return(retval); +} +#endif + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(nargc, nargv, options, long_options, index) + int nargc; + char ** nargv; + char * options; + struct option * long_options; + int * index; +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* index may be NULL */ + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + char *current_argv = nargv[optind++] + 2, *has_equal; + int i, current_argv_len, match = -1; + + if (*current_argv == '\0') { + return(-1); + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + if (strncmp(current_argv, long_options[i].name, current_argv_len)) + continue; + + if (strlen(long_options[i].name) == (unsigned)current_argv_len) { + match = i; + break; + } + if (match == -1) + match = i; + } + if (match != -1) { + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else + optarg = nargv[optind++]; + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument, leading : + * indicates no error should be generated + */ + if ((opterr) && (*options != ':')) + (void)fprintf(stderr, + "%s: option requires an argument -- %s\n", + __progname(nargv[0]), current_argv); + return (BADARG); + } + } else { /* No matching argument */ + if ((opterr) && (*options != ':')) + (void)fprintf(stderr, + "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv); + return (BADCH); + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (index) + *index = match; + } + return(retval); +} -- 2.26.2