1 /*
2 **	@(#)getopt.c	2.5 (smail) 9/15/87
3 */
4 
5 /*
6 *  This is the AT&T public domain source for getopt(3).  It is the code
7 *  which was given out at the 1985 UNIFORUM conference in Dallas.
8 *
9 *  There is no manual page.  That is because the one they gave out at
10 *  UNIFORUM was slightly different from the current System V Release 2
11 *  manual page.  The difference apparently involved a note about the
12 *  famous rules 5 and 6, recommending using white space between an
13 *  option and its first argument, and not grouping options that have
14 *  arguments.  Getopt itself is currently lenient about both of these
15 *  things.  White space is allowed, but not mandatory, and the last option
16 *  in a group can have an argument.  That particular version of the man
17 *  page evidently has no official existence.  The current SVR2 man page
18 *  reflects the actual behavor of this getopt.
19 */
20 
21 #include <string.h>
22 #include <stdio.h>
23 #include "getopt.h"
24 
25 /*LINTLIBRARY*/
26 #ifndef NULL
27 #define NULL	0
28 #endif
29 #define EOF	(-1)
30 #define ERR(str, chr) (opterr ? fprintf(stderr, "%s%s%c\n", argv[0], str, chr) : 0)
31 
32 int	opterr = 1;
33 int	optind = 1;
34 int	optopt = 0;
35 char	*optarg = 0;
36 
37 int
38 getopt(int argc, char **argv, char *opts)
39 {
40 	static int sp = 1;
41 	register int c;
42 	register char *cp;
43 
44 	if(sp == 1) {
45 		if(optind >= argc || (argv[optind][0] != '+' &&
46 		   argv[optind][0] != '-') || argv[optind][1] == '\0')
47 			return EOF;
48 		else if(strcmp(argv[optind], "--") == 0) {
49 			optind++;
50 			return EOF;
51 		}
52 		/* '+' for config options, '+' should not be in the opts list */
53 		if (argv[optind][0] == '+') {
54 			optarg = argv[optind++] + 1;
55 			return '+';
56 		}
57 	}
58 	optopt = c = argv[optind][sp];
59 	if(c == ':' || (cp=strchr(opts, c)) == NULL) {
60 		ERR(": illegal option -- ", c);
61 		if(argv[optind][++sp] == '\0') {
62 			optind++;
63 			sp = 1;
64 		}
65 		return '\0';
66 	}
67 	if(*++cp == ':') {
68 		if(argv[optind][sp+1] != '\0')
69 			optarg = &argv[optind++][sp+1];
70 		else if(++optind >= argc) {
71 			ERR(": option requires an argument -- ", c);
72 			sp = 1;
73 			return '\0';
74 		} else
75 			optarg = argv[optind++];
76 		sp = 1;
77 	} else {
78 		if(argv[optind][++sp] == '\0') {
79 			sp = 1;
80 			optind++;
81 		}
82 		optarg = NULL;
83 	}
84 	return c;
85 }
86 
87