mpatnode@polyslo.UUCP (Mike Patnode) (04/09/88)
Submitted-By: "Mike Patnode" <mpatnode@polyslo.UUCP> Archive-Name: getopt comp.sources.misc: Volume 2, Issue 90 Submitted-By: "Mike Patnode" <mpatnode@polyslo.UUCP> Archive-Name: getopt After my last posting I recieved so many requests for this that I decided this was just as well. I know it's been posted before. I also found a man page. ----------------------------- paste here -------------------------------- echo x - getopt.c sed 's/^X//' >getopt.c <<'*-*-END-of-getopt.c-*-*' X/* X** @(#)getopt.c 2.2 (smail) 1/26/87 X*/ X X/* X * Here's something you've all been waiting for: the AT&T public domain X * source for getopt(3). It is the code which was given out at the 1985 X * UNIFORUM conference in Dallas. I obtained it by electronic mail X * directly from AT&T. The people there assure me that it is indeed X * in the public domain. X * X * There is no manual page. That is because the one they gave out at X * UNIFORUM was slightly different from the current System V Release 2 X * manual page. The difference apparently involved a note about the X * famous rules 5 and 6, recommending using white space between an option X * and its first argument, and not grouping options that have arguments. X * Getopt itself is currently lenient about both of these things White X * space is allowed, but not mandatory, and the last option in a group can X * have an argument. That particular version of the man page evidently X * has no official existence, and my source at AT&T did not send a copy. X * The current SVR2 man page reflects the actual behavor of this getopt. X * However, I am not about to post a copy of anything licensed by AT&T. X */ X X#define BSD X#ifdef BSD X#include <strings.h> X#else X#include <string.h> X#endif X X/*LINTLIBRARY*/ X#define NULL 0 X#define EOF (-1) X#define ERR(s, c) if(opterr){\ X extern int write();\ X char errbuf[2];\ X errbuf[0] = c; errbuf[1] = '\n';\ X (void) write(2, argv[0], (unsigned)strlen(argv[0]));\ X (void) write(2, s, (unsigned)strlen(s));\ X (void) write(2, errbuf, 2);} X Xextern char *index(); X Xint opterr = 1; Xint optind = 1; Xint optopt; Xchar *optarg; X Xint Xgetopt(argc, argv, opts) Xint argc; Xchar **argv, *opts; X{ X static int sp = 1; X register int c; X register char *cp; X X if(sp == 1) X if(optind >= argc || X argv[optind][0] != '-' || argv[optind][1] == '\0') X return(EOF); X else if(strcmp(argv[optind], "--") == NULL) { X optind++; X return(EOF); X } X optopt = c = argv[optind][sp]; X if(c == ':' || (cp=index(opts, c)) == NULL) { X ERR(": illegal option -- ", c); X if(argv[optind][++sp] == '\0') { X optind++; X sp = 1; X } X return('?'); X } X if(*++cp == ':') { X if(argv[optind][sp+1] != '\0') X optarg = &argv[optind++][sp+1]; X else if(++optind >= argc) { X ERR(": option requires an argument -- ", c); X sp = 1; X return('?'); X } else X optarg = argv[optind++]; X sp = 1; X } else { X if(argv[optind][++sp] == '\0') { X sp = 1; X optind++; X } X optarg = NULL; X } X return(c); X} *-*-END-of-getopt.c-*-* echo x - getopt.l3 sed 's/^X//' >getopt.l3 <<'*-*-END-of-getopt.l3-*-*' X.TH GETOPT 3 local X.DA 25 March 1982 X.SH NAME Xgetopt \- get option letter from argv X.SH SYNOPSIS X.ft B Xint getopt(argc, argv, optstring) X.br Xint argc; X.br Xchar **argv; X.br Xchar *optstring; X.sp Xextern char *optarg; X.br Xextern int optind; X.ft X.SH DESCRIPTION X.I Getopt Xreturns the next option letter in X.I argv Xthat matches a letter in X.IR optstring . X.I Optstring Xis a string of recognized option letters; Xif a letter is followed by a colon, the option is expected to have Xan argument that may or may not be separated from it by white space. X.I Optarg Xis set to point to the start of the option argument on return from X.IR getopt . X.PP X.I Getopt Xplaces in X.I optind Xthe X.I argv Xindex of the next argument to be processed. XBecause X.I optind Xis external, it is normally initialized to zero automatically Xbefore the first call to X.IR getopt . X.PP XWhen all options have been processed (i.e., up to the first Xnon-option argument), X.I getopt Xreturns X.BR EOF . XThe special option X.B \-\- Xmay be used to delimit the end of the options; X.B EOF Xwill be returned, and X.B \-\- Xwill be skipped. X.SH SEE ALSO Xgetopt(1) X.SH DIAGNOSTICS X.I Getopt Xprints an error message on X.I stderr Xand returns a question mark X.RB ( ? ) Xwhen it encounters an option letter not included in X.IR optstring . X.SH EXAMPLE XThe following code fragment shows how one might process the arguments Xfor a command that can take the mutually exclusive options X.B a Xand X.BR b , Xand the options X.B f Xand X.BR o , Xboth of which require arguments: X.PP X.RS X.nf Xmain(argc, argv) Xint argc; Xchar **argv; X{ X int c; X extern int optind; X extern char *optarg; X \&. X \&. X \&. X while ((c = getopt(argc, argv, "abf:o:")) != EOF) X switch (c) { X case 'a': X if (bflg) X errflg++; X else X aflg++; X break; X case 'b': X if (aflg) X errflg++; X else X bproc(); X break; X case 'f': X ifile = optarg; X break; X case 'o': X ofile = optarg; X break; X case '?': X default: X errflg++; X break; X } X if (errflg) { X fprintf(stderr, "Usage: ..."); X exit(2); X } X for (; optind < argc; optind++) { X \&. X \&. X \&. X } X \&. X \&. X \&. X} X.RE X.PP XA template similar to this can be found in X.IR /usr/pub/template.c . X.SH HISTORY XWritten by Henry Spencer, working from a Bell Labs manual page. XBehavior believed identical to the Bell version. X.SH BUGS XIt is not obvious how X`\-' Xstanding alone should be treated; this version treats it as Xa non-option argument, which is not always right. X.PP XOption arguments are allowed to begin with `\-'; Xthis is reasonable but reduces the amount of error checking possible. X.PP X.I Getopt Xis quite flexible but the obvious price must be paid: there is much Xit could do that it doesn't, like Xchecking mutually exclusive options, checking type of Xoption arguments, etc. *-*-END-of-getopt.l3-*-* exit -- Mike "Dodger" Patnode | (n) ..csustan!polyslo!mpatnode Yitbos Innovations Inc. | (s) ..sdsu!polyslo!mpatnode 244 California Blvd | mpatnode@polyslo.UUCP San Luis Obispo, Ca 92630 | (805) 541-2048 / 543-9818 / 756-2516