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(®s, ®s);
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