xref: /original-bsd/lib/libc/stdlib/getopt.c (revision 3b4109a4)
1 /*
2  * Copyright (c) 1987 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)getopt.c	4.13 (Berkeley) 02/23/91";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 /*
17  * get option letter from argument vector
18  */
19 int	opterr = 1,		/* if error message should be printed */
20 	optind = 1,		/* index into parent argv vector */
21 	optopt;			/* character checked for validity */
22 char	*optarg;		/* argument associated with option */
23 
24 #define	BADCH	(int)'?'
25 #define	EMSG	""
26 
27 int
28 getopt(nargc, nargv, ostr)
29 	int nargc;
30 	char * const *nargv;
31 	const char *ostr;
32 {
33 	static char *place = EMSG;		/* option letter processing */
34 	register char *oli;			/* option letter list index */
35 	char *p;
36 
37 	if (!*place) {				/* update scanning pointer */
38 		if (optind >= nargc || *(place = nargv[optind]) != '-') {
39 			place = EMSG;
40 			return(EOF);
41 		}
42 		if (place[1] && *++place == '-') {	/* found "--" */
43 			++optind;
44 			place = EMSG;
45 			return(EOF);
46 		}
47 	}					/* option letter okay? */
48 	if ((optopt = (int)*place++) == (int)':' ||
49 	    !(oli = index(ostr, optopt))) {
50 		/*
51 		 * if the user didn't specify '-' as an option,
52 		 * assume it means EOF.
53 		 */
54 		if (optopt == (int)'-')
55 			return(EOF);
56 		if (!*place)
57 			++optind;
58 		if (opterr) {
59 			if (!(p = rindex(*nargv, '/')))
60 				p = *nargv;
61 			else
62 				++p;
63 			(void)fprintf(stderr, "%s: illegal option -- %c\n",
64 			    p, optopt);
65 		}
66 		return(BADCH);
67 	}
68 	if (*++oli != ':') {			/* don't need argument */
69 		optarg = NULL;
70 		if (!*place)
71 			++optind;
72 	}
73 	else {					/* need an argument */
74 		if (*place)			/* no white space */
75 			optarg = place;
76 		else if (nargc <= ++optind) {	/* no arg */
77 			place = EMSG;
78 			if (!(p = rindex(*nargv, '/')))
79 				p = *nargv;
80 			else
81 				++p;
82 			if (opterr)
83 				(void)fprintf(stderr,
84 				    "%s: option requires an argument -- %c\n",
85 				    p, optopt);
86 			return(BADCH);
87 		}
88 	 	else				/* white space */
89 			optarg = nargv[optind];
90 		place = EMSG;
91 		++optind;
92 	}
93 	return(optopt);				/* dump back option letter */
94 }
95