getopt.c   [plain text]


#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)getopt.c 1.1 90/03/23 SMI";
/* from 4.3BSD-tahoe 4.9 6/23/89 */
#endif

/*
 * Copyright (c) 1989 Sun Microsystems, Inc.
 */
/*
 * Copyright (c) 1987 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * /

/* LINTLIBRARY */

#include <stdio.h>
#include <string.h>

#include "getopt.h"

/*
 * get option letter from argument vector
 */
/* See lib/libc/gen/common/optind.c for next 3 definitions. */
extern char *optarg; /* argument associated with option */
extern int opterr; /* if error message should be printed */
extern int optind; /* index into parent argv vector */
int optopt; /* character checked for validity */


#define BADCH (int)'?'
#define EMSG ""

getopt(int nargc, char *const nargv[], const char *ostr)
{
	static char *place = EMSG; /* option letter processing */
	register char *oli; /* option letter list index */
	char *p;
	
	if (!*place) { /* update scanning pointer */
		if (optind >= nargc || *(place = nargv[optind]) != '-') {
			place = EMSG;
			return (EOF);
		}
		if (place[1] && *++place == '-') { /* found "--" */
			++optind;
			place = EMSG;
			return (EOF);
		}
	} /* option letter okay? */

	if ((optopt = (int)*place++) == (int)':' ||
		!(oli = strchr(ostr, optopt))) {
		
		/*
		* For backwards compatibility: don't treat '-' as an
		* option letter unless caller explicitly asked for it.
		*/
		if (optopt == (int)'-')
			return (EOF);
		if (!*place)
			++optind;
		if (opterr) {
			if (!(p = strrchr(*nargv, '/')))
				p = *nargv;
			else
				++p;
			(void)fprintf(stderr, "%s: illegal option -- %c\n",
				p, 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 (!(p = strrchr(*nargv, '/')))
				p = *nargv;
			else
				++p;
			if (opterr)
				(void)fprintf(stderr,
				"%s: option requires an argument -- %c\n",
				p, optopt);
			return (BADCH);
		} else /* white space */
			optarg = nargv[optind];
		place = EMSG;
		++optind;
	}

	return (optopt); /* dump back option letter */
}