jbc@mcc-db.UUCP (John B. Chambers) (07/15/85)
From: John Chambers (guest moderator) <ut-sally!std-unix> Topic: getopt and command line arguments continued ---------------------------------------------------------------------- Date: Wed, 10 Jul 85 15:14:05 edt From: harvard!talcott!wjh12!mirror!rs@ut-sally.ARPA (Rich Salz) Subject: Re; bostic's getopt I have modified Keith Bostic's getopt code to make three changes: 1. my own (warped) esthetics. 2. add non-stdio code compile-time flag. 3. add trivial code to handle the opterr variable. This last change is the most important; opterr, if set to 0 in mainline code, suppresses printing all error messages. i also cleaned up a couple of things. feel free to re-post this to std-unix, or even {net,mod}.sourceds if you think it will be worthwhile... -- Rich $alz {mit-eddie, ihnp4!inmet, wjh12, cca, datacube} !mirror!rs Mirror Systems 2067 Massachusetts Ave. 617-661-0777 Cambridge, MA, 02140 /* ** This is a public domain version of getopt(3). ** Bugs, fixes to: ** Keith Bostic ** ARPA: keith@seismo ** UUCP: seismo!keith ** Added NO_STDIO, opterr handling, Rich $alz (mirror!rs). */ #include <stdio.h> /* ** Error macro. Maybe we want stdio, maybe we don't. ** The (undocumented?) variable opterr tells us whether or not ** to print errors. */ #ifdef NO_STDIO #define tell(s) \ if (opterr) \ { \ char ebuf[2]; \ (void)write(2, nargv, (unsigned int)strlen(nargv)); \ (void)write(2, s, (unsigned int)strlen(s)); \ ebuf[0] = optopt; \ ebuf[1] = '\n'; \ (void)write(2, ebuf, 2); \ } #else #define tell(s) \ if (opterr) \ (void)fputs(*nargv, stderr), \ (void)fputs(s,stderr), \ (void)fputc(optopt, stderr), \ (void)fputc('\n', stderr) #endif /* Global variables. */ static char EMSG[] = ""; int opterr = 1; /* undocumented error-suppressor*/ int optind = 1, /* index into argv vector */ int optopt; /* char checked for validity */ char *optarg; /* arg associated with option */ /* Linked in later. */ extern char *index(); /* This may be strchr */ getopt(nargc, nargv, ostr) int nargc; char **nargv; char *ostr; { static char *place = EMSG; /* option letter processing */ register char *oli; /* option letter list index */ if (!*place) /* update scanning pointer */ { if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF); if (*place == '-') /* found "--" */ { optind++; return(EOF); } } /* option letter okay? */ if ((optopt = *place++) == ':' || (oli = index(ostr, optopt)) == NULL) { if (!*place) optind++; tell(": illegal option -- "); goto Bad; } if (*++oli != ':') /* don't need argument */ { optarg = NULL; if (!*place) optind++; } else /* need an argument */ { if (*place) optarg = place; /* no white space */ else if (nargc <= ++optind) { place = EMSG; tell(": option requires an argument -- "); goto Bad; } else optarg = nargv[optind]; /* white space */ place = EMSG; optind++; } return(optopt); /* dump back option letter */ Bad: return('?'); } ---------------------------------------------------------------------- -- John B. Chambers, Microelectronics and Computer Technology Corp., Austin, TX {ihnp4,seismo,ctvax}!ut-sally!mcc-db!jbc, jbc@ut-sally.ARPA, chambers@mcc.ARPA