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