1 | /* Copyright 1999-2004 The Apache Software Foundation |
---|
2 | * |
---|
3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
---|
4 | * you may not use this file except in compliance with the License. |
---|
5 | * You may obtain a copy of the License at |
---|
6 | * |
---|
7 | * http://www.apache.org/licenses/LICENSE-2.0 |
---|
8 | * |
---|
9 | * Unless required by applicable law or agreed to in writing, software |
---|
10 | * distributed under the License is distributed on an "AS IS" BASIS, |
---|
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
---|
12 | * See the License for the specific language governing permissions and |
---|
13 | * limitations under the License. |
---|
14 | */ |
---|
15 | |
---|
16 | #include <stdio.h> |
---|
17 | #include <string.h> |
---|
18 | #include <assert.h> |
---|
19 | #include <stdlib.h> |
---|
20 | |
---|
21 | #define OPTERRCOLON (1) |
---|
22 | #define OPTERRNF (2) |
---|
23 | #define OPTERRARG (3) |
---|
24 | |
---|
25 | char *optarg; |
---|
26 | int optreset = 0; |
---|
27 | int optind = 1; |
---|
28 | int opterr = 1; |
---|
29 | int optopt; |
---|
30 | |
---|
31 | static int |
---|
32 | optiserr(int argc, char * const *argv, int oint, const char *optstr, |
---|
33 | int optchr, int err) |
---|
34 | { |
---|
35 | if(opterr) |
---|
36 | { |
---|
37 | fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1); |
---|
38 | switch(err) |
---|
39 | { |
---|
40 | case OPTERRCOLON: |
---|
41 | fprintf(stderr, ": in flags\n"); |
---|
42 | break; |
---|
43 | case OPTERRNF: |
---|
44 | fprintf(stderr, "option not found %c\n", argv[oint][optchr]); |
---|
45 | break; |
---|
46 | case OPTERRARG: |
---|
47 | fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]); |
---|
48 | break; |
---|
49 | default: |
---|
50 | fprintf(stderr, "unknown\n"); |
---|
51 | break; |
---|
52 | } |
---|
53 | } |
---|
54 | optopt = argv[oint][optchr]; |
---|
55 | return('?'); |
---|
56 | } |
---|
57 | |
---|
58 | |
---|
59 | |
---|
60 | int |
---|
61 | getopt(int argc, char* const *argv, const char *optstr) |
---|
62 | { |
---|
63 | static int optchr = 0; |
---|
64 | static int dash = 0; /* have already seen the - */ |
---|
65 | |
---|
66 | char *cp; |
---|
67 | |
---|
68 | if (optreset) |
---|
69 | optreset = optchr = dash = 0; |
---|
70 | if(optind >= argc) |
---|
71 | return(EOF); |
---|
72 | if(!dash && (argv[optind][0] != '-')) |
---|
73 | return(EOF); |
---|
74 | if(!dash && (argv[optind][0] == '-') && !argv[optind][1]) |
---|
75 | { |
---|
76 | /* |
---|
77 | * use to specify stdin. Need to let pgm process this and |
---|
78 | * the following args |
---|
79 | */ |
---|
80 | return(EOF); |
---|
81 | } |
---|
82 | if((argv[optind][0] == '-') && (argv[optind][1] == '-')) |
---|
83 | { |
---|
84 | /* -- indicates end of args */ |
---|
85 | optind++; |
---|
86 | return(EOF); |
---|
87 | } |
---|
88 | if(!dash) |
---|
89 | { |
---|
90 | assert((argv[optind][0] == '-') && argv[optind][1]); |
---|
91 | dash = 1; |
---|
92 | optchr = 1; |
---|
93 | } |
---|
94 | |
---|
95 | /* Check if the guy tries to do a -: kind of flag */ |
---|
96 | assert(dash); |
---|
97 | if(argv[optind][optchr] == ':') |
---|
98 | { |
---|
99 | dash = 0; |
---|
100 | optind++; |
---|
101 | return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRCOLON)); |
---|
102 | } |
---|
103 | if(!(cp = strchr(optstr, argv[optind][optchr]))) |
---|
104 | { |
---|
105 | int errind = optind; |
---|
106 | int errchr = optchr; |
---|
107 | |
---|
108 | if(!argv[optind][optchr+1]) |
---|
109 | { |
---|
110 | dash = 0; |
---|
111 | optind++; |
---|
112 | } |
---|
113 | else |
---|
114 | optchr++; |
---|
115 | return(optiserr(argc, argv, errind, optstr, errchr, OPTERRNF)); |
---|
116 | } |
---|
117 | if(cp[1] == ':') |
---|
118 | { |
---|
119 | dash = 0; |
---|
120 | optind++; |
---|
121 | if(optind == argc) |
---|
122 | return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRARG)); |
---|
123 | optarg = argv[optind++]; |
---|
124 | return(*cp); |
---|
125 | } |
---|
126 | else |
---|
127 | { |
---|
128 | if(!argv[optind][optchr+1]) |
---|
129 | { |
---|
130 | dash = 0; |
---|
131 | optind++; |
---|
132 | } |
---|
133 | else |
---|
134 | optchr++; |
---|
135 | return(*cp); |
---|
136 | } |
---|
137 | assert(0); |
---|
138 | return(0); |
---|
139 | } |
---|
140 | |
---|
141 | #ifdef TESTGETOPT |
---|
142 | int |
---|
143 | main (int argc, char **argv) |
---|
144 | { |
---|
145 | int c; |
---|
146 | extern char *optarg; |
---|
147 | extern int optind; |
---|
148 | int aflg = 0; |
---|
149 | int bflg = 0; |
---|
150 | int errflg = 0; |
---|
151 | char *ofile = NULL; |
---|
152 | |
---|
153 | while ((c = getopt(argc, argv, "abo:")) != EOF) |
---|
154 | switch (c) { |
---|
155 | case 'a': |
---|
156 | if (bflg) |
---|
157 | errflg++; |
---|
158 | else |
---|
159 | aflg++; |
---|
160 | break; |
---|
161 | case 'b': |
---|
162 | if (aflg) |
---|
163 | errflg++; |
---|
164 | else |
---|
165 | bflg++; |
---|
166 | break; |
---|
167 | case 'o': |
---|
168 | ofile = optarg; |
---|
169 | (void)printf("ofile = %s\n", ofile); |
---|
170 | break; |
---|
171 | case '?': |
---|
172 | errflg++; |
---|
173 | } |
---|
174 | if (errflg) { |
---|
175 | (void)fprintf(stderr, |
---|
176 | "usage: cmd [-a|-b] [-o <filename>] files...\n"); |
---|
177 | exit (2); |
---|
178 | } |
---|
179 | for ( ; optind < argc; optind++) |
---|
180 | (void)printf("%s\n", argv[optind]); |
---|
181 | return 0; |
---|
182 | } |
---|
183 | |
---|
184 | #endif /* TESTGETOPT */ |
---|