OpenCoverage

getopt.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/builtins/getopt.c
Source codeSwitch to Preprocessed file
LineSourceCount
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. */-
39char *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. */-
54int sh_optind = 0;-
55-
56/* Index of the current argument. */-
57static 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-
66static char *nextchar;-
67static int sh_charindex;-
68-
69/* Callers store zero here to inhibit the error message-
70 for unrecognized options. */-
71-
72int 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-
78int sh_optopt = '?';-
79-
80/* Set to 1 when we see an invalid option; public so getopts can reset it. */-
81int 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-
113int-
114sh_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 */
sh_optind >= argcDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 68 times by 1 test
Evaluated by:
  • Self test
sh_optind < 0Description
TRUEnever evaluated
FALSEevaluated 68 times by 1 test
Evaluated by:
  • Self test
0-68
124 {-
125 sh_optind = argc;-
126 return (EOF);
executed 8 times by 1 test: return ( (-1) );
Executed by:
  • Self test
8
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)
sh_optind == 0Description
TRUEevaluated 34 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 34 times by 1 test
Evaluated by:
  • Self test
34
135 {-
136 sh_optind = 1;-
137 nextchar = (char *)NULL;-
138 }
executed 34 times by 1 test: end of block
Executed by:
  • Self test
34
139-
140 if (nextchar == 0 || *nextchar == '\0')
nextchar == 0Description
TRUEevaluated 63 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
*nextchar == '\0'Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
0-63
141 {-
142 /* If we have done all the ARGV-elements, stop the scan. */-
143 if (sh_optind >= argc)
sh_optind >= argcDescription
TRUEnever evaluated
FALSEevaluated 63 times by 1 test
Evaluated by:
  • Self test
0-63
144 return EOF;
never executed: return (-1) ;
0
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')
temp[0] == '-'Description
TRUEevaluated 54 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 9 times by 1 test
Evaluated by:
  • Self test
temp[1] == '-'Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 53 times by 1 test
Evaluated by:
  • Self test
temp[2] == '\0'Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-54
151 {-
152 sh_optind++;-
153 return EOF;
executed 1 time by 1 test: return (-1) ;
Executed by:
  • Self test
1
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')
temp[0] != '-'Description
TRUEevaluated 9 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 53 times by 1 test
Evaluated by:
  • Self test
temp[1] == '\0'Description
TRUEnever evaluated
FALSEevaluated 53 times by 1 test
Evaluated by:
  • Self test
0-53
160 return EOF;
executed 9 times by 1 test: return (-1) ;
Executed by:
  • Self test
9
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 }
executed 53 times by 1 test: end of block
Executed by:
  • Self test
53
167-
168 /* Look at and handle the next option-character. */-
169-
170 c = *nextchar++; sh_charindex++;-
171 temp = strchr (optstring, c);
__builtin_constant_p ( c )Description
TRUEnever evaluated
FALSEevaluated 58 times by 1 test
Evaluated by:
  • Self test
!__builtin_con... ( optstring )Description
TRUEnever evaluated
FALSEnever evaluated
( c ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0-58
172-
173 sh_optopt = c;-
174-
175 /* Increment `sh_optind' when we start to process its last character. */-
176 if (nextchar == 0 || *nextchar == '\0')
nextchar == 0Description
TRUEnever evaluated
FALSEevaluated 58 times by 1 test
Evaluated by:
  • Self test
*nextchar == '\0'Description
TRUEevaluated 50 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 8 times by 1 test
Evaluated by:
  • Self test
0-58
177 {-
178 sh_optind++;-
179 nextchar = (char *)NULL;-
180 }
executed 50 times by 1 test: end of block
Executed by:
  • Self test
50
181-
182 if (sh_badopt = (temp == NULL || c == ':'))
temp == ((void *)0)Description
TRUEevaluated 11 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 47 times by 1 test
Evaluated by:
  • Self test
c == ':'Description
TRUEnever evaluated
FALSEevaluated 47 times by 1 test
Evaluated by:
  • Self test
0-47
183 {-
184 if (sh_opterr)
sh_opterrDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 3 times by 1 test
Evaluated by:
  • Self test
3-8
185 BADOPT (c);
executed 8 times by 1 test: fprintf ( stderr , dcgettext (((void *)0), "%s: illegal option -- %c\n" , 5) , argv[0], c);
Executed by:
  • Self test
8
186-
187 return '?';
executed 11 times by 1 test: return '?';
Executed by:
  • Self test
11
188 }-
189-
190 if (temp[1] == ':')
temp[1] == ':'Description
TRUEevaluated 19 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 28 times by 1 test
Evaluated by:
  • Self test
19-28
191 {-
192 if (nextchar && *nextchar)
nextcharDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 18 times by 1 test
Evaluated by:
  • Self test
*nextcharDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-18
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 }
executed 1 time by 1 test: end of block
Executed by:
  • Self test
1
200 else if (sh_optind == argc)
sh_optind == argcDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 16 times by 1 test
Evaluated by:
  • Self test
2-16
201 {-
202 if (sh_opterr)
sh_opterrDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
1
203 NEEDARG (c);
executed 1 time by 1 test: fprintf ( stderr , dcgettext (((void *)0), "%s: option requires an argument -- %c\n" , 5) , argv[0], c);
Executed by:
  • Self test
1
204-
205 sh_optopt = c;-
206 sh_optarg = ""; /* Needed by getopts. */-
207 c = (optstring[0] == ':') ? ':' : '?';
(optstring[0] == ':')Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
0-2
208 }
executed 2 times by 1 test: end of block
Executed by:
  • Self test
2
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++];
executed 16 times by 1 test: sh_optarg = argv[sh_optind++];
Executed by:
  • Self test
16
213 nextchar = (char *)NULL;-
214 }
executed 19 times by 1 test: end of block
Executed by:
  • Self test
19
215 return c;
executed 47 times by 1 test: return c;
Executed by:
  • Self test
47
216}-
217-
218void-
219sh_getopt_restore_state (argv)-
220 char **argv;-
221{-
222 if (nextchar)
nextcharDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 68 times by 1 test
Evaluated by:
  • Self test
8-68
223 nextchar = argv[sh_curopt] + sh_charindex;
executed 8 times by 1 test: nextchar = argv[sh_curopt] + sh_charindex;
Executed by:
  • Self test
8
224}
executed 76 times by 1 test: end of block
Executed by:
  • Self test
76
225-
226sh_getopt_state_t *-
227sh_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;
executed 1640471 times by 1 test: return ret;
Executed by:
  • Self test
1640471
233}-
234-
235void-
236sh_getopt_dispose_istate (gs)-
237 sh_getopt_state_t *gs;-
238{-
239 free (gs);-
240}
executed 3 times by 1 test: end of block
Executed by:
  • Self test
3
241-
242sh_getopt_state_t *-
243sh_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;
executed 1640471 times by 1 test: return ret;
Executed by:
  • Self test
1640471
257}-
258-
259void-
260sh_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}
executed 3 times by 1 test: end of block
Executed by:
  • Self test
3
271-
272#if 0-
273void-
274sh_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-
290int-
291main (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 */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2