1 /* getopt.c - getopt for Bash. Used by the getopt builtin. */
2
3 /* Copyright (C) 1993-2009 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #if defined (HAVE_UNISTD_H)
24 # ifdef _MINIX
25 # include <sys/types.h>
26 # endif
27 # include <unistd.h>
28 #endif
29
30 #include <stdio.h>
31 #include "memalloc.h"
32 #include "../bashintl.h"
33 #include "../shell.h"
34 #include "getopt.h"
35
36 /* For communication from `sh_getopt' to the caller.
37 When `sh_getopt' finds an option that takes an argument,
38 the argument value is returned here. */
39 char *sh_optarg = 0;
40
41 /* Index in ARGV of the next element to be scanned.
42 This is used for communication to and from the caller
43 and for communication between successive calls to `sh_getopt'.
44
45 On entry to `sh_getopt', zero means this is the first call; initialize.
46
47 When `sh_getopt' returns EOF, this is the index of the first of the
48 non-option elements that the caller should itself scan.
49
50 Otherwise, `sh_optind' communicates from one call to the next
51 how much of ARGV has been scanned so far. */
52
53 /* XXX 1003.2 says this must be 1 before any call. */
54 int sh_optind = 0;
55
56 /* Index of the current argument. */
57 static int sh_curopt;
58
59 /* The next char to be scanned in the option-element
60 in which the last option character we returned was found.
61 This allows us to pick up the scan where we left off.
62
63 If this is zero, or a null string, it means resume the scan
64 by advancing to the next ARGV-element. */
65
66 static char *nextchar;
67 static int sh_charindex;
68
69 /* Callers store zero here to inhibit the error message
70 for unrecognized options. */
71
72 int sh_opterr = 1;
73
74 /* Set to an option character which was unrecognized.
75 This must be initialized on some systems to avoid linking in the
76 system's own getopt implementation. */
77
78 int sh_optopt = '?';
79
80 /* Set to 1 when we see an invalid option; public so getopts can reset it. */
81 int sh_badopt = 0;
82
83 /* Scan elements of ARGV (whose length is ARGC) for option characters
84 given in OPTSTRING.
85
86 If an element of ARGV starts with '-', and is not exactly "-" or "--",
87 then it is an option element. The characters of this element
88 (aside from the initial '-') are option characters. If `sh_getopt'
89 is called repeatedly, it returns successively each of the option characters
90 from each of the option elements.
91
92 If `sh_getopt' finds another option character, it returns that character,
93 updating `sh_optind' and `nextchar' so that the next call to `sh_getopt' can
94 resume the scan with the following option character or ARGV-element.
95
96 If there are no more option characters, `sh_getopt' returns `EOF'.
97 Then `sh_optind' is the index in ARGV of the first ARGV-element
98 that is not an option.
99
100 OPTSTRING is a string containing the legitimate option characters.
101 If an option character is seen that is not listed in OPTSTRING,
102 return '?' after printing an error message. If you set `sh_opterr' to
103 zero, the error message is suppressed but we still return '?'.
104
105 If a char in OPTSTRING is followed by a colon, that means it wants an arg,
106 so the following text in the same ARGV-element, or the text of the following
107 ARGV-element, is returned in `sh_optarg'. */
108
109 /* 1003.2 specifies the format of this message. */
110 #define BADOPT(x) fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], x)
111 #define NEEDARG(x) fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], x)
112
113 int
sh_getopt(argc,argv,optstring)114 sh_getopt (argc, argv, optstring)
115 int argc;
116 char *const *argv;
117 const char *optstring;
118 {
119 char c, *temp;
120
121 sh_optarg = 0;
122
123 if (sh_optind >= argc || sh_optind < 0) /* XXX was sh_optind > argc */
124 {
125 sh_optind = argc;
126 return (EOF);
127 }
128
129 /* Initialize the internal data when the first call is made.
130 Start processing options with ARGV-element 1 (since ARGV-element 0
131 is the program name); the sequence of previously skipped
132 non-option ARGV-elements is empty. */
133
134 if (sh_optind == 0)
135 {
136 sh_optind = 1;
137 nextchar = (char *)NULL;
138 }
139
140 if (nextchar == 0 || *nextchar == '\0')
141 {
142 /* If we have done all the ARGV-elements, stop the scan. */
143 if (sh_optind >= argc)
144 return EOF;
145
146 temp = argv[sh_optind];
147
148 /* Special ARGV-element `--' means premature end of options.
149 Skip it like a null option, and return EOF. */
150 if (temp[0] == '-' && temp[1] == '-' && temp[2] == '\0')
151 {
152 sh_optind++;
153 return EOF;
154 }
155
156 /* If we have come to a non-option, either stop the scan or describe
157 it to the caller and pass it by. This makes the pseudo-option
158 `-' mean the end of options, but does not skip over it. */
159 if (temp[0] != '-' || temp[1] == '\0')
160 return EOF;
161
162 /* We have found another option-ARGV-element.
163 Start decoding its characters. */
164 nextchar = argv[sh_curopt = sh_optind] + 1;
165 sh_charindex = 1;
166 }
167
168 /* Look at and handle the next option-character. */
169
170 c = *nextchar++; sh_charindex++;
171 temp = strchr (optstring, c);
172
173 sh_optopt = c;
174
175 /* Increment `sh_optind' when we start to process its last character. */
176 if (nextchar == 0 || *nextchar == '\0')
177 {
178 sh_optind++;
179 nextchar = (char *)NULL;
180 }
181
182 if (sh_badopt = (temp == NULL || c == ':'))
183 {
184 if (sh_opterr)
185 BADOPT (c);
186
187 return '?';
188 }
189
190 if (temp[1] == ':')
191 {
192 if (nextchar && *nextchar)
193 {
194 /* This is an option that requires an argument. */
195 sh_optarg = nextchar;
196 /* If we end this ARGV-element by taking the rest as an arg,
197 we must advance to the next element now. */
198 sh_optind++;
199 }
200 else if (sh_optind == argc)
201 {
202 if (sh_opterr)
203 NEEDARG (c);
204
205 sh_optopt = c;
206 sh_optarg = ""; /* Needed by getopts. */
207 c = (optstring[0] == ':') ? ':' : '?';
208 }
209 else
210 /* We already incremented `sh_optind' once;
211 increment it again when taking next ARGV-elt as argument. */
212 sh_optarg = argv[sh_optind++];
213 nextchar = (char *)NULL;
214 }
215 return c;
216 }
217
218 void
sh_getopt_restore_state(argv)219 sh_getopt_restore_state (argv)
220 char **argv;
221 {
222 if (nextchar)
223 nextchar = argv[sh_curopt] + sh_charindex;
224 }
225
226 sh_getopt_state_t *
sh_getopt_alloc_istate()227 sh_getopt_alloc_istate ()
228 {
229 sh_getopt_state_t *ret;
230
231 ret = (sh_getopt_state_t *)xmalloc (sizeof (sh_getopt_state_t));
232 return ret;
233 }
234
235 void
sh_getopt_dispose_istate(gs)236 sh_getopt_dispose_istate (gs)
237 sh_getopt_state_t *gs;
238 {
239 free (gs);
240 }
241
242 sh_getopt_state_t *
sh_getopt_save_istate()243 sh_getopt_save_istate ()
244 {
245 sh_getopt_state_t *ret;
246
247 ret = sh_getopt_alloc_istate ();
248
249 ret->gs_optarg = sh_optarg;
250 ret->gs_optind = sh_optind;
251 ret->gs_curopt = sh_curopt;
252 ret->gs_nextchar = nextchar; /* XXX */
253 ret->gs_charindex = sh_charindex;
254 ret->gs_flags = 0; /* XXX for later use */
255
256 return ret;
257 }
258
259 void
sh_getopt_restore_istate(state)260 sh_getopt_restore_istate (state)
261 sh_getopt_state_t *state;
262 {
263 sh_optarg = state->gs_optarg;
264 sh_optind = state->gs_optind;
265 sh_curopt = state->gs_curopt;
266 nextchar = state->gs_nextchar; /* XXX - probably not usable */
267 sh_charindex = state->gs_charindex;
268
269 sh_getopt_dispose_istate (state);
270 }
271
272 #if 0
273 void
274 sh_getopt_debug_restore_state (argv)
275 char **argv;
276 {
277 if (nextchar && nextchar != argv[sh_curopt] + sh_charindex)
278 {
279 itrace("sh_getopt_debug_restore_state: resetting nextchar");
280 nextchar = argv[sh_curopt] + sh_charindex;
281 }
282 }
283 #endif
284
285 #ifdef TEST
286
287 /* Compile with -DTEST to make an executable for use in testing
288 the above definition of `sh_getopt'. */
289
290 int
main(argc,argv)291 main (argc, argv)
292 int argc;
293 char **argv;
294 {
295 int c;
296 int digit_sh_optind = 0;
297
298 while (1)
299 {
300 int this_option_sh_optind = sh_optind ? sh_optind : 1;
301
302 c = sh_getopt (argc, argv, "abc:d:0123456789");
303 if (c == EOF)
304 break;
305
306 switch (c)
307 {
308 case '0':
309 case '1':
310 case '2':
311 case '3':
312 case '4':
313 case '5':
314 case '6':
315 case '7':
316 case '8':
317 case '9':
318 if (digit_sh_optind != 0 && digit_sh_optind != this_option_sh_optind)
319 printf ("digits occur in two different argv-elements.\n");
320 digit_sh_optind = this_option_sh_optind;
321 printf ("option %c\n", c);
322 break;
323
324 case 'a':
325 printf ("option a\n");
326 break;
327
328 case 'b':
329 printf ("option b\n");
330 break;
331
332 case 'c':
333 printf ("option c with value `%s'\n", sh_optarg);
334 break;
335
336 case '?':
337 break;
338
339 default:
340 printf ("?? sh_getopt returned character code 0%o ??\n", c);
341 }
342 }
343
344 if (sh_optind < argc)
345 {
346 printf ("non-option ARGV-elements: ");
347 while (sh_optind < argc)
348 printf ("%s ", argv[sh_optind++]);
349 printf ("\n");
350 }
351
352 exit (0);
353 }
354
355 #endif /* TEST */
356