1 /* getopt.c -
2    getopt() for those systems that don't have it.
3 
4    Derived from comp.sources.unix/volume3/att_getopt.
5    Modified by James Clark (jjc@jclark.com).
6 */
7 
8 #include "config.h"
9 
10 #ifndef HAVE_GETOPT
11 
12 #include "std.h"
13 #include "getopt.h"
14 
15 #ifdef SWITCHAR
16 #include <dos.h>
17 #endif
18 
19 int	opterr = 1;
20 int	optind = 1;
21 int	optopt;
22 char *optarg;
23 
24 #ifndef OPTION_CHAR
25 #define OPTION_CHAR '-'
26 #endif
27 
getopt(argc,argv,opts)28 int getopt(argc, argv, opts)
29 int argc;
30 char **argv;
31 char *opts;
32 {
33 #ifdef SWITCHAR
34 	union REGS regs;
35 	static char switchar = '\0';
36 #endif
37 	static int sp = 1;
38 	register int c;
39 	register char *cp;
40 	char *message;
41 #ifdef SWITCHAR
42 	if (switchar == '\0') {
43 		regs.x.ax = 0x3700;
44 		intdos(&regs, &regs);
45 		if (!regs.x.cflag)
46 			switchar = regs.h.dl;
47 		else
48 			switchar = '/';
49 	}
50 #endif
51 	if (sp == 1) {
52 		if (optind >= argc)
53 			return EOF;
54 		if ((
55 #ifdef SWITCHAR
56 			argv[optind][0] != switchar &&
57 #endif
58 			argv[optind][0] != OPTION_CHAR) || argv[optind][1] == '\0') {
59 #ifdef REORDER_ARGS
60 			int i;
61 			for (i = optind; i < argc; i++)
62 				if ((
63 #ifdef SWITCHAR
64 					 argv[i][0] == switchar ||
65 #endif
66 					 argv[i][0] == OPTION_CHAR) && argv[i][1] != '\0')
67 					break;
68 			if (i < argc) {
69 				c = argv[i][1];
70 #ifdef CASE_INSENSITIVE_OPTIONS
71 				if (isupper(c))
72 					c = tolower(c);
73 #endif
74 				if (c != ':' && c != OPTION_CHAR && (cp = strchr(opts, c)) != NULL
75 					&& cp[1] == ':' && argv[i][2] == 0 && i < argc - 1) {
76 					int j;
77 					char *temp1 = argv[i];
78 					char *temp2 = argv[i+1];
79 					for (j = i - 1; j >= optind; j--)
80 						argv[j+2] = argv[j];
81 					argv[optind] = temp1;
82 					argv[optind+1] = temp2;
83 				}
84 				else {
85 					int j;
86 					char *temp = argv[i];
87 					for (j = i - 1; j >= optind; j--)
88 						argv[j+1] = argv[j];
89 					argv[optind] = temp;
90 				}
91 			}
92 			else
93 #endif
94 				return EOF;
95 		}
96 		if ((argv[optind][0] == OPTION_CHAR && argv[optind][1] == OPTION_CHAR
97 				  && argv[optind][2] == '\0')
98 #ifdef SWITCHAR
99 			|| (argv[optind][0] == switchar && argv[optind][1] == switchar
100 				&& argv[optind][2] == '\0')
101 #endif
102 			) {
103 			optind++;
104 			return(EOF);
105 		}
106 	}
107 	optopt = c = argv[optind][sp];
108 #ifdef CASE_INSENSITIVE_OPTIONS
109 	if (
110 #ifdef USE_ISASCII
111 		isascii(c) &&
112 #endif /* USE_ISASCII */
113 		isupper((unsigned char)c))
114 		optopt = c = tolower((unsigned char)c);
115 #endif /* CASE_INSENSITIVE_OPTIONS */
116 	if (c == ':' || (cp = strchr(opts, c)) == NULL) {
117 		if (argv[optind][++sp] == '\0') {
118 			optind++;
119 			sp = 1;
120 		}
121 		message = ": illegal option -- ";
122 		goto bad;
123 	}
124 	if (*++cp == ':') {
125 		if (argv[optind][sp+1] != '\0')
126 			optarg = &argv[optind++][sp+1];
127 		else if (++optind >= argc) {
128 			sp = 1;
129 			message = ": option requires an argument -- ";
130 			goto bad;
131 		}
132 		else
133 			optarg = argv[optind++];
134 		sp = 1;
135 	}
136 	else {
137 		if (argv[optind][++sp] == '\0') {
138 			sp = 1;
139 			optind++;
140 		}
141 		optarg = NULL;
142 	}
143 	return c;
144 bad:
145 	if (opterr) {
146 		fputs(argv[0], stderr);
147 		fputs(message, stderr);
148 		fputc(optopt, stderr);
149 		fputc('\n', stderr);
150 	}
151 	return '?';
152 }
153 
154 #endif /* not HAVE_GETOPT */
155 
156 /*
157 Local Variables:
158 c-indent-level: 4
159 c-continued-statement-offset: 4
160 c-brace-offset: 4
161 c-argdecl-indent: 4
162 c-label-offset: -4
163 tab-width: 4
164 End:
165 */
166 
167