159583Smuller /*-
259599Sbostic * Copyright (c) 1991 Keith Muller.
3*62178Sbostic * Copyright (c) 1993
4*62178Sbostic * The Regents of the University of California. All rights reserved.
559583Smuller *
659599Sbostic * This code is derived from software contributed to Berkeley by
759599Sbostic * Keith Muller of the University of California, San Diego.
859599Sbostic *
959583Smuller * %sccs.include.redist.c%
1059583Smuller */
1159583Smuller
1259583Smuller #ifndef lint
13*62178Sbostic static char sccsid[] = "@(#)egetopt.c 8.1 (Berkeley) 06/06/93";
1459583Smuller #endif /* not lint */
1559583Smuller
1659599Sbostic #include <ctype.h>
1759583Smuller #include <stdio.h>
1859583Smuller #include <stdlib.h>
1959583Smuller #include <string.h>
2059599Sbostic
2159583Smuller #include "extern.h"
2259583Smuller
2359583Smuller /*
2459583Smuller * egetopt: get option letter from argument vector (an extended
2559583Smuller * version of getopt).
2659583Smuller *
2759583Smuller * Non standard additions to the ostr specs are:
2859583Smuller * 1) '?': immediate value following arg is optional (no white space
2959583Smuller * between the arg and the value)
3059583Smuller * 2) '#': +/- followed by a number (with an optional sign but
3159583Smuller * no white space between the arg and the number). The - may be
3259583Smuller * combined with other options, but the + cannot.
3359583Smuller */
3459583Smuller
3559583Smuller int eopterr = 1; /* if error message should be printed */
3659583Smuller int eoptind = 1; /* index into parent argv vector */
3759583Smuller int eoptopt; /* character checked for validity */
3859583Smuller char *eoptarg; /* argument associated with option */
3959583Smuller
4059583Smuller #define BADCH (int)'?'
4159583Smuller #define EMSG ""
4259583Smuller
4359583Smuller int
egetopt(nargc,nargv,ostr)4459583Smuller egetopt(nargc, nargv, ostr)
4559583Smuller int nargc;
4659599Sbostic char * const *nargv;
4759599Sbostic const char *ostr;
4859583Smuller {
4959583Smuller static char *place = EMSG; /* option letter processing */
5059583Smuller register char *oli; /* option letter list index */
5159583Smuller static int delim; /* which option delimeter */
5259583Smuller register char *p;
5359583Smuller static char savec = '\0';
5459583Smuller
5559583Smuller if (savec != '\0') {
5659583Smuller *place = savec;
5759583Smuller savec = '\0';
5859583Smuller }
5959583Smuller
6059583Smuller if (!*place) {
6159583Smuller /*
6259583Smuller * update scanning pointer
6359583Smuller */
6459583Smuller if ((eoptind >= nargc) ||
6559583Smuller ((*(place = nargv[eoptind]) != '-') && (*place != '+'))) {
6659583Smuller place = EMSG;
6759599Sbostic return (EOF);
6859583Smuller }
6959583Smuller
7059583Smuller delim = (int)*place;
7159583Smuller if (place[1] && *++place == '-' && !place[1]) {
7259583Smuller /*
7359583Smuller * found "--"
7459583Smuller */
7559583Smuller ++eoptind;
7659583Smuller place = EMSG;
7759599Sbostic return (EOF);
7859583Smuller }
7959583Smuller }
8059583Smuller
8159583Smuller /*
8259583Smuller * check option letter
8359583Smuller */
8459583Smuller if ((eoptopt = (int)*place++) == (int)':' || (eoptopt == (int)'?') ||
8559599Sbostic !(oli = strchr(ostr, eoptopt))) {
8659583Smuller /*
8759583Smuller * if the user didn't specify '-' as an option,
8859583Smuller * assume it means EOF when by itself.
8959583Smuller */
9059583Smuller if ((eoptopt == (int)'-') && !*place)
9159599Sbostic return (EOF);
9259599Sbostic if (strchr(ostr, '#') && (isdigit(eoptopt) ||
9359583Smuller (((eoptopt == (int)'-') || (eoptopt == (int)'+')) &&
9459583Smuller isdigit(*place)))) {
9559583Smuller /*
9659583Smuller * # option: +/- with a number is ok
9759583Smuller */
9859583Smuller for (p = place; *p != '\0'; ++p) {
9959583Smuller if (!isdigit(*p))
10059583Smuller break;
10159583Smuller }
10259583Smuller eoptarg = place-1;
10359583Smuller
10459583Smuller if (*p == '\0') {
10559583Smuller place = EMSG;
10659583Smuller ++eoptind;
10759583Smuller } else {
10859583Smuller place = p;
10959583Smuller savec = *p;
11059583Smuller *place = '\0';
11159583Smuller }
11259599Sbostic return (delim);
11359583Smuller }
11459583Smuller
11559583Smuller if (!*place)
11659583Smuller ++eoptind;
11759583Smuller if (eopterr) {
11859599Sbostic if (!(p = strrchr(*nargv, '/')))
11959583Smuller p = *nargv;
12059583Smuller else
12159583Smuller ++p;
12259583Smuller (void)fprintf(stderr, "%s: illegal option -- %c\n",
12359583Smuller p, eoptopt);
12459583Smuller }
12559599Sbostic return (BADCH);
12659583Smuller }
12759583Smuller if (delim == (int)'+') {
12859583Smuller /*
12959583Smuller * '+' is only allowed with numbers
13059583Smuller */
13159583Smuller if (!*place)
13259583Smuller ++eoptind;
13359583Smuller if (eopterr) {
13459599Sbostic if (!(p = strrchr(*nargv, '/')))
13559583Smuller p = *nargv;
13659583Smuller else
13759583Smuller ++p;
13859583Smuller (void)fprintf(stderr,
13959583Smuller "%s: illegal '+' delimiter with option -- %c\n",
14059583Smuller p, eoptopt);
14159583Smuller }
14259599Sbostic return (BADCH);
14359583Smuller }
14459583Smuller ++oli;
14559583Smuller if ((*oli != ':') && (*oli != '?')) {
14659583Smuller /*
14759583Smuller * don't need argument
14859583Smuller */
14959583Smuller eoptarg = NULL;
15059583Smuller if (!*place)
15159583Smuller ++eoptind;
15259599Sbostic return (eoptopt);
15359583Smuller }
15459583Smuller
15559583Smuller if (*place) {
15659583Smuller /*
15759583Smuller * no white space
15859583Smuller */
15959583Smuller eoptarg = place;
16059583Smuller } else if (*oli == '?') {
16159583Smuller /*
16259583Smuller * no arg, but NOT required
16359583Smuller */
16459583Smuller eoptarg = NULL;
16559583Smuller } else if (nargc <= ++eoptind) {
16659583Smuller /*
16759583Smuller * no arg, but IS required
16859583Smuller */
16959583Smuller place = EMSG;
17059583Smuller if (eopterr) {
17159599Sbostic if (!(p = strrchr(*nargv, '/')))
17259583Smuller p = *nargv;
17359583Smuller else
17459583Smuller ++p;
17559583Smuller (void)fprintf(stderr,
17659583Smuller "%s: option requires an argument -- %c\n", p,
17759583Smuller eoptopt);
17859583Smuller }
17959599Sbostic return (BADCH);
18059583Smuller } else {
18159583Smuller /*
18259583Smuller * arg has white space
18359583Smuller */
18459583Smuller eoptarg = nargv[eoptind];
18559583Smuller }
18659583Smuller place = EMSG;
18759583Smuller ++eoptind;
18859599Sbostic return (eoptopt);
18959583Smuller }
190