[comp.sources.misc] v02i090: getopt.c

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