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