Patch-ID: bash32-017
[bash.git] / builtins / getopts.def
bloba9aad62bd57a881e525fe910677d55324aa7f497
1 This file is getopts.def, from which is created getopts.c.
2 It implements the builtin "getopts" in Bash.
4 Copyright (C) 1987-2004 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
22 $PRODUCES getopts.c
24 $BUILTIN getopts
25 $FUNCTION getopts_builtin
26 $SHORT_DOC getopts optstring name [arg]
27 Getopts is used by shell procedures to parse positional parameters.
29 OPTSTRING contains the option letters to be recognized; if a letter
30 is followed by a colon, the option is expected to have an argument,
31 which should be separated from it by white space.
33 Each time it is invoked, getopts will place the next option in the
34 shell variable $name, initializing name if it does not exist, and
35 the index of the next argument to be processed into the shell
36 variable OPTIND. OPTIND is initialized to 1 each time the shell or
37 a shell script is invoked. When an option requires an argument,
38 getopts places that argument into the shell variable OPTARG.
40 getopts reports errors in one of two ways. If the first character
41 of OPTSTRING is a colon, getopts uses silent error reporting. In
42 this mode, no error messages are printed. If an invalid option is
43 seen, getopts places the option character found into OPTARG. If a
44 required argument is not found, getopts places a ':' into NAME and
45 sets OPTARG to the option character found. If getopts is not in
46 silent mode, and an invalid option is seen, getopts places '?' into
47 NAME and unsets OPTARG. If a required argument is not found, a '?'
48 is placed in NAME, OPTARG is unset, and a diagnostic message is
49 printed.
51 If the shell variable OPTERR has the value 0, getopts disables the
52 printing of error messages, even if the first character of
53 OPTSTRING is not a colon. OPTERR has the value 1 by default.
55 Getopts normally parses the positional parameters ($0 - $9), but if
56 more arguments are given, they are parsed instead.
57 $END
59 #include <config.h>
61 #include <stdio.h>
63 #if defined (HAVE_UNISTD_H)
64 # ifdef _MINIX
65 # include <sys/types.h>
66 # endif
67 # include <unistd.h>
68 #endif
70 #include "../bashansi.h"
72 #include "../shell.h"
73 #include "common.h"
74 #include "bashgetopt.h"
75 #include "getopt.h"
77 #define G_EOF -1
78 #define G_INVALID_OPT -2
79 #define G_ARG_MISSING -3
81 extern char *this_command_name;
83 static int getopts_bind_variable __P((char *, char *));
84 static int dogetopts __P((int, char **));
86 /* getopts_reset is magic code for when OPTIND is reset. N is the
87 value that has just been assigned to OPTIND. */
88 void
89 getopts_reset (newind)
90 int newind;
92 sh_optind = newind;
93 sh_badopt = 0;
96 static int
97 getopts_bind_variable (name, value)
98 char *name, *value;
100 SHELL_VAR *v;
102 if (legal_identifier (name))
104 v = bind_variable (name, value, 0);
105 return (v && (readonly_p (v) == 0)) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
107 else
109 sh_invalidid (name);
110 return (EXECUTION_FAILURE);
114 /* Error handling is now performed as specified by Posix.2, draft 11
115 (identical to that of ksh-88). The special handling is enabled if
116 the first character of the option string is a colon; this handling
117 disables diagnostic messages concerning missing option arguments
118 and invalid option characters. The handling is as follows.
120 INVALID OPTIONS:
121 name -> "?"
122 if (special_error) then
123 OPTARG = option character found
124 no error output
125 else
126 OPTARG unset
127 diagnostic message
130 MISSING OPTION ARGUMENT;
131 if (special_error) then
132 name -> ":"
133 OPTARG = option character found
134 else
135 name -> "?"
136 OPTARG unset
137 diagnostic message
141 static int
142 dogetopts (argc, argv)
143 int argc;
144 char **argv;
146 int ret, special_error, old_opterr, i, n;
147 char strval[2], numval[16];
148 char *optstr; /* list of options */
149 char *name; /* variable to get flag val */
150 char *t;
152 if (argc < 3)
154 builtin_usage ();
155 return (EX_USAGE);
158 /* argv[0] is "getopts". */
160 optstr = argv[1];
161 name = argv[2];
162 argc -= 2;
163 argv += 2;
165 special_error = optstr[0] == ':';
167 if (special_error)
169 old_opterr = sh_opterr;
170 optstr++;
171 sh_opterr = 0; /* suppress diagnostic messages */
174 if (argc > 1)
176 sh_getopt_restore_state (argv);
177 t = argv[0];
178 argv[0] = dollar_vars[0];
179 ret = sh_getopt (argc, argv, optstr);
180 argv[0] = t;
182 else if (rest_of_args == (WORD_LIST *)NULL)
184 for (i = 0; i < 10 && dollar_vars[i]; i++)
187 sh_getopt_restore_state (dollar_vars);
188 ret = sh_getopt (i, dollar_vars, optstr);
190 else
192 register WORD_LIST *words;
193 char **v;
195 for (i = 0; i < 10 && dollar_vars[i]; i++)
197 for (words = rest_of_args; words; words = words->next, i++)
199 v = strvec_create (i + 1);
200 for (i = 0; i < 10 && dollar_vars[i]; i++)
201 v[i] = dollar_vars[i];
202 for (words = rest_of_args; words; words = words->next, i++)
203 v[i] = words->word->word;
204 v[i] = (char *)NULL;
205 sh_getopt_restore_state (v);
206 ret = sh_getopt (i, v, optstr);
207 free (v);
210 if (special_error)
211 sh_opterr = old_opterr;
213 /* Set the OPTIND variable in any case, to handle "--" skipping. It's
214 highly unlikely that 14 digits will be too few. */
215 if (sh_optind < 10)
217 numval[14] = sh_optind + '0';
218 numval[15] = '\0';
219 i = 14;
221 else
223 numval[i = 15] = '\0';
224 n = sh_optind;
227 numval[--i] = (n % 10) + '0';
229 while (n /= 10);
231 bind_variable ("OPTIND", numval + i, 0);
233 /* If an error occurred, decide which one it is and set the return
234 code appropriately. In all cases, the option character in error
235 is in OPTOPT. If an invalid option was encountered, OPTARG is
236 NULL. If a required option argument was missing, OPTARG points
237 to a NULL string (that is, sh_optarg[0] == 0). */
238 if (ret == '?')
240 if (sh_optarg == NULL)
241 ret = G_INVALID_OPT;
242 else if (sh_optarg[0] == '\0')
243 ret = G_ARG_MISSING;
246 if (ret == G_EOF)
248 unbind_variable ("OPTARG");
249 getopts_bind_variable (name, "?");
250 return (EXECUTION_FAILURE);
253 if (ret == G_INVALID_OPT)
255 /* Invalid option encountered. */
256 ret = getopts_bind_variable (name, "?");
258 if (special_error)
260 strval[0] = (char)sh_optopt;
261 strval[1] = '\0';
262 bind_variable ("OPTARG", strval, 0);
264 else
265 unbind_variable ("OPTARG");
267 return (ret);
270 if (ret == G_ARG_MISSING)
272 /* Required argument missing. */
273 if (special_error)
275 ret = getopts_bind_variable (name, ":");
277 strval[0] = (char)sh_optopt;
278 strval[1] = '\0';
279 bind_variable ("OPTARG", strval, 0);
281 else
283 ret = getopts_bind_variable (name, "?");
284 unbind_variable ("OPTARG");
286 return (ret);
289 bind_variable ("OPTARG", sh_optarg, 0);
291 strval[0] = (char) ret;
292 strval[1] = '\0';
293 return (getopts_bind_variable (name, strval));
296 /* The getopts builtin. Build an argv, and call dogetopts with it. */
298 getopts_builtin (list)
299 WORD_LIST *list;
301 char **av;
302 int ac, ret;
304 if (list == 0)
306 builtin_usage ();
307 return EX_USAGE;
310 reset_internal_getopt ();
311 if (internal_getopt (list, "") != -1)
313 builtin_usage ();
314 return (EX_USAGE);
316 list = loptend;
318 av = make_builtin_argv (list, &ac);
319 ret = dogetopts (ac, av);
320 free ((char *)av);
322 return (ret);