blob: 1d2a68a44304303b7c2b86d5640e859c3d507511 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001This file is getopts.def, from which is created getopts.c.
2It implements the builtin "getopts" in Bash.
3
Jari Aalto95732b42005-12-07 14:08:12 +00004Copyright (C) 1987-2004 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
Jari Aalto726f6381996-08-26 18:22:31 +000020
21$PRODUCES getopts.c
22
23$BUILTIN getopts
Jari Aalto726f6381996-08-26 18:22:31 +000024$FUNCTION getopts_builtin
25$SHORT_DOC getopts optstring name [arg]
Jari Aalto31859422009-01-12 13:36:28 +000026Parse option arguments.
27
28Getopts is used by shell procedures to parse positional parameters
29as options.
Jari Aalto726f6381996-08-26 18:22:31 +000030
31OPTSTRING contains the option letters to be recognized; if a letter
32is followed by a colon, the option is expected to have an argument,
33which should be separated from it by white space.
34
35Each time it is invoked, getopts will place the next option in the
36shell variable $name, initializing name if it does not exist, and
37the index of the next argument to be processed into the shell
38variable OPTIND. OPTIND is initialized to 1 each time the shell or
39a shell script is invoked. When an option requires an argument,
40getopts places that argument into the shell variable OPTARG.
41
42getopts reports errors in one of two ways. If the first character
43of OPTSTRING is a colon, getopts uses silent error reporting. In
Jari Aalto7117c2d2002-07-17 14:10:11 +000044this mode, no error messages are printed. If an invalid option is
Jari Aalto726f6381996-08-26 18:22:31 +000045seen, getopts places the option character found into OPTARG. If a
46required argument is not found, getopts places a ':' into NAME and
47sets OPTARG to the option character found. If getopts is not in
Jari Aalto7117c2d2002-07-17 14:10:11 +000048silent mode, and an invalid option is seen, getopts places '?' into
Jari Aaltob80f6442004-07-27 13:29:18 +000049NAME and unsets OPTARG. If a required argument is not found, a '?'
Jari Aalto726f6381996-08-26 18:22:31 +000050is placed in NAME, OPTARG is unset, and a diagnostic message is
51printed.
52
53If the shell variable OPTERR has the value 0, getopts disables the
54printing of error messages, even if the first character of
55OPTSTRING is not a colon. OPTERR has the value 1 by default.
56
57Getopts normally parses the positional parameters ($0 - $9), but if
58more arguments are given, they are parsed instead.
Jari Aalto31859422009-01-12 13:36:28 +000059
60Exit Status:
61Returns success if an option is found; fails if the end of options is
62encountered or an error occurs.
Jari Aalto726f6381996-08-26 18:22:31 +000063$END
64
Jari Aaltoccc6cda1996-12-23 17:02:34 +000065#include <config.h>
66
Jari Aalto726f6381996-08-26 18:22:31 +000067#include <stdio.h>
68
Jari Aaltoccc6cda1996-12-23 17:02:34 +000069#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000070# ifdef _MINIX
71# include <sys/types.h>
72# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000073# include <unistd.h>
74#endif
75
76#include "../bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000077
78#include "../shell.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000079#include "common.h"
80#include "bashgetopt.h"
Jari Aalto726f6381996-08-26 18:22:31 +000081#include "getopt.h"
82
Jari Aaltoccc6cda1996-12-23 17:02:34 +000083#define G_EOF -1
Jari Aalto7117c2d2002-07-17 14:10:11 +000084#define G_INVALID_OPT -2
Jari Aaltoccc6cda1996-12-23 17:02:34 +000085#define G_ARG_MISSING -3
Jari Aalto726f6381996-08-26 18:22:31 +000086
87extern char *this_command_name;
Jari Aalto726f6381996-08-26 18:22:31 +000088
Jari Aalto7117c2d2002-07-17 14:10:11 +000089static int getopts_bind_variable __P((char *, char *));
90static int dogetopts __P((int, char **));
91
Jari Aalto726f6381996-08-26 18:22:31 +000092/* getopts_reset is magic code for when OPTIND is reset. N is the
93 value that has just been assigned to OPTIND. */
94void
95getopts_reset (newind)
96 int newind;
97{
98 sh_optind = newind;
Jari Aaltoccc6cda1996-12-23 17:02:34 +000099 sh_badopt = 0;
100}
101
102static int
103getopts_bind_variable (name, value)
104 char *name, *value;
105{
106 SHELL_VAR *v;
107
108 if (legal_identifier (name))
109 {
Jari Aalto95732b42005-12-07 14:08:12 +0000110 v = bind_variable (name, value, 0);
Chet Ramey495aee42011-11-22 19:11:26 -0500111 if (v && (readonly_p (v) || noassign_p (v)))
112 return (EX_MISCERROR);
113 return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000114 }
115 else
116 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000117 sh_invalidid (name);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000118 return (EXECUTION_FAILURE);
119 }
Jari Aalto726f6381996-08-26 18:22:31 +0000120}
121
122/* Error handling is now performed as specified by Posix.2, draft 11
123 (identical to that of ksh-88). The special handling is enabled if
124 the first character of the option string is a colon; this handling
125 disables diagnostic messages concerning missing option arguments
Jari Aalto7117c2d2002-07-17 14:10:11 +0000126 and invalid option characters. The handling is as follows.
Jari Aalto726f6381996-08-26 18:22:31 +0000127
Jari Aalto7117c2d2002-07-17 14:10:11 +0000128 INVALID OPTIONS:
Jari Aalto726f6381996-08-26 18:22:31 +0000129 name -> "?"
130 if (special_error) then
131 OPTARG = option character found
132 no error output
133 else
134 OPTARG unset
135 diagnostic message
136 fi
137
138 MISSING OPTION ARGUMENT;
139 if (special_error) then
140 name -> ":"
141 OPTARG = option character found
142 else
143 name -> "?"
144 OPTARG unset
145 diagnostic message
146 fi
147 */
148
149static int
150dogetopts (argc, argv)
151 int argc;
152 char **argv;
153{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000154 int ret, special_error, old_opterr, i, n;
Jari Aalto726f6381996-08-26 18:22:31 +0000155 char strval[2], numval[16];
156 char *optstr; /* list of options */
157 char *name; /* variable to get flag val */
158 char *t;
159
160 if (argc < 3)
161 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000162 builtin_usage ();
Jari Aalto726f6381996-08-26 18:22:31 +0000163 return (EX_USAGE);
164 }
165
166 /* argv[0] is "getopts". */
167
168 optstr = argv[1];
169 name = argv[2];
170 argc -= 2;
171 argv += 2;
172
173 special_error = optstr[0] == ':';
174
175 if (special_error)
176 {
177 old_opterr = sh_opterr;
178 optstr++;
179 sh_opterr = 0; /* suppress diagnostic messages */
180 }
181
182 if (argc > 1)
183 {
184 sh_getopt_restore_state (argv);
185 t = argv[0];
186 argv[0] = dollar_vars[0];
187 ret = sh_getopt (argc, argv, optstr);
188 argv[0] = t;
189 }
190 else if (rest_of_args == (WORD_LIST *)NULL)
191 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000192 for (i = 0; i < 10 && dollar_vars[i]; i++)
193 ;
Jari Aaltob72432f1999-02-19 17:11:39 +0000194
195 sh_getopt_restore_state (dollar_vars);
Jari Aalto726f6381996-08-26 18:22:31 +0000196 ret = sh_getopt (i, dollar_vars, optstr);
197 }
198 else
199 {
Jari Aalto726f6381996-08-26 18:22:31 +0000200 register WORD_LIST *words;
201 char **v;
202
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000203 for (i = 0; i < 10 && dollar_vars[i]; i++)
204 ;
205 for (words = rest_of_args; words; words = words->next, i++)
206 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000207 v = strvec_create (i + 1);
Jari Aalto726f6381996-08-26 18:22:31 +0000208 for (i = 0; i < 10 && dollar_vars[i]; i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000209 v[i] = dollar_vars[i];
Jari Aalto726f6381996-08-26 18:22:31 +0000210 for (words = rest_of_args; words; words = words->next, i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000211 v[i] = words->word->word;
Jari Aalto726f6381996-08-26 18:22:31 +0000212 v[i] = (char *)NULL;
Jari Aaltob72432f1999-02-19 17:11:39 +0000213 sh_getopt_restore_state (v);
Jari Aalto726f6381996-08-26 18:22:31 +0000214 ret = sh_getopt (i, v, optstr);
215 free (v);
216 }
217
218 if (special_error)
219 sh_opterr = old_opterr;
220
Jari Aalto7117c2d2002-07-17 14:10:11 +0000221 /* Set the OPTIND variable in any case, to handle "--" skipping. It's
222 highly unlikely that 14 digits will be too few. */
Jari Aalto726f6381996-08-26 18:22:31 +0000223 if (sh_optind < 10)
224 {
225 numval[14] = sh_optind + '0';
226 numval[15] = '\0';
227 i = 14;
228 }
229 else
230 {
231 numval[i = 15] = '\0';
232 n = sh_optind;
233 do
234 {
235 numval[--i] = (n % 10) + '0';
236 }
237 while (n /= 10);
238 }
Jari Aalto95732b42005-12-07 14:08:12 +0000239 bind_variable ("OPTIND", numval + i, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000240
241 /* If an error occurred, decide which one it is and set the return
242 code appropriately. In all cases, the option character in error
Jari Aalto7117c2d2002-07-17 14:10:11 +0000243 is in OPTOPT. If an invalid option was encountered, OPTARG is
Jari Aalto726f6381996-08-26 18:22:31 +0000244 NULL. If a required option argument was missing, OPTARG points
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000245 to a NULL string (that is, sh_optarg[0] == 0). */
Jari Aalto726f6381996-08-26 18:22:31 +0000246 if (ret == '?')
247 {
248 if (sh_optarg == NULL)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000249 ret = G_INVALID_OPT;
Jari Aalto726f6381996-08-26 18:22:31 +0000250 else if (sh_optarg[0] == '\0')
251 ret = G_ARG_MISSING;
252 }
253
254 if (ret == G_EOF)
255 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000256 unbind_variable ("OPTARG");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000257 getopts_bind_variable (name, "?");
Jari Aalto726f6381996-08-26 18:22:31 +0000258 return (EXECUTION_FAILURE);
259 }
260
Jari Aalto7117c2d2002-07-17 14:10:11 +0000261 if (ret == G_INVALID_OPT)
Jari Aalto726f6381996-08-26 18:22:31 +0000262 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000263 /* Invalid option encountered. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000264 ret = getopts_bind_variable (name, "?");
Jari Aalto726f6381996-08-26 18:22:31 +0000265
266 if (special_error)
267 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000268 strval[0] = (char)sh_optopt;
Jari Aalto726f6381996-08-26 18:22:31 +0000269 strval[1] = '\0';
Jari Aalto95732b42005-12-07 14:08:12 +0000270 bind_variable ("OPTARG", strval, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000271 }
272 else
Jari Aalto7117c2d2002-07-17 14:10:11 +0000273 unbind_variable ("OPTARG");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000274
275 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +0000276 }
277
278 if (ret == G_ARG_MISSING)
279 {
280 /* Required argument missing. */
281 if (special_error)
282 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000283 ret = getopts_bind_variable (name, ":");
Jari Aalto726f6381996-08-26 18:22:31 +0000284
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000285 strval[0] = (char)sh_optopt;
Jari Aalto726f6381996-08-26 18:22:31 +0000286 strval[1] = '\0';
Jari Aalto95732b42005-12-07 14:08:12 +0000287 bind_variable ("OPTARG", strval, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000288 }
289 else
290 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000291 ret = getopts_bind_variable (name, "?");
Jari Aalto7117c2d2002-07-17 14:10:11 +0000292 unbind_variable ("OPTARG");
Jari Aalto726f6381996-08-26 18:22:31 +0000293 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000294 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +0000295 }
296
Jari Aalto95732b42005-12-07 14:08:12 +0000297 bind_variable ("OPTARG", sh_optarg, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000298
299 strval[0] = (char) ret;
300 strval[1] = '\0';
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000301 return (getopts_bind_variable (name, strval));
Jari Aalto726f6381996-08-26 18:22:31 +0000302}
303
304/* The getopts builtin. Build an argv, and call dogetopts with it. */
305int
306getopts_builtin (list)
307 WORD_LIST *list;
308{
Jari Aalto726f6381996-08-26 18:22:31 +0000309 char **av;
310 int ac, ret;
Jari Aalto726f6381996-08-26 18:22:31 +0000311
312 if (list == 0)
Jari Aaltod166f041997-06-05 14:59:13 +0000313 {
314 builtin_usage ();
315 return EX_USAGE;
316 }
Jari Aalto726f6381996-08-26 18:22:31 +0000317
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000318 reset_internal_getopt ();
Jari Aaltof73dda02001-11-13 17:56:06 +0000319 if (internal_getopt (list, "") != -1)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000320 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000321 builtin_usage ();
322 return (EX_USAGE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000323 }
324 list = loptend;
Jari Aalto726f6381996-08-26 18:22:31 +0000325
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000326 av = make_builtin_argv (list, &ac);
Jari Aalto726f6381996-08-26 18:22:31 +0000327 ret = dogetopts (ac, av);
328 free ((char *)av);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000329
Jari Aalto726f6381996-08-26 18:22:31 +0000330 return (ret);
331}