]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/getopts.def
Bash-5.2 patch 26: fix typo when specifying readline's custom color prefix
[thirdparty/bash.git] / builtins / getopts.def
1 This file is getopts.def, from which is created getopts.c.
2 It implements the builtin "getopts" in Bash.
3
4 Copyright (C) 1987-2015 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20
21 $PRODUCES getopts.c
22
23 $BUILTIN getopts
24 $FUNCTION getopts_builtin
25 $SHORT_DOC getopts optstring name [arg]
26 Parse option arguments.
27
28 Getopts is used by shell procedures to parse positional parameters
29 as options.
30
31 OPTSTRING contains the option letters to be recognized; if a letter
32 is followed by a colon, the option is expected to have an argument,
33 which should be separated from it by white space.
34
35 Each time it is invoked, getopts will place the next option in the
36 shell variable $name, initializing name if it does not exist, and
37 the index of the next argument to be processed into the shell
38 variable OPTIND. OPTIND is initialized to 1 each time the shell or
39 a shell script is invoked. When an option requires an argument,
40 getopts places that argument into the shell variable OPTARG.
41
42 getopts reports errors in one of two ways. If the first character
43 of OPTSTRING is a colon, getopts uses silent error reporting. In
44 this mode, no error messages are printed. If an invalid option is
45 seen, getopts places the option character found into OPTARG. If a
46 required argument is not found, getopts places a ':' into NAME and
47 sets OPTARG to the option character found. If getopts is not in
48 silent mode, and an invalid option is seen, getopts places '?' into
49 NAME and unsets OPTARG. If a required argument is not found, a '?'
50 is placed in NAME, OPTARG is unset, and a diagnostic message is
51 printed.
52
53 If the shell variable OPTERR has the value 0, getopts disables the
54 printing of error messages, even if the first character of
55 OPTSTRING is not a colon. OPTERR has the value 1 by default.
56
57 Getopts normally parses the positional parameters ($0 - $9), but if
58 more arguments are given, they are parsed instead.
59
60 Exit Status:
61 Returns success if an option is found; fails if the end of options is
62 encountered or an error occurs.
63 $END
64
65 #include <config.h>
66
67 #include <stdio.h>
68
69 #if defined (HAVE_UNISTD_H)
70 # ifdef _MINIX
71 # include <sys/types.h>
72 # endif
73 # include <unistd.h>
74 #endif
75
76 #include "../bashansi.h"
77 #include "../bashintl.h"
78
79 #include "../shell.h"
80 #include "../execute_cmd.h"
81 #include "common.h"
82 #include "bashgetopt.h"
83 #include "getopt.h"
84
85 #define G_EOF -1
86 #define G_INVALID_OPT -2
87 #define G_ARG_MISSING -3
88
89 static int getopts_unbind_variable __P((char *));
90 static int getopts_bind_variable __P((char *, char *));
91 static int dogetopts __P((int, char **));
92
93 /* getopts_reset is magic code for when OPTIND is reset. N is the
94 value that has just been assigned to OPTIND. */
95 void
96 getopts_reset (newind)
97 int newind;
98 {
99 sh_optind = newind;
100 sh_badopt = 0;
101 }
102
103 static int
104 getopts_unbind_variable (name)
105 char *name;
106 {
107 #if 0
108 return (unbind_variable (name));
109 #else
110 return (unbind_variable_noref (name));
111 #endif
112 }
113
114 static int
115 getopts_bind_variable (name, value)
116 char *name, *value;
117 {
118 SHELL_VAR *v;
119
120 if (legal_identifier (name))
121 {
122 v = bind_variable (name, value, 0);
123 if (v && (readonly_p (v) || noassign_p (v)))
124 return (EX_MISCERROR);
125 return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
126 }
127 else
128 {
129 sh_invalidid (name);
130 return (EXECUTION_FAILURE);
131 }
132 }
133
134 /* Error handling is now performed as specified by Posix.2, draft 11
135 (identical to that of ksh-88). The special handling is enabled if
136 the first character of the option string is a colon; this handling
137 disables diagnostic messages concerning missing option arguments
138 and invalid option characters. The handling is as follows.
139
140 INVALID OPTIONS:
141 name -> "?"
142 if (special_error) then
143 OPTARG = option character found
144 no error output
145 else
146 OPTARG unset
147 diagnostic message
148 fi
149
150 MISSING OPTION ARGUMENT;
151 if (special_error) then
152 name -> ":"
153 OPTARG = option character found
154 else
155 name -> "?"
156 OPTARG unset
157 diagnostic message
158 fi
159 */
160
161 static int
162 dogetopts (argc, argv)
163 int argc;
164 char **argv;
165 {
166 int ret, special_error, old_opterr, i, n;
167 char strval[2], numval[16];
168 char *optstr; /* list of options */
169 char *name; /* variable to get flag val */
170 char *t;
171
172 if (argc < 3)
173 {
174 builtin_usage ();
175 return (EX_USAGE);
176 }
177
178 /* argv[0] is "getopts". */
179
180 optstr = argv[1];
181 name = argv[2];
182 argc -= 2;
183 argv += 2;
184
185 special_error = optstr[0] == ':';
186
187 if (special_error)
188 {
189 old_opterr = sh_opterr;
190 optstr++;
191 sh_opterr = 0; /* suppress diagnostic messages */
192 }
193
194 if (argc > 1)
195 {
196 sh_getopt_restore_state (argv);
197 t = argv[0];
198 argv[0] = dollar_vars[0];
199 ret = sh_getopt (argc, argv, optstr);
200 argv[0] = t;
201 }
202 else if (rest_of_args == (WORD_LIST *)NULL)
203 {
204 for (i = 0; i < 10 && dollar_vars[i]; i++)
205 ;
206
207 sh_getopt_restore_state (dollar_vars);
208 ret = sh_getopt (i, dollar_vars, optstr);
209 }
210 else
211 {
212 register WORD_LIST *words;
213 char **v;
214
215 for (i = 0; i < 10 && dollar_vars[i]; i++)
216 ;
217 for (words = rest_of_args; words; words = words->next, i++)
218 ;
219 v = strvec_create (i + 1);
220 for (i = 0; i < 10 && dollar_vars[i]; i++)
221 v[i] = dollar_vars[i];
222 for (words = rest_of_args; words; words = words->next, i++)
223 v[i] = words->word->word;
224 v[i] = (char *)NULL;
225 sh_getopt_restore_state (v);
226 ret = sh_getopt (i, v, optstr);
227 free (v);
228 }
229
230 if (special_error)
231 sh_opterr = old_opterr;
232
233 /* Set the OPTIND variable in any case, to handle "--" skipping. It's
234 highly unlikely that 14 digits will be too few. */
235 if (sh_optind < 10)
236 {
237 numval[14] = sh_optind + '0';
238 numval[15] = '\0';
239 i = 14;
240 }
241 else
242 {
243 numval[i = 15] = '\0';
244 n = sh_optind;
245 do
246 {
247 numval[--i] = (n % 10) + '0';
248 }
249 while (n /= 10);
250 }
251 bind_variable ("OPTIND", numval + i, 0);
252
253 /* If an error occurred, decide which one it is and set the return
254 code appropriately. In all cases, the option character in error
255 is in OPTOPT. If an invalid option was encountered, OPTARG is
256 NULL. If a required option argument was missing, OPTARG points
257 to a NULL string (that is, sh_optarg[0] == 0). */
258 if (ret == '?')
259 {
260 if (sh_optarg == NULL)
261 ret = G_INVALID_OPT;
262 else if (sh_optarg[0] == '\0')
263 ret = G_ARG_MISSING;
264 }
265
266 if (ret == G_EOF)
267 {
268 getopts_unbind_variable ("OPTARG");
269 getopts_bind_variable (name, "?");
270 return (EXECUTION_FAILURE);
271 }
272
273 if (ret == G_INVALID_OPT)
274 {
275 /* Invalid option encountered. */
276 ret = getopts_bind_variable (name, "?");
277
278 if (special_error)
279 {
280 strval[0] = (char)sh_optopt;
281 strval[1] = '\0';
282 bind_variable ("OPTARG", strval, 0);
283 }
284 else
285 getopts_unbind_variable ("OPTARG");
286
287 return (ret);
288 }
289
290 if (ret == G_ARG_MISSING)
291 {
292 /* Required argument missing. */
293 if (special_error)
294 {
295 ret = getopts_bind_variable (name, ":");
296
297 strval[0] = (char)sh_optopt;
298 strval[1] = '\0';
299 bind_variable ("OPTARG", strval, 0);
300 }
301 else
302 {
303 ret = getopts_bind_variable (name, "?");
304 getopts_unbind_variable ("OPTARG");
305 }
306 return (ret);
307 }
308
309 bind_variable ("OPTARG", sh_optarg, 0);
310
311 strval[0] = (char) ret;
312 strval[1] = '\0';
313 return (getopts_bind_variable (name, strval));
314 }
315
316 /* The getopts builtin. Build an argv, and call dogetopts with it. */
317 int
318 getopts_builtin (list)
319 WORD_LIST *list;
320 {
321 char **av;
322 int ac, ret;
323
324 if (list == 0)
325 {
326 builtin_usage ();
327 return EX_USAGE;
328 }
329
330 reset_internal_getopt ();
331 if ((ret = internal_getopt (list, "")) != -1)
332 {
333 if (ret == GETOPT_HELP)
334 builtin_help ();
335 else
336 builtin_usage ();
337 return (EX_USAGE);
338 }
339 list = loptend;
340
341 av = make_builtin_argv (list, &ac);
342 ret = dogetopts (ac, av);
343 free ((char *)av);
344
345 return (ret);
346 }